├── .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 | --------------------------------------------------------------------------------