Problem z odczytem karty CF

Jan 03, 2025 Last reply: 1 year ago 20 Replies

Jakiś czas temu złożyłem amatorski komputerek ośmiobitowy na procesorze



8080 (a właściie polskim MCY7880) i zabrałem się za uruchamianie na nim CP/M. Całość była złożona na płytce prototypowej, więc teraz zabrałem się za budowę bardziej finalnej wersji, przy okazji przenosząc się na
8085. Udało mi się uruchomić większość peryferiów i przenieść kod z wersji prototypowej. Tak naprawdę wymagane były tylko niewielkie zmiany

- np. niektóre peryferia znajdują się teraz pod innymi adresami.



W przypadku karty CF trafiłem jednak na ścianę. Z jakiegoś powodu nie jestem w stanie odczytać ani informacji o karcie (przychodzą bzdury, a powinna się wyświetlać jej nazwa) ani sektora rozruchowego (kod nie znajduje poprawnych wartości w MBR). Najwyraźniej jednak komunikacja pomiędzy kartą i systemem działa, bo:



  1. Jestem w stanie zainicjować kartę, a w trakcie operacji zmienia się zawartość odczytywanego rejestru STATUS.
  2. Przy próbie odczytu danych z karty zapala się na chwilę dioda na linii DASP.

Rzucił mi się w oczy jeszcze jeden dziwny szczegół. Dobrałem kwarc tak samo, aby zegar systemowy był dokładnie taki sam w wersji na 8080 i 8085 (2,048 MHz). Z jakiegoś powodu pojawiło się inne zachowanie karty, jeśli chodzi o timeout podczas jej inicjacji. Timeout to dwie pętle na rejestrach B i C. W wersji na 8080 rejestr C miał początkową wartość 32, a B był przy każdym przebiegu inicjowany wartością 255. W przypadku konstrukcji na 8085 jednak to nie wystarczało i musiałem podbić rejestr C do 64, żeby inicjacja miała szanse przejść.



Patrzę na schemat i nie mogę znaleźć żadnej różnicy w połączeniach. Kod jak mówiłem został przeniesiony ze starego projektu, zmienił się tylko adres karty.



Ktoś ma pomysł gdzie szukać przyczyny?


Roznic w czasach instrukcji chyba nie ma ..

a) kwarc Ci sie wzbudził na overtonie i masz 6MHz? choc pasowałoby raczej 4MHz.

b) jesli mnie skleroza nie myli system 8080 wymagał kwarca znacznie szybszego, który był dzielony w innej kosci. Rozumiem, że dobrałej odpowiednio?

c) a nie zapomniałej zmienic adresu w jakiejs instrukcji?

d) Use Z80, Luke :-)

e) Use ARM, Luke :-)

J.

Nie, z tego co kojarzę to 8080 i 8085 są ze sobą kompatybilne programowo. Są pewne różnice sprzętowe, które musiałem uwzględnić. Przykładowo system z 8080 posiada osobne linie IO_RD, IO_WR, MEM_RD i MEM_WR, generowane przez kontroler magistrali 8228. 8085 posiada tylko linie WR i RD, których funkcja jest zależna od stanu pinu IOM. Musiałem więc wygenerować sobie osobne linie dla IO oraz pamięci, za pomocą GAL-a. Ale raczej to nie tutaj leży przyczyna, bo wszystkie inne testowane peryferia działają poprawnie.

Sprawdzone oscyloskopem. Na linii CLK mam poprawną częstotliwość 2,048 MHz.

Tak, wziąłem to pod uwagę. W przypadku 8080 częstotliwość kwarcu była dzielona dziewięć razy, więc do uzyskania 2,048 MHz potrzebny był kwarc

18,432 MHz. W przypadku 8085 dzielona jest tylko dwa razy, wiec dałem kwarc 4,096 MHz.

Nie wydaje mi się. W projekcie mam wydzielony osobny plik definitions.asm, w którym znajdują się rozmaite parametry, które mogą się różnić pomiędzy poszczególnymi wersjami. W przypadku karty CF różni się tylko CFBASE - adresy poszczególnych rejestrów są generowane przez dodanie kolejnych liczb do tej bazy. A ten adres się zgadza. W dodatku gdyby się nie zgadzał, karta w ogóle nie byłaby wykrywana i nie reagowałaby na próbę inicjacji.

