 Welcome to this presentation of the STM32 WB standard peripherals. We'll begin by providing a brief introduction and a summary of the STM32 cube firmware package. We'll follow this with a presentation of some of the peripherals commonly used within the STM32 WB. Finally, we put everything together by going through a worked example. The focus of the STM32 is towards Bluetooth, LD, ZigBee, Thread, and 802.15.4 applications. The Cortex-M0 plus contains the binary stack contents for the various standards and protocols, while the Cortex-M4 contains the application programming. Although the CM0 accesses peripherals required to implement the various stack protocols, the user or application interface is accomplished by the M4. The CM4 represents the application area and contains the same standard set of peripherals similar to other STM32 devices. In this presentation, we focus on the peripherals most commonly used. A high-level walkthrough of the peripherals examples is provided. The examples chosen are most commonly used when developing with the STM32 WB. This slide represents a detailed view of the STM32 WB and all its components. The focus will be on the items related to the common run mode domain and the elements connected to the internal AHB bus. The functional operation of the STM32 WB can be summarized into the following key areas. Several examples within the STM32 CUBE firmware package are provided to demonstrate the operation of the key item shown in this slide. Let's look at the STM32 CUBE firmware package structure. The STM32 CUBE firmware can be obtained either through the update mode by a CUBE MX or directly from the ST.com website. The file structure contains the entire suite of examples for the various board and device variants available. Note that these examples are intended to offer a means to user can directly port to their application. Let's get started by migrating to the STM32 CUBE firmware main folder. Open this folder and select the Projects folder. It will open up to several choices of boards and wireless binaries. We'll use the WB55 board as the basis for examination of all examples. In this area we see several folders. The examples folder is the one we will use. Later in the presentation, a short summary of the examples low level and examples mixed folders will be provided. Select the examples folders and open it. Select the UART folder and open it. Once opened, the various projects available for this peripheral are shown in separate folders. Let's select the UART printout project. It opens to a series of files with various IDEs, the CUBE MX IOC file and a README file to briefly describe the project. For this presentation, we will be working with the STM32 CUBE IDE as the base IDE. However, any IDE can be used and provide the same outcome. A reduced set of interfaces and peripherals is shown. As describing all interfaces and peripherals can be a lengthy process, the most frequently used interfaces and peripherals are provided and summarized. Let's look at the board support package. The Nucleo board and the USB dongle board provide board support packages tailored to each board. This example demonstrates the various APIs contained within the HAL library. GPIO, API control, timer functions, switch interfaces are the key elements demonstrated by this example. As with any other example presented, this example can be built, modified as required. Here, an example extracted GPIO code that is generated by CUBE MX is shown. Built the configuration of the IRQ handler in a GPIO callback to service the interrupt that has occurred at the specific GPIO input pin. Some of the code is generated by CUBE MX and some of the code requires user inputs. The examples show the areas where the user code can be implemented and areas where auto-generated code is generated by CUBE MX. Again, this uses HAL APIs and the code is completely portable to a custom user interface. We now examine some important blocks within the CPU and system areas of the processor. This is a large and complex area study that could support its own separate presentation. In the next few slides, we touch on some of the more important aspects of this area. In the Cortex folder, two key examples are provided to demonstrate how to manage the various device stacks and also how to enable and disable memory protection. More important, the examples demonstrate how to control and switch into each mode of operation as well as how to recover when a fault or error occurs in either area. We urge the user to spend some time to run and review these examples. There are several useful commands in place to allow for customization and this is the best way to understand the workings of this very important aspect of the Cortex processor. DMA functionality is one of the most important blocks within a CPU system. It can be programmed to provide transfers between a memory map source and a memory map destination without the intervention of the CPU. In this example, the DMA set to transfer from Flash to Embedded SRAM. DMA1 channel 1 is set as a transfer mechanism. Within the example, both source and destination addresses are auto-incremented. A transfer complete is generated at the end of the transfer. This is very useful when interfacing to a peripheral. The DMA can be triggered in many ways. As an example, receiving a trigger from a peripheral such as a timer and transferring the data into another location based on the settings of the DMA itself. Power management is a large part of the device features, especially for remote battery operated scenarios or conditions which limit the available power that can be drawn from a particular DC or AC source. Several examples are provided to demonstrate the various methods available to the user in order to enter a low power state and various methods available to exit from a low power state and transition back to normal mode. In addition, examples that demonstrate how deep low power modes such as standby can be entered and controlled via the RTC clock domain. Wake can occur via RTC, inter-al wake settings or other mechanisms such as external interrupt. The table shows the current consumption for each of the various low power states as information only. Let's now look at some flash memory examples that demonstrate the control and programming of flash memory. In a flash folder we see two important examples. The flash erase program demonstrates a page by page erase prior to programming. The desired memory locations are erased and then programmed. This example also demonstrates options by programming and control. The second example demonstrates how to set up write protection for a defined set of pages. This makes use of the how flash option by launch function and the use of the flash page program directive. This example provides the required sequence of events required to access the erase and program a predefined set of pages. This is a very useful example that is easily extended to a dual bank programming. The quad-spy memory interface provides a communication interface allowing for the integration of external serial flash memories. This effectively extends the memory size of the device. Using the quad-spy interface becomes a very useful when other peripherals such as external display functionality is required. This example demonstrates how to execute in place, extend the memory map to the external flash, read, write, erase this memory. Timers and watchdogs. The timer examples provide a large set of functionality and flexibility when it comes to programming. Essentially almost any timing scenario can be developed. Examples demonstrate the ability to generate a straightforward time base through two examples that demonstrate generation of PWM and frequency IJAL outputs that can be modified on the fly. The examples also demonstrate waveform generation as well as a variety of different triggering combinations with both external and internal functionality. Finally, a timer can be set as the important trigger to define and execute a DMA event. The user is encouraged to experiment with the timer examples and to consult with the various references provided at the end of this presentation. The low-power block is treated as a separate item as it covers many application areas complementing the watchdog functionality and some security aspects. The advantage of a low-power timer is that it can operate in any low-power mode except for standby. Typical use cases are the implementation of a timeout where a trigger can be generated if the counter reaches a predetermined value, thereby serving as an alarm. Combined with the comparator block, this can provide a similar analog watchdog functionality as is provided by the ADC watchdog example. Other examples are that it does not require an internal clock to operate. It can operate when an external clock is needed. Watchdog timers provide application management allowing the MCU to be reset when a problem occurs. This also can be used to manage an exit from a hardware timeout condition. In addition, conditions where software end up in a runaway or a no exit condition can be managed and reset by the watchdog timers. This particular set of examples demonstrate what occurs when a right to an illegal location is performed. The resulting action is a hard fault. The example demonstrates how the watchdog timer times out, causing a reset, allowing the processor to exit and recover from the hard fault. Let's review the communication interfaces. We provide a description of the two more popular interfaces. However, as can be seen in the examples folder, other interfaces can be implemented. The serial peripherals folder provides several examples that demonstrate the operation in master or slave mode. The communications control interface is based upon DMA, interrupt or polling driven schemes. The SPI provides a standardized approach for communicating with external devices. The interface is configurable to support many standard protocols and requires only a few pins to implement. The UART interface offers several operational advantages. It provides wake from low power mode, transmit and receive files with the ability to operate in stop modes. Several interface centers are supported. It can act as an SPI master, can emulate the local interconnect mode, ISO, IEC smart cards and infrared devices, and also implements the Modbus communication. Let's review a special case implementation of the UART interface. The example demonstrates how the UART can be used to reroute the C library printf function via the UART to a terminal window. Printf is a very useful project to demonstrate how to add printf statements for debug and monitoring purposes within code. The example demonstrates how to incorporate the functionality such it becomes a useful debug tool for all projects. Analog interfaces. The analog section consists of ADCs and comparator functions. Note that a DAC is not available within the STM32WB peripheral library. However, in many cases, a DAC output can be emulated through the use and control of timer peripherals. Alternatively, through the use of a timer plus DMA plus GPIO configuration, a sinusoid can be generated by emulating a sigma delta modulator. This unfortunately is not a topic within the scope of this presentation. In the ADC folder, several important examples are provided. The ADC watchdog allows monitoring of external levels and processes in low-power modes. The user can compare this functionality with that of a low-powered timer plus comparator. ADC multi-channel conversion is commonly used to rank or order or schedule ADC sampling sequences when multiple channels of the same ADC are selected at the same time. ADC oversampling can be used to increase the number of effective bits of the ADC. As an example, a 12-bit ADC can be extended to provide 16-bit granularity by increasing a sampling rate. ADC single conversion is normally triggered by software and monitored by software. It can be a one-time or repetitive process. Finally, ADC trigger timer DMA utilizes timer trigger events to convert moved data from the ADC to DMA internally with an intervention of the processor. A quick word regarding the low-level and mixed examples. Up to this point, all of the examples described are based upon a HAL library or HAL driver. Whether or not one uses the HAL or low-level drivers depends upon circumstances. The HAL library will effectively integrate and check many conditions during execution, while the low-level library essentially provides specific commands at a bit or register level. To the user, this offers finer control of a particular function. It can also offer code size reduction and execution advantages. This HAL or needs to be evaluated on a case-by-case basis. The mixed format, as it is defined by the word mixed, combines both high-level and low-level function calls at the same time. The user may select the choice of how low-level calls or a mix of calls in QBMX configuration. Thank you for your patience to this point in the presentation. You'll now examine, run, and modify an existing example. This example is shown for demonstration purposes. It demonstrates a number of key features described. Timer 2 is set up to provide an interrupt on a repetitive basis. The ADC samples each timer to interrupt. The DMA controller is linked to timer 2. Thus, each time timer 2 generates an interrupt timer up command is also instructed to DMA to read ADC converted data and write it to an array in circular mode. Thus, the array gets continually filled. In this example, we also explore some useful debug features of the STM32 Q-by-DE. In step 2, we'll add another timer, timer 1 configured in PWM mode. This will serve as an input to ADC and additional debug features will be demonstrated. For the worked examples, please refer to the connection detail as shown below. Further detail can be found with reference to the STM32 WB nuclear schematic. Let's start QBMX and select the examples tab. This will directly load examples located in the QBMX firmware repository. This will also allow future modifications of the example while maintaining all existing code in place. On the left side, filter on STM32 WB. Then select the HAL trigger timer DMA example. Double-click on example. Select OK. Select OK again. We have now loaded the example and can generate directly from Qubed firmware to any IDE. Before we go further, we can also set up and demonstrate debug features that can be enabled to operate with Qubed IDE. Go to System Core. Select Sys. Select Trace Asynchronous. Select Project Manager. Under Advanced Settings, it is possible by peripheral to select what you want the HAL layer or the low level as an example. Go back to Project. Select the IDE chain to STM32 Qubed IDE and then generate code. Once complete, select the open project. Follow the Qubed IDE prompts and once complete, the project will be loaded. Expand the folders and select the main.c file. Much of the example code and initialization code is located in this file. The user can review the code and the flow. Note that the timer GPIO and DMA code is spread over the main.c and STM32 HAL MSP file. Once the build is completed, go to the Debug tab. Allow the debugger to load. Before going further, let's set up some debugger settings to assist in better viewing the results of this example. Once again, go back to the Debugger tab. Select Debug Configurations. Select Debugger. Ensure that the serial wire viewer is enabled and that the clock sands are 64 MHz. If they are not, please enter those values. Ensure also that the Enable Live Expressions is enabled. If you make a change, press Apply, then Debug. Successful download will be shown. Let's start the example. The example is now running, but we'd like to view the data. To do this, go to the top right window and select Live Expressions. Navigate down to the ADC Start DMA function call and copy and paste the ADC converted data into Live Expressions. Press Enter. We now see the ADC converted data represented by 64 Element Array. Let's expand this further. Re-adjust the window. We see now the ADC converted value. The input is actually set to 3.3 volts. In circular mode, the ADC values are being loaded through the DMA and continuously updated. This is a 64 Element Array that just continue runs in a circular mode. Take the time now to switch the input to 0 volts. Once this is done, we see that the input to ADC actually goes to 0. Let's now supply an input through another timer. We'll go back and adjust the Qubemix file and re-journey a new sample project. Make sure to stop the program. Navigate back to Qubemix and select the Pinout Configuration tab. Select Timers and Timer 1. We're going to set up a PWM output using Timer 1. Enable the PWM. Select the parameters as shown. In the Prescaler section, enter Value 64, and in the Counter Period, enter Value 40,000. Scroll down to PWM Generation of Channel 1. Enter a pulse width of 20,000. This will give us a 50% to be a cycle, but with a divide by 64 into the Prescalers, we have very slow waveforms. We can actually view this on the debugger output. Save your project and then generate file. Generate the code. Follow the prompts and Qubemix will automatically reload. Scroll down the main .c file to view the changes and additions we just made in Qubemix for Timer 1. Build this project. Before we build the project, there are a few steps we need to insert for both Timer 1 and debug purposes. On Line 67, initialize a temporary variable. On Line 156, we need to insert a function to start the PWM process. On Line 176, and for debug purposes only, inside the wild loop, we're going to isolate array element 12 from the ADC converted data. Notice otherwise that with the DMA process running, there would not be any processor intervention required. This is for debug purposes only. Save the changes, then build. Before starting the next step, we want to output to the ADC input. Select the Debugger tab and allow the debugger to load. Before launching the next session, we're going to add one additional debug feature. Go to Window, Show View, SWV, Trace Timeline Graph. A graph opens up at the bottom of your console. Let's configure this graph. I've already prefilled this table, but ensure the preschooler is enabled. Comparator 1 is selected. Temporary ADC is the variable we're trying to track. Access write, data value. Select OK. As the Timer 2 ADC and DMA conversion is not synchronized with Timer 1, we'll see two waveforms roll past each other. Start the trace and start the debug session. We now see two different debug outputs. In this window, we see the ADC array cycling through in a circular mode from the DMA process itself. Notice the 1010 format as the two Timer 1 and Timer 2 are not synchronized. In the graph output, we see the 12-bit ADC value from array element 12 isolated. We can zoom in a bit to show that it's oscillating between the 0 and 1 itself. So we have two different ways to display the waveform. Hopefully, this is useful for you. We've also shown how an example can be run automatically and modified to build on it to customize it for a particular use. I hope you enjoyed this session on STM32WB standard peripherals. Below some useful application notes are provided for further reference. Thank you.