STM32H7B3I-DK -  DISCOVERY KIT - Review

Table of contents

RoadTest: STM32H7B3I-DK -  DISCOVERY KIT

Author: jomoenginer

Creation date:

Evaluation Type: Development Boards & Tools

Did you receive all parts the manufacturer stated would be included in the package?: True

What other parts do you consider comparable to this product?: STM32H747i-DISCO STM32H745i-DISCO Renesas EK-RA6M3G Evaluation Kit

What were the biggest problems encountered?: Inconsistencies in the documentation such as the User's Manual does not match the board Schematic. Also, there were issues creating a project in TouchGFX and them bringing it into STM32CubeIDE where the .ioc file used to define the project is missing from the STM32CubeIDE .project file thus it is not imported. This had to be added manually and the name of the generated .ioc file had to be changed. There is an option in the STM32CubeIDE CubeMX implementation where clock define issues can be resolved automatically, however selecting this option leave the board in a non boot condition.

Detailed Review:

Overview

 

The STMicroelectronics STM32H7B3i-DK is a nice board to evaluate the STM line of STM32H7 MCUs. It is an excellent platform for creating Human Machine Interfaces (HMI) for both local and remote control.  The added Wi-Fi modules brings the ability to send and receive data remotely without the need for a physical interface.  This could be used as an environmental control station where the board receives data from remote sensors as well as used to set temperatures or thresholds for the remote sensors.

  With regards to features, STM32H7B3i-DK is packed with a good number of peripheral options.

 

Features

  • STM32H7B3LIH6QU Single Core 32-bit Arm® Cortex®-M7 280 MHz MCU
  • 4.3 TFT LCD Module with capacitive touch panel and RGB interface.
  • 128-Mbit SDRAM
  • 512-Mbit Octo-SPI NOR Flash memory
  • Wi-FI Module
  • USB OTS HS interface
  • USB STLINK-V3E debug interface

 

Expansion Options

  • STMod+ expansion connector
    • STMod+ Fan-out board with Grove, microBUS and ESP-01 compatible connectors (Included)
  • Arduino compatible headers
  • Audio daughterboard expansion connector
  • External i2C expansion connector
  • microSD card slot
  • Stereo headset jack and microphone input
  • DCMI style camera connector; support for STM32F4DIS-CAM camera module.

  .. and more

 

IDE Options

  • STM32CubeIDE
  • IAR EWARM
  • Keil MDK

 

Graphical UI Options

  • TouchGFX
  • Embedded Wizard
  • STemWin

 

Other tools used in RoadTest

  • MIKROE-3000 - H-Bridge 2 Click

    https://www.mikroe.com/h-bridge-2-click

    https://download.mikroe.com/documents/datasheets/MPC17510.pdf

 

References

  • STM32H7B3i-DK Resource page

    https://www.st.com/en/evaluation-tools/stm32h7b3i-dk.html

    https://www.st.com/resource/en/user_manual/dm00610478-discovery-kit-with-stm32h7b3li-mcu-stmicroelectronics.pdf

    https://www.st.com/resource/en/schematic_pack/mb1332-h7b3i-b02_schematic.pdf

 

  • TouchGFX

    https://support.touchgfx.com/docs/development/board-bring-up/example-gpio/ http://thehackerworkshop.com/?p=1271

    https://support.touchgfx.com/docs/development/ui-development/software-architecture/screen-definition-and-mvp/

 

  • EmbeddedWizard

    https://www.embedded-wizard.de/

 

Getting Started

 

Video Overview of STM32H7B3i-DK

 

Tool versions used

 

ToolVersion
STMCubeMX1.4.2
STM32CubeIDE6.0.1
STM32H71.8.0
X-Cube-TouchGFX4.14.0
CMSIS5.6.0

 

 

