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.

Committer:
davide.aliprandi@st.com
Date:
Tue Feb 28 11:20:53 2017 +0100
Revision:
0:d5552d432108
Library to handle the X-NUCLEO-CCA02M1 MEMS Microphones Expansion Board.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
davide.aliprandi@st.com 0:d5552d432108 1 /**
davide.aliprandi@st.com 0:d5552d432108 2 ******************************************************************************
davide.aliprandi@st.com 0:d5552d432108 3 * @file PDM2PCMAudio_class.cpp
davide.aliprandi@st.com 0:d5552d432108 4 * @author AST / Software Platforms and Cloud
davide.aliprandi@st.com 0:d5552d432108 5 * @version V1.0
davide.aliprandi@st.com 0:d5552d432108 6 * @date November 10th, 2016
davide.aliprandi@st.com 0:d5552d432108 7 * @brief Implementation file for the PDM2PCMAudio conversion library.
davide.aliprandi@st.com 0:d5552d432108 8 ******************************************************************************
davide.aliprandi@st.com 0:d5552d432108 9 * @attention
davide.aliprandi@st.com 0:d5552d432108 10 *
davide.aliprandi@st.com 0:d5552d432108 11 * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
davide.aliprandi@st.com 0:d5552d432108 12 *
davide.aliprandi@st.com 0:d5552d432108 13 * Redistribution and use in source and binary forms, with or without modification,
davide.aliprandi@st.com 0:d5552d432108 14 * are permitted provided that the following conditions are met:
davide.aliprandi@st.com 0:d5552d432108 15 * 1. Redistributions of source code must retain the above copyright notice,
davide.aliprandi@st.com 0:d5552d432108 16 * this list of conditions and the following disclaimer.
davide.aliprandi@st.com 0:d5552d432108 17 * 2. Redistributions in binary form must reproduce the above copyright notice,
davide.aliprandi@st.com 0:d5552d432108 18 * this list of conditions and the following disclaimer in the documentation
davide.aliprandi@st.com 0:d5552d432108 19 * and/or other materials provided with the distribution.
davide.aliprandi@st.com 0:d5552d432108 20 * 3. Neither the name of STMicroelectronics nor the names of its contributors
davide.aliprandi@st.com 0:d5552d432108 21 * may be used to endorse or promote products derived from this software
davide.aliprandi@st.com 0:d5552d432108 22 * without specific prior written permission.
davide.aliprandi@st.com 0:d5552d432108 23 *
davide.aliprandi@st.com 0:d5552d432108 24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
davide.aliprandi@st.com 0:d5552d432108 25 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
davide.aliprandi@st.com 0:d5552d432108 26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
davide.aliprandi@st.com 0:d5552d432108 27 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
davide.aliprandi@st.com 0:d5552d432108 28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
davide.aliprandi@st.com 0:d5552d432108 29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
davide.aliprandi@st.com 0:d5552d432108 30 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
davide.aliprandi@st.com 0:d5552d432108 31 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
davide.aliprandi@st.com 0:d5552d432108 32 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
davide.aliprandi@st.com 0:d5552d432108 33 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
davide.aliprandi@st.com 0:d5552d432108 34 *
davide.aliprandi@st.com 0:d5552d432108 35 ******************************************************************************
davide.aliprandi@st.com 0:d5552d432108 36 */
davide.aliprandi@st.com 0:d5552d432108 37
davide.aliprandi@st.com 0:d5552d432108 38
davide.aliprandi@st.com 0:d5552d432108 39 /* Includes ------------------------------------------------------------------*/
davide.aliprandi@st.com 0:d5552d432108 40
davide.aliprandi@st.com 0:d5552d432108 41 #include "PDM2PCMAudio_class.h"
davide.aliprandi@st.com 0:d5552d432108 42
davide.aliprandi@st.com 0:d5552d432108 43
davide.aliprandi@st.com 0:d5552d432108 44 /* Variables -----------------------------------------------------------------*/
davide.aliprandi@st.com 0:d5552d432108 45
davide.aliprandi@st.com 0:d5552d432108 46 /* Demux filter. */
davide.aliprandi@st.com 0:d5552d432108 47 const uint8_t PDM2PCMAudio::_demux_filter[DEMUX_FILTER_SIZE] =
davide.aliprandi@st.com 0:d5552d432108 48 {
davide.aliprandi@st.com 0:d5552d432108 49 0x00, 0x01, 0x00, 0x01, 0x02, 0x03, 0x02, 0x03,
davide.aliprandi@st.com 0:d5552d432108 50 0x00, 0x01, 0x00, 0x01, 0x02, 0x03, 0x02, 0x03,
davide.aliprandi@st.com 0:d5552d432108 51 0x04, 0x05, 0x04, 0x05, 0x06, 0x07, 0x06, 0x07,
davide.aliprandi@st.com 0:d5552d432108 52 0x04, 0x05, 0x04, 0x05, 0x06, 0x07, 0x06, 0x07,
davide.aliprandi@st.com 0:d5552d432108 53 0x00, 0x01, 0x00, 0x01, 0x02, 0x03, 0x02, 0x03,
davide.aliprandi@st.com 0:d5552d432108 54 0x00, 0x01, 0x00, 0x01, 0x02, 0x03, 0x02, 0x03,
davide.aliprandi@st.com 0:d5552d432108 55 0x04, 0x05, 0x04, 0x05, 0x06, 0x07, 0x06, 0x07,
davide.aliprandi@st.com 0:d5552d432108 56 0x04, 0x05, 0x04, 0x05, 0x06, 0x07, 0x06, 0x07,
davide.aliprandi@st.com 0:d5552d432108 57 0x08, 0x09, 0x08, 0x09, 0x0a, 0x0b, 0x0a, 0x0b,
davide.aliprandi@st.com 0:d5552d432108 58 0x08, 0x09, 0x08, 0x09, 0x0a, 0x0b, 0x0a, 0x0b,
davide.aliprandi@st.com 0:d5552d432108 59 0x0c, 0x0d, 0x0c, 0x0d, 0x0e, 0x0f, 0x0e, 0x0f,
davide.aliprandi@st.com 0:d5552d432108 60 0x0c, 0x0d, 0x0c, 0x0d, 0x0e, 0x0f, 0x0e, 0x0f,
davide.aliprandi@st.com 0:d5552d432108 61 0x08, 0x09, 0x08, 0x09, 0x0a, 0x0b, 0x0a, 0x0b,
davide.aliprandi@st.com 0:d5552d432108 62 0x08, 0x09, 0x08, 0x09, 0x0a, 0x0b, 0x0a, 0x0b,
davide.aliprandi@st.com 0:d5552d432108 63 0x0c, 0x0d, 0x0c, 0x0d, 0x0e, 0x0f, 0x0e, 0x0f,
davide.aliprandi@st.com 0:d5552d432108 64 0x0c, 0x0d, 0x0c, 0x0d, 0x0e, 0x0f, 0x0e, 0x0f
davide.aliprandi@st.com 0:d5552d432108 65 };
davide.aliprandi@st.com 0:d5552d432108 66
davide.aliprandi@st.com 0:d5552d432108 67
davide.aliprandi@st.com 0:d5552d432108 68 /* Methods -------------------------------------------------------------------*/
davide.aliprandi@st.com 0:d5552d432108 69
davide.aliprandi@st.com 0:d5552d432108 70 /**
davide.aliprandi@st.com 0:d5552d432108 71 * @brief Converting audio data from PDM to PCM.
davide.aliprandi@st.com 0:d5552d432108 72 * @param output_buffer Pointer to output PCM buffer data.
davide.aliprandi@st.com 0:d5552d432108 73 * @param input_buffer Pointer to input PDM buffer data.
davide.aliprandi@st.com 0:d5552d432108 74 * @param volume Volume level (it must be in the range [0..64]).
davide.aliprandi@st.com 0:d5552d432108 75 * @param decimation_factor Decimation factor (it must be either 64 or 128).
davide.aliprandi@st.com 0:d5552d432108 76 * @retval COMPONENT_OK in case of success, COMPONENT_ERROR otherwise.
davide.aliprandi@st.com 0:d5552d432108 77 */
davide.aliprandi@st.com 0:d5552d432108 78 Status_t PDM2PCMAudio::Convert(int16_t *output_buffer, uint16_t *input_buffer, uint32_t volume, uint32_t decimation_factor)
davide.aliprandi@st.com 0:d5552d432108 79 {
davide.aliprandi@st.com 0:d5552d432108 80 if (!(volume <= PDM2PCM_MAX_VOLUME))
davide.aliprandi@st.com 0:d5552d432108 81 error("Volume level not supported: it must be in the range [0..64].\r\n");
davide.aliprandi@st.com 0:d5552d432108 82
davide.aliprandi@st.com 0:d5552d432108 83 switch (decimation_factor)
davide.aliprandi@st.com 0:d5552d432108 84 {
davide.aliprandi@st.com 0:d5552d432108 85 case 64:
davide.aliprandi@st.com 0:d5552d432108 86 for (uint32_t index = 0; index < _channels; index++)
davide.aliprandi@st.com 0:d5552d432108 87 PDM_Filter_64_LSB(&((uint8_t *) input_buffer)[index], (uint16_t *) &(output_buffer[index]), volume, (PDMFilter_InitStruct *) &_PDM2PCM_filter[index]);
davide.aliprandi@st.com 0:d5552d432108 88 break;
davide.aliprandi@st.com 0:d5552d432108 89
davide.aliprandi@st.com 0:d5552d432108 90 case 128:
davide.aliprandi@st.com 0:d5552d432108 91 for (uint32_t index = 0; index < _channels; index++)
davide.aliprandi@st.com 0:d5552d432108 92 PDM_Filter_128_LSB(&((uint8_t *) input_buffer)[index], (uint16_t *) &(output_buffer[index]), volume, (PDMFilter_InitStruct *) &_PDM2PCM_filter[index]);
davide.aliprandi@st.com 0:d5552d432108 93 break;
davide.aliprandi@st.com 0:d5552d432108 94
davide.aliprandi@st.com 0:d5552d432108 95 default:
davide.aliprandi@st.com 0:d5552d432108 96 error("Decimation factor not supported: it must be either 64 or 128.\r\n");
davide.aliprandi@st.com 0:d5552d432108 97 }
davide.aliprandi@st.com 0:d5552d432108 98
davide.aliprandi@st.com 0:d5552d432108 99 return COMPONENT_OK;
davide.aliprandi@st.com 0:d5552d432108 100 }
davide.aliprandi@st.com 0:d5552d432108 101
davide.aliprandi@st.com 0:d5552d432108 102 /**
davide.aliprandi@st.com 0:d5552d432108 103 * @brief Scrambling audio data.
davide.aliprandi@st.com 0:d5552d432108 104 * @param output_buffer Pointer to output PDM buffer data.
davide.aliprandi@st.com 0:d5552d432108 105 * @param input_buffer Pointer to input PDM buffer data.
davide.aliprandi@st.com 0:d5552d432108 106 * @param size Size of the buffers (thay has to be equally sized).
davide.aliprandi@st.com 0:d5552d432108 107 * @retval COMPONENT_OK in case of success, COMPONENT_ERROR otherwise.
davide.aliprandi@st.com 0:d5552d432108 108 */
davide.aliprandi@st.com 0:d5552d432108 109 Status_t PDM2PCMAudio::Scramble(uint16_t *output_buffer, uint16_t *input_buffer, uint32_t size)
davide.aliprandi@st.com 0:d5552d432108 110 {
davide.aliprandi@st.com 0:d5552d432108 111 for (uint32_t index = 0; index < size; index++)
davide.aliprandi@st.com 0:d5552d432108 112 output_buffer[index] = HTONS(input_buffer[index]);
davide.aliprandi@st.com 0:d5552d432108 113
davide.aliprandi@st.com 0:d5552d432108 114 return COMPONENT_OK;
davide.aliprandi@st.com 0:d5552d432108 115 }
davide.aliprandi@st.com 0:d5552d432108 116
davide.aliprandi@st.com 0:d5552d432108 117 /**s
davide.aliprandi@st.com 0:d5552d432108 118 * @brief Demuxing audio data.
davide.aliprandi@st.com 0:d5552d432108 119 * @param output_buffer Pointer to output PDM buffer data.
davide.aliprandi@st.com 0:d5552d432108 120 * @param input_buffer Pointer to input PDM buffer data.
davide.aliprandi@st.com 0:d5552d432108 121 * @param size Size of the buffers (thay has to be equally sized).
davide.aliprandi@st.com 0:d5552d432108 122 * @retval COMPONENT_OK in case of success, COMPONENT_ERROR otherwise.
davide.aliprandi@st.com 0:d5552d432108 123 */
davide.aliprandi@st.com 0:d5552d432108 124 Status_t PDM2PCMAudio::Demux(uint16_t *output_buffer, uint16_t *input_buffer, uint32_t size)
davide.aliprandi@st.com 0:d5552d432108 125 {
davide.aliprandi@st.com 0:d5552d432108 126 for (uint32_t index = 0; index < size; index++)
davide.aliprandi@st.com 0:d5552d432108 127 {
davide.aliprandi@st.com 0:d5552d432108 128 uint8_t a = ((uint8_t *) input_buffer)[index * 2];
davide.aliprandi@st.com 0:d5552d432108 129 uint8_t b = ((uint8_t *) input_buffer)[index * 2 + 1];
davide.aliprandi@st.com 0:d5552d432108 130 ((uint8_t *) (output_buffer))[index * 2] = _demux_filter[a & DEMUX_FILTER_MASK] | _demux_filter[b & DEMUX_FILTER_MASK] << 4;
davide.aliprandi@st.com 0:d5552d432108 131 ((uint8_t *) (output_buffer))[index * 2 + 1] = _demux_filter[(a >> 1) & DEMUX_FILTER_MASK] | _demux_filter[(b >> 1) & DEMUX_FILTER_MASK] << 4;
davide.aliprandi@st.com 0:d5552d432108 132 }
davide.aliprandi@st.com 0:d5552d432108 133
davide.aliprandi@st.com 0:d5552d432108 134 return COMPONENT_OK;
davide.aliprandi@st.com 0:d5552d432108 135 }
davide.aliprandi@st.com 0:d5552d432108 136
davide.aliprandi@st.com 0:d5552d432108 137 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/