Hacer que el bus compartido actúe como OR


10

Para los impacientes, puede omitir el fondo.

Antecedentes

Estoy programando un conjunto de microcontroladores que se comunican con SPI. Hay un maestro y nesclavos que comparten el autobús. No hay selección de chip. (No es un mal diseño, pero nes grande y no hay suficiente espacio para nlíneas adicionales).

Por lo tanto, es responsabilidad de los esclavos mantener su MISO en alta impedancia y, a lo sumo, uno de ellos habla. Esto se hace respondiendo solo cuando se sondea su identificación.

Ahora nos gustaría tener una fase de descubrimiento inicial en la que el maestro descubra esclavos con los identificadores que tiene adjuntos. Para hacer la vida más fácil (en algunos aspectos), nos gustaría tener la identificación única (y, por lo tanto, por ejemplo, 32 bits). Esto hace que sea imposible para el maestro simplemente sondear los identificadores uno por uno y ver quién responde (hay demasiadas posibilidades).

Para resolver este problema, ideé una variación de búsqueda binaria donde los esclavos responden colectivamente y el maestro puede encontrar rápidamente la identificación mínima. Al esclavo con esa identificación se le dice que no participe más y el algoritmo se repite. (Detalles sin importancia).

Sin embargo, hay un problema. La respuesta colectiva debe ser el OR lógico (o el AND lógico) de todas las respuestas. Me han dicho que la línea se puede configurar de tal manera que el bus MISO pueda actuar como un OR lógico. Lo que me han dicho es:

  • Establezca MISO en el maestro como Pull-up y
  • Configure MISO en cada esclavo como drenaje abierto.

He intentado esto, pero incluso con un solo esclavo, esta configuración no funciona (el osciloscopio muestra un cero constante en la línea). Si configuro MISO en el maestro como entrada de alta impedancia, puedo ver con el osciloscopio que el voltaje cae a la mitad donde difieren los bits de las salidas de dos esclavos (supongo, básicamente, cortocircuito).

Nota: configurando MISO en maestro como alta impedancia y esclavos cada uno como push-pull, puedo hablar con cada uno de ellos individualmente, incluso si hay muchos de ellos en el mismo bus. Quiero decir, dudo que sea un problema de la línea misma.

Pregunta

Mi pregunta es, si esto es posible, y si es así, ¿cómo puedo configurar los pines de entrada y salida del maestro y los esclavos para que la línea MISO compartida actúe como OR lógico (o AND lógico)?


Editar

  1. Resultó que se convierte en un OR con lógica negativa verdadera (básicamente un AND).

  2. El problema con el esclavo único se resolvió escribiendo 1 en el pin pull-up en el maestro. Anteriormente tenía un estado inicial de 0.

Editar 2

Resultó que el esclavo ST anula mi configuración GPIO de MISO como drenaje abierto y lo estaba forzando alto cuando se escribió uno. Resolví silenciar SPI y generar MISO en este caso particular manualmente.


Odio preguntar, porque estoy seguro de que lo has pensado, pero ¿has considerado usar I2C o CAN? Están diseñados para n dispositivos, mientras que SPI está realmente diseñado para usarse con un chip seleccionado para cada dispositivo.
Bob

@bob, sí. Son muy lentos De todos modos, si la respuesta a mi pregunta es "es imposible", entonces solo tendríamos que hacer un poco de trabajo manual, pero aún así el producto final es mucho mejor con SPI.
Shahbaz

1
Es una pena que esté utilizando 32 bits como dirección porque si estuviera utilizando 24 bits (16.772.216 variaciones) podría enviar un comando "descubrir" y esperar 16.772.216 relojes y podría tener toda su información esclava. A 10Mbps eso tomaría menos de 2 segundos y no habría conflictos para resolver. Hey ho - me tienes pensando que +1 por eso.
Andy alias

@Andyaka, 24 bits también pueden no ser malos (pero 32 bits es ciertamente mejor). si te entendí correctamente, ¿quieres decir que cada esclavo responde en su reloj id'th con un 1 y el maestro mira qué relojes generaron uno? Eso no está mal, excepto que los esclavos responden en bytes. Entonces cada esclavo responde con 8 bits, y a menos que pueda hacer que el bus actúe como OR, la respuesta de un esclavo se "pierde" dentro de las respuestas del otro esclavo (el 1 de un esclavo es derribado por los ceros de todos el resto).
Shahbaz

