Elektroda.pl
Elektroda.pl
X
Mitronik
Proszę, dodaj wyjątek www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

25LC1024 - LPC1769 + SPI + Flash 25LC1024 - nie zapisuje do pamięci

Kubbaz 14 Kwi 2015 15:35 1677 25
  • #1 14 Kwi 2015 15:35
    Kubbaz
    Poziom 26  

    Witam wszystkich Elektrodowiczów,

    Chcę użyć pamięci Flash 1 Mb Microchip 25LC1024 na SPI.
    Podłączyłem pamięć do mikrokontrolera LPC1769:

    SO - do MISO0 uC (pin P0.17) (bez rezystora pull-up)
    SI - do MOSI0 uC (pin P0.18) (bez rezystora pull-up)
    SCK - do SCK0 uC (pin P0.15) (bez rezystora pull-up)
    !CS - do SSEL0 uC (pin P0.16) (bez rezystora pull-up)

    pin !WP podłączyłem przez rezystor pull-up 10 k? do Vcc (+3,3 V uC),
    pin !HOLD podłączyłem przez rezystor pull-up 10 k? do Vcc (+3,3 V uC).

    Zainicjalizowałem magistralę SPI 0 na 400 kHz (pomiar oscyloskopem to potwierdza).
    Zgonie z opisem w pkt. 2.3 na stronie 6 dokumentacji pamięci 25LC1024 wysyłam instrukcję "Write Enable Sequence - WREN" (bajt 0x06), po czym wysyłam sekwencję zapisu (0x02 0x00 0x00 0x00 0xCC), czekam pewien krótki czas i potem odczytuję wartość zapisanego bajtu z danego adresu - otrzymuję zawsze 0xFF. Zachowuje się to tak, jakby wcale nic nie zostało zapisywane do pamięci... :cry:

    Na oscyloskopie instrukcja WREN i sekwencja zapisu wygląda poprawnie:
    (kolor niebieski to linia zegarowa SPI - SCK0, a kolor czerwony to linia SPI - MOSI)
    Instrukcja WREN:
    25LC1024 - LPC1769 + SPI + Flash 25LC1024 - nie zapisuje do pamięci 25LC1024 - LPC1769 + SPI + Flash 25LC1024 - nie zapisuje do pamięci

    Sekwencja Byte Write:
    25LC1024 - LPC1769 + SPI + Flash 25LC1024 - nie zapisuje do pamięci 25LC1024 - LPC1769 + SPI + Flash 25LC1024 - nie zapisuje do pamięci





    Sekwencja Read:
    25LC1024 - LPC1769 + SPI + Flash 25LC1024 - nie zapisuje do pamięci 25LC1024 - LPC1769 + SPI + Flash 25LC1024 - nie zapisuje do pamięci

    Ale na linię SO (Serial Output) przenosi się sygnał zegarowy, który po po podglądnięciu na oscyloskopie wygląda jak poniżej:
    (kolor niebieski to linia SPI - MOSI, a czerwony do SPI - MISO)

    25LC1024 - LPC1769 + SPI + Flash 25LC1024 - nie zapisuje do pamięci

    Poniżej fragment kodu źródłowego:

    Kod: c
    Zaloguj się, aby zobaczyć kod

    0 25
  • Mitronik
  • #2 14 Kwi 2015 19:28
    michalko12
    Specjalista - Mikrokontrolery

    Sprawdź zasilanie, GND, CS, WP, HOLD, czy są na nich prawidłowe stany. Do póki nie zadziała Ci instrukcja READ nie masz co sprawdzać zapisu. Z ostatniego oscylogramu można wywnioskować problem z CS. Na oscylogramach nie pokazałeś zachowania się lini CS. Na czas testów podepnij jakiś pulldown na SO żeby nie było nieustalonych stanów na tej linii.

    0
  • #3 14 Kwi 2015 19:34
    oloam
    Poziom 21  

    Sprawdz czy wogole poprawnie komunikujesz sie z pamiecia odczytujac SR (Status Register). Odczytujac SR bedziesz wiedzial czy masz poprawna komunikacje oraz czy przypadkiem pamiec nie jest zabezpieczona (bity BP0 i BP1). Wyal timer a sprawdzaj bit busy odczytujac SR. cos na ksztalt:

    Kod: c
    Zaloguj się, aby zobaczyć kod


    zapis:
    Kod: c
    Zaloguj się, aby zobaczyć kod


    odczyt (tu jest akurat przyklad read array, ktorej to komendy twoj flash nie obsluguje):
    Kod: c
    Zaloguj się, aby zobaczyć kod

    0
  • #4 14 Kwi 2015 20:03
    michalko12
    Specjalista - Mikrokontrolery

    oloam napisał:
    Sprawdz czy wogole poprawnie komunikujesz sie z pamiecia odczytujac SR (Status Register)

    Przecież ma oscyloskop więc widzi co wysyła i odbiera. Co mu po czytaniu rejestru jak w ogóle mu odczyt nie działa. Na ostatnim oscylogramie podczas transmisji ostatniego bajtu pamięć nie steruje sygnałem SO, co oznacza, że nie rozpoznaje komendy i adresu, być może przez brak odpowiedniego sterowania sygnałem CS lub niewłaściwym zasilaniu pamięci.

    0
  • #5 15 Kwi 2015 09:16
    Kubbaz
    Poziom 26  

    michalko12 napisał:
    Sprawdź zasilanie, GND, CS, WP, HOLD, czy są na nich prawidłowe stany.


    Vcc = 3,20 V (zasilanie mam z płytki PCB LPCXpresso LPC1769),
    !WP = 3,20 V bezpośrednio do Vcc przez rezystor pull-up 10 kΩ,
    !HOLD = 3,20 bezpośrednio V do Vcc przez rezystor pull-up 10 kΩ,
    !CS = 3,16 V (w stanie wysokim) do pinu !SSEL0 uC + rezystor pull-up 10 kΩ do Vcc.

    dołożyłem także rezystory pull-up 10 kΩ na linie SI i SO, na linii SO przestał występować stan nieustalony ok. 2,3 V

    michalko12 napisał:
    Z ostatniego oscylogramu można wywnioskować problem z CS. Na oscylogramach nie pokazałeś zachowania się linii CS.


    Widok na całość (WREN + Write Byte + Read Byte), kolor niebieski to linia !CS, kolor czerwony to linia SI:
    25LC1024 - LPC1769 + SPI + Flash 25LC1024 - nie zapisuje do pamięci

    Teraz po kolei:

    Instrukcja WREN, kolor niebieski to linia !CS, kolor czerwony to linia SI:
    25LC1024 - LPC1769 + SPI + Flash 25LC1024 - nie zapisuje do pamięci

    Sekwencja Write Byte, kolor niebieski to linia !CS, kolor czerwony to linia SI:
    25LC1024 - LPC1769 + SPI + Flash 25LC1024 - nie zapisuje do pamięci

    Sekwencja Read Byte, kolor niebieski to linia !CS, kolor czerwony to linia SI:
    25LC1024 - LPC1769 + SPI + Flash 25LC1024 - nie zapisuje do pamięci

    Sekwencja Read Byte, kolor niebieski to linia !CS, kolor czerwony to linia SO:
    25LC1024 - LPC1769 + SPI + Flash 25LC1024 - nie zapisuje do pamięci

    I widok na całość z linią !CS i SO (WREN + Write Byte + Read Byte), kolor niebieski to linia !CS, kolor czerwony to linia SO:
    25LC1024 - LPC1769 + SPI + Flash 25LC1024 - nie zapisuje do pamięci

    Teraz poszerzyłem nawet czasy zmiany stanów linii !CS ze stanu wysokiego na stan niski (po 10 us) przed i po ustaniu transmisji na liniach SI i SO, ale również to nic nie pomogło.

    0
  • #6 15 Kwi 2015 10:13
    Freddie Chopin
    Specjalista - Mikrokontrolery

    Jak dla mnie na tych oscylogramach widać "jak na dłoni", że linia CS zmienia stan zbyt szybko - gdy jeszcze trwa transmisja.

    Pokaż lepiej kod funkcji sspWrite().

    4\/3!!

    0
  • #8 15 Kwi 2015 10:53
    Freddie Chopin
    Specjalista - Mikrokontrolery

    Spróbuj zamiast bitu RNE w rejestrze SR sprawdzać bit BSY (tyle że on ma odwrotną "polaryzację" niż RNE).

    Sprawdź czy problem nadal występuje gdy wstawisz opóźnienie przed ustawienie SS na stan wysoki i po ustawieniu SS na stan niski - tak aby na oscylogramach wyraźnie było widać że stan tej linii zmienia się "daleko" od wszelkich zmian na liniach danych i zegara.

    Pokaż jeszcze oscylogram CS i linii zegara, bo może ja źle patrzę i tylko mi się wydaje, że CS zmienia się zbyt wcześnie.

    Jeśli nic nie pomoże, to pokaż funkcję inicjalizacji SPI i upewnij się, że masz na 100% dobrze ustawione CPHA i CPOL.

    4\/3!!

    0
  • Mitronik
  • #9 15 Kwi 2015 11:11
    Kubbaz
    Poziom 26  

    Freddie Chopin napisał:
    Sprawdź czy problem nadal występuje gdy wstawisz opóźnienie przed ustawienie SS na stan wysoki i po ustawieniu SS na stan niski - tak aby na oscylogramach wyraźnie było widać że stan tej linii zmienia się "daleko" od wszelkich zmian na liniach danych i zegara.


    Zmieniłem tak jak zalecałeś - po 100 us przed i po, żadnych pozytywnych zmian przy tym ustawieniu zmian stanu linii !CS.

    Freddie Chopin napisał:
    Pokaż jeszcze oscylogram CS i linii zegara, bo może ja źle patrzę i tylko mi się wydaje, że CS zmienia się zbyt wcześnie.


    Bardzo proszę:

    Stan linii !CS vs. linii SCK:
    25LC1024 - LPC1769 + SPI + Flash 25LC1024 - nie zapisuje do pamięci 25LC1024 - LPC1769 + SPI + Flash 25LC1024 - nie zapisuje do pamięci 25LC1024 - LPC1769 + SPI + Flash 25LC1024 - nie zapisuje do pamięci

    Stan linii !CS vs. linii SO:
    25LC1024 - LPC1769 + SPI + Flash 25LC1024 - nie zapisuje do pamięci 25LC1024 - LPC1769 + SPI + Flash 25LC1024 - nie zapisuje do pamięci

    Freddie Chopin napisał:
    Jeśli nic nie pomoże, to pokaż funkcję inicjalizacji SPI i upewnij się, że masz na 100% dobrze ustawione CPHA i CPOL.


    Kod: c
    Zaloguj się, aby zobaczyć kod

    0
  • #10 15 Kwi 2015 11:19
    michalko12
    Specjalista - Mikrokontrolery

    Problem nie leży w zbyt krótkim CS. Widać to na oscylogramie Read Byte (CS+SO), pamięć nie reaguje na komendę. Na pewno to jest ten typ pamięci?

    0
  • #12 15 Kwi 2015 11:43
    michalko12
    Specjalista - Mikrokontrolery

    Połączenie GND pewne?

    0
  • #14 15 Kwi 2015 12:33
    michalko12
    Specjalista - Mikrokontrolery

    Hmmm... Co Ci jeszcze można poradzić? Kondensator blokujący bezpośrednio na pamięci, rezystor do 100R szeregowo na SCK, spowolnij jeszcze SPI ( to tylko tymczasowo do testów).
    Najważniejsze to uruchomić komendę READ, ostatni bajt tej komendy powinien być wysterowany przez pamięć na lini SO. Do póki tego nie osiągniesz nie masz co próbować innych komend. Na linii SO daj pull-down, bo wtedy widać odczyt 0xFF.

    Może pokaż na zdjęciu jak masz fizycznie przyczepioną tą pamięć do LPCXpresso?

    0
  • #15 15 Kwi 2015 14:24
    Kubbaz
    Poziom 26  

    michalko12 napisał:
    Kondensator blokujący bezpośrednio na pamięci

    Są nawet dwa: 1 uF/50 V ceramiczny MLCC i 100 nF/50 V ceramiczny MLCC (jakieś 5-8 mm od nóżek scalaka).

    michalko12 napisał:
    Na linii SO daj pull-down, bo wtedy widać odczyt 0xFF.

    Po dodaniu rezystora pull-down 100 kΩ na linię SO (pin nr 2 układu scalonego) pojawia się stan nieustalony na poziomie 1,96 V, co widać na oscylogramie:
    (kolor niebieski - linia !CS, kolor czerwony - linia SO)
    25LC1024 - LPC1769 + SPI + Flash 25LC1024 - nie zapisuje do pamięci

    Samo to już jest dziwne... :!: Poza tym włożyłem w podstawkę precyzyjną drugi (nowy) układ pamięci Microchip 25LC1024 i zachowanie jest takie samo.

    michalko12 napisał:
    Może pokaż na zdjęciu jak masz fizycznie przyczepioną tą pamięć do LPCXpresso?

    25LC1024 - LPC1769 + SPI + Flash 25LC1024 - nie zapisuje do pamięci 25LC1024 - LPC1769 + SPI + Flash 25LC1024 - nie zapisuje do pamięci 25LC1024 - LPC1769 + SPI + Flash 25LC1024 - nie zapisuje do pamięci 25LC1024 - LPC1769 + SPI + Flash 25LC1024 - nie zapisuje do pamięci 25LC1024 - LPC1769 + SPI + Flash 25LC1024 - nie zapisuje do pamięci 25LC1024 - LPC1769 + SPI + Flash 25LC1024 - nie zapisuje do pamięci

    0
  • #16 15 Kwi 2015 14:42
    Freddie Chopin
    Specjalista - Mikrokontrolery

    Patrząc na plątaninę powyżej, przypomina mi się podobny problem który kiedyś miałem. Występował on przy transmisji SPI z układem podpiętym do STM32F0DISCOVERY przy użyciu kabelków. Probiem zniknął dopiero wtedy, gdy dodałem pętlę mas... Jeśli masz tam już pętlę mas, to ją usuń. Jeśli jej nie masz, to spróbuj ją dodać... No i z racji kabelków, ustaw faktycznie wolniejszy zegar SPI.

    W akcie desperacji możesz też pomierzyć oscyloskopem zasilanie (na pinie tej pamięci), żeby zobaczyć czy coś tam nie przysiada.

    0
  • #17 15 Kwi 2015 14:53
    michalko12
    Specjalista - Mikrokontrolery

    Ze załączonych zdjęć wynika brak podłączenia CS.

    Edit: Nie zauważyłem prowadzenia "górą"

    0
  • #18 15 Kwi 2015 15:11
    Kubbaz
    Poziom 26  

    Freddie Chopin napisał:
    No i z racji kabelków, ustaw faktycznie wolniejszy zegar SPI.

    Ustawiłem zegar na 10 kHz (40 razy wolniejszy, bo było 400 kHz). Problem dalej pozostał. Najdziwniejsze jest to, że (abstrahując co jest na linii SO) to stan tej linii jest cały czas (w stanie powiedzmy nic nierobienia) na poziomie 2 V... :?:

    Freddie Chopin napisał:
    Problem zniknął dopiero wtedy, gdy dodałem pętlę mas... Jeśli masz tam już pętlę mas, to ją usuń. Jeśli jej nie masz, to spróbuj ją dodać...


    Zrobiłem bezpośrednie zasilanie płytki z pamięcią flash do LPCXpresso LPC1769 przy użyciu dwóch kabelków - teraz nie ma żadnych pętli masowych i żadnych innych odbiorników podłączonych do zasilania na płytce LPCXpresso - jest tylko ta pamięć. I dalej kicha... :cry: Dalej ten stan 2 V na linii SO jest utrzymany...

    Freddie Chopin napisał:
    W akcie desperacji możesz też pomierzyć oscyloskopem zasilanie (na pinie tej pamięci), żeby zobaczyć czy coś tam nie przysiada.

    Napięcie 3,20 V trzyma jak drut przez cały czas - jest OK.

    0
  • #19 15 Kwi 2015 15:26
    michalko12
    Specjalista - Mikrokontrolery

    Umyj tą płytkę jakimś rozpuszczalnikiem np. nitro albo jakimś alkoholem.

    0
  • #20 15 Kwi 2015 16:06
    Kubbaz
    Poziom 26  

    michalko12 napisał:
    Umyj tą płytkę jakimś rozpuszczalnikiem np. nitro albo jakimś alkoholem.

    Całą płytkę umyłem twardą szczoteczką do zębów alkoholem izopropanolem.
    Bez zmian...

    Linia SO z rezystorem pull-down 100 kΩ jest na poziomie 1,96 V, bez pull-down'a jest na poziomie 2,20 V, natomiast z pull-up'em 100 kΩ jest na poziomie 3,12 V.

    0
  • #21 15 Kwi 2015 17:08
    michalko12
    Specjalista - Mikrokontrolery

    A to nie dlatego, że jest włączony pull-up od strony procesora?

    Mnie zastanawiają te zakłócenia, które są przenoszone z SCK na inne linie. Dałeś te 100R na SCK?

    0
  • #22 17 Kwi 2015 14:14
    Kubbaz
    Poziom 26  

    Witam po krótkiej przerwie,

    Pozmieniałem nieco czasy zmiany stanów linii !CS i pamięć działa - na razie na kabelkach i na prędkości zegara 10 kHz :D. Dodanie szeregowo rezystora 100 Ω na linię zegarową (SCK) niczego nie zmienia - te zakłócenia od linii zegarowej dalej przenoszą się na linię SO.

    Poniżej kod źródłowy samej obsługi pamięci flash SPI:

    Kod: c
    Zaloguj się, aby zobaczyć kod


    Program po prostu zapisuje zmieniającą się wartość zmiennej temp do adresu zerowego i potem odczytuje z niego wartość i wyrzuca na UARTa0.

    Pamięć nieulotna jest mi potrzebna m.in. do przechowywania danych roboczych urządzenia (nastaw, ustawień, etc.) Mam napisaną dalszą część kodu źródłowego, który obsługuje mechaniczny enkoder jako przełącznik wielopozycyjny. Enkoder obsługiwany jest w przerwaniu od Timera1, które występuje co 100 ms (10 razy an sekundę).

    Kod: c
    Zaloguj się, aby zobaczyć kod


    Kod: c
    Zaloguj się, aby zobaczyć kod


    gdzie zmienna "EncoderTurn" jest zmienną globalną i znajduje się w pliku encoder_ctr_ed16111o.h:
    Kod: c
    Zaloguj się, aby zobaczyć kod


    oraz w pliku encoder_ctr_ed16111o.c:
    Kod: c
    Zaloguj się, aby zobaczyć kod


    Teraz na czym polega problem?
    Otóż gdy zakomentuję część kodu w programie głównym (main) odpowiedzialną za obsługę zapisu i odczytu danych do pamięci, to obsługa enkodera działa poprawnie - jak zakręci się w odpowiednią stronę, to UART wysyła odpowiednie wartości (0xFF lub 0xAA), natomiast jeśli dołączę już ten fragment z obsługą pamięci, to działa to tak, że na terminalu komputera wyświetla mi się odczytana (tudzież chwilę wcześniej zapisana wartość) dopiero gdy choć raz zakręcę enkoderem... :?: Tak jakby to kod obsługi enkodera w przerwaniu Timera1 w dziwny sposób uruchamiał kod główny... nie mam pojęcia jak to możliwe... :?:

    0
  • #23 17 Kwi 2015 14:29
    Freddie Chopin
    Specjalista - Mikrokontrolery

    Pierwsza sprawa jest taka, że zmienna odczytywana/zapisywana przez przerwanie i kod główny powinna być volatile.

    Druga zaś - 1ms delay w przerwaniu to nie jest szczególnie dobry pomysł...

    4\/3!!

    0
  • #24 20 Kwi 2015 08:29
    Kubbaz
    Poziom 26  

    Freddie Chopin napisał:
    Pierwsza sprawa jest taka, że zmienna odczytywana/zapisywana przez przerwanie i kod główny powinna być volatile.


    Zrobiłem tę zmienną ulotną:
    Kod: c
    Zaloguj się, aby zobaczyć kod


    Poza tym kodu nie zniemiałem. W zasadzie program działa dalej tak samo... :cry:

    Freddie Chopin napisał:
    Druga zaś - 1ms delay w przerwaniu to nie jest szczególnie dobry pomysł...


    Hmmm... Ten delay jest po to w tym miejscu, że po wyzwoleniu przez opadające zbocze jednego sygnału z dwóch wyjściowych enkodera (nazywam go referencyjnym/master), po tym delayu'u sprawdzić stan drugiego sygnału i na podstawie stanu tego drugiego stwierdzić czy obrót był w prawo czy w lewo.
    Jeśli nie delay, to zastanawiam się jak inaczej to rozwiązać... :?:

    0
  • #25 20 Kwi 2015 08:33
    Freddie Chopin
    Specjalista - Mikrokontrolery

    Kubbaz napisał:
    Jeśli nie delay, to zastanawiam się jak inaczej to rozwiązać...

    Ustawić przerwanie od timera, albo przenieść delay do głównej pętli programu.

    0
  • #26 20 Kwi 2015 09:00
    Kubbaz
    Poziom 26  

    Freddie Chopin napisał:
    Ustawić przerwanie od timera, albo przenieść delay do głównej pętli programu.


    Hmmm... Tak myślę, czy nie rozbić algorytmu obsługi enkodera na dwie części:

    Pierwsza część - byłaby w przerwaniu, obserwowała stan sygnału master/referencyjnego z wyjścia enkodera i tylko detekowała jego zbocze opadające (stan niski tak naprawdę),

    Druga część - byłaby w głównej pętli programu i robiła całą resztę, czyli analizowała po stanie drugiego sygnału wyjściowego z enkodera, w którą stronę nastąpił obrót...

    Niebawem to sprawdzę i napiszę o rezultatach.

    Dodano po 0 [sekundy]:

    Freddie Chopin napisał:
    Ustawić przerwanie od timera, albo przenieść delay do głównej pętli programu.


    Hmmm... Tak myślę, czy nie rozbić algorytmu obsługi enkodera na dwie części:

    Pierwsza część - byłaby w przerwaniu, obserwowała stan sygnału master/referencyjnego z wyjścia enkodera i tylko detekowała jego zbocze opadające (stan niski tak naprawdę),

    Druga część - byłaby w głównej pętli programu i robiła całą resztę, czyli analizowała po stanie drugiego sygnału wyjściowego z enkodera, w którą stronę nastąpił obrót...

    Niebawem to sprawdzę i napiszę o rezultatach.

    0