SPI entre MCU

Como recién llegado a la programación PIC, estoy buscando algunas ideas sobre cómo implementar SPI entre una MCU maestra y una esclava de la manera más eficiente.

El propósito de este sistema es proporcionar una forma extremadamente flexible de "asignar" hasta 32 pines de salida individuales de la MCU esclava a cualquiera de los 32 pines de entrada de la MCU maestra, utilizando una "matriz" configurable por software.

Para hacer las cosas un poco más claras, agregué un dibujo a continuación:

FLUJO SPI

Alguna otra MCU (no en el dibujo) administra la configuración del mapeo de puertos y transfiere esta información a la MCU esclava como una 'matriz de puertos' a través de I2C.

En el ejemplo del dibujo, el puerto de salida esclavo B, bit 0 (B.0) debe asignarse al pin de entrada maestro A, bit 0 (A.0) Además, la salida B.3 debe asignarse a la entrada A.1 y la salida C .6 debe corresponder a la entrada B.6

Entonces, cuando el pin maestro A.1 sube, el pin esclavo B.3 también debería subir. Desde el punto de vista de la aplicación, eso debería ser sencillo.

Pero, ¿cuál sería la forma más eficiente de leer 32 bits de 4 puertos en el maestro y representarlos en el esclavo como un número entero de 32 bits para que la aplicación proporcione la asignación a sus puertos de salida?

El reloj SPI debe ser al menos de 2 MHz para que sea funcionalmente aceptable. ¿DMA es una solución aquí? ¿Puede dicha solución de transporte basarse en interrupciones/eventos para evitar que la CPU realice encuestas? Los MCU de destino son PIC32MX795.

Definitivamente me vendrían bien algunos consejos para poner en marcha esta comunicación.

¡Gracias de antemano!

¿Qué has hecho hasta ahora y por qué no es lo suficientemente bueno? Necesitaría más información. ¿Cómo define "la forma más eficiente"? Por ejemplo, menor uso de ancho de banda SPI, menor cantidad de ciclos de CPU en esclavo, menor cantidad de ciclos de CPU en maestro, ¿algo más? ¿Cómo cambian los pines de entrada, uno a la vez, o mezclas aleatorias de pines? ¿Cuál es la duración mínima de cambio de pin de entrada que debe reconocerse y propagarse? ¿Qué es la latencia aceptable? ¿Latencia más baja entre el cambio de entrada de un solo pin y la salida que lo sigue, o latencia constante sin importar cuántos pines cambien? ¿Cuál es la latencia máxima para cambios de uno y varios pines?
Este proyecto basado en MCU está en fase de concepción. La implementación actual está en el hardware, pero no es lo suficientemente flexible. Su finalidad es reutilizar pulsos de máquina CNC. Aparecen mezclados aleatoriamente en todos los pines. La frecuencia de pulso máxima actual es de 400 khz. Duraciones de pulso alrededor de 1us. El único trabajo de Master es muestrear pines de entrada + transporte. La función de esclavo se limita a configurar los puertos de salida de acuerdo con la matriz de configuración. Las latencias de hasta 10 us son aceptables, si son consistentes. Con más eficiente, quise decir la configuración más rápida, ya sea DMA o código, todavía estoy aprendiendo sobre eso.
En el PIC32MX795, todos los registros del puerto son de 32 bits, aunque solo se implementan como máximo 16 bits. Solo muestra 8 bits para cada puerto. De acuerdo, salta los bits 8-15. Pero algunos de los pines del puerto no están implementados. Ignoraré el puerto A, ya que los pines que faltan están en el byte alto. Pero los pines RC0, RC5, RC6 y RC7 no están disponibles. Consulte la página 28 de la hoja de datos. Solo para que sepas.
Usando su requisito de latencia, 32 bits transferidos de maestro a esclavo en 10usec necesitan un reloj SPI no menor a 3.2MHz y eso ignora el tiempo requerido para cualquier procesamiento. El uso de su especificación de duración de pulso de 1usec conduce a un reloj SPI de 32MHz ...
De hecho, las 32 señales son parte de un conjunto más grande. La latencia de 10us proviene de nuestras señales para mantenerse sincronizadas con otras señales que no están dentro del alcance de la solución. Si cambio el enrutamiento y me aseguro de que todas las señales críticas pasen a través de la solución, la latencia se vuelve mucho menos estricta, ya que 1 ms estaría bien.
tcrosley, lo sé, los puertos en el dibujo no son puertos reales, solo sirven para aclarar ... ¡gracias!

Respuestas (3)

Para la transmisión de datos: la forma más fácil de hacerlo es con registros de desplazamiento. No tendrá que preocuparse por microcontroladores lentos, ni por hardware de programación en CPLD.

Tomemos por ejemplo 74HC164 y 74HC166

Puede conectar en cascada cuatro 74HC166 para crear un registro de desplazamiento de entrada/salida en serie de 32 bits y luego deserializar usando cuatro 74HC164 (registro de entrada/salida en serie de 32 bits). Estos chips pueden hacer 100Mhz fácilmente, cuestan casi nada y requieren un circuito mínimo.

El problema es esa "matriz de asignación de pines" que quería usar. Construir esto con puertas sería doloroso.

Si está dispuesto a modificar el protocolo de comunicación usted mismo, la forma más rápida podría ser usar las 4 líneas para enviar los estados de los pines (8 pines de datos por línea).

