Library to handle the X-NUCLEO-CCA02M1 MEMS Microphones Expansion Board.

Dependencies:   ST_I2S ST_FREQUENCY_DIVIDER USBDEVICE

Dependents:   HelloWorld_CCA02M1 HelloWorld_CCA02M1_mbedOS HelloWorld_CCA02M1 Karaoke_CCA01M1_CCA02M1_mbedOS

Fork of X_NUCLEO_CCA02M1 by ST Expansion SW Team

MEMS Microphones Library

Library to handle the X-NUCLEO-CCA02M1 MEMS Microphones Expansion Board. A single board allows to record a standard 2-channel stereo signal as an array of PCM samples (16 bit/sample); in principle, it could make use of six additional MEMS microphones to realize a 8-channel audio system.


Microphones configuration

Currently the configurations supported are the following:

  • Stereo@48KHz
  • Stereo@44.1KHz (CD audio quality)
  • Stereo@32KHz
  • Stereo@16KHz
  • Stereo@8KHz
  • Mono@48KHz
  • Mono@44.1KHz
  • Mono@32KHz
  • Mono@16KHz
  • Mono@8KHz

Mono configurations need a Jumper connecting PB_5 and PB_13 on the Morpho connector to properly work.


Platform compatibility

  • This board can be currently used with the Nucleo F4 Family only, please see the ST_I2S library compatibility for further information.
  • The library is compatible both with mbed OS 5.x and mbed classic 2.x (to work with mbed classic, the main application has to import the "events" library, which is not included into the "mbed" library).


I2S Peripheral Usage

By default this board makes use of the I2S peripheral available on Nucleo boards.


Acquiring through the USB

In order to acquire the recorded PCM audio channel with an audio SW on a PC, please connect the expansion board to a USB port of the PC, and the Nucleo board to a USB power supply.

Revision:
20:9952bef19da1
Parent:
19:1a061e306cc9
--- a/BSP/XNucleoCCA02M1.cpp	Thu May 04 10:39:39 2017 +0000
+++ b/BSP/XNucleoCCA02M1.cpp	Fri May 05 11:34:10 2017 +0000
@@ -67,7 +67,6 @@
 * @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.
-* @note   Currently only two channels at 16KHz are supported.
 */
 status_t XNucleoCCA02M1::init(void *init)
 {
@@ -80,7 +79,9 @@
 
 #ifdef USE_OPEN_PDM2PCM_LIBRARY
     /* Checking input parameters. */
-    if (!(((_frequency == 16000) && (_channels == 1)) ||
+    if (!(((_frequency ==  8000) && (_channels == 1)) ||
+          ((_frequency ==  8000) && (_channels == 2)) ||
+          ((_frequency == 16000) && (_channels == 1)) ||
           ((_frequency == 16000) && (_channels == 2)) ||
           ((_frequency == 32000) && (_channels == 1)) ||
           ((_frequency == 32000) && (_channels == 2)) ||
@@ -88,36 +89,9 @@
           ((_frequency == 44100) && (_channels == 2)) ||
           ((_frequency == 48000) && (_channels == 1)) ||
           ((_frequency == 48000) && (_channels == 2))))
-        error("\r\nError: please set one of the following configurations: mono/stereo 16/32/44.1/48 KHz.\n\r");
+        error("\r\nError: please set one of the following configurations: mono/stereo @ 8/16/32/44.1/48 KHz.\r\n");
 #endif
 
-	/* 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.
      * Note: put a jumper to connect PB_5 and PB_13 on the MORPHO connector when
@@ -139,6 +113,18 @@
     dev_i2s.protocol(MSB);
     dev_i2s.format(_channels == 1 ? 16 : 32, _channels == 1 ? 16 : 32, 1);
 
+    /* Buffer sizes in 16-bits samples. */
+    _PCM_samples_one_ms = ((_frequency * _channels) / 1000);
+    _PDM_samples_one_ms = _pdm2pcm->pcm2pdm_samples(_PCM_samples_one_ms);
+    _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));
+
     return COMPONENT_OK;
 }
 
@@ -277,7 +263,7 @@
 		_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);
+	    _pdm2pcm->convert(&_PCM_buffer_n_ms[_PCM_buffer_write_index], _PDM_buffer_one_ms, _volume);
 
         /* Copying PCM data to the user buffer. */
         if (_callback_attached)