Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions examples/examples.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ if(${CMAKE_SYSTEM_NAME} STREQUAL XCORE_XS3A)
include(${CMAKE_CURRENT_LIST_DIR}/ffd/ffd_sensory.cmake)
include(${CMAKE_CURRENT_LIST_DIR}/ffd/ffd_cyberon.cmake)
include(${CMAKE_CURRENT_LIST_DIR}/ffd/ffd_i2s_input_cyberon.cmake)
include(${CMAKE_CURRENT_LIST_DIR}/ffd/ffd_sensory_sq66.cmake)
include(${CMAKE_CURRENT_LIST_DIR}/ffd/ffd_cyberon_sq66.cmake)

include(${CMAKE_CURRENT_LIST_DIR}/low_power_ffd/low_power_ffd_sensory.cmake)
include(${CMAKE_CURRENT_LIST_DIR}/mic_aggregator/mic_aggregator.cmake)
Expand Down
4 changes: 2 additions & 2 deletions examples/ffd/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ Command Utterances
Supported Hardware and pre-requisites
=====================================

This example is supported on the XK_VOICE_L71 board.
This example is supported on the XK_VOICE_L71 board and XK_VOICE_SQ66 board.

Make sure that your XTC tools environment is activated.

Expand All @@ -71,7 +71,7 @@ This application requires a host application to create the flash data partition.

.. note::

In the commands below ``<speech_engine>`` can be either ``sensory`` or ``cyberon``, depending on the choice of the speech recognition engine and model.
In the commands below ``<speech_engine>`` can be either ``sensory``, ``cyberon``, ``sensory_sq66`` or ``cyberon_sq66``, depending on the choice of the speech recognition engine, model and board.

.. note::

Expand Down
78 changes: 78 additions & 0 deletions examples/ffd/bsp_config/XK_VOICE_SQ66/XK_VOICE_SQ66.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@

## SQ66 custom mic array
add_library(framework_rtos_drivers_mic_array_sq66 INTERFACE)
target_sources(framework_rtos_drivers_mic_array_sq66
INTERFACE
${FRAMEWORK_RTOS_ROOT_PATH}/modules/drivers/mic_array/src/rtos_mic_array.c
${FRAMEWORK_RTOS_ROOT_PATH}/modules/drivers/mic_array/src/rtos_mic_array_rpc.c
${CMAKE_CURRENT_LIST_DIR}/platform/mic_array_vanilla.cpp
)
target_include_directories(framework_rtos_drivers_mic_array_sq66
INTERFACE
${FRAMEWORK_RTOS_ROOT_PATH}/modules/drivers/mic_array/api
${FRAMEWORK_IO_ROOT_PATH}/modules/mic_array/etc/vanilla/
)
target_link_libraries(framework_rtos_drivers_mic_array_sq66
INTERFACE
lib_mic_array
rtos::osal
)
target_compile_definitions(framework_rtos_drivers_mic_array_sq66
INTERFACE
MIC_ARRAY_BASIC_API_ENABLE=1
)
## Create an alias
add_library(rtos::drivers::mic_array_sq66 ALIAS framework_rtos_drivers_mic_array_sq66)

## Create custom board targets for application
add_library(sln_voice_app_ffd_board_support_xk_voice_sq66 INTERFACE)
target_sources(sln_voice_app_ffd_board_support_xk_voice_sq66
INTERFACE
${CMAKE_CURRENT_LIST_DIR}/platform/app_pll_ctrl.c
${CMAKE_CURRENT_LIST_DIR}/platform/driver_instances.c
${CMAKE_CURRENT_LIST_DIR}/platform/platform_init.c
${CMAKE_CURRENT_LIST_DIR}/platform/platform_start.c
${CMAKE_CURRENT_LIST_DIR}/platform/dac_port.c
)
target_include_directories(sln_voice_app_ffd_board_support_xk_voice_sq66
INTERFACE
${CMAKE_CURRENT_LIST_DIR}
)
target_link_libraries(sln_voice_app_ffd_board_support_xk_voice_sq66
INTERFACE
core::general
rtos::freertos
rtos::drivers::general
rtos::drivers::i2s
rtos::drivers::mic_array_sq66
sln_voice::app::ffd::dac::dac3101
)
target_compile_options(sln_voice_app_ffd_board_support_xk_voice_sq66
INTERFACE
${CMAKE_CURRENT_LIST_DIR}/XK_VOICE_SQ66.xn
)
target_link_options(sln_voice_app_ffd_board_support_xk_voice_sq66
INTERFACE
${CMAKE_CURRENT_LIST_DIR}/XK_VOICE_SQ66.xn
)
target_compile_definitions(sln_voice_app_ffd_board_support_xk_voice_sq66
INTERFACE
XK_VOICE_SQ66=1
PLATFORM_SUPPORTS_TILE_0=1
PLATFORM_SUPPORTS_TILE_1=1
PLATFORM_SUPPORTS_TILE_2=0
PLATFORM_SUPPORTS_TILE_3=0

MIC_ARRAY_CONFIG_MCLK_FREQ=24576000
MIC_ARRAY_CONFIG_PDM_FREQ=3072000
MIC_ARRAY_CONFIG_SAMPLES_PER_FRAME=240
MIC_ARRAY_CONFIG_MIC_COUNT=2
MIC_ARRAY_CONFIG_CLOCK_BLOCK_A=XS1_CLKBLK_2
MIC_ARRAY_CONFIG_CLOCK_BLOCK_B=XS1_CLKBLK_3
MIC_ARRAY_CONFIG_PORT_MCLK=PORT_PDM_MCLK
MIC_ARRAY_CONFIG_PORT_PDM_CLK=PORT_PDM_CLK
MIC_ARRAY_CONFIG_PORT_PDM_DATA=PORT_PDM_DATA
)

