cancel
Showing results for 
Search instead for 
Did you mean: 

Creating a STM32CubMX ioc project for older STM32Cube firmware examples from the STM32Cube firmware repository part 1

AME MCU SM
ST Employee

The following article is part 1/2. In part 2, we briefly discuss how you can easily export your STM32 project to different STM32 series using the “List Pinout Compatible MCUs” option in the STM32CubeMX. Furthermore, part 2 also includes troubleshooting with the STM32F4. 

To view part 2, click here. 

Introduction

STM32 ioc files created using STM32CubeMX can streamline development and can abstract away all the tedious low-level configurations of the STM32 peripherals. However, the problem is that older STM32Cube firmware projects on the older boards lack this “ioc” configuration file. In this article, you get a walk through converting the old STM32 project, without the ioc file, to a more modern project containing the ioc file. In part 2 of the article, we briefly discuss how you can easily export your STM32 project to different STM32 series using the “List pinout compatible MCUs” option in the STM32CubeMX. If you get stuck at any point during the process, refer to the link section for the completed project [5].

 

1 Creating the STM32CubeMX ioc file from source code:

1.1 Pick your example project to convert:

Pick an example that has no ioc file. For this example, we pick the digital-to-analog converter (DAC) signal generation example on the STM32F4DISCOVERY. The good news is that you can easily generalize the process to any STM32 series and example projects. 

 

1334.png

  • The example code can be downloaded and accessed inside the STM32CubeF4 MCU firmware package:

  STM32F4 cube package examples [1]

  • Alternatively, you can also easily access the example through STMicroelectronics’s GitHub page:

  STM32F4 example signal generation GitHub page [2]
 

1.2 Understand your project output:

Before attempting to recreate the project, we should understand the expected output of the example project running on our MCU. According to the “readme.txt” of the “DAC_SignalsGeneration” example, the waveform will be generated on the PA4. Moving on, the user button will be used to select between the different waveforms (triangular or escalator). Also keep the DAC chapter in the STM32F407 reference manual RM0090 [6] handy as you walk through the original source code. This helps you understanding the configurations shown in the helper functions “DAC_Ch1_TriangleConfig” and “DAC_Ch1_EscalatorConfiging. It can also be helpful to reference any related application notes for the peripheral we are working with: For our example, we can reference the application note AN3126 [3]. To gain a good understanding of the project output, begin by running the original project without the ioc file and use your oscilloscope for measuring. Make the measurements at the pin PA4. Depending on whether the variable “ubSelectedWavesForm” is set to 1 or 0, you observe either a triangular wave generation (figure 1) or a custom wave (the escalator like waveform output in figure 2). 

 

Figure 1: Output for the original project from STM32Cube firmware example repository: Triangle wave generated by STM32F407 DAC on pin PA4.Figure 1: Output for the original project from STM32Cube firmware example repository: Triangle wave generated by STM32F407 DAC on pin PA4.
 

Figure 1 is easily generated using the dedicated HAL API “HAL_DACEx_TriangleWaveGenerate” (UM1725 [7]).  Also, refer to the triangular wave generator section in the MCU reference manual or refer to the DAC application note. Figure 2 is generated using DAC_Ch1_EscalatorConfig. Regarding figure 2, we create a custom waveform using an array of numbers then transfer the data to the DAC using the DMA peripheral. For more details on how to generate a custom waveform, refer to the application examples in AN3126. Similar to the DAC_SignalsGeneration example, we use the timer 6 for triggering the DMA transfer and for triggering the DAC steps. The frequency of the signal is related to the frequency of the trigger source (timer 6 in our case).
 

Figure 2: Output for the original project from STM32Cube firmware example repository: Custom wave (escalator waveform) generated by the STM32F407 DAC on pin PA4.Figure 2: Output for the original project from STM32Cube firmware example repository: Custom wave (escalator waveform) generated by the STM32F407 DAC on pin PA4.

1.3 Transfer the peripheral configuration to the ioc file:

Next, we use the “DAC_SignalsGeneration” main.c source file as a reference for creating our ioc project: STM32CubeF4/Projects/STM32F4-Discovery/Examples/DAC/DAC_SignalsGeneration/Src/main.c [4].


