├── .gitignore
├── CHANGELOG.rst
├── LICENSE.txt
├── Makefile
├── README.rst
├── app_slicekit_i2s_master_demo
├── .cproject
├── .project
├── .xproject
├── Makefile
├── README.rst
├── doc
│ ├── Makefile
│ ├── images
│ │ ├── hw_setup-wide.png
│ │ ├── hw_setup.JPG
│ │ └── hw_setup.png
│ └── index.rst
└── src
│ ├── app_global.h
│ ├── audio_hw.xc
│ ├── i2c_conf.h
│ ├── i2s_master_conf.h
│ ├── main.xc
│ ├── ports.h
│ └── xa_sk_audio_1v1.h
├── doc
├── Makefile
├── api.rst
├── hw.rst
├── index.rst
├── programming.rst
└── summary.rst
├── doc_slave
└── slave.rst
├── module_i2s_loopback
├── .cproject
├── .makefile
├── .project
├── .xproject
├── README.rst
├── module_build_info
├── module_i2s_loopback.metainfo
└── src
│ ├── i2s_loopback.h
│ └── i2s_loopback.xc
├── module_i2s_master
├── .cproject
├── .makefile
├── .project
├── .xproject
├── README
├── README.rst
├── i2s_master_conf_example.h
├── module_build_info
├── module_description
├── module_i2s_master.metainfo
└── src
│ ├── i2s_master.h
│ └── i2s_master.xc
├── module_i2s_slave
├── .cproject
├── .makefile
├── .project
├── .xproject
├── README
├── README.rst
├── module_build_info
├── module_description
└── src
│ ├── i2s_slave.h
│ └── i2s_slave.xc
└── xpd.xml
/.gitignore:
--------------------------------------------------------------------------------
1 | *.*~
2 |
--------------------------------------------------------------------------------
/CHANGELOG.rst:
--------------------------------------------------------------------------------
1 | sc_i2s Change Log
2 | =================
3 |
4 | 1.6.0
5 | -----
6 | - RESOLVED: LR clock not aligned properly due as it was set to be driven at 31 but then not
7 | driven again until after 64 clock ticks. This meant that it would be aligned to
8 | the instruction stream rather than clock edges as desired. The fix keeps the
9 | output buffer full to ensure that it keeps the initial alignment.
10 |
11 | 1.5.0
12 | -----
13 | - RESOLVED: ADC samples over the channel interface were misaligned. Instead of the
14 | expected left/right channel sequence: (l1, r1) ... (l2, r2) ... (l3, r3)
15 | the following order was returned:(r1, l2) ... (r2, l3) ... (r3, l4)
16 | This was resolved by by rotating the main loop such that the port I/O
17 | syncs with the channel I/O.
18 |
19 | * Changes to dependencies:
20 |
21 | - sc_i2c: 2.2.1rc0 -> 2.4.1rc0
22 |
23 | + module_i2c_simple header-file comments updated to correctly reflect API
24 | + module_i2c_simple can now be built with support to send repeated starts and retry reads and writes NACKd by slave
25 | + module_i2c_shared added to allow multiple logical cores to safely share a single I2C bus
26 | + Removed readreg() function from single_port module since it was not safe
27 |
28 | 1.4.3
29 | -----
30 | - Dependancy update only
31 |
32 | 1.4.2
33 | -----
34 | - Dependancy update only
35 |
36 | 1.4.1
37 | -----
38 | - More documentation and code updates following review
39 |
40 | 1.4.0
41 | -----
42 | - Updates to components and documents for slicekit and xSOFTip
43 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | Software License Agreement
2 |
3 | Copyright (c) 2011, XMOS Ltd., All rights reserved.
4 |
5 | The copyright holders hereby grant to any person obtaining a copy of this software (the "Software") and/or its associated
6 | documentation files (the Documentation), the perpetual, irrevocable (except in the case of breach of this license) no-cost,
7 | royalty free, sublicensable rights to use, copy, modify, merge, publish, display, publicly perform, distribute, and/or
8 | sell copies of the Software and the Documentation, together or separately, and to permit persons to whom the Software and/or
9 | Documentation is furnished to do so, subject to the following conditions:
10 |
11 | . Redistributions of the Software in source code must retain the above copyright notice, this list of conditions and the
12 | following disclaimers.
13 |
14 | . Redistributions of the Software in binary form must reproduce the above copyright notice, this list of conditions and
15 | the following disclaimers in the documentation and/or other materials provided with the distribution.
16 |
17 | . Redistributions of the Documentation must retain the above copyright notice, this list of conditions and the following
18 | disclaimers.
19 |
20 | Neither the name of XMOS, nor the names of its contributors may be used to endorse or promote products derived from this
21 | Software or the Documentation without specific prior written permission of the copyright holder.
22 |
23 | THE SOFTWARE AND DOCUMENTATION ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
24 | LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25 | CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
26 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR DOCUMENTATION OR THE USE OF OR OTHER
27 | DEALINGS WITH THE SOFTWARE OR DOCUMENTATION.
28 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | # This variable should contain a space separated list of all
2 | # the directories containing buildable applications (usually
3 | # prefixed with the app_ prefix)
4 | #
5 | # If the variable is set to "all" then all directories that start with app_
6 | # are built.
7 | BUILD_SUBDIRS = all
8 |
9 | XMOS_MAKE_PATH ?= ..
10 | include $(XMOS_MAKE_PATH)/xcommon/module_xcommon/build/Makefile.toplevel
11 |
--------------------------------------------------------------------------------
/README.rst:
--------------------------------------------------------------------------------
1 | I2S Digital Audio Component
2 | ...........................
3 |
4 | :Latest release: 1.6.0rc0
5 | :Maintainer: XMOS
6 | :Description: I2S Digital Audio Component
7 |
8 |
9 | Key Features
10 | ============
11 |
12 | * Master and Slave I2S component
13 | * Runs in a thread - multiple data interfaces supported (with same
14 | clock domain)
15 | * Includes application demonstrations
16 |
17 | Documentation
18 | =============
19 |
20 | Full documentation can be found at: http://xcore.github.com/sc_i2s/
21 |
22 | Support
23 | =======
24 |
25 | Issues may be submitted via the Issues tab in this github repo. Response to any issues submitted as at the discretion of the manitainer for this line.
26 |
27 | Required software (dependencies)
28 | ================================
29 |
30 | * sc_i2c (ssh://git@github.com/xcore/sc_i2c)
31 | * sc_util (git://github.com/xcore/sc_util)
32 |
33 |
--------------------------------------------------------------------------------
/app_slicekit_i2s_master_demo/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | app_slicekit_i2s_master_demo
4 |
5 |
6 |
7 |
8 |
9 | org.eclipse.cdt.managedbuilder.core.genmakebuilder
10 | clean,full,incremental,
11 |
12 |
13 | ?children?
14 | ?name?=outputEntries\|?children?=?name?=entry\\\\|\\|\||
15 |
16 |
17 | ?name?
18 |
19 |
20 |
21 | org.eclipse.cdt.make.core.append_environment
22 | true
23 |
24 |
25 | org.eclipse.cdt.make.core.buildArguments
26 | CONFIG=Debug
27 |
28 |
29 | org.eclipse.cdt.make.core.buildCommand
30 | xmake
31 |
32 |
33 | org.eclipse.cdt.make.core.cleanBuildTarget
34 | clean
35 |
36 |
37 | org.eclipse.cdt.make.core.contents
38 | org.eclipse.cdt.make.core.activeConfigSettings
39 |
40 |
41 | org.eclipse.cdt.make.core.enableAutoBuild
42 | false
43 |
44 |
45 | org.eclipse.cdt.make.core.enableCleanBuild
46 | true
47 |
48 |
49 | org.eclipse.cdt.make.core.enableFullBuild
50 | true
51 |
52 |
53 | org.eclipse.cdt.make.core.stopOnError
54 | true
55 |
56 |
57 | org.eclipse.cdt.make.core.useDefaultBuildCmd
58 | false
59 |
60 |
61 |
62 |
63 | org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder
64 | full,incremental,
65 |
66 |
67 |
68 |
69 |
70 | org.eclipse.cdt.core.cnature
71 | org.eclipse.cdt.managedbuilder.core.managedBuildNature
72 | org.eclipse.cdt.managedbuilder.core.ScannerConfigNature
73 | com.xmos.cdt.core.XdeProjectNature
74 |
75 |
76 |
77 |
--------------------------------------------------------------------------------
/app_slicekit_i2s_master_demo/.xproject:
--------------------------------------------------------------------------------
1 | sc_i2sXM-002000-SM
--------------------------------------------------------------------------------
/app_slicekit_i2s_master_demo/Makefile:
--------------------------------------------------------------------------------
1 | # The TARGET variable determines what target system the application is
2 | # compiled for. It either refers to an XN file in the source directories
3 | # or a valid argument for the --target option when compiling
4 | TARGET = SLICEKIT-L2
5 |
6 | # The APP_NAME variable determines the name of the final .xe file. It should
7 | # not include the .xe postfix. If left blank the name will default to
8 | # the project name
9 | APP_NAME = app_slicekit_i2s_master_demo
10 |
11 | # The USED_MODULES variable lists other module used by the application.
12 | USED_MODULES = module_i2c_single_port module_i2s_loopback module_i2s_master
13 |
14 | # The flags passed to xcc when building the application
15 | # You can also set the following to override flags for a particular language:
16 | # XCC_XC_FLAGS, XCC_C_FLAGS, XCC_ASM_FLAGS, XCC_CPP_FLAGS
17 | # If the variable XCC_MAP_FLAGS is set it overrides the flags passed to
18 | # xcc for the final link (mapping) stage.
19 | XCC_FLAGS_Debug = -O3 -g -Wall
20 | XCC_FLAGS_Release = -O3 -Wall
21 |
22 | # The VERBOSE variable, if set to 1, enables verbose output from the make system.
23 | VERBOSE = 0
24 |
25 | XMOS_MAKE_PATH ?= ../..
26 | -include $(XMOS_MAKE_PATH)/xcommon/module_xcommon/build/Makefile.common
27 |
28 |
--------------------------------------------------------------------------------
/app_slicekit_i2s_master_demo/README.rst:
--------------------------------------------------------------------------------
1 | I2S Master sliceKIT Loopback Demo
2 | =================================
3 |
4 | :scope: Example
5 | :description: Uses the I2S master in loopback mode to demonstrate usage of this component
6 | :keywords: Audio, I2S
7 | :boards: XA-SK-AUDIO
8 |
9 | Features
10 | --------
11 |
12 | * Input stereo audio via analog jack
13 | * Output stereo audio via analog jack
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/app_slicekit_i2s_master_demo/doc/Makefile:
--------------------------------------------------------------------------------
1 | all: html
2 |
3 | SPHINX_PROJECT_NAME = I2S Master Demonstration Application
4 | VERSION = 0.1
5 | SOURCE_INCLUDE_DIRS = ../
6 | XDOC_DIR ?= ../../../xdoc
7 | include $(XDOC_DIR)/Makefile.inc
8 |
--------------------------------------------------------------------------------
/app_slicekit_i2s_master_demo/doc/images/hw_setup-wide.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xcore/sc_i2s/9052dd638e5ae3346dfe1c7b3a386a61a88727fe/app_slicekit_i2s_master_demo/doc/images/hw_setup-wide.png
--------------------------------------------------------------------------------
/app_slicekit_i2s_master_demo/doc/images/hw_setup.JPG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xcore/sc_i2s/9052dd638e5ae3346dfe1c7b3a386a61a88727fe/app_slicekit_i2s_master_demo/doc/images/hw_setup.JPG
--------------------------------------------------------------------------------
/app_slicekit_i2s_master_demo/doc/images/hw_setup.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xcore/sc_i2s/9052dd638e5ae3346dfe1c7b3a386a61a88727fe/app_slicekit_i2s_master_demo/doc/images/hw_setup.png
--------------------------------------------------------------------------------
/app_slicekit_i2s_master_demo/doc/index.rst:
--------------------------------------------------------------------------------
1 | I2S Master sliceKIT Loopback Demo Quickstart Guide
2 | ==================================================
3 |
4 | .. toctree::
5 |
6 | This application uses the I2S master module to demonstrate a simple audio loopback in software and offers a simple introduction to implementing or prototyping audio processing on an xCORE processor. It is designed to run on the XMOS L2 sliceKIT Core Board (XP-SKC-L16) in conjuction with an Audio sliceCARD (XA-SK-AUDIO).
7 |
8 | The functionality of the program is a follows:
9 |
10 | * Setup the audio hardware on the board as required, this includes Master clock selection and CODEC setup (using module_i2c_master)
11 | * Provide a digital loopback from all ADC inputs to all DAC outputs (that is, ADC1 -> DAC1). A ``processing()`` function accepts ADC data from the I2S master component and outputs the back to the I2S component as DAC data.
12 |
13 |
14 | Hardware Setup
15 | ++++++++++++++
16 |
17 | To setup the hardware:
18 |
19 | #. Connect the XA-SK-AUDIO slice card to the XP-SKC-L16 sliceKIT Core Board using the connector marked with the ``CIRCLE``.
20 | #. Connect the XTAG-2 USB debug adaptor to the XP-SKC-L16 sliceKIT Core Board (via the supplied adaptor board)
21 | #. Connect the XTAG-2 to host PC (as USB extension cable can be used if desired)
22 | #. Connect the power supply to the XP-SKC-L16 sliceKIT Core Board
23 | #. Attach an audio source (such as an MP3 player) to input 1/2 (marked ``In 1-2``) via the 3.5mm audio jack.
24 | #. Attach speakers or headphones to output 1/2 via the 3.5mm audio jack (marked ``Out 1-2``)
25 |
26 | .. figure:: images/hw_setup.png
27 | :width: 300px
28 | :align: center
29 |
30 | Hardware Setup for XA-SK-AUDIO demo (I2S master)
31 |
32 | Import and Build the Application
33 | ++++++++++++++++++++++++++++++++
34 |
35 | #. Open xTIMEcomposer and open the edit perspective (Window->Open Perspective->XMOS Edit).
36 | #. Locate the ``I2S Master sliceKIT Loopback Demo`` item in the xSOFTip pane on the bottom left of the window and drag it into the Project Explorer window in the xTIMEcomposer. This will also cause the modules on which this application depends (in this case, module_i2c_master) to be imported as well.
37 | #. Click on the ``app_slicekit_i2s_master_demo`` item in the Explorer pane then click on the build icon (hammer) in xTIMEcomposer. Check the console window to verify that the application has built successfully.
38 |
39 | Note that the Developer Column in the xTIMEcomposer on the right hand side of your screen provides information on the xSOFTip components you are using. Select the module_i2c_master component in the Project Explorer, and you will see its description together with API documentation. Having done this, click the `back` icon until you return to this quickstart guide within the Developer Column.
40 |
41 | For help in using xTIMEcomposer, try the xTIMEcomposer tutorial (See Help->Tutorials in xTIMEcomposer).
42 |
43 | Run the Application
44 | +++++++++++++++++++
45 |
46 | Now that the application has been compiled, the next step is to run it on the sliceKIT Core Board using the tools to load the application over JTAG (via the xTAG2 and xTAG Adaptor card) into the xCORE multicore microcontroller.
47 |
48 | #. Click on the ``Run`` icon (the white arrow in the green circle). A dialog will appear asking which device to connect to. Select ``XMOS XTAG2``.
49 | #. The application will now be running and providing a loopback functionality. Listen for the output via headphones or speakers. If the audio source is changed to input 3/4, the output will be available on output 3/4. There is no need to restart the application, just switch the audio connections over.
50 | #. Terminating the application will cause the loopback to stop.
51 |
52 | Next Steps
53 | ++++++++++
54 |
55 | #. Take a look at the various Audio DSP and processing components provided within the xSOFTip suite including filter/biquad, delay lines, non-linear gain and reverb.
56 | #. Review the XMOS USB audio reference designs, available at xmos.com (See ``Resources -> xKITS Resources -> reference Designs``).
57 |
58 |
--------------------------------------------------------------------------------
/app_slicekit_i2s_master_demo/src/app_global.h:
--------------------------------------------------------------------------------
1 |
2 | #ifndef _APP_GLOBAL_H_
3 | #define _APP_GLOBAL_H_
4 |
5 | #include
6 | #include
7 |
8 | /* Core that Audio Slice is connected to */
9 | #define AUDIO_IO_CORE 1
10 |
11 | /* Audio sample frequency (Hz) */
12 | #define SAMP_FREQ 48000
13 |
14 | /**************/
15 | /* Audio clocking defines */
16 | /* Master clock defines (Hz) */
17 | #define MCLK_FREQ_441 (512*44100) /* 44.1, 88.2 etc */
18 | #define MCLK_FREQ_48 (512*48000) /* 48, 96 etc */
19 |
20 | #if (SAMP_FREQ%22050==0)
21 | #define MCLK_FREQ MCLK_FREQ_441
22 | #elif (SAMP_FREQ%24000==0)
23 | #define MCLK_FREQ MCLK_FREQ_48
24 | #else
25 | #error Unsupported sample frequency
26 | #endif
27 |
28 |
29 |
30 | #endif /* ifndef _GLOBAL_H_ */
31 |
32 |
--------------------------------------------------------------------------------
/app_slicekit_i2s_master_demo/src/audio_hw.xc:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include "app_global.h"
4 | #include "i2c.h"
5 | #include "xa_sk_audio_1v1.h"
6 |
7 | extern port p_i2c;
8 | extern out port p_gpio;
9 |
10 | void audio_hw_init()
11 | {
12 | /* Initialise the I2C bus */
13 | i2c_master_init(p_i2c);
14 | }
15 |
16 |
17 | #define CODEC1_I2C_DEVICE_ADDR (0x90)
18 | #define CODEC2_I2C_DEVICE_ADDR (0x92)
19 |
20 | #define CODEC_DEV_ID_ADDR 0x01
21 | #define CODEC_PWR_CTRL_ADDR 0x02
22 | #define CODEC_MODE_CTRL_ADDR 0x03
23 | #define CODEC_ADC_DAC_CTRL_ADDR 0x04
24 | #define CODEC_TRAN_CTRL_ADDR 0x05
25 | #define CODEC_MUTE_CTRL_ADDR 0x06
26 | #define CODEC_DACA_VOL_ADDR 0x07
27 | #define CODEC_DACB_VOL_ADDR 0x08
28 |
29 | #define IIC_REGWRITE(reg, val) {data[0] = val; i2c_master_write_reg(CODEC1_I2C_DEVICE_ADDR, reg, data, 1, p_i2c);data[0] = val; i2c_master_write_reg(CODEC2_I2C_DEVICE_ADDR, reg, data, 1, p_i2c);}
30 | #define IIC_REGREAD(reg, val) {i2c_master_read_reg(CODEC1_I2C_DEVICE_ADDR, reg, val, 1, p_i2c);}
31 |
32 | void audio_hw_config(unsigned samFreq)
33 | {
34 | timer t;
35 | unsigned time;
36 | unsigned tmp;
37 |
38 | int codec_dev_id;
39 | unsigned char data[1] = {0};
40 |
41 | /* Set CODEC in reset */
42 | tmp = P_GPIO_COD_RST_N;
43 |
44 | /* Set master clock select appropriately */
45 | if ((samFreq % 22050) == 0)
46 | {
47 | tmp &= ~P_GPIO_MCLK_SEL;
48 | }
49 | else //if((samFreq % 24000) == 0)
50 | {
51 | tmp |= P_GPIO_MCLK_SEL;
52 | }
53 |
54 | /* Output to port */
55 | p_gpio <: tmp;
56 |
57 | /* Hold in reset for 2ms while waiting for MCLK to stabilise */
58 | t :> time;
59 | time += 200000;
60 | t when timerafter(time) :> int _;
61 |
62 | /* CODEC out of reset */
63 | tmp |= P_GPIO_COD_RST_N;
64 | p_gpio <: tmp;
65 |
66 | /* Set power down bit in the CODEC over I2C */
67 | IIC_REGWRITE(CODEC_DEV_ID_ADDR, 0x01);
68 |
69 | #if 0
70 | /* Read CODEC device ID to make sure everything is OK */
71 | IIC_REGREAD(CODEC_DEV_ID_ADDR, data);
72 |
73 | codec_dev_id = data[0];
74 | if (((codec_dev_id & 0xF0) >> 4) != 0xC)
75 | {
76 | printstr("Unexpected CODEC Device ID, expected 0xC, got ");
77 | printhex(codec_dev_id);
78 | }
79 | #endif
80 |
81 | /* Now set all registers as we want them :
82 | Mode Control Reg:
83 | Set FM[1:0] as 11. This sets Slave mode.
84 | Set MCLK_FREQ[2:0] as 010. This sets MCLK to 512Fs in Single, 256Fs in Double and 128Fs in Quad Speed Modes.
85 | This means 24.576MHz for 48k and 22.5792MHz for 44.1k.
86 | Set Popguard Transient Control.
87 | So, write 0x35. */
88 | IIC_REGWRITE(CODEC_MODE_CTRL_ADDR, 0x35);
89 |
90 | /* ADC & DAC Control Reg:
91 | Leave HPF for ADC inputs continuously running.
92 | Digital Loopback: OFF
93 | DAC Digital Interface Format: I2S
94 | ADC Digital Interface Format: I2S
95 | So, write 0x09. */
96 | IIC_REGWRITE(CODEC_ADC_DAC_CTRL_ADDR, 0x09);
97 |
98 | /* Transition Control Reg:
99 | No De-emphasis. Don't invert any channels. Independent vol controls. Soft Ramp and Zero Cross enabled.*/
100 | IIC_REGWRITE(CODEC_TRAN_CTRL_ADDR, 0x60);
101 |
102 | /* Mute Control Reg: Turn off AUTO_MUTE */
103 | IIC_REGWRITE(CODEC_MUTE_CTRL_ADDR, 0x00);
104 |
105 | /* DAC Chan A Volume Reg:
106 | We don't require vol control so write 0x00 (0dB) */
107 | IIC_REGWRITE(CODEC_DACA_VOL_ADDR, 0x00);
108 |
109 | /* DAC Chan B Volume Reg:
110 | We don't require vol control so write 0x00 (0dB) */
111 | IIC_REGWRITE(CODEC_DACB_VOL_ADDR, 0x00);
112 |
113 | /* Clear power down bit in the CODEC over I2C */
114 | IIC_REGWRITE(CODEC_PWR_CTRL_ADDR, 0x00);
115 | }
116 | //:
117 |
--------------------------------------------------------------------------------
/app_slicekit_i2s_master_demo/src/i2c_conf.h:
--------------------------------------------------------------------------------
1 | #define SDA_HIGH 2
2 | #define SCL_HIGH 1
3 |
--------------------------------------------------------------------------------
/app_slicekit_i2s_master_demo/src/i2s_master_conf.h:
--------------------------------------------------------------------------------
1 | #define I2S_MASTER_NUM_CHANS_ADC 4
2 |
3 | #define I2S_MASTER_NUM_CHANS_DAC 4
4 |
--------------------------------------------------------------------------------
/app_slicekit_i2s_master_demo/src/main.xc:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2011, XMOS Ltd., All rights reserved
2 | // This software is freely distributable under a derivative of the
3 | // University of Illinois/NCSA Open Source License posted in
4 | // LICENSE.txt and at
5 |
6 | #include
7 | #include "i2s_loopback.h"
8 | #include "i2s_master.h"
9 | #include "app_global.h"
10 | #include "ports.h"
11 |
12 | void audio_hw_init(unsigned);
13 | void audio_hw_config(unsigned samFreq);
14 |
15 | //::main program
16 | int main()
17 | {
18 | streaming chan c_data;
19 |
20 | par
21 | {
22 | on stdcore[1] :
23 | {
24 | unsigned mclk_bclk_div = MCLK_FREQ/(SAMP_FREQ * 64);
25 | audio_hw_init(mclk_bclk_div);
26 |
27 | audio_hw_config(SAMP_FREQ);
28 |
29 | i2s_master(i2s_resources, c_data, mclk_bclk_div);
30 | }
31 |
32 | on stdcore[1] : loopback(c_data);
33 |
34 | }
35 | return 0;
36 | }
37 | //::
38 |
39 |
--------------------------------------------------------------------------------
/app_slicekit_i2s_master_demo/src/ports.h:
--------------------------------------------------------------------------------
1 |
2 |
3 | #include "xa_sk_audio_1v1.h"
4 |
5 | //::declaration
6 | on stdcore[1] : r_i2s i2s_resources =
7 | {
8 | XS1_CLKBLK_1,
9 | XS1_CLKBLK_2,
10 | PORT_MCLK_IN, // Master Clock
11 | PORT_I2S_BCLK, // Bit Clock
12 | PORT_I2S_LRCLK, // LR Clock
13 | {PORT_I2S_ADC0, PORT_I2S_ADC1},
14 | {PORT_I2S_DAC0, PORT_I2S_DAC1},
15 |
16 | };
17 | //::
18 |
19 | /* Some extra port declarations */
20 |
21 | /* Port for I2C bus. Both SDA and SCL are on lines on same port */
22 | on stdcore[1] : port p_i2c = PORT_I2C;
23 |
24 | /* GPIO port */
25 | on stdcore[1] : out port p_gpio = PORT_GPIO;
26 |
--------------------------------------------------------------------------------
/app_slicekit_i2s_master_demo/src/xa_sk_audio_1v1.h:
--------------------------------------------------------------------------------
1 |
2 | /* Port Map Defines for XA-SK-AUDIO ("Audio Slice") 1v1 */
3 | #define PORT_I2S_DAC0 XS1_PORT_1D
4 | #define PORT_I2S_DAC1 XS1_PORT_1H
5 | #define PORT_I2S_ADC0 XS1_PORT_1K
6 | #define PORT_I2S_ADC1 XS1_PORT_1L
7 | #define PORT_I2S_LRCLK XS1_PORT_1I
8 | #define PORT_I2S_BCLK XS1_PORT_1A
9 | #define PORT_MCLK_IN XS1_PORT_1E
10 |
11 | #define PORT_GPIO XS1_PORT_4E
12 | #define PORT_I2C XS1_PORT_4F
13 |
14 | /* General output port bit definitions */
15 | #define P_GPIO_SS_EN_CTRL 0x01 /* SPI Slave Select Enable. 0 - SPI SS Enabled, 1 - SPI SS Disabled. */
16 | #define P_GPIO_MCLK_SEL 0x02 /* MCLK frequency select. 0 - 22.5792MHz, 1 - 24.576MHz. */
17 | #define P_GPIO_COD_RST_N 0x04 /* CODEC RESET. Active low. */
18 | #define P_GPIO_LED 0x08 /* LED. Active high. */
19 |
--------------------------------------------------------------------------------
/doc/Makefile:
--------------------------------------------------------------------------------
1 | REPO=../../sc_i2s
2 | SPHINX_PROJECT_NAME=I2S Component
3 | VERSION=1.2.0
4 | DOXYGEN_DIRS=$(REPO)/module_i2s_master
5 | SOURCE_INCLUDE_DIRS=$(REPO)
6 | XDOC_DIR ?= ../../xdoc
7 | include $(XDOC_DIR)/Makefile.inc
8 |
9 | all: html pdf
10 | @if [ ! -d $(REPO)_gh_pages ] ; then echo '**** no gh_pages checked out ****'; exit 0; else cp -r _build/html/* $(REPO)_gh_pages/; cp -r _build/html/.doctrees $(REPO)_gh_pages/; echo 'HTML files copied to $(REPO)_gh_pages'; echo 'Now go to $(REPO)_gh_pages, add, commit, and push to publish the documentation'; fi
11 |
--------------------------------------------------------------------------------
/doc/api.rst:
--------------------------------------------------------------------------------
1 | I2S Master API
2 | ==============
3 |
4 | Symbolic constants
5 | ------------------
6 |
7 | .. doxygendefine:: I2S_MASTER_NUM_CHANS_ADC
8 |
9 | .. doxygendefine:: I2S_MASTER_NUM_CHANS_DAC
10 |
11 |
12 | Structures
13 | ----------
14 |
15 | .. doxygenstruct:: i2s_resources
16 |
17 | Functions
18 | ---------
19 |
20 | .. doxygenfunction:: i2s_master
21 | .. doxygenfunction:: get_mclk_bclk_div
22 |
23 |
--------------------------------------------------------------------------------
/doc/hw.rst:
--------------------------------------------------------------------------------
1 | Hardware Platforms
2 | ==================
3 |
4 | Recommended Hardware
5 | --------------------
6 |
7 | This module may be evaluated using the sliceKIT Modular Development Platform, available from digikey. Required board SKUs are:
8 |
9 | * XP-SKC-L16 (sliceKIT L16 Core Board) plus XA-SK-AUDIO plus XA-SK-XTAG2 (sliceKIT xTAG adaptor) plus xTAG2 (debug adaptor)
10 |
11 | Demonstration Application
12 | -------------------------
13 |
14 | The ``I2S Master sliceKIT Loopback Demo`` application shows a very simple input to output loopback. An analog audio source (e.g. Hifi) may be connected to the input jack on the Audio Slice Card and then the audio will be played back out of the output jack (e.g. to connected headphones).
15 |
16 | Third party hardware
17 | --------------------
18 |
19 | This module can be used with any audio DAC/ADC/CODEC that supports the I2S standard and doesn't rely on left or right justified data. Codec configuration may be required depending on the external DAC/ADC/CODEC used, but this is done by the application outside this module.
20 |
21 |
22 |
--------------------------------------------------------------------------------
/doc/index.rst:
--------------------------------------------------------------------------------
1 | I2S Software Component
2 | ----------------------
3 |
4 | .. toctree::
5 |
6 | summary.rst
7 | hw.rst
8 | api.rst
9 | programming.rst
10 |
--------------------------------------------------------------------------------
/doc/programming.rst:
--------------------------------------------------------------------------------
1 | Programming guide
2 | -----------------
3 |
4 | The I2S master component runs in a single logical core. This logical core takes the following parameters (see API for details):
5 |
6 | #. A structure containing the required hardware resources (i.e. clock-blocks and ports)
7 | #. A streaming channel end for communcation of data to/from the I2S logical core
8 | #. A master clock to bit clock divide value (typically 2, 4 or 8)
9 |
10 | Typically the devide value passed into the function is 2, 4 or 8. This can be calculated as follows:
11 |
12 | divide = MCLK Frequency / (Sample Frequency * 64)
13 |
14 | For example for a MCLK frequency of 24.576MHz and desired sample freqency of 48kHz::
15 |
16 | 24.576 / (48000 * 64) = 8
17 |
18 | And for 96kHz::
19 |
20 | 24.576 / (96000 * 64) = 4
21 |
22 | If required, the function get_mclk_bclk_div() returns this value given a sample freqency and master clock frequency.
23 |
24 | On calling the I2S master logical core it's first task is to setup the hardware resources into a configuration suitable for I2S operation. The data, LRCLK and BCLK are single bit ports setup as "buffered" ports with a transfer width of 32. This means that every input/output operation causes 32 bits of data to be transferred.
25 |
26 | One clock block is clocked from the master clock (MCLK port). This clock block is then used to clock the BCLK port.
27 |
28 | Another clock block is then clocked from this BCLK port. The LRCLK port and all data ports (both input and output) are then clocked from the BCLK clock-block::
29 |
30 | MCLK ----> CB1
31 | |
32 | |
33 | V
34 | BCLK Port
35 | |
36 | |
37 | V
38 | CB2 ---------> LRCLK
39 | |
40 | |
41 | L-----------> Data Port[0..n-1]
42 |
43 | Once the ports have been setup the main I2S I/O loop is called:
44 |
45 | #. The startup case is handled by setting up timed input/outputs on all of the data ports and the LRCLK port. These define when the next input/output will happen.
46 | #. BCLK is then driven in order to clock out/in these inputs/outputs.
47 | #. Audio data is then sent/received over the channel, data will be left aligned in all cases.
48 | #. The "left" audio data is then output and input to/from the data-ports, 0 is then output to the LRCLK port.
49 | #. The BCLK port is then driven with 32 clocks in order to clock out the output data and LRCLK and clock in the next input audio data samples.
50 | #. The process is then repeated for "right" audio samples with the LRCLK output being of the value 0xffffffff (i.e. 32 clocks of 1).
51 |
52 |
53 | Usage Example
54 | -------------
55 |
56 | The ``I2S Master sliceKIT Loopback Demo`` example application implements a audio basic loopback on all channels (ADC to DAC). This includes a main.xc with the call to I2S master, the loopback code and so on. These include board-support resources and functionalilty such as XN files, CODEC configuration, clocking configuration, port defines etc and a Makefile.
57 |
58 | .. literalinclude:: app_slicekit_i2s_master_demo/src/main.xc
59 | :start-after: //::main program
60 | :end-before: //::
61 |
62 | The function main() runs two logical cores, one which calls functions to setup the audio hardware on the board then finally the i2s_master() function. The other calls a simple processing function. This function simply inputs ADC data from the streaming channel and loops sends it back as ADC data over the streaming channel for all channels. In this case audio_hw_init() initilises the I2C bus, and audio_hw_config() configures clocking and CODEC via I2C.
63 |
64 | main.xc includes the file app_global which includes build parameters for the specific app such as master clock freqencies, sample rate etc.
65 |
66 | The app_* folders contain implementations of audio_hw_init() and audio_hw_config(). In all cases i2s_master.h should be included and the structure i2s_master defined.
67 |
68 | .. literalinclude:: app_slicekit_i2s_master_demo/src/ports.h
69 | :start-after: //::declaration
70 | :end-before: //::
71 |
72 |
73 |
74 |
--------------------------------------------------------------------------------
/doc/summary.rst:
--------------------------------------------------------------------------------
1 | I2S Digital Audio Master Component
2 | ==================================
3 |
4 | Overview
5 | --------
6 |
7 | I2S (also known as IIS, Inter-IC Sound or Integrated Interchip Sound) is a serial bus interface for digital audio transport.
8 |
9 | The bus consists of atleast three lines:
10 |
11 | * Bit clock - also known as serial clock or (SCLK)
12 | * Word clock - also known as word select line or Left/Right clock (LRCLK)
13 | * At least one multiplexed data line
14 |
15 | Each I2S data line carries 2 audio channels (left and right). Additional data lines(in either direction) can be added for more audio channels.
16 |
17 | Additionally a Master Clock line is used (typically 128, 256 or 512 x LRCLK.
18 |
19 | A typical usage for this is transport of PCM audio samples to/from an external DAC/ADC or CODEC.
20 |
21 | Features
22 | --------
23 |
24 | * Implements a "master" (where the xCORE provides LRCLK and BCLK to the CODEC). A "slave" version (where the CODEC provides LRCLK and BCLK to the XMOS chip) modes are forthcoming.
25 | * Input and output multiple stereo audio streams on multiple ports at sample frequencies up to 192 KHz
26 | * Audio samples are sent to and received from the client via a streaming channel
27 |
28 |
29 | Resource Requirements
30 | ----------------------
31 |
32 | This module is a single logical core I2S bus master. It can transmit and receive audio data and drives the word clock and bit clock.
33 |
34 | It requires the following resources:
35 |
36 | - 1 logical core (MIPS dependant on number of inputs and outputs)
37 | - 2 clock blocks
38 | - 1 x 1-bit input port for each I2S input plus 1 for MCLK
39 | - 1 x 1-bit output port for each I2S output plus 2 for BCLK and WCLK
40 | - approx 0.5 kB memory
41 |
42 | Performance
43 | -----------
44 |
45 | The performance the module can achieve depends on the number on the number of channels served, the sample frequency desired and the master clock frequency (or divide) used.
46 |
47 | Currently the component can achieve 10 channels input and output at 192kHz (based on a 512*48000Hz master clock)
48 |
--------------------------------------------------------------------------------
/doc_slave/slave.rst:
--------------------------------------------------------------------------------
1 | I2S Slave
2 | '''''''''
3 |
4 | This module is an I2S slave transmitter and receiver in a single thread. It sends and receives samples over a pair of chanends and transmits audio over I2S. It can send and receive multiple I2S links on separate ports.
5 |
6 | As a slave it is driven by the bit clock (BCK) and word clock (WCK) on input ports.
7 |
8 | module_i2s_slave
9 | ----------------
10 |
11 | This module is a single thread I2S bus slave. It can transmit and receive audio data from an external word clock and bit clock.
12 |
13 | It requires the following resources:
14 |
15 | - 1 thread (MIPS dependant on number of inputs and outputs)
16 |
17 | - 1 clock block
18 |
19 | - 1 x 1-bit input port for each I2S input plus 2 for BCK and WCK
20 |
21 | - 1 x 1-bit output port for each I2S output
22 |
23 | - 0.5 kB memory
24 |
25 | Hardware Requirements
26 | ---------------------
27 |
28 | This module can be used with any audio CODEC that supports the I2S standard.
29 |
30 | Component Description
31 | ---------------------
32 |
33 |
34 |
35 | API
36 | ===
37 |
38 | Symbolic constants
39 | ------------------
40 |
41 | .. doxygendefine:: I2S_SLAVE_NUM_IN
42 |
43 | .. doxygendefine:: I2S_SLAVE_NUM_OUT
44 |
45 | Structures
46 | ----------
47 |
48 | .. doxygenstruct:: i2s_slave
49 |
50 | Functions
51 | ---------
52 |
53 | .. doxygenfunction:: i2s_slave
54 |
55 | Example
56 | =======
57 |
58 | This example is designed to run on the XR-USB-AUDIO-2.0-MC board. It takes input on 3 I2S links and outputs the selected one on four I2S links. I2S_SLAVE_NUM_IN and I2S_SLAVE_NUM_OUT are defined in the Makefile.
59 |
60 | First of all i2s_slave should be included and the structure i2s_slave defined.
61 |
62 | .. literalinclude:: app_xai_i2s_slave_demo/src/main.xc
63 | :start-after: //::declaration
64 | :end-before: //::
65 |
66 | The top level of this example creates the i2s_slave on core 1, along with a 1KHz clock to the PLL and occupies the remaining 6 threads with computation.
67 |
68 | Core 0 runs the loopback function which reads the I2S inputs from the i2s_slave thread over a streaming channel and sends them over a streaming channel back to the i2s_slave thread to the I2S outputs.
69 |
70 | .. literalinclude:: app_xai_i2s_slave_demo/src/main.xc
71 | :start-after: //::main program
72 | :end-before: //::
73 |
--------------------------------------------------------------------------------
/module_i2s_loopback/.cproject:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | xmake
19 | -f .makefile
20 | all
21 | true
22 | true
23 | true
24 |
25 |
26 | xmake
27 | -f .makefile
28 | clean
29 | true
30 | true
31 | true
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
156 |
163 |
164 |
165 |
166 |
269 |
276 |
277 |
278 |
279 |
386 |
395 |
396 |
397 |
398 |
399 |
400 |
402 |
403 |
404 |
405 |
406 |
407 |
408 |
409 |
410 |
411 |
412 |
413 |
414 |
415 |
416 |
417 |
418 |
419 |
420 |
421 |
422 |
423 |
424 |
425 |
426 |
427 |
428 |
429 |
430 |
431 |
432 |
433 |
434 |
435 |
436 |
437 |
438 |
439 |
440 |
441 |
442 |
443 |
444 |
445 |
446 |
447 |
448 |
449 |
450 |
451 |
452 |
453 |
454 |
455 |
456 |
457 |
458 |
459 |
460 |
461 |
462 |
463 |
464 |
465 |
466 |
467 |
468 |
469 |
470 |
471 |
472 |
473 |
474 |
475 |
476 |
477 |
478 |
479 |
480 |
481 |
482 |
483 |
484 |
485 |
486 |
487 |
488 |
489 |
490 |
491 |
492 |
493 |
494 |
495 |
496 |
497 |
498 |
--------------------------------------------------------------------------------
/module_i2s_loopback/.makefile:
--------------------------------------------------------------------------------
1 | all:
2 | @echo "** Module only - only builds as part of application **"
3 |
4 |
5 | clean:
6 | @echo "** Module only - only builds as part of application **"
7 |
8 |
9 |
--------------------------------------------------------------------------------
/module_i2s_loopback/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | module_i2s_loopback
4 |
5 |
6 |
7 |
8 |
9 | org.eclipse.cdt.managedbuilder.core.genmakebuilder
10 | clean,full,incremental,
11 |
12 |
13 | ?children?
14 | ?name?=outputEntries\|?children?=?name?=entry\\\\|\\|\||
15 |
16 |
17 | ?name?
18 |
19 |
20 |
21 | org.eclipse.cdt.make.core.append_environment
22 | true
23 |
24 |
25 | org.eclipse.cdt.make.core.buildArguments
26 | CONFIG=Debug
27 |
28 |
29 | org.eclipse.cdt.make.core.buildCommand
30 | xmake
31 |
32 |
33 | org.eclipse.cdt.make.core.cleanBuildTarget
34 | clean
35 |
36 |
37 | org.eclipse.cdt.make.core.contents
38 | org.eclipse.cdt.make.core.activeConfigSettings
39 |
40 |
41 | org.eclipse.cdt.make.core.enableAutoBuild
42 | false
43 |
44 |
45 | org.eclipse.cdt.make.core.enableCleanBuild
46 | true
47 |
48 |
49 | org.eclipse.cdt.make.core.enableFullBuild
50 | true
51 |
52 |
53 | org.eclipse.cdt.make.core.stopOnError
54 | true
55 |
56 |
57 | org.eclipse.cdt.make.core.useDefaultBuildCmd
58 | false
59 |
60 |
61 |
62 |
63 | org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder
64 | full,incremental,
65 |
66 |
67 |
68 |
69 |
70 | org.eclipse.cdt.core.cnature
71 | org.eclipse.cdt.managedbuilder.core.managedBuildNature
72 | org.eclipse.cdt.managedbuilder.core.ScannerConfigNature
73 | com.xmos.cdt.core.XdeProjectNature
74 |
75 |
76 |
77 |
--------------------------------------------------------------------------------
/module_i2s_loopback/.xproject:
--------------------------------------------------------------------------------
1 | sc_i2sXM-002000-SM
--------------------------------------------------------------------------------
/module_i2s_loopback/README.rst:
--------------------------------------------------------------------------------
1 | I2S Loopback Component
2 | ======================
3 |
4 | :scope: Example
5 | :description: A simple block to add I2S loopback functionality to the I2S Driver component
6 | :keywords: Audio, I2S
7 | :boards: XA-SK-AUDIO
8 |
9 | A simple single logical core component which takes samples from the I2S driver component inputs and loops them back to the I2S driver component outputs.
10 |
--------------------------------------------------------------------------------
/module_i2s_loopback/module_build_info:
--------------------------------------------------------------------------------
1 | # You can set flags specifically for your module by using the MODULE_XCC_FLAGS
2 | # variable. So the following
3 | #
4 | # MODULE_XCC_FLAGS = $(XCC_FLAGS) -O3
5 | #
6 | # specifies that everything in the modules should have the application
7 | # build flags with -O3 appended (so the files will build at
8 | # optimization level -O3).
9 | #
10 | # You can also set MODULE_XCC_C_FLAGS, MODULE_XCC_XC_FLAGS etc..
11 |
12 | MODULE_XCC_XC_FLAGS = $(XCC_FLAGS)
13 |
14 |
--------------------------------------------------------------------------------
/module_i2s_loopback/module_i2s_loopback.metainfo:
--------------------------------------------------------------------------------
1 | -------------------------------------------------------------------------------
2 | -- Descriptive metadata
3 | -------------------------------------------------------------------------------
4 |
5 | componentName = "I2S Loopback"
6 | componentFullName = ""
7 | alternativeNames = { }
8 | componentDescription = "I2S Loopback for use in testing I2S Driver and external circuitry"
9 | componentVersion = "1v0"
10 |
11 | -------------------------------------------------------------------------------
12 | -- Parameter descriptions.
13 | -------------------------------------------------------------------------------
14 |
15 | configPoints =
16 | {
17 | numChansDAC =
18 | {
19 | short = "DAC Channels",
20 | long = "Number of DAC Audio Channels (output)",
21 | units = "",
22 | help = "",
23 | type = "int",
24 | resourceUsageFlags = {"orthogonal"},
25 | define = "I2S_MASTER_NUM_CHANS_DAC",
26 | options = {2,4,6,8},
27 | default = 2
28 | },
29 | numChansADC =
30 | {
31 | short = "ADC Channels",
32 | long = "Number of ADC Audio Channels (input)",
33 | help = "",
34 | units = "",
35 | type = "int",
36 | resourceUsageFlags = {"orthogonal"},
37 | define = "I2S_MASTER_NUM_CHANS_ADC",
38 | options = {2,4,6,8},
39 | default = 2
40 | }
41 |
42 | }
43 |
44 | derivedValues = {
45 | }
46 |
47 | ports = {
48 | }
49 |
50 | channels = {
51 | c_i2s_data = {
52 | short = "I2S Data Channel",
53 | type = "streaming",
54 | long = "Channel to exchange data with the I2S driver component",
55 | help = "",
56 | },
57 | }
58 |
59 | function getConfigStatus()
60 | local status = "Valid Configuration"
61 | local issues = {}
62 | return status, issues
63 | end
64 |
65 | -------------------------------------------------------------------------------
66 | -- Source generation functions
67 | -------------------------------------------------------------------------------
68 |
69 | generatedCode = {
70 | includes = {
71 | "processing.h"
72 | },
73 | globals = [[
74 | ]],
75 | body = [[
76 | processing(${swblock.chanends.c_i2s_data});
77 | ]]
78 | }
79 |
80 |
--------------------------------------------------------------------------------
/module_i2s_loopback/src/i2s_loopback.h:
--------------------------------------------------------------------------------
1 |
2 | #ifndef _I2S_LOOPBACK_H_
3 | #define _I2S_LOOPBACK_H_
4 | void loopback(streaming chanend c);
5 | #endif
6 |
--------------------------------------------------------------------------------
/module_i2s_loopback/src/i2s_loopback.xc:
--------------------------------------------------------------------------------
1 | #include "i2s_master.h"
2 |
3 | void loopback(streaming chanend c)
4 | {
5 | /* Audio sample buffers */
6 | unsigned sampsAdc[I2S_MASTER_NUM_CHANS_ADC];
7 | unsigned sampsDac[I2S_MASTER_NUM_CHANS_DAC];
8 |
9 | /* Samps innit */
10 | for (int i = 0; i < I2S_MASTER_NUM_CHANS_ADC; i++)
11 | {
12 | sampsAdc[i] = 0;
13 | }
14 | for (int i = 0; i < I2S_MASTER_NUM_CHANS_DAC; i++)
15 | {
16 | sampsDac[i] = 0;
17 | }
18 |
19 | while(1)
20 | {
21 | /* Receive ADC samples from audio thread */
22 | #pragma loop unroll
23 | for (int i = 0; i < I2S_MASTER_NUM_CHANS_ADC; i++)
24 | {
25 | c :> sampsAdc[i];
26 | }
27 |
28 | #pragma loop unroll
29 | /* Send out DAC samples */
30 | for (int i = 0; i < I2S_MASTER_NUM_CHANS_DAC; i++)
31 | {
32 | c <: sampsDac[i];
33 | }
34 |
35 | /* Do some processing - currently just loop back ADC to DAC on all channels */
36 | for(int i = 0; i < I2S_MASTER_NUM_CHANS_DAC; i++)
37 | {
38 | if(i < I2S_MASTER_NUM_CHANS_ADC)
39 | {
40 | sampsDac[i] = sampsAdc[i];
41 | }
42 | }
43 | }
44 | }
45 |
46 |
--------------------------------------------------------------------------------
/module_i2s_master/.cproject:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | xmake
19 | -f .makefile
20 | all
21 | true
22 | true
23 | true
24 |
25 |
26 | xmake
27 | -f .makefile
28 | clean
29 | true
30 | true
31 | true
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
156 |
163 |
164 |
165 |
166 |
269 |
276 |
277 |
278 |
279 |
386 |
395 |
396 |
397 |
398 |
399 |
400 |
402 |
403 |
404 |
405 |
406 |
407 |
408 |
409 |
410 |
411 |
412 |
413 |
414 |
415 |
416 |
417 |
418 |
419 |
420 |
421 |
422 |
423 |
424 |
425 |
426 |
427 |
428 |
429 |
430 |
431 |
432 |
433 |
434 |
435 |
436 |
437 |
438 |
439 |
440 |
441 |
442 |
443 |
444 |
445 |
446 |
447 |
448 |
449 |
450 |
451 |
452 |
453 |
454 |
455 |
456 |
457 |
458 |
459 |
460 |
461 |
462 |
463 |
464 |
465 |
466 |
467 |
468 |
469 |
470 |
471 |
472 |
473 |
474 |
475 |
476 |
477 |
478 |
479 |
480 |
481 |
482 |
483 |
484 |
485 |
486 |
487 |
488 |
489 |
490 |
491 |
492 |
493 |
494 |
495 |
496 |
497 |
498 |
--------------------------------------------------------------------------------
/module_i2s_master/.makefile:
--------------------------------------------------------------------------------
1 | all:
2 | @echo "** Module only - only builds as part of application **"
3 |
4 |
5 | clean:
6 | @echo "** Module only - only builds as part of application **"
7 |
8 |
9 |
--------------------------------------------------------------------------------
/module_i2s_master/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | module_i2s_master
4 |
5 |
6 |
7 |
8 |
9 | org.eclipse.cdt.managedbuilder.core.genmakebuilder
10 | clean,full,incremental,
11 |
12 |
13 | ?children?
14 | ?name?=outputEntries\|?children?=?name?=entry\\\\|\\|\||
15 |
16 |
17 | ?name?
18 |
19 |
20 |
21 | org.eclipse.cdt.make.core.append_environment
22 | true
23 |
24 |
25 | org.eclipse.cdt.make.core.buildArguments
26 | CONFIG=Debug
27 |
28 |
29 | org.eclipse.cdt.make.core.buildCommand
30 | xmake
31 |
32 |
33 | org.eclipse.cdt.make.core.cleanBuildTarget
34 | clean
35 |
36 |
37 | org.eclipse.cdt.make.core.contents
38 | org.eclipse.cdt.make.core.activeConfigSettings
39 |
40 |
41 | org.eclipse.cdt.make.core.enableAutoBuild
42 | false
43 |
44 |
45 | org.eclipse.cdt.make.core.enableCleanBuild
46 | true
47 |
48 |
49 | org.eclipse.cdt.make.core.enableFullBuild
50 | true
51 |
52 |
53 | org.eclipse.cdt.make.core.stopOnError
54 | true
55 |
56 |
57 | org.eclipse.cdt.make.core.useDefaultBuildCmd
58 | false
59 |
60 |
61 |
62 |
63 | org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder
64 | full,incremental,
65 |
66 |
67 |
68 |
69 |
70 | org.eclipse.cdt.core.cnature
71 | org.eclipse.cdt.managedbuilder.core.managedBuildNature
72 | org.eclipse.cdt.managedbuilder.core.ScannerConfigNature
73 | com.xmos.cdt.core.XdeProjectNature
74 |
75 |
76 |
77 |
--------------------------------------------------------------------------------
/module_i2s_master/.xproject:
--------------------------------------------------------------------------------
1 | sc_i2sXM-002000-SM
--------------------------------------------------------------------------------
/module_i2s_master/README:
--------------------------------------------------------------------------------
1 | This module provides code for the I2S digital audio interface with the
2 | XCore acting as master.
3 |
4 |
--------------------------------------------------------------------------------
/module_i2s_master/README.rst:
--------------------------------------------------------------------------------
1 | I2S Master Audio Driver
2 | =======================
3 |
4 | :scope: General Use
5 | :description: Component for driving Multichannel Audio I2S (Input and Output) with Codec as Slave
6 | :keywords: Audio, I2S, codec
7 | :boards: XA-SK-AUDIO
8 |
9 | Features
10 | --------
11 |
12 | * Runs in a single logical core
13 | * Multiple data lines (channels) supported (must all run with a common clock domain and sample frequency)
14 | * Includes application demonstrations
15 |
16 |
--------------------------------------------------------------------------------
/module_i2s_master/i2s_master_conf_example.h:
--------------------------------------------------------------------------------
1 |
2 | // Set this define to control the number of input
3 | // channels the I2S master component implements
4 | #define I2S_MASTER_NUM_CHANS_ADC 4
5 |
6 | // Set this define to control the number of output channels the
7 | // I2S master component implements
8 | #define I2S_MASTER_NUM_CHANS_DAC 4
9 |
--------------------------------------------------------------------------------
/module_i2s_master/module_build_info:
--------------------------------------------------------------------------------
1 | # You can set flags specifically for your module by using the MODULE_XCC_FLAGS
2 | # variable. So the following
3 | #
4 | # MODULE_XCC_FLAGS = $(XCC_FLAGS) -O3
5 | #
6 | # specifies that everything in the modules should have the application
7 | # build flags with -O3 appended (so the files will build at
8 | # optimization level -O3).
9 | #
10 | # You can also set MODULE_XCC_C_FLAGS, MODULE_XCC_XC_FLAGS etc..
11 |
12 | OPTIONAL_HEADERS += i2s_master_conf.h
13 |
14 | MODULE_XCC_XC_FLAGS = $(XCC_FLAGS) -O3
15 |
16 |
--------------------------------------------------------------------------------
/module_i2s_master/module_description:
--------------------------------------------------------------------------------
1 | I2S digital audio interface (XCore as master)
2 |
--------------------------------------------------------------------------------
/module_i2s_master/module_i2s_master.metainfo:
--------------------------------------------------------------------------------
1 | -------------------------------------------------------------------------------
2 | -- Descriptive metadata
3 | -------------------------------------------------------------------------------
4 |
5 | componentName = "I2S Audio Driver"
6 | componentFullName = ""
7 | alternativeNames = { }
8 | componentDescription = "I2S Driver component for audio input and output"
9 | componentVersion = "1v0"
10 |
11 | -------------------------------------------------------------------------------
12 | -- Parameter descriptions.
13 | -------------------------------------------------------------------------------
14 |
15 | configPoints =
16 | {
17 | numChansDAC =
18 | {
19 | short = "DAC Channels",
20 | long = "Number of DAC Audio Channels (output)",
21 | units = "",
22 | help = "",
23 | type = "int",
24 | resourceUsageFlags = {"orthogonal"},
25 | define = "I2S_MASTER_NUM_CHANS_DAC",
26 | options = {2,4,6,8},
27 | default = 2
28 | },
29 | numChansADC =
30 | {
31 | short = "ADC Channels",
32 | long = "Number of ADC Audio Channels (input)",
33 | help = "",
34 | units = "",
35 | type = "int",
36 | resourceUsageFlags = {"orthogonal"},
37 | define = "I2S_MASTER_NUM_CHANS_ADC",
38 | options = {2,4,6,8},
39 | default = 2
40 | },
41 | masterClockFreq =
42 | {
43 | short = "MCLK Frequency",
44 | long = "I2S Master Clock Frequency",
45 | help = "",
46 | units = "Hz",
47 | type = "int",
48 | resourceUsageFlags = {"noeffect"},
49 | min = 12288000,
50 | max = 49152000,
51 | default = 24576000
52 | },
53 | sampFreq =
54 | {
55 | short = "Initial Audio Sample Frequency",
56 | long = "",
57 | help = "Set the desired Audio Sample Frequency",
58 | units = "Hz",
59 | type = "int",
60 | resourceUsageFlags = {"noeffect"},
61 | options={44100,48000,88200,96000,176400,192000},
62 | default = 48000
63 | }
64 | }
65 |
66 | derivedValues = {
67 | }
68 |
69 | ports = {
70 | p_i2s_mck = {
71 | short = "I2S MCLK",
72 | long = "I2S Master Clock Input",
73 | help = "",
74 | width = 1
75 | },
76 | p_i2s_bck = {
77 | short = "I2S BCLK",
78 | long = "I2S Bit Clock Output",
79 | help = "",
80 | width = 1
81 | },
82 | p_i2s_wck = {
83 | short = "I2S WCLK",
84 | long = "I2S Word Clock Output",
85 | help = "",
86 | width = 1
87 | },
88 | p_i2s_din = {
89 | short = "I2S DIN",
90 | long = "I2S ADC Data In",
91 | arraySize = swblock.params.numChansADC,
92 | help = "",
93 | width = 1
94 | },
95 | p_i2s_dout = {
96 | short = "I2S DOUT",
97 | long = "I2S DAC Data Out",
98 | arraySize = swblock.params.numChansDAC,
99 | help = "",
100 | width = 1
101 | }
102 | }
103 |
104 | channels = {
105 | c_i2s_data = {
106 | short = "I2S Client Data Channel",
107 | type = "streaming",
108 | long = "Channel for the client to send and receive I2S data with the I2S driver component",
109 | help = "",
110 | },
111 | }
112 |
113 | function getConfigStatus()
114 | local status = "Valid Configuration"
115 | local issues = {}
116 | local div = swblock.params.masterClockFreq / (swblock.params.sampFreq * 64)
117 |
118 | -- Get rid of some untrusted configs...
119 |
120 | if not (div == 2 or div == 4 or div == 8) then
121 | status = "Invalid Configuration"
122 | table.insert(issues,
123 | {
124 | issues = "Master clock and Sample Freqnency combination not supported",
125 | suggestion = "Change sample freqency or master clock rate"
126 | })
127 |
128 | return status, issues
129 | end
130 |
131 | if (swblock.params.numChansDAC + swblock.params.numChansADC) > 10 then
132 | status = "Invalid Configuration"
133 | table.insert(issues,
134 | {
135 | issues = "The requested number of channels at this sample frequency cannot be supported",
136 | suggestion = "Reduce channel count"
137 | })
138 |
139 | return status, issues
140 | end
141 |
142 | -- Trusted is 4 in 4 out (in some combo), 48000/44100 with 512x MCLK (div 8)
143 |
144 | if ((swblock.params.numChansDAC + swblock.params.numChansADC) == 8) and (div == 8) and
145 | ((swblock.params.masterClockFreq == (512*48000)) or (swblock.params.masterClockFreq == (512*44100))) and
146 | (((swblock.params.sampFreq == 48000) or (swblock.params.sampFreq == 44100))) then
147 | status = "Trusted Configuration"
148 | end
149 |
150 | -- Everything else *should* be valid...
151 |
152 |
153 | return status, issues
154 | end
155 |
156 | -------------------------------------------------------------------------------
157 | -- Source generation functions
158 | -------------------------------------------------------------------------------
159 |
160 | generatedCode = {
161 | includes = {"i2s_master.h"},
162 | globals = [[
163 | r_i2s i2s${swblock.id}_resources = {
164 | ${swblock.clocks[0]},
165 | ${swblock.clocks[1]},
166 | ${swblock.ports.p_i2s_mck},
167 | ${swblock.ports.p_i2s_bck},
168 | ${swblock.ports.p_i2s_wck},
169 | ${swblock.ports.p_i2s_din},
170 | ${swblock.ports.p_i2s_dout}
171 | };
172 | ]],
173 | body = [[
174 | {
175 | unsigned mlk_blk_div = get_mclk_bclk_div(${swblock.params.sampFreq}, ${swblock.params.masterClockFreq});
176 | i2s_master(i2s_resources, ${swblock.chanends.c_i2s_data}, mlk_blk_div);
177 | }
178 | ]]
179 | }
180 |
181 | files = {["module_i2s_master/i2s_master_conf_example.h"] = "src/i2s_master_conf.h"}
182 |
--------------------------------------------------------------------------------
/module_i2s_master/src/i2s_master.h:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2011, XMOS Ltd., All rights reserved
2 | // This software is freely distributable under a derivative of the
3 | // University of Illinois/NCSA Open Source License posted in
4 | // LICENSE.txt and at
5 |
6 | ///////////////////////////////////////////////////////////////////////////////
7 | //
8 | // Multichannel I2S master receiver-transmitter
9 | //
10 |
11 | #ifndef _i2s_master_h_
12 | #define _i2s_master_h_
13 |
14 | #ifdef __i2s_master_conf_h_exists__
15 | #include "i2s_master_conf.h"
16 | #endif
17 |
18 | #include
19 |
20 | #ifndef I2S_MASTER_NUM_CHANS_ADC
21 | /** Number of ADC audio channels
22 | */
23 | #define I2S_MASTER_NUM_CHANS_ADC 2
24 | #warning I2S_MASTER_NUM_CHANS_ADC not defined, using 2 (i.e. stereo)
25 | #endif
26 |
27 | #ifndef I2S_MASTER_NUM_CHANS_DAC
28 | /** Number of DAC audio channels
29 | */
30 | #define I2S_MASTER_NUM_CHANS_DAC 2
31 | #warning I2S_MASTER_NUM_CHANS_DAC not defined, using 2 (i.e. stereo)
32 | #endif
33 |
34 | #ifndef I2S_MASTER_NUM_PORTS_DAC
35 | /** Number of I2S DAC ports
36 | */
37 | #define I2S_MASTER_NUM_PORTS_DAC (I2S_MASTER_NUM_CHANS_DAC>>1)
38 | #endif
39 |
40 | #ifndef I2S_MASTER_NUM_PORTS_ADC
41 | /** Number of I2S ADC ports
42 | */
43 | #define I2S_MASTER_NUM_PORTS_ADC (I2S_MASTER_NUM_CHANS_ADC>>1)
44 | #endif
45 |
46 |
47 |
48 | #ifndef MCK_BCK_RATIO
49 | /** BCK is soft divided off MCK.
50 | * MCK frequency is MCK_BCK_RATIO times BCK frequency.
51 | */
52 | #define MCK_BCK_RATIO 8
53 | #endif
54 |
55 | /** Resources for I2S_MASTER
56 | */
57 | typedef struct i2s_resources {
58 | clock cb1; /**< Clock block for MCK */
59 | clock cb2; /**< Clock block for BCK */
60 |
61 | in port mck; /**< Clock port for MCK */
62 | out buffered port:32 bck; /**< Clock port for BCK */
63 | out buffered port:32 wck; /**< Clock port for WCK */
64 |
65 | in buffered port:32 din[I2S_MASTER_NUM_PORTS_ADC]; /**< Array of I2S_MASTER_NUM_IN x 1-bit ports for audio input */
66 | out buffered port:32 dout[I2S_MASTER_NUM_PORTS_DAC]; /**< Array of I2S_MASTER_NUM_OUT x 1-bit ports for audio output */
67 | } r_i2s ;
68 |
69 | /** I2S Master function
70 | *
71 | * Samples are left-aligned signed values.
72 | * e.g. 24-bit audio will look like 0x12345600 (positive) or 0xFF123400 (negative)
73 | *
74 | * \param r_i2s Structure to configure the i2s_master
75 | *
76 | * \param c_data Streaming channel for sample data.
77 | *
78 | * First samples are exchanged over the channel in the following order:
79 | * Channel 0 (left), Channel 1 (right) ... Channel I2S_MASTER_NUM_CHAN_ADC-1, Channel I2S_MASTER_NUM_CHAN_ADC
80 | *
81 | * Samples should then be sent in the following order:
82 | * Channel 0 (left), Channel 1 (right) ... Channel I2S_MASTER_NUM_CHAN_DAC-1, Channel I2S_MASTER_NUM_CHAN_DAC
83 | *
84 | * \param mclk_bclk_div Divide required for Master clock to Bit Clock frequency. Supported values currently 2, 4, 8.
85 | */
86 | void i2s_master(r_i2s &r_i2s, streaming chanend c_data, unsigned mclk_bclk_div);
87 |
88 | /**
89 | *
90 | * \param sampFreq Desired sample frequency
91 | *
92 | * \param mClkFreq Master clock frequency
93 | *
94 | * \return Returns the mclk to bit clock ratio for given sample freq/master clock pair
95 | *
96 | */
97 | unsigned get_mclk_bclk_div(unsigned sampFreq, unsigned mClkFreq);
98 | #endif
99 |
--------------------------------------------------------------------------------
/module_i2s_master/src/i2s_master.xc:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | #include "i2s_master.h"
5 |
6 | /* Drive out 32 bit clocks. This essentially is dividing the master clock in software.
7 | * Note, currently only divide by 2,4,8 supported.
8 | */
9 | static inline void bck_32_ticks(out buffered port:32 p_bck, unsigned divide)
10 | {
11 | switch(divide)
12 | {
13 | case (2):
14 | p_bck <: 0x55555555;
15 | p_bck <: 0x55555555;
16 | break;
17 | case (4):
18 | p_bck <: 0x33333333;
19 | p_bck <: 0x33333333;
20 | p_bck <: 0x33333333;
21 | p_bck <: 0x33333333;
22 | break;
23 | case (8):
24 | p_bck <: 0x0F0F0F0F;
25 | p_bck <: 0x0F0F0F0F;
26 | p_bck <: 0x0F0F0F0F;
27 | p_bck <: 0x0F0F0F0F;
28 | p_bck <: 0x0F0F0F0F;
29 | p_bck <: 0x0F0F0F0F;
30 | p_bck <: 0x0F0F0F0F;
31 | p_bck <: 0x0F0F0F0F;
32 | break;
33 | default:
34 | /* This is an error case */
35 | break;
36 | }
37 | }
38 |
39 |
40 | void i2s_master_loop(in buffered port:32 p_i2s_adc[], out buffered port:32 p_i2s_dac[], streaming chanend c, out buffered port:32 p_lrclk, out buffered port:32 p_bclk, int divide)
41 | {
42 | unsigned sampsAdc[I2S_MASTER_NUM_CHANS_ADC];
43 | unsigned sampsDac[I2S_MASTER_NUM_CHANS_DAC];
44 |
45 | /* Init sample buffers */
46 | for (int i = 0; i < I2S_MASTER_NUM_CHANS_ADC; i++)
47 | {
48 | sampsAdc[i] = 0;
49 | }
50 | for (int i = 0; i < I2S_MASTER_NUM_CHANS_DAC; i++)
51 | {
52 | sampsDac[i] = 0;
53 | }
54 |
55 | /* Lets do some I2S.. */
56 | // inputs and outputs are 32 bits at a time
57 | // assuming clock block is reset - initial time is 0
58 | // split SETPT from IN using asm - basically a split transaction with BCK generation in between
59 | // input is always "up to" given time, output is always "starting from" given time
60 | // outputs will be aligned to WCK + 1 (first output at time 32, WCK at time 31)
61 | // inputs will also be aligned to WCK + 1 (first input up to time 63, WCK up to time 62)
62 |
63 | for (int i = 0; i < I2S_MASTER_NUM_PORTS_DAC; i++)
64 | {
65 | p_i2s_dac[i] @ 64 <: 0;
66 | }
67 |
68 | for (int i = 0; i < I2S_MASTER_NUM_PORTS_ADC; i++)
69 | {
70 | asm("setpt res[%0], %1" :: "r"(p_i2s_adc[i]), "r"(63));
71 | }
72 |
73 | p_lrclk @ 31 <: 0;
74 |
75 | // clocks for previous outputs / inputs
76 | bck_32_ticks(p_bclk, divide);
77 | p_lrclk <: 0;
78 | bck_32_ticks(p_bclk, divide);
79 |
80 | #pragma unsafe arrays
81 | while (1)
82 | {
83 | int p = 0;
84 |
85 | /* Send ADC samples over channel... */
86 | #pragma loop unroll
87 | for (int i = 0; i < I2S_MASTER_NUM_CHANS_ADC; i++)
88 | c <: sampsAdc[i];
89 |
90 | /* Receive DAC samples from channel... */
91 | #pragma loop unroll
92 | for (int i = 0; i < I2S_MASTER_NUM_CHANS_DAC; i++)
93 | c :> sampsDac[i];
94 |
95 | // input audio data
96 | // will be output to channel end as left-aligned
97 | // compiler would insert SETC FULL on DIN input, because it doesn't know about inline SETPT above
98 | // hence we need inline IN too
99 | p = 0;
100 | #pragma loop unroll
101 | for (int i = 0; i < I2S_MASTER_NUM_CHANS_ADC; i+=2)
102 | {
103 | int x;
104 | asm("in %0, res[%1]" : "=r"(x) : "r"(p_i2s_adc[p++]));
105 | sampsAdc[i] = bitrev(x);
106 | }
107 |
108 | /* Output LR clock to port */
109 | p_lrclk <: 0;
110 |
111 | /* drive bit clock */
112 | bck_32_ticks(p_bclk, divide);
113 |
114 | /* Output next DAC audio data for "Left" or "even" channels to I2S data ports.
115 | * Samples expected to come from channel end as left-aligned
116 | */
117 | p = 0;
118 | #pragma loop unroll
119 | for (int i = 0; i < I2S_MASTER_NUM_CHANS_DAC; i+=2)
120 | {
121 | p_i2s_dac[p++] <: bitrev(sampsDac[i]);
122 | }
123 |
124 | /* Input previous ADC audio data
125 | * Will be output to channel end as left-aligned
126 | * compiler would insert SETC FULL on DIN input, because it doesn't know about inline SETPT above
127 | * hence we need inline IN too
128 | */
129 | p = 0;
130 | #pragma loop unroll
131 | for (int i = 1; i < I2S_MASTER_NUM_CHANS_ADC; i+=2)
132 | {
133 | int x;
134 | asm("in %0, res[%1]" : "=r"(x) : "r"(p_i2s_adc[p++]));
135 | sampsAdc[i] = bitrev(x);
136 | }
137 |
138 | /* Output LR clock value to port */
139 | p_lrclk <: 0xffffffff;
140 |
141 | /* drive bit clock. This will clock out LRClk and DAC data from ports and clock in next
142 | * ADC data into ports
143 | */
144 | bck_32_ticks(p_bclk, divide);
145 |
146 | /* Output "right" (or "odd") channel DAC data to DAC ports */
147 | p = 0;
148 | #pragma loop unroll
149 | for (int i = 1; i < I2S_MASTER_NUM_CHANS_DAC; i+=2)
150 | {
151 | p_i2s_dac[p++] <: bitrev(sampsDac[i]);
152 | }
153 |
154 | }
155 | }
156 |
157 | unsigned get_mclk_bclk_div(unsigned sampFreq, unsigned mClkFreq)
158 | {
159 | return mClkFreq / ( sampFreq * 64 );
160 | }
161 |
162 | void i2s_master(r_i2s &r_i2s, streaming chanend c_data, unsigned mclk_bclk_div)
163 | {
164 | if(mclk_bclk_div == 1)
165 | {
166 | // TODO
167 | }
168 | else
169 | {
170 | // clock block 1 clocked off MCK
171 | set_clock_src(r_i2s.cb1, r_i2s.mck);
172 |
173 | // clock block 2 clocked off BCK (which is generated on-chip)
174 | set_clock_src(r_i2s.cb2, r_i2s.bck);
175 |
176 | // BCK port clocked off clock block 1
177 | set_port_clock(r_i2s.bck, r_i2s.cb1);
178 |
179 | // WCK and all data ports clocked off clock block 2
180 | set_port_clock(r_i2s.wck, r_i2s.cb2);
181 |
182 | for (int i = 0; i < I2S_MASTER_NUM_PORTS_ADC; i++)
183 | {
184 | set_port_clock(r_i2s.din[i], r_i2s.cb2);
185 | }
186 | for (int i = 0; i < I2S_MASTER_NUM_PORTS_DAC; i++)
187 | {
188 | set_port_clock(r_i2s.dout[i], r_i2s.cb2);
189 | }
190 |
191 |
192 | // Start clock blocks after configuration
193 | start_clock(r_i2s.cb1);
194 | start_clock(r_i2s.cb2);
195 |
196 | }
197 |
198 | // Run I2S i/o loop
199 | i2s_master_loop(r_i2s.din, r_i2s.dout, c_data, r_i2s.wck, r_i2s.bck, mclk_bclk_div);
200 |
201 | // Client must have killed us, so die..
202 | }
203 |
--------------------------------------------------------------------------------
/module_i2s_slave/.cproject:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | xmake
19 | -f .makefile
20 | all
21 | true
22 | true
23 | true
24 |
25 |
26 | xmake
27 | -f .makefile
28 | clean
29 | true
30 | true
31 | true
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
156 |
163 |
164 |
165 |
166 |
269 |
276 |
277 |
278 |
279 |
386 |
395 |
396 |
397 |
398 |
399 |
400 |
402 |
403 |
404 |
405 |
406 |
407 |
408 |
409 |
410 |
411 |
412 |
413 |
414 |
415 |
416 |
417 |
418 |
419 |
420 |
421 |
422 |
423 |
424 |
425 |
426 |
427 |
428 |
429 |
430 |
431 |
432 |
433 |
434 |
435 |
436 |
437 |
438 |
439 |
440 |
441 |
442 |
443 |
444 |
445 |
446 |
447 |
448 |
449 |
450 |
451 |
452 |
453 |
454 |
455 |
456 |
457 |
458 |
459 |
460 |
461 |
462 |
463 |
464 |
465 |
466 |
467 |
468 |
469 |
470 |
471 |
472 |
473 |
474 |
475 |
476 |
477 |
478 |
479 |
480 |
481 |
482 |
483 |
484 |
485 |
486 |
487 |
488 |
489 |
490 |
491 |
492 |
493 |
494 |
495 |
496 |
497 |
498 |
--------------------------------------------------------------------------------
/module_i2s_slave/.makefile:
--------------------------------------------------------------------------------
1 | all:
2 | @echo "** Module only - only builds as part of application **"
3 |
4 |
5 | clean:
6 | @echo "** Module only - only builds as part of application **"
7 |
8 |
9 |
--------------------------------------------------------------------------------
/module_i2s_slave/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | module_i2s_slave
4 |
5 |
6 |
7 |
8 |
9 | org.eclipse.cdt.managedbuilder.core.genmakebuilder
10 | clean,full,incremental,
11 |
12 |
13 | ?children?
14 | ?name?=outputEntries\|?children?=?name?=entry\\\\|\\|\||
15 |
16 |
17 | ?name?
18 |
19 |
20 |
21 | org.eclipse.cdt.make.core.append_environment
22 | true
23 |
24 |
25 | org.eclipse.cdt.make.core.buildArguments
26 | CONFIG=Debug
27 |
28 |
29 | org.eclipse.cdt.make.core.buildCommand
30 | xmake
31 |
32 |
33 | org.eclipse.cdt.make.core.cleanBuildTarget
34 | clean
35 |
36 |
37 | org.eclipse.cdt.make.core.contents
38 | org.eclipse.cdt.make.core.activeConfigSettings
39 |
40 |
41 | org.eclipse.cdt.make.core.enableAutoBuild
42 | false
43 |
44 |
45 | org.eclipse.cdt.make.core.enableCleanBuild
46 | true
47 |
48 |
49 | org.eclipse.cdt.make.core.enableFullBuild
50 | true
51 |
52 |
53 | org.eclipse.cdt.make.core.stopOnError
54 | true
55 |
56 |
57 | org.eclipse.cdt.make.core.useDefaultBuildCmd
58 | false
59 |
60 |
61 |
62 |
63 | org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder
64 | full,incremental,
65 |
66 |
67 |
68 |
69 |
70 | org.eclipse.cdt.core.cnature
71 | org.eclipse.cdt.managedbuilder.core.managedBuildNature
72 | org.eclipse.cdt.managedbuilder.core.ScannerConfigNature
73 | com.xmos.cdt.core.XdeProjectNature
74 |
75 |
76 |
77 |
--------------------------------------------------------------------------------
/module_i2s_slave/.xproject:
--------------------------------------------------------------------------------
1 | sc_i2sXM-002000-SM
--------------------------------------------------------------------------------
/module_i2s_slave/README:
--------------------------------------------------------------------------------
1 | This module provides I2S digital audio interface code with the XCore
2 | acting as slave.
3 |
--------------------------------------------------------------------------------
/module_i2s_slave/README.rst:
--------------------------------------------------------------------------------
1 |
2 | ================
3 |
4 | :scope:
5 | :description:
6 | :keywords:
7 | :boards:
8 |
9 |
10 |
--------------------------------------------------------------------------------
/module_i2s_slave/module_build_info:
--------------------------------------------------------------------------------
1 | # You can set flags specifically for your module by using the MODULE_XCC_FLAGS
2 | # variable. So the following
3 | #
4 | # MODULE_XCC_FLAGS = $(XCC_FLAGS) -O3
5 | #
6 | # specifies that everything in the modules should have the application
7 | # build flags with -O3 appended (so the files will build at
8 | # optimization level -O3).
9 | #
10 | # You can also set MODULE_XCC_C_FLAGS, MODULE_XCC_XC_FLAGS etc..
11 |
12 | OPTIONAL_HEADERS += i2s_slave_conf.h
13 |
14 | MODULE_XCC_XC_FLAGS = $(XCC_FLAGS) -O3
15 |
--------------------------------------------------------------------------------
/module_i2s_slave/module_description:
--------------------------------------------------------------------------------
1 | I2S digital audio interface module (XCore as slave)
2 |
--------------------------------------------------------------------------------
/module_i2s_slave/src/i2s_slave.h:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2011, XMOS Ltd., All rights reserved
2 | // This software is freely distributable under a derivative of the
3 | // University of Illinois/NCSA Open Source License posted in
4 | // LICENSE.txt and at
5 |
6 | ///////////////////////////////////////////////////////////////////////////////
7 | //
8 | // Multichannel I2S_SLAVE slave receiver-transmitter
9 |
10 | #ifndef _I2S_SLAVE_H_
11 | #define _I2S_SLAVE_H_
12 |
13 | #ifdef __i2s_slave_conf_h_exists__
14 | #include "i2s_slave_conf.h"
15 | #endif
16 |
17 | #ifndef I2S_SLAVE_NUM_IN
18 | /** Number of input ports, each carries two channels of audio
19 | */
20 | #define I2S_SLAVE_NUM_IN 1
21 | #endif
22 |
23 | #ifndef I2S_SLAVE_NUM_OUT
24 | /** Number of output ports, each carries two channels of audio
25 | */
26 | #define I2S_SLAVE_NUM_OUT 1
27 | #endif
28 |
29 | /** Resources for I2S_SLAVE
30 | */
31 | struct i2s_slave {
32 | clock cb; /**< Clock block for external BCK */
33 |
34 | in port bck; /**< Clock port for BCK */
35 | in port wck; /**< Clock port for WCK */
36 |
37 | in buffered port:32 din[I2S_SLAVE_NUM_IN]; /**< Array of I2S_SLAVE_NUM_IN x 1-bit ports for audio input */
38 | out buffered port:32 dout[I2S_SLAVE_NUM_OUT]; /**< Array of I2S_SLAVE_NUM_OUT x 1-bit ports for audio output */
39 | };
40 |
41 | /** I2S Slave function
42 | *
43 | * Samples are left-aligned signed values.
44 | * e.g. 24-bit audio will look like 0x12345600 (positive) or 0xFF123400 (negative)
45 | *
46 | * \param r_i2s_slave Structure to configure the i2s_slave
47 | *
48 | * \param c_in Input streaming channel for sample data.
49 | * Samples are returned in the following order:
50 | * Left (din[0]), .., Left (din[I2S_SLAVE_NUM_IN - 1]),
51 | * Right (din[0]), .., Right (din[I2S_SLAVE_NUM_IN - 1])
52 | *
53 | * \param c_out Output streaming channel for sample data
54 | * Samples should be sent in the following order:
55 | * Left (dout[0]), .., Left (dout[I2S_SLAVE_NUM_OUT - 1]),
56 | * Right (dout[0]), .., Right (dout[I2S_SLAVE_NUM_OUT - 1])
57 | */
58 | void i2s_slave(struct i2s_slave &r_i2s_slave, streaming chanend c_in, streaming chanend c_out);
59 |
60 | #endif // _I2S_SLAVE_H_
61 |
--------------------------------------------------------------------------------
/module_i2s_slave/src/i2s_slave.xc:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2011, XMOS Ltd., All rights reserved
2 | // This software is freely distributable under a derivative of the
3 | // University of Illinois/NCSA Open Source License posted in
4 | // LICENSE.txt and at
5 |
6 | ///////////////////////////////////////////////////////////////////////////////
7 | //
8 | // Multichannel I2S_SLAVE slave receiver-transmitter
9 |
10 | #include
11 | #include
12 | #include "i2s_slave.h"
13 |
14 | #pragma unsafe arrays
15 | void i2s_slave_loop(in buffered port:32 din[], out buffered port:32 dout[], streaming chanend c_in, streaming chanend c_out, in port wck)
16 | {
17 | int lr = 0;
18 | unsigned frame_counter = 0;
19 |
20 | while (1) {
21 | int t;
22 |
23 | // wait for WCK edge
24 | // timestamp this edge
25 | wck when pinsneq(lr) :> lr @ t;
26 |
27 | // set time for audio data input
28 | // split SETPT from IN using asm
29 | // basically a split transaction to allow multichannel timed input
30 | // input is always "up to" given time
31 | // I2S_SLAVE sample starts at t + 1, so capture "up to" t + 1 + 23
32 | #pragma loop unroll
33 | for (int i = 0; i < I2S_SLAVE_NUM_OUT; i++) {
34 | asm("setpt res[%0], %1" :: "r"(din[i]), "r"(t + 24));
35 | }
36 |
37 | // output audio data
38 | // output is always "starting from" given time
39 | // next I2S_SLAVE sample starts at t + 33, so output at that time
40 | // must do partial output of 24 bits
41 | // full 32-bit output would span entire cycle not allowing consecutive SETPT's
42 | #pragma loop unroll
43 | for (int i = 0; i < I2S_SLAVE_NUM_OUT; i++) {
44 | signed x = 0;
45 | c_out :> x;
46 | partout_timed(dout[i],24,bitrev(x),(t + 33));
47 | }
48 |
49 | // input audio data
50 | // port will capture I2S MSb at t + 1 and LSb at t + 24
51 | // bits 0..7 are older than I2S MSb and hence discard them
52 | // compiler would insert SETC FULL on DIN input, because it doesn't know about inline SETPT above
53 | // hence we need inline IN too
54 | #pragma loop unroll
55 | for (int i = 0; i < I2S_SLAVE_NUM_IN; i++) {
56 | signed x;
57 | asm("in %0, res[%1]" : "=r"(x) : "r"(din[i]));
58 | c_in <: bitrev(x) << 8;
59 | }
60 |
61 | frame_counter++;
62 | }
63 | }
64 |
65 | void i2s_slave(struct i2s_slave &r_i2s_slave, streaming chanend c_in, streaming chanend c_out)
66 | {
67 | // clock block clocked off external BCK
68 | set_clock_src(r_i2s_slave.cb, r_i2s_slave.bck);
69 |
70 | // WCK and all data ports clocked off BCK
71 | set_port_clock(r_i2s_slave.wck, r_i2s_slave.cb);
72 | for (int i = 0; i < I2S_SLAVE_NUM_IN; i++)
73 | {
74 | set_port_clock(r_i2s_slave.din[i], r_i2s_slave.cb);
75 | }
76 | for (int i = 0; i < I2S_SLAVE_NUM_OUT; i++)
77 | {
78 | set_port_clock(r_i2s_slave.dout[i], r_i2s_slave.cb);
79 | }
80 |
81 | // start clock block after configuration
82 | start_clock(r_i2s_slave.cb);
83 |
84 | // fast mode - instructions repeatedly issued instead of paused
85 | set_thread_fast_mode_on();
86 |
87 | i2s_slave_loop(r_i2s_slave.din, r_i2s_slave.dout, c_in, c_out, r_i2s_slave.wck);
88 |
89 | set_thread_fast_mode_off();
90 | }
91 |
--------------------------------------------------------------------------------
/xpd.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | XA-SK-AUDIO
6 | module_i2s_master
7 | module_i2c_single_port
8 | module_i2s_loopback
9 | Audio
10 | I2S
11 |
12 |
13 | XA-SK-AUDIO
14 | Audio
15 | I2S
16 | codec
17 |
18 |
19 |
20 | master
21 | 8809971a9e74a6201cb7817050d98dc4dd4bb9c9
22 | ssh://git@github.com/xcore/sc_i2c
23 | 2.4.1rc0
24 |
25 | I2S Digital Audio Component
26 | doc
27 | app_slicekit_i2s_master_demo/doc
28 | app_i2s_master_demo_xai
29 | app_i2s_slave_example_xai
30 | module_i2s_slave
31 | git@github.com:xcore/sc_i2s
32 | sc_i2s
33 | XMOS
34 | XM-001654-DH
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 | XM-002000-SM
60 | XMOS
61 |
62 | sc_i2s
63 | 1.0
64 | module_i2s_loopback
65 |
--------------------------------------------------------------------------------