## Create an alias
add_library(sln_voice::app::ffd::xk_voice_sq66 ALIAS sln_voice_app_ffd_board_support_xk_voice_sq66)
107 changes: 107 additions & 0 deletions examples/ffd/bsp_config/XK_VOICE_SQ66/XK_VOICE_SQ66.xn
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
<?xml version="1.0" encoding="UTF-8"?>
<Network xmlns="http://www.xmos.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.xmos.com http://www.xmos.com" ManuallySpecifiedRouting="true">
<Type>Board</Type>
<Name>XK-VOICE-SQ66</Name>
<Declarations>
<Declaration>tileref tile[2]</Declaration>
<Declaration>tileref usb_tile</Declaration>
</Declarations>
<Packages>
<Package id="0" Type="XS3-UnA-1024-QF60B">
<Nodes>
<Node Id="0" InPackageId="0" Type="XS3-L16A-1024" Oscillator="24MHz" SystemFrequency="600MHz" referencefrequency="100MHz">
<Boot>
<Source Location="SPI:bootFlash"/>
</Boot>
<Tile Number="0" Reference="tile[0]">

<!-- USB Ports -->
<Port Location="XS1_PORT_1H" Name="PORT_USB_TX_READYIN"/>
<Port Location="XS1_PORT_1J" Name="PORT_USB_CLK"/>
<Port Location="XS1_PORT_1K" Name="PORT_USB_TX_READYOUT"/>
<Port Location="XS1_PORT_1I" Name="PORT_USB_RX_READY"/>
<Port Location="XS1_PORT_1E" Name="PORT_USB_FLAG0"/>
<Port Location="XS1_PORT_1F" Name="PORT_USB_FLAG1"/>
<Port Location="XS1_PORT_8A" Name="PORT_USB_TXD"/>
<Port Location="XS1_PORT_8B" Name="PORT_USB_RXD"/>

<!-- QSPI Ports -->
<Port Location="XS1_PORT_1B" Name="PORT_SQI_CS_0"/>
<Port Location="XS1_PORT_1C" Name="PORT_SQI_SCLK_0"/>
<Port Location="XS1_PORT_4B" Name="PORT_SQI_SIO_0"/>

<!-- Mic related ports -->
<Port Location="XS1_PORT_1M" Name="PORT_PDM_CLK"/>
<Port Location="XS1_PORT_8D" Name="PORT_PDM_DATA"/> <!-- only bits 4,5,6 & 7 are used due to overlap with 1b ports -->
<Port Location="XS1_PORT_1L" Name="PORT_PDM_MCLK"/>
<Port Location="XS1_PORT_1L" Name="PORT_MCLK_IN_OUT"/>

<!-- Used by the adaptive PLL in UA build -->
<Port Location="XS1_PORT_16A" Name="PORT_MIC_CLK_COUNT"/>

<!-- I2C Master Ports -->
<Port Location="XS1_PORT_1N" Name="PORT_I2C_SCL"/>
<Port Location="XS1_PORT_1O" Name="PORT_I2C_SDA"/>

<!-- SPI Slave Ports -->
<Port Location="XS1_PORT_1A" Name="PORT_SPI_SLAVE_CS"/>
<Port Location="XS1_PORT_1C" Name="PORT_SPI_SLAVE_SCLK"/>
<Port Location="XS1_PORT_1D" Name="PORT_SPI_SLAVE_MOSI"/>
<Port Location="XS1_PORT_1P" Name="PORT_SPI_SLAVE_MISO"/>

<!-- GPIO Ports -->
<Port Location="XS1_PORT_8C" Name="GPO_TILE_0_PORT_8C"/> <!-- only bits 3,4,5,6 & 7 brought out on pckg -->

<Port Location="XS1_PORT_4E" Name="PORT_GPO"/>

</Tile>

