¿Cómo utilizar mejor SPI (maestro/esclavo)?

Esta es una nueva perspectiva de seguimiento con respecto a mi pregunta anterior Mensajes para el protocolo SPI .

Una idea de esa pregunta es usar la línea SS para saber que se está enviando un nuevo mensaje del maestro al esclavo. El maestro será el STM32 y el esclavo el Arduino, ver a continuación:

  Slave   <---  Master
 Arduino  (SPI) STM32
   |            ^ ^ ^
   V            | | |
RS485/DMX512   3x UART/MIDI

El maestro recibe señales MIDI de varias fuentes, las procesa, transmite mensajes MIDI (cambiados) y envía mensajes SPI al Arduino que envía las señales DMX.

Hasta ahora todo bien, actualmente estoy implementando el código Arduino (incluida una aplicación de prueba de Windows).

La razón por la que uso un Arduino para RS485/DMX es principalmente porque no pude hacerlo funcionar en un STM32, pero también para aliviar la potencia de procesamiento del STM32.

Sin embargo, necesito más SRAM en Arduino, así que usaré un chip SPI SRAM (32K256). El problema es que no estoy seguro de poder dejar que Arduino sea el esclavo.

SPI RAM 32K256
    |(SPI)
    V
   Slave   <---  Master
  Arduino  (SPI) STM32
    |            ^ ^ ^
    V            | | |
RS485/DMX512     3x UART/MIDI

Algunas cosas que consideré:

  • Hacer que Arduino sea el maestro y sondear al STM32 (lo que resulta en mis eventos de encuesta inútiles).
  • Mantener el maestro STM32 y cuando un envío falla al volver a intentarlo.
  • Usando I2C pero creo que SPI es más fácil de implementar.

Afaik, la comunicación debe ser completamente síncrona, pero no estoy seguro de si hay algo de 'relajación' debido a los búferes dentro de los periféricos SPI.

Más información de fondo sobre todo el proyecto:

  • El STM32 lee entradas de varias entradas MIDI (principalmente sintetizadores)
  • En una etapa posterior, también podría agregar otras entradas (no MIDI).
  • El STM32 procesa estos mensajes y envía mensajes y comandos MIDI para el esclavo Arduino.
  • El esclavo Arduino procesa los mensajes que pueden ser algo como (hacer que todas las luces DMX frontales se desvanezcan entre rojo y azul, hacer que las luces X e Y sean verdes, encender el estroboscopio con velocidad 50, etc.). Todos estos mensajes tienen la misma longitud (18 bytes).
  • Para cada luz DMX (17 hasta ahora, pero puede aumentar en el futuro), tengo una clase (instancia) que guarda información (máximo 64 bytes) por luz, esto no cabe en un Arduino, así que uso SRAM externo.
  • Con la mayor frecuencia posible (pero al menos cada pocos ms), el Arduino procesa una luz, leyendo sus datos de la SRAM y cambiando los colores de desvanecimiento, y también procesa nuevos comandos del maestro, si los hay. Y finalmente guardando los datos modificados en SRAM.

Cualquier idea sería útil.

