i2c használata, i2c-parport-light, hogy működik ez

Azért tettem ide ezt a kérdést, mert a "lavinát" az indította el, hogy clockolt soros kommunikációs modult/device -t kellene írnom.
Első lépésben a parallel portot használtam - egyenlőre csak az órajel előállítására koncentrálok, legfőképp a sebesség miatt.
Eszembe jutott, hogy az i2c (de az spi is) hasonlóan egy clockolt soros kommunikáció, amihez vannak kész driverek - nyílt forráskóddal :)
Addig eljutottam, hogy beemeltem az i2c_parport_light modult, de nem tudom "szóra bírni". Device node nem jelenik meg (vagy nem találom). Ráadásul, a forrásból ítélve ahhoz, hogy ez működjön kell az i2c_core és talán más "i2c" modul is (pl. i2c_algo_bit).
Hogy lehet a parportra kötött i2c buszt meghívni - írni, olvasni?
Talán az i2c-tools segít?
Aztán van itt valami libi2c-dev "userspace I2C programming library".
Hol kezdjem?

Hozzászólások

Nulladik kerdes: pontosan mit kotnel ossze mivel? Ez nem nagyon vilagos ;)

Parport-ra kotott I22: ez nagyon valoszinutlen hogy menni fog, mert a parport egyszerubb esetben is push-pull kimenetet ad, bonyolultabb esetben (lasd: bidirectional parallel port es tarsai) pedig push-pull+highz uzemmodban tudod hasznalni (es nem is mindegyik bitje't). Az I2C hardveresen viszont n-channel open collector + pull-up modon van bekotve, tehat sima push-pull outputot nem tudsz hasznalni I2C-re.

Ha csatornankent (SDA, SCL) ke't bitet ko"tsz be a parallel porton es egy egyszeru tranzisztor + ellenallas kombinacioval megcsinalod a "PHY"-t, akkor persze lehet jo a dolog, es nagyon realtime vezerles se kell az I2C master-slave jellege miatt. Lasd pl ez. Itt open collectorral megaldott not-kapukat hasznal ellenallas+tranzitsztor helyett (lasd megjegyzes, elso abra alja, 74HC05), lenyegeben ugyanaz. Szoval a sufni verzioban meguszhato 4 ellenallas + 2 NPN tranzisztorral a dolog.

Ha nem I2C-t hasznalsz, hanem mondjuk SPI-t (vagy barmilyen mas USART-ot) akkor persze lehet ra tudod kotni parportra tok egyszeruen a cuccot (lasd pl ez, a pin2, 3, 4 es 14-et hasznalja). Lenyegeben az ellenallasokat is kihagyhatod, bar a \CS-re illik egy felhuzot tenni azert (a tobbire absz nem kell). De ez ma'r erosen fugghet a slave eszkoztol (pl van olyan cucc amit permanensen \CS=0-ra lehet tenni, es viszonylag stabilan mukodik, szoval nem SPI frame-kben hanem folyamatos stream-mel kommunikal).

Visszaterve az I2C-re: a linuxban is meglevo" kernelmodulok dedikalt I2C PHY-re vannak optimalizalva, de persze nyilvan lehet irni bitbang-os modult az altalad keszitett paralell port + tranzisztor + ellenallas megoldasra is.

Lehet hogy nem voltam elég érthető :( Bocsánat.
A hw oldala, illesztés és a többi most majdnem érdektelen.
Az alap problémám az, hogy milyen sebességgel tudok kommunikálni, azaz a parport kimenetén elő kell állítanom a clockot pl. 100 mksec. Valami hasonlót csinál az i2c is így kiinduló pontnak jó lehet.
Most épp hogy "berántottam" a modult - i2c-parport-light (direkt IO port írás) de sem az SDA sem az SDC vonalon nem történik semmi (szkópon figyelem).
A kérdés, hogy lehet ezt a parport -ra írott i2c drivert használni - azaz hogy tudom elérni szoftverből, parancssorból?
Ráadásul, a parport -ra definiált "adaptert" kéne meghívni, nem a gép belső, perifériákat vezérlő, érzékelőket kezelő dolgait (pl. smbus).

* Én egy indián vagyok. Minden indián hazudik.

Az i2c clock az 100khz...400khz kozotti sztenderden, de lehet aka'r lejjebb is menni (lattam mar olyan doksit is ahol 0hz volt a minimum). Az i2c timingja elegge osszetett, hatarozottan komplexebb mint az SPI vagy egy USART. Az SDA e's az SCL is szinkronizalt egymashoz kepest, azaz az SCL nem egy "free running" clock, mint amit a tobbi szinkron kommunikacional megszoktunk.

Szkop: egy i2c-frame azert eleg rovid, me'g 100khz-s clock mellett is, ha nem kap egy ack-ot a master, akkor is lezajlik az egesz 0.1 millisec alatt. Azt latod barmi modon? jol van beallitva a trigger?

Illetve szoftverbol tudod figyelni az i2c layer viselt dolgait. A linuxos interface-kat nem ismerem, de MCU-n eleg sok bitnyi info van arrol hogy az i2c byteframe az jol atment-e (A: ACK, N: NACK, ...), ill a frame kezdest (S: START) es lezarast (P: STOP) is kezzel kell csinalni, konkretan anelkul nem is fog menni ;)

Ha me'g nem dolgoztal I2C-vel egyatalan, akkor lehet erdemesebb ugy kezdened az "ismerkedest", hogy egy kesz hardverrel kommunikalsz. Sok alaplapon vannak szenzorok, azok is i2c-n lognak, es ha tudod mi a szenzor tipusa akkor ma'ris tudsz vele kommunikalni. Pl LM75, LM86, LM92.

Mindemellett tudnal linket kulden iaz i2c-parport-lightrol? enszerintem ottan biztos kell valami kapcsolas is (lasd fentebb, amit irtam).

Annyival kiegészítem, hogy a linken ajánlott kapcsolási rajz nem jó, hiszen az SCL vonalnak is kétirányúnak kell lennie. Lévén, a device - slave - megfoghatja az órajelet, ha úgy óhajtja, pl. mert nem volt még érkezése átvenni az adatot. Ezt a master kontrollernek tudomásul kell vennie. Szóval nem úgy van, hogy a master diktálja az órajelet, a slave-ek meg nyelik az adatot, mint kacsa a nokedlit.

Szerk.: clock stretching

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

"Összefoglalom".
Az i2c csak úgy működik (ad mondjuk clockot) ha van mit adnia (master) és várja a nyugtát, ha az nincs akkor "leáll".
100 Khz - 10 mksec azaz (durván) 100 mksec alatt egy ilyen simán lezajlik.
A sebesség nagyjából stimmel - ez lehet nálam is a felső határ.
Azért jobban bele kell ásnom magam ebbe - lehet az i2c_core driverbe, mivel az i2c_parport_light nem tartalmaz mást mint az init/remove illetve néhány "atomikus" bit set/get rutint. A lényegi munkát a core végzi - ott kell hogy csinálja aclockot. Vajon használ interruptot vagy másképp állítja elő az időzítéseket?

* Én egy indián vagyok. Minden indián hazudik.

Szerintem nem jól foglaltad össze. Vannak keretek, ezek start feltétellel kezdődnek, stop feltétellel végződnek, bár lehet újabb start is. Aztán elmegy a cím, meg az, hogy írás vagy olvasás lesz. Adat csak az órajel alacsony szintje mellet változhat, hiszen, ha magas szintje mellett változna, az épp a start illetve stop feltétel.

Amikor a kereten belül elment egy byte, visszafelé jön ack vagy nack. Miután a címrész tartalmazza az adatirányt, kereten belül nem tudod azt megfordítani, azaz egy keretben vagy írsz, vagy olvasol. Az órajelet a slave megfoghatja, így a buszon addig nincs kommunikáció, amíg el nem engedi azt.

A kommunikációt a master kezdeményezi, tehát lényegében pollingolni tudja a slave-eket. Nyilván pl. megszakítást kérhet a slave egyéb vonalon, aminek hatására a master megkérdezi a slave-től, hogy ugyan már, mi bajod, miért zargatsz engem, a mastert.

Hevenyészetten, vázlatosan ennyi a lényeg. Aztán, hogy milyen réteget húzol i2c fölé, te dolgod, de lassúsága okán ez inkább arra való, hogy néhány byte-ot átadjunk vagy átvegyünk, pl. egy szenzortól. Tehát nem igazán kilobyte-ok átvitelére alkalmas valami.

Szerk.: amikor nincs mondanivaló, a vonalak magas szintűek.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

A lényegi munkát a core végzi - ott kell hogy csinálja aclockot. Vajon használ interruptot vagy másképp állítja elő az időzítéseket?

Szerintem valami általános kernel timer rutint használ (és akkor most várjunk 10us-ot), amit jó eséllyel a timer interrupt bh-ból hív vissza.

Azt is látni kell, hogy pl. az i2c-nél a master esetén nincs alapból felső korlátja a várakozásoknak, azaz a sebességre van felső korlát, ami minimum várakozási időket jelent, de lassaban szabad léptetni az órajelet (sőt, akár menet közben, bitenként, dinamikusan is lehet variálni). Nyilván ha irreálisan hosszú időre (pl. másodpercekig) megakad a tranzakció, akkor előfordulhat, hogy valamelyik device beépített védelme törli a maga részéről a tranzakciót, és már nem tudod befejezni az adatátvitelt.