Dodatkowo:

  1. Przeszukałem diffem kod źródłowy z obydwu wersji. Nie widzę żadnych różnic w okolicach związanych z kartą CF.
  2. Złożyłem dwa egzemplarze płytki. Różnią się niewielkimi detalami, ale część z kartą CF jest taka sama. Problem jest powtarzalny na obydwu płytkach.
  3. Zapomniałem dodać, że linie D0..D7 są podłączone do karty CF za pośrednictwem układu 74HCT245 (pin DIR do IO_RD, pin G do sygnału CS karty). To jest właśnie efekt eksperymentów na wersji prototypowej, gdzie nie byłem w stanie uzyskać stabilnych transmisji - czasem jakiś bajt został zgubiony lub przekłamany. Po dodaniu bufora wszystko zaczęło działać stabilnie i poprawnie, wiec uwzględniłem go także w wersji na 8085.

Hmm... Teraz właśnie dotarło do mnie, że w sumie pomiędzy wersjami jest istotna różnica - linie D0..D7 w 8085 są multipleksowane z młodszym bajtem magistrali adresowej. Może sterując buforem powinienem uwzględnić jeszcze sygnał ALE, żeby był zamknięty w momencie, gdy na liniach danych są linie adresowe?

Jest też taki plan, jednak 8085 wydawał się prostszym krokiem z poziomu już istniejącego projektu na 8080.

E tam, ARM nie pasuje do retro. :)

W dniu 4.01.2025 o 09:06, Atlantis pisze:

Wg mnie to będzie jedyna przyczyna, dane musisz zatrzaskiwać tym ALE.

Samo ALE to chyba za mało. W tej chwili polegam tylko na sygnale IO_RD do ustawiania kierunku transferu - jeśli linia jest w stanie niskim, to mamy odczyt z karty, jeśli jest wysoka, to zapis do niej. Gdybym w takim wypadku użył ALE do sterowania pinem G, to za każdym razem gdy tylko na liniach D0..D7 pojawiałyby się dane, bufor otwierałby się w którąś stronę. Pół biedy, gdyby linia IO_RD znajdowała się wtedy w stanie wysokim - karta by po prostu zignorowała to co pojawi się na magistrali, nie widząc aktywnych sygnałów CS i RD. Jednak gdyby kierunek bufora był ustawiony w przeciwną stronę, to wtedy pojawi się następująca sytuacja:

  1. ALE otworzy bufor.
  2. IO_RD ustawi kierunek od karty do magistrali systemowej.
  3. Karta nie widząc sygnału CS, będzie trzymała swoje wyjścia danych w stanie wysokiej impedancji. Przez bufor na magistralę trafią więc stany nieustalone.

Trochę poeksperymentowałem, dodając trochę logiki do GAL-a. Na chwilę obecną wygląda to tak:

/MEMRD = /IOM * /RD /MEMWR = /IOM * /WR /IORD = IOM * /RD /IOWR = IOM * /WR /LOCPTCS = /LOCIOCS * /A4 * IOM * /WR /LOCCFCS = /LOCIOCS * A4 * IOM * /ALE

Rzeczy, których mogę być pewien:

- Poprawnie działa generowanie sygnałów MEMRD i MEMWR, bo pamięci działają poprawnie i kod z EPROM-u się wykonuje.

- Poprawnie działa generowanie sygnałów IORD i IOWR, bo peryferia (poza kartą) działają poprawnie. Mogę odczytywać i zapisywać z/do nich dane.

- Poprawnie działa przynajmniej kawałek dekodera adresów, bo linia LOCPTCS (sterująca portem 74273) działa poprawnie.

Tylko z kartą są problemy. Bufor wydaje się być najbardziej oczywistym kandydatem, bo to główna różnica w stosunku do innych peryferiów. Zastanawiam się teraz czy przypadkiem nie mam jakiegoś problemu z timingami i któryś sygnał nie pojawia się za wcześnie lub za późno. Przykładowo w chwili obecnej sygnał CS steruje zarówno kartą, jak i otwarciem bufora (linia G). Może powinienem to jakoś rozdzielić?