@Shahbaz si tiene control sobre el código del esclavo, puede hacer que sea un "especial" donde el esclavo solo responde con 1 bit en el tiempo asignado. Sí, tienes la esencia de mis reflexiones.
Andy alias

Respuestas:


5

Su SPI-sin-selección es lo que utiliza Microchip en sus chips MCP23017 (y otros). No hay nada malo con ese enfoque.

Sí, lo que quieres es posible, pero debes hacer que los esclavos sean de drenaje abierto. Puede hacer trampa poniendo un diodo (schottky) en serie con cada salida si no puede hacer que se comporten como drenaje abierto.

Su enfoque de enumeración es el mismo que el utilizado por el bus de un cable de Dallas para la enumeración, y por el bus CAN para el arbitraje.

Pero un inconveniente grave de su enfoque es que la velocidad ahora está limitada por el tiempo de subida, impulsado por la resistencia pull-up. Esto será más lento que cuando es impulsado por una salida push-pull, y probablemente limitará la velocidad a la que puede operar el bus.

Si tiene dos pines de sobra en cada esclavo, puede encadenarlos y tener un esquema de enumeración basado en su lugar en la cadena de margaritas.


Sí, olvidé mencionar que también me dijeron que necesitaba reducir la velocidad (lo que hice aproximadamente 20 veces (de 4 Mbps a 128 Kbps)). Sin embargo, esa es una fase inicial y mi algoritmo puede manejar la velocidad más lenta (todavía es bastante rápida). Desafortunadamente, dudo que rediseñemos el hardware ahora. El costo es más que simplemente ignorar esta fase y decirle al maestro qué identificadores esperar.
Shahbaz

Volviendo a la pregunta, ya he configurado los esclavos como drenaje abierto. ¿Cómo debo configurar el maestro?
Shahbaz

1
Nada especial en el pin MISO del maestro, excepto el pullup. Dudo que llegue a 128 Kbps con un diseño pull-up, pero YMMV. Puede ser útil leer algunos documentos detallados de I2C, que es un autobús de conexión o pull-up, por lo que cada truco aplicado allí podría ayudarlo.
Wouter van Ooijen

Muchas gracias. Intentaré frenar aún más el autobús para ver qué pasa. Supongo que finalmente tengo que estudiar y comprender lo que realmente significan estos pull-up, open-drain y otros. (¡Ingeniero de software aquí!)
Shahbaz

1
Coloque un osciloscopio en el autobús y verifique qué sucede. El tiempo de subida puede ser demasiado lento, pero también puede estar sonando.
Wouter van Ooijen

4
  • Establezca MISO en el maestro como Pull-up y
  • Configure MISO en cada esclavo como drenaje abierto.

He intentado esto, pero incluso con un solo esclavo, esta configuración no funciona (el osciloscopio muestra un cero constante en la línea).

Debe verificar cuál es la resistencia equivalente del pin maestro de E / S en modo pull-up.

Por lo general, el modo pull-up tiene una resistencia muy alta, quizás 50 kOhms o más. Su objetivo es evitar que el pin falle debido a emi u otro ruido, o establecer un valor predeterminado para señales de control muy lentas y, al mismo tiempo, no desperdiciar demasiada energía al hacerlo.

Como señaló Wouter, en un bus de drenaje abierto la velocidad está limitada por la resistencia pull-up. Los valores de resistencia más altos hacen que el bus sea más lento. Los valores típicos en I2C (que obtiene 100 o 400 kHz) son de 1 a 5 kOhms. Necesitará una resistencia de pull-up similar para lograr una velocidad similar.

Creo que debe usar una resistencia pull-up externa (de 1 a 5 kOhms más o menos) en lugar del pull-up del pin de E / S del maestro para que este esquema funcione.


Gracias por las pistas. No soy un tipo de electrónica, pero tendría que pedirle a mi compañero de trabajo que eche un vistazo a su sugerencia. Necesito el cableado o solo para una fase inicial del programa y en la fase normal el pin no está configurado como pull-up. Entonces, probablemente la resistencia externa no es una opción.
Shahbaz

Si tiene un pin de E / S libre en el micro maestro, puede conectarlo al bus a través de, digamos, 5 kOhms. Luego, enciéndalo durante la enumeración del bus y enciéndalo en Z durante la comunicación normal.
The Photon

