STM32 DMA: transferencia continua de periférico a memoria (matriz)

Estoy tratando de usar un DMA en modo circular para transferir datos de un ADC a una matriz que contendrá los datos. Necesito usar simultáneamente los datos entrantes (en este caso, estoy usando comandos AT para enviar los datos a través de Wi-Fi con el módulo esp8266)

Me pregunto cómo sería el flujo de software.

Aquí hay algunas preguntas:

  • ¿Cómo sabrá el DMAC cuándo dar la vuelta cuando llegue al final de la matriz? -- es decir, ¿cómo puedo asegurarme de que el DMA no transfiera datos más allá del último índice de matriz? (¿Este límite de tamaño está definido por DMA_BufferSize?)

  • Debido a que quiero usar simultáneamente los datos recopilados, estoy pensando en usar 3 matrices para almacenar los datos. Leería y borraría los datos de una matriz mientras el DMA llena los demás, y se alternaría. ¿Es inteligente y/o posible cambiar el destino DMA constantemente de esta manera?

Gracias.

Respuestas (2)

¿Cómo sabrá el DMAC cuándo dar la vuelta cuando llegue al final de la matriz? -- es decir, ¿cómo puedo asegurarme de que el DMA no transfiera datos más allá del último índice de matriz? (¿Este límite de tamaño está definido por DMA_BufferSize?)

Sí, se detendrá en el límite que establezca o, si habilita el modo circular , comenzará de nuevo y sobrescribirá los datos al comienzo de la matriz. Nunca pasará del límite.

Leería y borraría los datos de una matriz mientras el DMA llena los demás, y se alternaría. ¿Es inteligente y/o posible cambiar el destino DMA constantemente de esta manera?

En el STM32, puede asignar una matriz grande y usar las dos mitades como doble búfer. Hay una interrupción de media transferencia (cuando está habilitada) que le indica que la primera mitad está llena y lista para procesarse y que la segunda mitad se está modificando. Luego obtendrá una interrupción de transferencia completa cuando la segunda mitad esté lista y (en modo circular) continúa actualizando la primera mitad nuevamente.

Por lo tanto, no es necesario cambiar el destino de DMA (no puede hacerlo de todos modos mientras se está ejecutando DMA), pero siempre podrá saber qué mitad está lista examinando los bits de estado de DMA.

En los controladores de gama alta (STM32F4, STM32F7), en realidad hay dos direcciones de memoria para cada canal DMA, las mitades de los búferes no necesitan ser contiguas e incluso puede cambiar la dirección del búfer inactivo sobre la marcha.

Ya veo, eso tiene mucho sentido: no conocía esta característica. ¡Gracias!
No todos los STM32, o más bien sus canales DMA, admiten la interrupción de media transferencia.

Parece que STM32 DMA admite la operación de almacenamiento en búfer doble (no soy un profesional de STM32, por lo que no puedo decirle cuáles son las llamadas API relacionadas). Esto es lo que realmente estás buscando. Así es como lo manejas:

  1. Configure el tamaño y la ubicación de la memoria para dos búferes. Por lo general, esos dos son del mismo tamaño.
  2. Empiezas la transferencia DMA
  3. Una vez que el primer búfer se haya llenado, el controlador DMA comenzará a almacenar automáticamente en el segundo búfer sin datos perdidos.
  4. Al mismo tiempo (cuando el DMA cambia el búfer) recibirá una interrupción que indica que el búfer estaba lleno, ahora es el momento de actuar sobre los datos en el búfer 1 mientras el búfer 2 se está llenando.
  5. Una vez que el búfer 2 se haya llenado, el controlador DMA comenzará a sobrescribir los datos en la primera ubicación del búfer, sin necesidad de eliminar ningún dato ni nada. Nuevamente, recibirá una interrupción y ahora puede trabajar con los datos almacenados en el búfer 2.
  6. Repetir desde el principio

Básicamente, la idea es que el DMA llene un búfer mientras trabaja en el otro, el cambio entre los dos lo maneja el propio controlador DMA y no perderá ningún dato debido al tiempo requerido para cambiar entre búferes si Lo hiciste en el software.

Los datos que se transfieren de una vez son, como dijiste, típicamente programados en uno de los registros DMA, BufferSize suena como el camino a seguir (aunque no puedo confirmar esto para el STM32 ya que no conozco esa plataforma tan bien) .

El tampón doble es una solución limpia. Sin embargo, estoy usando un STM32F0, que no es compatible con esta función.