Wloczykij555 5 Napisano 25 maja Udostępnij Napisano 25 maja Kombinuję nad przyśpieszeniem pracy wyświetlacza (opartego na sterowniku ST7735S) a konkretnie funkcji "czyszczenia" ekranu poprzez wypełnienie jednolitym kolorem. Punktem wyjścia były metody przedstawione w kursach dotyczących STM32L4 (czyli wysyłanie dwubajtowego koloru "na dwa razy") ale udało mi się to trochę usprawnić, poprzez deinicjalizację i ponowną inicjalizację SPI ze zmienioną długością ramki (8 -> 16 bitów). Choć działa to 2x szybciej to wciąż jest bieda bo muszę dla każdego piksela osobno wywoływać HAL_SPI_Transmit(). LCD_Set_Window(0, 0, 160, 128); //Ustawienie obszaru na cały ekran LCD_Cmd(RAMWR); //Komenda zapisu danych LCD_CS(HIGH); //Odcięcie wyświetlacza od MOSI i CLK HAL_SPI_DeInit(&hspi1); //Deinicjalizacja SPI MX_SPI1_Init16(); //Inicjalizacja ze zmienioną długością ramki na 16 bit LCD_DC(HIGH); //Rozpoczęcie przesyłu danych LCD_CS(LOW); for (int i = 0; i < 20480; i++) { HAL_SPI_Transmit(&hspi1, &color, 1, HAL_MAX_DELAY); } HAL_SPI_DeInit(&hspi1); //Deinicjalizacja zmodyfikowanego SPI MX_SPI1_Init(); //Powrót do pierwotnej konfiguracji SPI (wybaczcie magiczne liczby, jestem na etapie tworzenia koncepcji dopiero ) Drugą metodą było stworzenie tablicy wypełnionej bajtami (interesują mnie tylko kolory czarny i biały więc wystarczyło wypełnić tablicę wartościami 0x00 lub 0xFF) za pomocą funkcji memset() i wysłanie jej jako "obrazu". Osiągnąłem fajną szybkość działania ale oczywiście zapełniłem ogromną ilość RAM (ponad 40KB wyszło). Pytanie - czy da się w jakiś przystępny sposób "zmusić" SPI to wielokrotnego wysłania pojedynczego bajtu za jednym wywołaniem funkcji "Transmit" bez konieczności tworzenia wieloelementowej tablicy? Że się w ogóle da to nie mam wątpliwości ale bazuję na HALu i tutaj jestem chyba trochę ograniczony... Cytuj Link to post Share on other sites
H1M4W4R1 561 26 maja Udostępnij 26 maja (edytowany) 2 godziny temu, Wloczykij555 napisał: Pytanie - czy da się w jakiś przystępny sposób "zmusić" SPI to wielokrotnego wysłania pojedynczego bajtu za jednym wywołaniem funkcji "Transmit" bez konieczności tworzenia wieloelementowej tablicy? Że się w ogóle da to nie mam wątpliwości ale bazuję na HALu i tutaj jestem chyba trochę ograniczony... DMA Ale do pojedynczości to raczej ciężko bez tablicy... Robisz DMA do SPI, podpinasz transfer DMA do żądania SPI i uruchamiasz transfer SPI dla 'n' bajtów, gdzie DMA jest ustawione jako cykliczne. (pisane na bazie doświadczenia z RP2040, ale powinno zadziałać) Edytowano 26 maja przez H1M4W4R1 1 Cytuj Link to post Share on other sites
etet100 22 26 maja Udostępnij 26 maja Może zrób jednak tablicę ale niekoniecznie na całą ramkę? Wysłanie 2048 po 10 bajtów zamiast 20480 po jednym powinno dać znaczne przyspieszenie. Poza tym ta implementacja HAL_SPI_Transmit jest dosyć nieoptymalna bo za każdym razem sprawdza strasznie dużo rzeczy. To by się pewnie dało znacznie odchudzić. 1 Cytuj Link to post Share on other sites
Zealota 108 26 maja Udostępnij 26 maja 6 godzin temu, H1M4W4R1 napisał: DMA Ale do pojedynczości to raczej ciężko bez tablicy. Raczej nic specjalnego, tylko odp. konfiguracja kanału DMA bez inkrementacji, wysyłanie pojedynczego bajtu do kontrolera, co spowoduje wypełnienie bufora odbiorczego, a kanał DMA będzie nadawał cały czas to samo. 1 Cytuj Link to post Share on other sites
Polecacz 101 Zarejestruj się lub zaloguj, aby ukryć tę reklamę. Zarejestruj się lub zaloguj, aby ukryć tę reklamę. Produkcja i montaż PCB - wybierz sprawdzone PCBWay! • Darmowe płytki dla studentów i projektów non-profit • Tylko 5$ za 10 prototypów PCB w 24 godziny • Usługa projektowania PCB na zlecenie • Montaż PCB od 30$ + bezpłatna dostawa i szablony • Darmowe narzędzie do podglądu plików Gerber Zobacz również » Film z fabryki PCBWay
_LM_ 456 26 maja Udostępnij 26 maja Fajny pomysł, potrzeba jeszcze licznika (w przerwaniu DMA, SPI?) aby po wysłaniu danych wyłączyć dma Cytuj Link to post Share on other sites
Wloczykij555 5 26 maja Autor tematu Udostępnij 26 maja 7 godzin temu, H1M4W4R1 napisał: DMA O widzisz, muszę temat zgłębić 2 godziny temu, etet100 napisał: Może zrób jednak tablicę ale niekoniecznie na całą ramkę? Wysłanie 2048 po 10 bajtów zamiast 20480 po jednym powinno dać znaczne przyspieszenie. Też właśnie wpadłem na taki pomysł, jak nic innego nie pomoże to pójdę w tym kierunku ;) Cytuj Link to post Share on other sites
Zealota 108 26 maja Udostępnij 26 maja 57 minut temu, _LM_ napisał: Fajny pomysł, potrzeba jeszcze licznika (w przerwaniu DMA, SPI?) Nie jest konieczne. Również konfiguracja kanału DMA z odp. liczbą transakcji. Kanał sam się "wyłączy" gdy wewn. licznik kanału się wyzeruje. Tak właśnie działa DMA wyłączonym trybem circular 2 Cytuj Link to post Share on other sites
_LM_ 456 26 maja Udostępnij 26 maja 2 godziny temu, Wloczykij555 napisał: Też właśnie wpadłem na taki pomysł, jak nic innego nie pomoże to pójdę w tym kierunku Przecież @Zealotanapisał dokładnie to co trzeba zrobić. Cytuj Link to post Share on other sites
BlackJack 153 26 maja Udostępnij 26 maja A tak z ciekawości, po co koledze taka dziwna funkcja T_CLRS (Turbo_Clear_Screan)? ogólnie przy tworzeniu szybkich animacji nie korzysta z funkcji czyszczenia ekranu, tylko go po prostu nadpisuje. Cytuj Link to post Share on other sites
Popularny post Wloczykij555 5 28 maja Autor tematu Popularny post Udostępnij 28 maja (edytowany) Dnia 26.05.2022 o 11:59, Zealota napisał: Nie jest konieczne. Również konfiguracja kanału DMA z odp. liczbą transakcji. Kanał sam się "wyłączy" gdy wewn. licznik kanału się wyzeruje. Tak właśnie działa DMA wyłączonym trybem circular @_LM_ Uff, działa wyśmienicie ale zajęło mi to dwa długie wieczory... Okazuje się, że CubeIDE generuje inicjalizację peryferiów w niewłaściwej kolejności (przynajmniej, jeżeli chodzi o DMA). Kod wygenerowany przez program: /* Initialize all configured peripherals */ MX_GPIO_Init(); MX_SPI1_Init(); MX_DMA_Init(); MX_TIM2_Init(); Powinno być: /* Initialize all configured peripherals */ MX_GPIO_Init(); MX_DMA_Init(); MX_SPI1_Init(); MX_TIM2_Init(); Czyli DMA musi być przed inicjalizacją SPI. W przeciwnym razie, DMA nie będzie przekazywać danych do bufora. Dla potomnych Edytowano 28 maja przez Wloczykij555 3 1 Cytuj Link to post Share on other sites
Elvis 1 523 28 maja Udostępnij 28 maja @Wloczykij555 Błąd inicjalizacji DMA to nic nowego... Pisałem o tym samym błędzie dwa lata temu: Podczas przygotowywania kursu STM32L4 inicjalizacja DMA wyglądała poprawnie, więc jak widać błąd wrócił później. Ciekawe jak ST wykonuje testy zmian kodu, jak widać mają jeszcze sporo do poprawy 1 Cytuj Link to post Share on other sites
Wloczykij555 5 28 maja Autor tematu Udostępnij 28 maja @Elvis Czyli jednak mogłem doczytać do Twoje tutoriale do końca, oszczędziłbym sobie straconych nerwów 1 Cytuj Link to post Share on other sites
virtualny 5 29 maja Udostępnij 29 maja Albo coś źle zrozumiałem, albo autor wątku coś źle zrozumiał... Jeżeli jest to wyświetlacz z własnym sterownikiem, to zwykle sterownik wyświetlacza ma zaimplementowane procedury czyszczenia/wypełniania obszaru zadanego (okna)prostokąta. Podaje się zakres (rozmiar i położenie okna) i komendę wypełnienia zadanego obszaru przez sterownik wybranym kolorem. Sposób z wypełnianiem pikseli "na piechotę" zawsze będzie trwał o wiele dłużej jak komenda sterownika, bez względu na użycie DMA i czegokolwiek innego. Cytuj Link to post Share on other sites
Elvis 1 523 30 maja Udostępnij 30 maja @virtualny Nazwa użytego sterownika jest wymieniona w pierwszym poście i jest to ST7735S. Mógłbyś podać gdzie dokładnie znalazłeś informację o "zaimplementowanej procedurze czyszczenia/wypełniania wypełnianiu obszaru" przez ten sterownik? Cytuj Link to post Share on other sites
virtualny 5 30 maja Udostępnij 30 maja Ups, przepraszam... Najwidoczniej to ja źle zrozumiałem i niepotrzebnie wprowadziłem zamieszanie. Cytuj Link to post Share on other sites
Pomocna odpowiedź
Dołącz do dyskusji, napisz odpowiedź!
Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!