forked from PAWPAW-Mirror/lib_xua
96 lines
2.6 KiB
ReStructuredText
96 lines
2.6 KiB
ReStructuredText
S/PDIF Receive
|
|
---------------
|
|
|
|
XMOS devices can support S/PDIF receive up to 192kHz.
|
|
|
|
The S/PDIF receiver module uses a clockblock and a buffered one-bit port.
|
|
The clock-block is divided of a 100 MHz reference clock. The one bit port is buffered to 4-bits.
|
|
The receiver code uses this clock to over sample the input data.
|
|
|
|
The receiver outputs audio samples over a *streaming channel end* where data can be input using the
|
|
built-in input operator.
|
|
|
|
The S/PDIF receive function never returns. The 32-bit value from the channel
|
|
input comprises:
|
|
|
|
.. list-table:: S/PDIF RX Word Structure
|
|
:header-rows: 1
|
|
:widths: 10 32
|
|
|
|
* - Bits
|
|
-
|
|
* - 0:3
|
|
- A tag (see below)
|
|
* - 4:28
|
|
- PCM encoded sample value
|
|
* - 29:31
|
|
- User bits (parity, etc)
|
|
|
|
The tag has one of three values:
|
|
|
|
.. list-table:: S/PDIF RX Tags
|
|
:header-rows: 1
|
|
:widths: 10 32
|
|
|
|
* - Tag
|
|
- Meaning
|
|
* - FRAME\_X
|
|
- Sample on channel 0 (Left for stereo)
|
|
* - FRAME\_Y
|
|
- Sample on another channel (Right if for stereo)
|
|
* - FRAME\_Z
|
|
- Sample on channel 0 (Left), and the first sample of a frame; can be used if the user bits need to be reconstructed.
|
|
|
|
See S/PDIF specification for further details on format, user bits etc.
|
|
|
|
Usage and Integration
|
|
+++++++++++++++++++++
|
|
|
|
Since S/PDIF is a digital steam the devices master clock must be syncronised to it. This is typically
|
|
done with an external fractional-n multipier. See `Clock Recovery` (:ref:`usb_audio_sec_clock_recovery`)
|
|
|
|
The S/PDIF receive function communicates with the ``clockGen`` component with passes audio data to the
|
|
audio driver and handles locking to the S/PDIF clock source if required (see External Clock Recovery).
|
|
|
|
Ideally the parity of each word/sample received should be checked. This is done using the built in
|
|
``crc32`` function (see ``xs1.h``):
|
|
|
|
.. literalinclude:: lib_xua/src/core/clocking/clockgen.xc
|
|
:start-after: //:badParity
|
|
:end-before: //:
|
|
|
|
If bad parity is detected the word/sample is ignored, otherwise the tag is inspected for channel
|
|
(i.e. left or right) and the sample stored.
|
|
|
|
The following code snippet illustrates how the output of the S/PDIF receive component could be used::
|
|
|
|
|
|
while(1)
|
|
{
|
|
c_spdif_rx :> data;
|
|
|
|
if(badParity(data)
|
|
continue;
|
|
|
|
tag = data & 0xF;
|
|
|
|
/* Extract 24bit audio sample */
|
|
sample = (data << 4) & 0xFFFFFF00;
|
|
|
|
switch(tag)
|
|
{
|
|
case FRAME_X:
|
|
case FRAME_X:
|
|
// Store left
|
|
break;
|
|
|
|
case FRAME_Z:
|
|
// Store right
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|