Autor Tema: memcpy - DMA/SPI  (Leído 5344 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado planeta9999

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 3520
    • Pinballsp
Re:memcpy - DMA/SPI
« Respuesta #15 en: 16 de Octubre de 2017, 02:02:05 »
O sea que implementaste una demora para que el DMA termine de transferir los datos y recien alli hacer el memcpy?.

Si, eso es.

Citar
Pense que usabas una interrupcion para saber cuando es que el DMA finaliza de enviar los datos y asi moverlos con el memcpy..
Y aca mi miedo era una posible sobre escritura de alguna posicion.

Eso lo probé y no me funcionó bien, es una interrupción por buffer del DMA completo. Me desplazaba lateralmente la imagen de vez en cuando, una pesadilla.

    dmaSPI0rx->interruptAtCompletion();


Ahora lo hago con una interrupción por un pulso de sincronismo de inicio de linea, que me salta a la rutina donde entre otras cosas hago el memcpy de buffer del DMA.

attachInterrupt(digitalPinToInterrupt(DMD_ROW_CLK), portb_isr_wpc, RISING);


Citar
Realmente sigo sin entender, y estoy mas que seguro que el problema es otro a pesar que esto lo solucione, la transferencia del DMA es por bytes, no tiene otro sentido, es decir por hardware no vas a implementar un shift register en todas las posiciones de memoria RAM, y en los perifericos, mas en una FIFO que posee el SPI.

Ademas eso implicaria que el procesador tambien cuando necesite leer un registro de un periferico y/o memoria RAM lo haga de esa forma.

Pues no lo se, pero ha sido retrasar un poco la llamada al memcpy y se arregló todo, yo no le veo otra explicación. Además jugando con la duración del bucle, se desplazaba la imagen más o menos pixels.

Como la carga del buffer del DMA es independiente de la CPU, mientras se está ejecutando el bucle de retardo, el buffer del DMA se sigue llenando solo, y con ese pequeño retardo ha sido suficiente para capturar el buffer completo, los 128 puntos que tiene cada linea de la pantalla.

« Última modificación: 16 de Octubre de 2017, 02:16:05 por planeta9999 »

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:memcpy - DMA/SPI
« Respuesta #16 en: 16 de Octubre de 2017, 10:19:51 »
Citar
Además jugando con la duración del bucle, se desplazaba la imagen más o menos pixels.

Eso suena a atado con alambre :P, Un provisorio para siempre.
Pero si funciona.... adelante con eso xD jeje.

Vi el video esta espetacular planeta.

Desconectado planeta9999

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 3520
    • Pinballsp
Re:memcpy - DMA/SPI
« Respuesta #17 en: 13 de Diciembre de 2017, 12:19:52 »
Código: C
  1. // Flush the receive buffer, in case we're out of sync
  2.     SPI0_MCR |= SPI_MCR_HALT;
  3.     SPI0_MCR |= SPI_MCR_CLR_RXF;

Basicamente detiene cualquier transferencia del SPI (TX,RX) y hace un flush de los buffer de Recepcion, limpiando tambien los contadores de cantidad de datos que poseen.
Pero si esta configurado como modo continuo entonces no hace nada.


Esto me tiene intrigado. Tengo un problema con la recepción de datos en mis pantallas Led, el caso es que a veces, de manera aleatoria la imagen se desplaza lateralmente y se queda ya desplazada.

Tiene que ser un problema del DMA, que es el que alimenta los datos por SPI. Sospecho que de vez en cuando entra algún pulso fantasma, tipo interferencia que hace que se lean los datos del buffer del DMA cuando no toca. Por SPI/DMA se reciben y cargan en una matriz interna, bloques de 128 bits (1 linea de la imagen), y después de cada carga de esos bits, en teoría se para el SPI, se borra su buffer, y se resetea el DMA para iniciar una nueva captura de datos (una nueva linea de la imagen).

Aún entrando de vez en cuando alguna interferencia, si cada vez que se reciben 128 bits en el buffer del DMA, correspondientes a los puntos de una linea de la pantalla, todo se borra y vuelta a empezar, no entiendo como la imagen se queda desplazada de manera continua.


Es como si el buffer del DMA se quedará con datos, no se si tiene que ver algo lo del "modo continuo" del DMA (¿ modo circular ?).

¿ Alguna idea, con el fuente que pongo bajo realmente se está vaciando todo, el buffer del SPI y el buffer del DMA ?


Configuración de SPI y DMA en el arranque del programa.
====================================
 
// Configura pines para SPI0
CORE_PIN10_CONFIG = PORT_PCR_MUX(2) | PORT_PCR_PE | PORT_PCR_PS;
 
// Activa reloj para SPI0
SIM_SCGC6 |= SIM_SCGC6_SPI0;
SPI0_MCR = SPI_MCR_HALT | SPI_MCR_MDIS | SPI_MCR_PCSIS(1<<0);
 
// Transferencia 16 bit, on rising edge
SPI0_CTAR0_SLAVE = SPI_CTAR_FMSZ(15);

// Enable FIFO Drain Request DMA

SPI0_RSER = SPI_RSER_RFDF_RE | SPI_RSER_RFDF_DIRS;
dmaSPI0rx = new DMAChannel();
dmaSPI0rx->source((volatile uint16_t&) SPI0_POPR);
dmaSPI0rx->destinationBuffer(plane_buffer, ROW_LENGTH * sizeof(uint16_t));
dmaSPI0rx->triggerAtHardwareEvent(DMAMUX_SOURCE_SPI0_RX);

// Adjust isr priorities so SPI0 input preempts PORTB input  NVIC_SET_PRIORITY(IRQ_PORTB, 32);
NVIC_SET_PRIORITY(IRQ_SPI0, 0);
NVIC_DISABLE_IRQ(IRQ_PORTB);

// Arranca SPI
SPI0_MCR &= ~SPI_MCR_HALT & ~SPI_MCR_MDIS;
digitalWriteFast(DMD_CS, LOW);
NVIC_ENABLE_IRQ(IRQ_PORTB);
dmaSPI0rx->enable();


Por una interrupción ligada a una señal de sincronismo externa, salta a una función para copiar los datos del buffer de DMA (128 bits, correspondientes a una linea de la imagen). En teoría, luego lo reinicia todo, el buffer del SPI y el buffer del DMA, previamente para ambos.
===============================================================
   
// Para SPI, y vacía el buffer RX FIFO

SPI0_MCR |= SPI_MCR_HALT; // Detiene el módulo SPI
SPI0_MCR |= SPI_MCR_CLR_RXF; // Borra el RX FIFO, manteniendo el SPI detenido.

// Resetea la transferencia del DMA

dmaSPI0rx->disable();
dmaSPI0rx->clearComplete();
dmaSPI0rx->destinationBuffer(plane_buffer, ROW_LENGTH * sizeof(uint16_t));
dmaSPI0rx->enable();
   
// Arranca SPI de nuevo

SPI0_MCR &= ~SPI_MCR_HALT; // Inicia el módulo SPI, para que se ejecute nuevamente
digitalWriteFast(DMD_CS, LOW);
« Última modificación: 13 de Diciembre de 2017, 12:49:50 por planeta9999 »


 

anything