Maestro SPI dual con ATmega32u4

Surgió una necesidad inesperada en mi diseño, que es controlar 2 dispositivos SPI esclavos simultáneamente. Al principio, por supuesto, estaba planeando usar el bus SPI como de costumbre y controlar ambos dispositivos usando los pines /CS para que todo pareciera estar bien.

Al revisar la hoja de datos del dispositivo A hoy, noté que espera todos los datos de una sola vez, lo que significa que no puedo realizar el procedimiento que había planeado originalmente:

1) Seleccionar dispositivo B 2) Leer datos de B 3) Deseleccionar dispositivo B 4) Seleccionar dispositivo A 5) Escribir datos de B 6) Deseleccionar dispositivo A 7) Repetir hasta que todos los datos de B vayan a A (alrededor de 1,1 Mbit)

El dispositivo A asume que cuando su /CS sube, es el final del flujo de datos. Por supuesto, no puedo leer todo desde B en una sola ejecución y almacenarlos en MCU RAM, ya que los datos son mucho más grandes.

Naturalmente, lo siguiente que me vino a la mente es usar 2 SPI maestros separados al mismo tiempo: seleccione ambos chips, lea el byte de B y aliméntelo inmediatamente a A.

Entonces mis preguntas son:

a) ¿Es eso posible usando un ATmega32u4? Tiene un papel fundamental en el diseño general y cambiar a otro MCU sería un paso atrás.

b) Leí que el USART puede actuar como un segundo maestro SPI. ¿Es eso viable y confiable? ¿Qué tan difícil es implementar?

c) Si, lamentablemente, no es posible y tengo que cambiar de MCU, ¿cuál me recomendaría? Tenga en cuenta que la capacidad USB de ATmega32U4 es esencial.

d) ¿Es probable que el nuevo proceso (leer de B, alimentar a A) cause algún comportamiento inesperado? No parece bajo mi punto de vista, pregunto por si acaso ya que soy nuevo ingeniero.

¡Cualquier otra idea o dirección es bienvenida! Gracias de antemano.

ACTUALIZAR En caso de que juegue un papel importante, el Dispositivo A es un FPGA mientras que B es una memoria flash. La MCU tiene una doble función: descargar el flujo de bits de la PC a través de USB y almacenarlo en la ROM flash / usar el flujo de bits almacenado para configurar el FPGA al reiniciar/encender. Tanto FPGA como flash usan SPI. De acuerdo con la hoja de datos de la FPGA (familia ice40, Lattice, " Programación y configuración de iCE40 " p.26), la imagen debe programarse sin interrupción.

SPI master es razonablemente simple de implementar en software puro, usando solo GPIO.
Tiene 2 periféricos SPI?
@LongPham Sí, el ATmega32u4 ha conectado 2 periféricos SPI y el mcu toma los datos de uno y los pasa al otro.
Parece que necesita varias transferencias para obtener todos los datos de A a B, utilizando MCU como almacenamiento temporal de datos antes de cambiar la operación del SPI de "leer A" a "escribir B" y está limitado por la cantidad de memoria en el MCU en términos de una transferencia completa. Además, cuando vuelve a emitir una transacción de lectura SPI para obtener los datos restantes, el esclavo en el dispositivo externo no sabe cómo acceder a los datos desde una ubicación en la memoria donde se detuvo en la transferencia anterior (?) ¿Qué son "Dispositivo A" y "Dispositivo B"? "? Si los FPGA podemos arreglar esto fácilmente. ¿Puedes agregar un dibujo con los detalles pertinentes?
@CapnJJ Sí, de hecho, es un FPGA. La MCU tiene una doble función: descargar el flujo de bits de la PC a través de USB y almacenarlo en la ROM flash / usar el flujo de bits almacenado para configurar el FPGA al reiniciar/encender. Tanto FPGA como flash usan SPI. De acuerdo con la hoja de datos de la FPGA (familia ice40, Lattice, "Programación y configuración de iCE40" p.26), la imagen debe programarse sin interrupción.
@CapnJJ Un dibujo no está disponible, desafortunadamente.
Quise decir que podrías dibujar algo de alto nivel, pero creo que lo entiendo. Vea si entiendo esto ... PC -> FLASH, a través de MCU USB, sin problemas, y ahora está listo para encender y reiniciar para programar el FPGA a través de FLASH (?) Pero, FLASH -> FPGA a través de MCU SPI no suficiente memoria para almacenar localmente en MCU para luego programar FPGA sin interrupciones? ¿Tiene una memoria conectada a MCU lo suficientemente grande en su PCB que tiene un bus que no sea SPI? Si es así, tal vez puedas hacer FLASH -> FPGA en dos pasos. Si el bus SPI se comparte en PCB entre FPGA y FLASH, un maestro separado no será suficiente.
@CapnJJ Sí, lo entendiste correctamente. En el esquema actual, el bus sí se comparte, pero podría redirigir esas líneas.

Respuestas (4)

Es posible que desee adoptar un enfoque completamente diferente. En lugar de conectar la PROM y la FPGA al µC como dispositivos esclavos, conecte la PROM directamente a la FPGA y permita que la FPGA arranque en modo maestro SPI en lugar de modo esclavo SPI. Bonificación: el arranque ocurrirá más rápido.