There are a number of means to get started with the STM32H7B3i-SK, however for the purpose of this RoadTest, the approach was to start with TouchGFX and then edit the code and add additional logic in STM32CubeIDE.   The tools such as STM32H7, X-Cube-TouchGFX, and CMSIS can be install via STMCubeMX.  The STMCubeIDE can be downloaded from the STM website. There are many resources to cover the install of the tools, so this will not be covered in this posting.

 

 

 

Install tools from STMCubeMX

Ex:

image

 

  Create a Project in TouchGFX

  1. Launch TouchGFX

image

 

Create a GUI interface in TouchGFX Designer

  1. Create a new Application

 

image

 

    2. Choose an Application Template

       a. Select STM32H7B3i-DK

image

 

    3. Set the Application Name and Application Directory

        a. The UI TEMPLATE can be selected at this point or left to the default Blank UI setting.

        b. Click CREATE to create the project

image

   4. Add Widgets and Screens and Interactions from the TouchGFX Designer. The Canvas area is the main location to place Widgets and Screens.

image

 

5. On the left side of the Designer window various Widgets such as Buttons, Images, Containers and so on can be added

image

 

    6. Screens can be added to place the Widgets on as well as create multiple interface options.

image

 

    7. Custom Images can be added to the project and then added to a particular Widget. These are added by clicking on the Images icon at the top of the window and then the '+' symbol in the blue circle.  Here images were brought in for the Direction arrows and for the background.  The other images were provided by TouchGFX Designer

image

 

    8. If text is added to the GUI, the Texts option can be used to customize the settings such as Typology, Alignment, default values.

image

 

    9. On the right side of the Designer, there are options to customize the item placed on the Canvas such as Name, Locations, Style, Image, and so on.

        Here, the background_roadtest.png image was added to the backgroundImage Widget.

 

image

 

    10. Interactions can be added to created events such as "Button is clicked" Trigger with the upButton Widget. The Function Name textbox is used to add a name to the Interaction so it can be added to the code to handle an event from the GUI.

image

 

    11. Once the project is complete, click on Generate Code to create the code for the project.

    12.  The code will be located in the project folder

image

 

    12.  In the  gui_generated include folder, the gui_generated->main_screen folder should have a file MainViewBase.h file containing methods associated with the Interactions created in Designer. These are virtual methods that need to be added in the Main class to override them

 

class MainViewBase : public touchgfx::View<MainPresenter>
{
public:
    MainViewBase();
    virtual ~MainViewBase() {}
    virtual void setupScreen();

    /*
     * Virtual Action Handlers
     */
    virtual void buttonUpClicked()
    {
        // Override and implement this function in Main
    }

    virtual void buttonDownClicked()
    {
        // Override and implement this function in Main
    }

    virtual void motorButtonClicked()
    {
        // Override and implement this function in Main
    }

    virtual void motorSpeedSliderChanged(int value)
    {
        // Override and implement this function in Main
    }

    virtual void motorSpeedChanged(int value)
    {
        // Override and implement this function in Main
    }

protected:
    FrontendApplication& application() {
        return *static_cast<FrontendApplication*>(touchgfx::Application::getInstance());
    }

 

    13. These methods are placed in the TouchGFX\gui\src\main_screen\MainView.cpp file and associated .hpp file.

void MainView::buttonUpClicked()
{
    touchgfx_printf("buttonUpClicked\n");
    pwm += 100;
    if (pwm > 3906)
    {
        pwm = 3906;
    }
#ifndef SIMULATOR
    //__HAL_TIM_SetCompare(&htim13, TIM_CHANNEL_1, pwm);  // update pwm value
    HAL_GPIO_WritePin(GPIOH, GPIO_PIN_8, GPIO_PIN_SET);  // DIR HIGH
    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_SET);  // END HIGH
    HAL_Delay(5);
#endif
}
void MainView::buttonDownClicked()
{
    touchgfx_printf("buttonDownClicked\n");
    pwm -= 100;
    if (pwm < 0)
    {
        pwm = 0;
    }
#ifndef SIMULATOR
    //__HAL_TIM_SetCompare(&htim13, TIM_CHANNEL_1, pwm);  // update pwm value
    //HAL_GPIO_WritePin(GPIOH, GPIO_PIN_8, GPIO_PIN_RESET);  // DIR HIGH
    HAL_GPIO_WritePin(GPIOH, GPIO_PIN_8, GPIO_PIN_RESET);  // DIR HIGH
    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_SET);  // END HIGH
    HAL_Delay(5);
