Volendo realizzare un'interfaccia verso un sensore d’immagine CMOS le architetture digitali tra le quali operare una scelta sono principalmente due. La prima è basata su ASIC o logiche programmabili, nella seconda invece ci si affida a microcontrollori dotati di un'interfaccia in grado di gestire direttamente il sensore, ossia in grado di catturare il frame (il contenuto informativo alla base dell’immagine) proveniente da questo, realizzando così quella operazione che genericamente viene chiamata “frame grabbing”.
L’interfaccia digitale dei sensori CMOS
I sensori d’immagine CMOS solitamente hanno un interfaccia digitale basata su due canali di comunicazione, attraverso il primo canale è possibile accedere ai registri inter ni del sensore per la programmazione dei vari parametri come il formato dell’immagine, il tempo di esposizione e così via. A tal fine è solitamente presente un interfaccia seriale di tipo I2C o SPI. Attraverso il secondo canale di comunicazione che è unidirezionale transitano le informazioni sul frame in uscita dal sensore. Tale interfaccia è standardizzata da due normative la ITU-R BT.601 e la ITU-R BT.656, la prima definisce i parametri del trasferimento dei frame definendo la codifica del frame e dei segnali di sincronismo, la seconda definisce l’interfaccia fisica vera e propria del flusso dei dati necessaria per implementare un trasferimento come definito nella ITUR BT.601 dividendo il frame in zone e introducendo una codifica in banda dei segnali di sincronismo. La maggior parte dei sensori CMOS rispettano i segnali di sincronismo come definiti nelle normative e riportati nella figura 1.
L’interfaccia dei dati è solitamente di tipo parallela a 8 o 10 bit poiché permette di massimizzare il troughput a parità di clock. Ad ogni fronte di salita del segnale di clock viene campionato un byte che rientra nel contenuto attivo dell’immagine se sono attivi sia il sincronismo verticale (VSYNC o FRAME VALID) sia il sincronismo orizzontale o di riga (HSYNC o LINE VALID). Il sincronismo verticale definisce l’inizio del frame, poiché non tutti i pixel sono utili a ricostruire l’immagine il segnale di sincronismo orizzontale diventa attivo solamente in corrispondenza del contenuto utile. Un generico frame è rappresentato in figura 2.
Il flusso dei pixel provenienti dal sensore viene genericamente chiamato “read out” e solamente una parte di tale contenuto informativo viene identificato come valido per ottenere l’immagine. Come detto in precedenza la normativa ITU-R BT.656 introduce anche una codifica in banda dei segnali di sincronismo, in particolare alcuni valori di pixel sono dedicati a segnalare la zona utile compresa tra il pixel di SAV (Starting of Active Video) e quello di EAV (end of Active Video). Questo meccanismo permette di realizzare una semplice interfaccia priva di segnali aggiuntivi oltre ai dati di pixel e al clock.
Codifica dei dati
Una volta identificati i pixel utili è importante sapere con che codifica sono for niti, a tal fine gli standard sono molteplici. Per i sensori a colori il più diffuso sicuramente è quello abitualmente chiamato RGB Raw, infatti i fotorivelatori del sensore sono filtrati rispetto ai fotoni che li colpiscono con il famigerato “Bayer Patter n”. La prima riga utile di pixel per un sensore con flusso di dati in formato RGB raw è composta solamente dai pixel blu e verdi alternati, la seconda da quelli versi e rossi come rappresentato in figura 3.
Il risultato del “read out” è:
B(1,1), G(1,2), B(1,3), G(1,4)…G(1,x), G(2,1), R(2,2), G(2,3), R(2,4)…
I sensori con logica a bordo possono anche modificare il readout in modo progressivo:
B(1,1), G(1,2), R(2,2), G(2,1), B(1,3), G(1,4), R(2,4), G(2,3),…
Altri formati tipici sono lo YUV o YCbCr, la cosa importante e che il dispositivo pronto a ricevere i dati li interpreti in maniera corretta, se quindi c’è un microcontrollore che comunica direttamente con il sensore è necessario trovare una modalità di scambio dei dati gestita da entrambi.
Le proposte del mercato
Sul mercato tutte le più importanti case costruttrici di microcontrollori propongono almeno una soluzione in grado di interfacciarsi direttamente ad un sensore CMOS. Tra le soluzioni più comunemente adottate sicuramente è da segnalare la proposta Marvell che con i processori PXA270 e PXA320 offre una serie di soluzioni scalabili e in grado, in base alle esigenze dell’applicazione, di pilotare anche display LCD, lavorare con memorie DDR, e raggiungere frequenze di core elevatissime. Una soluzione ai problemi di gestione diretta del sensore CMOS molto utilizzata e affermata da anni è quella proposta da Freescale con la serie di Microcontrollori i.MX. Questa famiglia partita dall’ormai datato i.MXL (ma ancora ottimo per applicazioni cost-sensitive) si è sviluppata con i microcontrollori i.MX1, i.MX21, i.MX27 e l’ultimo nato i.MX31 che consente di effettuare una compressione MPG4 in formato VGA a ben 30 frame al secondo. Una delle soluzioni più economiche ma comunque performanti disponibili sul mercato è la serie di processori Blackfin di Analog Devices partendo dall’ADSP BF522 fino al BF527 questa famiglia di DSP integra una interfaccia parallela generica chiamata PPI che oltre a convertitori A/D e D/A può dialogare con periferiche video compatibili con la ITU-R-601/656, come può essere un sensore CMOS. La soluzione ottimale per chi ha bisogno di capacità di calcolo elevate abbinate alla gestione del sensore CMOS ed alla necessita di elaborazioni tipiche dei DSP è sicuramente la famiglia Da Vinci di Texas Instruments già un processore come TMS320DM642 è sufficiente per qualsiasi applicazione in più grazie alla modalità “raw capture mode” la porta video di questo DSP può interfacciarsi a praticamente tutte le tipologie di sensore lasciando le operazioni di conversione di formato, codifica e compressione al software. Grazie al notevole numero di MIPS che può vantare questo processore anche le operazioni più complesse come la rotazione dell’immagine o la compressione possono essere realizzate in tempi brevissimi, molto dipende anche dalla conoscenza approfondita di sensore e DSP che permette di ottenere un buon codice e soprattutto veloce. Anche Atmel propone una recente serie di processori AT91SAM9 con core ARM 9 e dotatai di una periferica integrata chiamata ISI (Imaging Sensor Interface), in grado di gestire un sensore fino a 4 megapixel con dati a 8 bit per sensori a colori e fino a 12 bit per sensori monocromatici permettendo di ottenere una preview dell’immagine grazie a meccanismi di ridimensionamento e una conversione automatica dai formati YCrCb e YUV verso il formato RGB gestito dagli LCD.
Cattura di un immagine con i.MX21
Per meglio comprendere come gestire l’interfaccia tra sensore CMOS e microprocessore analizziamo la “CMOS Sensor Interface” o più brevemente CSI con cui Freescale equipaggia la sua serie i.MX.
CMOS Sensor interface ovvero CSI
Analizziamo più in dettaglio l’MC9328MX21 chiamato per semplicità i.MX21 o anche solo MX21. La CSI dell’MX21 supporta tutti i tipi di sensori CMOS in grado di scambiare i dati in formato YUV, RGB, o se condo il Bayer format, viene supportato lo standard ITU-R BT.656, in più si ha la possibilità di abilitare un calcolo delle statistiche per generare un algoritmo che consenta l’autoesposizione e il bilanciamento dei bianchi necessari se l’applicazione richiede immagini di ottima qualità. Una caratteristica molto utile dell’MX21 e la possibilità di sfruttare sia il DMA per lo spostamento dei dati in memoria, ma anche la eMMA (enhanced Multimedia Accelerator) che consente di effettuare video codifica, decodifica, preprocessazione (conversione di formato e image scaling) e post-processazione (conversione di formato, ridimensionamento, Deblock e Dering). La eMMA è in grado di dialogare direttamente con la CSI senza l’intervento della CPU, tutto ciò consente di gestire quelle applicazioni, specialmente nei dispositivi portatili, che per la codifica video altrimenti richiederebbero un elevato numero di MIPS per il processore. Esiste infatti un bus privato che collega la CSI è e la PRP (ossia il blocco della eMMA che esegue la preprocessazione dei dati) configurato per uno scambio dei dati secondo gli standard YUV422 e RGB565, infatti la PRP ha due canali d’uscita uno in formato RGB565 per l’interfaccia LCD e uno in formato YUV422 destinato alla codifica MPEG e JPEG. La CSI supporta immagini ad una risoluzione massima di 2560x1920 pixel, mentre la PRP è limitata a 2048x2048 pixel.
Hardware configuration e data path
In figura 4 è schematizzato il tipico collegamento tra l’i.MX21 e un sensore CMOS dove si può osservare che la CSI viene coinvolta nel trasferimento dei dati, l’interfaccia I2C è utilizzata per la configurazione del sensore e un paio di GPIO sono utilizzati per il controllo dei segnali supplementari.
Al fine del corretto interfacciamento gli accorgimenti più importanti da osservare sono relativi al fatto che il clock di sistema per la CSI che viene chiamato HCLK per essere in grado di lavorare con un clock in arrivo dal sensore chiamato PIXCLK asincrono, deve essere almeno pari o superiore a due volte quest’ultimo. Solitamente è lo stesso sensore che richiede un segnale di clock (MCLK) in ingresso e lo divide per ottenere il segnale di PIXCLK in uscita. Prendiamo in considerazione tre diversi tipi di applicazione:
» Visualizzazione su LCD
» Cattura dell’immagine
» Registrazione video
Per ognuna di queste applicazioni consideriamo il percorso che seguono i dati (data path). Nel caso di visualizzazione su LCD L’immagine è prelevata dal sensore attraverso la CSI e passata al LCD buffer per la visualizzazione, come in figura 5.
Nel caso non sia necessario nessuna operazione il percorso dei dati e quello evidenziato in rosso, se invece è necessario un ridimensionamento dell’immagine per la visualizzazione (nella maggioranza dei casi) allora il percorso dei dati è evidenziato in blu. Se poi il sensore non è in grado di interfacciarsi direttamente con la PRP perché per esempio ha un formato d’uscita RGB raw allora è necessario seguire il percorso verde dove interviene il software per realizzare la processazione del colore. Nel processo di cattura dell’immagine ogni frame del sensore viene catturato e utilizzato per ottimizzare tempo di esposizione e guadagno, ottenendo alla fine un immagine di alta qualità adatta per essere convertita nel formato JPEG. Come visibile in figura 6 in questa applicazione si possono sfruttare entrambi i canali della PRP, uno per la visualizzazione su LCD e uno per la compressione JPEG, il percorso dei dati rosso è quello dedicato ai sensori intelligenti con un output adeguato alla PRP, quello blu è necessario per gli altri.
Per una applicazione che richiede invece la creazione di un video il percorso dei dati è schematizzato in figura 7.
La PRP permette di realizzare un codifica MPEG4 adatta alla memorizzazione su disco o allo streaming e allo stesso tempo attraverso il secondo canale la visualizzazione su LCD. Come in precedenza il percorso blu è quello dedicato ai dati provenienti da sensori intelligenti, quello rosso per gli altri.
Software design
In precedenza abbiamo visto come in base al tipo di sensore, intelligente o no, cambia il trattamento dei dati contenuti nella CSI FIFO e ottenuti dal sensore. I sensori definiti non intelligenti poiché non hanno un output direttamente compatibile con la PRP devono necessariamente essere gestiti attraverso DMA. In questo modo i dati dalla CSI FIFO passano nella memoria principale per poter essere elaborati via software. Se invece si utilizzano sensori compatibili, dal punto di vista del formato dati, con la PRP il meccanismo è molto più semplice e i dati sono trasferiti attraverso un bus privato dalla CSI FIFO alla eMMA-PRP, una volta attivato questo bus lavora in autonomia senza l’intervento del DMA e senza la necessita degli interrupt della CSI. Supponiamo allora di avere dal sensore una immagine con risoluzione VGA in formato RGB565 e in uscita dalla CSI un immagine VGA sempre in formato RGB565. Tale flusso di dati arriva alla PRP che usa il primo canale per generare un immagine in QVGA (sempre in formato RGB656 adatto al display LCD) e il secondo canale per un immagine sempre QVGA ma in formato YUV420 per una compressione JPEG. Nel listato 1 è riportato il software necessario per l’inizializzazione della CSI.
//CSI module init *(uint32_t *)GPIOB_GIUS &= ~0x3FFC00;//disable GPIO PB[21..10] *(uint32_t *)CRM_PCCR0 |= 0x80000000;//HCLK clock enable *(uint32_t *) CSI_CSICR1 = 0x0;//register clear *(uint32_t *) CSI_CSICR1 |= 0x0200;//MCLK = HCLK / 2 //timing control *(uint32_t *) CSI_CSICR1 |= 0x20000;//SOF rising edge *(uint32_t *) CSI_CSICR1 |= 0x10000;//SOF INT enable *(uint32_t *) CSI_CSICR1 |= 0x2;//latch on rising edge *(uint32_t *) CSI_CSICR1 |= 0x10;//gated clock mode *(uint32_t *) CSI_CSICR1 |= 0x800;//hsync active high //FIFO control *(uint32_t *) CSI_CSICR1 |= 0x100;//sync FIFO clear *(uint32_t *) CSI_CSICR1 |= 0x100000;//RXFF level = 16 //data manipulation *(uint32_t *) CSI_CSICR1 |= 0x80000000;//swap16 enable *(uint32_t *) CSI_CSICR1 |= 0x80;//big endian //PRP i/f control *(uint32_t *) CSI_CSICR1 |= 0x10000000;//PRP i/f enable
Listato 1 |
Dopo la CSI è necessario configurare anche la PRP (listato 2).
//PRP Module init *(uint32_t *)CRM_PCCR0 |= 0x8008000;//Clock enable for PRP *(uint32_t *)EMMA_PRP_CNTL |= 0x10000;//PRP reset //common control *(uint32_t *)EMMA_PRP_CNTL = 0x0008F24E;//LOOP mode //matrix B0 (YUV2RGB),matrix B0 (RGB2YUV) //RGB565 => RGB565 (ch1), YUV420 (ch2) //CSI i/f enable //ch1, ch2 enable *(uint32_t *)EMMA_PRP_CNTL |= 0x8000000;//bug fix *(uint32_t *)EMMA_PRP_RSIZE_CTRL = 0x40;//MAIN resize=2:1,CSC resize = 1:1 *(uint32_t *)EMMA_PRP_INTRCTRL = 0x00000000;//disable interrupt //source control //*(uint32_t *)EMMA_PRP_SY_PTR;//source ptr : NOT used with CSI *(uint32_t *)EMMA_PRP_SPIX_FMT = 0x2CA00565;//RGB565 input *(uint32_t *)EMMA_PRP_SFRM_SIZE = 0x028001E0;//source = 640 x 480 //*(uint32_t *)EMMA_PRP_SLIN_STRID;//source line stride : NOT used with CSI //ch1 (RGB) dest control *(uint32_t *)EMMA_PRP_DRGB1_PTR = rgb;//output buf1 *(uint32_t *)EMMA_PRP_DRGB2_PTR = rgb;//output buf2 *(uint32_t *)EMMA_PRP_DISIZE_CH1 = 0x00F000F0;//dest size = 240 x 240 *(uint32_t *)EMMA_PRP_DPIX_FMT = 0x2CA00565;//RGB565 output *(uint32_t *)EMMA_PRP_DLST_CH1 = 0x000001E0;//dest line stride = 240 //ch2 (YUV) dest control *(uint32_t *)EMMA_PRP_DY_PTR = y;//output buf1 *(uint32_t *)EMMA_PRP_DCB_PTR = u; *(uint32_t *)EMMA_PRP_DCR_PTR = v; *(uint32_t *)EMMA_PRP_SY_PTR = y;//output buf2 (re-used in LOOP mode) *(uint32_t *)EMMA_PRP_SCB_PTR = u; *(uint32_t *)EMMA_PRP_SCR_PTR = v; *(uint32_t *)EMMA_PRP_DISIZE_CH2 = 0x000000F0;//dest image height = 240 *(uint32_t *)EMMA_PRP_CNTL |= 0x1;//PRP enable
Listato 2 |
Dopo queste semplici inizializzazioni le immagini arriveranno alla PRP in maniera continua e senza l’utilizzo di risorse della CPU cosa che rappresenta sicuramente il vantaggio più grande di questa architettura.