<Tile Number="1" Reference="tile[1]">
<!-- button port -->
<Port Location="XS1_PORT_4A" Name="PORT_BUTTON"/>

<!-- Audio Ports -->
<Port Location="XS1_PORT_1D" Name="PORT_MCLK_IN_OUT"/>
<Port Location="XS1_PORT_1B" Name="PORT_I2S_LRCLK"/>
<Port Location="XS1_PORT_1C" Name="PORT_I2S_BCLK"/>
<Port Location="XS1_PORT_1A" Name="I2S_DATA_IN"/>
<Port Location="XS1_PORT_1G" Name="I2S_MIC_DATA"/>
<Port Location="XS1_PORT_1K" Name="PORT_I2S_DATA2"/> <!-- Optional in some configs. NOTE shared with GPIO_TILE_1_PORT_1K -->

<!-- MCLK recovery port. This is used internally to count MCLKs and isn't pinned out -->
<Port Location="XS1_PORT_32A" Name="PORT_MCLK_COUNT"/>

<!-- GPIO Ports -->
<Port Location="XS1_PORT_4A" Name="PORT_GPI_0"/> <!-- only bit 3 is pinned out on package -->
<Port Location="XS1_PORT_1F" Name="PORT_GPI_1"/>
<Port Location="XS1_PORT_1K" Name="GPIO_TILE_1_PORT_1K"/> <!-- NOTE shared with PORT_I2S_DATA2 -->

</Tile>
</Node>
</Nodes>
</Package>
</Packages>
<Nodes>
<Node Id="2" Type="device:" RoutingId="0x8000">
<Service Id="0" Proto="xscope_host_data(chanend c);">
<Chanend Identifier="c" end="3"/>
</Service>
</Node>
</Nodes>
<Links>
<Link Encoding="2wire" Delays="5clk" Flags="XSCOPE">
<LinkEndpoint NodeId="0" Link="XL0"/>
<LinkEndpoint NodeId="2" Chanend="1"/>
</Link>
</Links>
<ExternalDevices>
<Device NodeId="0" Tile="0" Class="SQIFlash" Name="bootFlash">
<Attribute Name="PORT_SQI_CS" Value="PORT_SQI_CS_0"/>
<Attribute Name="PORT_SQI_SCLK" Value="PORT_SQI_SCLK_0"/>
<Attribute Name="PORT_SQI_SIO" Value="PORT_SQI_SIO_0"/>
</Device>
</ExternalDevices>
<JTAGChain>
<JTAGDevice NodeId="0"/>
</JTAGChain>
</Network>
51 changes: 51 additions & 0 deletions examples/ffd/bsp_config/XK_VOICE_SQ66/platform/app_pll_ctrl.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// Copyright 2022-2023 XMOS LIMITED.
// This Software is subject to the terms of the XMOS Public Licence: Version 1.

/* System headers */
#include <platform.h>
#include <xs1.h>
#include <xcore/hwtimer.h>
#include <xcore/assert.h>

/* App headers */
#include "platform/app_pll_ctrl.h"

void app_pll_set_numerator(int numerator)
{
const unsigned tileid = get_local_tile_id();
uint32_t fracval = APP_PLL_FRAC_NOM & 0xFFFF00FF;
uint32_t f;

if (numerator > 255) {
f = 255;
} else if (numerator < 0) {
f = 0;
} else {
f = numerator;
}

fracval |= (f << 8);
write_sswitch_reg_no_ack(tileid, XS1_SSWITCH_SS_APP_PLL_FRAC_N_DIVIDER_NUM, fracval);
}

void app_pll_init(void)
{
unsigned tileid = get_local_tile_id();

const unsigned APP_PLL_DISABLE = 0x0201FF04;
const unsigned APP_PLL_DIV_0 = 0x80000004;

write_sswitch_reg(tileid, XS1_SSWITCH_SS_APP_PLL_CTL_NUM, APP_PLL_DISABLE);

hwtimer_t tmr = hwtimer_alloc();
{
xassert(tmr != 0);
hwtimer_delay(tmr, 100000); // 1ms with 100 MHz timer tick
}
hwtimer_free(tmr);

write_sswitch_reg(tileid, XS1_SSWITCH_SS_APP_PLL_CTL_NUM, APP_PLL_CTL_VAL);
write_sswitch_reg(tileid, XS1_SSWITCH_SS_APP_PLL_CTL_NUM, APP_PLL_CTL_VAL);
write_sswitch_reg(tileid, XS1_SSWITCH_SS_APP_PLL_FRAC_N_DIVIDER_NUM, APP_PLL_FRAC_NOM);
write_sswitch_reg(tileid, XS1_SSWITCH_SS_APP_CLK_DIVIDER_NUM, APP_PLL_DIV_0);
}
19 changes: 19 additions & 0 deletions examples/ffd/bsp_config/XK_VOICE_SQ66/platform/app_pll_ctrl.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Copyright 2022-2023 XMOS LIMITED.
// This Software is subject to the terms of the XMOS Public Licence: Version 1.