Nie wiem czy w akcie desperacji nie wywalę w ogóle tymczasowo bufora i nie połączę linii danych bezpośrednio. Widziałbym przynajmniej czy coś się zmieniło i czy jest poprawa. W prototypie na 8080 karta działała bez bufora w miarę ok, ale od czasu do czasu pojawiały się przekłamania w transmisjach.

Ok, w ramach eksperymentu usunąłem bufor i podłaczyłem kartę bezpośrednio do magistrali systemowej. Problem nadal występuje. Teraz już w ogóle nie mam pojęcia co może być nie tak. W wersji z 8080 bez bufora odczyt był niestabilny, ale przynajmniej był...

Czytam jeszcze informacje w Intenrecie, na temat podłączania karty CF do starych systemów mikroprocesorowych i z tego co widzę, pojawia się też temat opóźniania linii RD. Niektórzy proponują dodanie niewielkiego filtra RC, inni stosują dodatkową logikę (np. do synchronizacji RD z kolejnym impulsem na linii CLK). Skoro nie w buforze, to może tutaj leży przyczyna. Możliwe, że w przypadku prototypu sprawę załatwiały pojemności i indukcyjności montażowe - karta CF znajdowała się na osobnym module, a montaż był wykonany na płytkach uniwersalnych, za pomocą kynaru. W nowej wersji slot CF znajduje się tuż przy procesorze, a płytka jest wytrawiona.

Nie bez powodu np. w niektórych peryferiach jest slope config czy np. w spi konfiguracja momentu próbkowania linii SDI (middle/beginning/end).

Najwyraźniej to jeszcze ciągle nie to. Dodałem opóźnienie na linii RD karty, korzystając z niewykorzystanego pinu układu GAL. Linijka realizującego to kodu wygląda następująco:

DELCFRD.R = IORD

W wyniku tego stan linii IORD jest zatrzaskiwany na wyjściu DELCDRD za pomocą zegara systemowego.

Sprawdziłem na oscyloskopie - linia DELCFRD faktycznie przechodzi w stan niski jeden cykl zegarowy później, ale przejście do stanu wysokiego następuje dwa cykle po linii IORD. Co ciekawe rozwiązanie to nie chciało zadziałać na ATF16VB - linia DELCFRD była cały czas w stanie wysokim. Za to na starym GAL16VA nie ma tego problemu.

Niestety, nic się nie zmieniło w zachowaniu karty. Dioda nadal błyska, wskazując na próbę odczytu, nie są jednak odczytywane sensowne dane.

Połączenia w tej chwili wyglądają następująco:

  1. Magistrala danych podłączona przez dwukierunkowy bufor 74HCT245
  2. Kierunkiem bufora steruje linia IORD (ogólnosystemowa, nieopóźniona)
  3. Sygnałem G bufora steruje linia CS karty CF
  4. Sygnałem RD karty CF steruje opóźniony sygnał DELCFRD, generowany w GAL-u według powyższego opisu
  5. Sygrałem WR karty CF steruje sygnał IOWR (równiez ogólnosystemowy, nieopóźniony)

Na chwilę obecną kończą mi się już pomysły...

Ok, już po napisaniu poprzedniej wiadomości udało mi się rozwiązać problem z wydłużaniem opóźnionego sygnału RD dla karty. Wystarczyło dodać XOR wyjścia flip-flopa z jego wejściem. Niestety kosztowało mnie to jedną linię GAL16V8A. W lepszym układzie dałoby się to ogarnąć za pomocą wejścia asynchronous set, ale niestety ten konkretny GAL takiego nie posiada.

Problem nadal występuje. Niemniej w artykułach z sieci widzę, że ludzie dodają opóźnienie także opóźnienie na linii WR. Tego też spróbuję. Nawet jeśli nie zadziała, to pewnie i tak zostawię te opóźnienia w projekcie, dla zapewniania lepszej kompatybilności z kartami (gdy już uda mi się rozwiązać główny problem).

