Elektroda.pl
Elektroda.pl
X

Wyszukiwarki naszych partnerów

Wyszukaj w ofercie 200 tys. produktów TME
Europejski lider sprzedaży techniki i elektroniki.
Proszę, dodaj wyjątek elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

[STM32] - SPI z TFT ILI9341 i STM32F103, STM32F407

dziechu 25 Cze 2014 22:39 6783 57
  • #1 25 Cze 2014 22:39
    dziechu
    Poziom 27  

    Mam ciagle problemy z SPI tego wyświetlacza i procesorami STM32F103 i STM32F407. Problem dotyczy odbioru danych. Przy tych samych ustawieniach F407 odbiera dane jeżeli po bajcie rozkazu odbierane są dwa bajty danych. Zawiesza się TFT, jeżeli wysylany jest rozkaz po którym odbiera się więcej niż 2 bajty danych. Na STM32F103 dzieje się podobnie, jeżeli chodzi o wieszanie TFT, natomiast nie odbiera prawidłowo danych nigdy (odbiera przeważnie 0x00).

    Inicjalizacja dla F407:

    Kod: c
    Zaloguj się, aby zobaczyć kod


    Funkcje nadawania/odbierania:

    Kod: c
    Zaloguj się, aby zobaczyć kod


    Funkcja odczytu Read Display Power Mode (0x0A).
    Odczytuje dwa bajty, przy czym znaczący jest tylko drugi, pierwszy odbierany bajt po rozkazie jest zawsze nieokreślony (dummy). Działa prawidłowo:

    Kod: c
    Zaloguj się, aby zobaczyć kod


    Funkcja odczytu Read ID Information (0x04).
    Odczytuje cztery bajty, przy czym znaczące są trzy (pierwszy dummy).
    Zawiesza wyświetlacz:

    Kod: c
    Zaloguj się, aby zobaczyć kod


    Dla STM32F103 funkcje są idenstyczne, poza inicjalizacją. Z tym że funkcje odczytu 2 bajtów nie działają prawidłowo (odczyt 0x00), odczytu powyżej 2 bajtów także wieszają TFT.
    Inicjalizacja F103:

    Kod: c
    Zaloguj się, aby zobaczyć kod

    Samo sterowanie TFT bez odczytu, czyli transmisja do wyświetlacza działa prawidłowo i TFT reaguje tak jak powinien.

  • #2 25 Cze 2014 23:32
    el2010tmp
    Poziom 25  

    Myślę że jak się pisze:

    dziechu napisał:
    CS_bb=0;

    to musi też gdzieś być: CS_bb=1;

    Moja komunikacja z MEMS-em po spi [SPL niestety]:
    Kod: c
    Zaloguj się, aby zobaczyć kod

    Zwóć uwagę na flage RXNE której w Twoim kodzie nie ma.

  • #3 25 Cze 2014 23:36
    Jado_one
    Poziom 22  

    A co piszą na temat timingów w pdf'ie do tego wyświetlacza?
    Czasami wymagane są odp. (minimalne) okresy dotyczące załączenia/wyłączenia sygnałów CS lub innych sterujących wyświetlaczem.

    Czy to SDO/SDI w kodzie powyżej to jest zdefiniowane od strony wyświetlacza czy procesora (lub błąd w komentarzu) bo SDO widziałem jako floating, a powinno być PP, to samo jest źle (na odwrót) dla SDI.

    A druga sprawa to jeszcze ustawienie CPOL/CPHA może mieć znaczenie - a widzę, że u Ciebie nie jest to inicjalizowane. Powinno być opisane w datasheecie jaka ma być polaryzacja i czy dane wczytują się przy narastającym czy opadającym zboczu CLK.

  • #4 25 Cze 2014 23:56
    dziechu
    Poziom 27  

    el2010tmp napisał:
    Zwóć uwagę na flage RXNE której w Twoim kodzie nie ma.

    Próby z RXNE zamiast TXE też były - działanie bez zmian.
    Jado_one napisał:
    A co piszą na temat timingów w pdf'ie do tego wyświetlacza?

    Dokladnie tak samo zachowuje się przy zegarze 72MHz, jak i przy 8MHz.
    Jado_one napisał:
    Czy to SDO/SDI w kodzie powyżej to jest zdefiniowane od strony wyświetlacza czy procesora (lub błąd w komentarzu) bo SDO widziałem jako floating, a powinno być PP, to samo jest źle (na odwrót) dla SDI.

    Od wyświetlacza, to akurat musi być dobrze, bo jak wspomniałem transmisja do wyświetlacza działa poprawnie i bardzo szybko. W takim razie i polaryzacje powinny być ok. Nie rozumiem dlaczego odczyt rozkazów z więcej niż 2 bajtami zawiesza wyświetlacz, przecież wyświetlacz potrzebuje do zakończenia procedury tylko odpowiedniej ilości cykli zegarowych, przecież nawet 'nie wie' czy coś jego dane odbiera. Wysłanie czterech bajtów powinno dostarczyć odpowiedniej ilości impulsów zegarowych. Zreszta dodanie dodatkowych zapisów/odczytów danych nie odwiesza wyświetlacza. Zachowuje się tak, jakby nadal na coś czekał. Wg. dokumentu dane są czytane przy narastającym zboczu zegara.

    Dodano po 3 [minuty]:

    el2010tmp napisał:
    to musi też gdzieś być: CS_bb=1;

    CS może być stale 0, ale zostało na razie w funkcjach CS_bb=0; CS_bb=1 nie ma. Myślałem że po zakończeniu każdego rozkazu, CS musi wrócić na 1, ale nie musi.

  • #5 26 Cze 2014 10:47
    dziechu
    Poziom 27  

    Zmiany bitu CPOL niczego nie zmieniają w działaniu LCD, więc spoczynkowy stan zegara jest dla niego chyba obojętny. Ustawienie bitu CPHA powoduje całkowity zanik komunikacji, czyli powinien być 0. Ciągle zastanawia mnie ten Baud Rate. Przy prawidłowej transmisji nie powinno mieć znaczenia zwalnianie jej. Zresztą wyświetlacz działa prawidłowo przy 72MHz jak i 8 MHz, więc zwolnienie transmisji 9 razy niczego nie zmienia. Natomiast przy 72 MHz działa tylko jak bity BR są 000, lub 001. Przy 010 zaczynają się problemy, przy 011 przestaje działać. 010 to podział przez 8, a już transmisja zaczyna się sypać. Przy zwolnieniu zegara systemowego 9 razy jest ok. Coś nie tak jest z tą transmisją, ale co można jeszcze ustawiać?

  • #6 26 Cze 2014 11:32
    94075
    Usunięty  
  • #7 26 Cze 2014 11:35
    Jado_one
    Poziom 22  

    Ciekawe - ja u siebie mam wszystkie transmisje działające przy CPOL/CPHA=1 - no, ale może ten wyświetlacz ma inne wymagania.
    Przydałby się podgląd tego co wychodzi ze scalaka za pomocą analizatora stanów logicznych. Zmiana baudrate nie powinna na nic wpływać poza samą prędkością transmisji.
    Ja u siebie szybkość zmieniam tak:

    Kod: c
    Zaloguj się, aby zobaczyć kod

    Raz tylko miałem przypadek, kiedy zbyt szybka transmisja powodowała błędy.
    A było to związane z tym (obsługa transmisji odbywała się w procedurze obsługi przerwania), że zanim wykonał się kod obsługi przerwania, bajt przez SPI zdązył się wysłać i w tej samej obsłudze przerwania następowało ponowne zgłoszenie przerwania. Przeniesienie operacji kasowania flagi przerwania z dołu przerwania, na samą górę rozwiązało całkowicie problem.
    Ale tutaj mamy odwrotną sytuację.

  • #8 26 Cze 2014 11:40
    dziechu
    Poziom 27  

    Dummy Clock Cycle to chyba 8 cykli zegarowych po wysłaniu rozkazu. Jest to uwzględnione:

    dziechu napisał:
    Odczytuje cztery bajty, przy czym znaczące są trzy (pierwszy dummy).


    Dodano po 3 [minuty]:

    Jado_one napisał:
    ja u siebie mam wszystkie transmisje działające przy CPOL/CPHA=1 - no, ale może ten wyświetlacz ma inne wymagania.

    Być może mam wszystko pokopane, a transmisja działa tylko przypadkowo:)

    Dodano po 1 [minuty]:

    Jado_one napisał:
    SPI1->CR1 &= B16(11111111,11000111);// najpierw zerujemy

    A dlaczego zerujemy? Jeżeli po resecie domyślnie jest 000?

  • #9 26 Cze 2014 11:51
    94075
    Usunięty  
  • #10 26 Cze 2014 12:01
    dziechu
    Poziom 27  

    albertb napisał:
    strona 38

    Chodzi o ten jeden impuls zegarowy? Jak go wygenerować sprzętowym SPI? Ale zauważ że w tej chwili zastanawiamy się nad podstawowymi ustawieniami SPI, np. dlaczego ustawianie BR i zwalnianie transmisji powoduje jej brak/błędy.

  • #11 26 Cze 2014 12:03
    94075
    Usunięty  
  • #12 26 Cze 2014 12:16
    dziechu
    Poziom 27  

    albertb napisał:
    A to przepraszam że odpowiedziałem nie na temat. Już się poprawiam i zmykam z wątku.

    Nie, nie! Nie zmykaj. Po prostu wydaje mi się że muszę rozwiązać jakieś bardziej podstawowe problemy z transmisją, a potem wrócić do problemu odbioru danych. Z jednej strony wszystko działa szybko i stabilnie (wysyłanie do wyświetlacza), z drugiej występują niezrozumiałe efekty, jak wspomniane problemy z transmisją przy zwiększaniu wartości BR (a przy zmniejszaniu częstotliwości zegara systemowego nie).

  • #13 26 Cze 2014 17:10
    Jado_one
    Poziom 22  

    dziechu napisał:

    Jado_one napisał:
    SPI1->CR1 &= B16(11111111,11000111);// najpierw zerujemy

    A dlaczego zerujemy? Jeżeli po resecie domyślnie jest 000?

    No - akurat ja u siebie mam podpięte trzy urządzenia do SPI i każde gada na innej szybkości, więc zmieniam niektóre parametry "w locie".

    Kolega Albert może mieć rację - nie jesteś pewien czy błędne działanie wynika z błędnego działania samego SPI, czy też jakiś timingów wymaganych przez wyświetlacz, który w zależności od (przypadkowej) szybkości transmisji dobrze "załapuje dane" lub źle.
    A nie testowałeś samego SPI z innym scalakiem?

  • #14 26 Cze 2014 17:38
    eros81
    Poziom 14  

    Ja SPI rozpracowałem dopiero gdy analizator logiczny kupiłem (są tanie klony na portalu aukcyjnym)
    Wtedy dopiero zobaczyłem co i jak po kabelkach "lata" i naocznie zobaczyłem gdzie błędy popełniam.
    Bez tego TFT ILI9341 na STM32F103 bym nie uruchomił chyba nigdy.

    Pozdrawiam
    Tomek

  • #15 26 Cze 2014 17:47
    dziechu
    Poziom 27  

    Jado_one napisał:
    Kolega Albert może mieć rację - nie jesteś pewien czy błędne działanie wynika z błędnego działania samego SPI

    Tak, może mieć rację, ale to o czym pisze dotyczy tylko rozkazów z transmisją od wyświetlacza, a nie do. Na razie przestałem zajmować się odbieraniem danych i staram się dociec, dlaczego zwolnienie transmisji przez wpisanie wartości bo BR powoduje brak komunikacji. Problem o którym piszę występuje prawie tak samo z procesorem F407. Może sam rozwiążesz problem, jeżeli kupisz ten wyświetlacz:)

    Dodano po 3 [minuty]:

    eros81 napisał:
    Bez tego TFT ILI9341 na STM32F103 bym nie uruchomił chyba nigdy.

    Mógłbyś pokazać inicjalizację i główne funkcje komunikacyjne?

  • #16 26 Cze 2014 18:17
    Jado_one
    Poziom 22  

    dziechu napisał:
    Może sam rozwiążesz problem, jeżeli kupisz ten wyświetlacz:)

    Chyba jednak nie tym razem - własnie zamówiłem trochę modułów radiowych i trochę mnie to "szarpnie po kieszeni".
    Swoją drogą one też chodzą po SPI i mają dość wredne wymagania czasowe (chodzi o sygnał CS - musi być odpowiednio wcześniej przed transmisją "wystawiony" i tak samo po transmisji musi jeszcze potrwać trochę, bo inaczej "moduł może zgłupieć" :-)
    Nie wiem jak w praktyce działają te allegrowe analizatory - ja akurat kupiłem oryginalny (wtedy nie było jeszcze klonów) - teraz trudno mi wyobrazić sobie programowanie bez tego przydatnego urządzenia. Można sobie oprogramować transmisję bez urządzenia (jeśli mamy tylko samo nadawanie), podglądać jakie dane są odczytywane/wysyłane przez magistralę, itp...
    Tylko pod linuksem czasem lubi krzyczeć, że "nie wyrabia się z szybkością obróbki danych" i trzeba ponawiać samplowanie....(pod Win widziałem ze działało bezbłędnie).
    A tak to zastanawiasz się...WTF...dlaczego coś nie działa.....;-)

  • #17 26 Cze 2014 21:36
    dziechu
    Poziom 27  

    Kupiłem analizator, jak przyjdzie będę mógł sobie pooglądać. Fajne oprogramowanie jest do niego, z analizą typowych komunikacji. Zobaczymy co się dzieje na liniach SPI.

  • #19 01 Lip 2014 15:19
    dziechu
    Poziom 27  

    Ok. mam analizator. Okazuje się że bit TXE wcale nie oznacza koniec trasmisji, a bit RXNE także nie oznacza że zostały wygenerowane wszystkie bity zegarowe (8 w trybie 8bit).
    Nic z tego nie rozumiem. Wklejam rysunki. Wysyłany jest bajt 0x0A, co ładnie widać. Przed wysłaniem bajtu ustawiany jest trzeci kanał na 0 (DC_bb), po wysłaniu bajtu powinien zostać ustawiony na jeden, a jak widać, ustawiany jest na 1 już w trakcie wysyłania, bez względu na czekanie na TXE lub RXNE, dlaczego?

    Kod: c
    Zaloguj się, aby zobaczyć kod


    [STM32] - SPI z TFT ILI9341 i STM32F103, STM32F407

    z czekaniem na TXE:

    Kod: c
    Zaloguj się, aby zobaczyć kod



    [STM32] - SPI z TFT ILI9341 i STM32F103, STM32F407

    To na co mam czekać żeby wiedzieć że transfer bajtu się już skończył???

    Dodano po 40 [minuty]:

    Chyba sygnał BUSY (bit BSY) dobrze tu robi:) while(BUSY_bb==1); wydaje się że rozwiązuje sprawę.

    Dodano po 1 [minuty]:

    [STM32] - SPI z TFT ILI9341 i STM32F103, STM32F407

  • #20 01 Lip 2014 16:10
    Jado_one
    Poziom 22  

    Ja zawsze korzystam z RXNE, ale robię to w przerwaniach - być może czas potrzebny na przyjęcie przerwania powoduje, że w tym przypadku transmisja już jest zakończona (a może w przerwaniach to lepiej działa)
    Jeśli chodzi o TXE, to rzeczywiście - stan tego bitu wskazuje, że można już wpisywać dane do bufora, ale sama transmisja jeszcze trwa.

    No to skorzystaj z busy :-)

  • #21 01 Lip 2014 16:17
    atom1477
    Poziom 43  

    Powinieneś czekać na bit RXNE.
    Ale najpierw trzeba mieć pewność że wcześniej jest on równy 0.
    Dlatego przed nadawaniem oczytaj wartość rejestru SPI1->DR;

    Kod: c
    Zaloguj się, aby zobaczyć kod


    Nie widzę natomiast możliwości wystawienia jednego taktu zegarowego (Dummy Clock Cycle) w tym procku.

  • #22 01 Lip 2014 16:52
    dziechu
    Poziom 27  

    atom1477 napisał:
    Nie widzę natomiast możliwości wystawienia jednego taktu zegarowego (Dummy Clock Cycle) w tym procku.


    Nia ma takiej możliwości. trzeba zrobić to "ręcznie" - ustawić pin jako zwykły GPIO, wystawić impuls zegarowy i wrócić z GPIO do AF.

    atom1477 napisał:
    Powinieneś czekać na bit RXNE.

    Spróbuję jak piszesz.

    Dodano po 23 [minuty]:

    To jest SPI do wyświetlacza TFT, więc bardzo ważne jest uzyskanie max. szybkości. Nie wiem czy wczytywanie rejestru DR dla wyzerowania TXNE przed wysłaniem bajtu nie obniży prędkości względem czekania na bit BSY?

  • #23 01 Lip 2014 17:15
    atom1477
    Poziom 43  

    dziechu napisał:
    atom1477 napisał:
    Nie widzę natomiast możliwości wystawienia jednego taktu zegarowego (Dummy Clock Cycle) w tym procku.


    Nia ma takiej możliwości. trzeba zrobić to "ręcznie" - ustawić pin jako zwykły GPIO, wystawić impuls zegarowy i wrócić z GPIO do AF.

    Jak by był dostępny tryb 9-cio bitowy to by była taka możliwość.

    dziechu napisał:
    To jest SPI do wyświetlacza TFT, więc bardzo ważne jest uzyskanie max. szybkości. Nie wiem czy wczytywanie rejestru DR dla wyzerowania TXNE przed wysłaniem bajtu nie obniży prędkości względem czekania na bit BSY?

    RXNE a nie TXNE jak już.
    Trochę na pewno spowolni. Nie mniej jednak sprawdź czy to zadziała bo jestem ciekawy.

  • #24 01 Lip 2014 17:45
    dziechu
    Poziom 27  

    atom1477 napisał:
    RXNE a nie TXNE jak już.

    Tak, RXNE, literówka:) Działa. Trzebaby tylko sprawdzić która metoda szybciej.

  • #25 01 Lip 2014 18:12
    atom1477
    Poziom 43  

    Nie musisz kasować RXNE/odczytywać SPI1->DR przed każdym zapisem.
    Dałem Ci to do wnętrza funkcji do testu.
    Po poprawnym wysłaniu i odebraniu bajtu RXNE powinno być jednak wyzerowane.
    To coś wcześniej Ci bruździło i dlatego trzeba było ręcznie specjalnie kasować RXNE.
    Zamiast tego możesz dać jednokrotne kasować RXNE zaraz po inicjalizacji SPI. A potem powinna działać bez tego kasowania w funkcji.

  • #26 01 Lip 2014 18:50
    dziechu
    Poziom 27  

    Prawdopodobnie chodzi o to, że każde wyslanie bajtu, jednocześnie ustawia bit RXNE. Ja w funkcji wysylania kodu rozkazu nie czytam DR, więc bit pozostaje ustawiony. W takim razie każde wysłanie bajtu powinno być powiązane z odczytem DR, bez względu czy ma to sens czy nie.

  • #28 01 Lip 2014 19:25
    Jado_one
    Poziom 22  

    A czemu nie używasz trybu 4-"drutowego" - nie musiałbyś wtedy dodawać jeszcze jednego clock'a (własciwie to nawet 5-drutowy tryb ;-) - interface No II).
    Do tego DMA i transfer leci :-)

  • #29 01 Lip 2014 19:38
    atom1477
    Poziom 43  

    dziechu napisał:
    Prawdopodobnie chodzi o to, że każde wyslanie bajtu, jednocześnie ustawia bit RXNE. Ja w funkcji wysylania kodu rozkazu nie czytam DR, więc bit pozostaje ustawiony. W takim razie każde wysłanie bajtu powinno być powiązane z odczytem DR, bez względu czy ma to sens czy nie.

    No jak dla mnie to każda operacja na SPI to jest jednocześnie zapis i odczyt.
    I zawsze jak ktoś to próbuje to rozdzielić na osobny zapis i osobny odczyt to jest problem.

  • #30 01 Lip 2014 20:22
    dziechu
    Poziom 27  

    atom1477 napisał:
    No jak dla mnie to każda operacja na SPI to jest jednocześnie zapis i odczyt.

    Zapis to zapis, odczyt to odczyt. To że sprzętowo odbywa się to jednocześnie, nie znaczy że korzystając z komunikacji jednokierunkowej, trzeba bezwzględnie odczytywać rejestr DR. Najlepszym tego przykładem jest to, że tak mam zrobioną właśnie komunikację, i dzięki pozbyciu się rozkazu odczytu DR przy każdym bajcie, jest szybsza. W zasadzie do niczego mi ta komunikacja zwrotna nie jest potrzebna, bo przecież nie muszę odczytywać ID wyświetlacza, ani stanu rejestrów które sam ustawiłem. Ale meczę ten temat dla zasady, żeby poznać i kontrolować SPI - na przyszłość chociażby. Jeżeli używa się komunikacji dwukierunkowej, to owszem - zapis jest jednocześnie odczytem i nie ma po prostu sensu ich rozdział. Przy komunikacji jednokierunkowej jest tylko zapis - odczytu nie ma.

    Jado_one napisał:
    A czemu nie używasz trybu 4-"drutowego"


    No taki właśnie używam - str.38 - 4-wire serial protocol - Dummy Clock Cycle dla RDDID itp.

    Dodano po 2 [minuty]:

    tadzik85 napisał:
    Zawsze ma sens.

    Uważam że przy komunikacji jednokierunkowej nie ma.

 
Black Friday do -15%
Zamknij 
Wyszukaj w ofercie 200 tys. produktów TME
Ferguson