#########################################
AN00247: Using lib_xua with lib_mic_array
#########################################

********
Overview
********

The XMOS USB Audio (XUA) library provides an implementation of USB Audio Class versions 1.0 and 2.0.

This application note demonstrates the implementation of a basic USB Audio Device with
record functionality from PDM microphones on the `XK-EVK-XU316 <https://www.xmos.com/xk-evk-xu316>`_ board.

Core PDM microphone functionality is contained in` ``lib_mic_array``. This library includes both the physical
interfacing to the PDM microphones as well as efficient decimation to user configurable output
sample rates - essentially providing PDM to PCM conversion.

To reduce complexity this application note does not enable any other audio interfaces other than recording
from PDM microphones (i.e. no I2S but the on board DAC is configured to play out the mic signals).

Readers are encouraged to read application note AN00246 in conjunction with this application note.

**********************************
lib_xua with lib_mic_array example
**********************************

The CMakeLists.txt file
=======================

To start using ``lib_xua``, you need to add ``lib_xua`` to the dependent module list in the CMakeLists.txt
file. This application note also uses ``lib_mic_array``, so this must also be added to the list::

  set(APP_DEPENDENT_MODULES "lib_xua"
                            "lib_mic_array")

The dependencies for this example are specified by ``deps.cmake`` in the ``examples`` directory
and are included in the application ``CMakeLists.txt`` file.

The ``lib_xud`` library requires some flags for correct operation. Namely the
tile on which ``lib_xud`` will be executed, for example::

  set(APP_COMPILER_FLAGS = .. -DUSB_TILE=tile[0] ..)

Includes
========

This application requires the system header files that contains XMOS xCORE specific
defines for declaring and initialising hardware:

.. literalinclude:: ../../src/app_xua_pdm_mics.xc
   :start-at: include <xs1.h>
   :end-at: #include <string.h>

The XUA and XUD library functions are defined in header files ``xua.h`` and ``xud_device.h`` respectively. These headers must
be included in the code in order to use these libraries.

.. literalinclude:: ../../src/app_xua_pdm_mics.xc
   :start-at: include "xua.h"
   :end-at: include "xud_device.h"

The application uses hardware setup from ``lib_board_support``. This header
must be included in the code.

.. literalinclude:: ../../src/app_xua_pdm_mics.xc
   :start-at: #include "xk_evk_xu316/board.h"
   :end-at: #include "xk_evk_xu316/board.h"


Declarations
============

Allocating hardware resources for lib_xua
-----------------------------------------

This implementation of a USB Audio device using ``lib_xua`` requires the following I/O pins:

    - Audio Master clock (generated by the xCORE)
    - Bit clock (generated by the xCORE)
    - Word clock (generated by the xCORE)
    - I2S data output pin (generated by the xCORE)

On an xCORE the pins are controlled by ``ports``. The application therefore declares a
port for the master clock input signal.

.. literalinclude:: ../../src/app_xua_pdm_mics.xc
   :start-at: /* Port declarations.
   :end-at: in port p_mclk_in

``lib_xua`` also requires two ports for internally calculating USB feedback. Please refer to
the ``lib_xua`` library documentation for further details.  In this example ``XUA_Buffer()`` and ``XUA_AudioHub()``
reside on the same tile and can therefore make use of the same master-clock port.

These ports are declared as follows:

.. literalinclude:: ../../src/app_xua_pdm_mics.xc
   :start-at: /* Resources for USB feedback
   :end-at: in port p_mclk_in_usb

In addition to ``port`` resources a single clock-block resource is also required:

.. literalinclude:: ../../src/app_xua_pdm_mics.xc
   :start-at: /* Clock-block declarations
   :end-at: clock clk_audio_mclk_usb


Allocating hardware resources for lib_mic_array
-----------------------------------------------

``lib_mic_array`` requires a single 1-bit port for PDM data from two microphones. Each microphone is configured
to produce a PDM sample on an opposite clock edge from the other. This means the the data is effectively double
data rate (DDR) with respect to the PDM clock.

The microphones must be clocked by a clock synchronous to the audio application clock - typically 3.072MHz for 16, 32 or 48 kHz.

These ports, along with other ``mic_array`` required resources must be declared in ``xua_conf.h``:

.. literalinclude:: ../../src/xua_conf.h
   :start-at: #define XUA_NUM_PDM_MICS
   :end-at: #define MIC_ARRAY_CONFIG_CLOCK_BLOCK_B


The ``XK-EVK-XU316`` Board expects the xCORE to divide down the audio master clock (24.576MHz)
and output the result to the microphones. This is done internally by ``lib_mic_array`` from the definitions
``MIC_ARRAY_CONFIG_MCLK_FREQ`` and ``MIC_ARRAY_CONFIG_PDM_FREQ`` which are left as defaults in ``mic_array_conf.h`` to
generate the nominal 3.072 MHz PDM clock.

Please see the ``lib_mic_array`` library documentation for full details.


Other declarations
------------------

``lib_xua`` currently requires the manual declaration of tables for the endpoint types for
``lib_xud`` and the calling the main XUD function in a par (``XUD_Main()``).

For a simple application the following endpoints are required:

    - ``Control`` endpoint zero
    - ``Isochonous`` endpoint for each direction for audio data to/from the USB host

These are declared as follows:

.. literalinclude:: ../../src/app_xua_pdm_mics.xc
   :start-at: /* Endpoint type tables
   :end-at: XUD_EpType epTypeTableOut

Configuring lib_xua
===================

``lib_xua`` must be configured to enable support for PDM microphones.

``lib_xua`` has many parameters than can be configured at build time, some examples include:

    - Supported sample-rates (Note ``lib_mic_array`` does not currently support sample rate change after initialisation)
    - Channel counts
    - Audio Class version
    - Product/Vendor IDs
    - Various product strings
    - Master clock frequency

To enable PDM microphone support  ``XUA_NUM_PDM_MICS`` must be set to a non-zero value.  Setting this will cause the ``XUA_AudioHub``
task to forward sample rate information and receive samples from the relevant microphone related tasks.

These parameters are set via defines in the ``xua_conf.h`` header file. For this simple application the
complete contents of this file are as follows:

.. literalinclude:: ../../src/xua_conf.h
   :start-at: // Copyright
   :end-at: #endif

You can try changing ``XUA_PDM_MIC_FREQ`` to 32000 or 16000 to reconfigure the system to lower sample rates than the default 48 kHz.

The application main() function
===============================

The ``main()`` function sets up and runs the tasks in the application.

Channel declarations
--------------------

Various channels are required in order to allow the required tasks to communicate.
These must first be declared:

.. literalinclude:: ../../src/app_xua_pdm_mics.xc
   :start-at: /* Channels for lib_xud
   :end-at: chan c_mic_pcm

Standard ``lib_xua`` tasks
--------------------------

The rest of the ``main()`` function starts all of the tasks in parallel
using the xC ``par`` construct.

.. literalinclude:: ../../src/app_xua_pdm_mics.xc
   :start-at: par
   :end-before: /* par */


Firstly the standard ``lib_xua`` USB side tasks are run on tile 0. This code starts the low-level USB task and an Endpoint 0 task. The Audio buffering task and a task to handle
the audio I/O (``XUA_AudioHub``) is started on tile 1 where the I2S bus exists.

Microphone task
---------------

The microphone task ``mic_array_task`` spawns a single thread which handles PDM receive on the ports and the decimation filters to produce PCM.
This is placed on tile 1 where the microphone hardware is connected.
It connects directly to ``XUA_AudioHub`` and provides samples which are at the same rate as the audio I/O.


|newpage|

Demo Hardware Setup
===================

To run the demo, connect a USB cable to power the ``XK-EVK-XU316`` board, ensure the pair of PDM microphones are connected via the ribbon cables and
and plug the xTAG to the board and connect the xTAG USB cable to your development machine.

.. figure:: images/hw_setup.*
   :width: 80%

   Hardware setup

|newpage|

Building the Application
========================

The following section assumes you have downloaded and installed the `XMOS XTC tools <https://www.xmos.com/software-tools/>`_
(see `README` for required version). Installation instructions can be found `here <https://xmos.com/xtc-install-guide>`_.
Be sure to pay attention to the section `Installation of required third-party tools
<https://www.xmos.com/documentation/XM-014363-PC-10/html/installation/install-configure/install-tools/install_prerequisites.html>`_.

