dsPIC33, SPI slave y Timer1 se interrumpe. ¿Lo que pasa?

4

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.

    
pregunta Majenko

1 respuesta

1

Normalmente, configuraría el periférico SPI una vez y luego lo dejaría encendido. El apretón de manos adicional que está haciendo le impide utilizar el hardware en toda su capacidad. También hacer una espera ocupada para que el maestro haga una selección de esclavos es una mala idea si alguna vez desea que el procesador haga otra cosa.

Como está transfiriendo 16 bits de menos por mensaje, dejaría que el hardware se encargara de ello. Luego, puede monitorear el indicador de interrupción SPI para determinar cuándo se han recibido nuevos datos del maestro. Si necesita reducir la velocidad del maestro por razones de control de flujo, lo haría fuera del mensaje SPI. Sospecho que la interrupción está agregando latencia a su esquema de intercambio de manos, y algo en algún lugar no está bien y no puede tolerar esa latencia. Suponiendo que la interrupción no intente tocar el hardware de SPI ni ninguna de sus líneas de E / S.

    
respondido por el Olin Lathrop

Lea otras preguntas en las etiquetas