Chi ha iniziato a passare da baseline e Midrange agli Enhanced Midrange si
probabilmente trovato perplesso davanti alla funzione PPS di
rilocazione delle funzioni sui pin.
Qui alcune pagine per chiarire il problema.
Pochi pin e molte funzioni.
Una delle principali sfide dei dispositivi generici è fornire la più ampia gamma possibile di periferiche, il che crea inevitabilmente un certo numero di conflitti sulle assegnazioni dei pin, cosa particolarmente
sentita nei componenti
che ne hanno un numero limitato.
Chi ha familiarità con la linea di prodotti PIC24, ha già conoscenza della funzione
PPS: in questi PIC le periferiche non sono collegate per impostazione predefinita ad un determinato pin. I segnali di input e output periferici devono essere selezionati prima che la periferica sia abilitata. Questo consente la massima flessibilità
nell'impiego delle periferiche rispetto al rapporto con i pin. Gli utenti di questi chip hanno, dunque, l'abitudine di configurare
l'assegnazione dei pin ad una periferica integrata prima di utilizzarla.
Nei PIC a 8 bit, invece, si è abituati ad una relazione fissa tra pin e funzioni
applicabili.
Se prendiamo, ad esempio, il noto 16F688, ci troviamo con questa tabella che relazione le funzioni integrate e i pin disponibili:
Possiamo distinguere 2 classi di rapporti tra pin e funzioni integrate:
- funzioni la cui scelta è obbligatoria nella configurazione iniziale. A questo gruppo
appartengono MCLR, CLKOUT, CLKIN e programmazione LVP
Queste funzioni devono essere definite prima dell'avvio del programma e sono impostabili solo
durante la programmazione del chip
- funzioni "normali", che possiamo chiamare non
rimappabili. Queste funzioni sono associate ad un determinato pin,
multiplexate assieme ad altre funzioni. Ad esempio l'uscita dell'USART TX
è disponibile al pin RC4 e T1G al pin RA4, ecc.
Vediamo qui che non è possibile usare contemporaneamente l'uscita TX dell'USART assieme a
quella del comparatore 2 (C2OUT), dato che entrambe confluiscono sul pin RC4; lo stesso per il pin RA2, che supporta sia C1OUT che
T0CKI, oltre a AN2 e a INT.
In casi come questo l'utente che deve impiegare due periferiche che confluisco
nello stesso pin ha come unica alternativa quella di una riprogettazione completa scegliendo un diverso chip, tipicamente con un numero maggiore di
pin. Inoltre, l'attribuzione fissa funzione-pin fa si che occorra una certa cura nella progettazione dell'hardware e del circuito
stampato.
Assai più drammatica risulta la situazione dei recenti Enhanced Midrange: in
questi chip troviamo integrato un numero veramente elevato di periferiche, anche
per i classici packages a 8/14/18 pin.
Ad esempio, il 16F15313 (che, nonostante il nome, è un 8 pin), contiene un numero impressionante di periferiche
E' evidente che, potendo utilizzare una sola funzione per pin,
ci saranno certamente situazioni in cui un rapporto fisso tra pin e periferica
impedirebbe l'uso di un piccolo package.
E' stato chiaro ai progettisti che una relazione fissa tra pin e funzioni avrebbe reso i chip a basso numero di pin
inutilizzabili per molte applicazioni.
Quindi, anche per gli 8 bit, è sorta l'idea di aggiungere alle possibili opzioni del chip anche quella permettere all'utente di determinare
quale sarà il rapporto tra pin e funzioni, rendendone disponibili il massimo possibile in relazione al numero dei pin.
Questo può essere estremamente utile non solo per avere disponibili più periferiche una volta avrebbero richiesto lo stesso pin,
ma anche per i circuiti di routing: Vi sono casi in cui un cambio di posizione I/O può rendere più facile il routing di un circuito stampato; oppure, dove si sia fatto un errore di connessione oppure
all'ultimo momento sia necessaria una variazione delle risorse
L'avere la possibilità di modificare una mappatura dei pin in software piuttosto che creare un nuovo circuito stampato può essere molto
utile.
Peripheral Pin Select
Peripheral Pin Select (PPS) è l'opzione che consente la mappatura flessibile dei pin I/O periferici digitali su una vasta gamma di pin esterni.
Se nei vecchi dispositivi a 8 bit una periferica era cablata su un pin specifico (esempio: uscita PWM1 sul pin RC5), ora, attraverso
il PPS lo sviluppatore può scegliere i pin di output e di input per connettersi alla periferica.
Gli utenti, agendo da programma su alcuni registri, possono mappare in modo indipendente l'ingresso e/o l'uscita di un certo numero di
periferiche digitali su una qualsiasi delle opzioni dei pin I/O. La selezione viene eseguita nel software e non come
configurazione iniziale.
Ne deriva che la ri configurazione dei pin non richiede la ri programmazione del dispositivo, mentre consente
anche una variazione dinamica durante
l'esecuzione del programma, dove questo sia possibile. In questa direzione, viene inclusa una protezione hardware che impedisce una errata
ri assegnazione della periferica.
La selezione dei pin periferici viene utilizzata con una certo numero di
funzioni che dipendono dal particolare dispositivo e dal numero di pin.
Le periferiche gestite dalla periferica pin select sono tutte e solo periferiche
digitali e comprendono le comunicazioni seriali UART e SPI, gli ingressi di temporizzazione per uso generale,
periferiche relative al timer (cattura e confronto tra ingressi e uscite) e ingressi di interrupt esterni.
Sono escluse dalla selezione PPS le periferiche analogiche (ingressi modulo
ADC, uscita DAC, ingressi compratori, ecc.)..
Va osservato che anche alcuni moduli periferici solo digitali non sono attualmente inclusi nella
funzione di selezione dei pin; questo è dovuto al fatto che la funzione di periferica richiede circuiti I/O speciali per un dispositivo
specifico e questo non può essere facilmente collegato a più pin. Questi moduli includono
funzioni che hanno livelli diversi dallo
standard TTL, come comunicazioni speciali (Ethernet, I2C e USB).
Nota: va ben precisata una cosa fondamentale. PPS NON rende
disponibili TUTTE le funzioni integrate; questo è, in ogni caso,
impossibile, dato il numero limitato di pin.
PPS, invece, consente di collegare un pin piuttosto che un altro ad una
determinata funzione. Così, nel caso esemplificato prima del 16F688, se
necessito di usare sia USART che uscita del comparatore 2, con le assegnazioni
fisse che multiplexano sullo stesso pin, non lo posso fare. Però, se potessi
indirizzare C2OUT o TX su un pin diverso, ecco che la mia applicazione che
richiede USART e comparatore potrebbe trovare posto anche in questo chip.
Perplessità
L'allocazione dei pin negli Enhanced Midrange può creare una notevole perplessità a chi affronta per la prima volta i chip dotati di
PPS: proveniendo da chip privi di questa funzione, si stenta a capire come accedere, per esempio
all'USART o alle uscite PWM, che, nella mappa degli I/O non appaiono associati
ad alcun pin.
Prendiamo, ad esempio il 16F1574/5. Si tratta di chip a 14 pin con un numero elevato di
periferiche ed osserviamo la tabella di allocazione dei pin:
Nella tabella troviamo che l'uscita del DAC è accessibile su RA0, in
alternativa ad AN0 o C1IN+, oppure che AN4 è alternativa a C2IN+ su RC0, ma
se vogliamo utilizzare le uscite PWM o l'USART o le uscite di CWG e dei
comparatori, ci accorgiamo che NESSUNO dei pin è specificato per queste funzioni.
Dunque PWM1OUT o TX non hanno un pin di uscita?
Per venire a capo della situazione occorre considerare le note 1/2/3 riportate
alla base
della tabella. Troviamo così che le classi dei rapporti tra pin e funzione
sono diventate 4:
- funzioni la cui scelta è obbligatoria nella configurazione iniziale.
A questo gruppo appartengono MCLR, CLKOUT, CLKIN e programmazione LVP
Queste funzioni devono essere definite prima dell'avvio del programma e sono impostabili solo durante la programmazione del chip.
Niente di diverso dai PIC 8 bit più datati.
- funzioni non rimappabili. Queste funzioni sono associate ad un determinato pin (ad esempio
AN7 e C13-/C2IN3- sono alternative sul pin RC3 e AN4 e C2IN+ al pin
RC0). Siamo sempre in situazione analoga ai chip più datati.
- funzioni riposizionabili, indicate dalla nota 1. Qui entriamo
nell'ambito del PPS. Si tratta di
una serie di funzioni che sono, per default, collegate ad uno specifico
pin, ma con la modalità PPS possono essere riposizionate su un altro pin
(qui, ad esempio, CK, RX. T1G, ecc.)
- funzioni completamente rimappabili, indicate dalla nota 3. Si
tratta di una serie di funzioni che NON sono, per default, collegate ad
uno specifico pin, anzi, non sono collegate ad alcun pin, ma con la modalità PPS devono essere assegnate ad uno
dei pin (qui, si tratta essenzialmente delle uscite dei PWM, dell'USART
dei comparatori e del CWG).
.La differenza fondamentale tra periferica rimappabile e non rimappabile è
proprio questa:
- le periferiche non rimappabili sono sempre disponibili solo su un pin
predefinito, supponendo che la periferica sia attiva e
non in conflitto con un'altra periferica
- le rimappabili NON sono associate a un pin I/O
predefinito.
Ovvero, al default, nessuno dei pin è multiplexato con queste funzioni.
Se la periferica deve essere usata, è obbligatorio assegnarla ad un pin I/O specifico prima di poterla utilizzare.
APFCON vs. PPS
Si potrà obbiettare che, già da tempo, erano disponibili chip con la possibilità di rilocare alcune funzioni attraverso un registro
AFPCON.
Questo è il caso, ad esempio, di 16F1503, nella cui mappa degli I/O troviamo alcune funzioni
rilocabili:
La nota 1 identifica le funzioni che possono essere spostate su un diverso
pin.
Esiste una decisa differenza tra le periferiche riassegnabili gestite con APFCON e quelle rilocabili con
PPS:
- le periferiche gestibili con APFCON hanno una assegnazione di
default e quindi possono essere usate "immediatamente". Però,
nel caso di conflitti con un altra funzione multiplexata sullo stesso
pin, questa può venire riassegnata ad un altro pin specifico
- le periferiche rimappabili, per contro, NON hanno alcuna assegnazione di default: per essere usate, devono essere sempre assegnate ad un
pin, che può essere scelto fra molti disponibili con i registri PPS.
Ad esempio, se prendiamo la funzione SDO nel 16F1503, per default essa è attribuita a RC2. Se necessita
ridirezionarla, il bit 5 di APFCON ne consente lo spostamento su RA4.
Nel caso di 16F1574, l'uscita TX dell'USART, al default, NON è collegata a nessun pin! Se desidero utilizzare la funzione,
occorre agire su registro RyxPPS che permette di assegnarla ad uno qualsiasi dei pin disponibili.
I registri PPS
La funzione PPS è gestita da registri PPS.
PPS è configurato in modo diverso per l'ingresso e l'uscita dei segnali.
- Segnali di ingresso: I segnali di ingresso sono configurati
attraverso registri xxxPPS dove xxx va sostituito con la label della
funzione interessata. La porta deve essere configurata come ingresso utilizzando il registro TRIS associato.
- Segnali di uscita: I segnali di uscita sono controllati da
registri di selezione RxyPPS, dove Rxy va sostituito con la label del pin corrispondente per la selezione di uscita.
Il contenuto dei registri, una volta modifcato dal programma, resta immutato anche dopo un reset e si
cancella solamente al mancare dell'alimentazione, dato che è scritto in
memoria volatile.
Quindi è necessario che nell'inizializzazione del chip, nelle prime fasi dell'esecuzione del programma, si inserisca la
gestione corretta del PPS.
In generale abbiamo:
- un registro PPSLOCK che abilita/disabilita la funzione PPS. Si trova nel banco 28
- n registri xxxPPS (ad esempio T0CKIPPS, RXPPSS, ecc.). Si trovano nel banco 28
- n registri RxyPPS (ad esempio RA0PPS, RC4PPS, ecc.) per la gestione delle uscite. Si trovano nel banco 29.
Ad esempio:
16F1574/5 |
16F1704/8 |
|
|
Da notare che chip con un diverso numero di pin e di periferiche avranno una
cosnistenza diversa per i registri
PPS, ma comunque conforme a quanto indicato.
Selezione degli ingressi.
Ogni periferica che può essere riorganizzata con il PPS ha un registro per selezionare il pin di
ingresso da collegare alla circuiteria di ingresso. Il nome del registro avrà il nome della periferica seguito dalle lettere
PPS.
Avremo così un registro INTPPS per la funzione INT, un registro T0CKIPPS per
la funzione T0CKI e così via.
Prendiamo ad esempio il registro xxxPPS del 16F1708:
Ricordiamo ancora che esistono n registri xxxPPS per quante sono le
funzioni rilocabili, dove xxx indica il nome della funzione interessata.
Tutti questi registri sono composti allo stesso modo. Contengono 5
bit attivi, cambiando i quali si seleziona uno dei pin disponibili a cui sarà
collegata la funzione.
Vogliamo, ad esempio, collegare la funzione RX dell'USART al
pin RB4. La linea di comando da inserire nel sorgente XC8 sarà:
RXPPSbits.RXPPS = 0x0C // RB4
-> EUSART1:RX1
Nel caso dell' Assembly:
banksel RXPPS
movlw 0x0C
movwf RXPPS
Se vogliamo, ad esempio, collegare la funzione INT al pin RA3,
la linea di comando da inserire nel sorgente XC8 sarà:
INTPPSbits.INTPPS = 0x03 // RA3
-> INT
Nel caso dell' Assembly:
banksel INTPPS
movlw 0x03
movwf INTPPS
Per default al POR, questi registri di ingresso hanno un
contenuto specifico che dipende dalla periferica. Questo fa si che
all'accensione ci sia pre determinato un rapporto pin/funzione.
Ad esempio, il registro INTPPS, relativo alla funzione INT, in 16F1708 può
assumere le seguenti configurazioni:
Al POR il contenuto del registro è 0x02, ovvero INT è
connesso a RA2. Se si desidera collegarlo ad un altro pin, occorrerà
scriverne il valore corrispondente nel registro INTPPS. Così, se lo voglio
connettere a RA3 occorrerà scrivere 0x03 in INTPPS.
Selezione delle uscite.
Ogni uscita digitale periferica può essere collegata ad un pin I/O selezionato attraverso il
PPS.
Questo viene fatto in modo simile alla selezione degli ingressi, con la
caratteristica che la selezione della connessione di uscita è opposta alla selezione degli ingressi. Invece di nominare il registro con
il nome della periferica seguito da PPS, il pin di uscita è il nome seguito da
PPS. Così il pin RB0 avrà un registro RB0PPS per selezionare la sua
connessione, il pin RC4 avrà un RC4PPS e così via.
Anche qui ci sono cinque bit utilizzati per scegliere la connessione. Questi cinque bit selezionano
l'uscita periferica a cui sarà collegato il pin.
Vediamo la struttura dei registri di uscita, sempre con
riferimento al 16F1708:
Vogliamo, ad esempio, collegare l'uscita TX dell'USART al pin
RA0. La linea di comando da inserire nel sorgente XC8 sarà:
RA0PPSbits.RA0PPS = 0x14 //
EUSART1:TX1 -> RA0
Nel caso dell' Assembly:
banksel RA0PPS
movlw 0x14
movwf RA0PPS
Se vogliamo, ad esempio, collegare l'uscita CLC1OUT al pin
RA5, la linea di comando da inserire nel sorgente XC8 sarà:
CLC1PPSbits.CLC1PPS = 0x04 //
RA5 -> CLC1OUT
Nel caso dell' Assembly:
banksel CLC1PPS
movlw 0x04
movwf CLC1PPS
Per default al POR, questi registri di uscita hanno un
contenuto tipicamente 0. Questo fa si che all'accensione ci sia pre
determinato un rapporto pin/funzione e che questa sia la funzione generica di
GPIO (LATxy).
PPS Lock
Il PPS include una modalità in cui tutte le selezioni di ingresso e uscita possono essere bloccate per evitare modifiche involontarie.
Le selezioni PPS sono bloccate portando a 1 il bit PPSLOCKED del registro
PPSLOCK, che contiene solo questo bit.
L'impostazione e la cancellazione di questo bit richiede una sequenza speciale,
simile a quella di scrittura della EEPROM, come ulteriore precauzione contro modifiche involontarie.
bcf INTCON,
GIE ; Disabilita le interruzioni (se attive)
banksel PPSLOCK ;
movlw 55h
; Sequenza chiave
movwf PPSLOCK ; 4 istruzioni successive
movlw AAh
movwf PPSLOCK
bsf PPSLOCK, 0 ; PPSLOCK = 1
bsf INTCON, GIE ; riattivare le interruzioni
(se necessario)
Da notare che la sequenza chiave deve essere eseguita come indicato, senza
interruzioni, ovvero, se l'interrupt è attivato, va disattivato durante la
sequenza. In caso contrario la sequenza non ha effetto.
Se si desidera sbloccare l'accesso ai registri PPS, occorre portare a 0 il
bit PPSLOCK con la stessa procedura riattivare il bit
Un esempio in XC8 di azione sui registri PPS con sblocco e blocco:
GIE =
0
// stop interrupt
PPSLOCK =
0x55 //
security key
PPSLOCK = 0xAA
PPSLOCK =
00
// unlock PPS
RA1PPSbits.RA1PPS = 0x0E // RA1->PWM3OUT
PPSLOCK =
0x55 //
security key
PPSLOCK = 0xAA
PPSLOCK =
01
// lock PPS
GIE =
1
// enable interrupt
Per default il PPSLOCK è bloccato ed occorre la sequenza di sblocco
indicata. Terminata la programmazione dei bit PPS è quanto mai opportuno
eseguire il blocco del PPSLOCK per evitare qualsiasi problema dovuto ad errate
scritture dell'area PPS.
In questa direzione, se è possibile una ri mappatura dinamica del rapporto
pin/funzione, solitamente questa possibilità è abbastanza remota. Piuttosto,
il procedere ordinario, richiederà la mappatura delle funzioni una volta sola
all'inizio del programma, dopo l'arrivo dell'alimentazione.
Va in tal senso una opzione nella configurazione iniziale che permette di
bloccare il PPS in modo permanentemente. Si tratta del bit di configurazione
PPS1WAY.
Quando questo bit è posto a 1, il bit PPSLOCKED può essere cancellato e impostato solo una volta
dopo il POR del dispositivo. Questo permette che le selezioni degli ingressi e delle uscite possano essere effettuate durante
l'inizializzazione. Infatti, quando il bit PPSLOCKED è portato a 1 dopo che tutte le selezioni sono state
effettuate, esso
rimarrà a 1 e non potrà essere cancellato fino al successivo evento di POR del dispositivo.
Se il bit PPS1WAY è a zero, il controllo di sblocco e blocco dei PPS è
sempre possibile rispettando la sequenza di accesso indicata prima.
Per questo motivo si raccomanda che tutte le selezioni dei registri PPS siano posizionate vicino alla parte
iniziale del codice in modo che l'I/O sia impostato correttamente subito dopo il reset.
Modalità Sleep
Durante la modalità Sleep le selezioni di ingresso e uscita PPS non sono influenzate. Di conseguenza, l'entrata in modalità sleep e il ritorno dallo sleep lasceranno in posizione tutte le selezioni di connessione.
Reset
Quando l'alimentazione del dispositivo è sospesa, quanto programmato nella
configurazione iniziale resta fissato, dato che viene scritto nell'area Flash
non volatile. Potrà essere cambiata solo con una riprogrammazione.
Però, tutte le selezioni di ingresso e di uscita del PPS sono scritte in
memoria volatile e vengono riportate ai valori di default e questo richiede di
agire da programma con una opportuna inizializzazione.
Per contro,tutti gli altri tipi di reset
diversi dal POR lasciano invariate le
selezioni PPS.
Configuratore del codice MPLAB
Il configuratore di codice MPLAB® Code Configurator (MCC) rende la creazione del codice PPS abbastanza semplice.
Esso genera in uscita un codice in formato MPLAB® XC8 che corrisponde alle
istruzioni necessarie per la configurazione richiesta e che sarà inserito nel
sorgente.
MPLAB® Code Configurator fa parte dei tool gratuiti che possono
essere installati in MPLAB-X ed è scaricabile e installabile
direttamente dal pannello di controllo di MPLAB..
Su Youtube è disponibile un video tutorial sull'uso del PPS (in inglese)
per le MCU a 8 bit:
http://www.youtube.com/watch?v=tf2SfSm6fQg
|