#ifndef APP_PLL_CTRL_H_
#define APP_PLL_CTRL_H_

#include "platform_conf.h"

#if (MIC_ARRAY_CONFIG_MCLK_FREQ != 24576000)
#error PLL values only valid if MIC_ARRAY_CONFIG_MCLK_FREQ == 24576000
#endif

#define APP_PLL_CTL_VAL 0x0A019803 // Valid for all fractional values
#define APP_PLL_FRAC_NOM 0x800095F9 // 24.576000 MHz

void app_pll_set_numerator(int numerator);
void app_pll_init(void);

#endif /* APP_PLL_CTRL_H_ */
97 changes: 97 additions & 0 deletions examples/ffd/bsp_config/XK_VOICE_SQ66/platform/dac_port.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
// Copyright 2022-2023 XMOS LIMITED.
// This Software is subject to the terms of the XMOS Public Licence: Version 1.

/* System headers */
#include <platform.h>

/* FreeRTOS headers */
#include "FreeRTOS.h"

/* App headers */
#include "platform_conf.h"
#include "platform/driver_instances.h"
#include "dac3101.h"
#include "pcal6408a.h"

/* I2C io expander address on XCF3610_Q60A board */
#define IOEXP_I2C_ADDR PCAL6408A_I2C_ADDR

/* IO expander pinout */
#define XVF_RST_N_PIN 0
#define INT_N_PIN 1
#define DAC_RST_N_PIN 2
#define BOOT_SEL_PIN 3
#define MCLK_OE_PIN 4
#define SPI_OE_PIN 5
#define I2S_OE_PIN 6
#define MUTE_PIN 7

int dac3101_reg_write(uint8_t reg, uint8_t val)
{
i2c_regop_res_t ret;

ret = rtos_i2c_master_reg_write(i2c_master_ctx, DAC3101_I2C_DEVICE_ADDR, reg, val);

if (ret == I2C_REGOP_SUCCESS) {
return 0;
} else {
return -1;
}
}

void dac3101_codec_reset(void)
{
/* Set DAC_RST_N to 0 and enable level shifters */
i2c_regop_res_t ret;
uint8_t bitmask = (1<<XVF_RST_N_PIN) |
(1<<INT_N_PIN) |
(1<<BOOT_SEL_PIN) |
(1<<MCLK_OE_PIN) |
(1<<SPI_OE_PIN) |
(1<<I2S_OE_PIN) |
(1<<MUTE_PIN);
ret = rtos_i2c_master_reg_write(i2c_master_ctx, IOEXP_I2C_ADDR, PCAL6408A_OUTPUT_PORT, bitmask);
if (ret != I2C_REGOP_SUCCESS) {
rtos_printf("Failed to set io expander output port!\n");
}
vTaskDelay(pdMS_TO_TICKS(100));

/* Pin directions */
bitmask = (1<<XVF_RST_N_PIN) |
(1<<INT_N_PIN) |
(1<<BOOT_SEL_PIN) |
(1<<MUTE_PIN);
ret = rtos_i2c_master_reg_write(i2c_master_ctx, IOEXP_I2C_ADDR, PCAL6408A_CONF, bitmask);
if (ret != I2C_REGOP_SUCCESS) {
rtos_printf("Failed to set io expander configuration!\n");
}
vTaskDelay(pdMS_TO_TICKS(100));

/* Enable interrupts */
bitmask = 0xFF & ~(1<<INT_N_PIN);
ret = rtos_i2c_master_reg_write(i2c_master_ctx, IOEXP_I2C_ADDR, PCAL6408A_INTERRUPT_MASK, bitmask);
if (ret != I2C_REGOP_SUCCESS) {
rtos_printf("Failed to set io expander interrupt mask!\n");
}
vTaskDelay(pdMS_TO_TICKS(100));

/* Reset the dac */
bitmask = (1<<XVF_RST_N_PIN) |
(1<<INT_N_PIN) |
(1<<DAC_RST_N_PIN) |
(1<<BOOT_SEL_PIN) |
(1<<MCLK_OE_PIN) |
(1<<SPI_OE_PIN) |
(1<<I2S_OE_PIN) |
(1<<MUTE_PIN);
ret = rtos_i2c_master_reg_write(i2c_master_ctx, IOEXP_I2C_ADDR, PCAL6408A_OUTPUT_PORT, bitmask);
if (ret != I2C_REGOP_SUCCESS) {
rtos_printf("Failed to set io expander output!\n");
}
vTaskDelay(pdMS_TO_TICKS(100));
}

void dac3101_wait(uint32_t wait_ms)
{
vTaskDelay(pdMS_TO_TICKS(wait_ms));
}
Loading