cancel
Showing results for 
Search instead for 
Did you mean: 

How to replace the USC network in the Dual-mode application for STEVAL-STWINBX1

dzf
Associate II

Hi, 

I’m developing a voice-control system on ST’s STEVAL-STWINBX1 evaluation board. I’d like to build on the original “Dual-mode application with STM32Cube.AI and NanoEdge™ AI” by replacing the anomaly-detection function with a binary classifier based on IMP23ABSU microphone data (“xiaobei” vs. “other”). I also plan to replace the original USC model with a 10-class classification model trained on IMP23ABSU microphone data. The intended behavior is: when the MCU recognizes “xiaobei,” it should wake the USC model; otherwise, it should not.

My NanoEdge™ AI binary model is already running—when I execute start neai_class, I can see the classification output. However, after “xiaobei” is detected, the USC model fails to wake up and the firmware even falls into HardFault_Handler in some cases. I’m not sure what’s going wrong. Could you please share suggestions? For example, after modifying the USC model parameters, which source files need to be updated so the new model is compatible with the original code? Thank you!

zefang

1 ACCEPTED SOLUTION

Accepted Solutions
JennyMods
Associate II

Hi Zefang,

Your issue likely stems from inconsistencies between the modified USC model and the integration layer that manages inference triggering in the Dual-mode firmware. When you replace the original USC model with a new 10-class classifier, several dependencies must be updated to ensure proper model loading and memory alignment.

Here’s a step-by-step approach to resolve the issue:

  1. Update Model Parameters:
    Ensure that the usc_net.c and usc_net.h files reflect the new model’s structure — input size, output classes, and tensor dimensions. If you generated the model using STM32Cube.AI, re-export the C files and replace the old ones completely.

  2. Adjust Inference Management:
    In the dual-mode example, the app_x-cube-ai.c or app_neai.c files handle switching between the NanoEdge AI and the USC model. You need to modify the logic that triggers the USC inference to ensure it only runs after your “xiaobei” event. Add checks to confirm that memory buffers and model handlers are properly initialized before calling ai_run().

  3. Memory and Stack Configuration:
    A HardFault can indicate a memory overflow or misaligned pointer. Verify that the .bss, heap, and stack sizes in your linker script (STM32xxxx_FLASH.ld) are sufficient for both models to coexist. If needed, increase HEAP_SIZE or STACK_SIZE.

  4. Reinitialize AI Networks Properly:
    When switching from the NanoEdge AI model to the USC model, always call ai_network_destroy() before reinitializing another network to avoid overlapping memory contexts.

  5. Check Interrupt and DMA Conflicts:
    Since you’re using the IMP23ABSU microphone, confirm that DMA and I2S/DFSDM channels aren’t interrupted by concurrent tasks when switching modes.

  6. Debugging Tip:
    Use STM32CubeIDE’s debugger to check the call stack when HardFault occurs — it often points directly to the function (like ai_run() or a buffer operation) that’s misbehaving.

If the problem persists after updating these files, consider running both models independently in isolation first to confirm that each works before integrating them into the dual-mode framework.

View solution in original post

4 REPLIES 4
JennyMods
Associate II

Hi Zefang,

Your issue likely stems from inconsistencies between the modified USC model and the integration layer that manages inference triggering in the Dual-mode firmware. When you replace the original USC model with a new 10-class classifier, several dependencies must be updated to ensure proper model loading and memory alignment.

