Další ukázka z připravované knihy, pokračování předchozího článku.

Na zapojení procesoru není nic, co bychom už neviděli. Vstup DMA zůstane nepoužitý, je proto připojen na napájecí napětí, výstupy Q a BS jsou ponechány nezapojené.

Dekodér pamětí a signálů /RD, /WR funguje naprosto stejně jako u počítače Bravo. Opět stačí jeden obvod 7400. Jen místo výstupu PHI2 je použit výstup E se stejnou funkcí.

Paměti jsou vyřešené doslova stejně jako u předchozích počítačů. Na místě EEPROM jsem použil obvod 28C64 s kapacitou 8 kB, ale schéma je připravené i pro 28C256 – pak je potřeba přepínačem BANK zvolit vybranou polovinu paměti.

Dekodér pro periferie je zapojen tak, aby využíval adresy, kde je A15 = 1 a A14 = A13 = 0, tedy 8000h až 9FFFh. Pro každou periferii je vyhrazen prostor 1 kB, a to takto:

Periferie Adresa
IO0 8000h – 83FFh
IO1 9000h – 93FFh
IO2 8800h – 8BFFh
IO3 9800h – 9BFFh
IO4 8400h – 87FFh
IO5 9400h – 97FFh
IO6 8C00h – 8FFFh
IO7 9C00h – 9FFFh

Periferii IO0 věnujeme, podobně jako u Brava, sériovému portu:

Vstup RS, výběr registru, připojíme opět k A0, takže se sériový port objeví jako dvojice registrů na adresách 8000h – 83FFh. Na sudých to bude řídicí registr, na lichých datový. Opět doporučuju použít takové adresy, které mají v nedekódovaných bitech 1, tedy využít adresy 83FEh (řídicí) a 83FFh (datový).

Poslední část je připojení na sběrnici. Nevyvádím kompletní systémové sběrnice, pouze datovou a z adresní jen tři nejnižší bity. Kromě těchto signálů na sběrnici vyvádím i signály /WR, /RD, E, RESET, vstupy /WAIT (jiný název pro MRDY), /BUSRQ (jiný název pro HALT), /IRQ a /FIRQ.

Paralelní port PIA (6821)

Použili jsme už obvod PPI 8255 (u OMEN Alpha) i VIA 6522 (u Brava). Obvod PIA 6821 (v rodině 65xx má analogický obvod 6521 – liší se pouze označením některých vývodů, např. místo E je PHI2) je jednodušší verze obvodu VIA 6822 / 6522. Obsahuje dva osmibitové paralelní porty s možností nastavit každý bit každého portu nezávisle jako vstup nebo výstup.

Opět vidíme ze strany procesoru standardní rozhraní: datovou sběrnici se signály D0 – D7, dva vstupy pro výběr registrů (RS0 a RS1 – připojte je k adresní sběrnici, třeba na A0 a A1), signály R/W a E, které odpovídají signálům u procesoru 6809, vstup /RESET, tři vybavovací vstupy CS0, CS1 a /CS2 (obvod reaguje, pokud CS0 = CS1 = 1 a /CS2 = 0) a dva přerušovací výstupy /IRQA a /IRQB.  Tyto výstupy jsou v provedení „s otevřeným kolektorem“, tak je můžete bez problémů spojit dohromady a připojit oba ke vstupu /IRQ, /FIRQ nebo /NMI (nezapomeňte na pull up rezistor).

Ze strany portů jsou k dispozici port A (PA0 – PA7), port B (PB0 – PB7) a dva řídicí signály pro každý port (CA1, CA2, CB1, CB2).

Řídicí signály CA1, CB1 slouží jako zdroj požadavků na přerušení. Lze nastavit, jestli reagují na vzestupnou, nebo sestupnou hranu signálu, případně lze přerušení od těchto vstupů zamaskovat.

Řídicí signály CA2, CB2 mohou být naprogramovány buď jako zdroj přerušení, stejně jako v předchozím případě, nebo jako datový výstup. Výstup můžete řídit buď přímo, nebo můžete určit, že se výstup chová jako signalizace „data na portu připravena“. Signály Cx2 mají zapojený interní pull-up rezistor.