Przy okazji widzę, że mogę trochę zoptymalizować projekt odziedziczony po wersji z 8080. W tej chwili nie ma chociażby sensu generowanie osobnych linii IORD/IOWR, skoro dekoder adresów IO jest bramkowany sygnałem IOM. Sygnały MEMWR/MEMWR zostawię, bo przerobienie dekodera adresów dla pamięci byłoby trochę bardziej kłopotliwe.

Ok, przeanalizowałem jeszcze raz sytuację za pomocą oscyloskopu i wydaje mi się, że znalazłem potencjalną przyczynę.

Na linii CS karty CF widać krótkie szpilki. Gdy linia jest w stanie wysokim, przechodzi na krótki moment do stanu niskiego, gdy natomiast znajduje się w stanie niskim, przechodzi na moment do wysokiego. Sprawdziłem inne sygnały z dekodera IO (74HTC138) i podobną sytuację widać także na niektórych (obecnie niewykorzystywanych liniach CS).

Wygląda na to, że źródłem tych zakłóceń jest linia adresowa A5, ale podobne szpilki widzę także na innych liniach z mniej znaczącego bajtu linii adresowych (a więc multipleksowanego z magistralą danych). Więcej znaczące linie adresowe wyglądają zupełnie czysto. Momenty wystąpienia tych zakłóceń korelują narastającym zboczem sygnału ALE. Czasami widać to jako wyraźną szpilkę wyraźnej zmiany stanu, ale często też w tych punktach widać jedynie drobne wahania sygnału.

Wygląda na to, że szpilki są za krótkie, żeby zakłócić działanie retro peryferiów (jak 8251 albo 8253) ale już karta CF rejestruje je jako normalny sygnał aktywacji i stąd zaburzona komunikacja. Przynajmniej taka hipoteza wydaje się być sensowna.

Problem jest powtarzalny - występuje na dwóch egzemplarzach urządzenia.

Ktoś spotkał się z czymś takim? Zastanawiam się jak temu przeciwdziałać. Opóźnić aktywację rejestru 74HCT573 (trzymającego dolny bajt adresu) za pomocą jakiegoś filtra RC na linii ALE? A może winny jest rejestr z rodziny HCT, który działa za szybko?

Ale to jakaś wyjątkowo dziwnie jest poprowadzona? Zbocza ma szczególnie ostre? Dlaczego tylko ona? Nie szarpie zasilaniem? Sygnały, które zakłóca typu OC są ze słabymi pull-upami? ...choć jeśli to się dzieje w obydwie strony to bardziej to na hazard wygląda.

Nie wyraziłem się dostatecznie jasno. Problem nie dotyczy tylko linii A5, a całego niższego bajtu magistrali adresowej (który w 8085 jest multipleskowany z magistralą danych). Po prostu po linii A5 te szpilki przez 74HCT138 propagują na linię CS karty. Wygląda na to, że miejsca występowania szpilek korelują z narastającym zboczem sygnału ALE, który zatrzaskuje młodszy bajt adresu w układzie

74HCT573. Przy czym nie jest tak, że każdy impuls na ALE = jedna szpilka. Czasem w tych miejsach widoczny jest jedynie lekki szum na liniach adresowych, a czasami w ogóle nie widać szpilek.

W ramach eksperymentu próbowałem dodać filtr RC (330om, 100pF) na linii ALE. Jednak o ile zbocza sygnału się wygładziły, to problem ze szpilkami na liniach adresowych nie zniknął.

A ten 573 odfiltrowany dobrze? Czyli on jest źródłem szpilek?. ALE jest tylko do niego? No dobra, a jak 8085 wystawi ALE, to linie do 573 zmieniają natychmiast stan? - chodzi mi o to czy ta zmiana jest jakoś skorelowana ze szpilkami.

To ja bym próbował kondensatory dawać na A5, na CS...

A jak wyglądają czasy tych szpilek w porównaniu do taktu procesora?

Masz na myśli zasilanie? Standardowo (jak każdy układ scalony w projekcie) ma kondensator 100 nF do masy przy pinie VCC. Jednak jak przyjrzałem się projektowi płytki, to może faktycznie moża by w tej okolicy dać jakiś mały elektrolit i poprowadzić zasilanie jakaś krótszą drogą z okolicy miejsca podpięcia zasilacza. To samo z masą...

