Tengo algunas preguntas sobre el uso del DMA de la placa stm32f7 (nucleo F722ZE).
1) Entonces, para comenzar, explicaré lo que estoy haciendo:
Necesito leer datos de 2 pines GPIO (ADC) y tendré una señal de reloj alimentada al stm32f7 desde el dispositivo que suministra los datos. Planeo dejar que la señal del reloj active un temporizador de interrupción y cada vez que se active el temporizador quiero que el DMA haga una transferencia de memoria a periférico. La memoria será de 2 bits en el puerto GPIO con el periférico siendo una línea SPI acoplada a una tarjeta SD.
2) Acceso a los datos:
Me referí al manual de Arm Cortex 7 y encontré lo siguiente:
El puerto GPIOC se asigna a 0x40020800-0x40020BFF y los registros de datos de entrada se establecen en un desplazamiento de 0x14 .
Así que tomo el registro base asignado a la memoria (0x40020800 y le agrego 0x14). Por lo tanto, la dirección de origen que proporciono a la DMA será 0x40020814.
3) Hacer que el DMA desplace estos datos.
Este podría ser el problema más grande. Una vez que tenga los datos en los pines GPIO, esencialmente los recibiré bit por bit y los datos en realidad tienen una longitud de 24 bits, por pin. Entonces, en total, cada pin gpio recibirá paquetes de datos de 24 bits. Aunque cuando la señal externa active el temporizador, solo tendré un bit en cada uno de los GPIO.
¿Hay alguna manera de que el DMA pueda extraer los datos de forma selectiva poco a poco, hasta que tenga los 24 bits y luego enviarlos a través del SPI? ¿Usando algún tipo de transferencia de búfer y ráfaga? De lo contrario, parece que el DMA puede hacer una transferencia mínima de un byte, lo que requerirá que envíe cantidades masivas de bits basura por cada bit que transfiera.
Finalmente: para resumir, no estoy seguro de la ubicación de los datos GPIO, ¿es correcta la dirección que puse y no estoy completamente seguro de cómo hacer que el DMA transfiera estos datos?
¡Cualquier ayuda será apreciada!
GPIOA -> MODER
por ejemplo. Hay todas las definiciones de bits también en forma legible por humanos.1) Esto suena como SPI . ¿Tenemos un problema XY ?
2) Necesitaría el GPIO port input data register (GPIOx_IDR) (x = A..K)
, que está en el desplazamiento 0x10 del periférico GPIO base. La dirección base de cada periférico se encuentra en el encabezado stm32f7 o en la Tabla 1 del manual de referencia. (RM0385: Tabla 1) Puede acceder a los registros GPIO en modo palabra, media palabra o byte. (RM0385: 6.4) Nota: no puede acceder a todos los periféricos en todos los anchos.
3) No es la forma más eficiente con el DMA, la tasa de bits sería baja (kHz), pero se puede hacer.
La salida de bits con DMA funciona igual, excepto que debe usar el GPIO port bit set/reset register (GPIOx_BSRR) (x = A..K)
para no cambiar IO irrelevante.
una línea SPI acoplada a una tarjeta SD
Tiene STM32F722ZE
interfaces SDMMC dedicadas que son significativamente más rápidas que SPI, especialmente si conecta los 4 pines de datos.
Así que tomo el registro base asignado a la memoria (0x40020800 y le agrego 0x14). Por lo tanto, la dirección de origen que proporciono a la DMA será 0x40020814.
Eso estaría bien si tuviera la dirección correcta ( IDR
está en desplazamiento 0x10
), pero sería aún mejor usar las definiciones de los encabezados estándar
DMAx->SyPAR = (uint32_t)&(GPIOC->IDR);
y luego sería obvio para todos los que miran su código de qué se trata este fragmento de código. Además, ayuda a evitar errores en el cálculo de direcciones.
¿Hay alguna manera de que el DMA pueda extraer los datos de forma selectiva poco a poco, hasta que tenga los 24 bits y luego enviarlos a través del SPI?
Conecte cada línea de datos a un controlador SPI diferente (hay 5 de ellos), conecte la línea de reloj a ambos. Deje que cada uno llene un búfer de 256 bytes (con DMA), uno al lado del otro, para mantener contento al controlador SD con un tamaño de bloque de 512 bytes (2 * búferes de 2048 bytes pueden ser incluso mejores). Cuando los búferes están llenos, escriba el bloque completo en la tarjeta, mientras que los canales SPI DMA pueden cambiar automáticamente a búferes secundarios en una dirección diferente. Es posible que desee usar más de 2 búferes alternos para permitir las actualizaciones del sistema de archivos, si está usando alguno (FATFS puede ser terriblemente lento al actualizar la tabla FAT). Supongo que puede volver a ensamblar los bits más tarde, cuando realmente procese los datos.
siguió a Mónica a Codidact
Jeroen3