Nyt se on kaikki tehty. Koko alkuperäisen ohjauspurkin voisi periaatteessa heivata pois ja laittaa tilalle jotain modernimpaa. Tietysti tyylikkäintä olisi löytää puskuriylivuoto alkuperäisohjelmasta ja ohjata näyttöä sen kautta, mutta tehokkainta devausnopeuden, näyttönopeuden ja virrankulutuksen kannalta lie työntää joku arduino, raaka avr tms. mikrokontrolleri ohjaamaan graffaa ihan vaan sarjaportin tai usbin yli. Pikseleiden muodot, fontti, väylän bittiformaatti ja kaikki siinä välillä on käytännössä täysin reverse-engineerattu. Tutkittiin ensin softaa ja sitten verifioitiin taas puretun raudan äärellä Helsinki Hacklabilla. Suomeksi: näytön ruuduille saa mielivaltaista omaa grafiikkaa nopeasti.
Fonttikartta löytyi selvästi epromin loppuosasta, jokaisen kasibittisen merkin glyyfille on 24 tavua ja niitä luetaan koodissa 16 bitin sanoina. ASCII on kokonaan esitetty normaalisti alemmissa 7 bitissä, ja ylemmässä puolessa (128..255) on lähinnä ääkköset ja metrovaunujen symbolit, muuten tyhjää. Fonteissa on vähän metadataa glyyfin reunan välin koosta sekä siitä, mitkä glyyfin sarakkeet voi jättää tulostamatta - jokainen on esitetty viisi saraketta leveänä, ja tarpeen vaatiessa niitä voi vähän tiivistää.
Glyyfien bitit ovat siinä järjestyksessä, missä ne menevät emulaattoritutkimisten perusteella väylälle. Kahden ensimmäisen metadatatavun jälkeen tulee ylä- ja alapuoli siten, että sanan 12 ja 11 alinta bittiä ovat ne yhden sarakkeen grafiikkabitit suoraan. Grafikka voidaan siis purkaa ulos ja sen voi näyttää sillä samalla ohjelmalla kuin millä itse väylälle lähtevän datan saa emulaattoribiteistä parsittua kuvaksi. Metadatabittejä täytyy tutkia vielä hetki, että logiikka selviää täysin.
Emulaattorin i/o-tulostetta koodin parissa tarkastellen saatiin hypoteesi sille, mitä varsinaisella lcd-moduuleille menevällä lattakaapeliväylällä oikeastaan tapahtuu. Kyllä se prossu tekee kaiken osoitteistuksenkin databittien vetkutuksen lisäksi. Mitä koodissa tapahtuu missäkin:
sijainti | portti | data | kuvaus |
---|---|---|---|
4036 | 0x43 | 0x01 | Yläpuoliskon kellon nouseva reuna |
4040 | 0x43 | 0x00 | Yläpuoliskon kellon laskeva reuna |
4047 | 0x43 | 0x02 | Alapuoliskon kellon nouseva reuna |
4051 | 0x43 | 0x00 | Alapuoliskon kellon laskeva reuna |
405b | 0x42 | 0x00 | Nollatäytedataa yläpuoliskolle |
4070 | 0x42 | 0x00 | Nollatäytedataa alapuoliskolle |
408a | 0x42 | 0x0[01] | Yläpuoliskon ekat 8 databittiä |
409b | 0x42 | 0x0[01] | Yläpuoliskon seuraavat 4 databittiä |
40b4 | 0x42 | 0x0[01] | Alapuoliskon ekat 8 databittiä |
40c5 | 0x42 | 0x0[01] | Alapuoliskon seuraavat 3 databittiä |
40e8 | 0x43 | 0x0[04] | Puolen valinta |
40f6 | 0x42 | 0x0[248] | Rivin valinta |
4102 | 0x42 | 0x00 | Lopetus |
Tiedetään, että I/O-avaruus menee seuraavasti:
muistiosoite | piiri | portti | kuvaus |
---|---|---|---|
0x10 | uart1 | data | modeemiuartin dataportti |
0x11 | uart1 | ctrl | modeemiuartin konffausportti (7-E-1, baudrate 600bps) |
0x20 | uart2 | data | liittimestä ulos lähtevän rs232:n uartin dataportti (kuulutuskoneoptio?) |
0x21 | uart2 | ctrl | liittimestä ulos lähtevän rs232:n uartin konffausportti (8-N-1, baudrate 9600bps) |
0x30 | 8255 | PA | 8255 eli µPD8255 eli GPIO-expanderi, portti A, nastat 4-1, 40-37 |
0x31 | 8255 | PB | 8255:n portti B, nastat 18-25 |
0x32 | 8255 | PC | 8255:n portti C, nastat 14-17, 13-10 |
0x33 | 8255 | mode | PA out, PB out, PC in |
0x40 | 8155 | mode | 8155 eli µPD8155 eli 256B RAM + GPIO + ajastimia, PA in, PB out, PC out |
0x41 | 8155 | PA | 8155:n portti A, nastat 21-28 |
0x42 | 8155 | PB | 8155:n portti B, nastat 29-26 |
0x43 | 8155 | PC | 8155:n portti C, nastat 37-39, 1-2, 5 |
0x44 | 8155 | timerhi | ajastimen ylätavu |
0x45 | 8155 | timerlo | ajastimen alatavu |
Kaiken LCD:n liikenteen hoitaa 8155. Sitten vielä laitteet ja kytkentäkaaviot syliin ja pöydälle ja nähdään selvästi, että pinout menee näin (bitit lasketaan nollasta lähtien, pinnit ykkösestä):
muisti | bitti | portti | 8155-pin | lcd-pin | kuvaus |
---|---|---|---|---|---|
0x42 | 0 | PB0 | 29 | 2 | data |
0x42 | 1 | PB1 | 30 | 11 | rivi 1 |
0x42 | 2 | PB2 | 31 | 12 | rivi 2 |
0x42 | 3 | PB3 | 32 | 13 | rivi 3 |
0x43 | 0 | PC0 | 37 | 9 | yläpuolen kello |
0x43 | 1 | PC1 | 38 | 10 | alapuolen kello |
0x43 | 2 | PC2 | 39 | 19 | puolen valinta |
Superselvyydeksi vielä ohjainlaatikosta lähtevän näyttöväylän nastat kuten skemakuvassa: (nämä ovat vielä bufferipiirin 74HC245 takana; gpio-piiri ei aja näitä suoraan, ja lisäksi etu- ja takapuolen kaapelit ovat 1:1 rinnakkain)
pin | kuvaus |
---|---|
1 | maa |
2 | data |
3 | +5 V |
4 | +5 V |
5 | +7 V |
6 | maa |
7 | reset |
8 | 5 V 75 hertsin virkistyskello |
9 | yläpuolen datan kello |
10 | alapuolen datan kello |
11 | rivin 1 valinta (yläriviltä neljä ruutua) |
12 | rivin 2 valinta (alariviltä neljä ruutua) |
13 | rivin 3 valinta (reunimmaiset kaksi päällekkäistä ruutua) |
14 | ei käytössä |
15 | ei käytössä |
16 | ei käytössä |
17 | ei käytössä |
18 | ei käytössä |
19 | puolen valinta |
20 | maa |
Raaka LCD-väylä lähtee yhdeltä jakajapiiriltä per rivi, ja ketjuttuu eri moduulien läpi. Sen pinout on seuraavanlainen yläpuolille ("oben"), alapuolten ("unten") nastat käänteisessä järjestyksessä. Lisäksi skemakuvassa lienee bugi datanastan suhteen, mutta oletettavasti homma menee näin:
pin | kuvaus |
---|---|
1 | +5 V |
2 | data |
3 | maa |
4 | +7 V |
5 | 5 V 75 Hz |
6 | reset |
7 | datakello |
8 | latch |
9 | maa |
10 | +5 V |
Seitsemän volttia lienee jokin itse lcd:n tarvitsema höpöjännite, ehkä kontrasti tms. kun sitä ei suoraan tule itse virtalähteeltä; ehkä se generoidaan vain jollain vastusjakajalla (eikä siihen siis menisi juuri mitään virtaa). Viittä volttia käyttävät myös haaroitinlevyjen logiikat (bufferipiiri ja nand, nämä skemakuvassa). Tuo 75 hertsiä (kanttiaaltoa viidellä voltilla, 4020-laskuripiiriltä) on ilmeisesti jokin lcd-tekniikan vaatima ajojännitteen modulointi, ne kun ilmeisesti kärsivät jos samaa polariteettia antaa jatkuvasti (wikipediasta: "Both the liquid crystal material and the alignment layer material contain ionic compounds. If an electric field of one particular polarity is applied for a long period of time, this ionic material is attracted to the surfaces and degrades the device performance. This is avoided either by applying an alternating current or by reversing the polarity of the electric field as the device is addressed (the response of the liquid crystal layer is identical, regardless of the polarity of the applied field).")
Nastat 11-18 menevät riviohjainmoduulien piikkirimaan (merkitty "Zeile"), josta valitaan jumpperilla rivinumero. Kun rivejä on vain kolme, niin 14-18 ovat turhia. Nasta 19 menee jumpperille (merkitty "Seite"), joka valitsee puolen ("etu" tai "taka", riippuu kummalta puolelta katsoo...) - tämä nasta on siis aina ylhäällä tai alhaalla, ja jompikumpi puoli reagoi aina. Rivinumerovalinta on samalla latch-bitti; ruudut tuplapuskuroivat luetun datan, ja näyttävät kaiken kerralla sitten, kun rivibittiin tulee pulssi.
Väylän bittiformaatti tarkasti selviää edelleen emulaattorin tulosteita ja koodia tutkimalla. Pienimmät mahdolliset viiveet nastavetkutuksien välillä selviävät kokeellisesti; tuo ohjelma ei välttämättä aja ruutua ihan täysillä. Ja näyttöhän oli jaettu kahtia ylä- ja alapuoliskoon; yläosassa 12 monikulmiota ja alaosassa 11. Datanastan konffaamisen jälkeen kellonastaan tökätään pulssi.
Yläpuoliskon tulostus: Seuraava toistettuna 16 kertaa: (16 * 6 = 96 = 4 * 24, neljä paneelia ja 24 saraketta kussakin)
- 4 x 1 bit padding (nollaa)
- 6 x 12 bit sarakkeen yläpuoliskoa
- 4 x 1 bit padding (nollaa jälleen)
Alapuoliskon tulostus: Seuraava toistettuna neljästi (4 * 24 = 96)
- 36 x 1 bit padding
- 4 x 11 bit sarakkeen alapuoliskoa
- 5 x 1 bit padding
- 10 x 11 bit sarakkeen alapuoliskoa
- 10 x 1 bit padding
- 10 x 11 bit sarakkeen alapuoliskoa
- 5 x 1 bit padding
Lopuksi latchataan data näkyville valitsemalla puoli ja rivi seite- ja zeile-biteillä, pitämällä zeileä päällä hetken verran. Reunasarakkeelle homma menee vastaavasti, mutta piirtelylooppia toistetaan puolet määrästä (eli kahdeksan kertaa yläpuoliskolle ja kaksi alapuoliskolle). Ja yläpuoliskon bitithän syötetään "väärinpäin" eli lopusta alkuun.
Nyt kun kaikki on selvää, niin eiköhän omaa ohjaussoftaa ja fonttiparseri sekä parempi tekstipiirturiemulaattori.
- fontdecode.py: dekoodaa aiemmin luetusta binääristä (program.bin) fontteja samanlaisiksi databiteiksi kuin väylällä, tästä näkee myös eksaktisti tuon datan rakenteen
- printline_decoder.py emuloi vehkeen näyttöä, eli piirtää pikseleitä niin tarkasti kuin kännykamerakuvista sai mitattua. Pystyrivien välejä ja erillisten lcd-moduulien välissä olevia tyhjiä tiloja ei emuloida.
- printline.c on avr-prossulle C:llä kirjoitettu proof-of-concept, joka tuuppaa väylälle bittiä ennalta määrätystä staattisesta kuvasta.
- printline_to_header.py koodaa yhden rivin C-headeriksi printline.c:tä varten.
Tästä jatketaan sitten puuhaamalla esim. teensylle usbiin menevä proxyttäjä väylälle ja kirjoittamalla pc-puolelle graffasoftaa mappaamaan kuvatiedostot pikseleiksi höpösti supersamplaamalla. Ja tietysti pitäisi alkaa pohtimaan, millä ihmeen ilveellä tuollaisen 80 kg monoliitin kiinnittää yhtään mihinkään muualle kuin keskelle lattiaa. Ai niin, omissa näytöissä lukee vain AEG mutta hacklabin näytön nurkassa on teksti Adtranz eli joku vanha saksalainen junalaitevalmistaja, sieltä ovat ilmeisesti peräisin.
Laitoin softat kerrankin ihan githubiin nyt kun on projekti jota varmaan tulevat tunkkaamaan muutkin kuin minä itse.
0 kommenttia
Oma kommenttisi
Mielipide tämän sivun asiasta? Kirjoita toki. Älä raapusta kuitenkaan ihan asiattomia juttuja.
Jos on yksityisempää asiaa, tarkkaa kysyttävää tai aihetta pidemmälle keskustelulle, käytä yhteydenottolomaketta kommentoinnin sijaan.
Hölmöt kommentit saatetaan moderoida pois jälkikäteen.