1

Para que un cable y un bus funcionen, los nodos del bus deben ser de drenaje abierto, es decir, deben transmitir

  • la lógica baja tirando hacia abajo con fuerza, y
  • la lógica alta desconectando del bus.

Además, el autobús debe ser levantado débilmente.

El comportamiento peculiar que se ve con un solo maestro no transmisor y un solo esclavo transmisor podría explicarse ya sea por el maestro tirando hacia arriba fuertemente o el esclavo hacia abajo débilmente.

Debe determinar cuál de los anteriores está sucediendo.

Ponga el esclavo en modo de alta impedancia y conecte el bus a tierra a través de una resistencia de 10k. Si el voltaje de la línea no cambia significativamente, entonces el maestro está tirando fuertemente hacia arriba y necesita arreglarlo. De lo contrario, realice el mismo procedimiento con el esclavo (esta vez conecte la resistencia a Vcc); Si el voltaje de la línea aumenta significativamente, el esclavo está bajando débilmente (arregle eso). De lo contrario, busca distorsiones espacio-temporales en el área que te rodea.


Disculpe mi ignorancia en electrónica, pero si el esclavo se detiene con fuerza, ¿eso no hace que el autobús actúe como AND? Lo digo porque los esclavos que quieren alto se están desconectando y los que quieren bajo están bajando, por lo que el resultado general es bajo, ¿no?
Shahbaz

@Shahbaz, mi mal, por supuesto, el autobús estará conectado y arreglé la respuesta. Si desea cableado o simplemente invierta las polaridades (el maestro tira hacia abajo débilmente, los esclavos hacia arriba con fuerza).
avakar

Leyendo en wikipedia, me di cuenta de que se refieren a él como cableado y o cableado o con lógica negativa verdadera.
Shahbaz

1

Sugeriría tener un pull-up o pull-down pasivo en el autobús (supongo que pull-up), y que los esclavos conduzcan activamente el autobús (conduciendo alto y bajo) cuando tengan algo que decir y lo floten de otra manera . Tenga comandos de dirección de consulta que toman una dirección y una máscara, y le indica a cada esclavo que salga 00 o no haga nada (mantenga flotando su salida) en función de si le gusta la dirección y la máscara. Si es posible, haga que el maestro conduzca activamente el bus alto antes de que los esclavos comiencen a conducirlo. Dependiendo de la fuerza del pull-up y de si el maestro conduce el bus alto, antes de que los esclavos puedan bajarlo, puede ser necesario limitar la velocidad del bus durante la fase de configuración. Por otro lado, una vez que se completa la configuración,


Si dos esclavos conducen activamente alto y bajo, ¿qué se espera que lea del autobús?
Shahbaz

Uno debe evitar que un esclavo intente conducir alto mientras que otro conduce bajo. Un esclavo solo debe conducir el autobús cuando (1) sabe que será lo único que lo hace, o (2) sabe que él y todos los demás que conducen el autobús lo conducirán al contrario de su ralentí pasivo estado.
supercat

Entonces, qué significa esto? ... que cada esclavo seleccionado conduzca activamente los niveles alto y bajo permitirá que el autobús ...
Shahbaz

@Shahbaz: cuando un esclavo tiene algo que decir, debe conducir activamente el bus alto para transmitir bits "1" y bajo para transmitir bits "0". Cuando un esclavo no tiene nada que decir, no debe conducir el autobús en absoluto. Tenga en cuenta que tener esclavos conducen activamente el bus alto cuando quieren enviar bits "1" permitirá que el bus opere mucho más rápido de lo que dependería de un pull-up pasivo para conducir el bus alto.
supercat

@Shahbaz: Lo que Supercat está tratando de decir es que en el estado de enumeración, una resistencia debe levantar la línea, y los esclavos solo deben enviar "0" o nada (salida de drenaje abierta), pero luego, en comunicación normal, solo un el esclavo único debe estar activo a la vez, y el esclavo activo debe enviar "0" o "1" (salida normal). Por lo tanto, la resistencia pull-up y la capacitancia de línea solo limitan la velocidad de bits durante la enumeración. Posteriormente, en una comunicación normal, la velocidad de bits puede ser mayor, según lo permita la conducción activa.
Laszlo Valko
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.