Abstrakt

Krom řečí o CCD detektorech se zde prezentuje alternativní ovladač CCD kamer SBIG, včetně některých detailů jeho realizace. Člověka neastronomického asi nejvíce zaujme část s popisem soft-realtime řešení driveru. Člověka - astronoma tady nezaujme nic. Někoho, kdo chce zdrojáky k SBIG kamerám pak zmínka, že skutečně existují.

Úvod

URVC je program určený na ovládání astronomických CCD detektorů firmy SBIG. Současné provedení poskytuje uživateli jednoduchou příkazovou řádku, předpokládám však další postup, který bude spočívat v umožnění standardního knihovního přístupu k funkcím, případně řešení ve formě jaderného ovladače, které by eliminovalo nutnost rootích práv.

URVC vychází z existující knihovny pardrv, která není open source a volně šiřitelná je pouze její zkompilovaná (neslinkrovaná) knihovna pardrv.a. URVC sice doposud nedosahuje kompletní funkčnosti pardrv, její nesrovnatelnou výhodou je ovšem dostupnost zdrojových textů a možnost přizpůsobovat kód v případě potřeby.

Cílovým přístrojem programu je robotický teleskop BART v Ondřejově.

Motivace

Původní motivací pro celou práci bylo umožnit implementaci driveru v jednočipovém mikropočítači a umožnit přenos dat od teleskopu do počítače po médiu, které nemá drastickou nevýhodu paralelního portu v totálním zahlcení počítače I/O operacemi paralelního portu, které zahltí stejně starou pomalou 286 jako poslední model Pentia šest. V úvahu padá buďto USB nebo ethernet. Existuje sice možnost připojit kameru k dedikovanému (starému) počítači, ale to neumožní vytoužené omezení množství datových kabelů vedoucích na tubus z 50 na 4. (tak to asi dopadne)

Licence

URVC vzniklo zpětným inženýrstvím z pardrv, které je pod licencí SBIGu. Vzniklo proto, že SBIG odmítl vydat specifikaci svého protokolu na paralelním portu. Technologie je patentovaná. Přestože tedy URVC existuje, nikdo ho asi nesmí používat. Ze stejného důvodu nesmí nejspíš nikdo číst tento text.



Obrázek 1: CCD kamera SBIG

CCD detektor

Astronomické CCD kamery od SBIGu jsou opravdu pěkné věcičky, schopnostmi zdaleka předčí nejen obvykle dostupné vebové kamerky, ale i nejeden digitální fotoaparát. Čeho se u nich ovšem člověk nedočká je barevná detekce. Rozlišení největší kamery je 2184x1472, tj. 3M pixely (jak počítají rozlišení komerčníci). Rozměry ostatních verzí jsou v tabulce:


typrozlišenívyčtení
st7768x51213s
st81532x102450s
st9512x5129s
st102184x1472100s
st10011024x102435s

Tabulka 1: Rozlišení různých detektorů SBIG.

Pro astronomy velmi podstatnou záležitostí je 16 bitová digitalizace obrazu. Pro srovnání - digitální fotoaparáty používají obvykle 8 bitovou, vebkamerky většinou 5 bitovou digitalizaci. 16 bitová digitalizace s co nejmenším šumem a co nejlepší linearitou je důležitá na přesná fotometrická měření, která by s osmibitovou digitalizací prakticky neměla smysl. Daní za přesný a lineární převod je pomalá digitalizace, obraz z st9 se zdigitalizuje a vyčte za 9 sekund. Provozní rychlost A/D převodníku je 30kHz.

Nepoužívá se antiblooming, který je na fotografických čipech proto, aby odvodný kanál mezi pixely odvedl přebytečné elektrony z přeexponovaných pixelů, které by jinak přetekly do pixelů sousedních a zničily fotografii. Odvodný kanál totiž jednak přímo zmenšuje vlastní aktivní plochu pixelu asi o čtvrtinu, jednak se odtokový kanál neaktivuje až když je potřeba - funguje pořád a odvádí nějaké elektrony i z nepřeexponovaných pixelů - z plnějších víc než z prázdných - a výsledkem je krom ještě menší účinnosti navíc nelinearita detekce. V poslední době se navíc v některých případech před pixely instaluje matice mikročoček, která směruje světlo z celé plochy čipu na jeho aktivní část.

Nepoužívají se matice barevných filtrů před pixely k dozažení barevnosti snímku. Astronomové dosahují barevné detekce (nezbytné při redukci dat) pomocí předsazených filtrů.

