 Let's start with the first hands-on exercise that is concerned with a new feature called IOS Output State Retention in standby. Let's give some background at first. In the standby mode by default, the IOS are in a floating state, which means high impedance and thus they are not being driven to any defined logical level. Due to this, some customers in the past were forced to use the stop mode where the content of all registers is preserved and thus also the GPIO configuration. Even when the standby mode was fulfilling all the requirements concerning the low power consumption and the wake-up time. With the standby mode, of course, you can reach even lower power consumption than with the stop mode. The fact that by default, the IOS in the standby mode are in the high impedance state might be an issue for control signals for external devices, such as slave select or chip select for some SPI slave devices or for some low-power control signals. Because, of course, we need to ensure that the proper voltage level is maintained even when the MCU is in a deep low-power mode such as standby, so that, for example, an SPI slave doesn't get activated by accident. Now how to solve this situation? If we enable this new feature, the IOS output state retention in standby, then when entering the standby mode, the IOS state is automatically sampled and the corresponding voltage level is applied through a pull-up or a pull-down resistor. So all we need to do is just to set one bit and then this all is done automatically. If we have an output set to high, it will be sampled and afterwards, a pull-up resistor will be connected to maintain the same voltage level. As some of you may know, we had a similar feature already on, for instance, STMC to L4 microcontrollers, but in that case, it was done manually for all the pins, which means we had to manually set either a pull-up or pull-down resistor for, for instance, the pin PA14. I don't know. Here, we just need to set one bit and that's all. It's done automatically afterwards. Quite important to note is that the pull-up and pull-down resistors, they remain connected and maintain the voltage level until this feature, the IOS state retention, is disabled by software. So as you may know, after wake-up from the standby mode, there is a reset and the pull-up and pull-down resistors remain connected the whole time until we disable it by software, which is to be done, of course, when we finish the configuration and the peripherals initialization and they are again ready to drive the signals. I can illustrate it here on a picture. So this case, the first half, is the case when the IOS state retention is disabled. So you can see that we are in the run mode and the GPIO mode is normal, which means whatever we have previously configured. Then, upon the execution of, for example, WFI instruction, wait for interrupt, we enter the pre-configured low-power mode, which is in our case standby, and you see that the GPIO mode has changed to floating and the IOS are not driven. And then after wake-up, we wake up to the run mode again and the state we can, again, there is a reset after standby, just to remind, and we can configure again whatever is needed for the application. But the problematic is this period where the pins are not driven and the state is not defined. If we enable this feature, then this is done here, still in the run mode. And then when we enter standby, the GPIO mode changes from normal to let me say a state retained. This means either pull up or pull down resistor connected. And then after wake-up, this is still applied until we disable it by software in the run mode. So you can imagine that in this part, we perform the configuration and initialization after a set. And then when it's finished, we clear the bit and the pull-up and pull-down resistors are disconnected. And we are again driving the signals using the peripherals or GPIOs configured as outputs. So that's all from the theoretical part. And now let's move to the hands-on exercise itself. So in this lab, we will use the Nucleo H563 ZI development board, which is one of the development boards available for this H5 family. We will observe the difference in behavior with and without IO standard retention enabled in standby. And we will make use of the STM32Cube software ecosystem. In particular, we will use the STM32Cube IDE and the built-in STM32Cube MX version. So first we will configure the MCU pinout and peripherals in the Cube MX. Then we will generate the project and we will add some application code and then we will verify the correct functionality. So let's get started. I will switch now to the Cube IDE and I will start a new STM32 project. And it will open the MCU selector where I will select our microcontroller. Yeah, of course we have a very, to some extent similar family, STM32 U5, which is also a new family, which is a low-power microcontroller, but it can run I think up to 160 or 70 megahertz. It is similar to H5, but H5 is in the high performance part of the portfolio. So it's not really a low-power microcontroller, but of course every microcontroller family features the low-power modes. So then it always depends on the requirements, how low the power consumption has to be. Okay, so I will start from the MCU MPU selector. As you can see, we can start also from the board selector, in which case some pins would be already pre-configured for us based on the external components on the development board, but I will start from an empty device and I will put here H563ZI and I will select the part here that is used on the nuclear board. This helps me to select the right part. I'll click on next. Now I have to select the project name. So for example, STMs do H5 IO retention. And by the way, this is the point where I have to decide whether I will use the trust zone or not, because as you may know, the H5 family is based on the ARM Cortex-AMSERT this RECORE with the trust zone technology. But we have here a relatively simple example and to keep things simple, we will start the project without the trust zone. So we will have just one project and not separated the secure and non-secure parts. So I'm now starting the project. Now I get the warning about the ICASH that we should enable ICASH to reach the maximum performance. This is not anyhow essential for this hands-on. It's just warning because ICASH is something that has been introduced on STM32 microcontrollers not so long ago. And it really helps greatly to increase the performance since the number of accesses to the slow flash memory is reduced thanks to this ICASH. And some customers forgot to activate it and then we get some support requests that the performance is not as it should be as expected. So we decided to use this warning in the QPAMX. So I will do it, but let me emphasize once again that this is not anyhow essential for our hands-on. It's just to get rid of this warning next time we generate the code. Okay, in the next step, I will use the USART3 and this is the one that is connected to the virtual comport and I will use the serial port for some traces. So I will activate it in the asynchronous mode. And I know that on the nuclear board, the right pins to use are PD8 and PD9. So now I have to remap those USART3 signals to the right pins. So I can press control and left click. And I can see the alternatives that I have and using drag and drop, I can simply remap the pins here in the pinout and configuration tab. So I will do it for both signals. Now I need to configure PB0 as output. This is the pin that is connected to the green LED. So if I can't find it, I can use here the help of this. I can just put here PB0 and we'll start flashing. I know it's the pin 46 now. So I will configure it as output. And then we have a user button connected to pin PC13. This is the one here pin seven and I will configure it as input. And for the USART3, I forgot to mention that we can leave the default settings which means the border rate will be 115,200 bits, eight bits, no parity and one stop bit. Okay, and that's all from the pinout and configuration. So now I can either press control S to save the project and thus also generate the code or there is a dedicated button, device configuration tool, code generation. So I will click on it and you can see that the code is being generated. Okay, now it's done and I'm in the main.c file and if I scroll down a little bit, you can see here that we have here some initialization functions that were generated according to our configuration into Kupemix. So we have configured some GPIOs. We have enabled ICache and we have configured USART3. So that is correct. And now I will add some code. And for that, I will use the cheat sheet that we prepared for the purpose of this workshop. So I will switch here to the GPIO retention hands-on and I will start by including the standard input output library. And we have here the defined user code sections. User code sections are recommended to use because if we regenerated the project, for example, we add additional peripheral in the Kupemix and we click on generate the code, the code inside these sections will be kept. So this is quite important. So I will include the standard input output library because I want to use a printf for debugging. Then in the private define, I will include my define to either enable or disable the IO retention feature. Then in the private function prototypes, this is just the printf redirection to UART. And then on the next page, I have my application code in the user code section too. It is relatively simple. So as you can see, in the first step, we will use it without the IO retention enabled. So let me say in the legacy mode. And at the beginning, we set the green LED. We will read the bit if because this might be happening after wake up from standby. So we will check if this was enabled. And if so, we will disable the IO retention. And then in both cases, we will wait in the main loop. We will be toggling with the green LED and waiting for user button press. And once the button is pressed, we will turn on the LED. This means it should be on and we will enter the standby mode. And we will see the difference in the behavior. And there are of course some delays to make it easily visible so that it's not happening too fast. So I can now build the project. So the project is now built and I will flash it. I don't have to enter the debug session this time. And you can see that the green LED is toggling. Okay, so we are here. We are here in this loop. Okay. And we wait for a user button press. And if I press the button, the LED goes off even though we set it here to high, which means it should be on. But once we enter the standby mode, it goes off because the corresponding pin PB0 is in the high impedance state. And it's not driven. Basically, we lost the state of the IO. Now if I press reset, and of course, in the typical application use case, we would wake up on RTC or user button press or from some external signal. But here to keep it simple, we don't have any wake up source for the standby. So I have to press the black reset button to wake up again. And I'm again in the main loop toggling, waiting for user button press. If I press it, it goes off. I will also configure the virtual comport. So I can here choose the right comport and this configuration. And you see the traces corresponding to the behavior. So when I press the user button, sorry, I didn't press. I enter the standby mode, use the reset button to wake up. And again, okay. And now I will here define the IO retention enable. I will rebuild the project. You can see that this part of the code is now active. So just before entering the standby mode, we will enable standby IO retention by calling this HAL API. I flash the project. You can see that this LED is toggling. Now it's done. So I can open the console. And now when I press on the user button, I enter the standby mode. Before that, I enable the IO retention and you see that the LED is on because it's voltage level is maintained thanks to this feature. I press reset. I'm again waiting in the main loop and press the user button and you see that the LED doesn't go off. So the IO output state is kept. And even if I press and hold the reset button, I keep the device under a set. You can see that it's the same because it's kept until it is disabled by software here. That's all from the hands on. So let me just quickly summarize what we have learned. How to use the IO state attention in the standby mode and what it can be used for. We also learned how to use the STM2Cube software ecosystem in particular the STM2Cube IDE with its built-in STM2Cube MX version. And we became familiar with the Nucleo H563Zi development board.