398 lines
12 KiB
ReStructuredText
398 lines
12 KiB
ReStructuredText
.. _wm8960:
|
|
|
|
:mod:`WM8960` -- Driver for the WM8960 codec
|
|
============================================
|
|
|
|
This driver is used to control a WM8960 codec chip. It is a Python
|
|
translation of the C-Code provided by NXP/Freescale for their i.MX RT series of
|
|
MCUs. Very little has been added, and just a few API related names were changed
|
|
or added to cope with the naming style of MicroPython.
|
|
|
|
The primary purpose of the driver is initialization and setting operation modes
|
|
of the codec. It does not do the audio data processing for the codec. That is
|
|
the task of a separate driver.
|
|
|
|
The WM8960 supports an I2C interface, in addition to the audio interface. The
|
|
connection depends on the interface used and the number of devices in the
|
|
system. For the I2C interface, SCL and SDA have to be connected, and of course
|
|
GND and Vcc. The I2C default address is ``0x1A``.
|
|
|
|
Constructor
|
|
-----------
|
|
|
|
.. class:: WM8960(i2c, sample_rate, *, bits=16, swap=SWAP_NONE, route=ROUTE_PLAYBACK_RECORD, left_input=INPUT_MIC3, right_input=INPUT_MIC2, sysclk_source=SYSCLK_MCLK, mclk_freq=None, primary=False, adc_sync=SYNC_DAC, protocol=BUS_I2S, i2c_address=WM8960_I2C_ADDR)
|
|
|
|
Create a WM8960 driver object, initialize the device with default settings and return the
|
|
WM8960 object.
|
|
|
|
Only the first two arguments are mandatory. All others are optional. The arguments are:
|
|
|
|
- *i2c* is the I2C bus object.
|
|
- *sample_rate* is the audio sample rate. Acceptable values are 8000,
|
|
11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000, 96000, 192000
|
|
and 384000. Note that not every I2S hardware will support all values.
|
|
- *bits* is the number of bits per audio word. Acceptable value are 16,
|
|
20, 24, and 32.
|
|
- *swap* swaps the left & right channel, if set; see below for options.
|
|
- *route* Setting the audio path in the codec; see below for options.
|
|
- *left_input* sets the audio source for the left input channel;
|
|
see below for options.
|
|
- *right_input* sets the audio source for the right input channel;
|
|
see below for options.
|
|
- *play_source* sets the audio target for the output audio;
|
|
see below for options.
|
|
- *sysclk_source* controls whether the internal master clock called
|
|
"sysclk" is directly taken from the MCLK input or derived from it
|
|
using an internal PLL. It is usually not required to change this.
|
|
- *mclk_freq* sets the mclk frequency applied to the MCLK pin of the
|
|
codec. If not set, default values are used.
|
|
- *primary* lets the WM8960 act as primary or secondary device. The
|
|
default setting is ``False``. When set to ``False``,
|
|
*sample_rate* and *bits* are controlled by the MCU.
|
|
- *adc_sync* sets which input is used for the ADC sync signal.
|
|
The default is using the DACLRC pin.
|
|
- *protocol* sets the communication protocol. The default is I2S.
|
|
See below for all options.
|
|
- *i2c_address* sets the I2C address of the WM8960, with default ``0x1A``.
|
|
|
|
If *mclk_freq* is not set the following default values are used:
|
|
|
|
- sysclk_source == SYSCLK_PLL: 11.2896 MHz for sample rates of 44100,
|
|
22050 and 11015 Hz, and 12.288 Mhz for sample rates < 48000, otherwise
|
|
sample_rate * 256.
|
|
- sysclk_source == SYSCLK_MCLK: sample_rate * 256.
|
|
|
|
If the MCLK signal is applied using, for example,. a separate oscillator,
|
|
it must be specified for proper operation.
|
|
|
|
Tables of parameter constants
|
|
-----------------------------
|
|
|
|
.. table:: **Swap Parameter**
|
|
:widths: auto
|
|
:align: left
|
|
|
|
===== ====
|
|
Value Name
|
|
===== ====
|
|
0 SWAP_NONE
|
|
1 SWAP_INPUT
|
|
2 SWAP_OUTPUT
|
|
===== ====
|
|
|
|
.. table:: **Protocol Parameter**
|
|
:widths: auto
|
|
:align: left
|
|
|
|
===== ====
|
|
Value Name
|
|
===== ====
|
|
2 BUS_I2S
|
|
1 BUS_LEFT_JUSTIFIED
|
|
0 BUS_RIGHT_JUSTIFIED
|
|
3 BUS_PCMA
|
|
19 BUS_PCMB
|
|
===== ====
|
|
|
|
.. table:: **Input Source Parameter**
|
|
:widths: auto
|
|
:align: left
|
|
|
|
===== ============ ====
|
|
Value Name Type
|
|
===== ============ ====
|
|
0 INPUT_CLOSED
|
|
1 INPUT_MIC1 Single ended
|
|
2 INPUT_MIC2 Differential
|
|
3 INPUT_MIC3 Differential
|
|
4 INPUT_LINE2
|
|
5 INPUT_LINE3
|
|
===== ============ ====
|
|
|
|
.. table:: **Route Parameter**
|
|
:widths: auto
|
|
:align: left
|
|
|
|
===== ====
|
|
Value Name
|
|
===== ====
|
|
0 ROUTE_BYPASS
|
|
1 ROUTE_PLAYBACK
|
|
2 ROUTE_PLAYBACK_RECORD
|
|
5 ROUTE_RECORD
|
|
===== ====
|
|
|
|
.. table:: **Master Clock Source Parameter**
|
|
:widths: auto
|
|
:align: left
|
|
|
|
===== ====
|
|
Value Name
|
|
===== ====
|
|
0 SYSCLK_MCLK
|
|
1 SYSCLK_PLL
|
|
===== ====
|
|
|
|
.. table:: **Module Names**
|
|
:widths: auto
|
|
:align: left
|
|
|
|
===== ====
|
|
Value Name
|
|
===== ====
|
|
0 MODULE_ADC
|
|
1 MODULE_DAC
|
|
2 MODULE_VREF
|
|
3 MODULE_HEADPHONE
|
|
4 MODULE_MIC_BIAS
|
|
5 MODULE_MIC
|
|
6 MODULE_LINE_IN
|
|
7 MODULE_LINE_OUT
|
|
8 MODULE_SPEAKER
|
|
9 MODULE_OMIX
|
|
10 MODULE_MONO_OUT
|
|
===== ====
|
|
|
|
.. table:: **Play Channel Names**
|
|
:widths: auto
|
|
:align: left
|
|
|
|
===== ====
|
|
Value Name
|
|
===== ====
|
|
1 PLAY_HEADPHONE_LEFT
|
|
2 PLAY_HEADPHONE_RIGHT
|
|
4 PLAY_SPEAKER_LEFT
|
|
8 PLAY_SPEAKER_RIGHT
|
|
===== ====
|
|
|
|
.. table:: **adc_sync Parameters**
|
|
:widths: auto
|
|
:align: left
|
|
|
|
===== ====
|
|
Value Name
|
|
===== ====
|
|
0 SYNC_ADC
|
|
1 SYNC_DAC
|
|
===== ====
|
|
|
|
|
|
Methods
|
|
-------
|
|
|
|
In addition to initialization, the driver provides some useful methods for
|
|
controlling its operation:
|
|
|
|
.. method:: WM8960.set_left_input(input_source)
|
|
|
|
Specify the source for the left input. The input source names are listed above.
|
|
|
|
.. method:: WM8960.set_right_input(input_source)
|
|
|
|
Specify the source for the right input. The input source names are listed above.
|
|
|
|
.. method:: WM8960.volume(module, volume_l=None, volume_r=None)
|
|
|
|
Sets or gets the volume of a certain module.
|
|
|
|
If no volume values are supplied, the actual volume tuple is returned.
|
|
|
|
If one or two values are supplied, it sets the volume of a certain module.
|
|
If two values are provided, the first one is used for the left channel,
|
|
the second for the right channel. If only one value is supplied, it is used
|
|
for both channels. The value range is normalized to 0.0-100.0 with a
|
|
logarithmic scale.
|
|
|
|
For a list of suitable modules and db/step, see the table below.
|
|
|
|
.. table:: **Module Names and dB steps**
|
|
:widths: auto
|
|
:align: center
|
|
|
|
======= ====
|
|
dB/Step Name
|
|
======= ====
|
|
1.28 MODULE_ADC
|
|
1.28 MODULE_DAC
|
|
0.8 MODULE_HEADPHONE
|
|
0.475 MODULE_LINE_IN
|
|
0.8 MODULE_SPEAKER
|
|
======= ====
|
|
|
|
.. method:: WM8960.mute(module, mute, soft=True, ramp=wm8960.MUTE_FAST)
|
|
|
|
Mute or unmute the output. If *mute* is True, the output is muted, if ``False``
|
|
it is unmuted.
|
|
|
|
If *soft* is set as True, muting will happen as a soft transition. The time for
|
|
the transition is defined by *ramp*, which is either ``MUTE_FAST`` or ``MUTE_SLOW``.
|
|
|
|
.. method:: WM8960.set_data_route(route)
|
|
|
|
Set the audio data route. For the parameter value/names, see the table above.
|
|
|
|
.. method:: WM8960.set_module(module, active)
|
|
|
|
Enable or disable a module, with *active* being ``False`` or ``True``. For
|
|
the list of module names, see the table above.
|
|
|
|
Note that enabling ``MODULE_MONO_OUT`` is different from the `WM8960.mono`
|
|
method. The first enables output 3, while the `WM8960.mono` method sends a
|
|
mono mix to the left and right output.
|
|
|
|
.. method:: WM8960.enable_module(module)
|
|
|
|
Enable a module. For the list of module names, see the table above.
|
|
|
|
.. method:: WM8960.disable_module(module)
|
|
|
|
Disable a module. For the list of module names, see the table above.
|
|
|
|
.. method:: WM8960.expand_3d(level)
|
|
|
|
Enable Stereo 3D expansion. *level* is a number between 0 and 15.
|
|
A value of 0 disables the expansion.
|
|
|
|
.. method:: WM8960.mono(active)
|
|
|
|
If *active* is ``True``, a Mono mix is sent to the left and right output
|
|
channel. This is different from enabling the ``MODULE_MONO_MIX``, which
|
|
enables output 3.
|
|
|
|
.. method:: WM8960.alc_mode(channel, mode=ALC_MODE)
|
|
|
|
Enables or disables ALC mode. Parameters are:
|
|
|
|
- *channel* enables and sets the channel for ALC. The parameter values are:
|
|
|
|
- ALC_OFF: Switch ALC off
|
|
- ALS_RIGHT: Use the right input channel
|
|
- ALC_LEFT: Use the left input channel
|
|
- ALC_STEREO: Use both input channels.
|
|
|
|
- *mode* sets the ALC mode. Input values are:
|
|
|
|
- ALC_MODE: act as ALC
|
|
- ALC_LIMITER: act as limiter.
|
|
|
|
.. method:: WM8960.alc_gain(target=-12, max_gain=30, min_gain=-17.25, noise_gate=-78)
|
|
|
|
Set the target level, highest and lowest gain levels and the noise gate as dB level.
|
|
Permitted ranges are:
|
|
|
|
- *target*: -22.5 to -1.5 dB
|
|
- *max_gain*: -12 to 30 dB
|
|
- *min_gain*: -17 to 25 dB
|
|
- *noise_gate*: -78 to -30 dB
|
|
|
|
Excess values are limited to the permitted ranges. A value of -78 or less
|
|
for *noise_gate* disables the noise gate function.
|
|
|
|
.. method:: WM8960.alc_time(attack=24, decay=192, hold=0)
|
|
|
|
Set the dynamic characteristic of ALC. The times are given as millisecond
|
|
values. Permitted ranges are:
|
|
|
|
- *attack*: 6 to 6140
|
|
- *decay*: 24 to 24580
|
|
- *hold*: 0 to 43000
|
|
|
|
Excess values are limited within the permitted ranges.
|
|
|
|
.. method:: WM8960.deemphasis(active)
|
|
|
|
Enables or disables a deemphasis filter for playback, with *active* being
|
|
``False`` or ``True``. This filter is applied only for sample rates of
|
|
32000, 44100 and 48000. For other sample rates, the filter setting
|
|
is silently ignored.
|
|
|
|
.. method:: WM8960.deinit()
|
|
|
|
Disable all modules.
|
|
|
|
|
|
Examples
|
|
--------
|
|
|
|
Run WM8960 in secondary mode (default)::
|
|
|
|
# Micro_python WM8960 Codec driver
|
|
#
|
|
# Setting the driver to Slave mode using the default settings
|
|
#
|
|
from machine import Pin, I2C
|
|
import wm8960
|
|
i2c = I2C(0)
|
|
wm=wm8960.WM8960(i2c, 32000, left_input=wm8960.INPUT_MIC1)
|
|
wm.set_volume(wm8960.MODULE_HEADPHONE, 100)
|
|
|
|
|
|
Run WM8960 in primary mode::
|
|
|
|
# Micro_python WM8960 Codec driver
|
|
#
|
|
# Setting the driver to Master mode using specific audio format settings
|
|
#
|
|
from machine import Pin, I2C
|
|
import wm8960
|
|
|
|
i2c = I2C(0)
|
|
wm=wm8960.WM8960(i2c, 44100, primary=True, bits=16)
|
|
|
|
|
|
Run WM8960 on a MIMXRT10xx_DEV board in secondary mode (default)::
|
|
|
|
# Micro_python WM8960 Codec driver
|
|
#
|
|
# Setting the driver to Slave mode using the default settings
|
|
# swap the input channels such that a MIMXRT Dev board mic, which
|
|
# is connected to the right input, is assigned to the left audio channel.
|
|
#
|
|
from machine import Pin, I2C
|
|
import wm8960
|
|
i2c = I2C(0)
|
|
wm=wm8960.WM8960(i2c, sample_rate=16_000,
|
|
adc_sync=wm8960.SYNC_DAC,
|
|
swap=wm8960.SWAP_INPUT,
|
|
sysclk_source=wm8960.SYSCLK_MCLK)
|
|
|
|
|
|
Record with a Sparkfun WM8960 breakout board with Teensy in secondary mode (default)::
|
|
|
|
# Micro_python WM8960 Codec driver
|
|
#
|
|
# The breakout board uses a fixed 24MHz MCLK. Therefore the internal
|
|
# PLL must be used as sysclk, which is the master audio clock.
|
|
# The Sparkfun board has the WS pins for RX and TX connected on the
|
|
# board. Therefore adc_sync must be set to sync_adc, to configure
|
|
# it's ADCLRC pin as input.
|
|
#
|
|
from machine import Pin, I2C
|
|
import wm8960
|
|
i2c = I2C(0)
|
|
wm=wm8960.WM8960(i2c, sample_rate=16_000,
|
|
adc_sync=wm8960.SYNC_ADC,
|
|
sysclk_source=wm8960.SYSCLK_PLL,
|
|
mclk_freq=24_000_000,
|
|
left_input=wm8960.INPUT_MIC1,
|
|
right_input=wm8960.INPUT_CLOSED)
|
|
|
|
|
|
Play with a Sparkfun WM8960 breakout board with Teensy in secondary mode (default)::
|
|
|
|
# The breakout board uses a fixed 24MHz MCLK. Therefore the internal
|
|
# PLL must be used as sysclk, which is the master audio clock.
|
|
# The Sparkfun board has the WS pins for RX and TX connected on the
|
|
# board. Therefore adc_sync must be set to sync_adc, to configure
|
|
# it's ADCLRC pin as input.
|
|
|
|
from machine import I2C
|
|
i2c=I2C(0)
|
|
import wm8960
|
|
wm=wm8960.WM8960(i2c, sample_rate=44_100,
|
|
adc_sync=wm8960.SYNC_ADC,
|
|
sysclk_source=wm8960.SYSCLK_PLL,
|
|
mclk_freq=24_000_000)
|
|
wm.set_volume(wm8960.MODULE_HEADPHONE, 100)
|