#endif
}

void MainView::motorButtonClicked()
{
    touchgfx_printf("motorButtonClicked\n");
    
    motor_state = !motor_state;
#ifndef SIMULATOR
    if (motor_state)
    {
        HAL_GPIO_WritePin(GPIOH, GPIO_PIN_8, GPIO_PIN_SET);  // DIR HIGH
        HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_SET);  // END HIGH
        HAL_Delay(5);
    } else {
        HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_RESET);  // END LOW
    }
#endif
}

void MainView::motorSpeedSliderChanged(int value)
{
    touchgfx_printf("motorSpeedChanged %d\n", value);
    presenter->setMotorSpeed(value);

}

void MainView::motorSpeedMsg()
{
    touchgfx_printf("motorSpeedMsgReceived\n");
}

void MainView::motorSpeedChanged(int value)
{
    Unicode::snprintf(textMotorSpeedBuffer, 4, "%d", value);
    textMotorSpeed.invalidate();

}

 

    14. To test the code, the Run Simulator option can be used to run the code in a simulated environment.

           NOTE: Code that is not associated with the Simulator requires to be enclosed in "#ifndef SIMULATOR /#endif" tags to block out the code as seen in the previous code example.

image

    15. One particular issue with the TouchGFX STM32H7B3i-DK generated code is that the STM21CubeIDE code created by the Designer does not include the .ioc file for the project which is needed by CubeMX in STM32CubeIDE.  This reference needs to be added to the .project file and the .ioc file needs its name changed.

         The .project file is located under the STM32CubeIDE folder.

             C:\TouchGFXProjects\RoadTest_Motor2\STM32CubeIDE

         The .ioc file is located under the project folder and needs to be copied to "STM32H7B3I_DISCO.ioc".

          Leave the STM32H7B3I-DK.ioc file as is since it is needed by the Simulator/

 

     Add the following to the .project file under the linkedResources tag

image

    16. Double click on the .cproject file located under the STM32CubeIDE folder to open the project in STM32CubeIDE.

 

 

STM32CubeIDE

  1. Once the project is open in STM32CubeIDE, a few steps are required for the code to properly work on the STM32H7B3i-DK
  2. In the Project Explorer, double click on the STM32H7B3I_DISCO.ioc file to launch STM32CubeMX in the IDE

       NOTE: More than likely there will be an error seen since there is a mismatch between the STM32Cube FW_H7 from the TouchGFX project and that is installed in STM32CubeIDE.

       Click Migrate to update the TouchGFX generated code.

image

 

    An update progress window will be see.

image

    3. Once the process is complete, the MCU pinout screen will be seen

image

 

    4.  Save the project.  This should produce the following pop-up window.

        Click Yes

image

 

    5. Click Yes to change perspective

image

 

    6. A Warning Code Generation pop-up will appear regarding the Clock IPs.

       NOTE:Click Yes to generate the code.

image

 

    7. Once the code generation is complete, double click the .ioc file again to open the CubeMX perspective again,

        NOTE: This will produce the following Clock Configuration Pop-up.

                    DO NOT CLICK YES!  Click No. ( This may pop-up a second time but still select no.)

image

 

    8. This Clock Configuration window should appear.

image

 

    10. Click the Pinout & Configuration tab, select System Core, then RCC and in the Configuration Window, select Parameter Settings and Power Parameters.

        Change Power Regulator Voltage Scale from 2 to 0.

image

 

    11. Save the project and click Yes in the "Do you want to generate Code?" pop-up.