Here’s a step-by-step approach to resolve the issue:

  1. Update Model Parameters:
    Ensure that the usc_net.c and usc_net.h files reflect the new model’s structure — input size, output classes, and tensor dimensions. If you generated the model using STM32Cube.AI, re-export the C files and replace the old ones completely.

  2. Adjust Inference Management:
    In the dual-mode example, the app_x-cube-ai.c or app_neai.c files handle switching between the NanoEdge AI and the USC model. You need to modify the logic that triggers the USC inference to ensure it only runs after your “xiaobei” event. Add checks to confirm that memory buffers and model handlers are properly initialized before calling ai_run().

  3. Memory and Stack Configuration:
    A HardFault can indicate a memory overflow or misaligned pointer. Verify that the .bss, heap, and stack sizes in your linker script (STM32xxxx_FLASH.ld) are sufficient for both models to coexist. If needed, increase HEAP_SIZE or STACK_SIZE.

  4. Reinitialize AI Networks Properly:
    When switching from the NanoEdge AI model to the USC model, always call ai_network_destroy() before reinitializing another network to avoid overlapping memory contexts.

  5. Check Interrupt and DMA Conflicts:
    Since you’re using the IMP23ABSU microphone, confirm that DMA and I2S/DFSDM channels aren’t interrupted by concurrent tasks when switching modes.

  6. Debugging Tip:
    Use STM32CubeIDE’s debugger to check the call stack when HardFault occurs — it often points directly to the function (like ai_run() or a buffer operation) that’s misbehaving.

If the problem persists after updating these files, consider running both models independently in isolation first to confirm that each works before integrating them into the dual-mode framework.

Hi JennyMods,
I modified the parameters in stm32ai-modelzoo-services/audio_event_detection/user_config.yaml to match those in MfccDPU.c, and obtained two models: quantized_model.tflite and best_model.h5. I imported best_model.h5 into STM32CubeMX, and the generated network code runs correctly on the MCU—after recognizing “xiaobei,” it wakes the USC model and prints the classification information. However, when using code generated from quantized_model.tflite, the MCU does not print any classification results. Could you please share suggestions? What are the key differences between these two models, and is quantized_model.tflite supported/usable in this setup?
Additionally, with the code exported from best_model.h5, the USC prints one classification messages about every 40 seconds. This interval is too long. How can I reduce this interval? Thank you!
zefang

 
 
 

That’s a great observation — the issue likely stems from how quantization alters tensor shapes and data scaling between layers. In STM32Cube.AI pipelines, quantized_model.tflite uses int8 inference with per-tensor or per-channel quantization, while best_model.h5 retains floating-point weights and activations. If the generated Cube.AI code or DPU configuration (e.g., in network_data_params.c) doesn’t perfectly align with the quantized tensor metadata, the inference may silently fail or output constant predictions — which explains why no classification message is printed.

To test this, you could regenerate both models with consistent input normalization (same mean/std) and verify that the quantized model’s input scale matches the pre-processing in your audio feature extraction. Also, ensure the runtime (X-CUBE-AI or the model zoo scripts) supports the quantized operator set you’re using — not all tflite ops are fully mapped yet for STM32 targets.

As for the 40-second delay, that’s often due to the audio buffer windowing size and post-processing latency in the inference loop. Reducing the MFCC frame length and increasing the overlap ratio in your user_config.yaml usually helps improve responsiveness.

 

dzf
Associate II

Hi JennyMods,

Thanks for your previous suggestions , I’ve solved the earlier issue.
I’m now trying to port the STEVAL-STWINBX1 firmware to my custom hardware whose MCU is STM32U575VGT6. 
I started by porting the data logging application:

fp-sns-datalog2\STM32CubeFunctionPack_DATALOG2_V3.1.0\Projects\STM32U585AI-STWIN.box\Applications\DATALOG2
During execution the following code gets stuck,and eventually returns HAL_ERROR.

/* Wait for calibration completion */
while (LL_ADC_IsCalibrationOnGoing(hadc->Instance) != 0UL)
{
wait_loop_index++;
if (wait_loop_index >= ADC_CALIBRATION_TIMEOUT)
{
/* Update ADC state machine to error */
ADC_STATE_CLR_SET(hadc->State, HAL_ADC_STATE_BUSY_INTERNAL, HAL_ADC_STATE_ERROR_INTERNAL);

__HAL_UNLOCK(hadc);

return HAL_ERROR;
}

I’ve verified that the hardware is fine with my own test program (DAC generates a sine wave, ADC samples it, and I print the data over USART).  I’m not sure what’s wrong—could you give me some suggestions?

zefang