Far funzionare il bus condiviso come OR


10

Per gli impazienti, puoi saltare lo sfondo.

sfondo

Sto programmando una serie di microcontrollori che comunicano con SPI. C'è un maestro e degli nschiavi che condividono il bus. Non esiste una selezione di chip. (Non è un cattivo design, ma nè grande e non c'è abbastanza spazio per nle linee extra).

È quindi responsabilità degli schiavi mantenere il loro MISO in alta impedenza e al massimo uno di loro parla. Ciò avviene rispondendo solo quando viene eseguito il polling del loro ID.

Ora vorremmo avere una fase di scoperta iniziale in cui il master scopre gli schiavi con quali ID sono associati ad esso. Per semplificare la vita (per alcuni aspetti), vorremmo avere un ID unico (e quindi ad esempio 32 bit). Questo rende impossibile per il master semplicemente sondare gli ID uno per uno e vedere chi risponde (ci sono troppe possibilità).

Per risolvere questo problema, ho escogitato una variante della ricerca binaria in cui gli slave rispondono collettivamente e il master è in grado di trovare rapidamente l'id minimo. Lo slave con quell'id viene detto di non partecipare più e l'algoritmo si ripete. (Dettagli non importanti).

C'è un problema però. La risposta collettiva deve essere l'OR logico (o AND logico) di tutte le risposte. Mi è stato detto che la linea può essere configurata in modo tale che il bus MISO possa fungere da OR logico. Quello che mi è stato detto è:

  • Impostare MISO sul master come Pull-up e
  • Impostare MISO su ogni slave come Open-drain.