Na to wygląda. Na wyjściach 74HCT573 pojawiają się po raz pierwszy i stamtąd propagują na dekoder adresów IO.

Tak.

Jeśli dobrze rozumiem działanie 74573, to w stanie wysokim na wejściu LE będzie on po prostu powtarzał stany wejść na wyjściach. Zatrzaśnięcie następuje dopiero wraz ze zboczem opadającym na LE. Czyli mamy do czynienia z następującą sytuacją:

- Procesor ustawia stan wysoki na ALE.

- Na liniach AD0..AD7 nie zdążyły się jeszcze ustalić właściwe poziomu odpowiadające dolnemu bajtowi adresu. Przez chwil mamy tam stare dane z D0..D7 albo stany nieustalone. Mogą to tłumaczyć np. pojemności montażowe - magistrala rozciąga się na dwie płytki, podczas gdy sygnał ALE to krótka ścieżka pomiędzy dwoma sąsiadujacymi scalakami.

- Przez moment ten niepoprawny, niestabilny stan jest widoczny na wyjściach 74573 (bo w stanie wysokim LE jest on przezroczysty), co objawia się w postaci szpilki.

- Po chwili sytuacja się stabilizuje, na wyjścia przekazywane są już właściwe sygnały, a na zboczu opadającym ALE następuje ich zatrzaśnięcie.

- To też tłumaczyć dlaczego szpilki nie są widoczne przy każdym impulsie na ALE. Raz na jakiś czas po prostu zdarza się, że poprzedni stan jest zgodny z tym, co finalnie ma się znaleźć na danej linii Ax.

Tak, ale to będzie tylko walka z objawem, a nie przyczyną. Przy założeniu, że powyższa diagnoza jest prawidłowa, powinienem opóźnić moment, w którym 74HCT573 widzi stan wysoki na ALE, żeby linie AD0..AD7 miały czas się ustabilizować. Temu miał służyć filtr na tej linii, ale może zwyczajnie dałem za małe opóźnienie? Albo zamiast filtra RC powinienem dać jakąś linię opóźniającą na bramkach/inwertorach?

Są znacząco krótsze od czasów trwania normalnych sygnałów w tym systemie. Wydaje mi się, że właśnie dlatego nie wpływają na działanie innych komponentów, poza kartą CF. Stare peryferia w stylu 8251 albo

8253 zwyczajnie ignorują tak krótkie anomalie na liniach CF, podczas gdy (relatywnie) współczesna karta CF jest już na tyle szybka, że interpretuje je jako normalny sygnał aktywacji, co miesza w komunikacji z nią.

Po zatrzaśnieciu adresu szpilek nie powinno być. Przed, przy wysokim ALE - mogą, bo rejestr jest transparentny.

Datasheet nawet sugeruje, że wtedy jeszcze linie AD0-7 mogą się zmieniac.

Ale ... wtedy sygnały /RD i /WR nie są jeszcze aktywne.

Tak.

Jakos tak,

Tak.

Wiekszość peryferiow z tamtej rodziny, jest na takie zmiany na linii CS odporna - musi być jeszcze dodatkowo sygnał RD lub WR.

Karty CF ... chyba tak samo.

Tryb 8-bit ustawiłes, karty nie resetujesz, zasilania jej nie wyłączasz?

To jeszcze niby jakies czasy propagacji mogą być, że ten 573 i 138 jakies powolne, i zmiany docierają, gdy już sygnaly RD/WR są aktywne.

Ale wątpie, nie przy tym zegarze ...

Ogolnie to chyba o nic. Sam procesor zapewnia odpowiedni czas. Szpile mogą się pojawić, ale powinny być niegroźne.

J.

Może wystarczy tą ścieżkę ALE wydłużyć? Z drugiej strony - źle masz zrobione to generowanie CS - może powinno być dodatkowo uzależnione od ALE w stanie niskim? Ja źle zrozumiałem twoje "propaguje się" - skojarzyłem jako przesłuch między ścieżkami albo zakłócenie na zasilaniu itp. a wygląda na to, że to jest prawidłowe działanie 138 - dostaje szpilkę, to dekoduje szpilkę.

Gdyby to był problem to 574 powinien go rozwiązać.

