DISCO-F746NGのAudioOutから正弦波をスイープとして出力します。ダブルバッファリングを使って、リアルタイムにデータ生成をしています。 This program outputs sine sweep from AudioOut on DISCO-F746NG. The program uses double buffering when generates data signals.
Dependencies: BSP_DISCO_F746NG_patch_fixed LCD_DISCO_F746NG mbed
Revision 0:ece4ec581d2b, committed 2015-12-26
- Comitter:
- nanase
- Date:
- Sat Dec 26 07:20:53 2015 +0000
- Commit message:
- First commit
Changed in this revision
diff -r 000000000000 -r ece4ec581d2b BSP_DISCO_F746NG_patch_fixed.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/BSP_DISCO_F746NG_patch_fixed.lib Sat Dec 26 07:20:53 2015 +0000 @@ -0,0 +1,1 @@ +https://developer.mbed.org/users/the_sz/code/BSP_DISCO_F746NG_patch_fixed/#3c0a51826ecc
diff -r 000000000000 -r ece4ec581d2b BSP_overwrite.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/BSP_overwrite.cpp Sat Dec 26 07:20:53 2015 +0000 @@ -0,0 +1,102 @@ +#include "main.h" + +void BSP_AUDIO_OUT_HalfTransfer_CallBack(void) +{ + fill_buffer(0, BufferSize / 2); + BSP_AUDIO_OUT_ChangeBuffer((uint16_t*)&sweep_buffer[0], BufferByteSize / 2); +} + +void BSP_AUDIO_OUT_TransferComplete_CallBack(void) +{ + fill_buffer(BufferSize / 2, BufferSize / 2); + BSP_AUDIO_OUT_ChangeBuffer((uint16_t*)&sweep_buffer[BufferSize / 2], BufferByteSize / 2); +} + +void BSP_AUDIO_OUT_Error_CallBack(void) +{ + error_trap(); +} + +DMA_HandleTypeDef hdma_sai_tx; + +void AUDIO_OUT_SAIx_DMAx_IRQHandler(void) +{ + HAL_DMA_IRQHandler(&hdma_sai_tx); +} + +void BSP_AUDIO_OUT_MspInit(SAI_HandleTypeDef *hsai, void *Params) +{ + //static DMA_HandleTypeDef hdma_sai_tx; + GPIO_InitTypeDef gpio_init_structure; + + /* Enable SAI clock */ + AUDIO_OUT_SAIx_CLK_ENABLE(); + + /* Enable GPIO clock */ + AUDIO_OUT_SAIx_MCLK_ENABLE(); + AUDIO_OUT_SAIx_SCK_SD_ENABLE(); + AUDIO_OUT_SAIx_FS_ENABLE(); + + /* CODEC_SAI pins configuration: FS, SCK, MCK and SD pins ------------------*/ + gpio_init_structure.Pin = AUDIO_OUT_SAIx_FS_PIN; + gpio_init_structure.Mode = GPIO_MODE_AF_PP; + gpio_init_structure.Pull = GPIO_NOPULL; + gpio_init_structure.Speed = GPIO_SPEED_HIGH; + gpio_init_structure.Alternate = AUDIO_OUT_SAIx_FS_SD_MCLK_AF; + HAL_GPIO_Init(AUDIO_OUT_SAIx_FS_GPIO_PORT, &gpio_init_structure); + + gpio_init_structure.Pin = AUDIO_OUT_SAIx_SCK_PIN; + gpio_init_structure.Mode = GPIO_MODE_AF_PP; + gpio_init_structure.Pull = GPIO_NOPULL; + gpio_init_structure.Speed = GPIO_SPEED_HIGH; + gpio_init_structure.Alternate = AUDIO_OUT_SAIx_SCK_AF; + HAL_GPIO_Init(AUDIO_OUT_SAIx_SCK_SD_GPIO_PORT, &gpio_init_structure); + + gpio_init_structure.Pin = AUDIO_OUT_SAIx_SD_PIN; + gpio_init_structure.Mode = GPIO_MODE_AF_PP; + gpio_init_structure.Pull = GPIO_NOPULL; + gpio_init_structure.Speed = GPIO_SPEED_HIGH; + gpio_init_structure.Alternate = AUDIO_OUT_SAIx_FS_SD_MCLK_AF; + HAL_GPIO_Init(AUDIO_OUT_SAIx_SCK_SD_GPIO_PORT, &gpio_init_structure); + + gpio_init_structure.Pin = AUDIO_OUT_SAIx_MCLK_PIN; + gpio_init_structure.Mode = GPIO_MODE_AF_PP; + gpio_init_structure.Pull = GPIO_NOPULL; + gpio_init_structure.Speed = GPIO_SPEED_HIGH; + gpio_init_structure.Alternate = AUDIO_OUT_SAIx_FS_SD_MCLK_AF; + HAL_GPIO_Init(AUDIO_OUT_SAIx_MCLK_GPIO_PORT, &gpio_init_structure); + + /* Enable the DMA clock */ + AUDIO_OUT_SAIx_DMAx_CLK_ENABLE(); + + if(hsai->Instance == AUDIO_OUT_SAIx) { + /* Configure the hdma_saiTx handle parameters */ + hdma_sai_tx.Init.Channel = AUDIO_OUT_SAIx_DMAx_CHANNEL; + hdma_sai_tx.Init.Direction = DMA_MEMORY_TO_PERIPH; + hdma_sai_tx.Init.PeriphInc = DMA_PINC_DISABLE; + hdma_sai_tx.Init.MemInc = DMA_MINC_ENABLE; + hdma_sai_tx.Init.PeriphDataAlignment = AUDIO_OUT_SAIx_DMAx_PERIPH_DATA_SIZE; + hdma_sai_tx.Init.MemDataAlignment = AUDIO_OUT_SAIx_DMAx_MEM_DATA_SIZE; + hdma_sai_tx.Init.Mode = DMA_CIRCULAR; + hdma_sai_tx.Init.Priority = DMA_PRIORITY_HIGH; + hdma_sai_tx.Init.FIFOMode = DMA_FIFOMODE_ENABLE; + hdma_sai_tx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL; + hdma_sai_tx.Init.MemBurst = DMA_MBURST_SINGLE; + hdma_sai_tx.Init.PeriphBurst = DMA_PBURST_SINGLE; + + hdma_sai_tx.Instance = AUDIO_OUT_SAIx_DMAx_STREAM; + + /* Associate the DMA handle */ + __HAL_LINKDMA(hsai, hdmatx, hdma_sai_tx); + + /* Deinitialize the Stream for new transfer */ + HAL_DMA_DeInit(&hdma_sai_tx); + + /* Configure the DMA Stream */ + HAL_DMA_Init(&hdma_sai_tx); + } + + /* SAI DMA IRQ Channel configuration */ + HAL_NVIC_SetPriority(AUDIO_OUT_SAIx_DMAx_IRQ, AUDIO_OUT_IRQ_PREPRIO, 0); + HAL_NVIC_EnableIRQ(AUDIO_OUT_SAIx_DMAx_IRQ); +}
diff -r 000000000000 -r ece4ec581d2b LCD_DISCO_F746NG.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/LCD_DISCO_F746NG.lib Sat Dec 26 07:20:53 2015 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/teams/ST/code/LCD_DISCO_F746NG/#d44525b1de98
diff -r 000000000000 -r ece4ec581d2b common.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common.cpp Sat Dec 26 07:20:53 2015 +0000 @@ -0,0 +1,22 @@ +#include "main.h" + +DigitalOut led1(LED1); + +void error_trap() +{ + printlcd("### ERROR"); + while(1) { + led1 = !led1; + wait_ms(250); + } +} + +void printlcd(const char *str) +{ + printlcdAt(str, 0); +} + +void printlcdAt(const char *str, uint16_t line) +{ + lcd.DisplayStringAt(0, LINE(line), (uint8_t *)str, LEFT_MODE); +} \ No newline at end of file
diff -r 000000000000 -r ece4ec581d2b main.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Sat Dec 26 07:20:53 2015 +0000 @@ -0,0 +1,64 @@ +#include "main.h" + +LCD_DISCO_F746NG lcd; +int16_t sweep_buffer[BufferSize]; +double sweep_phase = 0.0; +double sweep_freq = MinFreq; + +void init_audio() +{ + if (BSP_AUDIO_OUT_Init(OUTPUT_DEVICE_BOTH, AudioVolume, SamplingFreq) == AUDIO_ERROR) + error_trap(); + + NVIC_SetVector(AUDIO_OUT_SAIx_DMAx_IRQ, (uint32_t)&AUDIO_OUT_SAIx_DMAx_IRQHandler); + BSP_AUDIO_OUT_SetAudioFrameSlot(CODEC_AUDIOFRAME_SLOT_02); +} + +void play_audio() +{ + if (BSP_AUDIO_OUT_Play((uint16_t*)&sweep_buffer, BufferByteSize) == AUDIO_ERROR) + error_trap(); +} + +void fill_buffer(uint32_t offset, uint32_t size) +{ + static double sweep_freq_delta = 1.0 + SweepSpeed; + double sweep_phase_delta = 1.0 / SamplingFreq; + double new_freq; + + for (int i = 0, j = offset; i < size / 2; i++ ) { + int16_t value = (int16_t)(Amplifier * sin(2.0 * PI * sweep_freq * sweep_phase) * 32767.5); + sweep_buffer[j++] = value; + sweep_buffer[j++] = value; + + sweep_phase += sweep_phase_delta; + } + + new_freq = sweep_freq * sweep_freq_delta; + sweep_phase = sweep_phase * sweep_freq / new_freq; + sweep_freq = new_freq; + + if (sweep_freq > MaxFreq) + sweep_freq_delta = 1.0 - SweepSpeed; + else if (sweep_freq < MinFreq) + sweep_freq_delta = 1.0 + SweepSpeed; +} + +int main() +{ + char strbuf[64]; + + lcd.Clear(LCD_COLOR_BLACK); + lcd.SetBackColor(LCD_COLOR_BLACK); + lcd.SetTextColor(LCD_COLOR_WHITE); + lcd.SetFont(&Font12); + + init_audio(); + play_audio(); + + while(1) { + sprintf(strbuf, "Freq: %.2f Hz, Phase: %.2f ", sweep_freq, sweep_phase); + printlcdAt(strbuf, 0); + wait_ms(100); + } +} \ No newline at end of file
diff -r 000000000000 -r ece4ec581d2b main.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.h Sat Dec 26 07:20:53 2015 +0000 @@ -0,0 +1,27 @@ +#include "mbed.h" +#include "stm32746g_discovery_audio.h" +#include "LCD_DISCO_F746NG.h" + +#define PI ((double)3.1415926535897932384626433832795028) +#define SamplingFreq I2S_AUDIOFREQ_16K +#define BufferSize (1024) /* Sample Size */ +#define BufferByteSize (BufferSize * AUDIODATA_SIZE) /* Byte Size */ + +#define AudioVolume ((uint8_t)8) +#define Amplifier ((double)0.25) + +#define MaxFreq ((double)8000) +#define MinFreq ((double)50) +#define SweepSpeed ((double)0.01) + +extern LCD_DISCO_F746NG lcd; +extern DigitalOut led1; +extern int16_t sweep_buffer[BufferSize]; + +void AUDIO_OUT_SAIx_DMAx_IRQHandler(); + +void error_trap(); +void printlcd(const char *str); +void printlcdAt(const char *str, uint16_t line); + +void fill_buffer(uint32_t offset, uint32_t size);
diff -r 000000000000 -r ece4ec581d2b mbed.bld --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Sat Dec 26 07:20:53 2015 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/4336505e4b1c \ No newline at end of file