GPIO – I2C – SPI – miniUART
La RPi offre sui connettori P1 e P5 (quest’ultimo solo nella RPi revisione 2) 8 GPIO, oltre alle interfacce: 2xI2C, 1xSPI e 1xUART. Le porte logiche sono realizzate in tecnologia CMOS, per cui i livelli di tensione sono compresi tra 0-3.3v. Le porte seriali a disposizione su questi connettori sono illustrate nella figura soprastante.
Osservazioni:
- la porta mini UART non è implementata con tutte le funzionalità di una UART (non è compatibile con IC 16650) ma permette di effettuare una semplice comunicazione a ridotta velocità di trasmissione. Questo significa che può essere usata come interfaccia di comunicazione seriale senza avvalersi delle seguenti features: Break detection, Framing errors detection, Parity bit, Receive Time-out interrupt, DCD, DSR, DTR or RI signals. Il consiglio di Broadcom di usarla ad una velocità ridotta non è relativo le sue capacità, visto che può raggiungere i 32Mbaud, ma all’elevata richiesta di risorse fatta alla CPU. In RPi di default, la porta UART, virtualizzata come dispositivo ttyAMA0, è usata come console di input/login; questa caratteristica deve essere disabilitata se si vuole usare questa porta per un’altro scopo. Per disabilitarla occorre: a) commentare nel file /etc/inittab la seguente linea che configura la porta: #T0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100; b) togliere nel file /boot/cmdline.txt i riferimento a ttyAMA0 (ad esempio sostituendo questa stringa con tty1
), c) fare reboot.
- Con RPi Revision 2 è stata introdotta una seconda porta I2C, presente sul connettore P5 oltre a quella già presente sul connettore P1. Le porte i2c su P5 e P1 sono distinguibili rispettivamente come I2C0 e I2C1 e accessibili come /dev/i2c-0 /dev/i2c-1 .
- L’interfaccia SPI è fisicamente una ma i pin SPI0 CE0 and CE1 possono venire usare come pin di selezione (Chip Enable) tra due SPI differenti. Per abilitare la porta SPI è possibile seguire i passi descritti in questo link. Una volta eseguita la configurazione, tali porte saranno accessibili come dispotiviti /dev/spidev0,1 e /dev/spidev1.1.
- Le interfacce SPI e I2C sono disabilitate di default. Per abilitarle seguire questa procedura: a) commentare le righe blacklist spi-bcm2708 e blacklist i2c-bcm2708 in /etc/modprobe.d/raspi-blacklist.conf; b) aggiungere la riga i2c-dev in /etc/modules; c) installare i2c-tools; d) aggiungere un nuvo utente al gruppo i2c: sudo adduser pi i2c; reboot.
La gestione di queste interfacce di comunicazione è semplificata dalla possibilità di usare la libreria WiringPi. E’ importante notare che questa libreria non segue la mappatura originale delle porte del microprocessore. Questa è la mappatura usata da WiringPi. Ad esempio, se si vuole accendere un led presente sul pin 26 di P1, si nota che nei documenti ufficiali di RPi viene mappato come GPIO7, mentre su WiringPi come GPIO11.
Per usare le librerie WiringPi, ad esempio in un programma C, è sufficiente includere nei sorgenti: #include <wiringPi.h>. Invece nel makefile le librerie possono essere linkate con: -I/usr/local/include -L/usr/local/lib -lwiringPi. All’interno del codice l’inizializzazione della libreria avviene eseguendo la funzione:
- wiringPiSetup()
Per gestire i GPIO ci sono a disposizione diverse funzioni. Per esempio, per settare il pin 26 di P1 a valore logico alto, si possono usare le seguenti funzioni:
- pinMode(OUTPUT, 11)
- digitalWrite(11, 1)
La libreria permette inoltre di pilotare un LCD, hd44780u compatibile, sia a 4 che a 8 linee dati, includendo nei sorgenti: #include <lcd.h>. L’inizializzazione del display avviene attraverso una funzione in cui vanno specificati i pin usati nell’interfacciamento e la modalità di uso del display:
- int lcdInit (int rows, int cols, int bits, int rs, int strb, int d0, int d1, int d2, int d3, int d4, int d5, int d6, int d7)
Nel caso si usi un LCD che mette su D4-D7 le linee dati quando viene usato a 4 linee, questi pin andranno messi in corrispondenza di d0-d3. Esistono poi molte funzioni per la gestione come quella per pulire lo schermo, posizionarsi sul primo carattere e scrivere un carattere:
- lcdClear (int handle)
- lcdHome (int handle)
- lcdPutchar (int handle, uint8_t data)
Per avere a disposizione delle funzioni di accesso al bus i2c, la libreria potrà essere usata includendo nei sorgenti: #include <wiringPiI2C.h>. Saranno così disponibili diverse funzioni, come ad esempio le seguenti per la lettura e la scrittura:
- int wiringPiI2CRead (int fd)
- int wiringPiI2CSetup (int devId)
In alternativa è possibile installare anche altre librerie di supporto al bus i2c (sudo apt-get install libi2c-dev). All’interno dei sorgenti C è possibile includerle scrivendo: #include <linux/i2c-dev.h>. L’accesso avviene con le funzioni che operano sui file. Ad esempio per configurare aprire, leggere e scrivere sulla porta i2c0 si possono usare queste funzioni:
- int fd = open(“/dev/i2c-0”, O_RDWR)
- ioctl(fd, I2C_SLAVE, i2caddr)
- i2c_smbus_read_byte_data(file, subreg)
- i2c_smbus_write_byte_data(file, subreg, data)
Per lavorare sulla porta SPI alcuni sorgenti per il test possono essere trovati qui.
Riportiamo alcuni esempi che mostrano come usare le utility disponibili da riga di comando per testare queste porte. Anche le utility, ad esempio ‘gpio’, seguono il mapping usato da WiringPi. Nel caso invece si interagisca direttamente con il sistema operativo, è necessario selezionare direttamente il GPIO relativo al microprocessore. Per comprendere le corrispondenze dei GPIO è importante porre attenzione alla versione della scheda di cui si è in possesso: R1 (Revision 1) o R2 (Revision 2).
GPIO. Per pilotare il livello di tensione del pin 26 di P1 in uscita ad 1 (livello TTL), si deve prima configurare il pin e poi settarne il valore:
- gpio mode 11 out
- gpio write 11 1
Se invece si decidesse di non usare queste utility, sarebbe necessario accedere direttamente all’uso di syscall:
- echo 7 > /sys/class/gpio/export
- echo out > /sys/class/gpio/gpio7/direction
- echo 1 > /sys/class/gpio/gpio7/value
I2C. E’ possibile accedere ai dispositivi i2c attraverso l’utility i2ctool. Per interrogare un dispositivo su i2c, ad esempio collegato su i2c1 (header P1), e richiedergli il suo indirizzo è possibile usare (nella RPi Revisione 2):
- i2cdetect -y 1
Per visualizzare quale dispositivi i2c sono visibili dalla distribuzione si può digitare:
- ls -l /dev/*i2c*
Nella nostra piattaforma abbiamo scelto di interfacciare il sensore inerziale via I2C. I dati dell’accelerometro e del magnetometro possono essere letti ai due seguenti indirizzi: 0011001b. e 00111100b.
La console di debug viene fornita attraverso UART mentre l’LCD è stato interfacciato a 4 linee dati + CS + RS relative a generici GPIO. La porta SPI non è stata usata perchè i suoi GPIO vengono sfruttati per collegare pulsanti e led di stato.
Ad uno specifico GPIO è stata collegata una linea verso un transistor NMOS che temporizza l’accensione dell’illuminatore IR unicamente nella fase di acquisizione dell’immagine (strobo) o lo spegne quando non viene usato. Acquisendo frames a 5fps, questo introduce un notevole risparmio di energia della batteria.
ETHERNET
La configurazione della scheda di rete, in modalità statica, può essere fatta andando a scrivere nel file /etc/network/interface questa configurazione:
auto lo
iface lo inet loopback
iface eth0 inet static
address 192.168.1.1 // n.b. possono essere inseriti valori a piacere
mask 255.255.255.0
gateway 192.168.0.254
Una volta scritta questa configurazione è necessario fermare e riavviare l’interfaccia di rete:
- ifdown eth0
- ifup eth0