image

 

    12. Click yes on the Open Associated Perspective pop-up.

image

 

    13.  A clock warning may appear again.  Just click yes to generate the code.

image

    14.  Build the project.

 

   Run the code on the STM32H7B3i-DK

 

   1. Right click on the project in the Project Explorer and select Debug As - Debug Configuration

image

 

    2. Select STM32 Cortex-M C/C++ Application and then New launch configuration

image

 

    3. In the Debugger Tab, select the External loader, click Scan, and then find the loader associated with the STM32H7B3i-DK

MX25LM51245G_STM32H7B3I_DISCO, 0x90000000, NOR_FLASH, MX25LM51245G_STM32H7B3I-DISCO.stldr

image

 

    4. Under GDB Server Command Line Options, set Reset Behavior to Software system reset

image

 

    5. Click Apply to run the debugger session

 

    6. Click the Resume button to run the code

image

STMod MIKROE-3000 Configuration

 

In order use the MIKROE-3000 H-Bridge with the STMod connection on the STM32H7B3i-DK, a few pins need to be configured and there are changes required on the STM32H7B3i-DK and the MIKROE-3000.

 

    1. For the STM32H7B3i-DK, SB6 (PA0) solder bridge needs to be closed.

 

image

 

    2. On the MIKROE-3000, move the VIN SEL zero ohm resistor to VIN so the power for the motors come from the external VIN on the board and not from the STM32H7B3i-DK.

image

 

    3. Mount the MIKROE-3000 on the STMod Fanout board

image

 

    4. In STM32CubeIDE, the following pin configurations are needed to control the MIKROE-3000.

image

 

    5. Pin Details:

  • GIN ( PA4) – Used to small motor between S1 and S2.
  • EN (END) ( PA0) – Used to enable the MPC17510 IC When high. Can be used as a brake
  • PWM ( PF8) – Routed to the 74LVC1G3157. Controls speed of motor

           Should be less than 200kHz.

  • DIR (RST) ( PH8) – Routed to 74LVC1G3157. Controls direction of motor

         If DIR is High, PWM is routed to IN2 of the MPC17510

         If DIR is Low (or float), PWM is routed to IN1 of MPC17510

 

 

Motor Controller Project Configuration

 

    1. Open the previous TouchGFX project in STM32CubeIDE.

image

 

    2. Open the .ioc file..

image

 

    3. Search for PA4 (AN), PA0 (CS) PH8 (DIR) signals as GPIO

image

 

    4. Set PF8 (PWM) to TIM13_CH1 for the PWM signal.

image

 

   5. Configure TIM13 for PWM

image

 

   Set the following:

   Under Mode

  • Activated - Enabled
  • Channel1 - PWM Generation CH1

    Configuration - Parameter Settings

  • Prescalar - 15
  • Counter Mode - TIM_COUNTERDIVISION_DIV1
  • Period - 3905
  • Clock Division - TIM_CLOCKDIVISION_DIV1

 

    6. Click on the Pinout & Configuration Tab and select GPIO to change the names of the MikroBus signal names.

    Ex;

    image

 

    7. Save the changes to generate the Code

image

 

    8. The GPIO configurations should be defined in the main.c file:

image

 

CMSIS RTOS v2 FreeRTOS Task and Message Queue

To control the MIKROE-3000 from the STM32H7B3i-DK GUI, a CMSIS (FreeRTOS) task and Message Queue were created.  This is used with the Slider from the TouchGFX GUI which sends a message to the Mortor Controller task via a Message Queue.

 

    1.  In STM32H7B3i-DK, open the .ioc file to access the CubeMX configuration.

         Click on Pinout & Configuration, then Middleware and select FREERTOS from the list.

image

 

    2. Under FREERTOS Mode and Configuration, in Configuration, select Tasks and Queue. Click Add to create a new task.

         The Task for the MotorSpeed Task is defined as follows.

