Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: ST_FREQUENCY_DIVIDER ST_I2S USBDEVICE
Fork of X_NUCLEO_CCA02M1 by
Revision 0:d5552d432108, committed 2017-02-28
- Comitter:
- davide.aliprandi@st.com
- Date:
- Tue Feb 28 11:20:53 2017 +0100
- Child:
- 1:245f83276546
- Commit message:
- Library to handle the X-NUCLEO-CCA02M1 MEMS Microphones Expansion Board.
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/BSP/PDM2PCMAudio_class.cpp Tue Feb 28 11:20:53 2017 +0100
@@ -0,0 +1,137 @@
+/**
+ ******************************************************************************
+ * @file PDM2PCMAudio_class.cpp
+ * @author AST / Software Platforms and Cloud
+ * @version V1.0
+ * @date November 10th, 2016
+ * @brief Implementation file for the PDM2PCMAudio conversion library.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
+ *
+ * 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.
+ *
+ ******************************************************************************
+ */
+
+
+/* Includes ------------------------------------------------------------------*/
+
+#include "PDM2PCMAudio_class.h"
+
+
+/* Variables -----------------------------------------------------------------*/
+
+/* Demux filter. */
+const uint8_t PDM2PCMAudio::_demux_filter[DEMUX_FILTER_SIZE] =
+{
+ 0x00, 0x01, 0x00, 0x01, 0x02, 0x03, 0x02, 0x03,
+ 0x00, 0x01, 0x00, 0x01, 0x02, 0x03, 0x02, 0x03,
+ 0x04, 0x05, 0x04, 0x05, 0x06, 0x07, 0x06, 0x07,
+ 0x04, 0x05, 0x04, 0x05, 0x06, 0x07, 0x06, 0x07,
+ 0x00, 0x01, 0x00, 0x01, 0x02, 0x03, 0x02, 0x03,
+ 0x00, 0x01, 0x00, 0x01, 0x02, 0x03, 0x02, 0x03,
+ 0x04, 0x05, 0x04, 0x05, 0x06, 0x07, 0x06, 0x07,
+ 0x04, 0x05, 0x04, 0x05, 0x06, 0x07, 0x06, 0x07,
+ 0x08, 0x09, 0x08, 0x09, 0x0a, 0x0b, 0x0a, 0x0b,
+ 0x08, 0x09, 0x08, 0x09, 0x0a, 0x0b, 0x0a, 0x0b,
+ 0x0c, 0x0d, 0x0c, 0x0d, 0x0e, 0x0f, 0x0e, 0x0f,
+ 0x0c, 0x0d, 0x0c, 0x0d, 0x0e, 0x0f, 0x0e, 0x0f,
+ 0x08, 0x09, 0x08, 0x09, 0x0a, 0x0b, 0x0a, 0x0b,
+ 0x08, 0x09, 0x08, 0x09, 0x0a, 0x0b, 0x0a, 0x0b,
+ 0x0c, 0x0d, 0x0c, 0x0d, 0x0e, 0x0f, 0x0e, 0x0f,
+ 0x0c, 0x0d, 0x0c, 0x0d, 0x0e, 0x0f, 0x0e, 0x0f
+};
+
+
+/* Methods -------------------------------------------------------------------*/
+
+/**
+* @brief Converting audio data from PDM to PCM.
+* @param output_buffer Pointer to output PCM buffer data.
+* @param input_buffer Pointer to input PDM buffer data.
+* @param volume Volume level (it must be in the range [0..64]).
+* @param decimation_factor Decimation factor (it must be either 64 or 128).
+* @retval COMPONENT_OK in case of success, COMPONENT_ERROR otherwise.
+*/
+Status_t PDM2PCMAudio::Convert(int16_t *output_buffer, uint16_t *input_buffer, uint32_t volume, uint32_t decimation_factor)
+{
+ if (!(volume <= PDM2PCM_MAX_VOLUME))
+ error("Volume level not supported: it must be in the range [0..64].\r\n");
+
+ switch (decimation_factor)
+ {
+ case 64:
+ for (uint32_t index = 0; index < _channels; index++)
+ PDM_Filter_64_LSB(&((uint8_t *) input_buffer)[index], (uint16_t *) &(output_buffer[index]), volume, (PDMFilter_InitStruct *) &_PDM2PCM_filter[index]);
+ break;
+
+ case 128:
+ for (uint32_t index = 0; index < _channels; index++)
+ PDM_Filter_128_LSB(&((uint8_t *) input_buffer)[index], (uint16_t *) &(output_buffer[index]), volume, (PDMFilter_InitStruct *) &_PDM2PCM_filter[index]);
+ break;
+
+ default:
+ error("Decimation factor not supported: it must be either 64 or 128.\r\n");
+ }
+
+ return COMPONENT_OK;
+}
+
+/**
+ * @brief Scrambling audio data.
+ * @param output_buffer Pointer to output PDM buffer data.
+ * @param input_buffer Pointer to input PDM buffer data.
+ * @param size Size of the buffers (thay has to be equally sized).
+ * @retval COMPONENT_OK in case of success, COMPONENT_ERROR otherwise.
+ */
+Status_t PDM2PCMAudio::Scramble(uint16_t *output_buffer, uint16_t *input_buffer, uint32_t size)
+{
+ for (uint32_t index = 0; index < size; index++)
+ output_buffer[index] = HTONS(input_buffer[index]);
+
+ return COMPONENT_OK;
+}
+
+/**s
+ * @brief Demuxing audio data.
+ * @param output_buffer Pointer to output PDM buffer data.
+ * @param input_buffer Pointer to input PDM buffer data.
+ * @param size Size of the buffers (thay has to be equally sized).
+ * @retval COMPONENT_OK in case of success, COMPONENT_ERROR otherwise.
+ */
+Status_t PDM2PCMAudio::Demux(uint16_t *output_buffer, uint16_t *input_buffer, uint32_t size)
+{
+ for (uint32_t index = 0; index < size; index++)
+ {
+ uint8_t a = ((uint8_t *) input_buffer)[index * 2];
+ uint8_t b = ((uint8_t *) input_buffer)[index * 2 + 1];
+ ((uint8_t *) (output_buffer))[index * 2] = _demux_filter[a & DEMUX_FILTER_MASK] | _demux_filter[b & DEMUX_FILTER_MASK] << 4;
+ ((uint8_t *) (output_buffer))[index * 2 + 1] = _demux_filter[(a >> 1) & DEMUX_FILTER_MASK] | _demux_filter[(b >> 1) & DEMUX_FILTER_MASK] << 4;
+ }
+
+ return COMPONENT_OK;
+}
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/BSP/PDM2PCMAudio_class.h Tue Feb 28 11:20:53 2017 +0100
@@ -0,0 +1,135 @@
+/**
+ ******************************************************************************
+ * @file PDM2PCMAudio_class.h
+ * @author AST / Software Platforms and Cloud
+ * @version V1.0
+ * @date November 10th, 2016
+ * @brief Class header file for the PDM2PCMAudio conversion library.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
+ *
+ * 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 __PDM2PCM_AUDIO_CLASS_H
+#define __PDM2PCM_AUDIO_CLASS_H
+
+
+/* Includes ------------------------------------------------------------------*/
+
+#include "mbed.h"
+#include "component.h"
+#include "pdm_filter.h"
+
+
+/* Definitions ---------------------------------------------------------------*/
+
+#define DEMUX_FILTER_SIZE 128
+#define DEMUX_FILTER_MASK 0x55
+#define PDM2PCM_FILTER_SIZE 4
+#define PDM2PCM_NOGAIN_VOLUME 4
+#define PDM2PCM_MAX_VOLUME 64
+#define PDM2PCM_DECIMATION_FACTOR 64
+
+
+/* Classes -------------------------------------------------------------------*/
+
+/** PDM2PCMAudio Conversion Library Class.
+ */
+class PDM2PCMAudio
+{
+public:
+
+
+ /**
+ * @brief Constructor.
+ * @param frequency Audio sampling frequency.
+ * @param _channels Number of audio _channels to be recorded.
+ */
+ PDM2PCMAudio(uint32_t frequency, uint32_t _channels) :
+ _frequency(frequency),
+ _channels(_channels)
+ {
+ /* Enable CRC peripheral to unlock the PDM2PCMAudio library. */
+ __CRC_CLK_ENABLE();
+
+ /* Initializing PDM2PCMAudio Filter. */
+ for (uint32_t i = 0; i < _channels; i++)
+ {
+ /* Filter LP and HP Init */
+ _PDM2PCM_filter[i].LP_HZ = _frequency / 2;
+ _PDM2PCM_filter[i].HP_HZ = 10;
+ _PDM2PCM_filter[i].Fs = _frequency;
+ _PDM2PCM_filter[i].Out_MicChannels = _channels;
+ _PDM2PCM_filter[i].In_MicChannels = _channels;
+ PDM_Filter_Init((PDMFilter_InitStruct *) &_PDM2PCM_filter[i]);
+ }
+ };
+
+ /**
+ * @brief Converting audio data from PDM to PCM.
+ * @param output_buffer Pointer to output PCM buffer data.
+ * @param input_buffer Pointer to input PDM buffer data.
+ * @param volume Volume level (it must be in the range [0..64]).
+ * @param decimation_factor Decimation factor (it must be either 64 or 128).
+ * @retval COMPONENT_OK in case of success, COMPONENT_ERROR otherwise.
+ */
+ Status_t Convert(int16_t *output_buffer, uint16_t *input_buffer, uint32_t volume, uint32_t decimation_factor);
+
+ /**
+ * @brief Scrambling audio data.
+ * @param output_buffer Pointer to output PDM buffer data.
+ * @param input_buffer Pointer to input PDM buffer data.
+ * @param size Size of the buffers (thay has to be equally sized).
+ * @retval COMPONENT_OK in case of success, COMPONENT_ERROR otherwise.
+ */
+ Status_t Scramble(uint16_t *output_buffer, uint16_t *input_buffer, uint32_t size);
+
+ /**
+ * @brief Demuxing audio data.
+ * @param output_buffer Pointer to output PDM buffer data.
+ * @param input_buffer Pointer to input PDM buffer data.
+ * @param size Size of the buffers (thay has to be equally sized).
+ * @retval COMPONENT_OK in case of success, COMPONENT_ERROR otherwise.
+ */
+ Status_t Demux(uint16_t *output_buffer, uint16_t *input_buffer, uint32_t size);
+
+
+protected:
+
+ uint32_t _frequency;
+ uint32_t _channels;
+ PDMFilter_InitStruct _PDM2PCM_filter[PDM2PCM_FILTER_SIZE];
+ static const uint8_t _demux_filter[DEMUX_FILTER_SIZE];
+};
+
+#endif /* __PDM2PCM_AUDIO_CLASS_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/BSP/divisor.c Tue Feb 28 11:20:53 2017 +0100
@@ -0,0 +1,144 @@
+/**
+ ******************************************************************************
+ * @file divisor.c
+ * @author AST / Software Platforms and Cloud
+ * @version V1.0
+ * @date November 8th, 2016
+ * @brief Utilities header file for the X_NUCLEO_CCA02M1 expansion board.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
+ *
+ * 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.
+ *
+ ******************************************************************************
+ */
+
+
+/* Includes ------------------------------------------------------------------*/
+
+#include "cmsis.h"
+#include "divisor.h"
+#include "component.h"
+
+
+/* Variables -----------------------------------------------------------------*/
+
+static TIM_HandleTypeDef TimDividerHandle;
+static TIM_SlaveConfigTypeDef sSlaveConfig;
+static TIM_IC_InitTypeDef sICConfig;
+static TIM_OC_InitTypeDef sOCConfig;
+
+
+/* Functions -----------------------------------------------------------------*/
+
+/**
+ * @brief Initializing audio timer.
+ * @param None.
+ * @retval COMPONENT_OK in case of success, COMPONENT_ERROR otherwise.
+ */
+Status_t AUDIO_IN_Timer_Init(void)
+{
+ GPIO_InitTypeDef GPIO_InitStruct;
+
+ /* Enable AUDIO_TIMER clock*/
+ AUDIO_IN_TIMER_CLK_ENABLE();
+ AUDIO_IN_TIMER_CHOUT_GPIO_PORT_CLK_ENABLE();
+ AUDIO_IN_TIMER_CHIN_GPIO_PORT_CLK_ENABLE();
+
+ GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+ GPIO_InitStruct.Pull = GPIO_PULLUP;
+ GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
+
+ GPIO_InitStruct.Alternate = AUDIO_IN_TIMER_CHIN_AF;
+ GPIO_InitStruct.Pin = AUDIO_IN_TIMER_CHIN_PIN;
+ HAL_GPIO_Init(AUDIO_IN_TIMER_CHIN_GPIO_PORT, &GPIO_InitStruct);
+
+ GPIO_InitStruct.Alternate = AUDIO_IN_TIMER_CHOUT_AF;
+ GPIO_InitStruct.Pin = AUDIO_IN_TIMER_CHOUT_PIN;
+ HAL_GPIO_Init(AUDIO_IN_TIMER_CHOUT_GPIO_PORT, &GPIO_InitStruct);
+
+ TimDividerHandle.Instance = AUDIO_IN_TIMER;
+
+ /* Configure the Input: channel_1 */
+ sICConfig.ICPolarity = TIM_ICPOLARITY_RISING;
+ sICConfig.ICSelection = TIM_ICSELECTION_DIRECTTI;
+ sICConfig.ICPrescaler = TIM_ICPSC_DIV1;
+ sICConfig.ICFilter = 0;
+ if (HAL_TIM_IC_ConfigChannel(&TimDividerHandle, &sICConfig, TIM_CHANNEL_1) != HAL_OK)
+ {
+ return COMPONENT_ERROR;
+ }
+
+ /* Configure TIM1 in Gated Slave mode for the external trigger (Filtered Timer
+ Input 1) */
+ sSlaveConfig.InputTrigger = TIM_TS_TI1FP1;
+ sSlaveConfig.SlaveMode = TIM_SLAVEMODE_EXTERNAL1;
+ if (HAL_TIM_SlaveConfigSynchronization(&TimDividerHandle, &sSlaveConfig) != HAL_OK)
+ {
+ return COMPONENT_ERROR;
+ }
+
+ /* Initialize TIM3 peripheral in PWM mode*/
+ TimDividerHandle.Init.Period = 1;
+ TimDividerHandle.Init.Prescaler = 0;
+ TimDividerHandle.Init.ClockDivision = 0;
+ TimDividerHandle.Init.CounterMode = TIM_COUNTERMODE_UP;
+ TimDividerHandle.Init.RepetitionCounter = 0;
+ if (HAL_TIM_PWM_Init(&TimDividerHandle) != HAL_OK)
+ {
+ return COMPONENT_ERROR;
+ }
+
+ /* Configure the PWM_channel_1 */
+ sOCConfig.OCMode = TIM_OCMODE_PWM1;
+ sOCConfig.OCPolarity = TIM_OCPOLARITY_HIGH;
+ sOCConfig.Pulse = 1;
+ if (HAL_TIM_PWM_ConfigChannel(&TimDividerHandle, &sOCConfig, TIM_CHANNEL_2) != HAL_OK)
+ {
+ return COMPONENT_ERROR;
+ }
+
+ return COMPONENT_OK;
+}
+
+/**
+* @brief Audio Timer Start
+* @param None
+* @retval None
+*/
+uint8_t AUDIO_IN_Timer_Start()
+{
+ if (HAL_TIM_IC_Start(&TimDividerHandle, TIM_CHANNEL_1) != HAL_OK)
+ {
+ return COMPONENT_ERROR;
+ }
+ /* Start the Output Compare */
+ if (HAL_TIM_OC_Start(&TimDividerHandle, TIM_CHANNEL_2) != HAL_OK)
+ {
+ return COMPONENT_ERROR;
+ }
+
+ return COMPONENT_OK;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/BSP/divisor.h Tue Feb 28 11:20:53 2017 +0100
@@ -0,0 +1,75 @@
+/**
+ ******************************************************************************
+ * @file divisor.h
+ * @author AST / Software Platforms and Cloud
+ * @version V1.0
+ * @date November 8th, 2016
+ * @brief Utilities header file for the X_NUCLEO_CCA02M1 expansion board.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
+ *
+ * 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 __DIVISOR_H
+#define __DIVISOR_H
+
+/* Includes ------------------------------------------------------------------*/
+
+#include <stdio.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Definitions ---------------------------------------------------------------*/
+
+#define AUDIO_IN_TIMER TIM3
+#define AUDIO_IN_TIMER_CLK_ENABLE() __TIM3_CLK_ENABLE()
+#define AUDIO_IN_TIMER_CHOUT_AF GPIO_AF2_TIM3
+#define AUDIO_IN_TIMER_CHOUT_PIN GPIO_PIN_5
+#define AUDIO_IN_TIMER_CHOUT_GPIO_PORT GPIOB
+#define AUDIO_IN_TIMER_CHOUT_GPIO_PORT_CLK_ENABLE() __GPIOB_CLK_ENABLE()
+#define AUDIO_IN_TIMER_CHIN_AF GPIO_AF2_TIM3
+#define AUDIO_IN_TIMER_CHIN_PIN GPIO_PIN_4
+#define AUDIO_IN_TIMER_CHIN_GPIO_PORT GPIOB
+#define AUDIO_IN_TIMER_CHIN_GPIO_PORT_CLK_ENABLE() __GPIOB_CLK_ENABLE()
+
+
+/* Functions -----------------------------------------------------------------*/
+
+uint8_t AUDIO_IN_Timer_Init(void);
+uint8_t AUDIO_IN_Timer_Start(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/BSP/x_nucleo_cca02m1_class.cpp Tue Feb 28 11:20:53 2017 +0100
@@ -0,0 +1,373 @@
+/**
+ ******************************************************************************
+ * @file x_nucleo_cca02m1_class.cpp
+ * @author AST / Software Platforms and Cloud
+ * @version V1.0
+ * @date October 17th, 2016
+ * @brief Implementation file for the X_NUCLEO_CCA02M1 expansion board.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
+ *
+ * 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.
+ *
+ ******************************************************************************
+ */
+
+
+/* Includes ------------------------------------------------------------------*/
+
+/* ACTION 1 ------------------------------------------------------------------*
+ * Include here platform specific header files. *
+ *----------------------------------------------------------------------------*/
+#include "mbed.h"
+/* ACTION 2 ------------------------------------------------------------------*
+ * Include here expansion board specific header files. *
+ *----------------------------------------------------------------------------*/
+#include "x_nucleo_cca02m1_class.h"
+
+
+/* Variables -----------------------------------------------------------------*/
+
+/* Indexes of the PCM buffer. */
+uint32_t X_NUCLEO_CCA02M1::_PCM_buffer_read_index = 0;
+uint32_t X_NUCLEO_CCA02M1::_PCM_buffer_write_index = 0;
+
+/* Number of expansion boards. */
+uint8_t X_NUCLEO_CCA02M1::_number_of_boards = 0;
+
+/* Accessing shared areas: the PCM buffer. */
+SingletonPtr<PlatformMutex> X_NUCLEO_CCA02M1::_mutex;
+
+
+/* Methods -------------------------------------------------------------------*/
+
+/**
+* @brief Initializing the X_NUCLEO_CCA02M1 board.
+* @param init Pointer to device specific initalization structure.
+* @retval "0" in case of success, an error code otherwise.
+*/
+Status_t X_NUCLEO_CCA02M1::Init(void *init)
+{
+ /* Storing data. */
+ if (init != NULL)
+ {
+ _frequency = (*((X_NUCLEO_CCA02M1_Init_t *) init)).frequency;
+ _channels = (*((X_NUCLEO_CCA02M1_Init_t *) init)).channels;
+ }
+
+ /* Setting configuration. */
+ switch (_frequency)
+ {
+ case I2S_AUDIOFREQ_8K:
+ _decimation_factor = 128;
+ break;
+
+ case I2S_AUDIOFREQ_16K:
+ case I2S_AUDIOFREQ_32K:
+ case I2S_AUDIOFREQ_48K:
+ default:
+ _decimation_factor = 64;
+ break;
+ }
+
+ /* Buffer sizes in 16-bits samples. */
+ _PCM_samples_one_ms = ((_frequency * _channels) / 1000);
+ _PDM_samples_one_ms = ((_PCM_samples_one_ms * _decimation_factor) / 16);
+ _PDM_samples_two_ms = (_PDM_samples_one_ms << 1);
+
+ /* Allocating input and output buffers. */
+ _PDM_buffer_two_ms = (uint16_t *) calloc(_PDM_samples_two_ms, sizeof(uint16_t));
+ _PCM_buffer_n_ms = (int16_t *) calloc(_PCM_samples_one_ms * PCM_BUFFER_SIZE_ms, sizeof(uint16_t));
+
+ /* Allocating support buffers. */
+ _PDM_buffer_one_ms = (uint16_t *) calloc(_PDM_samples_one_ms, sizeof(uint16_t));
+
+ /* Starting the I2S timer, if needed. */
+ if (_channels != 1)
+ if (InitI2STimer() != COMPONENT_OK)
+ return COMPONENT_ERROR;
+
+ /* Initializing the PDM to PCM conversion library. */
+ if ((_pdm2pcm = new PDM2PCMAudio(_frequency, _channels)) == NULL)
+ return COMPONENT_ERROR;
+
+ /* Setting I2S parameters. */
+ dev_i2s.mode(MASTER_RX, true);
+ dev_i2s.audio_frequency(_frequency == I2S_AUDIOFREQ_8K ? 4 * _frequency : 2 * _frequency);
+ dev_i2s.protocol(MSB);
+ dev_i2s.format(_channels == 1 ? 16 : 32, _channels == 1 ? 16 : 32, 1);
+
+ return COMPONENT_OK;
+}
+
+/**
+ * @brief Enabling transmission via USB.
+ * @param None.
+ * @retval "0" in case of success, an error code otherwise.
+ */
+Status_t X_NUCLEO_CCA02M1::EnableUSB(void)
+{
+ /* Initializing the USBAudio object. */
+ if ((_usb_audio = new USBAudio(32000, 2, _frequency, _channels)) == NULL)
+ return COMPONENT_ERROR;
+
+ /* Allocating support buffers. */
+ _USB_PCM_buffer_one_ms = (int16_t *) calloc(_PCM_samples_one_ms + _channels, sizeof(uint16_t));
+
+ _usb_enabled = true;
+
+ return COMPONENT_OK;
+}
+
+/**
+ * @brief Disabling transmission via USB.
+ * @param None.
+ * @retval "0" in case of success, an error code otherwise.
+ */
+Status_t X_NUCLEO_CCA02M1::DisableUSB(void)
+{
+ /* Freeing memory for the USBAudio object and support buffers. */
+ delete _usb_audio;
+ free(_USB_PCM_buffer_one_ms);
+
+ _usb_enabled = false;
+
+ return COMPONENT_OK;
+}
+
+/*
+ * @brief Start recording audio.
+ * @param None.
+ * @retval "0" in case of success, an error code otherwise.
+ */
+Status_t X_NUCLEO_CCA02M1::Record(void)
+{
+ /* Reading microphones via I2S. */
+ int res = dev_i2s.transfer(
+ (void *) NULL, 0,
+ (void *) _PDM_buffer_two_ms, _PDM_samples_two_ms * BYTES_PER_SAMPLE,
+ event_callback_t(this, &X_NUCLEO_CCA02M1::I2SCallback),
+ I2S_EVENT_ALL
+ );
+ if (res != 0)
+ return COMPONENT_ERROR;
+
+ /* Attaching a callback to send data through the USB at a standard frequency
+ of 1KHz. */
+ if (_usb_enabled)
+ _usb_audio->attachTx(this, &X_NUCLEO_CCA02M1::USBHandler);
+
+ return COMPONENT_OK;
+}
+
+/**
+ * @brief Attach a user-defined callback that will be executed whenever PCM
+ * data are ready, i.e. once each millisecond.
+ * The provided PCM buffer will be filled by the microphones.
+ * @param fptr Callback to attach.
+ * @retval None.
+ */
+void X_NUCLEO_CCA02M1::Attach(void (*fptr) (int16_t *PCM_buffer, uint16_t PCM_buffer_bytes))
+{
+ /* Allocating support buffers. */
+ if ((_USER_PCM_buffer_one_ms = (int16_t *) calloc(_PCM_samples_one_ms, sizeof(uint16_t))) == NULL)
+ error("Instantiation of support buffers failed.\r\n");
+
+ /* Attaching the callback. */
+ _callback.attach(fptr);
+ _callback_attached = true;
+}
+
+/**
+ * @brief Attach a user-defined non-static callback that will be executed
+ * whenever PCM data are ready, i.e. once each millisecond.
+ * The provided PCM buffer will be filled by the microphones.
+ * @param tptr Pointer to an object.
+ * @param mptr Pointer to an object's callback.
+ * @retval None.
+ */
+template<typename T>
+void X_NUCLEO_CCA02M1::Attach(T *tptr, void (T::*mptr) (int16_t *PCM_buffer, uint16_t PCM_buffer_bytes))
+{
+ /* Allocating support buffers. */
+ if ((_USER_PCM_buffer_one_ms = (int16_t *) calloc(_PCM_samples_one_ms, sizeof(uint16_t))) == NULL)
+ error("Instantiation of support buffers failed.\r\n");
+
+ /* Attaching the callback. */
+ _callback.attach(tptr, mptr);
+ _callback_attached = true;
+}
+
+/**
+ * @brief Initializing the I2S timer.
+ * @param None.
+ * @retval COMPONENT_OK in case of success, COMPONENT_ERROR otherwise.
+ */
+Status_t X_NUCLEO_CCA02M1::InitI2STimer(void)
+{
+ if (AUDIO_IN_Timer_Init() != COMPONENT_OK)
+ return COMPONENT_ERROR;
+
+ if (AUDIO_IN_Timer_Start() != COMPONENT_OK)
+ return COMPONENT_ERROR;
+
+ return COMPONENT_OK;
+}
+
+/**
+ * @brief I2S callback which is executed whenever PCM data are ready, i.e. once
+ * each millisecond.
+ * @param narg Narg flag.
+ * @retval None.
+ */
+void X_NUCLEO_CCA02M1::I2SCallback(int narg)
+{
+ /* Checking for errors. */
+ if (!(narg & (I2S_EVENT_RX_COMPLETE | I2S_EVENT_RX_HALF_COMPLETE)))
+ error("Unexpected transmission event.\r\n");
+
+ /* PDM to PCM Conversion. */
+ if (narg & (I2S_EVENT_RX_COMPLETE | I2S_EVENT_RX_HALF_COMPLETE))
+ {
+#ifdef X_NUCLEO_CCA02M1_DEBUG
+ _i2s_signal = 1;
+#endif
+
+ uint32_t PDM_index = (narg & I2S_EVENT_RX_HALF_COMPLETE ? 0 : _PDM_samples_one_ms);
+ switch (_channels)
+ {
+ case 1:
+ /* Scrambling PDM audio data. */
+ _pdm2pcm->Scramble(_PDM_buffer_one_ms, &_PDM_buffer_two_ms[PDM_index], _PDM_samples_one_ms);
+ break;
+
+ case 2:
+ /* Demuxing PDM audio data. */
+ _pdm2pcm->Demux(_PDM_buffer_one_ms, &_PDM_buffer_two_ms[PDM_index], _PDM_samples_one_ms);
+ break;
+ }
+
+ /* Acquiring resources. */
+ _mutex->lock();
+
+ /* Converting PDM to PCM audio data. */
+ _pdm2pcm->Convert(&_PCM_buffer_n_ms[_PCM_buffer_write_index], _PDM_buffer_one_ms, _volume, _decimation_factor);
+
+ /* Copying PCM data to the user buffer. */
+ if (_callback_attached)
+ memcpy(_USER_PCM_buffer_one_ms, &_PCM_buffer_n_ms[_PCM_buffer_write_index], _PCM_samples_one_ms * BYTES_PER_SAMPLE);
+
+ /* Updating write index. */
+ _PCM_buffer_write_index += _PCM_samples_one_ms;
+ _PCM_buffer_write_index %= (PCM_BUFFER_SIZE_ms * _PCM_samples_one_ms);
+
+ /* Releasing resources. */
+ _mutex->unlock();
+
+ /* Executing user-defined callback. */
+ static bool first_time = true;
+ if (_callback_attached && first_time)
+ {
+ _callback.call(_USER_PCM_buffer_one_ms, _PCM_samples_one_ms * BYTES_PER_SAMPLE);
+ first_time = !first_time;
+ }
+
+#ifdef X_NUCLEO_CCA02M1_DEBUG
+ _i2s_signal = 0;
+#endif
+ }
+
+ /* Start sending data through the USB whenever the PCM buffer has been
+ filled up to the medium threshold. */
+ if (_usb_enabled)
+ {
+ static bool done = false;
+ static uint32_t calls = 0;
+ if (!done)
+ if (calls++ >= PCM_BUFFER_TH_MED_ms)
+ {
+ USBHandler();
+ done = true;
+ }
+ }
+}
+
+/**
+ * @brief Sending PCM data via USB.
+ * @param None.
+ * @retval None.
+ */
+void X_NUCLEO_CCA02M1::USBHandler(void)
+{
+#ifdef X_NUCLEO_CCA02M1_DEBUG
+ _usb_signal = 1;
+#endif
+
+ /* Acquiring resources. */
+ _mutex->lock();
+
+ /* Computing the delta-data to send through the USB depending on the
+ dis-alignment between the read and write index of the PCM buffer,
+ which may happen whenever the I2S and the USB do not works at the
+ same frequency (i.e. 1KHz). */
+ int32_t PCM_diff = _PCM_buffer_write_index - _PCM_buffer_read_index;
+ PCM_diff = (PCM_diff >= 0 ? PCM_diff : PCM_diff + PCM_BUFFER_SIZE_ms * _PCM_samples_one_ms);
+ int32_t PCM_buffer_high_index = PCM_BUFFER_TH_HIG_ms * _PCM_samples_one_ms;
+ int32_t PCM_buffer_low_index = PCM_BUFFER_TH_LOW_ms * _PCM_samples_one_ms;
+ int32_t PCM_delta_samples = 0;
+
+ if (PCM_diff >= PCM_buffer_high_index) {
+ PCM_delta_samples = 1;
+#ifdef X_NUCLEO_CCA02M1_DEBUG
+ _buffer_overrun = 1;
+ _buffer_underrun = 0;
+#endif
+ }
+ else if (PCM_diff <= PCM_buffer_low_index) {
+ PCM_delta_samples = -1;
+#ifdef X_NUCLEO_CCA02M1_DEBUG
+ _buffer_overrun = 0;
+ _buffer_underrun = 1;
+ } else {
+ _buffer_overrun = _buffer_underrun = 0;
+#endif
+ }
+
+ /* Writing data through the USB. */
+ for (uint32_t i = 0, j = _PCM_buffer_read_index; i < _PCM_samples_one_ms + PCM_delta_samples * _channels; j %= (PCM_BUFFER_SIZE_ms * _PCM_samples_one_ms))
+ _USB_PCM_buffer_one_ms[i++] = _PCM_buffer_n_ms[j++];
+ _usb_audio->writeSync((uint8_t *) _USB_PCM_buffer_one_ms, PCM_delta_samples);
+
+ /* Updating read index. */
+ _PCM_buffer_read_index += _PCM_samples_one_ms + PCM_delta_samples * _channels;
+ _PCM_buffer_read_index %= (PCM_BUFFER_SIZE_ms * _PCM_samples_one_ms);
+
+ /* Releasing resources. */
+ _mutex->unlock();
+
+#ifdef X_NUCLEO_CCA02M1_DEBUG
+ _usb_signal = 0;
+#endif
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/BSP/x_nucleo_cca02m1_class.h Tue Feb 28 11:20:53 2017 +0100
@@ -0,0 +1,321 @@
+/**
+ ******************************************************************************
+ * @file x_nucleo_cca02m1_class.h
+ * @author AST / Software Platforms and Cloud
+ * @version V1.0
+ * @date October 17th, 2016
+ * @brief Class header file for the X_NUCLEO_CCA02M1 expansion board.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
+ *
+ * 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.
+ *
+ ******************************************************************************
+ */
+
+
+/* Generated with STM32CubeTOO -----------------------------------------------*/
+
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+
+#ifndef __X_NUCLEO_CCA02M1_CLASS_H
+#define __X_NUCLEO_CCA02M1_CLASS_H
+
+
+/* Includes ------------------------------------------------------------------*/
+
+/* ACTION 1 ------------------------------------------------------------------*
+ * Include here platform specific header files. *
+ *----------------------------------------------------------------------------*/
+#include "mbed.h"
+#include "I2S.h"
+#include "USBAudio.h"
+#include "divisor.h"
+/* ACTION 2 ------------------------------------------------------------------*
+ * Include here expansion board configuration's header files. *
+ *----------------------------------------------------------------------------*/
+/* ACTION 3 ------------------------------------------------------------------*
+ * Include here expansion board's components' header files. *
+ * *
+ * Example: *
+ * #include "component_1_class.h" *
+ * #include "component_2_class.h" *
+ *----------------------------------------------------------------------------*/
+#include "component.h"
+#include "PDM2PCMAudio_class.h"
+
+
+/* Definitions ---------------------------------------------------------------*/
+
+/* Maximum number of mounted "X-NUCLEO-CCA02M1" Expansion Boards. */
+#define EXPBRD_MOUNTED_NR_MAX 1
+
+/* Bytes per sample. */
+#define BYTES_PER_SAMPLE 2
+
+/* Default paramters. */
+#define DEFAULT_FREQUENCY 32000
+#define DEFAULT_CHANNELS 2
+
+/* PCM buffer size and thresholds in ms. */
+#define PCM_BUFFER_TH_LOW_ms 1
+#define PCM_BUFFER_TH_MED_ms 4
+#define PCM_BUFFER_TH_HIG_ms 7
+#define PCM_BUFFER_SIZE_ms 9
+
+
+/* Types ---------------------------------------------------------------------*/
+
+/* Audio processor initialization structure. */
+typedef struct
+{
+ uint32_t frequency;
+ uint8_t channels;
+} X_NUCLEO_CCA02M1_Init_t;
+
+
+/* Classes -------------------------------------------------------------------*/
+
+/** Class representing a X_NUCLEO_CCA02M1 board.
+ */
+class X_NUCLEO_CCA02M1
+{
+public:
+
+ /*** Constructor, Destructor, and Initialization Methods ***/
+
+ /**
+ * @brief Constructor.
+ * @param dpin pin name of the data input/output pin of the I2S device.
+ * @param clk pin name of the clock pin of the I2S device.
+ * @param wsel pin name of the word select output pin of the I2S device (might be NC for PDM sources).
+ * @param fdpin pin name of the data input pin of the I2S device (for full-duplex operations, default = NC).
+ * @param mck pin name of the master clock output pin of the I2S device (additional pin when needed for some external audio devices, default = NC)
+ */
+ X_NUCLEO_CCA02M1(PinName dpin, PinName clk, PinName wsel = NC, PinName fdpin = NC, PinName mck = NC) :
+ dev_i2s(dpin, clk, wsel, fdpin, mck),
+ _usb_enabled(false),
+ _volume(PDM2PCM_NOGAIN_VOLUME),
+ _decimation_factor(PDM2PCM_DECIMATION_FACTOR),
+ _frequency(DEFAULT_FREQUENCY),
+ _channels(DEFAULT_CHANNELS),
+ _callback_attached(false)
+#ifdef X_NUCLEO_CCA02M1_DEBUG
+ , _i2s_signal(D13),
+ _usb_signal(D12),
+ _buffer_overrun(D11),
+ _buffer_underrun(D10)
+#endif
+ {
+ /* Checking stackability. */
+ if (!(_number_of_boards < EXPBRD_MOUNTED_NR_MAX))
+ error("Instantiation of the X_NUCLEO_CCA02M1 expansion board failed: it can be stacked up to %d times.\r\n", EXPBRD_MOUNTED_NR_MAX);
+ _X_NUCLEO_CCA02M1_Id = _number_of_boards++;
+ }
+
+ /**
+ * @brief Destructor.
+ */
+ virtual ~X_NUCLEO_CCA02M1(void) {}
+
+
+ /*** Public Component Related Methods ***/
+
+ /**
+ * @brief Initializing the X_NUCLEO_CCA02M1 board.
+ * @param init Pointer to device specific initalization structure.
+ * @retval "0" in case of success, an error code otherwise.
+ */
+ virtual Status_t Init(void *init = NULL);
+
+ /**
+ * @brief Enabling transmission via USB.
+ * @param None.
+ * @retval "0" in case of success, an error code otherwise.
+ */
+ virtual Status_t EnableUSB(void);
+
+ /**
+ * @brief Disabling transmission via USB.
+ * @param None.
+ * @retval "0" in case of success, an error code otherwise.
+ */
+ virtual Status_t DisableUSB(void);
+
+ /**
+ * @brief Start recording audio.
+ * @param None.
+ * @retval "0" in case of success, an error code otherwise.
+ */
+ virtual Status_t Record(void);
+
+ /**
+ * @brief Attach a user-defined callback that will be executed whenever PCM
+ * data are ready, i.e. once each millisecond.
+ * The provided PCM buffer will be filled by the microphones.
+ * @param fptr Callback to attach.
+ * @retval None.
+ */
+ void Attach(void (*fptr) (int16_t *PCM_buffer, uint16_t PCM_buffer_bytes));
+
+ /**
+ * @brief Attach a user-defined non-static callback that will be executed
+ * whenever PCM data are ready, i.e. once each millisecond.
+ * The provided PCM buffer will be filled by the microphones.
+ * @param tptr Pointer to an object.
+ * @param mptr Pointer to an object's callback.
+ * @retval None.
+ */
+ template<typename T>
+ void Attach(T *tptr, void (T::*mptr) (int16_t *PCM_buffer, uint16_t PCM_buffer_bytes));
+
+
+ /*** Other Public Expansion Board Related Methods ***/
+
+ /*** Public Expansion Board Related Attributes ***/
+
+ /* ACTION 4 --------------------------------------------------------------*
+ * Declare here a public attribute for each expansion board's component. *
+ * You will have to call these attributes' public methods within your *
+ * main program. *
+ * *
+ * Example: *
+ * COMPONENT_1 *component_1; *
+ * COMPONENT_2 *component_2; *
+ *------------------------------------------------------------------------*/
+
+
+protected:
+
+ /*** Protected Expansion Board Related Related Methods ***/
+
+ /* ACTION 5 --------------------------------------------------------------*
+ * Declare here a protected initialization method for each expansion *
+ * board's component. *
+ * *
+ * Example: *
+ * bool Init_COMPONENT_1(void); *
+ * bool Init_COMPONENT_2(void); *
+ *------------------------------------------------------------------------*/
+ /**
+ * @brief Initializing the I2S timer.
+ * @param None.
+ * @retval COMPONENT_OK in case of success, COMPONENT_ERROR otherwise.
+ */
+ Status_t InitI2STimer(void);
+
+ /**
+ * @brief I2S callback which is executed whenever PCM data are ready, i.e. once
+ * each millisecond.
+ * @param narg Narg flag.
+ * @retval None.
+ */
+ void I2SCallback(int narg);
+
+ /**
+ * @brief Sending PCM data via USB.
+ * @param None.
+ * @retval None.
+ */
+ void USBHandler(void);
+
+
+ /*** Expansion Board's Instance Variables ***/
+
+ /* ACTION 6 --------------------------------------------------------------*
+ * Declare here the component's static and non-static data, one variable *
+ * per line. *
+ * *
+ * Example: *
+ * int instance_id; *
+ * static int number_of_instances; *
+ *------------------------------------------------------------------------*/
+public:
+
+ /* I2S Audio Device (exclusive). */
+ I2S dev_i2s;
+
+
+protected:
+
+ /* USB Audio Device. */
+ USBAudio *_usb_audio;
+ bool _usb_enabled;
+
+ /* PDM to PCM conversion library. */
+ PDM2PCMAudio *_pdm2pcm;
+
+ /* PDM to PCM conversion parameters. */
+ uint32_t _volume;
+ uint32_t _decimation_factor;
+
+ /* Microphone parameters. */
+ uint32_t _frequency;
+ uint32_t _channels;
+
+ /* Size of the buffers to store audio data. */
+ uint32_t _PDM_samples_one_ms;
+ uint32_t _PDM_samples_two_ms;
+ uint32_t _PCM_samples_one_ms;
+
+ /* Input and output audio buffers. */
+ uint16_t *_PDM_buffer_two_ms; /* Input double-buffered PDM audio data, from microphones. */
+ int16_t *_PCM_buffer_n_ms; /* Output n-ms-buffered PCM audio data, to USB. */
+
+ /* Support audio buffers for processing data. */
+ uint16_t *_PDM_buffer_one_ms;
+ int16_t *_USB_PCM_buffer_one_ms;
+ int16_t *_USER_PCM_buffer_one_ms;
+
+ /* Indexes of the output PCM buffer. */
+ static uint32_t _PCM_buffer_read_index;
+ static uint32_t _PCM_buffer_write_index;
+
+ /* User-defined PCM-data-ready callback. */
+ Callback<void(int16_t *PCM_buffer, uint16_t PCM_buffer_bytes)> _callback;
+ bool _callback_attached;
+
+ /* Accessing shared areas: the PCM buffer. */
+ static SingletonPtr<PlatformMutex> _mutex;
+
+ /* Expansion board identifier. */
+ uint8_t _X_NUCLEO_CCA02M1_Id;
+
+ /* Number of expansion boards. */
+ static uint8_t _number_of_boards;
+
+#ifdef X_NUCLEO_CCA02M1_DEBUG
+ /* Signals for debugging purposes. */
+ DigitalOut _i2s_signal;
+ DigitalOut _usb_signal;
+ DigitalOut _buffer_underrun;
+ DigitalOut _buffer_overrun;
+#endif
+};
+
+#endif /* __X_NUCLEO_CCA02M1_CLASS_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Common/component.h Tue Feb 28 11:20:53 2017 +0100
@@ -0,0 +1,93 @@
+/**
+ ******************************************************************************
+ * @file component.h
+ * @author AST
+ * @version V1.0.0
+ * @date 1 April 2015
+ * @brief Generic header file containing a generic component's definitions
+ * and I/O functions.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
+ *
+ * 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 __COMPONENT_H
+#define __COMPONENT_H
+
+
+/* Types ---------------------------------------------------------------------*/
+
+/**
+ * @brief Component's Context structure definition.
+ */
+typedef struct
+{
+ /* Identity. */
+ uint8_t who_am_i;
+
+ /* ACTION ----------------------------------------------------------------*/
+ /* There should be only a unique identifier for each component, which */
+ /* should be the "who_am_i" parameter, hence this parameter is optional. */
+ /* -----------------------------------------------------------------------*/
+ /* Type. */
+ uint8_t type;
+
+ /* Configuration. */
+ uint8_t address;
+
+ /* Pointer to the Data. */
+ void *pData;
+
+ /* Pointer to the Virtual Table. */
+ void *pVTable;
+
+ /* ACTION ----------------------------------------------------------------*/
+ /* There should be only a unique virtual table for each component, which */
+ /* should be the "pVTable" parameter, hence this parameter is optional. */
+ /* -----------------------------------------------------------------------*/
+ /* Pointer to the Extended Virtual Table. */
+ void *pExtVTable;
+} Handle_t;
+
+/**
+ * @brief Component's Status enumerator definition.
+ */
+typedef enum
+{
+ COMPONENT_OK = 0,
+ COMPONENT_ERROR,
+ COMPONENT_TIMEOUT,
+ COMPONENT_NOT_IMPLEMENTED
+} Status_t;
+
+#endif /* __COMPONENT_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
Binary file Middlewares/PDM2PCM/libPDMFilter_CM4_GCC.a has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Middlewares/PDM2PCM/pdm_filter.h Tue Feb 28 11:20:53 2017 +0100
@@ -0,0 +1,76 @@
+/**
+ ******************************************************************************
+ * @file pdm_filter.h
+ * @author MCD Application Team
+ * @version V2.0.1
+ * @date 17-December-2013
+ * @brief Header file for PDM audio software decoding Library.
+ * This Library is used to decode and reconstruct the audio signal
+ * produced by ST MEMS microphone (MP45Dxxx, MP34Dxxx).
+ * For more details about this Library, please refer to document
+ * "PDM audio software decoding on STM32 microcontrollers (AN3998)".
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2>
+ *
+ * Licensed under MCD-ST Image SW License Agreement V2, (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/software_license_agreement_image_v2
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __PDM_FILTER_H
+#define __PDM_FILTER_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include <stdint.h>
+
+
+/* Exported types ------------------------------------------------------------*/
+typedef struct {
+ uint16_t Fs;
+ float LP_HZ;
+ float HP_HZ;
+ uint16_t In_MicChannels;
+ uint16_t Out_MicChannels;
+ char InternalFilter[34];
+} PDMFilter_InitStruct;
+
+/* Exported constants --------------------------------------------------------*/
+/* Exported macros -----------------------------------------------------------*/
+#define HTONS(A) ((((uint16_t)(A) & 0xff00) >> 8) | \
+ (((uint16_t)(A) & 0x00ff) << 8))
+
+/* Exported functions ------------------------------------------------------- */
+void PDM_Filter_Init(PDMFilter_InitStruct * Filter);
+
+int32_t PDM_Filter_64_MSB(uint8_t* data, uint16_t* dataOut, uint16_t MicGain, PDMFilter_InitStruct * Filter);
+int32_t PDM_Filter_80_MSB(uint8_t* data, uint16_t* dataOut, uint16_t MicGain, PDMFilter_InitStruct * Filter);
+int32_t PDM_Filter_128_MSB(uint8_t* data, uint16_t* dataOut, uint16_t MicGain, PDMFilter_InitStruct * Filter);
+int32_t PDM_Filter_64_LSB(uint8_t* data, uint16_t* dataOut, uint16_t MicGain, PDMFilter_InitStruct * Filter);
+int32_t PDM_Filter_80_LSB(uint8_t* data, uint16_t* dataOut, uint16_t MicGain, PDMFilter_InitStruct * Filter);
+int32_t PDM_Filter_128_LSB(uint8_t* data, uint16_t* dataOut, uint16_t MicGain, PDMFilter_InitStruct * Filter);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __PDM_FILTER_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
Binary file Middlewares/PDM2PCM/software_license_agreement_image_v2.pdf has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ST_I2S.lib Tue Feb 28 11:20:53 2017 +0100 @@ -0,0 +1,1 @@ +https://developer.mbed.org/teams/ST/code/ST_I2S/#6ebde375d2d1
