 Hello and welcome to this video about STM32 Cubemix Advanced Features. In this video we will address the four advanced features of STM32 Cubemix. First one is the library selection between HL and LL. Second one is the function call control. Third one is a callback setup and last one is the interrupt settings. I will start from Cubemix interface and I will use Cubid to look at the code generated. So let's start. First library selection between HL and LL. What are these HL and LL? HL is the hardware abstraction layer. It provides an API independent from the STM32 used. And the main point about HL that allows easier porting from one STM32 to the other. Also HL provides an API that makes first tests really easy. So it's really an easy library that allows you to start prototyping. The second one is the LL, so the low layer. This one is providing mostly a register level abstraction API. It allows complete control on the implementation. You know exactly what happens. The drawback will be that obtaining a working use case will require more effort compared to the HL. But on the other hand it will use a less flash memory. Now let's start from Cubemix first screen. We are using Cubemix 6.4 here. And we will use the board selector to select one board. I will select the discovery board and take our latest U5 board. And start a project with this. And initialize all peripherals. And don't activate trust zone. Here it is. So you can see all the GPIOs that are already initialized. And you can see for instance, here in the connectivity, all these peripherals analog also. And you can see here that we will activate the iCache to get best performance for this device. And to avoid any warning when we generate the code. The clock configuration is already set. So let's move to project manager. And name our project. So we are on the STM32 U5 disco. And this is test one. We will use a cube ID. And now let's go to advanced settings. So the first thing I wanted to show you is the HL selection. So you can see here that we have sometimes only LL. And sometimes you can select between HL and LL. So let's first generate the code with the default settings. So I click generate the code. And this code generation will generate all the initialization functions for the peripherals. Ok, so now let's open the project. And the project is open in the cube ID. So let's open the cube ID. Here we can see it was successfully imported. Let's close this and we have our project. Now if I see what was generated in the main.c file, you can see that we have all our initialization functions. And if I go to the first one, I press F3, you see everything is using HL API. And same for if I go back, same for other HL. Now let's go back to the cube mix. And select for example GPIO initialize with LL and also initialize with LL for RCC. And generate again the code. And this time we will not open the project. As it is already open, so I will close it. And go back to cube ID. And you can see the system was updated with using LL interface instead of using HL. Same for RCC. So let's find RCC initialization, which is a system clock here. And you can see that LL is used to initialize. So it's really a simple way to select what you want, or you want to initialize. It is possible to mix LL and HL. For this you will need to read documentation that is provided back here. You have one user manual for each Steam32 series. That is called description of the HL and low-layer drivers. And so this one will give you all details how to use each of the layers and how to mix them. Ok, now after library selection, let's switch to function call control. The purpose of Steam32 Cubemix is to generate a project structure and to provide implementation of the initialization of all peripherals selected. This initialization is done through function code, as we could see before. And here are the controls we can have for each generation of this function. And we will see in detail with Cubemix. So you can order them. There is some dependency to manage. So put one initialization function before the other. You can avoid the implementation of the call, but keep implementation of the function itself. So you have the function and you will call it by yourself at some point later. You can also remove completely the initialization of a specific peripheral. If you want to remove it temporarily or for debug purpose. And you can also set the function to be static or not. So back to our Cubemix. So here we had our driver selection and now we will address this part of the advanced settings. This column to generate the code. So you can simply remove the code generation. For instance here, I don't want to generate UCPD and it will not generate at all. We can see in the Cubed IDE so it's UCPD is here and we will see it will disappear. So you have the rank here that gives you the order of calling of this function and you can change it using these settings. For instance, you want I2C2 to be called before I2C1. You just need to do this. And here you have the column to not generate function calls. So if you want to put the function call later you can click here for instance for USB. We have the function call of USB here. So this one should be removed. But the implementation that we have here should remain. And then we have the visibility, static or not. So by default all functions are defined as static. As you can see here, static, all these functions are static. So let's define one function for example SPI. That is not static. And let's generate the code. We close here and select here and see what happened. Let's come back here. So the first thing we did is removing, if I come back, we removed UCPD. So here you can see we don't have UCPD here neither in the implementation. It's completely removed. Second thing we have done is to change I2C1, I2C2 order. You can see I2C2 now is called before I2C1. So this is really useful when you have some dependencies between some peripherals for instance. The next point is to not generate function calls. So we didn't generate, we asked to not generate function calls for the USB initialization. So you can see here it's removed. No more USB initialization. But we kept the implementation of this initialization. Let's come back to the main. And last point, we change the SPI2 static. So you can see that SPI2 here is defined here but is no more defined here. So you will find it in the main.h that was created with all the defines. You can find now SPI2 here. So this is all what you can do with this part. Now let's address the register callback part. Callback setup. This option is specific to HL and HL is able to manage the interrupt handlers for peripherals and each interrupt handler is able to call user defined functions on specific events. These functions are some default callbacks provided as a weak function. Now HL also provides specific code to register callback that can be activated through compilation flag and STM32 Cubemix allows this activation. This is the proposal of these check boxes. For instance, when you enable callback for ADC you will be allowed to call HL-ADC register callback. So let's try this and for instance activate callback for the UART we have here. So we have UART enable, disable of the callbacks. So let's generate the code. Let's see where the change was done. Actually it is in this configuration file for HL. So at the beginning you have the activation of each module that is used in HL and at the end you have the flags for each register callback and you can see that we activated the UART register callback. So let's see what it means. So we will do a search in the code and you can see that this is what we have done and here in the driver so in the HL there is an impact in the HL UART you use this flag to define specific callbacks source code UART register callback So this one is under this flag and allows the registration of each callback for the different features of the UART and then you can call this function and use it to define all your specific callbacks. So that's the point of this feature here to activate the user callback. Now let's move to our last advanced feature which is interrupt settings. This settings is actually accessible through NVIC peripherals in code generation tab and not in the advanced settings. So in this tab you can simply remove the interrupt handler if you already manage it the specific file for instance or generate the interrupt handler but remove the call to the HL IR QNL associated so that you have your own implementation. It allows also to move the interrupt enable at the end of all initialization if you need to have every initialization done before activating interrupts and during this interrupt activated at the end you can control the order of activation. So let's see this in Cubemix. So this one is here in NVIC settings here in the code generation. So you can see by default there are no interrupts activated for the peripherals so we will activate for instance interrupts for our UART here in NVIC activate this interrupt also for the two I2C we want to manage interrupts in I2C and that's it. Go back to the NVIC configuration here you can see that all these interrupts have been added and we can set this interrupt here in this column you can activate for instance all these interrupts to be set at the end of the initialization code and each interrupt here can be ordered for instance we want to have the UART at the beginning and then I2C and here for instance you don't want for UART to use the HL implementation so let's see what happens back to QBID let's go back to our main.c we are in interrupts so in our interrupt handler we have all the default interrupts and we have now I2C with the call to the HL here IRQ handler so same for all I2C and you can see for the UART the HL was not called and if we come back to main.c you can see that this function was added to be able to activate the interrupts so we go to the implementation and we can see that the UART is activated or the I2C so that's it for this configuration and that's it for the advanced settings of STM32 QBemix thank you for your attention