Library to handle the X-NUCLEO-CCA02M1 MEMS Microphones Expansion Board.
Dependencies: ST_I2S ST_FREQUENCY_DIVIDER USBDEVICE
Dependents: HelloWorld_CCA02M1 HelloWorld_CCA02M1_mbedOS HelloWorld_CCA02M1 Karaoke_CCA01M1_CCA02M1_mbedOS
Fork of X_NUCLEO_CCA02M1 by
MEMS Microphones Library
Library to handle the X-NUCLEO-CCA02M1 MEMS Microphones Expansion Board. A single board allows to record a standard 2-channel stereo signal as an array of PCM samples (16 bit/sample); in principle, it could make use of six additional MEMS microphones to realize a 8-channel audio system.
Microphones configuration
Currently the configurations supported are the following:
- Stereo@48KHz
- Stereo@44.1KHz (CD audio quality)
- Stereo@32KHz
- Stereo@16KHz
- Stereo@8KHz
- Mono@48KHz
- Mono@44.1KHz
- Mono@32KHz
- Mono@16KHz
- Mono@8KHz
Mono configurations need a Jumper connecting PB_5 and PB_13 on the Morpho connector to properly work.
Platform compatibility
- This board can be currently used with the Nucleo F4 Family only, please see the ST_I2S library compatibility for further information.
- The library is compatible both with mbed OS 5.x and mbed classic 2.x (to work with mbed classic, the main application has to import the "events" library, which is not included into the "mbed" library).
I2S Peripheral Usage
By default this board makes use of the I2S peripheral available on Nucleo boards.
Acquiring through the USB
In order to acquire the recorded PCM audio channel with an audio SW on a PC, please connect the expansion board to a USB port of the PC, and the Nucleo board to a USB power supply.
Revision 2:9f389fd8fb2e, committed 2017-04-21
- Comitter:
- davide.aliprandi@st.com
- Date:
- Fri Apr 21 10:33:08 2017 +0200
- Parent:
- 1:245f83276546
- Child:
- 3:c5091e8deede
- Commit message:
- Aligned to ARM mbed codinmg style; OpenPDM2PCM middleware added.
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/BSP/PDM2PCMAudio.cpp Fri Apr 21 10:33:08 2017 +0200
@@ -0,0 +1,153 @@
+/**
+ ******************************************************************************
+ * @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.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 < 1/*_channels*/; index++) {
+#ifdef PDM2PCM_AUDIO_DEBUG
+ _pdm2pcm_audio_signal = 1;
+#endif
+#ifdef USE_OPEN_PDM2PCM_LIBRARY
+ Open_PDM_Filter(&((uint8_t *) input_buffer)[index], (uint16_t *) &(output_buffer[index]), volume, (TPDMFilter_InitStruct *) &_PDM2PCM_filter[index]);
+#else
+ PDM_Filter_64_LSB(&((uint8_t *) input_buffer)[index], (uint16_t *) &(output_buffer[index]), volume, (PDMFilter_InitStruct *) &_PDM2PCM_filter[index]);
+#endif
+#ifdef PDM2PCM_AUDIO_DEBUG
+ _pdm2pcm_audio_signal = 0;
+#endif
+ }
+ break;
+
+ case 128:
+ for (uint32_t index = 0; index < _channels; index++) {
+#ifdef USE_OPEN_PDM2PCM_LIBRARY
+ Open_PDM_Filter(&((uint8_t *) input_buffer)[index], (uint16_t *) &(output_buffer[index]), volume, (TPDMFilter_InitStruct *) &_PDM2PCM_filter[index]);
+#else
+ PDM_Filter_128_LSB(&((uint8_t *) input_buffer)[index], (uint16_t *) &(output_buffer[index]), volume, (PDMFilter_InitStruct *) &_PDM2PCM_filter[index]);
+#endif
+ }
+ 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.h Fri Apr 21 10:33:08 2017 +0200
@@ -0,0 +1,167 @@
+/**
+ ******************************************************************************
+ * @file PDM2PCMAudio.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
+
+
+/* Definitions ---------------------------------------------------------------*/
+
+#define USE_OPEN_PDM2PCM_LIBRARY
+#define PDM2PCM_AUDIO_DEBUG
+
+
+/* Includes ------------------------------------------------------------------*/
+
+#include "mbed.h"
+#include "component_def.h"
+#ifdef USE_OPEN_PDM2PCM_LIBRARY
+#include "OpenPDMFilter.h"
+#else
+#include "pdm_filter.h"
+#endif
+
+
+/* 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)
+#ifdef PDM2PCM_AUDIO_DEBUG
+ , _pdm2pcm_audio_signal(D9)
+#endif
+ {
+ /* Enable CRC peripheral to unlock the PDM2PCMAudio library. */
+ __CRC_CLK_ENABLE();
+
+ /* Initializing PDM2PCMAudio Filter. */
+ for (uint32_t i = 0; i < _channels; i++)
+ {
+#ifdef USE_OPEN_PDM2PCM_LIBRARY
+ /* 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;
+ _PDM2PCM_filter[i].Decimation = 64;
+ _PDM2PCM_filter[i].SincN = 3;
+ Open_PDM_Filter_Init((TPDMFilter_InitStruct *) &_PDM2PCM_filter[i]);
+#else
+ /* 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]);
+#endif
+ }
+ };
+
+ /**
+ * @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;
+#ifdef USE_OPEN_PDM2PCM_LIBRARY
+ TPDMFilter_InitStruct _PDM2PCM_filter[PDM2PCM_FILTER_SIZE];
+#else
+ PDMFilter_InitStruct _PDM2PCM_filter[PDM2PCM_FILTER_SIZE];
+#endif
+ static const uint8_t _demux_filter[DEMUX_FILTER_SIZE];
+
+#ifdef PDM2PCM_AUDIO_DEBUG
+ DigitalOut _pdm2pcm_audio_signal;
+#endif
+};
+
+#endif /* __PDM2PCM_AUDIO_CLASS_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- a/BSP/PDM2PCMAudio_class.cpp Fri Apr 21 10:31:01 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,137 +0,0 @@
-/**
- ******************************************************************************
- * @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****/
--- a/BSP/PDM2PCMAudio_class.h Fri Apr 21 10:31:01 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,135 +0,0 @@
-/**
- ******************************************************************************
- * @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/XNucleoCCA02M1.cpp Fri Apr 21 10:33:08 2017 +0200
@@ -0,0 +1,358 @@
+/**
+ ******************************************************************************
+ * @file XNucleoCCA02M1.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 "XNucleoCCA02M1.h"
+
+
+/* Variables -----------------------------------------------------------------*/
+
+/* Indexes of the PCM buffer. */
+uint32_t XNucleoCCA02M1::_PCM_buffer_read_index = 0;
+uint32_t XNucleoCCA02M1::_PCM_buffer_write_index = 0;
+
+/* Number of expansion boards. */
+uint8_t XNucleoCCA02M1::_number_of_boards = 0;
+
+/* Accessing shared areas: the PCM buffer. */
+SingletonPtr<PlatformMutex> XNucleoCCA02M1::_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 XNucleoCCA02M1::init(void *init)
+{
+ /* Storing data. */
+ if (init != NULL)
+ {
+ _frequency = (*((XNucleoCCA02M1_init_t *) init)).frequency;
+ _channels = (*((XNucleoCCA02M1_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 frequency divider, if needed. */
+ if (_channels != 1) {
+ FrequencyDivider *divider = new FrequencyDivider();
+ divider->start();
+ }
+
+ /* 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 XNucleoCCA02M1::enable_usb(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 XNucleoCCA02M1::disable_usb(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 XNucleoCCA02M1::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, &XNucleoCCA02M1::i2s_callback),
+ 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, &XNucleoCCA02M1::usb_handler);
+
+ 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 XNucleoCCA02M1::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 XNucleoCCA02M1::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 I2S callback which is executed whenever PCM data are ready, i.e. once
+ * each millisecond.
+ * @param narg Narg flag.
+ * @retval None.
+ */
+void XNucleoCCA02M1::i2s_callback(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)
+ {
+ usb_handler();
+ done = true;
+ }
+ }
+}
+
+/**
+ * @brief Sending PCM data via USB.
+ * @param None.
+ * @retval None.
+ */
+void XNucleoCCA02M1::usb_handler(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;
+ USBAudio::AudioSampleCorrectType PCM_delta_samples = USBAudio::NoCorrection;
+
+ if (PCM_diff >= PCM_buffer_high_index) {
+ PCM_delta_samples = USBAudio::AddOneSample;
+#ifdef X_NUCLEO_CCA02M1_DEBUG
+ _buffer_overrun = 1;
+ _buffer_underrun = 0;
+#endif
+ }
+ else if (PCM_diff <= PCM_buffer_low_index) {
+ PCM_delta_samples = USBAudio::RemoveOneSample;
+#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 + ((uint32_t) 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 + ((uint32_t) 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/XNucleoCCA02M1.h Fri Apr 21 10:33:08 2017 +0200
@@ -0,0 +1,314 @@
+/**
+ ******************************************************************************
+ * @file XNucleoCCA02M1.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 "FrequencyDivider.h"
+#include "USBAudio.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.h" *
+ * #include "COMPONENT_2.h" *
+ *----------------------------------------------------------------------------*/
+#include "component_def.h"
+#include "PDM2PCMAudio.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;
+} XNucleoCCA02M1_init_t;
+
+
+/* Classes -------------------------------------------------------------------*/
+
+/** Class representing a X_NUCLEO_CCA02M1 board.
+ */
+class XNucleoCCA02M1
+{
+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)
+ */
+ XNucleoCCA02M1(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);
+ _XNucleoCCA02M1_Id = _number_of_boards++;
+ }
+
+ /**
+ * @brief Destructor.
+ */
+ virtual ~XNucleoCCA02M1(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 enable_usb(void);
+
+ /**
+ * @brief Disabling transmission via USB.
+ * @param None.
+ * @retval "0" in case of success, an error code otherwise.
+ */
+ virtual status_t disable_usb(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 I2S callback which is executed whenever PCM data are ready, i.e. once
+ * each millisecond.
+ * @param narg Narg flag.
+ * @retval None.
+ */
+ void i2s_callback(int narg);
+
+ /**
+ * @brief Sending PCM data via USB.
+ * @param None.
+ * @retval None.
+ */
+ void usb_handler(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 _XNucleoCCA02M1_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_overrun;
+ DigitalOut _buffer_underrun;
+#endif
+};
+
+#endif /* __X_NUCLEO_CCA02M1_CLASS_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- a/BSP/divisor.c Fri Apr 21 10:31:01 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,144 +0,0 @@
-/**
- ******************************************************************************
- * @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;
-}
--- a/BSP/divisor.h Fri Apr 21 10:31:01 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,75 +0,0 @@
-/**
- ******************************************************************************
- * @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
--- a/BSP/x_nucleo_cca02m1_class.cpp Fri Apr 21 10:31:01 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,373 +0,0 @@
-/**
- ******************************************************************************
- * @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
-}
--- a/BSP/x_nucleo_cca02m1_class.h Fri Apr 21 10:31:01 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,321 +0,0 @@
-/**
- ******************************************************************************
- * @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****/
--- a/Common/component.h Fri Apr 21 10:31:01 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,93 +0,0 @@
-/**
- ******************************************************************************
- * @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****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Common/component_def.h Fri Apr 21 10:33:08 2017 +0200
@@ -0,0 +1,93 @@
+/**
+ ******************************************************************************
+ * @file component_def.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 *p_data;
+
+ /* Pointer to the Virtual Table. */
+ void *p_vt;
+
+ /* ACTION ----------------------------------------------------------------*/
+ /* There should be only a unique virtual table for each component, which */
+ /* should be the "p_vt" parameter, hence this parameter is optional. */
+ /* -----------------------------------------------------------------------*/
+ /* Pointer to the Extended Virtual Table. */
+ void *p_ext_vt;
+} 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****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Middlewares/OpenPDM2PCM/OpenPDMFilter.c Fri Apr 21 10:33:08 2017 +0200
@@ -0,0 +1,306 @@
+/**
+******************************************************************************
+* @file OpenPDMFilter.h
+* @author CL
+* @version V1.0.0
+* @date 9-September-2015
+* @brief Open PDM audio software decoding Library.
+* This Library is used to decode and reconstruct the audio signal
+* produced by ST MEMS microphone (MP45Dxxx, MP34Dxxx).
+******************************************************************************
+* @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.
+*
+******************************************************************************
+*/
+
+
+/* Includes ------------------------------------------------------------------*/
+
+#include "OpenPDMFilter.h"
+
+
+/* Definitions ---------------------------------------------------------------*/
+
+#define maxDecFactor 128
+#define maxVol 64
+#define FilterGain 16;
+#define RoundDiv(a, b) (((a)>0)?(((a)+(b)/2)/(b)):(((a)-(b)/2)/(b)))
+#define SaturaLH(N, L, H) (((N)<(L))?(L):(((N)>(H))?(H):(N)))
+
+
+/* Variables -----------------------------------------------------------------*/
+
+uint32_t coef[5][maxDecFactor]; // Max sinc 5 with decimation 128
+uint32_t DivideConst = 0;
+int64_t SubConst = 0;
+uint32_t sinc1[maxDecFactor];
+uint32_t sinc2[maxDecFactor*2];
+uint32_t sinc3[maxDecFactor*3];
+uint32_t sinc4[maxDecFactor*4];
+uint32_t sinc[maxDecFactor*5];
+int64_t Z = 0;
+uint16_t app;
+
+
+/* Functions -----------------------------------------------------------------*/
+
+int64_t filterTable(uint8_t *data, uint8_t table, TPDMFilter_InitStruct *Param);
+
+void convolve(uint32_t Signal[/* SignalLen */], unsigned short SignalLen,
+ uint32_t Kernel[/* KernelLen */], unsigned short KernelLen,
+ uint32_t Result[/* SignalLen + KernelLen - 1 */]);
+
+int64_t filterTable(uint8_t *data, uint8_t table, TPDMFilter_InitStruct *Param)
+{
+ uint16_t contatore = 0;
+ int64_t F = 0;
+ uint8_t c;
+ uint8_t i;
+ uint16_t internalBit = Param->bit[table];
+ uint16_t internalBit_copy = internalBit;
+ uint16_t In_Mic = Param->In_MicChannels;
+
+ c = data[0];
+ for(i=0; i<Param->Decimation;i++)
+ {
+ if (c & (1<<((7-internalBit))))
+ F += coef[table][i];
+ internalBit++;
+ if(internalBit==8)
+ {
+ contatore+=In_Mic;
+ internalBit = 0;
+ c = data[contatore];
+ }
+ }
+ Param->bit[table] = internalBit;
+ Param->byte = contatore;
+
+ return F;
+}
+
+void Open_PDM_Filter_Init(TPDMFilter_InitStruct *Param)
+{
+ uint16_t i,j;
+ int64_t sum = 0;
+ Param->Coef[0] = Param->Coef[1] = Param->Coef[2] = Param->Coef[3] = Param->Coef[4] = 0;
+ for(i=0;i<5;i++)
+ {
+ Param->bit[i]=0;
+ }
+
+ for(i=0;i<Param->Decimation;i++)
+ {
+ sinc1[i]=1;
+ }
+ Param->OldOut = Param->OldIn = Param->OldZ = 0;
+ if(Param->LP_HZ!=0)
+ {
+ Param->LP_ALFA = (uint16_t)(Param->LP_HZ*256 / (Param->LP_HZ + Param->Fs/(2*3.14)));
+ }else
+ {
+ Param->LP_ALFA = 0;
+ }
+
+ if(Param->HP_HZ!=0)
+ {
+ Param->HP_ALFA = (uint16_t)(Param->Fs*256 / (2*3.14*Param->HP_HZ + Param->Fs));
+ }else
+ {
+ Param->HP_ALFA = 0;
+ }
+
+ switch(Param->SincN)
+ {
+ case 1:
+ Param->FilterLen = Param->Decimation;
+
+ for(i=0;i<Param->Decimation;i++)
+ {
+ coef[0][i]=1;
+ sum+= 1;
+ }
+ break;
+ case 2:
+ Param->FilterLen = Param->Decimation * 2;
+
+ sinc[0] = 0;
+
+ convolve(sinc1, Param->Decimation,sinc1,Param->Decimation,&sinc[1]);
+
+ for(j=0;j<2;j++)
+ {
+ for(i=0;i<Param->Decimation;i++)
+ {
+ coef[j][i] = sinc[j*Param->Decimation+i];
+ sum+= sinc[j*Param->Decimation+i];
+ }
+ }
+
+ break;
+ case 3:
+ Param->FilterLen = Param->Decimation * 3;
+ sinc[0] = 0;
+ sinc[Param->Decimation*3-1] = 0;
+ convolve(sinc1, Param->Decimation,sinc1,Param->Decimation,sinc2);
+ convolve(sinc2, Param->Decimation*2-1,sinc1,Param->Decimation,&sinc[1]);
+ for(j=0;j<3;j++)
+ {
+ for(i=0;i<Param->Decimation;i++)
+ {
+ coef[j][i] = sinc[j*Param->Decimation+i];
+ sum+= sinc[j*Param->Decimation+i];
+ }
+ }
+ break;
+ case 4:
+ Param->FilterLen = Param->Decimation * 4;
+ sinc[0] = 0;
+ sinc[1] = 0;
+ sinc[Param->Decimation*4-1] = 0;
+ convolve(sinc1, Param->Decimation,sinc1,Param->Decimation,sinc2);
+ convolve(sinc2, Param->Decimation*2-1,sinc1,Param->Decimation,sinc3);
+ convolve(sinc3, Param->Decimation*3-2,sinc1,Param->Decimation,&sinc[2]);
+ for(j=0;j<4;j++)
+ {
+ for(i=0;i<Param->Decimation;i++)
+ {
+ coef[j][i] = sinc[j*Param->Decimation+i];
+ sum+= sinc[j*Param->Decimation+i];
+ }
+ }
+
+ break;
+ case 5:
+ Param->FilterLen = Param->Decimation*5; // Dec * 5 - 2
+ sinc[0] = 0;
+ sinc[1] = 0;
+ sinc[Param->Decimation*5-2] = 0;
+ sinc[Param->Decimation*5-1] = 0;
+
+ convolve(sinc1, Param->Decimation,sinc1,Param->Decimation,sinc2);
+ convolve(sinc2, Param->Decimation*2-1,sinc1,Param->Decimation,sinc3);
+ convolve(sinc3, Param->Decimation*3-2,sinc1,Param->Decimation,sinc4);
+ convolve(sinc4, Param->Decimation*4-3,sinc1,Param->Decimation,&sinc[2]);
+
+ for(j=0;j<5;j++)
+ {
+ for(i=0;i<Param->Decimation;i++)
+ {
+ coef[j][i] = sinc[j*Param->Decimation+i];
+ sum+= sinc[j*Param->Decimation+i];
+ }
+ }
+ break;
+ }
+ SubConst = sum / 2;
+ DivideConst = SubConst*maxVol/32768/FilterGain;
+ if(DivideConst == 0 ) DivideConst = 1;
+}
+
+void convolve(uint32_t Signal[/* SignalLen */], unsigned short SignalLen,
+ uint32_t Kernel[/* KernelLen */], unsigned short KernelLen,
+ uint32_t Result[/* SignalLen + KernelLen - 1 */])
+{
+ uint16_t n;
+ for (n = 0; n < SignalLen + KernelLen - 1; n++)
+ {
+ unsigned short kmin, kmax, k;
+
+ Result[n] = 0;
+
+ kmin = (n >= KernelLen - 1) ? n - (KernelLen - 1) : 0;
+ kmax = (n < SignalLen - 1) ? n : SignalLen - 1;
+
+ for (k = kmin; k <= kmax; k++)
+ {
+ Result[n] += Signal[k] * Kernel[n - k];
+ }
+ }
+}
+
+void Open_PDM_Filter(uint8_t* data, uint16_t* dataOut, uint16_t MicGain, TPDMFilter_InitStruct *Param)
+{
+ uint32_t i;
+ int64_t OldOut, OldIn, OldZ;
+ OldOut=Param->OldOut;
+ OldIn=Param->OldIn;
+ OldZ=Param->OldZ;
+
+ for (i = 0; i < Param->Fs/1000; i++)
+ {
+ switch(Param->SincN)
+ {
+ case 1:
+ Z = filterTable(data,0, Param);
+ break;
+ case 2:
+ Z = Param->Coef[0] + filterTable(data,1, Param);
+ Param->Coef[0] = filterTable(data,0, Param);
+ break;
+ case 3:
+ Z = Param->Coef[1] + filterTable(data,2, Param);
+ Param->Coef[1] = Param->Coef[0] + filterTable(data,1, Param);
+ Param->Coef[0] = filterTable(data,0, Param);
+ break;
+ case 4:
+ Z = Param->Coef[2] + filterTable(data,3, Param);
+ Param->Coef[2] = Param->Coef[1] + filterTable(data,2, Param);
+ Param->Coef[1] = Param->Coef[0] + filterTable(data,1, Param);
+ Param->Coef[0] = filterTable(data,0, Param);
+ break;
+ case 5:
+ Z = Param->Coef[3] + filterTable(data,4, Param);
+ Param->Coef[3] = Param->Coef[2] + filterTable(data,3, Param);
+ Param->Coef[2] = Param->Coef[1] + filterTable(data,2, Param);
+ Param->Coef[1] = Param->Coef[0] + filterTable(data,1, Param);
+ Param->Coef[0] = filterTable(data,0, Param);
+ break;
+ }
+
+ Z-=SubConst;
+
+ if(Param->HP_ALFA!= 0)
+ {
+ OldOut = (Param->HP_ALFA * (OldOut + Z - OldIn))/256;
+ OldIn=Z;
+ Z=OldOut;
+ }
+
+ if(Param->LP_ALFA != 0)
+ {
+ OldZ = ((256-Param->LP_ALFA)*OldZ+Param->LP_ALFA*Z)/256;
+ Z = OldZ;
+ }
+
+ // if(Param->SincN>=3){
+ // Z = RoundDiv(Z, DivideConst);
+ // Z *= MicGain;
+ // }else{
+ Z *= MicGain;
+ Z = RoundDiv(Z, DivideConst);
+ // }
+ Z = SaturaLH(Z, -32700, 32700); // saturation
+ dataOut[i*Param->Out_MicChannels] = Z ;
+ // data+=(Param->Decimation-app)/8 * Param->In_MicChannels;
+ data+=Param->byte;
+ // data+=Param->Decimation/8*Param->In_MicChannels;
+ }
+ Param->OldOut=OldOut;
+ Param->OldIn=OldIn;
+ Param->OldZ=OldZ;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Middlewares/OpenPDM2PCM/OpenPDMFilter.h Fri Apr 21 10:33:08 2017 +0200
@@ -0,0 +1,84 @@
+/**
+ ******************************************************************************
+ * @file OpenPDMFilter.h
+ * @author CL
+ * @version V1.0.0
+ * @date 9-September-2015
+ * @brief Header file for Open PDM audio software decoding Library.
+ * This Library is used to decode and reconstruct the audio signal
+ * produced by ST MEMS microphone (MP45Dxxx, MP34Dxxx).
+ ******************************************************************************
+ * @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 __OPENPDMFILTER_H
+#define __OPENPDMFILTER_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+
+/* Includes ------------------------------------------------------------------*/
+
+#include <stdint.h>
+
+
+/* Definitions ---------------------------------------------------------------*/
+
+#define HTONS(A) ((((uint16_t)(A) & 0xff00) >> 8) | \
+ (((uint16_t)(A) & 0x00ff) << 8))
+
+
+/* Types ---------------------------------------------------------------------*/
+
+typedef struct {
+ /* Public */
+ uint16_t Fs;
+ float LP_HZ;
+ float HP_HZ;
+ uint16_t In_MicChannels;
+ uint16_t Out_MicChannels;
+ uint16_t Decimation;
+ uint16_t SincN;
+ /* Private */
+ uint32_t Coef[5];
+ uint16_t FilterLen;
+ int64_t OldOut, OldIn, OldZ;
+ uint16_t LP_ALFA;
+ uint16_t HP_ALFA;
+ uint16_t bit[5];
+ uint16_t byte;
+} TPDMFilter_InitStruct;
+
+
+/* Exported functions ------------------------------------------------------- */
+
+void Open_PDM_Filter_Init(TPDMFilter_InitStruct *init_struct);
+void Open_PDM_Filter(uint8_t* data, uint16_t* data_out, uint16_t mic_gain, TPDMFilter_InitStruct *init_struct);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // __OPENPDMFILTER_H
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- a/Middlewares/PDM2PCM/pdm_filter.h Fri Apr 21 10:31:01 2017 +0200
+++ b/Middlewares/PDM2PCM/pdm_filter.h Fri Apr 21 10:33:08 2017 +0200
@@ -34,9 +34,10 @@
#define __PDM_FILTER_H
#ifdef __cplusplus
- extern "C" {
+ extern "C" {
#endif
+
/* Includes ------------------------------------------------------------------*/
#include <stdint.h>
@@ -58,7 +59,6 @@
/* 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);
--- a/ST_I2S.lib Fri Apr 21 10:31:01 2017 +0200 +++ b/ST_I2S.lib Fri Apr 21 10:33:08 2017 +0200 @@ -1,1 +1,1 @@ -https://developer.mbed.org/teams/ST/code/ST_I2S/#6ebde375d2d1 +https://Davidroid@developer.mbed.org/teams/ST/code/ST_I2S/#c2fc3330d0df

X-NUCLEO-CCA02M1 Digital MEMS Microphones Expansion Board.