Dependiendo de la velocidad que necesite, la implementación de SPI en una base de bit banging es bastante sencilla y, por lo general, muy tolerante con los tiempos de bits variables.
@PeterSmith Para la conexión Arduino-32K256, quiero una comunicación muy rápida, para la conexión Arduino-STM32 no necesito altas velocidades (probablemente). En realidad, no creo que pueda cambiar fácilmente la velocidad SPI de todos modos, así que tengo que encontrar un valor 'bueno'.
Una idea: las comunicaciones de esclavos de vuelta a un maestro suelen ser las más vulnerables para ser recibidas correctamente.
Según su segundo diagrama, parece que Arduino necesita una interfaz maestra SPI para comunicarse con la SRAM y una interfaz esclava SPI para recibir mensajes del STM32. ¿Hay alguna razón por la que esto no es factible?
@Andyaka, entonces, ¿cuál sería una buena solución si el esclavo usa 2 dispositivos SPI? (y tiene solo un periférico SPI)
@DaveTweed ... sí ... un Arduino tiene solo un periférico SPI.
Entonces, hazlo, o usa algún otro protocolo. Dices que el enlace STM -> Arduino tiene un ancho de banda relativamente bajo. ¿Puedes ponerle números reales a eso?
Suena como un problema XY. ¿Necesitas 32 kilobytes de SRAM en Arduino para qué? Me imagino que Arduino es solo la parte que envía continuamente el último paquete DMX completo que el STM32 le indicó que enviara. Describa con más detalle qué MCU hace qué en el sistema.
@DaveTweed, ¿te refieres a no usar ningún protocolo SPI/I2C? No pensé en esto, pero podría ser posible. ... probablemente el número real es muy bajo (alrededor de 20 bytes cada 20 ms, pero probablemente puede ser incluso más lento).
Yo no dije eso. Vea el primer comentario de @PeterSmith.
@Justme lo agregué al final (espero que sea suficiente).
@DaveTweed, lo siento, estoy un poco confundido... ¿hay una implementación de SPI que no funcione?

Respuestas (1)

Hacer que Arduino sea el maestro y sondear al STM32 (lo que resulta en mis eventos de encuesta inútiles probablemente)

Quizás pueda tener una línea de "interrupción" adicional desde el STM32 al Arduino para indicar cuándo hay datos disponibles. Podría desencadenar directamente una interrupción en el Arduino.

esquemático

simular este circuito : esquema creado con CircuitLab

Si tiene paquetes de datos de tamaño fijo, los periféricos STM32 SPI+DMA pueden manejar el tráfico esclavo SPI de forma autónoma, sin ninguna intervención de la CPU después de que se active la línea de interrupción (OK, la señal debe restablecerse eventualmente, una interrupción de transferencia DMA completa o una -disparo temporizador puede hacer eso).

Esto suena muy útil, nunca probé SPI + DMA pero es bueno probar eso.
Gracias... y dos pequeñas preguntas adicionales (no creo que el Arduino tenga DMA, pero supongo que puedo usarlo en el STM32 (más útil también, porque ese será el dispositivo crítico), y qué significa el pin NSS (N??? Seleccionar esclavo) ?
@MichelKeijzers 1. Sí, DMA está del lado de STM32. Puede alimentar el registro de datos SPI a toda velocidad, sin ralentizar notablemente la ejecución del programa (lo estoy usando, por ejemplo, para actualizar las pantallas SPI en segundo plano). 2. Por alguna razón, Chip Select se llama NSSen la documentación de ST. I N verted / N egated S lave S elect, supongo.
Gracias por la información adicional (por cierto, también planeo agregar una pantalla, pero tengo la intención de usar I2C para eso, ya que tengo un módulo I2C 1602 y 2004. Con suerte, STM (si alguna vez termino la parte anterior) ) obtener más entradas (como IR, nRF y tal vez incluso más) y ser reemplazado por un STM32F4VET6 (en lugar de STM32F1C8T6).
@MichelKeijzers Si actualiza el controlador ST, ciertamente podría ahorrar algo de RAM y ciclos para mantener las estructuras de datos de las luces también, haciendo innecesaria la parte adicional de SRAM.
cierto, pero necesitaría enviar comandos muy específicos muy rápido. Quiero decir, ahora puedo, por ejemplo, enviar desde STM-> Arduino: Fade lights de rojo a verde. En el Arduino, esto se traduce en cada tantos ms, para cambiar la luz lentamente.
Si hiciera eso en el STM, entonces 1) enviaría muchos comandos, 2) el STM tendría que hacer mucho más trabajo... Lo que podría hacer es agregar otro STM en el medio para hacer todo el procesamiento , por lo tanto, STM (lee MIDI y envía comandos) -> STM (comando-> mensajes DMX) -> Arduino (realmente envía mensajes DMX). Eso necesitaría un STM adicional, pero ahorro en el 32K256 y solo necesito un SPI en el Arduino.