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.

BSP/XNucleoCCA02M1.h

Committer:
davide.aliprandi@st.com
Date:
2017-04-21
Revision:
2:9f389fd8fb2e
Child:
16:4ab2eac7be21

File content as of revision 2:9f389fd8fb2e:

/**
 ******************************************************************************
 * @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****/