Quentin Roche / X_NUCLEO_CCA02M1

Dependencies:   ST_FREQUENCY_DIVIDER ST_I2S USBDEVICE

Fork of X_NUCLEO_CCA02M1 by ST

Files at this revision

API Documentation at this revision

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

BSP/PDM2PCMAudio.cpp Show annotated file Show diff for this revision Revisions of this file
BSP/PDM2PCMAudio.h Show annotated file Show diff for this revision Revisions of this file
BSP/PDM2PCMAudio_class.cpp Show diff for this revision Revisions of this file
BSP/PDM2PCMAudio_class.h Show diff for this revision Revisions of this file
BSP/XNucleoCCA02M1.cpp Show annotated file Show diff for this revision Revisions of this file
BSP/XNucleoCCA02M1.h Show annotated file Show diff for this revision Revisions of this file
BSP/divisor.c Show diff for this revision Revisions of this file
BSP/divisor.h Show diff for this revision Revisions of this file
BSP/x_nucleo_cca02m1_class.cpp Show diff for this revision Revisions of this file
BSP/x_nucleo_cca02m1_class.h Show diff for this revision Revisions of this file
Common/component.h Show diff for this revision Revisions of this file
Common/component_def.h Show annotated file Show diff for this revision Revisions of this file
Middlewares/OpenPDM2PCM/OpenPDMFilter.c Show annotated file Show diff for this revision Revisions of this file
Middlewares/OpenPDM2PCM/OpenPDMFilter.h Show annotated file Show diff for this revision Revisions of this file
Middlewares/PDM2PCM/pdm_filter.h Show annotated file Show diff for this revision Revisions of this file
ST_I2S.lib Show annotated file Show diff for this revision Revisions of this file
--- /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>&copy; 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>&copy; 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>&copy; 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>&copy; 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>&copy; 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>&copy; 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>&copy; 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>&copy; 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>&copy; 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>&copy; 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>&copy; 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>&copy; 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>&copy; 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>&copy; 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