#include "ch.h" #include "hal.h" #include "chprintf.h" #include "serial_output.h" #include "sound.h" // This is called when the board boots up with the user button pressed. The // idea is to enter this mode if the wrong SPI device has been used and flashing // is no longer possible. __attribute__ ((noreturn)) static void lockdown( void ) { palSetPad( GPIOD , GPIOD_LED3 ); while (TRUE) { // EMPTY } } static int increment; static int curPos; static const s16 sinTable[16384] = { #include "sin_table.h" }; void debug(void) { chprintf( (void*)&SD2 , "I2S:\r\n" ); chprintf( (void*)&SD2 , " CR2 %x\r\n" , SPI3->CR2 ); chprintf( (void*)&SD2 , " SR %x\r\n" , SPI3->SR ); chprintf( (void*)&SD2 , " CFG %x\r\n" , SPI3->I2SCFGR ); chprintf( (void*)&SD2 , " PR %x\r\n" , SPI3->I2SPR ); chprintf( (void*)&SD2 , "DMA:\r\n" ); chprintf( (void*)&SD2 , " CR %x\r\n" , SPID3.dmatx->stream->CR ); chprintf( (void*)&SD2 , " NDT %x\r\n" , SPID3.dmatx->stream->NDTR ); chprintf( (void*)&SD2 , " PAR %x\r\n" , SPID3.dmatx->stream->PAR ); chprintf( (void*)&SD2 , " M0A %x\r\n" , SPID3.dmatx->stream->M0AR ); chprintf( (void*)&SD2 , " M1A %x\r\n" , SPID3.dmatx->stream->M1AR ); chprintf( (void*)&SD2 , " FCR %x\r\n" , SPID3.dmatx->stream->FCR ); chprintf( (void*)&SD2 , "curPos: %d\r\n" , curPos ); } __attribute__ ((noreturn)) int main( void ) { halInit(); chSysInit(); if ( palReadPad( GPIOA , GPIOA_BUTTON ) ) { lockdown( ); } soInit( ); chprintf( (void*)&SD2 , "Sound card initialisation\r\n" ); sndInit( 11025 ); chprintf( (void*)&SD2 , "Sound card initialisation complete\r\n" ); increment = 654; // 16384 * 440 / 11025 curPos = 0; debug( ); #ifdef USE_DMA_FOR_SEXY_BEEPS int i = 0; while ( 1 ) { s16 * buffer = sndGetBuffer( ); if ( buffer == NULL ) { i ++; if ( i == 2000000 ) { i = 0; palTogglePad( GPIOD , GPIOD_LED4 ); debug( ); } continue; } palTogglePad( GPIOD , GPIOD_LED3 ); int z; for ( z = 0 ; z < SND_BUFSIZE / 2 ; z ++ ) { buffer[ z * 2 ] = buffer[ z * 2 + 1 ] = sinTable[ curPos ]; curPos = ( curPos + increment / 2 ) % 16384; } } #else // USE_DMA_FOR_SEXY_BEEPS int i = 0; while ( 1 ) { u16 sr = SPI3->SR; if ( ( sr & 0x2 ) == 0 ) { continue; } SPI3->DR = sinTable[ curPos ]; if ( ( sr & 0x4 ) == 0 ) { curPos = ( curPos + increment ) % 16384; } i ++; if ( i == 22100 ) { i = 0; palTogglePad( GPIOD , GPIOD_LED4 ); debug( ); } } #endif // USE_DMA_FOR_SEXY_BEEPS }