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

Pamięć FLASH M25P32 - Brak odpowiedzi na polecenie identyfikacji 0x9F

czarusgg 28 Kwi 2015 14:11 2871 53
  • #1 14651960
    czarusgg
    Poziom 12  
    Witam wszystkich!

    Mam problem ze zmuszeniem pamięci M25P32 od ST do jakiejkolwiek współpracy. Pamięć ta wydaje się być martwa :(

    Próbuję od dłuższego już czasu zmusić te pamięć tylko do tego, by odpowiedziała mi swoim identyfikatorem (polecenie 0x9F) według DATASHEET kość na takie polecenie powinna odpowiedzieć trzema bajtami o wartości:

    0x20, 0x20, 0x16

    Niestety, nic z tego nie wychodzi.

    Ponieważ w datasheet jest powiedziane, że w momencie startu pamięci, zanim ustali się napięcie zasilające linia CS kości musi być w stanie wysokim, to samo dotyczy zanikania napięcia zasilania. W datasheet sugerują zastosowanie rezystora podciągającego linię CS do VCC. Jeśli się tego nie zrobi, to układy logiki sterującej nie zostaną prawidłowo zresetowane i współpracę z pamięcią możemy włożyć między bajki.

    Ponieważ ta metoda także zawiodła, pomyślałem sobie, iż podłączę zasilanie kości przez tranzystor. Dzięki czemu, będą mógł ją zasilić dopiero wtedy, gdy wszystkie linie będą miały ustalone stany. W moim przykładowym programie są to czasy rzędu 1s. By mieć, że tak powiem czystą sytuację.

    Aktualnie schemat podłączenia pamięci do uC jest taki jak na rysunku. Poniżej też zamieszczam zrzut ektanu z analizatora stanów logicznych, by rozwiać ewentualne podejrzenia o błędną komunikację z układem.

    Czy ktoś miał może do czynienia z tymi pamięciami, wie gdzie może leżeć pies pogrzebany? Lub zna jakieś podobne układy, które są mniej "narowiste"? Zaznaczę iż próbowałem już różnych rzeczy. Za każdym razem, gdy zmieniał się układ połączeń brana do testów była inna kość.

    Kości posiadam z trzech różnych źródeł, wszystkie nowe ze sklepów.

    Próbowałem jeszcze podciągania WSZYSTKICH linii odpowiednio VCC i GND, by absolutnie wszystkie linie miały ustalone stany, gdy załączane jest napięcie zasilania, też to nic nie dało :(
  • #2 14652150
    dondu
    Moderator na urlopie...
    Korzystam z pamięci M25P80 i jedyne co przychodzi mi do głowy (patrząc na to co załączyłeś i opisałeś), to ustawienia SPI Modes:

    Cytat:
    These devices can be driven by a microcontroller with its serial peripheral interface
    (SPI) running in either of the following two SPI modes:
    • CPOL=0, CPHA=0
    • CPOL=1, CPHA=1
  • #3 14652171
    czarusgg
    Poziom 12  
    Hmm, dzięki za sugestię. Tak naprawdę SPI musiałem sobie wystawić na inne piny i zrealizować je programowo (programator nie mógł się dogadać z uC, mimo iż CS pamięci było podciągnięte do VCC i teoretycznie pamięć powinna być w stanie wysokiej impedancji i nie mieszać się do komunikacji uC - programator).

    Nie mniej wprowadzę w takim razie odpowiednie przesunięcie w fazie sygnału CLK tak, by dane były ustalone w trakcie narastania i / lub opadania zboczy zegara.

    Dam znać, czy to pomogło i dzięki za podpowiedź.
  • #4 14652276
    dondu
    Moderator na urlopie...
    czarusgg napisał:
    Tak naprawdę SPI musiałem sobie wystawić na inne piny i zrealizować je programowo (programator nie mógł się dogadać z uC, mimo iż CS pamięci było podciągnięte do VCC i teoretycznie pamięć powinna być w stanie wysokiej impedancji i nie mieszać się do komunikacji uC - programator).

    To faktycznie niepokojący objaw.
  • #5 14657375
    czarusgg
    Poziom 12  
    Oczywiście przesunięcie w fazie sygnału CLK nic nie dało :(

    Ale zdałem sobie sprawę z tego, że jeśli ta pamięć jest bardzo restrykcyjna, to znaczy faktycznie odczytuje stan swojego wejścia w chwili wejścia lini CLK w stan wysoki, to znaczy gdzieś tak w 2/3 wysokości zbocza, to programowe SPI nie da rady, ponieważ o ile da się wystawić stan lini MOSI i w następnej instrukcji podnieść zegar, o tyle nie da się programowo badać pinu na zboczu. Między zmianą linii zegarowej a odczytem pinu mija przynajmniej 1 takt zegara, (jak nie cztery). Dochodzi jeszcze synchronizator pinu :(

    Także dzisiaj spróbuję przenieść się na ATXMegę i włączyć układ zmniejszający stromizmę zbocz na lini CLK.

    Dam znać jak to wyjdzie :) (o ile kogoś to zagadnienie interesuje), w najgorszym razie spróbuję jeszcze na oscyloskopie zbadać, co się dzieje na liniach danych w połączeniu z linią CLK.
  • #6 14657503
    BlueDraco
    Specjalista - Mikrokontrolery
    Błędne wnioski. Pamięć może działać z programowym SPI i nie jest "restrykcyjna", a błąd leży zapewne gdzie indziej. Sprawdź połączenia SS i MISO.
  • #7 14659673
    czarusgg
    Poziom 12  
    Po przejsciu na ATXmege pamiec odżyła :) Jedyna różnica elektryczna jaka powstała (oczywiście poza samym uC) to taka, że w pierwszej wersji (ATMega + sprzętowe SPI) rezystor podciągający miał 4,7K. W drugiej wersji (ATMega + programowe SPI) 3,7K. Ostatnia, działająca wersja podciągnięta jest za pomocą 10K.

    Czy to może mieć znaczenie? Po majówce spróbuję jeszcza raz z ATMegą i dam znać.

    Pozdrawiam, udanej majówki wszystkim życzę.
  • #8 14661099
    kamyczek
    Poziom 38  
    SPI to nie I2C tu niczego nie musisz podciągać i wszystko ma działać masz 4 możliwe konfiguracje 00 01 10 i 11 zazwyczaj używane są dwie 00 i 11 . Dodatkową różnicą jest kolejność przesyłania bajtów czyli od najstarszego ,czy od najmłodszego . W tym przypadku może być problem bo jeśli tak samo skonfigurujesz analizator i mikrokontroler dane będą wizualnie poprawne jednak dla pamięci niezrozumiałe i nieczytelne ...
  • #9 14661366
    czarusgg
    Poziom 12  
    Nie o to chodzi. W nocie katalogowej do pamieci wyraznie jest napisane, ze linia CS musi byc w syanie H podczas wlaczania napiecia ze wzgledu na prawidlowy reset logiki w pamieci. Jest to do tego stopnia wazne, ze jesli podciagniecie nie odniesie skutku, nalezy zastosowac dedykowany układ reset.

    Takze nie chodzi o podciaganie lini danych czy zegara jak w I2C tylko podciagniecie lini CS.

    Co do CPOL i CPHA zas, to w kazdej sytuacji było to 00. Tak jest zresztą domyślnie w AVRach.
  • #10 14661712
    kamyczek
    Poziom 38  
    Nie wiem w jakim urządzeniu pracuje ta pamięć ale patrząc że pobiera do 20mA można ją zasilać z portu lub załączać jej zasilanie na czas odczytu i w takim przypadku ustawienie odpowiedniego wyprowadzenia w stan H przed odczytem nie stanowi problemu . Jeśli z pamięci nie korzystasz przez cały czas i urządzenie jest zasilane bateryjnie prosi się o stan uśpienia lub wyłączenie zasilania układu i ustawienie portów w stan L lub wysokiej impedancji .
  • #11 14661748
    czarusgg
    Poziom 12  
    Tak też już robiłem. Ustalałem wszystkie potrzebne stany a następnie za ponocą osobnego pinu wysterowywałem tranzystor, który podawał napięcie zasilania do pamięci. Post napisałem, ponieważ wszelkie próby nic nie dały.

    Dopiero podpięcie się ATXmegą dało skutek. To mnie poprostu nurtuje. Dlatego skoro już wiem, że z pamięcią wszystko jest OK, spróbuję jeszcze raz z ATMegą. Bo to poprostu musi działać.
  • #12 14661803
    kamyczek
    Poziom 38  
    Podłącz analizator do działającego układu i zarejestruj przebiegi i porównaj na tych samych ustawieniach jedyne co może być nie tak to kolejność wysyłania od starszego do młodszego lub odwrotnie z resztą zobaczysz różnice w wartościach analizatora .
  • #13 14661818
    czarusgg
    Poziom 12  
    W pierwszym poście załączyłem zrzut z analizatora, właśnie z osobną linią zasilania. Przebiegi z uC są na nim idealne a pamięć jest martwa. Niestety dopiero w poniedziałek mogę czynić dalsze próby.
  • #14 14661848
    kamyczek
    Poziom 38  
    Szkoda, w każdym razie w rejestrze SPCR masz bit o nazwie DORD zmień jego wartość na przeciwną i sprawdź czy to przypadkiem nie to...
  • #15 14661891
    dondu
    Moderator na urlopie...
    dondu napisał:
    Korzystam z pamięci M25P80 i jedyne co przychodzi mi do głowy (patrząc na to co załączyłeś i opisałeś), to ustawienia SPI Modes:

    Cytat:
    These devices can be driven by a microcontroller with its serial peripheral interface
    (SPI) running in either of the following two SPI modes:
    • CPOL=0, CPHA=0
    • CPOL=1, CPHA=1


    Do tego co napisałem w poście #2 dodam, że zerknąłem jak to realizowałem i znalazłem notatkę:

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

    Realizowałem to na ATmega32 - działa z takim ustawieniem jak powyżej.

    @tmf
    Przy okazji skomentuj proszę kod poniżej dopisku, że jest z Twojej książki, bo nie wgłębiałem się w zasadność.
  • #16 14661905
    czarusgg
    Poziom 12  
    Dzięki Dondu spróbuję, ale dopiero w poniedziałek :(
  • #17 14668351
    czarusgg
    Poziom 12  
    OK. Jedyna różnica, to zmiana w CPOL i CPHA z 00 na 11. Ale niestety nadal nic :( Pozostaje mi tylko podejrzeć sprawę na oscyloskopie. Niestety mam dostęp tylko do dwu - kanałowego :D
  • #18 14668650
    kamyczek
    Poziom 38  
    Czarek analizator ten sam co w pierwszym poście najprostszy z możliwych saeleae za 40 pln z alegraty.pl Analizuje spi i robi robotę narysuj kawałek schematu i powieś kawałek programu z obsługą i konfiguracją spi i tej pamięci . W rejestrze SPCR masz wskaźnik DODR który zmienia kolejność wysyłania bajtów do tego ważne jest czas pomiędzy zmianą na wyjściu CS a początkiem wysyłania informacji . Spi to najprostsza i najszybsza magistrala tak w obsłudze jak w komunikacji nie możliwe żeby nie działała poprawnie jedyna wada to konieczność dodawania linii CS do każdego układu ale przy jednym układzie wolę użyć 4 porty do SPI niż 2 do i2c .
  • #19 14669259
    czarusgg
    Poziom 12  
    @kamyczek - ja też bardzo lubię SPI, jeszcze nigdy nie miałem takich jazd z tym :)

    Ale OK. Wrzucam co mogę, co może pomóc w rozwiązaniu zagadki...

    Kod: text
    Zaloguj się, aby zobaczyć kod


    Jak widać z listingu (komentarze) próbowałem już wszystkiego :(

    Co prawda pamięć troszkę lepiej się zachowuje, ponieważ zawsze odpowiada to samo. Czyli wyniki, mimo iż są całkowicie błędne, to są powtarzalne.

    Użyta tutaj pamięć była wcześniej z ATXMega i zadziałała od pierwszego razu w powtarzalny sposób zgodnie z oczekiwaniami. Czyli wszystko było z nią OK.

    PS. Na schemacie jest ATMega 32, w rzeczywistości ATMega 1284
  • #20 14669287
    kamyczek
    Poziom 38  
    No dobra pamięć zachowuje się prawidłowo tylko komenda to 0x9F ,0x00 ,0x00 i jak chcesz po niej otrzymać odpowiedź to wyślij jeszcze dziewiętnaście razy pusty bajt otrzymasz kolejno 0x20 , 0x20 ,0x16 ,0x10 i taki ładny numerek ,który nazywa się CFI data . Jak znam życie to PDF jak zwykle nie jest do końca taki jednoznaczny ;)
  • #21 14669306
    czarusgg
    Poziom 12  
    Zaraz zaraz, przecież SPI to interfejs szeregowy full duplex. MASTER wysyła bajt, jednocześnie go odbierając. Jeśli wysłałeś polecenie (MASTER inicjuje transfer) 0x9F, czyli właśnie RDID, to pamięć na tę komendę odsyła Ci trzy bajty identyfikatora, które powinny brzmieć 0x20 0x20 0x16. Jak chcesz odebrać te trzy bajty, musisz właśnie wysłać do niej trzy bajty, by trzy odebrać :)

    Spójrz na przebieg (wyciągnięty z datasheet)

    Pamięć FLASH M25P32 - Brak odpowiedzi na polecenie identyfikacji 0x9F

    W zaznaczonym przeze mnie polu może być co chcesz, zobacz, że masz obie linie (zarówno stanu wysokiego jak i niskiego). Także spokojnie może tam być 0, 0, 0 jak u mnie, 255, 255, 255 czy też 'a', 'l', 'a' :) Zresztą tak samo wszystkie linie wejściowe pamięci mogą przyjmować dowolne stany do póki CS jest w stanie H.

    A jeśli się mylę, to jak mam odczytać te trzy bajty identyfikatora po wysłaniu polecenia 0x9F ?

    Nadmienię, że na ATXMedze nie tylko odczytałem ten identyfikator, ale też zapisałem stronę pamięci i ją później prawidłowo odczytałem...
  • #22 14669310
    kamyczek
    Poziom 38  
    Może i tak tylko dobrze oglądaj rysunki i czytaj to co nad nimi w tabelce ;) zrób proszę tak jak napisałem . Zobacz co otrzymasz na moje oko w tabeli napisano że poza kilkoma bajtami służącymi do identyfikacji producenta , wielkości jest tam jeszcze 16 bajtowy numer . Być może przy pierwszym odczycie pamięć musi wyjść z trybu uśpienia i wymaga kopa na rozpęd w postaci tych dwóch pustych bajtów tak jak jest to w przypadku budzenia pamięci z trybu uśpienia RES 0xab, 0x00,0x00,0x00,0x00 po którym pamięć dopiero zaczyna odpowiadać bajtem o wartości 0x15 . możliwe że lepszą metodą jest na wszelki wypadek wysłanie komendy res i po otrzymaniu odpowiedzi w postaci 0x15 zapytanie o sygnaturę i w takim przypadku otrzymasz faktycznie odpowiedź bez poślizgu w postaci tych dwóch bajtów.
  • #23 14669315
    czarusgg
    Poziom 12  
    No co Ty? Po Twojej uwadze przeczytałem cały "rozdział" odnośnie tego polecenia, który brzmi:

    Cytat:
    Read Identification (RDID)
    The Read Identification (RDID) instruction allows
    the 8-bit manufacturer identification to be read, followed
    by two bytes of device identification. The
    manufacturer identification is assigned by JEDEC,
    and has the value 20h for STMicroelectronics. The
    device identification is assigned by the device
    manufacturer, and indicates the memory type in
    the first byte (20h), and the memory capacity of the
    device in the second byte (16h).
    Any Read Identification (RDID) instruction while
    an Erase or Program cycle is in progress, is not
    decoded, and has no effect on the cycle that is in
    progress.
    The device is first selected by driving Chip Select
    (S) Low. Then, the 8-bit instruction code for the instruction
    is shifted in. This is followed by the 24-bit
    device identification, stored in the memory, being
    shifted out on Serial Data Output (Q), each bit being
    shifted out during the falling edge of Serial
    Clock (C).
    The instruction sequence is shown in Figure 11..
    The Read Identification (RDID) instruction is terminated
    by driving Chip Select (S) High at any time
    during data output.
    When Chip Select (S) is driven High, the device is
    put in the Standby Power mode. Once in the
    Standby Power mode, the device waits to be selected,
    so that it can receive, decode and execute
    instructions.


    Ja ten tekst rozumiem następująco:

    Cytat:
    Instrukcja RDID pozwala odczytać 8-bitowy identyfikator producenta, następnie dwa bajty identyfikujące urządzenie. Identyfikator producenta jest zgodny z identyfikatorem nadanym przez JEDEC i dla STMicroelectronics wynosi on 20. Identyfikator urządzenia zaś przypisany jest przez producenta i oznacza typ pamięci (pierwszy bajt = 0x20) oraz jej pojemność zapisaną w drugim bajcie identyfikatora urządzenia (wartość 0x16).

    Wydanie polecenia RDID podczas, gdy cykl kasowania bądź programowania jest w toku nie jest dekodowane i nie przynosi efektu do póki cykl nie zostanie zakończony.

    Najpierw musisz ustawić linię Chip Select w stan niski. Następnie wsunąć 8-bitową instrukcję na wejście. Następnie na wyjście Q zostanie wysuniętych 24 bity identyfikatora urządzenia. Bity będą wysuwane na każdym opadającym zboczu sygnału zegarowego.

    Odpowiednia sekwencja pokazana jest na rysunku 11.

    Wykonywanie instrukcji RDID można przerwać zmieniając stan linii CS na wysoki w dowolnym momencie, gdy pamięć wysyła dane.

    Jeśli linia CS jest w stanie wysokim, urządzenie przechodzi w stan czuwania. Urządzenie oczekuje, aż zostanie wybrane (linia CS) i będzie mogło odczytać, zdekodować i wykonać instrukcje.


    Jak coś źle zrozumiałem, naprostujcie mnie proszę, a Ciebie @kamyczek proszę powiedz po kolei, co mam według Ciebie zrobić a to zrobię i pokażę wyniki screenshota z analizatora stanów.
  • #24 14669317
    kamyczek
    Poziom 38  
    Ja potraktował bym pamięć po resecie komendą RES (0xab, 0x00,0x00,0x00,0x00) ostatni zwrócony bajt powinien mieć wartość 0x15 , po tej operacji wysłał bym kolejną nową komendę 0x9F, 0x00 , 0x00 , 0x00,0x00 powinieneś otrzymać odpowiedź 0x20,0x20,0x16,0x10 wysyłając kolejne bajty w tej samej komendzie otrzymasz 16 bajtowy numer seryjny układu .
  • #25 14669320
    czarusgg
    Poziom 12  
    Efekt dokładnie ten sam :(

    Zamieszczam już tylko widok z terminala, w którym widać, że:

    - czekam sekundę
    - wysyłam polecenie RES
    - czekam sekundę
    - wysyłam polecenie RDID

    Wydaje mi się, że to niestety nie to z dwóch powodów:

    1. Pamięć nie była wprowadzana w stan głębokiego uśpienia (pobiera wtedy 1uA prądu) po którym trzeba ją obudzić za pomocą RES lub RES z odczytem sygnatury.

    2. Na ATXMedze poprostu po włączeniu zasilania normalnie zareagowała na polecenie RDID (odsyłając trzy bajty o wartościach 20h, 20h, 16h) i także normalnie wykonywała całą resztę poleceń.

    Mogę zamieścić widok terminala z ATXMegi wraz z kodem programu, ale myślę, że nie przybliży to nas do rozwiązania.

    Wynik z terminala:

    Cytat:

    Start...
    Init SPI...
    Czekamy 1s...
    RES
    Odczekujemy 1sek.
    RDID
    00 00 20


    Dodano po 2 [minuty]:

    @kamyczek OK. Już sprawdzam
  • #26 14669322
    kamyczek
    Poziom 38  
    Jedno co mi jeszcze przychodzi do głowy to przeniesienie sygnału CS z wyprowadzenia SS na inne ,mimo że nie bierze ono udziału w obsłudze magistrali w trybie master i używa się jego jedynie w trybie slave miałem problem z komunikacją spi w trybie master podczas gdy wykorzystywałem to wyprowadzenie jako CS . Przeniesienie sygnału na inny pin portu rozwiązało problem z komunikacją więc możesz sprawdzić dla pewności jeszcze to .
  • #27 14669323
    czarusgg
    Poziom 12  
    Uzyskałem takie efekty:

    Cytat:
    Start...
    Init SPI...
    Czekamy 1s...

    CS -> LO
    >> ab 00 00 00 00
    << 00 00 00 00 00

    CS -> HI

    Czekamy 1sek.

    CS -> LO
    >> 9f 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    << 00 00 00 00 00 40 ff 00 5a 1b 5b 32 4a 1b 5b 30 3b 30 48 53 74

    CS -> HI
  • #28 14669324
    kamyczek
    Poziom 38  
    Możesz sprawdzić co wyjdzie jak zmienisz tryb spi z 00 na 11 i przeniesiesz ten CS na inny pin ? . Nie mam niestety takiego układu na testy , gdybym miał trafił by w programator a podczas odczytu i zapisu odczytał bym analizatorem co się tam wyprawia . Tak czy inaczej pewnie zamówię na testy kilka układów z tej serii bo mają spore pojemności i niewielkie wymiary.
  • #29 14669325
    czarusgg
    Poziom 12  
    Po przełączeniu się z linią CS na inny port i inny PIN transmisja SPI w ogóle się posypała.

    Wiem, że pin SS służy tylko do wysterowania SPI, gdy ten pracuje w trypie SLAVE a w trybie MASTER dowolny pin może grać rolę CS (tym bardziej, że przecież możemy mieć wiele urządzeń na magistrali SPI), ale efekt mam taki, że bit SPIF w rejestrze SPSR nigdy nie jest ustawiany, gdy SS jest wejściem i program oczekuje w wiecznej pętli aż ten @#$%^& bit się zapali :(

    :(

    Dodano po 3 [minuty]:

    Absolutnie nic się nie zmienia. Cały czas te same objawy. Odkąd zasugerowałeś wybudzanie i czytanie serial number, mam ustawione CPOL i CPHA. Jak skasuję, pamięć zachowuję się identycznie.
  • #30 14669591
    dondu
    Moderator na urlopie...
    Zamiast swojej funkcji inicjującej SPI wykorzystaj moją wersję (bez żadnych zmian dodając jedynie na początku CS_H ) i daj znać o rezultatach.

    Twoim problemem jest prawdopodobnie to, że po włączeniu trybu master masz na pinie SS ustawionym jako wejście sygnał niski (bo nie masz pull-upa na S pamięci FLASH), a to powoduje natychmiastowe przejście uC do trybu slave:

    Cytat:
    If SS is configured as an input and is driven low while MSTR is set, MSTR will be cleared,
    and SPIF in SPSR will become set.

    Czy tak się dzieje przy Twojej funkcji inicjującej SPI wystarczy sprawdzić po jej wywołaniu stan bitu MSTR - zapewne będzie on wyzerowany.
REKLAMA