Tengo un problema interesante con el dsPIC33FJ128GP802 .
Lo tengo configurado como un dispositivo SPI esclavo conectado a un Arduino que actúa como maestro.
Timer1 está configurado para desencadenar una interrupción en momentos específicos en una secuencia determinada.
Una de las secuencias de interrupciones tarda aproximadamente 50 µs en ejecutarse. Sí, sé que no es una "buena práctica" tener una rutina de interrupción que dure tanto tiempo, pero solo se está utilizando una única interrupción en el sistema, y las restricciones de tiempo significan que debe durar tanto tiempo.
Ahora, todo está funcionando: la SPI se está ejecutando y recibiendo comandos del Arduino. El Timer1 está activando la interrupción en el momento justo, y todo se ve bien.
Excepto, estoy viendo corrupción en el SPI. Solo puedo asumir que se debe a la interrupción de la activación del Timer1 durante la transferencia de SPI. Si desactivo el temporizador y su interrupción no tengo ningún problema con la transferencia SPI.
Por lo que entiendo de las interrupciones, se supone que todos los registros, etc., están exactamente en el mismo estado cuando el ISR vuelve a ser como estaban cuando se activó la interrupción. Eso es ciertamente lo que afirma el manual del usuario C30.
He intentado volver a escribir mi código C para la recepción SPI en ensamblaje, pero el problema aún persiste.
Aquí hay un fragmento de mi código C:
while(PORTAbits.RA3==1); // Wait for a transfer to be requested
SPI1STATbits.SPIEN=1; // Enable the SPI module
SPI1BUF=0x0; // Prime the buffer to start a transfer
LATAbits.LATA1=0; // Signal to the master it may transfer
while(PORTAbits.RA3==0); // Wait for the master to signal it has transferred
in = SPI1BUF; // Store the resultant word
SPI1STATbits.SPIEN=0; // Turn off the SPI module
... perform operations depending on SPI command received ...
LATAbits.LATA1=1; // Signal to the master the command has finished and it may transfer again.
- RA3 es el pin de selección de esclavos para el SPI
- LATA4 es un handshaking inverso del esclavo al maestro
Ambos son activos-bajos.
Como puede ver, estoy usando más handshaking que SPI normal, ya que necesito retroalimentar desde el esclavo al maestro cuando sea seguro comenzar a transferir otro comando SPI.
Mi ISR se define como:
void __attribute__((__interrupt__,no_auto_psv)) _T1Interrupt(void)
He intentado agregar el atributo __shadow__
para usar los registros en la sombra, pero no ha tenido ningún efecto.
Entonces, ¿qué sucede realmente con el SPI en este chip cuando se activa una interrupción del temporizador? Como se sincroniza independientemente de la CPU principal, y solo cambia los bits dentro / fuera de un registro de desplazamiento, seguramente no debería verse afectado por interrupciones.
Me está yendo bien, por lo que cualquier puntero sería bienvenido.