image

 

    3. Under Queues, click Add to add a new message queue for the task.

         This is defined as follows

image

 

    4. Click save to save the changes and generate the code.

         This will create the code for both the Task and message queue in the main.c file

/* Definitions for MotorSpeed_Task */
osThreadId_t MotorSpeed_TaskHandle;
const osThreadAttr_t MotorSpeed_Task_attributes = {
  .name = "MotorSpeed_Task",
  .priority = (osPriority_t) osPriorityNormal,
  .stack_size = 1024 * 4
};
/* Definitions for motorSpeedQueue */
osMessageQueueId_t motorSpeedQueueHandle;
const osMessageQueueAttr_t motorSpeedQueue_attributes = {
  .name = "motorSpeedQueue"
};

 

    5. A motor_speed_task.c file was create for the MotorSpeed task and PWM configuration.

/*
 * motor_speed_task.c
 *
 *  Created on: Sep 13, 2020
 *      Author: jomodev
 */

#include "motor_speed_task.h"
#include "cmsis_os2.h"
#include "stm32h7xx_hal.h"
#define LED3_Pin GPIO_PIN_11

/* Definitions for motorSpeedQueue */
//extern osMessageQueueId_t motorSpeedQueueHandle;
extern osMessageQueueId_t motorSpeedQueueHandle;
/*
const osMessageQueueAttr_t motorSpeedQueue_attributes = {
  .name = "motorSpeedQueue"
};
*/
extern TIM_HandleTypeDef htim13;

/* USER CODE BEGIN Header_Motor1PWM_Task */
/* Create the queue(s) */
/* creation of motorSpeedQueue */
uint32_t num_msgs = 1;

