From bab1dd3dc0e8123c2eab7fce16ac76883f42ccff Mon Sep 17 00:00:00 2001 From: Luciano Martin Date: Fri, 26 Jul 2024 14:58:27 +0100 Subject: [PATCH 01/34] Add first I2C slave calls --- .../XK_VOICE_L71/platform/driver_instances.c | 3 +++ .../XK_VOICE_L71/platform/driver_instances.h | 3 +++ .../XK_VOICE_L71/platform/platform_conf.h | 16 +++++++++++++++ .../XK_VOICE_L71/platform/platform_init.c | 10 ++++++++++ .../XK_VOICE_L71/platform/platform_start.c | 20 ++++++++++++++++++- examples/ffd/ffd_i2s_input_cyberon.cmake | 3 +++ examples/ffd/src/app_conf.h | 12 +++++++++++ 7 files changed, 66 insertions(+), 1 deletion(-) diff --git a/examples/ffd/bsp_config/XK_VOICE_L71/platform/driver_instances.c b/examples/ffd/bsp_config/XK_VOICE_L71/platform/driver_instances.c index 4ba009e3..49c86aaf 100644 --- a/examples/ffd/bsp_config/XK_VOICE_L71/platform/driver_instances.c +++ b/examples/ffd/bsp_config/XK_VOICE_L71/platform/driver_instances.c @@ -27,6 +27,9 @@ rtos_i2c_master_t *i2c_master_ctx = &i2c_master_ctx_s; static rtos_i2s_t i2s_ctx_s; rtos_i2s_t *i2s_ctx = &i2s_ctx_s; +static rtos_i2c_slave_t i2c_slave_ctx_s; +rtos_i2c_slave_t *i2c_slave_ctx = &i2c_slave_ctx_s; + static rtos_uart_tx_t uart_tx_ctx_s; rtos_uart_tx_t *uart_tx_ctx = &uart_tx_ctx_s; diff --git a/examples/ffd/bsp_config/XK_VOICE_L71/platform/driver_instances.h b/examples/ffd/bsp_config/XK_VOICE_L71/platform/driver_instances.h index cee3b29f..ebfb3180 100644 --- a/examples/ffd/bsp_config/XK_VOICE_L71/platform/driver_instances.h +++ b/examples/ffd/bsp_config/XK_VOICE_L71/platform/driver_instances.h @@ -12,6 +12,7 @@ extern "C" { #include "rtos_qspi_flash.h" #include "rtos_gpio.h" #include "rtos_i2c_master.h" +#include "rtos_i2c_slave.h" #include "rtos_i2s.h" #include "rtos_uart_tx.h" @@ -31,6 +32,7 @@ extern "C" { /* Tile specifiers */ #define FLASH_TILE_NO 0 #define I2C_TILE_NO 0 +#define I2C_CTRL_TILE_NO I2C_TILE_NO #define MICARRAY_TILE_NO 1 #define I2S_TILE_NO 1 #define UART_TILE_NO 0 @@ -59,6 +61,7 @@ extern rtos_gpio_t *gpio_ctx_t0; extern rtos_gpio_t *gpio_ctx_t1; extern rtos_mic_array_t *mic_array_ctx; extern rtos_i2c_master_t *i2c_master_ctx; +extern rtos_i2c_slave_t *i2c_slave_ctx; extern rtos_i2s_t *i2s_ctx; extern rtos_uart_tx_t *uart_tx_ctx; diff --git a/examples/ffd/bsp_config/XK_VOICE_L71/platform/platform_conf.h b/examples/ffd/bsp_config/XK_VOICE_L71/platform/platform_conf.h index 23d382de..bd44a308 100644 --- a/examples/ffd/bsp_config/XK_VOICE_L71/platform/platform_conf.h +++ b/examples/ffd/bsp_config/XK_VOICE_L71/platform/platform_conf.h @@ -54,6 +54,14 @@ #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 */ @@ -77,6 +85,14 @@ #define appconfPIPELINE_AUDIO_SAMPLE_RATE 16000 #endif /* appconfPIPELINE_AUDIO_SAMPLE_RATE */ +/*****************************************/ +/* Other required defines */ +/*****************************************/ + +#ifndef appconf_CONTROL_I2C_DEVICE_ADDR +#define appconf_CONTROL_I2C_DEVICE_ADDR 0x42 +#endif /* appconf_CONTROL_I2C_DEVICE_ADDR*/ + /*****************************************/ /* I/O Task Priorities */ /*****************************************/ diff --git a/examples/ffd/bsp_config/XK_VOICE_L71/platform/platform_init.c b/examples/ffd/bsp_config/XK_VOICE_L71/platform/platform_init.c index e75a2d1e..fe4c8fd5 100644 --- a/examples/ffd/bsp_config/XK_VOICE_L71/platform/platform_init.c +++ b/examples/ffd/bsp_config/XK_VOICE_L71/platform/platform_init.c @@ -74,6 +74,15 @@ static void i2c_init(void) { static rtos_driver_rpc_t i2c_rpc_config; +#if appconfI2C_SLAVE_ENABLED && ON_TILE(I2C_CTRL_TILE_NO) + rtos_i2c_slave_init(i2c_slave_ctx, + (1 << appconfI2C_IO_CORE), + PORT_I2C_SCL, + PORT_I2C_SDA, + appconf_CONTROL_I2C_DEVICE_ADDR); +#endif + +#if appconfI2C_MASTER_ENABLED #if ON_TILE(I2C_TILE_NO) rtos_intertile_t *client_intertile_ctx[1] = {intertile_ctx}; rtos_i2c_master_init( @@ -94,6 +103,7 @@ static void i2c_init(void) &i2c_rpc_config, intertile_ctx); #endif +#endif } #if ON_TILE(1) && appconfRECOVER_MCLK_I2S_APP_PLL diff --git a/examples/ffd/bsp_config/XK_VOICE_L71/platform/platform_start.c b/examples/ffd/bsp_config/XK_VOICE_L71/platform/platform_start.c index f09943a7..7f2a4496 100644 --- a/examples/ffd/bsp_config/XK_VOICE_L71/platform/platform_start.c +++ b/examples/ffd/bsp_config/XK_VOICE_L71/platform/platform_start.c @@ -39,16 +39,32 @@ static void flash_start(void) static void i2c_master_start(void) { +#if appconfI2C_MASTER_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 0 //appconfI2C_SLAVE_ENABLED && ON_TILE(I2C_CTRL_TILE_NO) + rtos_i2c_slave_start(i2c_slave_ctx, + device_control_i2c_ctx, + (rtos_i2c_slave_start_cb_t) device_control_i2c_start_cb, + (rtos_i2c_slave_rx_cb_t) device_control_i2c_rx_cb, + (rtos_i2c_slave_tx_start_cb_t) device_control_i2c_tx_start_cb, + (rtos_i2c_slave_tx_done_cb_t) NULL, + appconfI2C_INTERRUPT_CORE, + appconfI2C_TASK_PRIORITY); +#endif } static void audio_codec_start(void) { -#if appconfI2S_ENABLED +#if appconfI2S_ENABLED && appconfI2C_MASTER_ENABLED int ret = 0; #if ON_TILE(I2C_TILE_NO) if (dac3101_init(appconfI2S_AUDIO_SAMPLE_RATE) != 0) { @@ -114,4 +130,6 @@ void platform_start(void) 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/ffd_i2s_input_cyberon.cmake b/examples/ffd/ffd_i2s_input_cyberon.cmake index 8ef83611..a2810afd 100644 --- a/examples/ffd/ffd_i2s_input_cyberon.cmake +++ b/examples/ffd/ffd_i2s_input_cyberon.cmake @@ -80,6 +80,9 @@ set(APP_COMPILE_DEFINITIONS appconfI2S_MODE=appconfI2S_MODE_SLAVE appconfI2S_AUDIO_SAMPLE_RATE=48000 appconfI2S_ENABLED=1 + appconfI2C_SLAVE_ENABLED=0 + appconfI2C_MASTER_ENABLED=0 + appconfINTENT_I2C_OUTPUT_ENABLED=0 appconfRECOVER_MCLK_I2S_APP_PLL=1 appconfINTENT_UART_CMD_INFO=1 appconfAUDIO_PIPELINE_SKIP_IC_AND_VNR=1 diff --git a/examples/ffd/src/app_conf.h b/examples/ffd/src/app_conf.h index 6133e0b8..fc0be1d0 100644 --- a/examples/ffd/src/app_conf.h +++ b/examples/ffd/src/app_conf.h @@ -107,6 +107,18 @@ #define appconfI2S_MODE appconfI2S_MODE_MASTER #endif +#ifndef appconfI2C_MASTER_ENABLED +#define appconfI2C_MASTER_ENABLED 1 +#endif + +#ifndef appconfI2C_SLAVE_ENABLED +#define appconfI2C_SLAVE_ENABLED 0 +#endif + +#if appconfINTENT_I2C_OUTPUT_ENABLED==1 && appconfI2C_MASTER_ENABLED==0 +#error "I2C master must be enabled for intent I2C output" +#endif + #ifndef appconfAUDIO_PIPELINE_SKIP_IC_AND_VNR #define appconfAUDIO_PIPELINE_SKIP_IC_AND_VNR 0 #endif From 8a3dccb337b2a7d7274c559ea86d25b6abb8bc2f Mon Sep 17 00:00:00 2001 From: Luciano Martin Date: Mon, 29 Jul 2024 18:26:33 +0100 Subject: [PATCH 02/34] Fix I2C defines --- examples/ffd/bsp_config/XK_VOICE_L71/platform/platform_init.c | 4 ++-- examples/ffd/ffd_i2s_input_cyberon.cmake | 2 +- examples/ffd/src/app_conf.h | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/ffd/bsp_config/XK_VOICE_L71/platform/platform_init.c b/examples/ffd/bsp_config/XK_VOICE_L71/platform/platform_init.c index fe4c8fd5..7ab6d2ea 100644 --- a/examples/ffd/bsp_config/XK_VOICE_L71/platform/platform_init.c +++ b/examples/ffd/bsp_config/XK_VOICE_L71/platform/platform_init.c @@ -72,8 +72,6 @@ static void gpio_init(void) static void i2c_init(void) { - static rtos_driver_rpc_t i2c_rpc_config; - #if appconfI2C_SLAVE_ENABLED && ON_TILE(I2C_CTRL_TILE_NO) rtos_i2c_slave_init(i2c_slave_ctx, (1 << appconfI2C_IO_CORE), @@ -83,6 +81,8 @@ static void i2c_init(void) #endif #if appconfI2C_MASTER_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( diff --git a/examples/ffd/ffd_i2s_input_cyberon.cmake b/examples/ffd/ffd_i2s_input_cyberon.cmake index a2810afd..ca14917b 100644 --- a/examples/ffd/ffd_i2s_input_cyberon.cmake +++ b/examples/ffd/ffd_i2s_input_cyberon.cmake @@ -80,7 +80,7 @@ set(APP_COMPILE_DEFINITIONS appconfI2S_MODE=appconfI2S_MODE_SLAVE appconfI2S_AUDIO_SAMPLE_RATE=48000 appconfI2S_ENABLED=1 - appconfI2C_SLAVE_ENABLED=0 + appconfI2C_SLAVE_ENABLED=1 appconfI2C_MASTER_ENABLED=0 appconfINTENT_I2C_OUTPUT_ENABLED=0 appconfRECOVER_MCLK_I2S_APP_PLL=1 diff --git a/examples/ffd/src/app_conf.h b/examples/ffd/src/app_conf.h index fc0be1d0..69480075 100644 --- a/examples/ffd/src/app_conf.h +++ b/examples/ffd/src/app_conf.h @@ -108,7 +108,7 @@ #endif #ifndef appconfI2C_MASTER_ENABLED -#define appconfI2C_MASTER_ENABLED 1 +#define appconfI2C_MASTER_ENABLED 1 #endif #ifndef appconfI2C_SLAVE_ENABLED From ae76aadbcf2f54b27df986af26150fe3698278f2 Mon Sep 17 00:00:00 2001 From: Luciano Martin Date: Mon, 29 Jul 2024 18:29:06 +0100 Subject: [PATCH 03/34] Add entry --- CHANGELOG.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 2deda70a..fc8aa04b 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -10,6 +10,8 @@ XCORE-VOICE change log intent_handler from examples/ffd/src to folder modules/asr. * CHANGED: Remove need to use external MCLK in FFVA INT examples * ADDED: Support for DFU over I2C for FFVA INT example. + * ADDED: FFD example with I2S audio input to Cyberon speech recognition + engine and model. * CHANGED: Updated submodule fwk_rtos to version 3.1.0 from 3.0.5. * ADDED: lib_sw_pll submodule v1.1.0. * REMOVED: flash settings in .xn files, as they are not required by XMOS From 91ce681e8e31ab3b545d9aea28e5bb40e87f36c4 Mon Sep 17 00:00:00 2001 From: Luciano Martin Date: Wed, 31 Jul 2024 15:29:47 +0100 Subject: [PATCH 04/34] Example with I2C control compiles --- .../XK_VOICE_L71/platform/platform_conf.h | 18 +- .../XK_VOICE_L71/platform/platform_init.c | 21 +++ .../XK_VOICE_L71/platform/platform_start.c | 11 +- examples/ffd/ffd_i2s_input_cyberon.cmake | 3 + examples/ffd/src/app_conf.h | 1 + examples/ffd/src/control/cmd_map.h | 39 ++++ examples/ffd/src/control/intent_servicer.c | 125 +++++++++++++ examples/ffd/src/control/intent_servicer.h | 53 ++++++ examples/ffd/src/control/servicer.c | 169 ++++++++++++++++++ examples/ffd/src/control/servicer.h | 124 +++++++++++++ examples/ffd/src/main.c | 15 +- examples/ffd/src/tusb_config.h | 136 ++++++++++++++ .../platform/platform_start.c | 1 - .../XK_VOICE_L71/platform/platform_conf.h | 4 +- modules/asr/Cyberon/DSpotter_asr.c | 8 +- modules/asr/asr.h | 8 + 16 files changed, 721 insertions(+), 15 deletions(-) create mode 100644 examples/ffd/src/control/cmd_map.h create mode 100644 examples/ffd/src/control/intent_servicer.c create mode 100644 examples/ffd/src/control/intent_servicer.h create mode 100644 examples/ffd/src/control/servicer.c create mode 100644 examples/ffd/src/control/servicer.h create mode 100644 examples/ffd/src/tusb_config.h diff --git a/examples/ffd/bsp_config/XK_VOICE_L71/platform/platform_conf.h b/examples/ffd/bsp_config/XK_VOICE_L71/platform/platform_conf.h index bd44a308..525ab376 100644 --- a/examples/ffd/bsp_config/XK_VOICE_L71/platform/platform_conf.h +++ b/examples/ffd/bsp_config/XK_VOICE_L71/platform/platform_conf.h @@ -89,6 +89,14 @@ /* Other required defines */ /*****************************************/ +#ifndef APP_CONTROL_TRANSPORT_COUNT +#define APP_CONTROL_TRANSPORT_COUNT appconfI2C_SLAVE_ENABLED +#endif // APP_CONTROL_TRANSPORT_COUNT + +#ifndef appconf_CONTROL_I2C_DEVICE_ADDR +#define appconf_CONTROL_I2C_DEVICE_ADDR 0x42 +#endif /* appconf_CONTROL_I2C_DEVICE_ADDR*/ + #ifndef appconf_CONTROL_I2C_DEVICE_ADDR #define appconf_CONTROL_I2C_DEVICE_ADDR 0x42 #endif /* appconf_CONTROL_I2C_DEVICE_ADDR*/ @@ -97,7 +105,15 @@ /* I/O Task Priorities */ /*****************************************/ #ifndef appconfQSPI_FLASH_TASK_PRIORITY -#define appconfQSPI_FLASH_TASK_PRIORITY ( configMAX_PRIORITIES - 1 ) +#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 */ + +#ifndef appconfDEVICE_CONTROL_I2C_PRIORITY +#define appconfDEVICE_CONTROL_I2C_PRIORITY (configMAX_PRIORITIES-1) +#endif // appconfDEVICE_CONTROL_I2C_PRIORITY + #endif /* PLATFORM_CONF_H_ */ diff --git a/examples/ffd/bsp_config/XK_VOICE_L71/platform/platform_init.c b/examples/ffd/bsp_config/XK_VOICE_L71/platform/platform_init.c index 7ab6d2ea..8b4fa525 100644 --- a/examples/ffd/bsp_config/XK_VOICE_L71/platform/platform_init.c +++ b/examples/ffd/bsp_config/XK_VOICE_L71/platform/platform_init.c @@ -9,6 +9,10 @@ #include "platform/app_pll_ctrl.h" #include "platform/driver_instances.h" #include "platform/platform_init.h" +#include "device_control.h" +#include "servicer.h" + +extern device_control_t *device_control_i2c_ctx; static void mclk_init(chanend_t other_tile_c) { @@ -255,6 +259,22 @@ static void uart_init(void) #endif } +void control_init() { +#if appconfI2C_SLAVE+ENABLED == 1 && ON_TILE(I2C_TILE_NO) + control_ret_t ret = CONTROL_SUCCESS; + ret = device_control_init(device_control_i2c_ctx, + DEVICE_CONTROL_HOST_MODE, + (NUM_TILE_0_SERVICERS + NUM_TILE_1_SERVICERS), + NULL, 0); + xassert(ret == CONTROL_SUCCESS); + + ret = device_control_start(device_control_i2c_ctx, + -1, + -1); + xassert(ret == CONTROL_SUCCESS); +#endif +} + void platform_init(chanend_t other_tile_c) { rtos_intertile_init(intertile_ctx, other_tile_c); @@ -267,4 +287,5 @@ void platform_init(chanend_t other_tile_c) mics_init(); i2s_init(); uart_init(); + control_init(); } diff --git a/examples/ffd/bsp_config/XK_VOICE_L71/platform/platform_start.c b/examples/ffd/bsp_config/XK_VOICE_L71/platform/platform_start.c index 7f2a4496..3855b5d4 100644 --- a/examples/ffd/bsp_config/XK_VOICE_L71/platform/platform_start.c +++ b/examples/ffd/bsp_config/XK_VOICE_L71/platform/platform_start.c @@ -15,6 +15,11 @@ #include "platform/driver_instances.h" #include "dac3101.h" +#if appconfI2C_SLAVE_ENABLED == 1 +#include "servicer.h" +#include "device_control_i2c.h" +#endif + extern void i2s_rate_conversion_enable(void); static void gpio_start(void) @@ -39,7 +44,7 @@ static void flash_start(void) static void i2c_master_start(void) { -#if appconfI2C_MASTER_ENABLED +#if appconfI2C_ENABLED == 1 && appconfI2C_MODE == appconfI2C_MODE_MASTER rtos_i2c_master_rpc_config(i2c_master_ctx, appconfI2C_MASTER_RPC_PORT, appconfI2C_MASTER_RPC_PRIORITY); #if ON_TILE(I2C_TILE_NO) @@ -50,13 +55,15 @@ static void i2c_master_start(void) static void i2c_slave_start(void) { -#if 0 //appconfI2C_SLAVE_ENABLED && ON_TILE(I2C_CTRL_TILE_NO) +#if appconfI2C_SLAVE_ENABLED == 1 && ON_TILE(I2C_CTRL_TILE_NO) rtos_i2c_slave_start(i2c_slave_ctx, device_control_i2c_ctx, (rtos_i2c_slave_start_cb_t) device_control_i2c_start_cb, (rtos_i2c_slave_rx_cb_t) device_control_i2c_rx_cb, (rtos_i2c_slave_tx_start_cb_t) device_control_i2c_tx_start_cb, (rtos_i2c_slave_tx_done_cb_t) NULL, + NULL, + NULL, appconfI2C_INTERRUPT_CORE, appconfI2C_TASK_PRIORITY); #endif diff --git a/examples/ffd/ffd_i2s_input_cyberon.cmake b/examples/ffd/ffd_i2s_input_cyberon.cmake index 55bb079b..eef54a63 100644 --- a/examples/ffd/ffd_i2s_input_cyberon.cmake +++ b/examples/ffd/ffd_i2s_input_cyberon.cmake @@ -11,6 +11,7 @@ file(GLOB_RECURSE APP_SOURCES ${CMAKE_CURRENT_LIST_DIR}/src/*.c ) set(APP_INCLUDES ${CMAKE_CURRENT_LIST_DIR}/src + ${CMAKE_CURRENT_LIST_DIR}/src/control ${CMAKE_CURRENT_LIST_DIR}/src/gpio_ctrl ${CMAKE_CURRENT_LIST_DIR}/src/intent_engine ${CMAKE_CURRENT_LIST_DIR}/src/power @@ -104,6 +105,8 @@ set(APP_COMMON_LINK_LIBRARIES sln_voice::app::asr::intent_engine sln_voice::app::asr::intent_handler sln_voice::app::ffd::xk_voice_l71 + rtos::sw_services::device_control + rtos::freertos_usb lib_src lib_sw_pll ) diff --git a/examples/ffd/src/app_conf.h b/examples/ffd/src/app_conf.h index a3f2079b..82af6bd3 100644 --- a/examples/ffd/src/app_conf.h +++ b/examples/ffd/src/app_conf.h @@ -10,6 +10,7 @@ #define appconfINTENT_MODEL_RUNNER_SAMPLES_PORT 3 #define appconfI2C_MASTER_RPC_PORT 4 #define appconfI2S_RPC_PORT 5 +#define appconfDEVICE_CONTROL_I2C_PORT 6 #define appconfINTENT_ENGINE_READY_SYNC_PORT 16 #define appconfI2S_OUTPUT_SLAVE_PORT 8 diff --git a/examples/ffd/src/control/cmd_map.h b/examples/ffd/src/control/cmd_map.h new file mode 100644 index 00000000..71467e20 --- /dev/null +++ b/examples/ffd/src/control/cmd_map.h @@ -0,0 +1,39 @@ +// Copyright 2022-2024 XMOS LIMITED. +// This Software is subject to the terms of the XMOS Public Licence: Version 1. + +#pragma once + +#include +#include "device_control_shared.h" + +// Types of commands in the Command ID enum space - +// - Dedicated: Commands dedicated only for the resource +// - For SHF this is further spilt into dedicated SHF commands and dedicated custom commands +// - Shared: Commands shared between a resource and its servicer. These are present in the servicer's command map only though respources process them as well. (Used for special commands protocol) +// - External: space reserved for customers to add commands. +#define DEDICATED_COMMANDS_START_OFFSET (0) +#define SHARED_COMMANDS_START_OFFSET (90) +#define EXTERNAL_COMMANDS_START_OFFSET (110) +// Servicers will have commands in the above 4 categories. +// Resources will have commands in the dedicated, reserved and broadcast categories. + + +typedef enum +{ + CMD_READ_ONLY, + CMD_READ_WRITE, + CMD_WRITE_ONLY +}cmd_rw_type_t; + +typedef struct +{ + uint8_t cmd_id; + uint8_t num_vals; + uint8_t bytes_per_val; + uint8_t cmd_rw_type; +}control_cmd_info_t; + +typedef struct { + int32_t num_commands; + control_cmd_info_t *commands; +}command_map_t; diff --git a/examples/ffd/src/control/intent_servicer.c b/examples/ffd/src/control/intent_servicer.c new file mode 100644 index 00000000..6b2e022e --- /dev/null +++ b/examples/ffd/src/control/intent_servicer.c @@ -0,0 +1,125 @@ +// Copyright 2024 XMOS LIMITED. +// This Software is subject to the terms of the XMOS Public Licence: Version 1. +#define DEBUG_UNIT INTENT_SERVICER +#ifndef DEBUG_PRINT_ENABLE_INTENT_SERVICER +#define DEBUG_PRINT_ENABLE_INTENT_SERVICER 0 +#endif +#include "debug_print.h" + +#include +#include +#include +#include + +#include "platform/platform_conf.h" +#include "servicer.h" +#include "intent_servicer.h" + +#include "device_control_i2c.h" + +enum e_intent_controller_servicer_resid_cmds +{ +#ifndef INTENT_CONTROLLER_SERVICER_RESID_LAST_DETECTION + INTENT_CONTROLLER_SERVICER_RESID_LAST_DETECTION = 0, +#endif + NUM_INTENT_CONTROLLER_SERVICER_RESID_CMDS +}; +static control_cmd_info_t intent_controller_servicer_resid_cmd_map[] = +{ + { INTENT_CONTROLLER_SERVICER_RESID_LAST_DETECTION, 1, sizeof(uint8_t), CMD_READ_ONLY }, +}; + +void intent_servicer_init(servicer_t *servicer) +{ + // Servicer resource info + static control_resource_info_t intent_res_info[NUM_RESOURCES_INTENT_SERVICER]; + + memset(servicer, 0, sizeof(servicer_t)); + servicer->id = INTENT_CONTROLLER_SERVICER_RESID; + servicer->start_io = 0; + servicer->num_resources = NUM_RESOURCES_INTENT_SERVICER; + + servicer->res_info = &intent_res_info[0]; + // Servicer resource + servicer->res_info[0].resource = INTENT_CONTROLLER_SERVICER_RESID; + servicer->res_info[0].command_map.num_commands = NUM_INTENT_CONTROLLER_SERVICER_RESID_CMDS; + servicer->res_info[0].command_map.commands = intent_controller_servicer_resid_cmd_map; +} + +void intent_servicer(void *args) { + device_control_servicer_t servicer_ctx; + + servicer_t *servicer = (servicer_t*)args; + xassert(servicer != NULL); + + control_resid_t *resources = (control_resid_t*)pvPortMalloc(servicer->num_resources * sizeof(control_resid_t)); + for(int i=0; inum_resources; i++) + { + resources[i] = servicer->res_info[i].resource; + } + + control_ret_t dc_ret; + debug_printf("Calling device_control_servicer_register(), servicer ID %d, on tile %d, core %d.\n", servicer->id, THIS_XCORE_TILE, rtos_core_id_get()); + + dc_ret = device_control_servicer_register(&servicer_ctx, + device_control_ctxs, + 1, + resources, servicer->num_resources); + debug_printf("Out of device_control_servicer_register(), servicer ID %d, on tile %d. servicer_ctx address = 0x%x\n", servicer->id, THIS_XCORE_TILE, &servicer_ctx); + + vPortFree(resources); + + for(;;){ + device_control_servicer_cmd_recv(&servicer_ctx, read_cmd, write_cmd, servicer, RTOS_OSAL_WAIT_FOREVER); + } +} + +control_ret_t intent_servicer_read_cmd(control_resource_info_t *res_info, control_cmd_t cmd, uint8_t *payload, size_t payload_len) +{ + control_ret_t ret = CONTROL_SUCCESS; + uint8_t cmd_id = CONTROL_CMD_CLEAR_READ(cmd); + + memset(payload, 0, payload_len); + + debug_printf("intent_servicer_read_cmd, cmd_id: %d.\n", cmd_id); + + switch (cmd_id) + { + case INTENT_CONTROLLER_SERVICER_RESID_LAST_DETECTION: + { + debug_printf("INTENT_CONTROLLER_SERVICER_RESID_LAST_DETECTION\n"); + uint8_t last_detection = 0;//intent_get_last_detection(); + payload[0] = last_detection; + break; + } + + default: + { + debug_printf("INTENT_CONTROLLER_SERVICER UNHANDLED COMMAND!!!\n"); + ret = CONTROL_BAD_COMMAND; + break; + } + + } + return ret; +} + +control_ret_t intent_servicer_write_cmd(control_resource_info_t *res_info, control_cmd_t cmd, const uint8_t *payload, size_t payload_len) +{ + control_ret_t ret = CONTROL_SUCCESS; + + uint8_t cmd_id = CONTROL_CMD_CLEAR_READ(cmd); + debug_printf("intent_servicer_write_cmd cmd_id %d.\n", cmd_id); + + switch (cmd_id) + { + + // Add the handling of the write commands here + default: + debug_printf("INTENT_CONTROLLER_SERVICER UNHANDLED COMMAND!!!\n"); + ret = CONTROL_BAD_COMMAND; + break; + } + + return ret; +} diff --git a/examples/ffd/src/control/intent_servicer.h b/examples/ffd/src/control/intent_servicer.h new file mode 100644 index 00000000..cb1cba99 --- /dev/null +++ b/examples/ffd/src/control/intent_servicer.h @@ -0,0 +1,53 @@ +// Copyright 2024 XMOS LIMITED. +// This Software is subject to the terms of the XMOS Public Licence: Version 1. +#pragma once + +#include "servicer.h" + +#define INTENT_CONTROLLER_SERVICER_RESID (1) +#define NUM_RESOURCES_INTENT_SERVICER (1) // DFU servicer + +/** + * @brief DFU servicer task. + * + * This task handles DFU commands from the device control interface and relays + * them to the internal DFU INT state machine. + * + * \param args Pointer to the Servicer's state data structure + */ +void intent_servicer(void *args); + +// Servicer initialization functions +/** + * @brief DFU servicer initialisation function. + * \param servicer Pointer to the Servicer's state data structure + */ +void intent_servicer_init(servicer_t *servicer); + +/** + * @brief DFU servicer read command handler + * + * Handles read commands dedicated to the DFU servicer resource + * + * @param res_info Resource info of the current command + * @param cmd Command ID of this command + * @param payload Pointer to the payload that contains the write data + * @param payload_len Length in bytes of the write command payload + * @return control_ret_t CONTROL_SUCCESS if command handled successfully, + * otherwise control_ret_t error status indicating the error. + */ +control_ret_t intent_servicer_read_cmd(control_resource_info_t *res_info, control_cmd_t cmd, uint8_t *payload, size_t payload_len); + +/** + * @brief DFU servicer write command handler + * + * Handles write commands dedicated to the DFU servicer resource + * + * @param res_info Resource info of the current command + * @param cmd Command ID of this command + * @param payload Pointer to the payload that contains the write data + * @param payload_len Length in bytes of the write command payload + * @return control_ret_t CONTROL_SUCCESS if command handled successfully, + * otherwise control_ret_t error status indicating the error. + */ +control_ret_t intent_servicer_write_cmd(control_resource_info_t *res_info, control_cmd_t cmd, const uint8_t *payload, size_t payload_len); \ No newline at end of file diff --git a/examples/ffd/src/control/servicer.c b/examples/ffd/src/control/servicer.c new file mode 100644 index 00000000..9d9a39ab --- /dev/null +++ b/examples/ffd/src/control/servicer.c @@ -0,0 +1,169 @@ +// Copyright 2024 XMOS LIMITED. +// This Software is subject to the terms of the XMOS Public Licence: Version 1. +#define DEBUG_UNIT SERVICER_TASK +#ifndef DEBUG_PRINT_ENABLE_SERVICER_TASK + #define DEBUG_PRINT_ENABLE_SERVICER_TASK 0 +#endif +#include "debug_print.h" +#include +#include +#include "platform/platform_conf.h" +#include "device_control_i2c.h" +#include "servicer.h" +#include "intent_servicer.h" + +#if appconfI2C_SLAVE_ENABLED == 1 && ON_TILE(I2C_CTRL_TILE_NO) + +static device_control_t device_control_i2c_ctx_s; +device_control_t *device_control_i2c_ctx = (device_control_t *) &device_control_i2c_ctx_s; +device_control_t *device_control_ctxs[APP_CONTROL_TRANSPORT_COUNT] = { + (device_control_t *) &device_control_i2c_ctx_s, +}; +#endif + +//-----------------Servicer read write callback functions-----------------------// +DEVICE_CONTROL_CALLBACK_ATTR +control_ret_t read_cmd(control_resid_t resid, control_cmd_t cmd, uint8_t *payload, size_t payload_len, void *app_data) +{ + control_ret_t ret = CONTROL_SUCCESS; + servicer_t *servicer = (servicer_t*)app_data; + + // For read commands, payload[0] is reserved from status. So payload_len is one more than the payload_len stored in the resource command map + payload_len -= 1; + uint8_t *payload_ptr = &payload[1]; //Excluding the status byte, which is updated later. + + debug_printf("Servicer ID %d on tile %d received READ command %02x for resid %02x\n\t",servicer->id, THIS_XCORE_TILE, cmd, resid); + debug_printf("The command is requesting %d bytes\n\t", payload_len); + + + control_resource_info_t *current_res_info = get_res_info(resid, servicer); + xassert(current_res_info != NULL); // This should never happen + control_cmd_info_t *current_cmd_info; + ret = validate_cmd(¤t_cmd_info, current_res_info, cmd, payload_ptr, payload_len); + if(ret != CONTROL_SUCCESS) + { + payload[0] = ret; // Update status in byte 0 + return ret; + } + // Check if command is for the servicer itself + if(current_res_info->resource == servicer->res_info[0].resource) + { + ret = servicer_read_cmd(current_res_info, cmd, payload_ptr, payload_len); + payload[0] = ret; + return ret; + } + return CONTROL_ERROR; +} + +DEVICE_CONTROL_CALLBACK_ATTR +control_ret_t write_cmd(control_resid_t resid, control_cmd_t cmd, const uint8_t *payload, size_t payload_len, void *app_data) +{ + control_ret_t ret = CONTROL_SUCCESS; + servicer_t *servicer = (servicer_t*)app_data; + //debug_printf("Device control WRITE. Servicer ID %d\n\t", servicer->id); + + debug_printf("Servicer ID %d on tile %d received WRITE command %02x for resid %02x\n\t", servicer->id, THIS_XCORE_TILE, cmd, resid); + debug_printf("The command has %d bytes\n\t", payload_len); + + control_resource_info_t *current_res_info = get_res_info(resid, servicer); + xassert(current_res_info != NULL); + control_cmd_info_t *current_cmd_info; + ret = validate_cmd(¤t_cmd_info, current_res_info, cmd, payload, payload_len); + if(ret != CONTROL_SUCCESS) + { + return ret; + } + // Check if command is for the servicer itself + if(current_res_info->resource == servicer->res_info[0].resource) + { + ret = servicer_write_cmd(current_res_info, cmd, payload, payload_len); + return ret; + } + return CONTROL_ERROR; +} + +// Initialise packet payload pointers to point to valid memory. + + +//-----------------Servicer helper functions-----------------------// +// Return a pointer to the control_cmd_info_t structure for a given command ID. Return NULL if command not found in the +// command map for the resource. +control_cmd_info_t* get_cmd_info(uint8_t cmd_id, const control_resource_info_t *res_info) +{ + for(int i=0; icommand_map.num_commands; i++) + { + if(res_info->command_map.commands[i].cmd_id == cmd_id) + { + return &res_info->command_map.commands[i]; + } + } + return NULL; +} + +// Return a pointer to the servicer's control_resource_info_t structure for a given resource ID. +// Return NULL if the resource ID is not found in the list of resources serviced by the servicer. +control_resource_info_t* get_res_info(control_resid_t resource, const servicer_t *servicer) +{ + for(int res=0; resnum_resources; res++) + { + // Get the cmd_info for the current command + if(servicer->res_info[res].resource == resource) + { + return &servicer->res_info[res]; + } + } + return NULL; +} + +// Validate the command from the host against that commands information in the stored command_map +control_ret_t validate_cmd(control_cmd_info_t **cmd_info, + control_resource_info_t *res_info, + control_cmd_t cmd, + const uint8_t *payload, + size_t payload_len) +{ + control_ret_t ret = CONTROL_SUCCESS; + *cmd_info = get_cmd_info(CONTROL_CMD_CLEAR_READ(cmd), res_info); + if(*cmd_info == NULL) + { + return SERVICER_WRONG_COMMAND_ID; + } + + // Validate non special command length + // Don't do payload check for special commands since for the last filter chunk, host might request less than the payload length specified in the cmd_map + + if(payload_len != (*cmd_info)->bytes_per_val * (*cmd_info)->num_vals) + { + return SERVICER_WRONG_COMMAND_LEN; + } + // Payload validation happens either on the host or in the specific command handlers. No generic payload validation is done in the servicer. + + return ret; +} + +// Process write commands directed to the servicer resource +control_ret_t servicer_write_cmd(control_resource_info_t *res_info, control_cmd_t cmd, const uint8_t *payload, size_t payload_len) +{ + // Handle write commands directed to a servicer resource + switch(res_info->resource) + { + case INTENT_CONTROLLER_SERVICER_RESID: + return intent_servicer_write_cmd(res_info, cmd, payload, payload_len); + break; + } + return CONTROL_SUCCESS; +} + +// Process read commands directed to the servicer resource +control_ret_t servicer_read_cmd(control_resource_info_t *res_info, control_cmd_t cmd, uint8_t *payload, size_t payload_len) +{ + control_ret_t ret = CONTROL_SUCCESS; + // Handle read commands directed to a servicer resource + switch(res_info->resource) + { + case INTENT_CONTROLLER_SERVICER_RESID: + ret = intent_servicer_read_cmd(res_info, cmd, payload, payload_len); + break; + } + return ret; +} diff --git a/examples/ffd/src/control/servicer.h b/examples/ffd/src/control/servicer.h new file mode 100644 index 00000000..8e979b27 --- /dev/null +++ b/examples/ffd/src/control/servicer.h @@ -0,0 +1,124 @@ +// Copyright 2024 XMOS LIMITED. +// This Software is subject to the terms of the XMOS Public Licence: Version 1. +#pragma once +#include "device_control.h" +#include "cmd_map.h" + +#define NUM_TILE_0_SERVICERS (1) // only intent servicer is used +#define NUM_TILE_1_SERVICERS (0) // no control servicer + +extern device_control_t *device_control_i2c_ctx; +extern device_control_t *device_control_ctxs[1]; + +/** + * Clears the read bit on a command code + * + * \param[in,out] c The command code to clear the read bit on. + */ +#define CONTROL_CMD_CLEAR_READ(c) ((c) & ~0x80) + +// Structure encapsulating all the information about a resource +typedef struct +{ + control_resid_t resource; + command_map_t command_map; +}control_resource_info_t; + +typedef struct { + uint32_t start_io; // set to 1 on one servicer per tile to make it responsible for starting the IO tasks on that tile. + int32_t id; // Unique ID for the servicer. Used for debugging. + // Num resources + int32_t num_resources; + // Resource ID and command map for every resource + control_resource_info_t *res_info; +}servicer_t; + +// Servicer device_control callback functions +/** + * @brief Device control callback function to handle a read command. + * + * @param resid Resource ID of the command + * @param cmd Command ID of the command + * @param payload Pointer to the payload buffer that needs to be updated with the read command response. + * @param payload_len Length of the payload buffer + * @param app_data Application specific data. + * @return CONTROL_SUCCESS is command is handled successfully, + * otherwise control_ret_t error status indicating the error. + */ +extern DEVICE_CONTROL_CALLBACK_ATTR +control_ret_t read_cmd(control_resid_t resid, control_cmd_t cmd, uint8_t *payload, size_t payload_len, void *app_data); + +/** + * @brief Device control callback function to handle a write command + * + * @param resid Resource ID of the command + * @param cmd Command ID of the command + * @param payload Pointer to the payload buffer containing the payload the host wants to write to the device. + * @param payload_len Length of the payload buffer + * @param app_data Application specific data + * @return CONTROL_SUCCESS is command is handled successfully, + * otherwise control_ret_t error status indicating the error. + */ +extern DEVICE_CONTROL_CALLBACK_ATTR +control_ret_t write_cmd(control_resid_t resid, control_cmd_t cmd, const uint8_t *payload, size_t payload_len, void *app_data); + +// Servicer helper functions +/** + * @brief Check if a command exists in the command map for a given resource and return the pointer to the cmd info object for the given command + * + * @param cmd_id Command ID for which the control_cmd_info_t object is required. + * @param res_info Pointer to the resource info which contains all the command info objects for a given resource. + * @return Pointer to a control_cmd_info_t object when one is found for the given Command ID, NULL otherwise. + */ +control_cmd_info_t* get_cmd_info(uint8_t cmd_id, const control_resource_info_t *res_info); + +/** + * @brief Check if a resource ID is one of the resources supported by a servicer and return a pointer to the resource info object. + * + * @param resource Resource ID that needs to be checked. + * @param servicer Pointer to the servicer state structure that holds all the resource info objects for the servicer. + * @return Pointer to the resource_info_t object when one is found for a given resource ID, NULL otherwise. + */ +control_resource_info_t* get_res_info(control_resid_t resource, const servicer_t *servicer); + +/** + * @brief Validate the command received in the servicer and return a pointer to the command info if the command is valid. + * + * All checks related to the command such as command ID being valid, correctness of the payload length, + * validation of the actual payload for write commands are done in this function. + * + * @param cmd_info Pointer in which the address of the command info is returned if this is a valid command/ + * @param res_info Resource info of the resource the command is meant for. + * @param cmd Command ID of the command that needs validating + * @param payload Payload buffer of the command that needs validating. + * @param payload_len Payload length of the payload. + * @return CONTROL_SUCCESS if the command is found to be valid for the given resource. control_ret_t error otherwise + * indicating the error code of the specific validation check that failed. + */ +control_ret_t validate_cmd(control_cmd_info_t **cmd_info, + control_resource_info_t *res_info, + control_cmd_t cmd, + const uint8_t *payload, + size_t payload_len); + +/** + * @brief Function for handling write commands directed to the servicer resource itself. + * + * @param resid Command Resource ID + * @param cmd Command Command ID + * @param payload Command write payload buffer + * @param payload_len Length of the payload buffer + * @return CONTROL_SUCCESS if write command processed successfully. contro_ret_t error status otherwise. + */ +control_ret_t servicer_write_cmd(control_resource_info_t *res_info, control_cmd_t cmd, const uint8_t *payload, size_t payload_len); + +/** + * @brief Function for handling read commands directed to the servicer resource itself. + * + * @param resid Command Resource ID + * @param cmd Command Command ID + * @param payload Payload buffer to populate with the read response + * @param payload_len Length of the payload buffer + * @return CONTROL_SUCCESS if read command processed successfully. contro_ret_t error status otherwise. + */ +control_ret_t servicer_read_cmd(control_resource_info_t *res_info, control_cmd_t cmd, uint8_t *payload, size_t payload_len); diff --git a/examples/ffd/src/main.c b/examples/ffd/src/main.c index 780782b4..8addca03 100644 --- a/examples/ffd/src/main.c +++ b/examples/ffd/src/main.c @@ -30,6 +30,9 @@ #include "gpio_ctrl/gpi_ctrl.h" #include "gpio_ctrl/leds.h" #include "intent_handler/intent_handler.h" +#if appconfI2C_SLAVE_ENABLED == 1 +#include "intent_servicer.h" +#endif #if appconfRECOVER_MCLK_I2S_APP_PLL /* Config headers for sw_pll */ @@ -91,7 +94,7 @@ void audio_pipeline_input(void *input_app_data, size_t frame_count) { (void) input_app_data; - + #if !appconfUSE_I2S_INPUT static int flushed; while (!flushed) { @@ -125,8 +128,8 @@ void audio_pipeline_input(void *input_app_data, (int32_t *) tmp, frame_count, portMAX_DELAY); - - + + for (int i=0; i +#include "app_conf.h" +#include "audio_pipeline.h" +#include "rtos_printf.h" + +#define appconfUSB_INTERRUPT_CORE 2 /* Must be kept off I/O cores. Best kept off core 0 with the tick ISR. */ +#define appconfUSB_SOF_INTERRUPT_CORE 3 /* Must be kept off I/O cores. Best kept off cores with other ISRs. */ +#define appconfXUD_IO_CORE 1 /* Must be kept off core 0 with the RTOS tick ISR */ +#define appconfUSB_AUDIO_SAMPLE_RATE 48000 + +//-------------------------------------------------------------------- +// COMMON CONFIGURATION +//-------------------------------------------------------------------- + +#define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | OPT_MODE_HIGH_SPEED) +#define CFG_TUSB_OS OPT_OS_CUSTOM + +#ifndef CFG_TUSB_DEBUG +#define CFG_TUSB_DEBUG 0 +#endif + +#define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(8))) + +#ifndef CFG_TUSB_DEBUG_PRINTF +#ifdef rtos_printf +#define CFG_TUSB_DEBUG_PRINTF rtos_printf +#endif +#endif + +//-------------------------------------------------------------------- +// DEVICE CONFIGURATION +//-------------------------------------------------------------------- + +#define CFG_TUD_EP_MAX 12 +#define CFG_TUD_TASK_QUEUE_SZ 8 +#define CFG_TUD_ENDPOINT0_SIZE 64 + +#define CFG_TUD_XCORE_INTERRUPT_CORE appconfUSB_INTERRUPT_CORE +#define CFG_TUD_XCORE_SOF_INTERRUPT_CORE appconfUSB_SOF_INTERRUPT_CORE +#define CFG_TUD_XCORE_IO_CORE_MASK (1 << appconfXUD_IO_CORE) + +//------------- CLASS -------------// +#define CFG_TUD_CDC 0 +#define CFG_TUD_MSC 0 +#define CFG_TUD_HID 0 +#define CFG_TUD_MIDI 0 +#define CFG_TUD_AUDIO 1 +#define CFG_TUD_VENDOR 0 +#define CFG_TUD_DFU 1 + +//-------------------------------------------------------------------- +// DFU DRIVER CONFIGURATION +//-------------------------------------------------------------------- +// DFU buffer size, it has to be set to the buffer size used in TUD_DFU_DESCRIPTOR +#define CFG_TUD_DFU_XFER_BUFSIZE 4096 + +//-------------------------------------------------------------------- +// AUDIO CLASS DRIVER CONFIGURATION +//-------------------------------------------------------------------- +extern const uint16_t tud_audio_desc_lengths[CFG_TUD_AUDIO]; + +#define CFG_TUD_AUDIO_FUNC_1_DESC_LEN tud_audio_desc_lengths[0] +#define CFG_TUD_AUDIO_FUNC_1_N_AS_INT 1 +#define CFG_TUD_AUDIO_FUNC_1_CTRL_BUF_SZ 64 + +/* TODO make these configurable in app_conf? */ +#define CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX 2 +#define CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_RX 2 + +#if appconfUSB_AUDIO_MODE == appconfUSB_AUDIO_RELEASE +#define CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX 2 +#define CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX 2 +#else +#define CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX 6 +#define CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX 4 +#endif + +#if (appconfMIC_SRC_DEFAULT == appconfMIC_SRC_USB) +// In appconfMIC_SRC_USB, we wait forever for input mic and AEC reference channels +// will not overflow output +#define USB_AUDIO_RECV_DELAY portMAX_DELAY +#else +// In or any other mode, we do not wait for input AEC reference channels. +// The reference will be all zeros if no AEC reference is received. +// This is the typical mode. +#define USB_AUDIO_RECV_DELAY 0 +#endif + +// EP and buffer sizes +#define AUDIO_FRAMES_PER_USB_FRAME (appconfUSB_AUDIO_SAMPLE_RATE / 1000) +#if appconfUSB_AUDIO_SAMPLE_RATE == 48000 +#define USB_TASK_STACK_SIZE 2000 +#endif + +// To support USB Adaptive/Asynchronous, maximum packet size must be large enough to accommodate an extra set of samples per frame. +// Adding 1 to AUDIO_SAMPLES_PER_USB_FRAME allows this. +#define CFG_TUD_AUDIO_ENABLE_EP_IN 1 +#define CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ ((AUDIO_FRAMES_PER_USB_FRAME + 1) * CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX * CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX) +#define CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ_MAX (CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ) // Maximum EP IN size for all AS alternate settings used +#define CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ + +#define CFG_TUD_AUDIO_ENABLE_EP_OUT 1 +#define CFG_TUD_AUDIO_FUNC_1_EP_OUT_SZ ((AUDIO_FRAMES_PER_USB_FRAME + 1) * CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_RX * CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX) +#define CFG_TUD_AUDIO_FUNC_1_EP_OUT_SZ_MAX (CFG_TUD_AUDIO_FUNC_1_EP_OUT_SZ + 2) // Maximum EP OUT size for all AS alternate settings used. Plus 2 for CRC +#define CFG_TUD_AUDIO_FUNC_1_EP_OUT_SW_BUF_SZ CFG_TUD_AUDIO_FUNC_1_EP_OUT_SZ*3 + +#endif /* _TUSB_CONFIG_H_ */ diff --git a/examples/ffva/bsp_config/XCORE-AI-EXPLORER/platform/platform_start.c b/examples/ffva/bsp_config/XCORE-AI-EXPLORER/platform/platform_start.c index 846b0055..8b548ad2 100644 --- a/examples/ffva/bsp_config/XCORE-AI-EXPLORER/platform/platform_start.c +++ b/examples/ffva/bsp_config/XCORE-AI-EXPLORER/platform/platform_start.c @@ -17,7 +17,6 @@ #include "usb_support.h" #if appconfI2C_DFU_ENABLED -#include "app_control/app_control.h" #include "device_control_i2c.h" #endif diff --git a/examples/ffva/bsp_config/XK_VOICE_L71/platform/platform_conf.h b/examples/ffva/bsp_config/XK_VOICE_L71/platform/platform_conf.h index 6615a310..dc989760 100644 --- a/examples/ffva/bsp_config/XK_VOICE_L71/platform/platform_conf.h +++ b/examples/ffva/bsp_config/XK_VOICE_L71/platform/platform_conf.h @@ -145,7 +145,7 @@ /* I/O Task Priorities */ /*****************************************/ #ifndef appconfQSPI_FLASH_TASK_PRIORITY -#define appconfQSPI_FLASH_TASK_PRIORITY ( configMAX_PRIORITIES - 1 ) +#define appconfQSPI_FLASH_TASK_PRIORITY (configMAX_PRIORITIES-1) #endif /* appconfQSPI_FLASH_TASK_PRIORITY */ #ifndef appconfI2C_TASK_PRIORITY @@ -153,7 +153,7 @@ #endif /* appconfI2C_TASK_PRIORITY */ #ifndef appconfSPI_TASK_PRIORITY -#define appconfSPI_TASK_PRIORITY (configMAX_PRIORITIES/2) +#define appconfSPI_TASK_PRIORITY ( configMAX_PRIORITIES/2) #endif /* appconfSPI_TASK_PRIORITY */ #ifndef appconfDEVICE_CONTROL_I2C_PRIORITY diff --git a/modules/asr/Cyberon/DSpotter_asr.c b/modules/asr/Cyberon/DSpotter_asr.c index 79da9ee7..0768342f 100644 --- a/modules/asr/Cyberon/DSpotter_asr.c +++ b/modules/asr/Cyberon/DSpotter_asr.c @@ -169,13 +169,9 @@ asr_error_t asr_get_result(asr_port_t *ctx, asr_result_t *result) { DBG_TRACE("\r\nGet %s, ID=%d, Score=%d, SG_Diff=%d, Energy=%d\r\n", szCommand, nCmdID, nCmdScore, nCmdSG, nCmdEnergy); result->id = nCmdID; - result->score = nCmdScore; - result->gscore = nCmdSG; - // The following result fields are not implemented - result->start_index = -1; - result->end_index = -1; - result->duration = -1; + result->sg_diff = nCmdSG; + result->energy = nCmdEnergy; #if appconfINTENT_UART_DEBUG_INFO_ENABLED static char res_info[128]; snprintf(res_info, sizeof(res_info)-1, "ID:%d,Sc:%d,SGD:%d,En:%d\r\n", nCmdID, nCmdScore, nCmdSG, nCmdEnergy); diff --git a/modules/asr/asr.h b/modules/asr/asr.h index 92ca22aa..1dd5d218 100644 --- a/modules/asr/asr.h +++ b/modules/asr/asr.h @@ -64,11 +64,19 @@ typedef struct asr_attributes_struct typedef struct asr_result_struct { uint16_t id; ///< Keyword or command ID +#if ASR_CYBERON==1 + uint32_t score; ///< The confidence score of the detection + uint32_t sg_diff; ///< The voice similarity of the detection + uint32_t energy; ///< The energy of the detection +#elif ASR_SENSORY==1 uint16_t score; ///< The confidence score of the detection uint16_t gscore; ///< The garbage score int32_t start_index; ///< The audio sample index that corresponds to the start of the utterance int32_t end_index; ///< The audio sample index that corresponds to the end of the utterance int32_t duration; ///< THe length of the utterance in samples +#else + #error "Model has to be either Sensory or Cyberon" +#endif void* reserved; ///< Reserved for future use } asr_result_t; From 269a4301a73b36d16ee5b3ab147d508f1d586312 Mon Sep 17 00:00:00 2001 From: Luciano Martin Date: Thu, 1 Aug 2024 09:13:38 +0100 Subject: [PATCH 05/34] Commands are receivedintent_servicer_read_cmdfff --- .../ffd/bsp_config/XK_VOICE_L71/platform/platform_init.c | 2 +- examples/ffd/src/control/intent_servicer.c | 2 -- examples/ffd/src/control/intent_servicer.h | 4 ++-- examples/ffd/src/main.c | 7 +++++++ modules/asr/intent_handler/intent_handler.c | 1 - 5 files changed, 10 insertions(+), 6 deletions(-) diff --git a/examples/ffd/bsp_config/XK_VOICE_L71/platform/platform_init.c b/examples/ffd/bsp_config/XK_VOICE_L71/platform/platform_init.c index 8b4fa525..4b987021 100644 --- a/examples/ffd/bsp_config/XK_VOICE_L71/platform/platform_init.c +++ b/examples/ffd/bsp_config/XK_VOICE_L71/platform/platform_init.c @@ -260,7 +260,7 @@ static void uart_init(void) } void control_init() { -#if appconfI2C_SLAVE+ENABLED == 1 && ON_TILE(I2C_TILE_NO) +#if appconfI2C_SLAVE_ENABLED == 1 && ON_TILE(I2C_TILE_NO) control_ret_t ret = CONTROL_SUCCESS; ret = device_control_init(device_control_i2c_ctx, DEVICE_CONTROL_HOST_MODE, diff --git a/examples/ffd/src/control/intent_servicer.c b/examples/ffd/src/control/intent_servicer.c index 6b2e022e..30276f7a 100644 --- a/examples/ffd/src/control/intent_servicer.c +++ b/examples/ffd/src/control/intent_servicer.c @@ -51,7 +51,6 @@ void intent_servicer(void *args) { servicer_t *servicer = (servicer_t*)args; xassert(servicer != NULL); - control_resid_t *resources = (control_resid_t*)pvPortMalloc(servicer->num_resources * sizeof(control_resid_t)); for(int i=0; inum_resources; i++) { @@ -82,7 +81,6 @@ control_ret_t intent_servicer_read_cmd(control_resource_info_t *res_info, contro memset(payload, 0, payload_len); debug_printf("intent_servicer_read_cmd, cmd_id: %d.\n", cmd_id); - switch (cmd_id) { case INTENT_CONTROLLER_SERVICER_RESID_LAST_DETECTION: diff --git a/examples/ffd/src/control/intent_servicer.h b/examples/ffd/src/control/intent_servicer.h index cb1cba99..53914879 100644 --- a/examples/ffd/src/control/intent_servicer.h +++ b/examples/ffd/src/control/intent_servicer.h @@ -4,8 +4,8 @@ #include "servicer.h" -#define INTENT_CONTROLLER_SERVICER_RESID (1) -#define NUM_RESOURCES_INTENT_SERVICER (1) // DFU servicer +#define INTENT_CONTROLLER_SERVICER_RESID (240) +#define NUM_RESOURCES_INTENT_SERVICER (1) // Intent servicer /** * @brief DFU servicer task. diff --git a/examples/ffd/src/main.c b/examples/ffd/src/main.c index 8addca03..f88637bb 100644 --- a/examples/ffd/src/main.c +++ b/examples/ffd/src/main.c @@ -277,6 +277,13 @@ void startup_task(void *arg) // Initialise control related things servicer_t servicer_intent; intent_servicer_init(&servicer_intent); + + xTaskCreate((TaskFunction_t)intent_servicer, + "intent servicer", + RTOS_THREAD_STACK_SIZE(intent_servicer), + &servicer_intent, + appconfDEVICE_CONTROL_I2C_PRIORITY, + NULL); #endif #if ON_TILE(0) diff --git a/modules/asr/intent_handler/intent_handler.c b/modules/asr/intent_handler/intent_handler.c index cfa4cee6..7068ee70 100644 --- a/modules/asr/intent_handler/intent_handler.c +++ b/modules/asr/intent_handler/intent_handler.c @@ -98,7 +98,6 @@ int32_t intent_handler_create(uint32_t priority, void *args) args, priority, NULL); - return 0; } From 8fb0821a6ebf244a05bf96b5a9eafe3b41093fc4 Mon Sep 17 00:00:00 2001 From: Luciano Martin Date: Thu, 1 Aug 2024 13:47:49 +0100 Subject: [PATCH 06/34] Command working with test ID's and external variables --- .../XK_VOICE_L71/platform/platform_init.c | 2 +- .../XK_VOICE_L71/platform/platform_start.c | 4 ++-- examples/ffd/src/control/intent_servicer.c | 20 ++++++++++++------- examples/ffd/src/control/servicer.c | 2 +- examples/ffd/src/main.c | 4 ++-- modules/asr/Cyberon/DSpotter_asr.c | 2 +- modules/asr/intent_engine/intent_engine.c | 5 ++++- 7 files changed, 24 insertions(+), 15 deletions(-) diff --git a/examples/ffd/bsp_config/XK_VOICE_L71/platform/platform_init.c b/examples/ffd/bsp_config/XK_VOICE_L71/platform/platform_init.c index 4b987021..0c9e0cd6 100644 --- a/examples/ffd/bsp_config/XK_VOICE_L71/platform/platform_init.c +++ b/examples/ffd/bsp_config/XK_VOICE_L71/platform/platform_init.c @@ -260,7 +260,7 @@ static void uart_init(void) } void control_init() { -#if appconfI2C_SLAVE_ENABLED == 1 && ON_TILE(I2C_TILE_NO) +#if appconfI2C_SLAVE_ENABLED && ON_TILE(I2C_TILE_NO) control_ret_t ret = CONTROL_SUCCESS; ret = device_control_init(device_control_i2c_ctx, DEVICE_CONTROL_HOST_MODE, diff --git a/examples/ffd/bsp_config/XK_VOICE_L71/platform/platform_start.c b/examples/ffd/bsp_config/XK_VOICE_L71/platform/platform_start.c index 3855b5d4..db1da5d4 100644 --- a/examples/ffd/bsp_config/XK_VOICE_L71/platform/platform_start.c +++ b/examples/ffd/bsp_config/XK_VOICE_L71/platform/platform_start.c @@ -44,7 +44,7 @@ static void flash_start(void) static void i2c_master_start(void) { -#if appconfI2C_ENABLED == 1 && appconfI2C_MODE == appconfI2C_MODE_MASTER +#if appconfI2C_ENABLED && appconfI2C_MODE == appconfI2C_MODE_MASTER rtos_i2c_master_rpc_config(i2c_master_ctx, appconfI2C_MASTER_RPC_PORT, appconfI2C_MASTER_RPC_PRIORITY); #if ON_TILE(I2C_TILE_NO) @@ -55,7 +55,7 @@ static void i2c_master_start(void) static void i2c_slave_start(void) { -#if appconfI2C_SLAVE_ENABLED == 1 && ON_TILE(I2C_CTRL_TILE_NO) +#if appconfI2C_SLAVE_ENABLED && ON_TILE(I2C_CTRL_TILE_NO) rtos_i2c_slave_start(i2c_slave_ctx, device_control_i2c_ctx, (rtos_i2c_slave_start_cb_t) device_control_i2c_start_cb, diff --git a/examples/ffd/src/control/intent_servicer.c b/examples/ffd/src/control/intent_servicer.c index 30276f7a..371d591e 100644 --- a/examples/ffd/src/control/intent_servicer.c +++ b/examples/ffd/src/control/intent_servicer.c @@ -14,19 +14,19 @@ #include "platform/platform_conf.h" #include "servicer.h" #include "intent_servicer.h" - +#include "asr.h" #include "device_control_i2c.h" enum e_intent_controller_servicer_resid_cmds { #ifndef INTENT_CONTROLLER_SERVICER_RESID_LAST_DETECTION - INTENT_CONTROLLER_SERVICER_RESID_LAST_DETECTION = 0, + INTENT_CONTROLLER_SERVICER_RESID_LAST_DETECTION = 88, #endif - NUM_INTENT_CONTROLLER_SERVICER_RESID_CMDS + NUM_INTENT_CONTROLLER_SERVICER_RESID_CMDS = 1 }; static control_cmd_info_t intent_controller_servicer_resid_cmd_map[] = { - { INTENT_CONTROLLER_SERVICER_RESID_LAST_DETECTION, 1, sizeof(uint8_t), CMD_READ_ONLY }, + { INTENT_CONTROLLER_SERVICER_RESID_LAST_DETECTION, 3, sizeof(uint8_t), CMD_READ_ONLY }, }; void intent_servicer_init(servicer_t *servicer) @@ -72,7 +72,8 @@ void intent_servicer(void *args) { device_control_servicer_cmd_recv(&servicer_ctx, read_cmd, write_cmd, servicer, RTOS_OSAL_WAIT_FOREVER); } } - +extern uint32_t detection_number; +extern asr_result_t last_asr_result; control_ret_t intent_servicer_read_cmd(control_resource_info_t *res_info, control_cmd_t cmd, uint8_t *payload, size_t payload_len) { control_ret_t ret = CONTROL_SUCCESS; @@ -81,13 +82,18 @@ control_ret_t intent_servicer_read_cmd(control_resource_info_t *res_info, contro memset(payload, 0, payload_len); debug_printf("intent_servicer_read_cmd, cmd_id: %d.\n", cmd_id); + //asr_result_t asr_result; + + //asr_error_t asr_error = asr_get_result(NULL, &asr_result); + printf("detection_number %d, last_asr_result.id %d\n", detection_number, last_asr_result.id); + switch (cmd_id) { case INTENT_CONTROLLER_SERVICER_RESID_LAST_DETECTION: { debug_printf("INTENT_CONTROLLER_SERVICER_RESID_LAST_DETECTION\n"); - uint8_t last_detection = 0;//intent_get_last_detection(); - payload[0] = last_detection; + payload[0] = (uint8_t) last_asr_result.id; + payload[1] = (uint8_t) detection_number; break; } diff --git a/examples/ffd/src/control/servicer.c b/examples/ffd/src/control/servicer.c index 9d9a39ab..15f572b0 100644 --- a/examples/ffd/src/control/servicer.c +++ b/examples/ffd/src/control/servicer.c @@ -12,7 +12,7 @@ #include "servicer.h" #include "intent_servicer.h" -#if appconfI2C_SLAVE_ENABLED == 1 && ON_TILE(I2C_CTRL_TILE_NO) +#if appconfI2C_SLAVE_ENABLED && ON_TILE(I2C_CTRL_TILE_NO) static device_control_t device_control_i2c_ctx_s; device_control_t *device_control_i2c_ctx = (device_control_t *) &device_control_i2c_ctx_s; diff --git a/examples/ffd/src/main.c b/examples/ffd/src/main.c index f88637bb..7fc1d773 100644 --- a/examples/ffd/src/main.c +++ b/examples/ffd/src/main.c @@ -30,7 +30,7 @@ #include "gpio_ctrl/gpi_ctrl.h" #include "gpio_ctrl/leds.h" #include "intent_handler/intent_handler.h" -#if appconfI2C_SLAVE_ENABLED == 1 +#if appconfI2C_SLAVE_ENABLED #include "intent_servicer.h" #endif @@ -273,7 +273,7 @@ void startup_task(void *arg) #endif #endif -#if appconfI2C_SLAVE_ENABLED == 1 && ON_TILE(I2C_CTRL_TILE_NO) +#if appconfI2C_SLAVE_ENABLED && ON_TILE(I2C_CTRL_TILE_NO) // Initialise control related things servicer_t servicer_intent; intent_servicer_init(&servicer_intent); diff --git a/modules/asr/Cyberon/DSpotter_asr.c b/modules/asr/Cyberon/DSpotter_asr.c index 0768342f..3a7749eb 100644 --- a/modules/asr/Cyberon/DSpotter_asr.c +++ b/modules/asr/Cyberon/DSpotter_asr.c @@ -176,7 +176,7 @@ asr_error_t asr_get_result(asr_port_t *ctx, asr_result_t *result) static char res_info[128]; snprintf(res_info, sizeof(res_info)-1, "ID:%d,Sc:%d,SGD:%d,En:%d\r\n", nCmdID, nCmdScore, nCmdSG, nCmdEnergy); // Enable the printout below to see the information sent over UART - // rtos_printf(res_info); + rtos_printf(res_info); rtos_uart_tx_write(uart_tx_ctx, (uint8_t*)&res_info, strlen(res_info)); #endif return ASR_OK; diff --git a/modules/asr/intent_engine/intent_engine.c b/modules/asr/intent_engine/intent_engine.c index 46a951ea..2d258a5c 100644 --- a/modules/asr/intent_engine/intent_engine.c +++ b/modules/asr/intent_engine/intent_engine.c @@ -112,7 +112,8 @@ static void timeout_event_handler(TimerHandle_t pxTimer) intent_state = STATE_EXPECTING_WAKEWORD; } } - +asr_result_t last_asr_result = {0}; +uint32_t detection_number = 0; #pragma stackfunction 1000 void intent_engine_task(void *args) { @@ -169,6 +170,8 @@ void intent_engine_task(void *args) if (asr_error != ASR_OK) continue; asr_error = asr_get_result(asr_ctx, &asr_result); + memcpy(&last_asr_result, &asr_result, sizeof(asr_result_t)); + detection_number++; if (asr_error != ASR_OK) continue; word_id = asr_result.id; From 989027fce1a99461fbfcf5d17f8798169eabce68 Mon Sep 17 00:00:00 2001 From: Luciano Martin Date: Fri, 2 Aug 2024 09:10:06 +0100 Subject: [PATCH 07/34] Remove device control code --- .../XK_VOICE_L71/platform/platform_conf.h | 4 - .../XK_VOICE_L71/platform/platform_init.c | 21 --- .../XK_VOICE_L71/platform/platform_start.c | 55 +++++- examples/ffd/ffd_i2s_input_cyberon.cmake | 1 - examples/ffd/src/app_conf.h | 3 +- examples/ffd/src/control/cmd_map.h | 39 ---- examples/ffd/src/control/intent_servicer.c | 129 ------------- examples/ffd/src/control/intent_servicer.h | 53 ------ examples/ffd/src/control/servicer.c | 169 ------------------ examples/ffd/src/control/servicer.h | 124 ------------- examples/ffd/src/main.c | 16 -- examples/ffva/src/dfu_int/dfu_servicer.c | 4 +- modules/asr/intent_engine/intent_engine.c | 4 +- 13 files changed, 52 insertions(+), 570 deletions(-) delete mode 100644 examples/ffd/src/control/cmd_map.h delete mode 100644 examples/ffd/src/control/intent_servicer.c delete mode 100644 examples/ffd/src/control/intent_servicer.h delete mode 100644 examples/ffd/src/control/servicer.c delete mode 100644 examples/ffd/src/control/servicer.h diff --git a/examples/ffd/bsp_config/XK_VOICE_L71/platform/platform_conf.h b/examples/ffd/bsp_config/XK_VOICE_L71/platform/platform_conf.h index 525ab376..515f1f2d 100644 --- a/examples/ffd/bsp_config/XK_VOICE_L71/platform/platform_conf.h +++ b/examples/ffd/bsp_config/XK_VOICE_L71/platform/platform_conf.h @@ -112,8 +112,4 @@ #define appconfI2C_TASK_PRIORITY (configMAX_PRIORITIES/2) #endif /* appconfI2C_TASK_PRIORITY */ -#ifndef appconfDEVICE_CONTROL_I2C_PRIORITY -#define appconfDEVICE_CONTROL_I2C_PRIORITY (configMAX_PRIORITIES-1) -#endif // appconfDEVICE_CONTROL_I2C_PRIORITY - #endif /* PLATFORM_CONF_H_ */ diff --git a/examples/ffd/bsp_config/XK_VOICE_L71/platform/platform_init.c b/examples/ffd/bsp_config/XK_VOICE_L71/platform/platform_init.c index 0c9e0cd6..7ab6d2ea 100644 --- a/examples/ffd/bsp_config/XK_VOICE_L71/platform/platform_init.c +++ b/examples/ffd/bsp_config/XK_VOICE_L71/platform/platform_init.c @@ -9,10 +9,6 @@ #include "platform/app_pll_ctrl.h" #include "platform/driver_instances.h" #include "platform/platform_init.h" -#include "device_control.h" -#include "servicer.h" - -extern device_control_t *device_control_i2c_ctx; static void mclk_init(chanend_t other_tile_c) { @@ -259,22 +255,6 @@ static void uart_init(void) #endif } -void control_init() { -#if appconfI2C_SLAVE_ENABLED && ON_TILE(I2C_TILE_NO) - control_ret_t ret = CONTROL_SUCCESS; - ret = device_control_init(device_control_i2c_ctx, - DEVICE_CONTROL_HOST_MODE, - (NUM_TILE_0_SERVICERS + NUM_TILE_1_SERVICERS), - NULL, 0); - xassert(ret == CONTROL_SUCCESS); - - ret = device_control_start(device_control_i2c_ctx, - -1, - -1); - xassert(ret == CONTROL_SUCCESS); -#endif -} - void platform_init(chanend_t other_tile_c) { rtos_intertile_init(intertile_ctx, other_tile_c); @@ -287,5 +267,4 @@ void platform_init(chanend_t other_tile_c) mics_init(); i2s_init(); uart_init(); - control_init(); } diff --git a/examples/ffd/bsp_config/XK_VOICE_L71/platform/platform_start.c b/examples/ffd/bsp_config/XK_VOICE_L71/platform/platform_start.c index db1da5d4..4ebde1a4 100644 --- a/examples/ffd/bsp_config/XK_VOICE_L71/platform/platform_start.c +++ b/examples/ffd/bsp_config/XK_VOICE_L71/platform/platform_start.c @@ -14,11 +14,9 @@ #include "platform_conf.h" #include "platform/driver_instances.h" #include "dac3101.h" +#include "asr.h" -#if appconfI2C_SLAVE_ENABLED == 1 -#include "servicer.h" -#include "device_control_i2c.h" -#endif +extern asr_result_t last_asr_result; extern void i2s_rate_conversion_enable(void); @@ -53,14 +51,55 @@ static void i2c_master_start(void) #endif } +#define WAKEWORD_REG_ADDRESS_START 0x40 +#define WAKEWORD_REG_ADDRESS_END 0x49 +#define WRITE_REQUEST_MIN_LEN 1 + +RTOS_I2C_SLAVE_CALLBACK_ATTR +size_t read_device_reg(rtos_i2c_slave_t *ctx, + asr_result_t *last_asr_result, + uint8_t **data) +{ + uint8_t * data_p = *data; + uint8_t reg_addr = data_p[0]; + uint8_t reg_value = 0; + if (reg_addr >= WAKEWORD_REG_ADDRESS_START && reg_addr <= WAKEWORD_REG_ADDRESS_END) { + if (last_asr_result->id == reg_addr - WAKEWORD_REG_ADDRESS_START + 1) + { + uint8_t score = (uint8_t) last_asr_result->score&0xF; + printf("Found wakeword information: ID %d, score %d\n", last_asr_result->id, score); + reg_value = score; + } else { + reg_value = 0; + } + } else { + reg_value = reg_addr - 1; + } + data_p[0] = reg_value; + printf("Read from register 0x%02X value 0x%02X\n", reg_addr, reg_value); + return 1; +} + +RTOS_I2C_SLAVE_CALLBACK_ATTR +void write_device_reg(rtos_i2c_slave_t *ctx, + void *app_data, + uint8_t *data, + size_t len) +{ + // If the length is lower than WRITE_REQUEST_MIN_LEN, it is a read request + if (len > WRITE_REQUEST_MIN_LEN) { + printf("Write to register 0x%02X value 0x%02X (len %d)\n", data[0], data[1], len); + } +} + static void i2c_slave_start(void) { #if appconfI2C_SLAVE_ENABLED && ON_TILE(I2C_CTRL_TILE_NO) rtos_i2c_slave_start(i2c_slave_ctx, - device_control_i2c_ctx, - (rtos_i2c_slave_start_cb_t) device_control_i2c_start_cb, - (rtos_i2c_slave_rx_cb_t) device_control_i2c_rx_cb, - (rtos_i2c_slave_tx_start_cb_t) device_control_i2c_tx_start_cb, + &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, diff --git a/examples/ffd/ffd_i2s_input_cyberon.cmake b/examples/ffd/ffd_i2s_input_cyberon.cmake index eef54a63..600a3bbc 100644 --- a/examples/ffd/ffd_i2s_input_cyberon.cmake +++ b/examples/ffd/ffd_i2s_input_cyberon.cmake @@ -105,7 +105,6 @@ set(APP_COMMON_LINK_LIBRARIES sln_voice::app::asr::intent_engine sln_voice::app::asr::intent_handler sln_voice::app::ffd::xk_voice_l71 - rtos::sw_services::device_control rtos::freertos_usb lib_src lib_sw_pll diff --git a/examples/ffd/src/app_conf.h b/examples/ffd/src/app_conf.h index 82af6bd3..c0662230 100644 --- a/examples/ffd/src/app_conf.h +++ b/examples/ffd/src/app_conf.h @@ -10,7 +10,6 @@ #define appconfINTENT_MODEL_RUNNER_SAMPLES_PORT 3 #define appconfI2C_MASTER_RPC_PORT 4 #define appconfI2S_RPC_PORT 5 -#define appconfDEVICE_CONTROL_I2C_PORT 6 #define appconfINTENT_ENGINE_READY_SYNC_PORT 16 #define appconfI2S_OUTPUT_SLAVE_PORT 8 @@ -116,7 +115,7 @@ #define appconfI2C_SLAVE_ENABLED 0 #endif -#if appconfINTENT_I2C_OUTPUT_ENABLED==1 && appconfI2C_MASTER_ENABLED==0 +#if appconfINTENT_I2C_OUTPUT_ENABLED && ! appconfI2C_MASTER_ENABLED #error "I2C master must be enabled for intent I2C output" #endif diff --git a/examples/ffd/src/control/cmd_map.h b/examples/ffd/src/control/cmd_map.h deleted file mode 100644 index 71467e20..00000000 --- a/examples/ffd/src/control/cmd_map.h +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright 2022-2024 XMOS LIMITED. -// This Software is subject to the terms of the XMOS Public Licence: Version 1. - -#pragma once - -#include -#include "device_control_shared.h" - -// Types of commands in the Command ID enum space - -// - Dedicated: Commands dedicated only for the resource -// - For SHF this is further spilt into dedicated SHF commands and dedicated custom commands -// - Shared: Commands shared between a resource and its servicer. These are present in the servicer's command map only though respources process them as well. (Used for special commands protocol) -// - External: space reserved for customers to add commands. -#define DEDICATED_COMMANDS_START_OFFSET (0) -#define SHARED_COMMANDS_START_OFFSET (90) -#define EXTERNAL_COMMANDS_START_OFFSET (110) -// Servicers will have commands in the above 4 categories. -// Resources will have commands in the dedicated, reserved and broadcast categories. - - -typedef enum -{ - CMD_READ_ONLY, - CMD_READ_WRITE, - CMD_WRITE_ONLY -}cmd_rw_type_t; - -typedef struct -{ - uint8_t cmd_id; - uint8_t num_vals; - uint8_t bytes_per_val; - uint8_t cmd_rw_type; -}control_cmd_info_t; - -typedef struct { - int32_t num_commands; - control_cmd_info_t *commands; -}command_map_t; diff --git a/examples/ffd/src/control/intent_servicer.c b/examples/ffd/src/control/intent_servicer.c deleted file mode 100644 index 371d591e..00000000 --- a/examples/ffd/src/control/intent_servicer.c +++ /dev/null @@ -1,129 +0,0 @@ -// Copyright 2024 XMOS LIMITED. -// This Software is subject to the terms of the XMOS Public Licence: Version 1. -#define DEBUG_UNIT INTENT_SERVICER -#ifndef DEBUG_PRINT_ENABLE_INTENT_SERVICER -#define DEBUG_PRINT_ENABLE_INTENT_SERVICER 0 -#endif -#include "debug_print.h" - -#include -#include -#include -#include - -#include "platform/platform_conf.h" -#include "servicer.h" -#include "intent_servicer.h" -#include "asr.h" -#include "device_control_i2c.h" - -enum e_intent_controller_servicer_resid_cmds -{ -#ifndef INTENT_CONTROLLER_SERVICER_RESID_LAST_DETECTION - INTENT_CONTROLLER_SERVICER_RESID_LAST_DETECTION = 88, -#endif - NUM_INTENT_CONTROLLER_SERVICER_RESID_CMDS = 1 -}; -static control_cmd_info_t intent_controller_servicer_resid_cmd_map[] = -{ - { INTENT_CONTROLLER_SERVICER_RESID_LAST_DETECTION, 3, sizeof(uint8_t), CMD_READ_ONLY }, -}; - -void intent_servicer_init(servicer_t *servicer) -{ - // Servicer resource info - static control_resource_info_t intent_res_info[NUM_RESOURCES_INTENT_SERVICER]; - - memset(servicer, 0, sizeof(servicer_t)); - servicer->id = INTENT_CONTROLLER_SERVICER_RESID; - servicer->start_io = 0; - servicer->num_resources = NUM_RESOURCES_INTENT_SERVICER; - - servicer->res_info = &intent_res_info[0]; - // Servicer resource - servicer->res_info[0].resource = INTENT_CONTROLLER_SERVICER_RESID; - servicer->res_info[0].command_map.num_commands = NUM_INTENT_CONTROLLER_SERVICER_RESID_CMDS; - servicer->res_info[0].command_map.commands = intent_controller_servicer_resid_cmd_map; -} - -void intent_servicer(void *args) { - device_control_servicer_t servicer_ctx; - - servicer_t *servicer = (servicer_t*)args; - xassert(servicer != NULL); - control_resid_t *resources = (control_resid_t*)pvPortMalloc(servicer->num_resources * sizeof(control_resid_t)); - for(int i=0; inum_resources; i++) - { - resources[i] = servicer->res_info[i].resource; - } - - control_ret_t dc_ret; - debug_printf("Calling device_control_servicer_register(), servicer ID %d, on tile %d, core %d.\n", servicer->id, THIS_XCORE_TILE, rtos_core_id_get()); - - dc_ret = device_control_servicer_register(&servicer_ctx, - device_control_ctxs, - 1, - resources, servicer->num_resources); - debug_printf("Out of device_control_servicer_register(), servicer ID %d, on tile %d. servicer_ctx address = 0x%x\n", servicer->id, THIS_XCORE_TILE, &servicer_ctx); - - vPortFree(resources); - - for(;;){ - device_control_servicer_cmd_recv(&servicer_ctx, read_cmd, write_cmd, servicer, RTOS_OSAL_WAIT_FOREVER); - } -} -extern uint32_t detection_number; -extern asr_result_t last_asr_result; -control_ret_t intent_servicer_read_cmd(control_resource_info_t *res_info, control_cmd_t cmd, uint8_t *payload, size_t payload_len) -{ - control_ret_t ret = CONTROL_SUCCESS; - uint8_t cmd_id = CONTROL_CMD_CLEAR_READ(cmd); - - memset(payload, 0, payload_len); - - debug_printf("intent_servicer_read_cmd, cmd_id: %d.\n", cmd_id); - //asr_result_t asr_result; - - //asr_error_t asr_error = asr_get_result(NULL, &asr_result); - printf("detection_number %d, last_asr_result.id %d\n", detection_number, last_asr_result.id); - - switch (cmd_id) - { - case INTENT_CONTROLLER_SERVICER_RESID_LAST_DETECTION: - { - debug_printf("INTENT_CONTROLLER_SERVICER_RESID_LAST_DETECTION\n"); - payload[0] = (uint8_t) last_asr_result.id; - payload[1] = (uint8_t) detection_number; - break; - } - - default: - { - debug_printf("INTENT_CONTROLLER_SERVICER UNHANDLED COMMAND!!!\n"); - ret = CONTROL_BAD_COMMAND; - break; - } - - } - return ret; -} - -control_ret_t intent_servicer_write_cmd(control_resource_info_t *res_info, control_cmd_t cmd, const uint8_t *payload, size_t payload_len) -{ - control_ret_t ret = CONTROL_SUCCESS; - - uint8_t cmd_id = CONTROL_CMD_CLEAR_READ(cmd); - debug_printf("intent_servicer_write_cmd cmd_id %d.\n", cmd_id); - - switch (cmd_id) - { - - // Add the handling of the write commands here - default: - debug_printf("INTENT_CONTROLLER_SERVICER UNHANDLED COMMAND!!!\n"); - ret = CONTROL_BAD_COMMAND; - break; - } - - return ret; -} diff --git a/examples/ffd/src/control/intent_servicer.h b/examples/ffd/src/control/intent_servicer.h deleted file mode 100644 index 53914879..00000000 --- a/examples/ffd/src/control/intent_servicer.h +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright 2024 XMOS LIMITED. -// This Software is subject to the terms of the XMOS Public Licence: Version 1. -#pragma once - -#include "servicer.h" - -#define INTENT_CONTROLLER_SERVICER_RESID (240) -#define NUM_RESOURCES_INTENT_SERVICER (1) // Intent servicer - -/** - * @brief DFU servicer task. - * - * This task handles DFU commands from the device control interface and relays - * them to the internal DFU INT state machine. - * - * \param args Pointer to the Servicer's state data structure - */ -void intent_servicer(void *args); - -// Servicer initialization functions -/** - * @brief DFU servicer initialisation function. - * \param servicer Pointer to the Servicer's state data structure - */ -void intent_servicer_init(servicer_t *servicer); - -/** - * @brief DFU servicer read command handler - * - * Handles read commands dedicated to the DFU servicer resource - * - * @param res_info Resource info of the current command - * @param cmd Command ID of this command - * @param payload Pointer to the payload that contains the write data - * @param payload_len Length in bytes of the write command payload - * @return control_ret_t CONTROL_SUCCESS if command handled successfully, - * otherwise control_ret_t error status indicating the error. - */ -control_ret_t intent_servicer_read_cmd(control_resource_info_t *res_info, control_cmd_t cmd, uint8_t *payload, size_t payload_len); - -/** - * @brief DFU servicer write command handler - * - * Handles write commands dedicated to the DFU servicer resource - * - * @param res_info Resource info of the current command - * @param cmd Command ID of this command - * @param payload Pointer to the payload that contains the write data - * @param payload_len Length in bytes of the write command payload - * @return control_ret_t CONTROL_SUCCESS if command handled successfully, - * otherwise control_ret_t error status indicating the error. - */ -control_ret_t intent_servicer_write_cmd(control_resource_info_t *res_info, control_cmd_t cmd, const uint8_t *payload, size_t payload_len); \ No newline at end of file diff --git a/examples/ffd/src/control/servicer.c b/examples/ffd/src/control/servicer.c deleted file mode 100644 index 15f572b0..00000000 --- a/examples/ffd/src/control/servicer.c +++ /dev/null @@ -1,169 +0,0 @@ -// Copyright 2024 XMOS LIMITED. -// This Software is subject to the terms of the XMOS Public Licence: Version 1. -#define DEBUG_UNIT SERVICER_TASK -#ifndef DEBUG_PRINT_ENABLE_SERVICER_TASK - #define DEBUG_PRINT_ENABLE_SERVICER_TASK 0 -#endif -#include "debug_print.h" -#include -#include -#include "platform/platform_conf.h" -#include "device_control_i2c.h" -#include "servicer.h" -#include "intent_servicer.h" - -#if appconfI2C_SLAVE_ENABLED && ON_TILE(I2C_CTRL_TILE_NO) - -static device_control_t device_control_i2c_ctx_s; -device_control_t *device_control_i2c_ctx = (device_control_t *) &device_control_i2c_ctx_s; -device_control_t *device_control_ctxs[APP_CONTROL_TRANSPORT_COUNT] = { - (device_control_t *) &device_control_i2c_ctx_s, -}; -#endif - -//-----------------Servicer read write callback functions-----------------------// -DEVICE_CONTROL_CALLBACK_ATTR -control_ret_t read_cmd(control_resid_t resid, control_cmd_t cmd, uint8_t *payload, size_t payload_len, void *app_data) -{ - control_ret_t ret = CONTROL_SUCCESS; - servicer_t *servicer = (servicer_t*)app_data; - - // For read commands, payload[0] is reserved from status. So payload_len is one more than the payload_len stored in the resource command map - payload_len -= 1; - uint8_t *payload_ptr = &payload[1]; //Excluding the status byte, which is updated later. - - debug_printf("Servicer ID %d on tile %d received READ command %02x for resid %02x\n\t",servicer->id, THIS_XCORE_TILE, cmd, resid); - debug_printf("The command is requesting %d bytes\n\t", payload_len); - - - control_resource_info_t *current_res_info = get_res_info(resid, servicer); - xassert(current_res_info != NULL); // This should never happen - control_cmd_info_t *current_cmd_info; - ret = validate_cmd(¤t_cmd_info, current_res_info, cmd, payload_ptr, payload_len); - if(ret != CONTROL_SUCCESS) - { - payload[0] = ret; // Update status in byte 0 - return ret; - } - // Check if command is for the servicer itself - if(current_res_info->resource == servicer->res_info[0].resource) - { - ret = servicer_read_cmd(current_res_info, cmd, payload_ptr, payload_len); - payload[0] = ret; - return ret; - } - return CONTROL_ERROR; -} - -DEVICE_CONTROL_CALLBACK_ATTR -control_ret_t write_cmd(control_resid_t resid, control_cmd_t cmd, const uint8_t *payload, size_t payload_len, void *app_data) -{ - control_ret_t ret = CONTROL_SUCCESS; - servicer_t *servicer = (servicer_t*)app_data; - //debug_printf("Device control WRITE. Servicer ID %d\n\t", servicer->id); - - debug_printf("Servicer ID %d on tile %d received WRITE command %02x for resid %02x\n\t", servicer->id, THIS_XCORE_TILE, cmd, resid); - debug_printf("The command has %d bytes\n\t", payload_len); - - control_resource_info_t *current_res_info = get_res_info(resid, servicer); - xassert(current_res_info != NULL); - control_cmd_info_t *current_cmd_info; - ret = validate_cmd(¤t_cmd_info, current_res_info, cmd, payload, payload_len); - if(ret != CONTROL_SUCCESS) - { - return ret; - } - // Check if command is for the servicer itself - if(current_res_info->resource == servicer->res_info[0].resource) - { - ret = servicer_write_cmd(current_res_info, cmd, payload, payload_len); - return ret; - } - return CONTROL_ERROR; -} - -// Initialise packet payload pointers to point to valid memory. - - -//-----------------Servicer helper functions-----------------------// -// Return a pointer to the control_cmd_info_t structure for a given command ID. Return NULL if command not found in the -// command map for the resource. -control_cmd_info_t* get_cmd_info(uint8_t cmd_id, const control_resource_info_t *res_info) -{ - for(int i=0; icommand_map.num_commands; i++) - { - if(res_info->command_map.commands[i].cmd_id == cmd_id) - { - return &res_info->command_map.commands[i]; - } - } - return NULL; -} - -// Return a pointer to the servicer's control_resource_info_t structure for a given resource ID. -// Return NULL if the resource ID is not found in the list of resources serviced by the servicer. -control_resource_info_t* get_res_info(control_resid_t resource, const servicer_t *servicer) -{ - for(int res=0; resnum_resources; res++) - { - // Get the cmd_info for the current command - if(servicer->res_info[res].resource == resource) - { - return &servicer->res_info[res]; - } - } - return NULL; -} - -// Validate the command from the host against that commands information in the stored command_map -control_ret_t validate_cmd(control_cmd_info_t **cmd_info, - control_resource_info_t *res_info, - control_cmd_t cmd, - const uint8_t *payload, - size_t payload_len) -{ - control_ret_t ret = CONTROL_SUCCESS; - *cmd_info = get_cmd_info(CONTROL_CMD_CLEAR_READ(cmd), res_info); - if(*cmd_info == NULL) - { - return SERVICER_WRONG_COMMAND_ID; - } - - // Validate non special command length - // Don't do payload check for special commands since for the last filter chunk, host might request less than the payload length specified in the cmd_map - - if(payload_len != (*cmd_info)->bytes_per_val * (*cmd_info)->num_vals) - { - return SERVICER_WRONG_COMMAND_LEN; - } - // Payload validation happens either on the host or in the specific command handlers. No generic payload validation is done in the servicer. - - return ret; -} - -// Process write commands directed to the servicer resource -control_ret_t servicer_write_cmd(control_resource_info_t *res_info, control_cmd_t cmd, const uint8_t *payload, size_t payload_len) -{ - // Handle write commands directed to a servicer resource - switch(res_info->resource) - { - case INTENT_CONTROLLER_SERVICER_RESID: - return intent_servicer_write_cmd(res_info, cmd, payload, payload_len); - break; - } - return CONTROL_SUCCESS; -} - -// Process read commands directed to the servicer resource -control_ret_t servicer_read_cmd(control_resource_info_t *res_info, control_cmd_t cmd, uint8_t *payload, size_t payload_len) -{ - control_ret_t ret = CONTROL_SUCCESS; - // Handle read commands directed to a servicer resource - switch(res_info->resource) - { - case INTENT_CONTROLLER_SERVICER_RESID: - ret = intent_servicer_read_cmd(res_info, cmd, payload, payload_len); - break; - } - return ret; -} diff --git a/examples/ffd/src/control/servicer.h b/examples/ffd/src/control/servicer.h deleted file mode 100644 index 8e979b27..00000000 --- a/examples/ffd/src/control/servicer.h +++ /dev/null @@ -1,124 +0,0 @@ -// Copyright 2024 XMOS LIMITED. -// This Software is subject to the terms of the XMOS Public Licence: Version 1. -#pragma once -#include "device_control.h" -#include "cmd_map.h" - -#define NUM_TILE_0_SERVICERS (1) // only intent servicer is used -#define NUM_TILE_1_SERVICERS (0) // no control servicer - -extern device_control_t *device_control_i2c_ctx; -extern device_control_t *device_control_ctxs[1]; - -/** - * Clears the read bit on a command code - * - * \param[in,out] c The command code to clear the read bit on. - */ -#define CONTROL_CMD_CLEAR_READ(c) ((c) & ~0x80) - -// Structure encapsulating all the information about a resource -typedef struct -{ - control_resid_t resource; - command_map_t command_map; -}control_resource_info_t; - -typedef struct { - uint32_t start_io; // set to 1 on one servicer per tile to make it responsible for starting the IO tasks on that tile. - int32_t id; // Unique ID for the servicer. Used for debugging. - // Num resources - int32_t num_resources; - // Resource ID and command map for every resource - control_resource_info_t *res_info; -}servicer_t; - -// Servicer device_control callback functions -/** - * @brief Device control callback function to handle a read command. - * - * @param resid Resource ID of the command - * @param cmd Command ID of the command - * @param payload Pointer to the payload buffer that needs to be updated with the read command response. - * @param payload_len Length of the payload buffer - * @param app_data Application specific data. - * @return CONTROL_SUCCESS is command is handled successfully, - * otherwise control_ret_t error status indicating the error. - */ -extern DEVICE_CONTROL_CALLBACK_ATTR -control_ret_t read_cmd(control_resid_t resid, control_cmd_t cmd, uint8_t *payload, size_t payload_len, void *app_data); - -/** - * @brief Device control callback function to handle a write command - * - * @param resid Resource ID of the command - * @param cmd Command ID of the command - * @param payload Pointer to the payload buffer containing the payload the host wants to write to the device. - * @param payload_len Length of the payload buffer - * @param app_data Application specific data - * @return CONTROL_SUCCESS is command is handled successfully, - * otherwise control_ret_t error status indicating the error. - */ -extern DEVICE_CONTROL_CALLBACK_ATTR -control_ret_t write_cmd(control_resid_t resid, control_cmd_t cmd, const uint8_t *payload, size_t payload_len, void *app_data); - -// Servicer helper functions -/** - * @brief Check if a command exists in the command map for a given resource and return the pointer to the cmd info object for the given command - * - * @param cmd_id Command ID for which the control_cmd_info_t object is required. - * @param res_info Pointer to the resource info which contains all the command info objects for a given resource. - * @return Pointer to a control_cmd_info_t object when one is found for the given Command ID, NULL otherwise. - */ -control_cmd_info_t* get_cmd_info(uint8_t cmd_id, const control_resource_info_t *res_info); - -/** - * @brief Check if a resource ID is one of the resources supported by a servicer and return a pointer to the resource info object. - * - * @param resource Resource ID that needs to be checked. - * @param servicer Pointer to the servicer state structure that holds all the resource info objects for the servicer. - * @return Pointer to the resource_info_t object when one is found for a given resource ID, NULL otherwise. - */ -control_resource_info_t* get_res_info(control_resid_t resource, const servicer_t *servicer); - -/** - * @brief Validate the command received in the servicer and return a pointer to the command info if the command is valid. - * - * All checks related to the command such as command ID being valid, correctness of the payload length, - * validation of the actual payload for write commands are done in this function. - * - * @param cmd_info Pointer in which the address of the command info is returned if this is a valid command/ - * @param res_info Resource info of the resource the command is meant for. - * @param cmd Command ID of the command that needs validating - * @param payload Payload buffer of the command that needs validating. - * @param payload_len Payload length of the payload. - * @return CONTROL_SUCCESS if the command is found to be valid for the given resource. control_ret_t error otherwise - * indicating the error code of the specific validation check that failed. - */ -control_ret_t validate_cmd(control_cmd_info_t **cmd_info, - control_resource_info_t *res_info, - control_cmd_t cmd, - const uint8_t *payload, - size_t payload_len); - -/** - * @brief Function for handling write commands directed to the servicer resource itself. - * - * @param resid Command Resource ID - * @param cmd Command Command ID - * @param payload Command write payload buffer - * @param payload_len Length of the payload buffer - * @return CONTROL_SUCCESS if write command processed successfully. contro_ret_t error status otherwise. - */ -control_ret_t servicer_write_cmd(control_resource_info_t *res_info, control_cmd_t cmd, const uint8_t *payload, size_t payload_len); - -/** - * @brief Function for handling read commands directed to the servicer resource itself. - * - * @param resid Command Resource ID - * @param cmd Command Command ID - * @param payload Payload buffer to populate with the read response - * @param payload_len Length of the payload buffer - * @return CONTROL_SUCCESS if read command processed successfully. contro_ret_t error status otherwise. - */ -control_ret_t servicer_read_cmd(control_resource_info_t *res_info, control_cmd_t cmd, uint8_t *payload, size_t payload_len); diff --git a/examples/ffd/src/main.c b/examples/ffd/src/main.c index 7fc1d773..eb14930b 100644 --- a/examples/ffd/src/main.c +++ b/examples/ffd/src/main.c @@ -30,9 +30,6 @@ #include "gpio_ctrl/gpi_ctrl.h" #include "gpio_ctrl/leds.h" #include "intent_handler/intent_handler.h" -#if appconfI2C_SLAVE_ENABLED -#include "intent_servicer.h" -#endif #if appconfRECOVER_MCLK_I2S_APP_PLL /* Config headers for sw_pll */ @@ -273,19 +270,6 @@ void startup_task(void *arg) #endif #endif -#if appconfI2C_SLAVE_ENABLED && ON_TILE(I2C_CTRL_TILE_NO) - // Initialise control related things - servicer_t servicer_intent; - intent_servicer_init(&servicer_intent); - - xTaskCreate((TaskFunction_t)intent_servicer, - "intent servicer", - RTOS_THREAD_STACK_SIZE(intent_servicer), - &servicer_intent, - appconfDEVICE_CONTROL_I2C_PRIORITY, - NULL); -#endif - #if ON_TILE(0) led_task_create(appconfLED_TASK_PRIORITY, NULL); #endif diff --git a/examples/ffva/src/dfu_int/dfu_servicer.c b/examples/ffva/src/dfu_int/dfu_servicer.c index dfc5cc18..0606ad1c 100644 --- a/examples/ffva/src/dfu_int/dfu_servicer.c +++ b/examples/ffva/src/dfu_int/dfu_servicer.c @@ -114,7 +114,7 @@ control_ret_t dfu_servicer_read_cmd(control_resource_info_t *res_info, control_c payload[2] = time_mid; payload[3] = time_high; payload[4] = retval.next_state; - + break; } @@ -130,7 +130,7 @@ control_ret_t dfu_servicer_read_cmd(control_resource_info_t *res_info, control_c { debug_printf("DFU_CONTROLLER_SERVICER_RESID_DFU_TRANSFERBLOCK\n"); uint16_t transferblock = dfu_int_get_transfer_block(); - + uint8_t tb_high, tb_low; tb_low = (uint8_t)(transferblock & 0xFF); tb_high = (uint8_t)((transferblock >> 8) & 0xFF); diff --git a/modules/asr/intent_engine/intent_engine.c b/modules/asr/intent_engine/intent_engine.c index 2d258a5c..e8d231c6 100644 --- a/modules/asr/intent_engine/intent_engine.c +++ b/modules/asr/intent_engine/intent_engine.c @@ -113,7 +113,7 @@ static void timeout_event_handler(TimerHandle_t pxTimer) } } asr_result_t last_asr_result = {0}; -uint32_t detection_number = 0; + #pragma stackfunction 1000 void intent_engine_task(void *args) { @@ -171,7 +171,7 @@ void intent_engine_task(void *args) asr_error = asr_get_result(asr_ctx, &asr_result); memcpy(&last_asr_result, &asr_result, sizeof(asr_result_t)); - detection_number++; + if (asr_error != ASR_OK) continue; word_id = asr_result.id; From 4f004e29629307d45efd00103f52265ef505206a Mon Sep 17 00:00:00 2001 From: Luciano Martin Date: Fri, 2 Aug 2024 09:13:09 +0100 Subject: [PATCH 08/34] Remove USB code --- .../XK_VOICE_L71/platform/platform_conf.h | 8 -- examples/ffd/ffd_i2s_input_cyberon.cmake | 1 - examples/ffd/src/tusb_config.h | 136 ------------------ 3 files changed, 145 deletions(-) delete mode 100644 examples/ffd/src/tusb_config.h diff --git a/examples/ffd/bsp_config/XK_VOICE_L71/platform/platform_conf.h b/examples/ffd/bsp_config/XK_VOICE_L71/platform/platform_conf.h index 515f1f2d..306a3d32 100644 --- a/examples/ffd/bsp_config/XK_VOICE_L71/platform/platform_conf.h +++ b/examples/ffd/bsp_config/XK_VOICE_L71/platform/platform_conf.h @@ -89,14 +89,6 @@ /* Other required defines */ /*****************************************/ -#ifndef APP_CONTROL_TRANSPORT_COUNT -#define APP_CONTROL_TRANSPORT_COUNT appconfI2C_SLAVE_ENABLED -#endif // APP_CONTROL_TRANSPORT_COUNT - -#ifndef appconf_CONTROL_I2C_DEVICE_ADDR -#define appconf_CONTROL_I2C_DEVICE_ADDR 0x42 -#endif /* appconf_CONTROL_I2C_DEVICE_ADDR*/ - #ifndef appconf_CONTROL_I2C_DEVICE_ADDR #define appconf_CONTROL_I2C_DEVICE_ADDR 0x42 #endif /* appconf_CONTROL_I2C_DEVICE_ADDR*/ diff --git a/examples/ffd/ffd_i2s_input_cyberon.cmake b/examples/ffd/ffd_i2s_input_cyberon.cmake index 600a3bbc..3f460f13 100644 --- a/examples/ffd/ffd_i2s_input_cyberon.cmake +++ b/examples/ffd/ffd_i2s_input_cyberon.cmake @@ -105,7 +105,6 @@ set(APP_COMMON_LINK_LIBRARIES sln_voice::app::asr::intent_engine sln_voice::app::asr::intent_handler sln_voice::app::ffd::xk_voice_l71 - rtos::freertos_usb lib_src lib_sw_pll ) diff --git a/examples/ffd/src/tusb_config.h b/examples/ffd/src/tusb_config.h deleted file mode 100644 index ac13616f..00000000 --- a/examples/ffd/src/tusb_config.h +++ /dev/null @@ -1,136 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2019 Ha Thach (tinyusb.org) - * Copyright (c) 2021 XMOS LIMITED - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - */ - -#ifndef _TUSB_CONFIG_H_ -#define _TUSB_CONFIG_H_ - -#include -#include "app_conf.h" -#include "audio_pipeline.h" -#include "rtos_printf.h" - -#define appconfUSB_INTERRUPT_CORE 2 /* Must be kept off I/O cores. Best kept off core 0 with the tick ISR. */ -#define appconfUSB_SOF_INTERRUPT_CORE 3 /* Must be kept off I/O cores. Best kept off cores with other ISRs. */ -#define appconfXUD_IO_CORE 1 /* Must be kept off core 0 with the RTOS tick ISR */ -#define appconfUSB_AUDIO_SAMPLE_RATE 48000 - -//-------------------------------------------------------------------- -// COMMON CONFIGURATION -//-------------------------------------------------------------------- - -#define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | OPT_MODE_HIGH_SPEED) -#define CFG_TUSB_OS OPT_OS_CUSTOM - -#ifndef CFG_TUSB_DEBUG -#define CFG_TUSB_DEBUG 0 -#endif - -#define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(8))) - -#ifndef CFG_TUSB_DEBUG_PRINTF -#ifdef rtos_printf -#define CFG_TUSB_DEBUG_PRINTF rtos_printf -#endif -#endif - -//-------------------------------------------------------------------- -// DEVICE CONFIGURATION -//-------------------------------------------------------------------- - -#define CFG_TUD_EP_MAX 12 -#define CFG_TUD_TASK_QUEUE_SZ 8 -#define CFG_TUD_ENDPOINT0_SIZE 64 - -#define CFG_TUD_XCORE_INTERRUPT_CORE appconfUSB_INTERRUPT_CORE -#define CFG_TUD_XCORE_SOF_INTERRUPT_CORE appconfUSB_SOF_INTERRUPT_CORE -#define CFG_TUD_XCORE_IO_CORE_MASK (1 << appconfXUD_IO_CORE) - -//------------- CLASS -------------// -#define CFG_TUD_CDC 0 -#define CFG_TUD_MSC 0 -#define CFG_TUD_HID 0 -#define CFG_TUD_MIDI 0 -#define CFG_TUD_AUDIO 1 -#define CFG_TUD_VENDOR 0 -#define CFG_TUD_DFU 1 - -//-------------------------------------------------------------------- -// DFU DRIVER CONFIGURATION -//-------------------------------------------------------------------- -// DFU buffer size, it has to be set to the buffer size used in TUD_DFU_DESCRIPTOR -#define CFG_TUD_DFU_XFER_BUFSIZE 4096 - -//-------------------------------------------------------------------- -// AUDIO CLASS DRIVER CONFIGURATION -//-------------------------------------------------------------------- -extern const uint16_t tud_audio_desc_lengths[CFG_TUD_AUDIO]; - -#define CFG_TUD_AUDIO_FUNC_1_DESC_LEN tud_audio_desc_lengths[0] -#define CFG_TUD_AUDIO_FUNC_1_N_AS_INT 1 -#define CFG_TUD_AUDIO_FUNC_1_CTRL_BUF_SZ 64 - -/* TODO make these configurable in app_conf? */ -#define CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX 2 -#define CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_RX 2 - -#if appconfUSB_AUDIO_MODE == appconfUSB_AUDIO_RELEASE -#define CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX 2 -#define CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX 2 -#else -#define CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX 6 -#define CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX 4 -#endif - -#if (appconfMIC_SRC_DEFAULT == appconfMIC_SRC_USB) -// In appconfMIC_SRC_USB, we wait forever for input mic and AEC reference channels -// will not overflow output -#define USB_AUDIO_RECV_DELAY portMAX_DELAY -#else -// In or any other mode, we do not wait for input AEC reference channels. -// The reference will be all zeros if no AEC reference is received. -// This is the typical mode. -#define USB_AUDIO_RECV_DELAY 0 -#endif - -// EP and buffer sizes -#define AUDIO_FRAMES_PER_USB_FRAME (appconfUSB_AUDIO_SAMPLE_RATE / 1000) -#if appconfUSB_AUDIO_SAMPLE_RATE == 48000 -#define USB_TASK_STACK_SIZE 2000 -#endif - -// To support USB Adaptive/Asynchronous, maximum packet size must be large enough to accommodate an extra set of samples per frame. -// Adding 1 to AUDIO_SAMPLES_PER_USB_FRAME allows this. -#define CFG_TUD_AUDIO_ENABLE_EP_IN 1 -#define CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ ((AUDIO_FRAMES_PER_USB_FRAME + 1) * CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX * CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX) -#define CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ_MAX (CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ) // Maximum EP IN size for all AS alternate settings used -#define CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ - -#define CFG_TUD_AUDIO_ENABLE_EP_OUT 1 -#define CFG_TUD_AUDIO_FUNC_1_EP_OUT_SZ ((AUDIO_FRAMES_PER_USB_FRAME + 1) * CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_RX * CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX) -#define CFG_TUD_AUDIO_FUNC_1_EP_OUT_SZ_MAX (CFG_TUD_AUDIO_FUNC_1_EP_OUT_SZ + 2) // Maximum EP OUT size for all AS alternate settings used. Plus 2 for CRC -#define CFG_TUD_AUDIO_FUNC_1_EP_OUT_SW_BUF_SZ CFG_TUD_AUDIO_FUNC_1_EP_OUT_SZ*3 - -#endif /* _TUSB_CONFIG_H_ */ From 547d4d2cbfb1b202a1a3caadd115f8ecc600940d Mon Sep 17 00:00:00 2001 From: Luciano Martin Date: Fri, 2 Aug 2024 09:20:46 +0100 Subject: [PATCH 09/34] Move code to new files --- .../XK_VOICE_L71/platform/platform_start.c | 43 +---------------- examples/ffd/src/i2c_reg_handling.c | 46 +++++++++++++++++++ examples/ffd/src/i2c_reg_handling.h | 20 ++++++++ 3 files changed, 67 insertions(+), 42 deletions(-) create mode 100644 examples/ffd/src/i2c_reg_handling.c create mode 100644 examples/ffd/src/i2c_reg_handling.h diff --git a/examples/ffd/bsp_config/XK_VOICE_L71/platform/platform_start.c b/examples/ffd/bsp_config/XK_VOICE_L71/platform/platform_start.c index 4ebde1a4..6be13160 100644 --- a/examples/ffd/bsp_config/XK_VOICE_L71/platform/platform_start.c +++ b/examples/ffd/bsp_config/XK_VOICE_L71/platform/platform_start.c @@ -14,7 +14,7 @@ #include "platform_conf.h" #include "platform/driver_instances.h" #include "dac3101.h" -#include "asr.h" +#include "i2c_reg_handling.h" extern asr_result_t last_asr_result; @@ -51,47 +51,6 @@ static void i2c_master_start(void) #endif } -#define WAKEWORD_REG_ADDRESS_START 0x40 -#define WAKEWORD_REG_ADDRESS_END 0x49 -#define WRITE_REQUEST_MIN_LEN 1 - -RTOS_I2C_SLAVE_CALLBACK_ATTR -size_t read_device_reg(rtos_i2c_slave_t *ctx, - asr_result_t *last_asr_result, - uint8_t **data) -{ - uint8_t * data_p = *data; - uint8_t reg_addr = data_p[0]; - uint8_t reg_value = 0; - if (reg_addr >= WAKEWORD_REG_ADDRESS_START && reg_addr <= WAKEWORD_REG_ADDRESS_END) { - if (last_asr_result->id == reg_addr - WAKEWORD_REG_ADDRESS_START + 1) - { - uint8_t score = (uint8_t) last_asr_result->score&0xF; - printf("Found wakeword information: ID %d, score %d\n", last_asr_result->id, score); - reg_value = score; - } else { - reg_value = 0; - } - } else { - reg_value = reg_addr - 1; - } - data_p[0] = reg_value; - printf("Read from register 0x%02X value 0x%02X\n", reg_addr, reg_value); - return 1; -} - -RTOS_I2C_SLAVE_CALLBACK_ATTR -void write_device_reg(rtos_i2c_slave_t *ctx, - void *app_data, - uint8_t *data, - size_t len) -{ - // If the length is lower than WRITE_REQUEST_MIN_LEN, it is a read request - if (len > WRITE_REQUEST_MIN_LEN) { - printf("Write to register 0x%02X value 0x%02X (len %d)\n", data[0], data[1], len); - } -} - static void i2c_slave_start(void) { #if appconfI2C_SLAVE_ENABLED && ON_TILE(I2C_CTRL_TILE_NO) diff --git a/examples/ffd/src/i2c_reg_handling.c b/examples/ffd/src/i2c_reg_handling.c new file mode 100644 index 00000000..eeffb922 --- /dev/null +++ b/examples/ffd/src/i2c_reg_handling.c @@ -0,0 +1,46 @@ + +// Copyright 2024 XMOS LIMITED. +// This Software is subject to the terms of the XMOS Public Licence: Version 1. + +#include "i2c_reg_handling.h" + +#define WAKEWORD_REG_ADDRESS_START 0x40 +#define WAKEWORD_REG_ADDRESS_END 0x49 +#define WRITE_REQUEST_MIN_LEN 1 + +RTOS_I2C_SLAVE_CALLBACK_ATTR +size_t read_device_reg(rtos_i2c_slave_t *ctx, + asr_result_t *last_asr_result, + uint8_t **data) +{ + uint8_t * data_p = *data; + uint8_t reg_addr = data_p[0]; + uint8_t reg_value = 0; + if (reg_addr >= WAKEWORD_REG_ADDRESS_START && reg_addr <= WAKEWORD_REG_ADDRESS_END) { + if (last_asr_result->id == reg_addr - WAKEWORD_REG_ADDRESS_START + 1) + { + uint8_t score = (uint8_t) last_asr_result->score&0xF; + printf("Found wakeword information: ID %d, score %d\n", last_asr_result->id, score); + reg_value = score; + } else { + reg_value = 0; + } + } else { + reg_value = reg_addr - 1; + } + data_p[0] = reg_value; + printf("Read from register 0x%02X value 0x%02X\n", reg_addr, reg_value); + return 1; +} + +RTOS_I2C_SLAVE_CALLBACK_ATTR +void write_device_reg(rtos_i2c_slave_t *ctx, + void *app_data, + uint8_t *data, + size_t len) +{ + // If the length is lower than WRITE_REQUEST_MIN_LEN, it is a read request + if (len > WRITE_REQUEST_MIN_LEN) { + printf("Write to register 0x%02X value 0x%02X (len %d)\n", data[0], data[1], len); + } +} \ No newline at end of file diff --git a/examples/ffd/src/i2c_reg_handling.h b/examples/ffd/src/i2c_reg_handling.h new file mode 100644 index 00000000..a8e1f303 --- /dev/null +++ b/examples/ffd/src/i2c_reg_handling.h @@ -0,0 +1,20 @@ +// Copyright 2024 XMOS LIMITED. +// This Software is subject to the terms of the XMOS Public Licence: Version 1. + +#include "rtos_i2c_slave.h" +#include "asr.h" + +#define WAKEWORD_REG_ADDRESS_START 0x40 +#define WAKEWORD_REG_ADDRESS_END 0x49 +#define WRITE_REQUEST_MIN_LEN 1 + +RTOS_I2C_SLAVE_CALLBACK_ATTR +size_t read_device_reg(rtos_i2c_slave_t *ctx, + asr_result_t *last_asr_result, + uint8_t **data); + +RTOS_I2C_SLAVE_CALLBACK_ATTR +void write_device_reg(rtos_i2c_slave_t *ctx, + void *app_data, + uint8_t *data, + size_t len); \ No newline at end of file From d0546a6bab36a07db86b7fc34499618a4552d71f Mon Sep 17 00:00:00 2001 From: Luciano Martin Date: Fri, 2 Aug 2024 09:30:10 +0100 Subject: [PATCH 10/34] Add comments --- examples/ffd/src/i2c_reg_handling.c | 13 ++++++++++++ examples/ffd/src/i2c_reg_handling.h | 33 +++++++++++++++++++++-------- 2 files changed, 37 insertions(+), 9 deletions(-) diff --git a/examples/ffd/src/i2c_reg_handling.c b/examples/ffd/src/i2c_reg_handling.c index eeffb922..50f75f6f 100644 --- a/examples/ffd/src/i2c_reg_handling.c +++ b/examples/ffd/src/i2c_reg_handling.c @@ -4,8 +4,19 @@ #include "i2c_reg_handling.h" +/** + * @brief Start address for wakeword register. + */ #define WAKEWORD_REG_ADDRESS_START 0x40 + +/** + * @brief End address for wakeword register. + */ #define WAKEWORD_REG_ADDRESS_END 0x49 + +/** + * @brief Minimum length for a write request. + */ #define WRITE_REQUEST_MIN_LEN 1 RTOS_I2C_SLAVE_CALLBACK_ATTR @@ -16,6 +27,8 @@ size_t read_device_reg(rtos_i2c_slave_t *ctx, uint8_t * data_p = *data; uint8_t reg_addr = data_p[0]; uint8_t reg_value = 0; + // If the register address is in the wakeword range, return the score of the last wakeword detection + // Otherwise, return the register address - 1 if (reg_addr >= WAKEWORD_REG_ADDRESS_START && reg_addr <= WAKEWORD_REG_ADDRESS_END) { if (last_asr_result->id == reg_addr - WAKEWORD_REG_ADDRESS_START + 1) { diff --git a/examples/ffd/src/i2c_reg_handling.h b/examples/ffd/src/i2c_reg_handling.h index a8e1f303..40cc739d 100644 --- a/examples/ffd/src/i2c_reg_handling.h +++ b/examples/ffd/src/i2c_reg_handling.h @@ -4,17 +4,32 @@ #include "rtos_i2c_slave.h" #include "asr.h" -#define WAKEWORD_REG_ADDRESS_START 0x40 -#define WAKEWORD_REG_ADDRESS_END 0x49 -#define WRITE_REQUEST_MIN_LEN 1 - +/** + * @brief Callback for reading data from a device register over I2C. + * Only one byte of data is read from the register. + * + * @param ctx Pointer to the I2C slave context. + * @param last_asr_result Pointer to the last Automatic Speech Recognition (ASR) result. + * @param data Pointer to a pointer to the the data received from the master device. + * + * @return The size of the data read. + */ RTOS_I2C_SLAVE_CALLBACK_ATTR size_t read_device_reg(rtos_i2c_slave_t *ctx, - asr_result_t *last_asr_result, - uint8_t **data); + asr_result_t *last_asr_result, + uint8_t **data); +/** + * @brief Callback for writing data to a device register over I2C. + * Only one byte of data is written to the register. + * + * @param ctx Pointer to the I2C slave context. + * @param app_data Pointer to application-specific data. Not used. + * @param data Pointer pointer to the the data received from the master device. + * @param len The length of the data to be written. + */ RTOS_I2C_SLAVE_CALLBACK_ATTR void write_device_reg(rtos_i2c_slave_t *ctx, - void *app_data, - uint8_t *data, - size_t len); \ No newline at end of file + void *app_data, + uint8_t *data, + size_t len); From 8ed9894ff9acc339b7cbea0dec832ff7429778e6 Mon Sep 17 00:00:00 2001 From: Luciano Martin Date: Fri, 2 Aug 2024 10:05:23 +0100 Subject: [PATCH 11/34] Fix typo --- examples/ffd/src/i2c_reg_handling.c | 116 ++++++++++++++-------------- examples/ffd/src/i2c_reg_handling.h | 70 ++++++++--------- 2 files changed, 93 insertions(+), 93 deletions(-) diff --git a/examples/ffd/src/i2c_reg_handling.c b/examples/ffd/src/i2c_reg_handling.c index 50f75f6f..4be77a75 100644 --- a/examples/ffd/src/i2c_reg_handling.c +++ b/examples/ffd/src/i2c_reg_handling.c @@ -1,59 +1,59 @@ - -// Copyright 2024 XMOS LIMITED. -// This Software is subject to the terms of the XMOS Public Licence: Version 1. - -#include "i2c_reg_handling.h" - -/** - * @brief Start address for wakeword register. - */ -#define WAKEWORD_REG_ADDRESS_START 0x40 - -/** - * @brief End address for wakeword register. - */ -#define WAKEWORD_REG_ADDRESS_END 0x49 - -/** - * @brief Minimum length for a write request. - */ -#define WRITE_REQUEST_MIN_LEN 1 - -RTOS_I2C_SLAVE_CALLBACK_ATTR -size_t read_device_reg(rtos_i2c_slave_t *ctx, - asr_result_t *last_asr_result, - uint8_t **data) -{ - uint8_t * data_p = *data; - uint8_t reg_addr = data_p[0]; - uint8_t reg_value = 0; - // If the register address is in the wakeword range, return the score of the last wakeword detection - // Otherwise, return the register address - 1 - if (reg_addr >= WAKEWORD_REG_ADDRESS_START && reg_addr <= WAKEWORD_REG_ADDRESS_END) { - if (last_asr_result->id == reg_addr - WAKEWORD_REG_ADDRESS_START + 1) - { - uint8_t score = (uint8_t) last_asr_result->score&0xF; - printf("Found wakeword information: ID %d, score %d\n", last_asr_result->id, score); - reg_value = score; - } else { - reg_value = 0; - } - } else { - reg_value = reg_addr - 1; - } - data_p[0] = reg_value; - printf("Read from register 0x%02X value 0x%02X\n", reg_addr, reg_value); - return 1; -} - -RTOS_I2C_SLAVE_CALLBACK_ATTR -void write_device_reg(rtos_i2c_slave_t *ctx, - void *app_data, - uint8_t *data, - size_t len) -{ - // If the length is lower than WRITE_REQUEST_MIN_LEN, it is a read request - if (len > WRITE_REQUEST_MIN_LEN) { - printf("Write to register 0x%02X value 0x%02X (len %d)\n", data[0], data[1], len); - } + +// Copyright 2024 XMOS LIMITED. +// This Software is subject to the terms of the XMOS Public Licence: Version 1. + +#include "i2c_reg_handling.h" + +/** + * @brief Start address for wakeword register. + */ +#define WAKEWORD_REG_ADDRESS_START 0x40 + +/** + * @brief End address for wakeword register. + */ +#define WAKEWORD_REG_ADDRESS_END 0x49 + +/** + * @brief Minimum length for a write request. + */ +#define WRITE_REQUEST_MIN_LEN 1 + +RTOS_I2C_SLAVE_CALLBACK_ATTR +size_t read_device_reg(rtos_i2c_slave_t *ctx, + asr_result_t *last_asr_result, + uint8_t **data) +{ + uint8_t * data_p = *data; + uint8_t reg_addr = data_p[0]; + uint8_t reg_value = 0; + // If the register address is in the wakeword range, return the score of the last wakeword detection + // Otherwise, return the register address - 1 + if (reg_addr >= WAKEWORD_REG_ADDRESS_START && reg_addr <= WAKEWORD_REG_ADDRESS_END) { + if (last_asr_result->id == reg_addr - WAKEWORD_REG_ADDRESS_START + 1) + { + uint8_t score = (uint8_t) last_asr_result->score&0xFF; + printf("Found wakeword information: ID %d, score %d\n", last_asr_result->id, score); + reg_value = score; + } else { + reg_value = 0; + } + } else { + reg_value = reg_addr - 1; + } + data_p[0] = reg_value; + printf("Read from register 0x%02X value 0x%02X\n", reg_addr, reg_value); + return 1; +} + +RTOS_I2C_SLAVE_CALLBACK_ATTR +void write_device_reg(rtos_i2c_slave_t *ctx, + void *app_data, + uint8_t *data, + size_t len) +{ + // If the length is lower than WRITE_REQUEST_MIN_LEN, it is a read request + if (len > WRITE_REQUEST_MIN_LEN) { + printf("Write to register 0x%02X value 0x%02X (len %d)\n", data[0], data[1], len); + } } \ No newline at end of file diff --git a/examples/ffd/src/i2c_reg_handling.h b/examples/ffd/src/i2c_reg_handling.h index 40cc739d..a29f501d 100644 --- a/examples/ffd/src/i2c_reg_handling.h +++ b/examples/ffd/src/i2c_reg_handling.h @@ -1,35 +1,35 @@ -// Copyright 2024 XMOS LIMITED. -// This Software is subject to the terms of the XMOS Public Licence: Version 1. - -#include "rtos_i2c_slave.h" -#include "asr.h" - -/** - * @brief Callback for reading data from a device register over I2C. - * Only one byte of data is read from the register. - * - * @param ctx Pointer to the I2C slave context. - * @param last_asr_result Pointer to the last Automatic Speech Recognition (ASR) result. - * @param data Pointer to a pointer to the the data received from the master device. - * - * @return The size of the data read. - */ -RTOS_I2C_SLAVE_CALLBACK_ATTR -size_t read_device_reg(rtos_i2c_slave_t *ctx, - asr_result_t *last_asr_result, - uint8_t **data); - -/** - * @brief Callback for writing data to a device register over I2C. - * Only one byte of data is written to the register. - * - * @param ctx Pointer to the I2C slave context. - * @param app_data Pointer to application-specific data. Not used. - * @param data Pointer pointer to the the data received from the master device. - * @param len The length of the data to be written. - */ -RTOS_I2C_SLAVE_CALLBACK_ATTR -void write_device_reg(rtos_i2c_slave_t *ctx, - void *app_data, - uint8_t *data, - size_t len); +// Copyright 2024 XMOS LIMITED. +// This Software is subject to the terms of the XMOS Public Licence: Version 1. + +#include "rtos_i2c_slave.h" +#include "asr.h" + +/** + * @brief Callback for reading data from a device register over I2C. + * Only one byte of data is read from the register. + * + * @param ctx Pointer to the I2C slave context. + * @param last_asr_result Pointer to the last Automatic Speech Recognition (ASR) result. + * @param data Pointer to a pointer to the the data received from the master device. + * + * @return The size of the data read. + */ +RTOS_I2C_SLAVE_CALLBACK_ATTR +size_t read_device_reg(rtos_i2c_slave_t *ctx, + asr_result_t *last_asr_result, + uint8_t **data); + +/** + * @brief Callback for writing data to a device register over I2C. + * Only one byte of data is written to the register. + * + * @param ctx Pointer to the I2C slave context. + * @param app_data Pointer to application-specific data. Not used. + * @param data Pointer pointer to the the data received from the master device. + * @param len The length of the data to be written. + */ +RTOS_I2C_SLAVE_CALLBACK_ATTR +void write_device_reg(rtos_i2c_slave_t *ctx, + void *app_data, + uint8_t *data, + size_t len); From b290aeeaa0c092dca8a9d66234eb30a96cbdf69e Mon Sep 17 00:00:00 2001 From: Luciano Martin Date: Fri, 2 Aug 2024 10:12:03 +0100 Subject: [PATCH 12/34] Remove masking --- examples/ffd/src/i2c_reg_handling.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/ffd/src/i2c_reg_handling.c b/examples/ffd/src/i2c_reg_handling.c index 4be77a75..803b5d35 100644 --- a/examples/ffd/src/i2c_reg_handling.c +++ b/examples/ffd/src/i2c_reg_handling.c @@ -32,7 +32,7 @@ size_t read_device_reg(rtos_i2c_slave_t *ctx, if (reg_addr >= WAKEWORD_REG_ADDRESS_START && reg_addr <= WAKEWORD_REG_ADDRESS_END) { if (last_asr_result->id == reg_addr - WAKEWORD_REG_ADDRESS_START + 1) { - uint8_t score = (uint8_t) last_asr_result->score&0xFF; + uint8_t score = (uint8_t) last_asr_result->score; printf("Found wakeword information: ID %d, score %d\n", last_asr_result->id, score); reg_value = score; } else { From 677043541b88876ee4289849da6baddd2181e83e Mon Sep 17 00:00:00 2001 From: Luciano Martin Date: Wed, 7 Aug 2024 16:24:20 +0100 Subject: [PATCH 13/34] Fix defines and make code more generic --- examples/ffd/src/app_conf.h | 11 +++++++++- examples/ffd/src/i2c_reg_handling.c | 31 +++++------------------------ examples/ffd/src/i2c_reg_handling.h | 9 +++++---- 3 files changed, 20 insertions(+), 31 deletions(-) diff --git a/examples/ffd/src/app_conf.h b/examples/ffd/src/app_conf.h index c0662230..024e4b0f 100644 --- a/examples/ffd/src/app_conf.h +++ b/examples/ffd/src/app_conf.h @@ -79,6 +79,11 @@ #define appconfINTENT_I2C_OUTPUT_DEVICE_ADDR 0x01 #endif +/* @brief Address for wakeword register to be read over I2C slave*/ +#ifndef appconfWAKEWORD_REG_ADDRESS +#define appconfWAKEWORD_REG_ADDRESS 0x01 +#endif + #ifndef appconfINTENT_UART_OUTPUT_ENABLED #define appconfINTENT_UART_OUTPUT_ENABLED 1 #endif @@ -115,10 +120,14 @@ #define appconfI2C_SLAVE_ENABLED 0 #endif -#if appconfINTENT_I2C_OUTPUT_ENABLED && ! appconfI2C_MASTER_ENABLED +#if appconfINTENT_I2C_OUTPUT_ENABLED && !appconfI2C_MASTER_ENABLED #error "I2C master must be enabled for intent I2C output" #endif +#if appconfI2C_SLAVE_ENABLED && appconfINTENT_I2C_OUTPUT_ENABLED +#error "I2C slave cannot be enabled when intent I2C output over I2C master is enabled" +#endif + #ifndef appconfAUDIO_PIPELINE_SKIP_IC_AND_VNR #define appconfAUDIO_PIPELINE_SKIP_IC_AND_VNR 0 #endif diff --git a/examples/ffd/src/i2c_reg_handling.c b/examples/ffd/src/i2c_reg_handling.c index 803b5d35..ef92530a 100644 --- a/examples/ffd/src/i2c_reg_handling.c +++ b/examples/ffd/src/i2c_reg_handling.c @@ -4,20 +4,10 @@ #include "i2c_reg_handling.h" -/** - * @brief Start address for wakeword register. - */ -#define WAKEWORD_REG_ADDRESS_START 0x40 - -/** - * @brief End address for wakeword register. - */ -#define WAKEWORD_REG_ADDRESS_END 0x49 - /** * @brief Minimum length for a write request. */ -#define WRITE_REQUEST_MIN_LEN 1 +#define WRITE_REQUEST_MIN_LEN 1 RTOS_I2C_SLAVE_CALLBACK_ATTR size_t read_device_reg(rtos_i2c_slave_t *ctx, @@ -26,20 +16,9 @@ size_t read_device_reg(rtos_i2c_slave_t *ctx, { uint8_t * data_p = *data; uint8_t reg_addr = data_p[0]; - uint8_t reg_value = 0; - // If the register address is in the wakeword range, return the score of the last wakeword detection - // Otherwise, return the register address - 1 - if (reg_addr >= WAKEWORD_REG_ADDRESS_START && reg_addr <= WAKEWORD_REG_ADDRESS_END) { - if (last_asr_result->id == reg_addr - WAKEWORD_REG_ADDRESS_START + 1) - { - uint8_t score = (uint8_t) last_asr_result->score; - printf("Found wakeword information: ID %d, score %d\n", last_asr_result->id, score); - reg_value = score; - } else { - reg_value = 0; - } - } else { - reg_value = reg_addr - 1; + uint8_t reg_value = -1; + if (reg_addr == appconfWAKEWORD_REG_ADDRESS) { + reg_value = last_asr_result->id; } data_p[0] = reg_value; printf("Read from register 0x%02X value 0x%02X\n", reg_addr, reg_value); @@ -56,4 +35,4 @@ void write_device_reg(rtos_i2c_slave_t *ctx, if (len > WRITE_REQUEST_MIN_LEN) { printf("Write to register 0x%02X value 0x%02X (len %d)\n", data[0], data[1], len); } -} \ No newline at end of file +} diff --git a/examples/ffd/src/i2c_reg_handling.h b/examples/ffd/src/i2c_reg_handling.h index a29f501d..01ad7e0e 100644 --- a/examples/ffd/src/i2c_reg_handling.h +++ b/examples/ffd/src/i2c_reg_handling.h @@ -2,11 +2,12 @@ // This Software is subject to the terms of the XMOS Public Licence: Version 1. #include "rtos_i2c_slave.h" +#include "app_conf.h" #include "asr.h" /** - * @brief Callback for reading data from a device register over I2C. - * Only one byte of data is read from the register. + * Callback for reading data from a device register over I2C. + * Only one byte of data is read from the register. * * @param ctx Pointer to the I2C slave context. * @param last_asr_result Pointer to the last Automatic Speech Recognition (ASR) result. @@ -20,8 +21,8 @@ size_t read_device_reg(rtos_i2c_slave_t *ctx, uint8_t **data); /** - * @brief Callback for writing data to a device register over I2C. - * Only one byte of data is written to the register. + * Callback for writing data to a device register over I2C. + * Only one byte of data is written to the register. * * @param ctx Pointer to the I2C slave context. * @param app_data Pointer to application-specific data. Not used. From a1f111d117d02ee548604728582a102ce3744ace Mon Sep 17 00:00:00 2001 From: Luciano Martin Date: Wed, 7 Aug 2024 16:56:01 +0100 Subject: [PATCH 14/34] Update documentation --- .../ffd/deploying/configuration.rst | 51 +++++++++++++++++-- .../XK_VOICE_L71/platform/platform_conf.h | 8 --- .../XK_VOICE_L71/platform/platform_init.c | 2 +- examples/ffd/src/app_conf.h | 4 ++ .../platform/platform_conf.h | 6 +-- .../platform/platform_init.c | 2 +- .../XK_VOICE_L71/platform/platform_conf.h | 6 +-- .../XK_VOICE_L71/platform/platform_init.c | 2 +- 8 files changed, 60 insertions(+), 21 deletions(-) diff --git a/doc/programming_guide/ffd/deploying/configuration.rst b/doc/programming_guide/ffd/deploying/configuration.rst index 0d130cf3..1d5dd208 100644 --- a/doc/programming_guide/ffd/deploying/configuration.rst +++ b/doc/programming_guide/ffd/deploying/configuration.rst @@ -4,7 +4,7 @@ Configuring the Firmware ======================== -The default application performs as described in the :ref:`sln_voice_ffd_overview`. There are numerous compile time options that can be added to change the example design without requiring code changes. To change the options explained in the table below, add the desired configuration variables to the APP_COMPILE_DEFINITIONS cmake variable located `here `_. +The default application performs as described in the :ref:`sln_voice_ffd_overview`. There are numerous compile time options that can be added to change the example design without requiring code changes. To change the options explained in the table below, add the desired configuration variables to the APP_COMPILE_DEFINITIONS cmake variable in the ``.cmake`` file located in the ``examples/ffd/`` folder. If options are changed, the application firmware must be rebuilt. @@ -37,6 +37,21 @@ If options are changed, the application firmware must be rebuilt. * - appconfINTENT_I2C_OUTPUT_ENABLED - Enables/disables the |I2C| intent message - 1 + * - appconfI2C_MASTER_ENABLED + - Enabled the |I2C| master mode to configure the DAC and send the intent message + - 1 + * - appconfINTENT_I2C_OUTPUT_DEVICE_ADDR + - Sets the |I2C| address to transmit the intent to via the |I2C| master interface + - 0x01 + * - appconfI2C_SALVE_ENABLED + - Enabled the |I2C| slave mode to read the device register with the intent message + - 0 + * - appconfI2C_SLAVE_DEVICE_ADDR + - Sets the |I2C| address to read the intent message from via the |I2C| slave interface + - 0x42 + * - appconfINTENT_I2C_REG_ADDRESS + - Sets the |I2C| register to store the intent message, this value can be read via the |I2C| slave interface + - 0x01 * - appconfUART_BAUD_RATE - Sets the baud rate for the UART tx intent interface - 9600 @@ -52,9 +67,6 @@ If options are changed, the application firmware must be rebuilt. * - appconfRECOVER_MCLK_I2S_APP_PLL - Enables/disables the recovery of the MCLK from the Software PLL application; this removes the need to use an external MCLK. - 0 - * - appconfINTENT_I2C_OUTPUT_DEVICE_ADDR - - Sets the |I2C| slave address to transmit the intent to - - 0x01 * - appconfINTENT_TRANSPORT_DELAY_MS - Sets the delay between host wake up requested and |I2C| and UART keyword code transmission - 50 @@ -78,3 +90,34 @@ If options are changed, the application firmware must be rebuilt. The ``example_ffd_i2s_input_cyberon`` has different default values from the ones in the table above. The list of updated values can be found in the ``APP_COMPILE_DEFINITIONS`` list in ``examples\ffd\ffd_i2s_input_cyberon.cmake``. + +Configuring the |I2C| interfaces +-------------------------------- + +The |I2C| interfaces are used to communicate with the DAC and the host. The |I2C| interface can be configured as a master or slave. +The |I2C| master is used to send the intent message to the host, and the |I2C| slave is used to read the intent message from the host. +The |I2C| master and slave can be enabled or disabled by setting the ``appconfI2C_MASTER_ENABLED`` and ``appconfI2C_SLAVE_ENABLED`` configuration variables. +To send the intent ID via |I2C| master interface when a command is detected, the following variables must be set: + + - ``appconfINTENT_I2C_OUTPUT_ENABLED`` must be set to 1. + - ``appconfI2C_MASTER_ENABLED`` must be set to 1. + - ``appconfINTENT_I2C_OUTPUT_DEVICE_ADDR`` must be set to desired address used by the |I2C| slave device. + - ``appconfI2C_SLAVE_ENABLED`` must be set to 0. + +The retrieve the intent message from the host via the |I2C| slave interface, the following variables must be set: + + - ``appconfI2C_SLAVE_ENABLED`` must be set to 1. + - ``appconfI2C_SLAVE_DEVICE_ADDR`` must be set to the desired address used by the |I2C| master device. + - ``appconfINTENT_I2C_REG_ADDRESS`` must be set to the desired register read by of the |I2C| master device. + - ``appconfINTENT_I2C_OUTPUT_ENABLED`` must be set to 0. + +The handling of the |I2C| slave registers is done in the ``examples\ffd\src\i2c_reg_handling.c`` file. The vatiable ``appconfINTENT_I2C_REG_ADDRESS`` is used in the callback function ``read_device_reg()``. + +Configuring the |I2S| interfaces +-------------------------------- + +The |I2S| interface can be configured as a master or slave. The |I2S| interface is used to receive the audio data over the |I2S| interface. +The |I2S| interface can be enabled or disabled by setting the ``appconfI2S_MODE`` configuration variable either to ``appconfI2S_MODE_MASTER`` or ``appconfI2S_MODE_SLAVE``. +The sample rate of the |I2S| interface can be set by changing the ``appconfI2S_AUDIO_SAMPLE_RATE`` configuration variable. +The MCLK can be recovered from the Software PLL application by setting the ``appconfRECOVER_MCLK_I2S_APP_PLL`` configuration variable to 1, this will remove the need to use an external MCLK. + diff --git a/examples/ffd/bsp_config/XK_VOICE_L71/platform/platform_conf.h b/examples/ffd/bsp_config/XK_VOICE_L71/platform/platform_conf.h index 306a3d32..40d68c24 100644 --- a/examples/ffd/bsp_config/XK_VOICE_L71/platform/platform_conf.h +++ b/examples/ffd/bsp_config/XK_VOICE_L71/platform/platform_conf.h @@ -85,14 +85,6 @@ #define appconfPIPELINE_AUDIO_SAMPLE_RATE 16000 #endif /* appconfPIPELINE_AUDIO_SAMPLE_RATE */ -/*****************************************/ -/* Other required defines */ -/*****************************************/ - -#ifndef appconf_CONTROL_I2C_DEVICE_ADDR -#define appconf_CONTROL_I2C_DEVICE_ADDR 0x42 -#endif /* appconf_CONTROL_I2C_DEVICE_ADDR*/ - /*****************************************/ /* I/O Task Priorities */ /*****************************************/ diff --git a/examples/ffd/bsp_config/XK_VOICE_L71/platform/platform_init.c b/examples/ffd/bsp_config/XK_VOICE_L71/platform/platform_init.c index 7ab6d2ea..03cdf389 100644 --- a/examples/ffd/bsp_config/XK_VOICE_L71/platform/platform_init.c +++ b/examples/ffd/bsp_config/XK_VOICE_L71/platform/platform_init.c @@ -77,7 +77,7 @@ static void i2c_init(void) (1 << appconfI2C_IO_CORE), PORT_I2C_SCL, PORT_I2C_SDA, - appconf_CONTROL_I2C_DEVICE_ADDR); + appconfI2C_SLAVE_DEVICE_ADDR); #endif #if appconfI2C_MASTER_ENABLED diff --git a/examples/ffd/src/app_conf.h b/examples/ffd/src/app_conf.h index 024e4b0f..084324d1 100644 --- a/examples/ffd/src/app_conf.h +++ b/examples/ffd/src/app_conf.h @@ -120,6 +120,10 @@ #define appconfI2C_SLAVE_ENABLED 0 #endif +#ifndef appconfI2C_SLAVE_DEVICE_ADDR +#define appconfI2C_SLAVE_DEVICE_ADDR 0x42 +#endif + #if appconfINTENT_I2C_OUTPUT_ENABLED && !appconfI2C_MASTER_ENABLED #error "I2C master must be enabled for intent I2C output" #endif diff --git a/examples/ffva/bsp_config/XCORE-AI-EXPLORER/platform/platform_conf.h b/examples/ffva/bsp_config/XCORE-AI-EXPLORER/platform/platform_conf.h index bc5f6587..bfece44f 100644 --- a/examples/ffva/bsp_config/XCORE-AI-EXPLORER/platform/platform_conf.h +++ b/examples/ffva/bsp_config/XCORE-AI-EXPLORER/platform/platform_conf.h @@ -113,9 +113,9 @@ #define appconfEXTERNAL_MCLK 1 #endif /* appconfEXTERNAL_MCLK */ -#ifndef appconf_CONTROL_I2C_DEVICE_ADDR -#define appconf_CONTROL_I2C_DEVICE_ADDR 0x42 -#endif /* appconf_CONTROL_I2C_DEVICE_ADDR*/ +#ifndef appconfI2C_SLAVE_DEVICE_ADDR +#define appconfI2C_SLAVE_DEVICE_ADDR 0x42 +#endif /* appconfI2C_SLAVE_DEVICE_ADDR*/ #ifndef appconfSPI_OUTPUT_ENABLED #define appconfSPI_OUTPUT_ENABLED 0 diff --git a/examples/ffva/bsp_config/XCORE-AI-EXPLORER/platform/platform_init.c b/examples/ffva/bsp_config/XCORE-AI-EXPLORER/platform/platform_init.c index 70116ab8..6d11e5fb 100644 --- a/examples/ffva/bsp_config/XCORE-AI-EXPLORER/platform/platform_init.c +++ b/examples/ffva/bsp_config/XCORE-AI-EXPLORER/platform/platform_init.c @@ -94,7 +94,7 @@ static void i2c_init(void) (1 << appconfI2C_IO_CORE), PORT_I2C_SLAVE_SCL, PORT_I2C_SLAVE_SDA, - appconf_CONTROL_I2C_DEVICE_ADDR); + appconfI2C_SLAVE_DEVICE_ADDR); #endif #else static rtos_driver_rpc_t i2c_rpc_config; diff --git a/examples/ffva/bsp_config/XK_VOICE_L71/platform/platform_conf.h b/examples/ffva/bsp_config/XK_VOICE_L71/platform/platform_conf.h index dc989760..0405c7fb 100644 --- a/examples/ffva/bsp_config/XK_VOICE_L71/platform/platform_conf.h +++ b/examples/ffva/bsp_config/XK_VOICE_L71/platform/platform_conf.h @@ -124,9 +124,9 @@ #define appconfEXTERNAL_MCLK 1 #endif /* appconfEXTERNAL_MCLK */ -#ifndef appconf_CONTROL_I2C_DEVICE_ADDR -#define appconf_CONTROL_I2C_DEVICE_ADDR 0x42 -#endif /* appconf_CONTROL_I2C_DEVICE_ADDR*/ +#ifndef appconfI2C_SLAVE_DEVICE_ADDR +#define appconfI2C_SLAVE_DEVICE_ADDR 0x42 +#endif /* appconfI2C_SLAVE_DEVICE_ADDR*/ #ifndef appconfSPI_OUTPUT_ENABLED #define appconfSPI_OUTPUT_ENABLED 0 diff --git a/examples/ffva/bsp_config/XK_VOICE_L71/platform/platform_init.c b/examples/ffva/bsp_config/XK_VOICE_L71/platform/platform_init.c index 04620821..f47d20f0 100644 --- a/examples/ffva/bsp_config/XK_VOICE_L71/platform/platform_init.c +++ b/examples/ffva/bsp_config/XK_VOICE_L71/platform/platform_init.c @@ -115,7 +115,7 @@ static void i2c_init(void) (1 << appconfI2C_IO_CORE), PORT_I2C_SCL, PORT_I2C_SDA, - appconf_CONTROL_I2C_DEVICE_ADDR); + appconfI2C_SLAVE_DEVICE_ADDR); #endif #if ON_TILE(I2C_TILE_NO) From 071a3e4feafd98194079d32baf225e73fcc776b9 Mon Sep 17 00:00:00 2001 From: Luciano Martin Date: Wed, 7 Aug 2024 16:57:46 +0100 Subject: [PATCH 15/34] Update variable --- examples/ffd/src/i2c_reg_handling.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/ffd/src/i2c_reg_handling.c b/examples/ffd/src/i2c_reg_handling.c index ef92530a..29f88c19 100644 --- a/examples/ffd/src/i2c_reg_handling.c +++ b/examples/ffd/src/i2c_reg_handling.c @@ -17,7 +17,7 @@ size_t read_device_reg(rtos_i2c_slave_t *ctx, uint8_t * data_p = *data; uint8_t reg_addr = data_p[0]; uint8_t reg_value = -1; - if (reg_addr == appconfWAKEWORD_REG_ADDRESS) { + if (reg_addr == appconfINTENT_I2C_REG_ADDRESS) { reg_value = last_asr_result->id; } data_p[0] = reg_value; From ea9b92470710358d7e07aac3d1e4f2f02e0ce494 Mon Sep 17 00:00:00 2001 From: Luciano Martin Date: Thu, 8 Aug 2024 09:37:29 +0100 Subject: [PATCH 16/34] Update test --- test/asr/asr.cmake | 1 + 1 file changed, 1 insertion(+) diff --git a/test/asr/asr.cmake b/test/asr/asr.cmake index f3567622..0aaeb156 100644 --- a/test/asr/asr.cmake +++ b/test/asr/asr.cmake @@ -82,6 +82,7 @@ set(APP_COMPILE_DEFINITIONS XUD_CORE_CLOCK=600 XSCOPE_HOST_IO_ENABLED=1 XSCOPE_HOST_IO_TILE=0 + ASR_SENSORY=1 QSPI_FLASH_CALIBRATION_ADDRESS=${CALIBRATION_PATTERN_START_ADDRESS} QSPI_FLASH_MODEL_START_ADDRESS=${MODEL_START_ADDRESS} appconfASR_LIBRARY_ID=${TEST_ASR_LIBRARY_ID} From 2eec481d4393e99cf6f3d08cc74fa8f3e1f989db Mon Sep 17 00:00:00 2001 From: Luciano Martin Date: Thu, 8 Aug 2024 10:13:50 +0100 Subject: [PATCH 17/34] Fix ASR builds --- examples/ffd/src/app_conf.h | 4 ++-- examples/ffd/src/i2c_reg_handling.c | 4 ++++ modules/asr/Cyberon/DSpotter_asr.c | 8 +++++--- modules/asr/asr.h | 13 +++++-------- test/asr/asr.cmake | 11 ++++------- 5 files changed, 20 insertions(+), 20 deletions(-) diff --git a/examples/ffd/src/app_conf.h b/examples/ffd/src/app_conf.h index 084324d1..f04400ac 100644 --- a/examples/ffd/src/app_conf.h +++ b/examples/ffd/src/app_conf.h @@ -80,8 +80,8 @@ #endif /* @brief Address for wakeword register to be read over I2C slave*/ -#ifndef appconfWAKEWORD_REG_ADDRESS -#define appconfWAKEWORD_REG_ADDRESS 0x01 +#ifndef appconfINTENT_I2C_REG_ADDRESS +#define appconfINTENT_I2C_REG_ADDRESS 0x01 #endif #ifndef appconfINTENT_UART_OUTPUT_ENABLED diff --git a/examples/ffd/src/i2c_reg_handling.c b/examples/ffd/src/i2c_reg_handling.c index 29f88c19..8f042da6 100644 --- a/examples/ffd/src/i2c_reg_handling.c +++ b/examples/ffd/src/i2c_reg_handling.c @@ -14,6 +14,7 @@ size_t read_device_reg(rtos_i2c_slave_t *ctx, asr_result_t *last_asr_result, uint8_t **data) { +#if appconfI2C_SLAVE_ENABLED==1 uint8_t * data_p = *data; uint8_t reg_addr = data_p[0]; uint8_t reg_value = -1; @@ -22,6 +23,7 @@ size_t read_device_reg(rtos_i2c_slave_t *ctx, } data_p[0] = reg_value; printf("Read from register 0x%02X value 0x%02X\n", reg_addr, reg_value); +#endif return 1; } @@ -31,8 +33,10 @@ void write_device_reg(rtos_i2c_slave_t *ctx, uint8_t *data, size_t len) { +#if appconfI2C_SLAVE_ENABLED==1 // If the length is lower than WRITE_REQUEST_MIN_LEN, it is a read request if (len > WRITE_REQUEST_MIN_LEN) { printf("Write to register 0x%02X value 0x%02X (len %d)\n", data[0], data[1], len); } +#endif } diff --git a/modules/asr/Cyberon/DSpotter_asr.c b/modules/asr/Cyberon/DSpotter_asr.c index 3a7749eb..fab7f147 100644 --- a/modules/asr/Cyberon/DSpotter_asr.c +++ b/modules/asr/Cyberon/DSpotter_asr.c @@ -169,14 +169,16 @@ asr_error_t asr_get_result(asr_port_t *ctx, asr_result_t *result) { DBG_TRACE("\r\nGet %s, ID=%d, Score=%d, SG_Diff=%d, Energy=%d\r\n", szCommand, nCmdID, nCmdScore, nCmdSG, nCmdEnergy); result->id = nCmdID; - result->score = nCmdScore; result->sg_diff = nCmdSG; - result->energy = nCmdEnergy; + // The following result fields are not implemented + result->start_index = -1; + result->end_index = -1; + result->duration = -1; #if appconfINTENT_UART_DEBUG_INFO_ENABLED static char res_info[128]; snprintf(res_info, sizeof(res_info)-1, "ID:%d,Sc:%d,SGD:%d,En:%d\r\n", nCmdID, nCmdScore, nCmdSG, nCmdEnergy); // Enable the printout below to see the information sent over UART - rtos_printf(res_info); + // rtos_printf(res_info); rtos_uart_tx_write(uart_tx_ctx, (uint8_t*)&res_info, strlen(res_info)); #endif return ASR_OK; diff --git a/modules/asr/asr.h b/modules/asr/asr.h index 1dd5d218..4b6e496f 100644 --- a/modules/asr/asr.h +++ b/modules/asr/asr.h @@ -64,19 +64,16 @@ typedef struct asr_attributes_struct typedef struct asr_result_struct { uint16_t id; ///< Keyword or command ID -#if ASR_CYBERON==1 - uint32_t score; ///< The confidence score of the detection - uint32_t sg_diff; ///< The voice similarity of the detection - uint32_t energy; ///< The energy of the detection -#elif ASR_SENSORY==1 + + // The following fields are optional and may not be supported by all ASR ports uint16_t score; ///< The confidence score of the detection uint16_t gscore; ///< The garbage score int32_t start_index; ///< The audio sample index that corresponds to the start of the utterance int32_t end_index; ///< The audio sample index that corresponds to the end of the utterance int32_t duration; ///< THe length of the utterance in samples -#else - #error "Model has to be either Sensory or Cyberon" -#endif + uint32_t sg_diff; ///< The voice similarity of the detection + uint32_t energy; ///< The energy of the detection + void* reserved; ///< Reserved for future use } asr_result_t; diff --git a/test/asr/asr.cmake b/test/asr/asr.cmake index 0aaeb156..e222b122 100644 --- a/test/asr/asr.cmake +++ b/test/asr/asr.cmake @@ -48,6 +48,8 @@ if(${TEST_ASR} STREQUAL "SENSORY") set(MODEL_FILE ${FFD_SRC_ROOT}/model/english_usa/command-pc62w-6.4.0-op10-prod-net.bin.nibble_swapped) set(TEST_ASR_LIBRARY_ID 0) set(TEST_ASR_NAME test_asr_sensory) + set(ASR_FLAG ASR_SENSORY=1) + elseif(${TEST_ASR} STREQUAL "CYBERON") message(STATUS "Building Cyberon ASR test") set(ASR_LIBRARY sln_voice::app::asr::Cyberon) @@ -58,6 +60,7 @@ elseif(${TEST_ASR} STREQUAL "CYBERON") set(MODEL_FILE ${FFD_SRC_ROOT}/model/english_usa/Hello_XMOS_pack_WithTxt.bin.Enc.NibbleSwap) set(TEST_ASR_LIBRARY_ID 1) set(TEST_ASR_NAME test_asr_cyberon) + set(ASR_FLAG ASR_CYBERON=1) else() message(FATAL_ERROR "Unable to build ${TEST_ASR} test") endif() @@ -82,19 +85,13 @@ set(APP_COMPILE_DEFINITIONS XUD_CORE_CLOCK=600 XSCOPE_HOST_IO_ENABLED=1 XSCOPE_HOST_IO_TILE=0 - ASR_SENSORY=1 + ${ASR_FLAG} QSPI_FLASH_CALIBRATION_ADDRESS=${CALIBRATION_PATTERN_START_ADDRESS} QSPI_FLASH_MODEL_START_ADDRESS=${MODEL_START_ADDRESS} appconfASR_LIBRARY_ID=${TEST_ASR_LIBRARY_ID} appconfASR_BRICK_SIZE_SAMPLES=${ASR_BRICK_SIZE_SAMPLES} ) -if(${TEST_ASR} STREQUAL "SENSORY") - set(APP_COMPILE_DEFINITIONS - ${APP_COMPILE_DEFINITIONS} - ) -endif() - set(APP_LINK_OPTIONS -report ${CMAKE_CURRENT_LIST_DIR}/src/config.xscope From 4639dd61be4c4b813e10c7e6d7ca5096c99a7d21 Mon Sep 17 00:00:00 2001 From: Luciano Martin Date: Thu, 8 Aug 2024 13:32:15 +0100 Subject: [PATCH 18/34] Update fwk_rtos --- CHANGELOG.rst | 1 + modules/rtos | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index fc8aa04b..9fe40f4b 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -4,6 +4,7 @@ XCORE-VOICE change log 2.3.0 ----- + * CHANGED: Updated submodule fwk_rtos to version 3.2.0 from 3.0.5. * ADDED: FFVA INT example with Cyberon speech recognition engine and model (DSpotter v2.2.18.0). * CHANGED: Moved files in folders device_memory, gpio_ctrl, intent_engine and diff --git a/modules/rtos b/modules/rtos index 7be57246..44692113 160000 --- a/modules/rtos +++ b/modules/rtos @@ -1 +1 @@ -Subproject commit 7be57246f7541202b29f7cbab350a8b0e9a084f1 +Subproject commit 44692113625a04d85377ce4c4c909635a1c68932 From 3c9a00176f11d7434079aa68f181d895655e5a3b Mon Sep 17 00:00:00 2001 From: Luciano Martin Date: Thu, 8 Aug 2024 13:58:29 +0100 Subject: [PATCH 19/34] Tidy up --- .../ffd/deploying/configuration.rst | 47 +++++++++++-------- .../XK_VOICE_L71/platform/platform_init.c | 2 +- .../XK_VOICE_L71/platform/platform_start.c | 4 +- examples/ffd/ffd_i2s_input_cyberon.cmake | 1 - examples/ffd/src/app_conf.h | 4 -- examples/ffd/src/main.c | 6 +-- 6 files changed, 34 insertions(+), 30 deletions(-) diff --git a/doc/programming_guide/ffd/deploying/configuration.rst b/doc/programming_guide/ffd/deploying/configuration.rst index 1d5dd208..b7353258 100644 --- a/doc/programming_guide/ffd/deploying/configuration.rst +++ b/doc/programming_guide/ffd/deploying/configuration.rst @@ -94,30 +94,39 @@ If options are changed, the application firmware must be rebuilt. Configuring the |I2C| interfaces -------------------------------- -The |I2C| interfaces are used to communicate with the DAC and the host. The |I2C| interface can be configured as a master or slave. -The |I2C| master is used to send the intent message to the host, and the |I2C| slave is used to read the intent message from the host. +The |I2C| interfaces are used to configure the DAC and to communicate with the host. The |I2C| interface can be configured as a master and a slave. +The DAC must be configured at bootup via the |I2C| master interface. +The |I2C| master is used to send intent messages to the host, and the |I2C| slave is used to read intent messages from the host. + +.. note:: + Since the |I2C| interface cannot operate as both a master and a slave simultaneously, the FFD example design uses the |I2C| master interface to configure the DAC at bootup. + However, if the |I2C| slave interface is used to read intent messages, the |I2C| master interface will be disabled after the DAC configuration is complete. + The |I2C| master and slave can be enabled or disabled by setting the ``appconfI2C_MASTER_ENABLED`` and ``appconfI2C_SLAVE_ENABLED`` configuration variables. -To send the intent ID via |I2C| master interface when a command is detected, the following variables must be set: - - ``appconfINTENT_I2C_OUTPUT_ENABLED`` must be set to 1. - - ``appconfI2C_MASTER_ENABLED`` must be set to 1. - - ``appconfINTENT_I2C_OUTPUT_DEVICE_ADDR`` must be set to desired address used by the |I2C| slave device. - - ``appconfI2C_SLAVE_ENABLED`` must be set to 0. +To send the intent ID via the |I2C| master interface when a command is detected, set the following variables:: -The retrieve the intent message from the host via the |I2C| slave interface, the following variables must be set: + - ``appconfINTENT_I2C_OUTPUT_ENABLED`` to 1. + - ``appconfI2C_MASTER_ENABLED`` to 1. + - ``appconfINTENT_I2C_OUTPUT_DEVICE_ADDR`` to the desired address used by the |I2C| slave device. + - ``appconfI2C_SLAVE_ENABLED`` to 0. - - ``appconfI2C_SLAVE_ENABLED`` must be set to 1. - - ``appconfI2C_SLAVE_DEVICE_ADDR`` must be set to the desired address used by the |I2C| master device. - - ``appconfINTENT_I2C_REG_ADDRESS`` must be set to the desired register read by of the |I2C| master device. - - ``appconfINTENT_I2C_OUTPUT_ENABLED`` must be set to 0. +The retrieve the intent message from the host via the |I2C| slave interface, set the following variables: -The handling of the |I2C| slave registers is done in the ``examples\ffd\src\i2c_reg_handling.c`` file. The vatiable ``appconfINTENT_I2C_REG_ADDRESS`` is used in the callback function ``read_device_reg()``. + - ``appconfI2C_SLAVE_ENABLED`` to 1. + - ``appconfI2C_SLAVE_DEVICE_ADDR`` to the desired address used by the |I2C| master device. + - ``appconfINTENT_I2C_REG_ADDRESS`` to the desired register read by of the |I2C| master device. + - ``appconfINTENT_I2C_OUTPUT_ENABLED`` to 0, this will disable the |I2C| master interface. -Configuring the |I2S| interfaces --------------------------------- +The handling of the |I2C| slave registers is done in the ``examples\ffd\src\i2c_reg_handling.c`` file. The variable ``appconfINTENT_I2C_REG_ADDRESS`` is used in the callback function ``read_device_reg()``. + +Configuring the |I2S| interface +------------------------------- -The |I2S| interface can be configured as a master or slave. The |I2S| interface is used to receive the audio data over the |I2S| interface. -The |I2S| interface can be enabled or disabled by setting the ``appconfI2S_MODE`` configuration variable either to ``appconfI2S_MODE_MASTER`` or ``appconfI2S_MODE_SLAVE``. -The sample rate of the |I2S| interface can be set by changing the ``appconfI2S_AUDIO_SAMPLE_RATE`` configuration variable. -The MCLK can be recovered from the Software PLL application by setting the ``appconfRECOVER_MCLK_I2S_APP_PLL`` configuration variable to 1, this will remove the need to use an external MCLK. +The |I2S| interface is used to receive the audio data from the host. The |I2S| interface can be configured as either a master or a slave. +To configure the |I2S| interface, set the following variables: + - ``appconfUSE_I2S_INPUT`` to 1. + - ``appconfI2S_MODE`` to the desired mode, either ``appconfI2S_MODE_MASTER`` or ``appconfI2S_MODE_SLAVE``. + - ``appconfI2S_AUDIO_SAMPLE_RATE`` to the desired sample rate, either 16000 or 48000. + - ``appconfRECOVER_MCLK_I2S_APP_PLL`` to 1 if an external MCLK is not available, otherwise set it to 0. diff --git a/examples/ffd/bsp_config/XK_VOICE_L71/platform/platform_init.c b/examples/ffd/bsp_config/XK_VOICE_L71/platform/platform_init.c index 03cdf389..de560177 100644 --- a/examples/ffd/bsp_config/XK_VOICE_L71/platform/platform_init.c +++ b/examples/ffd/bsp_config/XK_VOICE_L71/platform/platform_init.c @@ -176,7 +176,7 @@ static void mics_init(void) static void i2s_init(void) { -#if appconfI2S_ENABLED +#if appconfUSE_I2S_INPUT #if appconfI2S_MODE == appconfI2S_MODE_MASTER static rtos_driver_rpc_t i2s_rpc_config; #endif diff --git a/examples/ffd/bsp_config/XK_VOICE_L71/platform/platform_start.c b/examples/ffd/bsp_config/XK_VOICE_L71/platform/platform_start.c index 6be13160..77690d1a 100644 --- a/examples/ffd/bsp_config/XK_VOICE_L71/platform/platform_start.c +++ b/examples/ffd/bsp_config/XK_VOICE_L71/platform/platform_start.c @@ -69,7 +69,7 @@ static void i2c_slave_start(void) static void audio_codec_start(void) { -#if appconfI2S_ENABLED && appconfI2C_MASTER_ENABLED +#if appconfUSE_I2S_INPUT && appconfI2C_MASTER_ENABLED int ret = 0; #if ON_TILE(I2C_TILE_NO) if (dac3101_init(appconfI2S_AUDIO_SAMPLE_RATE) != 0) { @@ -95,7 +95,7 @@ static void mics_start(void) static void i2s_start(void) { -#if appconfI2S_ENABLED +#if appconfUSE_I2S_INPUT #if appconfI2S_MODE == appconfI2S_MODE_MASTER rtos_i2s_rpc_config(i2s_ctx, appconfI2S_RPC_PORT, appconfI2S_RPC_PRIORITY); #endif diff --git a/examples/ffd/ffd_i2s_input_cyberon.cmake b/examples/ffd/ffd_i2s_input_cyberon.cmake index 3f460f13..7d07d868 100644 --- a/examples/ffd/ffd_i2s_input_cyberon.cmake +++ b/examples/ffd/ffd_i2s_input_cyberon.cmake @@ -80,7 +80,6 @@ set(APP_COMPILE_DEFINITIONS appconfAUDIO_PLAYBACK_ENABLED=1 appconfI2S_MODE=appconfI2S_MODE_SLAVE appconfI2S_AUDIO_SAMPLE_RATE=48000 - appconfI2S_ENABLED=1 appconfI2C_SLAVE_ENABLED=1 appconfI2C_MASTER_ENABLED=0 appconfINTENT_I2C_OUTPUT_ENABLED=0 diff --git a/examples/ffd/src/app_conf.h b/examples/ffd/src/app_conf.h index f04400ac..12dee278 100644 --- a/examples/ffd/src/app_conf.h +++ b/examples/ffd/src/app_conf.h @@ -96,10 +96,6 @@ #define appconfUART_BAUD_RATE 9600 #endif -#ifndef appconfI2S_ENABLED -#define appconfI2S_ENABLED 1 -#endif - #ifndef appconfI2S_MODE_MASTER #define appconfI2S_MODE_MASTER 0 #endif diff --git a/examples/ffd/src/main.c b/examples/ffd/src/main.c index eb14930b..0c0f253f 100644 --- a/examples/ffd/src/main.c +++ b/examples/ffd/src/main.c @@ -15,7 +15,7 @@ /* Library headers */ #include "rtos_printf.h" -#if appconfI2S_ENABLED +#if appconfUSE_I2S_INPUT #include "src.h" #endif @@ -40,7 +40,7 @@ #define MEM_ANALYSIS_ENABLED 0 #endif -#if appconfI2S_ENABLED && (appconfI2S_MODE == appconfI2S_MODE_SLAVE) +#if appconfUSE_I2S_INPUT && (appconfI2S_MODE == appconfI2S_MODE_SLAVE) void i2s_slave_intertile() { int32_t tmp[appconfAUDIO_PIPELINE_FRAME_ADVANCE][appconfAUDIO_PIPELINE_CHANNELS]; @@ -252,7 +252,7 @@ void startup_task(void *arg) platform_start(); -#if ON_TILE(1) && appconfI2S_ENABLED && (appconfI2S_MODE == appconfI2S_MODE_SLAVE) +#if ON_TILE(1) && appconfUSE_I2S_INPUT && (appconfI2S_MODE == appconfI2S_MODE_SLAVE) xTaskCreate((TaskFunction_t) i2s_slave_intertile, "i2s_slave_intertile", From 29e620c86fa47c8094280b769b3e84578413535c Mon Sep 17 00:00:00 2001 From: Luciano Martin Date: Thu, 8 Aug 2024 15:05:59 +0100 Subject: [PATCH 20/34] Fix format --- doc/programming_guide/ffd/deploying/configuration.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/programming_guide/ffd/deploying/configuration.rst b/doc/programming_guide/ffd/deploying/configuration.rst index b7353258..4f222131 100644 --- a/doc/programming_guide/ffd/deploying/configuration.rst +++ b/doc/programming_guide/ffd/deploying/configuration.rst @@ -104,7 +104,7 @@ The |I2C| master is used to send intent messages to the host, and the |I2C| slav The |I2C| master and slave can be enabled or disabled by setting the ``appconfI2C_MASTER_ENABLED`` and ``appconfI2C_SLAVE_ENABLED`` configuration variables. -To send the intent ID via the |I2C| master interface when a command is detected, set the following variables:: +To send the intent ID via the |I2C| master interface when a command is detected, set the following variables: - ``appconfINTENT_I2C_OUTPUT_ENABLED`` to 1. - ``appconfI2C_MASTER_ENABLED`` to 1. @@ -115,7 +115,7 @@ The retrieve the intent message from the host via the |I2C| slave interface, set - ``appconfI2C_SLAVE_ENABLED`` to 1. - ``appconfI2C_SLAVE_DEVICE_ADDR`` to the desired address used by the |I2C| master device. - - ``appconfINTENT_I2C_REG_ADDRESS`` to the desired register read by of the |I2C| master device. + - ``appconfINTENT_I2C_REG_ADDRESS`` to the desired register read by the |I2C| master device. - ``appconfINTENT_I2C_OUTPUT_ENABLED`` to 0, this will disable the |I2C| master interface. The handling of the |I2C| slave registers is done in the ``examples\ffd\src\i2c_reg_handling.c`` file. The variable ``appconfINTENT_I2C_REG_ADDRESS`` is used in the callback function ``read_device_reg()``. From 434f8f0de2b64348bd4933e5adaa806b7f117a00 Mon Sep 17 00:00:00 2001 From: Luciano Martin Date: Thu, 8 Aug 2024 15:47:07 +0100 Subject: [PATCH 21/34] Update list --- CHANGELOG.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 9fe40f4b..4d5fd5b5 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -4,7 +4,6 @@ XCORE-VOICE change log 2.3.0 ----- - * CHANGED: Updated submodule fwk_rtos to version 3.2.0 from 3.0.5. * ADDED: FFVA INT example with Cyberon speech recognition engine and model (DSpotter v2.2.18.0). * CHANGED: Moved files in folders device_memory, gpio_ctrl, intent_engine and @@ -13,10 +12,11 @@ XCORE-VOICE change log * ADDED: Support for DFU over I2C for FFVA INT example. * ADDED: FFD example with I2S audio input to Cyberon speech recognition engine and model. - * CHANGED: Updated submodule fwk_rtos to version 3.1.0 from 3.0.5. - * ADDED: lib_sw_pll submodule v1.1.0. * REMOVED: flash settings in .xn files, as they are not required by XMOS Tools 15.2.x. + * ADDED: Support for reading registers over I2C slave in FFD examples. + * CHANGED: Updated submodule fwk_rtos to version 3.2.0 from 3.0.5. + * ADDED: lib_sw_pll submodule v1.1.0. 2.2.0 ----- From 2bd7debb4b16dada5b25450d598492f4683dac7d Mon Sep 17 00:00:00 2001 From: Luciano Martin Date: Fri, 9 Aug 2024 08:13:30 +0100 Subject: [PATCH 22/34] Fix comments --- examples/ffd/src/i2c_reg_handling.c | 6 +++--- examples/ffd/src/i2c_reg_handling.h | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/examples/ffd/src/i2c_reg_handling.c b/examples/ffd/src/i2c_reg_handling.c index 8f042da6..44417ee2 100644 --- a/examples/ffd/src/i2c_reg_handling.c +++ b/examples/ffd/src/i2c_reg_handling.c @@ -17,12 +17,12 @@ size_t read_device_reg(rtos_i2c_slave_t *ctx, #if appconfI2C_SLAVE_ENABLED==1 uint8_t * data_p = *data; uint8_t reg_addr = data_p[0]; - uint8_t reg_value = -1; + uint8_t reg_value = 0xFF; if (reg_addr == appconfINTENT_I2C_REG_ADDRESS) { reg_value = last_asr_result->id; } data_p[0] = reg_value; - printf("Read from register 0x%02X value 0x%02X\n", reg_addr, reg_value); + rtos_printf("Read from register 0x%02X value 0x%02X\n", reg_addr, reg_value); #endif return 1; } @@ -36,7 +36,7 @@ void write_device_reg(rtos_i2c_slave_t *ctx, #if appconfI2C_SLAVE_ENABLED==1 // If the length is lower than WRITE_REQUEST_MIN_LEN, it is a read request if (len > WRITE_REQUEST_MIN_LEN) { - printf("Write to register 0x%02X value 0x%02X (len %d)\n", data[0], data[1], len); + rtos_printf("Write to register 0x%02X value 0x%02X (len %d)\n", data[0], data[1], len); } #endif } diff --git a/examples/ffd/src/i2c_reg_handling.h b/examples/ffd/src/i2c_reg_handling.h index 01ad7e0e..449b13de 100644 --- a/examples/ffd/src/i2c_reg_handling.h +++ b/examples/ffd/src/i2c_reg_handling.h @@ -6,12 +6,12 @@ #include "asr.h" /** - * Callback for reading data from a device register over I2C. + * Callback for reading data from a device register over I2C slave. * Only one byte of data is read from the register. * * @param ctx Pointer to the I2C slave context. * @param last_asr_result Pointer to the last Automatic Speech Recognition (ASR) result. - * @param data Pointer to a pointer to the the data received from the master device. + * @param data Pointer to a pointer to the the data to be sent to the master device. * * @return The size of the data read. */ @@ -21,12 +21,12 @@ size_t read_device_reg(rtos_i2c_slave_t *ctx, uint8_t **data); /** - * Callback for writing data to a device register over I2C. + * Callback for writing data to a device register over I2C slave. * Only one byte of data is written to the register. * * @param ctx Pointer to the I2C slave context. * @param app_data Pointer to application-specific data. Not used. - * @param data Pointer pointer to the the data received from the master device. + * @param data Pointer to the the data received from the master device. * @param len The length of the data to be written. */ RTOS_I2C_SLAVE_CALLBACK_ATTR From c8e1a261fc109ac1f2527ae3cfc9f63e076a5f1a Mon Sep 17 00:00:00 2001 From: Luciano Martin Date: Fri, 9 Aug 2024 08:18:16 +0100 Subject: [PATCH 23/34] Fix text --- doc/programming_guide/ffd/deploying/configuration.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/programming_guide/ffd/deploying/configuration.rst b/doc/programming_guide/ffd/deploying/configuration.rst index 4f222131..eedd2972 100644 --- a/doc/programming_guide/ffd/deploying/configuration.rst +++ b/doc/programming_guide/ffd/deploying/configuration.rst @@ -38,13 +38,13 @@ If options are changed, the application firmware must be rebuilt. - Enables/disables the |I2C| intent message - 1 * - appconfI2C_MASTER_ENABLED - - Enabled the |I2C| master mode to configure the DAC and send the intent message + - Enables/disables the |I2C| master mode to configure the DAC and send the intent message - 1 * - appconfINTENT_I2C_OUTPUT_DEVICE_ADDR - Sets the |I2C| address to transmit the intent to via the |I2C| master interface - 0x01 - * - appconfI2C_SALVE_ENABLED - - Enabled the |I2C| slave mode to read the device register with the intent message + * - appconfI2C_SLAVE_ENABLED + - Enables/disables the |I2C| slave mode to read the device register with the intent message - 0 * - appconfI2C_SLAVE_DEVICE_ADDR - Sets the |I2C| address to read the intent message from via the |I2C| slave interface From 795ac29743ceb59813f06646c5eefeda3d4ed274 Mon Sep 17 00:00:00 2001 From: Luciano Martin Date: Fri, 9 Aug 2024 14:52:17 +0100 Subject: [PATCH 24/34] Address some comments --- .../ffd/deploying/configuration.rst | 14 +++++++------- examples/ffd/src/i2c_reg_handling.c | 1 - .../XK_VOICE_L71/platform/platform_conf.h | 2 +- modules/asr/Cyberon/DSpotter_asr.c | 1 + 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/doc/programming_guide/ffd/deploying/configuration.rst b/doc/programming_guide/ffd/deploying/configuration.rst index eedd2972..9be50891 100644 --- a/doc/programming_guide/ffd/deploying/configuration.rst +++ b/doc/programming_guide/ffd/deploying/configuration.rst @@ -41,16 +41,16 @@ If options are changed, the application firmware must be rebuilt. - Enables/disables the |I2C| master mode to configure the DAC and send the intent message - 1 * - appconfINTENT_I2C_OUTPUT_DEVICE_ADDR - - Sets the |I2C| address to transmit the intent to via the |I2C| master interface + - Sets the address of the |I2C| device receiving the intent via the |I2C| master interface - 0x01 * - appconfI2C_SLAVE_ENABLED - Enables/disables the |I2C| slave mode to read the device register with the intent message - 0 * - appconfI2C_SLAVE_DEVICE_ADDR - - Sets the |I2C| address to read the intent message from via the |I2C| slave interface + - Sets the address of the |I2C| device receiving the intent via the |I2C| slave interface - 0x42 * - appconfINTENT_I2C_REG_ADDRESS - - Sets the |I2C| register to store the intent message, this value can be read via the |I2C| slave interface + - Sets the address of the |I2C| register to store the intent message, this value can be read via the |I2C| slave interface - 0x01 * - appconfUART_BAUD_RATE - Sets the baud rate for the UART tx intent interface @@ -94,13 +94,13 @@ If options are changed, the application firmware must be rebuilt. Configuring the |I2C| interfaces -------------------------------- -The |I2C| interfaces are used to configure the DAC and to communicate with the host. The |I2C| interface can be configured as a master and a slave. +The |I2C| interfaces are used to configure the DAC and to communicate with the host. The |I2C| interface can be configured as a master or a slave. The DAC must be configured at bootup via the |I2C| master interface. -The |I2C| master is used to send intent messages to the host, and the |I2C| slave is used to read intent messages from the host. +The |I2C| master is used when the FFD example asynchronously sends intent messages to the host. The |I2C| slave is used when the host wants to read intent messages from the FFD example through polling. .. note:: - Since the |I2C| interface cannot operate as both a master and a slave simultaneously, the FFD example design uses the |I2C| master interface to configure the DAC at bootup. - However, if the |I2C| slave interface is used to read intent messages, the |I2C| master interface will be disabled after the DAC configuration is complete. + The |I2C| interface cannot operate as both master and slave simultaneously. The FFD example design uses the |I2C| master interface to configure the DAC at device initialisation. + However, if the host reads intent messages from the FFD example using the |I2C| slave interface, the |I2C| master interface will be disabled after the DAC configuration is complete. The |I2C| master and slave can be enabled or disabled by setting the ``appconfI2C_MASTER_ENABLED`` and ``appconfI2C_SLAVE_ENABLED`` configuration variables. diff --git a/examples/ffd/src/i2c_reg_handling.c b/examples/ffd/src/i2c_reg_handling.c index 44417ee2..95ed45d3 100644 --- a/examples/ffd/src/i2c_reg_handling.c +++ b/examples/ffd/src/i2c_reg_handling.c @@ -1,4 +1,3 @@ - // Copyright 2024 XMOS LIMITED. // This Software is subject to the terms of the XMOS Public Licence: Version 1. diff --git a/examples/ffva/bsp_config/XK_VOICE_L71/platform/platform_conf.h b/examples/ffva/bsp_config/XK_VOICE_L71/platform/platform_conf.h index 0405c7fb..81d68279 100644 --- a/examples/ffva/bsp_config/XK_VOICE_L71/platform/platform_conf.h +++ b/examples/ffva/bsp_config/XK_VOICE_L71/platform/platform_conf.h @@ -153,7 +153,7 @@ #endif /* appconfI2C_TASK_PRIORITY */ #ifndef appconfSPI_TASK_PRIORITY -#define appconfSPI_TASK_PRIORITY ( configMAX_PRIORITIES/2) +#define appconfSPI_TASK_PRIORITY (configMAX_PRIORITIES/2) #endif /* appconfSPI_TASK_PRIORITY */ #ifndef appconfDEVICE_CONTROL_I2C_PRIORITY diff --git a/modules/asr/Cyberon/DSpotter_asr.c b/modules/asr/Cyberon/DSpotter_asr.c index fab7f147..89c0f52a 100644 --- a/modules/asr/Cyberon/DSpotter_asr.c +++ b/modules/asr/Cyberon/DSpotter_asr.c @@ -170,6 +170,7 @@ asr_error_t asr_get_result(asr_port_t *ctx, asr_result_t *result) DBG_TRACE("\r\nGet %s, ID=%d, Score=%d, SG_Diff=%d, Energy=%d\r\n", szCommand, nCmdID, nCmdScore, nCmdSG, nCmdEnergy); result->id = nCmdID; result->sg_diff = nCmdSG; + result->energy = nCmdEnergy; // The following result fields are not implemented result->start_index = -1; result->end_index = -1; From 00c99d2707d8b0b1ee73311d2b8338f8a482225e Mon Sep 17 00:00:00 2001 From: Luciano Martin Date: Fri, 9 Aug 2024 15:12:01 +0100 Subject: [PATCH 25/34] Update doc/programming_guide/ffd/deploying/configuration.rst Co-authored-by: Michael Banther --- doc/programming_guide/ffd/deploying/configuration.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/programming_guide/ffd/deploying/configuration.rst b/doc/programming_guide/ffd/deploying/configuration.rst index 9be50891..89fdb1e4 100644 --- a/doc/programming_guide/ffd/deploying/configuration.rst +++ b/doc/programming_guide/ffd/deploying/configuration.rst @@ -111,7 +111,7 @@ To send the intent ID via the |I2C| master interface when a command is detected, - ``appconfINTENT_I2C_OUTPUT_DEVICE_ADDR`` to the desired address used by the |I2C| slave device. - ``appconfI2C_SLAVE_ENABLED`` to 0. -The retrieve the intent message from the host via the |I2C| slave interface, set the following variables: +To configure the FFD example so that the host can poll for the intent via the |I2C| slave interface, set the following variables: - ``appconfI2C_SLAVE_ENABLED`` to 1. - ``appconfI2C_SLAVE_DEVICE_ADDR`` to the desired address used by the |I2C| master device. From 85f7642cfa15dbb068e87f4d89c9e7de115fae9e Mon Sep 17 00:00:00 2001 From: Luciano Martin Date: Fri, 9 Aug 2024 16:06:54 +0100 Subject: [PATCH 26/34] Improve defines for I2C and I2S --- .../ffd/deploying/configuration.rst | 37 ++++++++++--------- .../low_power_ffd/deploying/configuration.rst | 6 +-- .../XK_VOICE_L71/platform/platform_init.c | 6 +-- .../XK_VOICE_L71/platform/platform_start.c | 8 ++-- examples/ffd/ffd_i2s_input_cyberon.cmake | 5 +-- examples/ffd/src/app_conf.h | 34 +++++++++++------ examples/ffd/src/i2c_reg_handling.c | 4 +- examples/ffd/src/main.c | 8 ++-- examples/ffva/src/app_conf.h | 8 ++-- examples/low_power_ffd/src/app_conf.h | 8 ++-- .../src/intent_handler/intent_handler.c | 4 +- modules/asr/intent_handler/intent_handler.c | 4 +- test/ffd_gpio/src/app_conf.h | 4 +- 13 files changed, 74 insertions(+), 62 deletions(-) diff --git a/doc/programming_guide/ffd/deploying/configuration.rst b/doc/programming_guide/ffd/deploying/configuration.rst index 89fdb1e4..9bb05105 100644 --- a/doc/programming_guide/ffd/deploying/configuration.rst +++ b/doc/programming_guide/ffd/deploying/configuration.rst @@ -34,17 +34,17 @@ If options are changed, the application firmware must be rebuilt. * - appconfINTENT_UART_DEBUG_INFO_ENABLED - Enables/disables the UART intent debug information - 0 - * - appconfINTENT_I2C_OUTPUT_ENABLED - - Enables/disables the |I2C| intent message + * - appconfI2C_MASTER_DAC_ENABLED + - Enables/disables configuring the DAC over |I2C| master - 1 - * - appconfI2C_MASTER_ENABLED - - Enables/disables the |I2C| master mode to configure the DAC and send the intent message + * - appconfINTENT_I2C_MASTER_OUTPUT_ENABLED + - Enables/disables sending the intent message over |I2C| master - 1 - * - appconfINTENT_I2C_OUTPUT_DEVICE_ADDR + * - appconfINTENT_I2C_MASTER_DEVICE_ADDR - Sets the address of the |I2C| device receiving the intent via the |I2C| master interface - 0x01 - * - appconfI2C_SLAVE_ENABLED - - Enables/disables the |I2C| slave mode to read the device register with the intent message + * - appconfINTENT_I2C_SLAVE_POLLED_ENABLED + - Enables/disables allowing polling the intent message via |I2C| slave - 0 * - appconfI2C_SLAVE_DEVICE_ADDR - Sets the address of the |I2C| device receiving the intent via the |I2C| slave interface @@ -102,31 +102,32 @@ The |I2C| master is used when the FFD example asynchronously sends intent messag The |I2C| interface cannot operate as both master and slave simultaneously. The FFD example design uses the |I2C| master interface to configure the DAC at device initialisation. However, if the host reads intent messages from the FFD example using the |I2C| slave interface, the |I2C| master interface will be disabled after the DAC configuration is complete. -The |I2C| master and slave can be enabled or disabled by setting the ``appconfI2C_MASTER_ENABLED`` and ``appconfI2C_SLAVE_ENABLED`` configuration variables. - To send the intent ID via the |I2C| master interface when a command is detected, set the following variables: - - ``appconfINTENT_I2C_OUTPUT_ENABLED`` to 1. - - ``appconfI2C_MASTER_ENABLED`` to 1. - - ``appconfINTENT_I2C_OUTPUT_DEVICE_ADDR`` to the desired address used by the |I2C| slave device. - - ``appconfI2C_SLAVE_ENABLED`` to 0. + - ``appconfINTENT_I2C_MASTER_OUTPUT_ENABLED`` to 1. + - ``appconfINTENT_I2C_MASTER_DEVICE_ADDR`` to the desired address used by the |I2C| slave device. + - ``appconfINTENT_I2C_SLAVE_POLLED_ENABLED`` to 0, this will disable the |I2C| slave interface. To configure the FFD example so that the host can poll for the intent via the |I2C| slave interface, set the following variables: - - ``appconfI2C_SLAVE_ENABLED`` to 1. + - ``appconfINTENT_I2C_SLAVE_POLLED_ENABLED`` to 1. - ``appconfI2C_SLAVE_DEVICE_ADDR`` to the desired address used by the |I2C| master device. - ``appconfINTENT_I2C_REG_ADDRESS`` to the desired register read by the |I2C| master device. - - ``appconfINTENT_I2C_OUTPUT_ENABLED`` to 0, this will disable the |I2C| master interface. + - ``appconfINTENT_I2C_MASTER_OUTPUT_ENABLED`` to 0, this will disable the |I2C| master interface. The handling of the |I2C| slave registers is done in the ``examples\ffd\src\i2c_reg_handling.c`` file. The variable ``appconfINTENT_I2C_REG_ADDRESS`` is used in the callback function ``read_device_reg()``. Configuring the |I2S| interface ------------------------------- -The |I2S| interface is used to receive the audio data from the host. The |I2S| interface can be configured as either a master or a slave. -To configure the |I2S| interface, set the following variables: +The |I2S| interface is used to send the intent audio to the DAC and to receive the audio data from the host. The |I2S| interface can be configured as either a master or a slave. +To configure the |I2S| interface to send the audio to the DAC, set the following variables: - - ``appconfUSE_I2S_INPUT`` to 1. + - ``appconfI2S_ENABLED`` to 1. - ``appconfI2S_MODE`` to the desired mode, either ``appconfI2S_MODE_MASTER`` or ``appconfI2S_MODE_SLAVE``. - ``appconfI2S_AUDIO_SAMPLE_RATE`` to the desired sample rate, either 16000 or 48000. - ``appconfRECOVER_MCLK_I2S_APP_PLL`` to 1 if an external MCLK is not available, otherwise set it to 0. + +To configure the |I2S| interface to receive audio data from the host, set the variables above and set the following variable: + + - ``appconfUSE_I2S_INPUT`` to 1. diff --git a/doc/programming_guide/low_power_ffd/deploying/configuration.rst b/doc/programming_guide/low_power_ffd/deploying/configuration.rst index 4faabefa..d9e93008 100644 --- a/doc/programming_guide/low_power_ffd/deploying/configuration.rst +++ b/doc/programming_guide/low_power_ffd/deploying/configuration.rst @@ -26,13 +26,13 @@ If options are changed, the application firmware must be rebuilt. * - appconfINTENT_UART_OUTPUT_ENABLED - Enables/disables the UART intent message - 1 - * - appconfINTENT_I2C_OUTPUT_ENABLED - - Enables/disables the |I2C| intent message + * - appconfINTENT_I2C_MASTER_OUTPUT_ENABLED + - Enables/disables sending the intent message over |I2C| master - 1 * - appconfUART_BAUD_RATE - Sets the baud rate for the UART tx intent interface - 9600 - * - appconfINTENT_I2C_OUTPUT_DEVICE_ADDR + * - appconfINTENT_I2C_MASTER_DEVICE_ADDR - Sets the |I2C| slave address to transmit the intent to - 0x01 * - appconfINTENT_TRANSPORT_DELAY_MS diff --git a/examples/ffd/bsp_config/XK_VOICE_L71/platform/platform_init.c b/examples/ffd/bsp_config/XK_VOICE_L71/platform/platform_init.c index de560177..ec7117e9 100644 --- a/examples/ffd/bsp_config/XK_VOICE_L71/platform/platform_init.c +++ b/examples/ffd/bsp_config/XK_VOICE_L71/platform/platform_init.c @@ -72,7 +72,7 @@ static void gpio_init(void) static void i2c_init(void) { -#if appconfI2C_SLAVE_ENABLED && ON_TILE(I2C_CTRL_TILE_NO) +#if appconfINTENT_I2C_SLAVE_POLLED_ENABLED && ON_TILE(I2C_CTRL_TILE_NO) rtos_i2c_slave_init(i2c_slave_ctx, (1 << appconfI2C_IO_CORE), PORT_I2C_SCL, @@ -80,7 +80,7 @@ static void i2c_init(void) appconfI2C_SLAVE_DEVICE_ADDR); #endif -#if appconfI2C_MASTER_ENABLED +#if appconfI2C_MASTER_DAC_ENABLED || appconfINTENT_I2C_OUTPUT_ENABLED static rtos_driver_rpc_t i2c_rpc_config; #if ON_TILE(I2C_TILE_NO) @@ -176,7 +176,7 @@ static void mics_init(void) static void i2s_init(void) { -#if appconfUSE_I2S_INPUT +#if appconfI2S_ENABLED #if appconfI2S_MODE == appconfI2S_MODE_MASTER static rtos_driver_rpc_t i2s_rpc_config; #endif diff --git a/examples/ffd/bsp_config/XK_VOICE_L71/platform/platform_start.c b/examples/ffd/bsp_config/XK_VOICE_L71/platform/platform_start.c index 77690d1a..c66af1d9 100644 --- a/examples/ffd/bsp_config/XK_VOICE_L71/platform/platform_start.c +++ b/examples/ffd/bsp_config/XK_VOICE_L71/platform/platform_start.c @@ -42,7 +42,7 @@ static void flash_start(void) static void i2c_master_start(void) { -#if appconfI2C_ENABLED && appconfI2C_MODE == appconfI2C_MODE_MASTER +#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) @@ -53,7 +53,7 @@ static void i2c_master_start(void) static void i2c_slave_start(void) { -#if appconfI2C_SLAVE_ENABLED && ON_TILE(I2C_CTRL_TILE_NO) +#if appconfINTENT_I2C_SLAVE_POLLED_ENABLED && ON_TILE(I2C_CTRL_TILE_NO) rtos_i2c_slave_start(i2c_slave_ctx, &last_asr_result, (rtos_i2c_slave_start_cb_t) NULL, @@ -69,7 +69,7 @@ static void i2c_slave_start(void) static void audio_codec_start(void) { -#if appconfUSE_I2S_INPUT && appconfI2C_MASTER_ENABLED +#if #if appconfI2S_ENABLED && appconfI2C_MASTER_DAC_ENABLED int ret = 0; #if ON_TILE(I2C_TILE_NO) if (dac3101_init(appconfI2S_AUDIO_SAMPLE_RATE) != 0) { @@ -95,7 +95,7 @@ static void mics_start(void) static void i2s_start(void) { -#if appconfUSE_I2S_INPUT +#if appconfI2S_ENABLED #if appconfI2S_MODE == appconfI2S_MODE_MASTER rtos_i2s_rpc_config(i2s_ctx, appconfI2S_RPC_PORT, appconfI2S_RPC_PRIORITY); #endif diff --git a/examples/ffd/ffd_i2s_input_cyberon.cmake b/examples/ffd/ffd_i2s_input_cyberon.cmake index 7d07d868..35c3c4c9 100644 --- a/examples/ffd/ffd_i2s_input_cyberon.cmake +++ b/examples/ffd/ffd_i2s_input_cyberon.cmake @@ -80,9 +80,8 @@ set(APP_COMPILE_DEFINITIONS appconfAUDIO_PLAYBACK_ENABLED=1 appconfI2S_MODE=appconfI2S_MODE_SLAVE appconfI2S_AUDIO_SAMPLE_RATE=48000 - appconfI2C_SLAVE_ENABLED=1 - appconfI2C_MASTER_ENABLED=0 - appconfINTENT_I2C_OUTPUT_ENABLED=0 + appconfINTENT_I2C_SLAVE_POLLED_ENABLED=1 + appconfINTENT_I2C_MASTER_OUTPUT_ENABLED=0 appconfRECOVER_MCLK_I2S_APP_PLL=1 appconfINTENT_UART_DEBUG_INFO_ENABLED=1 appconfAUDIO_PIPELINE_SKIP_IC_AND_VNR=1 diff --git a/examples/ffd/src/app_conf.h b/examples/ffd/src/app_conf.h index 12dee278..3900674d 100644 --- a/examples/ffd/src/app_conf.h +++ b/examples/ffd/src/app_conf.h @@ -71,12 +71,12 @@ #define appconfINTENT_TRANSPORT_DELAY_MS 50 #endif -#ifndef appconfINTENT_I2C_OUTPUT_ENABLED -#define appconfINTENT_I2C_OUTPUT_ENABLED 1 +#ifndef appconfINTENT_I2C_MASTER_OUTPUT_ENABLED +#define appconfINTENT_I2C_MASTER_OUTPUT_ENABLED 1 #endif -#ifndef appconfINTENT_I2C_OUTPUT_DEVICE_ADDR -#define appconfINTENT_I2C_OUTPUT_DEVICE_ADDR 0x01 +#ifndef appconfINTENT_I2C_MASTER_DEVICE_ADDR +#define appconfINTENT_I2C_MASTER_DEVICE_ADDR 0x01 #endif /* @brief Address for wakeword register to be read over I2C slave*/ @@ -104,28 +104,40 @@ #define appconfI2S_MODE_SLAVE 1 #endif +#ifndef appconfI2S_ENABLED +#define appconfI2S_ENABLED 1 +#endif + #ifndef appconfI2S_MODE #define appconfI2S_MODE appconfI2S_MODE_MASTER #endif -#ifndef appconfI2C_MASTER_ENABLED -#define appconfI2C_MASTER_ENABLED 1 +#ifndef appconfUSE_I2S_INPUT +#define appconfUSE_I2S_INPUT 0 +#endif + +#if appconfUSE_I2S_INPUT && !appconfI2S_ENABLED +#error "I2S must be enabled if receiving the audio over I2S" +#endif + +#ifndef appconfINTENT_I2C_MASTER_OUTPUT_ENABLED +#define appconfINTENT_I2C_MASTER_OUTPUT_ENABLED 1 #endif -#ifndef appconfI2C_SLAVE_ENABLED -#define appconfI2C_SLAVE_ENABLED 0 +#ifndef appconfINTENT_I2C_MASTER_OUTPUT_ENABLED +#define appconfINTENT_I2C_MASTER_OUTPUT_ENABLED 0 #endif #ifndef appconfI2C_SLAVE_DEVICE_ADDR #define appconfI2C_SLAVE_DEVICE_ADDR 0x42 #endif -#if appconfINTENT_I2C_OUTPUT_ENABLED && !appconfI2C_MASTER_ENABLED +#if appconfINTENT_I2C_MASTER_OUTPUT_ENABLED && !appconfI2C_MASTER_ENABLED #error "I2C master must be enabled for intent I2C output" #endif -#if appconfI2C_SLAVE_ENABLED && appconfINTENT_I2C_OUTPUT_ENABLED -#error "I2C slave cannot be enabled when intent I2C output over I2C master is enabled" +#if appconfINTENT_I2C_MASTER_OUTPUT_ENABLED && appconfINTENT_I2C_MASTER_OUTPUT_ENABLED +#error "The intent message cannot be sent over I2C master and polled via I2C slave simultaneously" #endif #ifndef appconfAUDIO_PIPELINE_SKIP_IC_AND_VNR diff --git a/examples/ffd/src/i2c_reg_handling.c b/examples/ffd/src/i2c_reg_handling.c index 95ed45d3..9029d633 100644 --- a/examples/ffd/src/i2c_reg_handling.c +++ b/examples/ffd/src/i2c_reg_handling.c @@ -13,7 +13,7 @@ size_t read_device_reg(rtos_i2c_slave_t *ctx, asr_result_t *last_asr_result, uint8_t **data) { -#if appconfI2C_SLAVE_ENABLED==1 +#if appconfINTENT_I2C_SLAVE_POLLED_ENABLED==1 uint8_t * data_p = *data; uint8_t reg_addr = data_p[0]; uint8_t reg_value = 0xFF; @@ -32,7 +32,7 @@ void write_device_reg(rtos_i2c_slave_t *ctx, uint8_t *data, size_t len) { -#if appconfI2C_SLAVE_ENABLED==1 +#if appconfINTENT_I2C_SLAVE_POLLED_ENABLED==1 // If the length is lower than WRITE_REQUEST_MIN_LEN, it is a read request if (len > WRITE_REQUEST_MIN_LEN) { rtos_printf("Write to register 0x%02X value 0x%02X (len %d)\n", data[0], data[1], len); diff --git a/examples/ffd/src/main.c b/examples/ffd/src/main.c index 0c0f253f..a1cae78f 100644 --- a/examples/ffd/src/main.c +++ b/examples/ffd/src/main.c @@ -15,7 +15,7 @@ /* Library headers */ #include "rtos_printf.h" -#if appconfUSE_I2S_INPUT +#if appconfI2S_ENABLED #include "src.h" #endif @@ -40,7 +40,7 @@ #define MEM_ANALYSIS_ENABLED 0 #endif -#if appconfUSE_I2S_INPUT && (appconfI2S_MODE == appconfI2S_MODE_SLAVE) +#if appconfI2S_ENABLED && (appconfI2S_MODE == appconfI2S_MODE_SLAVE) void i2s_slave_intertile() { int32_t tmp[appconfAUDIO_PIPELINE_FRAME_ADVANCE][appconfAUDIO_PIPELINE_CHANNELS]; @@ -146,7 +146,7 @@ int audio_pipeline_output(void *output_app_data, return AUDIO_PIPELINE_FREE_FRAME; } -#if appconfUSE_I2S_INPUT +#if appconfI2S_ENABLED RTOS_I2S_APP_SEND_FILTER_CALLBACK_ATTR size_t i2s_send_upsample_cb(rtos_i2s_t *ctx, void *app_data, int32_t *i2s_frame, size_t i2s_frame_size, int32_t *send_buf, size_t samples_available) { @@ -252,7 +252,7 @@ void startup_task(void *arg) platform_start(); -#if ON_TILE(1) && appconfUSE_I2S_INPUT && (appconfI2S_MODE == appconfI2S_MODE_SLAVE) +#if ON_TILE(1) && appconfI2S_ENABLED && (appconfI2S_MODE == appconfI2S_MODE_SLAVE) xTaskCreate((TaskFunction_t) i2s_slave_intertile, "i2s_slave_intertile", diff --git a/examples/ffva/src/app_conf.h b/examples/ffva/src/app_conf.h index 6b5872ea..3d099331 100644 --- a/examples/ffva/src/app_conf.h +++ b/examples/ffva/src/app_conf.h @@ -87,12 +87,12 @@ #define appconfINTENT_TRANSPORT_DELAY_MS 50 #endif -#ifndef appconfINTENT_I2C_OUTPUT_ENABLED -#define appconfINTENT_I2C_OUTPUT_ENABLED 1 +#ifndef appconfINTENT_I2C_MASTER_OUTPUT_ENABLED +#define appconfINTENT_I2C_MASTER_OUTPUT_ENABLED 1 #endif -#ifndef appconfINTENT_I2C_OUTPUT_DEVICE_ADDR -#define appconfINTENT_I2C_OUTPUT_DEVICE_ADDR 0x01 +#ifndef appconfINTENT_I2C_MASTER_DEVICE_ADDR +#define appconfINTENT_I2C_MASTER_DEVICE_ADDR 0x01 #endif #ifndef appconfINTENT_UART_OUTPUT_ENABLED diff --git a/examples/low_power_ffd/src/app_conf.h b/examples/low_power_ffd/src/app_conf.h index 64061cfd..3d28cfbe 100644 --- a/examples/low_power_ffd/src/app_conf.h +++ b/examples/low_power_ffd/src/app_conf.h @@ -67,12 +67,12 @@ #define appconfINTENT_TRANSPORT_DELAY_MS 50 #endif -#ifndef appconfINTENT_I2C_OUTPUT_ENABLED -#define appconfINTENT_I2C_OUTPUT_ENABLED 1 +#ifndef appconfINTENT_I2C_MASTER_OUTPUT_ENABLED +#define appconfINTENT_I2C_MASTER_OUTPUT_ENABLED 1 #endif -#ifndef appconfINTENT_I2C_OUTPUT_DEVICE_ADDR -#define appconfINTENT_I2C_OUTPUT_DEVICE_ADDR 0x01 +#ifndef appconfINTENT_I2C_MASTER_DEVICE_ADDR +#define appconfINTENT_I2C_MASTER_DEVICE_ADDR 0x01 #endif #ifndef appconfINTENT_UART_OUTPUT_ENABLED diff --git a/examples/low_power_ffd/src/intent_handler/intent_handler.c b/examples/low_power_ffd/src/intent_handler/intent_handler.c index 84fca4bf..3c9dbd1b 100644 --- a/examples/low_power_ffd/src/intent_handler/intent_handler.c +++ b/examples/low_power_ffd/src/intent_handler/intent_handler.c @@ -50,14 +50,14 @@ static void proc_keyword_res(void *args) { vTaskDelay(pdMS_TO_TICKS(appconfINTENT_TRANSPORT_DELAY_MS)); rtos_gpio_port_out(gpio_ctx_t0, p_out_wakeup, WAKEUP_LOW); } -#if appconfINTENT_I2C_OUTPUT_ENABLED +#if appconfINTENT_I2C_MASTER_OUTPUT_ENABLED i2c_res_t ret; uint32_t buf = id; size_t sent = 0; ret = rtos_i2c_master_write( i2c_master_ctx, - appconfINTENT_I2C_OUTPUT_DEVICE_ADDR, + appconfINTENT_I2C_MASTER_DEVICE_ADDR, (uint8_t*)&buf, sizeof(uint32_t), &sent, diff --git a/modules/asr/intent_handler/intent_handler.c b/modules/asr/intent_handler/intent_handler.c index 7068ee70..0d26de9d 100644 --- a/modules/asr/intent_handler/intent_handler.c +++ b/modules/asr/intent_handler/intent_handler.c @@ -56,14 +56,14 @@ static void proc_keyword_res(void *args) { vTaskDelay(pdMS_TO_TICKS(appconfINTENT_TRANSPORT_DELAY_MS)); rtos_gpio_port_out(gpio_ctx_t0, p_out_wakeup, WAKEUP_LOW); } -#if appconfINTENT_I2C_OUTPUT_ENABLED +#if appconfINTENT_I2C_MASTER_OUTPUT_ENABLED i2c_res_t ret; uint32_t buf = id; size_t sent = 0; ret = rtos_i2c_master_write( i2c_master_ctx, - appconfINTENT_I2C_OUTPUT_DEVICE_ADDR, + appconfINTENT_I2C_MASTER_DEVICE_ADDR, (uint8_t*)&buf, sizeof(uint32_t), &sent, diff --git a/test/ffd_gpio/src/app_conf.h b/test/ffd_gpio/src/app_conf.h index f5747b96..33c096e7 100644 --- a/test/ffd_gpio/src/app_conf.h +++ b/test/ffd_gpio/src/app_conf.h @@ -15,10 +15,10 @@ #define I2C_SLAVE_CORE_MASK (1 << 3) #define I2C_SLAVE_ADDR 0x7A -#define appconfINTENT_I2C_OUTPUT_DEVICE_ADDR I2C_SLAVE_ADDR +#define appconfINTENT_I2C_MASTER_DEVICE_ADDR I2C_SLAVE_ADDR #define appconfAUDIO_PLAYBACK_ENABLED 0 -#define appconfINTENT_I2C_OUTPUT_ENABLED 0 +#define appconfINTENT_I2C_MASTER_OUTPUT_ENABLED 0 #define appconfINTENT_UART_OUTPUT_ENABLED 0 #define ASR_TILE_NO 0 From 2e9197c2cb0cbb2398e24168800ec46a9eb073d2 Mon Sep 17 00:00:00 2001 From: Luciano Martin Date: Fri, 9 Aug 2024 16:18:04 +0100 Subject: [PATCH 27/34] Changes for I2S --- doc/programming_guide/ffd/deploying/configuration.rst | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/doc/programming_guide/ffd/deploying/configuration.rst b/doc/programming_guide/ffd/deploying/configuration.rst index 9bb05105..953a4b22 100644 --- a/doc/programming_guide/ffd/deploying/configuration.rst +++ b/doc/programming_guide/ffd/deploying/configuration.rst @@ -113,21 +113,19 @@ To configure the FFD example so that the host can poll for the intent via the |I - ``appconfINTENT_I2C_SLAVE_POLLED_ENABLED`` to 1. - ``appconfI2C_SLAVE_DEVICE_ADDR`` to the desired address used by the |I2C| master device. - ``appconfINTENT_I2C_REG_ADDRESS`` to the desired register read by the |I2C| master device. - - ``appconfINTENT_I2C_MASTER_OUTPUT_ENABLED`` to 0, this will disable the |I2C| master interface. + - ``appconfINTENT_I2C_MASTER_OUTPUT_ENABLED`` to 0, this will disable the |I2C| master interface after initialization. The handling of the |I2C| slave registers is done in the ``examples\ffd\src\i2c_reg_handling.c`` file. The variable ``appconfINTENT_I2C_REG_ADDRESS`` is used in the callback function ``read_device_reg()``. Configuring the |I2S| interface ------------------------------- -The |I2S| interface is used to send the intent audio to the DAC and to receive the audio data from the host. The |I2S| interface can be configured as either a master or a slave. +The |I2S| interface is used to send the intent audio to the DAC, and to receive the audio samples from the host. The |I2S| interface can be configured as either a master or a slave. To configure the |I2S| interface to send the audio to the DAC, set the following variables: - ``appconfI2S_ENABLED`` to 1. - ``appconfI2S_MODE`` to the desired mode, either ``appconfI2S_MODE_MASTER`` or ``appconfI2S_MODE_SLAVE``. - ``appconfI2S_AUDIO_SAMPLE_RATE`` to the desired sample rate, either 16000 or 48000. - ``appconfRECOVER_MCLK_I2S_APP_PLL`` to 1 if an external MCLK is not available, otherwise set it to 0. - -To configure the |I2S| interface to receive audio data from the host, set the variables above and set the following variable: - - - ``appconfUSE_I2S_INPUT`` to 1. + - ``appconfAUDIO_PLAYBACK_ENABLED`` to 1, if the intent audio is to be played back. + - ``appconfUSE_I2S_INPUT`` to 1, if the |I2S| audio source is to be used instead of the microphone array audio source. From 7f1b7e468f85ea7e238a6ed5fca93d9812c1786b Mon Sep 17 00:00:00 2001 From: Luciano Martin Date: Fri, 9 Aug 2024 17:14:55 +0100 Subject: [PATCH 28/34] Fix builds --- .../ffd/bsp_config/XK_VOICE_L71/platform/platform_start.c | 2 +- examples/ffd/ffd_cyberon.cmake | 2 ++ examples/ffd/ffd_sensory.cmake | 2 ++ examples/ffd/src/app_conf.h | 6 +----- examples/ffd/src/main.c | 7 ++++--- 5 files changed, 10 insertions(+), 9 deletions(-) diff --git a/examples/ffd/bsp_config/XK_VOICE_L71/platform/platform_start.c b/examples/ffd/bsp_config/XK_VOICE_L71/platform/platform_start.c index c66af1d9..a4ea603e 100644 --- a/examples/ffd/bsp_config/XK_VOICE_L71/platform/platform_start.c +++ b/examples/ffd/bsp_config/XK_VOICE_L71/platform/platform_start.c @@ -69,7 +69,7 @@ static void i2c_slave_start(void) static void audio_codec_start(void) { -#if #if appconfI2S_ENABLED && appconfI2C_MASTER_DAC_ENABLED +#if appconfI2S_ENABLED && appconfI2C_MASTER_DAC_ENABLED int ret = 0; #if ON_TILE(I2C_TILE_NO) if (dac3101_init(appconfI2S_AUDIO_SAMPLE_RATE) != 0) { diff --git a/examples/ffd/ffd_cyberon.cmake b/examples/ffd/ffd_cyberon.cmake index 70d69f3c..355e9657 100644 --- a/examples/ffd/ffd_cyberon.cmake +++ b/examples/ffd/ffd_cyberon.cmake @@ -91,6 +91,8 @@ set(APP_COMMON_LINK_LIBRARIES sln_voice::app::asr::intent_engine sln_voice::app::asr::intent_handler sln_voice::app::ffd::xk_voice_l71 + lib_src + lib_sw_pll ) #********************** diff --git a/examples/ffd/ffd_sensory.cmake b/examples/ffd/ffd_sensory.cmake index 1e7cb56b..d2ad4ac6 100644 --- a/examples/ffd/ffd_sensory.cmake +++ b/examples/ffd/ffd_sensory.cmake @@ -103,6 +103,8 @@ set(APP_COMMON_LINK_LIBRARIES sln_voice::app::asr::intent_engine sln_voice::app::asr::intent_handler sln_voice::app::ffd::xk_voice_l71 + lib_src + lib_sw_pll ) #********************** diff --git a/examples/ffd/src/app_conf.h b/examples/ffd/src/app_conf.h index 3900674d..d46eda81 100644 --- a/examples/ffd/src/app_conf.h +++ b/examples/ffd/src/app_conf.h @@ -132,11 +132,7 @@ #define appconfI2C_SLAVE_DEVICE_ADDR 0x42 #endif -#if appconfINTENT_I2C_MASTER_OUTPUT_ENABLED && !appconfI2C_MASTER_ENABLED -#error "I2C master must be enabled for intent I2C output" -#endif - -#if appconfINTENT_I2C_MASTER_OUTPUT_ENABLED && appconfINTENT_I2C_MASTER_OUTPUT_ENABLED +#if appconfINTENT_I2C_MASTER_OUTPUT_ENABLED && appconfINTENT_I2C_SLAVE_POLLED_ENABLED #error "The intent message cannot be sent over I2C master and polled via I2C slave simultaneously" #endif diff --git a/examples/ffd/src/main.c b/examples/ffd/src/main.c index a1cae78f..f24d7fe3 100644 --- a/examples/ffd/src/main.c +++ b/examples/ffd/src/main.c @@ -15,9 +15,6 @@ /* Library headers */ #include "rtos_printf.h" -#if appconfI2S_ENABLED -#include "src.h" -#endif /* App headers */ #include "app_conf.h" @@ -31,6 +28,10 @@ #include "gpio_ctrl/leds.h" #include "intent_handler/intent_handler.h" +#if appconfI2S_ENABLED +#include "src.h" +#endif + #if appconfRECOVER_MCLK_I2S_APP_PLL /* Config headers for sw_pll */ #include "sw_pll.h" From a0c54b773a8a0c07b915c5f358e808de28eae699 Mon Sep 17 00:00:00 2001 From: Luciano Martin Date: Fri, 9 Aug 2024 17:15:58 +0100 Subject: [PATCH 29/34] Fix text --- doc/programming_guide/ffd/deploying/configuration.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/programming_guide/ffd/deploying/configuration.rst b/doc/programming_guide/ffd/deploying/configuration.rst index 953a4b22..a4405cef 100644 --- a/doc/programming_guide/ffd/deploying/configuration.rst +++ b/doc/programming_guide/ffd/deploying/configuration.rst @@ -121,7 +121,7 @@ Configuring the |I2S| interface ------------------------------- The |I2S| interface is used to send the intent audio to the DAC, and to receive the audio samples from the host. The |I2S| interface can be configured as either a master or a slave. -To configure the |I2S| interface to send the audio to the DAC, set the following variables: +To configure the |I2S| interface, set the following variables: - ``appconfI2S_ENABLED`` to 1. - ``appconfI2S_MODE`` to the desired mode, either ``appconfI2S_MODE_MASTER`` or ``appconfI2S_MODE_SLAVE``. From 45c1eeed1929c7daf9df55afe8d7feb1081cb196 Mon Sep 17 00:00:00 2001 From: Luciano Martin Date: Mon, 12 Aug 2024 14:38:38 +0100 Subject: [PATCH 30/34] More changes, FFD cyberon builds work --- .../ffd/deploying/configuration.rst | 2 +- .../bsp_config/XK_VOICE_L71/platform/platform_init.c | 12 ++++++------ .../XK_VOICE_L71/platform/platform_start.c | 2 +- examples/ffd/src/app_conf.h | 4 ++-- examples/ffd/src/main.c | 2 +- .../XCORE-AI-EXPLORER/platform/platform_init.c | 2 +- .../bsp_config/XK_VOICE_L71/platform/platform_init.c | 6 +++--- examples/ffva/src/main.c | 4 ++-- 8 files changed, 17 insertions(+), 17 deletions(-) diff --git a/doc/programming_guide/ffd/deploying/configuration.rst b/doc/programming_guide/ffd/deploying/configuration.rst index a4405cef..5b6e6a47 100644 --- a/doc/programming_guide/ffd/deploying/configuration.rst +++ b/doc/programming_guide/ffd/deploying/configuration.rst @@ -120,7 +120,7 @@ The handling of the |I2C| slave registers is done in the ``examples\ffd\src\i2c_ Configuring the |I2S| interface ------------------------------- -The |I2S| interface is used to send the intent audio to the DAC, and to receive the audio samples from the host. The |I2S| interface can be configured as either a master or a slave. +The |I2S| interface is used to send the intent audio to the DAC, and/or to receive the audio samples from the host. The |I2S| interface can be configured as either a master or a slave. To configure the |I2S| interface, set the following variables: - ``appconfI2S_ENABLED`` to 1. diff --git a/examples/ffd/bsp_config/XK_VOICE_L71/platform/platform_init.c b/examples/ffd/bsp_config/XK_VOICE_L71/platform/platform_init.c index ec7117e9..9b09714d 100644 --- a/examples/ffd/bsp_config/XK_VOICE_L71/platform/platform_init.c +++ b/examples/ffd/bsp_config/XK_VOICE_L71/platform/platform_init.c @@ -12,7 +12,7 @@ static void mclk_init(chanend_t other_tile_c) { -#if ON_TILE(1) +#if ON_TILE(I2S_TILE_NO) app_pll_init(); #endif } @@ -54,7 +54,7 @@ static void gpio_init(void) intertile_ctx); #endif -#if ON_TILE(1) +#if ON_TILE(I2S_TILE_NO) rtos_gpio_init(gpio_ctx_t1); rtos_gpio_rpc_client_init( @@ -72,7 +72,7 @@ static void gpio_init(void) static void i2c_init(void) { -#if appconfINTENT_I2C_SLAVE_POLLED_ENABLED && ON_TILE(I2C_CTRL_TILE_NO) +#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, @@ -80,7 +80,7 @@ static void i2c_init(void) appconfI2C_SLAVE_DEVICE_ADDR); #endif -#if appconfI2C_MASTER_DAC_ENABLED || appconfINTENT_I2C_OUTPUT_ENABLED +#if appconfI2C_MASTER_DAC_ENABLED || appconfINTENT_I2C_MASTER_OUTPUT_ENABLED static rtos_driver_rpc_t i2c_rpc_config; #if ON_TILE(I2C_TILE_NO) @@ -106,7 +106,7 @@ static void i2c_init(void) #endif } -#if ON_TILE(1) && appconfRECOVER_MCLK_I2S_APP_PLL +#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) @@ -117,7 +117,7 @@ static void set_pll_lock_status_ptr(int* p) static void platform_sw_pll_init(void) { -#if ON_TILE(1) && appconfRECOVER_MCLK_I2S_APP_PLL +#if ON_TILE(I2S_TILE_NO) && appconfRECOVER_MCLK_I2S_APP_PLL port_t p_bclk = PORT_I2S_BCLK; port_t p_mclk = PORT_MCLK; diff --git a/examples/ffd/bsp_config/XK_VOICE_L71/platform/platform_start.c b/examples/ffd/bsp_config/XK_VOICE_L71/platform/platform_start.c index a4ea603e..d30445aa 100644 --- a/examples/ffd/bsp_config/XK_VOICE_L71/platform/platform_start.c +++ b/examples/ffd/bsp_config/XK_VOICE_L71/platform/platform_start.c @@ -53,7 +53,7 @@ static void i2c_master_start(void) static void i2c_slave_start(void) { -#if appconfINTENT_I2C_SLAVE_POLLED_ENABLED && ON_TILE(I2C_CTRL_TILE_NO) +#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, diff --git a/examples/ffd/src/app_conf.h b/examples/ffd/src/app_conf.h index d46eda81..1a0e9e58 100644 --- a/examples/ffd/src/app_conf.h +++ b/examples/ffd/src/app_conf.h @@ -124,8 +124,8 @@ #define appconfINTENT_I2C_MASTER_OUTPUT_ENABLED 1 #endif -#ifndef appconfINTENT_I2C_MASTER_OUTPUT_ENABLED -#define appconfINTENT_I2C_MASTER_OUTPUT_ENABLED 0 +#ifndef appconfI2C_MASTER_DAC_ENABLED +#define appconfI2C_MASTER_DAC_ENABLED 1 #endif #ifndef appconfI2C_SLAVE_DEVICE_ADDR diff --git a/examples/ffd/src/main.c b/examples/ffd/src/main.c index f24d7fe3..43144628 100644 --- a/examples/ffd/src/main.c +++ b/examples/ffd/src/main.c @@ -253,7 +253,7 @@ void startup_task(void *arg) platform_start(); -#if ON_TILE(1) && appconfI2S_ENABLED && (appconfI2S_MODE == appconfI2S_MODE_SLAVE) +#if ON_TILE(I2S_TILE_NO) && appconfI2S_ENABLED && (appconfI2S_MODE == appconfI2S_MODE_SLAVE) xTaskCreate((TaskFunction_t) i2s_slave_intertile, "i2s_slave_intertile", diff --git a/examples/ffva/bsp_config/XCORE-AI-EXPLORER/platform/platform_init.c b/examples/ffva/bsp_config/XCORE-AI-EXPLORER/platform/platform_init.c index 6d11e5fb..84724f17 100644 --- a/examples/ffva/bsp_config/XCORE-AI-EXPLORER/platform/platform_init.c +++ b/examples/ffva/bsp_config/XCORE-AI-EXPLORER/platform/platform_init.c @@ -14,7 +14,7 @@ static void mclk_init(chanend_t other_tile_c) { -#if ON_TILE(1) && !appconfEXTERNAL_MCLK +#if ON_TILE(I2S_TILE_NO) && !appconfEXTERNAL_MCLK app_pll_init(); #endif #if appconfUSB_ENABLED && ON_TILE(USB_TILE_NO) diff --git a/examples/ffva/bsp_config/XK_VOICE_L71/platform/platform_init.c b/examples/ffva/bsp_config/XK_VOICE_L71/platform/platform_init.c index f47d20f0..0ab43438 100644 --- a/examples/ffva/bsp_config/XK_VOICE_L71/platform/platform_init.c +++ b/examples/ffva/bsp_config/XK_VOICE_L71/platform/platform_init.c @@ -18,7 +18,7 @@ extern device_control_t *device_control_i2c_ctx; static void mclk_init(chanend_t other_tile_c) { -#if !appconfEXTERNAL_MCLK && ON_TILE(1) +#if !appconfEXTERNAL_MCLK && ON_TILE(I2S_TILE_NO) app_pll_init(); #endif #if appconfUSB_ENABLED && ON_TILE(USB_TILE_NO) @@ -154,7 +154,7 @@ static void spi_init(void) #endif } -#if ON_TILE(1) && appconfRECOVER_MCLK_I2S_APP_PLL +#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) @@ -165,7 +165,7 @@ static void set_pll_lock_status_ptr(int* p) static void platform_sw_pll_init(void) { -#if ON_TILE(1) && appconfRECOVER_MCLK_I2S_APP_PLL +#if ON_TILE(I2S_TILE_NO) && appconfRECOVER_MCLK_I2S_APP_PLL port_t p_bclk = PORT_I2S_BCLK; port_t p_mclk = PORT_MCLK; diff --git a/examples/ffva/src/main.c b/examples/ffva/src/main.c index 1caceb76..faa80a72 100644 --- a/examples/ffva/src/main.c +++ b/examples/ffva/src/main.c @@ -68,7 +68,7 @@ void i2s_slave_intertile(void *args) { portMAX_DELAY); -#if ON_TILE(1) && appconfRECOVER_MCLK_I2S_APP_PLL +#if ON_TILE(I2S_TILE_NO) && appconfRECOVER_MCLK_I2S_APP_PLL sw_pll_ctx_t* i2s_callback_args = (sw_pll_ctx_t*) args; port_clear_buffer(i2s_callback_args->p_bclk_count); port_in(i2s_callback_args->p_bclk_count); // Block until BCLK transition to synchronise. Will consume up to 1/64 of a LRCLK cycle @@ -353,7 +353,7 @@ void startup_task(void *arg) rtos_printf("Startup task running from tile %d on core %d\n", THIS_XCORE_TILE, portGET_CORE_ID()); platform_start(); -#if ON_TILE(1) && appconfI2S_ENABLED && (appconfI2S_MODE == appconfI2S_MODE_SLAVE) +#if ON_TILE(I2S_TILE_NO) && appconfI2S_ENABLED && (appconfI2S_MODE == appconfI2S_MODE_SLAVE) // Use sw_pll_ctx only if the MCLK recovery is enabled #if appconfRECOVER_MCLK_I2S_APP_PLL From 78be7a2a1cfb3aca6a98aed08d56c344f46e498a Mon Sep 17 00:00:00 2001 From: Luciano Martin Date: Mon, 12 Aug 2024 14:47:44 +0100 Subject: [PATCH 31/34] Disable DAC for I2S input FFD example --- examples/ffd/ffd_i2s_input_cyberon.cmake | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/ffd/ffd_i2s_input_cyberon.cmake b/examples/ffd/ffd_i2s_input_cyberon.cmake index 35c3c4c9..c5ebfa08 100644 --- a/examples/ffd/ffd_i2s_input_cyberon.cmake +++ b/examples/ffd/ffd_i2s_input_cyberon.cmake @@ -82,6 +82,7 @@ set(APP_COMPILE_DEFINITIONS appconfI2S_AUDIO_SAMPLE_RATE=48000 appconfINTENT_I2C_SLAVE_POLLED_ENABLED=1 appconfINTENT_I2C_MASTER_OUTPUT_ENABLED=0 + appconfI2C_MASTER_DAC_ENABLED=0 appconfRECOVER_MCLK_I2S_APP_PLL=1 appconfINTENT_UART_DEBUG_INFO_ENABLED=1 appconfAUDIO_PIPELINE_SKIP_IC_AND_VNR=1 From e30e4603aca7a98dcbc5ec7757ef893a8840ee83 Mon Sep 17 00:00:00 2001 From: Luciano Martin Date: Wed, 14 Aug 2024 08:17:00 +0100 Subject: [PATCH 32/34] Add more info --- doc/programming_guide/ffd/deploying/configuration.rst | 4 ++-- doc/programming_guide/ffd/overview.rst | 7 +++++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/doc/programming_guide/ffd/deploying/configuration.rst b/doc/programming_guide/ffd/deploying/configuration.rst index 5b6e6a47..6b898d59 100644 --- a/doc/programming_guide/ffd/deploying/configuration.rst +++ b/doc/programming_guide/ffd/deploying/configuration.rst @@ -44,7 +44,7 @@ If options are changed, the application firmware must be rebuilt. - Sets the address of the |I2C| device receiving the intent via the |I2C| master interface - 0x01 * - appconfINTENT_I2C_SLAVE_POLLED_ENABLED - - Enables/disables allowing polling the intent message via |I2C| slave + - Enables/disables allowing another device to poll the intent message via |I2C| slave - 0 * - appconfI2C_SLAVE_DEVICE_ADDR - Sets the address of the |I2C| device receiving the intent via the |I2C| slave interface @@ -120,7 +120,7 @@ The handling of the |I2C| slave registers is done in the ``examples\ffd\src\i2c_ Configuring the |I2S| interface ------------------------------- -The |I2S| interface is used to send the intent audio to the DAC, and/or to receive the audio samples from the host. The |I2S| interface can be configured as either a master or a slave. +The |I2S| interface is used to play the audio command response to the DAC, and/or to receive the audio samples from the host. The |I2S| interface can be configured as either a master or a slave. To configure the |I2S| interface, set the following variables: - ``appconfI2S_ENABLED`` to 1. diff --git a/doc/programming_guide/ffd/overview.rst b/doc/programming_guide/ffd/overview.rst index 868a6c0c..f5adcc46 100644 --- a/doc/programming_guide/ffd/overview.rst +++ b/doc/programming_guide/ffd/overview.rst @@ -13,6 +13,13 @@ The examples using the microphone array as the audio source include an audio pip #. Noise Suppressor (NS) #. Adaptive Gain Control (AGC) +The FFD examples provide several options to inform the host of a possible intent detected by the intent engine. The device can notify the host by: + + - sending the intent ID over UART interface upon the detection + - sending the intent ID over |I2C| master interface upon the detection + - allowing the host polling the last detected intent ID over |I2C| slave interface + - listening to an audio message over the |I2S| interface + When a wakeword phrase is detected followed by a command phrase, the application will output an audio response and a discrete message over |I2C| and UART. Sensory's THF and Cyberon's DSpotterâ„¢ libraries ship with an expiring development license. The Sensory one will suspend recognition after 11.4 hours or 107 recognition events, and the Cyberon one will suspend recognition after 100 recognition events. After the maximum number of recognitions is reached, a device reset is required to resume normal operation. To perform a reset, either power cycle the device or press the SW2 button. From 2e4c50e53433b45b7e70b0990856266d7f306f5a Mon Sep 17 00:00:00 2001 From: Luciano Martin Date: Thu, 15 Aug 2024 14:47:31 +0100 Subject: [PATCH 33/34] Add missing articles in doc --- doc/programming_guide/ffd/overview.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/programming_guide/ffd/overview.rst b/doc/programming_guide/ffd/overview.rst index f5adcc46..7e5cf1dc 100644 --- a/doc/programming_guide/ffd/overview.rst +++ b/doc/programming_guide/ffd/overview.rst @@ -15,10 +15,10 @@ The examples using the microphone array as the audio source include an audio pip The FFD examples provide several options to inform the host of a possible intent detected by the intent engine. The device can notify the host by: - - sending the intent ID over UART interface upon the detection - - sending the intent ID over |I2C| master interface upon the detection - - allowing the host polling the last detected intent ID over |I2C| slave interface - - listening to an audio message over the |I2S| interface + - sending the intent ID over a UART interface upon detecting the intent + - sending the intent ID over an |I2C| master interface upon detecting the intent + - allowing the host to poll the last detected intent ID over the |I2C| slave interface + - listening to an audio message over an |I2S| interface When a wakeword phrase is detected followed by a command phrase, the application will output an audio response and a discrete message over |I2C| and UART. From 31d89fc7658380adc08353b903fea5fdac614774 Mon Sep 17 00:00:00 2001 From: Luciano Martin Date: Mon, 19 Aug 2024 12:09:20 +0100 Subject: [PATCH 34/34] Remove unused define --- test/ffd_gpio/src/app_conf.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/test/ffd_gpio/src/app_conf.h b/test/ffd_gpio/src/app_conf.h index 33c096e7..94a75cbb 100644 --- a/test/ffd_gpio/src/app_conf.h +++ b/test/ffd_gpio/src/app_conf.h @@ -15,8 +15,6 @@ #define I2C_SLAVE_CORE_MASK (1 << 3) #define I2C_SLAVE_ADDR 0x7A -#define appconfINTENT_I2C_MASTER_DEVICE_ADDR I2C_SLAVE_ADDR - #define appconfAUDIO_PLAYBACK_ENABLED 0 #define appconfINTENT_I2C_MASTER_OUTPUT_ENABLED 0 #define appconfINTENT_UART_OUTPUT_ENABLED 0