En tu línea de exploración, interrumpe tu ubicación:
// Then write first DMA words. Successive words requested by SPI module.
// TODO: offset DMA by one word, or we will get duplicates. OR, just write
// a null word first... Whichever is easiest/best.
SPI2BUF = scanline_level_out_dma[0];
SPI1BUF = scanline_mask_out_dma[0];
Simplemente configure DMAxCONbits.FORCE = 1
antes de habilitar el canal DMA y forzará el primer byte tan pronto como el canal DMA esté habilitado.
También puede configurar sus canales de lectura ficticios en modo continuo (en lugar de un solo disparo) con un búfer de 1 palabra e iniciarlos cuando arranque e ignore la interrupción, no es necesario volver a pensar en ellos después de eso.
En su ejemplo de DMA todavía tiene interrupciones SPI definidas:
/**
* _SPI1Interrupt: Primary ISR for SPI1.
*
* Only clears interrupt flag at the moment.
*/
void _MY_ISR _SPI1Interrupt()
{
uint16_t nullread;
nullread = SPI1BUF;
nullread = SPI2BUF;
IFS0bits.SPI1IF = 0;
}
Creo que esto aún se llama cuando DMA está habilitado a menos que deshabilites la interrupción de la CPU, es decir, tanto el controlador DMA como la CPU responden a la interrupción.
Esto parece repetir el trabajo del canal de lectura DMA y, además, es lento (solo use una variable global en lugar de una pila en un ISR como este). También puede estar bloqueando su transferencia, no sé realmente si el controlador DMA restablecería la interrupción mientras la CPU estaba en un controlador para esa interrupción.
¡Aquí está la cosa rara! Si lo hago
utilizando una rutina de bucle continuamente
escribiendo al registro SPI, hay
No hay huecos!
Esto es peligroso si no se comprueba SPIxIF, es muy posible que se esté confundiendo lo que sale y los bytes de prueba lo harían realmente difícil de encontrar.
EDITAR: Dado que su reloj SPI es aproximadamente 1/7 de su reloj de instrucciones, debe tener mucho cuidado en el controlador de interrupciones anterior para borrar SPI1IF ASAP o simplemente deshabilitarlo todo junto y dejar que Controlador DMA manejarlo. Para lograr un espacio sin interrupciones, tiene menos de 7 ciclos de instrucción para eliminar la siguiente palabra de la unidad SPI. Creo que tienes que deshabilitar completamente la intervención de la CPU y simplemente dejar que el controlador DMA se ocupe de él para tener alguna posibilidad, pero incluso entonces tienes 2 transferencias DMA y cualquier latencia de activación que haya desde el SPI - > DMA (su 1 reloj de instrucciones para SPIxIF para disparar, por ejemplo). Así que va a estar cerca.