The application uses the `xcommon-cmake <https://www.xmos.com/file/xcommon-cmake-documentation/?version=latest>`_
build system as bundled with the XTC tools.

The ``AN00248_xua_example_pdm_mics`` software zip-file should be downloaded and unzipped to a chosen directory.


To configure the build run the following from an XTC command prompt::

    cd examples
    cd AN00248_xua_example_pdm_mics
    cmake -G "Unix Makefiles" -B build

All required dependencies are included in the software download, however, if any are missing it is
at this configure step that they will be downloaded by the build system.

Finally, the application binaries can be built using ``xmake``::

    xmake -j -C build

The application uses approximately 49 kB on tile 0 and 17 kB on tile 1 (of 512 kB on each).

Launching the demo application
==============================

To run the application return to the ``/examples/AN00248_xua_example_pdm_mics`` directory and run the following command::

    xrun bin/app_xua_pdm_mics.xe

You should now see an audio device called ``XUA PDM Example`` and be able hear the stereo microphone audio
by recording the stream on the host or connecting to the analog output jacks.

|newpage|

***************
Further Reading
***************

   * XMOS XTC Tools Installation Guide

     https://xmos.com/xtc-install-guide

      * XMOS XTC Tools User Guide

        https://www.xmos.com/view/Tools-15-Documentation

      * XMOS application build and dependency management system; xcommon-cmake

        https://www.xmos.com/file/xcommon-cmake-documentation/?version=latest