Ho provato questo, ma con un solo slave, questa configurazione non funziona (l'oscilloscopio mostra uno zero costante sulla linea). Se configuro MISO sul master come ingresso ad alta impedenza, posso vedere con l'oscilloscopio che la tensione scende alla metà dove differiscono i bit delle uscite da due slave (fondamentalmente presumo un cortocircuito).

Nota: configurando MISO sul master come alta impedenza e slave ciascuno come push-pull, posso parlare con ciascuno di essi singolarmente anche se ce ne sono molti sullo stesso bus. Voglio dire, dubito che sia un problema della linea stessa.

Domanda

La mia domanda è, se possibile, e in tal caso, come posso configurare i pin di input e output del master e degli slave in modo che la linea MISO condivisa funga da OR logico (o AND logico)?


modificare

  1. Si è scoperto che diventa un OR con logica negativo-vera (sostanzialmente un AND).

  2. Il problema con il singolo slave è stato risolto scrivendo 1 sul pin pull-up sul master. In precedenza aveva uno stato iniziale di 0.

Modifica 2

Si è scoperto che lo slave ST ha la precedenza sulla mia configurazione GPIO di MISO come open-drain e lo stava forzando in alto quando uno è stato scritto. Ho deciso di mettere a tacere SPI e generare manualmente MISO in questo caso particolare.


Non vorrei chiedere, perché sono sicuro che ci hai pensato, ma hai preso in considerazione l'utilizzo di I2C o CAN? Sono progettati per n dispositivi, mentre SPI è davvero progettato per essere utilizzato con una selezione di chip per ciascun dispositivo.
Bob,

@bob, sì. Sono troppo lenti. Comunque, se la risposta alla mia domanda è "impossibile", allora dovremmo solo fare un po 'di lavoro manuale, ma con SPI il prodotto finale è molto meglio.
Shahbaz,

1
È un peccato che tu stia usando 32 bit come indirizzo perché se tu stessi usando 24 bit (16.772.216 variazioni) potresti inviare un comando "scopri" e attendere 16.772.216 orologi e potresti avere tutte le tue informazioni sugli slave. A 10 Mbps che richiederebbero meno di 2 secondi e nessun conflitto da capire. Ehi ho - mi hai fatto pensare così +1 per quello.
Andy aka

@Andyaka, anche 24 bit potrebbero non essere male (ma 32 bit è sicuramente migliore). se ti ho capito bene, intendi che ogni slave risponde al suo secondo orologio con un 1 e il master osserva quali orologi ne hanno generato uno? Non è male, tranne che gli schiavi rispondono in byte. Quindi ogni slave risponde con 8 bit e, a meno che non riesca a far funzionare il bus come OR, la risposta di uno slave viene "persa" all'interno delle risposte dell'altro slave (l'1 di uno slave viene abbattuto dagli 0 di tutti il riposo).
Shahbaz,

@Shahbaz se hai il controllo del codice dello slave puoi renderlo "speciale" in cui lo slave risponde solo con 1 bit al momento assegnato. Sì, hai capito bene le mie riflessioni.
Andy aka

Risposte:


5

SPI-senza-selezione è ciò che Microchip utilizza sui propri chip MCP23017 (e altri). Niente di sbagliato in questo approccio.

Sì, quello che vuoi è possibile, ma devi fare in modo che gli schiavi siano a tutto campo. Puoi imbrogliare mettendo un diodo (schottky) in serie con ogni uscita se non riesci a farli comportare come open-drain.

L'approccio di enumerazione è lo stesso utilizzato dal bus a un filo di Dallas per l'enumerazione e dal bus CAN per l'arbitrato.

Ma un grave inconveniente del tuo approccio è che la velocità è ora limitata dal tempo di salita, guidato dalla resistenza di pull-up. Questo sarà più lento di quando guidato da un'uscita push-pull e probabilmente limiterà la velocità alla quale è possibile operare il bus.

Se si hanno due pin da risparmiare su ogni slave, è possibile collegarli in cascata e disporre di uno schema di enumerazione basato sul loro posto nella catena.


Sì, ho dimenticato di menzionare che mi è stato anche detto che devo ridurre la velocità (cosa che ho fatto di circa 20 volte (da 4 Mb a 128 Kbps)). Questa è una fase iniziale e il mio algoritmo può gestire la velocità più lenta (è ancora abbastanza veloce). Sfortunatamente, dubito che ora ridisegneremmo l'hardware. Il costo è più che semplicemente ignorare questa fase e dire al master quali ID aspettarsi.
Shahbaz,

Tornando alla domanda, ho già configurato gli slave come open-drain. Come devo configurare il master?
Shahbaz,

1
Niente di speciale nel pin MISO del master, tranne il pullup. Dubito che raggiungerai 128 Kbps con un design pull-up, ma YMMV. La lettura di alcuni documenti I2C approfonditi potrebbe essere utile, ovvero un bus wire-o pull-up, quindi ogni trucco applicato potrebbe aiutarti.
Wouter van Ooijen,

Molte grazie. Proverò a rallentare ancora di più l'autobus per vedere cosa succede. Immagino che alla fine dovrò studiare e capire cosa significano questi pull-up, open-drain e altri. (Ingegnere del software qui!)
Shahbaz,

1
Metti un oscilloscopio sul bus e controlla cosa succede. Il tempo di salita potrebbe essere troppo lento, ma potrebbe esserci anche uno squillo.
Wouter van Ooijen,

4
  • Impostare MISO sul master come Pull-up e
  • Impostare MISO su ogni slave come Open-drain.

Ho provato questo, ma con un solo slave, questa configurazione non funziona (l'oscilloscopio mostra uno zero costante sulla linea).

È necessario verificare qual è la resistenza equivalente del pin di I / O principale in modalità pull-up.

In genere, la modalità pull-up ha una resistenza molto elevata, forse 50 kOhm o superiore. Ha lo scopo di evitare il glitching del pin a causa di emi o altri rumori, o di impostare un valore predefinito per segnali di controllo molto lenti, e allo stesso tempo di non sprecare troppa potenza nel farlo.

Come ha sottolineato Wouter, in un bus a drain aperto la velocità è limitata dalla resistenza di pull-up. Valori di resistenza più alti rendono il bus più lento. I valori tipici in I2C (che ottiene 100 o 400 kHz) sono compresi tra 1 e 5 kOhm. Avrai bisogno di una resistenza di pull-up simile per ottenere una velocità simile.

Penso che sia necessario utilizzare un resistore di pull-up esterno (da 1 a 5 kOhm circa) anziché il pull-up del pin di I / O del master per far funzionare questo schema.


Grazie per i suggerimenti. Non sono un ragazzo di elettronica, ma dovrei chiedere al mio collega di dare un'occhiata al tuo suggerimento. Ho bisogno del cavo o solo per una fase iniziale del programma e nella fase normale il pin non è configurato come pull-up. Quindi probabilmente la resistenza esterna non è un'opzione.
Shahbaz,

Se hai un pin I / o libero sul micro master, puoi collegarlo al bus attraverso, diciamo, 5 kOhm. Quindi ruotarlo in alto durante l'enumerazione del bus e girarlo in alto-Z durante la normale comunicazione.
The Photon,

1

Affinché un cavo e un bus funzionino, i nodi sul bus devono essere a drain aperto, cioè devono trasmettere

  • la logica in basso tirando giù fortemente, e
  • la logica alta scollegandosi dal bus.

Inoltre, l'autobus deve essere tirato su debolmente.

Il comportamento peculiare che si vede con un singolo master non trasmittente e un singolo slave trasmittente potrebbe essere spiegato dal master che si alza fortemente o dallo slave che si abbassa debolmente.

È necessario determinare quale di quanto sopra sta accadendo.

Mettere lo slave in modalità ad alta impedenza e collegare il bus a terra tramite una resistenza da 10k. Se la tensione di linea non cambia in modo significativo, il master si sta alzando fortemente e devi risolverlo. In caso contrario, eseguire la stessa procedura con lo slave (questa volta collegare la resistenza a Vcc); se la tensione di linea aumenta in modo significativo, lo slave si sta abbassando debolmente (risolverlo). Altrimenti, cerca le distorsioni spazio-temporali nell'area intorno a te.


Scusa la mia ignoranza nell'elettronica, ma se lo schiavo si abbassa fortemente, questo non fa funzionare il bus come AND? Sto dicendo che gli schiavi che vogliono alto si stanno disconnettendo e quelli che vogliono basso stanno tirando giù, quindi il risultato complessivo è basso, no?
Shahbaz,

@Shahbaz, mio ​​cattivo, ovviamente l'autobus sarà cablato e, ho risolto la risposta. Se si desidera cablare o, invertire semplicemente le polarità (il master si abbassa debolmente, gli slave si alzano fortemente).
avakar,

Leggendo su Wikipedia, mi sono reso conto che si riferiscono ad esso come cablati e / o cablati o con una logica di vero negativo.
Shahbaz,

1

Suggerirei di avere un pull-up o pull-down passivo sull'autobus (assumerò pull-up) e di avere degli schiavi che guidano attivamente l'autobus (guidando in alto e abbassando) quando hanno qualcosa da dire e lo fanno galleggiare altrimenti . Dispone di comandi query-address che accettano un indirizzo e una maschera e istruiscono ogni slave ad emettere 00 o a non fare nulla (continua a fluttuare il suo output) in base al gradimento dell'indirizzo e della maschera. Se possibile, chiedi al master di guidare attivamente il bus per un po 'di tempo prima che gli schiavi inizino a guidarlo. A seconda della forza del pull-up e del fatto che il master spinga il bus in alto, prima che gli slave possano abbassarlo, potrebbe essere necessario limitare la velocità del bus durante la fase di configurazione. D'altra parte, una volta completata l'installazione,


Se due schiavi guidano attivamente alti e bassi, cosa dovrei leggere dal bus?
Shahbaz,

Si dovrebbe evitare di avere mai uno schiavo che prova a guidare in alto mentre un altro sta guidando in basso. Uno schiavo dovrebbe guidare il bus solo quando (1) sa che sarà l'unica cosa a farlo, oppure (2) sa che esso e tutti gli altri che guidano il bus lo guideranno al contrario del suo minimo passivo stato.
Supercat,

Cosa significa questo allora? ... se ogni slave selezionato attiva attivamente sia i livelli alti che i bassi consentirà al bus di ...
Shahbaz,

@Shahbaz: quando uno slave ha qualcosa da dire, dovrebbe attivamente guidare il bus in alto per trasmettere bit "1" e in basso per trasmettere bit "0". Quando uno schiavo non ha nulla da dire, non dovrebbe guidare il bus. Si noti che avere schiavi attivamente guida il bus in alto quando vogliono inviare bit "1" consentirà al bus di funzionare molto più velocemente di quanto farebbe affidamento su un pull-up passivo per guidare il bus in alto.
Supercat,

@Shahbaz: Quello che il supercat sta cercando di dire, è che nello stato di enumerazione, un resistore dovrebbe tirare la linea e gli schiavi dovrebbero solo inviare "0" o niente (uscita di drain aperta), ma in seguito, in comunicazione normale, solo un lo slave singolo deve essere attivo alla volta e lo slave attivo deve inviare "0" o "1" (uscita normale). Pertanto, la resistenza di pull-up e la capacità di linea limitano il bit rate solo durante l'enumerazione. Successivamente, nella normale comunicazione, la velocità in bit può essere maggiore, come consente la guida attiva.
Laszlo Valko,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.