Porty A a B nejsou identické. Port A je vybavený pull-up rezistory a při čtení vrací vždy hodnotu, která je na vstupním pinu.

Port B má namísto toho klasický třístavový výstup, kompatibilní s úrovněmi TTL, a může budit vyšší zátěž. Při čtení se chová různě podle toho, jestli je nastaven jako vstup, nebo jako výstup. Pokud je nastaven jako vstup, čte se hodnota z pinu. Když je nastaven na výstup, při čtení z tohoto portu získáte data, která jste si uložili do registru.

Obvod PIA má šest interních registrů, ale přímo adresovatelné jsou jen čtyři (máme dva adresní vstupy RS0 a RS1). Jedná se o řídicí registr (CR), datový registr (PORT) a registr směru toku dat (DDR), všechny ve variantách pro port A a port B: CRA, CRB, PORTA, PORTB, DDRA, DDRB.

Jak návrháři vyřešili problém přístupu k šesti registrům, když jsou adresovatelné jen čtyři? Je to prosté: Na adresách 1 a 3 jsou řídicí registry CRA a CRB, na adresách 0 a 2 jsou datové a směrové registry (PORT/DDR). Bit 2 příslušného řídicího registru (CRA2, CRB2) udává, jestli na adrese 0, resp. 2, je k dispozici datový registr (PORTA, PORTB – když bit 2 = 1), nebo registr řízení směru (DDRA, DDRB – bit 2 = 0).

RS1 RS0 CRA2 CRB2 Registr
1 X PORTA
0 X DDRA
1 X X CRA
1 X 1 PORTB
1 X 0 DDRB
1 1 X X CRB

Registry PORT nastavují hodnoty, které jsou poslané na výstupní piny. Při čtení z těchto registrů získáte buď hodnoty na pinech (port A, port B v režimu vstup), nebo hodnoty předtím uložené do registru PORT (port B v režimu výstup).

Každý jednotlivý pin lze nastavit individuálně jako vstupní, nebo jako výstupní, a to zápisem hodnoty 0 nebo 1 do příslušného bitu registru DDR. Hodnota 0 znamená, že se příslušný pin chová jako vstup, hodnota 1 znamená výstup.

Řídicí registr CRx ovládá, kromě už zmíněného přepínání mezi datovým a směrovým registrem, hlavně chování vývodů Cx1, Cx2. Zároveň udržuje dva příznaky pro přerušení.

Bit 7 6 5 4 3 2 1
IRQx1F IRQx2F Cx2DIR Cx2CT1 Cx2CT0 DDR Cx1TR CX1IE

Bit 0 udává, jestli je povolené přerušení vstupem Cx1. Pokud je 0, je přerušení zakázané.

Bit 1 říká, jestli je přerušení vyvolané sestupnou (0), nebo vzestupnou (1) hranou na vstupu Cx1.

Bit 2 přepíná, jak už bylo zmíněno, přístup k registru DDR (0) nebo k PORT (1).

Bit 5 nastavuje chování vývodu Cx2. Pokud je 0, je Cx2 vstup, pokud je 1, je Cx2 výstup.

Bit 6 oznamuje, že došlo k přerušení od vstupu Cx2. Je automaticky vynulovaný při čtení datového registru, nebo RESETem. Pokud je Cx2 nakonfigurovaný jako výstup, je tento bit 0.

Bit 7 oznamuje, že došlo k přerušení od vstupu Cx1. Vynulovaný je při čtení datového registru a při RESETu.

Vynechal jsem bity 3 a 4. Tyto bity ovládají vývody Cx2 a jejich role se liší podle toho, jestli je tento vývod nakonfigurovaný jako vstup (bit 5 = 0), nebo jako výstup (bit 5 = 1).

Pokud je bit 5 = 0 (Cx2 je vstup), fungují analogicky jako bity 0 a 1. Tedy bit 3 zakazuje (0) nebo povoluje (1) přerušení od vstupu Cx2, bit 4 aktivuje přerušení od sestupné (0) nebo vzestupné (1) hrany.

Pokud je bit 5 = 1, tak můžeme buď přímo ovládat úroveň na tomto výstupu (pokud je bit 4 = 1, tak na výstup Cx2 je zapsána hodnota z bitu 3), nebo nastavit Cx2 jako strobovací signál (bit 4 = 0).

