From 73064d1a225bccd2c70085327bc318ec2c2e7f4e Mon Sep 17 00:00:00 2001 From: "J.A. de Jong - Redu-Sone B.V., ASCEE V.O.F" Date: Mon, 26 Jul 2021 12:01:43 +0200 Subject: [PATCH] Compilation with CMake seems to work --- .gitignore | 4 + .gitmodules | 12 +++ CMakeLists.txt | 53 +++++++++++++ README.md | 17 +++- lib_gpio | 1 + lib_i2c | 1 + lib_i2s | 1 + lib_xassert | 1 + src/main.xc | 162 ++++++++++++++++++++++++++++++++++++++ src/xcore_200_explorer.xn | 59 ++++++++++++++ 10 files changed, 309 insertions(+), 2 deletions(-) create mode 100644 .gitmodules create mode 100644 CMakeLists.txt create mode 160000 lib_gpio create mode 160000 lib_i2c create mode 160000 lib_i2s create mode 160000 lib_xassert create mode 100644 src/main.xc create mode 100644 src/xcore_200_explorer.xn diff --git a/.gitignore b/.gitignore index 2ebd382..ebe6650 100644 --- a/.gitignore +++ b/.gitignore @@ -192,3 +192,7 @@ dmypy.json # Cython debug symbols cython_debug/ +cmake_install.cmake +CMakeFiles +Makefile +CMakeCache.txt diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..3565d8b --- /dev/null +++ b/.gitmodules @@ -0,0 +1,12 @@ +[submodule "lib_i2s"] + path = lib_i2s + url = https://github.com/xmos/lib_i2s +[submodule "lib_gpio"] + path = lib_gpio + url = https://github.com/xmos/lib_gpio +[submodule "lib_i2c"] + path = lib_i2c + url = https://github.com/xmos/lib_i2c +[submodule "lib_xassert"] + path = lib_xassert + url = https://github.com/xmos/lib_xassert diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..cc085fe --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,53 @@ +cmake_minimum_required(VERSION 3.0) +project(xmos_loopback_cmake) +set(board_target "src/xcore_200_explorer.xn") + +######################### +# Set up cross compiler # +######################### +set(CMAKE_C_COMPILER xcc) +set(CMAKE_CXX_COMPILER xcc) +set(CMAKE_AR xmosar) + +set(CMAKE_C_FLAGS "${board_target} -MD -O2 -fxscope -report ") +set(CMAKE_C_FLAGS_RELEASE " -MD -O3 -fschedule -fxscope -report") +set(CMAKE_C_FLAGS_DEBUG " -MD -DDEBUG -O0 -g -fxscope -report") + +################## +# Compiler Flags # +################## +set(CMAKE_EXE_LINKER_FLAGS "") +################# +# Source files # +################# +file(GLOB lib_i2c_sources lib_i2c/lib_i2c/src/*.xc) +file(GLOB lib_gpio_sources lib_gpio/lib_gpio/src/*.xc) +set(compile_sources + src/main.xc + ${lib_i2c_sources} + ${lib_gpio_sources} + + ) + +################# +# Include files # +################# +set(INCLUDE_DIRS lib_spi/lib_spi/api/ + # i2s lib + lib_i2s/lib_i2s/api lib_i2s/lib_i2s/src + # i2c lib + lib_i2c/lib_i2c/api + lib_gpio/lib_gpio/api lib_gpio/lib_gpio/api + lib_xassert/lib_xassert/api lib_xassert/lib_xassert/api + ) + +############################## +# Compiler Language Settings # +############################## +set_source_files_properties(${compile_sources} PROPERTIES LANGUAGE C) + +################# +# Create Target # +################# +include_directories(${INCLUDE_DIRS}) +add_executable(loopback_example ${compile_sources}) diff --git a/README.md b/README.md index b0c4515..318993e 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,16 @@ -# xmos_loopback_cmake +# XMOS loopback cmake + +Loopback demo for the XMOS XCORE-200-EXPLORER kit. We use cmake as our build +system. + + +## Installation + +Please make sure that we are in a clean environment. The example makes use of +XMOS libraries, which are pulled in as submodules. Therefore we have to clone +this repository recursively: + + +`$ git clone --recursive ...` + -Loopback demo for the XMOS XCORE-200-EXPLORER kit. Using Cmake as the build system \ No newline at end of file diff --git a/lib_gpio b/lib_gpio new file mode 160000 index 0000000..e22d9a3 --- /dev/null +++ b/lib_gpio @@ -0,0 +1 @@ +Subproject commit e22d9a3549349faa01673d828d47ef344c8e4ac5 diff --git a/lib_i2c b/lib_i2c new file mode 160000 index 0000000..f57440f --- /dev/null +++ b/lib_i2c @@ -0,0 +1 @@ +Subproject commit f57440fa51553b9f2a59826f201217e7bc29265b diff --git a/lib_i2s b/lib_i2s new file mode 160000 index 0000000..54ca251 --- /dev/null +++ b/lib_i2s @@ -0,0 +1 @@ +Subproject commit 54ca251e20b849701bc7f095d0ae900337faa831 diff --git a/lib_xassert b/lib_xassert new file mode 160000 index 0000000..25508f9 --- /dev/null +++ b/lib_xassert @@ -0,0 +1 @@ +Subproject commit 25508f9f99cfbc7bd072dd811b3631dc5f55846c diff --git a/src/main.xc b/src/main.xc new file mode 100644 index 0000000..6c43ec2 --- /dev/null +++ b/src/main.xc @@ -0,0 +1,162 @@ +// Copyright (c) 2014-2016, XMOS Ltd, All rights reserved +#include +#include +#include "i2s.h" +#include "i2c.h" +#include "gpio.h" + +/* Ports and clocks used by the application */ +on tile[0]: out buffered port:32 p_lrclk = XS1_PORT_1G; +on tile[0]: out buffered port:32 p_bclk = XS1_PORT_1H; +on tile[0]: in port p_mclk = XS1_PORT_1F; +on tile[0]: out buffered port:32 p_dout[4] = {XS1_PORT_1M, XS1_PORT_1N, XS1_PORT_1O, XS1_PORT_1P}; +on tile[0]: in buffered port:32 p_din[4] = {XS1_PORT_1I, XS1_PORT_1J, XS1_PORT_1K, XS1_PORT_1L}; + +on tile[0]: clock mclk = XS1_CLKBLK_1; +on tile[0]: clock bclk = XS1_CLKBLK_2; + +on tile[0]: port p_i2c = XS1_PORT_4A; +on tile[0]: port p_gpio = XS1_PORT_8C; + +#define SAMPLE_FREQUENCY 48000 +#define MASTER_CLOCK_FREQUENCY 24576000 + +#define CS5368_ADDR 0x4C // I2C address of the CS5368 DAC +#define CS5368_GCTL_MDE 0x01 // I2C mode control register number +#define CS5368_PWR_DN 0x06 + +#define CS4384_ADDR 0x18 // I2C address of the CS4384 ADC +#define CS4384_MODE_CTRL 0x02 // I2C mode control register number +#define CS4384_PCM_CTRL 0x03 // I2C PCM control register number + +enum gpio_shared_audio_pins { + GPIO_DAC_RST_N = 1, + GPIO_PLL_SEL = 5, // 1 = CS2100, 0 = Phaselink clock source + GPIO_ADC_RST_N = 6, + GPIO_MCLK_FSEL = 7, // Select frequency on Phaselink clock. 0 = 24.576MHz for 48k, 1 = 22.5792MHz for 44.1k. +}; + +void reset_codecs(client i2c_master_if i2c) +{ + /* Mode Control 1 (Address: 0x02) */ + /* bit[7] : Control Port Enable (CPEN) : Set to 1 for enable + * bit[6] : Freeze controls (FREEZE) : Set to 1 for freeze + * bit[5] : PCM/DSD Selection (DSD/PCM) : Set to 0 for PCM + * bit[4:1] : DAC Pair Disable (DACx_DIS) : All Dac Pairs enabled + * bit[0] : Power Down (PDN) : Powered down + */ + i2c.write_reg(CS4384_ADDR, CS4384_MODE_CTRL, 0b11000001); + + /* PCM Control (Address: 0x03) */ + /* bit[7:4] : Digital Interface Format (DIF) : 0b1100 for TDM + * bit[3:2] : Reserved + * bit[1:0] : Functional Mode (FM) : 0x11 for auto-speed detect (32 to 200kHz) + */ + i2c.write_reg(CS4384_ADDR, CS4384_PCM_CTRL, 0b00010111); + + /* Mode Control 1 (Address: 0x02) */ + /* bit[7] : Control Port Enable (CPEN) : Set to 1 for enable + * bit[6] : Freeze controls (FREEZE) : Set to 0 for freeze + * bit[5] : PCM/DSD Selection (DSD/PCM) : Set to 0 for PCM + * bit[4:1] : DAC Pair Disable (DACx_DIS) : All Dac Pairs enabled + * bit[0] : Power Down (PDN) : Not powered down + */ + i2c.write_reg(CS4384_ADDR, CS4384_MODE_CTRL, 0b10000000); + + unsigned adc_dif = 0x01; // I2S mode + unsigned adc_mode = 0x03; // Slave mode all speeds + + /* Reg 0x01: (GCTL) Global Mode Control Register */ + /* Bit[7]: CP-EN: Manages control-port mode + * Bit[6]: CLKMODE: Setting puts part in 384x mode + * Bit[5:4]: MDIV[1:0]: Set to 01 for /2 + * Bit[3:2]: DIF[1:0]: Data Format: 0x01 for I2S, 0x02 for TDM + * Bit[1:0]: MODE[1:0]: Mode: 0x11 for slave mode + */ + i2c.write_reg(CS5368_ADDR, CS5368_GCTL_MDE, 0b10010000 | (adc_dif << 2) | adc_mode); + + /* Reg 0x06: (PDN) Power Down Register */ + /* Bit[7:6]: Reserved + * Bit[5]: PDN-BG: When set, this bit powers-own the bandgap reference + * Bit[4]: PDM-OSC: Controls power to internal oscillator core + * Bit[3:0]: PDN: When any bit is set all clocks going to that channel pair are turned off + */ + i2c.write_reg(CS5368_ADDR, CS5368_PWR_DN, 0b00000000); +} + +[[distributable]] +void i2s_loopback(server i2s_callback_if i2s, + client i2c_master_if i2c, + client output_gpio_if dac_reset, + client output_gpio_if adc_reset, + client output_gpio_if pll_select, + client output_gpio_if mclk_select) +{ + int32_t samples[8] = {0, 0, 0, 0, 0, 0, 0, 0}; + while (1) { + select { + case i2s.init(i2s_config_t &?i2s_config, tdm_config_t &?tdm_config): + i2s_config.mode = I2S_MODE_I2S; + i2s_config.mclk_bclk_ratio = (MASTER_CLOCK_FREQUENCY/SAMPLE_FREQUENCY)/64; + + // Set CODECs in reset + dac_reset.output(0); + adc_reset.output(0); + + // Select 48Khz family clock (24.576Mhz) + mclk_select.output(1); + pll_select.output(0); + + // Allow the clock to settle + delay_milliseconds(2); + + // Take CODECs out of reset + dac_reset.output(1); + adc_reset.output(1); + + reset_codecs(i2c); + break; + + case i2s.receive(size_t index, int32_t sample): + samples[index] = sample; + break; + + case i2s.send(size_t index) -> int32_t sample: + sample = samples[index]; + break; + + case i2s.restart_check() -> i2s_restart_t restart: + restart = I2S_NO_RESTART; + break; + } + } +} + +static char gpio_pin_map[4] = { + GPIO_DAC_RST_N, + GPIO_ADC_RST_N, + GPIO_PLL_SEL, + GPIO_MCLK_FSEL +}; + +int main() +{ + interface i2s_callback_if i_i2s; + interface i2c_master_if i_i2c[1]; + interface output_gpio_if i_gpio[4]; + par { + on tile[0]: { + /* System setup, I2S + Codec control over I2C */ + configure_clock_src(mclk, p_mclk); + start_clock(mclk); + i2s_master(i_i2s, p_dout, 4, p_din, 4, p_bclk, p_lrclk, bclk, mclk); + } + + on tile[0]: [[distribute]] i2c_master_single_port(i_i2c, 1, p_i2c, 100, 0, 1, 0); + on tile[0]: [[distribute]] output_gpio(i_gpio, 4, p_gpio, gpio_pin_map); + + /* The application - loopback the I2S samples */ + on tile[0]: [[distribute]] i2s_loopback(i_i2s, i_i2c[0], i_gpio[0], i_gpio[1], i_gpio[2], i_gpio[3]); + } + return 0; +} diff --git a/src/xcore_200_explorer.xn b/src/xcore_200_explorer.xn new file mode 100644 index 0000000..6875f77 --- /dev/null +++ b/src/xcore_200_explorer.xn @@ -0,0 +1,59 @@ + + + Board + xCORE-200 Explorer Kit + + tileref tile[2] + tileref usb_tile + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +