This commit is contained in:
Steven Dan
2025-12-11 09:43:42 +08:00
commit d8b2974133
1822 changed files with 280037 additions and 0 deletions

136
lib_i2s/CHANGELOG.rst Normal file
View File

@@ -0,0 +1,136 @@
I2S library change log
======================
5.1.0
-----
* ADDED: Support for XCommon CMake build system
* RESOLVED: Added missing shutdown feature to i2s_frame_slave
* FIXED: Allow input and output ports in the 4-bit port implementation to be
nullable
* FIXED: Behaviour of the restart_check() callback function in the example
applications
* REMOVED: Unused dependency lib_logging
* ADDED: Frame synch error field in i2s_config_t for I2S slave
* Changes to dependencies:
- lib_logging: Removed dependency
- lib_xassert: 2.0.0 -> 4.2.0
5.0.0
-----
* ADDED: Support for I2S data lengths less than 32 bit.
* ADDED: Implementation allowing use of a 4-bit port for up to 4 simultaneous
streaming inputs or outputs.
4.3.0
-----
* CHANGED: Use XMOS Public Licence Version 1
4.2.0
-----
* ADDED: Support for XS3 architecture
4.1.1
-----
* CHANGED: Pin Python package versions
* REMOVED: not necessary cpanfile
4.1.0
-----
* ADDED: Frame based I2S master that needs the bit clock to be set up
externally.
* REMOVED: I2S_BCLOCK_FROM_XCORE and I2S_XCORE_BLOCK_DIV optional #ifdefs
4.0.0
-----
* CHANGED: Build files updated to support new "xcommon" behaviour in xwaf.
3.0.1
-----
* CHANGE: At initialisation, configure LR clock of frame-based I2S slave for
input.
* CHANGE: Renamed example application directories to have standard "app"
prefix.
* ADDED: I2S_BCLOCK_FROM_XCORE and I2S_XCORE_BLOCK_DIV optional #ifdefs
3.0.0
-----
* REMOVED: Combined I2S and TDM master
2.4.0
-----
* ADDED: Frame-based I2S slave implementation.
* CHANGE: AN00162 now uses frame-based I2S master component.
2.3.0
-----
* ADDED: Configuration option for slave bit clock polarity. This allows
supporting masters that toggle word clock and data on rising edge of bit
clock.
2.2.0
-----
* ADDED: Frame-based I2S master using the new i2s_frame_callback_if. This
reduces the overhead of an interface call per sample.
* CHANGE: Reduce number of LR clock ticks needed to synchronise.
* RESOLVED: Documentation now correctly documents the valid values for FSYNC.
* RESOLVED: The I2S slave will now lock correctly in both I2S and
LEFT_JUSTFIED modes. Previously there was a bug that meant LEFT_JUSTFIED
would not work.
2.1.3
-----
* CHANGE: Slave mode now includes sync error detection and correction e.g.
when bit-clock is interrupted
2.1.2
-----
* RESOLVED: .project file fixes such that example(s) import into xTIMEComposer
correctly
2.1.1
-----
* CHANGE: Update to source code license and copyright
2.1.0
-----
* CHANGE: Input or output ports can now be null, for use when input or
output-only is required
* CHANGE: Software license changed to new license
2.0.1
-----
* CHANGE: Performance improvement to TDM to allow 32x32 operation
* RESOLVED: Bug fix to initialisation callback timing that could cause I2S
lock up
2.0.0
-----
* CHANGE: Major update to API from previous I2S components
* Changes to dependencies:
- lib_logging: Added dependency 2.0.0
- lib_xassert: Added dependency 2.0.0

84
lib_i2s/LICENSE.rst Normal file
View File

@@ -0,0 +1,84 @@
*******************************
XMOS PUBLIC LICENCE: Version 1
*******************************
Subject to the conditions and limitations below, permission is hereby granted by XMOS LIMITED (“XMOS”), free of charge, to any person or entity obtaining a copy of the XMOS Software.
**1. Definitions**
**“Applicable Patent Rights”** means: (a) where XMOS is the grantor of the rights, (i) claims of patents that are now or in future owned by or assigned to XMOS and (ii) that cover subject matter contained in the Software, but only to the extent it is necessary to use, reproduce or distribute the Software without infringement; and (b) where you are the grantor of the rights, (i) claims of patents that are now or in future owned by or assigned to you and (ii) that cover the subject matter contained in your Derivatives, taken alone or in combination with the Software.
**“Compiled Code”** means any compiled, binary, machine readable or executable version of the Source Code.
**“Contributor”** means any person or entity that creates or contributes to the creation of Derivatives.
**“Derivatives”** means any addition to, deletion from and/or change to the substance, structure of the Software, any previous Derivatives, the combination of the Derivatives and the Software and/or any respective portions thereof.
**“Source Code”** means the human readable code that is suitable for making modifications but excluding any Compiled Code.
**“Software”** means the software and associated documentation files which XMOS makes available and which contain a notice identifying the software as original XMOS software and referring to the software being subject to the terms of this XMOS Public Licence.
This Licence refers to XMOS Software and does not relate to any XMOS hardware or devices which are protected by intellectual property rights (including patent and trade marks) which may be sold to you under a separate agreement.
**2. Licence**
**Permitted Uses, Conditions and Restrictions.** Subject to the conditions below, XMOS grants you a worldwide, royalty free, non-exclusive licence, to the extent of any Patent Rights to do the following:
2.1 **Unmodified Software.** You may use, copy, display, publish, distribute and make available unmodified copies of the Software:
2.1.1 for personal or academic, non-commercial purposes; or
2.1.2 for commercial purposes provided the Software is at all times used on a device designed, licensed or developed by XMOS and, provided that in each instance (2.1.1 and 2.1.2):
(a) you must retain and reproduce in all copies of the Software the copyright and proprietary notices and disclaimers of XMOS as they appear in the Software, and keep intact all notices and disclaimers in the Software files that refer to this Licence; and
(b) you must include a copy of this Licence with every copy of the Software and documentation you publish, distribute and make available and you may not offer or impose any terms on such Software that alter or restrict this Licence or the intent of such Licence, except as permitted below (Additional Terms).
The licence above does not include any Compiled Code which XMOS may make available under a separate support and licence agreement.
2.2 **Derivatives.** You may create and modify Derivatives and use, copy, display, publish, distribute and make available Derivatives:
2.2.1 for personal or academic, non-commercial purposes; or
2.2.2 for commercial purposes, provided the Derivatives are at all times used on a device designed, licensed or developed by XMOS and, provided that in each instance (2.2.1 and 2.2.2):
(a) you must comply with the terms of clause 2.1 with respect to the Derivatives;
(b) you must copy (to the extent it doesnt already exist) the notice below in each file of the Derivatives, and ensure all the modified files carry prominent notices stating that you have changed the files and the date of any change; and
(c) if you sublicence, distribute or otherwise make the Software and/or the Derivatives available for commercial purposes, you must provide that the Software and Derivatives are at all times used on a device designed, licensed or developed by XMOS.
Without limitation to these terms and clause 3 below, the Source Code and Compiled Code to your Derivatives may at your discretion (but without obligation) be released, copied, displayed, published, distributed and made available; and if you elect to do so, it must be under the terms of this Licence including the terms of the licence at clauses 2.2.1, 2.2.2 and clause 3 below.
2.3 **Distribution of Executable Versions.** If you distribute or make available Derivatives, you must include a prominent notice in the code itself as well as in all related documentation, stating that the Source Code of the Software from which the Derivatives are based is available under the terms of this Licence, with information on how and where to obtain such Source Code.
**3. Your Grant of Rights.** In consideration and as a condition to this Licence, you grant to any person or entity receiving or distributing any Derivatives, a non-exclusive, royalty free, perpetual, irrevocable license under your Applicable Patent Rights and all other intellectual property rights owned or controlled by you, to use, copy, display, publish, distribute and make available your Derivatives of the same scope and extent as XMOSs licence under clause 2.2 above.
**4. Combined Products.** You may create a combined product by combining Software, Derivatives and other code not covered by this Licence as a single application or product. In such instance, you must comply with the requirements of this Licence for any portion of the Software and/or Derivatives.
**5. Additional Terms.** You may choose to offer, and to charge a fee for, warranty, support, indemnity or liability obligations and/or other rights consistent with the term of this Licence (“Additional Terms”) to any legitimate recipients of the Software and/or Derivatives. The terms on which you provide such Additional Terms are on your sole responsibility and you shall indemnify, defend and hold XMOS harmless against any claims asserted against XMOS.
**6. New Versions.** XMOS may publish revised and/or new versions of this Licence from time to time to accommodate changes to the Licence terms, new versions, updates and bug fixes of the Software. Each version will be given a distinguishing version number. Once Software has been published under a particular version of this Licence, you may continue to use it under the terms of that version. You may also choose to use the latest version of the Software under any subsequent version published by XMOS. Only XMOS shall have the right to modify these terms.
**7. IPR and Ownership**
Any rights, including all intellectual property rights and all trademarks not expressly granted herein are reserved in full by the authors or copyright holders. Any requests for additional permissions by XMOS including any rights to use XMOS trademarks, should be made (without obligation) to XMOS at **support@xmos.com**
Nothing herein shall limit any rights that XMOS is otherwise entitled to under the doctrines of patent exhaustion, implied license, or legal estoppel. Neither the name of the authors, the copyright holders or any contributors may be used to endorse or promote any Derivatives from this Software without specific written permission. Any attempt to deal with the Software which does not comply with this Licence shall be void and shall automatically terminate any rights granted under this licence (including any licence of any intellectual property rights granted herein).
Subject to the licences granted under this Licence any Contributor retains all rights, title and interest in and to any Derivatives made by Contributor subject to the underlying rights of XMOS in the Software. XMOS shall retain all rights, title and interest in the Software and any Derivatives made by XMOS (“XMOS Derivatives”). XMOS Derivatives will not automatically be subject to this Licence and XMOS shall be entitled to licence such rights on any terms (without obligation) as it sees fit.
**8. Termination**
8.1 This Licence will automatically terminate immediately, without notice to you, if:
(a) you fail to comply with the terms of this Licence; and/or
(b) you directly or indirectly commence any action for patent or intellectual property right infringement against XMOS, or any parent, group, affiliate or subsidiary of XMOS; provided XMOS did not first commence an action or patent infringement against you in that instance; and/or
(c) the terms of this Licence are held by any court of competent jurisdiction to be unenforceable in whole or in part.
**9. Critical Applications.** Unless XMOS has agreed in writing with you an agreement specifically governing use of the Goods in military, aerospace, automotive or medically related functions (collectively and individually hereinafter referred to as "Special Use"), any permitted use of the Software excludes Special Use. Notwithstanding any agreement between XMOS and you for Special Use, Special Use shall be at your own risk, and you shall fully indemnify XMOS against any damages, losses, costs and claims (direct and indirect) arising out of any Special Use.
**10. NO WARRANTY OR SUPPORT.** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL XMOS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, WARRANTY, CIVIL TORT (INCLUDING NEGLIGENCE), PRODUCTS LIABILITY OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE INCLUDING GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES EVEN IF SUCH PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES AND NOT WITHSTANDING THE FAILURE OF ESSENTIAL PURPOSE. IN SOME JURISDICTIONS PARTIES ARE UNABLE TO LIMIT LIABILTY IN THIS WAY, IF THIS APPLIES TO YOUR JURISDICTION THIS LIABILITY CLAUSE ABOVE MAY NOT APPLY. NOTWITHSTANDING THE ABOVE, IN NO EVENT SHALL XMOSs TOTAL LIABILITY TO YOU FOR ALL DAMAGES, LOSS OR OTHERWISE EXCEED $50.
**11. Governing Law and Jurisdiction.** This Licence constitutes the entire agreement between the parties with respect to the subject matter hereof. The Licence shall be governed by the laws of England and the conflict of laws and UN Convention on Contracts for the International Sale of Goods, shall not apply.

67
lib_i2s/README.rst Normal file
View File

@@ -0,0 +1,67 @@
.. |I2S| replace:: I\ :sup:`2`\ S
I2S/TDM Library
===============
:Version: 5.1.0
:Vendor: XMOS
Summary
-------
A software library that allows you to control an |I2S| or TDM (time
division multiplexed) bus via xCORE ports. |I2S| and TDM are digital
data streaming interfaces particularly appropriate for transmission of
audio data. The components in the library
are controlled via C using the XMOS multicore extensions (xC) and
can either act as |I2S| master, TDM master or |I2S| slave.
Features
........
* |I2S| master, TDM master and |I2S| slave modes.
* Handles multiple input and output data lines.
* Support for standard |I2S|, left justified or right justified
data modes for |I2S|.
* Support for multiple formats of TDM synchronization signal.
* Efficient "frame-based" versions of |I2S| master and slave allowing use of processor cycles in between I2S signal handling.
* Sample rate support up to 192kHz or 768kHz for "frame-based" versions.
* Up to 32 channels in/32 channels out (depending on sample rate and protocol).
Resource Usage
..............
The I2S and TDM modules use one logical core and between 1.6 and 2.1kB of memory. IO usage is 1 x 1b port for each signal.
Software version and dependencies
.................................
The CHANGELOG contains information about the current and previous versions.
For a list of direct dependencies, look for DEPENDENT_MODULES in lib_i2s/module_build_info.
Notes on "frame-based" |I2S| implementations
............................................
The library supports both "sample-based" and "frame-based" versions of |I2S| master and slave. The "frame-based" versions are recommended for new designs and support higher |I2S| channel counts and rates. In addition, the number of callbacks to pass data to and from the |I2S| handler task are reduced. "Frame-based" |I2S| pass an array of channels per sample period whereas "sample-based" versions make a callback per channel within a sample period. The "frame-based" callbacks are all grouped together allowing the user side to make maximum use of the MIPS between |I2S| frames. For example, a 48kHz (20.83us) |I2S| interface supports a total of 19us processing per sample period, in any order, across the callbacks. The older "sample-based" versions are currently maintained to provide compatibility with existing code examples.
Related application notes
.........................
The following application notes use this library:
* AN00162 - Using the |I2S| library
Required Software (dependencies)
================================
* lib_xassert (www.github.com/xmos/lib_xassert)
Documentation
=============
You can find the documentation for this software in the /doc directory of the package.
Support
=======
This package is supported by XMOS Ltd. Issues can be raised against the software at: http://www.xmos.com/support

View File

@@ -0,0 +1,84 @@
*******************************
XMOS PUBLIC LICENCE: Version 1
*******************************
Subject to the conditions and limitations below, permission is hereby granted by XMOS LIMITED (“XMOS”), free of charge, to any person or entity obtaining a copy of the XMOS Software.
**1. Definitions**
**“Applicable Patent Rights”** means: (a) where XMOS is the grantor of the rights, (i) claims of patents that are now or in future owned by or assigned to XMOS and (ii) that cover subject matter contained in the Software, but only to the extent it is necessary to use, reproduce or distribute the Software without infringement; and (b) where you are the grantor of the rights, (i) claims of patents that are now or in future owned by or assigned to you and (ii) that cover the subject matter contained in your Derivatives, taken alone or in combination with the Software.
**“Compiled Code”** means any compiled, binary, machine readable or executable version of the Source Code.
**“Contributor”** means any person or entity that creates or contributes to the creation of Derivatives.
**“Derivatives”** means any addition to, deletion from and/or change to the substance, structure of the Software, any previous Derivatives, the combination of the Derivatives and the Software and/or any respective portions thereof.
**“Source Code”** means the human readable code that is suitable for making modifications but excluding any Compiled Code.
**“Software”** means the software and associated documentation files which XMOS makes available and which contain a notice identifying the software as original XMOS software and referring to the software being subject to the terms of this XMOS Public Licence.
This Licence refers to XMOS Software and does not relate to any XMOS hardware or devices which are protected by intellectual property rights (including patent and trade marks) which may be sold to you under a separate agreement.
**2. Licence**
**Permitted Uses, Conditions and Restrictions.** Subject to the conditions below, XMOS grants you a worldwide, royalty free, non-exclusive licence, to the extent of any Patent Rights to do the following:
2.1 **Unmodified Software.** You may use, copy, display, publish, distribute and make available unmodified copies of the Software:
2.1.1 for personal or academic, non-commercial purposes; or
2.1.2 for commercial purposes provided the Software is at all times used on a device designed, licensed or developed by XMOS and, provided that in each instance (2.1.1 and 2.1.2):
(a) you must retain and reproduce in all copies of the Software the copyright and proprietary notices and disclaimers of XMOS as they appear in the Software, and keep intact all notices and disclaimers in the Software files that refer to this Licence; and
(b) you must include a copy of this Licence with every copy of the Software and documentation you publish, distribute and make available and you may not offer or impose any terms on such Software that alter or restrict this Licence or the intent of such Licence, except as permitted below (Additional Terms).
The licence above does not include any Compiled Code which XMOS may make available under a separate support and licence agreement.
2.2 **Derivatives.** You may create and modify Derivatives and use, copy, display, publish, distribute and make available Derivatives:
2.2.1 for personal or academic, non-commercial purposes; or
2.2.2 for commercial purposes, provided the Derivatives are at all times used on a device designed, licensed or developed by XMOS and, provided that in each instance (2.2.1 and 2.2.2):
(a) you must comply with the terms of clause 2.1 with respect to the Derivatives;
(b) you must copy (to the extent it doesnt already exist) the notice below in each file of the Derivatives, and ensure all the modified files carry prominent notices stating that you have changed the files and the date of any change; and
(c) if you sublicence, distribute or otherwise make the Software and/or the Derivatives available for commercial purposes, you must provide that the Software and Derivatives are at all times used on a device designed, licensed or developed by XMOS.
Without limitation to these terms and clause 3 below, the Source Code and Compiled Code to your Derivatives may at your discretion (but without obligation) be released, copied, displayed, published, distributed and made available; and if you elect to do so, it must be under the terms of this Licence including the terms of the licence at clauses 2.2.1, 2.2.2 and clause 3 below.
2.3 **Distribution of Executable Versions.** If you distribute or make available Derivatives, you must include a prominent notice in the code itself as well as in all related documentation, stating that the Source Code of the Software from which the Derivatives are based is available under the terms of this Licence, with information on how and where to obtain such Source Code.
**3. Your Grant of Rights.** In consideration and as a condition to this Licence, you grant to any person or entity receiving or distributing any Derivatives, a non-exclusive, royalty free, perpetual, irrevocable license under your Applicable Patent Rights and all other intellectual property rights owned or controlled by you, to use, copy, display, publish, distribute and make available your Derivatives of the same scope and extent as XMOSs licence under clause 2.2 above.
**4. Combined Products.** You may create a combined product by combining Software, Derivatives and other code not covered by this Licence as a single application or product. In such instance, you must comply with the requirements of this Licence for any portion of the Software and/or Derivatives.
**5. Additional Terms.** You may choose to offer, and to charge a fee for, warranty, support, indemnity or liability obligations and/or other rights consistent with the term of this Licence (“Additional Terms”) to any legitimate recipients of the Software and/or Derivatives. The terms on which you provide such Additional Terms are on your sole responsibility and you shall indemnify, defend and hold XMOS harmless against any claims asserted against XMOS.
**6. New Versions.** XMOS may publish revised and/or new versions of this Licence from time to time to accommodate changes to the Licence terms, new versions, updates and bug fixes of the Software. Each version will be given a distinguishing version number. Once Software has been published under a particular version of this Licence, you may continue to use it under the terms of that version. You may also choose to use the latest version of the Software under any subsequent version published by XMOS. Only XMOS shall have the right to modify these terms.
**7. IPR and Ownership**
Any rights, including all intellectual property rights and all trademarks not expressly granted herein are reserved in full by the authors or copyright holders. Any requests for additional permissions by XMOS including any rights to use XMOS trademarks, should be made (without obligation) to XMOS at **support@xmos.com**
Nothing herein shall limit any rights that XMOS is otherwise entitled to under the doctrines of patent exhaustion, implied license, or legal estoppel. Neither the name of the authors, the copyright holders or any contributors may be used to endorse or promote any Derivatives from this Software without specific written permission. Any attempt to deal with the Software which does not comply with this Licence shall be void and shall automatically terminate any rights granted under this licence (including any licence of any intellectual property rights granted herein).
Subject to the licences granted under this Licence any Contributor retains all rights, title and interest in and to any Derivatives made by Contributor subject to the underlying rights of XMOS in the Software. XMOS shall retain all rights, title and interest in the Software and any Derivatives made by XMOS (“XMOS Derivatives”). XMOS Derivatives will not automatically be subject to this Licence and XMOS shall be entitled to licence such rights on any terms (without obligation) as it sees fit.
**8. Termination**
8.1 This Licence will automatically terminate immediately, without notice to you, if:
(a) you fail to comply with the terms of this Licence; and/or
(b) you directly or indirectly commence any action for patent or intellectual property right infringement against XMOS, or any parent, group, affiliate or subsidiary of XMOS; provided XMOS did not first commence an action or patent infringement against you in that instance; and/or
(c) the terms of this Licence are held by any court of competent jurisdiction to be unenforceable in whole or in part.
**9. Critical Applications.** Unless XMOS has agreed in writing with you an agreement specifically governing use of the Goods in military, aerospace, automotive or medically related functions (collectively and individually hereinafter referred to as "Special Use"), any permitted use of the Software excludes Special Use. Notwithstanding any agreement between XMOS and you for Special Use, Special Use shall be at your own risk, and you shall fully indemnify XMOS against any damages, losses, costs and claims (direct and indirect) arising out of any Special Use.
**10. NO WARRANTY OR SUPPORT.** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL XMOS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, WARRANTY, CIVIL TORT (INCLUDING NEGLIGENCE), PRODUCTS LIABILITY OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE INCLUDING GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES EVEN IF SUCH PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES AND NOT WITHSTANDING THE FAILURE OF ESSENTIAL PURPOSE. IN SOME JURISDICTIONS PARTIES ARE UNABLE TO LIMIT LIABILTY IN THIS WAY, IF THIS APPLIES TO YOUR JURISDICTION THIS LIABILITY CLAUSE ABOVE MAY NOT APPLY. NOTWITHSTANDING THE ABOVE, IN NO EVENT SHALL XMOSs TOTAL LIABILITY TO YOU FOR ALL DAMAGES, LOSS OR OTHERWISE EXCEED $50.
**11. Governing Law and Jurisdiction.** This Licence constitutes the entire agreement between the parties with respect to the subject matter hereof. The Licence shall be governed by the laws of England and the conflict of laws and UN Convention on Contracts for the International Sale of Goods, shall not apply.

View File

@@ -0,0 +1,36 @@
# The TARGET variable determines what target system the application is
# compiled for. It either refers to an XN file in the source directories
# or a valid argument for the --target option when compiling
XCORE_AI ?= 0
ifeq ($(XCORE_AI),0)
TARGET = XCORE-200-EXPLORER
else
TARGET = XCORE-AI-EXPLORER
endif
# The APP_NAME variable determines the name of the final .xe file. It should
# not include the .xe postfix. If left blank the name will default to
# the project name
APP_NAME =
# The USED_MODULES variable lists other module used by the application.
USED_MODULES = lib_logging(>=3.2.0) lib_gpio(>=1.1.0) lib_i2c(>=5.0.0) lib_i2s(>=3.0.0)
# The flags passed to xcc when building the application
# You can also set the following to override flags for a particular language:
# XCC_XC_FLAGS, XCC_C_FLAGS, XCC_ASM_FLAGS, XCC_CPP_FLAGS
# If the variable XCC_MAP_FLAGS is set it overrides the flags passed to
# xcc for the final link (mapping) stage.
XCC_FLAGS = $(EXTRA_FLAGS) -O2 -report -g -DSIM_LOOPBACK_TEST=1 -DDEBUG_PRINT_ENABLE=1
# test: bin/i2s_loopback_demo.xe
# xsim bin/i2s_loopback_demo.xe --plugin LoopbackPort.dll '-port tile[0] XS1_PORT_1D 1 0 -port tile[1] XS1_PORT_1E 1 0'
#=============================================================================
# The following part of the Makefile includes the common build infrastructure
# for compiling XMOS applications. You should not need to edit below here.
XMOS_MAKE_PATH ?= ../..
include $(XMOS_MAKE_PATH)/xcommon/module_xcommon/build/Makefile.common

View File

