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

[STM32][Eclipse] - Zapis pamięci I2C EEPROM 24...1024/1025/1026

tamtaramtamtam 14 Sie 2012 19:10 4590 24
REKLAMA
  • #1 11208885
    tamtaramtamtam
    Poziom 10  
    Posty: 21
    Pomógł: 1
    Dzień dobry,

    Mam nietypowy problem z zapisem pamięci I2C z serii 24...1024/1025/1026 (różnią się tylko adresowaniem). Krótki wstęp: pamięci te mają dwa bloki po 512kb każdy. Blok jest wybierany po przesłaniu bajtu kontrolnego (control byte) z 7-bitowym adresem, przykładowo dla pamięci 24...1026 control byte ma postać [1 0 1 0 A2 A1 B0 R/W] gdzie B0 to wybór jednego z dwóch bloków, A0 i A1 sprzętowe adresowanie (w moim przypadku - masa) i R/W (odczyt/zapis).

    Aby zapisać 1-wszy blok przesyłam Control Byte = 0xA0, aby zapisać drugi blok Control Byte = 0xA2.

    Teraz do rzeczy.
    - odczytuje pierwszy i drugi blok bezbłędnie
    - zapisuje tylko pierwszy blok, a na drugim transmisja się wiesza od razu po przesłaniu control byte. Jak próbuje zapisać od razu drugi blok - to samo. Tak jakby przesłany adres (0xA2) był nieprawidłowy - jednak w trybie odczytu wszystko działa, więc tego typu błąd wykluczam.
    - a teraz żeby było ciekawiej - w trybie debugowania wszystko działa step-by-step i transmisja się nie wiesza, jak puszczę program z marszu i ustawię break-point na timeout_callback, to widać że transmisja się wiesza zaraz po przesłaniu adresu (control byte) w trybie zapisywania (w trybie odczytu jest OK.)

    Dodam, że komunikacja z pamięcią 24..512 działa niezawodnie (tam jest jeden blok). Z ciekawości sprawdziłem też dla 24...16 (tam jest 8 bloków) i co ciekawe - również działa.

    Korzystam z przykładu od ST dla pamięci EEPROM z wykorzystaniem ich bibliotek od I2C.

    Czy ktoś miał podobny problem albo ma pomysł co może być przyczyną?
  • REKLAMA
  • #2 11209204
    Krauser
    Poziom 26  
    Posty: 508
    Pomógł: 124
    Ocena: 12
    Czy wziąłeś pod uwagę, że zapis zajmuje kilka ms?
  • REKLAMA
  • #3 11209303
    tamtaramtamtam
    Poziom 10  
    Posty: 21
    Pomógł: 1
    Gdybym tego nie wziął pod uwagę to by mi żadnego eeproma nie zapisał ;) Poza tym pierwszy blok zapisuje, a drugi już nie (drugi blok by miał dłuższe czasy zapisu niż pierwszy?). Ale coś musi być na rzeczy z czasem, skoro w trybie debugowania krok po kroku działa. W tym kierunku będę szukał.
  • REKLAMA
  • #4 11209733
    michalko12
    Specjalista - Mikrokontrolery
    Posty: 3394
    Pomógł: 462
    Ocena: 321
    Z dokumentacji, która ja posiadam ( Microchip 24AA1025/24LC1025/24FC1025) wynika coś takiego: [1 0 1 0 B0 A1 A0 R/W] z kolei jakiś stary ATMEL 24c1024 ma coś takiego [1 0 1 0 0 A1 P0 R/W].
    Jesteś pewien, że masz dobrą dokumentację?
  • #5 11209941
    tamtaramtamtam
    Poziom 10  
    Posty: 21
    Pomógł: 1
    dla 1024 i 1025 jest jak mówisz - ja podałem dla 1026. Zresztą testowałem też inne warianty (tak na wszelki wypadek, w dokumentacjach też się błędy zdarzają), ale bez efektu.

    Nawet po wydłużeniu sztucznie czasów zapisów (do parudziesięciu ms) nie chce zapisać drugiego bloku. Pomyślałem że uwalona pamięć, ale czemu w trybie debugowania przechodzi? Wydłużyłem czasy do ponad 100ms między kolejnymi zapisami (zapisuje całymi stronami) i... poszło! Coś z tą pamięcią jest nie tak, w sensie z jej drugim blokiem. Pierwszemu spokojnie starcza 5ms na zapis całej strony, drugi potrzebuje ponad 100... Muszę zdobyć drugą pamięć i przetestuje.

    Dziękuje za pomoc - ukierunkowało mnie to!
  • Pomocny post
    #6 11210300
    Krauser
    Poziom 26  
    Posty: 508
    Pomógł: 124
    Ocena: 12
    Być może, że twoje opóźnienie wcale nie jest takie jak myślisz (skoro 3ms to typowy czas to 5ms spokojnie powinno wystarczyć). Zauważ, że jeśli zapisujesz pierwszą stronę to kolejną możesz zapisać jeśli wysłanie control byte zwróci ACK jeśli nie to pamięć jest zajęta i należy ponownie wysłać start i control byte. Co jeśli najpierw zapiszesz druga stronę a potem pierwszą?
  • #7 11210674
    tamtaramtamtam
    Poziom 10  
    Posty: 21
    Pomógł: 1
    Zrobiłem z użyciem 'acknowledge poling flow' opisane w datasheecie, tj.

    1) send start
    2) send control byte
    3) wait for ACK

    jeżeli jest ACK, przejdź do kolejnej operacji, jeżeli nie ma ACK wróć do pkt1. Dodatkowo sobie wyrzuciłem podgląd transferów na bieżąco.. no i teraz najlepsze.

    Zapisuje pamięć, dla pierwszego bloku transfer zapisu ok. 50kb/s, po czym przechodzi do drugiego bloku i transfer zapisu spada do... uwaga ... ok. 7kb/s (!). Jak to możliwe? Podejrzewałbym pamięć, ale znalazłem druga (24..1025 - ma trochę inne adresowanie) i jest TAKI SAM efekt.

    Transfer odczytu dla obu bloków jest taki sam.

    Przetestowałem też wariant zapisu tylko drugiego bloku (bez udziału pierwszego) i również transfer zapisu jest bardzo niski.

    Podsumowując - działać działa, ale w sumie ciekawi mnie skąd jest taki spadek wydajności.
  • #8 13295014
    kosster
    Poziom 12  
    Posty: 118
    Nie chce zakładać nowego tematu z I2C bo tematów jest sporo i dużo jest wałkowane o i2c w stm32. Mam procesor stm32f103 i niestety ale mam duży kłopot z tym interfejsem. Otóż problem dotyczy odczytu i czasami zapisu pamięci eeprom. Czytałem, że problem może być z zakłóceniami na szynie. Stosowałem różne metody DMA, przerwania i odpytywanie. Wszystko nie działa stabilnie. W magistralę za pomocą złącz wpinane są różne moduły w których jest zaimplementowana pamięć 24..01. Moduły mogą być wpinane i wypinane podczas włączonego zasilania. Zadaniem STMa jest odczytanie kilku bajtów z pamięci i zapisanie aktualnej daty pod konkretnym adresem. I tutaj pojawiają się szopki. I tutaj zupełnie pełna przypadkowość, albo zapisze dane pod innym adresem albo tak się zwiesi moduł i2c w stm32 ze tylko reset procesora pomaga. W związku z tym mam pytanie czy jest jakaś metoda programowa aby temu zapobiec? Może po prostu machać ręcznie pinami... Nie zdawałem sobie sprawy z błędów w STM... Zresztą na stronie nie mogę znaleźć erraty. Ktoś może mi podesłać ewentualnie link do erraty f103?
  • #9 13295222
    tadzik85
    Poziom 38  
    Posty: 3404
    Pomógł: 415
    Ocena: 16
    Słabo szukałeś, a na reset i2c są co najmniej 2 metody, omówione w RM i tu na forum wiele razy.
  • #10 13295331
    kosster
    Poziom 12  
    Posty: 118
    szukałem.... jedna z metod to jeśli się nie mylę to ta: I2Cx_CR1_SWRST Ale to nie do końca o to chodzi. Jak napisałem zdarza się ze przypadkowo zwiesi się całkiem i2c i nie jestem w stanie go wskrzesić. Ale nie o to już w tym wszystkim chodzi. Są to sporadyczne przypadki. Problemem jest poprawny odczyt i zapis. Opisze mniej więcej budowę urządzenia. W każdym module jest 1 EEPROM o takim samym adresie. Modułów wpiętych może być do 20. Wybierając moduł podłącza się magistrala I2C do EEpromu za pomocą switcha. Wówczas inne eepromy modułów są odpięte. Jak przełączam się pomiędzy modułami pojawiają się sporadycznie problemy o których pisałem. Czasami pojawiają się częsciej czasami rzadziej. A już na pewno pojawia się problem gdy nawet na chwilkę wyjmę i włożę moduł. Pomimo tego że w tym czasie nic nie czytam. Reset procesora dopiero jest w stanie odblokować i2c. Przerwania od timerów nie mogę wyłączać ponieważ mają bardzo ważne zadanie.
    Wiem ze może to skomplikowanie wygląda ale tak jest. Najgorzej z czytaniem...
    Być może coś popieprzyłem w kodzie, nie wiem tyle razy zmieniałem i robiłem doświadczenia, że mam już i galimatias w głowie.

    Wrzucę więc odczyt:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Do tego po wyjściu z błędem dokonuję restetu i2c.
    Najczęściej zatrzymuje się albo zaraz po wygenerowaniu startu, albo po wysłaniu adresu.
  • #11 13295698
    tadzik85
    Poziom 38  
    Posty: 3404
    Pomógł: 415
    Ocena: 16
    Zawsze można zresetować w RCC a potem po w I2C.
    A errata jest na stronie ST najszybciej znajdziesz wybierając swój procesor.
  • #12 13296118
    kosster
    Poziom 12  
    Posty: 118
    A pytanie mam czy trzeba jeszcze dodatkowo odczytywać rejestr albo kasować jakieś flagi. Bardzo to niestabilnie chodzi. Być może problemów nie będzie kiedy miałbym na stałe włączony eeprom. Jak to zrobić aby mogło działać stabilnie. Prędkość to około 20kHz a więc żadna prędkość. Niestety dalsze zmniejszanie prędkości nic nie poprawia. Wątpię aby inżynierowie z ST wypuścili takiego baga w krzemie, że proste I2C nie działa. Nie wiem czy resetowanie I2C coś da jak i tak nie mam pewności odczytu/zapisu a to jest dla urządzenia istotne.
  • #13 13296154
    tadzik85
    Poziom 38  
    Posty: 3404
    Pomógł: 415
    Ocena: 16
    Problemem dla ciebie jest moment zmiany modułu, styki wiadomo.
    Dla I2C są to sygnały i ..... sieczka..

    Jeśli masz możliwość zastosowania jakiejś detekcji włożenie modułu da się to zrobić rozsądnie.
  • #14 13296218
    kosster
    Poziom 12  
    Posty: 118
    A może robić to poprzez machanie pinami w sposób ręczny? Nie mam siły już na to. Może problemem są też przerwania, wisi USB, 4 timery przerwania zewnętrzne itd. W sumie usb i 2 timery są dla mnie najważniejsze i muszą być obsłużone w pierwszych kolejnościach.
    Niestety detekcji nie mogę wykonać, jedyną detekcją to jest właśnie ACK z I2C.
    Nie mam pojęcia dlaczego to się wiesza albo przekłamania wystepują pomimo tego ze moduł jest na swoim miejscu i nikt go nie rusza. poziomy napięć są ok podciągnięcie do 5V przez rezystor 4k7 (zmiana na 3k9 czy nawet 2k2 nie pomaga). ACK jest sciągany praktycznie do zera no może 0,2V. więc wszystko jest OK a jednak układ nie działa....
    Może z konfiguracją jest coś nie tak...

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE)

    Open drain ustawiony zarówno CLK jak i SDA

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Wstawienie resetowania i2c nie pomaga.
  • REKLAMA
  • #15 13296325
    tadzik85
    Poziom 38  
    Posty: 3404
    Pomógł: 415
    Ocena: 16
    I2C jest rygorystyczne czasowo. Inne przerwania mogą powodować błędy.
    Zrobić I2C na przerwaniach o najwyższym priorytecie.
    Uchronić przed błędami powstałymi z HOR-PLUG.
    Np cykliczne pytanie i resetowanie I2C po konfiguracji sprawdzenie flag oraz stanu pinów.
  • #16 13296357
    kosster
    Poziom 12  
    Posty: 118
    No niby tak... ale jak wiadomo i2c działa synchronicznie z zegarem więc to zegar dyktuje jak to ma być. Np mam napisaną pod windowsem aplikacje która działa z FT232 i tak naprawdę jak patrzy się na oscyloskop to chodzi to w cały świat (nierówne przebiegi na CLK) a jednak idealnie to śmiga z pamięciami, procesorami Attiny itd, przynajmniej na tym to testowałem.
    Rygorystycznie czasowo to może być peryferium w STMie tak mi się przynajmniej wydaje.

    Odnośnie tego resetowania. Zauważyłem że chyba się nie do końca to resetuje bo po resecie nie ustawiają mi się flagi pomimo ponownej konfiguracji. Podpowiedz proszę jak to powinienem zrobić poprawnie?
  • #18 13296442
    kosster
    Poziom 12  
    Posty: 118
    Zrobiłem to w taki sposób że w przypadku wystąpienia nieprawidłowosci
    wpisuję
    I2C2->CR1 |= I2C_CR1_SWRST;
    I2C2->CR1 &= ~I2C_CR1_SWRST;
    następnie konfiguracja
  • #20 13296551
    kosster
    Poziom 12  
    Posty: 118
    Czyli RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE) też mam ustawiać?
  • #22 13297285
    kosster
    Poziom 12  
    Posty: 118
    Niestety nadal jest kłopot, tzn. po wyjęciu modułu i jeszcze raz podłączeniu nie chce już za żadne skarby się uruchomić i2c. Tylko reset sprzętowy a tego nie mogę zrobić bo tracę połączenie USB.
    Jaka może być inna metoda kasowania/resetowania i2c?
  • #24 13319597
    kosster
    Poziom 12  
    Posty: 118
    Niestety mimo usilnych działań i różnych sztuczek nie udaje się aby odczyty/zapisy były pewne. Zdarzają się błędy, rzadko ale się zdarzają. Rozwiązaniem jest programowa obsługa i2c.
  • #25 16224789
    piotr529
    Poziom 11  
    Posty: 37
    Ocena: 18
    Fajnie zakończyliście temat bez pomocy koledze "tamtaramtamtam".

    Zacząłem zabawę z 24C1024 pod ATmega2560 i mam ten sam problem z zapisem drugiej połówki pamięci.

    Może, ktoś już kiedyś zmagał się z tym problemem, może jest jakieś logiczne wytłumaczenie tego zjawiska.

    Będę wdzięczny za każdą pomoc w tym temacie

Podsumowanie tematu

✨ Dyskusja dotyczy problemów z zapisem pamięci I2C EEPROM z serii 24...1024/1025/1026, gdzie użytkownik napotkał trudności w zapisie drugiego bloku pamięci, mimo że odczyt działał poprawnie. Użytkownik zauważył, że czas zapisu dla drugiego bloku jest znacznie dłuższy niż dla pierwszego, co sugeruje możliwe uszkodzenie pamięci. W odpowiedziach poruszono kwestie związane z czasem zapisu, poprawnością dokumentacji, a także metodami resetowania interfejsu I2C w STM32. Użytkownicy dzielili się doświadczeniami związanymi z zakłóceniami na szynie I2C oraz problemami z odczytem i zapisem, zwłaszcza w kontekście zmiany modułów pamięci. Wskazano na konieczność stosowania odpowiednich opóźnień oraz metod programowych do stabilizacji komunikacji I2C.
Wygenerowane przez model językowy.
REKLAMA