Sistemi multi - Master: bus collision e bus
arbitration.
I2C supporta la modalità multi-Master, la quale richiede la possibilità
di arbitraggio del bus, nel caso in cui due Master cerchino di accedere
contemporaneamente, creando una situazione di collisone sul bus.
In modalità multi-Master, la generazione di interrupt al rilevamento di condizioni di
Start e Stop consente la
determinazione dello stato del bus. Il controllo del bus può essere preso il bit
P
di SSPSTAT è a 1 oppure il bus è inattivo (idle) e i bit S e
P sono a zero.
Verificando, come peraltro consigliato da Microchip, che S e P
siano a zero, il bus è considerabile idle.
Questo, però, non toglie che, per circostanze fortuite, si verifichi
contemporaneamente da parte di un altro Master un tentativo di presa di
possesso del bus.
In questo caso si verifica una collisone sul bus al momento in cui i due
Master cercheranno di forzare una linea a livelli opposti.
Trattandosi di un bus
open collector, non sussiste alcun rischio di sovra correnti per i
dispositivi collegati, ma i dati trasmessi da uno dei due dispositivi sono
corroti. E' necessario che, quindi, un Master abbandoni il bus.
Ancora una volta, il rilevamento della situazione è automatizzato dal
modulo MSSP, che attiva un flag di collisione BCLIF, il quale,
tra l' altro, è sorgente di interrupt.
Al presentarsi della situazione anomala, il programma di gestione, avvertito
dal flag, dovrà intervenire con una procedura di arbitraggio.
La logica imposta è la seguente: il Master in cui il bit di collisione è
settato, perde il controllo del bus e abbandona il processo di comunicazione
in corso, che sarà ripreso non appena il bus è di nuovo libero.
Quando il Master invia bit sulla linea SDA, viene effettuato un campionamento
per verificare se il dato emesso è uguale allo stato della linea. Quando SDA
è
a livello alto, i dati devono essere stabili. Se il dato attesi su SDA è un '1
' e il campionamento riporta uno '0' , significa che un' altra unità sta
cercando di scrivere dati. Ha luogo una collisione.
Sul Master sarà portato a 1 il flag di interrupt per Bus Collision, BCLIF e il
modulo MSSP sarà riportato al suo stato di inattività.
Se una trasmissione era in corso al momento della collisione, essa viene interrotta, i flag
BF è
posto a 0, le linee SDA e SCL sono rilasciate.
BCLIF chiama un interrupt in quanto l' utente viene avvertito della situazione
anomala e deve intervenire.
Una routine di collisione potrà attendere lo stato di idle del bus per riprendere la comunicazione
generando una nuova condizione di Start.
Se erano in corso Start, Restart, Stop o ACK/NACK al momento della collisone
sul bus, la condizione è interrotta,le linee SDA e SCL sono rilasciate e i bit
di controllo rispettivi in SSPCON2 vengono cancellati. La routine di collisione
potrà attendere lo stato di idle del bus per riprendere la comunicazione
generando una nuova condizione di Start.
Il master continuerà a monitorare la SDA e SCL: se si verifica una condizione irreversibile, il bit
SSPIF verrà
settato.
La scrittura di SSPBUF inizierà la trasmissione di dati, indipendentemente da dove il
trasmettitore era stato interrotto quando la collisione sul bus si è verificata.
Una collisone in un sistema multi-Master si potrà presentare in vari
momenti dello scambio di dati sul bus.
Bus Collision durante la condizione di Start
E' probabile che una collisone avvenga durante lo Start: due Master che
intendono accedere al bus, lo trovano idle e generano per prima cosa la
condizione di Start.
E' anche possibile che un Master tenti un accesso al bus generando lo Start
mentre il bus è già impegnato.
Nel corso di una condizione di Start, una collisione bus si verifica se:
- SDA o SCL sono campionati bassi all'inizio della condizione di avvio.
- SCL viene campionato a basso prima che SDA sia a livello basso
Nel corso di una condizione di avvio, sia SDA che SCL sono monitorati. Se il pin
SDA è già basso, o il pin SCL è già
basso, si verificano gli eventi seguenti:
- la condizione di Start viene interrotta,
- il flag BCLIF va a 1
- il modulo MSSP viene ripristinato al suo stato di inattività.
La condizione di Start inizia con i pin SDA e SCL a livello alto. Quando il pin
SDA è
campionato alto, il Baud Rate Generator BRG è caricato da SSPADD <6:0> e conta fino a 0. Se il pin
SCL viene
campionato basso mentre SDA è a livello alto, si verifica una collisione perché è
da presumere che un altro Master stia tentando di mandare un dato '1' durante la condizione di
Start.
Se il pin SDA viene campionato basso durante questo conteggio, BRG viene azzerato e la linea
SDA
è a livello basso prima del conteggio.
Se, tuttavia, un '1 ' viene campionato su SDA, il pin va basso alla fine del
conteggio del BRG. Il generatore di baud rate viene poi ricaricato e conta di
nuovo fino a 0: se il pin SCL viene campionato come '0 ' durante questo tempo,
non si rileva una collisione bus. Alla fine del conteggio BRG, il pin SCL va
basso.
La ragione per cui collisione bus non è un fattore nel corso di una condizione
di Start è che non è possibile ragionevolmente che due Master possano far valere una condizione di avvio
esattamente allo stesso tempo.
Pertanto, un Master manderà a livello basso SDA prima dell'altro.
Questa condizione non causa un bus collision perché ai due master deve essere
permesso di arbitrare il primo indirizzo che segue la condizione di
Start. Se l'indirizzo è lo stessa, l'arbitrato prosegue nella porzione di
dati o nella condizione di Restart o Stop. |
Bus Collision durante il Restart
Nel corso di una condizione di Restart, una collisione bus si verifica se:
- Viene campionato un livello basso su SDA quando SCL va dal livello basso al livello alto.
- SCL va basso prima che SDA vada basso, il che indica che un altro
Master sta tentando di
trasmettere dati a '1 '.
Quando l'utente rilascia SDA e il pin dovrebbe tornare a livello 1 per i
pull-up, il BRG è caricato con SSPADD <6:0> e
conta fino a 0. Il pin SCL è quindi rilasciato e, quando campionato alto, il pin
SDA viene
pure campionato.
Se SDA è basso, una collisione bus si è verificato (ad esempio, un altro
Master
sta tentando di trasmettere un dato a '0).
Se SDA viene campionato alto, il BRG è ricaricato e inizia il conteggio. Se
SDA passa da
alto a basso prima della fine del conteggio, non c'è collisone perché non esistono due
Master che agiscono su SDA esattamente nello stesso momento.
Se SCL va da alto a basso prima del conteggio di BRG e SDA non è già stato
mandato basso, si verifica una collisione bus: in questo caso, un altro Master sta tentando di
trasmettere dati a '1 'durante la condizione di Restart.
Se, alla fine del conteggio di BRG, sia SCL e SDA sono ancora a livello 1, il pin
SDA è
mandato basso e BRG è
ricaricato e inizia a contare. Alla fine del conteggio, indipendentemente dallo stato del pin
SCL, SDA è mandato basso e la condizione di Restart è completata.
Bus Collision durante lo Stop
Una collisione sul bus avviene durante una condizione di Stop se:
- Dopo che il pin SDA è stato rilasciato, il suo livello viene campionata basso
al termine di un periodo di BRG.
- Dopo che il pin SCL è stato rilasciato, SCL è campionato basso prima
che SDA vada alto.
La condizione di Stop inizia con SDA a livello basso. Quando questa linea è campionata bassa, il pin
SCL è
rilasciato e deve andare a livello alto a causa del pull-up. Se il pin viene campionato
alto (arbitraggio di clock), il generatore di baud rate è caricato con SSPADD <6:0>
e conta fino a 0. Dopo il tempo di BRG, la linea SDA è campionata: se viene
trovata a
livello basso, si è verificata una collisione sul bus, dovuta a un altro Master
che cerca di portare la linea a '0.
Se il pin SCL è campionato basso prima che SDA sia rilasciato, è in corso
una collisione. Questo è un altro caso di un Master che sta tentando di
comandare la linea dati a 0.
|