/**
* @brief Function implementing the MotorSpeed_Task thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_Motor1PWM_Task */
void Motor1PWM_Task(void *argument)
{
  /* USER CODE BEGIN Motor1PWM_Task */

  uint16_t msg;
  volatile uint16_t motor_speed = 0; // Default motor_speed
  osStatus_t status;

  /*TIM13 define*/

  /* USER CODE BEGIN TIM13_Init 0 */
  TIM_ClockConfigTypeDef sClockSourceConfig;
  TIM_MasterConfigTypeDef sMasterConfig;
  /* USER CODE END TIM13_Init 0 */

  TIM_OC_InitTypeDef sConfigOC = {0};

  /* USER CODE BEGIN TIM13_Init 1 */

  /* USER CODE END TIM13_Init 1 */
  htim13.Instance = TIM13;
  //htim13.Init.Prescaler = 2800-1;
  htim13.Init.Prescaler = 15;
  htim13.Init.CounterMode = TIM_COUNTERMODE_UP;
  //htim13.Init.Period = 2000-1;
  htim13.Init.Period = 3906;
  htim13.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  //htim13.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;

  if (HAL_TIM_Base_Init(&htim13) != HAL_OK)
  {
    Error_Handler();
  }

  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  if (HAL_TIM_ConfigClockSource(&htim13, &sClockSourceConfig) != HAL_OK)
  {
     Error_Handler();
  }
  if (HAL_TIM_PWM_Init(&htim13) != HAL_OK)
  {
    Error_Handler();
  }

  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim13, &sMasterConfig) != HAL_OK)
  {
    Error_Handler();
  }

  sConfigOC.OCMode = TIM_OCMODE_PWM1;
  //sConfigOC.Pulse = 1953;
  sConfigOC.Pulse = 0;
  sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
  sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
  if (HAL_TIM_PWM_ConfigChannel(&htim13, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN TIM13_Init 2 */
  HAL_TIM_Base_Start(&htim13);
  HAL_TIM_PWM_Start(&htim13, TIM_CHANNEL_1);
  /* USER CODE END TIM13_Init 2 */
  HAL_TIM_MspPostInit(&htim13);
  /* Infinite loop */
  for(;;)
  {
        // Assign motor_speed based on message in queue
        status = osMessageQueueGet(motorSpeedQueueHandle, &msg, NULL, 0);

        // If message was received, update delay
        if ( status == osOK )
        {
            motor_speed = msg;


            if (motor_speed < 3906 && motor_speed >= 0)
            //if (motor_speed > 500)
            {
                __HAL_TIM_SetCompare(&htim13, TIM_CHANNEL_1, motor_speed);
                HAL_GPIO_TogglePin(GPIOG, LED3_Pin); // GPIO_PIN_11
                //HAL_GPIO_WritePin(GPIOG, LED3_Pin, GPIO_PIN_SET);
            } else {
                HAL_GPIO_WritePin(GPIOG, LED3_Pin, GPIO_PIN_RESET);
            }
        }

    osDelay(100);
  }

  // In case we accidentally exit from the task loop
  osThreadTerminate(motorSpeedQueueHandle);
  /* USER CODE END Motor1PWM_Task */
}

 

    6. If a Message is sent to the motorSpeedQueueHandle, the motor speed is sent to the value of 'msg'.  A user LED on the board is set to blink when a messages is seen.

  for(;;)
  {
        // Assign motor_speed based on message in queue
        status = osMessageQueueGet(motorSpeedQueueHandle, &msg, NULL, 0);

        // If message was received, update delay
        if ( status == osOK )
        {
            motor_speed = msg;


            if (motor_speed < 3906 && motor_speed >= 0)
            //if (motor_speed > 500)
            {
                __HAL_TIM_SetCompare(&htim13, TIM_CHANNEL_1, motor_speed);
                HAL_GPIO_TogglePin(GPIOG, LED3_Pin); // GPIO_PIN_11
                //HAL_GPIO_WritePin(GPIOG, LED3_Pin, GPIO_PIN_SET);
            } else {
                HAL_GPIO_WritePin(GPIOG, LED3_Pin, GPIO_PIN_RESET);
            }
        }

    osDelay(100);
  }

 

  NOTE: This uses the  TouchGFX Model-View-Presenter (MVP) pattern to pass messages between the TouchGFX GUI and the HAL layer.

 

TouchGFX HAL Config

 

In the TouchGFX code, the MainView.cpp file receives the messages from the GUI and handles the events associated with buttons and sliders.

 

    1. The button events are handled using the HAL GPIO options.

#include <gui/main_screen/MainView.hpp>

MainView::MainView()
{
    pwm = 0;
    motor_state = 0;
#ifndef SIMULATOR
    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_RESET);
#endif
}

void MainView::setupScreen()
{
    MainViewBase::setupScreen();
}

void MainView::tearDownScreen()
{
    MainViewBase::tearDownScreen();
}

void MainView::buttonUpClicked()
{
    touchgfx_printf("buttonUpClicked\n");
    pwm += 100;
    if (pwm > 3906)
    {
        pwm = 3906;
    }
#ifndef SIMULATOR
    //__HAL_TIM_SetCompare(&htim13, TIM_CHANNEL_1, pwm);  // update pwm value
    HAL_GPIO_WritePin(GPIOH, GPIO_PIN_8, GPIO_PIN_SET);  // DIR HIGH
    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_SET);  // END HIGH
    HAL_Delay(5);
#endif
}
void MainView::buttonDownClicked()
{
    touchgfx_printf("buttonDownClicked\n");
    pwm -= 100;
    if (pwm < 0)
    {
        pwm = 0;
    }
#ifndef SIMULATOR
    //__HAL_TIM_SetCompare(&htim13, TIM_CHANNEL_1, pwm);  // update pwm value
    //HAL_GPIO_WritePin(GPIOH, GPIO_PIN_8, GPIO_PIN_RESET);  // DIR HIGH
    HAL_GPIO_WritePin(GPIOH, GPIO_PIN_8, GPIO_PIN_RESET);  // DIR HIGH
    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_SET);  // END HIGH
    HAL_Delay(5);
#endif
}