Paralelní port

Podpora zařízení připojených na paralelní port v Linuxu, kde jsem ovladač začal programovat, je dosti rozsáhlá. Umožňuje v userspacu používat zařízení používat tiskárny a jiná zařízení v režimech IEEE1284. Podle schopností použitého portu je možné použít všech definovaných režimů (SPP, EPP, ECP).

Kamery SBIG nepoužívají IEEE protokolů. Protokol kamer se podobá standardnímu nibble modu (např. paralelní laplink), ale je optimalizovaná na rychlost vyčítání u starých počítačů. Informace směrem ke kameře se posílají po 8 datových pinech paralelního portu. Zpět se posílají po stavových linkách tiskárny. Optimalizace spočívá v hardwarové negaci bitů tak, aby nebylo nutné na přijímající straně provádět XOR přijatých 4 bitů - stačí jen potřebný bitový posun.

Protože je protokol nestandardní a protože je zapotřebí prioritního přístupu na port, nepoužívá se ovladač jádra, ale přímý přístup na I/O linky PC.

Přístup na I/O porty

Linux netrpí svým programům, aby přistupovaly na I/O linky PC. Při troše snahy se nám sice může podařit do programu zakompilovat instrukce IN a OUT:

#include <sys/io.h>

outb(baseAddress, value);
value = inb(baseaddress + 1) >> 3;

inb a outb jsou makra definovaná v uvedeném souboru. V ukázce jsou v nejobvyklejší používané podobě. Makra sama ovšem stojí za pokochání:

static __inline unsigned char
inb (unsigned short int port)
{
	unsigned char _v;

	__asm__ __volatile__ ("inb %w1,%0":"=a" (_v):"Nd" (port));
	return _v;
}

jedno určitě stačí. Umožní nám poměrně snadno dopsat další potřebné makro - zákaz a povolení přerušení. Opět jen poloviční ukázka:

static __inline void disable()
{
	__asm__ __volatile__("cli");
}

problém nastane až v okamžiku, kdy se program při svém běhu na nějaké takové místo dostane: Linux ho samozřejmě okamžitě odstřelí. :) Aby to neudělal, je potřeba mu to vysvětlit. To se dá udělat dvěma podobnými způsobyr.

Jednoduchým způsobem je volání

ioperm(from_port, num, turn_on);

která umožní procesu pristupovat na _num_ IO linek od portu from_port. Turn_on rovno jedné povolení zapne, nule vypne. Pomocí tohoto volání lze přistupovat jen na porty 0 - 3ffh a neumožňuje povolit zákaz přerušení. Jelikož byla předmětem řešení také PCI deska s paralelními porty na adresách mimo tento rozsah, používá nakonec URVC volání iopl(), které navíc procesu umožní zakázat přerušení

if(iopl(3) < 0)
{
	perror("iopl(3)");
	exit(1);
}

iopl() dovolí procesu přistupovat na IO porty v celém rozsahu 65536 portů bez nutnosti specifikovat rozsah.

Problémem při vyčítání kamery je nutnost zajistit, aby se digitalizovaná řádka vyčetla najednou. Kamera nemá buffer, takže je zapotřebí zajistit spojitý tok dat přes paralelní port do paměti počítače. K tomu potřebujeme provést ještě dvě akce: nastavit si nenulovou statickou prioritu a zamknout si paměť proti swapování.

Statická priorita je záležitost, která se týká jen real-time programů, všechny normální programy mají statickou prioritu nulovou a pracují s prioritou dynamickou (nice). Statickou prioritu můžeme nastavit takto:

struct sched_param s;
s.sched_priority = 0x32;

if(sched_setscheduler(0, SCHED_FIFO, &s) < 0)
{
perror("sched_setscheduler(0, FIFO, &(..0x32..) )");
exit(1);
}

Abychom zamezili prodlevám způsobeným načítáním kusu naší paměti ze swapu, musíme si ji zamknout voláním funkce mlock(). V následujícím útržku programu si paměť zamykáme všechnu přes mlockall().

if(mlockall(1) < 0)
{
perror("mlockall(1)");
exit(1);
}

Komunikační protokol SBIG

K detektorům SBIG určitě existuje nějaká dokumentace. Já jsem ji nikdy neviděl a proto zde používané termíny mohou být divné, ve knihovnách se ovšem vyskytuje spousta literálů, takže některé názvy budou zřejmě v pořádku.

