diff --git a/libraries/PDM/src/stm32/PDM.cpp b/libraries/PDM/src/stm32/PDM.cpp
index 0ad5feea4..f34fbc5f4 100644
--- a/libraries/PDM/src/stm32/PDM.cpp
+++ b/libraries/PDM/src/stm32/PDM.cpp
@@ -23,15 +23,12 @@
#ifdef TARGET_STM
#include "PDM.h"
-#include "audio.h"
#include "mbed.h"
+extern "C" {
+ #include "audio.h"
+}
-#define AUDIO_FREQUENCY BSP_AUDIO_FREQUENCY_16K
-#define AUDIO_IN_PDM_BUFFER_SIZE (uint32_t)(128)
-
-//ALIGN_32BYTES (uint16_t recordPDMBuf[AUDIO_IN_PDM_BUFFER_SIZE]) __attribute__((section(".OPEN_AMP_SHMEM")));
-// FIXME: need to add an entry for RAM_D3 to linker script
-uint16_t* recordPDMBuf = (uint16_t*)0x38000000;
+extern "C" uint16_t *g_pcmbuf;
PDMClass::PDMClass(int dinPin, int clkPin, int pwrPin) :
_dinPin(dinPin),
@@ -45,14 +42,10 @@ PDMClass::~PDMClass()
{
}
-int PDMClass::begin(int channels, long sampleRate) {
-
- _channels = channels;
-
- // fixme: only works in stereo mode
- channels = 2;
+static int gain_db = -1;
+static int _samplerate = -1;
- setBufferSize(AUDIO_IN_PDM_BUFFER_SIZE / 4 * channels);
+int PDMClass::begin(int channels, long sampleRate) {
if (isBoardRev2()) {
mbed::I2C i2c(PB_7, PB_6);
@@ -69,43 +62,36 @@ int PDMClass::begin(int channels, long sampleRate) {
i2c.write(8 << 1, data, sizeof(data));
}
- BSP_AUDIO_IN_SelectInterface(AUDIO_IN_INTERFACE_PDM);
+ _channels = channels;
+ _samplerate = sampleRate;
- /* Initialize audio IN at REC_FREQ*/
- if (BSP_AUDIO_IN_InitEx(INPUT_DEVICE_DIGITAL_MIC, AUDIO_FREQUENCY, DEFAULT_AUDIO_IN_BIT_RESOLUTION, channels) != AUDIO_OK)
- {
- return 0;
+ if (gain_db == -1) {
+ gain_db = 24;
}
- /* Start the record */
- BSP_AUDIO_IN_Record((uint16_t*)recordPDMBuf, AUDIO_IN_PDM_BUFFER_SIZE * channels);
- return 1;
+ //g_pcmbuf = (uint16_t*)_doubleBuffer.data();
+
+ if(py_audio_init(channels, sampleRate, gain_db, 0.9883f)) {
+ py_audio_start_streaming();
+ return 1;
+ }
+ return 0;
}
void PDMClass::end()
{
+ py_audio_stop_streaming();
+ py_audio_deinit();
}
int PDMClass::available()
{
size_t avail = _doubleBuffer.available();
- if (_channels == 1) {
- return avail/2;
- } else {
- return avail;
- }
+ return avail;
}
int PDMClass::read(void* buffer, size_t size)
{
- if (_channels == 1) {
- uint16_t temp[size*2];
- int read = _doubleBuffer.read(temp, size*2);
- for (int i = 0; i < size; i++) {
- ((uint16_t*)buffer)[i] = temp[i*2];
- }
- return read;
- }
int read = _doubleBuffer.read(buffer, size);
return read;
}
@@ -117,7 +103,9 @@ void PDMClass::onReceive(void(*function)(void))
void PDMClass::setGain(int gain)
{
-
+ gain_db = gain;
+ //end();
+ //begin(_channels, _samplerate);
}
void PDMClass::setBufferSize(int bufferSize)
@@ -127,49 +115,28 @@ void PDMClass::setBufferSize(int bufferSize)
void PDMClass::IrqHandler(bool halftranfer)
{
-
- int start = halftranfer ? 0 : AUDIO_IN_PDM_BUFFER_SIZE;
-
- if (BSP_AUDIO_IN_GetInterface() == AUDIO_IN_INTERFACE_PDM && _doubleBuffer.available() == 0) {
-
- /* Invalidate Data Cache to get the updated content of the SRAM*/
- SCB_InvalidateDCache_by_Addr((uint32_t *)&recordPDMBuf[start], AUDIO_IN_PDM_BUFFER_SIZE * 2);
-
- //memcpy((uint16_t*)_doubleBuffer.data(), (uint16_t*)&recordPDMBuf[start], AUDIO_IN_PDM_BUFFER_SIZE/2);
- BSP_AUDIO_IN_PDMToPCM((uint16_t*)&recordPDMBuf[start], (uint16_t*)_doubleBuffer.data());
-
- /* Clean Data Cache to update the content of the SRAM */
- SCB_CleanDCache_by_Addr((uint32_t*)_doubleBuffer.data(), AUDIO_IN_PDM_BUFFER_SIZE * 2);
-
+ if (_doubleBuffer.available() == 0) {
+ g_pcmbuf = (uint16_t*)_doubleBuffer.data();
+ audio_pendsv_callback();
_doubleBuffer.swap(_doubleBuffer.availableForWrite());
}
+
if (_onReceive) {
_onReceive();
}
}
extern "C" {
- /**
- @brief Calculates the remaining file size and new position of the pointer.
- @param None
- @retval None
- */
- __attribute__((__used__)) void BSP_AUDIO_IN_TransferComplete_CallBack(void)
- {
- PDM.IrqHandler(false);
- }
+void PDMIrqHandler(bool halftranfer)
+{
+ PDM.IrqHandler(halftranfer);
+}
- /**
- @brief Manages the DMA Half Transfer complete interrupt.
- @param None
- @retval None
- */
- __attribute__((__used__)) void BSP_AUDIO_IN_HalfTransfer_CallBack(void)
- {
- PDM.IrqHandler(true);
- }
+void PDMsetBufferSize(int size) {
+ PDM.setBufferSize(size);
+}
}
PDMClass PDM(0, 0, 0);
-#endif
\ No newline at end of file
+#endif
diff --git a/libraries/PDM/src/stm32/audio.c b/libraries/PDM/src/stm32/audio.c
index 84d33ce99..f52aaa6e8 100644
--- a/libraries/PDM/src/stm32/audio.c
+++ b/libraries/PDM/src/stm32/audio.c
@@ -1,1659 +1,377 @@
-/**
- ******************************************************************************
- * @file stm32h747i_discovery_audio.c
- * @author MCD Application Team
- * @brief This file provides the Audio driver for the STM32H747I-DISCOVERY
- * board.
- @verbatim
- How To use this driver:
- -----------------------
- + This driver supports STM32H7xx devices on STM32H747I-DISCOVERY (MB1248) Discovery boards.
- + Call the function BSP_AUDIO_OUT_Init(
- OutputDevice: physical output mode (OUTPUT_DEVICE_SPEAKER,
- OUTPUT_DEVICE_HEADPHONE or OUTPUT_DEVICE_BOTH)
- Volume : Initial volume to be set (0 is min (mute), 100 is max (100%)
- AudioFreq : Audio frequency in Hz (8000, 16000, 22500, 32000...)
- this parameter is relative to the audio file/stream type.
- )
- This function configures all the hardware required for the audio application (codec, I2C, SAI,
- GPIOs, DMA and interrupt if needed). This function returns AUDIO_OK if configuration is OK.
- If the returned value is different from AUDIO_OK or the function is stuck then the communication with
- the codec has failed (try to un-plug the power or reset device in this case).
- - OUTPUT_DEVICE_SPEAKER : only speaker will be set as output for the audio stream.
- - OUTPUT_DEVICE_HEADPHONE: only headphones will be set as output for the audio stream.
- - OUTPUT_DEVICE_BOTH : both Speaker and Headphone are used as outputs for the audio stream
- at the same time.
- Note. On STM32H747I-DISCOVERY SAI_DMA is configured in CIRCULAR mode. Due to this the application
- does NOT need to call BSP_AUDIO_OUT_ChangeBuffer() to assure streaming.
- + Call the function BSP_AUDIO_OUT_Play(
- pBuffer: pointer to the audio data file address
- Size : size of the buffer to be sent in Bytes
- )
- to start playing (for the first time) from the audio file/stream.
- + Call the function BSP_AUDIO_OUT_Pause() to pause playing
- + Call the function BSP_AUDIO_OUT_Resume() to resume playing.
- Note. After calling BSP_AUDIO_OUT_Pause() function for pause, only BSP_AUDIO_OUT_Resume() should be called
- for resume (it is not allowed to call BSP_AUDIO_OUT_Play() in this case).
- Note. This function should be called only when the audio file is played or paused (not stopped).
- + For each mode, you may need to implement the relative callback functions into your code.
- The Callback functions are named BSP_AUDIO_OUT_XXX_CallBack() and only their prototypes are declared in
- the stm32h747i_discovery_audio.h file. (refer to the example for more details on the callbacks implementations)
- + To Stop playing, to modify the volume level, the frequency, the audio frame slot,
- the device output mode the mute or the stop, use the functions: BSP_AUDIO_OUT_SetVolume(),
- AUDIO_OUT_SetFrequency(), BSP_AUDIO_OUT_SetAudioFrameSlot(), BSP_AUDIO_OUT_SetOutputMode(),
- BSP_AUDIO_OUT_SetMute() and BSP_AUDIO_OUT_Stop().
-
- + Call the function BSP_AUDIO_IN_Init(
- AudioFreq: Audio frequency in Hz (8000, 16000, 22500, 32000...)
- this parameter is relative to the audio file/stream type.
- BitRes: Bit resolution fixed to 16bit
- ChnlNbr: Number of channel to be configured for the DFSDM peripheral
- )
- This function configures all the hardware required for the audio in application (channels,
- Clock source for SAI PDM periphiral, GPIOs, DMA and interrupt if needed).
- This function returns AUDIO_OK if configuration is OK.If the returned value is different from AUDIO_OK then
- the configuration should be wrong.
- + Call the function BSP_AUDIO_IN_AllocScratch(
- pScratch: pointer to scratch tables
- size: size of scratch buffer)
- This function must be called before BSP_AUDIO_IN_RECORD() to allocate buffer scratch for each DFSDM channel
- and its size.
- Note: These buffers scratch are used as intermidiate buffers to collect data within final record buffer.
- size is the total size of the four buffers scratch; If size is 512 then the size of each is 128.
- This function must be called after BSP_AUDIO_IN_Init()
- + Call the function BSP_AUDIO_IN_RECORD(
- pBuf: pointer to the recorded audio data file address
- Size: size of the buffer to be written in Bytes
- )
- to start recording from microphones.
-
- + Call the function BSP_AUDIO_IN_Pause() to pause recording
- + Call the function BSP_AUDIO_IN_Resume() to recording playing.
- Note. After calling BSP_AUDIO_IN_Pause() function for pause, only BSP_AUDIO_IN_Resume() should be called
- for resume (it is not allowed to call BSP_AUDIO_IN_RECORD() in this case).
- + Call the function BSP_AUDIO_IN_Stop() to stop recording
- + For each mode, you may need to implement the relative callback functions into your code.
- The Callback functions are named BSP_AUDIO_IN_XXX_CallBack() and only their prototypes are declared in
- the stm32h747i_discovery_audio.h file. (refer to the example for more details on the callbacks implementations)
- + Call the function BSP_AUDIO_IN_SelectInterface(uint32_t Interface) to select one of the two interfaces
- available on the STM32H747I-Discovery board: SAI or PDM. This function is to be called before BSP_AUDIO_IN_InitEx().
- + Call the function BSP_AUDIO_IN_GetInterface() to get the current used interface.
- + Call the function BSP_AUDIO_IN_PDMToPCM_Init(uint32_t AudioFreq, uint32_t ChnlNbrIn, uint32_t ChnlNbrOut)
- to init PDM filters if the libPDMFilter is used for audio data filtering.
- + Call the function BSP_AUDIO_IN_PDMToPCM(uint16_t* PDMBuf, uint16_t* PCMBuf) to filter PDM data to PCM format
- if the libPDMFilter library is used for audio data filtering.
-
- Driver architecture:
- --------------------
- + This driver provides the High Audio Layer: consists of the function API exported in the stm32h747i_discovery_audio.h file
- (BSP_AUDIO_OUT_Init(), BSP_AUDIO_OUT_Play() ...)
- + This driver provide also the Media Access Layer (MAL): which consists of functions allowing to access the media containing/
- providing the audio file/stream. These functions are also included as local functions into
- the stm32h747i_discovery_audio.c file (DFSDMx_Init(), DFSDMx_DeInit(), SAIx_Init() and SAIx_DeInit())
-
- Known Limitations:
- ------------------
- 1- If the TDM Format used to play in parallel 2 audio Stream (the first Stream is configured in codec SLOT0 and second
- Stream in SLOT1) the Pause/Resume, volume and mute feature will control the both streams.
- 2- Parsing of audio file is not implemented (in order to determine audio file properties: Mono/Stereo, Data size,
- File size, Audio Frequency, Audio Data header size ...). The configuration is fixed for the given audio file.
- 3- Supports only Stereo audio streaming.
- 4- Supports only 16-bits audio data size.
- @endverbatim
- ******************************************************************************
- * @attention
- *
- *
© Copyright (c) 2019 STMicroelectronics.
- * All rights reserved.
- *
- * This software component is licensed by ST under BSD 3-Clause license,
- * the "License"; You may not use this file except in compliance with the
- * License. You may obtain a copy of the License at:
- * opensource.org/licenses/BSD-3-Clause
- *
- ******************************************************************************
- */
-
+/*
+ * This file is part of the OpenMV project.
+ *
+ * Copyright (c) 2013-2021 Ibrahim Abdelkader
+ * Copyright (c) 2013-2021 Kwabena W. Agyeman
+ *
+ * This work is licensed under the MIT license, see the file LICENSE for details.
+ *
+ * Audio Python module.
+ */
#ifdef TARGET_STM
-/* Includes ------------------------------------------------------------------*/
+#include
+#include "stm32h7xx_hal.h"
+#include "pdm2pcm_glo.h"
#include "audio.h"
+#include "stdbool.h"
-/** @addtogroup BSP
- * @{
- */
-
-/** @addtogroup STM32H747I_DISCOVERY
- * @{
- */
-
-/** @defgroup STM32H747I_DISCOVERY_AUDIO STM32H747I_DISCOVERY_AUDIO
- * @brief This file includes the low layer driver for wm8994 Audio Codec
- * available on STM32H747I-DISCOVERY discovery board(MB1248).
- * @{
- */
-
-/** @defgroup STM32H747I_DISCOVERY_AUDIO_Private_Variables Private Variables
- * @{
- */
-/* PLAY */
-AUDIO_DrvTypeDef *audio_drv;
-SAI_HandleTypeDef haudio_out_sai;
-SAI_HandleTypeDef haudio_in_sai;
-
-/* RECORD */
-AUDIOIN_ContextTypeDef hAudioIn;
-
-
-
-/* Audio in Volume value */
-__IO uint16_t AudioInVolume = DEFAULT_AUDIO_IN_VOLUME;
-
-/* PDM filters params */
-PDM_Filter_Handler_t PDM_FilterHandler[2];
-PDM_Filter_Config_t PDM_FilterConfig[2];
-
-/**
- * @}
- */
-
-/** @defgroup STM32H747I_DISCOVERY_AUDIO_Private_Function_Prototypes Private FunctionPrototypes
- * @{
- */
-static void SAIx_Out_Init(uint32_t SaiOutMode, uint32_t SlotActive, uint32_t AudioFreq);
-static void SAIx_Out_DeInit(SAI_HandleTypeDef *hsai);
-static void SAIx_In_MspInit(SAI_HandleTypeDef *hsai, void *Params);
-static void SAIx_In_MspDeInit(SAI_HandleTypeDef *hsai, void *Params);
-static void SAIx_In_Init(uint32_t SaiInMode, uint32_t SlotActive, uint32_t AudioFreq, bool mono);
-static void SAIx_In_DeInit(SAI_HandleTypeDef *hsai);
-
-// TODO: this needs to become a library function
-bool isBoardRev2() {
- uint32_t hse_speed;
- uint8_t* bootloader_data = (uint8_t*)(0x801F000);
- if (bootloader_data[0] != 0xA0 || bootloader_data[1] < 14) {
- hse_speed = 27000000;
- } else {
- hse_speed = bootloader_data[10] * 1000000;
- }
- return (hse_speed == 25000000);
-}
-
-/**
- * @}
- */
-
-/** @defgroup STM32H747I_DISCOVERY_AUDIO_OUT_Exported_Functions OUT Exported Functions
- * @{
- */
-
-/**
- * @brief Configures the audio Out peripheral.
- * @param OutputDevice: OUTPUT_DEVICE_SPEAKER, OUTPUT_DEVICE_HEADPHONE,
- * or OUTPUT_DEVICE_BOTH.
- * @param Volume: Initial volume level (from 0 (Mute) to 100 (Max))
- * @param AudioFreq: Audio frequency used to play the audio stream.
- * @retval AUDIO_OK if correct communication, else wrong communication
- */
-uint8_t BSP_AUDIO_OUT_Init(uint16_t OutputDevice, uint8_t Volume, uint32_t AudioFreq)
-{
- uint8_t ret = AUDIO_ERROR;
- uint32_t deviceid = 0x00;
- uint32_t slot_active;
-
- /* Initialize SAI1 sub_block A as MASTER TX */
- haudio_out_sai.Instance = AUDIO_OUT_SAIx;
-
- /* Disable SAI */
- SAIx_Out_DeInit(&haudio_out_sai);
-
- /* PLL clock is set depending by the AudioFreq (44.1khz vs 48khz groups) */
- BSP_AUDIO_OUT_ClockConfig(&haudio_out_sai, AudioFreq, NULL);
-
- /* SAI data transfer preparation:
- Prepare the Media to be used for the audio transfer from memory to SAI peripheral */
-
- if(HAL_SAI_GetState(&haudio_out_sai) == HAL_SAI_STATE_RESET)
- {
- /* Init the SAI MSP: this __weak function can be redefined by the application*/
- BSP_AUDIO_OUT_MspInit(&haudio_out_sai, NULL);
- }
-
- /* Init SAI as master RX output */
- slot_active = CODEC_AUDIOFRAME_SLOT_0123;
- SAIx_Out_Init(SAI_MODEMASTER_TX, slot_active, AudioFreq);
-
- /* wm8994 codec initialization */
- deviceid = wm8994_drv.ReadID(AUDIO_I2C_ADDRESS);
-
- if((deviceid) == WM8994_ID)
- {
- /* Reset the Codec Registers */
- wm8994_drv.Reset(AUDIO_I2C_ADDRESS);
- /* Initialize the audio driver structure */
- audio_drv = &wm8994_drv;
- ret = AUDIO_OK;
- }
- else
- {
- ret = AUDIO_ERROR;
- }
-
- if(ret == AUDIO_OK)
- {
- /* Initialize the codec internal registers */
- audio_drv->Init(AUDIO_I2C_ADDRESS, OutputDevice, Volume, AudioFreq);
- }
-
- return ret;
-}
-
-/**
- * @brief Starts playing audio stream from a data buffer for a determined size.
- * @param pBuffer: Pointer to the buffer
- * @param Size: Number of audio data BYTES.
- * @retval AUDIO_OK if correct communication, else wrong communication
- */
-uint8_t BSP_AUDIO_OUT_Play(uint16_t* pBuffer, uint32_t Size)
-{
- /* Call the audio Codec Play function */
- if(audio_drv->Play(AUDIO_I2C_ADDRESS, pBuffer, Size) != 0)
- {
- return AUDIO_ERROR;
- }
- else
- {
- /* Update the Media layer and enable it for play */
- HAL_SAI_Transmit_DMA(&haudio_out_sai, (uint8_t*) pBuffer, DMA_MAX(Size / AUDIODATA_SIZE));
-
- return AUDIO_OK;
- }
-}
-
-/**
- * @brief Sends n-Bytes on the SAI interface.
- * @param pData: pointer on data address
- * @param Size: number of data to be written
- * @retval None
- */
-void BSP_AUDIO_OUT_ChangeBuffer(uint16_t *pData, uint16_t Size)
-{
- HAL_SAI_Transmit_DMA(&haudio_out_sai, (uint8_t*) pData, Size);
-}
-
-/**
- * @brief This function Pauses the audio file stream. In case
- * of using DMA, the DMA Pause feature is used.
- * @warning When calling BSP_AUDIO_OUT_Pause() function for pause, only
- * BSP_AUDIO_OUT_Resume() function should be called for resume (use of BSP_AUDIO_OUT_Play()
- * function for resume could lead to unexpected behaviour).
- * @retval AUDIO_OK if correct communication, else wrong communication
- */
-uint8_t BSP_AUDIO_OUT_Pause(void)
-{
- /* Call the Audio Codec Pause/Resume function */
- if(audio_drv->Pause(AUDIO_I2C_ADDRESS) != 0)
- {
- return AUDIO_ERROR;
- }
- else
- {
- /* Call the Media layer pause function */
- HAL_SAI_DMAPause(&haudio_out_sai);
-
- /* Return AUDIO_OK when all operations are correctly done */
- return AUDIO_OK;
- }
-}
-
-/**
- * @brief Resumes the audio file stream.
- * @warning When calling BSP_AUDIO_OUT_Pause() function for pause, only
- * BSP_AUDIO_OUT_Resume() function should be called for resume (use of BSP_AUDIO_OUT_Play()
- * function for resume could lead to unexpected behaviour).
- * @retval AUDIO_OK if correct communication, else wrong communication
- */
-uint8_t BSP_AUDIO_OUT_Resume(void)
-{
- /* Call the Audio Codec Pause/Resume function */
- if(audio_drv->Resume(AUDIO_I2C_ADDRESS) != 0)
- {
- return AUDIO_ERROR;
- }
- else
- {
- /* Call the Media layer pause/resume function */
- HAL_SAI_DMAResume(&haudio_out_sai);
-
- /* Return AUDIO_OK when all operations are correctly done */
- return AUDIO_OK;
- }
-}
-
-/**
- * @brief Stops audio playing and Power down the Audio Codec.
- * @param Option: could be one of the following parameters
- * - CODEC_PDWN_SW: for software power off (by writing registers).
- * Then no need to reconfigure the Codec after power on.
- * - CODEC_PDWN_HW: completely shut down the codec (physically).
- * Then need to reconfigure the Codec after power on.
- * @retval AUDIO_OK if correct communication, else wrong communication
- */
-uint8_t BSP_AUDIO_OUT_Stop(uint32_t Option)
-{
- /* Call the Media layer stop function */
- HAL_SAI_DMAStop(&haudio_out_sai);
-
- /* Call Audio Codec Stop function */
- if(audio_drv->Stop(AUDIO_I2C_ADDRESS, Option) != 0)
- {
- return AUDIO_ERROR;
- }
- else
- {
- if(Option == CODEC_PDWN_HW)
- {
- /* Wait at least 100us */
- HAL_Delay(1);
- }
- /* Return AUDIO_OK when all operations are correctly done */
- return AUDIO_OK;
- }
-}
-
-/**
- * @brief Controls the current audio volume level.
- * @param Volume: Volume level to be set in percentage from 0% to 100% (0 for
- * Mute and 100 for Max volume level).
- * @retval AUDIO_OK if correct communication, else wrong communication
- */
-uint8_t BSP_AUDIO_OUT_SetVolume(uint8_t Volume)
-{
- /* Call the codec volume control function with converted volume value */
- if(audio_drv->SetVolume(AUDIO_I2C_ADDRESS, Volume) != 0)
- {
- return AUDIO_ERROR;
- }
- else
- {
- /* Return AUDIO_OK when all operations are correctly done */
- return AUDIO_OK;
- }
-}
-
-/**
- * @brief Enables or disables the MUTE mode by software
- * @param Cmd: Could be AUDIO_MUTE_ON to mute sound or AUDIO_MUTE_OFF to
- * unmute the codec and restore previous volume level.
- * @retval AUDIO_OK if correct communication, else wrong communication
- */
-uint8_t BSP_AUDIO_OUT_SetMute(uint32_t Cmd)
-{
- /* Call the Codec Mute function */
- if(audio_drv->SetMute(AUDIO_I2C_ADDRESS, Cmd) != 0)
- {
- return AUDIO_ERROR;
- }
- else
- {
- /* Return AUDIO_OK when all operations are correctly done */
- return AUDIO_OK;
- }
-}
-
-/**
- * @brief Switch dynamically (while audio file is played) the output target
- * (speaker or headphone).
- * @param Output: The audio output target: OUTPUT_DEVICE_SPEAKER,
- * OUTPUT_DEVICE_HEADPHONE or OUTPUT_DEVICE_BOTH
- * @retval AUDIO_OK if correct communication, else wrong communication
- */
-uint8_t BSP_AUDIO_OUT_SetOutputMode(uint8_t Output)
-{
- /* Call the Codec output device function */
- if(audio_drv->SetOutputMode(AUDIO_I2C_ADDRESS, Output) != 0)
- {
- return AUDIO_ERROR;
- }
- else
- {
- /* Return AUDIO_OK when all operations are correctly done */
- return AUDIO_OK;
- }
-}
-
-/**
- * @brief Updates the audio frequency.
- * @param AudioFreq: Audio frequency used to play the audio stream.
- * @note This API should be called after the BSP_AUDIO_OUT_Init() to adjust the
- * audio frequency.
- * @retval None
- */
-void BSP_AUDIO_OUT_SetFrequency(uint32_t AudioFreq)
-{
- /* PLL clock is set depending by the AudioFreq (44.1khz vs 48khz groups) */
- BSP_AUDIO_OUT_ClockConfig(&haudio_out_sai, AudioFreq, NULL);
+static CRC_HandleTypeDef hcrc;
+static SAI_HandleTypeDef hsai;
+static DMA_HandleTypeDef hdma_sai_rx;
- /* Disable SAI peripheral to allow access to SAI internal registers */
- __HAL_SAI_DISABLE(&haudio_out_sai);
+volatile uint16_t *g_pcmbuf = NULL;
- /* Update the SAI audio frequency configuration */
- haudio_out_sai.Init.AudioFrequency = AudioFreq;
- HAL_SAI_Init(&haudio_out_sai);
+static int g_i_channels = AUDIO_SAI_NBR_CHANNELS;
+static int g_o_channels = AUDIO_SAI_NBR_CHANNELS;
+static PDM_Filter_Handler_t PDM_FilterHandler[2];
+static PDM_Filter_Config_t PDM_FilterConfig[2];
- /* Enable SAI peripheral to generate MCLK */
- __HAL_SAI_ENABLE(&haudio_out_sai);
-}
+#define DMA_XFER_NONE (0x00U)
+#define DMA_XFER_HALF (0x01U)
+#define DMA_XFER_FULL (0x04U)
-/**
- * @brief Updates the Audio frame slot configuration.
- * @param AudioFrameSlot: specifies the audio Frame slot
- * @note This API should be called after the BSP_AUDIO_OUT_Init() to adjust the
- * audio frame slot.
- * @retval None
- */
-void BSP_AUDIO_OUT_SetAudioFrameSlot(uint32_t AudioFrameSlot)
-{
- /* Disable SAI peripheral to allow access to SAI internal registers */
- __HAL_SAI_DISABLE(&haudio_out_sai);
+#define AUDIO_FREQUENCY_192K ((uint32_t)192000)
+#define AUDIO_FREQUENCY_96K ((uint32_t)96000)
+#define AUDIO_FREQUENCY_64K ((uint32_t)64000)
+#define AUDIO_FREQUENCY_48K ((uint32_t)48000)
+#define AUDIO_FREQUENCY_44K ((uint32_t)44100)
+#define AUDIO_FREQUENCY_32K ((uint32_t)32000)
+#define AUDIO_FREQUENCY_22K ((uint32_t)22050)
+#define AUDIO_FREQUENCY_16K ((uint32_t)16000)
+#define AUDIO_FREQUENCY_11K ((uint32_t)11025)
+#define AUDIO_FREQUENCY_8K ((uint32_t)8000)
- /* Update the SAI audio frame slot configuration */
- haudio_out_sai.SlotInit.SlotActive = AudioFrameSlot;
- HAL_SAI_Init(&haudio_out_sai);
- /* Enable SAI peripheral to generate MCLK */
- __HAL_SAI_ENABLE(&haudio_out_sai);
-}
+static volatile uint32_t xfer_status = 0;
-/**
- * @brief De-initializes the audio out peripheral.
- * @retval None
- */
-void BSP_AUDIO_OUT_DeInit(void)
-{
- SAIx_Out_DeInit(&haudio_out_sai);
- /* DeInit the SAI MSP : this __weak function can be rewritten by the application */
- BSP_AUDIO_OUT_MspDeInit(&haudio_out_sai, NULL);
-}
+// BDMA can only access D3 SRAM4 memory.
+//int8_t* PDM_BUFFER = (uint16_t*)0x38000000;
+uint8_t PDM_BUFFER[PDM_BUFFER_SIZE] __attribute__ ((section(".pdm_buffer")));
-/**
- * @brief Manages the DMA full Transfer complete event.
- * @retval None
- */
-__weak void BSP_AUDIO_OUT_TransferComplete_CallBack(void)
-{
-}
-
-/**
- * @brief Manages the DMA Half Transfer complete event.
- * @retval None
- */
-__weak void BSP_AUDIO_OUT_HalfTransfer_CallBack(void)
-{
-}
+void PDMIrqHandler(bool halftranfer);
+void PDMsetBufferSize(int size);
-/**
- * @brief Manages the DMA FIFO error event.
- * @retval None
- */
-__weak void BSP_AUDIO_OUT_Error_CallBack(void)
+void AUDIO_SAI_DMA_IRQHandler(void)
{
+ HAL_DMA_IRQHandler(hsai.hdmarx);
}
-/**
- * @brief Initializes BSP_AUDIO_OUT MSP.
- * @param hsai: SAI handle
- * @param Params: pointer on additional configuration parameters, can be NULL.
- * @retval None
- */
-__weak void BSP_AUDIO_OUT_MspInit(SAI_HandleTypeDef *hsai, void *Params)
+void HAL_SAI_RxHalfCpltCallback(SAI_HandleTypeDef *hsai)
{
- static DMA_HandleTypeDef hdma_sai_tx;
- GPIO_InitTypeDef gpio_init_structure;
-
- /* Enable SAI clock */
- AUDIO_OUT_SAIx_CLK_ENABLE();
-
- /* CODEC_SAI pins configuration: FS, SCK and SD pins */
- /* Enable FS, SCK and SD clocks */
- AUDIO_OUT_SAIx_SD_FS_CLK_ENABLE();
- /* Enable FS, SCK and SD pins */
- gpio_init_structure.Pin = AUDIO_OUT_SAIx_FS_PIN | AUDIO_OUT_SAIx_SCK_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_FREQ_VERY_HIGH;
- gpio_init_structure.Alternate = AUDIO_OUT_SAIx_AF;
- HAL_GPIO_Init(AUDIO_OUT_SAIx_SD_FS_SCK_GPIO_PORT, &gpio_init_structure);
-
- /* Enable MCLK clock */
- AUDIO_OUT_SAIx_MCLK_ENABLE();
- /* Enable MCLK pin */
- gpio_init_structure.Pin = AUDIO_OUT_SAIx_MCLK_PIN;
- 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.Request = AUDIO_OUT_SAIx_DMAx_REQUEST;
- 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);
+ xfer_status |= DMA_XFER_HALF;
+ SCB_InvalidateDCache_by_Addr((uint32_t *)(&PDM_BUFFER[0]), PDM_BUFFER_SIZE / 2);
+ PDMIrqHandler(true);
}
-/**
- * @brief Deinitializes SAI MSP.
- * @param hsai: SAI handle
- * @param Params: pointer on additional configuration parameters, can be NULL.
- * @retval None
- */
-__weak void BSP_AUDIO_OUT_MspDeInit(SAI_HandleTypeDef *hsai, void *Params)
+void HAL_SAI_RxCpltCallback(SAI_HandleTypeDef *hsai)
{
- GPIO_InitTypeDef gpio_init_structure;
-
- /* SAI DMA IRQ Channel deactivation */
- HAL_NVIC_DisableIRQ(AUDIO_OUT_SAIx_DMAx_IRQ);
-
- if(hsai->Instance == AUDIO_OUT_SAIx)
- {
- /* Deinitialize the DMA stream */
- HAL_DMA_DeInit(hsai->hdmatx);
- }
-
- /* Disable SAI peripheral */
- __HAL_SAI_DISABLE(hsai);
-
- /* Deactivates CODEC_SAI pins FS, SCK, MCK and SD by putting them in input mode */
- gpio_init_structure.Pin = AUDIO_OUT_SAIx_FS_PIN | AUDIO_OUT_SAIx_SCK_PIN | AUDIO_OUT_SAIx_SD_PIN;
- HAL_GPIO_DeInit(AUDIO_OUT_SAIx_SD_FS_SCK_GPIO_PORT, gpio_init_structure.Pin);
-
- gpio_init_structure.Pin = AUDIO_OUT_SAIx_MCLK_PIN;
- HAL_GPIO_DeInit(AUDIO_OUT_SAIx_MCLK_GPIO_PORT, gpio_init_structure.Pin);
-
- /* Disable SAI clock */
- AUDIO_OUT_SAIx_CLK_DISABLE();
-
- /* GPIO pins clock and DMA clock can be shut down in the applic
- by surcharging this __weak function */
+ xfer_status |= DMA_XFER_FULL;
+ SCB_InvalidateDCache_by_Addr((uint32_t *)(&PDM_BUFFER[PDM_BUFFER_SIZE / 2]), PDM_BUFFER_SIZE / 2);
+ PDMIrqHandler(false);
}
-/**
- * @brief Clock Config.
- * @param hsai: might be required to set audio peripheral predivider if any.
- * @param AudioFreq: Audio frequency used to play the audio stream.
- * @param Params: pointer on additional configuration parameters, can be NULL.
- * @note This API is called by BSP_AUDIO_OUT_Init() and BSP_AUDIO_OUT_SetFrequency()
- * Being __weak it can be overwritten by the application
- * @retval None
- */
-__weak void BSP_AUDIO_OUT_ClockConfig(SAI_HandleTypeDef *hsai, uint32_t AudioFreq, void *Params)
+static uint32_t get_decimation_factor(uint32_t decimation)
{
- RCC_PeriphCLKInitTypeDef rcc_ex_clk_init_struct;
-
- HAL_RCCEx_GetPeriphCLKConfig(&rcc_ex_clk_init_struct);
-
- /* Set the PLL configuration according to the audio frequency */
- if((AudioFreq == AUDIO_FREQUENCY_11K) || (AudioFreq == AUDIO_FREQUENCY_22K) || (AudioFreq == AUDIO_FREQUENCY_44K))
- {
- /* SAI clock config:
- PLL2_VCO Input = HSE_VALUE/PLL2M = 1 Mhz
- PLL2_VCO Output = PLL2_VCO Input * PLL2N = 429 Mhz
- SAI_CLK_x = PLL2_VCO Output/PLL2P = 429/38 = 11.289 Mhz */
- rcc_ex_clk_init_struct.PeriphClockSelection = RCC_PERIPHCLK_SAI1;
- rcc_ex_clk_init_struct.Sai1ClockSelection = RCC_SAI1CLKSOURCE_PLL2;
- rcc_ex_clk_init_struct.PLL2.PLL2P = 38;
- rcc_ex_clk_init_struct.PLL2.PLL2Q = 1;
- rcc_ex_clk_init_struct.PLL2.PLL2R = 1;
- rcc_ex_clk_init_struct.PLL2.PLL2N = 429;
- if (isBoardRev2()) {
- rcc_ex_clk_init_struct.PLL2.PLL2M = 25;
- } else {
- rcc_ex_clk_init_struct.PLL2.PLL2M = 27;
+ switch (decimation) {
+ case 16: return PDM_FILTER_DEC_FACTOR_16;
+ case 24: return PDM_FILTER_DEC_FACTOR_24;
+ case 32: return PDM_FILTER_DEC_FACTOR_32;
+ case 48: return PDM_FILTER_DEC_FACTOR_48;
+ case 64: return PDM_FILTER_DEC_FACTOR_64;
+ case 80: return PDM_FILTER_DEC_FACTOR_80;
+ case 128: return PDM_FILTER_DEC_FACTOR_128;
+ default: return 0;
}
- HAL_RCCEx_PeriphCLKConfig(&rcc_ex_clk_init_struct);
- }
- else /* AUDIO_FREQUENCY_8K, AUDIO_FREQUENCY_16K, AUDIO_FREQUENCY_48K, AUDIO_FREQUENCY_96K */
- {
- /* SAI clock config:
- PLL2_VCO Input = HSE_VALUE/PLL2M = 1 Mhz
- PLL2_VCO Output = PLL2_VCO Input * PLL2N = 344 Mhz
- SAI_CLK_x = PLL2_VCO Output/PLL2P = 344/7 = 49.142 Mhz */
- rcc_ex_clk_init_struct.PeriphClockSelection = RCC_PERIPHCLK_SAI1;
- rcc_ex_clk_init_struct.Sai1ClockSelection = RCC_SAI1CLKSOURCE_PLL2;
- rcc_ex_clk_init_struct.PLL2.PLL2P = 7;
- rcc_ex_clk_init_struct.PLL2.PLL2Q = 1;
- rcc_ex_clk_init_struct.PLL2.PLL2R = 1;
- rcc_ex_clk_init_struct.PLL2.PLL2N = 344;
- if (isBoardRev2()) {
- rcc_ex_clk_init_struct.PLL2.PLL2M = 25;
- } else {
- rcc_ex_clk_init_struct.PLL2.PLL2M = 27;
- }
- HAL_RCCEx_PeriphCLKConfig(&rcc_ex_clk_init_struct);
- }
}
-/**
- * @}
- */
-/** @defgroup STM32H747I_DISCOVERY_AUDIO_OUT_Private_Functions OUT Private Functions
- * @{
- */
-/*******************************************************************************
- HAL Callbacks
-*******************************************************************************/
-/**
- * @brief Tx Transfer completed callbacks.
- * @param hsai: SAI handle
- * @retval None
- */
-void HAL_SAI_TxCpltCallback(SAI_HandleTypeDef *hsai)
+static uint8_t get_mck_div(uint32_t frequency)
{
- /* Manage the remaining file size and new address offset: This function
- should be coded by user (its prototype is already declared in stm32h747i_discovery_audio.h) */
- BSP_AUDIO_OUT_TransferComplete_CallBack();
+ switch(frequency){
+ case AUDIO_FREQUENCY_8K: return 48; //SCK_x = sai_x_ker_ck/48 = 1024KHz Ffs = SCK_x/64 = 16KHz stereo
+ case AUDIO_FREQUENCY_11K: return 8; //SCK_x = sai_x_ker_ck/8 = 1411KHz Ffs = SCK_x/64 = 22KHz stereo
+ case AUDIO_FREQUENCY_16K: return 24; //SCK_x = sai_x_ker_ck/24 = 2048KHz Ffs = SCK_x/64 = 32KHz stereo
+ case AUDIO_FREQUENCY_22K: return 4; //SCK_x = sai_x_ker_ck/4 = 2822KHz Ffs = SCK_x/64 = 44KHz stereo
+ case AUDIO_FREQUENCY_32K: return 12; //SCK_x = sai_x_ker_ck/12 = 4096KHz Ffs = SCK_x/64 = 64KHz stereo
+ case AUDIO_FREQUENCY_44K: return 2; //SCK_x = sai_x_ker_ck/2 = 5644KHz Ffs = SCK_x/64 = 88KHz stereo
+ case AUDIO_FREQUENCY_48K: return 8; //SCK_x = sai_x_ker_ck/8 = 6144KHz Ffs = SCK_x/64 = 96KHz stereo
+ case AUDIO_FREQUENCY_64K: return 6; //SCK_x = sai_x_ker_ck/6 = 8192KHz Ffs = SCK_x/64 = 128KHz stereo
+ case AUDIO_FREQUENCY_96K: return 4; //SCK_x = sai_x_ker_ck/4 = 12288KHz Ffs = SCK_x/64 = 192KHz stereo
+ case AUDIO_FREQUENCY_192K: return 2; //SCK_x = sai_x_ker_ck/2 = 24576KHz Ffs = SCK_x/64 = 384KHz stereo
+ default: return 0; //Same as 1
+ }
}
-/**
- * @brief Tx Half Transfer completed callbacks.
- * @param hsai: SAI handle
- * @retval None
- */
-void HAL_SAI_TxHalfCpltCallback(SAI_HandleTypeDef *hsai)
-{
- /* Manage the remaining file size and new address offset: This function
- should be coded by user (its prototype is already declared in stm32h747i_discovery_audio.h) */
- BSP_AUDIO_OUT_HalfTransfer_CallBack();
-}
-/**
- * @brief SAI error callbacks.
- * @param hsai: SAI handle
- * @retval None
- */
-void HAL_SAI_ErrorCallback(SAI_HandleTypeDef *hsai)
-{
- if(hsai->Instance == AUDIO_OUT_SAIx)
- {
- BSP_AUDIO_OUT_Error_CallBack();
- }
- else
- {
- BSP_AUDIO_IN_Error_CallBack();
+// TODO: this needs to become a library function
+bool isBoardRev2() {
+ uint32_t hse_speed;
+ uint8_t* bootloader_data = (uint8_t*)(0x801F000);
+ if (bootloader_data[0] != 0xA0 || bootloader_data[1] < 14) {
+ hse_speed = 27000000;
+ } else {
+ hse_speed = bootloader_data[10] * 1000000;
}
+ return (hse_speed == 25000000);
}
-/*******************************************************************************
- Static Functions
-*******************************************************************************/
-
-/**
- * @brief Initializes the Audio Codec audio interface (SAI).
- * @param SaiOutMode: Audio mode to be configured for the SAI peripheral.
- * @param SlotActive: Audio active slot to be configured for the SAI peripheral.
- * @param AudioFreq: Audio frequency to be configured for the SAI peripheral.
- * @note The default SlotActive configuration is set to CODEC_AUDIOFRAME_SLOT_0123
- * and user can update this configuration using
- * @retval None
- */
-static void SAIx_Out_Init(uint32_t SaiOutMode, uint32_t SlotActive, uint32_t AudioFreq)
-{
- /* Disable SAI peripheral to allow access to SAI internal registers */
- __HAL_SAI_DISABLE(&haudio_out_sai);
-
- /* Configure SAI_Block_x
- LSBFirst: Disabled
- DataSize: 16 */
- haudio_out_sai.Init.MonoStereoMode = SAI_STEREOMODE;
- haudio_out_sai.Init.AudioFrequency = AudioFreq;
- haudio_out_sai.Init.AudioMode = SaiOutMode;
- haudio_out_sai.Init.NoDivider = SAI_MASTERDIVIDER_ENABLE;
- haudio_out_sai.Init.Protocol = SAI_FREE_PROTOCOL;
- haudio_out_sai.Init.DataSize = SAI_DATASIZE_16;
- haudio_out_sai.Init.FirstBit = SAI_FIRSTBIT_MSB;
- haudio_out_sai.Init.ClockStrobing = SAI_CLOCKSTROBING_RISINGEDGE;
- haudio_out_sai.Init.Synchro = SAI_ASYNCHRONOUS;
- haudio_out_sai.Init.OutputDrive = SAI_OUTPUTDRIVE_ENABLE;
- haudio_out_sai.Init.FIFOThreshold = SAI_FIFOTHRESHOLD_1QF;
- haudio_out_sai.Init.SynchroExt = SAI_SYNCEXT_DISABLE;
- haudio_out_sai.Init.CompandingMode = SAI_NOCOMPANDING;
- haudio_out_sai.Init.TriState = SAI_OUTPUT_NOTRELEASED;
- haudio_out_sai.Init.Mckdiv = 0;
- haudio_out_sai.Init.MckOverSampling = SAI_MCK_OVERSAMPLING_DISABLE;
- haudio_out_sai.Init.PdmInit.Activation = DISABLE;
- haudio_out_sai.Init.PdmInit.ClockEnable = 0;
- haudio_out_sai.Init.PdmInit.MicPairsNbr = 0;
-
- /* Configure SAI_Block_x Frame
- Frame Length: 64
- Frame active Length: 32
- FS Definition: Start frame + Channel Side identification
- FS Polarity: FS active Low
- FS Offset: FS asserted one bit before the first bit of slot 0 */
- haudio_out_sai.FrameInit.FrameLength = 128;
- haudio_out_sai.FrameInit.ActiveFrameLength = 64;
- haudio_out_sai.FrameInit.FSDefinition = SAI_FS_CHANNEL_IDENTIFICATION;
- haudio_out_sai.FrameInit.FSPolarity = SAI_FS_ACTIVE_LOW;
- haudio_out_sai.FrameInit.FSOffset = SAI_FS_BEFOREFIRSTBIT;
-
- /* Configure SAI Block_x Slot
- Slot First Bit Offset: 0
- Slot Size : 16
- Slot Number: 4
- Slot Active: All slot actives */
- haudio_out_sai.SlotInit.FirstBitOffset = 0;
- haudio_out_sai.SlotInit.SlotSize = SAI_SLOTSIZE_DATASIZE;
- haudio_out_sai.SlotInit.SlotNumber = 4;
- haudio_out_sai.SlotInit.SlotActive = SlotActive;
- HAL_SAI_Init(&haudio_out_sai);
-
- /* Enable SAI peripheral to generate MCLK */
- __HAL_SAI_ENABLE(&haudio_out_sai);
-}
-
-/**
- * @brief Deinitializes the Audio Codec audio interface (SAI).
- * @retval None
- */
-static void SAIx_Out_DeInit(SAI_HandleTypeDef *hsai)
+void sai_init()
{
- /* Disable SAI peripheral */
- __HAL_SAI_DISABLE(hsai);
-
- HAL_SAI_DeInit(hsai);
-}
+ GPIO_InitTypeDef GPIO_InitStruct;
+ AUDIO_SAI_CLK_ENABLE();
+ __GPIOB_CLK_ENABLE();
+ __GPIOE_CLK_ENABLE();
-/**
- * @}
- */
+ GPIO_InitStruct.Pin = AUDIO_SAI_CK_PIN;
+ GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
+ GPIO_InitStruct.Alternate = AUDIO_SAI_CK_AF;
+ HAL_GPIO_Init(AUDIO_SAI_CK_PORT, &GPIO_InitStruct);
-/** @defgroup STM32H747I_DISCOVERY_AUDIO_IN_Exported_Functions IN Exported Functions
- * @{
- */
-
-/**
- * @brief Initialize wave recording.
- * @param AudioFreq: Audio frequency to be configured for the DFSDM peripheral.
- * @param BitRes: Audio frequency to be configured for the DFSDM peripheral.
- * @param ChnlNbr: Audio frequency to be configured for the DFSDM peripheral.
- * @retval AUDIO_OK if correct communication, else wrong communication
- */
-uint8_t BSP_AUDIO_IN_Init(uint32_t AudioFreq, uint32_t BitRes, uint32_t ChnlNbr)
-{
- /* Set audio in interface to default one */
- BSP_AUDIO_IN_SelectInterface(AUDIO_IN_INTERFACE_PDM);
- return BSP_AUDIO_IN_InitEx(INPUT_DEVICE_DIGITAL_MIC, AudioFreq, BitRes, ChnlNbr);
+ GPIO_InitStruct.Pin = AUDIO_SAI_D1_PIN;
+ GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
+ GPIO_InitStruct.Alternate = AUDIO_SAI_D1_AF;
+ HAL_GPIO_Init(AUDIO_SAI_D1_PORT, &GPIO_InitStruct);
}
-/**
- * @brief Initialize wave recording.
- * @param InputDevice: INPUT_DEVICE_DIGITAL_MIC or INPUT_DEVICE_ANALOG_MIC.
- * @param AudioFreq: Audio frequency to be configured.
- * @param BitRes: Audio bit resolution to be configured..
- * @param ChnlNbr: Number of channel to be configured.
- * @retval AUDIO_OK if correct communication, else wrong communication
- */
-uint8_t BSP_AUDIO_IN_InitEx(uint16_t InputDevice, uint32_t AudioFreq, uint32_t BitRes, uint32_t ChnlNbr)
+int py_audio_init(size_t channels, uint32_t frequency, int gain_db, float highpass)
{
- uint8_t ret = AUDIO_OK;
- uint32_t slot_active;
-
- /* Store the audio record context */
- hAudioIn.Frequency = AudioFreq;
- hAudioIn.BitResolution = BitRes;
- hAudioIn.InputDevice = InputDevice;
- hAudioIn.ChannelNbr = ChnlNbr;
-
- if(hAudioIn.InputDevice == INPUT_DEVICE_DIGITAL_MIC)
- {
- if(hAudioIn.Interface == AUDIO_IN_INTERFACE_SAI)
- {
- /* Initialize SAI1 block B as SLAVE RX synchrounous with SAI1 block A */
- haudio_in_sai.Instance = AUDIO_IN_SAIx;
-
- /* Disable SAI */
- SAIx_In_DeInit(&haudio_in_sai);
-
- /* PLL clock is set depending on the AudioFreq (44.1khz vs 48khz groups) */
- BSP_AUDIO_IN_ClockConfig(AudioFreq, NULL); /* Clock config is shared between AUDIO IN and OUT */
-
- /* SAI data transfer preparation:
- Prepare the Media to be used for the audio transfer from SAI peripheral to memory */
- if(HAL_SAI_GetState(&haudio_in_sai) == HAL_SAI_STATE_RESET)
- {
- /* Init the SAI MSP: this __weak function can be redefined by the application*/
- BSP_AUDIO_IN_MspInit();
- }
-
- /* Configure SAI in master mode :
- * - SAI1_block_B in slave RX mode synchronous from SAI1_block_A
- */
- slot_active = CODEC_AUDIOFRAME_SLOT_13;
- SAIx_In_Init(SAI_MODESLAVE_RX, slot_active, AudioFreq, ChnlNbr == 1);
- }
- else if(hAudioIn.Interface == AUDIO_IN_INTERFACE_PDM)
- {
- /* Initialize SAI1 block A as MASTER RX */
- haudio_in_sai.Instance = AUDIO_IN_SAI_PDMx;
- /* Disable SAI */
- SAIx_In_DeInit(&haudio_in_sai);
+ RCC_PeriphCLKInitTypeDef rcc_ex_clk_init_struct;
- /* PLL clock is set depending on the AudioFreq (44.1khz vs 48khz groups) */
- BSP_AUDIO_IN_ClockConfig(AudioFreq, NULL);
+ HAL_RCCEx_GetPeriphCLKConfig(&rcc_ex_clk_init_struct);
- /* SAI data transfer preparation:
- Prepare the Media to be used for the audio transfer from SAI peripheral to memory */
- /* Initialize the haudio_in_sai Instance parameter */
-
- if(HAL_SAI_GetState(&haudio_in_sai) == HAL_SAI_STATE_RESET)
- {
- /* Init the SAI MSP: this __weak function can be redefined by the application*/
- BSP_AUDIO_IN_MspInit();
- }
-
- /* Configure SAI in master mode :
- * - SAI1_block_A in master RX mode
- */
- slot_active = CODEC_AUDIOFRAME_SLOT_0;
- SAIx_In_Init(SAI_MODEMASTER_RX, slot_active, AudioFreq, ChnlNbr == 1);
-
- if(BSP_AUDIO_IN_PDMToPCM_Init(AudioFreq, hAudioIn.ChannelNbr, hAudioIn.ChannelNbr) != AUDIO_OK)
- {
- ret = AUDIO_ERROR;
- }
- }
- else
+ if((frequency == AUDIO_FREQUENCY_11K) || (frequency == AUDIO_FREQUENCY_22K) || (frequency == AUDIO_FREQUENCY_44K))
{
- ret = AUDIO_ERROR;
- }
- }
- else
- {
- /* Analog Input */
- ret = AUDIO_ERROR;
- }
-
- /* Return AUDIO_OK when all operations are correctly done */
- return ret;
-}
+ /* SAI clock config:
+ PLL2_VCO Input = HSE_VALUE/PLL2M = 1 Mhz
+ PLL2_VCO Output = PLL2_VCO Input * PLL2N = 429 Mhz
+ SAI_CLK_x = PLL2_VCO Output/PLL2P = 429/38 = 11.289 Mhz */
+ rcc_ex_clk_init_struct.PeriphClockSelection = RCC_PERIPHCLK_SAI4A;
+ rcc_ex_clk_init_struct.Sai4AClockSelection = RCC_SAI4ACLKSOURCE_PLL2;
+ rcc_ex_clk_init_struct.PLL2.PLL2P = 38;
+ rcc_ex_clk_init_struct.PLL2.PLL2Q = 1;
+ rcc_ex_clk_init_struct.PLL2.PLL2R = 1;
+ rcc_ex_clk_init_struct.PLL2.PLL2N = 429;
+ rcc_ex_clk_init_struct.PLL2.PLL2M = isBoardRev2() ? 25 : 27;
-
-/**
- * @brief Initializes wave recording and playback in parallel.
- * @param InputDevice: INPUT_DEVICE_DIGITAL_MICROPHONE_2
- * @param OutputDevice: OUTPUT_DEVICE_SPEAKER, OUTPUT_DEVICE_HEADPHONE,
- * or OUTPUT_DEVICE_BOTH.
- * @param AudioFreq: Audio frequency to be configured for the SAI peripheral.
- * @param BitRes: Audio frequency to be configured.
- * @param ChnlNbr: Channel number.
- * @retval AUDIO_OK if correct communication, else wrong communication
- */
-uint8_t BSP_AUDIO_IN_OUT_Init(uint32_t InputDevice, uint32_t OutputDevice, uint32_t AudioFreq, uint32_t BitRes, uint32_t ChnlNbr)
-{
- uint32_t slot_active;
- uint32_t deviceid = 0, ret = AUDIO_OK;
-
- /* Store the audio record context */
- hAudioIn.Frequency = AudioFreq;
- hAudioIn.BitResolution = BitRes;
- hAudioIn.InputDevice = InputDevice;
- hAudioIn.ChannelNbr = ChnlNbr;
-
- /* Input device is Digital MIC2 and Codec interface is SAI */
- if (hAudioIn.InputDevice == INPUT_DEVICE_DIGITAL_MICROPHONE_2)
- {
- haudio_in_sai.Instance = AUDIO_IN_SAIx;
- haudio_out_sai.Instance = AUDIO_OUT_SAIx;
-
- /* PLL clock is set depending on the AudioFreq (44.1khz vs 48khz groups) */
- BSP_AUDIO_OUT_ClockConfig(&haudio_in_sai, AudioFreq, NULL);
- /* SAI data transfer preparation:
- Prepare the Media to be used for the audio transfer from SAI peripheral to memory */
- if(HAL_SAI_GetState(&haudio_in_sai) == HAL_SAI_STATE_RESET)
- {
- /* Init the SAI MSP: this __weak function can be redefined by the application*/
- BSP_AUDIO_IN_MspInit();
- }
-
- /* SAI data transfer preparation:
- Prepare the Media to be used for the audio transfer from memory to SAI peripheral */
- if(HAL_SAI_GetState(&haudio_out_sai) == HAL_SAI_STATE_RESET)
- {
- /* Init the SAI MSP: this __weak function can be redefined by the application*/
- BSP_AUDIO_OUT_MspInit(&haudio_out_sai, NULL);
+ } else {
+ /* SAI clock config:
+ PLL2_VCO Input = HSE_VALUE/PLL2M = 1 Mhz
+ PLL2_VCO Output = PLL2_VCO Input * PLL2N = 344 Mhz
+ sai_x_ker_ck = PLL2_VCO Output/PLL2P = 344/7 = 49.142 Mhz */
+ rcc_ex_clk_init_struct.PeriphClockSelection = RCC_PERIPHCLK_SAI4A;
+ rcc_ex_clk_init_struct.Sai4AClockSelection = RCC_SAI4ACLKSOURCE_PLL2;
+ rcc_ex_clk_init_struct.PLL2.PLL2P = 7;
+ rcc_ex_clk_init_struct.PLL2.PLL2Q = 1;
+ rcc_ex_clk_init_struct.PLL2.PLL2R = 1;
+ rcc_ex_clk_init_struct.PLL2.PLL2N = 344;
+ rcc_ex_clk_init_struct.PLL2.PLL2M = isBoardRev2() ? 25 : 27;
}
- /* Configure SAI in master TX mode :
- * - SAI1_block_A in master TX mode
- * - SAI1_block_B in slave RX mode synchronous from SAI1_block_A
- */
- slot_active = CODEC_AUDIOFRAME_SLOT_13;
- SAIx_In_Init(SAI_MODESLAVE_RX, slot_active, AudioFreq, ChnlNbr == 1);
-
- slot_active = CODEC_AUDIOFRAME_SLOT_02;
- SAIx_Out_Init(SAI_MODEMASTER_TX, slot_active, AudioFreq);
-
- /* wm8994 codec initialization */
- deviceid = wm8994_drv.ReadID(AUDIO_I2C_ADDRESS);
-
- if((deviceid) == WM8994_ID)
- {
- /* Reset the Codec Registers */
- wm8994_drv.Reset(AUDIO_I2C_ADDRESS);
- /* Initialize the audio driver structure */
- audio_drv = &wm8994_drv;
- ret = AUDIO_OK;
- }
- else
- {
- ret = AUDIO_ERROR;
- }
+ HAL_RCCEx_PeriphCLKConfig(&rcc_ex_clk_init_struct);
- if(ret == AUDIO_OK)
- {
- /* Initialize the codec internal registers */
- audio_drv->Init(AUDIO_I2C_ADDRESS, InputDevice|OutputDevice, 90, AudioFreq);
+ sai_init();
+
+ // Sanity checks
+ if ((frequency != AUDIO_FREQUENCY_8K) &&
+ (frequency != AUDIO_FREQUENCY_11K) &&
+ (frequency != AUDIO_FREQUENCY_16K) &&
+ (frequency != AUDIO_FREQUENCY_22K) &&
+ (frequency != AUDIO_FREQUENCY_32K) &&
+ (frequency != AUDIO_FREQUENCY_44K) &&
+ (frequency != AUDIO_FREQUENCY_48K) &&
+ (frequency != AUDIO_FREQUENCY_64K) &&
+ (frequency != AUDIO_FREQUENCY_96K)){
+ return 0;
}
- }
- else
- {
- ret = AUDIO_ERROR;
- }
-
- /* Return AUDIO_OK when all operations are correctly done */
- return ret;
-}
-
-/**
- * @brief Link digital mic to specified source
- * @param Interface : Audio In interface for Digital mic. It can be:
- * AUDIO_IN_INTERFACE_SAI
- * AUDIO_IN_INTERFACE_PDM
- * @retval None
- */
-void BSP_AUDIO_IN_SelectInterface(uint32_t Interface)
-{
- hAudioIn.Interface = Interface;
-}
-
-/**
- * @brief Get digital mic interface
- * @retval Digital mic interface.
- */
-uint32_t BSP_AUDIO_IN_GetInterface(void)
-{
- return (hAudioIn.Interface);
-}
-
-/**
- * @brief Return audio in channel number
- * @retval Number of channel
- */
-uint8_t BSP_AUDIO_IN_GetChannelNumber(void)
-{
- return hAudioIn.ChannelNbr;
-}
-
-/**
- * @brief Start audio recording.
- * @param pBuf: Main buffer pointer for the recorded data storing
- * @param size: Current size of the recorded buffer
- * @retval AUDIO_OK if correct communication, else wrong communication
- */
-uint8_t BSP_AUDIO_IN_Record(uint16_t *pBuf, uint32_t size)
-{
- /* Start the process receive DMA */
- if(HAL_OK != HAL_SAI_Receive_DMA(&haudio_in_sai, (uint8_t*)pBuf, size))
- {
- return AUDIO_ERROR;
- }
-
- /* Return AUDIO_OK when all operations are correctly done */
- return AUDIO_OK;
-}
-
-/**
- * @brief Stop audio recording.
- * @retval AUDIO_OK if correct communication, else wrong communication
- */
-uint8_t BSP_AUDIO_IN_Stop(void)
-{
- /* Call the Media layer stop function */
- HAL_SAI_DMAStop(&haudio_in_sai);
-
- /* Return AUDIO_OK when all operations are correctly done */
- return AUDIO_OK;
-}
-
-/**
- * @brief Pause the audio file stream.
- * @retval AUDIO_OK if correct communication, else wrong communication
- */
-uint8_t BSP_AUDIO_IN_Pause(void)
-{
- if (hAudioIn.InputDevice == INPUT_DEVICE_ANALOG_MIC)
- {
- return AUDIO_ERROR;
- }
- else
- {
- /* Call the Media layer pause function */
- HAL_SAI_DMAPause(&haudio_in_sai);
- }
-
- /* Return AUDIO_OK when all operations are correctly done */
- return AUDIO_OK;
-}
-
-/**
- * @brief Resume the audio file stream.
- * @retval AUDIO_OK if correct communication, else wrong communication
- */
-uint8_t BSP_AUDIO_IN_Resume(void)
-{
- if (hAudioIn.InputDevice == INPUT_DEVICE_ANALOG_MIC)
- {
- return AUDIO_ERROR;
- }
- else
- {
- /* Call the Media layer resume function */
- HAL_SAI_DMAResume(&haudio_in_sai);
- }
-
- /* Return AUDIO_OK when all operations are correctly done */
- return AUDIO_OK;
-}
-
-/**
- * @brief Controls the audio in volume level.
- * @param Volume: Volume level to be set in percentage from 0% to 100% (0 for
- * Mute and 100 for Max volume level).
- * @retval AUDIO_OK if correct communication, else wrong communication
- */
-uint8_t BSP_AUDIO_IN_SetVolume(uint8_t Volume)
-{
- /* Set the Global variable AudioInVolume */
- AudioInVolume = Volume;
-
- /* Return AUDIO_OK when all operations are correctly done */
- return AUDIO_OK;
-}
-
-/**
- * @brief Deinit the audio IN peripherals.
- * @retval None
- */
-void BSP_AUDIO_IN_DeInit(void)
-{
- SAIx_In_DeInit(&haudio_in_sai);
-
- BSP_AUDIO_IN_MspDeInit();
-}
-
-/**
-* @brief Initialize the PDM library.
-* @param AudioFreq: Audio sampling frequency
-* @param ChnlNbrIn: Number of input audio channels in the PDM buffer
-* @param ChnlNbrOut: Number of desired output audio channels in the resulting PCM buffer
-* @retval None
-*/
-uint8_t BSP_AUDIO_IN_PDMToPCM_Init(uint32_t AudioFreq, uint32_t ChnlNbrIn, uint32_t ChnlNbrOut)
-{
- uint32_t index = 0;
-
- /* Enable CRC peripheral to unlock the PDM library */
- __HAL_RCC_CRC_CLK_ENABLE();
-
- for(index = 0; index < ChnlNbrIn; index++)
- {
- /* Init PDM filters */
- PDM_FilterHandler[index].bit_order = PDM_FILTER_BIT_ORDER_MSB;
- PDM_FilterHandler[index].endianness = PDM_FILTER_ENDIANNESS_LE;
- PDM_FilterHandler[index].high_pass_tap = 2122358088;
- PDM_FilterHandler[index].out_ptr_channels = ChnlNbrOut;
- PDM_FilterHandler[index].in_ptr_channels = ChnlNbrIn;
- PDM_Filter_Init((PDM_Filter_Handler_t *)(&PDM_FilterHandler[index]));
-
- /* PDM lib config phase */
- PDM_FilterConfig[index].output_samples_number = AudioFreq/1000;
- PDM_FilterConfig[index].mic_gain = 24;
- PDM_FilterConfig[index].decimation_factor = PDM_FILTER_DEC_FACTOR_64;
- PDM_Filter_setConfig((PDM_Filter_Handler_t *)&PDM_FilterHandler[index], &PDM_FilterConfig[index]);
- }
-
- return AUDIO_OK;
-}
-
-
-/**
-* @brief Converts audio format from PDM to PCM.
-
-* @param PDMBuf: Pointer to PDM buffer data
-* @param PCMBuf: Pointer to PCM buffer data
-* @retval AUDIO_OK in case of success, AUDIO_ERROR otherwise
-*/
-uint8_t BSP_AUDIO_IN_PDMToPCM(uint16_t *PDMBuf, uint16_t *PCMBuf)
-{
- uint32_t index = 0;
-
- for(index = 0; index < hAudioIn.ChannelNbr; index++)
- {
- PDM_Filter(&((uint8_t*)(PDMBuf))[index], (uint16_t*)&(PCMBuf[index]), &PDM_FilterHandler[index]);
- }
-
- return AUDIO_OK;
-}
-
-/**
- * @brief User callback when record buffer is filled.
- * @retval None
- */
-__weak void BSP_AUDIO_IN_TransferComplete_CallBack(void)
-{
- /* This function should be implemented by the user application.
- It is called into this driver when the current buffer is filled
- to prepare the next buffer pointer and its size. */
-}
-
-/**
- * @brief Manages the DMA Half Transfer complete event.
- * @retval None
- */
-__weak void BSP_AUDIO_IN_HalfTransfer_CallBack(void)
-{
- /* This function should be implemented by the user application.
- It is called into this driver when the current buffer is filled
- to prepare the next buffer pointer and its size. */
-}
-/**
- * @brief User callback when record buffer is filled.
- * @param InputDevice: INPUT_DEVICE_DIGITAL_MIC1 or INPUT_DEVICE_DIGITAL_MIC2
- */
-__weak void BSP_AUDIO_IN_TransferComplete_CallBackEx(uint32_t InputDevice)
-{
- /* This function should be implemented by the user application.
- It is called into this driver when the current buffer is filled
- to prepare the next buffer pointer and its size. */
-}
-
-/**
- * @brief User callback when record buffer is filled.
- * @param InputDevice: INPUT_DEVICE_DIGITAL_MIC1 or INPUT_DEVICE_DIGITAL_MIC2
- */
-__weak void BSP_AUDIO_IN_HalfTransfer_CallBackEx(uint32_t InputDevice)
-{
- /* This function should be implemented by the user application.
- It is called into this driver when the current buffer is filled
- to prepare the next buffer pointer and its size. */
-}
-
-/**
- * @brief Audio IN Error callback function.
- * @retval None
- */
-__weak void BSP_AUDIO_IN_Error_CallBack(void)
-{
- /* This function is called when an Interrupt due to transfer error on or peripheral
- error occurs. */
-}
-
-/**
- * @brief Initialize BSP_AUDIO_IN MSP.
- * @retval None
- */
-__weak void BSP_AUDIO_IN_MspInit(void)
-{
- SAIx_In_MspInit(&haudio_in_sai, NULL);
-}
-
-/**
- * @brief DeInitialize BSP_AUDIO_IN MSP.
- * @retval None
- */
-__weak void BSP_AUDIO_IN_MspDeInit(void)
-{
- SAIx_In_MspDeInit(&haudio_in_sai, NULL);
-}
-
-/**
- * @brief Clock Config.
- * @param AudioFreq: Audio frequency used to play the audio stream.
- * @param Params: pointer on additional configuration parameters, can be NULL.
- * @note This API is called by BSP_AUDIO_IN_Init()
- * Being __weak it can be overwritten by the application
- * @retval None
- */
-__weak void BSP_AUDIO_IN_ClockConfig(uint32_t AudioFreq, void *Params)
-{
- RCC_PeriphCLKInitTypeDef rcc_ex_clk_init_struct;
-
- HAL_RCCEx_GetPeriphCLKConfig(&rcc_ex_clk_init_struct);
-
- /* Set the PLL configuration according to the audio frequency */
- if((AudioFreq == AUDIO_FREQUENCY_11K) || (AudioFreq == AUDIO_FREQUENCY_22K) || (AudioFreq == AUDIO_FREQUENCY_44K))
- {
- /* SAI clock config:
- PLL2_VCO Input = HSE_VALUE/PLL2M = 1 Mhz
- PLL2_VCO Output = PLL2_VCO Input * PLL2N = 429 Mhz
- SAI_CLK_x = PLL2_VCO Output/PLL2P = 429/38 = 11.289 Mhz */
- rcc_ex_clk_init_struct.PeriphClockSelection = RCC_PERIPHCLK_SAI1;
- rcc_ex_clk_init_struct.Sai1ClockSelection = RCC_SAI1CLKSOURCE_PLL2;
- rcc_ex_clk_init_struct.PLL2.PLL2P = 38;
- rcc_ex_clk_init_struct.PLL2.PLL2Q = 1;
- rcc_ex_clk_init_struct.PLL2.PLL2R = 1;
- rcc_ex_clk_init_struct.PLL2.PLL2N = 429;
- if (isBoardRev2()) {
- rcc_ex_clk_init_struct.PLL2.PLL2M = 25;
+ if (channels != 1 && channels != 2) {
+ return 0;
} else {
- rcc_ex_clk_init_struct.PLL2.PLL2M = 27;
- }
- if (hAudioIn.Interface == AUDIO_IN_INTERFACE_PDM)
- {
- rcc_ex_clk_init_struct.PeriphClockSelection = RCC_PERIPHCLK_SAI4A;
- rcc_ex_clk_init_struct.Sai4AClockSelection = RCC_SAI4ACLKSOURCE_PLL2;
+ g_o_channels = channels;
}
- HAL_RCCEx_PeriphCLKConfig(&rcc_ex_clk_init_struct);
- }
- else /* AUDIO_FREQUENCY_8K, AUDIO_FREQUENCY_16K, AUDIO_FREQUENCY_32K, AUDIO_FREQUENCY_48K, AUDIO_FREQUENCY_96K */
- {
- /* SAI clock config:
- PLL2_VCO Input = HSE_VALUE/PLL2M = 1 Mhz
- PLL2_VCO Output = PLL2_VCO Input * PLL2N = 344 Mhz
- SAI_CLK_x = PLL2_VCO Output/PLL2P = 344/7 = 49.142 Mhz */
- rcc_ex_clk_init_struct.PeriphClockSelection = RCC_PERIPHCLK_SAI1;
- rcc_ex_clk_init_struct.Sai1ClockSelection = RCC_SAI1CLKSOURCE_PLL2;
- rcc_ex_clk_init_struct.PLL2.PLL2P = 7;
- rcc_ex_clk_init_struct.PLL2.PLL2Q = 1;
- rcc_ex_clk_init_struct.PLL2.PLL2R = 1;
- rcc_ex_clk_init_struct.PLL2.PLL2N = 344;
- if (isBoardRev2()) {
- rcc_ex_clk_init_struct.PLL2.PLL2M = 25;
- } else {
- rcc_ex_clk_init_struct.PLL2.PLL2M = 27;
+ uint32_t decimation_factor = 64; // Fixed decimation factor
+ uint32_t decimation_factor_const = get_decimation_factor(decimation_factor);
+ if (decimation_factor_const == 0) {
+ return 0;
}
- if (hAudioIn.Interface == AUDIO_IN_INTERFACE_PDM)
- {
- rcc_ex_clk_init_struct.PeriphClockSelection = RCC_PERIPHCLK_SAI4A;
- rcc_ex_clk_init_struct.Sai4AClockSelection = RCC_SAI4ACLKSOURCE_PLL2;
+ uint32_t samples_per_channel = (PDM_BUFFER_SIZE * 8) / (decimation_factor * g_i_channels * 2); // Half a transfer
+
+ hsai.Instance = AUDIO_SAI;
+ hsai.Init.Protocol = SAI_FREE_PROTOCOL;
+ hsai.Init.AudioMode = SAI_MODEMASTER_RX;
+ hsai.Init.DataSize = (g_i_channels == 1) ? SAI_DATASIZE_8 : SAI_DATASIZE_16;
+ hsai.Init.FirstBit = SAI_FIRSTBIT_LSB;
+ hsai.Init.ClockStrobing = SAI_CLOCKSTROBING_RISINGEDGE;
+ hsai.Init.Synchro = SAI_ASYNCHRONOUS;
+ hsai.Init.OutputDrive = SAI_OUTPUTDRIVE_DISABLE;
+ hsai.Init.NoDivider = SAI_MASTERDIVIDER_DISABLE;
+ hsai.Init.FIFOThreshold = SAI_FIFOTHRESHOLD_1QF;
+ hsai.Init.SynchroExt = SAI_SYNCEXT_DISABLE;
+ hsai.Init.AudioFrequency = SAI_AUDIO_FREQUENCY_MCKDIV;
+ hsai.Init.MonoStereoMode = (g_i_channels == 1) ? SAI_MONOMODE: SAI_STEREOMODE;
+ hsai.Init.CompandingMode = SAI_NOCOMPANDING;
+ hsai.Init.TriState = SAI_OUTPUT_RELEASED;
+
+ // The master clock output (MCLK_x) is disabled and the SAI clock
+ // is passed out to SCK_x bit clock. SCKx frequency = SAI_KER_CK / MCKDIV
+ hsai.Init.Mckdiv = get_mck_div(frequency);
+ hsai.Init.MckOutput = SAI_MCK_OUTPUT_DISABLE;
+ hsai.Init.MckOverSampling = SAI_MCK_OVERSAMPLING_DISABLE;
+
+ // Enable and configure PDM mode.
+ hsai.Init.PdmInit.Activation = ENABLE;
+ hsai.Init.PdmInit.MicPairsNbr = 1;
+ hsai.Init.PdmInit.ClockEnable = SAI_PDM_CLOCK1_ENABLE;
+
+ hsai.FrameInit.FrameLength = 16;
+ hsai.FrameInit.ActiveFrameLength = 1;
+ hsai.FrameInit.FSDefinition = SAI_FS_STARTFRAME;
+ hsai.FrameInit.FSPolarity = SAI_FS_ACTIVE_HIGH;
+ hsai.FrameInit.FSOffset = SAI_FS_FIRSTBIT;
+
+ hsai.SlotInit.FirstBitOffset = 0;
+ hsai.SlotInit.SlotSize = SAI_SLOTSIZE_DATASIZE;
+ hsai.SlotInit.SlotNumber = (g_i_channels == 1) ? 2 : 1;
+ hsai.SlotInit.SlotActive = (g_i_channels == 1) ? (SAI_SLOTACTIVE_0 | SAI_SLOTACTIVE_1) : SAI_SLOTACTIVE_0;
+
+ // Initialize the SAI
+ HAL_SAI_DeInit(&hsai);
+ if (HAL_SAI_Init(&hsai) != HAL_OK) {
+ return 0;
}
- HAL_RCCEx_PeriphCLKConfig(&rcc_ex_clk_init_struct);
- }
-}
-/**
- * @}
- */
-
-
-/** @defgroup STM32H747I_DISCOVERY_AUDIO_IN_Private_Functions IN Private Functions
- * @{
- */
-
-/*******************************************************************************
- HAL Callbacks
-*******************************************************************************/
-
-/**
- * @brief Half reception complete callback.
- * @param hsai: SAI handle.
- * @retval None
- */
-void HAL_SAI_RxHalfCpltCallback(SAI_HandleTypeDef *hsai)
-{
- /* Manage the remaining file size and new address offset: This function should be coded by user */
- BSP_AUDIO_IN_HalfTransfer_CallBack();
-}
-
-/**
- * @brief Reception complete callback.
- * @param hsai: SAI handle.
- * @retval None
- */
-void HAL_SAI_RxCpltCallback(SAI_HandleTypeDef *hsai)
-{
- /* Call the record update function to get the next buffer to fill and its size (size is ignored) */
- BSP_AUDIO_IN_TransferComplete_CallBack();
-}
-
-/*******************************************************************************
- Static Functions
-*******************************************************************************/
-/**
- * @brief Initializes SAI Audio IN MSP.
- * @param hsai: SAI handle
- * @param Params: pointer on additional configuration parameters, can be NULL.
- * @retval None
- */
-static void SAIx_In_MspInit(SAI_HandleTypeDef *hsai, void *Params)
-{
- static DMA_HandleTypeDef hdma_sai_rx;
- GPIO_InitTypeDef gpio_init_structure;
-
- if(hsai->Instance == AUDIO_IN_SAI_PDMx)
- {
- /* Enable SAI clock */
- AUDIO_IN_SAI_PDMx_CLK_ENABLE();
-
- AUDIO_IN_SAI_PDMx_CLK_IN_ENABLE();
- AUDIO_IN_SAI_PDMx_DATA_IN_ENABLE();
-
- gpio_init_structure.Pin = AUDIO_IN_SAI_PDMx_CLK_IN_PIN;
- gpio_init_structure.Mode = GPIO_MODE_AF_PP;
- gpio_init_structure.Pull = GPIO_NOPULL;
- gpio_init_structure.Speed = GPIO_SPEED_FREQ_MEDIUM;
- gpio_init_structure.Alternate = AUDIO_IN_SAI_PDMx_DATA_CLK_AF;
- HAL_GPIO_Init(AUDIO_IN_SAI_PDMx_CLK_IN_PORT, &gpio_init_structure);
-
- gpio_init_structure.Pull = GPIO_PULLUP;
- gpio_init_structure.Speed = GPIO_SPEED_FREQ_MEDIUM;
- gpio_init_structure.Pin = AUDIO_IN_SAI_PDMx_DATA_IN_PIN;
- HAL_GPIO_Init(AUDIO_IN_SAI_PDMx_DATA_IN_PORT, &gpio_init_structure);
- AUDIO_IN_SAI_PDMx_FS_SCK_ENABLE();
+ // Enable the DMA clock
+ AUDIO_SAI_DMA_CLK_ENABLE();
- /* CODEC_SAI pins configuration: FS, SCK, MCK and SD pins ------------------*/
- gpio_init_structure.Pin = AUDIO_IN_SAI_PDMx_FS_PIN | AUDIO_IN_SAI_PDMx_SCK_PIN;
- gpio_init_structure.Mode = GPIO_MODE_AF_PP;
- gpio_init_structure.Pull = GPIO_NOPULL;
- gpio_init_structure.Speed = GPIO_SPEED_FREQ_HIGH;
- gpio_init_structure.Alternate = AUDIO_IN_SAI_PDMx_FS_SCK_AF;
- HAL_GPIO_Init(AUDIO_IN_SAI_PDMx_FS_SCK_GPIO_PORT, &gpio_init_structure);
-
- /* Enable the DMA clock */
- AUDIO_IN_SAI_PDMx_DMAx_CLK_ENABLE();
-
- /* Configure the hdma_sai_rx handle parameters */
- hdma_sai_rx.Init.Request = AUDIO_IN_SAI_PDMx_DMAx_REQUEST;
+ // Configure the SAI DMA
+ hdma_sai_rx.Instance = AUDIO_SAI_DMA_STREAM;
+ hdma_sai_rx.Init.Request = AUDIO_SAI_DMA_REQUEST;
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_SAI_PDMx_DMAx_PERIPH_DATA_SIZE;
- hdma_sai_rx.Init.MemDataAlignment = AUDIO_IN_SAI_PDMx_DMAx_MEM_DATA_SIZE;
+ hdma_sai_rx.Init.PeriphDataAlignment = (g_i_channels == 1) ? DMA_PDATAALIGN_BYTE : DMA_PDATAALIGN_HALFWORD;
+ hdma_sai_rx.Init.MemDataAlignment = (g_i_channels == 1) ? DMA_MDATAALIGN_BYTE : DMA_MDATAALIGN_HALFWORD;
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.FIFOMode = DMA_FIFOMODE_ENABLE;
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;
+ __HAL_LINKDMA(&hsai, hdmarx, hdma_sai_rx);
- hdma_sai_rx.Instance = AUDIO_IN_SAI_PDMx_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_SAI_PDMx_DMAx_IRQ, AUDIO_IN_IRQ_PREPRIO, 0);
- HAL_NVIC_EnableIRQ(AUDIO_IN_SAI_PDMx_DMAx_IRQ);
- }
- else
- {
- /* 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_FREQ_HIGH;
- gpio_init_structure.Alternate = AUDIO_IN_SAIx_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_FREQ_HIGH;
- HAL_GPIO_Init(AUDIO_IN_INT_GPIO_PORT, &gpio_init_structure);
-
- /* Enable the DMA clock */
- AUDIO_IN_SAIx_DMAx_CLK_ENABLE();
-
- /* Configure the hdma_sai_rx handle parameters */
- hdma_sai_rx.Init.Request = AUDIO_IN_SAIx_DMAx_REQUEST;
- 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 */
+ // Initialize the DMA stream
HAL_DMA_DeInit(&hdma_sai_rx);
+ if (HAL_DMA_Init(&hdma_sai_rx) != HAL_OK) {
+ return 0;
+ }
- /* Configure the DMA Stream */
- HAL_DMA_Init(&hdma_sai_rx);
+ // Configure and enable SAI DMA IRQ Channel
+ HAL_NVIC_SetPriority(AUDIO_SAI_DMA_IRQ, AUDIO_IN_IRQ_PREPRIO, 0);
+ HAL_NVIC_EnableIRQ(AUDIO_SAI_DMA_IRQ);
+
+ // Init CRC for the PDM library
+ hcrc.Instance = CRC;
+ hcrc.Init.DefaultPolynomialUse = DEFAULT_POLYNOMIAL_ENABLE;
+ hcrc.Init.DefaultInitValueUse = DEFAULT_INIT_VALUE_ENABLE;
+ hcrc.Init.InputDataInversionMode = CRC_INPUTDATA_INVERSION_NONE;
+ hcrc.Init.OutputDataInversionMode = CRC_OUTPUTDATA_INVERSION_DISABLE;
+ hcrc.InputDataFormat = CRC_INPUTDATA_FORMAT_BYTES;
+ if (HAL_CRC_Init(&hcrc) != HAL_OK) {
+ return 0;
+ }
+ __HAL_CRC_DR_RESET(&hcrc);
+
+ // Configure PDM filters
+ for (int i=0; iInstance == AUDIO_IN_SAI_PDMx)
- {
- /* Deinitialize the DMA stream */
- HAL_DMA_Abort(hsai->hdmarx);
-
- HAL_SAI_DeInit(hsai);
- /* Disable SAI peripheral */
- __HAL_SAI_DISABLE(hsai);
-
- /* Deinitialize the DMA stream */
- HAL_DMA_DeInit(hsai->hdmarx);
-
- gpio_init_structure.Pin = AUDIO_IN_SAI_PDMx_CLK_IN_PIN;
- HAL_GPIO_DeInit(AUDIO_IN_SAI_PDMx_CLK_IN_PORT, gpio_init_structure.Pin);
-
- gpio_init_structure.Pin = AUDIO_IN_SAI_PDMx_DATA_IN_PIN;
- HAL_GPIO_DeInit(AUDIO_IN_SAI_PDMx_DATA_IN_PORT, gpio_init_structure.Pin);
-
- /* CODEC_SAI pins configuration: FS, SCK, MCK and SD pins ------------------*/
- gpio_init_structure.Pin = AUDIO_IN_SAI_PDMx_FS_PIN | AUDIO_IN_SAI_PDMx_SCK_PIN;
- HAL_GPIO_DeInit(AUDIO_IN_SAI_PDMx_FS_SCK_GPIO_PORT, gpio_init_structure.Pin);
-
- /* Disable SAI clock */
- AUDIO_IN_SAI_PDMx_CLK_DISABLE();
- }
- else
- {
- /* SAI DMA IRQ Channel deactivation */
- HAL_NVIC_DisableIRQ(AUDIO_IN_SAIx_DMAx_IRQ);
-
- if(hsai->Instance == AUDIO_IN_SAIx)
- {
- /* Deinitialize the DMA stream */
- HAL_DMA_DeInit(hsai->hdmatx);
+ // Stop SAI DMA.
+ if (hdma_sai_rx.Instance != NULL) {
+ HAL_SAI_DMAStop(&hsai);
}
- /* Disable SAI peripheral */
- __HAL_SAI_DISABLE(hsai);
+ // Disable IRQs
+ HAL_NVIC_DisableIRQ(AUDIO_SAI_DMA_IRQ);
- /* Deactivates CODEC_SAI pin SD by putting them in input mode */
- gpio_init_structure.Pin = AUDIO_IN_SAIx_SD_PIN;
- HAL_GPIO_DeInit(AUDIO_IN_SAIx_SD_GPIO_PORT, gpio_init_structure.Pin);
+ if (hsai.Instance != NULL) {
+ HAL_SAI_DeInit(&hsai);
+ hsai.Instance = NULL;
+ }
- gpio_init_structure.Pin = AUDIO_IN_INT_GPIO_PIN;
- HAL_GPIO_DeInit(AUDIO_IN_INT_GPIO_PORT, gpio_init_structure.Pin);
+ if (hdma_sai_rx.Instance != NULL) {
+ HAL_DMA_DeInit(&hdma_sai_rx);
+ hdma_sai_rx.Instance = NULL;
+ }
- /* Disable SAI clock */
- AUDIO_IN_SAIx_CLK_DISABLE();
- }
+ g_i_channels = 0;
+ g_o_channels = 0;
+ //free(g_pcmbuf);
+ g_pcmbuf = NULL;
}
-/**
- * @brief Initializes the Audio Codec audio interface (SAI).
- * @param SaiInMode: Audio mode to be configured for the SAI peripheral.
- * @param SlotActive: Audio active slot to be configured for the SAI peripheral.
- * @param AudioFreq: Audio frequency to be configured for the SAI peripheral.
- * @retval None
- */
-static void SAIx_In_Init(uint32_t SaiInMode, uint32_t SlotActive, uint32_t AudioFreq, bool mono)
+void audio_pendsv_callback(void)
{
- /* Disable SAI peripheral to allow access to SAI internal registers */
- __HAL_SAI_DISABLE(&haudio_in_sai);
-
- /* Configure SAI_Block_x
- LSBFirst: Disabled
- DataSize: 16 */
- haudio_in_sai.Init.MonoStereoMode = mono ? SAI_MONOMODE : SAI_STEREOMODE;
- haudio_in_sai.Init.AudioFrequency = AudioFreq;
- haudio_in_sai.Init.AudioMode = SaiInMode;
- haudio_in_sai.Init.NoDivider = SAI_MASTERDIVIDER_ENABLE;
- haudio_in_sai.Init.Protocol = SAI_FREE_PROTOCOL;
- haudio_in_sai.Init.DataSize = SAI_DATASIZE_16;
- haudio_in_sai.Init.FirstBit = SAI_FIRSTBIT_MSB;
- haudio_in_sai.Init.ClockStrobing = SAI_CLOCKSTROBING_RISINGEDGE;
- haudio_in_sai.Init.Synchro = SAI_SYNCHRONOUS;
- haudio_in_sai.Init.OutputDrive = SAI_OUTPUTDRIVE_DISABLE;
- haudio_in_sai.Init.FIFOThreshold = SAI_FIFOTHRESHOLD_1QF;
- haudio_in_sai.Init.SynchroExt = SAI_SYNCEXT_DISABLE;
- haudio_in_sai.Init.CompandingMode = SAI_NOCOMPANDING;
- haudio_in_sai.Init.TriState = SAI_OUTPUT_RELEASED;
- haudio_in_sai.Init.Mckdiv = 0;
- haudio_in_sai.Init.MckOverSampling = SAI_MCK_OVERSAMPLING_DISABLE;
- haudio_in_sai.Init.PdmInit.Activation = DISABLE;
-
- /* Configure SAI_Block_x Frame
- Frame Length: 64
- Frame active Length: 32
- FS Definition: Start frame + Channel Side identification
- FS Polarity: FS active Low
- FS Offset: FS asserted one bit before the first bit of slot 0 */
- haudio_in_sai.FrameInit.FrameLength = 128;
- haudio_in_sai.FrameInit.ActiveFrameLength = 64;
- haudio_in_sai.FrameInit.FSDefinition = SAI_FS_CHANNEL_IDENTIFICATION;
- haudio_in_sai.FrameInit.FSPolarity = SAI_FS_ACTIVE_LOW;
- haudio_in_sai.FrameInit.FSOffset = SAI_FS_BEFOREFIRSTBIT;
-
- /* Configure SAI Block_x Slot
- Slot First Bit Offset: 0
- Slot Size : 16
- Slot Number: 4
- Slot Active: All slot active */
- haudio_in_sai.SlotInit.FirstBitOffset = 0;
- haudio_in_sai.SlotInit.SlotSize = SAI_SLOTSIZE_DATASIZE;
- haudio_in_sai.SlotInit.SlotNumber = 4;
- haudio_in_sai.SlotInit.SlotActive = SlotActive;
-
- if(hAudioIn.Interface == AUDIO_IN_INTERFACE_PDM)
- {
- haudio_in_sai.Init.AudioFrequency = AudioFreq * 8;
- haudio_in_sai.Init.Synchro = SAI_ASYNCHRONOUS;
- haudio_in_sai.Init.NoDivider = SAI_MASTERDIVIDER_DISABLE;
+ // Check for half transfer complete.
+ if ((xfer_status & DMA_XFER_HALF)) {
+ // Clear buffer state.
+ xfer_status &= ~(DMA_XFER_HALF);
- haudio_in_sai.Init.PdmInit.Activation = ENABLE;
- haudio_in_sai.Init.PdmInit.MicPairsNbr = 1;
- haudio_in_sai.Init.PdmInit.ClockEnable = SAI_PDM_CLOCK1_ENABLE;
- haudio_in_sai.Init.FirstBit = SAI_FIRSTBIT_LSB;
- haudio_in_sai.Init.ClockStrobing = SAI_CLOCKSTROBING_FALLINGEDGE;
+ // Convert PDM samples to PCM.
+ for (int i=0; i© Copyright (c) 2019 STMicroelectronics.
- * All rights reserved.
- *
- * This software component is licensed by ST under BSD 3-Clause license,
- * the "License"; You may not use this file except in compliance with the
- * License. You may obtain a copy of the License at:
- * opensource.org/licenses/BSD-3-Clause
- *
- ******************************************************************************
- */
+#ifdef TARGET_STM
-/* Define to prevent recursive inclusion -------------------------------------*/
-#ifndef __STM32H747I_DISCOVERY_AUDIO_H
-#define __STM32H747I_DISCOVERY_AUDIO_H
+#include "stdbool.h"
-#ifdef __cplusplus
- extern "C" {
-#endif
+// SAI4
+#define AUDIO_SAI (SAI4_Block_A)
+// SCKx frequency = SAI_KER_CK / MCKDIV / 2
+#define AUDIO_SAI_MCKDIV (12)
+#define AUDIO_SAI_FREQKHZ (2048U) // 2048KHz
+#define AUDIO_SAI_NBR_CHANNELS (2) // Default number of channels.
-/* Includes ------------------------------------------------------------------*/
-/* Include audio component Driver */
-#include "wm8994.h"
-#include "stm32h7xx_hal.h"
-#include
-#include
-/* Include PDM to PCM lib header file */
-#include "pdm2pcm_glo.h"
+#define AUDIO_SAI_CK_PORT (GPIOE)
+#define AUDIO_SAI_CK_PIN (GPIO_PIN_2)
+#define AUDIO_SAI_CK_AF (GPIO_AF10_SAI4)
-/** @addtogroup BSP
- * @{
- */
+#define AUDIO_SAI_D1_PORT (GPIOB)
+#define AUDIO_SAI_D1_PIN (GPIO_PIN_2)
+#define AUDIO_SAI_D1_AF (GPIO_AF10_SAI4)
-/** @addtogroup STM32H747I_DISCOVERY
- * @{
- */
-
-/** @addtogroup STM32H747I_DISCOVERY_AUDIO
- * @{
- */
+#define AUDIO_SAI_DMA_STREAM BDMA_Channel1
+#define AUDIO_SAI_DMA_REQUEST BDMA_REQUEST_SAI4_A
+#define AUDIO_SAI_DMA_IRQ BDMA_Channel1_IRQn
+#define AUDIO_SAI_DMA_IRQHandler BDMA_Channel1_IRQHandler
-/** @defgroup STM32H747I_DISCOVERY_AUDIO_Exported_Types Exported Types
- * @{
- */
-typedef struct
-{
- uint32_t Frequency; /* Record Frequency */
- uint32_t BitResolution; /* Record bit resolution */
- uint32_t ChannelNbr; /* Record Channel Number */
- uint16_t *pRecBuf; /* Pointer to record user buffer */
- uint32_t RecSize; /* Size to record in mono, double size to record in stereo */
- uint32_t InputDevice; /* Audio Input Device */
- uint32_t Interface; /* Audio Input Interface */
- uint32_t MultiBuffMode; /* Multi buffer mode selection */
-}AUDIOIN_ContextTypeDef;
-/**
- * @}
- */
+#define AUDIO_SAI_CLK_ENABLE() __HAL_RCC_SAI4_CLK_ENABLE()
+#define AUDIO_SAI_CLK_DISABLE() __HAL_RCC_SAI4_CLK_DISABLE()
+#define AUDIO_SAI_DMA_CLK_ENABLE() __HAL_RCC_BDMA_CLK_ENABLE()
-/** @defgroup STM32H747I_DISCOVERY_AUDIO_Exported_Constants Exported Constants
- * @{
- */
-#define BSP_AUDIO_FREQUENCY_96K SAI_AUDIO_FREQUENCY_96K
-#define BSP_AUDIO_FREQUENCY_48K SAI_AUDIO_FREQUENCY_48K
-#define BSP_AUDIO_FREQUENCY_44K SAI_AUDIO_FREQUENCY_44K
-#define BSP_AUDIO_FREQUENCY_32K SAI_AUDIO_FREQUENCY_32K
-#define BSP_AUDIO_FREQUENCY_22K SAI_AUDIO_FREQUENCY_22K
-#define BSP_AUDIO_FREQUENCY_16K SAI_AUDIO_FREQUENCY_16K
-#define BSP_AUDIO_FREQUENCY_11K SAI_AUDIO_FREQUENCY_11K
-#define BSP_AUDIO_FREQUENCY_8K SAI_AUDIO_FREQUENCY_8K
-
-/*------------------------------------------------------------------------------
- USER SAI defines parameters
- -----------------------------------------------------------------------------*/
-/** In W8994 codec the Audio frame contains 4 slots : TDM Mode
- * TDM format :
- * +------------------|------------------|--------------------|-------------------+
- * | CODEC_SLOT0 Left | CODEC_SLOT1 Left | CODEC_SLOT0 Right | CODEC_SLOT1 Right |
- * +------------------------------------------------------------------------------+
- */
-/* To have 2 separate audio stream in Both headphone and speaker the 4 slot must be activated */
-#define CODEC_AUDIOFRAME_SLOT_0123 SAI_SLOTACTIVE_0 | SAI_SLOTACTIVE_1 | SAI_SLOTACTIVE_2 | SAI_SLOTACTIVE_3
-
-/* To have an audio stream in headphone only SAI Slot 0 and Slot 2 must be activated */
-#define CODEC_AUDIOFRAME_SLOT_02 SAI_SLOTACTIVE_0 | SAI_SLOTACTIVE_2
-/* To have an audio stream in speaker only SAI Slot 1 and Slot 3 must be activated */
-#define CODEC_AUDIOFRAME_SLOT_13 SAI_SLOTACTIVE_1 | SAI_SLOTACTIVE_3
-/* To have an audio stream in SAI PDM input Slot 0 must be activated */
-#define CODEC_AUDIOFRAME_SLOT_0 SAI_SLOTACTIVE_0
-
-/*------------------------------------------------------------------------------
- AUDIO OUT CONFIGURATION
-------------------------------------------------------------------------------*/
-/* SAI peripheral configuration defines */
-#define AUDIO_OUT_SAIx SAI1_Block_A
-#define AUDIO_OUT_SAIx_CLK_ENABLE() __HAL_RCC_SAI1_CLK_ENABLE()
-#define AUDIO_OUT_SAIx_CLK_DISABLE() __HAL_RCC_SAI1_CLK_DISABLE()
-#define AUDIO_OUT_SAIx_AF GPIO_AF6_SAI1
-
-#define AUDIO_OUT_SAIx_MCLK_ENABLE() __HAL_RCC_GPIOG_CLK_ENABLE()
-#define AUDIO_OUT_SAIx_MCLK_GPIO_PORT GPIOG
-#define AUDIO_OUT_SAIx_MCLK_PIN GPIO_PIN_7
-#define AUDIO_OUT_SAIx_SD_FS_CLK_ENABLE() __HAL_RCC_GPIOE_CLK_ENABLE()
-#define AUDIO_OUT_SAIx_SD_FS_SCK_GPIO_PORT GPIOE
-#define AUDIO_OUT_SAIx_FS_PIN GPIO_PIN_4
-#define AUDIO_OUT_SAIx_SCK_PIN GPIO_PIN_5
-#define AUDIO_OUT_SAIx_SD_PIN GPIO_PIN_6
-
-/* SAI DMA Stream definitions */
-#define AUDIO_OUT_SAIx_DMAx_CLK_ENABLE() __HAL_RCC_DMA2_CLK_ENABLE()
-#define AUDIO_OUT_SAIx_DMAx_STREAM DMA2_Stream1
-#define AUDIO_OUT_SAIx_DMAx_REQUEST DMA_REQUEST_SAI1_A
-#define AUDIO_OUT_SAIx_DMAx_IRQ DMA2_Stream1_IRQn
-#define AUDIO_OUT_SAIx_DMAx_PERIPH_DATA_SIZE DMA_PDATAALIGN_HALFWORD
-#define AUDIO_OUT_SAIx_DMAx_MEM_DATA_SIZE DMA_MDATAALIGN_HALFWORD
-#define AUDIO_OUT_SAIx_DMAx_IRQHandler DMA2_Stream1_IRQHandler
-
-/* Select the interrupt preemption priority and subpriority for the DMA interrupt */
-#define AUDIO_OUT_IRQ_PREPRIO ((uint32_t)0x0E)
-
-/*------------------------------------------------------------------------------
- AUDIO IN CONFIGURATION
-------------------------------------------------------------------------------*/
-/* SAI peripheral configuration defines */
-#define AUDIO_IN_SAIx SAI1_Block_B
-#define AUDIO_IN_SAIx_CLK_ENABLE() __HAL_RCC_SAI1_CLK_ENABLE()
-#define AUDIO_IN_SAIx_CLK_DISABLE() __HAL_RCC_SAI1_CLK_DISABLE()
-#define AUDIO_IN_SAIx_AF GPIO_AF6_SAI1
-#define AUDIO_IN_SAIx_SD_ENABLE() __HAL_RCC_GPIOE_CLK_ENABLE()
-#define AUDIO_IN_SAIx_SD_GPIO_PORT GPIOE
-#define AUDIO_IN_SAIx_SD_PIN GPIO_PIN_3
-
-/* SAI DMA Stream definitions */
-#define AUDIO_IN_SAIx_DMAx_CLK_ENABLE() __HAL_RCC_DMA2_CLK_ENABLE()
-#define AUDIO_IN_SAIx_DMAx_STREAM DMA2_Stream4
-#define AUDIO_IN_SAIx_DMAx_REQUEST DMA_REQUEST_SAI1_B
-#define AUDIO_IN_SAIx_DMAx_IRQ DMA2_Stream4_IRQn
-#define AUDIO_IN_SAIx_DMAx_PERIPH_DATA_SIZE DMA_PDATAALIGN_HALFWORD
-#define AUDIO_IN_SAIx_DMAx_MEM_DATA_SIZE DMA_MDATAALIGN_HALFWORD
-
-#define AUDIO_IN_SAIx_DMAx_IRQHandler DMA2_Stream4_IRQHandler
-
-#define AUDIO_IN_INT_GPIO_ENABLE() __HAL_RCC_GPIOJ_CLK_ENABLE()
-#define AUDIO_IN_INT_GPIO_PORT GPIOJ
-#define AUDIO_IN_INT_GPIO_PIN GPIO_PIN_15
-#define AUDIO_IN_INT_IRQ EXTI15_10_IRQn
-
-/* SAI PDM input definitions */
-#define AUDIO_IN_SAI_PDMx SAI4_Block_A
-#define AUDIO_IN_SAI_PDMx_CLK_ENABLE() __HAL_RCC_SAI4_CLK_ENABLE()
-#define AUDIO_IN_SAI_PDMx_CLK_DISABLE() __HAL_RCC_SAI4_CLK_DISABLE()
-#define AUDIO_IN_SAI_PDMx_FS_SCK_AF GPIO_AF8_SAI4
-#define AUDIO_IN_SAI_PDMx_FS_SCK_ENABLE() __HAL_RCC_GPIOE_CLK_ENABLE()
-#define AUDIO_IN_SAI_PDMx_FS_SCK_GPIO_PORT GPIOE
-#define AUDIO_IN_SAI_PDMx_FS_PIN GPIO_PIN_4
-#define AUDIO_IN_SAI_PDMx_SCK_PIN GPIO_PIN_5
-
-#define AUDIO_IN_SAI_PDMx_CLK_IN_ENABLE() __HAL_RCC_GPIOE_CLK_ENABLE()
-#define AUDIO_IN_SAI_PDMx_CLK_IN_PIN GPIO_PIN_2
-#define AUDIO_IN_SAI_PDMx_CLK_IN_PORT GPIOE
-#define AUDIO_IN_SAI_PDMx_DATA_IN_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE()
-#define AUDIO_IN_SAI_PDMx_DATA_IN_PIN GPIO_PIN_2
-#define AUDIO_IN_SAI_PDMx_DATA_IN_PORT GPIOB
-#define AUDIO_IN_SAI_PDMx_DATA_CLK_AF GPIO_AF10_SAI4
-#define AUDIO_IN_SAI_PDMx_IRQHandler SAI4_IRQHandler
-#define AUDIO_IN_SAI_PDMx_IRQ SAI4_IRQn
-
-/* SAI PDM DMA Stream definitions */
-#define AUDIO_IN_SAI_PDMx_DMAx_CLK_ENABLE() __HAL_RCC_BDMA_CLK_ENABLE()
-#define AUDIO_IN_SAI_PDMx_DMAx_STREAM BDMA_Channel1
-#define AUDIO_IN_SAI_PDMx_DMAx_REQUEST BDMA_REQUEST_SAI4_A
-#define AUDIO_IN_SAI_PDMx_DMAx_IRQ BDMA_Channel1_IRQn
-#define AUDIO_IN_SAI_PDMx_DMAx_PERIPH_DATA_SIZE DMA_PDATAALIGN_HALFWORD
-#define AUDIO_IN_SAI_PDMx_DMAx_MEM_DATA_SIZE DMA_MDATAALIGN_HALFWORD
-#define AUDIO_IN_SAI_PDMx_DMAx_IRQHandler BDMA_Channel1_IRQHandler
-
-/* Select the interrupt preemption priority and subpriority for the DMA interrupt */
#define AUDIO_IN_IRQ_PREPRIO ((uint32_t)0x0F)
-#define AUDIO_I2C_ADDRESS (0x2c)
-
-/*------------------------------------------------------------------------------
- CONFIGURATION: Audio Driver Configuration parameters
-------------------------------------------------------------------------------*/
-
-#define AUDIODATA_SIZE ((uint32_t)2) /* 16-bits audio data size */
-
-/* Audio status definition */
-#define AUDIO_OK ((uint8_t)0)
-#define AUDIO_ERROR ((uint8_t)1)
-#define AUDIO_TIMEOUT ((uint8_t)2)
-
-/* Audio In default settings */
-#define DEFAULT_AUDIO_IN_FREQ BSP_AUDIO_FREQUENCY_16K
-#define DEFAULT_AUDIO_IN_BIT_RESOLUTION ((uint8_t)16)
-#define DEFAULT_AUDIO_IN_CHANNEL_NBR ((uint8_t)2)
-#define DEFAULT_AUDIO_IN_VOLUME ((uint16_t)64)
-
-/*------------------------------------------------------------------------------
- OUTPUT DEVICES definition
-------------------------------------------------------------------------------*/
-/* Alias on existing output devices to adapt for 2 headphones output */
-#define OUTPUT_DEVICE_HEADPHONE1 OUTPUT_DEVICE_HEADPHONE
-#define OUTPUT_DEVICE_HEADPHONE2 OUTPUT_DEVICE_SPEAKER /* Headphone2 is connected to Speaker output of the wm8994 */
-
-/*------------------------------------------------------------------------------
- INPUT DEVICES definition
-------------------------------------------------------------------------------*/
-/* Analog microphone input from 3.5 audio jack connector */
-#define INPUT_DEVICE_ANALOG_MIC ((uint32_t)0x00000001)
-/* MP34DT01TR digital microphone on PCB top side */
-#define INPUT_DEVICE_DIGITAL_MIC1 ((uint32_t)0x00000010)
-#define INPUT_DEVICE_DIGITAL_MIC2 ((uint32_t)0x00000020)
-#define INPUT_DEVICE_DIGITAL_MIC ((uint32_t)(INPUT_DEVICE_DIGITAL_MIC1 | INPUT_DEVICE_DIGITAL_MIC2))
-
-/* Audio In interface for Digital mic */
-#define AUDIO_IN_INTERFACE_SAI ((uint16_t)0)
-#define AUDIO_IN_INTERFACE_PDM ((uint16_t)1)
-
-/**
- * @}
- */
-
-/** @defgroup STM32H747I_DISCOVERY_AUDIO_Exported_Macros Exported Macros
- * @{
- */
-#define DMA_MAX_SIZE 0xFFFF
-#define DMA_MAX(x) (((x) <= DMA_MAX_SIZE)? (x):DMA_MAX_SIZE)
-#define POS_VAL(VAL) (POSITION_VAL(VAL) - 4)
-/**
- * @}
- */
-
-/** @addtogroup STM32H747I_DISCOVERY_AUDIO_OUT_Exported_Functions
- * @{
- */
-uint8_t BSP_AUDIO_OUT_Init(uint16_t OutputDevice, uint8_t Volume, uint32_t AudioFreq);
-void BSP_AUDIO_OUT_DeInit(void);
-uint8_t BSP_AUDIO_OUT_Play(uint16_t* pBuffer, uint32_t Size);
-void BSP_AUDIO_OUT_ChangeBuffer(uint16_t *pData, uint16_t Size);
-uint8_t BSP_AUDIO_OUT_Pause(void);
-uint8_t BSP_AUDIO_OUT_Resume(void);
-uint8_t BSP_AUDIO_OUT_Stop(uint32_t Option);
-uint8_t BSP_AUDIO_OUT_SetVolume(uint8_t Volume);
-void BSP_AUDIO_OUT_SetFrequency(uint32_t AudioFreq);
-void BSP_AUDIO_OUT_SetAudioFrameSlot(uint32_t AudioFrameSlot);
-uint8_t BSP_AUDIO_OUT_SetMute(uint32_t Cmd);
-uint8_t BSP_AUDIO_OUT_SetOutputMode(uint8_t Output);
-
-/* User Callbacks: user has to implement these functions in his code if they are needed. */
-/* This function is called when the requested data has been completely transferred.*/
-void BSP_AUDIO_OUT_TransferComplete_CallBack(void);
-
-/* This function is called when half of the requested buffer has been transferred. */
-void BSP_AUDIO_OUT_HalfTransfer_CallBack(void);
-
-/* This function is called when an Interrupt due to transfer error on or peripheral
- error occurs. */
-void BSP_AUDIO_OUT_Error_CallBack(void);
-
-/* These function can be modified in case the current settings (e.g. DMA stream)
- need to be changed for specific application needs */
-void BSP_AUDIO_OUT_ClockConfig(SAI_HandleTypeDef *hsai, uint32_t AudioFreq, void *Params);
-void BSP_AUDIO_OUT_MspInit(SAI_HandleTypeDef *hsai, void *Params);
-void BSP_AUDIO_OUT_MspDeInit(SAI_HandleTypeDef *hsai, void *Params);
-
-/**
- * @}
- */
-
-/** @addtogroup STM32H747I_DISCOVERY_AUDIO_IN_Exported_Functions
- * @{
- */
-uint8_t BSP_AUDIO_IN_Init(uint32_t AudioFreq, uint32_t BitRes, uint32_t ChnlNbr);
-uint8_t BSP_AUDIO_IN_InitEx(uint16_t InputDevice, uint32_t AudioFreq, uint32_t BitRes, uint32_t ChnlNbr);
-uint8_t BSP_AUDIO_IN_AllocScratch (int32_t *pScratch, uint32_t size);
-uint8_t BSP_AUDIO_IN_Record(uint16_t *pBuf, uint32_t Size);
-uint8_t BSP_AUDIO_IN_RecordEx(uint32_t *pBuf, uint32_t Size);
-uint8_t BSP_AUDIO_IN_SetFrequency(uint32_t AudioFreq);
-uint8_t BSP_AUDIO_IN_Stop(void);
-uint8_t BSP_AUDIO_IN_StopEx(uint32_t InputDevice);
-uint8_t BSP_AUDIO_IN_Pause(void);
-uint8_t BSP_AUDIO_IN_PauseEx(uint32_t InputDevice);
-uint8_t BSP_AUDIO_IN_Resume(void);
-uint8_t BSP_AUDIO_IN_ResumeEx(uint32_t *pBuf, uint32_t InputDevice);
-uint8_t BSP_AUDIO_IN_SetVolume(uint8_t Volume);
-void BSP_AUDIO_IN_DeInit(void);
-uint8_t BSP_AUDIO_IN_PDMToPCM(uint16_t *PDMBuf, uint16_t *PCMBuf);
-uint8_t BSP_AUDIO_IN_PDMToPCM_Init(uint32_t AudioFreq, uint32_t ChnlNbrIn, uint32_t ChnlNbrOut);
-void BSP_AUDIO_IN_SelectInterface(uint32_t Interface);
-uint32_t BSP_AUDIO_IN_GetInterface(void);
-uint8_t BSP_AUDIO_IN_OUT_Init(uint32_t InputDevice, uint32_t OutputDevice, uint32_t AudioFreq, uint32_t BitRes, uint32_t ChnlNbr);
-uint8_t BSP_AUDIO_IN_GetChannelNumber(void);
-void BSP_AUDIO_IN_Error_Callback(void);
-
-/* User Callbacks: user has to implement these functions in his code if they are needed. */
-/* This function should be implemented by the user application.
- It is called into this driver when the current buffer is filled to prepare the next
- buffer pointer and its size. */
-void BSP_AUDIO_IN_TransferComplete_CallBack(void);
-void BSP_AUDIO_IN_HalfTransfer_CallBack(void);
-void BSP_AUDIO_IN_TransferComplete_CallBackEx(uint32_t InputDevice);
-void BSP_AUDIO_IN_HalfTransfer_CallBackEx(uint32_t InputDevice);
-
-/* This function is called when an Interrupt due to transfer error on or peripheral
- error occurs. */
-void BSP_AUDIO_IN_Error_CallBack(void);
-
-/* These function can be modified in case the current settings (e.g. DMA stream)
- need to be changed for specific application needs */
-void BSP_AUDIO_IN_ClockConfig(uint32_t AudioFreq, void *Params);
-void BSP_AUDIO_IN_MspInit(void);
-void BSP_AUDIO_IN_MspDeInit(void);
+#define PDM_BUFFER_SIZE (1024)
+void py_audio_deinit();
+int py_audio_init(size_t g_channels, uint32_t frequency, int gain_db, float highpass);
+void audio_pendsv_callback(void);
+void py_audio_start_streaming();
+void py_audio_stop_streaming();
bool isBoardRev2();
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-/**
- * @}
- */
-
-#ifdef __cplusplus
-}
#endif
-
-#endif /* __STM32H747I_DISCOVERY_AUDIO_H */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/libraries/PDM/src/stm32/codec_api.h b/libraries/PDM/src/stm32/codec_api.h
deleted file mode 100644
index 8b93673ff..000000000
--- a/libraries/PDM/src/stm32/codec_api.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/**
- ******************************************************************************
- * @file audio.h
- * @author MCD Application Team
- * @version V4.0.1
- * @date 21-July-2015
- * @brief This header file contains the common defines and functions prototypes
- * for the Audio driver.
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2015 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- * 3. Neither the name of STMicroelectronics nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- ******************************************************************************
- */
-
-/* Define to prevent recursive inclusion -------------------------------------*/
-#ifndef __AUDIO_H
-#define __AUDIO_H
-
-#ifdef __cplusplus
- extern "C" {
-#endif
-
-/* Includes ------------------------------------------------------------------*/
-#include
-
-/** @addtogroup BSP
- * @{
- */
-
-/** @addtogroup Components
- * @{
- */
-
-/** @addtogroup AUDIO
- * @{
- */
-
-/** @defgroup AUDIO_Exported_Constants
- * @{
- */
-
-/* Codec audio Standards */
-#define CODEC_STANDARD 0x04
-#define I2S_STANDARD I2S_STANDARD_PHILIPS
-
-/**
- * @}
- */
-
-/** @defgroup AUDIO_Exported_Types
- * @{
- */
-
-/** @defgroup AUDIO_Driver_structure Audio Driver structure
- * @{
- */
-typedef struct
-{
- uint32_t (*Init)(uint16_t, uint16_t, uint8_t, uint32_t);
- void (*DeInit)(void);
- uint32_t (*ReadID)(uint16_t);
- uint32_t (*Play)(uint16_t, uint16_t*, uint16_t);
- uint32_t (*Pause)(uint16_t);
- uint32_t (*Resume)(uint16_t);
- uint32_t (*Stop)(uint16_t, uint32_t);
- uint32_t (*SetFrequency)(uint16_t, uint32_t);
- uint32_t (*SetVolume)(uint16_t, uint8_t);
- uint32_t (*SetMute)(uint16_t, uint32_t);
- uint32_t (*SetOutputMode)(uint16_t, uint8_t);
- uint32_t (*Reset)(uint16_t);
-}AUDIO_DrvTypeDef;
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __AUDIO_H */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/libraries/PDM/src/stm32/irq.c b/libraries/PDM/src/stm32/irq.c
deleted file mode 100644
index cb7042f1b..000000000
--- a/libraries/PDM/src/stm32/irq.c
+++ /dev/null
@@ -1,28 +0,0 @@
-#ifdef TARGET_STM
-
-#include "audio.h"
-
-extern SAI_HandleTypeDef haudio_out_sai;
-extern SAI_HandleTypeDef haudio_in_sai;
-
-void DMA2_Stream6_IRQHandler(void)
-{
- HAL_DMA_IRQHandler(haudio_out_sai.hdmatx);
-}
-
-void AUDIO_OUT_SAIx_DMAx_IRQHandler(void)
-{
- HAL_DMA_IRQHandler(haudio_out_sai.hdmatx);
-}
-
-/**
- * @brief This function handles BDMA Channel 1 for SAI_PDM interrupt request.
- * @param None
- * @retval None
- */
-void AUDIO_IN_SAI_PDMx_DMAx_IRQHandler(void)
-{
- HAL_DMA_IRQHandler(haudio_in_sai.hdmarx);
-}
-
-#endif
\ No newline at end of file
diff --git a/libraries/PDM/src/stm32/wm8994.c b/libraries/PDM/src/stm32/wm8994.c
deleted file mode 100644
index fa6371a72..000000000
--- a/libraries/PDM/src/stm32/wm8994.c
+++ /dev/null
@@ -1,1043 +0,0 @@
-/**
- ******************************************************************************
- * @file wm8994.c
- * @author MCD Application Team
- * @version V2.1.0
- * @date 22-February-2016
- * @brief This file provides the WM8994 Audio Codec driver.
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2016 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- * 3. Neither the name of STMicroelectronics nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- ******************************************************************************
- */
-
-#ifdef TARGET_STM
-/* Includes ------------------------------------------------------------------*/
-#include "wm8994.h"
-
-/** @addtogroup BSP
- * @{
- */
-
-/** @addtogroup Components
- * @{
- */
-
-/** @addtogroup wm8994
- * @brief This file provides a set of functions needed to drive the
- * WM8994 audio codec.
- * @{
- */
-
-/** @defgroup WM8994_Private_Types
- * @{
- */
-
-/**
- * @}
- */
-
-/** @defgroup WM8994_Private_Defines
- * @{
- */
-/* Uncomment this line to enable verifying data sent to codec after each write
- operation (for debug purpose) */
-#if !defined (VERIFY_WRITTENDATA)
-/*#define VERIFY_WRITTENDATA*/
-#endif /* VERIFY_WRITTENDATA */
-/**
- * @}
- */
-
-/** @defgroup WM8994_Private_Macros
- * @{
- */
-
-/**
- * @}
- */
-
-/** @defgroup WM8994_Private_Variables
- * @{
- */
-
-/* Audio codec driver structure initialization */
-AUDIO_DrvTypeDef wm8994_drv =
-{
- wm8994_Init,
- wm8994_DeInit,
- wm8994_ReadID,
-
- wm8994_Play,
- wm8994_Pause,
- wm8994_Resume,
- wm8994_Stop,
-
- wm8994_SetFrequency,
- wm8994_SetVolume,
- wm8994_SetMute,
- wm8994_SetOutputMode,
-
- wm8994_Reset
-};
-
-static uint32_t outputEnabled = 0;
-static uint32_t inputEnabled = 0;
-/**
- * @}
- */
-
-/** @defgroup WM8994_Function_Prototypes
- * @{
- */
-static uint8_t CODEC_IO_Write(uint8_t Addr, uint16_t Reg, uint16_t Value);
-/**
- * @}
- */
-
-/** @defgroup WM8994_Private_Functions
- * @{
- */
-
-/**
- * @brief Initializes the audio codec and the control interface.
- * @param DeviceAddr: Device address on communication Bus.
- * @param OutputInputDevice: can be OUTPUT_DEVICE_SPEAKER, OUTPUT_DEVICE_HEADPHONE,
- * OUTPUT_DEVICE_BOTH, OUTPUT_DEVICE_AUTO, INPUT_DEVICE_DIGITAL_MICROPHONE_1,
- * INPUT_DEVICE_DIGITAL_MICROPHONE_2, INPUT_DEVICE_DIGITAL_MIC1_MIC2,
- * INPUT_DEVICE_INPUT_LINE_1 or INPUT_DEVICE_INPUT_LINE_2.
- * @param Volume: Initial volume level (from 0 (Mute) to 100 (Max))
- * @param AudioFreq: Audio Frequency
- * @retval 0 if correct communication, else wrong communication
- */
-uint32_t wm8994_Init(uint16_t DeviceAddr, uint16_t OutputInputDevice, uint8_t Volume, uint32_t AudioFreq)
-{
- uint32_t counter = 0;
- uint16_t output_device = OutputInputDevice & 0xFF;
- uint16_t input_device = OutputInputDevice & 0xFF00;
- uint16_t power_mgnt_reg_1 = 0;
-
- /* Initialize the Control interface of the Audio Codec */
- AUDIO_IO_Init();
- /* wm8994 Errata Work-Arounds */
- counter += CODEC_IO_Write(DeviceAddr, 0x102, 0x0003);
- counter += CODEC_IO_Write(DeviceAddr, 0x817, 0x0000);
- counter += CODEC_IO_Write(DeviceAddr, 0x102, 0x0000);
-
- /* Enable VMID soft start (fast), Start-up Bias Current Enabled */
- counter += CODEC_IO_Write(DeviceAddr, 0x39, 0x006C);
-
- /* Enable bias generator, Enable VMID */
- if (input_device > 0)
- {
- counter += CODEC_IO_Write(DeviceAddr, 0x01, 0x0013);
- }
- else
- {
- counter += CODEC_IO_Write(DeviceAddr, 0x01, 0x0003);
- }
-
- /* Add Delay */
- AUDIO_IO_Delay(50);
-
- /* Path Configurations for output */
- if (output_device > 0)
- {
- outputEnabled = 1;
- switch (output_device)
- {
- case OUTPUT_DEVICE_SPEAKER:
- /* Enable DAC1 (Left), Enable DAC1 (Right),
- Disable DAC2 (Left), Disable DAC2 (Right)*/
- counter += CODEC_IO_Write(DeviceAddr, 0x05, 0x0C0C);
-
- /* Enable the AIF1 Timeslot 0 (Left) to DAC 1 (Left) mixer path */
- counter += CODEC_IO_Write(DeviceAddr, 0x601, 0x0000);
-
- /* Enable the AIF1 Timeslot 0 (Right) to DAC 1 (Right) mixer path */
- counter += CODEC_IO_Write(DeviceAddr, 0x602, 0x0000);
-
- /* Disable the AIF1 Timeslot 1 (Left) to DAC 2 (Left) mixer path */
- counter += CODEC_IO_Write(DeviceAddr, 0x604, 0x0002);
-
- /* Disable the AIF1 Timeslot 1 (Right) to DAC 2 (Right) mixer path */
- counter += CODEC_IO_Write(DeviceAddr, 0x605, 0x0002);
- break;
-
- case OUTPUT_DEVICE_HEADPHONE:
- /* Disable DAC1 (Left), Disable DAC1 (Right),
- Enable DAC2 (Left), Enable DAC2 (Right)*/
- counter += CODEC_IO_Write(DeviceAddr, 0x05, 0x0303);
-
- /* Enable the AIF1 Timeslot 0 (Left) to DAC 1 (Left) mixer path */
- counter += CODEC_IO_Write(DeviceAddr, 0x601, 0x0001);
-
- /* Enable the AIF1 Timeslot 0 (Right) to DAC 1 (Right) mixer path */
- counter += CODEC_IO_Write(DeviceAddr, 0x602, 0x0001);
-
- /* Disable the AIF1 Timeslot 1 (Left) to DAC 2 (Left) mixer path */
- counter += CODEC_IO_Write(DeviceAddr, 0x604, 0x0000);
-
- /* Disable the AIF1 Timeslot 1 (Right) to DAC 2 (Right) mixer path */
- counter += CODEC_IO_Write(DeviceAddr, 0x605, 0x0000);
- break;
-
- case OUTPUT_DEVICE_BOTH:
- if (input_device == INPUT_DEVICE_DIGITAL_MIC1_MIC2)
- {
- /* Enable DAC1 (Left), Enable DAC1 (Right),
- also Enable DAC2 (Left), Enable DAC2 (Right)*/
- counter += CODEC_IO_Write(DeviceAddr, 0x05, 0x0303 | 0x0C0C);
-
- /* Enable the AIF1 Timeslot 0 (Left) to DAC 1 (Left) mixer path
- Enable the AIF1 Timeslot 1 (Left) to DAC 1 (Left) mixer path */
- counter += CODEC_IO_Write(DeviceAddr, 0x601, 0x0003);
-
- /* Enable the AIF1 Timeslot 0 (Right) to DAC 1 (Right) mixer path
- Enable the AIF1 Timeslot 1 (Right) to DAC 1 (Right) mixer path */
- counter += CODEC_IO_Write(DeviceAddr, 0x602, 0x0003);
-
- /* Enable the AIF1 Timeslot 0 (Left) to DAC 2 (Left) mixer path
- Enable the AIF1 Timeslot 1 (Left) to DAC 2 (Left) mixer path */
- counter += CODEC_IO_Write(DeviceAddr, 0x604, 0x0003);
-
- /* Enable the AIF1 Timeslot 0 (Right) to DAC 2 (Right) mixer path
- Enable the AIF1 Timeslot 1 (Right) to DAC 2 (Right) mixer path */
- counter += CODEC_IO_Write(DeviceAddr, 0x605, 0x0003);
- }
- else
- {
- /* Enable DAC1 (Left), Enable DAC1 (Right),
- also Enable DAC2 (Left), Enable DAC2 (Right)*/
- counter += CODEC_IO_Write(DeviceAddr, 0x05, 0x0303 | 0x0C0C);
-
- /* Enable the AIF1 Timeslot 0 (Left) to DAC 1 (Left) mixer path */
- counter += CODEC_IO_Write(DeviceAddr, 0x601, 0x0001);
-
- /* Enable the AIF1 Timeslot 0 (Right) to DAC 1 (Right) mixer path */
- counter += CODEC_IO_Write(DeviceAddr, 0x602, 0x0001);
-
- /* Enable the AIF1 Timeslot 1 (Left) to DAC 2 (Left) mixer path */
- counter += CODEC_IO_Write(DeviceAddr, 0x604, 0x0002);
-
- /* Enable the AIF1 Timeslot 1 (Right) to DAC 2 (Right) mixer path */
- counter += CODEC_IO_Write(DeviceAddr, 0x605, 0x0002);
- }
- break;
-
- case OUTPUT_DEVICE_AUTO :
- default:
- /* Disable DAC1 (Left), Disable DAC1 (Right),
- Enable DAC2 (Left), Enable DAC2 (Right)*/
- counter += CODEC_IO_Write(DeviceAddr, 0x05, 0x0303);
-
- /* Enable the AIF1 Timeslot 0 (Left) to DAC 1 (Left) mixer path */
- counter += CODEC_IO_Write(DeviceAddr, 0x601, 0x0001);
-
- /* Enable the AIF1 Timeslot 0 (Right) to DAC 1 (Right) mixer path */
- counter += CODEC_IO_Write(DeviceAddr, 0x602, 0x0001);
-
- /* Disable the AIF1 Timeslot 1 (Left) to DAC 2 (Left) mixer path */
- counter += CODEC_IO_Write(DeviceAddr, 0x604, 0x0000);
-
- /* Disable the AIF1 Timeslot 1 (Right) to DAC 2 (Right) mixer path */
- counter += CODEC_IO_Write(DeviceAddr, 0x605, 0x0000);
- break;
- }
- }
- else
- {
- outputEnabled = 0;
- }
-
- /* Path Configurations for input */
- if (input_device > 0)
- {
- inputEnabled = 1;
- switch (input_device)
- {
- case INPUT_DEVICE_DIGITAL_MICROPHONE_2 :
- /* Enable AIF1ADC2 (Left), Enable AIF1ADC2 (Right)
- * Enable DMICDAT2 (Left), Enable DMICDAT2 (Right)
- * Enable Left ADC, Enable Right ADC */
- counter += CODEC_IO_Write(DeviceAddr, 0x04, 0x0C30);
-
- /* Enable AIF1 DRC2 Signal Detect & DRC in AIF1ADC2 Left/Right Timeslot 1 */
- counter += CODEC_IO_Write(DeviceAddr, 0x450, 0x00DB);
-
- /* Disable IN1L, IN1R, IN2L, IN2R, Enable Thermal sensor & shutdown */
- counter += CODEC_IO_Write(DeviceAddr, 0x02, 0x6000);
-
- /* Enable the DMIC2(Left) to AIF1 Timeslot 1 (Left) mixer path */
- counter += CODEC_IO_Write(DeviceAddr, 0x608, 0x0002);
-
- /* Enable the DMIC2(Right) to AIF1 Timeslot 1 (Right) mixer path */
- counter += CODEC_IO_Write(DeviceAddr, 0x609, 0x0002);
-
- /* GPIO1 pin configuration GP1_DIR = output, GP1_FN = AIF1 DRC2 signal detect */
- counter += CODEC_IO_Write(DeviceAddr, 0x700, 0x000E);
- break;
-
- case INPUT_DEVICE_INPUT_LINE_1 :
- /* IN1LN_TO_IN1L, IN1LP_TO_VMID, IN1RN_TO_IN1R, IN1RP_TO_VMID */
- counter += CODEC_IO_Write(DeviceAddr, 0x28, 0x0011);
-
- /* Disable mute on IN1L_TO_MIXINL and +30dB on IN1L PGA output */
- counter += CODEC_IO_Write(DeviceAddr, 0x29, 0x0035);
-
- /* Disable mute on IN1R_TO_MIXINL, Gain = +30dB */
- counter += CODEC_IO_Write(DeviceAddr, 0x2A, 0x0035);
-
- /* Enable AIF1ADC1 (Left), Enable AIF1ADC1 (Right)
- * Enable Left ADC, Enable Right ADC */
- counter += CODEC_IO_Write(DeviceAddr, 0x04, 0x0303);
-
- /* Enable AIF1 DRC1 Signal Detect & DRC in AIF1ADC1 Left/Right Timeslot 0 */
- counter += CODEC_IO_Write(DeviceAddr, 0x440, 0x00DB);
-
- /* Enable IN1L and IN1R, Disable IN2L and IN2R, Enable Thermal sensor & shutdown */
- counter += CODEC_IO_Write(DeviceAddr, 0x02, 0x6350);
-
- /* Enable the ADCL(Left) to AIF1 Timeslot 0 (Left) mixer path */
- counter += CODEC_IO_Write(DeviceAddr, 0x606, 0x0002);
-
- /* Enable the ADCR(Right) to AIF1 Timeslot 0 (Right) mixer path */
- counter += CODEC_IO_Write(DeviceAddr, 0x607, 0x0002);
-
- /* GPIO1 pin configuration GP1_DIR = output, GP1_FN = AIF1 DRC1 signal detect */
- counter += CODEC_IO_Write(DeviceAddr, 0x700, 0x000D);
- break;
-
- case INPUT_DEVICE_DIGITAL_MICROPHONE_1 :
- /* Enable AIF1ADC1 (Left), Enable AIF1ADC1 (Right)
- * Enable DMICDAT1 (Left), Enable DMICDAT1 (Right)
- * Enable Left ADC, Enable Right ADC */
- counter += CODEC_IO_Write(DeviceAddr, 0x04, 0x030C);
-
- /* Enable AIF1 DRC2 Signal Detect & DRC in AIF1ADC1 Left/Right Timeslot 0 */
- counter += CODEC_IO_Write(DeviceAddr, 0x440, 0x00DB);
-
- /* Disable IN1L, IN1R, IN2L, IN2R, Enable Thermal sensor & shutdown */
- counter += CODEC_IO_Write(DeviceAddr, 0x02, 0x6350);
-
- /* Enable the DMIC2(Left) to AIF1 Timeslot 0 (Left) mixer path */
- counter += CODEC_IO_Write(DeviceAddr, 0x606, 0x0002);
-
- /* Enable the DMIC2(Right) to AIF1 Timeslot 0 (Right) mixer path */
- counter += CODEC_IO_Write(DeviceAddr, 0x607, 0x0002);
-
- /* GPIO1 pin configuration GP1_DIR = output, GP1_FN = AIF1 DRC1 signal detect */
- counter += CODEC_IO_Write(DeviceAddr, 0x700, 0x000D);
- break;
- case INPUT_DEVICE_DIGITAL_MIC1_MIC2 :
- /* Enable AIF1ADC1 (Left), Enable AIF1ADC1 (Right)
- * Enable DMICDAT1 (Left), Enable DMICDAT1 (Right)
- * Enable Left ADC, Enable Right ADC */
- counter += CODEC_IO_Write(DeviceAddr, 0x04, 0x0F3C);
-
- /* Enable AIF1 DRC2 Signal Detect & DRC in AIF1ADC2 Left/Right Timeslot 1 */
- counter += CODEC_IO_Write(DeviceAddr, 0x450, 0x00DB);
-
- /* Enable AIF1 DRC2 Signal Detect & DRC in AIF1ADC1 Left/Right Timeslot 0 */
- counter += CODEC_IO_Write(DeviceAddr, 0x440, 0x00DB);
-
- /* Disable IN1L, IN1R, Enable IN2L, IN2R, Thermal sensor & shutdown */
- counter += CODEC_IO_Write(DeviceAddr, 0x02, 0x63A0);
-
- /* Enable the DMIC2(Left) to AIF1 Timeslot 0 (Left) mixer path */
- counter += CODEC_IO_Write(DeviceAddr, 0x606, 0x0002);
-
- /* Enable the DMIC2(Right) to AIF1 Timeslot 0 (Right) mixer path */
- counter += CODEC_IO_Write(DeviceAddr, 0x607, 0x0002);
-
- /* Enable the DMIC2(Left) to AIF1 Timeslot 1 (Left) mixer path */
- counter += CODEC_IO_Write(DeviceAddr, 0x608, 0x0002);
-
- /* Enable the DMIC2(Right) to AIF1 Timeslot 1 (Right) mixer path */
- counter += CODEC_IO_Write(DeviceAddr, 0x609, 0x0002);
-
- /* GPIO1 pin configuration GP1_DIR = output, GP1_FN = AIF1 DRC1 signal detect */
- counter += CODEC_IO_Write(DeviceAddr, 0x700, 0x000D);
- break;
- case INPUT_DEVICE_INPUT_LINE_2 :
- default:
- /* Actually, no other input devices supported */
- counter++;
- break;
- }
- }
- else
- {
- inputEnabled = 0;
- }
-
- /* Clock Configurations */
- switch (AudioFreq)
- {
- case AUDIO_FREQUENCY_8K:
- /* AIF1 Sample Rate = 8 (KHz), ratio=256 */
- counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x0003);
- break;
-
- case AUDIO_FREQUENCY_16K:
- /* AIF1 Sample Rate = 16 (KHz), ratio=256 */
- counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x0033);
- break;
-
- case AUDIO_FREQUENCY_32K:
- /* AIF1 Sample Rate = 32 (KHz), ratio=256 */
- counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x0063);
- break;
-
- case AUDIO_FREQUENCY_48K:
- /* AIF1 Sample Rate = 48 (KHz), ratio=256 */
- counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x0083);
- break;
-
- case AUDIO_FREQUENCY_96K:
- /* AIF1 Sample Rate = 96 (KHz), ratio=256 */
- counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x00A3);
- break;
-
- case AUDIO_FREQUENCY_11K:
- /* AIF1 Sample Rate = 11.025 (KHz), ratio=256 */
- counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x0013);
- break;
-
- case AUDIO_FREQUENCY_22K:
- /* AIF1 Sample Rate = 22.050 (KHz), ratio=256 */
- counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x0043);
- break;
-
- case AUDIO_FREQUENCY_44K:
- /* AIF1 Sample Rate = 44.1 (KHz), ratio=256 */
- counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x0073);
- break;
-
- default:
- /* AIF1 Sample Rate = 48 (KHz), ratio=256 */
- counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x0083);
- break;
- }
-
- if(input_device == INPUT_DEVICE_DIGITAL_MIC1_MIC2)
- {
- /* AIF1 Word Length = 16-bits, AIF1 Format = DSP mode */
- counter += CODEC_IO_Write(DeviceAddr, 0x300, 0x4018);
- }
- else
- {
- /* AIF1 Word Length = 16-bits, AIF1 Format = I2S (Default Register Value) */
- counter += CODEC_IO_Write(DeviceAddr, 0x300, 0x4010);
- }
-
- /* slave mode */
- counter += CODEC_IO_Write(DeviceAddr, 0x302, 0x0000);
-
- /* Enable the DSP processing clock for AIF1, Enable the core clock */
- counter += CODEC_IO_Write(DeviceAddr, 0x208, 0x000A);
-
- /* Enable AIF1 Clock, AIF1 Clock Source = MCLK1 pin */
- counter += CODEC_IO_Write(DeviceAddr, 0x200, 0x0001);
-
- if (output_device > 0) /* Audio output selected */
- {
- /* Analog Output Configuration */
-
- /* Enable SPKRVOL PGA, Enable SPKMIXR, Enable SPKLVOL PGA, Enable SPKMIXL */
- counter += CODEC_IO_Write(DeviceAddr, 0x03, 0x0300);
-
- /* Left Speaker Mixer Volume = 0dB */
- counter += CODEC_IO_Write(DeviceAddr, 0x22, 0x0000);
-
- /* Speaker output mode = Class D, Right Speaker Mixer Volume = 0dB ((0x23, 0x0100) = class AB)*/
- counter += CODEC_IO_Write(DeviceAddr, 0x23, 0x0000);
-
- /* Unmute DAC2 (Left) to Left Speaker Mixer (SPKMIXL) path,
- Unmute DAC2 (Right) to Right Speaker Mixer (SPKMIXR) path */
- counter += CODEC_IO_Write(DeviceAddr, 0x36, 0x0300);
-
- /* Enable bias generator, Enable VMID, Enable SPKOUTL, Enable SPKOUTR */
- counter += CODEC_IO_Write(DeviceAddr, 0x01, 0x3003);
-
- /* Headphone/Speaker Enable */
-
- if (input_device == INPUT_DEVICE_DIGITAL_MIC1_MIC2)
- {
- /* Enable Class W, Class W Envelope Tracking = AIF1 Timeslots 0 and 1 */
- counter += CODEC_IO_Write(DeviceAddr, 0x51, 0x0205);
- }
- else
- {
- /* Enable Class W, Class W Envelope Tracking = AIF1 Timeslot 0 */
- counter += CODEC_IO_Write(DeviceAddr, 0x51, 0x0005);
- }
-
- /* Enable bias generator, Enable VMID, Enable HPOUT1 (Left) and Enable HPOUT1 (Right) input stages */
- /* idem for Speaker */
- power_mgnt_reg_1 |= 0x0303 | 0x3003;
- counter += CODEC_IO_Write(DeviceAddr, 0x01, power_mgnt_reg_1);
-
- /* Enable HPOUT1 (Left) and HPOUT1 (Right) intermediate stages */
- counter += CODEC_IO_Write(DeviceAddr, 0x60, 0x0022);
-
- /* Enable Charge Pump */
- counter += CODEC_IO_Write(DeviceAddr, 0x4C, 0x9F25);
-
- /* Add Delay */
- AUDIO_IO_Delay(15);
-
- /* Select DAC1 (Left) to Left Headphone Output PGA (HPOUT1LVOL) path */
- counter += CODEC_IO_Write(DeviceAddr, 0x2D, 0x0001);
-
- /* Select DAC1 (Right) to Right Headphone Output PGA (HPOUT1RVOL) path */
- counter += CODEC_IO_Write(DeviceAddr, 0x2E, 0x0001);
-
- /* Enable Left Output Mixer (MIXOUTL), Enable Right Output Mixer (MIXOUTR) */
- /* idem for SPKOUTL and SPKOUTR */
- counter += CODEC_IO_Write(DeviceAddr, 0x03, 0x0030 | 0x0300);
-
- /* Enable DC Servo and trigger start-up mode on left and right channels */
- counter += CODEC_IO_Write(DeviceAddr, 0x54, 0x0033);
-
- /* Add Delay */
- AUDIO_IO_Delay(250);
-
- /* Enable HPOUT1 (Left) and HPOUT1 (Right) intermediate and output stages. Remove clamps */
- counter += CODEC_IO_Write(DeviceAddr, 0x60, 0x00EE);
-
- /* Unmutes */
-
- /* Unmute DAC 1 (Left) */
- counter += CODEC_IO_Write(DeviceAddr, 0x610, 0x00C0);
-
- /* Unmute DAC 1 (Right) */
- counter += CODEC_IO_Write(DeviceAddr, 0x611, 0x00C0);
-
- /* Unmute the AIF1 Timeslot 0 DAC path */
- counter += CODEC_IO_Write(DeviceAddr, 0x420, 0x0000);
-
- /* Unmute DAC 2 (Left) */
- counter += CODEC_IO_Write(DeviceAddr, 0x612, 0x00C0);
-
- /* Unmute DAC 2 (Right) */
- counter += CODEC_IO_Write(DeviceAddr, 0x613, 0x00C0);
-
- /* Unmute the AIF1 Timeslot 1 DAC2 path */
- counter += CODEC_IO_Write(DeviceAddr, 0x422, 0x0000);
-
- /* Volume Control */
- wm8994_SetVolume(DeviceAddr, Volume);
- }
-
- if (input_device > 0) /* Audio input selected */
- {
- if ((input_device == INPUT_DEVICE_DIGITAL_MICROPHONE_1) || (input_device == INPUT_DEVICE_DIGITAL_MICROPHONE_2))
- {
- /* Enable Microphone bias 1 generator, Enable VMID */
- power_mgnt_reg_1 |= 0x0013;
- counter += CODEC_IO_Write(DeviceAddr, 0x01, power_mgnt_reg_1);
-
- /* ADC oversample enable */
- counter += CODEC_IO_Write(DeviceAddr, 0x620, 0x0002);
-
- /* AIF ADC2 HPF enable, HPF cut = voice mode 1 fc=127Hz at fs=8kHz */
- counter += CODEC_IO_Write(DeviceAddr, 0x411, 0x3800);
- }
- else if(input_device == INPUT_DEVICE_DIGITAL_MIC1_MIC2)
- {
- /* Enable Microphone bias 1 generator, Enable VMID */
- power_mgnt_reg_1 |= 0x0013;
- counter += CODEC_IO_Write(DeviceAddr, 0x01, power_mgnt_reg_1);
-
- /* ADC oversample enable */
- counter += CODEC_IO_Write(DeviceAddr, 0x620, 0x0002);
-
- /* AIF ADC1 HPF enable, HPF cut = voice mode 1 fc=127Hz at fs=8kHz */
- counter += CODEC_IO_Write(DeviceAddr, 0x410, 0x1800);
-
- /* AIF ADC2 HPF enable, HPF cut = voice mode 1 fc=127Hz at fs=8kHz */
- counter += CODEC_IO_Write(DeviceAddr, 0x411, 0x1800);
- }
- else if ((input_device == INPUT_DEVICE_INPUT_LINE_1) || (input_device == INPUT_DEVICE_INPUT_LINE_2))
- {
-
- /* Disable mute on IN1L, IN1L Volume = +0dB */
- counter += CODEC_IO_Write(DeviceAddr, 0x18, 0x000B);
-
- /* Disable mute on IN1R, IN1R Volume = +0dB */
- counter += CODEC_IO_Write(DeviceAddr, 0x1A, 0x000B);
-
- /* AIF ADC1 HPF enable, HPF cut = hifi mode fc=4Hz at fs=48kHz */
- counter += CODEC_IO_Write(DeviceAddr, 0x410, 0x1800);
- }
- /* Volume Control */
- wm8994_SetVolume(DeviceAddr, Volume);
- }
- /* Return communication control value */
- return counter;
-}
-
-/**
- * @brief Deinitializes the audio codec.
- * @param None
- * @retval None
- */
-void wm8994_DeInit(void)
-{
- /* Deinitialize Audio Codec interface */
- AUDIO_IO_DeInit();
-}
-
-/**
- * @brief Get the WM8994 ID.
- * @param DeviceAddr: Device address on communication Bus.
- * @retval The WM8994 ID
- */
-uint32_t wm8994_ReadID(uint16_t DeviceAddr)
-{
- /* Initialize the Control interface of the Audio Codec */
- AUDIO_IO_Init();
-
- return ((uint32_t)AUDIO_IO_Read(DeviceAddr, WM8994_CHIPID_ADDR));
-}
-
-/**
- * @brief Start the audio Codec play feature.
- * @note For this codec no Play options are required.
- * @param DeviceAddr: Device address on communication Bus.
- * @retval 0 if correct communication, else wrong communication
- */
-uint32_t wm8994_Play(uint16_t DeviceAddr, uint16_t* pBuffer, uint16_t Size)
-{
- uint32_t counter = 0;
-
- /* Resumes the audio file playing */
- /* Unmute the output first */
- counter += wm8994_SetMute(DeviceAddr, AUDIO_MUTE_OFF);
-
- return counter;
-}
-
-/**
- * @brief Pauses playing on the audio codec.
- * @param DeviceAddr: Device address on communication Bus.
- * @retval 0 if correct communication, else wrong communication
- */
-uint32_t wm8994_Pause(uint16_t DeviceAddr)
-{
- uint32_t counter = 0;
-
- /* Pause the audio file playing */
- /* Mute the output first */
- counter += wm8994_SetMute(DeviceAddr, AUDIO_MUTE_ON);
-
- /* Put the Codec in Power save mode */
- counter += CODEC_IO_Write(DeviceAddr, 0x02, 0x01);
-
- return counter;
-}
-
-/**
- * @brief Resumes playing on the audio codec.
- * @param DeviceAddr: Device address on communication Bus.
- * @retval 0 if correct communication, else wrong communication
- */
-uint32_t wm8994_Resume(uint16_t DeviceAddr)
-{
- uint32_t counter = 0;
-
- /* Resumes the audio file playing */
- /* Unmute the output first */
- counter += wm8994_SetMute(DeviceAddr, AUDIO_MUTE_OFF);
-
- return counter;
-}
-
-/**
- * @brief Stops audio Codec playing. It powers down the codec.
- * @param DeviceAddr: Device address on communication Bus.
- * @param CodecPdwnMode: selects the power down mode.
- * - CODEC_PDWN_SW: only mutes the audio codec. When resuming from this
- * mode the codec keeps the previous initialization
- * (no need to re-Initialize the codec registers).
- * - CODEC_PDWN_HW: Physically power down the codec. When resuming from this
- * mode, the codec is set to default configuration
- * (user should re-Initialize the codec in order to
- * play again the audio stream).
- * @retval 0 if correct communication, else wrong communication
- */
-uint32_t wm8994_Stop(uint16_t DeviceAddr, uint32_t CodecPdwnMode)
-{
- uint32_t counter = 0;
-
- if (outputEnabled != 0)
- {
- /* Mute the output first */
- counter += wm8994_SetMute(DeviceAddr, AUDIO_MUTE_ON);
-
- if (CodecPdwnMode == CODEC_PDWN_SW)
- {
- /* Only output mute required*/
- }
- else /* CODEC_PDWN_HW */
- {
- /* Mute the AIF1 Timeslot 0 DAC1 path */
- counter += CODEC_IO_Write(DeviceAddr, 0x420, 0x0200);
-
- /* Mute the AIF1 Timeslot 1 DAC2 path */
- counter += CODEC_IO_Write(DeviceAddr, 0x422, 0x0200);
-
- /* Disable DAC1L_TO_HPOUT1L */
- counter += CODEC_IO_Write(DeviceAddr, 0x2D, 0x0000);
-
- /* Disable DAC1R_TO_HPOUT1R */
- counter += CODEC_IO_Write(DeviceAddr, 0x2E, 0x0000);
-
- /* Disable DAC1 and DAC2 */
- counter += CODEC_IO_Write(DeviceAddr, 0x05, 0x0000);
-
- /* Reset Codec by writing in 0x0000 address register */
- counter += CODEC_IO_Write(DeviceAddr, 0x0000, 0x0000);
-
- outputEnabled = 0;
- }
- }
- return counter;
-}
-
-/**
- * @brief Sets higher or lower the codec volume level.
- * @param DeviceAddr: Device address on communication Bus.
- * @param Volume: a byte value from 0 to 255 (refer to codec registers
- * description for more details).
- * @retval 0 if correct communication, else wrong communication
- */
-uint32_t wm8994_SetVolume(uint16_t DeviceAddr, uint8_t Volume)
-{
- uint32_t counter = 0;
- uint8_t convertedvol = VOLUME_CONVERT(Volume);
-
- /* Output volume */
- if (outputEnabled != 0)
- {
- if(convertedvol > 0x3E)
- {
- /* Unmute audio codec */
- counter += wm8994_SetMute(DeviceAddr, AUDIO_MUTE_OFF);
-
- /* Left Headphone Volume */
- counter += CODEC_IO_Write(DeviceAddr, 0x1C, 0x3F | 0x140);
-
- /* Right Headphone Volume */
- counter += CODEC_IO_Write(DeviceAddr, 0x1D, 0x3F | 0x140);
-
- /* Left Speaker Volume */
- counter += CODEC_IO_Write(DeviceAddr, 0x26, 0x3F | 0x140);
-
- /* Right Speaker Volume */
- counter += CODEC_IO_Write(DeviceAddr, 0x27, 0x3F | 0x140);
- }
- else if (Volume == 0)
- {
- /* Mute audio codec */
- counter += wm8994_SetMute(DeviceAddr, AUDIO_MUTE_ON);
- }
- else
- {
- /* Unmute audio codec */
- counter += wm8994_SetMute(DeviceAddr, AUDIO_MUTE_OFF);
-
- /* Left Headphone Volume */
- counter += CODEC_IO_Write(DeviceAddr, 0x1C, convertedvol | 0x140);
-
- /* Right Headphone Volume */
- counter += CODEC_IO_Write(DeviceAddr, 0x1D, convertedvol | 0x140);
-
- /* Left Speaker Volume */
- counter += CODEC_IO_Write(DeviceAddr, 0x26, convertedvol | 0x140);
-
- /* Right Speaker Volume */
- counter += CODEC_IO_Write(DeviceAddr, 0x27, convertedvol | 0x140);
- }
- }
-
- /* Input volume */
- if (inputEnabled != 0)
- {
- convertedvol = VOLUME_IN_CONVERT(Volume);
-
- /* Left AIF1 ADC1 volume */
- counter += CODEC_IO_Write(DeviceAddr, 0x400, convertedvol | 0x100);
-
- /* Right AIF1 ADC1 volume */
- counter += CODEC_IO_Write(DeviceAddr, 0x401, convertedvol | 0x100);
-
- /* Left AIF1 ADC2 volume */
- counter += CODEC_IO_Write(DeviceAddr, 0x404, convertedvol | 0x100);
-
- /* Right AIF1 ADC2 volume */
- counter += CODEC_IO_Write(DeviceAddr, 0x405, convertedvol | 0x100);
- }
- return counter;
-}
-
-/**
- * @brief Enables or disables the mute feature on the audio codec.
- * @param DeviceAddr: Device address on communication Bus.
- * @param Cmd: AUDIO_MUTE_ON to enable the mute or AUDIO_MUTE_OFF to disable the
- * mute mode.
- * @retval 0 if correct communication, else wrong communication
- */
-uint32_t wm8994_SetMute(uint16_t DeviceAddr, uint32_t Cmd)
-{
- uint32_t counter = 0;
-
- if (outputEnabled != 0)
- {
- /* Set the Mute mode */
- if(Cmd == AUDIO_MUTE_ON)
- {
- /* Soft Mute the AIF1 Timeslot 0 DAC1 path L&R */
- counter += CODEC_IO_Write(DeviceAddr, 0x420, 0x0200);
-
- /* Soft Mute the AIF1 Timeslot 1 DAC2 path L&R */
- counter += CODEC_IO_Write(DeviceAddr, 0x422, 0x0200);
- }
- else /* AUDIO_MUTE_OFF Disable the Mute */
- {
- /* Unmute the AIF1 Timeslot 0 DAC1 path L&R */
- counter += CODEC_IO_Write(DeviceAddr, 0x420, 0x0000);
-
- /* Unmute the AIF1 Timeslot 1 DAC2 path L&R */
- counter += CODEC_IO_Write(DeviceAddr, 0x422, 0x0000);
- }
- }
- return counter;
-}
-
-/**
- * @brief Switch dynamically (while audio file is played) the output target
- * (speaker or headphone).
- * @param DeviceAddr: Device address on communication Bus.
- * @param Output: specifies the audio output target: OUTPUT_DEVICE_SPEAKER,
- * OUTPUT_DEVICE_HEADPHONE, OUTPUT_DEVICE_BOTH or OUTPUT_DEVICE_AUTO
- * @retval 0 if correct communication, else wrong communication
- */
-uint32_t wm8994_SetOutputMode(uint16_t DeviceAddr, uint8_t Output)
-{
- uint32_t counter = 0;
-
- switch (Output)
- {
- case OUTPUT_DEVICE_SPEAKER:
- /* Enable DAC1 (Left), Enable DAC1 (Right),
- Disable DAC2 (Left), Disable DAC2 (Right)*/
- counter += CODEC_IO_Write(DeviceAddr, 0x05, 0x0C0C);
-
- /* Enable the AIF1 Timeslot 0 (Left) to DAC 1 (Left) mixer path */
- counter += CODEC_IO_Write(DeviceAddr, 0x601, 0x0000);
-
- /* Enable the AIF1 Timeslot 0 (Right) to DAC 1 (Right) mixer path */
- counter += CODEC_IO_Write(DeviceAddr, 0x602, 0x0000);
-
- /* Disable the AIF1 Timeslot 1 (Left) to DAC 2 (Left) mixer path */
- counter += CODEC_IO_Write(DeviceAddr, 0x604, 0x0002);
-
- /* Disable the AIF1 Timeslot 1 (Right) to DAC 2 (Right) mixer path */
- counter += CODEC_IO_Write(DeviceAddr, 0x605, 0x0002);
- break;
-
- case OUTPUT_DEVICE_HEADPHONE:
- /* Disable DAC1 (Left), Disable DAC1 (Right),
- Enable DAC2 (Left), Enable DAC2 (Right)*/
- counter += CODEC_IO_Write(DeviceAddr, 0x05, 0x0303);
-
- /* Enable the AIF1 Timeslot 0 (Left) to DAC 1 (Left) mixer path */
- counter += CODEC_IO_Write(DeviceAddr, 0x601, 0x0001);
-
- /* Enable the AIF1 Timeslot 0 (Right) to DAC 1 (Right) mixer path */
- counter += CODEC_IO_Write(DeviceAddr, 0x602, 0x0001);
-
- /* Disable the AIF1 Timeslot 1 (Left) to DAC 2 (Left) mixer path */
- counter += CODEC_IO_Write(DeviceAddr, 0x604, 0x0000);
-
- /* Disable the AIF1 Timeslot 1 (Right) to DAC 2 (Right) mixer path */
- counter += CODEC_IO_Write(DeviceAddr, 0x605, 0x0000);
- break;
-
- case OUTPUT_DEVICE_BOTH:
- /* Enable DAC1 (Left), Enable DAC1 (Right),
- also Enable DAC2 (Left), Enable DAC2 (Right)*/
- counter += CODEC_IO_Write(DeviceAddr, 0x05, 0x0303 | 0x0C0C);
-
- /* Enable the AIF1 Timeslot 0 (Left) to DAC 1 (Left) mixer path */
- counter += CODEC_IO_Write(DeviceAddr, 0x601, 0x0001);
-
- /* Enable the AIF1 Timeslot 0 (Right) to DAC 1 (Right) mixer path */
- counter += CODEC_IO_Write(DeviceAddr, 0x602, 0x0001);
-
- /* Enable the AIF1 Timeslot 1 (Left) to DAC 2 (Left) mixer path */
- counter += CODEC_IO_Write(DeviceAddr, 0x604, 0x0002);
-
- /* Enable the AIF1 Timeslot 1 (Right) to DAC 2 (Right) mixer path */
- counter += CODEC_IO_Write(DeviceAddr, 0x605, 0x0002);
- break;
-
- default:
- /* Disable DAC1 (Left), Disable DAC1 (Right),
- Enable DAC2 (Left), Enable DAC2 (Right)*/
- counter += CODEC_IO_Write(DeviceAddr, 0x05, 0x0303);
-
- /* Enable the AIF1 Timeslot 0 (Left) to DAC 1 (Left) mixer path */
- counter += CODEC_IO_Write(DeviceAddr, 0x601, 0x0001);
-
- /* Enable the AIF1 Timeslot 0 (Right) to DAC 1 (Right) mixer path */
- counter += CODEC_IO_Write(DeviceAddr, 0x602, 0x0001);
-
- /* Disable the AIF1 Timeslot 1 (Left) to DAC 2 (Left) mixer path */
- counter += CODEC_IO_Write(DeviceAddr, 0x604, 0x0000);
-
- /* Disable the AIF1 Timeslot 1 (Right) to DAC 2 (Right) mixer path */
- counter += CODEC_IO_Write(DeviceAddr, 0x605, 0x0000);
- break;
- }
- return counter;
-}
-
-/**
- * @brief Sets new frequency.
- * @param DeviceAddr: Device address on communication Bus.
- * @param AudioFreq: Audio frequency used to play the audio stream.
- * @retval 0 if correct communication, else wrong communication
- */
-uint32_t wm8994_SetFrequency(uint16_t DeviceAddr, uint32_t AudioFreq)
-{
- uint32_t counter = 0;
-
- /* Clock Configurations */
- switch (AudioFreq)
- {
- case AUDIO_FREQUENCY_8K:
- /* AIF1 Sample Rate = 8 (KHz), ratio=256 */
- counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x0003);
- break;
-
- case AUDIO_FREQUENCY_16K:
- /* AIF1 Sample Rate = 16 (KHz), ratio=256 */
- counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x0033);
- break;
-
- case AUDIO_FREQUENCY_48K:
- /* AIF1 Sample Rate = 48 (KHz), ratio=256 */
- counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x0083);
- break;
-
- case AUDIO_FREQUENCY_96K:
- /* AIF1 Sample Rate = 96 (KHz), ratio=256 */
- counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x00A3);
- break;
-
- case AUDIO_FREQUENCY_11K:
- /* AIF1 Sample Rate = 11.025 (KHz), ratio=256 */
- counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x0013);
- break;
-
- case AUDIO_FREQUENCY_22K:
- /* AIF1 Sample Rate = 22.050 (KHz), ratio=256 */
- counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x0043);
- break;
-
- case AUDIO_FREQUENCY_44K:
- /* AIF1 Sample Rate = 44.1 (KHz), ratio=256 */
- counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x0073);
- break;
-
- default:
- /* AIF1 Sample Rate = 48 (KHz), ratio=256 */
- counter += CODEC_IO_Write(DeviceAddr, 0x210, 0x0083);
- break;
- }
- return counter;
-}
-
-/**
- * @brief Resets wm8994 registers.
- * @param DeviceAddr: Device address on communication Bus.
- * @retval 0 if correct communication, else wrong communication
- */
-uint32_t wm8994_Reset(uint16_t DeviceAddr)
-{
- uint32_t counter = 0;
-
- /* Reset Codec by writing in 0x0000 address register */
- counter = CODEC_IO_Write(DeviceAddr, 0x0000, 0x0000);
- outputEnabled = 0;
- inputEnabled=0;
-
- return counter;
-}
-
-/**
- * @brief Writes/Read a single data.
- * @param Addr: I2C address
- * @param Reg: Reg address
- * @param Value: Data to be written
- * @retval None
- */
-static uint8_t CODEC_IO_Write(uint8_t Addr, uint16_t Reg, uint16_t Value)
-{
- uint32_t result = 0;
-
- AUDIO_IO_Write(Addr, Reg, Value);
-
-#ifdef VERIFY_WRITTENDATA
- /* Verify that the data has been correctly written */
- result = (AUDIO_IO_Read(Addr, Reg) == Value)? 0:1;
-#endif /* VERIFY_WRITTENDATA */
-
- return result;
-}
-
-#endif
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/libraries/PDM/src/stm32/wm8994.h b/libraries/PDM/src/stm32/wm8994.h
deleted file mode 100644
index c4d625b32..000000000
--- a/libraries/PDM/src/stm32/wm8994.h
+++ /dev/null
@@ -1,188 +0,0 @@
-/**
- ******************************************************************************
- * @file wm8994.h
- * @author MCD Application Team
- * @version V2.1.0
- * @date 22-February-2016
- * @brief This file contains all the functions prototypes for the
- * wm8994.c driver.
- ******************************************************************************
- * @attention
- *
- * © COPYRIGHT(c) 2016 STMicroelectronics
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- * 3. Neither the name of STMicroelectronics nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- ******************************************************************************
- */
-
-/* Define to prevent recursive inclusion -------------------------------------*/
-#ifndef __WM8994_H
-#define __WM8994_H
-
-/* Includes ------------------------------------------------------------------*/
-#include "codec_api.h"
-
-/** @addtogroup BSP
- * @{
- */
-
-/** @addtogroup Component
- * @{
- */
-
-/** @addtogroup WM8994
- * @{
- */
-
-/** @defgroup WM8994_Exported_Types
- * @{
- */
-
-/**
- * @}
- */
-
-/** @defgroup WM8994_Exported_Constants
- * @{
- */
-
-/******************************************************************************/
-/*************************** Codec User defines ******************************/
-/******************************************************************************/
-/* Codec output DEVICE */
-#define OUTPUT_DEVICE_SPEAKER ((uint16_t)0x0001)
-#define OUTPUT_DEVICE_HEADPHONE ((uint16_t)0x0002)
-#define OUTPUT_DEVICE_BOTH ((uint16_t)0x0003)
-#define OUTPUT_DEVICE_AUTO ((uint16_t)0x0004)
-#define INPUT_DEVICE_DIGITAL_MICROPHONE_1 ((uint16_t)0x0100)
-#define INPUT_DEVICE_DIGITAL_MICROPHONE_2 ((uint16_t)0x0200)
-#define INPUT_DEVICE_INPUT_LINE_1 ((uint16_t)0x0300)
-#define INPUT_DEVICE_INPUT_LINE_2 ((uint16_t)0x0400)
-#define INPUT_DEVICE_DIGITAL_MIC1_MIC2 ((uint16_t)0x0800)
-
-/* Volume Levels values */
-#define DEFAULT_VOLMIN 0x00
-#define DEFAULT_VOLMAX 0xFF
-#define DEFAULT_VOLSTEP 0x04
-
-#define AUDIO_PAUSE 0
-#define AUDIO_RESUME 1
-
-/* Codec POWER DOWN modes */
-#define CODEC_PDWN_HW 1
-#define CODEC_PDWN_SW 2
-
-/* MUTE commands */
-#define AUDIO_MUTE_ON 1
-#define AUDIO_MUTE_OFF 0
-
-/* AUDIO FREQUENCY */
-#define AUDIO_FREQUENCY_192K ((uint32_t)192000)
-#define AUDIO_FREQUENCY_96K ((uint32_t)96000)
-#define AUDIO_FREQUENCY_48K ((uint32_t)48000)
-#define AUDIO_FREQUENCY_44K ((uint32_t)44100)
-#define AUDIO_FREQUENCY_32K ((uint32_t)32000)
-#define AUDIO_FREQUENCY_22K ((uint32_t)22050)
-#define AUDIO_FREQUENCY_16K ((uint32_t)16000)
-#define AUDIO_FREQUENCY_11K ((uint32_t)11025)
-#define AUDIO_FREQUENCY_8K ((uint32_t)8000)
-
-#define VOLUME_CONVERT(Volume) (((Volume) > 100)? 100:((uint8_t)(((Volume) * 63) / 100)))
-#define VOLUME_IN_CONVERT(Volume) (((Volume) >= 100)? 239:((uint8_t)(((Volume) * 240) / 100)))
-
-/******************************************************************************/
-/****************************** REGISTER MAPPING ******************************/
-/******************************************************************************/
-/**
- * @brief WM8994 ID
- */
-#define WM8994_ID 0x8994
-
-/**
- * @brief Device ID Register: Reading from this register will indicate device
- * family ID 8994h
- */
-#define WM8994_CHIPID_ADDR 0x00
-
-/**
- * @}
- */
-
-/** @defgroup WM8994_Exported_Macros
- * @{
- */
-/**
- * @}
- */
-
-/** @defgroup WM8994_Exported_Functions
- * @{
- */
-
-/*------------------------------------------------------------------------------
- Audio Codec functions
-------------------------------------------------------------------------------*/
-/* High Layer codec functions */
-uint32_t wm8994_Init(uint16_t DeviceAddr, uint16_t OutputInputDevice, uint8_t Volume, uint32_t AudioFreq);
-void wm8994_DeInit(void);
-uint32_t wm8994_ReadID(uint16_t DeviceAddr);
-uint32_t wm8994_Play(uint16_t DeviceAddr, uint16_t* pBuffer, uint16_t Size);
-uint32_t wm8994_Pause(uint16_t DeviceAddr);
-uint32_t wm8994_Resume(uint16_t DeviceAddr);
-uint32_t wm8994_Stop(uint16_t DeviceAddr, uint32_t Cmd);
-uint32_t wm8994_SetVolume(uint16_t DeviceAddr, uint8_t Volume);
-uint32_t wm8994_SetMute(uint16_t DeviceAddr, uint32_t Cmd);
-uint32_t wm8994_SetOutputMode(uint16_t DeviceAddr, uint8_t Output);
-uint32_t wm8994_SetFrequency(uint16_t DeviceAddr, uint32_t AudioFreq);
-uint32_t wm8994_Reset(uint16_t DeviceAddr);
-
-/* AUDIO IO functions */
-void AUDIO_IO_Init(void);
-void AUDIO_IO_DeInit(void);
-void AUDIO_IO_Write(uint8_t Addr, uint16_t Reg, uint16_t Value);
-uint16_t AUDIO_IO_Read(uint8_t Addr, uint16_t Reg);
-void AUDIO_IO_Delay(uint32_t Delay);
-
-/* Audio driver structure */
-extern AUDIO_DrvTypeDef wm8994_drv;
-
-#endif /* __WM8994_H */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/libraries/PDM/src/utility/PDMDoubleBuffer.cpp b/libraries/PDM/src/utility/PDMDoubleBuffer.cpp
index 15bd9cad2..2e6a4c2c7 100644
--- a/libraries/PDM/src/utility/PDMDoubleBuffer.cpp
+++ b/libraries/PDM/src/utility/PDMDoubleBuffer.cpp
@@ -34,6 +34,7 @@ PDMDoubleBuffer::~PDMDoubleBuffer()
void PDMDoubleBuffer::setSize(int size)
{
_size = size;
+ reset();
}
void PDMDoubleBuffer::reset()
diff --git a/libraries/PDM/src/utility/PDMDoubleBuffer.h b/libraries/PDM/src/utility/PDMDoubleBuffer.h
index e410b62d7..1544af5bf 100644
--- a/libraries/PDM/src/utility/PDMDoubleBuffer.h
+++ b/libraries/PDM/src/utility/PDMDoubleBuffer.h
@@ -43,7 +43,7 @@ class PDMDoubleBuffer
void swap(int length = 0);
private:
- uint8_t* _buffer[2];
+ uint8_t* _buffer[2] __attribute__((aligned (16)));
int _size;
volatile int _length[2];
volatile int _readOffset[2];