void MainView::motorButtonClicked()
{
    touchgfx_printf("motorButtonClicked\n");
    
    motor_state = !motor_state;
#ifndef SIMULATOR
    if (motor_state)
    {
        HAL_GPIO_WritePin(GPIOH, GPIO_PIN_8, GPIO_PIN_SET);  // DIR HIGH
        HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_SET);  // END HIGH
        HAL_Delay(5);
    } else {
        HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_RESET);  // END LOW
    }
#endif
}

 

 

    2. For the Motor Speed slider, when a change is detected, the Presenter setMotorSpeed method is called with the value of the motor speed.

        Also, the value is passed back to the GUI to display it next to the slider.

void MainView::motorSpeedSliderChanged(int value)
{
    touchgfx_printf("motorSpeedChanged %d\n", value);
    presenter->setMotorSpeed(value);

}

void MainView::motorSpeedMsg()
{
    touchgfx_printf("motorSpeedMsgReceived\n");
}

void MainView::motorSpeedChanged(int value)
{
    Unicode::snprintf(textMotorSpeedBuffer, 4, "%d", value);
    textMotorSpeed.invalidate();

}

 

 

    3. In MainPresenter.cpp, the model userSetMotorSpeed method is called with the speed value.

void MainPresenter::setMotorSpeed(int value)
{
    model->userSetMotorSpeed(value);
}

 

    4. The value is sent to the Message Queue via the Model userSetMotorSpeed method using the CMSIS RTOS "osMessageQueuePut" method.

        NOTE: A reference to the "motorSpeedQueueHandle" is added using the 'extern "C"' option.

#include <gui/model/Model.hpp>
#include <gui/model/ModelListener.hpp>

#ifndef SIMULATOR

    //#include "stm32f769i_discovery.h"
    #include "FreeRTOS.h"
    #include "touchgfx/Utils.hpp"
    #include "queue.h"
    #include "cmsis_os.h"
    #include "motor_speed_task.h"


    //*******************************************************
    //   Define Queue handles
    //*******************************************************
    //extern "C" xQueueHandle gui_msg_q; //From LEDTask
    extern "C" osMessageQueueId_t motorSpeedQueueHandle; // From motor_speed_task
    xQueueHandle gui_msg_q;

#else
    #include <stdio.h>
#endif

Model::Model() : modelListener(0)
{
    #ifndef SIMULATOR
    
    //*******************************************************
    // 
    //  Create GUI message queue
    //
    //  Check for messages from backend, with zero timeout
    //  Any time there's a message on this mailbox, react to it. value is meaningless in this case..
    //    
    //*******************************************************
    //
    gui_msg_q = xQueueGenericCreate(1, 1, 0);
    #endif
}

void Model::tick()
{
#ifndef SIMULATOR

    //*******************************************************
    // 
    //  HANDLE MESSAGES
    //
    //  Check for messages from backend, with zero timeout to 
    //  avoid blocking the UI. 
    // 
    //*******************************************************
    //
    
    uint8_t msg = 0;
    osStatus_t status;
    if (xQueueReceive(gui_msg_q, &msg, 0) == pdTRUE)
    {
      // Queue is used as a flag, so don't check msg.
    // Full = PRESSED, Empty = Do nothing.        
     //btnPressed();
        //touchgfx_printf("motorSpeedInQueued %d\n", msg);
    }
    /*
    status = osMessageQueueGet(motorSpeedQueueHandle, &msg, NULL, 0);
    if ( status == osOK )
    {
        motorSpeedSet();
    }
    */
#endif

}

void Model:: motorSpeedSet()
{
    modelListener->motorSpeedSet();
}