V dalším můžeme klidně zapomenout na to, že na daném I/O rozsahu visí paralelní port a můžeme předpokládat, že jsou tam za sebou dva registry, kterými se přímo ovládá kamera. (Je to pravda jen "skoro", předtím je potřeba uvést paralelní port do stavu, kdy to tak začne vypadat.)

Všechno nasvědčuje tomu, že kamera má osm čtyřbitových registrů, jejichž obsah se dá přečíst nebo zapsat pomocí adresování horní polovinou datového bajtu paralelního portu. Čtený a zapisovaný port zřejmě nejsou identické. Hodnota posílaná do registru se zapíše do spodních čtyřech bajtů datového portu, hodnota vyčítaná se objeví na stavových linkách portu.

Programátorský model:
base + 0:  write |  reg2 |  reg1 |  reg0 | send3 | send2 | send1 | send0 |
base + 1:  busy  | recv3 | recv2 | recv1 | recv0 |   -   |   -   |   -   |

Chceme-li pak poslat nibble do registru kamery, dáme do reg0-2 číslo registru, do send0-3 posílaná data a na malou chvíli nastavíme bit write na jedničku. Vyčtení registru se dělá tak, že se do reg0-2 napíše registr a ze stavového portu se vyčte jeho hodnota. Hodnota je k dispozici teprve když se vynuluje bit busy. Obvyklý přenos pak vypadá takto:


1počkám, až busy bude nula
2OUT registr << 4 + hodnota
3OUT registr << 4 + hodnota + 0x80
4OUT registr << 4 + hodnota
5počkám, až busy bude nula
6...

Tabulka 2: Posílací cyklus


1počkám, až busy bude nula
2OUT registr << 4
3počkám, až busy bude nula
4IN registr << 4 + hodnota + 0x80
5...

Tabulka 3: Přijímací cyklus

Zde všude znamená OUT výstup na datový port a IN vstup ze stavového portu.

Časování:

Zvláštní pozornost při komunikaci s kamerou si zaslouží realizace časování, tj. správných odstupů řídících impulsů při jejich posílání kameře.

Paralelní port je zařízení překvapivě pomalé. Jeden IN nebo out na paralelní port mi na většině systémů, které se mi dostaly do ruky, trval od 0.6 do 3 mikrosekund. Na standardním PC paralelním portu trval skoro vždycky kolem 1.3 us. Při takhle dlouhé instrukci (cca 86 taktů 486/66) lze dosahovat řádově mikrosekundových pulsů sekvencemi OUTů. To je poměrně sympatické, ale pro extrémně dlouhé nebo extrémně krátké OUTy některých počítačů jsem sekvence musl upravit. (Já upravil sekvenci, kdežto originální sw od SBIGu prostě přestal fungovat joj!). U velmi pomalých I/O operací byl problém dosáhnout rychlosti A/D převodu 30kHz, tj. 120 000 půlbajtů za vteřinu.

Mikropříkazy:

Výše zmíněný "hloupý" způsob komunikace s kamerou je omezen jen na časově kritické úkoly a několik speciálních akcí. Ostatní diplomacie se řeší přes tzv. mikropříkazy. Mikropříkazy představují komunikaci na vyšší úrovni. Umožňují zadat kameře příkaz včetně parametrů a umožňují získání různých návratových hodnot. Známe dohromady 13 různých mikropříkazů, jeden má dvě modifikace, architektura umožňuje 16. Mikropříkaz je sekvence nibblů s následující obecnou strukturou:

0xA | 0x5 | kod prikazu | delka | data...

A5h je hlavička příkazu a je vždycky stejná. Kódy příkazů jsou v tabulce a délka je počet následujících _bajtů_ dat, tedy počet půlbajtů lomeno dvěma.


kódbajtů tambajtů zpětsmysl
08-začátek expozice
12-konec expozice
26/6-regulace chlazení (2 varianty)
3-10status chlazení
410-relé (pointace teleskopu)
510-pulz (ovládání periferií)
6-4vrať verzi
742/-ovládání EEPROM (r/w)
82-různé (LEDka, větrák, závěrka)
9-4status
a4-test systému
b2-2552přenos bajtů
c4-CCD control

Tabulka 4: Mikropříkazy

Detaily o posílání mikropříkazů, případně o digitalizaci obrazu viz. zdrojáky nebo tento dokument časem.