La idea aquí es usar básicamente un protocolo serial de un solo cable. Dado que no tendrá una línea de reloj, deberá usar algún tipo de bit de inicio para identificar el comienzo de la transmisión.

Digamos que las líneas de datos se mantienen altas cuando están inactivas y 0 es el bit de inicio. Si desea transferir 0x12345678 de datos pin (32 bits), transferiría 0x12 en la primera línea, 0x34 en la segunda línea y así sucesivamente.

El patrón de bits en la primera línea se verá así:

0 0 0 0 1 0 0 1 0

^ es el bit de inicio

En la segunda línea obtendrías:

0 0 0 1 1 0 1 0 0

^ es el bit de inicio

Puedes ver a dónde voy con esto. Es posible que desee agregar un bit de suma de verificación al final para verificar que no tuvo errores de lectura. Para implementar esto, deberá esperar a que la línea baje (puede usar una interrupción para esto) y, desde ese punto, implementar esencialmente cualquier otro algoritmo en serie: muestree la línea varias veces por período de bit (duración máxima de un solo bit ) y asegúrese de que el valor sea estable antes de registrarlo.

Luego, todo lo que tiene que hacer es compactar los datos recopilados de las 4 líneas utilizando algunos cambios de bits y escribirlos directamente en la salida.

Esto no funcionaría: comunicación asíncrona. con sincronización basada en palabras para una velocidad de 2Mhz sería difícil incluso si se implementa en hardware. Por eso RS-232 es tan lento.
Bueno, dijo que necesitaría 2 MHz si usaba SPI para transferir los 32 bits. De esta manera, solo necesita transferir 8 bits a la vez, por lo que potencialmente puede tomar más tiempo por bit. Esta es solo una sincronización basada en bits.
No lo es: la sincronización de bits requiere que PLL bloquee la fase/frecuencia del transmisor. Sin embargo, la sincronización basada en palabras sincroniza en fase en el borde generado con el bit de inicio. Luego muestrea algunos bits (8-10) en intervalos predefinidos esperando que el reloj del transmisor esté cerca de su propio reloj. 2Mhz significa un período de 500ns por un bit, eso es demasiado rápido para el PIC.
¿Esta Imagen? Su frecuencia máxima es de 80 MHz, los pines pueden incluso alternar a esa frecuencia. Esto debería ser factible. Una vez más, no necesitamos 2 MHz si solo necesita obtener 8 bits.
Debe realizar la sincronización de fase en todas esas líneas paralelas, lo que significa que necesita muestrear cada bit en aproximadamente 10 lugares. Entonces, en lugar de tener, digamos, una frecuencia de muestreo de 500 kHz, necesita 5 Mhz. Eso significa que tiene una ventana de aproximadamente 16 instrucciones para manejar las 4 comunicaciones paralelas. líneas. ¿Empiezas a ver por qué esto no es bueno? Ahora, puede hacer su vida mucho más fácil si solo agrega la quinta línea para la sincronización, porque esto eliminará la necesidad de sincronización de fase y bits de inicio, etc.

Sus requisitos son bastante estrictos (2Mhz, 10us de retraso) para que se realice en un PIC con unas pocas docenas de MIPS. Dicho esto, podría ser posible. Pero todavía no es la mejor herramienta para el trabajo.

¿Conoces los FPGA? Son demasiado grandes y caros para esto, pero algunos pequeños CPLD baratos también pueden hacerlo. En lugar de escribir software, implementaría golpes de bits SPI en VHDL o Verilog en el lado maestro y luego el esclavo podría ser su controlador CNC, PIC u otro CPLD.

No he aprendido acerca de ellos CPLD. De hecho, una alternativa interesante para mirar. ¡gracias!
Pensé en una forma aún más simple de hacer esto y lo publiqué como otra respuesta
Supongamos que cambiamos el diseño y optamos por CPLD, eso resolvería el problema de muestreo en el maestro, permitiría implementar cualquier protocolo en serie y resolvería el problema de las salidas de conmutación como una matriz. Lo único que no me queda claro es cómo construir cierto nivel de libertad de configuración en un CPLD o alguna EEPROM o flash circundante. ¿Deberíamos poder 'conectar' salidas a entradas sobre la marcha, no en tiempo de compilación?
Una forma fácil de configurarlo en línea es crear otra interfaz de comunicación (puede ser SPI, UART, 1 cable o incluso un simple registro de desplazamiento...) a través de la cual escribe su configuración en los registros internos. Sus estados determinarán cómo se enrutan las señales. Solo asegúrese de que la configuración se realice siempre en un estado en el que el dispositivo no lea las entradas paralelas; de lo contrario, es posible que vea pulsos espurios (los llamados peligros) en la salida serializada.
¿Altera o Xilinx? ¿Cuál sería el consejo para un recién llegado? ¿No solo el silicio, sino también el entorno de desarrollo?
No soy la persona adecuada para responder eso: intente buscarlo aquí en EE o publique una nueva pregunta.
Ok, las placas de desarrollo Altera Max II han llegado. He estado buscando inspiración en los interruptores de punto de cruce, los diseños de referencia están disponibles. Pero esto no es una coincidencia exacta. Desde el punto de vista de la arquitectura, ¿cuál sería la mejor manera de implementar dicho registro de configuración?