Karta powinna ignorować co jest na szynie dopuki nie jest wybrana. Może wymagać żeby sygnał był stabilny jakiś czas przed wybraniem. Ja by raczej patrzył na logikę zmieniającą sygnały sterujące do karty, jeśli tam masz szpilki czy za małe opóźnienie to może być problem.

Szpilki właśnie najwyraźniej wynikały z transparentności 573. W ramach eksperymentu zmieniłem podejście i zastosowałem 574 zatrzaskiwany zanegowanym sygnałem ALE. Teraz rejestr jest uzupełniany dopiero na zboczu opadającym ALE, już po ustabilizowaniu się adresu. Szpilki zniknęły, ale i tak mam fałszywą aktywność na liniach CS wychodzących z dekodera IO. Nie wziąłem pod uwagę tego, że samo połączenie linii IO_M z wejściem G1 74HCT138 nie wystarczy aby skutecznie zablokować dekoder. Linia IO_M przechodzi w stan wysoki już na samum początku cyklu, zanim adresy się zaktualizują, więc przez chwilę siedzi tam jeszcze stara wartość. Mógłbym to rozwiązać stosując dodatkowy układ 7474, ale chyba sobie daruję, bo bo te fałszywe stany niskie i tak pojawiają się przed sygnałami RD/WR. Chociaż może pomyślę o tym przy projektowaniu kolejnej wersji płytki. ;)

No właśnie... Początkowo myślałem, że te szpilki na linii CS karty CF mogą mieć jakiś związek z moimi problemami z kartą CF. Ale im więcej o tym myślę... Przecież w poprzednim komputerku z 8080 karta działała bez problemu, a tam dekoder IO w ogóle nie był w żaden sposób blokowany (choćby dlatego, że 8080 nie ma linii IO_M i trzeba by ją generować z innych sygnałów). Dekoder działał cały czas, reagując na wszystko, co akurat pojawiło się na dolnym bajcie magistrali adresowej. Dopiero aktywność na jednej z linii IORD, IOWR, MEMRD, MEMWR powodowała aktywację konkretnego urządzenia.

Właśnie... Sam fakt, że byłem w stanie używac karty CF w systemie z 8080 tego dowodzi.

Kod jest dokładnie taki sam jak w systemie z 8080 (gdzie karta działała bez problemu). Jedyna zmiana polegała na podmianie adresów rejestrów karty (które w nowym komputerze znalazły się w innych miejscach) oraz podniesieniu timeoutów przy odczytach (to już później, w ramach eksperymentów). Poza tym sterownik jest identyczny. Linię reset też sprawdziłem. Od razu przyszło mi do głowy, czy przypadkiem nie pomyliłem się i nie podpiąłem jej do linii reset o odwróconej logice, ale nie. Zresztą wtedy karta w ogóle byłaby trzymana w stanie wiecznego resetu, a ona reaguje na próby komunikacji (dioda miga przy próbie inicjacji i odczytu, jestem w stanie odczytywać rejestr STATUS). Po prostu gdy próbuję odczytać strukturę info i MBR, przychodzą bzdury.

Oscylogramy tego nie potwierdzają. Dodatkowo jeszcze dodałem w GAL-u logikę opóźniającą aktywację linii RD i WR dla karty CF o jeden cykl zegara. Niektóre źródła zalecają takie rozwiązanie dla większej kompatybilności - niektóre karty są ponoć na to wyczulone.

Właśnie też zaczyna mi się wydawać, że przyczyna pewnie leży gdzie indziej...

W dniu 17 sty 2025 o 11:30, Waldek Hebisch pisze:

Sie znaczy pUka do dnia wyborów?...

-- `_._ _,-'""`-._ .`'.-. ._. .-. (,-.`._,'( |\`-/| '.'O`-,` .,; o.' eneuel@@gmail.com '.O_' `-.-' \ )-`( , o o) `-:`-'.'.`\.'.' '~'~'~'~'~'~'~'~' o.`.,t

-bf- `- \`_`"'-.o'\:/.d`|'.p \;

formatting link
\|/..s

Join the Discussion

Have something to add? Share your thoughts — no account required.

Didn't find your answer?

Ask the community — no account required