2026-02-17 4:11 AM - last edited on 2026-02-17 4:22 AM by Andrew Neil
As I've written, I'm writing an application for a hardware custom solution uing a Nucleo N6 board for speech enhancement and I want that my audio is denoised by a NN. The problem is that, listening to my transmitter, that audio is blocked and not correctly sampled when running MX_X_CUBE_AI_Process() (the NN alone without I2S activity makes inferences normally).
How can I prevent this blocking acitivity? I CANNOT use a STM32N6570-DK board(I ONLY have a NUCLEO N6, so please don't tell me to see speech enhancement examples because I've checked them out and, appearently, they are only conceived for STM32N6570-DK board)
This is my main.c + app_x-cube-ai.c code
/**
******************************************************************************
* @file app_x-cube-ai.c
* @author X-CUBE-AI C code generator
* @brief AI program body
******************************************************************************
* @attention
*
* Copyright (c) 2026 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/*
* Description
* v1.0 - Minimum template to show how to use the Neural ART Embedded Client API
* Re-target of the printf function is out-of-scope.
*
* For more information, see the embeded documentation:
*
* [1] %X_CUBE_AI_DIR%/Documentation/index.html
*
* X_CUBE_AI_DIR indicates the location where the X-CUBE-AI pack is installed
* typical : C:\Users\[user_name]\STM32Cube\Repository\STMicroelectronics\X-CUBE-AI\7.1.0
*/
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
/* System headers */
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <inttypes.h>
#include <string.h>
#include "app_x-cube-ai.h"
#include "main.h"
/* USER CODE BEGIN includes */
uint32_t buff_in_len, buff_out_len;
/* USER CODE END includes */
/* Entry points --------------------------------------------------------------*/
LL_ATON_DECLARE_NAMED_NN_INSTANCE_AND_INTERFACE(Default)
uint8_t *buffer_in;
uint8_t *buffer_out;
void set_clk_sleep_mode(void)
{
/* Leave clocks enabled in Low Power modes */
// Low-power clock enable misc
#if defined (CPU_IN_SECURE_STATE)
__HAL_RCC_DBG_CLK_SLEEP_ENABLE();
#endif
__HAL_RCC_XSPIPHYCOMP_CLK_SLEEP_ENABLE();
// Low-power clock enable for memories
__HAL_RCC_AXISRAM1_MEM_CLK_SLEEP_ENABLE();
__HAL_RCC_AXISRAM2_MEM_CLK_SLEEP_ENABLE();
__HAL_RCC_AXISRAM3_MEM_CLK_SLEEP_ENABLE();
__HAL_RCC_AXISRAM4_MEM_CLK_SLEEP_ENABLE();
__HAL_RCC_AXISRAM5_MEM_CLK_SLEEP_ENABLE();
__HAL_RCC_AXISRAM6_MEM_CLK_SLEEP_ENABLE();
__HAL_RCC_FLEXRAM_MEM_CLK_SLEEP_ENABLE();
__HAL_RCC_CACHEAXIRAM_MEM_CLK_SLEEP_ENABLE();
// LP clock AHB1: None
// LP clock AHB2: None
// LP clock AHB3
#if defined (CPU_IN_SECURE_STATE)
__HAL_RCC_RIFSC_CLK_SLEEP_ENABLE();
__HAL_RCC_RISAF_CLK_SLEEP_ENABLE();
__HAL_RCC_IAC_CLK_SLEEP_ENABLE();
#endif
// LP clock AHB4: None
// LP clocks AHB5
__HAL_RCC_XSPI1_CLK_SLEEP_ENABLE();
__HAL_RCC_XSPI2_CLK_SLEEP_ENABLE();
__HAL_RCC_CACHEAXI_CLK_SLEEP_ENABLE();
__HAL_RCC_NPU_CLK_SLEEP_ENABLE();
// LP clocks APB1: None
// LP clocks APB2
__HAL_RCC_USART1_CLK_SLEEP_ENABLE();
// LP clocks APB4: None
// LP clocks APB5: None
}
void MX_X_CUBE_AI_Init(void)
{
__HAL_RCC_AXISRAM2_MEM_CLK_ENABLE();
__HAL_RCC_AXISRAM3_MEM_CLK_ENABLE();
__HAL_RCC_AXISRAM4_MEM_CLK_ENABLE();
__HAL_RCC_AXISRAM5_MEM_CLK_ENABLE();
__HAL_RCC_AXISRAM6_MEM_CLK_ENABLE();
RAMCFG_SRAM2_AXI->CR &= ~RAMCFG_CR_SRAMSD;
RAMCFG_SRAM3_AXI->CR &= ~RAMCFG_CR_SRAMSD;
RAMCFG_SRAM4_AXI->CR &= ~RAMCFG_CR_SRAMSD;
RAMCFG_SRAM5_AXI->CR &= ~RAMCFG_CR_SRAMSD;
RAMCFG_SRAM6_AXI->CR &= ~RAMCFG_CR_SRAMSD;
set_clk_sleep_mode();
__HAL_RCC_NPU_CLK_ENABLE();
__HAL_RCC_NPU_FORCE_RESET();
__HAL_RCC_NPU_RELEASE_RESET();
npu_cache_init();
/* USER CODE BEGIN 5 */
/* USER CODE END 5 */
}
void MX_X_CUBE_AI_Process(void)
{
/* USER CODE BEGIN 6 */
LL_ATON_RT_RetValues_t ll_aton_rt_ret = LL_ATON_RT_DONE;
const LL_Buffer_InfoTypeDef * ibuffersInfos = NN_Interface_Default.input_buffers_info();
const LL_Buffer_InfoTypeDef * obuffersInfos = NN_Interface_Default.output_buffers_info();
buffer_in = (uint8_t *)LL_Buffer_addr_start(&ibuffersInfos[0]);
buffer_out = (uint8_t *)LL_Buffer_addr_start(&obuffersInfos[0]);
/*
uint8_t msg1[100];
uint8_t msg2[100];
sprintf((char*)msg1, "Input buffer: offset start = %lu, \n \r offset end = %lu \n \r",ibuffersInfos->offset_start,ibuffersInfos->offset_end);
sprintf((char*)msg2, "Output buffer: offset start = %lu, \n \r offset end = %lu \n \r",obuffersInfos->offset_start,obuffersInfos->offset_end);
HAL_UART_Transmit_DMA(&hlpuart1, msg1, strlen((char*)msg1));
HAL_UART_Transmit_DMA(&hlpuart1, msg2, strlen((char*)msg2));
*/
//printf("Input buffer: offset start = %lu, \n \r offset end = %lu \n \r",ibuffersInfos->offset_start,ibuffersInfos->offset_end);
//printf("Output buffer: offset start = %lu, \n \r offset end = %lu \n \r",obuffersInfos->offset_start,obuffersInfos->offset_end);
// Getting buffer size and printing it.
buff_in_len = ibuffersInfos->offset_end - ibuffersInfos->offset_start;
buff_out_len = obuffersInfos->offset_end - obuffersInfos->offset_start;
/*
uint8_t msg3[100];
sprintf((char*)msg3, "Buffer input size = %lu \n\r Buffer output size = %lu \n\r",buff_in_len, buff_out_len);
HAL_UART_Transmit_DMA(&hlpuart1, msg3, strlen((char*)msg3));
*/
//printf("Buffer input size = %lu \n\r Buffer output size = %lu \n\r", buff_in_len, buff_out_len);
uint8_t val = 10;
LL_ATON_RT_RuntimeInit();
// run 10 inferences
//for (int inferenceNb = 0; inferenceNb<10; ++inferenceNb) {
/* ------------- */
/* - Inference - */
/* ------------- */
/* Pre-process and fill the input buffer */
for(uint32_t i = 0; i < buff_in_len; i++){
buffer_in[i] = val;
}
mcu_cache_clean_invalidate_range(buffer_in, buffer_in + buff_in_len);
npu_cache_invalidate();
// Check that input buffer was properly assigned with "val".
/*
uint8_t bf1[50];
uint8_t bf2[50];
uint8_t bf3[50];
sprintf((char*)bf1, "Buffer[1] = %d \n \r", buffer_in[1]);
sprintf((char*)bf2, "Buffer[1000] = %d \n \r", buffer_in[1000]);
sprintf((char*)bf3, "Buffer[10000] = %d \n \r", buffer_in[10000]);
HAL_UART_Transmit_DMA(&hlpuart1, bf1, sizeof((char*)bf1));
HAL_UART_Transmit_DMA(&hlpuart1, bf2, sizeof((char*)bf2));
HAL_UART_Transmit_DMA(&hlpuart1, bf3, sizeof((char*)bf3));
*/
//_pre_process(buffer_in);
/* Perform the inference */
LL_ATON_RT_Init_Network(&NN_Instance_Default); // Initialize passed network instance object
do {
/* Execute first/next step */
ll_aton_rt_ret = LL_ATON_RT_RunEpochBlock(&NN_Instance_Default);
/* Wait for next event */
if (ll_aton_rt_ret == LL_ATON_RT_WFE) {
LL_ATON_OSAL_WFE();
}
} while (ll_aton_rt_ret != LL_ATON_RT_DONE);
/* Post-process the output buffer */
/* Invalidate the associated CPU cache region if requested */
uint8_t aux[4];
float_t *conver;
for(uint32_t i = 0; i < buff_out_len; i += 4){
aux[0] = buffer_out[i];
aux[1] = buffer_out[i+1];
aux[2] = buffer_out[i+2];
aux[3] = buffer_out[i+3];
conver = (float_t *)aux;
/*
uint8_t out_str[50];
sprintf((char*)out_str, "Out %lu = %f \n \r", i, *conver);
HAL_UART_Transmit_DMA(&hlpuart1, out_str, strlen((char*)out_str));
*/
//printf("Out %lu = %f \n \r", i, *conver);
}
/*
uint8_t out_str[50];
sprintf((char*)out_str, "Inference done \n \r");
HAL_UART_Transmit_DMA(&hlpuart1, out_str, strlen((char*)out_str));
*/
//_post_process(buffer_out);
LL_ATON_RT_DeInit_Network(&NN_Instance_Default);
/* -------------------- */
/* - End of Inference - */
/* -------------------- */
//}
LL_ATON_RT_RuntimeDeInit();
/* USER CODE END 6 */
}
#ifdef __cplusplus
}
#endif/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : main.c
* @brief : Main program body
******************************************************************************
* @attention
*
* Copyright (c) 2026 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "app_x-cube-ai.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
#define AUDIO_BUFFER_SIZE 20560 //input are F32 and output int8 for the NN
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
CACHEAXI_HandleTypeDef hcacheaxi;
I2S_HandleTypeDef hi2s1;
I2S_HandleTypeDef hi2s3;
DMA_NodeTypeDef Node_GPDMA1_Channel0 __NON_CACHEABLE;
DMA_QListTypeDef List_GPDMA1_Channel0;
DMA_HandleTypeDef handle_GPDMA1_Channel0;
DMA_NodeTypeDef Node_GPDMA1_Channel1 __NON_CACHEABLE;
DMA_QListTypeDef List_GPDMA1_Channel1;
DMA_HandleTypeDef handle_GPDMA1_Channel1;
UART_HandleTypeDef hlpuart1;
DMA_HandleTypeDef handle_GPDMA1_Channel2;
RAMCFG_HandleTypeDef hramcfg_SRAM3;
RAMCFG_HandleTypeDef hramcfg_SRAM4;
RAMCFG_HandleTypeDef hramcfg_SRAM5;
RAMCFG_HandleTypeDef hramcfg_SRAM6;
/* USER CODE BEGIN PV */
int32_t rxBuffer[AUDIO_BUFFER_SIZE];
int32_t txBuffer[AUDIO_BUFFER_SIZE];
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
static void MX_GPIO_Init(void);
static void MX_GPDMA1_Init(void);
static void MX_CACHEAXI_Init(void);
static void MX_I2S1_Init(void);
static void MX_I2S3_Init(void);
static void MX_LPUART1_UART_Init(void);
static void MX_RAMCFG_Init(void);
static void SystemIsolation_Config(void);
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
static uint32_t start;
static uint32_t finish;
int half_ready=0;
int full_ready=0;
/* USER CODE END 0 */
/**
* @brief The application entry point.
* @retval int
*/
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_GPDMA1_Init();
MX_CACHEAXI_Init();
MX_I2S1_Init();
MX_I2S3_Init();
MX_LPUART1_UART_Init();
MX_RAMCFG_Init();
MX_X_CUBE_AI_Init();
SystemIsolation_Config();
/* USER CODE BEGIN 2 */
HAL_I2S_Receive_DMA(&hi2s1, (uint16_t*)rxBuffer, AUDIO_BUFFER_SIZE);
HAL_I2S_Transmit_DMA(&hi2s3, (uint16_t*)txBuffer, AUDIO_BUFFER_SIZE);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/*
uint32_t start = HAL_GetTick();
uint8_t msg[50];
sprintf((char*)msg, "Prova \n \r");
HAL_UART_Transmit_DMA(&hlpuart1, msg, strlen((char*)msg));
*/
if ((half_ready)||(full_ready)){
MX_X_CUBE_AI_Process();
half_ready=0;
full_ready=0;
uint8_t out_str[50];
sprintf((char*)out_str, "Inference done \n \r");
HAL_UART_Transmit_DMA(&hlpuart1, out_str, strlen((char*)out_str));
}
/* USER CODE END WHILE */
//MX_X_CUBE_AI_Process();
/* USER CODE BEGIN 3 */
/*
uint32_t finish = HAL_GetTick()-start;
uint8_t msg1[50];
sprintf((char*)msg1, "Time elapsed = %d \n \r", finish);
HAL_UART_Transmit_DMA(&hlpuart1, msg1, strlen((char*)msg1));
*/
}
/* USER CODE END 3 */
}
/**
* @brief CACHEAXI Initialization Function
* None
* @retval None
*/
static void MX_CACHEAXI_Init(void)
{
/* USER CODE BEGIN CACHEAXI_Init 0 */
/* USER CODE END CACHEAXI_Init 0 */
/* USER CODE BEGIN CACHEAXI_Init 1 */
/* USER CODE END CACHEAXI_Init 1 */
hcacheaxi.Instance = CACHEAXI;
if (HAL_CACHEAXI_Init(&hcacheaxi) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN CACHEAXI_Init 2 */
/* USER CODE END CACHEAXI_Init 2 */
}
/**
* @brief GPDMA1 Initialization Function
* None
* @retval None
*/
static void MX_GPDMA1_Init(void)
{
/* USER CODE BEGIN GPDMA1_Init 0 */
/* USER CODE END GPDMA1_Init 0 */
/* Peripheral clock enable */
__HAL_RCC_GPDMA1_CLK_ENABLE();
/* GPDMA1 interrupt Init */
HAL_NVIC_SetPriority(GPDMA1_Channel0_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(GPDMA1_Channel0_IRQn);
HAL_NVIC_SetPriority(GPDMA1_Channel1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(GPDMA1_Channel1_IRQn);
HAL_NVIC_SetPriority(GPDMA1_Channel2_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(GPDMA1_Channel2_IRQn);
/* USER CODE BEGIN GPDMA1_Init 1 */
/* USER CODE END GPDMA1_Init 1 */
/* USER CODE BEGIN GPDMA1_Init 2 */
/* USER CODE END GPDMA1_Init 2 */
}
/**
* @brief I2S1 Initialization Function
* None
* @retval None
*/
static void MX_I2S1_Init(void)
{
/* USER CODE BEGIN I2S1_Init 0 */
/* USER CODE END I2S1_Init 0 */
/* USER CODE BEGIN I2S1_Init 1 */
/* USER CODE END I2S1_Init 1 */
hi2s1.Instance = SPI1;
hi2s1.Init.Mode = I2S_MODE_MASTER_RX;
hi2s1.Init.Standard = I2S_STANDARD_PHILIPS;
hi2s1.Init.DataFormat = I2S_DATAFORMAT_32B;
hi2s1.Init.MCLKOutput = I2S_MCLKOUTPUT_DISABLE;
hi2s1.Init.AudioFreq = I2S_AUDIOFREQ_32K;
hi2s1.Init.CPOL = I2S_CPOL_LOW;
hi2s1.Init.FirstBit = I2S_FIRSTBIT_MSB;
hi2s1.Init.WSInversion = I2S_WS_INVERSION_DISABLE;
hi2s1.Init.Data24BitAlignment = I2S_DATA_24BIT_ALIGNMENT_RIGHT;
hi2s1.Init.MasterKeepIOState = I2S_MASTER_KEEP_IO_STATE_DISABLE;
if (HAL_I2S_Init(&hi2s1) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN I2S1_Init 2 */
/* USER CODE END I2S1_Init 2 */
}
/**
* @brief I2S3 Initialization Function
* None
* @retval None
*/
static void MX_I2S3_Init(void)
{
/* USER CODE BEGIN I2S3_Init 0 */
/* USER CODE END I2S3_Init 0 */
/* USER CODE BEGIN I2S3_Init 1 */
/* USER CODE END I2S3_Init 1 */
hi2s3.Instance = SPI3;
hi2s3.Init.Mode = I2S_MODE_MASTER_TX;
hi2s3.Init.Standard = I2S_STANDARD_PHILIPS;
hi2s3.Init.DataFormat = I2S_DATAFORMAT_32B;
hi2s3.Init.MCLKOutput = I2S_MCLKOUTPUT_DISABLE;
hi2s3.Init.AudioFreq = I2S_AUDIOFREQ_32K;
hi2s3.Init.CPOL = I2S_CPOL_LOW;
hi2s3.Init.FirstBit = I2S_FIRSTBIT_MSB;
hi2s3.Init.WSInversion = I2S_WS_INVERSION_DISABLE;
hi2s3.Init.Data24BitAlignment = I2S_DATA_24BIT_ALIGNMENT_RIGHT;
hi2s3.Init.MasterKeepIOState = I2S_MASTER_KEEP_IO_STATE_DISABLE;
if (HAL_I2S_Init(&hi2s3) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN I2S3_Init 2 */
/* USER CODE END I2S3_Init 2 */
}
/**
* @brief LPUART1 Initialization Function
* None
* @retval None
*/
static void MX_LPUART1_UART_Init(void)
{
/* USER CODE BEGIN LPUART1_Init 0 */
/* USER CODE END LPUART1_Init 0 */
/* USER CODE BEGIN LPUART1_Init 1 */
/* USER CODE END LPUART1_Init 1 */
hlpuart1.Instance = LPUART1;
hlpuart1.Init.BaudRate = 115200;
hlpuart1.Init.WordLength = UART_WORDLENGTH_8B;
hlpuart1.Init.StopBits = UART_STOPBITS_1;
hlpuart1.Init.Parity = UART_PARITY_NONE;
hlpuart1.Init.Mode = UART_MODE_TX_RX;
hlpuart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
hlpuart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
hlpuart1.Init.ClockPrescaler = UART_PRESCALER_DIV1;
hlpuart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
hlpuart1.FifoMode = UART_FIFOMODE_DISABLE;
if (HAL_UART_Init(&hlpuart1) != HAL_OK)
{
Error_Handler();
}
if (HAL_UARTEx_SetTxFifoThreshold(&hlpuart1, UART_TXFIFO_THRESHOLD_1_8) != HAL_OK)
{
Error_Handler();
}
if (HAL_UARTEx_SetRxFifoThreshold(&hlpuart1, UART_RXFIFO_THRESHOLD_1_8) != HAL_OK)
{
Error_Handler();
}
if (HAL_UARTEx_DisableFifoMode(&hlpuart1) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN LPUART1_Init 2 */
/* USER CODE END LPUART1_Init 2 */
}
/**
* @brief RAMCFG Initialization Function
* None
* @retval None
*/
static void MX_RAMCFG_Init(void)
{
/* USER CODE BEGIN RAMCFG_Init 0 */
/* USER CODE END RAMCFG_Init 0 */
/* USER CODE BEGIN RAMCFG_Init 1 */
/* USER CODE END RAMCFG_Init 1 */
/** Initialize RAMCFG SRAM3
*/
hramcfg_SRAM3.Instance = RAMCFG_SRAM3_AXI;
if (HAL_RAMCFG_Init(&hramcfg_SRAM3) != HAL_OK)
{
Error_Handler();
}
/** Initialize RAMCFG SRAM4
*/
hramcfg_SRAM4.Instance = RAMCFG_SRAM4_AXI;
if (HAL_RAMCFG_Init(&hramcfg_SRAM4) != HAL_OK)
{
Error_Handler();
}
/** Initialize RAMCFG SRAM5
*/
hramcfg_SRAM5.Instance = RAMCFG_SRAM5_AXI;
if (HAL_RAMCFG_Init(&hramcfg_SRAM5) != HAL_OK)
{
Error_Handler();
}
/** Initialize RAMCFG SRAM6
*/
hramcfg_SRAM6.Instance = RAMCFG_SRAM6_AXI;
if (HAL_RAMCFG_Init(&hramcfg_SRAM6) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN RAMCFG_Init 2 */
/* USER CODE END RAMCFG_Init 2 */
}
/**
* @brief RIF Initialization Function
* None
* @retval None
*/
static void SystemIsolation_Config(void)
{
/* USER CODE BEGIN RIF_Init 0 */
/* USER CODE END RIF_Init 0 */
/* set all required IPs as secure privileged */
__HAL_RCC_RIFSC_CLK_ENABLE();
RIMC_MasterConfig_t RIMC_master = {0};
RIMC_master.MasterCID = RIF_CID_1;
RIMC_master.SecPriv = RIF_ATTRIBUTE_SEC | RIF_ATTRIBUTE_PRIV;
HAL_RIF_RIMC_ConfigMasterAttributes(RIF_MASTER_INDEX_NPU, &RIMC_master);
HAL_RIF_RISC_SetSlaveSecureAttributes(RIF_RISC_PERIPH_INDEX_NPU, RIF_ATTRIBUTE_PRIV | RIF_ATTRIBUTE_SEC);
/* RIF-Aware IPs Config */
/* set up GPDMA configuration */
/* set GPDMA1 channel 0 used by I2S1 */
if (HAL_DMA_ConfigChannelAttributes(&handle_GPDMA1_Channel0,DMA_CHANNEL_SEC|DMA_CHANNEL_PRIV|DMA_CHANNEL_SRC_SEC|DMA_CHANNEL_DEST_SEC)!= HAL_OK )
{
Error_Handler();
}
/* set GPDMA1 channel 1 used by I2S3 */
if (HAL_DMA_ConfigChannelAttributes(&handle_GPDMA1_Channel1,DMA_CHANNEL_SEC|DMA_CHANNEL_PRIV|DMA_CHANNEL_SRC_SEC|DMA_CHANNEL_DEST_SEC)!= HAL_OK )
{
Error_Handler();
}
/* set GPDMA1 channel 2 used by LPUART1 */
if (HAL_DMA_ConfigChannelAttributes(&handle_GPDMA1_Channel2,DMA_CHANNEL_SEC|DMA_CHANNEL_PRIV|DMA_CHANNEL_SRC_SEC|DMA_CHANNEL_DEST_SEC)!= HAL_OK )
{
Error_Handler();
}
/* set up GPIO configuration */
HAL_GPIO_ConfigPinAttributes(GPIOA,GPIO_PIN_11,GPIO_PIN_SEC|GPIO_PIN_NPRIV);
HAL_GPIO_ConfigPinAttributes(GPIOB,GPIO_PIN_0,GPIO_PIN_SEC|GPIO_PIN_NPRIV);
HAL_GPIO_ConfigPinAttributes(GPIOB,GPIO_PIN_3,GPIO_PIN_SEC|GPIO_PIN_NPRIV);
HAL_GPIO_ConfigPinAttributes(GPIOB,GPIO_PIN_6,GPIO_PIN_SEC|GPIO_PIN_NPRIV);
HAL_GPIO_ConfigPinAttributes(GPIOB,GPIO_PIN_7,GPIO_PIN_SEC|GPIO_PIN_NPRIV);
HAL_GPIO_ConfigPinAttributes(GPIOB,GPIO_PIN_8,GPIO_PIN_SEC|GPIO_PIN_NPRIV);
HAL_GPIO_ConfigPinAttributes(GPIOB,GPIO_PIN_9,GPIO_PIN_SEC|GPIO_PIN_NPRIV);
HAL_GPIO_ConfigPinAttributes(GPIOB,GPIO_PIN_12,GPIO_PIN_SEC|GPIO_PIN_NPRIV);
HAL_GPIO_ConfigPinAttributes(GPIOC,GPIO_PIN_0,GPIO_PIN_SEC|GPIO_PIN_NPRIV);
HAL_GPIO_ConfigPinAttributes(GPIOC,GPIO_PIN_5,GPIO_PIN_SEC|GPIO_PIN_NPRIV);
HAL_GPIO_ConfigPinAttributes(GPIOC,GPIO_PIN_12,GPIO_PIN_SEC|GPIO_PIN_NPRIV);
HAL_GPIO_ConfigPinAttributes(GPIOD,GPIO_PIN_7,GPIO_PIN_SEC|GPIO_PIN_NPRIV);
HAL_GPIO_ConfigPinAttributes(GPIOE,GPIO_PIN_3,GPIO_PIN_SEC|GPIO_PIN_NPRIV);
HAL_GPIO_ConfigPinAttributes(GPIOE,GPIO_PIN_5,GPIO_PIN_SEC|GPIO_PIN_NPRIV);
HAL_GPIO_ConfigPinAttributes(GPIOE,GPIO_PIN_6,GPIO_PIN_SEC|GPIO_PIN_NPRIV);
/* USER CODE BEGIN RIF_Init 1 */
/* USER CODE END RIF_Init 1 */
/* USER CODE BEGIN RIF_Init 2 */
/* USER CODE END RIF_Init 2 */
}
/**
* @brief GPIO Initialization Function
* None
* @retval None
*/
static void MX_GPIO_Init(void)
{
/* USER CODE BEGIN MX_GPIO_Init_1 */
/* USER CODE END MX_GPIO_Init_1 */
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOE_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
/* USER CODE BEGIN MX_GPIO_Init_2 */
/* USER CODE END MX_GPIO_Init_2 */
}
/* USER CODE BEGIN 4 */
static inline int32_t amplify_sample(int32_t sample)
{
int32_t amplified = sample*4;
if (amplified > 0xFFFFFFFE) {
return 0xFFFFFFFE;
}
else if (amplified < -0xFFFFFFFE) {
return -0xFFFFFFFE;
}
else {
return (int32_t)amplified;
}
}
void HAL_I2S_RxHalfCpltCallback(I2S_HandleTypeDef *hi2s)
{
//start = HAL_GetTick();
SCB_CleanDCache_by_Addr((uint32_t*)txBuffer, AUDIO_BUFFER_SIZE);
for (int i = 0; i < AUDIO_BUFFER_SIZE / 2; i++)
{
//MX_X_CUBE_AI_Process();
//HAL_UART_Transmit_DMA(&hlpuart1, (uint8_t*)rxBuffer[i], sizeof(rxBuffer[i]));
txBuffer[i] = amplify_sample(rxBuffer[i]);
//txBuffer[i] = rxBuffer[i];
}
half_ready=1;
uint8_t out_str[50];
sprintf((char*)out_str, "Half ready \n \r");
HAL_UART_Transmit_DMA(&hlpuart1, out_str, strlen((char*)out_str));
}
void HAL_I2S_RxCpltCallback(I2S_HandleTypeDef *hi2s)
{
for (int i = AUDIO_BUFFER_SIZE / 2; i < AUDIO_BUFFER_SIZE; i++)
{
//MX_X_CUBE_AI_Process();
//HAL_UART_Transmit_DMA(&hlpuart1, (uint8_t*)rxBuffer[i], sizeof(rxBuffer[i]));
txBuffer[i] = amplify_sample(rxBuffer[i]);
//txBuffer[i] = rxBuffer[i];
}
full_ready=1;
uint8_t out_str[50];
sprintf((char*)out_str, "Full ready \n \r");
HAL_UART_Transmit_DMA(&hlpuart1, out_str, strlen((char*)out_str));
SCB_InvalidateDCache_by_Addr((uint32_t*)txBuffer, AUDIO_BUFFER_SIZE);
//finish = HAL_GetTick() - start;
//uint8_t msg1[50];
//sprintf((char*)msg1, "Time elapsed = %d \n \r", finish);
//HAL_UART_Transmit_DMA(&hlpuart1, msg1, strlen((char*)msg1));
}
/* USER CODE END 4 */
/**
* @brief This function is executed in case of error occurrence.
* @retval None
*/
void Error_Handler(void)
{
/* USER CODE BEGIN Error_Handler_Debug */
/* User can add his own implementation to report the HAL error return state */
__disable_irq();
while (1)
{
}
/* USER CODE END Error_Handler_Debug */
}
#ifdef USE_FULL_ASSERT
/**
* @brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* file: pointer to the source file name
* line: assert_param error line source number
* @retval None
*/
void assert_failed(uint8_t *file, uint32_t line)
{
/* USER CODE BEGIN 6 */
/* User can add his own implementation to report the file name and line number,
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */
2026-02-19 6:29 AM
Have you checked the IRQ priorities? Also have you considered using FreeRTOS?
2026-02-19 7:19 AM
Hi @s319189,
From what I can see, there may be some real-time issues. That is, the inference may take longer than the acquisition of a half audio buffer… but it’s hard to know.
In the Audio event detection demo, which indeed runs only on the STM32N6 DK, a circular buffer was used, but it’s the same thing on the Nucleo, so you can take still inspiration from that.
Have a good day,
Julian
2026-02-21 8:08 AM