void Model::userSetMotorSpeed(int speed)
{
    //struct Message msg;
    //msg.eventType = 

    //xQueueSend(gui_msg_q, &msg, 0);
    //touchgfx_printf("motorSpeedChanged %d\n", speed);
#ifndef SIMULATOR
    int msg = 0;
    msg = speed * 30;
    osStatus_t status;

    status = osMessageQueuePut (motorSpeedQueueHandle, &msg, 0, 0);

    //if ( status == osOK )
    //{

    //}
#endif
}

 

 

    5. This is picked up by the Motor Speed task via the 'osMessageQueueGet' method defined previously where the speed value is sent to the STMod Fanout board and then the MIKROE-3000.

 

    6. Build and load the code

 

    7.  Install the STMod Fanout board with MIKROE-3000 to the STM32H7B3i-DK

image

 

   Wiring:

   VIN        - 5V Power Supply

   GND      - Ground of Power Supply

   M1-M2  - Motor

 

    8. Video of Motor Controll Demo

 

Embeddded Wizard

 

Useful Links


  Embedded Wizard is another tool that can be used to great a GUI Interface for the STM32H7B3i-DK.  There is a different approach with Embedded Wizard in that it has a built in Prototyer which provides a WYSIWYG interface where the GUI designed in the Embedded Wizard Studio is what will be seen when installed on the board.  Also, there are two versions of the Embedded Wizard - Free and Pro.  The Free version has limitations with regards to the GUI design that can be created where the Pro version is full-featured but requires a purchased license. 

    1. The first step is to download and install the Embedded Wizard.  The Free version was used in the RoadTest:

        https://www.embedded-wizard.de/download/download-free-edition

 

    2. Then open the Embedded Wizard Studio to create a GUI.

image

 

    3. There are multiple options to choose at this point.  In the right side of the screen there is an option to "Open an example project" to access the avaiable examples.

image

 

    4. The Quick Tour is a good place to start.

image

 

    5. From Embedded Wizard Studio, there are many options to edit a GUI.  Embedded Wizard uses a universal, target system imdependent programming language called Chora for creating the interfaces.

    See: https://doc.embedded-wizard.de/chora-reference?v=9.30

 

    6. For the RoadTest, a 'Hello' prjoject was created showing a basic screen with text in the middle.

image

 

    7. To load the code to the STM32H7B3i-DK, find the location of the Embedded Wizard project and copy the files in the Project folder and place them in the Application/GeneratedCode folder for the asscociated board.

   Ex:  Project location:

image

 

      Embedded Wizard STM32H7B30-Discovery folder:

image

 

    8. Under the STM32H7B30-Discovery folder, there is a file 'StartGccBuildEnvironment.bat'. This file has the settings for the target board and is where the STMCubeProgrammer tool location is defined.

image

 

    9. The 'devenv.cmd' file located under 'EmbeddedWizard\STM32H7B3-Discovery\Application\Project\GCC' defines the paths for the code, libraries and ST-LINK.

image

 

    10.  To build and install the application to the target, open a command window and navigate to the 'STM32H7B3-Discovery' folder.

           Run the 'StartGccBuildEnvironment.bat' script.  This will set the environment variables and place the cursor in the GCC folder.

image

 

    11.  Type 'make' to build the code.

image

 

    12. Ensure the board is connected and run 'make install' to load the code to the board.

image

image

 

    13. If all goes well, the code should be running on the board.

image

 

    14. Video of Embedded Wizard Hello code running

 

   Embedded Wizard MasterDemo

 

    This is an example of running the Embedded Wizard MasterDemo on the STM32H7B3i-DK

    1. Navigate to the 'EmbeddedWizard\STM32H7B3-Discovery\MasterDemo' folder and run the 'FlashMasterDemo.bat' script.

        This should build and flash the code to the board.

image

image

 

    2. MasterDemo running on the board

image

 

    3. Video of MasterDemo running

 

Conclusion

 

The STM32H7B3i-DK is a nice board with many features which were barely touched in this RoadTest. This is an excellent platform for evaluating the STM32H7 Single Core MCU as well as to get familiar with the STM GUI tools. Overall, outside of some issues between the STMCube software applications, the platform and tools were good to work with. I can see using this in a future project.

Anonymous