Create an empty STM32CubeMX project based on the STM32F4DISCOVERY like shown in figure 3:

 

Figure 3: ioc configuration: Empty STM32CubeMX project.Figure 3: ioc configuration: Empty STM32CubeMX project.

Next, we transfer the DAC configurations shown in the helper function DAC_Ch1_EscalatorConfig to the STM32CubeMX. For example, referring to figure 4, line 195, the trigger source is timer 6. We transfer these settings to the STM32CubeMX interface as shown in figure 6.

 

Figure 4: Original source code without the ioc: code for the DAC_Ch1_EscalatorConfig function.Figure 4: Original source code without the ioc: code for the DAC_Ch1_EscalatorConfig function.

Both escalator and triangle wave functions shown in figure 4 and 5 share some common DAC configurations. For our new project, based on the STM32CubeMX ioc configuration, we make some improvements to the code. Feel free to improve any of the code shown here, if you want. For example, we remove the old duplicate configuration code and use the “MX_DAC1_Init()” instead. You can also observe this in the attached project files.
 

Figure 5: Original source code without the ioc: code for the DAC_Ch1_TriangleConfig function.Figure 5: Original source code without the ioc: code for the DAC_Ch1_TriangleConfig function.

In figure 5, pay attention to the content for the variables inside the “DAC_ChannelConfTypeDef” structure (“sConfig”). As another example, line 228 indicates that the output buffer must be enabled (as we do in figure 6). This gives you clues on the DAC settings that need to be configured in the STM32CubeMX interface.
 

Figure 6: ioc configuration: STM32CubeMX DAC peripheral configuration.Figure 6: ioc configuration: STM32CubeMX DAC peripheral configuration.

 

Figure 7 shows the DMA configuration inside the “HAL_DAC_MspInit” located inside the “stm32f4xx_hal_msp.c” file.
 

Figure 7: Original source code without the ioc: DAC DMA configuration inside stm32f4xx_hal_msp.c file.Figure 7: Original source code without the ioc: DAC DMA configuration inside stm32f4xx_hal_msp.c file.

We transfer the DMA configuration to our ioc file shown in figure 8. Line 94 in figure 7 also shows we must enable the interrupt. This is done for us automatically by the STM32CubeMX, as shown in figure 9.
 

Figure 8: ioc configuration: DAC DMA configuration.Figure 8: ioc configuration: DAC DMA configuration.

Figure 9: ioc configuration: DAC interrupt configuration.Figure 9: ioc configuration: DAC interrupt configuration.

For figure 10, we arrive at the configuration for the general-purpose hardware timer on the STM32. Lines 288-291 and line 295 from figure 10 is transferred to the timer configuration window shown in figure 11. Timer 6 interrupts are not enabled, as shown in figure 12.
 

Figure 10: Original source code without the ioc: timer 6 configuration.Figure 10: Original source code without the ioc: timer 6 configuration.


 

Figure 11: ioc configuration: timer 6 configuration.Figure 11: ioc configuration: timer 6 configuration.

 

Figure 12: ioc configuration: timer 6 interrupt configuration.Figure 12: ioc configuration: timer 6 interrupt configuration.

Finally, we transfer the system clock configuration shown in figure 13 into the ioc clock tree shown in figure 14 and 15. In figure 14, we select the HSE crystal resonator as the fundamental clock source for our system (as shown on line 144 of figure 13).

 

Figure 13: Original source code without the ioc: MCU clock configuration.Figure 13: Original source code without the ioc: MCU clock configuration.

 

 

Figure 14: ioc configuration: Select HSE oscillator like original source code.Figure 14: ioc configuration: Select HSE oscillator like original source code.

 

 

Figure 15: ioc configuration: setup clock tree, reference "SystemClock_Config" function from original source code.Figure 15: ioc configuration: setup clock tree, reference "SystemClock_Config" function from original source code.

 

 

1.4 Transfer the main code logic into your new project space:

Note: at this point, make sure to save your STM32CubeMX ioc project and generate the code before proceeding
Before reproducing the output of the original project, do the following: Transfer some of the logic code from the old main.c to our new main.c in the project space with the ioc file.
Please note: you cannot simply copy and paste the main.c. If this is done, you only transfer the DAC related logic over into your new project - refer to the sample main.c inside the solution
project [5provided.
Do not copy the BSP routines into your new project. As seen in the main.c of the project solution, we made some minor changes. For example, we removed some of the duplicate DAC configuration code and instead used the generated "MX_DAC_Init()" call inside of the "DAC_Ch1_EscalatorConfig(void)" routine. As another example, observe the differences between this snippet of original source code for "DAC_Ch1_EscalatorConfig" and the modified version in our new project:

Original source code for one of the routines:

 

 

static void DAC_Ch1_EscalatorConfig(void)
{
  /*##-1- Initialize the DAC peripheral ######################################*/
  if(HAL_DAC_Init(&DacHandle) != HAL_OK)
  {
    /* Initialization Error */
    Error_Handler();
  }
  /*##-1- DAC channel1 Configuration #########################################*/
  sConfig.DAC_Trigger = DAC_TRIGGER_T6_TRGO;
  sConfig.DAC_OutputBuffer = DAC_OUTPUTBUFFER_ENABLE; 
  if(HAL_DAC_ConfigChannel(&DacHandle, &sConfig, DACx_CHANNEL1) != HAL_OK)
  {
    /* Channel configuration Error */
    Error_Handler();
  }
  /*##-2- Enable DAC Channel1 and associated DMA #############################*/
  if(HAL_DAC_Start_DMA(&DacHandle, DACx_CHANNEL1, (uint32_t*)aEscalator8bit, 6, DAC_ALIGN_8B_R) != HAL_OK)
  {
    /* Start DMA Error */
    Error_Handler();
  }
}

 

 

Our modified routine inside our new project:

 

 

static void DAC_Ch1_EscalatorConfig(void)
{
       MX_DAC1_Init();
         /*##-2- Enable DAC Channel1 and associated DMA #############################*/
         if(HAL_DAC_Start_DMA(&hdac1, DAC_CHANNEL_1, (uint32_t*)aEscalator8bit, 6, DAC_ALIGN_8B_R) != HAL_OK)
         {
           /* Start DMA Error */
           Error_Handler();
         }
}

 

 

 

1.5 Result:

For observing the result, you need at least a single oscilloscope channel attached to pin PA4. After compiling the code (see the attachment for the full project) and executing the code on the evaluation board, you should observe the following signal output shown in figure 16 and 17. 

Figure 16 Output result based on the new project with the STM32CubeMX ioc configuration file: Triangle wave generated by STM32F407 DAC on pin PA4.Figure 16 Output result based on the new project with the STM32CubeMX ioc configuration file: Triangle wave generated by STM32F407 DAC on pin PA4.

 

Figure 17: Output result based on the new project with the STM32CubeMX ioc configuration file: Custom wave (escalator waveform) generated by the STM32F407 DAC on pin PA4.Figure 17: Output result based on the new project with the STM32CubeMX ioc configuration file: Custom wave (escalator waveform) generated by the STM32F407 DAC on pin PA4.

 

2 What if we are having trouble sourcing the STM32F4?

Click here to enter part 2 of the article, explaining this issue. 

 

3 Links:

  1. https://www.st.com/en/embedded-software/stm32cubef4.html 
  2. https://github.com/STMicroelectronics/STM32CubeF4/blob/master/Projects/STM32F4-Discovery/Examples/DAC/DAC_SignalsGeneration/Src/main.c 
  3. https://www.st.com/resource/en/application_note/an3126-audio-and-waveform-generation-using-the-dac-in-stm32-products-stmicroelectronics.pdf
  4. https://github.com/STMicroelectronics/STM32CubeF4/blob/master/Projects/STM32F4-Discovery/Examples/DAC/DAC_SignalsGeneration/Src/main.c
  5. https://www.st.com/content/dam/AME/2023/MDG/stm32f407disc-and-nucleol476-projects.zip
  6. https://www.st.com/resource/en/reference_manual/rm0090-stm32f405415-stm32f407417-stm32f427437-and-stm32f429439-advanced-armbased-32bit-mcus-stmicroelectronics.pdf
  7. https://www.st.com/resource/en/user_manual/um1725-description-of-stm32f4-hal-and-lowlayer-drivers-stmicroelectronics.pdf
Version history
Last update:
‎2023-08-17 12:12 AM
Updated by: