diff --git a/examples/examples.cmake b/examples/examples.cmake index 517a507e4..1eb8aa229 100644 --- a/examples/examples.cmake +++ b/examples/examples.cmake @@ -7,6 +7,8 @@ if(${CMAKE_SYSTEM_NAME} STREQUAL XCORE_XS3A) include(${CMAKE_CURRENT_LIST_DIR}/ffd/ffd_sensory.cmake) include(${CMAKE_CURRENT_LIST_DIR}/ffd/ffd_cyberon.cmake) include(${CMAKE_CURRENT_LIST_DIR}/ffd/ffd_i2s_input_cyberon.cmake) + include(${CMAKE_CURRENT_LIST_DIR}/ffd/ffd_sensory_sq66.cmake) + include(${CMAKE_CURRENT_LIST_DIR}/ffd/ffd_cyberon_sq66.cmake) include(${CMAKE_CURRENT_LIST_DIR}/low_power_ffd/low_power_ffd_sensory.cmake) include(${CMAKE_CURRENT_LIST_DIR}/mic_aggregator/mic_aggregator.cmake) diff --git a/examples/ffd/README.rst b/examples/ffd/README.rst index 1184dc461..d65b0ac6a 100644 --- a/examples/ffd/README.rst +++ b/examples/ffd/README.rst @@ -46,7 +46,7 @@ Command Utterances Supported Hardware and pre-requisites ===================================== -This example is supported on the XK_VOICE_L71 board. +This example is supported on the XK_VOICE_L71 board and XK_VOICE_SQ66 board. Make sure that your XTC tools environment is activated. @@ -71,7 +71,7 @@ This application requires a host application to create the flash data partition. .. note:: - In the commands below ```` can be either ``sensory`` or ``cyberon``, depending on the choice of the speech recognition engine and model. + In the commands below ```` can be either ``sensory``, ``cyberon``, ``sensory_sq66`` or ``cyberon_sq66``, depending on the choice of the speech recognition engine, model and board. .. note:: diff --git a/examples/ffd/bsp_config/XK_VOICE_SQ66/XK_VOICE_SQ66.cmake b/examples/ffd/bsp_config/XK_VOICE_SQ66/XK_VOICE_SQ66.cmake new file mode 100644 index 000000000..94001ecf0 --- /dev/null +++ b/examples/ffd/bsp_config/XK_VOICE_SQ66/XK_VOICE_SQ66.cmake @@ -0,0 +1,78 @@ + +## SQ66 custom mic array +add_library(framework_rtos_drivers_mic_array_sq66 INTERFACE) +target_sources(framework_rtos_drivers_mic_array_sq66 + INTERFACE + ${FRAMEWORK_RTOS_ROOT_PATH}/modules/drivers/mic_array/src/rtos_mic_array.c + ${FRAMEWORK_RTOS_ROOT_PATH}/modules/drivers/mic_array/src/rtos_mic_array_rpc.c + ${CMAKE_CURRENT_LIST_DIR}/platform/mic_array_vanilla.cpp +) +target_include_directories(framework_rtos_drivers_mic_array_sq66 + INTERFACE + ${FRAMEWORK_RTOS_ROOT_PATH}/modules/drivers/mic_array/api + ${FRAMEWORK_IO_ROOT_PATH}/modules/mic_array/etc/vanilla/ +) +target_link_libraries(framework_rtos_drivers_mic_array_sq66 + INTERFACE + lib_mic_array + rtos::osal +) +target_compile_definitions(framework_rtos_drivers_mic_array_sq66 + INTERFACE + MIC_ARRAY_BASIC_API_ENABLE=1 +) +## Create an alias +add_library(rtos::drivers::mic_array_sq66 ALIAS framework_rtos_drivers_mic_array_sq66) + +## Create custom board targets for application +add_library(sln_voice_app_ffd_board_support_xk_voice_sq66 INTERFACE) +target_sources(sln_voice_app_ffd_board_support_xk_voice_sq66 + INTERFACE + ${CMAKE_CURRENT_LIST_DIR}/platform/app_pll_ctrl.c + ${CMAKE_CURRENT_LIST_DIR}/platform/driver_instances.c + ${CMAKE_CURRENT_LIST_DIR}/platform/platform_init.c + ${CMAKE_CURRENT_LIST_DIR}/platform/platform_start.c + ${CMAKE_CURRENT_LIST_DIR}/platform/dac_port.c +) +target_include_directories(sln_voice_app_ffd_board_support_xk_voice_sq66 + INTERFACE + ${CMAKE_CURRENT_LIST_DIR} +) +target_link_libraries(sln_voice_app_ffd_board_support_xk_voice_sq66 + INTERFACE + core::general + rtos::freertos + rtos::drivers::general + rtos::drivers::i2s + rtos::drivers::mic_array_sq66 + sln_voice::app::ffd::dac::dac3101 +) +target_compile_options(sln_voice_app_ffd_board_support_xk_voice_sq66 + INTERFACE + ${CMAKE_CURRENT_LIST_DIR}/XK_VOICE_SQ66.xn +) +target_link_options(sln_voice_app_ffd_board_support_xk_voice_sq66 + INTERFACE + ${CMAKE_CURRENT_LIST_DIR}/XK_VOICE_SQ66.xn +) +target_compile_definitions(sln_voice_app_ffd_board_support_xk_voice_sq66 + INTERFACE + XK_VOICE_SQ66=1 + PLATFORM_SUPPORTS_TILE_0=1 + PLATFORM_SUPPORTS_TILE_1=1 + PLATFORM_SUPPORTS_TILE_2=0 + PLATFORM_SUPPORTS_TILE_3=0 + + MIC_ARRAY_CONFIG_MCLK_FREQ=24576000 + MIC_ARRAY_CONFIG_PDM_FREQ=3072000 + MIC_ARRAY_CONFIG_SAMPLES_PER_FRAME=240 + MIC_ARRAY_CONFIG_MIC_COUNT=2 + MIC_ARRAY_CONFIG_CLOCK_BLOCK_A=XS1_CLKBLK_2 + MIC_ARRAY_CONFIG_CLOCK_BLOCK_B=XS1_CLKBLK_3 + MIC_ARRAY_CONFIG_PORT_MCLK=PORT_PDM_MCLK + MIC_ARRAY_CONFIG_PORT_PDM_CLK=PORT_PDM_CLK + MIC_ARRAY_CONFIG_PORT_PDM_DATA=PORT_PDM_DATA +) + +## Create an alias +add_library(sln_voice::app::ffd::xk_voice_sq66 ALIAS sln_voice_app_ffd_board_support_xk_voice_sq66) diff --git a/examples/ffd/bsp_config/XK_VOICE_SQ66/XK_VOICE_SQ66.xn b/examples/ffd/bsp_config/XK_VOICE_SQ66/XK_VOICE_SQ66.xn new file mode 100644 index 000000000..76a6f523f --- /dev/null +++ b/examples/ffd/bsp_config/XK_VOICE_SQ66/XK_VOICE_SQ66.xn @@ -0,0 +1,107 @@ + + + Board + XK-VOICE-SQ66 + + tileref tile[2] + tileref usb_tile + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/ffd/bsp_config/XK_VOICE_SQ66/platform/app_pll_ctrl.c b/examples/ffd/bsp_config/XK_VOICE_SQ66/platform/app_pll_ctrl.c new file mode 100644 index 000000000..4d963efb0 --- /dev/null +++ b/examples/ffd/bsp_config/XK_VOICE_SQ66/platform/app_pll_ctrl.c @@ -0,0 +1,51 @@ +// Copyright 2022-2023 XMOS LIMITED. +// This Software is subject to the terms of the XMOS Public Licence: Version 1. + +/* System headers */ +#include +#include +#include +#include + +/* App headers */ +#include "platform/app_pll_ctrl.h" + +void app_pll_set_numerator(int numerator) +{ + const unsigned tileid = get_local_tile_id(); + uint32_t fracval = APP_PLL_FRAC_NOM & 0xFFFF00FF; + uint32_t f; + + if (numerator > 255) { + f = 255; + } else if (numerator < 0) { + f = 0; + } else { + f = numerator; + } + + fracval |= (f << 8); + write_sswitch_reg_no_ack(tileid, XS1_SSWITCH_SS_APP_PLL_FRAC_N_DIVIDER_NUM, fracval); +} + +void app_pll_init(void) +{ + unsigned tileid = get_local_tile_id(); + + const unsigned APP_PLL_DISABLE = 0x0201FF04; + const unsigned APP_PLL_DIV_0 = 0x80000004; + + write_sswitch_reg(tileid, XS1_SSWITCH_SS_APP_PLL_CTL_NUM, APP_PLL_DISABLE); + + hwtimer_t tmr = hwtimer_alloc(); + { + xassert(tmr != 0); + hwtimer_delay(tmr, 100000); // 1ms with 100 MHz timer tick + } + hwtimer_free(tmr); + + write_sswitch_reg(tileid, XS1_SSWITCH_SS_APP_PLL_CTL_NUM, APP_PLL_CTL_VAL); + write_sswitch_reg(tileid, XS1_SSWITCH_SS_APP_PLL_CTL_NUM, APP_PLL_CTL_VAL); + write_sswitch_reg(tileid, XS1_SSWITCH_SS_APP_PLL_FRAC_N_DIVIDER_NUM, APP_PLL_FRAC_NOM); + write_sswitch_reg(tileid, XS1_SSWITCH_SS_APP_CLK_DIVIDER_NUM, APP_PLL_DIV_0); +} diff --git a/examples/ffd/bsp_config/XK_VOICE_SQ66/platform/app_pll_ctrl.h b/examples/ffd/bsp_config/XK_VOICE_SQ66/platform/app_pll_ctrl.h new file mode 100644 index 000000000..b4f3e7c64 --- /dev/null +++ b/examples/ffd/bsp_config/XK_VOICE_SQ66/platform/app_pll_ctrl.h @@ -0,0 +1,19 @@ +// Copyright 2022-2023 XMOS LIMITED. +// This Software is subject to the terms of the XMOS Public Licence: Version 1. + +#ifndef APP_PLL_CTRL_H_ +#define APP_PLL_CTRL_H_ + +#include "platform_conf.h" + +#if (MIC_ARRAY_CONFIG_MCLK_FREQ != 24576000) +#error PLL values only valid if MIC_ARRAY_CONFIG_MCLK_FREQ == 24576000 +#endif + +#define APP_PLL_CTL_VAL 0x0A019803 // Valid for all fractional values +#define APP_PLL_FRAC_NOM 0x800095F9 // 24.576000 MHz + +void app_pll_set_numerator(int numerator); +void app_pll_init(void); + +#endif /* APP_PLL_CTRL_H_ */ diff --git a/examples/ffd/bsp_config/XK_VOICE_SQ66/platform/dac_port.c b/examples/ffd/bsp_config/XK_VOICE_SQ66/platform/dac_port.c new file mode 100644 index 000000000..1c72c4f3a --- /dev/null +++ b/examples/ffd/bsp_config/XK_VOICE_SQ66/platform/dac_port.c @@ -0,0 +1,97 @@ +// Copyright 2022-2023 XMOS LIMITED. +// This Software is subject to the terms of the XMOS Public Licence: Version 1. + +/* System headers */ +#include + +/* FreeRTOS headers */ +#include "FreeRTOS.h" + +/* App headers */ +#include "platform_conf.h" +#include "platform/driver_instances.h" +#include "dac3101.h" +#include "pcal6408a.h" + +/* I2C io expander address on XCF3610_Q60A board */ +#define IOEXP_I2C_ADDR PCAL6408A_I2C_ADDR + +/* IO expander pinout */ +#define XVF_RST_N_PIN 0 +#define INT_N_PIN 1 +#define DAC_RST_N_PIN 2 +#define BOOT_SEL_PIN 3 +#define MCLK_OE_PIN 4 +#define SPI_OE_PIN 5 +#define I2S_OE_PIN 6 +#define MUTE_PIN 7 + +int dac3101_reg_write(uint8_t reg, uint8_t val) +{ + i2c_regop_res_t ret; + + ret = rtos_i2c_master_reg_write(i2c_master_ctx, DAC3101_I2C_DEVICE_ADDR, reg, val); + + if (ret == I2C_REGOP_SUCCESS) { + return 0; + } else { + return -1; + } +} + +void dac3101_codec_reset(void) +{ + /* Set DAC_RST_N to 0 and enable level shifters */ + i2c_regop_res_t ret; + uint8_t bitmask = (1< +#include +#include + +#include + +#include "mic_array_vanilla.h" +#include "mic_array/cpp/Prefab.hpp" +#include "mic_array.h" +#include "mic_array/etc/filters_default.h" + + +////// Check that all the required config macros have been defined. + +#ifndef MIC_ARRAY_CONFIG_MCLK_FREQ +# error Application must specify the master clock frequency by defining MIC_ARRAY_CONFIG_MCLK_FREQ. +#endif + +#ifndef MIC_ARRAY_CONFIG_PDM_FREQ +# error Application must specify the PDM clock frequency by defining MIC_ARRAY_CONFIG_PDM_FREQ. +#endif + +#ifndef MIC_ARRAY_CONFIG_MIC_COUNT +# error Application must specify the microphone count by defining MIC_ARRAY_CONFIG_MIC_COUNT. +#endif + + +////// Provide default values for optional config macros + +#ifndef MIC_ARRAY_CONFIG_SAMPLES_PER_FRAME +# define MIC_ARRAY_CONFIG_SAMPLES_PER_FRAME (1) +#else +# if ((MIC_ARRAY_CONFIG_SAMPLES_PER_FRAME) < 1) +# error MIC_ARRAY_CONFIG_SAMPLES_PER_FRAME must be positive. +# endif +#endif + +#ifndef MIC_ARRAY_CONFIG_USE_DC_ELIMINATION +# define MIC_ARRAY_CONFIG_USE_DC_ELIMINATION (1) +#endif + +#ifndef MIC_ARRAY_CONFIG_PORT_MCLK +# define MIC_ARRAY_CONFIG_PORT_MCLK (PORT_MCLK_IN_OUT) +#endif + +#ifndef MIC_ARRAY_CONFIG_PORT_PDM_CLK +# define MIC_ARRAY_CONFIG_PORT_PDM_CLK (PORT_PDM_CLK) +#endif + +#ifndef MIC_ARRAY_CONFIG_PORT_PDM_DATA +# define MIC_ARRAY_CONFIG_PORT_PDM_DATA (PORT_PDM_DATA) +#endif + +#ifndef MIC_ARRAY_CONFIG_CLOCK_BLOCK_A +# define MIC_ARRAY_CONFIG_CLOCK_BLOCK_A (XS1_CLKBLK_1) +#endif + +#ifndef MIC_ARRAY_CONFIG_CLOCK_BLOCK_B +# define MIC_ARRAY_CONFIG_CLOCK_BLOCK_B (XS1_CLKBLK_2) +#endif + +#ifndef MIC_ARRAY_CONFIG_USE_DDR +# define MIC_ARRAY_CONFIG_USE_DDR ((MIC_ARRAY_CONFIG_MIC_COUNT)==2) +#endif + +////// Additional macros derived from others + +#define MIC_ARRAY_CONFIG_MCLK_DIVIDER ((MIC_ARRAY_CONFIG_MCLK_FREQ) \ + /(MIC_ARRAY_CONFIG_PDM_FREQ)) +#define MIC_ARRAY_CONFIG_OUT_SAMPLE_RATE ((MIC_ARRAY_CONFIG_PDM_FREQ) \ + /(STAGE2_DEC_FACTOR)) + +////// Any Additional correctness checks + + + +////// Allocate needed objects + +pdm_rx_resources_t pdm_res = PDM_RX_RESOURCES_SDR( + MIC_ARRAY_CONFIG_PORT_MCLK, + MIC_ARRAY_CONFIG_PORT_PDM_CLK, + MIC_ARRAY_CONFIG_PORT_PDM_DATA, + MIC_ARRAY_CONFIG_CLOCK_BLOCK_A); + +using TMicArray = mic_array::prefab::BasicMicArray< + MIC_ARRAY_CONFIG_MIC_COUNT, + MIC_ARRAY_CONFIG_SAMPLES_PER_FRAME, + MIC_ARRAY_CONFIG_USE_DC_ELIMINATION, + 8>; + +TMicArray mics; + + +void ma_vanilla_init() +{ + mics.Init(); + mics.SetPort(pdm_res.p_pdm_mics); + mics.PdmRx.AssertOnDroppedBlock(false); // Do not assert on dropped blocks + unsigned channel_map[MIC_ARRAY_CONFIG_MIC_COUNT] = {4, 6};//, 6, 7}; + mics.PdmRx.MapChannels(channel_map); + mic_array_resources_configure(&pdm_res, MIC_ARRAY_CONFIG_MCLK_DIVIDER); + mic_array_pdm_clock_start(&pdm_res); +} + + +void ma_vanilla_task( + chanend_t c_frames_out) +{ + mics.SetOutputChannel(c_frames_out); + + mics.InstallPdmRxISR(); + mics.UnmaskPdmRxISR(); + + mics.ThreadEntry(); +} \ No newline at end of file diff --git a/examples/ffd/bsp_config/XK_VOICE_SQ66/platform/pcal6408a.h b/examples/ffd/bsp_config/XK_VOICE_SQ66/platform/pcal6408a.h new file mode 100644 index 000000000..23eb924bf --- /dev/null +++ b/examples/ffd/bsp_config/XK_VOICE_SQ66/platform/pcal6408a.h @@ -0,0 +1,22 @@ +// Copyright 2022-2023 XMOS LIMITED. +// This Software is subject to the terms of the XMOS Public Licence: Version 1. + +#ifndef PCAL6408A_H_ +#define PCAL6408A_H_ + +#define PCAL6408A_I2C_ADDR 0x20 + +#define PCAL6408A_INPUT_PORT 0x00 +#define PCAL6408A_OUTPUT_PORT 0x01 +#define PCAL6408A_POLARITY_INV 0x02 +#define PCAL6408A_CONF 0x03 +#define PCAL6408A_OUTPUT_DRIVE_STR0 0x40 +#define PCAL6408A_OUTPUT_DRIVE_STR1 0x41 +#define PCAL6408A_INPUT_LATCH 0x42 +#define PCAL6408A_PULLUPDOWN_EN 0x43 +#define PCAL6408A_PULLUPDOWN_SEL 0x44 +#define PCAL6408A_INTERRUPT_MASK 0x45 +#define PCAL6408A_INTERRUPT_STATUS 0x46 +#define PCAL6408A_OUTPUT_PORT_CONF 0x4F + +#endif /* PCAL6408A_H_ */ diff --git a/examples/ffd/bsp_config/XK_VOICE_SQ66/platform/platform_conf.h b/examples/ffd/bsp_config/XK_VOICE_SQ66/platform/platform_conf.h new file mode 100644 index 000000000..3b1d1da78 --- /dev/null +++ b/examples/ffd/bsp_config/XK_VOICE_SQ66/platform/platform_conf.h @@ -0,0 +1,99 @@ +// Copyright 2022-2023 XMOS LIMITED. +// This Software is subject to the terms of the XMOS Public Licence: Version 1. + +#ifndef PLATFORM_CONF_H_ +#define PLATFORM_CONF_H_ + +/* + * Board support package for XK_VOICE_SQ66 + */ + +#if __has_include("app_conf.h") +#include "app_conf.h" +#endif /* __has_include("app_conf.h") */ + +/*****************************************/ +/* Intertile Communication Configuration */ +/*****************************************/ +#ifndef appconfI2C_MASTER_RPC_PORT +#define appconfI2C_MASTER_RPC_PORT 10 +#endif /* appconfI2C_MASTER_RPC_PORT */ + +#ifndef appconfI2C_MASTER_RPC_PRIORITY +#define appconfI2C_MASTER_RPC_PRIORITY (configMAX_PRIORITIES/2) +#endif /* appconfI2C_MASTER_RPC_PRIORITY */ + +#ifndef appconfGPIO_T0_RPC_PORT +#define appconfGPIO_T0_RPC_PORT 11 +#endif /* appconfGPIO_T0_RPC_PORT */ + +#ifndef appconfGPIO_T1_RPC_PORT +#define appconfGPIO_T1_RPC_PORT 12 +#endif /* appconfGPIO_T1_RPC_PORT */ + +#ifndef appconfGPIO_RPC_PRIORITY +#define appconfGPIO_RPC_PRIORITY (configMAX_PRIORITIES/2) +#endif /* appconfGPIO_RPC_PRIORITY */ + +#ifndef appconfI2S_RPC_PORT +#define appconfI2S_RPC_PORT 13 +#endif /* appconfI2S_RPC_PORT */ + +#ifndef appconfI2S_RPC_PRIORITY +#define appconfI2S_RPC_PRIORITY (configMAX_PRIORITIES/2) +#endif /* appconfI2S_RPC_PRIORITY */ + +/*****************************************/ +/* I/O and interrupt cores for Tile 1 */ +/*****************************************/ +#ifndef appconfPDM_MIC_IO_CORE +#define appconfPDM_MIC_IO_CORE 1 /* Must be kept off I/O cores. Must be kept off core 0 with the RTOS tick ISR */ +#endif /* appconfPDM_MIC_IO_CORE */ + +#ifndef appconfI2S_IO_CORE +#define appconfI2S_IO_CORE 2 /* Must be kept off core 0 with the RTOS tick ISR */ +#endif /* appconfI2S_IO_CORE */ + +#ifndef appconfI2C_IO_CORE +#define appconfI2C_IO_CORE 3 /* Must be kept off core 0 with the RTOS tick ISR */ +#endif /* appconfI2C_IO_CORE */ + +#ifndef appconfI2C_INTERRUPT_CORE +#define appconfI2C_INTERRUPT_CORE 0 /* Must be kept off I/O cores. */ +#endif /* appconfI2C_INTERRUPT_CORE */ + +#ifndef appconfPDM_MIC_INTERRUPT_CORE +#define appconfPDM_MIC_INTERRUPT_CORE 3 /* Must be kept off I/O cores. Best kept off core 0 with the tick ISR. */ +#endif /* appconfPDM_MIC_INTERRUPT_CORE */ + +#ifndef appconfI2S_INTERRUPT_CORE +#define appconfI2S_INTERRUPT_CORE 4 /* Must be kept off I/O cores. Best kept off core 0 with the tick ISR. */ +#endif /* appconfI2S_INTERRUPT_CORE */ + +/*****************************************/ +/* I/O and interrupt cores for Tile 1 */ +/*****************************************/ +#ifndef appconfPDM_CLOCK_FREQUENCY +#define appconfPDM_CLOCK_FREQUENCY MIC_ARRAY_CONFIG_MCLK_FREQ +#endif /* appconfPDM_CLOCK_FREQUENCY */ + +#ifndef appconfAUDIO_CLOCK_FREQUENCY +#define appconfAUDIO_CLOCK_FREQUENCY MIC_ARRAY_CONFIG_PDM_FREQ +#endif /* appconfAUDIO_CLOCK_FREQUENCY */ + +#ifndef appconfPIPELINE_AUDIO_SAMPLE_RATE +#define appconfPIPELINE_AUDIO_SAMPLE_RATE 16000 +#endif /* appconfPIPELINE_AUDIO_SAMPLE_RATE */ + +/*****************************************/ +/* I/O Task Priorities */ +/*****************************************/ +#ifndef appconfQSPI_FLASH_TASK_PRIORITY +#define appconfQSPI_FLASH_TASK_PRIORITY (configMAX_PRIORITIES-1) +#endif /* appconfQSPI_FLASH_TASK_PRIORITY */ + +#ifndef appconfI2C_TASK_PRIORITY +#define appconfI2C_TASK_PRIORITY (configMAX_PRIORITIES/2) +#endif /* appconfI2C_TASK_PRIORITY */ + +#endif /* PLATFORM_CONF_H_ */ diff --git a/examples/ffd/bsp_config/XK_VOICE_SQ66/platform/platform_init.c b/examples/ffd/bsp_config/XK_VOICE_SQ66/platform/platform_init.c new file mode 100644 index 000000000..7ef649aae --- /dev/null +++ b/examples/ffd/bsp_config/XK_VOICE_SQ66/platform/platform_init.c @@ -0,0 +1,283 @@ +// Copyright 2022-2023 XMOS LIMITED. +// This Software is subject to the terms of the XMOS Public Licence: Version 1. + +/* System headers */ +#include + +/* App headers */ +#include "platform_conf.h" +#include "platform/app_pll_ctrl.h" +#include "platform/driver_instances.h" +#include "platform/platform_init.h" + +static void mclk_init(chanend_t other_tile_c) +{ +#if ON_TILE(I2S_TILE_NO) + app_pll_init(); +#endif +} + +static void flash_init(void) +{ +#if ON_TILE(FLASH_TILE_NO) + rtos_qspi_flash_fast_read_init( + qspi_flash_ctx, + FLASH_CLKBLK, + PORT_SQI_CS, + PORT_SQI_SCLK, + PORT_SQI_SIO, + NULL, + qspi_fast_flash_read_transfer_nibble_swap, + 3, + QSPI_FLASH_CALIBRATION_ADDRESS); +#endif +} + +static void gpio_init(void) +{ + static rtos_driver_rpc_t gpio_rpc_config_t0; + static rtos_driver_rpc_t gpio_rpc_config_t1; + rtos_intertile_t *client_intertile_ctx[1] = {intertile_ctx}; + +#if ON_TILE(0) + rtos_gpio_init(gpio_ctx_t0); + + rtos_gpio_rpc_host_init( + gpio_ctx_t0, + &gpio_rpc_config_t0, + client_intertile_ctx, + 1); + + rtos_gpio_rpc_client_init( + gpio_ctx_t1, + &gpio_rpc_config_t1, + intertile_ctx); +#endif + +#if ON_TILE(I2S_TILE_NO) + rtos_gpio_init(gpio_ctx_t1); + + rtos_gpio_rpc_client_init( + gpio_ctx_t0, + &gpio_rpc_config_t0, + intertile_ctx); + + rtos_gpio_rpc_host_init( + gpio_ctx_t1, + &gpio_rpc_config_t1, + client_intertile_ctx, + 1); +#endif +} + +static void i2c_init(void) +{ +#if appconfINTENT_I2C_SLAVE_POLLED_ENABLED && ON_TILE(I2C_TILE_NO) + rtos_i2c_slave_init(i2c_slave_ctx, + (1 << appconfI2C_IO_CORE), + PORT_I2C_SCL, + PORT_I2C_SDA, + appconfI2C_SLAVE_DEVICE_ADDR); +#endif + +#if appconfI2C_MASTER_DAC_ENABLED || appconfINTENT_I2C_MASTER_OUTPUT_ENABLED + static rtos_driver_rpc_t i2c_rpc_config; + +#if ON_TILE(I2C_TILE_NO) + rtos_intertile_t *client_intertile_ctx[1] = {intertile_ctx}; + rtos_i2c_master_init( + i2c_master_ctx, + PORT_I2C_SCL, 0, 0, + PORT_I2C_SDA, 0, 0, + 0, + 400); + + rtos_i2c_master_rpc_host_init( + i2c_master_ctx, + &i2c_rpc_config, + client_intertile_ctx, + 1); +#else + rtos_i2c_master_rpc_client_init( + i2c_master_ctx, + &i2c_rpc_config, + intertile_ctx); +#endif +#endif +} + +#if ON_TILE(I2S_TILE_NO) && appconfRECOVER_MCLK_I2S_APP_PLL +static int *p_lock_status = NULL; +/// @brief Save the pointer to the pll lock_status variable +static void set_pll_lock_status_ptr(int* p) +{ + p_lock_status = p; +} +#endif + +static void platform_sw_pll_init(void) +{ +#if ON_TILE(I2S_TILE_NO) && appconfRECOVER_MCLK_I2S_APP_PLL + + port_t p_bclk = PORT_I2S_BCLK; + port_t p_mclk = PORT_MCLK; + port_t p_mclk_count = PORT_MCLK_COUNT; // Used internally by sw_pll + port_t p_bclk_count = PORT_BCLK_COUNT; // Used internally by sw_pll + xclock_t ck_bclk = I2S_CLKBLK; + + port_enable(p_mclk); + port_enable(p_bclk); + // NOTE: p_lrclk does not need to be enabled by the caller + + set_pll_lock_status_ptr(&sw_pll.lock_status); + // Create clock from mclk port and use it to clock the p_mclk_count port which will count MCLKs. + port_enable(p_mclk_count); + port_enable(p_bclk_count); + + // Allow p_mclk_count to count mclks + xclock_t clk_mclk = MCLK_CLKBLK; + clock_enable(clk_mclk); + clock_set_source_port(clk_mclk, p_mclk); + port_set_clock(p_mclk_count, clk_mclk); + clock_start(clk_mclk); + + // Allow p_bclk_count to count bclks + port_set_clock(p_bclk_count, ck_bclk); + sw_pll_lut_init(&sw_pll, + SW_PLL_15Q16(0.0), + SW_PLL_15Q16(1.0), + SW_PLL_15Q16(0.0), + PLL_CONTROL_LOOP_COUNT_INT, + PLL_RATIO, + (appconfBCLK_NOMINAL_HZ / appconfLRCLK_NOMINAL_HZ), + frac_values_90, + SW_PLL_NUM_LUT_ENTRIES(frac_values_90), + APP_PLL_CTL_REG, + APP_PLL_DIV_REG, + SW_PLL_NUM_LUT_ENTRIES(frac_values_90) / 2, + PLL_PPM_RANGE); + + debug_printf("Using SW PLL to track I2S input\n"); + sw_pll_ctx->sw_pll = &sw_pll; + sw_pll_ctx->p_mclk_count = p_mclk_count; + sw_pll_ctx->p_bclk_count = p_bclk_count; + +#endif +} + +static void mics_init(void) +{ + static rtos_driver_rpc_t mic_rpc_config; +#if ON_TILE(MICARRAY_TILE_NO) + rtos_intertile_t *client_intertile_ctx[1] = {intertile_ctx}; + rtos_mic_array_init( + mic_array_ctx, + (1 << appconfPDM_MIC_IO_CORE), + RTOS_MIC_ARRAY_CHANNEL_SAMPLE); + rtos_mic_array_rpc_host_init( + mic_array_ctx, + &mic_rpc_config, + client_intertile_ctx, + 1); +#else + rtos_mic_array_rpc_client_init( + mic_array_ctx, + &mic_rpc_config, + intertile_ctx); +#endif +} + +static void i2s_init(void) +{ +#if appconfI2S_ENABLED +#if appconfI2S_MODE == appconfI2S_MODE_MASTER + static rtos_driver_rpc_t i2s_rpc_config; +#endif +#if ON_TILE(I2S_TILE_NO) +#if appconfI2S_MODE == appconfI2S_MODE_MASTER + rtos_intertile_t *client_intertile_ctx[1] = {intertile_ctx}; + port_t p_i2s_dout[1] = { + PORT_I2S_DAC_DATA + }; + port_t p_i2s_din[1] = { + PORT_I2S_ADC_DATA + }; + + rtos_i2s_master_init( + i2s_ctx, + (1 << appconfI2S_IO_CORE), + p_i2s_dout, + 1, + p_i2s_din, + 1, + PORT_I2S_BCLK, + PORT_I2S_LRCLK, + PORT_MCLK, + I2S_CLKBLK); + + + rtos_i2s_rpc_host_init( + i2s_ctx, + &i2s_rpc_config, + client_intertile_ctx, + 1); +#elif appconfI2S_MODE == appconfI2S_MODE_SLAVE + port_t p_i2s_dout[1] = { + PORT_I2S_ADC_DATA + }; + port_t p_i2s_din[1] = { + PORT_I2S_DAC_DATA + }; + rtos_i2s_slave_init( + i2s_ctx, + (1 << appconfI2S_IO_CORE), + p_i2s_dout, + 1, + p_i2s_din, + 1, + PORT_I2S_BCLK, + PORT_I2S_LRCLK, + I2S_CLKBLK); +#else + #error "Invalid I2S mode" +#endif +#else +#if appconfI2S_MODE == appconfI2S_MODE_MASTER + rtos_i2s_rpc_client_init( + i2s_ctx, + &i2s_rpc_config, + intertile_ctx); +#endif +#endif +#endif +} + +static void uart_init(void) +{ +#if ON_TILE(UART_TILE_NO) + hwtimer_t tmr_tx = hwtimer_alloc(); + + rtos_uart_tx_init( + uart_tx_ctx, + XS1_PORT_1A, /* J4:24*/ + appconfUART_BAUD_RATE, + 8, + UART_PARITY_NONE, + 1, + tmr_tx); +#endif +} + +void platform_init(chanend_t other_tile_c) +{ + rtos_intertile_init(intertile_ctx, other_tile_c); + rtos_intertile_init(intertile_ap_ctx, other_tile_c); + platform_sw_pll_init(); + mclk_init(other_tile_c); + gpio_init(); + flash_init(); + i2c_init(); + mics_init(); + i2s_init(); + uart_init(); +} diff --git a/examples/ffd/bsp_config/XK_VOICE_SQ66/platform/platform_init.h b/examples/ffd/bsp_config/XK_VOICE_SQ66/platform/platform_init.h new file mode 100644 index 000000000..3eeea9d29 --- /dev/null +++ b/examples/ffd/bsp_config/XK_VOICE_SQ66/platform/platform_init.h @@ -0,0 +1,12 @@ +// Copyright 2022-2023 XMOS LIMITED. +// This Software is subject to the terms of the XMOS Public Licence: Version 1. + +#ifndef PLATFORM_INIT_H_ +#define PLATFORM_INIT_H_ + +#include + +void platform_init(chanend_t other_tile_c); +void platform_start(void); + +#endif /* PLATFORM_INIT_H_ */ diff --git a/examples/ffd/bsp_config/XK_VOICE_SQ66/platform/platform_start.c b/examples/ffd/bsp_config/XK_VOICE_SQ66/platform/platform_start.c new file mode 100644 index 000000000..49eb98cdf --- /dev/null +++ b/examples/ffd/bsp_config/XK_VOICE_SQ66/platform/platform_start.c @@ -0,0 +1,141 @@ +// Copyright 2022-2023 XMOS LIMITED. +// This Software is subject to the terms of the XMOS Public Licence: Version 1. + +/* System headers */ +#include + +/* FreeRTOS headers */ +#include "FreeRTOS.h" + +/* Library headers */ +#include "fs_support.h" + +/* App headers */ +#include "platform_conf.h" +#include "platform/driver_instances.h" +#include "dac3101.h" +#include "i2c_reg_handling.h" + +extern asr_result_t last_asr_result; + +extern void i2s_rate_conversion_enable(void); + +static void gpio_start(void) +{ + rtos_gpio_rpc_config(gpio_ctx_t0, appconfGPIO_T0_RPC_PORT, appconfGPIO_RPC_PRIORITY); + rtos_gpio_rpc_config(gpio_ctx_t1, appconfGPIO_T1_RPC_PORT, appconfGPIO_RPC_PRIORITY); + +#if ON_TILE(0) + rtos_gpio_start(gpio_ctx_t0); +#endif +#if ON_TILE(1) + rtos_gpio_start(gpio_ctx_t1); +#endif +} + +static void flash_start(void) +{ +#if ON_TILE(FLASH_TILE_NO) + rtos_qspi_flash_start(qspi_flash_ctx, appconfQSPI_FLASH_TASK_PRIORITY); +#endif +} + +static void i2c_master_start(void) +{ +#if appconfI2C_MASTER_DAC_ENABLED || appconfINTENT_I2C_MASTER_OUTPUT_ENABLED + rtos_i2c_master_rpc_config(i2c_master_ctx, appconfI2C_MASTER_RPC_PORT, appconfI2C_MASTER_RPC_PRIORITY); + +#if ON_TILE(I2C_TILE_NO) + rtos_i2c_master_start(i2c_master_ctx); +#endif +#endif +} + +static void i2c_slave_start(void) +{ +#if appconfINTENT_I2C_SLAVE_POLLED_ENABLED && ON_TILE(I2C_TILE_NO) + rtos_i2c_slave_start(i2c_slave_ctx, + &last_asr_result, + (rtos_i2c_slave_start_cb_t) NULL, + (rtos_i2c_slave_rx_cb_t) write_device_reg, + (rtos_i2c_slave_tx_start_cb_t) read_device_reg, + (rtos_i2c_slave_tx_done_cb_t) NULL, + NULL, + NULL, + appconfI2C_INTERRUPT_CORE, + appconfI2C_TASK_PRIORITY); +#endif +} + +static void audio_codec_start(void) +{ +#if appconfI2S_ENABLED && appconfI2C_MASTER_DAC_ENABLED + int ret = 0; +#if ON_TILE(I2C_TILE_NO) + if (dac3101_init(appconfI2S_AUDIO_SAMPLE_RATE) != 0) { + rtos_printf("DAC initialization failed\n"); + } + rtos_intertile_tx(intertile_ctx, 0, &ret, sizeof(ret)); +#else + rtos_intertile_rx_len(intertile_ctx, 0, RTOS_OSAL_WAIT_FOREVER); + rtos_intertile_rx_data(intertile_ctx, &ret, sizeof(ret)); +#endif +#endif +} + +static void mics_start(void) +{ + rtos_mic_array_rpc_config(mic_array_ctx, appconfMICARRAY_RPC_PORT, appconfMICARRAY_RPC_PRIORITY); +#if ON_TILE(MICARRAY_TILE_NO) + rtos_mic_array_start( + mic_array_ctx, + 2 * MIC_ARRAY_CONFIG_SAMPLES_PER_FRAME, + appconfPDM_MIC_INTERRUPT_CORE); +#endif +} + +static void i2s_start(void) +{ +#if appconfI2S_ENABLED +#if appconfI2S_MODE == appconfI2S_MODE_MASTER + rtos_i2s_rpc_config(i2s_ctx, appconfI2S_RPC_PORT, appconfI2S_RPC_PRIORITY); +#endif +#if ON_TILE(I2S_TILE_NO) + + if (appconfI2S_AUDIO_SAMPLE_RATE == 3*appconfAUDIO_PIPELINE_SAMPLE_RATE) { + i2s_rate_conversion_enable(); + } + + rtos_i2s_start( + i2s_ctx, + rtos_i2s_mclk_bclk_ratio(appconfAUDIO_CLOCK_FREQUENCY, appconfI2S_AUDIO_SAMPLE_RATE), + I2S_MODE_I2S, + 2.2 * appconfAUDIO_PIPELINE_FRAME_ADVANCE, + 1.2 * appconfAUDIO_PIPELINE_FRAME_ADVANCE, + appconfI2S_INTERRUPT_CORE); +#endif +#endif +} + +static void uart_start(void) +{ +#if ON_TILE(UART_TILE_NO) + rtos_uart_tx_start(uart_tx_ctx); +#endif +} + +void platform_start(void) +{ + rtos_intertile_start(intertile_ctx); + rtos_intertile_start(intertile_ap_ctx); + + gpio_start(); + flash_start(); + i2c_master_start(); + audio_codec_start(); + mics_start(); + i2s_start(); + uart_start(); + // I2C slave can be started only after i2c_master_start() is completed + i2c_slave_start(); +} diff --git a/examples/ffd/bsp_config/bsp_config.cmake b/examples/ffd/bsp_config/bsp_config.cmake index 9f002d80c..d7912ab75 100644 --- a/examples/ffd/bsp_config/bsp_config.cmake +++ b/examples/ffd/bsp_config/bsp_config.cmake @@ -1,3 +1,4 @@ include(${CMAKE_CURRENT_LIST_DIR}/dac/dac.cmake) include(${CMAKE_CURRENT_LIST_DIR}/XK_VOICE_L71/XK_VOICE_L71.cmake) +include(${CMAKE_CURRENT_LIST_DIR}/XK_VOICE_SQ66/XK_VOICE_SQ66.cmake) diff --git a/examples/ffd/ffd_cyberon_sq66.cmake b/examples/ffd/ffd_cyberon_sq66.cmake new file mode 100644 index 000000000..f528a1de5 --- /dev/null +++ b/examples/ffd/ffd_cyberon_sq66.cmake @@ -0,0 +1,198 @@ +set(FFD_SRC_ROOT ${CMAKE_CURRENT_LIST_DIR}) + +set(MODEL_LANGUAGE "english_usa") +set(CYBERON_COMMAND_NET_FILE "${FFD_SRC_ROOT}/model/english_usa/Hello_XMOS_pack_WithTxt.bin.Enc.NibbleSwap") + +#********************** +# Gather Sources +#********************** +file(GLOB_RECURSE APP_SOURCES ${CMAKE_CURRENT_LIST_DIR}/src/*.c ) + + +set(APP_INCLUDES + ${CMAKE_CURRENT_LIST_DIR}/src + ${CMAKE_CURRENT_LIST_DIR}/src/gpio_ctrl + ${CMAKE_CURRENT_LIST_DIR}/src/intent_engine + ${CMAKE_CURRENT_LIST_DIR}/src/power +) +set(RTOS_CONF_INCLUDES + ${CMAKE_CURRENT_LIST_DIR}/src/rtos_conf +) + +#********************** +# QSPI Flash Layout +#********************** +set(BOOT_PARTITION_SIZE 0x100000) +set(FILESYSTEM_SIZE_KB 1024) +math(EXPR FILESYSTEM_SIZE_BYTES + "1024 * ${FILESYSTEM_SIZE_KB}" + OUTPUT_FORMAT HEXADECIMAL +) + +set(CALIBRATION_PATTERN_START_ADDRESS ${BOOT_PARTITION_SIZE}) + +math(EXPR FILESYSTEM_START_ADDRESS + "${CALIBRATION_PATTERN_START_ADDRESS} + ${LIB_QSPI_FAST_READ_DEFAULT_CAL_SIZE_BYTES}" + OUTPUT_FORMAT HEXADECIMAL +) + +math(EXPR MODEL_START_ADDRESS + "${FILESYSTEM_START_ADDRESS} + ${FILESYSTEM_SIZE_BYTES}" + OUTPUT_FORMAT HEXADECIMAL +) + +set(CALIBRATION_PATTERN_DATA_PARTITION_OFFSET 0) + +math(EXPR FILESYSTEM_DATA_PARTITION_OFFSET + "${CALIBRATION_PATTERN_DATA_PARTITION_OFFSET} + ${LIB_QSPI_FAST_READ_DEFAULT_CAL_SIZE_BYTES}" + OUTPUT_FORMAT DECIMAL +) + +math(EXPR MODEL_DATA_PARTITION_OFFSET + "${FILESYSTEM_DATA_PARTITION_OFFSET} + ${FILESYSTEM_SIZE_BYTES}" + OUTPUT_FORMAT DECIMAL +) + + +#********************** +# Flags +#********************** +set(APP_COMPILER_FLAGS + -Os + -g + -report + -fxscope + -mcmodel=large + -Wno-xcore-fptrgroup + ${CMAKE_CURRENT_LIST_DIR}/src/config.xscope +) + +set(APP_COMPILE_DEFINITIONS + configENABLE_DEBUG_PRINTF=1 + PLATFORM_USES_TILE_0=1 + PLATFORM_USES_TILE_1=1 + QSPI_FLASH_FILESYSTEM_START_ADDRESS=${FILESYSTEM_START_ADDRESS} + QSPI_FLASH_MODEL_START_ADDRESS=${MODEL_START_ADDRESS} + QSPI_FLASH_CALIBRATION_ADDRESS=${CALIBRATION_PATTERN_START_ADDRESS} + ASR_CYBERON=1 +) + +set(APP_LINK_OPTIONS + -report + -lotp3 + ${CMAKE_CURRENT_LIST_DIR}/src/config.xscope +) + +set(APP_COMMON_LINK_LIBRARIES + sln_voice::app::ffd::ap + sln_voice::app::asr::Cyberon + sln_voice::app::asr::device_memory + sln_voice::app::asr::gpio_ctrl + sln_voice::app::asr::intent_engine + sln_voice::app::asr::intent_handler + sln_voice::app::ffd::xk_voice_sq66 + lib_src + lib_sw_pll +) + +#********************** +# Tile Targets +#********************** +set(TARGET_NAME tile0_example_ffd_cyberon_sq66) +add_executable(${TARGET_NAME} EXCLUDE_FROM_ALL) +target_sources(${TARGET_NAME} PUBLIC ${APP_SOURCES}) +target_include_directories(${TARGET_NAME} PUBLIC ${APP_INCLUDES} ${RTOS_CONF_INCLUDES}) +target_compile_definitions(${TARGET_NAME} PUBLIC ${APP_COMPILE_DEFINITIONS} THIS_XCORE_TILE=0) +target_compile_options(${TARGET_NAME} PRIVATE ${APP_COMPILER_FLAGS}) +target_link_libraries(${TARGET_NAME} PUBLIC ${APP_COMMON_LINK_LIBRARIES}) +target_link_options(${TARGET_NAME} PRIVATE ${APP_LINK_OPTIONS}) +unset(TARGET_NAME) + +set(TARGET_NAME tile1_example_ffd_cyberon_sq66) +add_executable(${TARGET_NAME} EXCLUDE_FROM_ALL) +target_sources(${TARGET_NAME} PUBLIC ${APP_SOURCES}) +target_include_directories(${TARGET_NAME} PUBLIC ${APP_INCLUDES} ${RTOS_CONF_INCLUDES}) +target_compile_definitions(${TARGET_NAME} PUBLIC ${APP_COMPILE_DEFINITIONS} THIS_XCORE_TILE=1) +target_compile_options(${TARGET_NAME} PRIVATE ${APP_COMPILER_FLAGS}) +target_link_libraries(${TARGET_NAME} PUBLIC ${APP_COMMON_LINK_LIBRARIES}) +target_link_options(${TARGET_NAME} PRIVATE ${APP_LINK_OPTIONS} ) +unset(TARGET_NAME) + +#********************** +# Merge binaries +#********************** +merge_binaries(example_ffd_cyberon_sq66 tile0_example_ffd_cyberon_sq66 tile1_example_ffd_cyberon_sq66 1) + +#********************** +# Create run and debug targets +#********************** +create_run_target(example_ffd_cyberon_sq66) +create_debug_target(example_ffd_cyberon_sq66) + +#********************** +# Create data partition support targets +#********************** +set(TARGET_NAME example_ffd_cyberon_sq66) +set(DATA_PARTITION_FILE ${TARGET_NAME}_data_partition.bin) +set(MODEL_FILE ${TARGET_NAME}_model.bin) +set(FATFS_FILE ${TARGET_NAME}_fat.fs) +set(FLASH_CAL_FILE ${LIB_QSPI_FAST_READ_ROOT_PATH}/lib_qspi_fast_read/calibration_pattern_nibble_swap.bin) + +add_custom_target(${MODEL_FILE} ALL + COMMAND ${CMAKE_COMMAND} -E copy ${CYBERON_COMMAND_NET_FILE} ${MODEL_FILE} + COMMENT + "Copy Cyberon NET file" + VERBATIM +) + +create_filesystem_target( + #[[ Target ]] ${TARGET_NAME} + #[[ Input Directory ]] ${CMAKE_CURRENT_LIST_DIR}/filesystem_support/${MODEL_LANGUAGE} + #[[ Image Size ]] ${FILESYSTEM_SIZE_BYTES} +) + +add_custom_command( + OUTPUT ${DATA_PARTITION_FILE} + COMMAND ${CMAKE_COMMAND} -E rm -f ${DATA_PARTITION_FILE} + COMMAND datapartition_mkimage -v -b 1 + -i ${FLASH_CAL_FILE}:${CALIBRATION_PATTERN_DATA_PARTITION_OFFSET} ${FATFS_FILE}:${FILESYSTEM_DATA_PARTITION_OFFSET} ${MODEL_FILE}:${MODEL_DATA_PARTITION_OFFSET} + -o ${DATA_PARTITION_FILE} + DEPENDS + ${MODEL_FILE} + make_fs_${TARGET_NAME} + ${FLASH_CAL_FILE} + COMMENT + "Create data partition" + VERBATIM +) + +set(DATA_PARTITION_FILE_LIST + ${DATA_PARTITION_FILE} + ${MODEL_FILE} + ${FATFS_FILE} + ${FLASH_CAL_FILE} +) + +set(DATA_PARTITION_DEPENDS_LIST + ${DATA_PARTITION_FILE} + ${MODEL_FILE} + make_fs_${TARGET_NAME} +) + +# The list of files to copy and the dependency list for populating +# the data partition folder are identical. +create_data_partition_directory( + #[[ Target ]] ${TARGET_NAME} + #[[ Copy Files ]] "${DATA_PARTITION_FILE_LIST}" + #[[ Dependencies ]] "${DATA_PARTITION_DEPENDS_LIST}" +) + +create_flash_app_target( + #[[ Target ]] ${TARGET_NAME} + #[[ Boot Partition Size ]] ${BOOT_PARTITION_SIZE} + #[[ Data Partition Contents ]] ${DATA_PARTITION_FILE} + #[[ Dependencies ]] ${DATA_PARTITION_FILE} +) + +unset(DATA_PARTITION_FILE_LIST) +unset(DATA_PARTITION_DEPENDS_LIST) diff --git a/examples/ffd/ffd_sensory_sq66.cmake b/examples/ffd/ffd_sensory_sq66.cmake new file mode 100644 index 000000000..035cf2142 --- /dev/null +++ b/examples/ffd/ffd_sensory_sq66.cmake @@ -0,0 +1,210 @@ +set(FFD_SRC_ROOT ${CMAKE_CURRENT_LIST_DIR}) + +#**************************** +# Set Sensory model variables +# +# NOTE: Change the value of MODEL_LANGUAGE to "mandarin_mainland" for the Mandarin demo +# +#**************************** +set(MODEL_LANGUAGE "english_usa") +set(SENSORY_COMMAND_SEARCH_HEADER_FILE "${FFD_SRC_ROOT}/model/${MODEL_LANGUAGE}/command-pc62w-6.4.0-op10-prod-search.h") +set(SENSORY_COMMAND_SEARCH_SOURCE_FILE "${FFD_SRC_ROOT}/model/${MODEL_LANGUAGE}/command-pc62w-6.4.0-op10-prod-search.c") +set(SENSORY_COMMAND_NET_FILE "${FFD_SRC_ROOT}/model/${MODEL_LANGUAGE}/command-pc62w-6.4.0-op10-prod-net.bin.nibble_swapped") + +#********************** +# Gather Sources +#********************** +file(GLOB_RECURSE APP_SOURCES ${CMAKE_CURRENT_LIST_DIR}/src/*.c ) + +set(APP_SOURCES + ${APP_SOURCES} + ${SENSORY_COMMAND_SEARCH_SOURCE_FILE} +) + +set(APP_INCLUDES + ${CMAKE_CURRENT_LIST_DIR}/src + ${CMAKE_CURRENT_LIST_DIR}/src/gpio_ctrl + ${CMAKE_CURRENT_LIST_DIR}/src/intent_engine + ${CMAKE_CURRENT_LIST_DIR}/src/power +) +set(RTOS_CONF_INCLUDES + ${CMAKE_CURRENT_LIST_DIR}/src/rtos_conf +) + +#********************** +# QSPI Flash Layout +#********************** +set(BOOT_PARTITION_SIZE 0x100000) +set(FILESYSTEM_SIZE_KB 1024) +math(EXPR FILESYSTEM_SIZE_BYTES + "1024 * ${FILESYSTEM_SIZE_KB}" + OUTPUT_FORMAT HEXADECIMAL +) + +set(CALIBRATION_PATTERN_START_ADDRESS ${BOOT_PARTITION_SIZE}) + +math(EXPR FILESYSTEM_START_ADDRESS + "${CALIBRATION_PATTERN_START_ADDRESS} + ${LIB_QSPI_FAST_READ_DEFAULT_CAL_SIZE_BYTES}" + OUTPUT_FORMAT HEXADECIMAL +) + +math(EXPR MODEL_START_ADDRESS + "${FILESYSTEM_START_ADDRESS} + ${FILESYSTEM_SIZE_BYTES}" + OUTPUT_FORMAT HEXADECIMAL +) + +set(CALIBRATION_PATTERN_DATA_PARTITION_OFFSET 0) + +math(EXPR FILESYSTEM_DATA_PARTITION_OFFSET + "${CALIBRATION_PATTERN_DATA_PARTITION_OFFSET} + ${LIB_QSPI_FAST_READ_DEFAULT_CAL_SIZE_BYTES}" + OUTPUT_FORMAT DECIMAL +) + +math(EXPR MODEL_DATA_PARTITION_OFFSET + "${FILESYSTEM_DATA_PARTITION_OFFSET} + ${FILESYSTEM_SIZE_BYTES}" + OUTPUT_FORMAT DECIMAL +) + + +#********************** +# Flags +#********************** +set(APP_COMPILER_FLAGS + -Os + -g + -report + -fxscope + -mcmodel=large + -Wno-xcore-fptrgroup + ${CMAKE_CURRENT_LIST_DIR}/src/config.xscope +) + +set(APP_COMPILE_DEFINITIONS + configENABLE_DEBUG_PRINTF=1 + PLATFORM_USES_TILE_0=1 + PLATFORM_USES_TILE_1=1 + QSPI_FLASH_FILESYSTEM_START_ADDRESS=${FILESYSTEM_START_ADDRESS} + QSPI_FLASH_MODEL_START_ADDRESS=${MODEL_START_ADDRESS} + QSPI_FLASH_CALIBRATION_ADDRESS=${CALIBRATION_PATTERN_START_ADDRESS} + COMMAND_SEARCH_SOURCE_FILE="${SENSORY_COMMAND_SEARCH_SOURCE_FILE}" + ASR_SENSORY=1 +) + +set(APP_LINK_OPTIONS + -report + ${CMAKE_CURRENT_LIST_DIR}/src/config.xscope +) + +set(APP_COMMON_LINK_LIBRARIES + sln_voice::app::ffd::ap + sln_voice::app::asr::sensory + sln_voice::app::asr::device_memory + sln_voice::app::asr::gpio_ctrl + sln_voice::app::asr::intent_engine + sln_voice::app::asr::intent_handler + sln_voice::app::ffd::xk_voice_sq66 + lib_src + lib_sw_pll +) + +#********************** +# Tile Targets +#********************** +set(TARGET_NAME tile0_example_ffd_sensory_sq66) +add_executable(${TARGET_NAME} EXCLUDE_FROM_ALL) +target_sources(${TARGET_NAME} PUBLIC ${APP_SOURCES}) +target_include_directories(${TARGET_NAME} PUBLIC ${APP_INCLUDES} ${RTOS_CONF_INCLUDES}) +target_compile_definitions(${TARGET_NAME} PUBLIC ${APP_COMPILE_DEFINITIONS} THIS_XCORE_TILE=0) +target_compile_options(${TARGET_NAME} PRIVATE ${APP_COMPILER_FLAGS}) +target_link_libraries(${TARGET_NAME} PUBLIC ${APP_COMMON_LINK_LIBRARIES}) +target_link_options(${TARGET_NAME} PRIVATE ${APP_LINK_OPTIONS}) +unset(TARGET_NAME) + +set(TARGET_NAME tile1_example_ffd_sensory_sq66) +add_executable(${TARGET_NAME} EXCLUDE_FROM_ALL) +target_sources(${TARGET_NAME} PUBLIC ${APP_SOURCES}) +target_include_directories(${TARGET_NAME} PUBLIC ${APP_INCLUDES} ${RTOS_CONF_INCLUDES}) +target_compile_definitions(${TARGET_NAME} PUBLIC ${APP_COMPILE_DEFINITIONS} THIS_XCORE_TILE=1) +target_compile_options(${TARGET_NAME} PRIVATE ${APP_COMPILER_FLAGS}) +target_link_libraries(${TARGET_NAME} PUBLIC ${APP_COMMON_LINK_LIBRARIES}) +target_link_options(${TARGET_NAME} PRIVATE ${APP_LINK_OPTIONS} ) +unset(TARGET_NAME) + +#********************** +# Merge binaries +#********************** +merge_binaries(example_ffd_sensory_sq66 tile0_example_ffd_sensory_sq66 tile1_example_ffd_sensory_sq66 1) + +#********************** +# Create run and debug targets +#********************** +create_run_target(example_ffd_sensory_sq66) +create_debug_target(example_ffd_sensory_sq66) + +#********************** +# Create data partition support targets +#********************** +set(TARGET_NAME example_ffd_sensory_sq66) +set(DATA_PARTITION_FILE ${TARGET_NAME}_data_partition.bin) +set(MODEL_FILE ${TARGET_NAME}_model.bin) +set(FATFS_FILE ${TARGET_NAME}_fat.fs) +set(FLASH_CAL_FILE ${LIB_QSPI_FAST_READ_ROOT_PATH}/lib_qspi_fast_read/calibration_pattern_nibble_swap.bin) + +add_custom_target(${MODEL_FILE} ALL + COMMAND ${CMAKE_COMMAND} -E copy ${SENSORY_COMMAND_NET_FILE} ${MODEL_FILE} + COMMENT + "Copy Sensory NET file" + VERBATIM +) + +create_filesystem_target( + #[[ Target ]] ${TARGET_NAME} + #[[ Input Directory ]] ${CMAKE_CURRENT_LIST_DIR}/filesystem_support/${MODEL_LANGUAGE} + #[[ Image Size ]] ${FILESYSTEM_SIZE_BYTES} +) + +add_custom_command( + OUTPUT ${DATA_PARTITION_FILE} + COMMAND ${CMAKE_COMMAND} -E rm -f ${DATA_PARTITION_FILE} + COMMAND datapartition_mkimage -v -b 1 + -i ${FLASH_CAL_FILE}:${CALIBRATION_PATTERN_DATA_PARTITION_OFFSET} ${FATFS_FILE}:${FILESYSTEM_DATA_PARTITION_OFFSET} ${MODEL_FILE}:${MODEL_DATA_PARTITION_OFFSET} + -o ${DATA_PARTITION_FILE} + DEPENDS + ${MODEL_FILE} + make_fs_${TARGET_NAME} + ${FLASH_CAL_FILE} + COMMENT + "Create data partition" + VERBATIM +) + +set(DATA_PARTITION_FILE_LIST + ${DATA_PARTITION_FILE} + ${MODEL_FILE} + ${FATFS_FILE} + ${FLASH_CAL_FILE} +) + +set(DATA_PARTITION_DEPENDS_LIST + ${DATA_PARTITION_FILE} + ${MODEL_FILE} + make_fs_${TARGET_NAME} +) + +# The list of files to copy and the dependency list for populating +# the data partition folder are identical. +create_data_partition_directory( + #[[ Target ]] ${TARGET_NAME} + #[[ Copy Files ]] "${DATA_PARTITION_FILE_LIST}" + #[[ Dependencies ]] "${DATA_PARTITION_DEPENDS_LIST}" +) + +create_flash_app_target( + #[[ Target ]] ${TARGET_NAME} + #[[ Boot Partition Size ]] ${BOOT_PARTITION_SIZE} + #[[ Data Partition Contents ]] ${DATA_PARTITION_FILE} + #[[ Dependencies ]] ${DATA_PARTITION_FILE} +) + +unset(DATA_PARTITION_FILE_LIST) +unset(DATA_PARTITION_DEPENDS_LIST) diff --git a/examples/ffd/src/app_conf.h b/examples/ffd/src/app_conf.h index 1a0e9e58d..b57c0228c 100644 --- a/examples/ffd/src/app_conf.h +++ b/examples/ffd/src/app_conf.h @@ -10,12 +10,19 @@ #define appconfINTENT_MODEL_RUNNER_SAMPLES_PORT 3 #define appconfI2C_MASTER_RPC_PORT 4 #define appconfI2S_RPC_PORT 5 +#ifdef XK_VOICE_SQ66 + #define appconfMICARRAY_RPC_PORT 6 +#endif #define appconfINTENT_ENGINE_READY_SYNC_PORT 16 #define appconfI2S_OUTPUT_SLAVE_PORT 8 /* Application tile specifiers */ #include "platform/driver_instances.h" -#define AUDIO_PIPELINE_OUTPUT_TILE_NO MICARRAY_TILE_NO +#ifdef XK_VOICE_SQ66 + #define AUDIO_PIPELINE_OUTPUT_TILE_NO 1 +#else + #define AUDIO_PIPELINE_OUTPUT_TILE_NO MICARRAY_TILE_NO +#endif #define ASR_TILE_NO FLASH_TILE_NO #define FS_TILE_NO FLASH_TILE_NO @@ -153,12 +160,21 @@ #endif /* I/O and interrupt cores for Tile 0 */ +#ifdef XK_VOICE_SQ66 + #define appconfPDM_MIC_IO_CORE 2 /* Must be kept off core 0 with the RTOS tick ISR */ + #define appconfPDM_MIC_INTERRUPT_CORE 3 /* Must be kept off I/O cores. Best kept off core 0 with the tick ISR. */ +#endif /* I/O and interrupt cores for Tile 1 */ -#define appconfPDM_MIC_IO_CORE 1 /* Must be kept off core 0 with the RTOS tick ISR */ -#define appconfI2S_IO_CORE 2 /* Must be kept off core 0 with the RTOS tick ISR */ -#define appconfPDM_MIC_INTERRUPT_CORE 4 /* Must be kept off I/O cores. Best kept off core 0 with the tick ISR. */ -#define appconfI2S_INTERRUPT_CORE 3 /* Must be kept off I/O cores. Best kept off core 0 with the tick ISR. */ +#ifdef XK_VOICE_SQ66 + #define appconfI2S_IO_CORE 2 /* Must be kept off core 0 with the RTOS tick ISR */ + #define appconfI2S_INTERRUPT_CORE 3 /* Must be kept off I/O cores. Best kept off core 0 with the tick ISR. */ +#else + #define appconfPDM_MIC_IO_CORE 1 /* Must be kept off core 0 with the RTOS tick ISR */ + #define appconfI2S_IO_CORE 2 /* Must be kept off core 0 with the RTOS tick ISR */ + #define appconfPDM_MIC_INTERRUPT_CORE 4 /* Must be kept off I/O cores. Best kept off core 0 with the tick ISR. */ + #define appconfI2S_INTERRUPT_CORE 3 /* Must be kept off I/O cores. Best kept off core 0 with the tick ISR. */ +#endif /* Task Priorities */ #define appconfSTARTUP_TASK_PRIORITY (configMAX_PRIORITIES / 2 + 5) @@ -169,6 +185,9 @@ #define appconfI2C_MASTER_RPC_PRIORITY (configMAX_PRIORITIES / 2) #define appconfQSPI_FLASH_TASK_PRIORITY (configMAX_PRIORITIES - 1) #define appconfLED_TASK_PRIORITY (configMAX_PRIORITIES / 2 - 1) +#ifdef XK_VOICE_SQ66 + #define appconfMICARRAY_RPC_PRIORITY (configMAX_PRIORITIES / 2 - 2) +#endif #if appconfI2S_MODE==appconfI2S_MODE_SLAVE /* Software PLL settings for mclk recovery configurations */ diff --git a/modules/asr/gpio_ctrl/gpi_ctrl.h b/modules/asr/gpio_ctrl/gpi_ctrl.h index 7165edc54..7ef2b86c1 100644 --- a/modules/asr/gpio_ctrl/gpi_ctrl.h +++ b/modules/asr/gpio_ctrl/gpi_ctrl.h @@ -15,6 +15,11 @@ #define GPIO_BITMASK (BUTTON_MUTE_BITMASK | BUTTON_BTN_BITMASK | BUTTON_IP_2_BITMASK | BUTTON_IP_3_BITMASK) #define GPIO_PORT PORT_GPI +#elif XK_VOICE_SQ66 +#define BUTTON_BTN_BITMASK 0x8 +#define GPIO_BITMASK (BUTTON_BTN_BITMASK) +#define GPIO_PORT PORT_GPI_0 + #elif XCOREAI_EXPLORER #define BUTTON_MUTE_BITMASK 0x01 #define BUTTON_BTN_BITMASK 0x02 diff --git a/modules/asr/gpio_ctrl/leds.c b/modules/asr/gpio_ctrl/leds.c index 66e2b9e28..283db4f9f 100644 --- a/modules/asr/gpio_ctrl/leds.c +++ b/modules/asr/gpio_ctrl/leds.c @@ -47,6 +47,16 @@ typedef enum led_color { rtos_gpio_port_enable(gpio_ctx_t0, gpo_port); \ } +#elif XK_VOICE_SQ66 +#define LED_GREEN_MASK (1<<3) +#define LED_RED_MASK (1<<2) +#define LED_YELLOW_MASK (LED_GREEN_MASK | LED_RED_MASK) + +#define gpo_setup() { \ + gpo_port = rtos_gpio_port(PORT_GPO); \ + rtos_gpio_port_enable(gpio_ctx_t0, gpo_port); \ +} + #elif XCOREAI_EXPLORER /* LED 0 is "green" * LED 1 is "red" */ diff --git a/modules/asr/intent_handler/intent_handler.h b/modules/asr/intent_handler/intent_handler.h index 5fd3f2107..01970b3e6 100644 --- a/modules/asr/intent_handler/intent_handler.h +++ b/modules/asr/intent_handler/intent_handler.h @@ -10,6 +10,10 @@ #define GPIO_OUT_HOST_WAKEUP_PORT XS1_PORT_1D /* PORT_SPI_MOSI */ #define GPIO_IN_HOST_STATUS_PORT XS1_PORT_1P /* PORT_SPI_MISO */ +#elif XK_VOICE_SQ66 +#define GPIO_OUT_HOST_WAKEUP_PORT XS1_PORT_1D /* PORT_SPI_MOSI */ +#define GPIO_IN_HOST_STATUS_PORT XS1_PORT_1P /* PORT_SPI_MISO */ + #elif XCOREAI_EXPLORER #define GPIO_OUT_HOST_WAKEUP_PORT XS1_PORT_1M /* X0D36 */ #define GPIO_IN_HOST_STATUS_PORT XS1_PORT_1P /* X0D39 */