logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

atmega master slave spi buforowanie, przesunięte dane, znikający ostatni bajt

ktosnikt 11 Lip 2023 14:15 477 3
REKLAMA
  • #1 20650228
    ktosnikt
    Poziom 9  
    Cześć, witajcie. uruchomiłem komunikację dwóch atmeg po spi. w bascomie z pominięciem wbudowanych komend, tylko na rejestrach procesora. hardwarowo wszystko chodzi, dane sie przesyłają w obie strony z jednym dużym problemem. drugi dzień nad tym siedzę i mam już kwadratowy łeb.

    potrzebuję przesyłać tabele, których specyfika jest taka, że nigdy nie wystąpią po sobie cztery bajty puste. Zawsze też mogą wystąpić jakieś błędy, urwanie transmisji lub wznowienie od jakiegoś momentu. Dlatego do synchronizacji początku transmisji wysyłam cztery bajty puste. wtedy slave zaczyna zapis do pierwszej komórki tabeli.

    Działa to w przerwaniach. Wywołuję obsługę spi w masterze, on odbiera i wysyła. w slave włącza się przerwanie, odczytuje i odpowiada. Wtedy w masterze włącza się przerwanie i wywołuje już bez mojego udziału tą samą obsługę spi. odbiera i wysyła, aż się wyczerpią bajty w tabeli.

    problemem jest jakieś dziwne opóźnienie magistrali. to znaczy z rejestru spdr odczytuję bajty wysłane jakies dwa przerwania wcześniej, przykładowo:

    master wysyła 0 0 0 0 11 12 13 14 15 16 17 18 (11-18 to liczby z tabeli)
    slave dostaje 0 0 0 0 0 11 12 13 14 15 16 17 (piec zer i zjada ostatni bajt)

    lub
    slave wysyła X X X 0 21 22 23 24 25 26 27 28
    master odbiera X X X X X 0 21 22 23 24 25 26 27
    gdzie X to liczba losowa, slave dopiero 4 bajt =0 traktuje jako synchronizujący, tak powinno byc. Ale tych bajtów na początku zawsze za dużo, przez to licznik bajtów osiąga 8 a odczytuje 7 bajt. Różnie to bywa ale czasem ten ostarni bajt tkwi w rejestrze któregoś z procesorów i potem wypluwa go jako pierwszy podczas nastepnej transmisji. gdzie ja już wziąłem pod uwagę to i ostatnie przerwanie tylko odbiera, nie nadaje.

    tu jest jakieś podwójne buforowanie odczytu, nie wiem do końca o chodzi ale sam fakt, że jeśli w przerwaniu nie odczytam spdr, a tylko zapiszę (jesli chce utracic dane) to coś się zmienia. Próbowałem wysłać różną liczbę zer w masterze i slave ale zawsze którys zgubi dane. jeden albo więcej bajtów na końcu.


    fragment master
    Kod: VB.net
    Zaloguj się, aby zobaczyć kod



    fragment slave
    Kod: VB.net
    Zaloguj się, aby zobaczyć kod
  • REKLAMA
  • Pomocny post
    #2 20650375
    tmf
    VIP Zasłużony dla elektroda
    Pamiętaj, że rejestry SPI, w zależności czy to jest M/S, czy realizujesz przez USART, mają bufory. Jeśli więc coś nadajesz, a nie odczytasz SPDR, to ta wartość i tak tam jest, zostanie odczytana przy kolejnej okazji. Stąd możesz mieć opisane problemy z odczytem jakiś wcześniej przesłanych bajtów. Stąd też najlepiej albo jednocześnie zapisywać i odpisywać rejestr, albo czyścić bufor odbiornika, przed nadaniem kolejnej paczki danych. Drugi problem na który warto zwrócić uwagę związany jest z tym jak przygotowujesz dane w slave. Czy zawsze w rejestrze nadajnika masz chociaż jeden bajt gotowy? Jeśli nie, to i tak po SPI zostanie coś nadane, bo slave jest taktowany przez mastera i nawet jeśli ma pusty bufor nadajnika, to i tak coś musi wystawić na MISO, więc zawsze coś master odbierze.
  • REKLAMA
  • Pomocny post
    #3 20650399
    bart-projects
    Poziom 29  
    Gdzies juz chyba widziałem, jak napisałeś coś w stylu, że "ogólnie wiadomym jest, że bascomowe SPISLAVE nie konfiguruje tak jak potrzeba" .
    Ja o tym czytałem pierwszy raz... Mogę wiedzieć której wersji Bascom używasz jeśli nie najnowszej 2085?

    W SPI najważniejsze jest to, że to master taktuje slave`a. Dlatego nie bez powodu w komendzie konfiguracyjnej jest też SPIIN=255 ale możesz wpisać cokolwiek. Najczęściej nie ma znaczenia jaką wartość wysyła MASTER by coś odczytać ze SLAVE`a, ale COŚ WYSŁAĆ MUSI.

    Piszę o tym by uzmysłowić że kiedy MASTER coś chce odebrać to MUSI taktować SLAVE`a.
    Prawdopodobnie ten ostatni bajt musisz dotaktować wysyłając cokolwiek lub po prostu przemyśleć logikę Twojego programu bo jakoś ten dotaktowany bajt SLAVE musi też interpretować/ignorować.

    SLAVE po resecie nie na pewno w SPDR ma zero i tę wartość wyśle równolegle do tego jak otrzyma pierwsze zero od MASTER`a.
    Te synchronizację to bym przemyślał :D W Bascom wszystkie zmienne SRAM są inicjowane wartością 0, ale SPDR musisz chyba zapisać sam a w nocie pisze, że po restarcie stan to "undefined".

    Zupełnie innym zagadnieniem jest obsługa przerwania. W Bascom bez użycia Nosave wchodząc w przerwanie odkładasz i zdejmujesz około 28 rejestrów co nie jest optymalne. Mój program NoSaveTool trochę pomaga ;)
    Ale, żeby nie wyjśc na to, że tylko go reklamuję i nic się zrobić nie da proponuję:
    - daj temu drugiemu procesorowi czas na obróbkę danych. Powstawiaj wszędzie w MASTER (do testów) Waitms 1 czy tam 3 i zobacz czy się wyrabiają.
    - czyli MASTER wysyła, ignoruje pierwszy otrzymany bajt i czeka 3ms aż Slave załaduje coś do swojego SPDR. Wtedy nadaje drugi bajt a otrzymuje to co załadował SLAVE.
  • #4 20651580
    ktosnikt
    Poziom 9  
    Dziękuję.

    Rejestr już jest odczytywany przed zapisem.

    Każde przerwanie w slave zapisuje coś do SPDR, więc jeśli slave ZDĄŻY obsłużyć przerwanie i wpisać to zawsze jeden bajt jest wpisany. Przed transmisją przy inicjacji nic nie wpisuję do spdr, pierwszy wpis jest w przerwaniu.

    Wygląda na to, że oba wyrabiają się z wpisywaniem danych do rejestrów bo dodanie 2ms w przerwaniu nic nie zmienia. Tym stosem na razie się nie interesowałem, ale procesor będzie obliczał jeszcze dwa krytyczne czasowo przerwania, także i tym będę musiał się zająć.

    Bascom 2075. Właśnie komendy konfiguracji spi działają prawidłowo. Polecenia natomiast działają tylko na masterze. ja robię w [przerwaniu+spdr] dla mastera i slave. spi pracuje tak samo dla poleceń poniżej i wartosci rejestru spcr

    Kod: VB.net
    Zaloguj się, aby zobaczyć kod


    Kod: VB.net
    Zaloguj się, aby zobaczyć kod



    Cytat:
    - czyli MASTER wysyła, ignoruje pierwszy otrzymany bajt i czeka 3ms aż Slave załaduje coś do swojego SPDR. Wtedy nadaje drugi bajt a otrzymuje to co załadował SLAVE.


    i tu jest sedno sprawy! master otrzymuje PIERWSZY bajt kiedy nadaje TRZECI, nie drugi. i to jest stałe opóźnienie. nadaje CZWARTY, dostaje DRUGI

    -----------------------------------------------------------------------------

    Działa. Nie wiem skąd bierze się opóźnienie dwóch bajtów, nie jednego, ale przystosowałem procedurę mastera żeby w taki właśnie opóźniony sposób zapisywał dane i chodzi bez żadnych błędów.

    Zastanawiam się jeszcze czy taka dosyć długa procedura obsługi przerwania spi w masterze nie powinna czasem pójść do pętli głównej programu, a w przerwaniu ustawiać tylko bit o odbiorze bajtu, i procedura wykona się przy najbliższym obrocie pętli. W końcu master może dowolnie długo zwlekać z nadaniem danych, to slave jest tylko zobowiązany do szybkiego ładowania. Jak byście zrobili?

    Ostatnie pytanie. potrzebuję zbadać wielkość uzywanego w programie stosu hwstack, swstack framesize. jak to zrobić na pracującym procesorze?
REKLAMA