@@ -0,0 +1,46 @@
.. |I2S| replace:: I\ :sup:`2`\ S
.. |I2C| replace:: I\ :sup:`2`\ C
Using the I2S library
=====================
Summary
-------
|I2S| interfaces are key to many audio systems. XMOS technology is perfectly suited
to these applications - supporting a wide variety of standard interfaces and
also a large range of DSP functions.
This application note demonstrates the use of the XMOS |I2S| library to
create a digital audio loopback on an XMOS multicore microcontroller.
The code used in the application note configures the audio codecs to simultaneously
send and receive audio samples. It then uses the |I2S| library to
loopback all 8 channels.
Required tools and libraries
............................
* xTIMEcomposer Tools - Version 14.3.2
* XMOS |I2S|/TDM library - Version 2.4.0
* XMOS GPIO library - Version 1.1.0
* XMOS |I2C| library - Version 5.0.0
Required hardware
.................
The example code provided with the application has been implemented
and tested on the xCORE-200 Multichannel Audio Platform.
Prerequisites
..............
* This document assumes familarity with |I2S| interfaces, the XMOS xCORE
architecture, the XMOS tool chain and the xC language. Documentation related
to these aspects which are not specific to this application note are linked
to in the references appendix.
* For a description of XMOS related terms found in this document
please see the XMOS Glossary [#]_.
.. [#] http://www.xmos.com/published/glossary

View File

@@ -0,0 +1,57 @@
<?xml version="1.0" encoding="UTF-8"?>
<Network xmlns="http://www.xmos.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.xmos.com http://www.xmos.com" ManuallySpecifiedRouting="true">
<Type>Board</Type>
<Name>xCORE-200 MC Audio</Name>
<Declarations>
<Declaration>tileref tile[2]</Declaration>
<Declaration>tileref usb_tile</Declaration>
</Declarations>
<Packages>
<Package id="0" Type="XS2-UEnA-512-FB236">
<Nodes>
<Node Id="0" InPackageId="0" Type="XS2-L16A-512" OscillatorSrc="1" SystemFrequency="500MHz">
<Boot>
<Source Location="bootFlash"/>
</Boot>
<Tile Number="0" Reference="tile[0]">
<Port Location="XS1_PORT_1B" Name="PORT_SQI_CS"/>
<Port Location="XS1_PORT_1C" Name="PORT_SQI_SCLK"/>
<Port Location="XS1_PORT_4B" Name="PORT_SQI_SIO"/>
</Tile>
<Tile Number="1" Reference="tile[1]"/>
</Node>
<Node Id="1" InPackageId="1" Type="periph:XS1-SU" Reference="usb_tile" Oscillator="24MHz">
</Node>
</Nodes>
<Links>
<Link Encoding="5wire">
<LinkEndpoint NodeId="0" Link="8" Delays="52clk,52clk"/>
<LinkEndpoint NodeId="1" Link="0" Delays="1clk,1clk"/>
</Link>
</Links>
</Package>
</Packages>
<Nodes>
<Node Id="2" Type="device:" RoutingId="0x8000">
<Service Id="0" Proto="xscope_host_data(chanend c);">
<Chanend Identifier="c" end="3"/>
</Service>
</Node>
</Nodes>
<Links>
<Link Encoding="2wire" Delays="4,4" Flags="XSCOPE">
<LinkEndpoint NodeId="0" Link="0"/>
<LinkEndpoint NodeId="2" Chanend="1"/>
</Link>
</Links>
<ExternalDevices>
<Device NodeId="0" Tile="0" Class="SQIFlash" Name="bootFlash" Type="S25FL116K" PageSize="256" SectorSize="4096" NumPages="8192">
<Attribute Name="PORT_SQI_CS" Value="PORT_SQI_CS"/>
<Attribute Name="PORT_SQI_SCLK" Value="PORT_SQI_SCLK"/>
<Attribute Name="PORT_SQI_SIO" Value="PORT_SQI_SIO"/>
</Device>
</ExternalDevices>
<JTAGChain>
<JTAGDevice NodeId="0"/>
</JTAGChain>
</Network>

View File

@@ -0,0 +1,158 @@
// Copyright 2014-2021 XMOS LIMITED.
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
#include <platform.h>
#include <xs1.h>
#include "i2s.h"
#include "i2c.h"
#include "gpio.h"
/* Ports and clocks used by the application */
on tile[0]: out buffered port:32 p_lrclk = XS1_PORT_1G;
on tile[0]: out port p_bclk = XS1_PORT_1H;
on tile[0]: in port p_mclk = XS1_PORT_1F;
on tile[0]: out buffered port:32 p_dout[4] = {XS1_PORT_1M, XS1_PORT_1N, XS1_PORT_1O, XS1_PORT_1P};
on tile[0]: in buffered port:32 p_din[4] = {XS1_PORT_1I, XS1_PORT_1J, XS1_PORT_1K, XS1_PORT_1L};
on tile[0]: clock bclk = XS1_CLKBLK_2;
on tile[0]: port p_i2c = XS1_PORT_4A;
on tile[0]: port p_gpio = XS1_PORT_8C;
#define SAMPLE_FREQUENCY (48000)
#define MASTER_CLOCK_FREQUENCY (24576000)
#define DATA_BITS (32)
#define CS5368_ADDR (0x4C) // I2C address of the CS5368 DAC
#define CS5368_GCTL_MDE (0x01) // I2C mode control register number
#define CS5368_PWR_DN (0x06)
#define CS4384_ADDR (0x18) // I2C address of the CS4384 ADC
#define CS4384_MODE_CTRL (0x02) // I2C mode control register number
#define CS4384_PCM_CTRL (0x03) // I2C PCM control register number
enum gpio_shared_audio_pins {
GPIO_DAC_RST_N = 1,
GPIO_PLL_SEL = 5, // 1 = CS2100, 0 = Phaselink clock source
GPIO_ADC_RST_N = 6,
GPIO_MCLK_FSEL = 7, // Select frequency on Phaselink clock. 0 = 24.576MHz for 48k, 1 = 22.5792MHz for 44.1k.
};
void reset_codecs(client i2c_master_if i2c)
{
/* Mode Control 1 (Address: 0x02) */
/* bit[7] : Control Port Enable (CPEN) : Set to 1 for enable
* bit[6] : Freeze controls (FREEZE) : Set to 1 for freeze
* bit[5] : PCM/DSD Selection (DSD/PCM) : Set to 0 for PCM
* bit[4:1] : DAC Pair Disable (DACx_DIS) : All Dac Pairs enabled
* bit[0] : Power Down (PDN) : Powered down
*/
i2c.write_reg(CS4384_ADDR, CS4384_MODE_CTRL, 0b11000001);
/* PCM Control (Address: 0x03) */
/* bit[7:4] : Digital Interface Format (DIF) : 0b1100 for TDM
* bit[3:2] : Reserved
* bit[1:0] : Functional Mode (FM) : 0x11 for auto-speed detect (32 to 200kHz)
*/
i2c.write_reg(CS4384_ADDR, CS4384_PCM_CTRL, 0b00010111);
/* Mode Control 1 (Address: 0x02) */
/* bit[7] : Control Port Enable (CPEN) : Set to 1 for enable
* bit[6] : Freeze controls (FREEZE) : Set to 0 for freeze
* bit[5] : PCM/DSD Selection (DSD/PCM) : Set to 0 for PCM
* bit[4:1] : DAC Pair Disable (DACx_DIS) : All Dac Pairs enabled
* bit[0] : Power Down (PDN) : Not powered down
*/
i2c.write_reg(CS4384_ADDR, CS4384_MODE_CTRL, 0b10000000);
unsigned adc_dif = 0x01; // I2S mode
unsigned adc_mode = 0x03; // Slave mode all speeds
/* Reg 0x01: (GCTL) Global Mode Control Register */
/* Bit[7]: CP-EN: Manages control-port mode
* Bit[6]: CLKMODE: Setting puts part in 384x mode
* Bit[5:4]: MDIV[1:0]: Set to 01 for /2
* Bit[3:2]: DIF[1:0]: Data Format: 0x01 for I2S, 0x02 for TDM
* Bit[1:0]: MODE[1:0]: Mode: 0x11 for slave mode
*/
i2c.write_reg(CS5368_ADDR, CS5368_GCTL_MDE, 0b10010000 | (adc_dif << 2) | adc_mode);
/* Reg 0x06: (PDN) Power Down Register */
/* Bit[7:6]: Reserved
* Bit[5]: PDN-BG: When set, this bit powers-own the bandgap reference
* Bit[4]: PDM-OSC: Controls power to internal oscillator core
* Bit[3:0]: PDN: When any bit is set all clocks going to that channel pair are turned off
*/
i2c.write_reg(CS5368_ADDR, CS5368_PWR_DN, 0b00000000);
}
[[distributable]]
void i2s_loopback(server i2s_frame_callback_if i2s,
client i2c_master_if i2c,
client output_gpio_if dac_reset,
client output_gpio_if adc_reset,
client output_gpio_if pll_select,
client output_gpio_if mclk_select)
{
int32_t samples[8] = {0}; // Array used for looping back samples
while (1) {
select {
case i2s.init(i2s_config_t &?i2s_config, tdm_config_t &?tdm_config):
i2s_config.mode = I2S_MODE_I2S;
i2s_config.mclk_bclk_ratio = (MASTER_CLOCK_FREQUENCY/(SAMPLE_FREQUENCY*2*DATA_BITS));
// Set CODECs in reset
dac_reset.output(0);
adc_reset.output(0);
// Select 48Khz family clock (24.576Mhz)
mclk_select.output(1);
pll_select.output(0);
// Allow the clock to settle
delay_milliseconds(2);
// Take CODECs out of reset
dac_reset.output(1);
adc_reset.output(1);
reset_codecs(i2c);
break;
case i2s.receive(size_t n_chans, int32_t in_samps[n_chans]):
for (int i = 0; i < n_chans; i++) samples[i] = in_samps[i]; // copy samples
break;
case i2s.send(size_t n_chans, int32_t out_samps[n_chans]):
for (int i = 0; i < n_chans; i++) out_samps[i] = samples[i]; // copy samples
break;
case i2s.restart_check() -> i2s_restart_t restart:
restart = I2S_NO_RESTART; // Keep on looping
break;
}
}
}
static char gpio_pin_map[4] = {
GPIO_DAC_RST_N,
GPIO_ADC_RST_N,
GPIO_PLL_SEL,
GPIO_MCLK_FSEL
};
int main()
{
interface i2s_frame_callback_if i_i2s;
interface i2c_master_if i_i2c[1];
interface output_gpio_if i_gpio[4];
par {
/* System setup, I2S + Codec control over I2C */
on tile[0]: i2s_frame_master(i_i2s, p_dout, 4, p_din, 4, DATA_BITS, p_bclk, p_lrclk, p_mclk, bclk);
on tile[0]: [[distribute]] i2c_master_single_port(i_i2c, 1, p_i2c, 100, 0, 1, 0);
on tile[0]: [[distribute]] output_gpio(i_gpio, 4, p_gpio, gpio_pin_map);
/* The application - loopback the I2S samples */
on tile[0]: [[distribute]] i2s_loopback(i_i2s, i_i2c[0], i_gpio[0], i_gpio[1], i_gpio[2], i_gpio[3]);
}
return 0;
}

View File

@@ -0,0 +1,14 @@
def options(opt):
opt.load('xwaf.xcommon')
def configure(conf):
conf.load('xwaf.xcommon')
def build(bld):
bld.do_xcommon()
def dist(ctx):
ctx.load('xwaf.xcommon')
def distcheck(ctx):
ctx.load('xwaf.xcommon')

View File

@@ -0,0 +1,84 @@
*******************************
XMOS PUBLIC LICENCE: Version 1
*******************************
Subject to the conditions and limitations below, permission is hereby granted by XMOS LIMITED (“XMOS”), free of charge, to any person or entity obtaining a copy of the XMOS Software.
**1. Definitions**
**“Applicable Patent Rights”** means: (a) where XMOS is the grantor of the rights, (i) claims of patents that are now or in future owned by or assigned to XMOS and (ii) that cover subject matter contained in the Software, but only to the extent it is necessary to use, reproduce or distribute the Software without infringement; and (b) where you are the grantor of the rights, (i) claims of patents that are now or in future owned by or assigned to you and (ii) that cover the subject matter contained in your Derivatives, taken alone or in combination with the Software.
**“Compiled Code”** means any compiled, binary, machine readable or executable version of the Source Code.
**“Contributor”** means any person or entity that creates or contributes to the creation of Derivatives.
**“Derivatives”** means any addition to, deletion from and/or change to the substance, structure of the Software, any previous Derivatives, the combination of the Derivatives and the Software and/or any respective portions thereof.
**“Source Code”** means the human readable code that is suitable for making modifications but excluding any Compiled Code.
**“Software”** means the software and associated documentation files which XMOS makes available and which contain a notice identifying the software as original XMOS software and referring to the software being subject to the terms of this XMOS Public Licence.
This Licence refers to XMOS Software and does not relate to any XMOS hardware or devices which are protected by intellectual property rights (including patent and trade marks) which may be sold to you under a separate agreement.
**2. Licence**
**Permitted Uses, Conditions and Restrictions.** Subject to the conditions below, XMOS grants you a worldwide, royalty free, non-exclusive licence, to the extent of any Patent Rights to do the following:
2.1 **Unmodified Software.** You may use, copy, display, publish, distribute and make available unmodified copies of the Software:
2.1.1 for personal or academic, non-commercial purposes; or
2.1.2 for commercial purposes provided the Software is at all times used on a device designed, licensed or developed by XMOS and, provided that in each instance (2.1.1 and 2.1.2):
(a) you must retain and reproduce in all copies of the Software the copyright and proprietary notices and disclaimers of XMOS as they appear in the Software, and keep intact all notices and disclaimers in the Software files that refer to this Licence; and
(b) you must include a copy of this Licence with every copy of the Software and documentation you publish, distribute and make available and you may not offer or impose any terms on such Software that alter or restrict this Licence or the intent of such Licence, except as permitted below (Additional Terms).
The licence above does not include any Compiled Code which XMOS may make available under a separate support and licence agreement.
2.2 **Derivatives.** You may create and modify Derivatives and use, copy, display, publish, distribute and make available Derivatives:
2.2.1 for personal or academic, non-commercial purposes; or
2.2.2 for commercial purposes, provided the Derivatives are at all times used on a device designed, licensed or developed by XMOS and, provided that in each instance (2.2.1 and 2.2.2):
(a) you must comply with the terms of clause 2.1 with respect to the Derivatives;
(b) you must copy (to the extent it doesnt already exist) the notice below in each file of the Derivatives, and ensure all the modified files carry prominent notices stating that you have changed the files and the date of any change; and
(c) if you sublicence, distribute or otherwise make the Software and/or the Derivatives available for commercial purposes, you must provide that the Software and Derivatives are at all times used on a device designed, licensed or developed by XMOS.
Without limitation to these terms and clause 3 below, the Source Code and Compiled Code to your Derivatives may at your discretion (but without obligation) be released, copied, displayed, published, distributed and made available; and if you elect to do so, it must be under the terms of this Licence including the terms of the licence at clauses 2.2.1, 2.2.2 and clause 3 below.
2.3 **Distribution of Executable Versions.** If you distribute or make available Derivatives, you must include a prominent notice in the code itself as well as in all related documentation, stating that the Source Code of the Software from which the Derivatives are based is available under the terms of this Licence, with information on how and where to obtain such Source Code.
**3. Your Grant of Rights.** In consideration and as a condition to this Licence, you grant to any person or entity receiving or distributing any Derivatives, a non-exclusive, royalty free, perpetual, irrevocable license under your Applicable Patent Rights and all other intellectual property rights owned or controlled by you, to use, copy, display, publish, distribute and make available your Derivatives of the same scope and extent as XMOSs licence under clause 2.2 above.
**4. Combined Products.** You may create a combined product by combining Software, Derivatives and other code not covered by this Licence as a single application or product. In such instance, you must comply with the requirements of this Licence for any portion of the Software and/or Derivatives.
**5. Additional Terms.** You may choose to offer, and to charge a fee for, warranty, support, indemnity or liability obligations and/or other rights consistent with the term of this Licence (“Additional Terms”) to any legitimate recipients of the Software and/or Derivatives. The terms on which you provide such Additional Terms are on your sole responsibility and you shall indemnify, defend and hold XMOS harmless against any claims asserted against XMOS.
**6. New Versions.** XMOS may publish revised and/or new versions of this Licence from time to time to accommodate changes to the Licence terms, new versions, updates and bug fixes of the Software. Each version will be given a distinguishing version number. Once Software has been published under a particular version of this Licence, you may continue to use it under the terms of that version. You may also choose to use the latest version of the Software under any subsequent version published by XMOS. Only XMOS shall have the right to modify these terms.
**7. IPR and Ownership**
Any rights, including all intellectual property rights and all trademarks not expressly granted herein are reserved in full by the authors or copyright holders. Any requests for additional permissions by XMOS including any rights to use XMOS trademarks, should be made (without obligation) to XMOS at **support@xmos.com**
Nothing herein shall limit any rights that XMOS is otherwise entitled to under the doctrines of patent exhaustion, implied license, or legal estoppel. Neither the name of the authors, the copyright holders or any contributors may be used to endorse or promote any Derivatives from this Software without specific written permission. Any attempt to deal with the Software which does not comply with this Licence shall be void and shall automatically terminate any rights granted under this licence (including any licence of any intellectual property rights granted herein).
Subject to the licences granted under this Licence any Contributor retains all rights, title and interest in and to any Derivatives made by Contributor subject to the underlying rights of XMOS in the Software. XMOS shall retain all rights, title and interest in the Software and any Derivatives made by XMOS (“XMOS Derivatives”). XMOS Derivatives will not automatically be subject to this Licence and XMOS shall be entitled to licence such rights on any terms (without obligation) as it sees fit.
**8. Termination**
8.1 This Licence will automatically terminate immediately, without notice to you, if:
(a) you fail to comply with the terms of this Licence; and/or
(b) you directly or indirectly commence any action for patent or intellectual property right infringement against XMOS, or any parent, group, affiliate or subsidiary of XMOS; provided XMOS did not first commence an action or patent infringement against you in that instance; and/or
(c) the terms of this Licence are held by any court of competent jurisdiction to be unenforceable in whole or in part.
**9. Critical Applications.** Unless XMOS has agreed in writing with you an agreement specifically governing use of the Goods in military, aerospace, automotive or medically related functions (collectively and individually hereinafter referred to as "Special Use"), any permitted use of the Software excludes Special Use. Notwithstanding any agreement between XMOS and you for Special Use, Special Use shall be at your own risk, and you shall fully indemnify XMOS against any damages, losses, costs and claims (direct and indirect) arising out of any Special Use.
**10. NO WARRANTY OR SUPPORT.** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL XMOS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, WARRANTY, CIVIL TORT (INCLUDING NEGLIGENCE), PRODUCTS LIABILITY OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE INCLUDING GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES EVEN IF SUCH PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES AND NOT WITHSTANDING THE FAILURE OF ESSENTIAL PURPOSE. IN SOME JURISDICTIONS PARTIES ARE UNABLE TO LIMIT LIABILTY IN THIS WAY, IF THIS APPLIES TO YOUR JURISDICTION THIS LIABILITY CLAUSE ABOVE MAY NOT APPLY. NOTWITHSTANDING THE ABOVE, IN NO EVENT SHALL XMOSs TOTAL LIABILITY TO YOU FOR ALL DAMAGES, LOSS OR OTHERWISE EXCEED $50.
**11. Governing Law and Jurisdiction.** This Licence constitutes the entire agreement between the parties with respect to the subject matter hereof. The Licence shall be governed by the laws of England and the conflict of laws and UN Convention on Contracts for the International Sale of Goods, shall not apply.

View File

@@ -0,0 +1,34 @@
# The TARGET variable determines what target system the application is
# compiled for. It either refers to an XN file in the source directories
# or a valid argument for the --target option when compiling
TARGET ?= XCORE-200-EXPLORER
ifeq ($(XCORE_AI), 1)
TARGET = XCORE-AI-EXPLORER
endif
# The APP_NAME variable determines the name of the final .xe file. It should
# not include the .xe postfix. If left blank the name will default to
# the project name
APP_NAME = i2s_frame_loopback_demo
# The USED_MODULES variable lists other module used by the application.
USED_MODULES = lib_gpio(>=1.1.0) lib_i2c(>=5.0.0) lib_i2s(>=3.0.0) lib_logging(>=2.1.0)
# The flags passed to xcc when building the application
# You can also set the following to override flags for a particular language:
# XCC_XC_FLAGS, XCC_C_FLAGS, XCC_ASM_FLAGS, XCC_CPP_FLAGS
# If the variable XCC_MAP_FLAGS is set it overrides the flags passed to
# xcc for the final link (mapping) stage.
XCC_FLAGS = -O2 -g -report
# The XCORE_ARM_PROJECT variable, if set to 1, configures this
# project to create both xCORE and ARM binaries.
XCORE_ARM_PROJECT = 0
#=============================================================================
# The following part of the Makefile includes the common build infrastructure
# for compiling XMOS applications. You should not need to edit below here.
XMOS_MAKE_PATH ?= ../..
include $(XMOS_MAKE_PATH)/xcommon/module_xcommon/build/Makefile.common

View File

@@ -0,0 +1,57 @@
<?xml version="1.0" encoding="UTF-8"?>
<Network xmlns="http://www.xmos.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.xmos.com http://www.xmos.com" ManuallySpecifiedRouting="true">
<Type>Board</Type>
<Name>xCORE-200 MC Audio</Name>
<Declarations>
<Declaration>tileref tile[2]</Declaration>
<Declaration>tileref usb_tile</Declaration>
</Declarations>
<Packages>
<Package id="0" Type="XS2-UEnA-512-FB236">
<Nodes>
<Node Id="0" InPackageId="0" Type="XS2-L16A-512" OscillatorSrc="1" SystemFrequency="500MHz">
<Boot>
<Source Location="bootFlash"/>
</Boot>
<Tile Number="0" Reference="tile[0]">
<Port Location="XS1_PORT_1B" Name="PORT_SQI_CS"/>
<Port Location="XS1_PORT_1C" Name="PORT_SQI_SCLK"/>
<Port Location="XS1_PORT_4B" Name="PORT_SQI_SIO"/>
</Tile>
<Tile Number="1" Reference="tile[1]"/>
</Node>
<Node Id="1" InPackageId="1" Type="periph:XS1-SU" Reference="usb_tile" Oscillator="24MHz">
</Node>
</Nodes>
<Links>
<Link Encoding="5wire">
<LinkEndpoint NodeId="0" Link="8" Delays="52clk,52clk"/>
<LinkEndpoint NodeId="1" Link="0" Delays="1clk,1clk"/>
</Link>
</Links>
</Package>
</Packages>
<Nodes>
<Node Id="2" Type="device:" RoutingId="0x8000">
<Service Id="0" Proto="xscope_host_data(chanend c);">
<Chanend Identifier="c" end="3"/>
</Service>
</Node>
</Nodes>
<Links>
<Link Encoding="2wire" Delays="4,4" Flags="XSCOPE">
<LinkEndpoint NodeId="0" Link="0"/>
<LinkEndpoint NodeId="2" Chanend="1"/>
</Link>
</Links>
<ExternalDevices>
<Device NodeId="0" Tile="0" Class="SQIFlash" Name="bootFlash" Type="S25FL116K" PageSize="256" SectorSize="4096" NumPages="8192">
<Attribute Name="PORT_SQI_CS" Value="PORT_SQI_CS"/>
<Attribute Name="PORT_SQI_SCLK" Value="PORT_SQI_SCLK"/>
<Attribute Name="PORT_SQI_SIO" Value="PORT_SQI_SIO"/>
</Device>
</ExternalDevices>
<JTAGChain>
<JTAGDevice NodeId="0"/>
</JTAGChain>
</Network>

View File

@@ -0,0 +1,170 @@
// Copyright 2014-2021 XMOS LIMITED.
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
#include <platform.h>
#include <xs1.h>
#include "i2s.h"
#include "i2c.h"
#include "gpio.h"
#include "xassert.h"
#include <print.h>
#include <stdlib.h>
#define SAMPLE_FREQUENCY (192000)
#define MASTER_CLOCK_FREQUENCY (24576000)
#define DATA_BITS (32)
/* Ports and clocks used by the application */
on tile[0]: out buffered port:32 p_lrclk = XS1_PORT_1G;
on tile[0]: out port p_bclk = XS1_PORT_1H;
on tile[0]: in port p_mclk = XS1_PORT_1F;
on tile[0]: out buffered port:32 p_dout[4] = {XS1_PORT_1M, XS1_PORT_1N, XS1_PORT_1O, XS1_PORT_1P};
on tile[0]: in buffered port:32 p_din[4] = {XS1_PORT_1I, XS1_PORT_1J, XS1_PORT_1K, XS1_PORT_1L};
on tile[0]: clock bclk = XS1_CLKBLK_1;
on tile[0]: port p_i2c = XS1_PORT_4A;
on tile[0]: port p_gpio = XS1_PORT_8C;
#define CS5368_ADDR (0x4C) // I2C address of the CS5368 DAC
#define CS5368_GCTL_MDE (0x01) // I2C mode control register number
#define CS5368_PWR_DN (0x06)
#define CS4384_ADDR (0x18) // I2C address of the CS4384 ADC
#define CS4384_MODE_CTRL (0x02) // I2C mode control register number
#define CS4384_PCM_CTRL (0x03) // I2C PCM control register number
enum gpio_shared_audio_pins {
GPIO_DAC_RST_N = 1,
GPIO_PLL_SEL = 5, // 1 = CS2100, 0 = Phaselink clock source
GPIO_ADC_RST_N = 6,
GPIO_MCLK_FSEL = 7, // Select frequency on Phaselink clock. 0 = 24.576MHz for 48k, 1 = 22.5792MHz for 44.1k.
};
void reset_codecs(client i2c_master_if i2c)
{
/* Mode Control 1 (Address: 0x02) */
/* bit[7] : Control Port Enable (CPEN) : Set to 1 for enable
* bit[6] : Freeze controls (FREEZE) : Set to 1 for freeze
* bit[5] : PCM/DSD Selection (DSD/PCM) : Set to 0 for PCM
* bit[4:1] : DAC Pair Disable (DACx_DIS) : All Dac Pairs enabled
* bit[0] : Power Down (PDN) : Powered down
*/
i2c.write_reg(CS4384_ADDR, CS4384_MODE_CTRL, 0b11000001);
/* PCM Control (Address: 0x03) */
/* bit[7:4] : Digital Interface Format (DIF) : 0b1100 for TDM
* bit[3:2] : Reserved
* bit[1:0] : Functional Mode (FM) : 0x11 for auto-speed detect (32 to 200kHz)
*/
i2c.write_reg(CS4384_ADDR, CS4384_PCM_CTRL, 0b00010111);
/* Mode Control 1 (Address: 0x02) */
/* bit[7] : Control Port Enable (CPEN) : Set to 1 for enable
* bit[6] : Freeze controls (FREEZE) : Set to 0 for freeze
* bit[5] : PCM/DSD Selection (DSD/PCM) : Set to 0 for PCM
* bit[4:1] : DAC Pair Disable (DACx_DIS) : All Dac Pairs enabled
* bit[0] : Power Down (PDN) : Not powered down
*/
i2c.write_reg(CS4384_ADDR, CS4384_MODE_CTRL, 0b10000000);
unsigned adc_dif = 0x01; // I2S mode
unsigned adc_mode = 0x03; // Slave mode all speeds
/* Reg 0x01: (GCTL) Global Mode Control Register */
/* Bit[7]: CP-EN: Manages control-port mode
* Bit[6]: CLKMODE: Setting puts part in 384x mode
* Bit[5:4]: MDIV[1:0]: Set to 01 for /2
* Bit[3:2]: DIF[1:0]: Data Format: 0x01 for I2S, 0x02 for TDM
* Bit[1:0]: MODE[1:0]: Mode: 0x11 for slave mode
*/
i2c.write_reg(CS5368_ADDR, CS5368_GCTL_MDE, 0b10010000 | (adc_dif << 2) | adc_mode);
/* Reg 0x06: (PDN) Power Down Register */
/* Bit[7:6]: Reserved
* Bit[5]: PDN-BG: When set, this bit powers-own the bandgap reference
* Bit[4]: PDM-OSC: Controls power to internal oscillator core
* Bit[3:0]: PDN: When any bit is set all clocks going to that channel pair are turned off
*/
i2c.write_reg(CS5368_ADDR, CS5368_PWR_DN, 0b00000000);
}
[[distributable]]
void i2s_loopback(server i2s_frame_callback_if i2s,
client i2c_master_if i2c,
client output_gpio_if dac_reset,
client output_gpio_if adc_reset,
client output_gpio_if pll_select,
client output_gpio_if mclk_select
)
{
int32_t samples[8] = {0, 0, 0, 0, 0, 0, 0, 0};
while (1) {
select {
case i2s.init(i2s_config_t &?i2s_config, tdm_config_t &?tdm_config):
i2s_config.mode = I2S_MODE_I2S;
i2s_config.mclk_bclk_ratio = (MASTER_CLOCK_FREQUENCY/SAMPLE_FREQUENCY)/64;
// Set CODECs in reset
dac_reset.output(0);
adc_reset.output(0);
// Select 48Khz family clock (24.576Mhz)
mclk_select.output(1);
pll_select.output(0);
// Allow the clock to settle
delay_milliseconds(2);
// Take CODECs out of reset
dac_reset.output(1);
adc_reset.output(1);
reset_codecs(i2c);
break;
case i2s.receive(size_t num_chan_in, int32_t sample[num_chan_in]):
for (size_t i=0; i<num_chan_in; i++) {
samples[i] = sample[i];
}
break;
case i2s.send(size_t num_chan_out, int32_t sample[num_chan_out]):
for (size_t i=0; i<num_chan_out; i++){
sample[i] = samples[i];
}
break;
case i2s.restart_check() -> i2s_restart_t restart:
restart = I2S_NO_RESTART;
break;
}
}
}
static char gpio_pin_map[4] = {
GPIO_DAC_RST_N,
GPIO_ADC_RST_N,
GPIO_PLL_SEL,
GPIO_MCLK_FSEL
};
int main()
{
interface i2s_frame_callback_if i_i2s;
interface i2c_master_if i_i2c[1];
interface output_gpio_if i_gpio[4];
par {
on tile[0]: i2s_frame_master(i_i2s, p_dout, 4, p_din, 4, DATA_BITS, p_bclk, p_lrclk, p_mclk, bclk);
on tile[0]: [[distribute]] i2c_master_single_port(i_i2c, 1, p_i2c, 100, 0, 1, 0);
on tile[0]: [[distribute]] output_gpio(i_gpio, 4, p_gpio, gpio_pin_map);
/* The application - loopback the I2S samples */
on tile[0]: [[distribute]] i2s_loopback(i_i2s, i_i2c[0], i_gpio[0], i_gpio[1], i_gpio[2], i_gpio[3]);
}
return 0;
}

View File

@@ -0,0 +1,14 @@
def options(opt):
opt.load('xwaf.xcommon')
def configure(conf):
conf.load('xwaf.xcommon')
def build(bld):
bld.do_xcommon()
def dist(ctx):
ctx.load('xwaf.xcommon')
def distcheck(ctx):
ctx.load('xwaf.xcommon')

View File

@@ -0,0 +1,84 @@
*******************************
XMOS PUBLIC LICENCE: Version 1
*******************************
Subject to the conditions and limitations below, permission is hereby granted by XMOS LIMITED (“XMOS”), free of charge, to any person or entity obtaining a copy of the XMOS Software.
**1. Definitions**
**“Applicable Patent Rights”** means: (a) where XMOS is the grantor of the rights, (i) claims of patents that are now or in future owned by or assigned to XMOS and (ii) that cover subject matter contained in the Software, but only to the extent it is necessary to use, reproduce or distribute the Software without infringement; and (b) where you are the grantor of the rights, (i) claims of patents that are now or in future owned by or assigned to you and (ii) that cover the subject matter contained in your Derivatives, taken alone or in combination with the Software.
**“Compiled Code”** means any compiled, binary, machine readable or executable version of the Source Code.
**“Contributor”** means any person or entity that creates or contributes to the creation of Derivatives.
**“Derivatives”** means any addition to, deletion from and/or change to the substance, structure of the Software, any previous Derivatives, the combination of the Derivatives and the Software and/or any respective portions thereof.
**“Source Code”** means the human readable code that is suitable for making modifications but excluding any Compiled Code.
**“Software”** means the software and associated documentation files which XMOS makes available and which contain a notice identifying the software as original XMOS software and referring to the software being subject to the terms of this XMOS Public Licence.
This Licence refers to XMOS Software and does not relate to any XMOS hardware or devices which are protected by intellectual property rights (including patent and trade marks) which may be sold to you under a separate agreement.
**2. Licence**
**Permitted Uses, Conditions and Restrictions.** Subject to the conditions below, XMOS grants you a worldwide, royalty free, non-exclusive licence, to the extent of any Patent Rights to do the following:
2.1 **Unmodified Software.** You may use, copy, display, publish, distribute and make available unmodified copies of the Software:
2.1.1 for personal or academic, non-commercial purposes; or
2.1.2 for commercial purposes provided the Software is at all times used on a device designed, licensed or developed by XMOS and, provided that in each instance (2.1.1 and 2.1.2):
(a) you must retain and reproduce in all copies of the Software the copyright and proprietary notices and disclaimers of XMOS as they appear in the Software, and keep intact all notices and disclaimers in the Software files that refer to this Licence; and
(b) you must include a copy of this Licence with every copy of the Software and documentation you publish, distribute and make available and you may not offer or impose any terms on such Software that alter or restrict this Licence or the intent of such Licence, except as permitted below (Additional Terms).
The licence above does not include any Compiled Code which XMOS may make available under a separate support and licence agreement.
2.2 **Derivatives.** You may create and modify Derivatives and use, copy, display, publish, distribute and make available Derivatives:
2.2.1 for personal or academic, non-commercial purposes; or
2.2.2 for commercial purposes, provided the Derivatives are at all times used on a device designed, licensed or developed by XMOS and, provided that in each instance (2.2.1 and 2.2.2):
(a) you must comply with the terms of clause 2.1 with respect to the Derivatives;
(b) you must copy (to the extent it doesnt already exist) the notice below in each file of the Derivatives, and ensure all the modified files carry prominent notices stating that you have changed the files and the date of any change; and
(c) if you sublicence, distribute or otherwise make the Software and/or the Derivatives available for commercial purposes, you must provide that the Software and Derivatives are at all times used on a device designed, licensed or developed by XMOS.
Without limitation to these terms and clause 3 below, the Source Code and Compiled Code to your Derivatives may at your discretion (but without obligation) be released, copied, displayed, published, distributed and made available; and if you elect to do so, it must be under the terms of this Licence including the terms of the licence at clauses 2.2.1, 2.2.2 and clause 3 below.
2.3 **Distribution of Executable Versions.** If you distribute or make available Derivatives, you must include a prominent notice in the code itself as well as in all related documentation, stating that the Source Code of the Software from which the Derivatives are based is available under the terms of this Licence, with information on how and where to obtain such Source Code.
**3. Your Grant of Rights.** In consideration and as a condition to this Licence, you grant to any person or entity receiving or distributing any Derivatives, a non-exclusive, royalty free, perpetual, irrevocable license under your Applicable Patent Rights and all other intellectual property rights owned or controlled by you, to use, copy, display, publish, distribute and make available your Derivatives of the same scope and extent as XMOSs licence under clause 2.2 above.
**4. Combined Products.** You may create a combined product by combining Software, Derivatives and other code not covered by this Licence as a single application or product. In such instance, you must comply with the requirements of this Licence for any portion of the Software and/or Derivatives.
**5. Additional Terms.** You may choose to offer, and to charge a fee for, warranty, support, indemnity or liability obligations and/or other rights consistent with the term of this Licence (“Additional Terms”) to any legitimate recipients of the Software and/or Derivatives. The terms on which you provide such Additional Terms are on your sole responsibility and you shall indemnify, defend and hold XMOS harmless against any claims asserted against XMOS.
**6. New Versions.** XMOS may publish revised and/or new versions of this Licence from time to time to accommodate changes to the Licence terms, new versions, updates and bug fixes of the Software. Each version will be given a distinguishing version number. Once Software has been published under a particular version of this Licence, you may continue to use it under the terms of that version. You may also choose to use the latest version of the Software under any subsequent version published by XMOS. Only XMOS shall have the right to modify these terms.
**7. IPR and Ownership**
Any rights, including all intellectual property rights and all trademarks not expressly granted herein are reserved in full by the authors or copyright holders. Any requests for additional permissions by XMOS including any rights to use XMOS trademarks, should be made (without obligation) to XMOS at **support@xmos.com**
Nothing herein shall limit any rights that XMOS is otherwise entitled to under the doctrines of patent exhaustion, implied license, or legal estoppel. Neither the name of the authors, the copyright holders or any contributors may be used to endorse or promote any Derivatives from this Software without specific written permission. Any attempt to deal with the Software which does not comply with this Licence shall be void and shall automatically terminate any rights granted under this licence (including any licence of any intellectual property rights granted herein).
Subject to the licences granted under this Licence any Contributor retains all rights, title and interest in and to any Derivatives made by Contributor subject to the underlying rights of XMOS in the Software. XMOS shall retain all rights, title and interest in the Software and any Derivatives made by XMOS (“XMOS Derivatives”). XMOS Derivatives will not automatically be subject to this Licence and XMOS shall be entitled to licence such rights on any terms (without obligation) as it sees fit.
**8. Termination**
8.1 This Licence will automatically terminate immediately, without notice to you, if:
(a) you fail to comply with the terms of this Licence; and/or
(b) you directly or indirectly commence any action for patent or intellectual property right infringement against XMOS, or any parent, group, affiliate or subsidiary of XMOS; provided XMOS did not first commence an action or patent infringement against you in that instance; and/or
(c) the terms of this Licence are held by any court of competent jurisdiction to be unenforceable in whole or in part.
**9. Critical Applications.** Unless XMOS has agreed in writing with you an agreement specifically governing use of the Goods in military, aerospace, automotive or medically related functions (collectively and individually hereinafter referred to as "Special Use"), any permitted use of the Software excludes Special Use. Notwithstanding any agreement between XMOS and you for Special Use, Special Use shall be at your own risk, and you shall fully indemnify XMOS against any damages, losses, costs and claims (direct and indirect) arising out of any Special Use.
**10. NO WARRANTY OR SUPPORT.** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL XMOS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, WARRANTY, CIVIL TORT (INCLUDING NEGLIGENCE), PRODUCTS LIABILITY OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE INCLUDING GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES EVEN IF SUCH PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES AND NOT WITHSTANDING THE FAILURE OF ESSENTIAL PURPOSE. IN SOME JURISDICTIONS PARTIES ARE UNABLE TO LIMIT LIABILTY IN THIS WAY, IF THIS APPLIES TO YOUR JURISDICTION THIS LIABILITY CLAUSE ABOVE MAY NOT APPLY. NOTWITHSTANDING THE ABOVE, IN NO EVENT SHALL XMOSs TOTAL LIABILITY TO YOU FOR ALL DAMAGES, LOSS OR OTHERWISE EXCEED $50.
**11. Governing Law and Jurisdiction.** This Licence constitutes the entire agreement between the parties with respect to the subject matter hereof. The Licence shall be governed by the laws of England and the conflict of laws and UN Convention on Contracts for the International Sale of Goods, shall not apply.

View File

@@ -0,0 +1,30 @@
# The TARGET variable determines what target system the application is
# compiled for. It either refers to an XN file in the source directories
# or a valid argument for the --target option when compiling
TARGET ?= XCORE-200-EXPLORER
ifeq ($(XCORE_AI), 1)
TARGET = XCORE-AI-EXPLORER
endif
# The APP_NAME variable determines the name of the final .xe file. It should
# not include the .xe postfix. If left blank the name will default to
# the project name
APP_NAME =
# The USED_MODULES variable lists other module used by the application.
USED_MODULES = lib_logging(>=3.2.0) lib_gpio(>=1.1.0) lib_i2c(>=5.0.0) lib_i2s(>=3.0.0)
# The flags passed to xcc when building the application
# You can also set the following to override flags for a particular language:
# XCC_XC_FLAGS, XCC_C_FLAGS, XCC_ASM_FLAGS, XCC_CPP_FLAGS
# If the variable XCC_MAP_FLAGS is set it overrides the flags passed to
# xcc for the final link (mapping) stage.
XCC_FLAGS = $(EXTRA_FLAGS) -O3 -report -g -DSIM_LOOPBACK_TEST=0 -DDEBUG_PRINT_ENABLE=1
#=============================================================================
# The following part of the Makefile includes the common build infrastructure
# for compiling XMOS applications. You should not need to edit below here.
XMOS_MAKE_PATH ?= ../..
include $(XMOS_MAKE_PATH)/xcommon/module_xcommon/build/Makefile.common

View File

@@ -0,0 +1,57 @@
<?xml version="1.0" encoding="UTF-8"?>
<Network xmlns="http://www.xmos.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.xmos.com http://www.xmos.com" ManuallySpecifiedRouting="true">
<Type>Board</Type>
<Name>xCORE-200 MC Audio</Name>
<Declarations>
<Declaration>tileref tile[2]</Declaration>
<Declaration>tileref usb_tile</Declaration>
</Declarations>
<Packages>
<Package id="0" Type="XS2-UEnA-512-FB236">
<Nodes>
<Node Id="0" InPackageId="0" Type="XS2-L16A-512" OscillatorSrc="1" SystemFrequency="500MHz">
<Boot>
<Source Location="bootFlash"/>
</Boot>
<Tile Number="0" Reference="tile[0]">
<Port Location="XS1_PORT_1B" Name="PORT_SQI_CS"/>
<Port Location="XS1_PORT_1C" Name="PORT_SQI_SCLK"/>
<Port Location="XS1_PORT_4B" Name="PORT_SQI_SIO"/>
</Tile>
<Tile Number="1" Reference="tile[1]"/>
</Node>
<Node Id="1" InPackageId="1" Type="periph:XS1-SU" Reference="usb_tile" Oscillator="24MHz">
</Node>
</Nodes>
<Links>
<Link Encoding="5wire">
<LinkEndpoint NodeId="0" Link="8" Delays="52clk,52clk"/>
<LinkEndpoint NodeId="1" Link="0" Delays="1clk,1clk"/>
</Link>
</Links>
</Package>
</Packages>
<Nodes>
<Node Id="2" Type="device:" RoutingId="0x8000">
<Service Id="0" Proto="xscope_host_data(chanend c);">
<Chanend Identifier="c" end="3"/>
</Service>
</Node>
</Nodes>
<Links>
<Link Encoding="2wire" Delays="4,4" Flags="XSCOPE">
<LinkEndpoint NodeId="0" Link="0"/>
<LinkEndpoint NodeId="2" Chanend="1"/>
</Link>
</Links>
<ExternalDevices>
<Device NodeId="0" Tile="0" Class="SQIFlash" Name="bootFlash" Type="S25FL116K" PageSize="256" SectorSize="4096" NumPages="8192">
<Attribute Name="PORT_SQI_CS" Value="PORT_SQI_CS"/>
<Attribute Name="PORT_SQI_SCLK" Value="PORT_SQI_SCLK"/>
<Attribute Name="PORT_SQI_SIO" Value="PORT_SQI_SIO"/>
</Device>
</ExternalDevices>
<JTAGChain>
<JTAGDevice NodeId="0"/>
</JTAGChain>
</Network>

View File

@@ -0,0 +1,274 @@
// Copyright 2014-2022 XMOS LIMITED.
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
#include <platform.h>
#include <xs1.h>
#include "i2s.h"
#include "i2c.h"
#include "gpio.h"
#include "xassert.h"
#include <stdlib.h>
#include <debug_print.h>
#include <string.h>
#define TEST_LENGTH (8) // Number of I2S frames to check
#ifndef NUM_I2S_LINES
#define NUM_I2S_LINES (4)
#endif
#ifndef SAMPLE_FREQUENCY
#define SAMPLE_FREQUENCY (192000)
#endif
#ifndef MASTER_CLOCK_FREQUENCY
#define MASTER_CLOCK_FREQUENCY (24576000)
#endif
#ifndef SIM_LOOPBACK_TEST
#define SIM_LOOPBACK_TEST (0)
#endif
#ifndef DATA_BITS
#define DATA_BITS (32)
#endif
/* Ports and clocks used by the application */
on tile[0]: in buffered port:32 p_lrclk = XS1_PORT_1G;
on tile[0]: in port p_bclk = XS1_PORT_1H;
on tile[0]: out buffered port:32 p_dout[4] = {XS1_PORT_1M, XS1_PORT_1N, XS1_PORT_1O, XS1_PORT_1P};
on tile[0]: in buffered port:32 p_din[4] = {XS1_PORT_1I, XS1_PORT_1J, XS1_PORT_1K, XS1_PORT_1L};
on tile[0]: clock clk_bclk = XS1_CLKBLK_2;
on tile[0]: port p_i2c = XS1_PORT_4A;
on tile[0]: port p_gpio = XS1_PORT_8C;
enum gpio_shared_audio_pins {
GPIO_DAC_RST_N = 1,
GPIO_PLL_SEL = 5, // 1 = CS2100, 0 = Phaselink clock source
GPIO_ADC_RST_N = 6,
GPIO_MCLK_FSEL = 7, // Select frequency on Phaselink clock. 0 = 24.576MHz for 48k, 1 = 22.5792MHz for 44.1k.
};
#define CS5368_ADDR (0x4C) // I2C address of the CS5368 DAC
#define CS5368_GCTL_MDE (0x01) // I2C mode control register number
#define CS5368_PWR_DN (0x06)
#define CS4384_ADDR (0x18) // I2C address of the CS4384 ADC
#define CS4384_MODE_CTRL (0x02) // I2C mode control register number
#define CS4384_PCM_CTRL (0x03) // I2C PCM control register number
//Simulator master I2S waveform gen
on tile[0]: out port p_mclk_gen = XS1_PORT_1A;
on tile[0]: clock clk_audio_mclk_gen = XS1_CLKBLK_3;
on tile[0]: out port p_bclk_gen = XS1_PORT_1B;
on tile[0]: clock clk_audio_bclk_gen = XS1_CLKBLK_4;
on tile[0]: out port p_lrclk_gen = XS1_PORT_1C;
on tile[0]: clock clk_audio_lrclk_gen = XS1_CLKBLK_5;
void reset_codecs(client i2c_master_if i2c)
{
/* Mode Control 1 (Address: 0x02) */
/* bit[7] : Control Port Enable (CPEN) : Set to 1 for enable
* bit[6] : Freeze controls (FREEZE) : Set to 1 for freeze
* bit[5] : PCM/DSD Selection (DSD/PCM) : Set to 0 for PCM
* bit[4:1] : DAC Pair Disable (DACx_DIS) : All Dac Pairs enabled
* bit[0] : Power Down (PDN) : Powered down
*/
i2c.write_reg(CS4384_ADDR, CS4384_MODE_CTRL, 0b11000001);
/* PCM Control (Address: 0x03) */
/* bit[7:4] : Digital Interface Format (DIF) : 0b1100 for TDM
* bit[3:2] : Reserved
* bit[1:0] : Functional Mode (FM) : 0x11 for auto-speed detect (32 to 200kHz)
*/
i2c.write_reg(CS4384_ADDR, CS4384_PCM_CTRL, 0b00010111);
/* Mode Control 1 (Address: 0x02) */
/* bit[7] : Control Port Enable (CPEN) : Set to 1 for enable
* bit[6] : Freeze controls (FREEZE) : Set to 0 for freeze
* bit[5] : PCM/DSD Selection (DSD/PCM) : Set to 0 for PCM
* bit[4:1] : DAC Pair Disable (DACx_DIS) : All Dac Pairs enabled
* bit[0] : Power Down (PDN) : Not powered down
*/
i2c.write_reg(CS4384_ADDR, CS4384_MODE_CTRL, 0b10000000);
unsigned adc_dif = 0x01; // I2S mode
const unsigned samFreq = SAMPLE_FREQUENCY;
unsigned adc_mode;
if(samFreq < 54000)
adc_mode = 0x00; /* Single-speed Mode Master */
else if(samFreq < 108000)
adc_mode = 0x01; /* Double-speed Mode Master */
else if(samFreq < 216000)
adc_mode = 0x02; /* Quad-speed Mode Master */
/* Reg 0x01: (GCTL) Global Mode Control Register */
/* Bit[7]: CP-EN: Manages control-port mode
* Bit[6]: CLKMODE: Setting puts part in 384x mode
* Bit[5:4]: MDIV[1:0]: Set to 01 for /2
* Bit[3:2]: DIF[1:0]: Data Format: 0x01 for I2S, 0x02 for TDM
* Bit[1:0]: MODE[1:0]: Mode: 0x11 for slave mode
*/
i2c.write_reg(CS5368_ADDR, CS5368_GCTL_MDE, 0b10010000 | (adc_dif << 2) | adc_mode);
/* Reg 0x06: (PDN) Power Down Register */
/* Bit[7:6]: Reserved
* Bit[5]: PDN-BG: When set, this bit powers-own the bandgap reference
* Bit[4]: PDM-OSC: Controls power to internal oscillator core
* Bit[3:0]: PDN: When any bit is set all clocks going to that channel pair are turned off
*/
i2c.write_reg(CS5368_ADDR, CS5368_PWR_DN, 0b00000000);
}
void slave_mode_clk_setup_sim(const unsigned samFreq, const unsigned chans_per_frame){
const unsigned data_bits = DATA_BITS;
const unsigned mclk_freq = MASTER_CLOCK_FREQUENCY;
const unsigned mclk_freq_round_up = (mclk_freq / 1000000) + 1;
const unsigned mclk_bclk_ratio = mclk_freq / (chans_per_frame * samFreq * data_bits);
const unsigned bclk_lrclk_ratio = (chans_per_frame * data_bits); // 48.828Hz LRCLK
debug_printf("mclk:bclk - %d\nbclk_lrclk - %d\nmclk_freq_round_up - %d\n", mclk_bclk_ratio, bclk_lrclk_ratio, mclk_freq_round_up);
//bclk generator
configure_clock_src_divide(clk_audio_bclk_gen, p_mclk_gen, mclk_bclk_ratio/2);
configure_port_clock_output(p_bclk_gen, clk_audio_bclk_gen);
start_clock(clk_audio_bclk_gen);
//lrclk generator
configure_clock_src_divide(clk_audio_lrclk_gen, p_bclk_gen, bclk_lrclk_ratio/2);
configure_port_clock_output(p_lrclk_gen, clk_audio_lrclk_gen);
start_clock(clk_audio_lrclk_gen);
//mclk generator
configure_clock_rate(clk_audio_mclk_gen, mclk_freq_round_up, 1); // Slighly faster than typical MCLK of 24.576MHz
configure_port_clock_output(p_mclk_gen, clk_audio_mclk_gen);
start_clock(clk_audio_mclk_gen);
}
static char gpio_pin_map[4] = {
GPIO_DAC_RST_N,
GPIO_ADC_RST_N,
GPIO_PLL_SEL,
GPIO_MCLK_FSEL
};
//Generate psuedo-random test sequence
int32_t random(int32_t rand){
unsigned random = (unsigned)rand;
crc32(random, -1, 0xEB31D82E);
return (int32_t)random;
}
[[distributable]]
#pragma unsafe arrays
void i2s_handler(server i2s_frame_callback_if i_i2s, client i2c_master_if i_i2c,
client output_gpio_if dac_reset,
client output_gpio_if adc_reset,
client output_gpio_if pll_select,
client output_gpio_if mclk_select)
{
int32_t tx_data = 0xf00faa00; //Seed
int32_t rx_data = 0xf00faa00; //Seed
uint32_t cycle_count = 0;
int32_t loopback[NUM_I2S_LINES * 2] = {0};
while (1) {
select {
case i_i2s.init(i2s_config_t &?i2s_config, tdm_config_t &?tdm_config):
i2s_config.mode = I2S_MODE_I2S;
i2s_config.mclk_bclk_ratio = (MASTER_CLOCK_FREQUENCY/SAMPLE_FREQUENCY)/64;
if (SIM_LOOPBACK_TEST){
slave_mode_clk_setup_sim(SAMPLE_FREQUENCY, 2);
debug_printf("Initialse I2S on simulator\n");
}
else{
// Set CODECs in reset
dac_reset.output(0);
adc_reset.output(0);
// Select 48Khz family clock (24.576Mhz)
mclk_select.output(1);
pll_select.output(0);
// Allow the clock to settle
delay_milliseconds(2);
// Take CODECs out of reset
dac_reset.output(1);
adc_reset.output(1);
reset_codecs(i_i2c);
debug_printf("Initialse I2S on hardware\n");
delay_milliseconds(500); //Allow print to complete
}
break;
case i_i2s.receive(size_t num_chan_in, int32_t sample[num_chan_in]):
if(SIM_LOOPBACK_TEST){
for (size_t i=0; i<num_chan_in; i++) {
if(sample[i] != rx_data){
debug_printf("Rx from master at cycle %d. Data = 0x%x, expected = 0x%x\n", cycle_count, sample[i], rx_data);
fail("ERROR: Data mismatch");
}
else{
//debug_printf("OK\n");
}
rx_data = random(rx_data);
cycle_count++;
if (cycle_count >= TEST_LENGTH){
debug_printf("Test pass\n");
delay_microseconds(10); //Allow print to happen before we exit
_Exit(0);
}
}
}
else{
memcpy(loopback, sample, num_chan_in * sizeof(int32_t));
}
//delay_microseconds(19);
break;
case i_i2s.send(size_t num_chan_out, int32_t sample[num_chan_out]):
if(SIM_LOOPBACK_TEST){
for (size_t i=0; i<num_chan_out; i++){
sample[i] = tx_data;
tx_data = random(tx_data);
}
}
else{
memcpy(sample, loopback, num_chan_out * sizeof(int32_t));
}
//delay_microseconds(19);
break;
case i_i2s.restart_check() -> i2s_restart_t restart:
restart = I2S_NO_RESTART;
break;
}
}
}
int main()
{
interface i2s_frame_callback_if i_i2s_slave;
interface i2c_master_if i_i2c[1];
interface output_gpio_if i_gpio[4];
par {
on tile[0]: i2s_frame_slave(i_i2s_slave, p_dout, NUM_I2S_LINES, p_din, NUM_I2S_LINES, DATA_BITS, p_bclk, p_lrclk, clk_bclk);
on tile[0]: [[distribute]] i2c_master_single_port(i_i2c, 1, p_i2c, 100, 0, 1, 0);
on tile[0]: [[distribute]] output_gpio(i_gpio, 4, p_gpio, gpio_pin_map);
/* The application - loopback the I2S samples */
on tile[0]: [[distribute]] i2s_handler(i_i2s_slave, i_i2c[0], i_gpio[0], i_gpio[1], i_gpio[2], i_gpio[3]);
on tile[0]: par (int i=0; i<7; i++) while(1); //Burn threads to restrict i2s to 62.5MIPS
}
return 0;
}

View File

@@ -0,0 +1,14 @@
def options(opt):
opt.load('xwaf.xcommon')
def configure(conf):
conf.load('xwaf.xcommon')
def build(bld):
bld.do_xcommon()
def dist(ctx):
ctx.load('xwaf.xcommon')
def distcheck(ctx):
ctx.load('xwaf.xcommon')

View File

@@ -0,0 +1,84 @@
*******************************
XMOS PUBLIC LICENCE: Version 1
*******************************
Subject to the conditions and limitations below, permission is hereby granted by XMOS LIMITED (“XMOS”), free of charge, to any person or entity obtaining a copy of the XMOS Software.
**1. Definitions**
**“Applicable Patent Rights”** means: (a) where XMOS is the grantor of the rights, (i) claims of patents that are now or in future owned by or assigned to XMOS and (ii) that cover subject matter contained in the Software, but only to the extent it is necessary to use, reproduce or distribute the Software without infringement; and (b) where you are the grantor of the rights, (i) claims of patents that are now or in future owned by or assigned to you and (ii) that cover the subject matter contained in your Derivatives, taken alone or in combination with the Software.
**“Compiled Code”** means any compiled, binary, machine readable or executable version of the Source Code.
**“Contributor”** means any person or entity that creates or contributes to the creation of Derivatives.
**“Derivatives”** means any addition to, deletion from and/or change to the substance, structure of the Software, any previous Derivatives, the combination of the Derivatives and the Software and/or any respective portions thereof.
**“Source Code”** means the human readable code that is suitable for making modifications but excluding any Compiled Code.
**“Software”** means the software and associated documentation files which XMOS makes available and which contain a notice identifying the software as original XMOS software and referring to the software being subject to the terms of this XMOS Public Licence.
This Licence refers to XMOS Software and does not relate to any XMOS hardware or devices which are protected by intellectual property rights (including patent and trade marks) which may be sold to you under a separate agreement.
**2. Licence**
**Permitted Uses, Conditions and Restrictions.** Subject to the conditions below, XMOS grants you a worldwide, royalty free, non-exclusive licence, to the extent of any Patent Rights to do the following:
2.1 **Unmodified Software.** You may use, copy, display, publish, distribute and make available unmodified copies of the Software:
2.1.1 for personal or academic, non-commercial purposes; or
2.1.2 for commercial purposes provided the Software is at all times used on a device designed, licensed or developed by XMOS and, provided that in each instance (2.1.1 and 2.1.2):
(a) you must retain and reproduce in all copies of the Software the copyright and proprietary notices and disclaimers of XMOS as they appear in the Software, and keep intact all notices and disclaimers in the Software files that refer to this Licence; and
(b) you must include a copy of this Licence with every copy of the Software and documentation you publish, distribute and make available and you may not offer or impose any terms on such Software that alter or restrict this Licence or the intent of such Licence, except as permitted below (Additional Terms).
The licence above does not include any Compiled Code which XMOS may make available under a separate support and licence agreement.
2.2 **Derivatives.** You may create and modify Derivatives and use, copy, display, publish, distribute and make available Derivatives:
2.2.1 for personal or academic, non-commercial purposes; or
2.2.2 for commercial purposes, provided the Derivatives are at all times used on a device designed, licensed or developed by XMOS and, provided that in each instance (2.2.1 and 2.2.2):
(a) you must comply with the terms of clause 2.1 with respect to the Derivatives;
(b) you must copy (to the extent it doesnt already exist) the notice below in each file of the Derivatives, and ensure all the modified files carry prominent notices stating that you have changed the files and the date of any change; and
(c) if you sublicence, distribute or otherwise make the Software and/or the Derivatives available for commercial purposes, you must provide that the Software and Derivatives are at all times used on a device designed, licensed or developed by XMOS.
Without limitation to these terms and clause 3 below, the Source Code and Compiled Code to your Derivatives may at your discretion (but without obligation) be released, copied, displayed, published, distributed and made available; and if you elect to do so, it must be under the terms of this Licence including the terms of the licence at clauses 2.2.1, 2.2.2 and clause 3 below.
2.3 **Distribution of Executable Versions.** If you distribute or make available Derivatives, you must include a prominent notice in the code itself as well as in all related documentation, stating that the Source Code of the Software from which the Derivatives are based is available under the terms of this Licence, with information on how and where to obtain such Source Code.
**3. Your Grant of Rights.** In consideration and as a condition to this Licence, you grant to any person or entity receiving or distributing any Derivatives, a non-exclusive, royalty free, perpetual, irrevocable license under your Applicable Patent Rights and all other intellectual property rights owned or controlled by you, to use, copy, display, publish, distribute and make available your Derivatives of the same scope and extent as XMOSs licence under clause 2.2 above.
**4. Combined Products.** You may create a combined product by combining Software, Derivatives and other code not covered by this Licence as a single application or product. In such instance, you must comply with the requirements of this Licence for any portion of the Software and/or Derivatives.
**5. Additional Terms.** You may choose to offer, and to charge a fee for, warranty, support, indemnity or liability obligations and/or other rights consistent with the term of this Licence (“Additional Terms”) to any legitimate recipients of the Software and/or Derivatives. The terms on which you provide such Additional Terms are on your sole responsibility and you shall indemnify, defend and hold XMOS harmless against any claims asserted against XMOS.
**6. New Versions.** XMOS may publish revised and/or new versions of this Licence from time to time to accommodate changes to the Licence terms, new versions, updates and bug fixes of the Software. Each version will be given a distinguishing version number. Once Software has been published under a particular version of this Licence, you may continue to use it under the terms of that version. You may also choose to use the latest version of the Software under any subsequent version published by XMOS. Only XMOS shall have the right to modify these terms.
**7. IPR and Ownership**
Any rights, including all intellectual property rights and all trademarks not expressly granted herein are reserved in full by the authors or copyright holders. Any requests for additional permissions by XMOS including any rights to use XMOS trademarks, should be made (without obligation) to XMOS at **support@xmos.com**
Nothing herein shall limit any rights that XMOS is otherwise entitled to under the doctrines of patent exhaustion, implied license, or legal estoppel. Neither the name of the authors, the copyright holders or any contributors may be used to endorse or promote any Derivatives from this Software without specific written permission. Any attempt to deal with the Software which does not comply with this Licence shall be void and shall automatically terminate any rights granted under this licence (including any licence of any intellectual property rights granted herein).
Subject to the licences granted under this Licence any Contributor retains all rights, title and interest in and to any Derivatives made by Contributor subject to the underlying rights of XMOS in the Software. XMOS shall retain all rights, title and interest in the Software and any Derivatives made by XMOS (“XMOS Derivatives”). XMOS Derivatives will not automatically be subject to this Licence and XMOS shall be entitled to licence such rights on any terms (without obligation) as it sees fit.
**8. Termination**
8.1 This Licence will automatically terminate immediately, without notice to you, if:
(a) you fail to comply with the terms of this Licence; and/or
(b) you directly or indirectly commence any action for patent or intellectual property right infringement against XMOS, or any parent, group, affiliate or subsidiary of XMOS; provided XMOS did not first commence an action or patent infringement against you in that instance; and/or
(c) the terms of this Licence are held by any court of competent jurisdiction to be unenforceable in whole or in part.
**9. Critical Applications.** Unless XMOS has agreed in writing with you an agreement specifically governing use of the Goods in military, aerospace, automotive or medically related functions (collectively and individually hereinafter referred to as "Special Use"), any permitted use of the Software excludes Special Use. Notwithstanding any agreement between XMOS and you for Special Use, Special Use shall be at your own risk, and you shall fully indemnify XMOS against any damages, losses, costs and claims (direct and indirect) arising out of any Special Use.
**10. NO WARRANTY OR SUPPORT.** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL XMOS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, WARRANTY, CIVIL TORT (INCLUDING NEGLIGENCE), PRODUCTS LIABILITY OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE INCLUDING GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES EVEN IF SUCH PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES AND NOT WITHSTANDING THE FAILURE OF ESSENTIAL PURPOSE. IN SOME JURISDICTIONS PARTIES ARE UNABLE TO LIMIT LIABILTY IN THIS WAY, IF THIS APPLIES TO YOUR JURISDICTION THIS LIABILITY CLAUSE ABOVE MAY NOT APPLY. NOTWITHSTANDING THE ABOVE, IN NO EVENT SHALL XMOSs TOTAL LIABILITY TO YOU FOR ALL DAMAGES, LOSS OR OTHERWISE EXCEED $50.
**11. Governing Law and Jurisdiction.** This Licence constitutes the entire agreement between the parties with respect to the subject matter hereof. The Licence shall be governed by the laws of England and the conflict of laws and UN Convention on Contracts for the International Sale of Goods, shall not apply.

View File

@@ -0,0 +1,29 @@
# The TARGET variable determines what target system the application is
# compiled for. It either refers to an XN file in the source directories
# or a valid argument for the --target option when compiling
TARGET ?= XCORE-200-EXPLORER
ifeq ($(XCORE_AI), 1)
TARGET = XCORE-AI-EXPLORER
endif
# The USED_MODULES variable lists other module used by the application.
USED_MODULES = lib_i2s(>=5.0.0)
# The flags passed to xcc when building the application
# You can also set the following to override flags for a particular language:
# XCC_XC_FLAGS, XCC_C_FLAGS, XCC_ASM_FLAGS, XCC_CPP_FLAGS
# If the variable XCC_MAP_FLAGS is set it overrides the flags passed to
# xcc for the final link (mapping) stage.
XCC_FLAGS = -O2 -g -report
# The XCORE_ARM_PROJECT variable, if set to 1, configures this
# project to create both xCORE and ARM binaries.
XCORE_ARM_PROJECT = 0
#=============================================================================
# The following part of the Makefile includes the common build infrastructure
# for compiling XMOS applications. You should not need to edit below here.
XMOS_MAKE_PATH ?= ../..
include $(XMOS_MAKE_PATH)/xcommon/module_xcommon/build/Makefile.common

View File

@@ -0,0 +1,58 @@
// Copyright 2018-2022 XMOS LIMITED.
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
/* A simple application example used for code snippets in the library
* documentation.
*/
#include <platform.h>
#include <xs1.h>
#include "i2s.h"
#include <print.h>
#include <stdlib.h>
#define SAMPLE_FREQUENCY (192000)
#define MASTER_CLOCK_FREQUENCY (24576000)
#define DATA_BITS (32)
[[distributable]]
void my_application(server i2s_frame_callback_if i_i2s) {
while (1) {
select {
case i_i2s.init(i2s_config_t &?i2s_config, tdm_config_t &?tdm_config):
i2s_config.mclk_bclk_ratio = (MASTER_CLOCK_FREQUENCY / (SAMPLE_FREQUENCY*2*DATA_BITS));
i2s_config.mode = I2S_MODE_LEFT_JUSTIFIED;
// Complete setup
break;
case i_i2s.restart_check() -> i2s_restart_t restart:
// Inform the I2S slave whether it should restart or exit
restart = I2S_NO_RESTART;
break;
case i_i2s.receive(size_t num_in, int32_t samples[num_in]):
// Handle a received sample
break;
case i_i2s.send(size_t num_out, int32_t samples[num_out]):
// Provide a sample to send
break;
}
}
}
out buffered port:32 p_dout[2] = {XS1_PORT_1D, XS1_PORT_1E};
in buffered port:32 p_din[2] = {XS1_PORT_1I, XS1_PORT_1J};
out port p_bclk = XS1_PORT_1M;
out buffered port:32 p_lrclk = XS1_PORT_1A;
in port p_mclk = XS1_PORT_1B;
clock bclk = XS1_CLKBLK_1;
int main(void) {
i2s_frame_callback_if i_i2s;
par {
i2s_frame_master(i_i2s, p_dout, 2, p_din, 2, DATA_BITS, p_bclk, p_lrclk, p_mclk, bclk);
my_application(i_i2s);
}
return 0;
}
// end

View File

@@ -0,0 +1,14 @@
def options(opt):
opt.load('xwaf.xcommon')
def configure(conf):
conf.load('xwaf.xcommon')
def build(bld):
bld.do_xcommon()
def dist(ctx):
ctx.load('xwaf.xcommon')
def distcheck(ctx):
ctx.load('xwaf.xcommon')

View File

@@ -0,0 +1,84 @@
*******************************
XMOS PUBLIC LICENCE: Version 1
*******************************
Subject to the conditions and limitations below, permission is hereby granted by XMOS LIMITED (“XMOS”), free of charge, to any person or entity obtaining a copy of the XMOS Software.
**1. Definitions**
**“Applicable Patent Rights”** means: (a) where XMOS is the grantor of the rights, (i) claims of patents that are now or in future owned by or assigned to XMOS and (ii) that cover subject matter contained in the Software, but only to the extent it is necessary to use, reproduce or distribute the Software without infringement; and (b) where you are the grantor of the rights, (i) claims of patents that are now or in future owned by or assigned to you and (ii) that cover the subject matter contained in your Derivatives, taken alone or in combination with the Software.
**“Compiled Code”** means any compiled, binary, machine readable or executable version of the Source Code.
**“Contributor”** means any person or entity that creates or contributes to the creation of Derivatives.
**“Derivatives”** means any addition to, deletion from and/or change to the substance, structure of the Software, any previous Derivatives, the combination of the Derivatives and the Software and/or any respective portions thereof.
**“Source Code”** means the human readable code that is suitable for making modifications but excluding any Compiled Code.
**“Software”** means the software and associated documentation files which XMOS makes available and which contain a notice identifying the software as original XMOS software and referring to the software being subject to the terms of this XMOS Public Licence.
This Licence refers to XMOS Software and does not relate to any XMOS hardware or devices which are protected by intellectual property rights (including patent and trade marks) which may be sold to you under a separate agreement.
**2. Licence**
**Permitted Uses, Conditions and Restrictions.** Subject to the conditions below, XMOS grants you a worldwide, royalty free, non-exclusive licence, to the extent of any Patent Rights to do the following:
2.1 **Unmodified Software.** You may use, copy, display, publish, distribute and make available unmodified copies of the Software:
2.1.1 for personal or academic, non-commercial purposes; or
2.1.2 for commercial purposes provided the Software is at all times used on a device designed, licensed or developed by XMOS and, provided that in each instance (2.1.1 and 2.1.2):
(a) you must retain and reproduce in all copies of the Software the copyright and proprietary notices and disclaimers of XMOS as they appear in the Software, and keep intact all notices and disclaimers in the Software files that refer to this Licence; and
(b) you must include a copy of this Licence with every copy of the Software and documentation you publish, distribute and make available and you may not offer or impose any terms on such Software that alter or restrict this Licence or the intent of such Licence, except as permitted below (Additional Terms).
The licence above does not include any Compiled Code which XMOS may make available under a separate support and licence agreement.
2.2 **Derivatives.** You may create and modify Derivatives and use, copy, display, publish, distribute and make available Derivatives:
2.2.1 for personal or academic, non-commercial purposes; or
2.2.2 for commercial purposes, provided the Derivatives are at all times used on a device designed, licensed or developed by XMOS and, provided that in each instance (2.2.1 and 2.2.2):
(a) you must comply with the terms of clause 2.1 with respect to the Derivatives;
(b) you must copy (to the extent it doesnt already exist) the notice below in each file of the Derivatives, and ensure all the modified files carry prominent notices stating that you have changed the files and the date of any change; and
(c) if you sublicence, distribute or otherwise make the Software and/or the Derivatives available for commercial purposes, you must provide that the Software and Derivatives are at all times used on a device designed, licensed or developed by XMOS.
Without limitation to these terms and clause 3 below, the Source Code and Compiled Code to your Derivatives may at your discretion (but without obligation) be released, copied, displayed, published, distributed and made available; and if you elect to do so, it must be under the terms of this Licence including the terms of the licence at clauses 2.2.1, 2.2.2 and clause 3 below.
2.3 **Distribution of Executable Versions.** If you distribute or make available Derivatives, you must include a prominent notice in the code itself as well as in all related documentation, stating that the Source Code of the Software from which the Derivatives are based is available under the terms of this Licence, with information on how and where to obtain such Source Code.
**3. Your Grant of Rights.** In consideration and as a condition to this Licence, you grant to any person or entity receiving or distributing any Derivatives, a non-exclusive, royalty free, perpetual, irrevocable license under your Applicable Patent Rights and all other intellectual property rights owned or controlled by you, to use, copy, display, publish, distribute and make available your Derivatives of the same scope and extent as XMOSs licence under clause 2.2 above.
**4. Combined Products.** You may create a combined product by combining Software, Derivatives and other code not covered by this Licence as a single application or product. In such instance, you must comply with the requirements of this Licence for any portion of the Software and/or Derivatives.
**5. Additional Terms.** You may choose to offer, and to charge a fee for, warranty, support, indemnity or liability obligations and/or other rights consistent with the term of this Licence (“Additional Terms”) to any legitimate recipients of the Software and/or Derivatives. The terms on which you provide such Additional Terms are on your sole responsibility and you shall indemnify, defend and hold XMOS harmless against any claims asserted against XMOS.
**6. New Versions.** XMOS may publish revised and/or new versions of this Licence from time to time to accommodate changes to the Licence terms, new versions, updates and bug fixes of the Software. Each version will be given a distinguishing version number. Once Software has been published under a particular version of this Licence, you may continue to use it under the terms of that version. You may also choose to use the latest version of the Software under any subsequent version published by XMOS. Only XMOS shall have the right to modify these terms.
**7. IPR and Ownership**
Any rights, including all intellectual property rights and all trademarks not expressly granted herein are reserved in full by the authors or copyright holders. Any requests for additional permissions by XMOS including any rights to use XMOS trademarks, should be made (without obligation) to XMOS at **support@xmos.com**
Nothing herein shall limit any rights that XMOS is otherwise entitled to under the doctrines of patent exhaustion, implied license, or legal estoppel. Neither the name of the authors, the copyright holders or any contributors may be used to endorse or promote any Derivatives from this Software without specific written permission. Any attempt to deal with the Software which does not comply with this Licence shall be void and shall automatically terminate any rights granted under this licence (including any licence of any intellectual property rights granted herein).
Subject to the licences granted under this Licence any Contributor retains all rights, title and interest in and to any Derivatives made by Contributor subject to the underlying rights of XMOS in the Software. XMOS shall retain all rights, title and interest in the Software and any Derivatives made by XMOS (“XMOS Derivatives”). XMOS Derivatives will not automatically be subject to this Licence and XMOS shall be entitled to licence such rights on any terms (without obligation) as it sees fit.
**8. Termination**
8.1 This Licence will automatically terminate immediately, without notice to you, if:
(a) you fail to comply with the terms of this Licence; and/or
(b) you directly or indirectly commence any action for patent or intellectual property right infringement against XMOS, or any parent, group, affiliate or subsidiary of XMOS; provided XMOS did not first commence an action or patent infringement against you in that instance; and/or
(c) the terms of this Licence are held by any court of competent jurisdiction to be unenforceable in whole or in part.
**9. Critical Applications.** Unless XMOS has agreed in writing with you an agreement specifically governing use of the Goods in military, aerospace, automotive or medically related functions (collectively and individually hereinafter referred to as "Special Use"), any permitted use of the Software excludes Special Use. Notwithstanding any agreement between XMOS and you for Special Use, Special Use shall be at your own risk, and you shall fully indemnify XMOS against any damages, losses, costs and claims (direct and indirect) arising out of any Special Use.
**10. NO WARRANTY OR SUPPORT.** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL XMOS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, WARRANTY, CIVIL TORT (INCLUDING NEGLIGENCE), PRODUCTS LIABILITY OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE INCLUDING GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES EVEN IF SUCH PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES AND NOT WITHSTANDING THE FAILURE OF ESSENTIAL PURPOSE. IN SOME JURISDICTIONS PARTIES ARE UNABLE TO LIMIT LIABILTY IN THIS WAY, IF THIS APPLIES TO YOUR JURISDICTION THIS LIABILITY CLAUSE ABOVE MAY NOT APPLY. NOTWITHSTANDING THE ABOVE, IN NO EVENT SHALL XMOSs TOTAL LIABILITY TO YOU FOR ALL DAMAGES, LOSS OR OTHERWISE EXCEED $50.
**11. Governing Law and Jurisdiction.** This Licence constitutes the entire agreement between the parties with respect to the subject matter hereof. The Licence shall be governed by the laws of England and the conflict of laws and UN Convention on Contracts for the International Sale of Goods, shall not apply.

View File

@@ -0,0 +1,29 @@
# The TARGET variable determines what target system the application is
# compiled for. It either refers to an XN file in the source directories
# or a valid argument for the --target option when compiling
TARGET ?= XCORE-200-EXPLORER
ifeq ($(XCORE_AI), 1)
TARGET = XCORE-AI-EXPLORER
endif
# The USED_MODULES variable lists other module used by the application.
USED_MODULES = lib_i2s(>=5.0.0)
# The flags passed to xcc when building the application
# You can also set the following to override flags for a particular language:
# XCC_XC_FLAGS, XCC_C_FLAGS, XCC_ASM_FLAGS, XCC_CPP_FLAGS
# If the variable XCC_MAP_FLAGS is set it overrides the flags passed to
# xcc for the final link (mapping) stage.
XCC_FLAGS = -O2 -g -report
# The XCORE_ARM_PROJECT variable, if set to 1, configures this
# project to create both xCORE and ARM binaries.
XCORE_ARM_PROJECT = 0
#=============================================================================
# The following part of the Makefile includes the common build infrastructure
# for compiling XMOS applications. You should not need to edit below here.
XMOS_MAKE_PATH ?= ../..
include $(XMOS_MAKE_PATH)/xcommon/module_xcommon/build/Makefile.common

View File

@@ -0,0 +1,58 @@
// Copyright 2018-2022 XMOS LIMITED.
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
/* A simple application example used for code snippets in the library
* documentation.
*/
#include <platform.h>
#include <xs1.h>
#include "i2s.h"
#include <print.h>
#include <stdlib.h>
#define SAMPLE_FREQUENCY (192000)
#define MASTER_CLOCK_FREQUENCY (24576000)
#define DATA_BITS (32)
[[distributable]]
void my_application(server i2s_frame_callback_if i_i2s) {
while (1) {
select {
case i_i2s.init(i2s_config_t &?i2s_config, tdm_config_t &?tdm_config):
i2s_config.mclk_bclk_ratio = (MASTER_CLOCK_FREQUENCY / (SAMPLE_FREQUENCY*2*DATA_BITS));
i2s_config.mode = I2S_MODE_LEFT_JUSTIFIED;
// Complete setup
break;
case i_i2s.restart_check() -> i2s_restart_t restart:
// Inform the I2S slave whether it should restart or exit
restart = I2S_NO_RESTART;
break;
case i_i2s.receive(size_t num_in, int32_t samples[num_in]):
// Handle a received sample
break;
case i_i2s.send(size_t num_out, int32_t samples[num_out]):
// Provide a sample to send
break;
}
}
}
out buffered port:32 p_dout = XS1_PORT_4F;
in buffered port:32 p_din = XS1_PORT_4E;
out port p_bclk = XS1_PORT_1M;
out buffered port:32 p_lrclk = XS1_PORT_1A;
in port p_mclk = XS1_PORT_1B;
clock bclk = XS1_CLKBLK_1;
int main(void) {
i2s_frame_callback_if i_i2s;
par {
i2s_frame_master_4b(i_i2s, p_dout, 4, p_din, 4, p_bclk, p_lrclk, p_mclk, bclk);
my_application(i_i2s);
}
return 0;
}
// end

View File

@@ -0,0 +1,14 @@
def options(opt):
opt.load('xwaf.xcommon')
def configure(conf):
conf.load('xwaf.xcommon')
def build(bld):
bld.do_xcommon()
def dist(ctx):
ctx.load('xwaf.xcommon')
def distcheck(ctx):
ctx.load('xwaf.xcommon')

View File

@@ -0,0 +1,84 @@
*******************************
XMOS PUBLIC LICENCE: Version 1
*******************************
Subject to the conditions and limitations below, permission is hereby granted by XMOS LIMITED (“XMOS”), free of charge, to any person or entity obtaining a copy of the XMOS Software.
**1. Definitions**
**“Applicable Patent Rights”** means: (a) where XMOS is the grantor of the rights, (i) claims of patents that are now or in future owned by or assigned to XMOS and (ii) that cover subject matter contained in the Software, but only to the extent it is necessary to use, reproduce or distribute the Software without infringement; and (b) where you are the grantor of the rights, (i) claims of patents that are now or in future owned by or assigned to you and (ii) that cover the subject matter contained in your Derivatives, taken alone or in combination with the Software.
**“Compiled Code”** means any compiled, binary, machine readable or executable version of the Source Code.
**“Contributor”** means any person or entity that creates or contributes to the creation of Derivatives.
**“Derivatives”** means any addition to, deletion from and/or change to the substance, structure of the Software, any previous Derivatives, the combination of the Derivatives and the Software and/or any respective portions thereof.
**“Source Code”** means the human readable code that is suitable for making modifications but excluding any Compiled Code.
**“Software”** means the software and associated documentation files which XMOS makes available and which contain a notice identifying the software as original XMOS software and referring to the software being subject to the terms of this XMOS Public Licence.
This Licence refers to XMOS Software and does not relate to any XMOS hardware or devices which are protected by intellectual property rights (including patent and trade marks) which may be sold to you under a separate agreement.
**2. Licence**
**Permitted Uses, Conditions and Restrictions.** Subject to the conditions below, XMOS grants you a worldwide, royalty free, non-exclusive licence, to the extent of any Patent Rights to do the following:
2.1 **Unmodified Software.** You may use, copy, display, publish, distribute and make available unmodified copies of the Software:
2.1.1 for personal or academic, non-commercial purposes; or
2.1.2 for commercial purposes provided the Software is at all times used on a device designed, licensed or developed by XMOS and, provided that in each instance (2.1.1 and 2.1.2):
(a) you must retain and reproduce in all copies of the Software the copyright and proprietary notices and disclaimers of XMOS as they appear in the Software, and keep intact all notices and disclaimers in the Software files that refer to this Licence; and
(b) you must include a copy of this Licence with every copy of the Software and documentation you publish, distribute and make available and you may not offer or impose any terms on such Software that alter or restrict this Licence or the intent of such Licence, except as permitted below (Additional Terms).
The licence above does not include any Compiled Code which XMOS may make available under a separate support and licence agreement.
2.2 **Derivatives.** You may create and modify Derivatives and use, copy, display, publish, distribute and make available Derivatives:
2.2.1 for personal or academic, non-commercial purposes; or
2.2.2 for commercial purposes, provided the Derivatives are at all times used on a device designed, licensed or developed by XMOS and, provided that in each instance (2.2.1 and 2.2.2):
(a) you must comply with the terms of clause 2.1 with respect to the Derivatives;
(b) you must copy (to the extent it doesnt already exist) the notice below in each file of the Derivatives, and ensure all the modified files carry prominent notices stating that you have changed the files and the date of any change; and
(c) if you sublicence, distribute or otherwise make the Software and/or the Derivatives available for commercial purposes, you must provide that the Software and Derivatives are at all times used on a device designed, licensed or developed by XMOS.
Without limitation to these terms and clause 3 below, the Source Code and Compiled Code to your Derivatives may at your discretion (but without obligation) be released, copied, displayed, published, distributed and made available; and if you elect to do so, it must be under the terms of this Licence including the terms of the licence at clauses 2.2.1, 2.2.2 and clause 3 below.
2.3 **Distribution of Executable Versions.** If you distribute or make available Derivatives, you must include a prominent notice in the code itself as well as in all related documentation, stating that the Source Code of the Software from which the Derivatives are based is available under the terms of this Licence, with information on how and where to obtain such Source Code.
**3. Your Grant of Rights.** In consideration and as a condition to this Licence, you grant to any person or entity receiving or distributing any Derivatives, a non-exclusive, royalty free, perpetual, irrevocable license under your Applicable Patent Rights and all other intellectual property rights owned or controlled by you, to use, copy, display, publish, distribute and make available your Derivatives of the same scope and extent as XMOSs licence under clause 2.2 above.
**4. Combined Products.** You may create a combined product by combining Software, Derivatives and other code not covered by this Licence as a single application or product. In such instance, you must comply with the requirements of this Licence for any portion of the Software and/or Derivatives.
**5. Additional Terms.** You may choose to offer, and to charge a fee for, warranty, support, indemnity or liability obligations and/or other rights consistent with the term of this Licence (“Additional Terms”) to any legitimate recipients of the Software and/or Derivatives. The terms on which you provide such Additional Terms are on your sole responsibility and you shall indemnify, defend and hold XMOS harmless against any claims asserted against XMOS.
**6. New Versions.** XMOS may publish revised and/or new versions of this Licence from time to time to accommodate changes to the Licence terms, new versions, updates and bug fixes of the Software. Each version will be given a distinguishing version number. Once Software has been published under a particular version of this Licence, you may continue to use it under the terms of that version. You may also choose to use the latest version of the Software under any subsequent version published by XMOS. Only XMOS shall have the right to modify these terms.
**7. IPR and Ownership**
Any rights, including all intellectual property rights and all trademarks not expressly granted herein are reserved in full by the authors or copyright holders. Any requests for additional permissions by XMOS including any rights to use XMOS trademarks, should be made (without obligation) to XMOS at **support@xmos.com**
Nothing herein shall limit any rights that XMOS is otherwise entitled to under the doctrines of patent exhaustion, implied license, or legal estoppel. Neither the name of the authors, the copyright holders or any contributors may be used to endorse or promote any Derivatives from this Software without specific written permission. Any attempt to deal with the Software which does not comply with this Licence shall be void and shall automatically terminate any rights granted under this licence (including any licence of any intellectual property rights granted herein).
Subject to the licences granted under this Licence any Contributor retains all rights, title and interest in and to any Derivatives made by Contributor subject to the underlying rights of XMOS in the Software. XMOS shall retain all rights, title and interest in the Software and any Derivatives made by XMOS (“XMOS Derivatives”). XMOS Derivatives will not automatically be subject to this Licence and XMOS shall be entitled to licence such rights on any terms (without obligation) as it sees fit.
**8. Termination**
8.1 This Licence will automatically terminate immediately, without notice to you, if:
(a) you fail to comply with the terms of this Licence; and/or
(b) you directly or indirectly commence any action for patent or intellectual property right infringement against XMOS, or any parent, group, affiliate or subsidiary of XMOS; provided XMOS did not first commence an action or patent infringement against you in that instance; and/or
(c) the terms of this Licence are held by any court of competent jurisdiction to be unenforceable in whole or in part.
**9. Critical Applications.** Unless XMOS has agreed in writing with you an agreement specifically governing use of the Goods in military, aerospace, automotive or medically related functions (collectively and individually hereinafter referred to as "Special Use"), any permitted use of the Software excludes Special Use. Notwithstanding any agreement between XMOS and you for Special Use, Special Use shall be at your own risk, and you shall fully indemnify XMOS against any damages, losses, costs and claims (direct and indirect) arising out of any Special Use.
**10. NO WARRANTY OR SUPPORT.** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL XMOS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, WARRANTY, CIVIL TORT (INCLUDING NEGLIGENCE), PRODUCTS LIABILITY OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE INCLUDING GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES EVEN IF SUCH PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES AND NOT WITHSTANDING THE FAILURE OF ESSENTIAL PURPOSE. IN SOME JURISDICTIONS PARTIES ARE UNABLE TO LIMIT LIABILTY IN THIS WAY, IF THIS APPLIES TO YOUR JURISDICTION THIS LIABILITY CLAUSE ABOVE MAY NOT APPLY. NOTWITHSTANDING THE ABOVE, IN NO EVENT SHALL XMOSs TOTAL LIABILITY TO YOU FOR ALL DAMAGES, LOSS OR OTHERWISE EXCEED $50.
**11. Governing Law and Jurisdiction.** This Licence constitutes the entire agreement between the parties with respect to the subject matter hereof. The Licence shall be governed by the laws of England and the conflict of laws and UN Convention on Contracts for the International Sale of Goods, shall not apply.

View File

@@ -0,0 +1,29 @@
# The TARGET variable determines what target system the application is
# compiled for. It either refers to an XN file in the source directories
# or a valid argument for the --target option when compiling
TARGET ?= XCORE-200-EXPLORER
ifeq ($(XCORE_AI), 1)
TARGET = XCORE-AI-EXPLORER
endif
# The USED_MODULES variable lists other module used by the application.
USED_MODULES = lib_i2s(>=5.0.0)
# The flags passed to xcc when building the application
# You can also set the following to override flags for a particular language:
# XCC_XC_FLAGS, XCC_C_FLAGS, XCC_ASM_FLAGS, XCC_CPP_FLAGS
# If the variable XCC_MAP_FLAGS is set it overrides the flags passed to
# xcc for the final link (mapping) stage.
XCC_FLAGS = -O2 -g -report
# The XCORE_ARM_PROJECT variable, if set to 1, configures this
# project to create both xCORE and ARM binaries.
XCORE_ARM_PROJECT = 0
#=============================================================================
# The following part of the Makefile includes the common build infrastructure
# for compiling XMOS applications. You should not need to edit below here.
XMOS_MAKE_PATH ?= ../..
include $(XMOS_MAKE_PATH)/xcommon/module_xcommon/build/Makefile.common

View File

@@ -0,0 +1,69 @@
// Copyright 2018-2022 XMOS LIMITED.
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
/* A simple application example used for code snippets in the library
* documentation.
*/
#include <platform.h>
#include <xs1.h>
#include "i2s.h"
#include <print.h>
#include <stdlib.h>
#define SAMPLE_FREQUENCY (192000)
#define MASTER_CLOCK_FREQUENCY (24576000)
#define DATA_BITS (32)
[[distributable]]
void my_application(server i2s_frame_callback_if i_i2s) {
while (1) {
select {
case i_i2s.init(i2s_config_t &?i2s_config, tdm_config_t &?tdm_config):
i2s_config.mode = I2S_MODE_LEFT_JUSTIFIED;
// Complete setup
break;
case i_i2s.restart_check() -> i2s_restart_t restart:
// Inform the I2S slave whether it should restart or exit
restart = I2S_NO_RESTART;
break;
case i_i2s.receive(size_t num_in, int32_t samples[num_in]):
// Handle a received sample
break;
case i_i2s.send(size_t num_out, int32_t samples[num_out]):
// Provide a sample to send
break;
}
}
}
out buffered port:32 p_dout[2] = {XS1_PORT_1D, XS1_PORT_1E};
in buffered port:32 p_din[2] = {XS1_PORT_1I, XS1_PORT_1J};
out port p_bclk = XS1_PORT_1M;
out buffered port:32 p_lrclk = XS1_PORT_1A;
in port p_mclk = XS1_PORT_1B;
clock bclk = XS1_CLKBLK_1;
static void setup_bclock()
{
uint32_t mclk_bclk_ratio = (MASTER_CLOCK_FREQUENCY/(SAMPLE_FREQUENCY*2*DATA_BITS));
configure_clock_src_divide(bclk, p_mclk, mclk_bclk_ratio >> 1);
}
int main(void) {
i2s_frame_callback_if i_i2s;
par
{
{
setup_bclock();
par {
i2s_frame_master_external_clock(i_i2s, p_dout, 2, p_din, 2, DATA_BITS, p_bclk, p_lrclk, bclk);
my_application(i_i2s);
}
}
}
return 0;
}
// end

View File

@@ -0,0 +1,14 @@
def options(opt):
opt.load('xwaf.xcommon')
def configure(conf):
conf.load('xwaf.xcommon')
def build(bld):
bld.do_xcommon()
def dist(ctx):
ctx.load('xwaf.xcommon')
def distcheck(ctx):
ctx.load('xwaf.xcommon')

View File

@@ -0,0 +1,84 @@
*******************************
XMOS PUBLIC LICENCE: Version 1
*******************************
Subject to the conditions and limitations below, permission is hereby granted by XMOS LIMITED (“XMOS”), free of charge, to any person or entity obtaining a copy of the XMOS Software.
**1. Definitions**
**“Applicable Patent Rights”** means: (a) where XMOS is the grantor of the rights, (i) claims of patents that are now or in future owned by or assigned to XMOS and (ii) that cover subject matter contained in the Software, but only to the extent it is necessary to use, reproduce or distribute the Software without infringement; and (b) where you are the grantor of the rights, (i) claims of patents that are now or in future owned by or assigned to you and (ii) that cover the subject matter contained in your Derivatives, taken alone or in combination with the Software.
**“Compiled Code”** means any compiled, binary, machine readable or executable version of the Source Code.
**“Contributor”** means any person or entity that creates or contributes to the creation of Derivatives.
**“Derivatives”** means any addition to, deletion from and/or change to the substance, structure of the Software, any previous Derivatives, the combination of the Derivatives and the Software and/or any respective portions thereof.
**“Source Code”** means the human readable code that is suitable for making modifications but excluding any Compiled Code.
**“Software”** means the software and associated documentation files which XMOS makes available and which contain a notice identifying the software as original XMOS software and referring to the software being subject to the terms of this XMOS Public Licence.
This Licence refers to XMOS Software and does not relate to any XMOS hardware or devices which are protected by intellectual property rights (including patent and trade marks) which may be sold to you under a separate agreement.
**2. Licence**
**Permitted Uses, Conditions and Restrictions.** Subject to the conditions below, XMOS grants you a worldwide, royalty free, non-exclusive licence, to the extent of any Patent Rights to do the following:
2.1 **Unmodified Software.** You may use, copy, display, publish, distribute and make available unmodified copies of the Software:
2.1.1 for personal or academic, non-commercial purposes; or
2.1.2 for commercial purposes provided the Software is at all times used on a device designed, licensed or developed by XMOS and, provided that in each instance (2.1.1 and 2.1.2):
(a) you must retain and reproduce in all copies of the Software the copyright and proprietary notices and disclaimers of XMOS as they appear in the Software, and keep intact all notices and disclaimers in the Software files that refer to this Licence; and
(b) you must include a copy of this Licence with every copy of the Software and documentation you publish, distribute and make available and you may not offer or impose any terms on such Software that alter or restrict this Licence or the intent of such Licence, except as permitted below (Additional Terms).
The licence above does not include any Compiled Code which XMOS may make available under a separate support and licence agreement.
2.2 **Derivatives.** You may create and modify Derivatives and use, copy, display, publish, distribute and make available Derivatives:
2.2.1 for personal or academic, non-commercial purposes; or
2.2.2 for commercial purposes, provided the Derivatives are at all times used on a device designed, licensed or developed by XMOS and, provided that in each instance (2.2.1 and 2.2.2):
(a) you must comply with the terms of clause 2.1 with respect to the Derivatives;
(b) you must copy (to the extent it doesnt already exist) the notice below in each file of the Derivatives, and ensure all the modified files carry prominent notices stating that you have changed the files and the date of any change; and
(c) if you sublicence, distribute or otherwise make the Software and/or the Derivatives available for commercial purposes, you must provide that the Software and Derivatives are at all times used on a device designed, licensed or developed by XMOS.
Without limitation to these terms and clause 3 below, the Source Code and Compiled Code to your Derivatives may at your discretion (but without obligation) be released, copied, displayed, published, distributed and made available; and if you elect to do so, it must be under the terms of this Licence including the terms of the licence at clauses 2.2.1, 2.2.2 and clause 3 below.
2.3 **Distribution of Executable Versions.** If you distribute or make available Derivatives, you must include a prominent notice in the code itself as well as in all related documentation, stating that the Source Code of the Software from which the Derivatives are based is available under the terms of this Licence, with information on how and where to obtain such Source Code.
**3. Your Grant of Rights.** In consideration and as a condition to this Licence, you grant to any person or entity receiving or distributing any Derivatives, a non-exclusive, royalty free, perpetual, irrevocable license under your Applicable Patent Rights and all other intellectual property rights owned or controlled by you, to use, copy, display, publish, distribute and make available your Derivatives of the same scope and extent as XMOSs licence under clause 2.2 above.
**4. Combined Products.** You may create a combined product by combining Software, Derivatives and other code not covered by this Licence as a single application or product. In such instance, you must comply with the requirements of this Licence for any portion of the Software and/or Derivatives.
**5. Additional Terms.** You may choose to offer, and to charge a fee for, warranty, support, indemnity or liability obligations and/or other rights consistent with the term of this Licence (“Additional Terms”) to any legitimate recipients of the Software and/or Derivatives. The terms on which you provide such Additional Terms are on your sole responsibility and you shall indemnify, defend and hold XMOS harmless against any claims asserted against XMOS.
**6. New Versions.** XMOS may publish revised and/or new versions of this Licence from time to time to accommodate changes to the Licence terms, new versions, updates and bug fixes of the Software. Each version will be given a distinguishing version number. Once Software has been published under a particular version of this Licence, you may continue to use it under the terms of that version. You may also choose to use the latest version of the Software under any subsequent version published by XMOS. Only XMOS shall have the right to modify these terms.
**7. IPR and Ownership**
Any rights, including all intellectual property rights and all trademarks not expressly granted herein are reserved in full by the authors or copyright holders. Any requests for additional permissions by XMOS including any rights to use XMOS trademarks, should be made (without obligation) to XMOS at **support@xmos.com**
Nothing herein shall limit any rights that XMOS is otherwise entitled to under the doctrines of patent exhaustion, implied license, or legal estoppel. Neither the name of the authors, the copyright holders or any contributors may be used to endorse or promote any Derivatives from this Software without specific written permission. Any attempt to deal with the Software which does not comply with this Licence shall be void and shall automatically terminate any rights granted under this licence (including any licence of any intellectual property rights granted herein).
Subject to the licences granted under this Licence any Contributor retains all rights, title and interest in and to any Derivatives made by Contributor subject to the underlying rights of XMOS in the Software. XMOS shall retain all rights, title and interest in the Software and any Derivatives made by XMOS (“XMOS Derivatives”). XMOS Derivatives will not automatically be subject to this Licence and XMOS shall be entitled to licence such rights on any terms (without obligation) as it sees fit.
**8. Termination**
8.1 This Licence will automatically terminate immediately, without notice to you, if:
(a) you fail to comply with the terms of this Licence; and/or
(b) you directly or indirectly commence any action for patent or intellectual property right infringement against XMOS, or any parent, group, affiliate or subsidiary of XMOS; provided XMOS did not first commence an action or patent infringement against you in that instance; and/or
(c) the terms of this Licence are held by any court of competent jurisdiction to be unenforceable in whole or in part.
**9. Critical Applications.** Unless XMOS has agreed in writing with you an agreement specifically governing use of the Goods in military, aerospace, automotive or medically related functions (collectively and individually hereinafter referred to as "Special Use"), any permitted use of the Software excludes Special Use. Notwithstanding any agreement between XMOS and you for Special Use, Special Use shall be at your own risk, and you shall fully indemnify XMOS against any damages, losses, costs and claims (direct and indirect) arising out of any Special Use.
**10. NO WARRANTY OR SUPPORT.** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL XMOS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, WARRANTY, CIVIL TORT (INCLUDING NEGLIGENCE), PRODUCTS LIABILITY OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE INCLUDING GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES EVEN IF SUCH PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES AND NOT WITHSTANDING THE FAILURE OF ESSENTIAL PURPOSE. IN SOME JURISDICTIONS PARTIES ARE UNABLE TO LIMIT LIABILTY IN THIS WAY, IF THIS APPLIES TO YOUR JURISDICTION THIS LIABILITY CLAUSE ABOVE MAY NOT APPLY. NOTWITHSTANDING THE ABOVE, IN NO EVENT SHALL XMOSs TOTAL LIABILITY TO YOU FOR ALL DAMAGES, LOSS OR OTHERWISE EXCEED $50.
**11. Governing Law and Jurisdiction.** This Licence constitutes the entire agreement between the parties with respect to the subject matter hereof. The Licence shall be governed by the laws of England and the conflict of laws and UN Convention on Contracts for the International Sale of Goods, shall not apply.

View File

@@ -0,0 +1,29 @@
# The TARGET variable determines what target system the application is
# compiled for. It either refers to an XN file in the source directories
# or a valid argument for the --target option when compiling
TARGET ?= XCORE-200-EXPLORER
ifeq ($(XCORE_AI), 1)
TARGET = XCORE-AI-EXPLORER
endif
# The USED_MODULES variable lists other module used by the application.
USED_MODULES = lib_i2s(>=5.0.0)
# The flags passed to xcc when building the application
# You can also set the following to override flags for a particular language:
# XCC_XC_FLAGS, XCC_C_FLAGS, XCC_ASM_FLAGS, XCC_CPP_FLAGS
# If the variable XCC_MAP_FLAGS is set it overrides the flags passed to
# xcc for the final link (mapping) stage.
XCC_FLAGS = -O2 -g -report
# The XCORE_ARM_PROJECT variable, if set to 1, configures this
# project to create both xCORE and ARM binaries.
XCORE_ARM_PROJECT = 0
#=============================================================================
# The following part of the Makefile includes the common build infrastructure
# for compiling XMOS applications. You should not need to edit below here.
XMOS_MAKE_PATH ?= ../..
include $(XMOS_MAKE_PATH)/xcommon/module_xcommon/build/Makefile.common

View File

@@ -0,0 +1,56 @@
// Copyright 2018-2022 XMOS LIMITED.
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
/* A simple application example used for code snippets in the library
* documentation.
*/
#include <platform.h>
#include <xs1.h>
#include "i2s.h"
#include <print.h>
#include <stdlib.h>
#define SAMPLE_FREQUENCY (192000)
#define MASTER_CLOCK_FREQUENCY (24576000)
#define DATA_BITS (32)
[[distributable]]
void my_application(server i2s_frame_callback_if i_i2s) {
while (1) {
select {
case i_i2s.init(i2s_config_t &?i2s_config, tdm_config_t &?tdm_config):
i2s_config.mode = I2S_MODE_LEFT_JUSTIFIED;
// Complete setup
break;
case i_i2s.restart_check() -> i2s_restart_t restart:
// Inform the I2S slave whether it should restart or exit
restart = I2S_NO_RESTART;
break;
case i_i2s.receive(size_t num_in, int32_t samples[num_in]):
// Handle a received sample
break;
case i_i2s.send(size_t num_out, int32_t samples[num_out]):
// Provide a sample to send
break;
}
}
}
out buffered port:32 p_dout[2] = {XS1_PORT_1D, XS1_PORT_1E};
in buffered port:32 p_din[2] = {XS1_PORT_1I, XS1_PORT_1J};
in port p_bclk = XS1_PORT_1A;
in buffered port:32 p_lrclk = XS1_PORT_1C;
clock bclk = XS1_CLKBLK_1;
int main(void) {
interface i2s_frame_callback_if i_i2s;
par {
i2s_frame_slave(i_i2s, p_dout, 2, p_din, 2, DATA_BITS, p_bclk, p_lrclk, bclk);
my_application(i_i2s);
}
return 0;
}
// end

View File

@@ -0,0 +1,14 @@
def options(opt):
opt.load('xwaf.xcommon')
def configure(conf):
conf.load('xwaf.xcommon')
def build(bld):
bld.do_xcommon()
def dist(ctx):
ctx.load('xwaf.xcommon')
def distcheck(ctx):
ctx.load('xwaf.xcommon')

View File

@@ -0,0 +1,84 @@
*******************************
XMOS PUBLIC LICENCE: Version 1
*******************************
Subject to the conditions and limitations below, permission is hereby granted by XMOS LIMITED (“XMOS”), free of charge, to any person or entity obtaining a copy of the XMOS Software.
**1. Definitions**
**“Applicable Patent Rights”** means: (a) where XMOS is the grantor of the rights, (i) claims of patents that are now or in future owned by or assigned to XMOS and (ii) that cover subject matter contained in the Software, but only to the extent it is necessary to use, reproduce or distribute the Software without infringement; and (b) where you are the grantor of the rights, (i) claims of patents that are now or in future owned by or assigned to you and (ii) that cover the subject matter contained in your Derivatives, taken alone or in combination with the Software.
**“Compiled Code”** means any compiled, binary, machine readable or executable version of the Source Code.
**“Contributor”** means any person or entity that creates or contributes to the creation of Derivatives.
**“Derivatives”** means any addition to, deletion from and/or change to the substance, structure of the Software, any previous Derivatives, the combination of the Derivatives and the Software and/or any respective portions thereof.
**“Source Code”** means the human readable code that is suitable for making modifications but excluding any Compiled Code.
**“Software”** means the software and associated documentation files which XMOS makes available and which contain a notice identifying the software as original XMOS software and referring to the software being subject to the terms of this XMOS Public Licence.
This Licence refers to XMOS Software and does not relate to any XMOS hardware or devices which are protected by intellectual property rights (including patent and trade marks) which may be sold to you under a separate agreement.
**2. Licence**
**Permitted Uses, Conditions and Restrictions.** Subject to the conditions below, XMOS grants you a worldwide, royalty free, non-exclusive licence, to the extent of any Patent Rights to do the following:
2.1 **Unmodified Software.** You may use, copy, display, publish, distribute and make available unmodified copies of the Software:
2.1.1 for personal or academic, non-commercial purposes; or
2.1.2 for commercial purposes provided the Software is at all times used on a device designed, licensed or developed by XMOS and, provided that in each instance (2.1.1 and 2.1.2):
(a) you must retain and reproduce in all copies of the Software the copyright and proprietary notices and disclaimers of XMOS as they appear in the Software, and keep intact all notices and disclaimers in the Software files that refer to this Licence; and
(b) you must include a copy of this Licence with every copy of the Software and documentation you publish, distribute and make available and you may not offer or impose any terms on such Software that alter or restrict this Licence or the intent of such Licence, except as permitted below (Additional Terms).
The licence above does not include any Compiled Code which XMOS may make available under a separate support and licence agreement.
2.2 **Derivatives.** You may create and modify Derivatives and use, copy, display, publish, distribute and make available Derivatives:
2.2.1 for personal or academic, non-commercial purposes; or
2.2.2 for commercial purposes, provided the Derivatives are at all times used on a device designed, licensed or developed by XMOS and, provided that in each instance (2.2.1 and 2.2.2):
(a) you must comply with the terms of clause 2.1 with respect to the Derivatives;
(b) you must copy (to the extent it doesnt already exist) the notice below in each file of the Derivatives, and ensure all the modified files carry prominent notices stating that you have changed the files and the date of any change; and
(c) if you sublicence, distribute or otherwise make the Software and/or the Derivatives available for commercial purposes, you must provide that the Software and Derivatives are at all times used on a device designed, licensed or developed by XMOS.
Without limitation to these terms and clause 3 below, the Source Code and Compiled Code to your Derivatives may at your discretion (but without obligation) be released, copied, displayed, published, distributed and made available; and if you elect to do so, it must be under the terms of this Licence including the terms of the licence at clauses 2.2.1, 2.2.2 and clause 3 below.
2.3 **Distribution of Executable Versions.** If you distribute or make available Derivatives, you must include a prominent notice in the code itself as well as in all related documentation, stating that the Source Code of the Software from which the Derivatives are based is available under the terms of this Licence, with information on how and where to obtain such Source Code.
**3. Your Grant of Rights.** In consideration and as a condition to this Licence, you grant to any person or entity receiving or distributing any Derivatives, a non-exclusive, royalty free, perpetual, irrevocable license under your Applicable Patent Rights and all other intellectual property rights owned or controlled by you, to use, copy, display, publish, distribute and make available your Derivatives of the same scope and extent as XMOSs licence under clause 2.2 above.
**4. Combined Products.** You may create a combined product by combining Software, Derivatives and other code not covered by this Licence as a single application or product. In such instance, you must comply with the requirements of this Licence for any portion of the Software and/or Derivatives.
**5. Additional Terms.** You may choose to offer, and to charge a fee for, warranty, support, indemnity or liability obligations and/or other rights consistent with the term of this Licence (“Additional Terms”) to any legitimate recipients of the Software and/or Derivatives. The terms on which you provide such Additional Terms are on your sole responsibility and you shall indemnify, defend and hold XMOS harmless against any claims asserted against XMOS.
**6. New Versions.** XMOS may publish revised and/or new versions of this Licence from time to time to accommodate changes to the Licence terms, new versions, updates and bug fixes of the Software. Each version will be given a distinguishing version number. Once Software has been published under a particular version of this Licence, you may continue to use it under the terms of that version. You may also choose to use the latest version of the Software under any subsequent version published by XMOS. Only XMOS shall have the right to modify these terms.
**7. IPR and Ownership**
Any rights, including all intellectual property rights and all trademarks not expressly granted herein are reserved in full by the authors or copyright holders. Any requests for additional permissions by XMOS including any rights to use XMOS trademarks, should be made (without obligation) to XMOS at **support@xmos.com**
Nothing herein shall limit any rights that XMOS is otherwise entitled to under the doctrines of patent exhaustion, implied license, or legal estoppel. Neither the name of the authors, the copyright holders or any contributors may be used to endorse or promote any Derivatives from this Software without specific written permission. Any attempt to deal with the Software which does not comply with this Licence shall be void and shall automatically terminate any rights granted under this licence (including any licence of any intellectual property rights granted herein).
Subject to the licences granted under this Licence any Contributor retains all rights, title and interest in and to any Derivatives made by Contributor subject to the underlying rights of XMOS in the Software. XMOS shall retain all rights, title and interest in the Software and any Derivatives made by XMOS (“XMOS Derivatives”). XMOS Derivatives will not automatically be subject to this Licence and XMOS shall be entitled to licence such rights on any terms (without obligation) as it sees fit.
**8. Termination**
8.1 This Licence will automatically terminate immediately, without notice to you, if:
(a) you fail to comply with the terms of this Licence; and/or
(b) you directly or indirectly commence any action for patent or intellectual property right infringement against XMOS, or any parent, group, affiliate or subsidiary of XMOS; provided XMOS did not first commence an action or patent infringement against you in that instance; and/or
(c) the terms of this Licence are held by any court of competent jurisdiction to be unenforceable in whole or in part.
**9. Critical Applications.** Unless XMOS has agreed in writing with you an agreement specifically governing use of the Goods in military, aerospace, automotive or medically related functions (collectively and individually hereinafter referred to as "Special Use"), any permitted use of the Software excludes Special Use. Notwithstanding any agreement between XMOS and you for Special Use, Special Use shall be at your own risk, and you shall fully indemnify XMOS against any damages, losses, costs and claims (direct and indirect) arising out of any Special Use.
**10. NO WARRANTY OR SUPPORT.** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL XMOS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, WARRANTY, CIVIL TORT (INCLUDING NEGLIGENCE), PRODUCTS LIABILITY OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE INCLUDING GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES EVEN IF SUCH PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES AND NOT WITHSTANDING THE FAILURE OF ESSENTIAL PURPOSE. IN SOME JURISDICTIONS PARTIES ARE UNABLE TO LIMIT LIABILTY IN THIS WAY, IF THIS APPLIES TO YOUR JURISDICTION THIS LIABILITY CLAUSE ABOVE MAY NOT APPLY. NOTWITHSTANDING THE ABOVE, IN NO EVENT SHALL XMOSs TOTAL LIABILITY TO YOU FOR ALL DAMAGES, LOSS OR OTHERWISE EXCEED $50.
**11. Governing Law and Jurisdiction.** This Licence constitutes the entire agreement between the parties with respect to the subject matter hereof. The Licence shall be governed by the laws of England and the conflict of laws and UN Convention on Contracts for the International Sale of Goods, shall not apply.

View File

@@ -0,0 +1,29 @@
# The TARGET variable determines what target system the application is
# compiled for. It either refers to an XN file in the source directories
# or a valid argument for the --target option when compiling
TARGET ?= XCORE-200-EXPLORER
ifeq ($(XCORE_AI), 1)
TARGET = XCORE-AI-EXPLORER
endif
# The USED_MODULES variable lists other module used by the application.
USED_MODULES = lib_i2s(>=5.0.0)
# The flags passed to xcc when building the application
# You can also set the following to override flags for a particular language:
# XCC_XC_FLAGS, XCC_C_FLAGS, XCC_ASM_FLAGS, XCC_CPP_FLAGS
# If the variable XCC_MAP_FLAGS is set it overrides the flags passed to
# xcc for the final link (mapping) stage.
XCC_FLAGS = -O2 -g -report
# The XCORE_ARM_PROJECT variable, if set to 1, configures this
# project to create both xCORE and ARM binaries.
XCORE_ARM_PROJECT = 0
#=============================================================================
# The following part of the Makefile includes the common build infrastructure
# for compiling XMOS applications. You should not need to edit below here.
XMOS_MAKE_PATH ?= ../..
include $(XMOS_MAKE_PATH)/xcommon/module_xcommon/build/Makefile.common

View File

@@ -0,0 +1,61 @@
// Copyright 2018-2022 XMOS LIMITED.
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
/* A simple application example used for code snippets in the library
* documentation.
*/
#include <platform.h>
#include <xs1.h>
#include "i2s.h"
#include <print.h>
#include <stdlib.h>
#define SAMPLE_FREQUENCY (192000)
#define MASTER_CLOCK_FREQUENCY (24576000)
[[distributable]]
void my_application(server i2s_callback_if i_i2s) {
while (1) {
select {
case i_i2s.init(i2s_config_t &?i2s_config, tdm_config_t &?tdm_config):
i2s_config.mclk_bclk_ratio = (MASTER_CLOCK_FREQUENCY/SAMPLE_FREQUENCY)/64;
i2s_config.mode = I2S_MODE_LEFT_JUSTIFIED;
// Complete setup
break;
case i_i2s.restart_check() -> i2s_restart_t restart:
// Inform the I2S master whether it should restart or exit
restart = I2S_NO_RESTART;
break;
case i_i2s.receive(size_t index, int32_t sample):
// Handle a received sample
break;
case i_i2s.send(size_t index) -> int32_t sample:
// Provide a sample to send
break;
}
}
}
out buffered port:32 p_dout[2] = {XS1_PORT_1D, XS1_PORT_1E};
in buffered port:32 p_din[2] = {XS1_PORT_1I, XS1_PORT_1J};
port p_mclk = XS1_PORT_1M;
out buffered port:32 p_bclk = XS1_PORT_1A;
out buffered port:32 p_lrclk = XS1_PORT_1C;
clock bclk = XS1_CLKBLK_1;
clock mclk = XS1_CLKBLK_2;
int main() {
interface i2s_callback_if i_i2s;
configure_clock_src(mclk, p_mclk);
start_clock(mclk);
par {
i2s_master(i_i2s, p_dout, 2, p_din, 2, p_bclk, p_lrclk, bclk, mclk);
my_application(i_i2s);
}
return 0;
}
// end

View File

@@ -0,0 +1,14 @@
def options(opt):
opt.load('xwaf.xcommon')
def configure(conf):
conf.load('xwaf.xcommon')
def build(bld):
bld.do_xcommon()
def dist(ctx):
ctx.load('xwaf.xcommon')
def distcheck(ctx):
ctx.load('xwaf.xcommon')

View File

@@ -0,0 +1,84 @@
*******************************
XMOS PUBLIC LICENCE: Version 1
*******************************
Subject to the conditions and limitations below, permission is hereby granted by XMOS LIMITED (“XMOS”), free of charge, to any person or entity obtaining a copy of the XMOS Software.
**1. Definitions**
**“Applicable Patent Rights”** means: (a) where XMOS is the grantor of the rights, (i) claims of patents that are now or in future owned by or assigned to XMOS and (ii) that cover subject matter contained in the Software, but only to the extent it is necessary to use, reproduce or distribute the Software without infringement; and (b) where you are the grantor of the rights, (i) claims of patents that are now or in future owned by or assigned to you and (ii) that cover the subject matter contained in your Derivatives, taken alone or in combination with the Software.
**“Compiled Code”** means any compiled, binary, machine readable or executable version of the Source Code.
**“Contributor”** means any person or entity that creates or contributes to the creation of Derivatives.
**“Derivatives”** means any addition to, deletion from and/or change to the substance, structure of the Software, any previous Derivatives, the combination of the Derivatives and the Software and/or any respective portions thereof.
**“Source Code”** means the human readable code that is suitable for making modifications but excluding any Compiled Code.
**“Software”** means the software and associated documentation files which XMOS makes available and which contain a notice identifying the software as original XMOS software and referring to the software being subject to the terms of this XMOS Public Licence.
This Licence refers to XMOS Software and does not relate to any XMOS hardware or devices which are protected by intellectual property rights (including patent and trade marks) which may be sold to you under a separate agreement.
**2. Licence**
**Permitted Uses, Conditions and Restrictions.** Subject to the conditions below, XMOS grants you a worldwide, royalty free, non-exclusive licence, to the extent of any Patent Rights to do the following:
2.1 **Unmodified Software.** You may use, copy, display, publish, distribute and make available unmodified copies of the Software:
2.1.1 for personal or academic, non-commercial purposes; or
2.1.2 for commercial purposes provided the Software is at all times used on a device designed, licensed or developed by XMOS and, provided that in each instance (2.1.1 and 2.1.2):
(a) you must retain and reproduce in all copies of the Software the copyright and proprietary notices and disclaimers of XMOS as they appear in the Software, and keep intact all notices and disclaimers in the Software files that refer to this Licence; and
(b) you must include a copy of this Licence with every copy of the Software and documentation you publish, distribute and make available and you may not offer or impose any terms on such Software that alter or restrict this Licence or the intent of such Licence, except as permitted below (Additional Terms).
The licence above does not include any Compiled Code which XMOS may make available under a separate support and licence agreement.
2.2 **Derivatives.** You may create and modify Derivatives and use, copy, display, publish, distribute and make available Derivatives:
2.2.1 for personal or academic, non-commercial purposes; or
2.2.2 for commercial purposes, provided the Derivatives are at all times used on a device designed, licensed or developed by XMOS and, provided that in each instance (2.2.1 and 2.2.2):
(a) you must comply with the terms of clause 2.1 with respect to the Derivatives;
(b) you must copy (to the extent it doesnt already exist) the notice below in each file of the Derivatives, and ensure all the modified files carry prominent notices stating that you have changed the files and the date of any change; and
(c) if you sublicence, distribute or otherwise make the Software and/or the Derivatives available for commercial purposes, you must provide that the Software and Derivatives are at all times used on a device designed, licensed or developed by XMOS.
Without limitation to these terms and clause 3 below, the Source Code and Compiled Code to your Derivatives may at your discretion (but without obligation) be released, copied, displayed, published, distributed and made available; and if you elect to do so, it must be under the terms of this Licence including the terms of the licence at clauses 2.2.1, 2.2.2 and clause 3 below.
2.3 **Distribution of Executable Versions.** If you distribute or make available Derivatives, you must include a prominent notice in the code itself as well as in all related documentation, stating that the Source Code of the Software from which the Derivatives are based is available under the terms of this Licence, with information on how and where to obtain such Source Code.
**3. Your Grant of Rights.** In consideration and as a condition to this Licence, you grant to any person or entity receiving or distributing any Derivatives, a non-exclusive, royalty free, perpetual, irrevocable license under your Applicable Patent Rights and all other intellectual property rights owned or controlled by you, to use, copy, display, publish, distribute and make available your Derivatives of the same scope and extent as XMOSs licence under clause 2.2 above.
**4. Combined Products.** You may create a combined product by combining Software, Derivatives and other code not covered by this Licence as a single application or product. In such instance, you must comply with the requirements of this Licence for any portion of the Software and/or Derivatives.
**5. Additional Terms.** You may choose to offer, and to charge a fee for, warranty, support, indemnity or liability obligations and/or other rights consistent with the term of this Licence (“Additional Terms”) to any legitimate recipients of the Software and/or Derivatives. The terms on which you provide such Additional Terms are on your sole responsibility and you shall indemnify, defend and hold XMOS harmless against any claims asserted against XMOS.
**6. New Versions.** XMOS may publish revised and/or new versions of this Licence from time to time to accommodate changes to the Licence terms, new versions, updates and bug fixes of the Software. Each version will be given a distinguishing version number. Once Software has been published under a particular version of this Licence, you may continue to use it under the terms of that version. You may also choose to use the latest version of the Software under any subsequent version published by XMOS. Only XMOS shall have the right to modify these terms.
**7. IPR and Ownership**
Any rights, including all intellectual property rights and all trademarks not expressly granted herein are reserved in full by the authors or copyright holders. Any requests for additional permissions by XMOS including any rights to use XMOS trademarks, should be made (without obligation) to XMOS at **support@xmos.com**
Nothing herein shall limit any rights that XMOS is otherwise entitled to under the doctrines of patent exhaustion, implied license, or legal estoppel. Neither the name of the authors, the copyright holders or any contributors may be used to endorse or promote any Derivatives from this Software without specific written permission. Any attempt to deal with the Software which does not comply with this Licence shall be void and shall automatically terminate any rights granted under this licence (including any licence of any intellectual property rights granted herein).
Subject to the licences granted under this Licence any Contributor retains all rights, title and interest in and to any Derivatives made by Contributor subject to the underlying rights of XMOS in the Software. XMOS shall retain all rights, title and interest in the Software and any Derivatives made by XMOS (“XMOS Derivatives”). XMOS Derivatives will not automatically be subject to this Licence and XMOS shall be entitled to licence such rights on any terms (without obligation) as it sees fit.
**8. Termination**
8.1 This Licence will automatically terminate immediately, without notice to you, if:
(a) you fail to comply with the terms of this Licence; and/or
(b) you directly or indirectly commence any action for patent or intellectual property right infringement against XMOS, or any parent, group, affiliate or subsidiary of XMOS; provided XMOS did not first commence an action or patent infringement against you in that instance; and/or
(c) the terms of this Licence are held by any court of competent jurisdiction to be unenforceable in whole or in part.
**9. Critical Applications.** Unless XMOS has agreed in writing with you an agreement specifically governing use of the Goods in military, aerospace, automotive or medically related functions (collectively and individually hereinafter referred to as "Special Use"), any permitted use of the Software excludes Special Use. Notwithstanding any agreement between XMOS and you for Special Use, Special Use shall be at your own risk, and you shall fully indemnify XMOS against any damages, losses, costs and claims (direct and indirect) arising out of any Special Use.
**10. NO WARRANTY OR SUPPORT.** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL XMOS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, WARRANTY, CIVIL TORT (INCLUDING NEGLIGENCE), PRODUCTS LIABILITY OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE INCLUDING GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES EVEN IF SUCH PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES AND NOT WITHSTANDING THE FAILURE OF ESSENTIAL PURPOSE. IN SOME JURISDICTIONS PARTIES ARE UNABLE TO LIMIT LIABILTY IN THIS WAY, IF THIS APPLIES TO YOUR JURISDICTION THIS LIABILITY CLAUSE ABOVE MAY NOT APPLY. NOTWITHSTANDING THE ABOVE, IN NO EVENT SHALL XMOSs TOTAL LIABILITY TO YOU FOR ALL DAMAGES, LOSS OR OTHERWISE EXCEED $50.
**11. Governing Law and Jurisdiction.** This Licence constitutes the entire agreement between the parties with respect to the subject matter hereof. The Licence shall be governed by the laws of England and the conflict of laws and UN Convention on Contracts for the International Sale of Goods, shall not apply.

View File

@@ -0,0 +1,29 @@
# The TARGET variable determines what target system the application is
# compiled for. It either refers to an XN file in the source directories
# or a valid argument for the --target option when compiling
TARGET ?= XCORE-200-EXPLORER
ifeq ($(XCORE_AI), 1)
TARGET = XCORE-AI-EXPLORER
endif
# The USED_MODULES variable lists other module used by the application.
USED_MODULES = lib_i2s(>=5.0.0)
# The flags passed to xcc when building the application
# You can also set the following to override flags for a particular language:
# XCC_XC_FLAGS, XCC_C_FLAGS, XCC_ASM_FLAGS, XCC_CPP_FLAGS
# If the variable XCC_MAP_FLAGS is set it overrides the flags passed to
# xcc for the final link (mapping) stage.
XCC_FLAGS = -O2 -g -report
# The XCORE_ARM_PROJECT variable, if set to 1, configures this
# project to create both xCORE and ARM binaries.
XCORE_ARM_PROJECT = 0
#=============================================================================
# The following part of the Makefile includes the common build infrastructure
# for compiling XMOS applications. You should not need to edit below here.
XMOS_MAKE_PATH ?= ../..
include $(XMOS_MAKE_PATH)/xcommon/module_xcommon/build/Makefile.common

View File

@@ -0,0 +1,55 @@
// Copyright 2018-2022 XMOS LIMITED.
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
/* A simple application example used for code snippets in the library
* documentation.
*/
#include <platform.h>
#include <xs1.h>
#include "i2s.h"
#include <print.h>
#include <stdlib.h>
#define SAMPLE_FREQUENCY (192000)
#define MASTER_CLOCK_FREQUENCY (24576000)
[[distributable]]
void my_application(server i2s_callback_if i_i2s) {
while (1) {
select {
case i_i2s.init(i2s_config_t &?i2s_config, tdm_config_t &?tdm_config):
i2s_config.mode = I2S_MODE_LEFT_JUSTIFIED;
// Complete setup
break;
case i_i2s.restart_check() -> i2s_restart_t restart:
// Inform the I2S slave whether it should restart or exit
restart = I2S_NO_RESTART;
break;
case i_i2s.receive(size_t index, int32_t sample):
// Handle a received sample
break;
case i_i2s.send(size_t index) -> int32_t sample:
// Provide a sample to send
break;
}
}
}
out buffered port:32 p_dout[2] = {XS1_PORT_1D, XS1_PORT_1E};
in buffered port:32 p_din[2] = {XS1_PORT_1I, XS1_PORT_1K};
in port p_bclk = XS1_PORT_1A;
in buffered port:32 p_lrclk = XS1_PORT_1C;
clock bclk = XS1_CLKBLK_1;
int main(void) {
interface i2s_callback_if i_i2s;
par {
i2s_slave(i_i2s, p_dout, 2, p_din, 2, p_bclk, p_lrclk, bclk);
my_application(i_i2s);
}
return 0;
}
// end

View File

@@ -0,0 +1,14 @@
def options(opt):
opt.load('xwaf.xcommon')
def configure(conf):
conf.load('xwaf.xcommon')
def build(bld):
bld.do_xcommon()
def dist(ctx):
ctx.load('xwaf.xcommon')
def distcheck(ctx):
ctx.load('xwaf.xcommon')

View File

@@ -0,0 +1,84 @@
*******************************
XMOS PUBLIC LICENCE: Version 1
*******************************
Subject to the conditions and limitations below, permission is hereby granted by XMOS LIMITED (“XMOS”), free of charge, to any person or entity obtaining a copy of the XMOS Software.
**1. Definitions**
**“Applicable Patent Rights”** means: (a) where XMOS is the grantor of the rights, (i) claims of patents that are now or in future owned by or assigned to XMOS and (ii) that cover subject matter contained in the Software, but only to the extent it is necessary to use, reproduce or distribute the Software without infringement; and (b) where you are the grantor of the rights, (i) claims of patents that are now or in future owned by or assigned to you and (ii) that cover the subject matter contained in your Derivatives, taken alone or in combination with the Software.
**“Compiled Code”** means any compiled, binary, machine readable or executable version of the Source Code.
**“Contributor”** means any person or entity that creates or contributes to the creation of Derivatives.
**“Derivatives”** means any addition to, deletion from and/or change to the substance, structure of the Software, any previous Derivatives, the combination of the Derivatives and the Software and/or any respective portions thereof.
**“Source Code”** means the human readable code that is suitable for making modifications but excluding any Compiled Code.
**“Software”** means the software and associated documentation files which XMOS makes available and which contain a notice identifying the software as original XMOS software and referring to the software being subject to the terms of this XMOS Public Licence.
This Licence refers to XMOS Software and does not relate to any XMOS hardware or devices which are protected by intellectual property rights (including patent and trade marks) which may be sold to you under a separate agreement.
**2. Licence**
**Permitted Uses, Conditions and Restrictions.** Subject to the conditions below, XMOS grants you a worldwide, royalty free, non-exclusive licence, to the extent of any Patent Rights to do the following:
2.1 **Unmodified Software.** You may use, copy, display, publish, distribute and make available unmodified copies of the Software:
2.1.1 for personal or academic, non-commercial purposes; or
2.1.2 for commercial purposes provided the Software is at all times used on a device designed, licensed or developed by XMOS and, provided that in each instance (2.1.1 and 2.1.2):
(a) you must retain and reproduce in all copies of the Software the copyright and proprietary notices and disclaimers of XMOS as they appear in the Software, and keep intact all notices and disclaimers in the Software files that refer to this Licence; and
(b) you must include a copy of this Licence with every copy of the Software and documentation you publish, distribute and make available and you may not offer or impose any terms on such Software that alter or restrict this Licence or the intent of such Licence, except as permitted below (Additional Terms).
The licence above does not include any Compiled Code which XMOS may make available under a separate support and licence agreement.
2.2 **Derivatives.** You may create and modify Derivatives and use, copy, display, publish, distribute and make available Derivatives:
2.2.1 for personal or academic, non-commercial purposes; or
2.2.2 for commercial purposes, provided the Derivatives are at all times used on a device designed, licensed or developed by XMOS and, provided that in each instance (2.2.1 and 2.2.2):
(a) you must comply with the terms of clause 2.1 with respect to the Derivatives;
(b) you must copy (to the extent it doesnt already exist) the notice below in each file of the Derivatives, and ensure all the modified files carry prominent notices stating that you have changed the files and the date of any change; and
(c) if you sublicence, distribute or otherwise make the Software and/or the Derivatives available for commercial purposes, you must provide that the Software and Derivatives are at all times used on a device designed, licensed or developed by XMOS.
Without limitation to these terms and clause 3 below, the Source Code and Compiled Code to your Derivatives may at your discretion (but without obligation) be released, copied, displayed, published, distributed and made available; and if you elect to do so, it must be under the terms of this Licence including the terms of the licence at clauses 2.2.1, 2.2.2 and clause 3 below.
2.3 **Distribution of Executable Versions.** If you distribute or make available Derivatives, you must include a prominent notice in the code itself as well as in all related documentation, stating that the Source Code of the Software from which the Derivatives are based is available under the terms of this Licence, with information on how and where to obtain such Source Code.
**3. Your Grant of Rights.** In consideration and as a condition to this Licence, you grant to any person or entity receiving or distributing any Derivatives, a non-exclusive, royalty free, perpetual, irrevocable license under your Applicable Patent Rights and all other intellectual property rights owned or controlled by you, to use, copy, display, publish, distribute and make available your Derivatives of the same scope and extent as XMOSs licence under clause 2.2 above.
**4. Combined Products.** You may create a combined product by combining Software, Derivatives and other code not covered by this Licence as a single application or product. In such instance, you must comply with the requirements of this Licence for any portion of the Software and/or Derivatives.
**5. Additional Terms.** You may choose to offer, and to charge a fee for, warranty, support, indemnity or liability obligations and/or other rights consistent with the term of this Licence (“Additional Terms”) to any legitimate recipients of the Software and/or Derivatives. The terms on which you provide such Additional Terms are on your sole responsibility and you shall indemnify, defend and hold XMOS harmless against any claims asserted against XMOS.
**6. New Versions.** XMOS may publish revised and/or new versions of this Licence from time to time to accommodate changes to the Licence terms, new versions, updates and bug fixes of the Software. Each version will be given a distinguishing version number. Once Software has been published under a particular version of this Licence, you may continue to use it under the terms of that version. You may also choose to use the latest version of the Software under any subsequent version published by XMOS. Only XMOS shall have the right to modify these terms.
**7. IPR and Ownership**
Any rights, including all intellectual property rights and all trademarks not expressly granted herein are reserved in full by the authors or copyright holders. Any requests for additional permissions by XMOS including any rights to use XMOS trademarks, should be made (without obligation) to XMOS at **support@xmos.com**
Nothing herein shall limit any rights that XMOS is otherwise entitled to under the doctrines of patent exhaustion, implied license, or legal estoppel. Neither the name of the authors, the copyright holders or any contributors may be used to endorse or promote any Derivatives from this Software without specific written permission. Any attempt to deal with the Software which does not comply with this Licence shall be void and shall automatically terminate any rights granted under this licence (including any licence of any intellectual property rights granted herein).
Subject to the licences granted under this Licence any Contributor retains all rights, title and interest in and to any Derivatives made by Contributor subject to the underlying rights of XMOS in the Software. XMOS shall retain all rights, title and interest in the Software and any Derivatives made by XMOS (“XMOS Derivatives”). XMOS Derivatives will not automatically be subject to this Licence and XMOS shall be entitled to licence such rights on any terms (without obligation) as it sees fit.
**8. Termination**
8.1 This Licence will automatically terminate immediately, without notice to you, if:
(a) you fail to comply with the terms of this Licence; and/or
(b) you directly or indirectly commence any action for patent or intellectual property right infringement against XMOS, or any parent, group, affiliate or subsidiary of XMOS; provided XMOS did not first commence an action or patent infringement against you in that instance; and/or
(c) the terms of this Licence are held by any court of competent jurisdiction to be unenforceable in whole or in part.
**9. Critical Applications.** Unless XMOS has agreed in writing with you an agreement specifically governing use of the Goods in military, aerospace, automotive or medically related functions (collectively and individually hereinafter referred to as "Special Use"), any permitted use of the Software excludes Special Use. Notwithstanding any agreement between XMOS and you for Special Use, Special Use shall be at your own risk, and you shall fully indemnify XMOS against any damages, losses, costs and claims (direct and indirect) arising out of any Special Use.
**10. NO WARRANTY OR SUPPORT.** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL XMOS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, WARRANTY, CIVIL TORT (INCLUDING NEGLIGENCE), PRODUCTS LIABILITY OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE INCLUDING GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES EVEN IF SUCH PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES AND NOT WITHSTANDING THE FAILURE OF ESSENTIAL PURPOSE. IN SOME JURISDICTIONS PARTIES ARE UNABLE TO LIMIT LIABILTY IN THIS WAY, IF THIS APPLIES TO YOUR JURISDICTION THIS LIABILITY CLAUSE ABOVE MAY NOT APPLY. NOTWITHSTANDING THE ABOVE, IN NO EVENT SHALL XMOSs TOTAL LIABILITY TO YOU FOR ALL DAMAGES, LOSS OR OTHERWISE EXCEED $50.
**11. Governing Law and Jurisdiction.** This Licence constitutes the entire agreement between the parties with respect to the subject matter hereof. The Licence shall be governed by the laws of England and the conflict of laws and UN Convention on Contracts for the International Sale of Goods, shall not apply.

View File

@@ -0,0 +1,29 @@
# The TARGET variable determines what target system the application is
# compiled for. It either refers to an XN file in the source directories
# or a valid argument for the --target option when compiling
TARGET ?= XCORE-200-EXPLORER
ifeq ($(XCORE_AI), 1)
TARGET = XCORE-AI-EXPLORER
endif
# The USED_MODULES variable lists other module used by the application.
USED_MODULES = lib_i2s(>=5.0.0)
# The flags passed to xcc when building the application
# You can also set the following to override flags for a particular language:
# XCC_XC_FLAGS, XCC_C_FLAGS, XCC_ASM_FLAGS, XCC_CPP_FLAGS
# If the variable XCC_MAP_FLAGS is set it overrides the flags passed to
# xcc for the final link (mapping) stage.
XCC_FLAGS = -O2 -g -report
# The XCORE_ARM_PROJECT variable, if set to 1, configures this
# project to create both xCORE and ARM binaries.
XCORE_ARM_PROJECT = 0
#=============================================================================
# The following part of the Makefile includes the common build infrastructure
# for compiling XMOS applications. You should not need to edit below here.
XMOS_MAKE_PATH ?= ../..
include $(XMOS_MAKE_PATH)/xcommon/module_xcommon/build/Makefile.common

View File

@@ -0,0 +1,57 @@
// Copyright 2018-2022 XMOS LIMITED.
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
/* A simple application example used for code snippets in the library
* documentation.
*/
#include <platform.h>
#include <xs1.h>
#include "i2s.h"
#include <print.h>
#include <stdlib.h>
#define SAMPLE_FREQUENCY (192000)
#define MASTER_CLOCK_FREQUENCY (24576000)
[[distributable]]
void my_application(server i2s_callback_if i_i2s) {
while (1) {
select {
case i_i2s.init(i2s_config_t &?i2s_config, tdm_config_t &?tdm_config):
i2s_config.mclk_bclk_ratio = (MASTER_CLOCK_FREQUENCY/SAMPLE_FREQUENCY)/64;
i2s_config.mode = I2S_MODE_LEFT_JUSTIFIED;
// Complete setup
break;
case i_i2s.restart_check() -> i2s_restart_t restart:
// Inform the TDM master whether it should restart or exit
restart = I2S_NO_RESTART;
break;
case i_i2s.receive(size_t index, int32_t sample):
// Handle a received sample
break;
case i_i2s.send(size_t index) -> int32_t sample:
// Provide a sample to send
break;
}
}
}
out buffered port:32 p_dout[2] = {XS1_PORT_1D, XS1_PORT_1E};
in buffered port:32 p_din[2] = {XS1_PORT_1I, XS1_PORT_1K};
in port p_bclk = XS1_PORT_1A;
out buffered port:32 p_fsync = XS1_PORT_1C;
clock bclk = XS1_CLKBLK_1;
int main(void) {
i2s_callback_if i_i2s;
configure_clock_src(bclk, p_bclk);
par {
tdm_master(i_i2s, p_fsync, p_dout, 2, p_din, 2, bclk);
my_application(i_i2s);
}
return 0;
}
// end

View File

@@ -0,0 +1,14 @@
def options(opt):
opt.load('xwaf.xcommon')
def configure(conf):
conf.load('xwaf.xcommon')
def build(bld):
bld.do_xcommon()
def dist(ctx):
ctx.load('xwaf.xcommon')
def distcheck(ctx):
ctx.load('xwaf.xcommon')

View File

@@ -0,0 +1,84 @@
*******************************
XMOS PUBLIC LICENCE: Version 1
*******************************
Subject to the conditions and limitations below, permission is hereby granted by XMOS LIMITED (“XMOS”), free of charge, to any person or entity obtaining a copy of the XMOS Software.
**1. Definitions**
**“Applicable Patent Rights”** means: (a) where XMOS is the grantor of the rights, (i) claims of patents that are now or in future owned by or assigned to XMOS and (ii) that cover subject matter contained in the Software, but only to the extent it is necessary to use, reproduce or distribute the Software without infringement; and (b) where you are the grantor of the rights, (i) claims of patents that are now or in future owned by or assigned to you and (ii) that cover the subject matter contained in your Derivatives, taken alone or in combination with the Software.
**“Compiled Code”** means any compiled, binary, machine readable or executable version of the Source Code.
**“Contributor”** means any person or entity that creates or contributes to the creation of Derivatives.
**“Derivatives”** means any addition to, deletion from and/or change to the substance, structure of the Software, any previous Derivatives, the combination of the Derivatives and the Software and/or any respective portions thereof.
**“Source Code”** means the human readable code that is suitable for making modifications but excluding any Compiled Code.
**“Software”** means the software and associated documentation files which XMOS makes available and which contain a notice identifying the software as original XMOS software and referring to the software being subject to the terms of this XMOS Public Licence.
This Licence refers to XMOS Software and does not relate to any XMOS hardware or devices which are protected by intellectual property rights (including patent and trade marks) which may be sold to you under a separate agreement.
**2. Licence**
**Permitted Uses, Conditions and Restrictions.** Subject to the conditions below, XMOS grants you a worldwide, royalty free, non-exclusive licence, to the extent of any Patent Rights to do the following:
2.1 **Unmodified Software.** You may use, copy, display, publish, distribute and make available unmodified copies of the Software:
2.1.1 for personal or academic, non-commercial purposes; or
2.1.2 for commercial purposes provided the Software is at all times used on a device designed, licensed or developed by XMOS and, provided that in each instance (2.1.1 and 2.1.2):
(a) you must retain and reproduce in all copies of the Software the copyright and proprietary notices and disclaimers of XMOS as they appear in the Software, and keep intact all notices and disclaimers in the Software files that refer to this Licence; and
(b) you must include a copy of this Licence with every copy of the Software and documentation you publish, distribute and make available and you may not offer or impose any terms on such Software that alter or restrict this Licence or the intent of such Licence, except as permitted below (Additional Terms).
The licence above does not include any Compiled Code which XMOS may make available under a separate support and licence agreement.
2.2 **Derivatives.** You may create and modify Derivatives and use, copy, display, publish, distribute and make available Derivatives:
2.2.1 for personal or academic, non-commercial purposes; or
2.2.2 for commercial purposes, provided the Derivatives are at all times used on a device designed, licensed or developed by XMOS and, provided that in each instance (2.2.1 and 2.2.2):
(a) you must comply with the terms of clause 2.1 with respect to the Derivatives;
(b) you must copy (to the extent it doesnt already exist) the notice below in each file of the Derivatives, and ensure all the modified files carry prominent notices stating that you have changed the files and the date of any change; and
(c) if you sublicence, distribute or otherwise make the Software and/or the Derivatives available for commercial purposes, you must provide that the Software and Derivatives are at all times used on a device designed, licensed or developed by XMOS.
Without limitation to these terms and clause 3 below, the Source Code and Compiled Code to your Derivatives may at your discretion (but without obligation) be released, copied, displayed, published, distributed and made available; and if you elect to do so, it must be under the terms of this Licence including the terms of the licence at clauses 2.2.1, 2.2.2 and clause 3 below.
2.3 **Distribution of Executable Versions.** If you distribute or make available Derivatives, you must include a prominent notice in the code itself as well as in all related documentation, stating that the Source Code of the Software from which the Derivatives are based is available under the terms of this Licence, with information on how and where to obtain such Source Code.
**3. Your Grant of Rights.** In consideration and as a condition to this Licence, you grant to any person or entity receiving or distributing any Derivatives, a non-exclusive, royalty free, perpetual, irrevocable license under your Applicable Patent Rights and all other intellectual property rights owned or controlled by you, to use, copy, display, publish, distribute and make available your Derivatives of the same scope and extent as XMOSs licence under clause 2.2 above.
**4. Combined Products.** You may create a combined product by combining Software, Derivatives and other code not covered by this Licence as a single application or product. In such instance, you must comply with the requirements of this Licence for any portion of the Software and/or Derivatives.
**5. Additional Terms.** You may choose to offer, and to charge a fee for, warranty, support, indemnity or liability obligations and/or other rights consistent with the term of this Licence (“Additional Terms”) to any legitimate recipients of the Software and/or Derivatives. The terms on which you provide such Additional Terms are on your sole responsibility and you shall indemnify, defend and hold XMOS harmless against any claims asserted against XMOS.
**6. New Versions.** XMOS may publish revised and/or new versions of this Licence from time to time to accommodate changes to the Licence terms, new versions, updates and bug fixes of the Software. Each version will be given a distinguishing version number. Once Software has been published under a particular version of this Licence, you may continue to use it under the terms of that version. You may also choose to use the latest version of the Software under any subsequent version published by XMOS. Only XMOS shall have the right to modify these terms.
**7. IPR and Ownership**
Any rights, including all intellectual property rights and all trademarks not expressly granted herein are reserved in full by the authors or copyright holders. Any requests for additional permissions by XMOS including any rights to use XMOS trademarks, should be made (without obligation) to XMOS at **support@xmos.com**
Nothing herein shall limit any rights that XMOS is otherwise entitled to under the doctrines of patent exhaustion, implied license, or legal estoppel. Neither the name of the authors, the copyright holders or any contributors may be used to endorse or promote any Derivatives from this Software without specific written permission. Any attempt to deal with the Software which does not comply with this Licence shall be void and shall automatically terminate any rights granted under this licence (including any licence of any intellectual property rights granted herein).
Subject to the licences granted under this Licence any Contributor retains all rights, title and interest in and to any Derivatives made by Contributor subject to the underlying rights of XMOS in the Software. XMOS shall retain all rights, title and interest in the Software and any Derivatives made by XMOS (“XMOS Derivatives”). XMOS Derivatives will not automatically be subject to this Licence and XMOS shall be entitled to licence such rights on any terms (without obligation) as it sees fit.
**8. Termination**
8.1 This Licence will automatically terminate immediately, without notice to you, if:
(a) you fail to comply with the terms of this Licence; and/or
(b) you directly or indirectly commence any action for patent or intellectual property right infringement against XMOS, or any parent, group, affiliate or subsidiary of XMOS; provided XMOS did not first commence an action or patent infringement against you in that instance; and/or
(c) the terms of this Licence are held by any court of competent jurisdiction to be unenforceable in whole or in part.
**9. Critical Applications.** Unless XMOS has agreed in writing with you an agreement specifically governing use of the Goods in military, aerospace, automotive or medically related functions (collectively and individually hereinafter referred to as "Special Use"), any permitted use of the Software excludes Special Use. Notwithstanding any agreement between XMOS and you for Special Use, Special Use shall be at your own risk, and you shall fully indemnify XMOS against any damages, losses, costs and claims (direct and indirect) arising out of any Special Use.
**10. NO WARRANTY OR SUPPORT.** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL XMOS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, WARRANTY, CIVIL TORT (INCLUDING NEGLIGENCE), PRODUCTS LIABILITY OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE INCLUDING GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES EVEN IF SUCH PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES AND NOT WITHSTANDING THE FAILURE OF ESSENTIAL PURPOSE. IN SOME JURISDICTIONS PARTIES ARE UNABLE TO LIMIT LIABILTY IN THIS WAY, IF THIS APPLIES TO YOUR JURISDICTION THIS LIABILITY CLAUSE ABOVE MAY NOT APPLY. NOTWITHSTANDING THE ABOVE, IN NO EVENT SHALL XMOSs TOTAL LIABILITY TO YOU FOR ALL DAMAGES, LOSS OR OTHERWISE EXCEED $50.
**11. Governing Law and Jurisdiction.** This Licence constitutes the entire agreement between the parties with respect to the subject matter hereof. The Licence shall be governed by the laws of England and the conflict of laws and UN Convention on Contracts for the International Sale of Goods, shall not apply.

View File

@@ -0,0 +1,30 @@
# The TARGET variable determines what target system the application is
# compiled for. It either refers to an XN file in the source directories
# or a valid argument for the --target option when compiling
TARGET ?= XCORE-200-EXPLORER
ifeq ($(XCORE_AI), 1)
TARGET = XCORE-AI-EXPLORER
endif
# The APP_NAME variable determines the name of the final .xe file. It should
# not include the .xe postfix. If left blank the name will default to
# the project name
APP_NAME =
# The USED_MODULES variable lists other module used by the application.
USED_MODULES = lib_gpio(>=1.1.0) lib_i2c(>=5.0.0) lib_i2s(>=3.0.0)
# The flags passed to xcc when building the application
# You can also set the following to override flags for a particular language:
# XCC_XC_FLAGS, XCC_C_FLAGS, XCC_ASM_FLAGS, XCC_CPP_FLAGS
# If the variable XCC_MAP_FLAGS is set it overrides the flags passed to
# xcc for the final link (mapping) stage.
XCC_FLAGS = -O3 -report -g
#=============================================================================
# The following part of the Makefile includes the common build infrastructure
# for compiling XMOS applications. You should not need to edit below here.
XMOS_MAKE_PATH ?= ../..
include $(XMOS_MAKE_PATH)/xcommon/module_xcommon/build/Makefile.common

View File

@@ -0,0 +1,57 @@
<?xml version="1.0" encoding="UTF-8"?>
<Network xmlns="http://www.xmos.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.xmos.com http://www.xmos.com" ManuallySpecifiedRouting="true">
<Type>Board</Type>
<Name>xCORE-200 MC Audio</Name>
<Declarations>
<Declaration>tileref tile[2]</Declaration>
<Declaration>tileref usb_tile</Declaration>
</Declarations>
<Packages>
<Package id="0" Type="XS2-UEnA-512-FB236">
<Nodes>
<Node Id="0" InPackageId="0" Type="XS2-L16A-512" OscillatorSrc="1" SystemFrequency="500MHz">
<Boot>
<Source Location="bootFlash"/>
</Boot>
<Tile Number="0" Reference="tile[0]">
<Port Location="XS1_PORT_1B" Name="PORT_SQI_CS"/>
<Port Location="XS1_PORT_1C" Name="PORT_SQI_SCLK"/>
<Port Location="XS1_PORT_4B" Name="PORT_SQI_SIO"/>
</Tile>
<Tile Number="1" Reference="tile[1]"/>
</Node>
<Node Id="1" InPackageId="1" Type="periph:XS1-SU" Reference="usb_tile" Oscillator="24MHz">
</Node>
</Nodes>
<Links>
<Link Encoding="5wire">
<LinkEndpoint NodeId="0" Link="8" Delays="52clk,52clk"/>
<LinkEndpoint NodeId="1" Link="0" Delays="1clk,1clk"/>
</Link>
</Links>
</Package>
</Packages>
<Nodes>
<Node Id="2" Type="device:" RoutingId="0x8000">
<Service Id="0" Proto="xscope_host_data(chanend c);">
<Chanend Identifier="c" end="3"/>
</Service>
</Node>
</Nodes>
<Links>
<Link Encoding="2wire" Delays="4,4" Flags="XSCOPE">
<LinkEndpoint NodeId="0" Link="0"/>
<LinkEndpoint NodeId="2" Chanend="1"/>
</Link>
</Links>
<ExternalDevices>
<Device NodeId="0" Tile="0" Class="SQIFlash" Name="bootFlash" Type="S25FL116K" PageSize="256" SectorSize="4096" NumPages="8192">
<Attribute Name="PORT_SQI_CS" Value="PORT_SQI_CS"/>
<Attribute Name="PORT_SQI_SCLK" Value="PORT_SQI_SCLK"/>
<Attribute Name="PORT_SQI_SIO" Value="PORT_SQI_SIO"/>
</Device>
</ExternalDevices>
<JTAGChain>
<JTAGDevice NodeId="0"/>
</JTAGChain>
</Network>

View File

@@ -0,0 +1,227 @@
// Copyright 2015-2022 XMOS LIMITED.
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
#include <xs1.h>
#include <print.h>
#include <i2s.h>
#include <i2c.h>
#include <gpio.h>
#include <platform.h>
/* Ports and clocks used by the application */
out buffered port:32 p_dout[4] = on tile[0]: {XS1_PORT_1M, XS1_PORT_1N,
XS1_PORT_1O, XS1_PORT_1P};
in buffered port:32 p_din[4] = on tile[0]: {XS1_PORT_1I, XS1_PORT_1J,
XS1_PORT_1K, XS1_PORT_1L};
out buffered port:32 p_fsync = on tile[0]: XS1_PORT_1G;
out port p_bclk = on tile[0]: XS1_PORT_1H;
in port p_mclk = on tile[0]: XS1_PORT_1F;
out port p_gpio = on tile[0]: XS1_PORT_8C;
port p_i2c = on tile[0]: XS1_PORT_4A;
port p_led1 = on tile[1]:XS1_PORT_4C;
port p_led2 = on tile[1]:XS1_PORT_4D;
clock clk1 = on tile[0]: XS1_CLKBLK_1;
//Address on I2C bus
#define CS5368_ADDR (0x4C)
//Register Addresess
#define CS5368_CHIP_REV (0x00)
#define CS5368_GCTL_MDE (0x01)
#define CS5368_OVFL_ST (0x02)
//Address on I2C bus
#define CS4384_ADDR (0x18)
//Register Addresess
#define CS4384_CHIP_REV (0x01)
#define CS4384_MODE_CTRL (0x02)
#define CS4384_PCM_CTRL (0x03)
#define CS4384_DSD_CTRL (0x04)
#define CS4384_FLT_CTRL (0x05)
#define CS4384_INV_CTRL (0x06)
#define CS4384_GRP_CTRL (0x07)
#define CS4384_RMP_MUTE (0x08)
#define CS4384_MUTE_CTRL (0x09)
#define CS4384_MIX_PR1 (0x0a)
#define CS4384_VOL_A1 (0x0b)
#define CS4384_VOL_B1 (0x0c)
#define CS4384_MIX_PR2 (0x0d)
#define CS4384_VOL_A2 (0x0e)
#define CS4384_VOL_B2 (0x0f)
#define CS4384_MIX_PR3 (0x10)
#define CS4384_VOL_A3 (0x11)
#define CS4384_VOL_B3 (0x12)
#define CS4384_MIX_PR4 (0x13)
#define CS4384_VOL_A4 (0x14)
#define CS4384_VOL_B4 (0x15)
#define CS4384_CM_MODE (0x16)
#define CS5368_CHIP_REV (0x00)
#define CS5368_GCTL_MDE (0x01)
#define CS5368_OVFL_ST (0x02)
#define CS5368_OVFL_MSK (0x03)
#define CS5368_HPF_CTRL (0x04)
#define CS5368_PWR_DN (0x06)
#define CS5368_MUTE_CTRL (0x08)
#define CS5368_SDO_EN (0x0a)
[[distributable]]
void tdm_loopback(server i2s_callback_if i2s,
client i2c_master_if i2c,
client output_gpio_if dac_reset,
client output_gpio_if adc_reset,
client output_gpio_if clock_select,
client output_gpio_if led)
{
int32_t samples[32];
int count = 0;
int led_val = 1;
led.output(led_val);
while (1) {
select {
case i2s.init(i2s_config_t &?i2s_config, tdm_config_t &?tdm_config):
tdm_config.offset = 0;
tdm_config.sync_len = 32;
tdm_config.channels_per_frame = 8;
/* Set CODEC in reset */
dac_reset.output(0);
adc_reset.output(0);
/* Select 48Khz family clock (24.576Mhz) */
clock_select.output(1);
/* Allow the clock to settle */
delay_milliseconds(2);
/* DAC out of reset */
dac_reset.output(1);
/* Mode Control 1 (Address: 0x02) */
/* bit[7] : Control Port Enable (CPEN) : Set to 1 for enable
* bit[6] : Freeze controls (FREEZE) : Set to 1 for freeze
* bit[5] : PCM/DSD Selection (DSD/PCM) : Set to 0 for PCM
* bit[4:1] : DAC Pair Disable (DACx_DIS) : All Dac Pairs enabled
* bit[0] : Power Down (PDN) : Powered down
*/
i2c.write_reg(CS4384_ADDR, CS4384_MODE_CTRL, 0b11000001);
uint8_t x;
i2c_regop_res_t result;
x = i2c.read_reg(CS4384_ADDR, CS4384_MODE_CTRL, result);
printbinln(x);
printintln(result);
//uint8_t data[1];
// i2c.read(CS4384_ADDR, data, 1, 1);
// printbinln(data[0]);
/* PCM Control (Address: 0x03) */
/* bit[7:4] : Digital Interface Format (DIF) : 0b1100 for TDM
* bit[3:2] : Reserved
* bit[1:0] : Functional Mode (FM) : 0x11 for auto-speed detect (32 to 200kHz)
*/
i2c.write_reg(CS4384_ADDR, CS4384_PCM_CTRL, 0b11000111);
x = i2c.read_reg(CS4384_ADDR, CS4384_PCM_CTRL, result);
printbinln(x);
// printintln(result);
// i2c.read(CS4384_ADDR, data, 1, 1);
// printbinln(data[0]);
/* Mode Control 1 (Address: 0x02) */
/* bit[7] : Control Port Enable (CPEN) : Set to 1 for enable
* bit[6] : Freeze controls (FREEZE) : Set to 0 for freeze
* bit[5] : PCM/DSD Selection (DSD/PCM) : Set to 0 for PCM
* bit[4:1] : DAC Pair Disable (DACx_DIS) : All Dac Pairs enabled
* bit[0] : Power Down (PDN) : Not powered down
*/
i2c.write_reg(CS4384_ADDR, CS4384_MODE_CTRL, 0b10000000);
x = i2c.read_reg(CS4384_ADDR, CS4384_MODE_CTRL, result);
printbinln(x);
// i2c.read(CS4384_ADDR, data, 1, 1);
// printbinln(data[0]);
/* ADC out of reset */
adc_reset.output(1);
unsigned adc_dif = 0x02; // TDM mode
unsigned adc_mode = 0x03; /* Slave mode all speeds */
/* Reg 0x01: (GCTL) Global Mode Control Register */
/* Bit[7]: CP-EN: Manages control-port mode
* Bit[6]: CLKMODE: Setting puts part in 384x mode
* Bit[5:4]: MDIV[1:0]: Set to 01 for /2
* Bit[3:2]: DIF[1:0]: Data Format: 0x01 for I2S, 0x02 for TDM
* Bit[1:0]: MODE[1:0]: Mode: 0x11 for slave mode
*/
i2c.write_reg(CS5368_ADDR, CS5368_GCTL_MDE, 0b10010000 | (adc_dif << 2) | adc_mode);
/* Reg 0x06: (PDN) Power Down Register */
/* Bit[7:6]: Reserved
* Bit[5]: PDN-BG: When set, this bit powers-own the bandgap reference
* Bit[4]: PDM-OSC: Controls power to internal oscillator core
* Bit[3:0]: PDN: When any bit is set all clocks going to that channel pair are turned off
*/
i2c.write_reg(CS5368_ADDR, CS5368_PWR_DN, 0b00000000);
break;
case i2s.restart_check() -> i2s_restart_t restart:
restart = I2S_NO_RESTART;
break;
case i2s.receive(size_t index, int32_t sample):
if (index == 0) {
count++;
if (count == 48000) {
led_val = 1-led_val;
//led.output(led_val);
count = 0;
}
}
samples[index] = sample;
break;
case i2s.send(size_t index) -> int32_t sample:
sample = samples[index];
break;
}
}
}
static char gpio_pin_map[3] =
{1, // dac reset
2, // adc reset
6 // clock select
};
int main() {
interface i2s_callback_if i_i2s;
interface i2c_master_if i_i2c[1];
interface output_gpio_if i_gpio[3];
interface output_gpio_if i_gpio_led[1];
par {
on tile[0]: {
configure_clock_src_divide(clk1, p_mclk, 1);
configure_port_clock_output(p_bclk, clk1);
tdm_master(i_i2s, p_fsync, p_dout, 4, p_din, 4, clk1);
}
on tile[0]: [[distribute]]
tdm_loopback(i_i2s, i_i2c[0], i_gpio[0], i_gpio[1], i_gpio[2],
i_gpio_led[0]);
on tile[0]: i2c_master_single_port(i_i2c, 1, p_i2c, 10, 0, 1, 0);
on tile[0]: output_gpio(i_gpio, 3, p_gpio, gpio_pin_map);
on tile[0]: par(int i=0;i<7;i++) while(1);
on tile[1]: {p_led2 <: 0xf;output_gpio(i_gpio_led, 1, p_led1, null);}
}
return 0;
}

View File

@@ -0,0 +1,14 @@
def options(opt):
opt.load('xwaf.xcommon')
def configure(conf):
conf.load('xwaf.xcommon')
def build(bld):
bld.do_xcommon()
def dist(ctx):
ctx.load('xwaf.xcommon')
def distcheck(ctx):
ctx.load('xwaf.xcommon')

490
lib_i2s/lib_i2s/api/i2s.h Normal file
View File

@@ -0,0 +1,490 @@
// Copyright 2014-2024 XMOS LIMITED.
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
#ifndef _i2s_h_
#define _i2s_h_
#include <xs1.h>
#include <stdint.h>
#include <stddef.h>
/** I2S mode.
*
* This type is used to describe the I2S mode.
*/
typedef enum i2s_mode_t {
I2S_MODE_I2S, ///< The LR clock transitions ahead of the data by one bit clock.
I2S_MODE_LEFT_JUSTIFIED, ///< The LR clock and data are phase aligned.
} i2s_mode_t;
/** I2S slave bit clock polarity.
*
* Standard I2S is positive, that is toggle data and LR clock on falling
* edge of bit clock and sample them on rising edge of bit clock. Some
* masters have it the other way around.
*/
typedef enum i2s_slave_bclk_polarity_t {
I2S_SLAVE_SAMPLE_ON_BCLK_RISING, ///<< Toggle falling, sample rising (default if not set)
I2S_SLAVE_SAMPLE_ON_BCLK_FALLING, ///<< Toggle rising, sample falling
} i2s_slave_bclk_polarity_t;
/** I2S configuration structure.
*
* This structure describes the configuration of an I2S bus.
*/
typedef struct i2s_config_t {
unsigned mclk_bclk_ratio; ///< The ratio between the master clock and bit clock signals.
i2s_mode_t mode; ///< The mode of the LR clock.
i2s_slave_bclk_polarity_t slave_bclk_polarity; ///< Slave bit clock polarity.
unsigned slave_frame_synch_error;///< Set if I2S slave restarted because of a frame synch error. No meaning for master.
} i2s_config_t;
/** TDM configuration structure.
*
* This structure describes the configuration of a TDM bus.
*/
typedef struct tdm_config_t {
int offset; ///< The number of bits that the FSYNC signal transitions before the data. Must be a value between -31 and 31.
unsigned sync_len; ///< The length that the FSYNC signal stays high counted as ticks of the bit clock.
unsigned channels_per_frame; ///< The number of channels in a TDM frame. This must be a power of 2.
} tdm_config_t;
/** Restart command type.
*
* Restart commands that can be signalled to the I2S or TDM component.
*/
typedef enum i2s_restart_t {
I2S_NO_RESTART = 0, ///< Do not restart.
I2S_RESTART, ///< Restart the bus (causes the I2S/TDM to stop and a new init callback to occur allowing reconfiguration of the BUS).
I2S_SHUTDOWN ///< Shutdown. This will cause the I2S/TDM component to exit.
} i2s_restart_t;
/** Interface representing callback events that can occur during the
* operation of the I2S task
*/
typedef interface i2s_callback_if {
/** I2S initialization event callback.
*
* The I2S component will call this
* when it first initializes on first run of after a restart.
*
* \param i2s_config This structure is provided if the connected
* component drives an I2S bus. The members
* of the structure should be set to the
* required configuration.
* \param tdm_config This structure is provided if the connected
* component drives an TDM bus. The members
* of the structure should be set to the
* required configuration.
*/
void init(i2s_config_t &?i2s_config, tdm_config_t &?tdm_config);
/** I2S restart check callback.
*
* This callback is called once per frame. The application must return the
* required restart behaviour.
*
* \return The return value should be set to
* ``I2S_NO_RESTART``, ``I2S_RESTART`` or
* ``I2S_SHUTDOWN``.
*/
i2s_restart_t restart_check();
/** Receive an incoming sample.
*
* This callback will be called when a new sample is read in by the I2S
* component.
*
* \param index The index of the sample in the frame.
* \param sample The sample data as a signed 32-bit value. The component
* may not use all 32 bits of the value (for example, many
* I2S codecs are 24-bit), in which case the bottom bits
* are ignored.
*/
void receive(size_t index, int32_t sample);
/** Request an outgoing sample.
*
* This callback will be called when the I2S component needs a new sample.
*
* \param index The index of the requested sample in the frame.
* \returns The sample data as a signed 32-bit value. The component
* may not have 32-bits of accuracy (for example, many
* I2S codecs are 24-bit), in which case the bottom bits
* will be arbitrary values.
*/
int32_t send(size_t index);
} i2s_callback_if;
/** Interface representing callback events that can occur during the
* operation of the I2S task. This is a more efficient interface
* and reccomended for new designs.
*/
typedef interface i2s_frame_callback_if {
/** I2S frame-based initialization event callback.
*
* The I2S component will call this
* when it first initializes on first run of after a restart.
*
* \param i2s_config This structure is provided if the connected
* component drives an I2S bus. The members
* of the structure should be set to the
* required configuration.
* \param tdm_config This structure is provided if the connected
* component drives an TDM bus. The members
* of the structure should be set to the
* required configuration.
*/
void init(i2s_config_t &?i2s_config, tdm_config_t &?tdm_config);
/** I2S frame-based restart check callback.
*
* This callback is called once per frame. The application must return the
* required restart behaviour.
*
* \return The return value should be set to
* ``I2S_NO_RESTART``, ``I2S_RESTART`` or
* ``I2S_SHUTDOWN``.
*/
i2s_restart_t restart_check();
/** Receive an incoming frame of samples.
*
* This callback will be called when a new frame of samples is read in by the I2S
* frame-based component.
*
* \param num_in The number of input channels contained within the array.
* \param samples The samples data array as signed 32-bit values. The component
* may not have 32-bits of accuracy (for example, many
* I2S codecs are 24-bit), in which case the bottom bits
* will be arbitrary values.
*/
void receive(size_t num_in, int32_t samples[num_in]);
/** Request an outgoing frame of samples.
*
* This callback will be called when the I2S frame-based component needs
* a new frame of samples.
*
* \param num_out The number of output channels contained within the array.
* \param samples The samples data array as signed 32-bit values. The component
* may not have 32-bits of accuracy (for example, many
* I2S codecs are 24-bit), in which case the bottom bits
* will be arbitrary values.
*/
void send(size_t num_out, int32_t samples[num_out]);
} i2s_frame_callback_if;
/** I2S master component.
*
* This task performs I2S on the provided pins. It will perform callbacks over
* the i2s_callback_if interface to get/receive data from the application
* using this component.
*
* The component performs I2S master so will drive the word clock and
* bit clock lines.
*
* \param i2s_i The I2S callback interface to connect to
* the application
* \param p_dout An array of data output ports
* \param num_out The number of output data ports
* \param p_din An array of data input ports
* \param num_in The number of input data ports
* \param p_bclk The bit clock output port
* \param p_lrclk The word clock output port
* \param bclk A clock that will get configured for use with
* the bit clock
* \param mclk The clock connected to the master clock frequency.
* Usually this should be configured to be driven by
* an incoming master system clock.
*/
void i2s_master(client i2s_callback_if i2s_i,
out buffered port:32 (&?p_dout)[num_out],
static const size_t num_out,
in buffered port:32 (&?p_din)[num_in],
static const size_t num_in,
out buffered port:32 p_bclk,
out buffered port:32 p_lrclk,
clock bclk,
const clock mclk);
#if defined(__XS2A__) || defined(__XS3A__) || defined(__DOXYGEN__)
/** I2S frame-based master component **for xCORE200 and xcore.ai only**
*
* This task performs I2S on the provided pins. It will perform callbacks over
* the i2s_frame_callback_if interface to get/receive frames of data from the
* application using this component.
*
* The component performs I2S master so will drive the word clock and
* bit clock lines.
*
* This is a more efficient version of i2s master which reduces callback
* frequency and allows useful processing to be done in distributable i2s handler tasks.
* It also uses xCORE200 and xcore.ai specific features to remove the need for software
* BCLK generation which decreases processor overhead.
*
* \param i2s_i The I2S frame callback interface to connect to
* the application
* \param p_dout An array of data output ports
* \param num_out The number of output data ports
* \param p_din An array of data input ports
* \param num_in The number of input data ports
* \param num_data_bits The number of bits per data word
* \param p_bclk The bit clock output port
* \param p_lrclk The word clock output port
* \param p_mclk Input port which supplies the master clock
* \param bclk A clock that will get configured for use with
* the bit clock
*/
void i2s_frame_master(client i2s_frame_callback_if i2s_i,
out buffered port:32 (&?p_dout)[num_out],
static const size_t num_out,
in buffered port:32 (&?p_din)[num_in],
static const size_t num_in,
static const size_t num_data_bits,
out port p_bclk,
out buffered port:32 p_lrclk,
in port p_mclk,
clock bclk);
/** I2S frame-based master component with 4-bit ports **for xCORE200 and xcore.ai only**
*
* This task performs I2S on the provided 4-bit ports. It will perform callbacks over
* the i2s_frame_callback_if interface to get/receive frames of data from the
* application using this component.
*
* The component performs I2S master so will drive the word clock and
* bit clock lines.
*
* This is a more efficient version of i2s master which reduces callback
* frequency and allows useful processing to be done in distributable i2s handler tasks.
* It also uses xCORE200 and xcore.ai specific features to remove the need for software
* BCLK generation which decreases processor overhead.
*
* This component can only operate with a 32-bit data word length.
*
* \param i2s_i The I2S frame callback interface to connect to
* the application
* \param p_dout A 4-bit data output port
* \param num_out The number of output data streams
* \param p_din A 4-bit data input port
* \param num_in The number of input data streams
* \param p_bclk The bit clock output port
* \param p_lrclk The word clock output port
* \param p_mclk Input port which supplies the master clock
* \param bclk A clock that will get configured for use with
* the bit clock
*/
void i2s_frame_master_4b(client i2s_frame_callback_if i2s_i,
out buffered port:32 ?p_dout,
static const size_t num_out,
in buffered port:32 ?p_din,
static const size_t num_in,
out port p_bclk,
out buffered port:32 p_lrclk,
in port p_mclk,
clock bclk);
/** I2S frame-based master component **for xCORE200 and xcore.ai only**
*
* This task performs I2S on the provided pins. It will perform callbacks over
* the i2s_frame_callback_if interface to get/receive frames of data from the
* application using this component.
*
* The component performs I2S master so will drive the word clock and
* bit clock lines.
*
* This is a more efficient version of i2s master which reduces callback
* frequency and allows useful processing to be done in distributable i2s handler tasks.
* It also uses xCORE200 and xcore.ai specific features to remove the need for software
* BCLK generation which decreases processor overhead.
*
* \param i2s_i The I2S frame callback interface to connect to
* the application
* \param p_dout An array of data output ports
* \param num_out The number of output data ports
* \param p_din An array of data input ports
* \param num_in The number of input data ports
* \param num_data_bits The number of bits per data word
* \param p_bclk The bit clock output port
* \param p_lrclk The word clock output port
* \param bclk A clock that is configured externally to be used as the bit clock
*
*/
void i2s_frame_master_external_clock(client i2s_frame_callback_if i2s_i,
out buffered port:32 (&?p_dout)[num_out],
static const size_t num_out,
in buffered port:32 (&?p_din)[num_in],
static const size_t num_in,
static const size_t num_data_bits,
out port p_bclk,
out buffered port:32 p_lrclk,
clock bclk);
/** I2S frame-based master component with 4-bit ports **for xCORE200 amd xcore.ai only**
*
* This task performs I2S on the provided 4-bit ports. It will perform callbacks over
* the i2s_frame_callback_if interface to get/receive frames of data from the
* application using this component.
*
* The component performs I2S master so will drive the word clock and
* bit clock lines.
*
* This is a more efficient version of i2s master which reduces callback
* frequency and allows useful processing to be done in distributable i2s handler tasks.
* It also uses xCORE200 and xcore.ai specific features to remove the need for software
* BCLK generation which decreases processor overhead.
*
* This component can only operate with a 32-bit data word length.
*
* \param i2s_i The I2S frame callback interface to connect to
* the application
* \param p_dout An array of data output ports
* \param num_out The number of output data ports
* \param p_din An array of data input ports
* \param num_in The number of input data ports
* \param p_bclk The bit clock output port
* \param p_lrclk The word clock output port
* \param bclk A clock that will get configured for use with
* the bit clock
*/
void i2s_frame_master_external_clock_4b(client i2s_frame_callback_if i2s_i,
out buffered port:32 (&?p_dout)[num_out],
static const size_t num_out,
in buffered port:32 (&?p_din)[num_in],
static const size_t num_in,
out port p_bclk,
out buffered port:32 p_lrclk,
clock bclk);
#endif // __XS2A__
/** I2S slave component.
*
* This task performs I2S on the provided pins. It will perform callbacks over
* the i2s_callback_if interface to get/receive data from the application
* using this component.
*
* The component performs I2S slave so will expect the word clock and
* bit clock to be driven externally.
*
* \param i2s_i The I2S callback interface to connect to
* the application
* \param p_dout An array of data output ports
* \param num_out The number of output data ports
* \param p_din An array of data input ports
* \param num_in The number of input data ports
* \param p_bclk The bit clock input port
* \param p_lrclk The word clock input port
* \param bclk A clock that will get configured for use with
* the bit clock
*/
void i2s_slave(client i2s_callback_if i2s_i,
out buffered port:32 (&?p_dout)[num_out],
static const size_t num_out,
in buffered port:32 (&?p_din)[num_in],
static const size_t num_in,
in port p_bclk,
in buffered port:32 p_lrclk,
clock bclk);
/** I2S High Efficiency slave component.
*
* This task performs I2S on the provided pins. It will perform callbacks over
* the i2s_callback_if interface to get/receive data from the application
* using this component.
*
* The component performs I2S slave so will expect the word clock and
* bit clock to be driven externally.
*
* \param i2s_i The I2S callback interface to connect to
* the application
* \param p_dout An array of data output ports
* \param num_out The number of output data ports
* \param p_din An array of data input ports
* \param num_in The number of input data ports
* \param num_data_bits The number of bits per data word
* \param p_bclk The bit clock input port
* \param p_lrclk The word clock input port
* \param bclk A clock that will get configured for use with
* the bit clock
*/
void i2s_frame_slave(client i2s_frame_callback_if i2s_i,
out buffered port:32 (&?p_dout)[num_out],
static const size_t num_out,
in buffered port:32 (&?p_din)[num_in],
static const size_t num_in,
static const size_t num_data_bits,
in port p_bclk,
in buffered port:32 p_lrclk,
clock bclk);
/** I2S High Efficiency slave component.
*
* This task performs I2S on the provided pins. It will perform callbacks over
* the i2s_callback_if interface to get/receive data from the application
* using this component.
*
* The component performs I2S slave so will expect the word clock and
* bit clock to be driven externally.
*
* \param i2s_i The I2S callback interface to connect to
* the application
* \param p_dout An array of data output ports
* \param num_out The number of output data ports
* \param p_din An array of data input ports
* \param num_in The number of input data ports
* \param p_bclk The bit clock input port
* \param p_lrclk The word clock input port
* \param bclk A clock that will get configured for use with
* the bit clock
*/
void i2s_frame_slave_4b(client i2s_frame_callback_if i2s_i,
out buffered port:32 (&?p_dout)[num_out],
static const size_t num_out,
in buffered port:32 (&?p_din)[num_in],
static const size_t num_in,
in port p_bclk,
in buffered port:32 p_lrclk,
clock bclk);
/** TDM master component.
*
* This task performs TDM on the provided pins. It will perform callbacks over
* the i2s_callback_if interface to get/receive data from the application
* using this component.
*
* The component performs as TDM master so will drive the fsync signal.
*
* \param tdm_i The TDM callback interface to connect to
* the application
* \param p_fsync The frame sync output port
* \param p_dout An array of data output ports
* \param num_out The number of output data ports
* \param p_din An array of data input ports
* \param num_in The number of input data ports
* \param clk The clock connected to the bit/master clock frequency.
* Usually this should be configured to be driven by
* an incoming master system clock.
*/
void tdm_master(client interface i2s_callback_if tdm_i,
out buffered port:32 p_fsync,
out buffered port:32 (&?p_dout)[num_out],
size_t num_out,
in buffered port:32 (&?p_din)[num_in],
size_t num_in,
clock clk);
#include <i2s_master_impl.h>
#include <i2s_frame_master_impl.h>
#include <i2s_frame_master_4b_impl.h>
#include <i2s_slave_impl.h>
#include <i2s_frame_slave_impl.h>
#include <i2s_frame_slave_4b_impl.h>
#include <tdm_master_impl.h>
#endif // _i2s_h_

View File

@@ -0,0 +1,7 @@
set(LIB_NAME lib_i2s)
set(LIB_VERSION 5.1.0)
set(LIB_INCLUDES api src)
set(LIB_COMPILER_FLAGS -O3)
set(LIB_DEPENDENT_MODULES "lib_xassert(4.2.0)")
XMOS_REGISTER_MODULE()

View File

@@ -0,0 +1,15 @@
VERSION = 5.1.0
DEPENDENT_MODULES = lib_xassert(>=4.2.0)
MODULE_XCC_FLAGS = $(XCC_FLAGS) \
-O3
OPTIONAL_HEADERS +=
EXPORT_INCLUDE_DIRS = api \
src
INCLUDE_DIRS = $(EXPORT_INCLUDE_DIRS)
SOURCE_DIRS = src

View File

@@ -0,0 +1,67 @@
// Copyright 2015-2021 XMOS LIMITED.
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
#include <i2s.h>
#undef i2s_master
void i2s_master(client i2s_callback_if i2s_i,
out buffered port:32 (&?p_dout)[num_out],
static const size_t num_out,
in buffered port:32 (&?p_din)[num_in],
static const size_t num_in,
out buffered port:32 p_bclk,
out buffered port:32 p_lrclk,
clock bclk,
const clock mclk)
{}
#if defined(__XS2A__) || defined(__XS3A__)
#undef i2s_frame_master
void i2s_frame_master(client i2s_frame_callback_if i2s_i,
out buffered port:32 (&?p_dout)[num_out],
static const size_t num_out,
in buffered port:32 (&?p_din)[num_in],
static const size_t num_in,
static const size_t num_data_bits,
out port p_bclk,
out buffered port:32 p_lrclk,
in port p_mclk,
clock bclk)
{}
#endif // __XS2A__ || __XS3A__
#undef i2s_slave
void i2s_slave(client i2s_callback_if i2s_i,
out buffered port:32 (&?p_dout)[num_out],
static const size_t num_out,
in buffered port:32 (&?p_din)[num_in],
static const size_t num_in,
in port p_bclk,
in buffered port:32 p_lrclk,
clock bclk)
{
}
#undef i2s_frame_slave
void i2s_frame_slave(client i2s_frame_callback_if i2s_i,
out buffered port:32 (&?p_dout)[num_out],
static const size_t num_out,
in buffered port:32 (&?p_din)[num_in],
static const size_t num_in,
static const size_t num_data_bits,
in port p_bclk,
in buffered port:32 p_lrclk,
clock bclk)
{
}
#undef tdm_master
void tdm_master(client interface i2s_callback_if tdm_i,
out buffered port:32 p_fsync,
out buffered port:32 (&?p_dout)[num_out],
size_t num_out,
in buffered port:32 (&?p_din)[num_in],
size_t num_in,
clock clk){
}

View File

@@ -0,0 +1,259 @@
// Copyright 2016-2022 XMOS LIMITED.
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
#if defined(__XS2A__) || defined(__XS3A__)
#include "limits.h"
#include <xs1.h>
#include <xclib.h>
#include "i2s.h"
#include "xassert.h"
void i2s_frame_master_4b_setup(
int32_t out_samps[],
int32_t in_samps[],
out buffered port:32 ?p_dout,
in buffered port:32 ?p_din,
clock bclk,
out buffered port:32 p_lrclk
);
void i2s_frame_master_4b_loop_part_1(
int32_t out_samps[],
int32_t in_samps[],
out buffered port:32 ?p_dout,
in buffered port:32 ?p_din,
out buffered port:32 p_lrclk
);
void i2s_frame_master_4b_loop_part_2(
int32_t out_samps[],
int32_t in_samps[],
out buffered port:32 ?p_dout,
in buffered port:32 ?p_din,
out buffered port:32 p_lrclk
);
static void i2s_setup_bclk_4b(
clock bclk,
in port p_mclk,
unsigned mclk_bclk_ratio
){
set_clock_on(bclk);
configure_clock_src_divide(bclk, p_mclk, mclk_bclk_ratio >> 1);
}
static void i2s_frame_init_ports_4b(
out buffered port:32 ?p_dout,
static const size_t num_out,
in buffered port:32 ?p_din,
static const size_t num_in,
out port p_bclk,
out buffered port:32 p_lrclk,
clock bclk
){
if (!isnull(p_dout))
{
configure_out_port(p_dout, bclk, 0);
clearbuf(p_dout);
}
if (!isnull(p_din))
{
configure_in_port(p_din, bclk);
clearbuf(p_din);
}
configure_out_port(p_lrclk, bclk, 1);
clearbuf(p_lrclk);
configure_port_clock_output(p_bclk, bclk);
}
#pragma unsafe arrays
static i2s_restart_t i2s_frame_ratio_n_4b(
client i2s_frame_callback_if i2s_i,
out buffered port:32 ?p_dout,
static const size_t num_out,
in buffered port:32 ?p_din,
static const size_t num_in,
out port p_bclk,
clock bclk,
out buffered port:32 p_lrclk,
i2s_mode_t mode){
const int offset = (mode == I2S_MODE_I2S) ? 1 : 0;
int32_t in_samps[16] = {0}; // Workaround: should be (num_in << 1) but compiler thinks that isn't const,
int32_t out_samps[16] = {0}; // so setting to 16 which should be big enough for most cases
// Since #pragma unsafe arrays is used need to ensure array won't overflow.
assert((num_in << 1) <= 16);
if (num_out)
{
i2s_i.send(num_out << 1, out_samps);
}
p_lrclk @ 1 <: 0;
if (!isnull(p_din))
{
asm volatile("setpt res[%0], %1"
:
:"r"(p_din), "r"(8 + offset));
}
if (!isnull(p_dout))
{
asm volatile("setpt res[%0], %1"
:
:"r"(p_dout), "r"(1 + offset));
}
i2s_frame_master_4b_setup(out_samps, in_samps, p_dout, p_din, bclk, p_lrclk);
while (1)
{
// Check for restart
i2s_restart_t restart = i2s_i.restart_check();
if (num_out)
{
i2s_i.send(num_out << 1, out_samps);
}
i2s_frame_master_4b_loop_part_1(out_samps, in_samps, p_dout, p_din, p_lrclk);
if (num_in)
{
i2s_i.receive(num_in << 1, in_samps);
}
if (restart == I2S_NO_RESTART)
{
i2s_frame_master_4b_loop_part_2(out_samps, in_samps, p_dout, p_din, p_lrclk);
}
else
{
if (!num_in)
{
// Prevent the clock from being stopped before the last word
// has been sent if there are no RX ports.
sync(p_dout);
}
stop_clock(bclk);
return restart;
}
}
return I2S_RESTART;
}
#define i2s_frame_master_4b i2s_frame_master0_4b
static void i2s_frame_master0_4b(
client i2s_frame_callback_if i2s_i,
out buffered port:32 ?p_dout,
static const size_t num_out,
in buffered port:32 ?p_din,
static const size_t num_in,
out port p_bclk,
out buffered port:32 p_lrclk,
in port p_mclk,
clock bclk){
while(1){
i2s_config_t config;
i2s_i.init(config, null);
if (isnull(p_dout) && isnull(p_din)) {
fail("Must provide non-null p_dout or p_din");
}
unsafe
{
if ((!isnull(p_din) && (XS1_RES_ID_PORTWIDTH((int)p_din) != 4)) ||
(!isnull(p_dout) && (XS1_RES_ID_PORTWIDTH((int)p_dout) != 4)))
{
fail("This function is designed only for use with 4b ports");
}
}
i2s_setup_bclk_4b(bclk, p_mclk, config.mclk_bclk_ratio);
//This ensures that the port time on all the ports is at 0
i2s_frame_init_ports_4b(p_dout, num_out, p_din, num_in, p_bclk, p_lrclk, bclk);
i2s_restart_t restart =
i2s_frame_ratio_n_4b(i2s_i, p_dout, num_out, p_din,
num_in, p_bclk, bclk, p_lrclk,
config.mode);
if (restart == I2S_SHUTDOWN)
return;
}
}
#define i2s_frame_master_external_clock_4b i2s_frame_master0_external_clock_4b
static void i2s_frame_master0_external_clock_4b(
client i2s_frame_callback_if i2s_i,
out buffered port:32 ?p_dout,
static const size_t num_out,
in buffered port:32 ?p_din,
static const size_t num_in,
out port p_bclk,
out buffered port:32 p_lrclk,
clock bclk){
while(1){
i2s_config_t config;
i2s_i.init(config, null);
if (isnull(p_dout) && isnull(p_din)) {
fail("Must provide non-null p_dout or p_din");
}
unsafe
{
if ((!isnull(p_din) && (XS1_RES_ID_PORTWIDTH((int)p_din) != 4)) ||
(!isnull(p_dout) && (XS1_RES_ID_PORTWIDTH((int)p_dout) != 4)))
{
fail("This function is designed only for use with 4b ports");
}
}
//This ensures that the port time on all the ports is at 0
i2s_frame_init_ports_4b(p_dout, num_out, p_din, num_in, p_bclk, p_lrclk, bclk);
i2s_restart_t restart =
i2s_frame_ratio_n_4b(i2s_i, p_dout, num_out, p_din,
num_in, p_bclk, bclk, p_lrclk,
config.mode);
if (restart == I2S_SHUTDOWN)
return;
}
}
// These functions are just to avoid unused static function warnings for i2s_frame_master0
// and i2s_frame_master0_external_clock. They should never be called.
inline void i2s_frame_master1_4b(client interface i2s_frame_callback_if i,
out buffered port:32 i2s_dout,
static const size_t num_i2s_out,
in buffered port:32 i2s_din,
static const size_t num_i2s_in,
out port i2s_bclk,
out buffered port:32 i2s_lrclk,
in port p_mclk,
clock clk_bclk) {
i2s_frame_master0_4b(i, i2s_dout, num_i2s_out, i2s_din, num_i2s_in,
i2s_bclk, i2s_lrclk, p_mclk, clk_bclk);
}
inline void i2s_frame_master1_external_clock_4b(client interface i2s_frame_callback_if i,
out buffered port:32 i2s_dout,
static const size_t num_i2s_out,
in buffered port:32 i2s_din,
static const size_t num_i2s_in,
out port i2s_bclk,
out buffered port:32 i2s_lrclk,
clock clk_bclk) {
i2s_frame_master0_external_clock_4b(i, i2s_dout, num_i2s_out, i2s_din, num_i2s_in,
i2s_bclk, i2s_lrclk, clk_bclk);
}
#endif // __XS2A__ || __XS3A__

View File

@@ -0,0 +1,168 @@
// Copyright 2022 XMOS LIMITED.
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
/*
void i2s_frame_master_4b_loop_part_1(
int32_t out_samps[],
int32_t in_samps[],
out buffered port:32 ?p_dout,
in buffered port:32 ?p_din,
out buffered port:32 p_lrclk
);
*/
#define NSTACKWORDS (8)
#define FUNCTION_NAME i2s_frame_master_4b_loop_part_1
#define out_array r0
#define inp_array r1
#define out_port r2
#define inp_port r3
#define lr_clock r4
#define a r5
#define b r6
#define c r7
#define d r8
#define e r9
#define f r10
.text
.issue_mode dual
.align 4
.cc_top FUNCTION_NAME.function,FUNCTION_NAME
FUNCTION_NAME:
dualentsp NSTACKWORDS
// Store registers r4 upwards to the stack.
stw lr_clock, sp[0]
std a, b, sp[1]
std c, d, sp[2]
std e, f, sp[3]
// Retrieve final argument to the function.
ldw lr_clock, sp[9]
// Split into input-only, output-only, or input-output body implementations
// If the input port is nulled (0), only output. Otherwise, proceed to input
bf inp_port, i2s_frame_master_4b_loop_part_1_out_body
i2s_frame_master_4b_loop_part_1_in_body:
// If we are here and the output port is not null (non-0), then both in and
// out are in use. Jump to the input-output implementation.
// Otherwise, just input.
bt out_port, i2s_frame_master_4b_loop_part_1_in_out_body
// Output 32 bits of 0 for lr clock
ldc e, 0
out res[lr_clock], e
// Retrieve the two odd samples we stored earlier, and input the other two
{ ldw f, inp_array[1] ; in d, res[inp_port] }
{ ldw e, inp_array[3] ; in c, res[inp_port] }
// Unzip the recieved odd samples as required
// aeim bfjn cgko dhlp -> (abcd) (efgh) (ijkl) (mnop)
unzip e, f, 0
unzip c, d, 0
unzip d, f, 0
unzip c, e, 0
// Bit-reverse and store the recieved odd samples. At this point, we have
// recieved all 8 samples and must call the recieve callback to pass these
// to the user.
{ ; bitrev f, f }
{ stw f, inp_array[7] ; bitrev e, e }
{ stw e, inp_array[5] ; bitrev d, d }
{ stw d, inp_array[3] ; bitrev c, c }
{ stw c, inp_array[1] ; }
// Jump to the common end section
bu i2s_frame_master_4b_loop_part_1_final
i2s_frame_master_4b_loop_part_1_out_body:
// Load and bit-reverse the even 32-bit samples we intend to send
// Generate and output 32 bits of 0 for the lrclock
{ ldw a, out_array[0] ; ldc e, 0 }
{ ldw b, out_array[2] ; out res[lr_clock], e }
{ ldw c, out_array[4] ; bitrev a, a }
{ ldw d, out_array[6] ; bitrev b, b }
{ bitrev c, c ; bitrev d, d }
// Zip the even samples as required to send in parallel on a 4b port
// (abcd) (efgh) (ijkl) (mnop) -> aeim bfjn cgko dhlp
zip a, c, 0
zip b, d, 0
zip a, b, 0
zip c, d, 0
// Output the first two even samples.
// Stash the 3rd and 4th even samples for transmission later.
{ stw a, out_array[0] ; out res[out_port], d }
{ stw b, out_array[2] ; out res[out_port], c }
// Jump to the common end section
bu i2s_frame_master_4b_loop_part_1_final
i2s_frame_master_4b_loop_part_1_in_out_body:
// Load and bit-reverse the even 32-bit samples we intend to send
// Generate and output 32 bits of 0 for the lrclock
{ ldw a, out_array[0] ; ldc e, 0 }
{ ldw b, out_array[2] ; out res[lr_clock], e }
{ ldw c, out_array[4] ; bitrev a, a }
{ ldw d, out_array[6] ; bitrev b, b }
{ bitrev c, c ; bitrev d, d }
// Zip the even samples as required to send in parallel on a 4b port
// (abcd) (efgh) (ijkl) (mnop) -> aeim bfjn cgko dhlp
zip a, c, 0
zip b, d, 0
zip a, b, 0
zip c, d, 0
// We stashed the 1st and 2nd recieved odd samples earlier - retrieve these.
// Input the 3rd and 4th odd samples.
// Stash the 3rd and 4th even samples for transmission later.
{ ldw f, inp_array[1] ; out res[out_port], d }
{ ldw e, inp_array[3] ; in d, res[inp_port] }
{ stw a, out_array[0] ; out res[out_port], c }
{ stw b, out_array[2] ; in c, res[inp_port] }
// Unzip the recieved odd samples as required
// aeim bfjn cgko dhlp -> (abcd) (efgh) (ijkl) (mnop)
unzip e, f, 0
unzip c, d, 0
unzip d, f, 0
unzip c, e, 0
// Bit-reverse and store the recieved odd samples. At this point, we have
// recieved all 8 samples and must call the recieve callback to pass these
// to the user.
{ ; bitrev f, f }
{ stw f, inp_array[7] ; bitrev e, e }
{ stw e, inp_array[5] ; bitrev d, d }
{ stw d, inp_array[3] ; bitrev c, c }
{ stw c, inp_array[1] ; }
// Continue to common end section
i2s_frame_master_4b_loop_part_1_final:
// Restore registers and return.
ldw lr_clock, sp[0]
ldd a, b, sp[1]
ldd c, d, sp[2]
ldd e, f, sp[3]
retsp NSTACKWORDS
.L_func_end:
.cc_bottom FUNCTION_NAME.function
.globl FUNCTION_NAME
.type FUNCTION_NAME,@function
.set FUNCTION_NAME.nstackwords,NSTACKWORDS; .global FUNCTION_NAME.nstackwords
.set FUNCTION_NAME.maxcores,1; .global FUNCTION_NAME.maxcores
.set FUNCTION_NAME.maxtimers,0; .global FUNCTION_NAME.maxtimers
.set FUNCTION_NAME.maxchanends,0; .global FUNCTION_NAME.maxchanends

View File

@@ -0,0 +1,202 @@
// Copyright 2022 XMOS LIMITED.
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
/*
void i2s_frame_master_4b_loop_part_2(
int32_t out_samps[],
int32_t in_samps[],
out buffered port:32 ?p_dout,
in buffered port:32 ?p_din,
out buffered port:32 p_lrclk
);
*/
#define NSTACKWORDS (8)
#define FUNCTION_NAME i2s_frame_master_4b_loop_part_2
#define out_array r0
#define inp_array r1
#define out_port r2
#define inp_port r3
#define lr_clock r4
#define a r5
#define b r6
#define c r7
#define d r8
#define e r9
#define f r10
.text
.issue_mode dual
.align 4
.cc_top FUNCTION_NAME.function,FUNCTION_NAME
FUNCTION_NAME:
dualentsp NSTACKWORDS
// Store registers r4 upwards to the stack.
stw lr_clock, sp[0]
std a, b, sp[1]
std c, d, sp[2]
std e, f, sp[3]
// Retrieve final argument to the function.
ldw lr_clock, sp[9]
// Split into input-only, output-only, or input-output body implementations
// If the input port is nulled (0), only output. Otherwise, proceed to input
bf inp_port, i2s_frame_master_4b_loop_part_2_out_body
i2s_frame_master_4b_loop_part_2_in_body:
// If we are here and the output port is not null (non-0), then both in and
// out are in use. Jump to the input-output implementation.
// Otherwise, just input.
bt out_port, i2s_frame_master_4b_loop_part_2_in_out_body
// Generate and output 32 bits of 1 to the LR clock
mkmsk e, 32
out res[lr_clock], e
// Recieve the even samples
in f, res[inp_port]
in e, res[inp_port]
in d, res[inp_port]
in c, res[inp_port]
// Unzip the recieved even samples as required
// aeim bfjn cgko dhlp -> (abcd) (efgh) (ijkl) (mnop)
unzip e, f, 0
unzip c, d, 0
unzip d, f, 0
unzip c, e, 0
// Bit-reverse and store the recieved even samples.
{ ; bitrev f, f }
{ stw f, inp_array[6] ; bitrev e, e }
{ stw e, inp_array[4] ; bitrev d, d }
{ stw d, inp_array[2] ; bitrev c, c }
{ stw c, inp_array[0] ; }
// Input the first two odd samples. As we are returning from this function,
// we must store these recieved samples in memory to pick up later.
{ ; in f, res[inp_port] }
{ stw f, inp_array[1] ; in e, res[inp_port] }
{ stw e, inp_array[3] ; }
// Jump to the common end section
bu i2s_frame_master_4b_loop_part_2_final
i2s_frame_master_4b_loop_part_2_out_body:
// We stashed the 3rd and 4th even samples for transmission earlier.
// Retrieve these and immediately transmit the 3rd.
{ ldw b, out_array[2] ; }
{ ldw a, out_array[0] ; out res[out_port], b }
// Generate and output 32 bits of 1 for the lrclock.
// Output the 4th even sample
// Load the odd samples we intend to send
// Output the 4th even sample
{ ldw d, out_array[7] ; mkmsk e, 32 }
{ ldw c, out_array[5] ; out res[lr_clock], e }
{ ldw b, out_array[3] ; }
{ ldw a, out_array[1] ; out res[out_port], a }
// Bit-reverse the odd samples
{ bitrev d, d ; bitrev c, c }
{ bitrev b, b ; bitrev a, a }
// Zip the odd samples as required to send in parallel on a 4b port
// (abcd) (efgh) (ijkl) (mnop) -> aeim bfjn cgko dhlp
zip a, c, 0
zip b, d, 0
zip a, b, 0
zip c, d, 0
// Output the odd samples
out res[out_port], d
out res[out_port], c
out res[out_port], b
out res[out_port], a
// Jump to the common end section
bu i2s_frame_master_4b_loop_part_2_final
i2s_frame_master_4b_loop_part_2_in_out_body:
// We stashed the 3rd and 4th even samples for transmission earlier.
// Retrieve these and immediately transmit the 3rd.
{ ldw b, out_array[2] ; }
{ ldw a, out_array[0] ; out res[out_port], b }
// Generate and output 32 bits of 1 for the lrclock.
// Output the 4th even sample
// Load the odd samples we intend to send
// Input the 1st even sample
{ ldw d, out_array[7] ; mkmsk e, 32 }
{ ldw c, out_array[5] ; out res[lr_clock], e }
{ ldw b, out_array[3] ; in f, res[inp_port] }
{ ldw a, out_array[1] ; out res[out_port], a }
// Bit-reverse the odd samples
{ bitrev d, d ; bitrev c, c }
{ bitrev b, b ; bitrev a, a }
// Zip the odd samples as required to send in parallel on a 4b port
// (abcd) (efgh) (ijkl) (mnop) -> aeim bfjn cgko dhlp
zip a, c, 0
zip b, d, 0
zip a, b, 0
zip c, d, 0
// Output the first two odd samples
// Input the remaining even samples
{ ; in e, res[inp_port] }
{ ; out res[out_port], d }
{ ; in d, res[inp_port] }
{ ; out res[out_port], c }
{ ; in c, res[inp_port] }
// Unzip the recieved even samples as required
// aeim bfjn cgko dhlp -> (abcd) (efgh) (ijkl) (mnop)
unzip e, f, 0
unzip c, d, 0
unzip d, f, 0
unzip c, e, 0
// Bit-reverse and store the recieved even samples.
{ ; bitrev f, f }
{ stw f, inp_array[6] ; bitrev e, e }
{ stw e, inp_array[4] ; bitrev d, d }
{ stw d, inp_array[2] ; bitrev c, c }
{ stw c, inp_array[0] ; }
// Output the remaining odd samples. At this point, we have transmitted all
// 8 samples, and must call the send callback to recieve the next batch.
// Input the first two odd samples. As we are returning from this function
// in order to call the send callback, we must store these recieved samples in
// memory to pick up later.
{ ; out res[out_port], b }
{ ; in f, res[inp_port] }
{ stw f, inp_array[1] ; out res[out_port], a }
{ ; in e, res[inp_port] }
{ stw e, inp_array[3] ; }
// Continue to the common end section
i2s_frame_master_4b_loop_part_2_final:
// Restore registers and return.
ldw lr_clock, sp[0]
ldd a, b, sp[1]
ldd c, d, sp[2]
ldd e, f, sp[3]
retsp NSTACKWORDS
.L_func_end:
.cc_bottom FUNCTION_NAME.function
.globl FUNCTION_NAME
.type FUNCTION_NAME,@function
.set FUNCTION_NAME.nstackwords,NSTACKWORDS; .global FUNCTION_NAME.nstackwords
.set FUNCTION_NAME.maxcores,1; .global FUNCTION_NAME.maxcores
.set FUNCTION_NAME.maxtimers,0; .global FUNCTION_NAME.maxtimers
.set FUNCTION_NAME.maxchanends,0; .global FUNCTION_NAME.maxchanends

View File

@@ -0,0 +1,229 @@
// Copyright 2022 XMOS LIMITED.
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
/*
void i2s_frame_master_4b_setup(
int32_t out_samps[],
int32_t in_samps[],
out buffered port:32 ?p_dout,
in buffered port:32 ?p_din,
clock bclk,
out buffered port:32 p_lrclk
);
*/
#define NSTACKWORDS (8)
#define FUNCTION_NAME i2s_frame_master_4b_setup
#define out_array r0
#define inp_array r1
#define out_port r2
#define inp_port r3
#define bt_clock r4
#define lr_clock r5
#define a r6
#define b r7
#define c r8
#define d r9
#define e r10
#define f r11
.text
.issue_mode dual
.align 4
.cc_top FUNCTION_NAME.function,FUNCTION_NAME
FUNCTION_NAME:
dualentsp NSTACKWORDS
// Store registers r4 upwards to the stack.
std bt_clock, lr_clock, sp[0]
std a, b, sp[1]
std c, d, sp[2]
std e, f, sp[3]
// Retrieve final two arguments to function
ldw bt_clock, sp[9]
ldw lr_clock, sp[10]
// Split into input-only, output-only, or input-output body implementations
// If the input port is nulled (0), only set up an output. Otherwise, proceed
// to set up an input.
bf inp_port, i2s_frame_master_4b_setup_out_body
i2s_frame_master_4b_setup_in_body:
// If we are here and the output port is not null (non-0), then both in and
// out are in use. Jump to the input-output implementation.
// Otherwise, just set up an input.
bt out_port, i2s_frame_master_4b_setup_in_out_body
// Start the bit clock
setc res[bt_clock], 0xF
// Output 32 1s to lr_clock
mkmsk e, 32
out res[lr_clock], e
// Input samples
{ ; in f, res[inp_port] }
{ ; in e, res[inp_port] }
{ ; in d, res[inp_port] }
{ ; in c, res[inp_port] }
// Unzip the recieved even samples as required
// aeim bfjn cgko dhlp -> (abcd) (efgh) (ijkl) (mnop)
unzip e, f, 0
unzip c, d, 0
unzip d, f, 0
unzip c, e, 0
// Bit-reverse and store the recieved even samples
{ ; bitrev f, f }
{ stw f, inp_array[6] ; bitrev e, e }
{ stw e, inp_array[4] ; bitrev d, d }
{ stw d, inp_array[2] ; bitrev c, c }
{ stw c, inp_array[0] ; }
// Input the first two odd samples. As we are returning from this function,
// we must store these recieved samples in memory to pick up later.
{ ; in f, res[inp_port] }
{ stw f, inp_array[1] ; in e, res[inp_port] }
{ stw e, inp_array[3] ; }
// Jump to the common end section
bu i2s_frame_master_4b_setup_final
i2s_frame_master_4b_setup_out_body:
// Load and bit-reverse the even 32-bit samples we intend to send
// Generate 32 bits of 1 for the lrclock
{ ldw a, out_array[0] ; }
{ ldw b, out_array[2] ; bitrev a, a }
{ ldw c, out_array[4] ; bitrev b, b }
{ ldw d, out_array[6] ; bitrev c, c }
{ mkmsk e, 32 ; bitrev d, d }
// Zip the even samples as required to send in parallel on a 4b port
// (abcd) (efgh) (ijkl) (mnop) -> aeim bfjn cgko dhlp
zip a, c, 0
zip b, d, 0
zip a, b, 0
zip c, d, 0
// Load and bit-reverse the odd 32-bit samples we intend to send
// Output 32 1s to the lrclock transfer register
// Output the even samples
// Start the bit clock
{ ldw d, out_array[7] ; out res[out_port], d }
setc res[bt_clock], 0xF
{ ldw c, out_array[5] ; out res[out_port], c }
{ bitrev d, d ; out res[lr_clock], e }
{ ldw b, out_array[3] ; out res[out_port], b }
{ bitrev c, c ; }
{ ldw a, out_array[1] ; out res[out_port], a }
{ bitrev b, b ; bitrev a, a }
// Zip the odd samples as required to send in parallel on a 4b port
zip a, c, 0
zip b, d, 0
zip a, b, 0
zip c, d, 0
// Output the odd samples. At this point, we have transmitted all
// 8 samples, and must call the send callback to recieve the next batch.
{ ; out res[out_port], d }
{ ; out res[out_port], c }
{ ; out res[out_port], b }
{ ; out res[out_port], a }
// Jump to the common end section
bu i2s_frame_master_4b_setup_final
i2s_frame_master_4b_setup_in_out_body:
// Load and bit-reverse the even 32-bit samples we intend to send
// Generate 32 bits of 1 for the lrclock
{ ldw a, out_array[0] ; }
{ ldw b, out_array[2] ; bitrev a, a }
{ ldw c, out_array[4] ; bitrev b, b }
{ ldw d, out_array[6] ; bitrev c, c }
{ mkmsk e, 32 ; bitrev d, d }
// Zip the even samples as required to send in parallel on a 4b port
// (abcd) (efgh) (ijkl) (mnop) -> aeim bfjn cgko dhlp
zip a, c, 0
zip b, d, 0
zip a, b, 0
zip c, d, 0
// Load and bit-reverse the odd 32-bit samples we intend to send
// Output 32 1s to the lrclock transfer register
// Output the even samples
// Start the bit clock
// Input the first even sample - this must happen here to meet timing
{ ldw d, out_array[7] ; out res[out_port], d }
setc res[bt_clock], 0xF
{ ldw c, out_array[5] ; out res[out_port], c }
{ bitrev d, d ; out res[lr_clock], e }
{ ldw b, out_array[3] ; out res[out_port], b }
{ bitrev c, c ; in f, res[inp_port] }
{ ldw a, out_array[1] ; out res[out_port], a }
{ bitrev b, b ; bitrev a, a }
// Zip the odd samples as required to send in parallel on a 4b port
zip a, c, 0
zip b, d, 0
zip a, b, 0
zip c, d, 0
// Output the first two odd samples
// Input the remaining even samples
{ ; in e, res[inp_port] }
{ ; out res[out_port], d }
{ ; in d, res[inp_port] }
{ ; out res[out_port], c }
{ ; in c, res[inp_port] }
// Unzip the recieved even samples as required
// aeim bfjn cgko dhlp -> (abcd) (efgh) (ijkl) (mnop)
unzip e, f, 0
unzip c, d, 0
unzip d, f, 0
unzip c, e, 0
// Bit-reverse and store the recieved even samples
{ ; bitrev f, f }
{ stw f, inp_array[6] ; bitrev e, e }
{ stw e, inp_array[4] ; bitrev d, d }
{ stw d, inp_array[2] ; bitrev c, c }
{ stw c, inp_array[0] ; }
// Output the remaining odd samples. At this point, we have transmitted all
// 8 samples, and must call the send callback to recieve the next batch.
// Input the first two odd samples. As we are returning from this function
// in order to call the send callback, we must store these recieved samples in
// memory to pick up later.
{ ; out res[out_port], b }
{ ; in f, res[inp_port] }
{ stw f, inp_array[1] ; out res[out_port], a }
{ ; in e, res[inp_port] }
{ stw e, inp_array[3] ; }
// Continue to common end section
i2s_frame_master_4b_setup_final:
// Restore registers and return.
ldd bt_clock, lr_clock, sp[0]
ldd a, b, sp[1]
ldd c, d, sp[2]
ldd e, f, sp[3]
retsp NSTACKWORDS
.L_func_end:
.cc_bottom FUNCTION_NAME.function
.globl FUNCTION_NAME
.type FUNCTION_NAME,@function
.set FUNCTION_NAME.nstackwords,NSTACKWORDS; .global FUNCTION_NAME.nstackwords
.set FUNCTION_NAME.maxcores,1; .global FUNCTION_NAME.maxcores
.set FUNCTION_NAME.maxtimers,0; .global FUNCTION_NAME.maxtimers
.set FUNCTION_NAME.maxchanends,0; .global FUNCTION_NAME.maxchanends

View File

@@ -0,0 +1,370 @@
// Copyright 2016-2021 XMOS LIMITED.
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
#if defined(__XS2A__) || defined(__XS3A__)
#include "limits.h"
#include <xs1.h>
#include <xclib.h>
#include "i2s.h"
#include "xassert.h"
static void i2s_setup_bclk(
clock bclk,
in port p_mclk,
unsigned mclk_bclk_ratio
){
set_clock_on(bclk);
configure_clock_src_divide(bclk, p_mclk, mclk_bclk_ratio >> 1);
}
static void i2s_frame_init_ports(
out buffered port:32 (&?p_dout)[num_out],
static const size_t num_out,
in buffered port:32 (&?p_din)[num_in],
static const size_t num_in,
out port p_bclk,
out buffered port:32 p_lrclk,
clock bclk
){
for (size_t i = 0; i < num_out; i++)
{
configure_out_port(p_dout[i], bclk, 0);
clearbuf(p_dout[i]);
}
for (size_t i = 0; i < num_in; i++)
{
configure_in_port(p_din[i], bclk);
clearbuf(p_din[i]);
}
configure_port_clock_output(p_bclk, bclk);
configure_out_port(p_lrclk, bclk, 1);
clearbuf(p_lrclk);
}
#pragma unsafe arrays
static i2s_restart_t i2s_frame_ratio_n(client i2s_frame_callback_if i2s_i,
out buffered port:32 (&?p_dout)[num_out],
static const size_t num_out,
in buffered port:32 (&?p_din)[num_in],
static const size_t num_in,
static const size_t num_data_bits,
out port p_bclk,
clock bclk,
out buffered port:32 p_lrclk,
i2s_mode_t mode){
const int offset = (mode == I2S_MODE_I2S) ? 1 : 0;
int32_t in_samps[16]; // Workaround: should be (num_in << 1) but compiler thinks that isn't const,
int32_t out_samps[16]; // so setting to 16 which should be big enough for most cases
// Since #pragma unsafe arrays is used need to ensure array won't overflow.
assert((num_in << 1) <= 16);
unsigned lr_mask = 0;
const unsigned data_bit_offset = 32 - num_data_bits;
const unsigned data_bit_mask = UINT_MAX >> data_bit_offset; // e.g. 00011111 for 5b data
if (num_out)
{
i2s_i.send(num_out << 1, out_samps);
}
// Start outputting evens (0,2,4..) data at correct point relative to the clock
if (num_data_bits == 32)
{
#pragma loop unroll
for (size_t i = 0, idx = 0; i < num_out; i++, idx += 2)
{
p_dout[i] @ (1 + offset) <: bitrev(out_samps[idx]);
}
p_lrclk @ 1 <: lr_mask;
}
else
{
#pragma loop unroll
for (size_t i = 0, idx = 0; i < num_out; i++, idx += 2)
{
partout_timed(p_dout[i], num_data_bits, bitrev(out_samps[idx] << data_bit_offset), (1 + offset));
}
partout_timed(p_lrclk, num_data_bits, lr_mask, 1);
}
start_clock(bclk);
// Pre-load the odds (1,3,5..) and setup timing on the input ports
if (num_data_bits == 32)
{
#pragma loop unroll
for (size_t i = 0, idx = 1; i < num_out; i++, idx += 2)
{
p_dout[i] <: bitrev(out_samps[idx]);
}
lr_mask = ~lr_mask;
p_lrclk <: lr_mask;
for (size_t i = 0; i < num_in; i++)
{
asm volatile("setpt res[%0], %1"
:
:"r"(p_din[i]), "r"(32 + offset));
}
}
else
{
#pragma loop unroll
for (size_t i = 0, idx = 1; i < num_out; i++, idx += 2)
{
partout(p_dout[i], num_data_bits, bitrev(out_samps[idx] << data_bit_offset));
}
lr_mask = ~lr_mask;
partout(p_lrclk, num_data_bits, lr_mask);
for (size_t i = 0; i < num_in; i++)
{
asm volatile("setpt res[%0], %1"
:
:"r"(p_din[i]), "r"(num_data_bits + offset));
set_port_shift_count(p_din[i], num_data_bits);
}
}
while (1)
{
// Check for restart
i2s_restart_t restart = i2s_i.restart_check();
if (restart == I2S_NO_RESTART)
{
if (num_out)
{
i2s_i.send(num_out << 1, out_samps);
}
// Output i2s evens (0,2,4..)
if (num_data_bits == 32)
{
#pragma loop unroll
for (size_t i = 0, idx = 0; i < num_out; i++, idx += 2)
{
p_dout[i] <: bitrev(out_samps[idx]);
}
}
else
{
#pragma loop unroll
for (size_t i = 0, idx = 0; i < num_out; i++, idx += 2)
{
partout(p_dout[i], num_data_bits, bitrev(out_samps[idx] << data_bit_offset));
}
}
}
// Input i2s evens (0,2,4..)
if (num_data_bits == 32)
{
#pragma loop unroll
for (size_t i = 0, idx = 0; i < num_in; i++, idx += 2)
{
int32_t data;
asm volatile("in %0, res[%1]"
:"=r"(data)
:"r"(p_din[i]));
in_samps[idx] = bitrev(data);
}
lr_mask = ~lr_mask;
p_lrclk <: lr_mask;
}
else
{
#pragma loop unroll
for (size_t i = 0, idx = 0; i < num_in; i++, idx += 2)
{
int32_t data;
asm volatile("in %0, res[%1]"
:"=r"(data)
:"r"(p_din[i]));
set_port_shift_count(p_din[i], num_data_bits);
in_samps[idx] = bitrev(data) & data_bit_mask;
}
lr_mask = ~lr_mask;
partout(p_lrclk, num_data_bits, lr_mask);
}
if (restart == I2S_NO_RESTART)
{
// Output i2s odds (1,3,5..)
if (num_data_bits == 32)
{
#pragma loop unroll
for (size_t i = 0, idx = 1; i < num_out; i++, idx += 2)
{
p_dout[i] <: bitrev(out_samps[idx]);
}
lr_mask = ~lr_mask;
p_lrclk <: lr_mask;
}
else
{
#pragma loop unroll
for (size_t i = 0, idx = 1; i < num_out; i++, idx += 2)
{
partout(p_dout[i], num_data_bits, bitrev(out_samps[idx] << data_bit_offset));
}
lr_mask = ~lr_mask;
partout(p_lrclk, num_data_bits, lr_mask);
}
}
// Input i2s odds (1,3,5..)
if (num_data_bits == 32)
{
#pragma loop unroll
for (size_t i = 0, idx = 1; i < num_in; i++, idx += 2)
{
int32_t data;
asm volatile("in %0, res[%1]"
:"=r"(data)
:"r"(p_din[i]));
in_samps[idx] = bitrev(data);
}
}
else
{
#pragma loop unroll
for (size_t i = 0, idx = 1; i < num_in; i++, idx += 2)
{
int32_t data;
asm volatile("in %0, res[%1]"
:"=r"(data)
:"r"(p_din[i])
:"memory");
set_port_shift_count(p_din[i], num_data_bits);
in_samps[idx] = bitrev(data) & data_bit_mask;
}
}
if (num_in)
{
i2s_i.receive(num_in << 1, in_samps);
}
if (restart != I2S_NO_RESTART)
{
if (!num_in)
{
// Prevent the clock from being stopped before the last word
// has been sent if there are no RX ports.
sync(p_dout[0]);
}
stop_clock(bclk);
return restart;
}
}
return I2S_RESTART;
}
#define i2s_frame_master i2s_frame_master0
static void i2s_frame_master0(client i2s_frame_callback_if i2s_i,
out buffered port:32 (&?p_dout)[num_out],
static const size_t num_out,
in buffered port:32 (&?p_din)[num_in],
static const size_t num_in,
static const size_t num_data_bits,
out port p_bclk,
out buffered port:32 p_lrclk,
in port p_mclk,
clock bclk){
while(1){
i2s_config_t config;
i2s_i.init(config, null);
if (isnull(p_dout) && isnull(p_din)) {
fail("Must provide non-null p_dout or p_din");
}
i2s_setup_bclk(bclk, p_mclk, config.mclk_bclk_ratio);
//This ensures that the port time on all the ports is at 0
i2s_frame_init_ports(p_dout, num_out, p_din, num_in, p_bclk, p_lrclk, bclk);
i2s_restart_t restart =
i2s_frame_ratio_n(i2s_i, p_dout, num_out, p_din,
num_in, num_data_bits, p_bclk, bclk, p_lrclk,
config.mode);
if (restart == I2S_SHUTDOWN)
return;
}
}
#define i2s_frame_master_external_clock i2s_frame_master0_external_clock
static void i2s_frame_master0_external_clock(client i2s_frame_callback_if i2s_i,
out buffered port:32 (&?p_dout)[num_out],
static const size_t num_out,
in buffered port:32 (&?p_din)[num_in],
static const size_t num_in,
static const size_t num_data_bits,
out port p_bclk,
out buffered port:32 p_lrclk,
clock bclk){
while(1){
i2s_config_t config;
i2s_i.init(config, null);
if (isnull(p_dout) && isnull(p_din)) {
fail("Must provide non-null p_dout or p_din");
}
//This ensures that the port time on all the ports is at 0
i2s_frame_init_ports(p_dout, num_out, p_din, num_in, p_bclk, p_lrclk, bclk);
i2s_restart_t restart =
i2s_frame_ratio_n(i2s_i, p_dout, num_out, p_din,
num_in, num_data_bits, p_bclk, bclk, p_lrclk,
config.mode);
if (restart == I2S_SHUTDOWN)
return;
}
}
// These functions is just to avoid unused static function warnings for i2s_frame_master0
// and i2s_frame_master0_external_clock. They should never be called.
inline void i2s_frame_master1(client interface i2s_frame_callback_if i,
out buffered port:32 i2s_dout[num_i2s_out],
static const size_t num_i2s_out,
in buffered port:32 i2s_din[num_i2s_in],
static const size_t num_i2s_in,
static const size_t num_data_bits,
out port i2s_bclk,
out buffered port:32 i2s_lrclk,
in port p_mclk,
clock clk_bclk) {
i2s_frame_master0(i, i2s_dout, num_i2s_out, i2s_din, num_i2s_in, num_data_bits,
i2s_bclk, i2s_lrclk, p_mclk, clk_bclk);
}
inline void i2s_frame_master1_external_clock(client interface i2s_frame_callback_if i,
out buffered port:32 i2s_dout[num_i2s_out],
static const size_t num_i2s_out,
in buffered port:32 i2s_din[num_i2s_in],
static const size_t num_i2s_in,
static const size_t num_data_bits,
out port i2s_bclk,
out buffered port:32 i2s_lrclk,
clock clk_bclk) {
i2s_frame_master0_external_clock(i, i2s_dout, num_i2s_out, i2s_din, num_i2s_in, num_data_bits,
i2s_bclk, i2s_lrclk, clk_bclk);
}
#endif // __XS2A__ || __XS3A__

View File

@@ -0,0 +1,187 @@
// Copyright 2015-2022 XMOS LIMITED.
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
#include <xs1.h>
#include <xclib.h>
#include "i2s.h"
#include <print.h>
#include "limits.h"
#include "xassert.h"
#include <stdlib.h>
#include <stdio.h>
unsigned i2s_frame_slave_4b_setup(
int32_t out_samps[],
int32_t in_samps[],
out buffered port:32 ?p_dout,
in buffered port:32 ?p_din,
in buffered port:32 p_lrclk
);
unsigned i2s_frame_slave_4b_loop_part_1(
int32_t out_samps[],
int32_t in_samps[],
out buffered port:32 ?p_dout,
in buffered port:32 ?p_din,
in buffered port:32 p_lrclk
);
unsigned i2s_frame_slave_4b_loop_part_2(
int32_t out_samps[],
int32_t in_samps[],
out buffered port:32 ?p_dout,
in buffered port:32 ?p_din,
in buffered port:32 p_lrclk
);
static void i2s_frame_slave_init_ports_4b(
out buffered port:32 ?p_dout,
size_t num_out,
in buffered port:32 ?p_din,
size_t num_in,
in port p_bclk,
in buffered port:32 p_lrclk,
clock bclk){
set_clock_on(bclk);
configure_clock_src(bclk, p_bclk);
configure_in_port(p_lrclk, bclk);
if (!isnull(p_din))
{
configure_in_port(p_din, bclk);
}
if (!isnull(p_dout))
{
configure_out_port(p_dout, bclk, 0);
}
start_clock(bclk);
}
#define i2s_frame_slave_4b i2s_frame_slave_4b0
#pragma unsafe arrays
static void i2s_frame_slave_4b0(client i2s_frame_callback_if i2s_i,
out buffered port:32 ?p_dout,
static const size_t num_out,
in buffered port:32 ?p_din,
static const size_t num_in,
in port p_bclk,
in buffered port:32 p_lrclk,
clock bclk){
unsigned port_time;
int32_t in_samps[16] = {0}; //Workaround: should be (num_in << 1) but compiler thinks that isn't const,
int32_t out_samps[16] = {0}; //so setting to 16 which should be big enough for most cases
// Since #pragma unsafe arrays is used need to ensure array won't overflow.
assert((num_in << 1) <= 16);
i2s_frame_slave_init_ports_4b(p_dout, num_out, p_din, num_in, p_bclk, p_lrclk, bclk);
while(1)
{
i2s_config_t config;
i2s_restart_t restart = I2S_NO_RESTART;
i2s_i.init(config, null);
unsigned mode = config.mode;
if (config.slave_bclk_polarity == I2S_SLAVE_SAMPLE_ON_BCLK_FALLING)
set_port_inv(p_bclk);
else
set_port_no_inv(p_bclk);
const unsigned expected_low = (mode == I2S_MODE_I2S ? 0x80000000 : 0x00000000);
const unsigned expected_high = (mode == I2S_MODE_I2S ? 0x7fffffff : 0xffffffff);
unsigned syncerror = 0;
unsigned lrval;
if (!isnull(p_dout))
{
clearbuf(p_dout);
}
if (!isnull(p_din))
{
clearbuf(p_din);
}
clearbuf(p_lrclk);
unsigned offset = (mode == I2S_MODE_I2S ? 1 : 0);
// Wait for LRCLK edge (in I2S LRCLK = 0 is left, TDM rising edge is start of frame)
p_lrclk when pinseq(1) :> void;
p_lrclk when pinseq(0) :> void @ port_time;
unsigned initial_lr_port_time = port_time + offset + ((I2S_CHANS_PER_FRAME*32)+32) - 1;
unsigned initial_out_port_time = port_time + offset + (I2S_CHANS_PER_FRAME*32);
unsigned initial_in_port_time = port_time + offset + ((I2S_CHANS_PER_FRAME*32)+8) - 1;
// XC doesn't have syntax for setting a timed input without waiting for the input
asm volatile("setpt res[%0], %1"
:
:"r"(p_lrclk),"r"(initial_lr_port_time));
if (!isnull(p_din))
{
asm volatile("setpt res[%0], %1"
:
:"r"(p_din),"r"(initial_in_port_time));
}
if (!isnull(p_dout))
{
asm volatile("setpt res[%0], %1"
:
:"r"(p_dout),"r"(initial_out_port_time));
}
//Get initial send data if output enabled
if (num_out)
{
i2s_i.send(num_out << 1, out_samps);
}
lrval = i2s_frame_slave_4b_setup(out_samps, in_samps, p_dout, p_din, p_lrclk);
syncerror += (lrval != expected_low);
//Main loop
while (!syncerror && (restart == I2S_NO_RESTART))
{
restart = i2s_i.restart_check();
if (num_out)
{
i2s_i.send(num_out << 1, out_samps);
}
lrval = i2s_frame_slave_4b_loop_part_1(out_samps, in_samps, p_dout, p_din, p_lrclk);
syncerror += (lrval != expected_high);
if (num_in)
{
i2s_i.receive(num_in << 1, in_samps);
}
if (restart == I2S_NO_RESTART)
{
lrval = i2s_frame_slave_4b_loop_part_2(out_samps, in_samps, p_dout, p_din, p_lrclk);
syncerror += (lrval != expected_low);
}
}// main loop, runs until user restart or synch error
}// while(1)
}
// This function is just to avoid unused static function warnings for
// i2s_frame_slave0,it should never be called.
inline void i2s_frame_slave_4b1(client i2s_frame_callback_if i2s_i,
out buffered port:32 ?p_dout,
static const size_t num_out,
in buffered port:32 ?p_din,
static const size_t num_in,
in port p_bclk,
in buffered port:32 p_lrclk,
clock bclk){
if (isnull(p_dout) && isnull(p_din)) {
fail("Must provide non-null p_dout or p_din");
}
i2s_frame_slave_4b0(i2s_i, p_dout, num_out, p_din, num_in, p_bclk, p_lrclk, bclk);
}

View File

@@ -0,0 +1,165 @@
// Copyright 2022 XMOS LIMITED.
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
/*
unsigned i2s_frame_slave_4b_loop_part_1(
int32_t out_samps[],
int32_t in_samps[],
out buffered port:32 ?p_dout,
in buffered port:32 ?p_din,
out buffered port:32 p_lrclk
);
*/
#define NSTACKWORDS (8)
#define FUNCTION_NAME i2s_frame_slave_4b_loop_part_1
#define out_array r0
#define inp_array r1
#define out_port r2
#define inp_port r3
#define lr_clock r4
#define a r5
#define b r6
#define c r7
#define d r8
#define e r9
#define f r10
.text
.issue_mode dual
.align 4
.cc_top FUNCTION_NAME.function,FUNCTION_NAME
FUNCTION_NAME:
dualentsp NSTACKWORDS
// Store registers r4 upwards to the stack.
stw lr_clock, sp[0]
std a, b, sp[1]
std c, d, sp[2]
std e, f, sp[3]
// Retrieve final argument to the function.
ldw lr_clock, sp[9]
// Split into input-only, output-only, or input-output body implementations
// If the input port is nulled (0), only set up an output. Otherwise, proceed
// to set up an input.
bf inp_port, i2s_frame_slave_4b_loop_part_1_out_body
i2s_frame_slave_4b_loop_part_1_in_body:
// If we are here and the output port is not null (non-0), then both in and
// out are in use. Jump to the input-output implementation.
// Otherwise, just set up an input.
bt out_port, i2s_frame_slave_4b_loop_part_1_in_out_body
// Retrieve the two odd samples we stored earlier, and input the other two
{ ldw f, inp_array[1] ; in d, res[inp_port] }
{ ldw e, inp_array[3] ; in c, res[inp_port] }
// Unzip the recieved odd samples as required
// aeim bfjn cgko dhlp -> (abcd) (efgh) (ijkl) (mnop)
unzip e, f, 0
unzip c, d, 0
unzip d, f, 0
unzip c, e, 0
// Bit-reverse and store the recieved odd samples. At this point, we have
// recieved all 8 samples and must call the recieve callback to pass these
// to the user.
// Input value of the lr_clock and return it
{ ; bitrev f, f }
{ stw f, inp_array[7] ; bitrev e, e }
{ stw e, inp_array[5] ; bitrev d, d }
{ stw d, inp_array[3] ; bitrev c, c }
{ stw c, inp_array[1] ; in r0, res[lr_clock] }
// Jump to the common end section
bu i2s_frame_slave_4b_loop_part_1_final
i2s_frame_slave_4b_loop_part_1_out_body:
// Load and bit-reverse the even 32-bit samples we intend to send
{ ldw a, out_array[0] ; }
{ ldw b, out_array[2] ; bitrev a, a }
{ ldw c, out_array[4] ; bitrev b, b }
{ ldw d, out_array[6] ; bitrev c, c }
{ ; bitrev d, d }
// Zip the even samples as required to send in parallel on a 4b port
// (abcd) (efgh) (ijkl) (mnop) -> aeim bfjn cgko dhlp
zip a, c, 0
zip b, d, 0
zip a, b, 0
zip c, d, 0
// Output the first two even samples.
// Stash the 3rd and 4th even samples for transmission later.
{ stw a, out_array[0] ; out res[out_port], d }
{ stw b, out_array[2] ; out res[out_port], c }
// Input value of the lr_clock and return it
in r0, res[lr_clock]
// Jump to the common end section
bu i2s_frame_slave_4b_loop_part_1_final
i2s_frame_slave_4b_loop_part_1_in_out_body:
// Load and bit-reverse the even 32-bit samples we intend to send
{ ldw a, out_array[0] ; }
{ ldw b, out_array[2] ; bitrev a, a }
{ ldw c, out_array[4] ; bitrev b, b }
{ ldw d, out_array[6] ; bitrev c, c }
{ ; bitrev d, d }
// Zip the even samples as required to send in parallel on a 4b port
// (abcd) (efgh) (ijkl) (mnop) -> aeim bfjn cgko dhlp
zip a, c, 0
zip b, d, 0
zip a, b, 0
zip c, d, 0
// We stashed the 1st and 2nd recieved odd samples earlier - retrieve these.
// Input the 3rd and 4th odd samples.
// Stash the 3rd and 4th even samples for transmission later.
{ ldw f, inp_array[1] ; out res[out_port], d }
{ ldw e, inp_array[3] ; in d, res[inp_port] }
{ stw a, out_array[0] ; out res[out_port], c }
{ stw b, out_array[2] ; in c, res[inp_port] }
// Unzip the recieved odd samples as required
// aeim bfjn cgko dhlp -> (abcd) (efgh) (ijkl) (mnop)
unzip e, f, 0
unzip c, d, 0
unzip d, f, 0
unzip c, e, 0
// Bit-reverse and store the recieved odd samples. At this point, we have
// recieved all 8 samples and must call the recieve callback to pass these
// to the user.
// Input value of the lr_clock and return it
{ ; bitrev f, f }
{ stw f, inp_array[7] ; bitrev e, e }
{ stw e, inp_array[5] ; bitrev d, d }
{ stw d, inp_array[3] ; bitrev c, c }
{ stw c, inp_array[1] ; in r0, res[lr_clock] }
// Continue to common end section
i2s_frame_slave_4b_loop_part_1_final:
// Restore registers and return.
ldw lr_clock, sp[0]
ldd a, b, sp[1]
ldd c, d, sp[2]
ldd e, f, sp[3]
retsp NSTACKWORDS
.L_func_end:
.cc_bottom FUNCTION_NAME.function
.globl FUNCTION_NAME
.type FUNCTION_NAME,@function
.set FUNCTION_NAME.nstackwords,NSTACKWORDS; .global FUNCTION_NAME.nstackwords
.set FUNCTION_NAME.maxcores,1; .global FUNCTION_NAME.maxcores
.set FUNCTION_NAME.maxtimers,0; .global FUNCTION_NAME.maxtimers
.set FUNCTION_NAME.maxchanends,0; .global FUNCTION_NAME.maxchanends

View File

@@ -0,0 +1,201 @@
// Copyright 2022 XMOS LIMITED.
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
/*
void i2s_frame_slave_4b_loop_part_2(
int32_t out_samps[],
int32_t in_samps[],
out buffered port:32 ?p_dout,
in buffered port:32 ?p_din,
out buffered port:32 p_lrclk
);
*/
#define NSTACKWORDS (8)
#define FUNCTION_NAME i2s_frame_slave_4b_loop_part_2
#define out_array r0
#define inp_array r1
#define out_port r2
#define inp_port r3
#define lr_clock r4
#define a r5
#define b r6
#define c r7
#define d r8
#define e r9
#define f r10
.text
.issue_mode dual
.align 4
.cc_top FUNCTION_NAME.function,FUNCTION_NAME
FUNCTION_NAME:
dualentsp NSTACKWORDS
// Store registers r4 upwards to the stack.
stw lr_clock, sp[0]
std a, b, sp[1]
std c, d, sp[2]
std e, f, sp[3]
// Retrieve final argument to the function.
ldw lr_clock, sp[9]
// Split into input-only, output-only, or input-output body implementations
// If the input port is nulled (0), only set up an output. Otherwise, proceed
// to set up an input.
bf inp_port, i2s_frame_slave_4b_loop_part_2_out_body
i2s_frame_slave_4b_loop_part_2_in_body:
// If we are here and the output port is not null (non-0), then both in and
// out are in use. Jump to the input-output implementation.
// Otherwise, just set up an input.
bt out_port, i2s_frame_slave_4b_loop_part_2_in_out_body
// Recieve the even samples
in f, res[inp_port]
in e, res[inp_port]
in d, res[inp_port]
in c, res[inp_port]
// Unzip the recieved even samples as required
// aeim bfjn cgko dhlp -> (abcd) (efgh) (ijkl) (mnop)
unzip e, f, 0
unzip c, d, 0
unzip d, f, 0
unzip c, e, 0
// Bit-reverse and store the recieved even samples.
{ ; bitrev f, f }
{ stw f, inp_array[6] ; bitrev e, e }
{ stw e, inp_array[4] ; bitrev d, d }
{ stw d, inp_array[2] ; bitrev c, c }
{ stw c, inp_array[0] ; }
// Input the first two odd samples. As we are returning from this function,
// we must store these recieved samples in memory to pick up later.
// Input the value of the lr clock and return it
{ ; in f, res[inp_port] }
{ stw f, inp_array[1] ; in e, res[inp_port] }
{ stw e, inp_array[3] ; in r0, res[lr_clock] }
// Jump to the common end section
bu i2s_frame_slave_4b_loop_part_2_final
i2s_frame_slave_4b_loop_part_2_out_body:
// We stashed the 3rd and 4th even samples for transmission earlier.
// Retrieve these and immediately transmit the 3rd.
{ ldw b, out_array[2] ; }
{ ldw a, out_array[0] ; out res[out_port], b }
// Output the 4th even sample
// Load the odd samples we intend to send
{ ldw d, out_array[7] ; }
{ ldw c, out_array[5] ; }
{ ldw b, out_array[3] ; }
{ ldw a, out_array[1] ; out res[out_port], a }
// Bit-reverse the odd samples
{ bitrev d, d ; bitrev c, c }
{ bitrev b, b ; bitrev a, a }
// Zip the odd samples as required to send in parallel on a 4b port
// (abcd) (efgh) (ijkl) (mnop) -> aeim bfjn cgko dhlp
zip a, c, 0
zip b, d, 0
zip a, b, 0
zip c, d, 0
// Output the odd samples
out res[out_port], d
out res[out_port], c
out res[out_port], b
out res[out_port], a
// Input the value of the lr clock and return it
in r0, res[lr_clock]
// Jump to the common end section
bu i2s_frame_slave_4b_loop_part_2_final
i2s_frame_slave_4b_loop_part_2_in_out_body:
// We stashed the 3rd and 4th even samples for transmission earlier.
// Retrieve these and immediately transmit the 3rd.
{ ldw b, out_array[2] ; }
{ ldw a, out_array[0] ; out res[out_port], b }
// Output the 4th even sample
// Load the odd samples we intend to send
// Input the 1st even sample
{ ldw d, out_array[7] ; }
{ ldw c, out_array[5] ; }
{ ldw b, out_array[3] ; in f, res[inp_port] }
{ ldw a, out_array[1] ; out res[out_port], a }
// Bit-reverse the odd samples
{ bitrev d, d ; bitrev c, c }
{ bitrev b, b ; bitrev a, a }
// Zip the odd samples as required to send in parallel on a 4b port
// (abcd) (efgh) (ijkl) (mnop) -> aeim bfjn cgko dhlp
zip a, c, 0
zip b, d, 0
zip a, b, 0
zip c, d, 0
// Output the first two odd samples
// Input the remaining even samples
{ ; in e, res[inp_port] }
{ ; out res[out_port], d }
{ ; in d, res[inp_port] }
{ ; out res[out_port], c }
{ ; in c, res[inp_port] }
// Unzip the recieved even samples as required
// aeim bfjn cgko dhlp -> (abcd) (efgh) (ijkl) (mnop)
unzip e, f, 0
unzip c, d, 0
unzip d, f, 0
unzip c, e, 0
// Bit-reverse and store the recieved even samples.
{ ; bitrev f, f }
{ stw f, inp_array[6] ; bitrev e, e }
{ stw e, inp_array[4] ; bitrev d, d }
{ stw d, inp_array[2] ; bitrev c, c }
{ stw c, inp_array[0] ; }
// Output the remaining odd samples. At this point, we have transmitted all
// 8 samples, and must call the send callback to recieve the next batch.
// Input the first two odd samples. As we are returning from this function
// in order to call the send callback, we must store these recieved samples in
// memory to pick up later.
// Input value of the lr_clock and return it
{ ; out res[out_port], b }
{ ; in f, res[inp_port] }
{ stw f, inp_array[1] ; out res[out_port], a }
{ ; in e, res[inp_port] }
{ stw e, inp_array[3] ; in r0, res[lr_clock] }
// Continue to common end section
i2s_frame_slave_4b_loop_part_2_final:
// Restore registers and return.
ldw lr_clock, sp[0]
ldd a, b, sp[1]
ldd c, d, sp[2]
ldd e, f, sp[3]
retsp NSTACKWORDS
.L_func_end:
.cc_bottom FUNCTION_NAME.function
.globl FUNCTION_NAME
.type FUNCTION_NAME,@function
.set FUNCTION_NAME.nstackwords,NSTACKWORDS; .global FUNCTION_NAME.nstackwords
.set FUNCTION_NAME.maxcores,1; .global FUNCTION_NAME.maxcores
.set FUNCTION_NAME.maxtimers,0; .global FUNCTION_NAME.maxtimers
.set FUNCTION_NAME.maxchanends,0; .global FUNCTION_NAME.maxchanends

View File

@@ -0,0 +1,215 @@
// Copyright 2022 XMOS LIMITED.
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
/*
unsigned i2s_frame_slave_4b_setup(
int32_t out_samps[],
int32_t in_samps[],
out buffered port:32 ?p_dout,
in buffered port:32 ?p_din,
in buffered port:32 p_lrclk
);
*/
#define NSTACKWORDS (8)
#define FUNCTION_NAME i2s_frame_slave_4b_setup
#define out_array r0
#define inp_array r1
#define out_port r2
#define inp_port r3
#define a r4
#define b r5
#define c r6
#define d r7
#define e r8
#define f r9
#define lr_clock r10
.text
.issue_mode dual
.align 4
.cc_top FUNCTION_NAME.function,FUNCTION_NAME
FUNCTION_NAME:
dualentsp NSTACKWORDS
// Store registers r4 upwards to the stack.
std a, b, sp[0]
std c, d, sp[1]
std e, f, sp[2]
stw lr_clock, sp[6]
// Retrieve final argument to the function.
ldw lr_clock, sp[9]
// Split into input-only, output-only, or input-output body implementations
// If the input port is nulled (0), only set up an output. Otherwise, proceed
// to set up an input.
bf inp_port, i2s_frame_slave_4b_setup_out_body
i2s_frame_slave_4b_setup_in_body:
// If we are here and the output port is not null (non-0), then both in and
// out are in use. Jump to the input-output implementation.
// Otherwise, just set up an input.
bt out_port, i2s_frame_slave_4b_setup_in_out_body
// Input samples
{ ; in f, res[inp_port] }
{ ; in e, res[inp_port] }
{ ; in d, res[inp_port] }
{ ; in c, res[inp_port] }
// Unzip the recieved even samples as required
// aeim bfjn cgko dhlp -> (abcd) (efgh) (ijkl) (mnop)
unzip e, f, 0
unzip c, d, 0
unzip d, f, 0
unzip c, e, 0
// Bit-reverse and store the recieved even samples
{ ; bitrev f, f }
{ stw f, inp_array[6] ; bitrev e, e }
{ stw e, inp_array[4] ; bitrev d, d }
{ stw d, inp_array[2] ; bitrev c, c }
{ stw c, inp_array[0] ; }
// Input the first two odd samples. As we are returning from this function,
// we must store these recieved samples in memory to pick up later.
// Input the value of the lr_clock and return it
{ ; in f, res[inp_port] }
{ stw f, inp_array[1] ; in e, res[inp_port] }
{ stw e, inp_array[3] ; in r0, res[lr_clock] }
// Jump to the common end section
bu i2s_frame_slave_4b_setup_final
i2s_frame_slave_4b_setup_out_body:
// Load and bit-reverse the even 32-bit samples we intend to send
{ ldw a, out_array[0] ; }
{ ldw b, out_array[2] ; bitrev a, a }
{ ldw c, out_array[4] ; bitrev b, b }
{ ldw d, out_array[6] ; bitrev c, c }
{ ; bitrev d, d }
// Zip the even samples as required to send in parallel on a 4b port
// (abcd) (efgh) (ijkl) (mnop) -> aeim bfjn cgko dhlp
zip a, c, 0
zip b, d, 0
zip a, b, 0
zip c, d, 0
// Load and bit-reverse the odd 32-bit samples we intend to send
// Output the even samples
{ ldw d, out_array[7] ; out res[out_port], d }
{ ldw c, out_array[5] ; out res[out_port], c }
{ bitrev d, d ; bitrev c, c }
{ ldw b, out_array[3] ; out res[out_port], b }
{ ldw a, out_array[1] ; out res[out_port], a }
{ bitrev b, b ; bitrev a, a }
// Zip the odd samples as required to send in parallel on a 4b port
zip a, c, 0
zip b, d, 0
zip a, b, 0
zip c, d, 0
// Output the odd samples. At this point, we have transmitted all
// 8 samples, and must call the send callback to recieve the next batch.
{ ; out res[out_port], d }
{ ; out res[out_port], c }
{ ; out res[out_port], b }
{ ; out res[out_port], a }
// Input the value of the lr_clock and return it
in r0, res[lr_clock]
// Jump to the common end section
bu i2s_frame_slave_4b_setup_final
i2s_frame_slave_4b_setup_in_out_body:
// Load and bit-reverse the even 32-bit samples we intend to send
{ ldw a, out_array[0] ; }
{ ldw b, out_array[2] ; bitrev a, a }
{ ldw c, out_array[4] ; bitrev b, b }
{ ldw d, out_array[6] ; bitrev c, c }
{ ; bitrev d, d }
// Zip the even samples as required to send in parallel on a 4b port
// (abcd) (efgh) (ijkl) (mnop) -> aeim bfjn cgko dhlp
zip a, c, 0
zip b, d, 0
zip a, b, 0
zip c, d, 0
// Load and bit-reverse the odd 32-bit samples we intend to send
// Output the even samples
// Input the first even sample - this must happen here to meet timing
{ ldw d, out_array[7] ; out res[out_port], d }
{ ldw c, out_array[5] ; out res[out_port], c }
{ ldw b, out_array[3] ; out res[out_port], b }
{ ; in f, res[inp_port] }
{ ldw a, out_array[1] ; out res[out_port], a }
{ bitrev d, d ; bitrev c, c }
{ bitrev b, b ; bitrev a, a }
// Zip the odd samples as required to send in parallel on a 4b port
zip a, c, 0
zip b, d, 0
zip a, b, 0
zip c, d, 0
// Output the first two odd samples
// Input the remaining even samples
{ ; in e, res[inp_port] }
{ ; out res[out_port], d }
{ ; in d, res[inp_port] }
{ ; out res[out_port], c }
{ ; in c, res[inp_port] }
// Unzip the recieved even samples as required
// aeim bfjn cgko dhlp -> (abcd) (efgh) (ijkl) (mnop)
unzip e, f, 0
unzip c, d, 0
unzip d, f, 0
unzip c, e, 0
// Bit-reverse and store the recieved even samples
{ ; bitrev f, f }
{ stw f, inp_array[6] ; bitrev e, e }
{ stw e, inp_array[4] ; bitrev d, d }
{ stw d, inp_array[2] ; bitrev c, c }
{ stw c, inp_array[0] ; }
// Output the remaining odd samples. At this point, we have transmitted all
// 8 samples, and must call the send callback to recieve the next batch.
// Input the first two odd samples. As we are returning from this function
// in order to call the send callback, we must store these recieved samples in
// memory to pick up later.
// Input the value of the lr_clock and return it
{ ; out res[out_port], b }
{ ; in f, res[inp_port] }
{ stw f, inp_array[1] ; out res[out_port], a }
{ ; in e, res[inp_port] }
{ stw e, inp_array[3] ; in r0, res[lr_clock] }
// Continue to common end section
i2s_frame_slave_4b_setup_final:
// Restore registers and return.
ldd a, b, sp[0]
ldd c, d, sp[1]
ldd e, f, sp[2]
ldw lr_clock, sp[6]
retsp NSTACKWORDS
.L_func_end:
.cc_bottom FUNCTION_NAME.function
.globl FUNCTION_NAME
.type FUNCTION_NAME,@function
.set FUNCTION_NAME.nstackwords,NSTACKWORDS; .global FUNCTION_NAME.nstackwords
.set FUNCTION_NAME.maxcores,1; .global FUNCTION_NAME.maxcores
.set FUNCTION_NAME.maxtimers,0; .global FUNCTION_NAME.maxtimers
.set FUNCTION_NAME.maxchanends,0; .global FUNCTION_NAME.maxchanends

View File

@@ -0,0 +1,361 @@
// Copyright 2015-2024 XMOS LIMITED.
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
#include <xs1.h>
#include <xclib.h>
#include "i2s.h"
#include <print.h>
#include "limits.h"
#include "xassert.h"
#include <stdlib.h>
#include <stdio.h>
static void i2s_frame_slave_init_ports(
out buffered port:32 (&?p_dout)[num_out],
size_t num_out,
in buffered port:32 (&?p_din)[num_in],
size_t num_in,
in port p_bclk,
in buffered port:32 p_lrclk,
clock bclk)
{
set_clock_on(bclk);
configure_clock_src(bclk, p_bclk);
configure_in_port(p_lrclk, bclk);
for (size_t i = 0; i < num_out; i++)
configure_out_port(p_dout[i], bclk, 0);
for (size_t i = 0; i < num_in; i++)
configure_in_port(p_din[i], bclk);
start_clock(bclk);
}
#define i2s_frame_slave i2s_frame_slave0
#pragma unsafe arrays
static void i2s_frame_slave0(client i2s_frame_callback_if i2s_i,
out buffered port:32 (&?p_dout)[num_out],
static const size_t num_out,
in buffered port:32 (&?p_din)[num_in],
static const size_t num_in,
static const size_t num_data_bits,
in port p_bclk,
in buffered port:32 p_lrclk,
clock bclk)
{
unsigned port_time;
int32_t in_samps[16]; //Workaround: should be (num_in << 1) but compiler thinks that isn't const,
int32_t out_samps[16];//so setting to 16 which should be big enough for most cases
// Since #pragma unsafe arrays is used need to ensure array won't overflow.
assert((num_in << 1) <= 16);
i2s_config_t config;
config.slave_frame_synch_error = 0;
if (num_data_bits == 32)
{
while(1){
i2s_frame_slave_init_ports(p_dout, num_out, p_din, num_in, p_bclk, p_lrclk, bclk);
i2s_restart_t restart = I2S_NO_RESTART;
i2s_i.init(config, null);
config.slave_frame_synch_error = 0;
//Get initial send data if output enabled
if (num_out) i2s_i.send(num_out << 1, out_samps);
unsigned mode = config.mode;
if (config.slave_bclk_polarity == I2S_SLAVE_SAMPLE_ON_BCLK_FALLING)
set_port_inv(p_bclk);
else
set_port_no_inv(p_bclk);
const unsigned expected_low = (mode == I2S_MODE_I2S ? 0x80000000 : 0x00000000);
const unsigned expected_high = (mode == I2S_MODE_I2S ? 0x7fffffff : 0xffffffff);
unsigned syncerror = 0;
unsigned lrval;
for (size_t i=0;i<num_out;i++)
clearbuf(p_dout[i]);
for (size_t i=0;i<num_in;i++)
clearbuf(p_din[i]);
clearbuf(p_lrclk);
unsigned offset = 0;
if (mode==I2S_MODE_I2S) {
offset = 1;
}
// Wait for LRCLK edge (in I2S LRCLK = 0 is left, TDM rising edge is start of frame)
p_lrclk when pinseq(1) :> void;
p_lrclk when pinseq(0) :> void @ port_time;
unsigned initial_out_port_time = port_time + offset + (I2S_CHANS_PER_FRAME*32);
unsigned initial_in_port_time = port_time + offset + ((I2S_CHANS_PER_FRAME*32)+32) - 1;
//Start outputting evens (0,2,4..) data at correct point relative to the clock
for (size_t i=0, idx=0; i<num_out; i++, idx+=2){
p_dout[i] @ initial_out_port_time <: bitrev(out_samps[idx]);
}
// XC doesn't have syntax for setting a timed input without waiting for the input
asm("setpt res[%0], %1"::"r"(p_lrclk),"r"(initial_in_port_time));
for (size_t i=0;i<num_in;i++) {
asm("setpt res[%0], %1"::"r"(p_din[i]),"r"(initial_in_port_time));
}
//And pre-load the odds (1,3,5..) to follow immediately afterwards
for (size_t i=0, idx=1; i<num_out; i++, idx+=2){
p_dout[i] <: bitrev(out_samps[idx]);
}
//Main loop
while (!syncerror && (restart == I2S_NO_RESTART)) {
restart = i2s_i.restart_check();
if (num_out && (restart == I2S_NO_RESTART)){
i2s_i.send(num_out << 1, out_samps);
//Output i2s evens (0,2,4..)
#pragma loop unroll
for (size_t i=0, idx=0; i<num_out; i++, idx+=2){
p_dout[i] <: bitrev(out_samps[idx]);
}
}
//Read lrclk value
p_lrclk :> lrval;
//Input i2s evens (0,2,4..)
#pragma loop unroll
for (size_t i=0, idx=0; i<num_in; i++, idx+=2){
int32_t data;
asm volatile("in %0, res[%1]":"=r"(data):"r"(p_din[i]):"memory");
in_samps[idx] = bitrev(data);
}
syncerror += (lrval != expected_low);
//Read lrclk value
p_lrclk :> lrval;
//Output i2s odds (1,3,5..)
#pragma loop unroll
if (num_out && (restart == I2S_NO_RESTART)){
for (size_t i=0, idx=1; i<num_out; i++, idx+=2){
p_dout[i] <: bitrev(out_samps[idx]);
}
}
//Input i2s odds (1,3,5..)
#pragma loop unroll
for (size_t i=0, idx=1; i<num_in; i++, idx+=2){
int32_t data;
asm volatile("in %0, res[%1]":"=r"(data):"r"(p_din[i]):"memory");
in_samps[idx] = bitrev(data);
}
syncerror += (lrval != expected_high);
if (num_in && (restart == I2S_NO_RESTART))
{
i2s_i.receive(num_in << 1, in_samps);
}//main loop, runs until user restart or synch error
}
if(restart == I2S_SHUTDOWN)
{
return;
}
if(syncerror)
{
config.slave_frame_synch_error = 1;
}
}// while(1)
}
else // else if num_data_bits != 32
{
const unsigned data_bit_offset = 32 - num_data_bits;
const unsigned data_bit_mask = UINT_MAX >> data_bit_offset; // e.g. 00011111 for 5b data
while (1)
{
i2s_frame_slave_init_ports(p_dout, num_out, p_din, num_in, p_bclk, p_lrclk, bclk);
i2s_config_t config;
i2s_restart_t restart = I2S_NO_RESTART;
i2s_i.init(config, null);
config.slave_frame_synch_error = 0;
// Get initial send data if output enabled
if (num_out)
{
i2s_i.send(num_out << 1, out_samps);
}
unsigned mode = config.mode;
if (config.slave_bclk_polarity == I2S_SLAVE_SAMPLE_ON_BCLK_FALLING)
set_port_inv(p_bclk);
else
set_port_no_inv(p_bclk);
const unsigned expected_low = (mode == I2S_MODE_I2S ? 0x80000000 : 0x00000000) & !data_bit_mask;
const unsigned expected_high = (mode == I2S_MODE_I2S ? 0x7fffffff : 0xffffffff) & !data_bit_mask;
unsigned syncerror = 0;
unsigned lrval;
for (size_t i = 0; i < num_out; i++)
clearbuf(p_dout[i]);
for (size_t i = 0; i < num_in; i++)
clearbuf(p_din[i]);
clearbuf(p_lrclk);
unsigned offset = 0;
if (mode == I2S_MODE_I2S)
{
offset = 1;
}
// Wait for LRCLK edge (in I2S LRCLK = 0 is left, TDM rising edge is start of frame)
p_lrclk when pinseq(1) :> void;
p_lrclk when pinseq(0) :> void @ port_time;
unsigned initial_out_port_time = port_time + offset + (I2S_CHANS_PER_FRAME * num_data_bits);
unsigned initial_in_port_time = port_time + offset + ((I2S_CHANS_PER_FRAME * num_data_bits) + num_data_bits) - 1;
// Start outputting evens (0,2,4..) data at correct point relative to the clock
for (size_t i = 0, idx = 0; i < num_out; i++, idx += 2)
{
partout_timed(p_dout[i], num_data_bits, bitrev(out_samps[idx] << data_bit_offset), initial_out_port_time);
}
// XC doesn't have syntax for setting a timed input without waiting for the input
asm volatile("setpt res[%0], %1"
:
: "r"(p_lrclk), "r"(initial_in_port_time));
set_port_shift_count(p_lrclk, num_data_bits);
for (size_t i = 0; i < num_in; i++)
{
asm volatile("setpt res[%0], %1"
:
: "r"(p_din[i]), "r"(initial_in_port_time));
set_port_shift_count(p_din[i], num_data_bits);
}
// And pre-load the odds (1,3,5..) to follow immediately afterwards
for (size_t i = 0, idx = 1; i < num_out; i++, idx += 2)
{
partout(p_dout[i], num_data_bits, bitrev(out_samps[idx] << data_bit_offset));
}
// Main loop
while (!syncerror && (restart == I2S_NO_RESTART))
{
restart = i2s_i.restart_check();
if (num_out && (restart == I2S_NO_RESTART))
{
i2s_i.send(num_out << 1, out_samps);
// Output i2s evens (0,2,4..)
for (size_t i = 0, idx = 0; i < num_out; i++, idx += 2)
{
partout(p_dout[i], num_data_bits, bitrev(out_samps[idx] << data_bit_offset));
}
}
// Read lrclk value
asm volatile("in %0, res[%1]"
: "=r"(lrval)
: "r"(p_lrclk));
set_port_shift_count(p_lrclk, num_data_bits);
// Input i2s evens (0,2,4..)
for (size_t i = 0, idx = 0; i < num_in; i++, idx += 2)
{
int32_t data;
asm volatile("in %0, res[%1]"
: "=r"(data)
: "r"(p_din[i]));
set_port_shift_count(p_din[i], num_data_bits);
in_samps[idx] = bitrev(data) & data_bit_mask;
}
syncerror += ((lrval & !data_bit_mask) != expected_low);
// Read lrclk value
asm volatile("in %0, res[%1]"
: "=r"(lrval)
: "r"(p_lrclk));
set_port_shift_count(p_lrclk, num_data_bits);
// Output i2s odds (1,3,5..)
#pragma loop unroll
if (num_out && (restart == I2S_NO_RESTART))
{
for (size_t i = 0, idx = 1; i < num_out; i++, idx += 2)
{
partout(p_dout[i], num_data_bits, bitrev(out_samps[idx] << data_bit_offset));
}
}
// Input i2s odds (1,3,5..)
#pragma loop unroll
for (size_t i = 0, idx = 1; i < num_in; i++, idx += 2)
{
int32_t data;
asm volatile("in %0, res[%1]"
: "=r"(data)
: "r"(p_din[i]));
set_port_shift_count(p_din[i], num_data_bits);
in_samps[idx] = bitrev(data) & data_bit_mask;
}
syncerror += ((lrval & !data_bit_mask) != expected_high);
if (num_in && (restart == I2S_NO_RESTART))
{
i2s_i.receive(num_in << 1, in_samps);
}
} // main loop, runs until user restart or synch error
if(restart == I2S_SHUTDOWN)
{
return;
}
if(syncerror)
{
config.slave_frame_synch_error = 1;
}
}// while(1)
} // if num_data_bits == 32
}
// This function is just to avoid unused static function warnings for
// i2s_frame_slave0,it should never be called.
inline void i2s_frame_slave1(client i2s_frame_callback_if i2s_i,
out buffered port:32 (&?p_dout)[num_out],
static const size_t num_out,
in buffered port:32 (&?p_din)[num_in],
static const size_t num_in,
static const size_t num_data_bits,
in port p_bclk,
in buffered port:32 p_lrclk,
clock bclk)
{
if (isnull(p_dout) && isnull(p_din))
{
fail("Must provide non-null p_dout or p_din");
}
i2s_frame_slave0(i2s_i, p_dout, num_out, p_din, num_in, num_data_bits, p_bclk, p_lrclk, bclk);
}

View File

@@ -0,0 +1,229 @@
// Copyright 2015-2021 XMOS LIMITED.
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
#include <xs1.h>
#include <xclib.h>
#include "i2s.h"
#include "xassert.h"
#define FRAME_WORDS (2)
static const unsigned i2s_clk_mask_lookup[5] = {
0xaaaaaaaa, //div 2
0xcccccccc, //div 4
0xf0f0f0f0, //div 8
0xff00ff00, //div 16
0xffff0000, //div 32
};
static void i2s_init_ports(
out buffered port:32 (&?p_dout)[num_out],
static const size_t num_out,
in buffered port:32 (&?p_din)[num_in],
static const size_t num_in,
out buffered port:32 p_bclk,
out buffered port:32 p_lrclk,
clock bclk,
const clock mclk){
set_clock_on(bclk);
configure_clock_src(bclk, p_bclk);
configure_out_port(p_bclk, mclk, 1);
configure_out_port(p_lrclk, bclk, 1);
for (size_t i = 0; i < num_out; i++)
configure_out_port(p_dout[i], bclk, 0);
for (size_t i = 0; i < num_in; i++)
configure_in_port(p_din[i], bclk);
start_clock(bclk);
}
static void inline i2s_output_clock_pair(out buffered port:32 p_bclk,unsigned clk_mask){
p_bclk <: clk_mask;
p_bclk <: clk_mask;
}
#pragma unsafe arrays
static void output_word(
out buffered port:32 p_lrclk,
unsigned &lr_mask,
unsigned total_clk_pairs,
client i2s_callback_if i2s_i,
out buffered port:32 (&?p_dout)[num_out],
static const size_t num_out,
in buffered port:32 (&?p_din)[num_in],
static const size_t num_in,
out buffered port:32 p_bclk,
unsigned clk_mask,
unsigned calls_per_pair,
unsigned offset){
//This is non-blocking
lr_mask = ~lr_mask;
p_lrclk <: lr_mask;
unsigned if_call_num = 0;
for(unsigned clk_pair=0; clk_pair < total_clk_pairs;clk_pair++){
for(unsigned i=0;i<calls_per_pair;i++){
if(if_call_num < num_in){
unsigned data;
asm volatile("in %0, res[%1]":"=r"(data):"r"(p_din[if_call_num]):"memory");
i2s_i.receive(if_call_num*FRAME_WORDS + offset, bitrev(data));
} else if(if_call_num < num_in + num_out){
unsigned index = if_call_num - num_in;
p_dout[index] <: bitrev(i2s_i.send(index*FRAME_WORDS + offset));
}
if_call_num++;
}
//This is blocking
i2s_output_clock_pair(p_bclk, clk_mask);
}
}
#pragma unsafe arrays
static i2s_restart_t i2s_ratio_n(client i2s_callback_if i2s_i,
out buffered port:32 (&?p_dout)[num_out],
static const size_t num_out,
in buffered port:32 (&?p_din)[num_in],
static const size_t num_in,
out buffered port:32 p_bclk,
out buffered port:32 p_lrclk,
unsigned ratio,
i2s_mode_t mode){
unsigned clk_mask = i2s_clk_mask_lookup[ratio-1];
unsigned lr_mask = 0;
int32_t data;
unsigned total_clk_pairs = (1<<(ratio-1));
unsigned calls_per_pair = ((num_in + num_out) + (1<<(ratio-1))-1)>>(ratio-1);
for(size_t i=0;i<num_out;i++)
clearbuf(p_dout[i]);
for(size_t i=0;i<num_in;i++)
clearbuf(p_din[i]);
clearbuf(p_lrclk);
clearbuf(p_bclk);
//Preload word 0
if(mode == I2S_MODE_I2S){
for(size_t i=0;i<num_out;i++)
p_dout[i] @ 2 <: bitrev(i2s_i.send(i*FRAME_WORDS));
partout(p_lrclk, 1, 0);
for(size_t i=0;i<num_in;i++)
asm("setpt res[%0], %1"::"r"(p_din[i]), "r"(32+1));
lr_mask = 0x80000000;
partout(p_bclk, 1<<ratio, clk_mask);
} else {
for(size_t i=0;i<num_out;i++)
p_dout[i] <: bitrev(i2s_i.send(i*FRAME_WORDS));
}
p_lrclk <: lr_mask;
i2s_output_clock_pair(p_bclk, clk_mask);
//This is non-blocking
lr_mask = ~lr_mask;
p_lrclk <: lr_mask;
//Now preload word 1
unsigned if_call_num = 0;
for(unsigned clk_pair=0; clk_pair < total_clk_pairs;clk_pair++){
for(unsigned i=0;i<calls_per_pair;i++){
if(if_call_num < num_out)
p_dout[if_call_num] <: bitrev(i2s_i.send(if_call_num*FRAME_WORDS+1));
if_call_num++;
}
//This is blocking
i2s_output_clock_pair(p_bclk, clk_mask);
}
for(unsigned frm_word_no=1;frm_word_no < FRAME_WORDS - 1; frm_word_no++){
output_word(p_lrclk, lr_mask, total_clk_pairs, i2s_i, p_dout, num_out,
p_din, num_in, p_bclk, clk_mask, calls_per_pair, (1 + frm_word_no)%FRAME_WORDS);
}
//body
while(1){
// Do the first (FRAME_WORDS-1) words of the frame
i2s_restart_t restart = i2s_i.restart_check();
// The final word of each frame is special as it might terminate the transfer
if (restart != I2S_NO_RESTART) {
if_call_num = 0;
for(unsigned clk_pair=0; clk_pair < total_clk_pairs;clk_pair++){
for(unsigned i=0;i<calls_per_pair;i++){
if(if_call_num < num_in){
asm volatile("in %0, res[%1]":"=r"(data):"r"(p_din[if_call_num]):"memory");
i2s_i.receive(if_call_num*FRAME_WORDS + FRAME_WORDS - 2, bitrev(data));
}
if_call_num++;
}
if(clk_pair < total_clk_pairs-1)
i2s_output_clock_pair(p_bclk, clk_mask);
}
sync(p_bclk);
for(size_t i=0;i<num_in;i++){
asm volatile("in %0, res[%1]":"=r"(data):"r"(p_din[i]):"memory");
i2s_i.receive(i*FRAME_WORDS + FRAME_WORDS - 1, bitrev(data));
}
return restart;
} else {
output_word(p_lrclk, lr_mask, total_clk_pairs, i2s_i, p_dout, num_out,
p_din, num_in, p_bclk, clk_mask, calls_per_pair, 0);
}
for(unsigned frm_word_no=0;frm_word_no < FRAME_WORDS-1; frm_word_no++){
output_word(p_lrclk, lr_mask, total_clk_pairs, i2s_i, p_dout, num_out,
p_din, num_in, p_bclk, clk_mask, calls_per_pair, (1 + frm_word_no)%FRAME_WORDS);
}
}
return I2S_RESTART;
}
#define i2s_master i2s_master0
static void i2s_master0(client i2s_callback_if i2s_i,
out buffered port:32 (&?p_dout)[num_out],
static const size_t num_out,
in buffered port:32 (&?p_din)[num_in],
static const size_t num_in,
out buffered port:32 p_bclk,
out buffered port:32 p_lrclk,
clock bclk,
const clock mclk){
while(1){
i2s_config_t config;
unsigned mclk_bclk_ratio_log2;
i2s_i.init(config, null);
if (isnull(p_dout) && isnull(p_din)) {
fail("Must provide non-null p_dout or p_din");
}
mclk_bclk_ratio_log2 = clz(bitrev(config.mclk_bclk_ratio));
//This ensures that the port time on all the ports is at 0
i2s_init_ports(p_dout, num_out, p_din, num_in,
p_bclk, p_lrclk, bclk, mclk);
i2s_restart_t restart =
i2s_ratio_n(i2s_i, p_dout, num_out, p_din,
num_in, p_bclk, p_lrclk,
mclk_bclk_ratio_log2, config.mode);
if (restart == I2S_SHUTDOWN)
return;
}
}
// This function is just to avoid unused static function warnings for i2s_master0,
// it should never be called.
inline void i2s_master1(client interface i2s_callback_if i,
out buffered port:32 i2s_dout[num_i2s_out],
static const size_t num_i2s_out,
in buffered port:32 i2s_din[num_i2s_in],
static const size_t num_i2s_in,
out buffered port:32 i2s_bclk,
out buffered port:32 i2s_lrclk,
clock clk_bclk,
const clock clk_mclk) {
i2s_master0(i, i2s_dout, num_i2s_out, i2s_din, num_i2s_in,
i2s_bclk, i2s_lrclk,
clk_bclk, clk_mclk);
}

View File

@@ -0,0 +1,148 @@
// Copyright 2015-2024 XMOS LIMITED.
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
#include <xs1.h>
#include <xclib.h>
#include "i2s.h"
#define I2S_CHANS_PER_FRAME (2)
static void i2s_slave_init_ports(
out buffered port:32 (&?p_dout)[num_out],
size_t num_out,
in buffered port:32 (&?p_din)[num_in],
size_t num_in,
in port p_bclk,
in buffered port:32 p_lrclk,
clock bclk){
set_clock_on(bclk);
configure_clock_src(bclk, p_bclk);
configure_in_port(p_lrclk, bclk);
for (size_t i = 0; i < num_out; i++) {
configure_out_port(p_dout[i], bclk, 0);
}
for (size_t i = 0; i < num_in; i++) {
configure_in_port(p_din[i], bclk);
}
start_clock(bclk);
}
static void i2s_slave_send(client i2s_callback_if i2s_i,
out buffered port:32 (&?p_dout)[num_out],
size_t num_out, unsigned frame_word){
for(size_t i=0;i<num_out;i++) {
p_dout[i] <: bitrev(i2s_i.send(i*2+frame_word));
}
}
static void i2s_slave_receive(client i2s_callback_if i2s_i,
in buffered port:32 (&?p_din)[num_in],
size_t num_in, unsigned frame_word){
for (size_t i=0;i<num_in;i++) {
unsigned data;
p_din[i] :> data;
i2s_i.receive(i*2 + frame_word, bitrev(data));
}
}
#define i2s_slave i2s_slave0
static void i2s_slave0(client i2s_callback_if i2s_i,
out buffered port:32 (&?p_dout)[num_out],
static const size_t num_out,
in buffered port:32 (&?p_din)[num_in],
static const size_t num_in,
in port p_bclk,
in buffered port:32 p_lrclk,
clock bclk){
unsigned syncerror;
unsigned lrval;
unsigned port_time;
i2s_slave_init_ports(p_dout, num_out, p_din, num_in, p_bclk, p_lrclk, bclk);
i2s_config_t config;
config.slave_frame_synch_error = 0;
while(1) {
i2s_mode_t m;
i2s_restart_t restart = I2S_NO_RESTART;
config.slave_bclk_polarity = I2S_SLAVE_SAMPLE_ON_BCLK_RISING;
i2s_i.init(config, null);
config.slave_frame_synch_error = 0;
m = config.mode;
if (config.slave_bclk_polarity == I2S_SLAVE_SAMPLE_ON_BCLK_FALLING)
set_port_inv(p_bclk);
else
set_port_no_inv(p_bclk);
unsigned expected_low = (m==I2S_MODE_I2S) ? 0 : 0x80000000;
unsigned expected_high = (m==I2S_MODE_I2S) ? 0xffffffff : 0x7fffffff;
syncerror = 0;
clearbuf(p_lrclk);
/* Wait for LRCLK edge (in I2S LRCLK = 0 is left, TDM rising edge is start of frame) */
p_lrclk when pinseq(1) :> void;
p_lrclk when pinseq(0) :> void @ port_time;
for (size_t i=0;i<num_out;i++) {
p_dout[i] @ (port_time+32+32+(m==I2S_MODE_I2S)) <: bitrev(i2s_i.send(i*2));
}
/* Setup input for next frame. Account for the buffering in port */
port_time += ((I2S_CHANS_PER_FRAME*32)+32);
/* XC doesn't have syntax for setting a timed input without waiting for the input */
/* -1 on LRClock makes checking a lot easier since data is offset with LRclock by 1 clk */
asm("setpt res[%0], %1"::"r"(p_lrclk),"r"(port_time-(m==I2S_MODE_I2S)));
for (size_t i=0;i<num_in;i++) {
asm("setpt res[%0], %1"::"r"(p_din[i]),"r"(port_time-(m!=I2S_MODE_I2S)));
}
while (!syncerror && (restart == I2S_NO_RESTART)) {
i2s_slave_send(i2s_i, p_dout, num_out, 1);
i2s_slave_receive(i2s_i, p_din, num_in, 0);
p_lrclk :> lrval;
syncerror += (lrval != expected_low);
restart = i2s_i.restart_check();
if (restart == I2S_NO_RESTART) {
i2s_slave_send(i2s_i, p_dout, num_out, 0);
}
i2s_slave_receive(i2s_i, p_din, num_in, 1);
p_lrclk :> lrval;
syncerror += (lrval != expected_high);
}
if (restart == I2S_SHUTDOWN) {
return;
}
if(syncerror){
config.slave_frame_synch_error = 1;
}
}
}
// This function is just to avoid unused static function warnings for
// i2s_slave0,it should never be called.
inline void i2s_slave1(client i2s_callback_if i2s_i,
out buffered port:32 (&?p_dout)[num_out],
static const size_t num_out,
in buffered port:32 (&?p_din)[num_in],
static const size_t num_in,
in port p_bclk,
in buffered port:32 p_lrclk,
clock bclk){
if (isnull(p_dout) && isnull(p_din)) {
fail("Must provide non-null p_dout or p_din");
}
i2s_slave0(i2s_i, p_dout, num_out, p_din, num_in, p_bclk, p_lrclk, bclk);
}

View File

@@ -0,0 +1,33 @@
// Copyright 2015-2021 XMOS LIMITED.
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
#ifndef TDM_COMMON_H_
#define TDM_COMMON_H_
#include <xclib.h>
#define TDM_MAX_CHANNELS_PER_DATA_LINE (16)
static void make_fsync_mask(
unsigned fsync_mask[],
int offset,
unsigned sclk_edge_count,
unsigned channels_per_data_line){
unsigned hi_edge = (offset)%(channels_per_data_line*32);
unsigned lo_edge = (sclk_edge_count+offset)%(channels_per_data_line*32);
unsigned bit_no = 0;
unsigned w;
for(unsigned i=0;i<channels_per_data_line;i++){
for(unsigned j=0;j<32;j++){
w<<=1;
if(lo_edge > hi_edge)
w += ((bit_no>=hi_edge)&&(bit_no < lo_edge));
else
w += ((bit_no>=hi_edge)||(bit_no < lo_edge));
bit_no++;
}
fsync_mask[i] = bitrev(w);
}
}
#endif /* TDM_COMMON_H_ */

View File

@@ -0,0 +1,167 @@
// Copyright 2015-2021 XMOS LIMITED.
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
#include <i2s.h>
#include <xs1.h>
#include <xclib.h>
#include "tdm_common.h"
static void tdm_init_ports(
out buffered port:32 (&?p_dout)[num_out],
const size_t num_out,
in buffered port:32 (&?p_din)[num_in],
const size_t num_in,
out buffered port:32 p_fsync,
clock clk){
stop_clock(clk);
configure_out_port(p_fsync, clk, 0);
for (size_t i = 0; i < num_out; i++)
configure_out_port(p_dout[i], clk, 0);
for (size_t i = 0; i < num_in; i++)
configure_in_port(p_din[i], clk);
start_clock(clk);
}
[[always_inline]]
static void tdm_send(client i2s_callback_if tdm_i,
out buffered port:32 (&?p_dout)[num_out],
size_t num_out,
unsigned channels_per_data_line,
unsigned word){
for(size_t i=0;i<num_out;i++)
p_dout[i] <: bitrev(tdm_i.send(i*channels_per_data_line + word));
}
[[always_inline]]
static void tdm_receive(client i2s_callback_if tdm_i,
in buffered port:32 (&?p_din)[num_in],
size_t num_in,
unsigned channels_per_data_line,
unsigned word){
for(size_t i=0;i<num_in;i++){
uint32_t data;
asm volatile("in %0, res[%1]":"=r"(data):"r"(p_din[i]):"memory");
tdm_i.receive(i*channels_per_data_line + word, bitrev(data));
}
}
[[always_inline]]
static i2s_restart_t do_tdm(client i2s_callback_if tdm_i,
out buffered port:32 (&?p_dout)[num_out],
size_t num_out,
in buffered port:32 (&?p_din)[num_in],
size_t num_in,
out buffered port:32 p_fsync,
int offset,
unsigned sclk_edge_count,
unsigned channels_per_data_line){
i2s_restart_t restart = I2S_NO_RESTART;
unsigned fsync_mask[TDM_MAX_CHANNELS_PER_DATA_LINE] ={0};
p_fsync <: 0;
make_fsync_mask(fsync_mask, offset, sclk_edge_count, channels_per_data_line);
for(size_t i=0;i<num_out;i++){
clearbuf(p_dout[i]);
p_dout[i] <: 0;
}
for(size_t i=0;i<num_in;i++)
clearbuf(p_din[i]);
unsigned port_time;
p_fsync <: 0 @ port_time;
port_time += 80;//lots!
if(offset < 0)
partout_timed(p_fsync, -offset, bitrev(fsync_mask[channels_per_data_line-1]), port_time + offset);
for(size_t i=0;i<num_in;i++)
asm("setpt res[%0], %1"::"r"(p_din[i]), "r"(port_time+32-1));
for(size_t i=0;i<num_out;i++)
p_dout[i] @ port_time <: bitrev(tdm_i.send(i*channels_per_data_line + 0));
p_fsync @ port_time <: fsync_mask[0];
restart = tdm_i.restart_check();
p_fsync <: fsync_mask[1];
tdm_send(tdm_i, p_dout, num_out, channels_per_data_line, 1);
for(unsigned frm_word_no = 2;frm_word_no < channels_per_data_line; frm_word_no++){
tdm_receive(tdm_i, p_din, num_in, channels_per_data_line, frm_word_no-2);
p_fsync <: fsync_mask[frm_word_no];
tdm_send(tdm_i, p_dout, num_out, channels_per_data_line, frm_word_no);
}
while(1){
if (restart != I2S_NO_RESTART){
tdm_receive(tdm_i, p_din, num_in, channels_per_data_line, channels_per_data_line-2);
tdm_receive(tdm_i, p_din, num_in, channels_per_data_line, channels_per_data_line-1);
sync(p_din[0]);
p_fsync <: 0;
return restart;
}
tdm_receive(tdm_i, p_din, num_in, channels_per_data_line, channels_per_data_line-2);
p_fsync <: fsync_mask[0];
tdm_send(tdm_i, p_dout, num_out, channels_per_data_line, 0);
restart = tdm_i.restart_check();
for(unsigned frm_word_no=1;frm_word_no < channels_per_data_line; frm_word_no++){
tdm_receive(tdm_i, p_din, num_in, channels_per_data_line,
(frm_word_no-2)&(channels_per_data_line-1));
p_fsync <: fsync_mask[frm_word_no];
tdm_send(tdm_i, p_dout, num_out, channels_per_data_line, frm_word_no);
}
}
return I2S_RESTART;
}
#define tdm_master tdm_master0
static void tdm_master0(client interface i2s_callback_if tdm_i,
out buffered port:32 p_fsync,
out buffered port:32 (&?p_dout)[num_out],
size_t num_out,
in buffered port:32 (&?p_din)[num_in],
size_t num_in,
clock clk){
if (isnull(p_dout) && isnull(p_din)) {
fail("Must provide non-null p_dout or p_din");
}
tdm_init_ports(p_dout, num_out, p_din, num_in, p_fsync, clk);
while(1){
int offset;
unsigned sclk_edge_count;
unsigned channels_per_data_line;
tdm_config_t config;
tdm_i.init(null, config);
i2s_restart_t restart =
do_tdm(tdm_i,
p_dout,num_out,
p_din, num_in,
p_fsync,
config.offset, config.sync_len, config.channels_per_frame);
if (restart == I2S_SHUTDOWN)
return;
}
}
// This function is just to avoid unused static function warnings for
// tdm_master0,it should never be called.
inline void tdm_master1(client interface i2s_callback_if tdm_i,
out buffered port:32 p_fsync,
out buffered port:32 (&?p_dout)[num_out],
size_t num_out,
in buffered port:32 (&?p_din)[num_in],
size_t num_in,
clock clk){
tdm_master0(tdm_i, p_fsync, p_dout, num_out, p_din, num_in, clk);
}

20
lib_i2s/python/setup.py Normal file
View File

@@ -0,0 +1,20 @@
# Copyright 2020-2021 XMOS LIMITED.
# This Software is subject to the terms of the XMOS Public Licence: Version 1.
import setuptools
# Another repository might depend on python code defined in this one. The
# procedure to set up a suitable python environment for that repository may
# pip-install this one as editable using this setup.py file. To minimise the
# chance of version conflicts while ensuring a minimal degree of conformity,
# the 3rd-party modules listed here require the same major version and at
# least the same minor version as specified in the requirements.txt file.
# The same modules should appear in the requirements.txt file as given below.
setuptools.setup(
name='lib_i2s',
packages=setuptools.find_packages(),
install_requires=[
'flake8~=3.8',
],
dependency_links=[
],
)