Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

Version 1 Next »

About This Application Note

This application note contains instructions for using the IAR embedded workbench for Arm to compile the single core BSP for the Cortex M7 running on the STM32H747 Discovery board (EVK), generating .awb, .h and .c files from a design, and using the control interface API to enable hardware control of the embedded design. This guide assumes the user has some experience with Audio Weaver.

Building and flashing a BSP with IAR Embedded workbench for Arm

The BSP used in this example is “awe8-bsp-stm32h747i-discovery-single-core”

In IAR, select File -> Open workspace in IAR. The “STM32H747i_Discovery.eww” project file is located in <REPO LOCATION>\SampleApp\STM32H747i-SingleCore\Build\EWARM

Rebuilding the BSP can be performed by right-clicking the workspace name and selecting “Rebuild All”

image-20240513-141438.png

The build will output a .bin file located in “<REPO LOCATION>\SampleApp\STM32H747i-SingleCore\Bin\EWARM\” which can be flashed when not debugging by using the STM32 ST-LINK Utility software. Contact support@dspconcepts.com for more information.

Connect the Discovery Board to the PC via both the USB OTG_HS and ST-LINK V3E ports with USB micro cables then select “Download and Debug” from the IAR toolbar. (Ensure the JP6 jumper on the bottom of the board is set to HS)

image-20240513-142011.png

Once flashed, run the code with the “play” button. From here, breakpoints can be set in the code, and variables can be watched for debugging.

image-20240513-172608.png

By default, main.c will run AWEIdleLoop() located in AWEplatform.c. At this point the board should be seen by the AWE Server, able to connect, a run a design in Tuning Mode.

image-20240513-143019.png

Generating Target Files to Run a Design

An example .awd is attached to this Application Note. It is a simple design which outputs a sine tone. Using the control interface API we’ll set up hardware control so while the blue “wakeup” user button on the STM32H747 is pushed, the sine tone is muted awe_ctrlSetValue()and a blue LED illuminates. Additionally, the value of a block counter within the design will be queried with awe_ctrlGetValue() and toggle an orange LED every 500 blocks.

For the control interface to access parameters of a module, the module will need to have an ObjectID assigned. An objectID can be assigned as an integer between 30000 and 32767. In the screenshot below, SinkInt and Mute1 have been assigned objectIDs which is indicated by the bold border. Set the objectID of a module in the build tab of its properties.

image-20240513-165658.png

With the design to be exported open in Designer, go to Tools -> Generate Target Files

image-20240513-151709.png

Check the appropriate boxes to generate the .awb, .h, and .c files.

image-20240513-151725.png

Export an .awb, ControlInterface.h, and InitAWB.c files. (InitAWB.h will be generated automatically)

Copy the generated C and header files to the Source files path in your project.

image-20240513-164438.png

In main.c define RUN_STANDALONE (line 17) and include “HW_Button_Mute_InitAWB.h” (line 21). This will instruct the board to load a design on startup in standalone mode. When compiled, the code will call awe_loadAWBfromArray() which references the “Core0_InitCommands” array generated previously from Designer.

image-20240513-163930.png

Include “HW_Button_Mute_ControlInterface.h” in AWEPlatform.c. For this example we’ll also declare some variables for the control interface steps.

//Add these 5 lines for Application Note Example
#include "HW_Button_Mute_ControlInterface.h"
UINT32 buttonState;
UINT32 lastButtonState;
UINT32 runTime;
UINT32 classID;

Using the Control Interface with the STM32H747

Note: Additional Control Interface and API documentation here:

https://w.dspconcepts.com/hubfs/Docs-AWECore/AWECore_API_Doc/index.html#ctrl-interface-overview

The below code was added to AWEIdleLoop() in AWEPlatform.c

First, check if the module exists and is of the right class with awe_ctrlGetModuleClass(). Then use one of the awe_ctrl functions to set/get something about a module. We get the AWE_Mute1_isMuted_HANDLE and AWE_Mute1_classID variables from "HW_Button_Mute_ControlInterface.h" which is also where AWE_OBJECT_FOUND is defined.

In this example we check the state of the blue (wakeup) user button on the board. If the button is pushed changing from 0 to 1, the mute module’s “isMuted” parameter is set to 1, and a blue LED is turned on while the button is pushed.

Similary, in the next section of code, we query a SinkInt module’s value which returns the number of blocks processed since the design began running. An orange LED is toggled every 500 blocks.

//Control I/O
//If the Mute module is found...
if (awe_ctrlGetModuleClass(&g_AWEInstance, AWE_Mute1_isMuted_HANDLE, &classID) == AWE_OBJECT_FOUND)
{
  //...check that the module assigned this classID is of module class Mute
  if (classID == AWE_Mute1_classID)
  {
    //If the blue button on the board is pushed, mute the output in the design and turn on the Blue LED
    awe_pltGPIOGetPin(1, (UINT32 *)&buttonState);
    if (buttonState != lastButtonState)
    {
      awe_ctrlSetValue(&g_AWEInstance, AWE_Mute1_isMuted_HANDLE, (void *)&buttonState, 0, 1);
      BSP_LED_Toggle(LED_BLUE);
      lastButtonState = buttonState;
    }
  }
}
    
    
if (awe_ctrlGetModuleClass(&g_AWEInstance, AWE_SinkInt1_value_HANDLE, &classID) == AWE_OBJECT_FOUND)
{
  if (classID == AWE_SinkInt1_classID)
  {
    //Read the "SinkInt" value from the design for total runTime(48bs) and toggle every 500 blocks
    awe_ctrlGetValue(&g_AWEInstance, AWE_SinkInt1_value_HANDLE, (void *)&runTime, 0, 1);
    if (runTime % 1000 > 500)
    {
      BSP_LED_On(LED_ORANGE);
    }
    else
    {
      BSP_LED_Off(LED_ORANGE);
    }
  }
}

Note: If many parameters are being sent via the control interface, it is advisable to send all parameters as a single array to a single Buffer Source module in the design. In the screenshot below, a BufferSourceInt module named “Control_IPC_In” receives an array from the application code, then outputs to a Control_Logic subsystem for next steps.

image-20240513-173052.png

Once the array is received in the design, Mapper and ParamSet modules can be used to route specific array indices to the correct module parameters.

image-20240513-173226.png

  • No labels