Estaba probando un experimento de sonido, comenzando con un código de muestra que enviaba datos al códec de audio del Discovery F4 utilizando I2S. El código de muestra utilizó el sondeo en el bucle principal y envió datos cuando el búfer de transmisión estaba vacío.
Configuré un controlador de interrupción para que SPI (en modo I2S) haga lo mismo. Puse una bandera cuando se generó la interrupción y luego esta bandera activó la transmisión de datos en el bucle principal. El problema es que las interrupciones se generaron demasiado rápido y el código en el bucle principal nunca se ejecutó. Tuve que deshabilitar y habilitar las interrupciones para que esto funcione.
void SPI3_IRQHandler ( void )
{
STM_EVAL_LEDToggle(LED3); // NC
if (SPI_I2S_GetITStatus(SPI3, SPI_I2S_IT_TXE) != RESET) {
SPI_I2S_ClearITPendingBit(SPI3, SPI_I2S_IT_TXE);
if (SPI_I2S_GetFlagStatus(CODEC_I2S, SPI_I2S_FLAG_TXE)) {
STM_EVAL_LEDToggle(LED4);
transferFlag = true;
ready = false;
__disable_irq();
}
}
}
Bucle principal:
while(1)
{
STM_EVAL_LEDToggle(LED6);
if (transferFlag){
STM_EVAL_LEDToggle(LED5);
//generate the sound
SPI_I2S_SendData(CODEC_I2S, value);
transferFlag = false;
__enable_irq();
}
}
Incluso hice que el sonido de generación fuera muy simple (como valor = 1000), y aún así no funcionó, sin habilitar y deshabilitar las interrupciones. De hecho, LED5 y LED6 nunca se encendieron, lo que indica que no se ingresó al bucle principal. Además, coloqué el código de "generación de sonido y transmisión a SPI" en el controlador de interrupción. Esto funcionó, pero el sonido era más suave que el código actual que se muestra arriba.
El Cortex M4 en el STM definitivamente no es tan lento, la FPU también está encendida. Planeo hacer una versión DMA de esto, pero no creo que activar y desactivar las interrupciones es una buena solución.