SPKT
Revision 0:f255629eada1, committed 2019-06-07
- Comitter:
- phungductung
- Date:
- Fri Jun 07 05:10:10 2019 +0000
- Commit message:
- spkt; ;
Changed in this revision
diff -r 000000000000 -r f255629eada1 Array_Matrix.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Array_Matrix.lib Fri Jun 07 05:10:10 2019 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/MikamiUitOpen/code/Array_Matrix/#a25dba17218c
diff -r 000000000000 -r f255629eada1 BSP_AudioIn_Overwrite.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/BSP_AudioIn_Overwrite.cpp Fri Jun 07 05:10:10 2019 +0000 @@ -0,0 +1,102 @@ +//------------------------------------------------------------------------------ +// Overwrite functuions and define calback function +// for functions in stm32746g_discovery_audio.cpp +// +// Original version: BSP_overwrite.cpp by Nanase +// https://developer.mbed.org/users/nanase/code/DISCO-F746NG_Oscilloscope/ +//------------------------------------------------------------------------------ + +#include "BSP_AudioIn_Overwrite.hpp" + +// These three callback functions are modyfied by Mikami +void BSP_AUDIO_IN_HalfTransfer_CallBack() +{ + Mikami::SaiIO::Captured1st(); +} + +void BSP_AUDIO_IN_TransferComplete_CallBack() +{ + Mikami::SaiIO::Captured2nd(); +} + +void BSP_AUDIO_IN_Error_CallBack() +{ + Mikami::SaiIO::ErrorTrap(); +} + +//-------------------------------------------------------------- +// Followings are original by Nanase +//-------------------------------------------------------------- + +DMA_HandleTypeDef hdma_sai_rx; + +void AUDIO_IN_SAIx_DMAx_IRQHandler() +{ + HAL_DMA_IRQHandler(&hdma_sai_rx); +} + +void BSP_AUDIO_IN_MspInit(SAI_HandleTypeDef *hsai, void *Params) +{ + GPIO_InitTypeDef gpio_init_structure; + + /* Enable SAI clock */ + AUDIO_IN_SAIx_CLK_ENABLE(); + + /* Enable SD GPIO clock */ + AUDIO_IN_SAIx_SD_ENABLE(); + /* CODEC_SAI pin configuration: SD pin */ + gpio_init_structure.Pin = AUDIO_IN_SAIx_SD_PIN; + gpio_init_structure.Mode = GPIO_MODE_AF_PP; + gpio_init_structure.Pull = GPIO_NOPULL; + gpio_init_structure.Speed = GPIO_SPEED_FAST; + gpio_init_structure.Alternate = AUDIO_IN_SAIx_SD_AF; + HAL_GPIO_Init(AUDIO_IN_SAIx_SD_GPIO_PORT, &gpio_init_structure); + + /* Enable Audio INT GPIO clock */ + AUDIO_IN_INT_GPIO_ENABLE(); + /* Audio INT pin configuration: input */ + gpio_init_structure.Pin = AUDIO_IN_INT_GPIO_PIN; + gpio_init_structure.Mode = GPIO_MODE_INPUT; + gpio_init_structure.Pull = GPIO_NOPULL; + gpio_init_structure.Speed = GPIO_SPEED_FAST; + HAL_GPIO_Init(AUDIO_IN_INT_GPIO_PORT, &gpio_init_structure); + + /* Enable the DMA clock */ + AUDIO_IN_SAIx_DMAx_CLK_ENABLE(); + + if(hsai->Instance == AUDIO_IN_SAIx) + { + /* Configure the hdma_sai_rx handle parameters */ + hdma_sai_rx.Init.Channel = AUDIO_IN_SAIx_DMAx_CHANNEL; + hdma_sai_rx.Init.Direction = DMA_PERIPH_TO_MEMORY; + hdma_sai_rx.Init.PeriphInc = DMA_PINC_DISABLE; + hdma_sai_rx.Init.MemInc = DMA_MINC_ENABLE; + hdma_sai_rx.Init.PeriphDataAlignment = AUDIO_IN_SAIx_DMAx_PERIPH_DATA_SIZE; + hdma_sai_rx.Init.MemDataAlignment = AUDIO_IN_SAIx_DMAx_MEM_DATA_SIZE; + hdma_sai_rx.Init.Mode = DMA_CIRCULAR; + hdma_sai_rx.Init.Priority = DMA_PRIORITY_HIGH; + hdma_sai_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE; + hdma_sai_rx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL; + hdma_sai_rx.Init.MemBurst = DMA_MBURST_SINGLE; + hdma_sai_rx.Init.PeriphBurst = DMA_MBURST_SINGLE; + + hdma_sai_rx.Instance = AUDIO_IN_SAIx_DMAx_STREAM; + + /* Associate the DMA handle */ + __HAL_LINKDMA(hsai, hdmarx, hdma_sai_rx); + + /* Deinitialize the Stream for new transfer */ + HAL_DMA_DeInit(&hdma_sai_rx); + + /* Configure the DMA Stream */ + HAL_DMA_Init(&hdma_sai_rx); + } + + /* SAI DMA IRQ Channel configuration */ + HAL_NVIC_SetPriority(AUDIO_IN_SAIx_DMAx_IRQ, AUDIO_IN_IRQ_PREPRIO, 0); + HAL_NVIC_EnableIRQ(AUDIO_IN_SAIx_DMAx_IRQ); + + /* Audio INT IRQ Channel configuration */ + HAL_NVIC_SetPriority(AUDIO_IN_INT_IRQ, AUDIO_IN_IRQ_PREPRIO, 0); + HAL_NVIC_EnableIRQ(AUDIO_IN_INT_IRQ); +}
diff -r 000000000000 -r f255629eada1 BSP_AudioIn_Overwrite.hpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/BSP_AudioIn_Overwrite.hpp Fri Jun 07 05:10:10 2019 +0000 @@ -0,0 +1,15 @@ +//-------------------------------------------------------------- +// Overwrite functuions and define calback function (Header) +// for functions in stm32746g_discovery_audio.cpp +//-------------------------------------------------------------- + +#ifndef F746_AUDIO_IN_OVERWRITE_HPP +#define F746_AUDIO_IN_OVERWRITE_HPP + +#include "stm32746g_discovery_audio.h" +#include "SAI_InOut.hpp" + +void AUDIO_IN_SAIx_DMAx_IRQHandler(); + +#endif // F746_AUDIO_IN_OVERWRITE_HPP +
diff -r 000000000000 -r f255629eada1 BSP_AudioOut_Overwrite.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/BSP_AudioOut_Overwrite.cpp Fri Jun 07 05:10:10 2019 +0000 @@ -0,0 +1,113 @@ +//------------------------------------------------------------------------------ +// Overwrite functuions and define calback functions +// for functions in stm32746g_discovery_audio.cpp +// +// Original version: BSP_overwrite.cpp by Nanase +// https://developer.mbed.org/users/nanase/code/DISCO-F746NG_Sweep/ +//------------------------------------------------------------------------------ +#include "BSP_AudioOut_Overwrite.hpp" + +// These three callback functions are modyfied by Mikami +void BSP_AUDIO_OUT_HalfTransfer_CallBack() +{ + Mikami::SaiIO::FillBuffer1st(); +} + +void BSP_AUDIO_OUT_TransferComplete_CallBack() +{ + Mikami::SaiIO::FillBuffer2nd(); +} + +void BSP_AUDIO_OUT_Error_CallBack() +{ + Mikami::SaiIO::ErrorTrap(); +} + +//-------------------------------------------------------------- +// Followings are original by Nanase +//-------------------------------------------------------------- + +DMA_HandleTypeDef hdma_sai_tx; + +void AUDIO_OUT_SAIx_DMAx_IRQHandler() +{ + 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 f255629eada1 BSP_AudioOut_Overwrite.hpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/BSP_AudioOut_Overwrite.hpp Fri Jun 07 05:10:10 2019 +0000 @@ -0,0 +1,14 @@ +//-------------------------------------------------------------- +// Overwrite functuions and define calback function (Header) +// for functions in stm32746g_discovery_audio.cpp +//-------------------------------------------------------------- + +#ifndef F746_AUDIO_OUT_OVERWRITE_HPP +#define F746_AUDIO_OUT_OVERWRITE_HPP + +#include "stm32746g_discovery_audio.h" +#include "SAI_InOut.hpp" + +void AUDIO_OUT_SAIx_DMAx_IRQHandler(); + +#endif // F746_AUDIO_OUT_OVERWRITE_HPP
diff -r 000000000000 -r f255629eada1 SAI_InOut.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SAI_InOut.cpp Fri Jun 07 05:10:10 2019 +0000 @@ -0,0 +1,190 @@ +//----------------------------------------------------------- +// SaiIO class +// 2017/03/16, Copyright (c) 2017 MIKAMI, Naoki +//----------------------------------------------------------- + +#include "SAI_InOut.hpp" + +namespace Mikami +{ + // Constructor + SaiIO::SaiIO(InOutBoth ioBoth, int size, int fs, + uint16_t inputDevice) + : FS_(fs), IOBOTH_(ioBoth) + { + nData_ = size; + bufferSize_ = (size*2)*2; + + if (ioBoth != OUTPUT) + { + inBuffer_.SetSize((size*2)*2); + inOffset_ = 0; + captured_ = false; + } + if (ioBoth != INPUT) + { + outBuffer_.SetSize((size*2)*2); + tmp_.SetSize(size*2); + tmpIndex_ = 0; + xferred_ = false; + ClearBuffer(); + } + InitCodec(inputDevice); + } + + // Input start + void SaiIO::RecordIn() + { + if (BSP_AUDIO_IN_Record(inBuffer_, bufferSize_) == AUDIO_ERROR) + ErrorTrap(); + } + + // Switching input device and run + void SaiIO::SwitchInputDevice(int sw) + { + uint16_t dev = (sw == 0) ? + INPUT_DEVICE_DIGITAL_MICROPHONE_2 + : INPUT_DEVICE_INPUT_LINE_1; + InitInput(dev); + ClearBuffer(); + RecordIn(); + if (IOBOTH_ == BOTH) PlayOut(); + } + + // If captured, return true + bool SaiIO::IsCaptured() + { + if (!captured_) return false; + + inIndex_ = inOffset_; + captured_ = false; + return true; + } + + void SaiIO::PlayOut() + { + ClearBuffer(); + BSP_AUDIO_OUT_SetAudioFrameSlot(CODEC_AUDIOFRAME_SLOT_02); + if (BSP_AUDIO_OUT_Play(outBuffer_, bufferSize_*AUDIODATA_SIZE) + == AUDIO_ERROR) + ErrorTrap(); + } + + // Return true if transfer completion to output + bool SaiIO::IsXferred() + { + if (!xferred_) return false; + + tmpIndex_ = 0; + xferred_ = false; + return true; + } + + void SaiIO::Output(int16_t xL, int16_t xR) + { + tmp_[tmpIndex_++] = xL; // Left + tmp_[tmpIndex_++] = xR; // Right + } + + void SaiIO::ErrorTrap() + { + DigitalOut led1(LED1); + fprintf(stderr, "\r\n#### ERROR ####\r\n"); + while(true) + { + led1 = !led1; + wait_ms(250); + } + } + + // Initialize audio input and output + void SaiIO::InitCodec(uint16_t inputDevice) + { + if (inputDevice != 0) InitInput(inputDevice); + + if (IOBOTH_ == OUTPUT) + if (BSP_AUDIO_OUT_Init(OUTPUT_DEVICE_HEADPHONE, + 100, FS_) == AUDIO_ERROR) + ErrorTrap(); + + if (IOBOTH_ != OUTPUT) SetInput(); + if (IOBOTH_ != INPUT) SetOutput(); + } + + void SaiIO::InitInput(uint16_t inputDevice) + { + int audioInVolume = (inputDevice == INPUT_DEVICE_INPUT_LINE_1) ? + 70 : 90; + InputFp = (inputDevice == INPUT_DEVICE_INPUT_LINE_1) ? + &SaiIO::InputNormal : &SaiIO::InputReversal; + + if (IOBOTH_ == BOTH) + if (BSP_AUDIO_IN_OUT_Init(inputDevice, OUTPUT_DEVICE_HEADPHONE, + audioInVolume, FS_) == AUDIO_ERROR) + ErrorTrap(); + + if (IOBOTH_ == INPUT) + if (BSP_AUDIO_IN_Init(inputDevice, + audioInVolume, FS_) == AUDIO_ERROR) + ErrorTrap(); + } + + void SaiIO::SetInput() + { + NVIC_SetVector(AUDIO_IN_SAIx_DMAx_IRQ, + (uint32_t)AUDIO_IN_SAIx_DMAx_IRQHandler); + } + + void SaiIO::SetOutput() + { + NVIC_SetVector(AUDIO_OUT_SAIx_DMAx_IRQ, + (uint32_t)AUDIO_OUT_SAIx_DMAx_IRQHandler); + BSP_AUDIO_OUT_SetAudioFrameSlot(CODEC_AUDIOFRAME_SLOT_02); + } + + void SaiIO::ClearBuffer() + { + if (IOBOTH_ != OUTPUT) + for (int n=0; n<bufferSize_; n++) inBuffer_[n] = 0; + for (int n=0; n<bufferSize_; n++) outBuffer_[n] = 0; + for (int n=0; n<nData_*2; n++) tmp_[n] = 0; + } + + // For line input + void SaiIO::InputNormal(int16_t &xL, int16_t &xR) + { + xL = inBuffer_[inIndex_++]; + xR = inBuffer_[inIndex_++]; + } + + // For MEMS microphone input + void SaiIO::InputReversal(int16_t &xL, int16_t &xR) + { + xR = inBuffer_[inIndex_++]; + xL = inBuffer_[inIndex_++]; + } + + void SaiIO::Captured(int32_t offset) + { + captured_ = true; + inOffset_ = offset; + } + + void SaiIO::FillBuffer(uint32_t offset) + { + int k = offset; + for (int n=0; n<nData_*2; n++) + outBuffer_[k++] = tmp_[n]; + xferred_ = true; + } + + int32_t SaiIO::nData_; + int32_t SaiIO::bufferSize_; + + __IO bool SaiIO::captured_; + __IO int32_t SaiIO::inOffset_; + + Array<uint16_t> SaiIO::outBuffer_; + Array<uint16_t> SaiIO::tmp_; + __IO bool SaiIO::xferred_; +}
diff -r 000000000000 -r f255629eada1 SAI_InOut.hpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SAI_InOut.hpp Fri Jun 07 05:10:10 2019 +0000 @@ -0,0 +1,110 @@ +//----------------------------------------------------------- +// SaiIO class (Header) +// 2017/03/17, Copyright (c) 2017 MIKAMI, Naoki +//----------------------------------------------------------- + +#ifndef F746_SAI_IO_HPP +#define F746_SAI_IO_HPP + +#include "mbed.h" +#include "stm32746g_discovery_audio.h" +#include "BSP_AudioIn_Overwrite.hpp" +#include "BSP_AudioOut_Overwrite.hpp" +#include "Array.hpp" + +namespace Mikami +{ + class SaiIO + { + public: + enum InOutBoth { INPUT, // input only + OUTPUT, // output only + BOTH }; // input and output + // Constructor + // inputDevice: INPUT_DEVICE_DIGITAL_MICROPHONE_2 or + // INPUT_DEVICE_INPUT_LINE_1 + // inputDevice == 0 : not use input device + SaiIO(InOutBoth ioBoth, int size, int fs, + uint16_t inputDevice = 0); + virtual ~SaiIO() {} + + int32_t GetLength() { return nData_; } + + void RecordIn(); + // sw = 0: DIGITAL_MICROPHONE_2 + // 1: LINE_1 + void SwitchInputDevice(int sw); + + bool IsCaptured(); + // Input using SAI + void Input(int16_t &xL, int16_t &xR) + { (this->*InputFp)(xL, xR); } + + void StopIn() { BSP_AUDIO_IN_Stop(CODEC_PDWN_SW); } + void PauseIn() { BSP_AUDIO_IN_Pause(); } + void ResumeIn() { BSP_AUDIO_IN_Resume(); } + + void PlayOut(); + bool IsXferred(); + // Output using SAI + void Output(int16_t xL, int16_t xR); + + void StopOut() { BSP_AUDIO_OUT_Stop(CODEC_PDWN_SW); } + void PauseOut() { BSP_AUDIO_OUT_Pause(); } + void ResumeOut() { BSP_AUDIO_OUT_Resume(); } + + // IF you use both input and output of SAI, + // you can use following function + bool IsCompleted() + { return IsCaptured() && IsXferred(); } + + // Following two member functions are called from + // callback functions in "BSP_AudioIn_Overwrite.cpp" + static void Captured1st() { Captured(0); } + static void Captured2nd() { Captured(bufferSize_/2); } + + // Following two member functions are called from + // callback functions in "BSP_AudioOut_Overwrite.cpp" + static void FillBuffer1st() { FillBuffer(0); } + static void FillBuffer2nd() { FillBuffer(bufferSize_/2); } + + // Called form the functions in "BSP_AudioIn_Overwrite.cpp" + // and "BSP_AudioOut_Overwrite.cpp" + static void ErrorTrap(); + + private: + const int FS_; + const InOutBoth IOBOTH_; + + Array<uint16_t> inBuffer_; + static Array<uint16_t> outBuffer_; + static Array<uint16_t> tmp_; + + __IO int32_t inIndex_; + __IO int32_t tmpIndex_; + + static int32_t nData_; + static int32_t bufferSize_; + static __IO bool captured_; + static __IO int32_t inOffset_; + static __IO bool xferred_; + + void InitCodec(uint16_t inputDevice); + void InitInput(uint16_t inputDevice); + void SetInput(); + void SetOutput(); + void ClearBuffer(); + + // This function pointer is assigned by + // InputNormal() or InputReversal() + void (SaiIO::*InputFp)(int16_t &, int16_t &); + // For line input + void InputNormal(int16_t &xL, int16_t &xR); + // For MEMS microphone input + void InputReversal(int16_t &xL, int16_t &xR); + + static void Captured(int32_t offset); + static void FillBuffer(uint32_t offset); + }; +} +#endif // F746_SAI_IO_HPP