Strobovací mód je asi nejsložitější, navíc se liší u portu A a portu B.

U portu A funguje jako příznak „procesor přečetl data“. Jakmile přečte data z registru PORTA, nastaví se při sestupné hraně vstupu E pin CA2 do log. 0. Zpátky do log. 1 je nastaven podle toho, co je v bitu 3 řídicího registru CRA. Pokud 0, čeká se na aktivní přechod na vstupu CA1 (který přechod je aktivní určuje bit 1 řídicího registru). Pokud je tam 1, čeká se na první sestupnou hranu signálu E.

U portu B funguje jako příznak „data připravena ke čtení“. Jakmile procesor zapíše data do registru PORTB, nastaví se při následující vzestupné hraně vstupu E pin CB2 do log. 0. Zpátky do log. 1 je nastaven podle toho, co je v bitu 3 řídicího registru CRB. Pokud 0, čeká se na aktivní přechod na vstupu CB1. Pokud je tam 1, čeká se na první vzestupnou hranu signálu E.

Já jsem si udělal malý modul, který obsahuje pouze tento obvod a pinové lišty. Pomocí switche přepínám mezi adresami IO1 – IO7. Tento obvod lze docela dobře připojit ke všem dosud probíraným konstrukcím. Doporučuju variantu 68B21, která zvládá vyšší rychlosti (verze 6821 do 1 MHz, 68A21 do 1,5 MHz, 68B21 do 2 MHz).

Díky tomuto modulu tak získávám velmi užitečné rozhraní, na které mohu pohlížet i jako na 16 konfigurovatelných vývodů. Díky nim mohu připojovat moderní periferie s rozhraním SPI (4 vývody) a I2C (3 vývody)…

Moderní periferie (SPI)

Několik jsem jich zmínil v Hradlech, voltech. Spousta dalších je ale použitelná i s „novými starými osmibity“. Jako příklad mě napadá třeba SD karta nebo některé displeje s rozhraním SPI.

Staré osmibity bohužel nemají přímo rozhraní SPI, to vzniklo až mnohem později. Dokonce nejsou ani široce dostupné obvody, které by člověk mohl k těmto procesorům připojit a ony by fungovaly jako řadiče sběrnice SPI.

Existuje řešení, implementované v obvodech CPLD (Xilinx XC9532 apod.), popřípadě přímo obvodově, pomocí posuvných registrů a čítačů. Výhodou takového řešení je vysoká přenosová rychlost, klidně i vyšší, než je pracovní rychlost procesoru.

Jednodušší řešení nechává většinu námahy na procesoru a programátorovi. Nejčastěji se použije paralelní port, buď PPI 8255, nebo PIA/VIA, popsané v minulé kapitole, a jeho piny se využijí na vstup a výstup dat. U PIA/VIA je to o něco snazší, u 8255 musíme myslet na to, že jako vstup či výstup může být nastavena vždy celá brána A, B, případně polovina brány C.

Potřebné průběhy signálů pak musíte generovat programem, a to včetně hodinových pulsů SCK. Není to nijak složité, jen to zabere nějaký čas a paměťový prostor.

Zkusím hrubý odhad: na vyslání jednoho bitu bude u procesoru 6809 potřeba cca 16 – 20 taktů hodin. Je potřeba nejprve připravit datový bit a hodinový puls do registru, jeho obsah poslat do PIA, negovat bit s hodinami, opět poslat obsah do PIA a rotovat data. Vyslání jednoho bajtu tak bude trvat 128 – 160 taktů. Počítejme 150. Teoreticky tedy stihneme za jednu sekundu poslat 12 kilobajtů. Čtení bude ještě o něco pomalejší.

Pokud by rozhraní SPI běželo na kmitočtu, rovném hodinovému, stihli byste za sekundu poslat 225 kilobajtů. Je to málo? Je to moc? Pokud budete přes SPI připojovat třeba externí paměť, tak asi není problém počkat pár sekund na načtení celých 32 kB do paměti RAM. Pokud ale zvažujete připojit přes SPI například displej, tak na nějaké akční divoké hrátky s obrazem spíš zapomeňte – nebo sáhněte po obvodovém řešení.