Todavía podrá acceder a la PROM desde el µC después de que la FPGA haya arrancado para actualizaciones de firmware o almacenamiento de datos, pasando las señales de la interfaz SPI de la µC a través de la lógica de la FPGA.

Esta es una solución muy elegante y la consideré cuidadosamente y finalmente se me ocurrió una versión "modificada" de la suya. Al examinar las hojas de datos de FPGA y MCU, ambos dispositivos, obviamente, arrancan con sus E/S en HiZ. Esto significa que pueden ser maestros de la PROM y compartir las mismas líneas, aunque no al mismo tiempo. Entonces, FPGA y MCU arrancan con los pines comunes en HiZ, luego FPGA se configura y desactiva esos pines nuevamente. Después de esto, la MCU es libre de realizar actualizaciones: habilite el SPI, realice la actualización, luego deshabilite el SPI y devuelva esos PIN a HiZ. (Sin embargo, aún no probado)
Sí, eso también funciona. La razón principal por la que sugerí el paso a través es que le brinda la oportunidad de usar esa misma interfaz SPI en el uC para controlar también la lógica de la aplicación en el FPGA si lo desea.
Bueno, la conexión directa significa que la MCU puede programar el flash cuando la FPGA no tiene ninguna configuración cargada. Además, si proporciona una línea de selección de chip separada a la FPGA, entonces la FPGA y la memoria flash SPI pueden comportarse como dos esclavos SPI separados. Recomendaría conectar un par de señales más: a saber, la MCU debe tener la capacidad de restablecer el FPGA y mantenerlo en el reinicio para que pueda acceder al flash SPI sin contención, así como activar el FPGA para cargar la nueva configuración. , y la MCU debería poder saber cuándo la FPGA ha terminado de cargar la configuración.
Para Xilinx, esas señales son PROGRAM_B y DONE. Parece que las señales equivalentes en las partes de Lattice son CRESET_B y CDONE.

a) Afaik, el Atmega tiene solo 1 bus SPI.

b) Sin experiencia (pero soy novato)

c) Uso principalmente STM#2. Estos tienen 2 buses SPI y si necesita más, hay una versión que tiene 3 (o incluso más posiblemente). El más barato (cuesta menos que un Arduino) STM32F103C8T6 tiene 2 buses SPI.

d) Los buses SPI en el STM32 (y probablemente otros UC) son independientes, por lo que no debería haber ningún problema con el proceso. Sin embargo, dado que STM32 tiene DMA, es posible que pueda hacerlo 'directamente', es decir, enviar datos SPI entrantes inmediatamente al SPI saliente.

Gracias por tu respuesta, se ven interesantes los tendré en cuenta por si no se puede hacer nada con el actual.
Buena suerte (por cierto, puedes usar algunos STM32 también con código Arduino). Sin embargo, tenga en cuenta que, en principio, el STM32 también es un paso adelante en complejidad (todavía estoy aprendiendo, siendo un novato).

Usted afirma que el FPGA asume el final de los datos de configuración cuando se anula la afirmación de CS. ¿Hay un tiempo de espera también? Es decir, si puede tener un retraso indefinido mientras deja CS activo, ¿el dispositivo se comportará correctamente?

Si simplemente hay una necesidad de evitar que el dispositivo FPGA cierre la transacción, entonces el problema se puede simplificar como uno de mantener CS seleccionado sin permitir que los comandos al flash se lean como datos basura. Para esto, un segundo maestro SPI puede ser excesivo

Sugeriría usar un dispositivo de búfer entre MCU y FPGA para la línea MISO, MOSIy SCLK, y usarlo para deshabilitar las señales SPI usando el pin de reinicio/habilitación en el dispositivo de búfer.

La transacción se vería como

  1. Afirmar asincrónicamente CS para FPGA
  2. Desactivar dispositivo de búfer
  3. Lea el dispositivo FLASH como de costumbre
  4. Habilitar dispositivo de búfer
  5. Transacción FPGA (CS ya afirmado)
  6. GOTO 2 hasta que termine
  7. De-Assert CS para FPGA de forma asíncrona
De acuerdo con el documento proporcionado sobre la configuración, hay un tiempo de espera (p. 25), pero no está del todo claro si se refiere solo al modo Maestro oa ambos modos Maestro y Esclavo. Además, revisé toda la hoja de datos pero no pude ubicar la hora real. Sin embargo, preferiría una forma de no instalar hardware adicional en este diseño en particular, pero lo tendría en cuenta para futuros diseños, ¡gracias!

USART como maestro SPI

Como dice la hoja de datos en el capítulo 19,

El receptor y transmisor serial síncrono y asíncrono universal (USART) se puede configurar en un modo de operación maestro compatible con SPI.

Entonces puede tener dos puertos SPI (maestros) independientes para transferir datos entre los esclavos.

Uso de una EEPROM externa I 2 C

En lugar de un flash SPI, puede conectar una EEPROM I 2 C al puerto TWI (PD0, PD1) en la MCU. I 2 C se llama TWI o interfaz serial de 2 hilos en Atmel-ese, pero son esencialmente lo mismo. Inconveniente: Las EEPROM son generalmente más caras que las memorias flash.

Sugeriría una parte FRAM, que es una parte similar y generalmente comparte el mismo protocolo I2C, pero tiene tiempos de acceso <100us en lugar de los típicos 5-10ms para EEPROM.