From af6a43b2e5268644f503e21b497fb7d870a3022a Mon Sep 17 00:00:00 2001
From: wisabel0 <wisabel@umich.edu>
Date: Thu, 19 Sep 2024 19:52:34 -0400
Subject: [PATCH] replaced pwm cube project with c++ project

---
 .../starter/servo/part1-pwm.md                |   31 +-
 starter-projects/servo/p1-pwm/.cproject       |  420 +-
 starter-projects/servo/p1-pwm/.mxproject      |   27 +-
 starter-projects/servo/p1-pwm/.project        |   66 +-
 starter-projects/servo/p1-pwm/Core/Inc/main.h |   10 +-
 .../p1-pwm/Core/Inc/stm32g4xx_hal_conf.h      |    2 +-
 .../servo/p1-pwm/Core/Inc/stm32g4xx_it.h      |    1 +
 .../p1-pwm/Core/Inc/stm32g4xx_nucleo_conf.h   |   78 +
 starter-projects/servo/p1-pwm/Core/Src/main.c |   53 +-
 .../servo/p1-pwm/Core/Src/stm32g4xx_it.c      |   14 +
 .../BSP/STM32G4xx_Nucleo/stm32g4xx_nucleo.c   |  676 +++
 .../BSP/STM32G4xx_Nucleo/stm32g4xx_nucleo.h   |  313 ++
 .../STM32G4xx_Nucleo/stm32g4xx_nucleo_errno.h |   46 +
 .../Inc/stm32g4xx_hal_uart.h                  | 1745 ++++++
 .../Inc/stm32g4xx_hal_uart_ex.h               |  929 ++++
 .../Inc/stm32g4xx_hal_usart.h                 | 1036 ++++
 .../Inc/stm32g4xx_hal_usart_ex.h              |  282 +
 .../Src/stm32g4xx_hal_uart.c                  | 4696 +++++++++++++++++
 .../Src/stm32g4xx_hal_uart_ex.c               | 1042 ++++
 .../Src/stm32g4xx_hal_usart.c                 | 3701 +++++++++++++
 .../Src/stm32g4xx_hal_usart_ex.c              |  541 ++
 ...{servo-p1-pwm.ioc => servo-p1-pwm-cpp.ioc} |  356 +-
 22 files changed, 15577 insertions(+), 488 deletions(-)
 create mode 100644 starter-projects/servo/p1-pwm/Core/Inc/stm32g4xx_nucleo_conf.h
 create mode 100644 starter-projects/servo/p1-pwm/Drivers/BSP/STM32G4xx_Nucleo/stm32g4xx_nucleo.c
 create mode 100644 starter-projects/servo/p1-pwm/Drivers/BSP/STM32G4xx_Nucleo/stm32g4xx_nucleo.h
 create mode 100644 starter-projects/servo/p1-pwm/Drivers/BSP/STM32G4xx_Nucleo/stm32g4xx_nucleo_errno.h
 create mode 100644 starter-projects/servo/p1-pwm/Drivers/STM32G4xx_HAL_Driver/Inc/stm32g4xx_hal_uart.h
 create mode 100644 starter-projects/servo/p1-pwm/Drivers/STM32G4xx_HAL_Driver/Inc/stm32g4xx_hal_uart_ex.h
 create mode 100644 starter-projects/servo/p1-pwm/Drivers/STM32G4xx_HAL_Driver/Inc/stm32g4xx_hal_usart.h
 create mode 100644 starter-projects/servo/p1-pwm/Drivers/STM32G4xx_HAL_Driver/Inc/stm32g4xx_hal_usart_ex.h
 create mode 100644 starter-projects/servo/p1-pwm/Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_uart.c
 create mode 100644 starter-projects/servo/p1-pwm/Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_uart_ex.c
 create mode 100644 starter-projects/servo/p1-pwm/Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_usart.c
 create mode 100644 starter-projects/servo/p1-pwm/Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_usart_ex.c
 rename starter-projects/servo/p1-pwm/{servo-p1-pwm.ioc => servo-p1-pwm-cpp.ioc} (68%)

diff --git a/docs/getting-started/starter/servo/part1-pwm.md b/docs/getting-started/starter/servo/part1-pwm.md
index b8e24a6..f9d50ae 100644
--- a/docs/getting-started/starter/servo/part1-pwm.md
+++ b/docs/getting-started/starter/servo/part1-pwm.md
@@ -20,10 +20,9 @@ so please reach out if you ever get stuck!
 ## Intro
 
 As mentioned earlier, by the end of the project you should be able to drive a servo.
-This project will also teach some coding practices used for STM32 code.
+This project will also teach some coding practices used for STM32 code. Similar to our real code, this starter project will be in C++.
 While you are working through the project, keep the following in mind:
 
-* How could you decrease the amount of space or processing power needed for your code?
 * How could you document your code so that others can easily read and understand it?
 * How could you write your code so that it can easily be adjusted for different pins, different number of servos, etc.?
 
@@ -75,10 +74,10 @@ calculating these values.
 ### 3. Creating the header file
 
 Having a Servo object will make it easier to adjust the number servos or where the servos are
-in the future, so for good practice, we will create a servo object and function prototypes in a
-header file.
+in the future, so for good practice, we will create a servo class and declare any member variables
+and member functions in a header file.
 
-On the menu to the left, in `Core`&rarr;`Inc`, create a new header file named `servo.h`.
+On the menu to the left, in `Core`&rarr;`Inc`, create a new header file named `servo.hpp`.
 
 ![creating a header file in CubeIDE](create_header.webp)
 
@@ -91,32 +90,22 @@ Near the top of the header file, copy in the following lines:
 
 #include <stdlib.h>
 
-#include "stm32f3xx_hal.h"
+#include "stm32g4xx_hal.h"
 ```
 
-Then, create a Servo struct with 3 member variables:
+Then, create a Servo class with 3 member variables:
 
 * `TIM_HandleTypeDef *timer` : this tells the STM which timer is being used to generate the PWM signal
 * `uint32_t channel` : this tells the STM which channel is being used for the PWM signal
 * `uint32_t *output` : this is the address of the output register where the number of ticks that are set to high is stored
 
-To avoid getting errors when using your Servo struct later on, make sure to declare it like this:
-```
-typedef struct {
-	// TODO: fill this in
-} Servo;
-```
 
-Create the function prototypes for the 3 functions that are needed to create and use a Servo object:
-* `new_servo`
-* `initialize_servo`
-* `set_servo_angle`
 
+Create the function prototypes for the 3 functions that are needed to create and use a Servo object:
+* A default constructor that does not take in any parameters
+* A constructor that initializes the servo with a timer, sets the channel, and 
+* `set_servo_angle` that converts an angle to the number of ticks for the CCR
 
-Try to fill out the header on your own, but here are some hints if you get stuck:
-* `new_servo` should take in parameters and return a Servo*
-* `initialize_servo` should initialize an existing Servo* to have a certain starting angle, it should also start the timer
-* `set_servo_angle` should convert an angle to the number of ticks for the CCR
 
 ### 4. Implementing Servo functions
 
diff --git a/starter-projects/servo/p1-pwm/.cproject b/starter-projects/servo/p1-pwm/.cproject
index 410fb06..6ccb06f 100644
--- a/starter-projects/servo/p1-pwm/.cproject
+++ b/starter-projects/servo/p1-pwm/.cproject
@@ -1,207 +1,215 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
-	<storageModule moduleId="org.eclipse.cdt.core.settings">
-		<cconfiguration id="com.st.stm32cube.ide.mcu.gnu.managedbuild.config.exe.debug.693426909">
-			<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.st.stm32cube.ide.mcu.gnu.managedbuild.config.exe.debug.693426909" moduleId="org.eclipse.cdt.core.settings" name="Debug">
-				<externalSettings/>
-				<extensions>
-					<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
-					<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
-					<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
-					<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
-					<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
-					<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
-				</extensions>
-			</storageModule>
-			<storageModule moduleId="cdtBuildSystem" version="4.0.0">
-				<configuration artifactExtension="elf" artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug" cleanCommand="rm -rf" description="" id="com.st.stm32cube.ide.mcu.gnu.managedbuild.config.exe.debug.693426909" name="Debug" parent="com.st.stm32cube.ide.mcu.gnu.managedbuild.config.exe.debug">
-					<folderInfo id="com.st.stm32cube.ide.mcu.gnu.managedbuild.config.exe.debug.693426909." name="/" resourcePath="">
-						<toolChain id="com.st.stm32cube.ide.mcu.gnu.managedbuild.toolchain.exe.debug.362112723" name="MCU ARM GCC" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.toolchain.exe.debug">
-							<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.target_mcu.2122221374" name="MCU" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.target_mcu" useByScannerDiscovery="true" value="STM32G431RBTx" valueType="string"/>
-							<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.target_cpuid.415017579" name="CPU" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.target_cpuid" useByScannerDiscovery="false" value="0" valueType="string"/>
-							<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.target_coreid.1746999933" name="Core" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.target_coreid" useByScannerDiscovery="false" value="0" valueType="string"/>
-							<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.fpu.1358872530" name="Floating-point unit" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.fpu" useByScannerDiscovery="true" value="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.fpu.value.fpv4-sp-d16" valueType="enumerated"/>
-							<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.floatabi.1870461520" name="Floating-point ABI" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.floatabi" useByScannerDiscovery="true" value="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.floatabi.value.hard" valueType="enumerated"/>
-							<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.target_board.1195798974" name="Board" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.target_board" useByScannerDiscovery="false" value="NUCLEO-G431RB" valueType="string"/>
-							<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.defaults.193731211" name="Defaults" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.defaults" useByScannerDiscovery="false" value="com.st.stm32cube.ide.common.services.build.inputs.revA.1.0.6 || Debug || true || Executable || com.st.stm32cube.ide.mcu.gnu.managedbuild.option.toolchain.value.workspace || NUCLEO-G431RB || 0 || 0 || arm-none-eabi- || ${gnu_tools_for_stm32_compiler_path} || ../Core/Inc | ../Drivers/STM32G4xx_HAL_Driver/Inc | ../Drivers/STM32G4xx_HAL_Driver/Inc/Legacy | ../Drivers/CMSIS/Device/ST/STM32G4xx/Include | ../Drivers/CMSIS/Include ||  ||  || USE_HAL_DRIVER | STM32G431xx ||  || Drivers | Core/Startup | Core ||  ||  || ${workspace_loc:/${ProjName}/STM32G431RBTX_FLASH.ld} || true || NonSecure ||  || secure_nsclib.o ||  || None ||  ||  || " valueType="string"/>
-							<option id="com.st.stm32cube.ide.mcu.debug.option.cpuclock.1789866402" superClass="com.st.stm32cube.ide.mcu.debug.option.cpuclock" useByScannerDiscovery="false" value="72" valueType="string"/>
-							<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="com.st.stm32cube.ide.mcu.gnu.managedbuild.targetplatform.1348907842" isAbstract="false" osList="all" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.targetplatform"/>
-							<builder buildPath="${workspace_loc:/servo-p1-pwm}/Debug" id="com.st.stm32cube.ide.mcu.gnu.managedbuild.builder.1145740871" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.builder"/>
-							<tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.1840751303" name="MCU/MPU GCC Assembler" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler">
-								<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.option.debuglevel.801205726" name="Debug level" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.option.debuglevel" value="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.option.debuglevel.value.g3" valueType="enumerated"/>
-								<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.option.definedsymbols.1235880470" name="Define symbols (-D)" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.option.definedsymbols" valueType="definedSymbols">
-									<listOptionValue builtIn="false" value="DEBUG"/>
-								</option>
-								<inputType id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.input.1211471336" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.input"/>
-							</tool>
-							<tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.1278399073" name="MCU/MPU GCC Compiler" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler">
-								<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.debuglevel.1466644975" name="Debug level" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.debuglevel" useByScannerDiscovery="false" value="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.debuglevel.value.g3" valueType="enumerated"/>
-								<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.optimization.level.888781489" name="Optimization level" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.optimization.level" useByScannerDiscovery="false"/>
-								<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.definedsymbols.956386600" name="Define symbols (-D)" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.definedsymbols" useByScannerDiscovery="false" valueType="definedSymbols">
-									<listOptionValue builtIn="false" value="DEBUG"/>
-									<listOptionValue builtIn="false" value="USE_HAL_DRIVER"/>
-									<listOptionValue builtIn="false" value="STM32G431xx"/>
-								</option>
-								<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.includepaths.431278467" name="Include paths (-I)" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.includepaths" useByScannerDiscovery="false" valueType="includePath">
-									<listOptionValue builtIn="false" value="../Core/Inc"/>
-									<listOptionValue builtIn="false" value="../Drivers/STM32G4xx_HAL_Driver/Inc"/>
-									<listOptionValue builtIn="false" value="../Drivers/STM32G4xx_HAL_Driver/Inc/Legacy"/>
-									<listOptionValue builtIn="false" value="../Drivers/CMSIS/Device/ST/STM32G4xx/Include"/>
-									<listOptionValue builtIn="false" value="../Drivers/CMSIS/Include"/>
-								</option>
-								<inputType id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.input.c.701098688" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.input.c"/>
-							</tool>
-							<tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.compiler.1798233582" name="MCU/MPU G++ Compiler" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.compiler">
-								<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.compiler.option.debuglevel.657580377" name="Debug level" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.compiler.option.debuglevel" useByScannerDiscovery="false" value="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.compiler.option.debuglevel.value.g3" valueType="enumerated"/>
-								<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.compiler.option.optimization.level.725131236" name="Optimization level" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.compiler.option.optimization.level" useByScannerDiscovery="false"/>
-								<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.compiler.option.definedsymbols.689452420" name="Define symbols (-D)" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.compiler.option.definedsymbols" useByScannerDiscovery="false" valueType="definedSymbols">
-									<listOptionValue builtIn="false" value="DEBUG"/>
-									<listOptionValue builtIn="false" value="USE_HAL_DRIVER"/>
-									<listOptionValue builtIn="false" value="STM32G431xx"/>
-								</option>
-								<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.compiler.option.includepaths.1026962372" name="Include paths (-I)" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.compiler.option.includepaths" useByScannerDiscovery="false" valueType="includePath">
-									<listOptionValue builtIn="false" value="../Core/Inc"/>
-									<listOptionValue builtIn="false" value="../Drivers/STM32G4xx_HAL_Driver/Inc"/>
-									<listOptionValue builtIn="false" value="../Drivers/STM32G4xx_HAL_Driver/Inc/Legacy"/>
-									<listOptionValue builtIn="false" value="../Drivers/CMSIS/Device/ST/STM32G4xx/Include"/>
-									<listOptionValue builtIn="false" value="../Drivers/CMSIS/Include"/>
-								</option>
-								<inputType id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.compiler.input.cpp.814282412" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.compiler.input.cpp"/>
-							</tool>
-							<tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.linker.1618638103" name="MCU/MPU GCC Linker" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.linker"/>
-							<tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.linker.1139929483" name="MCU/MPU G++ Linker" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.linker">
-								<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.linker.option.script.565150551" name="Linker Script (-T)" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.linker.option.script" value="${workspace_loc:/${ProjName}/STM32G431RBTX_FLASH.ld}" valueType="string"/>
-								<inputType id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.linker.input.1273056720" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.linker.input">
-									<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
-									<additionalInput kind="additionalinput" paths="$(LIBS)"/>
-								</inputType>
-							</tool>
-							<tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.archiver.685093225" name="MCU/MPU GCC Archiver" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.archiver"/>
-							<tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.size.578794979" name="MCU Size" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.size"/>
-							<tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.objdump.listfile.917883767" name="MCU Output Converter list file" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.objdump.listfile"/>
-							<tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.objcopy.hex.418009615" name="MCU Output Converter Hex" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.objcopy.hex"/>
-							<tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.objcopy.binary.1594903831" name="MCU Output Converter Binary" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.objcopy.binary"/>
-							<tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.objcopy.verilog.1079075219" name="MCU Output Converter Verilog" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.objcopy.verilog"/>
-							<tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.objcopy.srec.1212985957" name="MCU Output Converter Motorola S-rec" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.objcopy.srec"/>
-							<tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.objcopy.symbolsrec.123319457" name="MCU Output Converter Motorola S-rec with symbols" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.objcopy.symbolsrec"/>
-						</toolChain>
-					</folderInfo>
-					<sourceEntries>
-						<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="Core"/>
-						<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="Drivers"/>
-					</sourceEntries>
-				</configuration>
-			</storageModule>
-			<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
-		</cconfiguration>
-		<cconfiguration id="com.st.stm32cube.ide.mcu.gnu.managedbuild.config.exe.release.1895031093">
-			<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.st.stm32cube.ide.mcu.gnu.managedbuild.config.exe.release.1895031093" moduleId="org.eclipse.cdt.core.settings" name="Release">
-				<externalSettings/>
-				<extensions>
-					<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
-					<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
-					<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
-					<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
-					<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
-					<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
-				</extensions>
-			</storageModule>
-			<storageModule moduleId="cdtBuildSystem" version="4.0.0">
-				<configuration artifactExtension="elf" artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release" cleanCommand="rm -rf" description="" id="com.st.stm32cube.ide.mcu.gnu.managedbuild.config.exe.release.1895031093" name="Release" parent="com.st.stm32cube.ide.mcu.gnu.managedbuild.config.exe.release">
-					<folderInfo id="com.st.stm32cube.ide.mcu.gnu.managedbuild.config.exe.release.1895031093." name="/" resourcePath="">
-						<toolChain id="com.st.stm32cube.ide.mcu.gnu.managedbuild.toolchain.exe.release.240871197" name="MCU ARM GCC" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.toolchain.exe.release">
-							<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.target_mcu.2105813390" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.target_mcu" useByScannerDiscovery="true" value="STM32G431RBTx" valueType="string"/>
-							<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.target_cpuid.1525538957" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.target_cpuid" useByScannerDiscovery="false" value="0" valueType="string"/>
-							<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.target_coreid.97130308" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.target_coreid" useByScannerDiscovery="false" value="0" valueType="string"/>
-							<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.fpu.1729056299" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.fpu" useByScannerDiscovery="true" value="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.fpu.value.fpv4-sp-d16" valueType="enumerated"/>
-							<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.floatabi.691124038" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.floatabi" useByScannerDiscovery="true" value="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.floatabi.value.hard" valueType="enumerated"/>
-							<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.target_board.415398111" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.target_board" useByScannerDiscovery="false" value="NUCLEO-G431RB" valueType="string"/>
-							<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.defaults.773490245" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.defaults" useByScannerDiscovery="false" value="com.st.stm32cube.ide.common.services.build.inputs.revA.1.0.6 || Release || false || Executable || com.st.stm32cube.ide.mcu.gnu.managedbuild.option.toolchain.value.workspace || NUCLEO-G431RB || 0 || 0 || arm-none-eabi- || ${gnu_tools_for_stm32_compiler_path} || ../Core/Inc | ../Drivers/STM32G4xx_HAL_Driver/Inc | ../Drivers/STM32G4xx_HAL_Driver/Inc/Legacy | ../Drivers/CMSIS/Device/ST/STM32G4xx/Include | ../Drivers/CMSIS/Include ||  ||  || USE_HAL_DRIVER | STM32G431xx ||  || Drivers | Core/Startup | Core ||  ||  || ${workspace_loc:/${ProjName}/STM32G431RBTX_FLASH.ld} || true || NonSecure ||  || secure_nsclib.o ||  || None ||  ||  || " valueType="string"/>
-							<option id="com.st.stm32cube.ide.mcu.debug.option.cpuclock.978138956" superClass="com.st.stm32cube.ide.mcu.debug.option.cpuclock" useByScannerDiscovery="false" value="72" valueType="string"/>
-							<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="com.st.stm32cube.ide.mcu.gnu.managedbuild.targetplatform.94692934" isAbstract="false" osList="all" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.targetplatform"/>
-							<builder buildPath="${workspace_loc:/servo-p1-pwm}/Release" id="com.st.stm32cube.ide.mcu.gnu.managedbuild.builder.99516340" managedBuildOn="true" name="Gnu Make Builder.Release" parallelBuildOn="true" parallelizationNumber="optimal" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.builder"/>
-							<tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.2139743332" name="MCU/MPU GCC Assembler" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler">
-								<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.option.debuglevel.1956421651" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.option.debuglevel" value="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.option.debuglevel.value.g0" valueType="enumerated"/>
-								<inputType id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.input.294376248" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.input"/>
-							</tool>
-							<tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.236666190" name="MCU/MPU GCC Compiler" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler">
-								<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.debuglevel.1579600062" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.debuglevel" useByScannerDiscovery="false" value="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.debuglevel.value.g0" valueType="enumerated"/>
-								<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.optimization.level.1427627339" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.optimization.level" useByScannerDiscovery="false" value="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.optimization.level.value.os" valueType="enumerated"/>
-								<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.definedsymbols.55831467" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.definedsymbols" useByScannerDiscovery="false" valueType="definedSymbols">
-									<listOptionValue builtIn="false" value="USE_HAL_DRIVER"/>
-									<listOptionValue builtIn="false" value="STM32G431xx"/>
-								</option>
-								<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.includepaths.57120960" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.includepaths" useByScannerDiscovery="false" valueType="includePath">
-									<listOptionValue builtIn="false" value="../Core/Inc"/>
-									<listOptionValue builtIn="false" value="../Drivers/STM32G4xx_HAL_Driver/Inc"/>
-									<listOptionValue builtIn="false" value="../Drivers/STM32G4xx_HAL_Driver/Inc/Legacy"/>
-									<listOptionValue builtIn="false" value="../Drivers/CMSIS/Device/ST/STM32G4xx/Include"/>
-									<listOptionValue builtIn="false" value="../Drivers/CMSIS/Include"/>
-								</option>
-								<inputType id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.input.c.653698021" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.input.c"/>
-							</tool>
-							<tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.compiler.1619976885" name="MCU/MPU G++ Compiler" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.compiler">
-								<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.compiler.option.debuglevel.403939393" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.compiler.option.debuglevel" useByScannerDiscovery="false" value="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.compiler.option.debuglevel.value.g0" valueType="enumerated"/>
-								<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.compiler.option.optimization.level.1411550150" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.compiler.option.optimization.level" useByScannerDiscovery="false" value="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.compiler.option.optimization.level.value.os" valueType="enumerated"/>
-								<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.compiler.option.definedsymbols.1316182432" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.compiler.option.definedsymbols" useByScannerDiscovery="false" valueType="definedSymbols">
-									<listOptionValue builtIn="false" value="USE_HAL_DRIVER"/>
-									<listOptionValue builtIn="false" value="STM32G431xx"/>
-								</option>
-								<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.compiler.option.includepaths.518560466" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.compiler.option.includepaths" useByScannerDiscovery="false" valueType="includePath">
-									<listOptionValue builtIn="false" value="../Core/Inc"/>
-									<listOptionValue builtIn="false" value="../Drivers/STM32G4xx_HAL_Driver/Inc"/>
-									<listOptionValue builtIn="false" value="../Drivers/STM32G4xx_HAL_Driver/Inc/Legacy"/>
-									<listOptionValue builtIn="false" value="../Drivers/CMSIS/Device/ST/STM32G4xx/Include"/>
-									<listOptionValue builtIn="false" value="../Drivers/CMSIS/Include"/>
-								</option>
-								<inputType id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.compiler.input.cpp.305112550" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.compiler.input.cpp"/>
-							</tool>
-							<tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.linker.1091125883" name="MCU/MPU GCC Linker" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.linker"/>
-							<tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.linker.1633858427" name="MCU/MPU G++ Linker" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.linker">
-								<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.linker.option.script.1278753951" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.linker.option.script" value="${workspace_loc:/${ProjName}/STM32G431RBTX_FLASH.ld}" valueType="string"/>
-								<inputType id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.linker.input.1754926254" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.linker.input">
-									<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
-									<additionalInput kind="additionalinput" paths="$(LIBS)"/>
-								</inputType>
-							</tool>
-							<tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.archiver.136719829" name="MCU/MPU GCC Archiver" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.archiver"/>
-							<tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.size.845220032" name="MCU Size" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.size"/>
-							<tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.objdump.listfile.745233860" name="MCU Output Converter list file" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.objdump.listfile"/>
-							<tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.objcopy.hex.407477441" name="MCU Output Converter Hex" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.objcopy.hex"/>
-							<tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.objcopy.binary.1802421296" name="MCU Output Converter Binary" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.objcopy.binary"/>
-							<tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.objcopy.verilog.1355947175" name="MCU Output Converter Verilog" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.objcopy.verilog"/>
-							<tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.objcopy.srec.587333182" name="MCU Output Converter Motorola S-rec" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.objcopy.srec"/>
-							<tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.objcopy.symbolsrec.1200635422" name="MCU Output Converter Motorola S-rec with symbols" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.objcopy.symbolsrec"/>
-						</toolChain>
-					</folderInfo>
-					<sourceEntries>
-						<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="Core"/>
-						<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="Drivers"/>
-					</sourceEntries>
-				</configuration>
-			</storageModule>
-			<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
-		</cconfiguration>
-	</storageModule>
-	<storageModule moduleId="org.eclipse.cdt.core.pathentry"/>
-	<storageModule moduleId="cdtBuildSystem" version="4.0.0">
-		<project id="servo-p1-pwm.null.1814750046" name="servo-p1-pwm"/>
-	</storageModule>
-	<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
-	<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets"/>
-	<storageModule moduleId="scannerConfiguration">
-		<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
-		<scannerConfigBuildInfo instanceId="com.st.stm32cube.ide.mcu.gnu.managedbuild.config.exe.debug.693426909;com.st.stm32cube.ide.mcu.gnu.managedbuild.config.exe.debug.693426909.;com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.compiler.1798233582;com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.compiler.input.cpp.814282412">
-			<autodiscovery enabled="false" problemReportingEnabled="true" selectedProfileId=""/>
-		</scannerConfigBuildInfo>
-		<scannerConfigBuildInfo instanceId="com.st.stm32cube.ide.mcu.gnu.managedbuild.config.exe.release.1895031093;com.st.stm32cube.ide.mcu.gnu.managedbuild.config.exe.release.1895031093.;com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.compiler.1619976885;com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.compiler.input.cpp.305112550">
-			<autodiscovery enabled="false" problemReportingEnabled="true" selectedProfileId=""/>
-		</scannerConfigBuildInfo>
-		<scannerConfigBuildInfo instanceId="com.st.stm32cube.ide.mcu.gnu.managedbuild.config.exe.debug.693426909;com.st.stm32cube.ide.mcu.gnu.managedbuild.config.exe.debug.693426909.;com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.1278399073;com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.input.c.701098688">
-			<autodiscovery enabled="false" problemReportingEnabled="true" selectedProfileId=""/>
-		</scannerConfigBuildInfo>
-		<scannerConfigBuildInfo instanceId="com.st.stm32cube.ide.mcu.gnu.managedbuild.config.exe.release.1895031093;com.st.stm32cube.ide.mcu.gnu.managedbuild.config.exe.release.1895031093.;com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.236666190;com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.input.c.653698021">
-			<autodiscovery enabled="false" problemReportingEnabled="true" selectedProfileId=""/>
-		</scannerConfigBuildInfo>
-	</storageModule>
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
+	<storageModule moduleId="org.eclipse.cdt.core.settings">
+		<cconfiguration id="com.st.stm32cube.ide.mcu.gnu.managedbuild.config.exe.debug.348758887">
+			<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.st.stm32cube.ide.mcu.gnu.managedbuild.config.exe.debug.348758887" moduleId="org.eclipse.cdt.core.settings" name="Debug">
+				<externalSettings/>
+				<extensions>
+					<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
+					<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+				</extensions>
+			</storageModule>
+			<storageModule moduleId="cdtBuildSystem" version="4.0.0">
+				<configuration artifactExtension="elf" artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug" cleanCommand="rm -rf" description="" id="com.st.stm32cube.ide.mcu.gnu.managedbuild.config.exe.debug.348758887" name="Debug" parent="com.st.stm32cube.ide.mcu.gnu.managedbuild.config.exe.debug">
+					<folderInfo id="com.st.stm32cube.ide.mcu.gnu.managedbuild.config.exe.debug.348758887." name="/" resourcePath="">
+						<toolChain id="com.st.stm32cube.ide.mcu.gnu.managedbuild.toolchain.exe.debug.477769090" name="MCU ARM GCC" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.toolchain.exe.debug">
+							<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.target_mcu.1349733724" name="MCU" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.target_mcu" useByScannerDiscovery="true" value="STM32G431RBTx" valueType="string"/>
+							<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.target_cpuid.1234423684" name="CPU" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.target_cpuid" useByScannerDiscovery="false" value="0" valueType="string"/>
+							<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.target_coreid.2016888397" name="Core" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.target_coreid" useByScannerDiscovery="false" value="0" valueType="string"/>
+							<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.fpu.311083883" name="Floating-point unit" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.fpu" useByScannerDiscovery="true" value="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.fpu.value.fpv4-sp-d16" valueType="enumerated"/>
+							<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.floatabi.290930714" name="Floating-point ABI" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.floatabi" useByScannerDiscovery="true" value="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.floatabi.value.hard" valueType="enumerated"/>
+							<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.target_board.46319183" name="Board" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.target_board" useByScannerDiscovery="false" value="NUCLEO-G431RB" valueType="string"/>
+							<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.defaults.287093602" name="Defaults" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.defaults" useByScannerDiscovery="false" value="com.st.stm32cube.ide.common.services.build.inputs.revA.1.0.6 || Debug || true || Executable || com.st.stm32cube.ide.mcu.gnu.managedbuild.option.toolchain.value.workspace || NUCLEO-G431RB || 0 || 0 || arm-none-eabi- || ${gnu_tools_for_stm32_compiler_path} || ../Core/Inc | ../Drivers/STM32G4xx_HAL_Driver/Inc | ../Drivers/STM32G4xx_HAL_Driver/Inc/Legacy | ../Drivers/BSP/STM32G4xx_Nucleo | ../Drivers/CMSIS/Device/ST/STM32G4xx/Include | ../Drivers/CMSIS/Include ||  ||  || USE_NUCLEO_64 | USE_HAL_DRIVER | STM32G431xx ||  || Drivers | Core/Startup | Core ||  ||  || ${workspace_loc:/${ProjName}/STM32G431RBTX_FLASH.ld} || true || NonSecure ||  || secure_nsclib.o ||  || None ||  ||  || " valueType="string"/>
+							<option id="com.st.stm32cube.ide.mcu.debug.option.cpuclock.1870764986" superClass="com.st.stm32cube.ide.mcu.debug.option.cpuclock" useByScannerDiscovery="false" value="170" valueType="string"/>
+							<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="com.st.stm32cube.ide.mcu.gnu.managedbuild.targetplatform.211022890" isAbstract="false" osList="all" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.targetplatform"/>
+							<builder buildPath="${workspace_loc:/servo-p1-pwm-cpp}/Debug" id="com.st.stm32cube.ide.mcu.gnu.managedbuild.builder.967683024" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.builder"/>
+							<tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.1547703957" name="MCU/MPU GCC Assembler" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler">
+								<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.option.debuglevel.852383085" name="Debug level" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.option.debuglevel" value="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.option.debuglevel.value.g3" valueType="enumerated"/>
+								<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.option.definedsymbols.492886008" name="Define symbols (-D)" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.option.definedsymbols" valueType="definedSymbols">
+									<listOptionValue builtIn="false" value="DEBUG"/>
+								</option>
+								<inputType id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.input.856439359" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.input"/>
+							</tool>
+							<tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.785817497" name="MCU/MPU GCC Compiler" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler">
+								<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.debuglevel.1861822108" name="Debug level" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.debuglevel" useByScannerDiscovery="false" value="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.debuglevel.value.g3" valueType="enumerated"/>
+								<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.optimization.level.630386877" name="Optimization level" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.optimization.level" useByScannerDiscovery="false"/>
+								<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.definedsymbols.376142849" name="Define symbols (-D)" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.definedsymbols" useByScannerDiscovery="false" valueType="definedSymbols">
+									<listOptionValue builtIn="false" value="DEBUG"/>
+									<listOptionValue builtIn="false" value="USE_NUCLEO_64"/>
+									<listOptionValue builtIn="false" value="USE_HAL_DRIVER"/>
+									<listOptionValue builtIn="false" value="STM32G431xx"/>
+								</option>
+								<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.includepaths.1158915418" name="Include paths (-I)" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.includepaths" useByScannerDiscovery="false" valueType="includePath">
+									<listOptionValue builtIn="false" value="../Core/Inc"/>
+									<listOptionValue builtIn="false" value="../Drivers/STM32G4xx_HAL_Driver/Inc"/>
+									<listOptionValue builtIn="false" value="../Drivers/STM32G4xx_HAL_Driver/Inc/Legacy"/>
+									<listOptionValue builtIn="false" value="../Drivers/BSP/STM32G4xx_Nucleo"/>
+									<listOptionValue builtIn="false" value="../Drivers/CMSIS/Device/ST/STM32G4xx/Include"/>
+									<listOptionValue builtIn="false" value="../Drivers/CMSIS/Include"/>
+								</option>
+								<inputType id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.input.c.395568319" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.input.c"/>
+							</tool>
+							<tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.compiler.563940751" name="MCU/MPU G++ Compiler" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.compiler">
+								<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.compiler.option.debuglevel.1969708617" name="Debug level" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.compiler.option.debuglevel" useByScannerDiscovery="false" value="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.compiler.option.debuglevel.value.g3" valueType="enumerated"/>
+								<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.compiler.option.optimization.level.741948399" name="Optimization level" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.compiler.option.optimization.level" useByScannerDiscovery="false"/>
+								<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.compiler.option.definedsymbols.552512906" name="Define symbols (-D)" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.compiler.option.definedsymbols" useByScannerDiscovery="false" valueType="definedSymbols">
+									<listOptionValue builtIn="false" value="DEBUG"/>
+									<listOptionValue builtIn="false" value="USE_NUCLEO_64"/>
+									<listOptionValue builtIn="false" value="USE_HAL_DRIVER"/>
+									<listOptionValue builtIn="false" value="STM32G431xx"/>
+								</option>
+								<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.compiler.option.includepaths.445776435" name="Include paths (-I)" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.compiler.option.includepaths" useByScannerDiscovery="false" valueType="includePath">
+									<listOptionValue builtIn="false" value="../Core/Inc"/>
+									<listOptionValue builtIn="false" value="../Drivers/STM32G4xx_HAL_Driver/Inc"/>
+									<listOptionValue builtIn="false" value="../Drivers/STM32G4xx_HAL_Driver/Inc/Legacy"/>
+									<listOptionValue builtIn="false" value="../Drivers/BSP/STM32G4xx_Nucleo"/>
+									<listOptionValue builtIn="false" value="../Drivers/CMSIS/Device/ST/STM32G4xx/Include"/>
+									<listOptionValue builtIn="false" value="../Drivers/CMSIS/Include"/>
+								</option>
+								<inputType id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.compiler.input.cpp.236047746" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.compiler.input.cpp"/>
+							</tool>
+							<tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.linker.34908003" name="MCU/MPU GCC Linker" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.linker"/>
+							<tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.linker.1966543659" name="MCU/MPU G++ Linker" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.linker">
+								<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.linker.option.script.1462172632" name="Linker Script (-T)" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.linker.option.script" value="${workspace_loc:/${ProjName}/STM32G431RBTX_FLASH.ld}" valueType="string"/>
+								<inputType id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.linker.input.1274621626" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.linker.input">
+									<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
+									<additionalInput kind="additionalinput" paths="$(LIBS)"/>
+								</inputType>
+							</tool>
+							<tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.archiver.862848358" name="MCU/MPU GCC Archiver" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.archiver"/>
+							<tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.size.352261161" name="MCU Size" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.size"/>
+							<tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.objdump.listfile.857326654" name="MCU Output Converter list file" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.objdump.listfile"/>
+							<tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.objcopy.hex.610704237" name="MCU Output Converter Hex" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.objcopy.hex"/>
+							<tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.objcopy.binary.868335553" name="MCU Output Converter Binary" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.objcopy.binary"/>
+							<tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.objcopy.verilog.969783059" name="MCU Output Converter Verilog" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.objcopy.verilog"/>
+							<tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.objcopy.srec.166930491" name="MCU Output Converter Motorola S-rec" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.objcopy.srec"/>
+							<tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.objcopy.symbolsrec.1327386055" name="MCU Output Converter Motorola S-rec with symbols" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.objcopy.symbolsrec"/>
+						</toolChain>
+					</folderInfo>
+					<sourceEntries>
+						<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="Core"/>
+						<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="Drivers"/>
+					</sourceEntries>
+				</configuration>
+			</storageModule>
+			<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
+		</cconfiguration>
+		<cconfiguration id="com.st.stm32cube.ide.mcu.gnu.managedbuild.config.exe.release.2107684687">
+			<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.st.stm32cube.ide.mcu.gnu.managedbuild.config.exe.release.2107684687" moduleId="org.eclipse.cdt.core.settings" name="Release">
+				<externalSettings/>
+				<extensions>
+					<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
+					<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+				</extensions>
+			</storageModule>
+			<storageModule moduleId="cdtBuildSystem" version="4.0.0">
+				<configuration artifactExtension="elf" artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release" cleanCommand="rm -rf" description="" id="com.st.stm32cube.ide.mcu.gnu.managedbuild.config.exe.release.2107684687" name="Release" parent="com.st.stm32cube.ide.mcu.gnu.managedbuild.config.exe.release">
+					<folderInfo id="com.st.stm32cube.ide.mcu.gnu.managedbuild.config.exe.release.2107684687." name="/" resourcePath="">
+						<toolChain id="com.st.stm32cube.ide.mcu.gnu.managedbuild.toolchain.exe.release.1748166308" name="MCU ARM GCC" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.toolchain.exe.release">
+							<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.target_mcu.590232302" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.target_mcu" useByScannerDiscovery="true" value="STM32G431RBTx" valueType="string"/>
+							<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.target_cpuid.1067020634" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.target_cpuid" useByScannerDiscovery="false" value="0" valueType="string"/>
+							<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.target_coreid.1486209587" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.target_coreid" useByScannerDiscovery="false" value="0" valueType="string"/>
+							<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.fpu.1192480690" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.fpu" useByScannerDiscovery="true" value="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.fpu.value.fpv4-sp-d16" valueType="enumerated"/>
+							<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.floatabi.134971308" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.floatabi" useByScannerDiscovery="true" value="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.floatabi.value.hard" valueType="enumerated"/>
+							<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.target_board.328811400" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.target_board" useByScannerDiscovery="false" value="NUCLEO-G431RB" valueType="string"/>
+							<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.defaults.1805435785" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.defaults" useByScannerDiscovery="false" value="com.st.stm32cube.ide.common.services.build.inputs.revA.1.0.6 || Release || false || Executable || com.st.stm32cube.ide.mcu.gnu.managedbuild.option.toolchain.value.workspace || NUCLEO-G431RB || 0 || 0 || arm-none-eabi- || ${gnu_tools_for_stm32_compiler_path} || ../Core/Inc | ../Drivers/STM32G4xx_HAL_Driver/Inc | ../Drivers/STM32G4xx_HAL_Driver/Inc/Legacy | ../Drivers/BSP/STM32G4xx_Nucleo | ../Drivers/CMSIS/Device/ST/STM32G4xx/Include | ../Drivers/CMSIS/Include ||  ||  || USE_NUCLEO_64 | USE_HAL_DRIVER | STM32G431xx ||  || Drivers | Core/Startup | Core ||  ||  || ${workspace_loc:/${ProjName}/STM32G431RBTX_FLASH.ld} || true || NonSecure ||  || secure_nsclib.o ||  || None ||  ||  || " valueType="string"/>
+							<option id="com.st.stm32cube.ide.mcu.debug.option.cpuclock.1847903541" superClass="com.st.stm32cube.ide.mcu.debug.option.cpuclock" useByScannerDiscovery="false" value="170" valueType="string"/>
+							<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="com.st.stm32cube.ide.mcu.gnu.managedbuild.targetplatform.606840389" isAbstract="false" osList="all" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.targetplatform"/>
+							<builder buildPath="${workspace_loc:/servo-p1-pwm-cpp}/Release" id="com.st.stm32cube.ide.mcu.gnu.managedbuild.builder.1506825396" managedBuildOn="true" name="Gnu Make Builder.Release" parallelBuildOn="true" parallelizationNumber="optimal" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.builder"/>
+							<tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.1299820523" name="MCU/MPU GCC Assembler" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler">
+								<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.option.debuglevel.179749274" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.option.debuglevel" value="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.option.debuglevel.value.g0" valueType="enumerated"/>
+								<inputType id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.input.236668252" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.input"/>
+							</tool>
+							<tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.1673572823" name="MCU/MPU GCC Compiler" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler">
+								<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.debuglevel.1507346562" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.debuglevel" useByScannerDiscovery="false" value="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.debuglevel.value.g0" valueType="enumerated"/>
+								<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.optimization.level.1701899794" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.optimization.level" useByScannerDiscovery="false" value="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.optimization.level.value.os" valueType="enumerated"/>
+								<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.definedsymbols.251342544" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.definedsymbols" useByScannerDiscovery="false" valueType="definedSymbols">
+									<listOptionValue builtIn="false" value="USE_NUCLEO_64"/>
+									<listOptionValue builtIn="false" value="USE_HAL_DRIVER"/>
+									<listOptionValue builtIn="false" value="STM32G431xx"/>
+								</option>
+								<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.includepaths.898157651" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.includepaths" useByScannerDiscovery="false" valueType="includePath">
+									<listOptionValue builtIn="false" value="../Core/Inc"/>
+									<listOptionValue builtIn="false" value="../Drivers/STM32G4xx_HAL_Driver/Inc"/>
+									<listOptionValue builtIn="false" value="../Drivers/STM32G4xx_HAL_Driver/Inc/Legacy"/>
+									<listOptionValue builtIn="false" value="../Drivers/BSP/STM32G4xx_Nucleo"/>
+									<listOptionValue builtIn="false" value="../Drivers/CMSIS/Device/ST/STM32G4xx/Include"/>
+									<listOptionValue builtIn="false" value="../Drivers/CMSIS/Include"/>
+								</option>
+								<inputType id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.input.c.1084780046" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.input.c"/>
+							</tool>
+							<tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.compiler.1091284800" name="MCU/MPU G++ Compiler" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.compiler">
+								<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.compiler.option.debuglevel.1007964721" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.compiler.option.debuglevel" useByScannerDiscovery="false" value="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.compiler.option.debuglevel.value.g0" valueType="enumerated"/>
+								<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.compiler.option.optimization.level.236947014" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.compiler.option.optimization.level" useByScannerDiscovery="false" value="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.compiler.option.optimization.level.value.os" valueType="enumerated"/>
+								<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.compiler.option.definedsymbols.170306944" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.compiler.option.definedsymbols" useByScannerDiscovery="false" valueType="definedSymbols">
+									<listOptionValue builtIn="false" value="USE_NUCLEO_64"/>
+									<listOptionValue builtIn="false" value="USE_HAL_DRIVER"/>
+									<listOptionValue builtIn="false" value="STM32G431xx"/>
+								</option>
+								<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.compiler.option.includepaths.86517114" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.compiler.option.includepaths" useByScannerDiscovery="false" valueType="includePath">
+									<listOptionValue builtIn="false" value="../Core/Inc"/>
+									<listOptionValue builtIn="false" value="../Drivers/STM32G4xx_HAL_Driver/Inc"/>
+									<listOptionValue builtIn="false" value="../Drivers/STM32G4xx_HAL_Driver/Inc/Legacy"/>
+									<listOptionValue builtIn="false" value="../Drivers/BSP/STM32G4xx_Nucleo"/>
+									<listOptionValue builtIn="false" value="../Drivers/CMSIS/Device/ST/STM32G4xx/Include"/>
+									<listOptionValue builtIn="false" value="../Drivers/CMSIS/Include"/>
+								</option>
+								<inputType id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.compiler.input.cpp.1043748950" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.compiler.input.cpp"/>
+							</tool>
+							<tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.linker.1522908181" name="MCU/MPU GCC Linker" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.linker"/>
+							<tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.linker.384636908" name="MCU/MPU G++ Linker" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.linker">
+								<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.linker.option.script.535903432" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.linker.option.script" value="${workspace_loc:/${ProjName}/STM32G431RBTX_FLASH.ld}" valueType="string"/>
+								<inputType id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.linker.input.508806248" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.linker.input">
+									<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
+									<additionalInput kind="additionalinput" paths="$(LIBS)"/>
+								</inputType>
+							</tool>
+							<tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.archiver.988952543" name="MCU/MPU GCC Archiver" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.archiver"/>
+							<tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.size.986437503" name="MCU Size" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.size"/>
+							<tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.objdump.listfile.459588633" name="MCU Output Converter list file" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.objdump.listfile"/>
+							<tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.objcopy.hex.375115907" name="MCU Output Converter Hex" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.objcopy.hex"/>
+							<tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.objcopy.binary.461150259" name="MCU Output Converter Binary" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.objcopy.binary"/>
+							<tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.objcopy.verilog.1930796477" name="MCU Output Converter Verilog" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.objcopy.verilog"/>
+							<tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.objcopy.srec.1247176667" name="MCU Output Converter Motorola S-rec" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.objcopy.srec"/>
+							<tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.objcopy.symbolsrec.1717936671" name="MCU Output Converter Motorola S-rec with symbols" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.objcopy.symbolsrec"/>
+						</toolChain>
+					</folderInfo>
+					<sourceEntries>
+						<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="Core"/>
+						<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="Drivers"/>
+					</sourceEntries>
+				</configuration>
+			</storageModule>
+			<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
+		</cconfiguration>
+	</storageModule>
+	<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets"/>
+	<storageModule moduleId="org.eclipse.cdt.core.pathentry"/>
+	<storageModule moduleId="cdtBuildSystem" version="4.0.0">
+		<project id="servo-p1-pwm-cpp.null.1424326129" name="servo-p1-pwm-cpp"/>
+	</storageModule>
+	<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
+	<storageModule moduleId="scannerConfiguration">
+		<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
+		<scannerConfigBuildInfo instanceId="com.st.stm32cube.ide.mcu.gnu.managedbuild.config.exe.release.2107684687;com.st.stm32cube.ide.mcu.gnu.managedbuild.config.exe.release.2107684687.;com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.1673572823;com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.input.c.1084780046">
+			<autodiscovery enabled="false" problemReportingEnabled="true" selectedProfileId=""/>
+		</scannerConfigBuildInfo>
+		<scannerConfigBuildInfo instanceId="com.st.stm32cube.ide.mcu.gnu.managedbuild.config.exe.release.2107684687;com.st.stm32cube.ide.mcu.gnu.managedbuild.config.exe.release.2107684687.;com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.compiler.1091284800;com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.compiler.input.cpp.1043748950">
+			<autodiscovery enabled="false" problemReportingEnabled="true" selectedProfileId=""/>
+		</scannerConfigBuildInfo>
+		<scannerConfigBuildInfo instanceId="com.st.stm32cube.ide.mcu.gnu.managedbuild.config.exe.debug.348758887;com.st.stm32cube.ide.mcu.gnu.managedbuild.config.exe.debug.348758887.;com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.785817497;com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.input.c.395568319">
+			<autodiscovery enabled="false" problemReportingEnabled="true" selectedProfileId=""/>
+		</scannerConfigBuildInfo>
+		<scannerConfigBuildInfo instanceId="com.st.stm32cube.ide.mcu.gnu.managedbuild.config.exe.debug.348758887;com.st.stm32cube.ide.mcu.gnu.managedbuild.config.exe.debug.348758887.;com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.compiler.563940751;com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.cpp.compiler.input.cpp.236047746">
+			<autodiscovery enabled="false" problemReportingEnabled="true" selectedProfileId=""/>
+		</scannerConfigBuildInfo>
+	</storageModule>
 </cproject>
\ No newline at end of file
diff --git a/starter-projects/servo/p1-pwm/.mxproject b/starter-projects/servo/p1-pwm/.mxproject
index bd4177b..3c7a5d4 100644
--- a/starter-projects/servo/p1-pwm/.mxproject
+++ b/starter-projects/servo/p1-pwm/.mxproject
@@ -1,25 +1,26 @@
 [PreviousLibFiles]
-LibFiles=Drivers/STM32G4xx_HAL_Driver/Inc/stm32g4xx_hal_tim.h;Drivers/STM32G4xx_HAL_Driver/Inc/stm32g4xx_hal.h;Drivers/STM32G4xx_HAL_Driver/Inc/stm32g4xx_hal_tim_ex.h;Drivers/STM32G4xx_HAL_Driver/Inc/stm32g4xx_hal_pwr_ex.h;Drivers/STM32G4xx_HAL_Driver/Inc/stm32g4xx_hal_def.h;Drivers/STM32G4xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h;Drivers/STM32G4xx_HAL_Driver/Inc/stm32g4xx_hal_rcc.h;Drivers/STM32G4xx_HAL_Driver/Inc/stm32g4xx_hal_rcc_ex.h;Drivers/STM32G4xx_HAL_Driver/Inc/stm32g4xx_ll_bus.h;Drivers/STM32G4xx_HAL_Driver/Inc/stm32g4xx_ll_rcc.h;Drivers/STM32G4xx_HAL_Driver/Inc/stm32g4xx_ll_system.h;Drivers/STM32G4xx_HAL_Driver/Inc/stm32g4xx_ll_utils.h;Drivers/STM32G4xx_HAL_Driver/Inc/stm32g4xx_ll_crs.h;Drivers/STM32G4xx_HAL_Driver/Inc/stm32g4xx_hal_flash.h;Drivers/STM32G4xx_HAL_Driver/Inc/stm32g4xx_hal_flash_ex.h;Drivers/STM32G4xx_HAL_Driver/Inc/stm32g4xx_hal_flash_ramfunc.h;Drivers/STM32G4xx_HAL_Driver/Inc/stm32g4xx_hal_gpio.h;Drivers/STM32G4xx_HAL_Driver/Inc/stm32g4xx_hal_gpio_ex.h;Drivers/STM32G4xx_HAL_Driver/Inc/stm32g4xx_ll_gpio.h;Drivers/STM32G4xx_HAL_Driver/Inc/stm32g4xx_hal_exti.h;Drivers/STM32G4xx_HAL_Driver/Inc/stm32g4xx_ll_exti.h;Drivers/STM32G4xx_HAL_Driver/Inc/stm32g4xx_hal_dma.h;Drivers/STM32G4xx_HAL_Driver/Inc/stm32g4xx_hal_dma_ex.h;Drivers/STM32G4xx_HAL_Driver/Inc/stm32g4xx_ll_dma.h;Drivers/STM32G4xx_HAL_Driver/Inc/stm32g4xx_ll_dmamux.h;Drivers/STM32G4xx_HAL_Driver/Inc/stm32g4xx_hal_pwr.h;Drivers/STM32G4xx_HAL_Driver/Inc/stm32g4xx_ll_pwr.h;Drivers/STM32G4xx_HAL_Driver/Inc/stm32g4xx_hal_cortex.h;Drivers/STM32G4xx_HAL_Driver/Inc/stm32g4xx_ll_cortex.h;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_tim.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_tim_ex.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_pwr_ex.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_rcc.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_rcc_ex.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_flash.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_flash_ex.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_flash_ramfunc.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_gpio.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_exti.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_dma.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_dma_ex.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_pwr.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_cortex.c;Drivers/STM32G4xx_HAL_Driver/Inc/stm32g4xx_hal_tim.h;Drivers/STM32G4xx_HAL_Driver/Inc/stm32g4xx_hal.h;Drivers/STM32G4xx_HAL_Driver/Inc/stm32g4xx_hal_tim_ex.h;Drivers/STM32G4xx_HAL_Driver/Inc/stm32g4xx_hal_pwr_ex.h;Drivers/STM32G4xx_HAL_Driver/Inc/stm32g4xx_hal_def.h;Drivers/STM32G4xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h;Drivers/STM32G4xx_HAL_Driver/Inc/stm32g4xx_hal_rcc.h;Drivers/STM32G4xx_HAL_Driver/Inc/stm32g4xx_hal_rcc_ex.h;Drivers/STM32G4xx_HAL_Driver/Inc/stm32g4xx_ll_bus.h;Drivers/STM32G4xx_HAL_Driver/Inc/stm32g4xx_ll_rcc.h;Drivers/STM32G4xx_HAL_Driver/Inc/stm32g4xx_ll_system.h;Drivers/STM32G4xx_HAL_Driver/Inc/stm32g4xx_ll_utils.h;Drivers/STM32G4xx_HAL_Driver/Inc/stm32g4xx_ll_crs.h;Drivers/STM32G4xx_HAL_Driver/Inc/stm32g4xx_hal_flash.h;Drivers/STM32G4xx_HAL_Driver/Inc/stm32g4xx_hal_flash_ex.h;Drivers/STM32G4xx_HAL_Driver/Inc/stm32g4xx_hal_flash_ramfunc.h;Drivers/STM32G4xx_HAL_Driver/Inc/stm32g4xx_hal_gpio.h;Drivers/STM32G4xx_HAL_Driver/Inc/stm32g4xx_hal_gpio_ex.h;Drivers/STM32G4xx_HAL_Driver/Inc/stm32g4xx_ll_gpio.h;Drivers/STM32G4xx_HAL_Driver/Inc/stm32g4xx_hal_exti.h;Drivers/STM32G4xx_HAL_Driver/Inc/stm32g4xx_ll_exti.h;Drivers/STM32G4xx_HAL_Driver/Inc/stm32g4xx_hal_dma.h;Drivers/STM32G4xx_HAL_Driver/Inc/stm32g4xx_hal_dma_ex.h;Drivers/STM32G4xx_HAL_Driver/Inc/stm32g4xx_ll_dma.h;Drivers/STM32G4xx_HAL_Driver/Inc/stm32g4xx_ll_dmamux.h;Drivers/STM32G4xx_HAL_Driver/Inc/stm32g4xx_hal_pwr.h;Drivers/STM32G4xx_HAL_Driver/Inc/stm32g4xx_ll_pwr.h;Drivers/STM32G4xx_HAL_Driver/Inc/stm32g4xx_hal_cortex.h;Drivers/STM32G4xx_HAL_Driver/Inc/stm32g4xx_ll_cortex.h;Drivers/CMSIS/Device/ST/STM32G4xx/Include/stm32g431xx.h;Drivers/CMSIS/Device/ST/STM32G4xx/Include/stm32g4xx.h;Drivers/CMSIS/Device/ST/STM32G4xx/Include/system_stm32g4xx.h;Drivers/CMSIS/Device/ST/STM32G4xx/Include/system_stm32g4xx.h;Drivers/CMSIS/Device/ST/STM32G4xx/Source/Templates/system_stm32g4xx.c;Drivers/CMSIS/Include/core_sc300.h;Drivers/CMSIS/Include/core_armv8mbl.h;Drivers/CMSIS/Include/core_sc000.h;Drivers/CMSIS/Include/cmsis_version.h;Drivers/CMSIS/Include/cmsis_gcc.h;Drivers/CMSIS/Include/core_cm3.h;Drivers/CMSIS/Include/cmsis_iccarm.h;Drivers/CMSIS/Include/core_cm35p.h;Drivers/CMSIS/Include/core_armv81mml.h;Drivers/CMSIS/Include/cmsis_armclang.h;Drivers/CMSIS/Include/mpu_armv7.h;Drivers/CMSIS/Include/core_cm23.h;Drivers/CMSIS/Include/cmsis_armcc.h;Drivers/CMSIS/Include/core_cm0plus.h;Drivers/CMSIS/Include/core_cm7.h;Drivers/CMSIS/Include/core_cm4.h;Drivers/CMSIS/Include/tz_context.h;Drivers/CMSIS/Include/core_cm0.h;Drivers/CMSIS/Include/cmsis_armclang_ltm.h;Drivers/CMSIS/Include/core_cm1.h;Drivers/CMSIS/Include/cmsis_compiler.h;Drivers/CMSIS/Include/mpu_armv8.h;Drivers/CMSIS/Include/core_cm33.h;Drivers/CMSIS/Include/core_armv8mml.h;
+LibFiles=Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_hal.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_hal_def.h;Drivers\STM32G4xx_HAL_Driver\Inc\Legacy\stm32_hal_legacy.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_hal_rcc.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_hal_rcc_ex.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_ll_bus.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_ll_rcc.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_ll_system.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_ll_utils.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_ll_crs.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_hal_flash.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_hal_flash_ex.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_hal_flash_ramfunc.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_hal_gpio.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_hal_gpio_ex.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_ll_gpio.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_hal_exti.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_ll_exti.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_hal_dma.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_hal_dma_ex.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_ll_dma.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_ll_dmamux.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_hal_pwr.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_hal_pwr_ex.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_ll_pwr.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_hal_cortex.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_ll_cortex.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_hal_tim.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_hal_tim_ex.h;Drivers\BSP\STM32G4xx_Nucleo\stm32g4xx_nucleo_errno.h;Drivers\BSP\STM32G4xx_Nucleo\stm32g4xx_nucleo.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_hal_usart.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_hal_usart_ex.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_hal_uart.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_hal_uart_ex.h;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_rcc.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_rcc_ex.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_flash.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_flash_ex.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_flash_ramfunc.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_gpio.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_exti.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_dma.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_dma_ex.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_pwr.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_pwr_ex.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_cortex.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_tim.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_tim_ex.c;Drivers\BSP\STM32G4xx_Nucleo\stm32g4xx_nucleo.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_usart.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_usart_ex.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_uart_ex.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_uart.c;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_hal.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_hal_def.h;Drivers\STM32G4xx_HAL_Driver\Inc\Legacy\stm32_hal_legacy.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_hal_rcc.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_hal_rcc_ex.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_ll_bus.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_ll_rcc.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_ll_system.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_ll_utils.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_ll_crs.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_hal_flash.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_hal_flash_ex.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_hal_flash_ramfunc.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_hal_gpio.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_hal_gpio_ex.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_ll_gpio.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_hal_exti.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_ll_exti.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_hal_dma.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_hal_dma_ex.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_ll_dma.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_ll_dmamux.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_hal_pwr.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_hal_pwr_ex.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_ll_pwr.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_hal_cortex.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_ll_cortex.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_hal_tim.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_hal_tim_ex.h;Drivers\BSP\STM32G4xx_Nucleo\stm32g4xx_nucleo_errno.h;Drivers\BSP\STM32G4xx_Nucleo\stm32g4xx_nucleo.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_hal_usart.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_hal_usart_ex.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_hal_uart.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_hal_uart_ex.h;Drivers\CMSIS\Device\ST\STM32G4xx\Include\stm32g431xx.h;Drivers\CMSIS\Device\ST\STM32G4xx\Include\stm32g4xx.h;Drivers\CMSIS\Device\ST\STM32G4xx\Include\system_stm32g4xx.h;Drivers\CMSIS\Device\ST\STM32G4xx\Include\system_stm32g4xx.h;Drivers\CMSIS\Device\ST\STM32G4xx\Source\Templates\system_stm32g4xx.c;Drivers\CMSIS\Include\cmsis_armcc.h;Drivers\CMSIS\Include\cmsis_armclang.h;Drivers\CMSIS\Include\cmsis_armclang_ltm.h;Drivers\CMSIS\Include\cmsis_compiler.h;Drivers\CMSIS\Include\cmsis_gcc.h;Drivers\CMSIS\Include\cmsis_iccarm.h;Drivers\CMSIS\Include\cmsis_version.h;Drivers\CMSIS\Include\core_armv81mml.h;Drivers\CMSIS\Include\core_armv8mbl.h;Drivers\CMSIS\Include\core_armv8mml.h;Drivers\CMSIS\Include\core_cm0.h;Drivers\CMSIS\Include\core_cm0plus.h;Drivers\CMSIS\Include\core_cm1.h;Drivers\CMSIS\Include\core_cm23.h;Drivers\CMSIS\Include\core_cm3.h;Drivers\CMSIS\Include\core_cm33.h;Drivers\CMSIS\Include\core_cm35p.h;Drivers\CMSIS\Include\core_cm4.h;Drivers\CMSIS\Include\core_cm7.h;Drivers\CMSIS\Include\core_sc000.h;Drivers\CMSIS\Include\core_sc300.h;Drivers\CMSIS\Include\mpu_armv7.h;Drivers\CMSIS\Include\mpu_armv8.h;Drivers\CMSIS\Include\tz_context.h;
 
 [PreviousUsedCubeIDEFiles]
-SourceFiles=Core/Src/main.c;Core/Src/stm32g4xx_it.c;Core/Src/stm32g4xx_hal_msp.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_tim.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_tim_ex.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_pwr_ex.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_rcc.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_rcc_ex.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_flash.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_flash_ex.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_flash_ramfunc.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_gpio.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_exti.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_dma.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_dma_ex.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_pwr.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_cortex.c;Drivers/CMSIS/Device/ST/STM32G4xx/Source/Templates/system_stm32g4xx.c;Core/Src/system_stm32g4xx.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_tim.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_tim_ex.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_pwr_ex.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_rcc.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_rcc_ex.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_flash.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_flash_ex.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_flash_ramfunc.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_gpio.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_exti.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_dma.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_dma_ex.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_pwr.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_cortex.c;Drivers/CMSIS/Device/ST/STM32G4xx/Source/Templates/system_stm32g4xx.c;Core/Src/system_stm32g4xx.c;;;
-HeaderPath=Drivers/STM32G4xx_HAL_Driver/Inc;Drivers/STM32G4xx_HAL_Driver/Inc/Legacy;Drivers/CMSIS/Device/ST/STM32G4xx/Include;Drivers/CMSIS/Include;Core/Inc;
-CDefines=USE_HAL_DRIVER;STM32G431xx;USE_HAL_DRIVER;USE_HAL_DRIVER;
+SourceFiles=Core\Src\main.c;Core\Src\stm32g4xx_it.c;Core\Src\stm32g4xx_hal_msp.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_rcc.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_rcc_ex.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_flash.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_flash_ex.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_flash_ramfunc.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_gpio.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_exti.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_dma.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_dma_ex.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_pwr.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_pwr_ex.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_cortex.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_tim.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_tim_ex.c;Drivers\BSP\STM32G4xx_Nucleo\stm32g4xx_nucleo.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_usart.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_usart_ex.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_uart_ex.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_uart.c;Drivers\CMSIS\Device\ST\STM32G4xx\Source\Templates\system_stm32g4xx.c;Core\Src\system_stm32g4xx.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_rcc.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_rcc_ex.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_flash.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_flash_ex.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_flash_ramfunc.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_gpio.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_exti.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_dma.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_dma_ex.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_pwr.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_pwr_ex.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_cortex.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_tim.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_tim_ex.c;Drivers\BSP\STM32G4xx_Nucleo\stm32g4xx_nucleo.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_usart.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_usart_ex.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_uart_ex.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_uart.c;Drivers\CMSIS\Device\ST\STM32G4xx\Source\Templates\system_stm32g4xx.c;Core\Src\system_stm32g4xx.c;;;
+HeaderPath=Drivers\STM32G4xx_HAL_Driver\Inc;Drivers\STM32G4xx_HAL_Driver\Inc\Legacy;Drivers\BSP\STM32G4xx_Nucleo;Drivers\CMSIS\Device\ST\STM32G4xx\Include;Drivers\CMSIS\Include;Core\Inc;
+CDefines=USE_NUCLEO_64;USE_HAL_DRIVER;STM32G431xx;USE_HAL_DRIVER;USE_HAL_DRIVER;
 
 [PreviousGenFiles]
 AdvancedFolderStructure=true
-HeaderFileListSize=3
-HeaderFiles#0=../Core/Inc/stm32g4xx_it.h
-HeaderFiles#1=../Core/Inc/stm32g4xx_hal_conf.h
-HeaderFiles#2=../Core/Inc/main.h
+HeaderFileListSize=4
+HeaderFiles#0=..\Core\Inc\stm32g4xx_nucleo_conf.h
+HeaderFiles#1=..\Core\Inc\stm32g4xx_it.h
+HeaderFiles#2=..\Core\Inc\stm32g4xx_hal_conf.h
+HeaderFiles#3=..\Core\Inc\main.h
 HeaderFolderListSize=1
-HeaderPath#0=../Core/Inc
+HeaderPath#0=..\Core\Inc
 HeaderFiles=;
 SourceFileListSize=3
-SourceFiles#0=../Core/Src/stm32g4xx_it.c
-SourceFiles#1=../Core/Src/stm32g4xx_hal_msp.c
-SourceFiles#2=../Core/Src/main.c
+SourceFiles#0=..\Core\Src\stm32g4xx_it.c
+SourceFiles#1=..\Core\Src\stm32g4xx_hal_msp.c
+SourceFiles#2=..\Core\Src\main.c
 SourceFolderListSize=1
-SourcePath#0=../Core/Src
+SourcePath#0=..\Core\Src
 SourceFiles=;
 
diff --git a/starter-projects/servo/p1-pwm/.project b/starter-projects/servo/p1-pwm/.project
index b57b3f1..c9fa895 100644
--- a/starter-projects/servo/p1-pwm/.project
+++ b/starter-projects/servo/p1-pwm/.project
@@ -1,33 +1,33 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
-	<name>servo-p1-pwm</name>
-	<comment></comment>
-	<projects>
-	</projects>
-	<buildSpec>
-		<buildCommand>
-			<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
-			<triggers>clean,full,incremental,</triggers>
-			<arguments>
-			</arguments>
-		</buildCommand>
-		<buildCommand>
-			<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
-			<triggers>full,incremental,</triggers>
-			<arguments>
-			</arguments>
-		</buildCommand>
-	</buildSpec>
-	<natures>
-		<nature>com.st.stm32cube.ide.mcu.MCUProjectNature</nature>
-		<nature>com.st.stm32cube.ide.mcu.MCUCubeProjectNature</nature>
-		<nature>org.eclipse.cdt.core.cnature</nature>
-		<nature>org.eclipse.cdt.core.ccnature</nature>
-		<nature>com.st.stm32cube.ide.mcu.MCUCubeIdeServicesRevAev2ProjectNature</nature>
-		<nature>com.st.stm32cube.ide.mcu.MCUAdvancedStructureProjectNature</nature>
-		<nature>com.st.stm32cube.ide.mcu.MCUSingleCpuProjectNature</nature>
-		<nature>com.st.stm32cube.ide.mcu.MCURootProjectNature</nature>
-		<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
-		<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
-	</natures>
-</projectDescription>
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>servo-p1-pwm-cpp</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
+			<triggers>clean,full,incremental,</triggers>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
+			<triggers>full,incremental,</triggers>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>com.st.stm32cube.ide.mcu.MCUProjectNature</nature>
+		<nature>com.st.stm32cube.ide.mcu.MCUCubeProjectNature</nature>
+		<nature>org.eclipse.cdt.core.cnature</nature>
+		<nature>org.eclipse.cdt.core.ccnature</nature>
+		<nature>com.st.stm32cube.ide.mcu.MCUCubeIdeServicesRevAev2ProjectNature</nature>
+		<nature>com.st.stm32cube.ide.mcu.MCUAdvancedStructureProjectNature</nature>
+		<nature>com.st.stm32cube.ide.mcu.MCUSingleCpuProjectNature</nature>
+		<nature>com.st.stm32cube.ide.mcu.MCURootProjectNature</nature>
+		<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
+		<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
+	</natures>
+</projectDescription>
diff --git a/starter-projects/servo/p1-pwm/Core/Inc/main.h b/starter-projects/servo/p1-pwm/Core/Inc/main.h
index 8ce4964..0ea929e 100644
--- a/starter-projects/servo/p1-pwm/Core/Inc/main.h
+++ b/starter-projects/servo/p1-pwm/Core/Inc/main.h
@@ -28,6 +28,8 @@ extern "C" {
 
 /* Includes ------------------------------------------------------------------*/
 #include "stm32g4xx_hal.h"
+#include "stm32g4xx_nucleo.h"
+#include <stdio.h>
 
 /* Private includes ----------------------------------------------------------*/
 /* USER CODE BEGIN Includes */
@@ -57,8 +59,6 @@ void Error_Handler(void);
 /* USER CODE END EFP */
 
 /* Private defines -----------------------------------------------------------*/
-#define B1_Pin GPIO_PIN_13
-#define B1_GPIO_Port GPIOC
 #define RCC_OSC32_OUT_Pin GPIO_PIN_14
 #define RCC_OSC32_OUT_GPIO_Port GPIOC
 #define RCC_OSC32_OUTC15_Pin GPIO_PIN_15
@@ -67,12 +67,6 @@ void Error_Handler(void);
 #define RCC_OSC_IN_GPIO_Port GPIOF
 #define RCC_OSC_OUT_Pin GPIO_PIN_1
 #define RCC_OSC_OUT_GPIO_Port GPIOF
-#define LPUART1_TX_Pin GPIO_PIN_2
-#define LPUART1_TX_GPIO_Port GPIOA
-#define LPUART1_RX_Pin GPIO_PIN_3
-#define LPUART1_RX_GPIO_Port GPIOA
-#define LD2_Pin GPIO_PIN_5
-#define LD2_GPIO_Port GPIOA
 #define T_SWDIO_Pin GPIO_PIN_13
 #define T_SWDIO_GPIO_Port GPIOA
 #define T_SWCLK_Pin GPIO_PIN_14
diff --git a/starter-projects/servo/p1-pwm/Core/Inc/stm32g4xx_hal_conf.h b/starter-projects/servo/p1-pwm/Core/Inc/stm32g4xx_hal_conf.h
index 5240099..3fd515d 100644
--- a/starter-projects/servo/p1-pwm/Core/Inc/stm32g4xx_hal_conf.h
+++ b/starter-projects/servo/p1-pwm/Core/Inc/stm32g4xx_hal_conf.h
@@ -63,7 +63,7 @@
 /*#define HAL_SPI_MODULE_ENABLED   */
 /*#define HAL_SRAM_MODULE_ENABLED   */
 /*#define HAL_TIM_MODULE_ENABLED   */
-/*#define HAL_UART_MODULE_ENABLED   */
+#define HAL_UART_MODULE_ENABLED
 /*#define HAL_USART_MODULE_ENABLED   */
 /*#define HAL_WWDG_MODULE_ENABLED   */
 #define HAL_GPIO_MODULE_ENABLED
diff --git a/starter-projects/servo/p1-pwm/Core/Inc/stm32g4xx_it.h b/starter-projects/servo/p1-pwm/Core/Inc/stm32g4xx_it.h
index 02a8a4e..df51a60 100644
--- a/starter-projects/servo/p1-pwm/Core/Inc/stm32g4xx_it.h
+++ b/starter-projects/servo/p1-pwm/Core/Inc/stm32g4xx_it.h
@@ -55,6 +55,7 @@ void SVC_Handler(void);
 void DebugMon_Handler(void);
 void PendSV_Handler(void);
 void SysTick_Handler(void);
+void EXTI15_10_IRQHandler(void);
 /* USER CODE BEGIN EFP */
 
 /* USER CODE END EFP */
diff --git a/starter-projects/servo/p1-pwm/Core/Inc/stm32g4xx_nucleo_conf.h b/starter-projects/servo/p1-pwm/Core/Inc/stm32g4xx_nucleo_conf.h
new file mode 100644
index 0000000..a49cb51
--- /dev/null
+++ b/starter-projects/servo/p1-pwm/Core/Inc/stm32g4xx_nucleo_conf.h
@@ -0,0 +1,78 @@
+
+/**
+  ******************************************************************************
+  * @file    stm32g4xx_nucleo_conf.h
+  * @author  MCD Application Team
+  * @brief   STM32G4xx_Nucleo board configuration file.
+  *          This file should be copied to the application folder and renamed
+  *          to stm32g4xx_nucleo_conf.h
+  ******************************************************************************
+  * @attention
+  *
+  * Copyright (c) 2022 STMicroelectronics.
+  * All rights reserved.
+  *
+  * This software is licensed under terms that can be found in the LICENSE file
+  * in the root directory of this software component.
+  * If no LICENSE file comes with this software, it is provided AS-IS.
+  *
+  ******************************************************************************
+  */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef STM32G4XX_NUCLEO_CONF_H
+#define STM32G4XX_NUCLEO_CONF_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32g4xx_hal.h"
+
+/** @addtogroup BSP
+  * @{
+  */
+
+/** @addtogroup STM32G4XX_NUCLEO
+  * @{
+  */
+
+/** @defgroup STM32G4XX_NUCLEO_CONFIG Config
+  * @{
+  */
+
+/** @defgroup STM32C0XX_NUCLEO_CONFIG_Exported_Constants Exported Constants
+  * @{
+  */
+/* Nucleo pin and part number defines */
+#define USE_STM32G4XX_NUCLEO
+
+/* COM define */
+#define USE_COM_LOG                         1U
+#define USE_BSP_COM_FEATURE                 1U
+
+/* IRQ priorities */
+#define BSP_BUTTON_USER_IT_PRIORITY         15U
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* STM32G4XX_NUCLEO_CONF_H */
diff --git a/starter-projects/servo/p1-pwm/Core/Src/main.c b/starter-projects/servo/p1-pwm/Core/Src/main.c
index b1de217..74a5bd7 100644
--- a/starter-projects/servo/p1-pwm/Core/Src/main.c
+++ b/starter-projects/servo/p1-pwm/Core/Src/main.c
@@ -41,6 +41,8 @@
 
 /* Private variables ---------------------------------------------------------*/
 
+COM_InitTypeDef BspCOMInit;
+
 /* USER CODE BEGIN PV */
 
 /* USER CODE END PV */
@@ -90,10 +92,28 @@ int main(void)
 
   /* USER CODE END 2 */
 
+  /* Initialize leds */
+  BSP_LED_Init(LED_GREEN);
+
+  /* Initialize USER push-button, will be used to trigger an interrupt each time it's pressed.*/
+  BSP_PB_Init(BUTTON_USER, BUTTON_MODE_EXTI);
+
+  /* Initialize COM1 port (115200, 8 bits (7-bit data + 1 stop bit), no parity */
+  BspCOMInit.BaudRate   = 115200;
+  BspCOMInit.WordLength = COM_WORDLENGTH_8B;
+  BspCOMInit.StopBits   = COM_STOPBITS_1;
+  BspCOMInit.Parity     = COM_PARITY_NONE;
+  BspCOMInit.HwFlowCtl  = COM_HWCONTROL_NONE;
+  if (BSP_COM_Init(COM1, &BspCOMInit) != BSP_ERROR_NONE)
+  {
+    Error_Handler();
+  }
+
   /* Infinite loop */
   /* USER CODE BEGIN WHILE */
   while (1)
   {
+
     /* USER CODE END WHILE */
 
     /* USER CODE BEGIN 3 */
@@ -112,7 +132,7 @@ void SystemClock_Config(void)
 
   /** Configure the main internal regulator output voltage
   */
-  HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1);
+  HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1_BOOST);
 
   /** Initializes the RCC Oscillators according to the specified parameters
   * in the RCC_OscInitTypeDef structure.
@@ -122,8 +142,8 @@ void SystemClock_Config(void)
   RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
   RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
   RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
-  RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV1;
-  RCC_OscInitStruct.PLL.PLLN = 9;
+  RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV4;
+  RCC_OscInitStruct.PLL.PLLN = 85;
   RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
   RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;
   RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
@@ -141,7 +161,7 @@ void SystemClock_Config(void)
   RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
   RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
 
-  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
+  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4) != HAL_OK)
   {
     Error_Handler();
   }
@@ -154,7 +174,6 @@ void SystemClock_Config(void)
   */
 static void MX_GPIO_Init(void)
 {
-  GPIO_InitTypeDef GPIO_InitStruct = {0};
 /* USER CODE BEGIN MX_GPIO_Init_1 */
 /* USER CODE END MX_GPIO_Init_1 */
 
@@ -164,30 +183,6 @@ static void MX_GPIO_Init(void)
   __HAL_RCC_GPIOA_CLK_ENABLE();
   __HAL_RCC_GPIOB_CLK_ENABLE();
 
-  /*Configure GPIO pin Output Level */
-  HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, GPIO_PIN_RESET);
-
-  /*Configure GPIO pin : B1_Pin */
-  GPIO_InitStruct.Pin = B1_Pin;
-  GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
-  GPIO_InitStruct.Pull = GPIO_NOPULL;
-  HAL_GPIO_Init(B1_GPIO_Port, &GPIO_InitStruct);
-
-  /*Configure GPIO pins : LPUART1_TX_Pin LPUART1_RX_Pin */
-  GPIO_InitStruct.Pin = LPUART1_TX_Pin|LPUART1_RX_Pin;
-  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
-  GPIO_InitStruct.Pull = GPIO_NOPULL;
-  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
-  GPIO_InitStruct.Alternate = GPIO_AF12_LPUART1;
-  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
-
-  /*Configure GPIO pin : LD2_Pin */
-  GPIO_InitStruct.Pin = LD2_Pin;
-  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
-  GPIO_InitStruct.Pull = GPIO_NOPULL;
-  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
-  HAL_GPIO_Init(LD2_GPIO_Port, &GPIO_InitStruct);
-
 /* USER CODE BEGIN MX_GPIO_Init_2 */
 /* USER CODE END MX_GPIO_Init_2 */
 }
diff --git a/starter-projects/servo/p1-pwm/Core/Src/stm32g4xx_it.c b/starter-projects/servo/p1-pwm/Core/Src/stm32g4xx_it.c
index f3835a5..5f7c2bd 100644
--- a/starter-projects/servo/p1-pwm/Core/Src/stm32g4xx_it.c
+++ b/starter-projects/servo/p1-pwm/Core/Src/stm32g4xx_it.c
@@ -198,6 +198,20 @@ void SysTick_Handler(void)
 /* please refer to the startup file (startup_stm32g4xx.s).                    */
 /******************************************************************************/
 
+/**
+  * @brief This function handles EXTI line[15:10] interrupts.
+  */
+void EXTI15_10_IRQHandler(void)
+{
+  /* USER CODE BEGIN EXTI15_10_IRQn 0 */
+
+  /* USER CODE END EXTI15_10_IRQn 0 */
+  BSP_PB_IRQHandler(BUTTON_USER);
+  /* USER CODE BEGIN EXTI15_10_IRQn 1 */
+
+  /* USER CODE END EXTI15_10_IRQn 1 */
+}
+
 /* USER CODE BEGIN 1 */
 
 /* USER CODE END 1 */
diff --git a/starter-projects/servo/p1-pwm/Drivers/BSP/STM32G4xx_Nucleo/stm32g4xx_nucleo.c b/starter-projects/servo/p1-pwm/Drivers/BSP/STM32G4xx_Nucleo/stm32g4xx_nucleo.c
new file mode 100644
index 0000000..9456224
--- /dev/null
+++ b/starter-projects/servo/p1-pwm/Drivers/BSP/STM32G4xx_Nucleo/stm32g4xx_nucleo.c
@@ -0,0 +1,676 @@
+/**
+  ******************************************************************************
+  * @file    stm32g4xx_nucleo.c
+  * @author  MCD Application Team
+  * @brief   This file provides set of firmware functions to manage:
+  *          - LEDs and push-button available on STM32G4xx-Nucleo Kit
+  *            from STMicroelectronics
+  ******************************************************************************
+  * @attention
+  *
+  * Copyright (c) 2019 STMicroelectronics.
+  * All rights reserved.
+  *
+  * This software is licensed under terms that can be found in the LICENSE file
+  * in the root directory of this software component.
+  * If no LICENSE file comes with this software, it is provided AS-IS.
+  *
+  ******************************************************************************
+  */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32g4xx_nucleo.h"
+#if defined(__ICCARM__)
+#include <LowLevelIOInterface.h>
+#endif /* __ICCARM__ */
+
+/** @addtogroup BSP
+  * @{
+  */
+
+/** @addtogroup STM32G4XX_NUCLEO
+  * @{
+  */
+
+/** @addtogroup STM32G4XX_NUCLEO_LOW_LEVEL
+  * @brief This file provides set of firmware functions to manage Leds and push-button
+  *        available on STM32G4xx-Nucleo Kit from STMicroelectronics.
+  * @{
+  */
+
+
+/** @defgroup STM32G4XX_NUCLEO_LOW_LEVEL_Exported_Variables LOW LEVEL Exported Variables
+  * @{
+  */
+#if defined (USE_NUCLEO_64)
+EXTI_HandleTypeDef hpb_exti[BUTTONn];
+#endif /* USE_NUCLEO_64 */
+#if (USE_BSP_COM_FEATURE > 0)
+UART_HandleTypeDef hcom_uart[COMn];
+#endif /* (USE_BSP_COM_FEATURE > 0) */
+/**
+  * @}
+  */
+
+/** @defgroup STM32G4XX_NUCLEO_LOW_LEVEL_Private_Defines LOW LEVEL Private Defines
+  * @{
+  */
+
+/**
+  * @}
+  */
+
+/** @defgroup STM32G4XX_NUCLEO_LOW_LEVEL_Private_TypesDefinitions LOW LEVEL Private Typedef
+  * @{
+  */
+#if defined (USE_NUCLEO_64)
+typedef void (* BSP_EXTI_LineCallback) (void);
+#endif /* USE_NUCLEO_64 */
+/**
+  * @}
+  */
+
+/** @defgroup STM32G4XX_NUCLEO_LOW_LEVEL_Private_Variables LOW LEVEL Private Variables
+  * @{
+  */
+static GPIO_TypeDef*   LED_PORT[LEDn] = {LED2_GPIO_PORT};
+
+static const uint16_t  LED_PIN[LEDn] = {LED2_PIN};
+
+#if defined (USE_NUCLEO_64)
+static GPIO_TypeDef*   BUTTON_PORT[BUTTONn] = {USER_BUTTON_GPIO_PORT};
+
+static const uint16_t  BUTTON_PIN[BUTTONn] = {USER_BUTTON_PIN};
+
+static const IRQn_Type BUTTON_IRQn[BUTTONn] = {USER_BUTTON_EXTI_IRQn};
+#endif /* USE_NUCLEO_64 */
+
+#if (USE_BSP_COM_FEATURE > 0)
+static USART_TypeDef*  COM_USART[COMn] = {COM1_UART};
+
+#if (USE_COM_LOG > 0)
+static COM_TypeDef COM_ActiveLogPort = COM1;
+#endif
+
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+static uint32_t IsComMspCbValid[COMn] = {0};
+#endif
+#endif /* (USE_BSP_COM_FEATURE > 0) */
+
+/**
+  * @}
+  */
+
+/** @defgroup STM32G4XX_NUCLEO_LOW_LEVEL_Private_Functions LOW LEVEL Private Functions
+  * @{
+  */
+#if defined (USE_NUCLEO_64)
+static void BUTTON_USER_EXTI_Callback(void);
+#endif /* USE_NUCLEO_64 */
+#if (USE_BSP_COM_FEATURE > 0)
+static void COM1_MspInit(UART_HandleTypeDef *huart);
+static void COM1_MspDeInit(UART_HandleTypeDef *huart);
+#endif /* (USE_BSP_COM_FEATURE > 0) */
+
+#if defined(__ICCARM__)
+/* New definition from EWARM V9, compatible with EWARM8 */
+int iar_fputc(int ch);
+#define PUTCHAR_PROTOTYPE int iar_fputc(int ch)
+#elif defined ( __CC_ARM ) || defined(__ARMCC_VERSION)
+/* ARM Compiler 5/6*/
+#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
+#elif defined(__GNUC__)
+#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
+#endif /* __ICCARM__ */
+
+/**
+  * @}
+  */
+
+/** @addtogroup STM32G4XX_NUCLEO_LOW_LEVEL_Exported_Functions
+  * @{
+  */
+
+/**
+  * @brief  This method returns the STM32G4xx NUCLEO BSP Driver revision
+  * @retval version 0xXYZR (8bits for each decimal, R for RC)
+  */
+int32_t BSP_GetVersion(void)
+{
+  return (int32_t)STM32G4XX_NUCLEO_BSP_VERSION;
+}
+
+/**
+  * @brief  This method returns the board name
+  * @retval pointer to the board name string
+  */
+const uint8_t* BSP_GetBoardName(void)
+{
+  return (const uint8_t*)STM32G4XX_NUCLEO_BSP_BOARD_NAME;
+}
+
+/**
+  * @brief  This method returns the board ID
+  * @retval pointer to the board ID string
+  */
+const uint8_t* BSP_GetBoardID(void)
+{
+  return (const uint8_t*)STM32G4XX_NUCLEO_BSP_BOARD_ID;
+}
+
+/**
+  * @brief  Configures LED GPIO.
+  * @param  Led Specifies the Led to be configured.
+  *         This parameter can be one of following parameters:
+  *           @arg  LED2
+  * @retval BSP status
+  */
+int32_t BSP_LED_Init(Led_TypeDef Led)
+{
+  GPIO_InitTypeDef  gpio_init_structure;
+
+  /* Enable the GPIO LED Clock */
+  LED2_GPIO_CLK_ENABLE();
+
+  /* Configure the GPIO_LED pin */
+  gpio_init_structure.Pin   = LED_PIN[Led];
+  gpio_init_structure.Mode  = GPIO_MODE_OUTPUT_PP;
+  gpio_init_structure.Pull  = GPIO_NOPULL;
+  gpio_init_structure.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
+
+  HAL_GPIO_Init(LED_PORT[Led], &gpio_init_structure);
+  HAL_GPIO_WritePin(LED_PORT[Led], LED_PIN[Led], GPIO_PIN_RESET);
+
+  return BSP_ERROR_NONE;
+}
+
+/**
+  * @brief  DeInit LEDs.
+  * @param  Led Specifies the Led to be de-init.
+  *         This parameter can be one of the following values:
+  *           @arg  LED2
+  * @note Led DeInit does not disable the GPIO clock
+  * @retval BSP status
+  */
+int32_t BSP_LED_DeInit(Led_TypeDef Led)
+{
+  /* Turn off LED */
+  HAL_GPIO_WritePin(LED_PORT[Led], LED_PIN[Led], GPIO_PIN_RESET);
+
+  /* DeInit the GPIO_LED pin */
+  HAL_GPIO_DeInit(LED_PORT[Led], LED_PIN[Led]);
+
+  return BSP_ERROR_NONE;
+}
+
+/**
+  * @brief  Turns selected LED On.
+  * @param  Led Specifies the Led to be set on.
+  *         This parameter can be one of following parameters:
+  *           @arg  LED2
+  * @retval BSP status
+  */
+int32_t BSP_LED_On(Led_TypeDef Led)
+{
+  HAL_GPIO_WritePin(LED_PORT[Led], LED_PIN[Led], GPIO_PIN_SET);
+
+  return BSP_ERROR_NONE;
+}
+
+/**
+  * @brief  Turns selected LED Off.
+  * @param  Led Specifies the Led to be set off.
+  *         This parameter can be one of following parameters:
+  *           @arg  LED2
+  * @retval BSP status
+  */
+int32_t BSP_LED_Off(Led_TypeDef Led)
+{
+  HAL_GPIO_WritePin(LED_PORT[Led], LED_PIN[Led], GPIO_PIN_RESET);
+
+  return BSP_ERROR_NONE;
+}
+
+/**
+  * @brief  Toggles the selected LED.
+  * @param  Led Specifies the Led to be toggled.
+  *         This parameter can be one of following parameters:
+  *           @arg  LED2
+  * @retval BSP status
+  */
+int32_t BSP_LED_Toggle(Led_TypeDef Led)
+{
+  HAL_GPIO_TogglePin(LED_PORT[Led], LED_PIN[Led]);
+
+  return BSP_ERROR_NONE;
+}
+
+/**
+  * @brief  Get the status of the selected LED.
+  * @param  Led Specifies the Led to get its state.
+  *         This parameter can be one of following parameters:
+  *           @arg  LED2
+  * @retval LED status
+  */
+int32_t BSP_LED_GetState(Led_TypeDef Led)
+{
+  return (int32_t)HAL_GPIO_ReadPin(LED_PORT[Led], LED_PIN[Led]);
+}
+
+#if defined (USE_NUCLEO_64)
+/**
+  * @brief  Configures Button GPIO and EXTI Line.
+  * @param  Button Button to be configured.
+  *         This parameter can be one of the following values:
+  *           @arg  BUTTON_USER: User Push Button
+  * @param  ButtonMode Button mode.
+  *         This parameter can be one of following parameters:
+  *           @arg BUTTON_MODE_GPIO: Button will be used as simple IO
+  *           @arg BUTTON_MODE_EXTI: Button will be connected to EXTI line
+  *                                  with interrupt generation capability
+  * @retval BSP status
+  */
+int32_t BSP_PB_Init(Button_TypeDef Button, ButtonMode_TypeDef ButtonMode)
+{
+  GPIO_InitTypeDef gpio_init_structure;
+  static BSP_EXTI_LineCallback ButtonCallback[BUTTONn] = {BUTTON_USER_EXTI_Callback};
+  static uint32_t BSP_BUTTON_PRIO [BUTTONn] = {BSP_BUTTON_USER_IT_PRIORITY};
+  static const uint32_t BUTTON_EXTI_LINE[BUTTONn] = {USER_BUTTON_EXTI_LINE};
+
+  /* Enable the BUTTON Clock */
+  USER_BUTTON_GPIO_CLK_ENABLE();
+
+  gpio_init_structure.Pin = BUTTON_PIN[Button];
+  gpio_init_structure.Pull = GPIO_PULLDOWN;
+  gpio_init_structure.Speed = GPIO_SPEED_FREQ_HIGH;
+
+  if(ButtonMode == BUTTON_MODE_GPIO)
+  {
+    /* Configure Button pin as input */
+    gpio_init_structure.Mode = GPIO_MODE_INPUT;
+    HAL_GPIO_Init(BUTTON_PORT[Button], &gpio_init_structure);
+  }
+  else /* (ButtonMode == BUTTON_MODE_EXTI) */
+  {
+    /* Configure Button pin as input with External interrupt */
+    gpio_init_structure.Mode = GPIO_MODE_IT_RISING;
+
+    HAL_GPIO_Init(BUTTON_PORT[Button], &gpio_init_structure);
+
+    (void)HAL_EXTI_GetHandle(&hpb_exti[Button], BUTTON_EXTI_LINE[Button]);
+    (void)HAL_EXTI_RegisterCallback(&hpb_exti[Button],  HAL_EXTI_COMMON_CB_ID, ButtonCallback[Button]);
+
+    /* Enable and set Button EXTI Interrupt to the lowest priority */
+    HAL_NVIC_SetPriority((BUTTON_IRQn[Button]), BSP_BUTTON_PRIO[Button], 0x00);
+    HAL_NVIC_EnableIRQ((BUTTON_IRQn[Button]));
+  }
+
+  return BSP_ERROR_NONE;
+}
+
+/**
+  * @brief  Push Button DeInit.
+  * @param  Button Button to be configured
+  *          This parameter can be one of the following values:
+  *            @arg  BUTTON_USER: User Push Button
+  * @note PB DeInit does not disable the GPIO clock
+  * @retval BSP status
+  */
+int32_t BSP_PB_DeInit(Button_TypeDef Button)
+{
+  HAL_NVIC_DisableIRQ((BUTTON_IRQn[Button]));
+  HAL_GPIO_DeInit(BUTTON_PORT[Button], BUTTON_PIN[Button]);
+
+  return BSP_ERROR_NONE;
+}
+
+/**
+  * @brief  Returns the selected Button state.
+  * @param  Button Button to be checked.
+  *          This parameter can be one of the following values:
+  *            @arg  BUTTON_USER: User Push Button
+  * @retval The Button GPIO pin value
+  */
+int32_t BSP_PB_GetState(Button_TypeDef Button)
+{
+  return (int32_t)HAL_GPIO_ReadPin(BUTTON_PORT[Button], BUTTON_PIN[Button]);
+}
+
+/**
+  * @brief  This function handles Push-Button interrupt requests.
+  * @param  Button Specifies the pin connected EXTI line
+  * @retval None
+  */
+void BSP_PB_IRQHandler(Button_TypeDef Button)
+{
+  HAL_EXTI_IRQHandler(&hpb_exti[Button]);
+}
+
+/**
+  * @brief  BSP Push Button callback
+  * @param  Button Specifies the pin connected EXTI line
+  * @retval None.
+  */
+__weak void BSP_PB_Callback(Button_TypeDef Button)
+{
+  /* Prevent unused argument(s) compilation warning */
+  UNUSED(Button);
+
+  /* This function should be implemented by the user application.
+     It is called into this driver when an event on Button is triggered. */
+}
+#endif /* USE_NUCLEO_64 */
+
+#if (USE_BSP_COM_FEATURE > 0)
+/**
+  * @brief  Configures COM port.
+  * @param  COM COM port to be configured.
+  *         This parameter can be COM1
+  * @param  COM_Init Pointer to a UART_HandleTypeDef structure that contains the
+  *                  configuration information for the specified USART peripheral.
+  * @retval BSP error code
+  */
+int32_t BSP_COM_Init(COM_TypeDef COM, COM_InitTypeDef *COM_Init)
+{
+  int32_t ret = BSP_ERROR_NONE;
+
+  if(COM > COMn)
+  {
+    ret = BSP_ERROR_WRONG_PARAM;
+  }
+  else
+  {
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 0)
+    /* Init the UART Msp */
+    COM1_MspInit(&hcom_uart[COM]);
+#else
+    if(IsComMspCbValid == 0U)
+    {
+      if(BSP_COM_RegisterDefaultMspCallbacks(COM) != BSP_ERROR_NONE)
+      {
+        return BSP_ERROR_MSP_FAILURE;
+      }
+    }
+#endif
+
+    if(MX_LPUART1_Init(&hcom_uart[COM], COM_Init) != HAL_OK)
+    {
+      return BSP_ERROR_PERIPH_FAILURE;
+    }
+  }
+
+  return ret;
+}
+
+/**
+  * @brief  DeInit COM port.
+  * @param  COM COM port to be configured.
+  *          This parameter can be COM1
+  * @retval BSP status
+  */
+int32_t BSP_COM_DeInit(COM_TypeDef COM)
+{
+  int32_t ret = BSP_ERROR_NONE;
+
+  if(COM >= COMn)
+  {
+    ret = BSP_ERROR_WRONG_PARAM;
+  }
+  else
+  {
+    /* USART configuration */
+    hcom_uart[COM].Instance = COM_USART[COM];
+
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 0)
+    COM1_MspDeInit(&hcom_uart[COM]);
+#endif /* (USE_HAL_UART_REGISTER_CALLBACKS == 0) */
+
+    if(HAL_UART_DeInit(&hcom_uart[COM]) != HAL_OK)
+    {
+      return BSP_ERROR_PERIPH_FAILURE;
+    }
+  }
+
+  return ret;
+}
+
+/**
+  * @brief  Configures COM port.
+  * @param  huart USART handle
+  * @param  COM_Init Pointer to a UART_HandleTypeDef structure that contains the
+  *                  configuration information for the specified USART peripheral.
+  * @retval HAL error code
+  */
+__weak HAL_StatusTypeDef MX_LPUART1_Init(UART_HandleTypeDef *huart, MX_UART_InitTypeDef *COM_Init)
+{
+  /* USART configuration */
+ huart->Instance          = COM_USART[COM1];
+ huart->Init.BaudRate     = COM_Init->BaudRate;
+ huart->Init.Mode         = UART_MODE_TX_RX;
+ huart->Init.Parity       = (uint32_t)COM_Init->Parity;
+ huart->Init.WordLength   = COM_Init->WordLength;
+ huart->Init.StopBits     = (uint32_t)COM_Init->StopBits;
+ huart->Init.HwFlowCtl    = (uint32_t)COM_Init->HwFlowCtl;
+ huart->Init.OverSampling = UART_OVERSAMPLING_8;
+
+ return HAL_UART_Init(huart);
+}
+
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+/**
+  * @brief Register Default COM Msp Callbacks
+  * @param  COM COM port to be configured.
+  *          This parameter can be COM1
+  * @retval BSP status
+  */
+int32_t BSP_COM_RegisterDefaultMspCallbacks(COM_TypeDef COM)
+{
+  int32_t ret = BSP_ERROR_NONE;
+
+  if(COM >= COMn)
+  {
+    ret = BSP_ERROR_WRONG_PARAM;
+  }
+  else
+  {
+    __HAL_UART_RESET_HANDLE_STATE(&hcom_uart[COM]);
+
+    /* Register default MspInit/MspDeInit Callback */
+    if(HAL_UART_RegisterCallback(&hcom_uart[COM], HAL_UART_MSPINIT_CB_ID, COM1_MspInit) != HAL_OK)
+    {
+      ret = BSP_ERROR_PERIPH_FAILURE;
+    }
+    else if(HAL_UART_RegisterCallback(&hcom_uart[COM], HAL_UART_MSPDEINIT_CB_ID, COM1_MspDeInit) != HAL_OK)
+    {
+      ret = BSP_ERROR_PERIPH_FAILURE;
+    }
+    else
+    {
+      IsComMspCbValid[COM] = 1U;
+    }
+  }
+
+  /* BSP status */
+  return ret;
+}
+
+/**
+  * @brief Register COM Msp Callback registering
+  * @param  COM COM port to be configured.
+  *          This parameter can be COM1
+  * @param Callbacks     pointer to COM1 MspInit/MspDeInit callback functions
+  * @retval BSP status
+  */
+int32_t BSP_COM_RegisterMspCallbacks(COM_TypeDef COM , BSP_COM_Cb_t *Callback)
+{
+  int32_t ret = BSP_ERROR_NONE;
+
+  if(COM >= COMn)
+  {
+    ret = BSP_ERROR_WRONG_PARAM;
+  }
+  else
+  {
+    __HAL_UART_RESET_HANDLE_STATE(&hcom_uart[COM]);
+
+    /* Register MspInit/MspDeInit Callbacks */
+    if(HAL_UART_RegisterCallback(&hcom_uart[COM], HAL_UART_MSPINIT_CB_ID, Callback->pMspInitCb) != HAL_OK)
+    {
+      ret = BSP_ERROR_PERIPH_FAILURE;
+    }
+    else if(HAL_UART_RegisterCallback(&hcom_uart[COM], HAL_UART_MSPDEINIT_CB_ID, Callback->pMspDeInitCb) != HAL_OK)
+    {
+      ret = BSP_ERROR_PERIPH_FAILURE;
+    }
+    else
+    {
+      IsComMspCbValid[COM] = 1U;
+    }
+  }
+  /* BSP status */
+  return ret;
+}
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+
+#if (USE_COM_LOG > 0)
+/**
+  * @brief  Select the active COM port.
+  * @param  COM COM port to be activated.
+  *          This parameter can be COM1
+  * @retval BSP status
+  */
+int32_t BSP_COM_SelectLogPort(COM_TypeDef COM)
+{
+  if(COM_ActiveLogPort != COM)
+  {
+    COM_ActiveLogPort = COM;
+  }
+  return BSP_ERROR_NONE;
+}
+
+/**
+  * @brief  Retargets the C library __write function to the IAR function iar_fputc.
+  * @param  file: file descriptor.
+  * @param  ptr: pointer to the buffer where the data is stored.
+  * @param  len: length of the data to write in bytes.
+  * @retval length of the written data in bytes.
+  */
+#if defined(__ICCARM__)
+size_t __write(int file, unsigned char const *ptr, size_t len)
+{
+  size_t idx;
+  unsigned char const *pdata = ptr;
+
+  for (idx = 0; idx < len; idx++)
+  {
+    iar_fputc((int)*pdata);
+    pdata++;
+  }
+  return len;
+}
+#endif /* __ICCARM__ */
+
+/**
+  * @brief  Redirect console output to COM
+  */
+PUTCHAR_PROTOTYPE
+{
+  (void) HAL_UART_Transmit(&hcom_uart [COM_ActiveLogPort], (uint8_t *) &ch, 1, COM_POLL_TIMEOUT);
+  return ch;
+}
+#endif /* USE_COM_LOG */
+#endif /* (USE_BSP_COM_FEATURE > 0) */
+
+/**
+  * @}
+  */
+
+/** @addtogroup STM32G4XX_NUCLEO_LOW_LEVEL_Private_Functions
+  * @{
+  */
+#if defined (USE_NUCLEO_64)
+/**
+  * @brief  Key EXTI line detection callbacks.
+  * @retval BSP status
+  */
+static void BUTTON_USER_EXTI_Callback(void)
+{
+  BSP_PB_Callback(BUTTON_USER);
+}
+#endif /* USE_NUCLEO_64 */
+
+#if (USE_BSP_COM_FEATURE > 0)
+/**
+  * @brief  Initializes COM1 MSP.
+  * @param  huart UART handle
+  * @retval BSP status
+  */
+static void COM1_MspInit(UART_HandleTypeDef *huart)
+{
+  GPIO_InitTypeDef gpio_init_structure;
+
+  /* Prevent unused argument(s) compilation warning */
+  UNUSED(huart);
+
+  /* Enable GPIO clock */
+  COM1_TX_GPIO_CLK_ENABLE();
+  COM1_RX_GPIO_CLK_ENABLE();
+
+  /* Enable USART clock */
+  COM1_CLK_ENABLE();
+
+  /* Configure USART Tx as alternate function */
+  gpio_init_structure.Pin       = COM1_TX_PIN;
+  gpio_init_structure.Mode      = GPIO_MODE_AF_PP;
+  gpio_init_structure.Speed     = GPIO_SPEED_FREQ_HIGH;
+  gpio_init_structure.Pull      = GPIO_PULLUP;
+  gpio_init_structure.Alternate = COM1_TX_AF;
+  HAL_GPIO_Init(COM1_TX_GPIO_PORT, &gpio_init_structure);
+
+  /* Configure USART Rx as alternate function */
+  gpio_init_structure.Pin = COM1_RX_PIN;
+  gpio_init_structure.Mode = GPIO_MODE_AF_PP;
+  gpio_init_structure.Alternate = COM1_RX_AF;
+  HAL_GPIO_Init(COM1_RX_GPIO_PORT, &gpio_init_structure);
+}
+
+/**
+  * @brief  DeInitialize COM1 MSP part
+  * @param  huart UART handle
+  * @retval BSP status
+  */
+static void COM1_MspDeInit(UART_HandleTypeDef *huart)
+{
+  GPIO_InitTypeDef gpio_init_structure;
+
+  /* Prevent unused argument(s) compilation warning */
+  UNUSED(huart);
+
+  /* COM GPIO pin configuration */
+  gpio_init_structure.Pin  = COM1_TX_PIN;
+  HAL_GPIO_DeInit(COM1_TX_GPIO_PORT, gpio_init_structure.Pin);
+
+  gpio_init_structure.Pin  = COM1_RX_PIN;
+  HAL_GPIO_DeInit(COM1_RX_GPIO_PORT, gpio_init_structure.Pin);
+
+  /* Disable USART clock */
+  COM1_CLK_DISABLE();
+}
+#endif /* (USE_BSP_COM_FEATURE > 0) */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
diff --git a/starter-projects/servo/p1-pwm/Drivers/BSP/STM32G4xx_Nucleo/stm32g4xx_nucleo.h b/starter-projects/servo/p1-pwm/Drivers/BSP/STM32G4xx_Nucleo/stm32g4xx_nucleo.h
new file mode 100644
index 0000000..72f587d
--- /dev/null
+++ b/starter-projects/servo/p1-pwm/Drivers/BSP/STM32G4xx_Nucleo/stm32g4xx_nucleo.h
@@ -0,0 +1,313 @@
+/**
+  ******************************************************************************
+  * @file    stm32g4xx_nucleo.h
+  * @author  MCD Application Team
+  * @brief   This file contains definitions for:
+  *          - LEDs and push-button available on STM32G4xx-Nucleo Kit
+  *            from STMicroelectronics
+  ******************************************************************************
+  * @attention
+  *
+  * Copyright (c) 2019 STMicroelectronics.
+  * All rights reserved.
+  *
+  * This software is licensed under terms that can be found in the LICENSE file
+  * in the root directory of this software component.
+  * If no LICENSE file comes with this software, it is provided AS-IS.
+  *
+  ******************************************************************************
+  */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef STM32G4XX_NUCLEO_H
+#define STM32G4XX_NUCLEO_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32g4xx_nucleo_errno.h"
+#include "stm32g4xx_nucleo_conf.h"
+
+#if (USE_BSP_COM_FEATURE > 0)
+  #if (USE_COM_LOG > 0)
+    #ifndef __GNUC__
+      #include "stdio.h"
+    #endif
+  #endif
+#endif
+
+#if !defined (USE_NUCLEO_32) && !defined (USE_NUCLEO_64)
+#error "Board Pin number not defined"
+#endif
+
+/** @addtogroup BSP
+  * @{
+  */
+
+/** @defgroup STM32G4XX_NUCLEO STM32G4XX_NUCLEO
+  * @{
+  */
+
+/** @defgroup STM32G4XX_NUCLEO_LOW_LEVEL LOW LEVEL
+  * @{
+  */
+
+/** @defgroup STM32G4XX_NUCLEO_LOW_LEVEL_Exported_Types LOW LEVEL Exported Types
+  * @{
+  */
+typedef enum
+{
+  LED2 = 0U,
+  LED_GREEN = LED2,
+  LEDn
+}Led_TypeDef;
+
+#if defined (USE_NUCLEO_64)
+typedef enum
+{
+  BUTTON_USER = 0U,
+  BUTTONn
+}Button_TypeDef;
+
+typedef enum
+{
+  BUTTON_MODE_GPIO = 0U,
+  BUTTON_MODE_EXTI = 1U
+}ButtonMode_TypeDef;
+#endif /* USE_NUCLEO_64 */
+
+#if (USE_BSP_COM_FEATURE > 0)
+typedef enum
+{
+  COM1 = 0U,
+  COMn
+}COM_TypeDef;
+
+typedef enum
+{
+  COM_STOPBITS_1     =   UART_STOPBITS_1,
+  COM_STOPBITS_2     =   UART_STOPBITS_2,
+}COM_StopBitsTypeDef;
+
+typedef enum
+{
+  COM_PARITY_NONE     =  UART_PARITY_NONE,
+  COM_PARITY_EVEN     =  UART_PARITY_EVEN,
+  COM_PARITY_ODD      =  UART_PARITY_ODD,
+}COM_ParityTypeDef;
+
+typedef enum
+{
+  COM_HWCONTROL_NONE    =  UART_HWCONTROL_NONE,
+  COM_HWCONTROL_RTS     =  UART_HWCONTROL_RTS,
+  COM_HWCONTROL_CTS     =  UART_HWCONTROL_CTS,
+  COM_HWCONTROL_RTS_CTS =  UART_HWCONTROL_RTS_CTS,
+}COM_HwFlowCtlTypeDef;
+
+typedef enum
+{
+  COM_WORDLENGTH_7B = UART_WORDLENGTH_7B,
+  COM_WORDLENGTH_8B = UART_WORDLENGTH_8B,
+  COM_WORDLENGTH_9B = UART_WORDLENGTH_9B,
+}COM_WordLengthTypeDef;
+
+typedef struct
+{
+  uint32_t              BaudRate;
+  COM_WordLengthTypeDef WordLength;
+  COM_StopBitsTypeDef   StopBits;
+  COM_ParityTypeDef     Parity;
+  COM_HwFlowCtlTypeDef  HwFlowCtl;
+}COM_InitTypeDef;
+
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+typedef struct
+{
+  pUART_CallbackTypeDef  pMspInitCb;
+  pUART_CallbackTypeDef  pMspDeInitCb;
+}BSP_COM_Cb_t;
+#endif /* (USE_HAL_UART_REGISTER_CALLBACKS == 1) */
+#endif /* (USE_BSP_COM_FEATURE > 0) */
+
+/**
+  * @}
+  */
+
+/** @defgroup STM32G4XX_NUCLEO_LOW_LEVEL_Exported_Constants LOW LEVEL Exported Constants
+  * @{
+  */
+
+/**
+  * @brief STM32G4XX_NUCLEO BSP Driver version number
+  */
+#define STM32G4XX_NUCLEO_BSP_VERSION_MAIN   0x01U /*!< [31:24] main version */
+#define STM32G4XX_NUCLEO_BSP_VERSION_SUB1   0x00U /*!< [23:16] sub1 version */
+#define STM32G4XX_NUCLEO_BSP_VERSION_SUB2   0x05U /*!< [15:8]  sub2 version */
+#define STM32G4XX_NUCLEO_BSP_VERSION_RC     0x00U /*!< [7:0]  release candidate */
+#define STM32G4XX_NUCLEO_BSP_VERSION        ((STM32G4XX_NUCLEO_BSP_VERSION_MAIN << 24)\
+                                            |(STM32G4XX_NUCLEO_BSP_VERSION_SUB1 << 16)\
+                                            |(STM32G4XX_NUCLEO_BSP_VERSION_SUB2 << 8 )\
+                                            |(STM32G4XX_NUCLEO_BSP_VERSION_RC))
+
+/**
+  * @brief Define for STM32G4XX_NUCLEO board
+  */
+#if !defined (USE_STM32G4XX_NUCLEO)
+ #define USE_STM32G4XX_NUCLEO
+#endif
+
+#define STM32G4XX_NUCLEO_BSP_BOARD_NAME  "STM32G474-NUCLEO"
+#define STM32G4XX_NUCLEO_BSP_BOARD_ID    "MB1367"
+
+/** @defgroup STM32G4XX_NUCLEO_LOW_LEVEL_LED LOW LEVEL LED
+  * @{
+  */
+#if defined (USE_NUCLEO_32)
+#define LED2_PIN                              GPIO_PIN_8
+#define LED2_GPIO_PORT                        GPIOB
+#define LED2_GPIO_CLK_ENABLE()                __HAL_RCC_GPIOB_CLK_ENABLE()
+#define LED2_GPIO_CLK_DISABLE()               __HAL_RCC_GPIOB_CLK_DISABLE()
+
+#elif defined (USE_NUCLEO_64)
+#define LED2_PIN                              GPIO_PIN_5
+#define LED2_GPIO_PORT                        GPIOA
+#define LED2_GPIO_CLK_ENABLE()                __HAL_RCC_GPIOA_CLK_ENABLE()
+#define LED2_GPIO_CLK_DISABLE()               __HAL_RCC_GPIOA_CLK_DISABLE()
+#endif /* USE_NUCLEO_32 */
+
+/**
+  * @}
+  */
+
+/** @defgroup STM32G4XX_NUCLEO_LOW_LEVEL_BUTTON LOW LEVEL BUTTON
+  * @{
+  */
+#if defined (USE_NUCLEO_64)
+/* Button state */
+#define BUTTON_RELEASED                       0U
+#define BUTTON_PRESSED                        1U
+
+/**
+  * @brief User push-button
+  */
+#define USER_BUTTON_PIN                       GPIO_PIN_13
+#define USER_BUTTON_GPIO_PORT                 GPIOC
+#define USER_BUTTON_GPIO_CLK_ENABLE()         __HAL_RCC_GPIOC_CLK_ENABLE()
+#define USER_BUTTON_GPIO_CLK_DISABLE()        __HAL_RCC_GPIOC_CLK_DISABLE()
+#define USER_BUTTON_EXTI_IRQn                 EXTI15_10_IRQn
+#define USER_BUTTON_EXTI_LINE                 EXTI_LINE_13
+
+#endif /* USE_NUCLEO_64 */
+/**
+  * @}
+  */
+
+/** @defgroup STM32G4XX_NUCLEO_LOW_LEVEL_COM LOW LEVEL COM
+  * @{
+  */
+/**
+ * @brief Definition for COM port1, connected to LPUART1
+ */
+#if (USE_BSP_COM_FEATURE > 0)
+#define COM1_UART                             LPUART1
+#define COM1_CLK_ENABLE()                     __HAL_RCC_LPUART1_CLK_ENABLE()
+#define COM1_CLK_DISABLE()                    __HAL_RCC_LPUART1_CLK_DISABLE()
+
+#define COM1_TX_PIN                           GPIO_PIN_2
+#define COM1_TX_GPIO_PORT                     GPIOA
+#define COM1_TX_GPIO_CLK_ENABLE()             __HAL_RCC_GPIOA_CLK_ENABLE()
+#define COM1_TX_GPIO_CLK_DISABLE()            __HAL_RCC_GPIOA_CLK_DISABLE()
+#define COM1_TX_AF                            GPIO_AF12_LPUART1
+
+#define COM1_RX_PIN                           GPIO_PIN_3
+#define COM1_RX_GPIO_PORT                     GPIOA
+#define COM1_RX_GPIO_CLK_ENABLE()             __HAL_RCC_GPIOA_CLK_ENABLE()
+#define COM1_RX_GPIO_CLK_DISABLE()            __HAL_RCC_GPIOA_CLK_DISABLE()
+#define COM1_RX_AF                            GPIO_AF12_LPUART1
+#define COM_POLL_TIMEOUT                      1000
+
+#define MX_UART_InitTypeDef COM_InitTypeDef
+#endif /* (USE_BSP_COM_FEATURE > 0)*/
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/** @addtogroup STM32G4XX_NUCLEO_LOW_LEVEL_Exported_Variables
+  * @{
+  */
+#if defined (USE_NUCLEO_64)
+extern EXTI_HandleTypeDef hpb_exti[];
+#endif /* USE_NUCLEO_64 */
+#if (USE_BSP_COM_FEATURE > 0)
+extern UART_HandleTypeDef hcom_uart[];
+#endif /* (USE_BSP_COM_FEATURE > 0) */
+/**
+  * @}
+  */
+
+/** @defgroup STM32G4XX_NUCLEO_LOW_LEVEL_Exported_Functions LOW LEVEL Exported Functions
+  * @{
+  */
+int32_t  BSP_GetVersion(void);
+const uint8_t* BSP_GetBoardName(void);
+const uint8_t* BSP_GetBoardID(void);
+
+/* Legacy APIs aliases */
+#define BSP_GetHWBoardVersionName    BSP_GetBoardName
+#define BSP_GetPDTypeName            BSP_GetBoardID
+
+int32_t  BSP_LED_Init(Led_TypeDef Led);
+int32_t  BSP_LED_DeInit(Led_TypeDef Led);
+int32_t  BSP_LED_On(Led_TypeDef Led);
+int32_t  BSP_LED_Off(Led_TypeDef Led);
+int32_t  BSP_LED_Toggle(Led_TypeDef Led);
+int32_t  BSP_LED_GetState (Led_TypeDef Led);
+#if defined (USE_NUCLEO_64)
+int32_t  BSP_PB_Init(Button_TypeDef Button, ButtonMode_TypeDef ButtonMode);
+int32_t  BSP_PB_DeInit(Button_TypeDef Button);
+int32_t  BSP_PB_GetState(Button_TypeDef Button);
+void     BSP_PB_Callback(Button_TypeDef Button);
+void     BSP_PB_IRQHandler(Button_TypeDef Button);
+#endif /* USE_NUCLEO_64 */
+#if (USE_BSP_COM_FEATURE > 0)
+int32_t  BSP_COM_Init(COM_TypeDef COM, COM_InitTypeDef *COM_Init);
+int32_t  BSP_COM_DeInit(COM_TypeDef COM);
+#if (USE_COM_LOG > 0)
+int32_t  BSP_COM_SelectLogPort (COM_TypeDef COM);
+#endif
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+int32_t  BSP_COM_RegisterDefaultMspCallbacks(COM_TypeDef COM);
+int32_t  BSP_COM_RegisterMspCallbacks(COM_TypeDef COM , BSP_COM_Cb_t *Callback);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+HAL_StatusTypeDef MX_LPUART1_Init(UART_HandleTypeDef *huart, MX_UART_InitTypeDef *COM_Init);
+#endif /* (USE_BSP_COM_FEATURE > 0) */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* STM32G4XX_NUCLEO_H */
+
+
diff --git a/starter-projects/servo/p1-pwm/Drivers/BSP/STM32G4xx_Nucleo/stm32g4xx_nucleo_errno.h b/starter-projects/servo/p1-pwm/Drivers/BSP/STM32G4xx_Nucleo/stm32g4xx_nucleo_errno.h
new file mode 100644
index 0000000..9a9cab5
--- /dev/null
+++ b/starter-projects/servo/p1-pwm/Drivers/BSP/STM32G4xx_Nucleo/stm32g4xx_nucleo_errno.h
@@ -0,0 +1,46 @@
+/**
+  ******************************************************************************
+  * @file    stm32g4xx_nucleo_errno.h
+  * @author  MCD Application Team
+  * @brief   Error Code.
+  ******************************************************************************
+  * @attention
+  *
+  * Copyright (c) 2019 STMicroelectronics.
+  * All rights reserved.
+  *
+  * This software is licensed under terms that can be found in the LICENSE file
+  * in the root directory of this software component.
+  * If no LICENSE file comes with this software, it is provided AS-IS.
+  *
+  ******************************************************************************
+  */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef STM32G4XX_NUCLEO_ERRNO_H
+#define STM32G4XX_NUCLEO_ERRNO_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Common Error codes */
+#define BSP_ERROR_NONE                         0
+#define BSP_ERROR_NO_INIT                     -1
+#define BSP_ERROR_WRONG_PARAM                 -2
+#define BSP_ERROR_BUSY                        -3
+#define BSP_ERROR_PERIPH_FAILURE              -4
+#define BSP_ERROR_COMPONENT_FAILURE           -5
+#define BSP_ERROR_UNKNOWN_FAILURE             -6
+#define BSP_ERROR_UNKNOWN_COMPONENT           -7
+#define BSP_ERROR_BUS_FAILURE                 -8
+#define BSP_ERROR_CLOCK_FAILURE               -9
+#define BSP_ERROR_MSP_FAILURE                 -10
+#define BSP_ERROR_FEATURE_NOT_SUPPORTED       -11
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* STM32G4XX_NUCLEO_ERRNO_H */
+
diff --git a/starter-projects/servo/p1-pwm/Drivers/STM32G4xx_HAL_Driver/Inc/stm32g4xx_hal_uart.h b/starter-projects/servo/p1-pwm/Drivers/STM32G4xx_HAL_Driver/Inc/stm32g4xx_hal_uart.h
new file mode 100644
index 0000000..383e3c6
--- /dev/null
+++ b/starter-projects/servo/p1-pwm/Drivers/STM32G4xx_HAL_Driver/Inc/stm32g4xx_hal_uart.h
@@ -0,0 +1,1745 @@
+/**
+  ******************************************************************************
+  * @file    stm32g4xx_hal_uart.h
+  * @author  MCD Application Team
+  * @brief   Header file of UART HAL module.
+  ******************************************************************************
+  * @attention
+  *
+  * Copyright (c) 2019 STMicroelectronics.
+  * All rights reserved.
+  *
+  * This software is licensed under terms that can be found in the LICENSE file
+  * in the root directory of this software component.
+  * If no LICENSE file comes with this software, it is provided AS-IS.
+  *
+  ******************************************************************************
+  */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef STM32G4xx_HAL_UART_H
+#define STM32G4xx_HAL_UART_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32g4xx_hal_def.h"
+
+/** @addtogroup STM32G4xx_HAL_Driver
+  * @{
+  */
+
+/** @addtogroup UART
+  * @{
+  */
+
+/* Exported types ------------------------------------------------------------*/
+/** @defgroup UART_Exported_Types UART Exported Types
+  * @{
+  */
+
+/**
+  * @brief UART Init Structure definition
+  */
+typedef struct
+{
+  uint32_t BaudRate;                /*!< This member configures the UART communication baud rate.
+                                         The baud rate register is computed using the following formula:
+                                         LPUART:
+                                         =======
+                                         Baud Rate Register = ((256 * lpuart_ker_ckpres) / ((huart->Init.BaudRate)))
+                                         where lpuart_ker_ck_pres is the UART input clock divided by a prescaler
+                                         UART:
+                                         =====
+                                         - If oversampling is 16 or in LIN mode,
+                                            Baud Rate Register = ((uart_ker_ckpres) / ((huart->Init.BaudRate)))
+                                         - If oversampling is 8,
+                                            Baud Rate Register[15:4] = ((2 * uart_ker_ckpres) /
+                                            ((huart->Init.BaudRate)))[15:4]
+                                            Baud Rate Register[3] =  0
+                                            Baud Rate Register[2:0] =  (((2 * uart_ker_ckpres) /
+                                            ((huart->Init.BaudRate)))[3:0]) >> 1
+                                         where uart_ker_ck_pres is the UART input clock divided by a prescaler */
+
+  uint32_t WordLength;              /*!< Specifies the number of data bits transmitted or received in a frame.
+                                         This parameter can be a value of @ref UARTEx_Word_Length. */
+
+  uint32_t StopBits;                /*!< Specifies the number of stop bits transmitted.
+                                         This parameter can be a value of @ref UART_Stop_Bits. */
+
+  uint32_t Parity;                  /*!< Specifies the parity mode.
+                                         This parameter can be a value of @ref UART_Parity
+                                         @note When parity is enabled, the computed parity is inserted
+                                               at the MSB position of the transmitted data (9th bit when
+                                               the word length is set to 9 data bits; 8th bit when the
+                                               word length is set to 8 data bits). */
+
+  uint32_t Mode;                    /*!< Specifies whether the Receive or Transmit mode is enabled or disabled.
+                                         This parameter can be a value of @ref UART_Mode. */
+
+  uint32_t HwFlowCtl;               /*!< Specifies whether the hardware flow control mode is enabled
+                                         or disabled.
+                                         This parameter can be a value of @ref UART_Hardware_Flow_Control. */
+
+  uint32_t OverSampling;            /*!< Specifies whether the Over sampling 8 is enabled or disabled,
+                                         to achieve higher speed (up to f_PCLK/8).
+                                         This parameter can be a value of @ref UART_Over_Sampling. */
+
+  uint32_t OneBitSampling;          /*!< Specifies whether a single sample or three samples' majority vote is selected.
+                                         Selecting the single sample method increases the receiver tolerance to clock
+                                         deviations. This parameter can be a value of @ref UART_OneBit_Sampling. */
+
+  uint32_t ClockPrescaler;          /*!< Specifies the prescaler value used to divide the UART clock source.
+                                         This parameter can be a value of @ref UART_ClockPrescaler. */
+
+} UART_InitTypeDef;
+
+/**
+  * @brief  UART Advanced Features initialization structure definition
+  */
+typedef struct
+{
+  uint32_t AdvFeatureInit;        /*!< Specifies which advanced UART features is initialized. Several
+                                       Advanced Features may be initialized at the same time .
+                                       This parameter can be a value of
+                                       @ref UART_Advanced_Features_Initialization_Type. */
+
+  uint32_t TxPinLevelInvert;      /*!< Specifies whether the TX pin active level is inverted.
+                                       This parameter can be a value of @ref UART_Tx_Inv. */
+
+  uint32_t RxPinLevelInvert;      /*!< Specifies whether the RX pin active level is inverted.
+                                       This parameter can be a value of @ref UART_Rx_Inv. */
+
+  uint32_t DataInvert;            /*!< Specifies whether data are inverted (positive/direct logic
+                                       vs negative/inverted logic).
+                                       This parameter can be a value of @ref UART_Data_Inv. */
+
+  uint32_t Swap;                  /*!< Specifies whether TX and RX pins are swapped.
+                                       This parameter can be a value of @ref UART_Rx_Tx_Swap. */
+
+  uint32_t OverrunDisable;        /*!< Specifies whether the reception overrun detection is disabled.
+                                       This parameter can be a value of @ref UART_Overrun_Disable. */
+
+  uint32_t DMADisableonRxError;   /*!< Specifies whether the DMA is disabled in case of reception error.
+                                       This parameter can be a value of @ref UART_DMA_Disable_on_Rx_Error. */
+
+  uint32_t AutoBaudRateEnable;    /*!< Specifies whether auto Baud rate detection is enabled.
+                                       This parameter can be a value of @ref UART_AutoBaudRate_Enable. */
+
+  uint32_t AutoBaudRateMode;      /*!< If auto Baud rate detection is enabled, specifies how the rate
+                                       detection is carried out.
+                                       This parameter can be a value of @ref UART_AutoBaud_Rate_Mode. */
+
+  uint32_t MSBFirst;              /*!< Specifies whether MSB is sent first on UART line.
+                                       This parameter can be a value of @ref UART_MSB_First. */
+} UART_AdvFeatureInitTypeDef;
+
+/**
+  * @brief HAL UART State definition
+  * @note  HAL UART State value is a combination of 2 different substates:
+  *        gState and RxState (see @ref UART_State_Definition).
+  *        - gState contains UART state information related to global Handle management
+  *          and also information related to Tx operations.
+  *          gState value coding follow below described bitmap :
+  *          b7-b6  Error information
+  *             00 : No Error
+  *             01 : (Not Used)
+  *             10 : Timeout
+  *             11 : Error
+  *          b5     Peripheral initialization status
+  *             0  : Reset (Peripheral not initialized)
+  *             1  : Init done (Peripheral initialized. HAL UART Init function already called)
+  *          b4-b3  (not used)
+  *             xx : Should be set to 00
+  *          b2     Intrinsic process state
+  *             0  : Ready
+  *             1  : Busy (Peripheral busy with some configuration or internal operations)
+  *          b1     (not used)
+  *             x  : Should be set to 0
+  *          b0     Tx state
+  *             0  : Ready (no Tx operation ongoing)
+  *             1  : Busy (Tx operation ongoing)
+  *        - RxState contains information related to Rx operations.
+  *          RxState value coding follow below described bitmap :
+  *          b7-b6  (not used)
+  *             xx : Should be set to 00
+  *          b5     Peripheral initialization status
+  *             0  : Reset (Peripheral not initialized)
+  *             1  : Init done (Peripheral initialized)
+  *          b4-b2  (not used)
+  *            xxx : Should be set to 000
+  *          b1     Rx state
+  *             0  : Ready (no Rx operation ongoing)
+  *             1  : Busy (Rx operation ongoing)
+  *          b0     (not used)
+  *             x  : Should be set to 0.
+  */
+typedef uint32_t HAL_UART_StateTypeDef;
+
+/**
+  * @brief UART clock sources definition
+  */
+typedef enum
+{
+  UART_CLOCKSOURCE_PCLK1      = 0x00U,    /*!< PCLK1 clock source  */
+  UART_CLOCKSOURCE_PCLK2      = 0x01U,    /*!< PCLK2 clock source  */
+  UART_CLOCKSOURCE_HSI        = 0x02U,    /*!< HSI clock source    */
+  UART_CLOCKSOURCE_SYSCLK     = 0x04U,    /*!< SYSCLK clock source */
+  UART_CLOCKSOURCE_LSE        = 0x08U,    /*!< LSE clock source       */
+  UART_CLOCKSOURCE_UNDEFINED  = 0x10U     /*!< Undefined clock source */
+} UART_ClockSourceTypeDef;
+
+/**
+  * @brief HAL UART Reception type definition
+  * @note  HAL UART Reception type value aims to identify which type of Reception is ongoing.
+  *        This parameter can be a value of @ref UART_Reception_Type_Values :
+  *           HAL_UART_RECEPTION_STANDARD         = 0x00U,
+  *           HAL_UART_RECEPTION_TOIDLE           = 0x01U,
+  *           HAL_UART_RECEPTION_TORTO            = 0x02U,
+  *           HAL_UART_RECEPTION_TOCHARMATCH      = 0x03U,
+  */
+typedef uint32_t HAL_UART_RxTypeTypeDef;
+
+/**
+  * @brief HAL UART Rx Event type definition
+  * @note  HAL UART Rx Event type value aims to identify which type of Event has occurred
+  *        leading to call of the RxEvent callback.
+  *        This parameter can be a value of @ref UART_RxEvent_Type_Values :
+  *           HAL_UART_RXEVENT_TC                 = 0x00U,
+  *           HAL_UART_RXEVENT_HT                 = 0x01U,
+  *           HAL_UART_RXEVENT_IDLE               = 0x02U,
+  */
+typedef uint32_t HAL_UART_RxEventTypeTypeDef;
+
+/**
+  * @brief  UART handle Structure definition
+  */
+typedef struct __UART_HandleTypeDef
+{
+  USART_TypeDef            *Instance;                /*!< UART registers base address        */
+
+  UART_InitTypeDef         Init;                     /*!< UART communication parameters      */
+
+  UART_AdvFeatureInitTypeDef AdvancedInit;           /*!< UART Advanced Features initialization parameters */
+
+  const uint8_t            *pTxBuffPtr;              /*!< Pointer to UART Tx transfer Buffer */
+
+  uint16_t                 TxXferSize;               /*!< UART Tx Transfer size              */
+
+  __IO uint16_t            TxXferCount;              /*!< UART Tx Transfer Counter           */
+
+  uint8_t                  *pRxBuffPtr;              /*!< Pointer to UART Rx transfer Buffer */
+
+  uint16_t                 RxXferSize;               /*!< UART Rx Transfer size              */
+
+  __IO uint16_t            RxXferCount;              /*!< UART Rx Transfer Counter           */
+
+  uint16_t                 Mask;                     /*!< UART Rx RDR register mask          */
+
+  uint32_t                 FifoMode;                 /*!< Specifies if the FIFO mode is being used.
+                                                          This parameter can be a value of @ref UARTEx_FIFO_mode. */
+
+  uint16_t                 NbRxDataToProcess;        /*!< Number of data to process during RX ISR execution */
+
+  uint16_t                 NbTxDataToProcess;        /*!< Number of data to process during TX ISR execution */
+
+  __IO HAL_UART_RxTypeTypeDef ReceptionType;         /*!< Type of ongoing reception          */
+
+  __IO HAL_UART_RxEventTypeTypeDef RxEventType;      /*!< Type of Rx Event                   */
+
+  void (*RxISR)(struct __UART_HandleTypeDef *huart); /*!< Function pointer on Rx IRQ handler */
+
+  void (*TxISR)(struct __UART_HandleTypeDef *huart); /*!< Function pointer on Tx IRQ handler */
+
+  DMA_HandleTypeDef        *hdmatx;                  /*!< UART Tx DMA Handle parameters      */
+
+  DMA_HandleTypeDef        *hdmarx;                  /*!< UART Rx DMA Handle parameters      */
+
+  HAL_LockTypeDef           Lock;                    /*!< Locking object                     */
+
+  __IO HAL_UART_StateTypeDef    gState;              /*!< UART state information related to global Handle management
+                                                          and also related to Tx operations. This parameter
+                                                          can be a value of @ref HAL_UART_StateTypeDef */
+
+  __IO HAL_UART_StateTypeDef    RxState;             /*!< UART state information related to Rx operations. This
+                                                          parameter can be a value of @ref HAL_UART_StateTypeDef */
+
+  __IO uint32_t                 ErrorCode;           /*!< UART Error code                    */
+
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+  void (* TxHalfCpltCallback)(struct __UART_HandleTypeDef *huart);        /*!< UART Tx Half Complete Callback        */
+  void (* TxCpltCallback)(struct __UART_HandleTypeDef *huart);            /*!< UART Tx Complete Callback             */
+  void (* RxHalfCpltCallback)(struct __UART_HandleTypeDef *huart);        /*!< UART Rx Half Complete Callback        */
+  void (* RxCpltCallback)(struct __UART_HandleTypeDef *huart);            /*!< UART Rx Complete Callback             */
+  void (* ErrorCallback)(struct __UART_HandleTypeDef *huart);             /*!< UART Error Callback                   */
+  void (* AbortCpltCallback)(struct __UART_HandleTypeDef *huart);         /*!< UART Abort Complete Callback          */
+  void (* AbortTransmitCpltCallback)(struct __UART_HandleTypeDef *huart); /*!< UART Abort Transmit Complete Callback */
+  void (* AbortReceiveCpltCallback)(struct __UART_HandleTypeDef *huart);  /*!< UART Abort Receive Complete Callback  */
+  void (* WakeupCallback)(struct __UART_HandleTypeDef *huart);            /*!< UART Wakeup Callback                  */
+  void (* RxFifoFullCallback)(struct __UART_HandleTypeDef *huart);        /*!< UART Rx Fifo Full Callback            */
+  void (* TxFifoEmptyCallback)(struct __UART_HandleTypeDef *huart);       /*!< UART Tx Fifo Empty Callback           */
+  void (* RxEventCallback)(struct __UART_HandleTypeDef *huart, uint16_t Pos); /*!< UART Reception Event Callback     */
+
+  void (* MspInitCallback)(struct __UART_HandleTypeDef *huart);           /*!< UART Msp Init callback                */
+  void (* MspDeInitCallback)(struct __UART_HandleTypeDef *huart);         /*!< UART Msp DeInit callback              */
+#endif  /* USE_HAL_UART_REGISTER_CALLBACKS */
+
+} UART_HandleTypeDef;
+
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+/**
+  * @brief  HAL UART Callback ID enumeration definition
+  */
+typedef enum
+{
+  HAL_UART_TX_HALFCOMPLETE_CB_ID         = 0x00U,    /*!< UART Tx Half Complete Callback ID        */
+  HAL_UART_TX_COMPLETE_CB_ID             = 0x01U,    /*!< UART Tx Complete Callback ID             */
+  HAL_UART_RX_HALFCOMPLETE_CB_ID         = 0x02U,    /*!< UART Rx Half Complete Callback ID        */
+  HAL_UART_RX_COMPLETE_CB_ID             = 0x03U,    /*!< UART Rx Complete Callback ID             */
+  HAL_UART_ERROR_CB_ID                   = 0x04U,    /*!< UART Error Callback ID                   */
+  HAL_UART_ABORT_COMPLETE_CB_ID          = 0x05U,    /*!< UART Abort Complete Callback ID          */
+  HAL_UART_ABORT_TRANSMIT_COMPLETE_CB_ID = 0x06U,    /*!< UART Abort Transmit Complete Callback ID */
+  HAL_UART_ABORT_RECEIVE_COMPLETE_CB_ID  = 0x07U,    /*!< UART Abort Receive Complete Callback ID  */
+  HAL_UART_WAKEUP_CB_ID                  = 0x08U,    /*!< UART Wakeup Callback ID                  */
+  HAL_UART_RX_FIFO_FULL_CB_ID            = 0x09U,    /*!< UART Rx Fifo Full Callback ID            */
+  HAL_UART_TX_FIFO_EMPTY_CB_ID           = 0x0AU,    /*!< UART Tx Fifo Empty Callback ID           */
+
+  HAL_UART_MSPINIT_CB_ID                 = 0x0BU,    /*!< UART MspInit callback ID                 */
+  HAL_UART_MSPDEINIT_CB_ID               = 0x0CU     /*!< UART MspDeInit callback ID               */
+
+} HAL_UART_CallbackIDTypeDef;
+
+/**
+  * @brief  HAL UART Callback pointer definition
+  */
+typedef  void (*pUART_CallbackTypeDef)(UART_HandleTypeDef *huart); /*!< pointer to an UART callback function */
+typedef  void (*pUART_RxEventCallbackTypeDef)
+(struct __UART_HandleTypeDef *huart, uint16_t Pos); /*!< pointer to a UART Rx Event specific callback function */
+
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+
+/**
+  * @}
+  */
+
+/* Exported constants --------------------------------------------------------*/
+/** @defgroup UART_Exported_Constants UART Exported Constants
+  * @{
+  */
+
+/** @defgroup UART_State_Definition UART State Code Definition
+  * @{
+  */
+#define  HAL_UART_STATE_RESET         0x00000000U    /*!< Peripheral is not initialized
+                                                          Value is allowed for gState and RxState */
+#define  HAL_UART_STATE_READY         0x00000020U    /*!< Peripheral Initialized and ready for use
+                                                          Value is allowed for gState and RxState */
+#define  HAL_UART_STATE_BUSY          0x00000024U    /*!< an internal process is ongoing
+                                                          Value is allowed for gState only */
+#define  HAL_UART_STATE_BUSY_TX       0x00000021U    /*!< Data Transmission process is ongoing
+                                                          Value is allowed for gState only */
+#define  HAL_UART_STATE_BUSY_RX       0x00000022U    /*!< Data Reception process is ongoing
+                                                          Value is allowed for RxState only */
+#define  HAL_UART_STATE_BUSY_TX_RX    0x00000023U    /*!< Data Transmission and Reception process is ongoing
+                                                          Not to be used for neither gState nor RxState.Value is result
+                                                          of combination (Or) between gState and RxState values */
+#define  HAL_UART_STATE_TIMEOUT       0x000000A0U    /*!< Timeout state
+                                                          Value is allowed for gState only */
+#define  HAL_UART_STATE_ERROR         0x000000E0U    /*!< Error
+                                                          Value is allowed for gState only */
+/**
+  * @}
+  */
+
+/** @defgroup UART_Error_Definition   UART Error Definition
+  * @{
+  */
+#define  HAL_UART_ERROR_NONE             (0x00000000U)    /*!< No error                */
+#define  HAL_UART_ERROR_PE               (0x00000001U)    /*!< Parity error            */
+#define  HAL_UART_ERROR_NE               (0x00000002U)    /*!< Noise error             */
+#define  HAL_UART_ERROR_FE               (0x00000004U)    /*!< Frame error             */
+#define  HAL_UART_ERROR_ORE              (0x00000008U)    /*!< Overrun error           */
+#define  HAL_UART_ERROR_DMA              (0x00000010U)    /*!< DMA transfer error      */
+#define  HAL_UART_ERROR_RTO              (0x00000020U)    /*!< Receiver Timeout error  */
+
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+#define  HAL_UART_ERROR_INVALID_CALLBACK (0x00000040U)    /*!< Invalid Callback error  */
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+/**
+  * @}
+  */
+
+/** @defgroup UART_Stop_Bits   UART Number of Stop Bits
+  * @{
+  */
+#define UART_STOPBITS_0_5                    USART_CR2_STOP_0                     /*!< UART frame with 0.5 stop bit  */
+#define UART_STOPBITS_1                     0x00000000U                           /*!< UART frame with 1 stop bit    */
+#define UART_STOPBITS_1_5                   (USART_CR2_STOP_0 | USART_CR2_STOP_1) /*!< UART frame with 1.5 stop bits */
+#define UART_STOPBITS_2                      USART_CR2_STOP_1                     /*!< UART frame with 2 stop bits   */
+/**
+  * @}
+  */
+
+/** @defgroup UART_Parity  UART Parity
+  * @{
+  */
+#define UART_PARITY_NONE                    0x00000000U                        /*!< No parity   */
+#define UART_PARITY_EVEN                    USART_CR1_PCE                      /*!< Even parity */
+#define UART_PARITY_ODD                     (USART_CR1_PCE | USART_CR1_PS)     /*!< Odd parity  */
+/**
+  * @}
+  */
+
+/** @defgroup UART_Hardware_Flow_Control UART Hardware Flow Control
+  * @{
+  */
+#define UART_HWCONTROL_NONE                  0x00000000U                          /*!< No hardware control       */
+#define UART_HWCONTROL_RTS                   USART_CR3_RTSE                       /*!< Request To Send           */
+#define UART_HWCONTROL_CTS                   USART_CR3_CTSE                       /*!< Clear To Send             */
+#define UART_HWCONTROL_RTS_CTS               (USART_CR3_RTSE | USART_CR3_CTSE)    /*!< Request and Clear To Send */
+/**
+  * @}
+  */
+
+/** @defgroup UART_Mode UART Transfer Mode
+  * @{
+  */
+#define UART_MODE_RX                        USART_CR1_RE                    /*!< RX mode        */
+#define UART_MODE_TX                        USART_CR1_TE                    /*!< TX mode        */
+#define UART_MODE_TX_RX                     (USART_CR1_TE |USART_CR1_RE)    /*!< RX and TX mode */
+/**
+  * @}
+  */
+
+/** @defgroup UART_State  UART State
+  * @{
+  */
+#define UART_STATE_DISABLE                  0x00000000U         /*!< UART disabled  */
+#define UART_STATE_ENABLE                   USART_CR1_UE        /*!< UART enabled   */
+/**
+  * @}
+  */
+
+/** @defgroup UART_Over_Sampling UART Over Sampling
+  * @{
+  */
+#define UART_OVERSAMPLING_16                0x00000000U         /*!< Oversampling by 16 */
+#define UART_OVERSAMPLING_8                 USART_CR1_OVER8     /*!< Oversampling by 8  */
+/**
+  * @}
+  */
+
+/** @defgroup UART_OneBit_Sampling UART One Bit Sampling Method
+  * @{
+  */
+#define UART_ONE_BIT_SAMPLE_DISABLE         0x00000000U         /*!< One-bit sampling disable */
+#define UART_ONE_BIT_SAMPLE_ENABLE          USART_CR3_ONEBIT    /*!< One-bit sampling enable  */
+/**
+  * @}
+  */
+
+/** @defgroup UART_ClockPrescaler  UART Clock Prescaler
+  * @{
+  */
+#define UART_PRESCALER_DIV1    0x00000000U  /*!< fclk_pres = fclk     */
+#define UART_PRESCALER_DIV2    0x00000001U  /*!< fclk_pres = fclk/2   */
+#define UART_PRESCALER_DIV4    0x00000002U  /*!< fclk_pres = fclk/4   */
+#define UART_PRESCALER_DIV6    0x00000003U  /*!< fclk_pres = fclk/6   */
+#define UART_PRESCALER_DIV8    0x00000004U  /*!< fclk_pres = fclk/8   */
+#define UART_PRESCALER_DIV10   0x00000005U  /*!< fclk_pres = fclk/10  */
+#define UART_PRESCALER_DIV12   0x00000006U  /*!< fclk_pres = fclk/12  */
+#define UART_PRESCALER_DIV16   0x00000007U  /*!< fclk_pres = fclk/16  */
+#define UART_PRESCALER_DIV32   0x00000008U  /*!< fclk_pres = fclk/32  */
+#define UART_PRESCALER_DIV64   0x00000009U  /*!< fclk_pres = fclk/64  */
+#define UART_PRESCALER_DIV128  0x0000000AU  /*!< fclk_pres = fclk/128 */
+#define UART_PRESCALER_DIV256  0x0000000BU  /*!< fclk_pres = fclk/256 */
+/**
+  * @}
+  */
+
+/** @defgroup UART_AutoBaud_Rate_Mode    UART Advanced Feature AutoBaud Rate Mode
+  * @{
+  */
+#define UART_ADVFEATURE_AUTOBAUDRATE_ONSTARTBIT    0x00000000U           /*!< Auto Baud rate detection
+                                                                              on start bit              */
+#define UART_ADVFEATURE_AUTOBAUDRATE_ONFALLINGEDGE USART_CR2_ABRMODE_0   /*!< Auto Baud rate detection
+                                                                              on falling edge           */
+#define UART_ADVFEATURE_AUTOBAUDRATE_ON0X7FFRAME   USART_CR2_ABRMODE_1   /*!< Auto Baud rate detection
+                                                                              on 0x7F frame detection   */
+#define UART_ADVFEATURE_AUTOBAUDRATE_ON0X55FRAME   USART_CR2_ABRMODE     /*!< Auto Baud rate detection
+                                                                              on 0x55 frame detection   */
+/**
+  * @}
+  */
+
+/** @defgroup UART_Receiver_Timeout UART Receiver Timeout
+  * @{
+  */
+#define UART_RECEIVER_TIMEOUT_DISABLE       0x00000000U                /*!< UART Receiver Timeout disable */
+#define UART_RECEIVER_TIMEOUT_ENABLE        USART_CR2_RTOEN            /*!< UART Receiver Timeout enable  */
+/**
+  * @}
+  */
+
+/** @defgroup UART_LIN    UART Local Interconnection Network mode
+  * @{
+  */
+#define UART_LIN_DISABLE                    0x00000000U                /*!< Local Interconnect Network disable */
+#define UART_LIN_ENABLE                     USART_CR2_LINEN            /*!< Local Interconnect Network enable  */
+/**
+  * @}
+  */
+
+/** @defgroup UART_LIN_Break_Detection  UART LIN Break Detection
+  * @{
+  */
+#define UART_LINBREAKDETECTLENGTH_10B       0x00000000U                /*!< LIN 10-bit break detection length */
+#define UART_LINBREAKDETECTLENGTH_11B       USART_CR2_LBDL             /*!< LIN 11-bit break detection length  */
+/**
+  * @}
+  */
+
+/** @defgroup UART_DMA_Tx    UART DMA Tx
+  * @{
+  */
+#define UART_DMA_TX_DISABLE                 0x00000000U                /*!< UART DMA TX disabled */
+#define UART_DMA_TX_ENABLE                  USART_CR3_DMAT             /*!< UART DMA TX enabled  */
+/**
+  * @}
+  */
+
+/** @defgroup UART_DMA_Rx   UART DMA Rx
+  * @{
+  */
+#define UART_DMA_RX_DISABLE                 0x00000000U                 /*!< UART DMA RX disabled */
+#define UART_DMA_RX_ENABLE                  USART_CR3_DMAR              /*!< UART DMA RX enabled  */
+/**
+  * @}
+  */
+
+/** @defgroup UART_Half_Duplex_Selection  UART Half Duplex Selection
+  * @{
+  */
+#define UART_HALF_DUPLEX_DISABLE            0x00000000U                 /*!< UART half-duplex disabled */
+#define UART_HALF_DUPLEX_ENABLE             USART_CR3_HDSEL             /*!< UART half-duplex enabled  */
+/**
+  * @}
+  */
+
+/** @defgroup UART_WakeUp_Methods   UART WakeUp Methods
+  * @{
+  */
+#define UART_WAKEUPMETHOD_IDLELINE          0x00000000U                 /*!< UART wake-up on idle line    */
+#define UART_WAKEUPMETHOD_ADDRESSMARK       USART_CR1_WAKE              /*!< UART wake-up on address mark */
+/**
+  * @}
+  */
+
+/** @defgroup UART_Request_Parameters UART Request Parameters
+  * @{
+  */
+#define UART_AUTOBAUD_REQUEST               USART_RQR_ABRRQ        /*!< Auto-Baud Rate Request      */
+#define UART_SENDBREAK_REQUEST              USART_RQR_SBKRQ        /*!< Send Break Request          */
+#define UART_MUTE_MODE_REQUEST              USART_RQR_MMRQ         /*!< Mute Mode Request           */
+#define UART_RXDATA_FLUSH_REQUEST           USART_RQR_RXFRQ        /*!< Receive Data flush Request  */
+#define UART_TXDATA_FLUSH_REQUEST           USART_RQR_TXFRQ        /*!< Transmit data flush Request */
+/**
+  * @}
+  */
+
+/** @defgroup UART_Advanced_Features_Initialization_Type  UART Advanced Feature Initialization Type
+  * @{
+  */
+#define UART_ADVFEATURE_NO_INIT                 0x00000000U          /*!< No advanced feature initialization       */
+#define UART_ADVFEATURE_TXINVERT_INIT           0x00000001U          /*!< TX pin active level inversion            */
+#define UART_ADVFEATURE_RXINVERT_INIT           0x00000002U          /*!< RX pin active level inversion            */
+#define UART_ADVFEATURE_DATAINVERT_INIT         0x00000004U          /*!< Binary data inversion                    */
+#define UART_ADVFEATURE_SWAP_INIT               0x00000008U          /*!< TX/RX pins swap                          */
+#define UART_ADVFEATURE_RXOVERRUNDISABLE_INIT   0x00000010U          /*!< RX overrun disable                       */
+#define UART_ADVFEATURE_DMADISABLEONERROR_INIT  0x00000020U          /*!< DMA disable on Reception Error           */
+#define UART_ADVFEATURE_AUTOBAUDRATE_INIT       0x00000040U          /*!< Auto Baud rate detection initialization  */
+#define UART_ADVFEATURE_MSBFIRST_INIT           0x00000080U          /*!< Most significant bit sent/received first */
+/**
+  * @}
+  */
+
+/** @defgroup UART_Tx_Inv UART Advanced Feature TX Pin Active Level Inversion
+  * @{
+  */
+#define UART_ADVFEATURE_TXINV_DISABLE       0x00000000U             /*!< TX pin active level inversion disable */
+#define UART_ADVFEATURE_TXINV_ENABLE        USART_CR2_TXINV         /*!< TX pin active level inversion enable  */
+/**
+  * @}
+  */
+
+/** @defgroup UART_Rx_Inv UART Advanced Feature RX Pin Active Level Inversion
+  * @{
+  */
+#define UART_ADVFEATURE_RXINV_DISABLE       0x00000000U             /*!< RX pin active level inversion disable */
+#define UART_ADVFEATURE_RXINV_ENABLE        USART_CR2_RXINV         /*!< RX pin active level inversion enable  */
+/**
+  * @}
+  */
+
+/** @defgroup UART_Data_Inv  UART Advanced Feature Binary Data Inversion
+  * @{
+  */
+#define UART_ADVFEATURE_DATAINV_DISABLE     0x00000000U             /*!< Binary data inversion disable */
+#define UART_ADVFEATURE_DATAINV_ENABLE      USART_CR2_DATAINV       /*!< Binary data inversion enable  */
+/**
+  * @}
+  */
+
+/** @defgroup UART_Rx_Tx_Swap UART Advanced Feature RX TX Pins Swap
+  * @{
+  */
+#define UART_ADVFEATURE_SWAP_DISABLE        0x00000000U             /*!< TX/RX pins swap disable */
+#define UART_ADVFEATURE_SWAP_ENABLE         USART_CR2_SWAP          /*!< TX/RX pins swap enable  */
+/**
+  * @}
+  */
+
+/** @defgroup UART_Overrun_Disable  UART Advanced Feature Overrun Disable
+  * @{
+  */
+#define UART_ADVFEATURE_OVERRUN_ENABLE      0x00000000U             /*!< RX overrun enable  */
+#define UART_ADVFEATURE_OVERRUN_DISABLE     USART_CR3_OVRDIS        /*!< RX overrun disable */
+/**
+  * @}
+  */
+
+/** @defgroup UART_AutoBaudRate_Enable  UART Advanced Feature Auto BaudRate Enable
+  * @{
+  */
+#define UART_ADVFEATURE_AUTOBAUDRATE_DISABLE   0x00000000U          /*!< RX Auto Baud rate detection enable  */
+#define UART_ADVFEATURE_AUTOBAUDRATE_ENABLE    USART_CR2_ABREN      /*!< RX Auto Baud rate detection disable */
+/**
+  * @}
+  */
+
+/** @defgroup UART_DMA_Disable_on_Rx_Error   UART Advanced Feature DMA Disable On Rx Error
+  * @{
+  */
+#define UART_ADVFEATURE_DMA_ENABLEONRXERROR    0x00000000U          /*!< DMA enable on Reception Error  */
+#define UART_ADVFEATURE_DMA_DISABLEONRXERROR   USART_CR3_DDRE       /*!< DMA disable on Reception Error */
+/**
+  * @}
+  */
+
+/** @defgroup UART_MSB_First   UART Advanced Feature MSB First
+  * @{
+  */
+#define UART_ADVFEATURE_MSBFIRST_DISABLE    0x00000000U             /*!< Most significant bit sent/received
+                                                                         first disable                      */
+#define UART_ADVFEATURE_MSBFIRST_ENABLE     USART_CR2_MSBFIRST      /*!< Most significant bit sent/received
+                                                                         first enable                       */
+/**
+  * @}
+  */
+
+/** @defgroup UART_Stop_Mode_Enable   UART Advanced Feature Stop Mode Enable
+  * @{
+  */
+#define UART_ADVFEATURE_STOPMODE_DISABLE    0x00000000U             /*!< UART stop mode disable */
+#define UART_ADVFEATURE_STOPMODE_ENABLE     USART_CR1_UESM          /*!< UART stop mode enable  */
+/**
+  * @}
+  */
+
+/** @defgroup UART_Mute_Mode   UART Advanced Feature Mute Mode Enable
+  * @{
+  */
+#define UART_ADVFEATURE_MUTEMODE_DISABLE    0x00000000U             /*!< UART mute mode disable */
+#define UART_ADVFEATURE_MUTEMODE_ENABLE     USART_CR1_MME           /*!< UART mute mode enable  */
+/**
+  * @}
+  */
+
+/** @defgroup UART_CR2_ADDRESS_LSB_POS    UART Address-matching LSB Position In CR2 Register
+  * @{
+  */
+#define UART_CR2_ADDRESS_LSB_POS             24U             /*!< UART address-matching LSB position in CR2 register */
+/**
+  * @}
+  */
+
+/** @defgroup UART_WakeUp_from_Stop_Selection   UART WakeUp From Stop Selection
+  * @{
+  */
+#define UART_WAKEUP_ON_ADDRESS              0x00000000U             /*!< UART wake-up on address                     */
+#define UART_WAKEUP_ON_STARTBIT             USART_CR3_WUS_1         /*!< UART wake-up on start bit                   */
+#define UART_WAKEUP_ON_READDATA_NONEMPTY    USART_CR3_WUS           /*!< UART wake-up on receive data register
+                                                                         not empty or RXFIFO is not empty            */
+/**
+  * @}
+  */
+
+/** @defgroup UART_DriverEnable_Polarity      UART DriverEnable Polarity
+  * @{
+  */
+#define UART_DE_POLARITY_HIGH               0x00000000U             /*!< Driver enable signal is active high */
+#define UART_DE_POLARITY_LOW                USART_CR3_DEP           /*!< Driver enable signal is active low  */
+/**
+  * @}
+  */
+
+/** @defgroup UART_CR1_DEAT_ADDRESS_LSB_POS    UART Driver Enable Assertion Time LSB Position In CR1 Register
+  * @{
+  */
+#define UART_CR1_DEAT_ADDRESS_LSB_POS       21U      /*!< UART Driver Enable assertion time LSB
+                                                          position in CR1 register */
+/**
+  * @}
+  */
+
+/** @defgroup UART_CR1_DEDT_ADDRESS_LSB_POS    UART Driver Enable DeAssertion Time LSB Position In CR1 Register
+  * @{
+  */
+#define UART_CR1_DEDT_ADDRESS_LSB_POS       16U      /*!< UART Driver Enable de-assertion time LSB
+                                                          position in CR1 register */
+/**
+  * @}
+  */
+
+/** @defgroup UART_Interruption_Mask    UART Interruptions Flag Mask
+  * @{
+  */
+#define UART_IT_MASK                        0x001FU  /*!< UART interruptions flags mask */
+/**
+  * @}
+  */
+
+/** @defgroup UART_TimeOut_Value    UART polling-based communications time-out value
+  * @{
+  */
+#define HAL_UART_TIMEOUT_VALUE              0x1FFFFFFU  /*!< UART polling-based communications time-out value */
+/**
+  * @}
+  */
+
+/** @defgroup UART_Flags     UART Status Flags
+  *        Elements values convention: 0xXXXX
+  *           - 0xXXXX  : Flag mask in the ISR register
+  * @{
+  */
+#define UART_FLAG_TXFT                      USART_ISR_TXFT          /*!< UART TXFIFO threshold flag                */
+#define UART_FLAG_RXFT                      USART_ISR_RXFT          /*!< UART RXFIFO threshold flag                */
+#define UART_FLAG_RXFF                      USART_ISR_RXFF          /*!< UART RXFIFO Full flag                     */
+#define UART_FLAG_TXFE                      USART_ISR_TXFE          /*!< UART TXFIFO Empty flag                    */
+#define UART_FLAG_REACK                     USART_ISR_REACK         /*!< UART receive enable acknowledge flag      */
+#define UART_FLAG_TEACK                     USART_ISR_TEACK         /*!< UART transmit enable acknowledge flag     */
+#define UART_FLAG_WUF                       USART_ISR_WUF           /*!< UART wake-up from stop mode flag          */
+#define UART_FLAG_RWU                       USART_ISR_RWU           /*!< UART receiver wake-up from mute mode flag */
+#define UART_FLAG_SBKF                      USART_ISR_SBKF          /*!< UART send break flag                      */
+#define UART_FLAG_CMF                       USART_ISR_CMF           /*!< UART character match flag                 */
+#define UART_FLAG_BUSY                      USART_ISR_BUSY          /*!< UART busy flag                            */
+#define UART_FLAG_ABRF                      USART_ISR_ABRF          /*!< UART auto Baud rate flag                  */
+#define UART_FLAG_ABRE                      USART_ISR_ABRE          /*!< UART auto Baud rate error                 */
+#define UART_FLAG_RTOF                      USART_ISR_RTOF          /*!< UART receiver timeout flag                */
+#define UART_FLAG_CTS                       USART_ISR_CTS           /*!< UART clear to send flag                   */
+#define UART_FLAG_CTSIF                     USART_ISR_CTSIF         /*!< UART clear to send interrupt flag         */
+#define UART_FLAG_LBDF                      USART_ISR_LBDF          /*!< UART LIN break detection flag             */
+#define UART_FLAG_TXE                       USART_ISR_TXE_TXFNF     /*!< UART transmit data register empty         */
+#define UART_FLAG_TXFNF                     USART_ISR_TXE_TXFNF     /*!< UART TXFIFO not full                      */
+#define UART_FLAG_TC                        USART_ISR_TC            /*!< UART transmission complete                */
+#define UART_FLAG_RXNE                      USART_ISR_RXNE_RXFNE    /*!< UART read data register not empty         */
+#define UART_FLAG_RXFNE                     USART_ISR_RXNE_RXFNE    /*!< UART RXFIFO not empty                     */
+#define UART_FLAG_IDLE                      USART_ISR_IDLE          /*!< UART idle flag                            */
+#define UART_FLAG_ORE                       USART_ISR_ORE           /*!< UART overrun error                        */
+#define UART_FLAG_NE                        USART_ISR_NE            /*!< UART noise error                          */
+#define UART_FLAG_FE                        USART_ISR_FE            /*!< UART frame error                          */
+#define UART_FLAG_PE                        USART_ISR_PE            /*!< UART parity error                         */
+/**
+  * @}
+  */
+
+/** @defgroup UART_Interrupt_definition   UART Interrupts Definition
+  *        Elements values convention: 000ZZZZZ0XXYYYYYb
+  *           - YYYYY  : Interrupt source position in the XX register (5bits)
+  *           - XX  : Interrupt source register (2bits)
+  *                 - 01: CR1 register
+  *                 - 10: CR2 register
+  *                 - 11: CR3 register
+  *           - ZZZZZ  : Flag position in the ISR register(5bits)
+  *        Elements values convention: 000000000XXYYYYYb
+  *           - YYYYY  : Interrupt source position in the XX register (5bits)
+  *           - XX  : Interrupt source register (2bits)
+  *                 - 01: CR1 register
+  *                 - 10: CR2 register
+  *                 - 11: CR3 register
+  *        Elements values convention: 0000ZZZZ00000000b
+  *           - ZZZZ  : Flag position in the ISR register(4bits)
+  * @{
+  */
+#define UART_IT_PE                          0x0028U              /*!< UART parity error interruption                 */
+#define UART_IT_TXE                         0x0727U              /*!< UART transmit data register empty interruption */
+#define UART_IT_TXFNF                       0x0727U              /*!< UART TX FIFO not full interruption             */
+#define UART_IT_TC                          0x0626U              /*!< UART transmission complete interruption        */
+#define UART_IT_RXNE                        0x0525U              /*!< UART read data register not empty interruption */
+#define UART_IT_RXFNE                       0x0525U              /*!< UART RXFIFO not empty interruption             */
+#define UART_IT_IDLE                        0x0424U              /*!< UART idle interruption                         */
+#define UART_IT_LBD                         0x0846U              /*!< UART LIN break detection interruption          */
+#define UART_IT_CTS                         0x096AU              /*!< UART CTS interruption                          */
+#define UART_IT_CM                          0x112EU              /*!< UART character match interruption              */
+#define UART_IT_WUF                         0x1476U              /*!< UART wake-up from stop mode interruption       */
+#define UART_IT_RXFF                        0x183FU              /*!< UART RXFIFO full interruption                  */
+#define UART_IT_TXFE                        0x173EU              /*!< UART TXFIFO empty interruption                 */
+#define UART_IT_RXFT                        0x1A7CU              /*!< UART RXFIFO threshold reached interruption     */
+#define UART_IT_TXFT                        0x1B77U              /*!< UART TXFIFO threshold reached interruption     */
+#define UART_IT_RTO                         0x0B3AU              /*!< UART receiver timeout interruption             */
+
+#define UART_IT_ERR                         0x0060U              /*!< UART error interruption                        */
+
+#define UART_IT_ORE                         0x0300U              /*!< UART overrun error interruption                */
+#define UART_IT_NE                          0x0200U              /*!< UART noise error interruption                  */
+#define UART_IT_FE                          0x0100U              /*!< UART frame error interruption                  */
+/**
+  * @}
+  */
+
+/** @defgroup UART_IT_CLEAR_Flags  UART Interruption Clear Flags
+  * @{
+  */
+#define UART_CLEAR_PEF                       USART_ICR_PECF            /*!< Parity Error Clear Flag           */
+#define UART_CLEAR_FEF                       USART_ICR_FECF            /*!< Framing Error Clear Flag          */
+#define UART_CLEAR_NEF                       USART_ICR_NECF            /*!< Noise Error detected Clear Flag   */
+#define UART_CLEAR_OREF                      USART_ICR_ORECF           /*!< Overrun Error Clear Flag          */
+#define UART_CLEAR_IDLEF                     USART_ICR_IDLECF          /*!< IDLE line detected Clear Flag     */
+#define UART_CLEAR_TXFECF                    USART_ICR_TXFECF          /*!< TXFIFO empty clear flag           */
+#define UART_CLEAR_TCF                       USART_ICR_TCCF            /*!< Transmission Complete Clear Flag  */
+#define UART_CLEAR_LBDF                      USART_ICR_LBDCF           /*!< LIN Break Detection Clear Flag    */
+#define UART_CLEAR_CTSF                      USART_ICR_CTSCF           /*!< CTS Interrupt Clear Flag          */
+#define UART_CLEAR_CMF                       USART_ICR_CMCF            /*!< Character Match Clear Flag        */
+#define UART_CLEAR_WUF                       USART_ICR_WUCF            /*!< Wake Up from stop mode Clear Flag */
+#define UART_CLEAR_RTOF                      USART_ICR_RTOCF           /*!< UART receiver timeout clear flag  */
+/**
+  * @}
+  */
+
+/** @defgroup UART_Reception_Type_Values  UART Reception type values
+  * @{
+  */
+#define HAL_UART_RECEPTION_STANDARD          (0x00000000U)             /*!< Standard reception                       */
+#define HAL_UART_RECEPTION_TOIDLE            (0x00000001U)             /*!< Reception till completion or IDLE event  */
+#define HAL_UART_RECEPTION_TORTO             (0x00000002U)             /*!< Reception till completion or RTO event   */
+#define HAL_UART_RECEPTION_TOCHARMATCH       (0x00000003U)             /*!< Reception till completion or CM event    */
+/**
+  * @}
+  */
+
+/** @defgroup UART_RxEvent_Type_Values  UART RxEvent type values
+  * @{
+  */
+#define HAL_UART_RXEVENT_TC                  (0x00000000U)             /*!< RxEvent linked to Transfer Complete event */
+#define HAL_UART_RXEVENT_HT                  (0x00000001U)             /*!< RxEvent linked to Half Transfer event     */
+#define HAL_UART_RXEVENT_IDLE                (0x00000002U)             /*!< RxEvent linked to IDLE event              */
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/* Exported macros -----------------------------------------------------------*/
+/** @defgroup UART_Exported_Macros UART Exported Macros
+  * @{
+  */
+
+/** @brief  Reset UART handle states.
+  * @param  __HANDLE__ UART handle.
+  * @retval None
+  */
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+#define __HAL_UART_RESET_HANDLE_STATE(__HANDLE__)  do{                                                   \
+                                                       (__HANDLE__)->gState = HAL_UART_STATE_RESET;      \
+                                                       (__HANDLE__)->RxState = HAL_UART_STATE_RESET;     \
+                                                       (__HANDLE__)->MspInitCallback = NULL;             \
+                                                       (__HANDLE__)->MspDeInitCallback = NULL;           \
+                                                     } while(0U)
+#else
+#define __HAL_UART_RESET_HANDLE_STATE(__HANDLE__)  do{                                                   \
+                                                       (__HANDLE__)->gState = HAL_UART_STATE_RESET;      \
+                                                       (__HANDLE__)->RxState = HAL_UART_STATE_RESET;     \
+                                                     } while(0U)
+#endif /*USE_HAL_UART_REGISTER_CALLBACKS */
+
+/** @brief  Flush the UART Data registers.
+  * @param  __HANDLE__ specifies the UART Handle.
+  * @retval None
+  */
+#define __HAL_UART_FLUSH_DRREGISTER(__HANDLE__)  \
+  do{                \
+    SET_BIT((__HANDLE__)->Instance->RQR, UART_RXDATA_FLUSH_REQUEST); \
+    SET_BIT((__HANDLE__)->Instance->RQR, UART_TXDATA_FLUSH_REQUEST); \
+  }  while(0U)
+
+/** @brief  Clear the specified UART pending flag.
+  * @param  __HANDLE__ specifies the UART Handle.
+  * @param  __FLAG__ specifies the flag to check.
+  *          This parameter can be any combination of the following values:
+  *            @arg @ref UART_CLEAR_PEF      Parity Error Clear Flag
+  *            @arg @ref UART_CLEAR_FEF      Framing Error Clear Flag
+  *            @arg @ref UART_CLEAR_NEF      Noise detected Clear Flag
+  *            @arg @ref UART_CLEAR_OREF     Overrun Error Clear Flag
+  *            @arg @ref UART_CLEAR_IDLEF    IDLE line detected Clear Flag
+  *            @arg @ref UART_CLEAR_TXFECF   TXFIFO empty clear Flag
+  *            @arg @ref UART_CLEAR_TCF      Transmission Complete Clear Flag
+  *            @arg @ref UART_CLEAR_RTOF     Receiver Timeout clear flag
+  *            @arg @ref UART_CLEAR_LBDF     LIN Break Detection Clear Flag
+  *            @arg @ref UART_CLEAR_CTSF     CTS Interrupt Clear Flag
+  *            @arg @ref UART_CLEAR_CMF      Character Match Clear Flag
+  *            @arg @ref UART_CLEAR_WUF      Wake Up from stop mode Clear Flag
+  * @retval None
+  */
+#define __HAL_UART_CLEAR_FLAG(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->ICR = (__FLAG__))
+
+/** @brief  Clear the UART PE pending flag.
+  * @param  __HANDLE__ specifies the UART Handle.
+  * @retval None
+  */
+#define __HAL_UART_CLEAR_PEFLAG(__HANDLE__)   __HAL_UART_CLEAR_FLAG((__HANDLE__), UART_CLEAR_PEF)
+
+/** @brief  Clear the UART FE pending flag.
+  * @param  __HANDLE__ specifies the UART Handle.
+  * @retval None
+  */
+#define __HAL_UART_CLEAR_FEFLAG(__HANDLE__)   __HAL_UART_CLEAR_FLAG((__HANDLE__), UART_CLEAR_FEF)
+
+/** @brief  Clear the UART NE pending flag.
+  * @param  __HANDLE__ specifies the UART Handle.
+  * @retval None
+  */
+#define __HAL_UART_CLEAR_NEFLAG(__HANDLE__)  __HAL_UART_CLEAR_FLAG((__HANDLE__), UART_CLEAR_NEF)
+
+/** @brief  Clear the UART ORE pending flag.
+  * @param  __HANDLE__ specifies the UART Handle.
+  * @retval None
+  */
+#define __HAL_UART_CLEAR_OREFLAG(__HANDLE__)   __HAL_UART_CLEAR_FLAG((__HANDLE__), UART_CLEAR_OREF)
+
+/** @brief  Clear the UART IDLE pending flag.
+  * @param  __HANDLE__ specifies the UART Handle.
+  * @retval None
+  */
+#define __HAL_UART_CLEAR_IDLEFLAG(__HANDLE__)   __HAL_UART_CLEAR_FLAG((__HANDLE__), UART_CLEAR_IDLEF)
+
+/** @brief  Clear the UART TX FIFO empty clear flag.
+  * @param  __HANDLE__ specifies the UART Handle.
+  * @retval None
+  */
+#define __HAL_UART_CLEAR_TXFECF(__HANDLE__)   __HAL_UART_CLEAR_FLAG((__HANDLE__), UART_CLEAR_TXFECF)
+
+/** @brief  Check whether the specified UART flag is set or not.
+  * @param  __HANDLE__ specifies the UART Handle.
+  * @param  __FLAG__ specifies the flag to check.
+  *        This parameter can be one of the following values:
+  *            @arg @ref UART_FLAG_TXFT  TXFIFO threshold flag
+  *            @arg @ref UART_FLAG_RXFT  RXFIFO threshold flag
+  *            @arg @ref UART_FLAG_RXFF  RXFIFO Full flag
+  *            @arg @ref UART_FLAG_TXFE  TXFIFO Empty flag
+  *            @arg @ref UART_FLAG_REACK Receive enable acknowledge flag
+  *            @arg @ref UART_FLAG_TEACK Transmit enable acknowledge flag
+  *            @arg @ref UART_FLAG_WUF   Wake up from stop mode flag
+  *            @arg @ref UART_FLAG_RWU   Receiver wake up flag (if the UART in mute mode)
+  *            @arg @ref UART_FLAG_SBKF  Send Break flag
+  *            @arg @ref UART_FLAG_CMF   Character match flag
+  *            @arg @ref UART_FLAG_BUSY  Busy flag
+  *            @arg @ref UART_FLAG_ABRF  Auto Baud rate detection flag
+  *            @arg @ref UART_FLAG_ABRE  Auto Baud rate detection error flag
+  *            @arg @ref UART_FLAG_CTS   CTS Change flag
+  *            @arg @ref UART_FLAG_LBDF  LIN Break detection flag
+  *            @arg @ref UART_FLAG_TXE   Transmit data register empty flag
+  *            @arg @ref UART_FLAG_TXFNF UART TXFIFO not full flag
+  *            @arg @ref UART_FLAG_TC    Transmission Complete flag
+  *            @arg @ref UART_FLAG_RXNE  Receive data register not empty flag
+  *            @arg @ref UART_FLAG_RXFNE UART RXFIFO not empty flag
+  *            @arg @ref UART_FLAG_RTOF  Receiver Timeout flag
+  *            @arg @ref UART_FLAG_IDLE  Idle Line detection flag
+  *            @arg @ref UART_FLAG_ORE   Overrun Error flag
+  *            @arg @ref UART_FLAG_NE    Noise Error flag
+  *            @arg @ref UART_FLAG_FE    Framing Error flag
+  *            @arg @ref UART_FLAG_PE    Parity Error flag
+  * @retval The new state of __FLAG__ (TRUE or FALSE).
+  */
+#define __HAL_UART_GET_FLAG(__HANDLE__, __FLAG__) (((__HANDLE__)->Instance->ISR & (__FLAG__)) == (__FLAG__))
+
+/** @brief  Enable the specified UART interrupt.
+  * @param  __HANDLE__ specifies the UART Handle.
+  * @param  __INTERRUPT__ specifies the UART interrupt source to enable.
+  *          This parameter can be one of the following values:
+  *            @arg @ref UART_IT_RXFF  RXFIFO Full interrupt
+  *            @arg @ref UART_IT_TXFE  TXFIFO Empty interrupt
+  *            @arg @ref UART_IT_RXFT  RXFIFO threshold interrupt
+  *            @arg @ref UART_IT_TXFT  TXFIFO threshold interrupt
+  *            @arg @ref UART_IT_WUF   Wakeup from stop mode interrupt
+  *            @arg @ref UART_IT_CM    Character match interrupt
+  *            @arg @ref UART_IT_CTS   CTS change interrupt
+  *            @arg @ref UART_IT_LBD   LIN Break detection interrupt
+  *            @arg @ref UART_IT_TXE   Transmit Data Register empty interrupt
+  *            @arg @ref UART_IT_TXFNF TX FIFO not full interrupt
+  *            @arg @ref UART_IT_TC    Transmission complete interrupt
+  *            @arg @ref UART_IT_RXNE  Receive Data register not empty interrupt
+  *            @arg @ref UART_IT_RXFNE RXFIFO not empty interrupt
+  *            @arg @ref UART_IT_RTO   Receive Timeout interrupt
+  *            @arg @ref UART_IT_IDLE  Idle line detection interrupt
+  *            @arg @ref UART_IT_PE    Parity Error interrupt
+  *            @arg @ref UART_IT_ERR   Error interrupt (frame error, noise error, overrun error)
+  * @retval None
+  */
+#define __HAL_UART_ENABLE_IT(__HANDLE__, __INTERRUPT__)   (\
+                                                           ((((uint8_t)(__INTERRUPT__)) >> 5U) == 1U)?\
+                                                           ((__HANDLE__)->Instance->CR1 |= (1U <<\
+                                                               ((__INTERRUPT__) & UART_IT_MASK))): \
+                                                           ((((uint8_t)(__INTERRUPT__)) >> 5U) == 2U)?\
+                                                           ((__HANDLE__)->Instance->CR2 |= (1U <<\
+                                                               ((__INTERRUPT__) & UART_IT_MASK))): \
+                                                           ((__HANDLE__)->Instance->CR3 |= (1U <<\
+                                                               ((__INTERRUPT__) & UART_IT_MASK))))
+
+/** @brief  Disable the specified UART interrupt.
+  * @param  __HANDLE__ specifies the UART Handle.
+  * @param  __INTERRUPT__ specifies the UART interrupt source to disable.
+  *          This parameter can be one of the following values:
+  *            @arg @ref UART_IT_RXFF  RXFIFO Full interrupt
+  *            @arg @ref UART_IT_TXFE  TXFIFO Empty interrupt
+  *            @arg @ref UART_IT_RXFT  RXFIFO threshold interrupt
+  *            @arg @ref UART_IT_TXFT  TXFIFO threshold interrupt
+  *            @arg @ref UART_IT_WUF   Wakeup from stop mode interrupt
+  *            @arg @ref UART_IT_CM    Character match interrupt
+  *            @arg @ref UART_IT_CTS   CTS change interrupt
+  *            @arg @ref UART_IT_LBD   LIN Break detection interrupt
+  *            @arg @ref UART_IT_TXE   Transmit Data Register empty interrupt
+  *            @arg @ref UART_IT_TXFNF TX FIFO not full interrupt
+  *            @arg @ref UART_IT_TC    Transmission complete interrupt
+  *            @arg @ref UART_IT_RXNE  Receive Data register not empty interrupt
+  *            @arg @ref UART_IT_RXFNE RXFIFO not empty interrupt
+  *            @arg @ref UART_IT_RTO   Receive Timeout interrupt
+  *            @arg @ref UART_IT_IDLE  Idle line detection interrupt
+  *            @arg @ref UART_IT_PE    Parity Error interrupt
+  *            @arg @ref UART_IT_ERR   Error interrupt (Frame error, noise error, overrun error)
+  * @retval None
+  */
+#define __HAL_UART_DISABLE_IT(__HANDLE__, __INTERRUPT__)  (\
+                                                           ((((uint8_t)(__INTERRUPT__)) >> 5U) == 1U)?\
+                                                           ((__HANDLE__)->Instance->CR1 &= ~ (1U <<\
+                                                               ((__INTERRUPT__) & UART_IT_MASK))): \
+                                                           ((((uint8_t)(__INTERRUPT__)) >> 5U) == 2U)?\
+                                                           ((__HANDLE__)->Instance->CR2 &= ~ (1U <<\
+                                                               ((__INTERRUPT__) & UART_IT_MASK))): \
+                                                           ((__HANDLE__)->Instance->CR3 &= ~ (1U <<\
+                                                               ((__INTERRUPT__) & UART_IT_MASK))))
+
+/** @brief  Check whether the specified UART interrupt has occurred or not.
+  * @param  __HANDLE__ specifies the UART Handle.
+  * @param  __INTERRUPT__ specifies the UART interrupt to check.
+  *          This parameter can be one of the following values:
+  *            @arg @ref UART_IT_RXFF  RXFIFO Full interrupt
+  *            @arg @ref UART_IT_TXFE  TXFIFO Empty interrupt
+  *            @arg @ref UART_IT_RXFT  RXFIFO threshold interrupt
+  *            @arg @ref UART_IT_TXFT  TXFIFO threshold interrupt
+  *            @arg @ref UART_IT_WUF   Wakeup from stop mode interrupt
+  *            @arg @ref UART_IT_CM    Character match interrupt
+  *            @arg @ref UART_IT_CTS   CTS change interrupt
+  *            @arg @ref UART_IT_LBD   LIN Break detection interrupt
+  *            @arg @ref UART_IT_TXE   Transmit Data Register empty interrupt
+  *            @arg @ref UART_IT_TXFNF TX FIFO not full interrupt
+  *            @arg @ref UART_IT_TC    Transmission complete interrupt
+  *            @arg @ref UART_IT_RXNE  Receive Data register not empty interrupt
+  *            @arg @ref UART_IT_RXFNE RXFIFO not empty interrupt
+  *            @arg @ref UART_IT_RTO   Receive Timeout interrupt
+  *            @arg @ref UART_IT_IDLE  Idle line detection interrupt
+  *            @arg @ref UART_IT_PE    Parity Error interrupt
+  *            @arg @ref UART_IT_ERR   Error interrupt (Frame error, noise error, overrun error)
+  * @retval The new state of __INTERRUPT__ (SET or RESET).
+  */
+#define __HAL_UART_GET_IT(__HANDLE__, __INTERRUPT__) ((((__HANDLE__)->Instance->ISR\
+                                                        & (1U << ((__INTERRUPT__)>> 8U))) != RESET) ? SET : RESET)
+
+/** @brief  Check whether the specified UART interrupt source is enabled or not.
+  * @param  __HANDLE__ specifies the UART Handle.
+  * @param  __INTERRUPT__ specifies the UART interrupt source to check.
+  *          This parameter can be one of the following values:
+  *            @arg @ref UART_IT_RXFF  RXFIFO Full interrupt
+  *            @arg @ref UART_IT_TXFE  TXFIFO Empty interrupt
+  *            @arg @ref UART_IT_RXFT  RXFIFO threshold interrupt
+  *            @arg @ref UART_IT_TXFT  TXFIFO threshold interrupt
+  *            @arg @ref UART_IT_WUF   Wakeup from stop mode interrupt
+  *            @arg @ref UART_IT_CM    Character match interrupt
+  *            @arg @ref UART_IT_CTS   CTS change interrupt
+  *            @arg @ref UART_IT_LBD   LIN Break detection interrupt
+  *            @arg @ref UART_IT_TXE   Transmit Data Register empty interrupt
+  *            @arg @ref UART_IT_TXFNF TX FIFO not full interrupt
+  *            @arg @ref UART_IT_TC    Transmission complete interrupt
+  *            @arg @ref UART_IT_RXNE  Receive Data register not empty interrupt
+  *            @arg @ref UART_IT_RXFNE RXFIFO not empty interrupt
+  *            @arg @ref UART_IT_RTO   Receive Timeout interrupt
+  *            @arg @ref UART_IT_IDLE  Idle line detection interrupt
+  *            @arg @ref UART_IT_PE    Parity Error interrupt
+  *            @arg @ref UART_IT_ERR   Error interrupt (Frame error, noise error, overrun error)
+  * @retval The new state of __INTERRUPT__ (SET or RESET).
+  */
+#define __HAL_UART_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) ((((((((uint8_t)(__INTERRUPT__)) >> 5U) == 1U) ?\
+                                                                (__HANDLE__)->Instance->CR1 : \
+                                                                (((((uint8_t)(__INTERRUPT__)) >> 5U) == 2U) ?\
+                                                                 (__HANDLE__)->Instance->CR2 : \
+                                                                 (__HANDLE__)->Instance->CR3)) & (1U <<\
+                                                                     (((uint16_t)(__INTERRUPT__)) &\
+                                                                      UART_IT_MASK)))  != RESET) ? SET : RESET)
+
+/** @brief  Clear the specified UART ISR flag, in setting the proper ICR register flag.
+  * @param  __HANDLE__ specifies the UART Handle.
+  * @param  __IT_CLEAR__ specifies the interrupt clear register flag that needs to be set
+  *                       to clear the corresponding interrupt
+  *          This parameter can be one of the following values:
+  *            @arg @ref UART_CLEAR_PEF    Parity Error Clear Flag
+  *            @arg @ref UART_CLEAR_FEF    Framing Error Clear Flag
+  *            @arg @ref UART_CLEAR_NEF    Noise detected Clear Flag
+  *            @arg @ref UART_CLEAR_OREF   Overrun Error Clear Flag
+  *            @arg @ref UART_CLEAR_IDLEF  IDLE line detected Clear Flag
+  *            @arg @ref UART_CLEAR_RTOF   Receiver timeout clear flag
+  *            @arg @ref UART_CLEAR_TXFECF TXFIFO empty Clear Flag
+  *            @arg @ref UART_CLEAR_TCF    Transmission Complete Clear Flag
+  *            @arg @ref UART_CLEAR_LBDF   LIN Break Detection Clear Flag
+  *            @arg @ref UART_CLEAR_CTSF   CTS Interrupt Clear Flag
+  *            @arg @ref UART_CLEAR_CMF    Character Match Clear Flag
+  *            @arg @ref UART_CLEAR_WUF    Wake Up from stop mode Clear Flag
+  * @retval None
+  */
+#define __HAL_UART_CLEAR_IT(__HANDLE__, __IT_CLEAR__) ((__HANDLE__)->Instance->ICR = (uint32_t)(__IT_CLEAR__))
+
+/** @brief  Set a specific UART request flag.
+  * @param  __HANDLE__ specifies the UART Handle.
+  * @param  __REQ__ specifies the request flag to set
+  *          This parameter can be one of the following values:
+  *            @arg @ref UART_AUTOBAUD_REQUEST Auto-Baud Rate Request
+  *            @arg @ref UART_SENDBREAK_REQUEST Send Break Request
+  *            @arg @ref UART_MUTE_MODE_REQUEST Mute Mode Request
+  *            @arg @ref UART_RXDATA_FLUSH_REQUEST Receive Data flush Request
+  *            @arg @ref UART_TXDATA_FLUSH_REQUEST Transmit data flush Request
+  * @retval None
+  */
+#define __HAL_UART_SEND_REQ(__HANDLE__, __REQ__) ((__HANDLE__)->Instance->RQR |= (uint16_t)(__REQ__))
+
+/** @brief  Enable the UART one bit sample method.
+  * @param  __HANDLE__ specifies the UART Handle.
+  * @retval None
+  */
+#define __HAL_UART_ONE_BIT_SAMPLE_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->CR3|= USART_CR3_ONEBIT)
+
+/** @brief  Disable the UART one bit sample method.
+  * @param  __HANDLE__ specifies the UART Handle.
+  * @retval None
+  */
+#define __HAL_UART_ONE_BIT_SAMPLE_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->CR3 &= ~USART_CR3_ONEBIT)
+
+/** @brief  Enable UART.
+  * @param  __HANDLE__ specifies the UART Handle.
+  * @retval None
+  */
+#define __HAL_UART_ENABLE(__HANDLE__)                   ((__HANDLE__)->Instance->CR1 |= USART_CR1_UE)
+
+/** @brief  Disable UART.
+  * @param  __HANDLE__ specifies the UART Handle.
+  * @retval None
+  */
+#define __HAL_UART_DISABLE(__HANDLE__)                  ((__HANDLE__)->Instance->CR1 &= ~USART_CR1_UE)
+
+/** @brief  Enable CTS flow control.
+  * @note   This macro allows to enable CTS hardware flow control for a given UART instance,
+  *         without need to call HAL_UART_Init() function.
+  *         As involving direct access to UART registers, usage of this macro should be fully endorsed by user.
+  * @note   As macro is expected to be used for modifying CTS Hw flow control feature activation, without need
+  *         for USART instance Deinit/Init, following conditions for macro call should be fulfilled :
+  *           - UART instance should have already been initialised (through call of HAL_UART_Init() )
+  *           - macro could only be called when corresponding UART instance is disabled
+  *             (i.e. __HAL_UART_DISABLE(__HANDLE__)) and should be followed by an Enable
+  *              macro (i.e. __HAL_UART_ENABLE(__HANDLE__)).
+  * @param  __HANDLE__ specifies the UART Handle.
+  * @retval None
+  */
+#define __HAL_UART_HWCONTROL_CTS_ENABLE(__HANDLE__)               \
+  do{                                                             \
+    ATOMIC_SET_BIT((__HANDLE__)->Instance->CR3, USART_CR3_CTSE);  \
+    (__HANDLE__)->Init.HwFlowCtl |= USART_CR3_CTSE;               \
+  } while(0U)
+
+/** @brief  Disable CTS flow control.
+  * @note   This macro allows to disable CTS hardware flow control for a given UART instance,
+  *         without need to call HAL_UART_Init() function.
+  *         As involving direct access to UART registers, usage of this macro should be fully endorsed by user.
+  * @note   As macro is expected to be used for modifying CTS Hw flow control feature activation, without need
+  *         for USART instance Deinit/Init, following conditions for macro call should be fulfilled :
+  *           - UART instance should have already been initialised (through call of HAL_UART_Init() )
+  *           - macro could only be called when corresponding UART instance is disabled
+  *             (i.e. __HAL_UART_DISABLE(__HANDLE__)) and should be followed by an Enable
+  *              macro (i.e. __HAL_UART_ENABLE(__HANDLE__)).
+  * @param  __HANDLE__ specifies the UART Handle.
+  * @retval None
+  */
+#define __HAL_UART_HWCONTROL_CTS_DISABLE(__HANDLE__)               \
+  do{                                                              \
+    ATOMIC_CLEAR_BIT((__HANDLE__)->Instance->CR3, USART_CR3_CTSE); \
+    (__HANDLE__)->Init.HwFlowCtl &= ~(USART_CR3_CTSE);             \
+  } while(0U)
+
+/** @brief  Enable RTS flow control.
+  * @note   This macro allows to enable RTS hardware flow control for a given UART instance,
+  *         without need to call HAL_UART_Init() function.
+  *         As involving direct access to UART registers, usage of this macro should be fully endorsed by user.
+  * @note   As macro is expected to be used for modifying RTS Hw flow control feature activation, without need
+  *         for USART instance Deinit/Init, following conditions for macro call should be fulfilled :
+  *           - UART instance should have already been initialised (through call of HAL_UART_Init() )
+  *           - macro could only be called when corresponding UART instance is disabled
+  *             (i.e. __HAL_UART_DISABLE(__HANDLE__)) and should be followed by an Enable
+  *              macro (i.e. __HAL_UART_ENABLE(__HANDLE__)).
+  * @param  __HANDLE__ specifies the UART Handle.
+  * @retval None
+  */
+#define __HAL_UART_HWCONTROL_RTS_ENABLE(__HANDLE__)              \
+  do{                                                            \
+    ATOMIC_SET_BIT((__HANDLE__)->Instance->CR3, USART_CR3_RTSE); \
+    (__HANDLE__)->Init.HwFlowCtl |= USART_CR3_RTSE;              \
+  } while(0U)
+
+/** @brief  Disable RTS flow control.
+  * @note   This macro allows to disable RTS hardware flow control for a given UART instance,
+  *         without need to call HAL_UART_Init() function.
+  *         As involving direct access to UART registers, usage of this macro should be fully endorsed by user.
+  * @note   As macro is expected to be used for modifying RTS Hw flow control feature activation, without need
+  *         for USART instance Deinit/Init, following conditions for macro call should be fulfilled :
+  *           - UART instance should have already been initialised (through call of HAL_UART_Init() )
+  *           - macro could only be called when corresponding UART instance is disabled
+  *             (i.e. __HAL_UART_DISABLE(__HANDLE__)) and should be followed by an Enable
+  *              macro (i.e. __HAL_UART_ENABLE(__HANDLE__)).
+  * @param  __HANDLE__ specifies the UART Handle.
+  * @retval None
+  */
+#define __HAL_UART_HWCONTROL_RTS_DISABLE(__HANDLE__)              \
+  do{                                                             \
+    ATOMIC_CLEAR_BIT((__HANDLE__)->Instance->CR3, USART_CR3_RTSE);\
+    (__HANDLE__)->Init.HwFlowCtl &= ~(USART_CR3_RTSE);            \
+  } while(0U)
+/**
+  * @}
+  */
+
+/* Private macros --------------------------------------------------------*/
+/** @defgroup UART_Private_Macros   UART Private Macros
+  * @{
+  */
+/** @brief  Get UART clock division factor from clock prescaler value.
+  * @param  __CLOCKPRESCALER__ UART prescaler value.
+  * @retval UART clock division factor
+  */
+#define UART_GET_DIV_FACTOR(__CLOCKPRESCALER__) \
+  (((__CLOCKPRESCALER__) == UART_PRESCALER_DIV1)   ? 1U :       \
+   ((__CLOCKPRESCALER__) == UART_PRESCALER_DIV2)   ? 2U :       \
+   ((__CLOCKPRESCALER__) == UART_PRESCALER_DIV4)   ? 4U :       \
+   ((__CLOCKPRESCALER__) == UART_PRESCALER_DIV6)   ? 6U :       \
+   ((__CLOCKPRESCALER__) == UART_PRESCALER_DIV8)   ? 8U :       \
+   ((__CLOCKPRESCALER__) == UART_PRESCALER_DIV10)  ? 10U :      \
+   ((__CLOCKPRESCALER__) == UART_PRESCALER_DIV12)  ? 12U :      \
+   ((__CLOCKPRESCALER__) == UART_PRESCALER_DIV16)  ? 16U :      \
+   ((__CLOCKPRESCALER__) == UART_PRESCALER_DIV32)  ? 32U :      \
+   ((__CLOCKPRESCALER__) == UART_PRESCALER_DIV64)  ? 64U :      \
+   ((__CLOCKPRESCALER__) == UART_PRESCALER_DIV128) ? 128U : 256U)
+
+/** @brief  BRR division operation to set BRR register with LPUART.
+  * @param  __PCLK__ LPUART clock.
+  * @param  __BAUD__ Baud rate set by the user.
+  * @param  __CLOCKPRESCALER__ UART prescaler value.
+  * @retval Division result
+  */
+#define UART_DIV_LPUART(__PCLK__, __BAUD__, __CLOCKPRESCALER__)                        \
+  ((uint32_t)((((((uint64_t)(__PCLK__))/(UARTPrescTable[(__CLOCKPRESCALER__)]))*256U)+ \
+               (uint32_t)((__BAUD__)/2U)) / (__BAUD__))                                \
+  )
+
+/** @brief  BRR division operation to set BRR register in 8-bit oversampling mode.
+  * @param  __PCLK__ UART clock.
+  * @param  __BAUD__ Baud rate set by the user.
+  * @param  __CLOCKPRESCALER__ UART prescaler value.
+  * @retval Division result
+  */
+#define UART_DIV_SAMPLING8(__PCLK__, __BAUD__, __CLOCKPRESCALER__)                        \
+  (((((__PCLK__)/UARTPrescTable[(__CLOCKPRESCALER__)])*2U) + ((__BAUD__)/2U)) / (__BAUD__))
+
+/** @brief  BRR division operation to set BRR register in 16-bit oversampling mode.
+  * @param  __PCLK__ UART clock.
+  * @param  __BAUD__ Baud rate set by the user.
+  * @param  __CLOCKPRESCALER__ UART prescaler value.
+  * @retval Division result
+  */
+#define UART_DIV_SAMPLING16(__PCLK__, __BAUD__, __CLOCKPRESCALER__)                       \
+  ((((__PCLK__)/UARTPrescTable[(__CLOCKPRESCALER__)]) + ((__BAUD__)/2U)) / (__BAUD__))
+
+/** @brief  Check whether or not UART instance is Low Power UART.
+  * @param  __HANDLE__ specifies the UART Handle.
+  * @retval SET (instance is LPUART) or RESET (instance isn't LPUART)
+  */
+#define UART_INSTANCE_LOWPOWER(__HANDLE__) (IS_LPUART_INSTANCE((__HANDLE__)->Instance))
+
+/** @brief  Check UART Baud rate.
+  * @param  __BAUDRATE__ Baudrate specified by the user.
+  *         The maximum Baud Rate is derived from the maximum clock on G4 (i.e. 150 MHz)
+  *         divided by the smallest oversampling used on the USART (i.e. 8)
+  * @retval SET (__BAUDRATE__ is valid) or RESET (__BAUDRATE__ is invalid)
+  */
+#define IS_UART_BAUDRATE(__BAUDRATE__) ((__BAUDRATE__) < 18750001U)
+
+/** @brief  Check UART assertion time.
+  * @param  __TIME__ 5-bit value assertion time.
+  * @retval Test result (TRUE or FALSE).
+  */
+#define IS_UART_ASSERTIONTIME(__TIME__)    ((__TIME__) <= 0x1FU)
+
+/** @brief  Check UART deassertion time.
+  * @param  __TIME__ 5-bit value deassertion time.
+  * @retval Test result (TRUE or FALSE).
+  */
+#define IS_UART_DEASSERTIONTIME(__TIME__) ((__TIME__) <= 0x1FU)
+
+/**
+  * @brief Ensure that UART frame number of stop bits is valid.
+  * @param __STOPBITS__ UART frame number of stop bits.
+  * @retval SET (__STOPBITS__ is valid) or RESET (__STOPBITS__ is invalid)
+  */
+#define IS_UART_STOPBITS(__STOPBITS__) (((__STOPBITS__) == UART_STOPBITS_0_5) || \
+                                        ((__STOPBITS__) == UART_STOPBITS_1)   || \
+                                        ((__STOPBITS__) == UART_STOPBITS_1_5) || \
+                                        ((__STOPBITS__) == UART_STOPBITS_2))
+
+/**
+  * @brief Ensure that LPUART frame number of stop bits is valid.
+  * @param __STOPBITS__ LPUART frame number of stop bits.
+  * @retval SET (__STOPBITS__ is valid) or RESET (__STOPBITS__ is invalid)
+  */
+#define IS_LPUART_STOPBITS(__STOPBITS__) (((__STOPBITS__) == UART_STOPBITS_1) || \
+                                          ((__STOPBITS__) == UART_STOPBITS_2))
+
+/**
+  * @brief Ensure that UART frame parity is valid.
+  * @param __PARITY__ UART frame parity.
+  * @retval SET (__PARITY__ is valid) or RESET (__PARITY__ is invalid)
+  */
+#define IS_UART_PARITY(__PARITY__) (((__PARITY__) == UART_PARITY_NONE) || \
+                                    ((__PARITY__) == UART_PARITY_EVEN) || \
+                                    ((__PARITY__) == UART_PARITY_ODD))
+
+/**
+  * @brief Ensure that UART hardware flow control is valid.
+  * @param __CONTROL__ UART hardware flow control.
+  * @retval SET (__CONTROL__ is valid) or RESET (__CONTROL__ is invalid)
+  */
+#define IS_UART_HARDWARE_FLOW_CONTROL(__CONTROL__)\
+  (((__CONTROL__) == UART_HWCONTROL_NONE) || \
+   ((__CONTROL__) == UART_HWCONTROL_RTS)  || \
+   ((__CONTROL__) == UART_HWCONTROL_CTS)  || \
+   ((__CONTROL__) == UART_HWCONTROL_RTS_CTS))
+
+/**
+  * @brief Ensure that UART communication mode is valid.
+  * @param __MODE__ UART communication mode.
+  * @retval SET (__MODE__ is valid) or RESET (__MODE__ is invalid)
+  */
+#define IS_UART_MODE(__MODE__) ((((__MODE__) & (~((uint32_t)(UART_MODE_TX_RX)))) == 0x00U) && ((__MODE__) != 0x00U))
+
+/**
+  * @brief Ensure that UART state is valid.
+  * @param __STATE__ UART state.
+  * @retval SET (__STATE__ is valid) or RESET (__STATE__ is invalid)
+  */
+#define IS_UART_STATE(__STATE__) (((__STATE__) == UART_STATE_DISABLE) || \
+                                  ((__STATE__) == UART_STATE_ENABLE))
+
+/**
+  * @brief Ensure that UART oversampling is valid.
+  * @param __SAMPLING__ UART oversampling.
+  * @retval SET (__SAMPLING__ is valid) or RESET (__SAMPLING__ is invalid)
+  */
+#define IS_UART_OVERSAMPLING(__SAMPLING__) (((__SAMPLING__) == UART_OVERSAMPLING_16) || \
+                                            ((__SAMPLING__) == UART_OVERSAMPLING_8))
+
+/**
+  * @brief Ensure that UART frame sampling is valid.
+  * @param __ONEBIT__ UART frame sampling.
+  * @retval SET (__ONEBIT__ is valid) or RESET (__ONEBIT__ is invalid)
+  */
+#define IS_UART_ONE_BIT_SAMPLE(__ONEBIT__) (((__ONEBIT__) == UART_ONE_BIT_SAMPLE_DISABLE) || \
+                                            ((__ONEBIT__) == UART_ONE_BIT_SAMPLE_ENABLE))
+
+/**
+  * @brief Ensure that UART auto Baud rate detection mode is valid.
+  * @param __MODE__ UART auto Baud rate detection mode.
+  * @retval SET (__MODE__ is valid) or RESET (__MODE__ is invalid)
+  */
+#define IS_UART_ADVFEATURE_AUTOBAUDRATEMODE(__MODE__)  (((__MODE__) == UART_ADVFEATURE_AUTOBAUDRATE_ONSTARTBIT)    || \
+                                                        ((__MODE__) == UART_ADVFEATURE_AUTOBAUDRATE_ONFALLINGEDGE) || \
+                                                        ((__MODE__) == UART_ADVFEATURE_AUTOBAUDRATE_ON0X7FFRAME)   || \
+                                                        ((__MODE__) == UART_ADVFEATURE_AUTOBAUDRATE_ON0X55FRAME))
+
+/**
+  * @brief Ensure that UART receiver timeout setting is valid.
+  * @param __TIMEOUT__ UART receiver timeout setting.
+  * @retval SET (__TIMEOUT__ is valid) or RESET (__TIMEOUT__ is invalid)
+  */
+#define IS_UART_RECEIVER_TIMEOUT(__TIMEOUT__)  (((__TIMEOUT__) == UART_RECEIVER_TIMEOUT_DISABLE) || \
+                                                ((__TIMEOUT__) == UART_RECEIVER_TIMEOUT_ENABLE))
+
+/** @brief  Check the receiver timeout value.
+  * @note   The maximum UART receiver timeout value is 0xFFFFFF.
+  * @param  __TIMEOUTVALUE__ receiver timeout value.
+  * @retval Test result (TRUE or FALSE)
+  */
+#define IS_UART_RECEIVER_TIMEOUT_VALUE(__TIMEOUTVALUE__)  ((__TIMEOUTVALUE__) <= 0xFFFFFFU)
+
+/**
+  * @brief Ensure that UART LIN state is valid.
+  * @param __LIN__ UART LIN state.
+  * @retval SET (__LIN__ is valid) or RESET (__LIN__ is invalid)
+  */
+#define IS_UART_LIN(__LIN__)        (((__LIN__) == UART_LIN_DISABLE) || \
+                                     ((__LIN__) == UART_LIN_ENABLE))
+
+/**
+  * @brief Ensure that UART LIN break detection length is valid.
+  * @param __LENGTH__ UART LIN break detection length.
+  * @retval SET (__LENGTH__ is valid) or RESET (__LENGTH__ is invalid)
+  */
+#define IS_UART_LIN_BREAK_DETECT_LENGTH(__LENGTH__) (((__LENGTH__) == UART_LINBREAKDETECTLENGTH_10B) || \
+                                                     ((__LENGTH__) == UART_LINBREAKDETECTLENGTH_11B))
+
+/**
+  * @brief Ensure that UART DMA TX state is valid.
+  * @param __DMATX__ UART DMA TX state.
+  * @retval SET (__DMATX__ is valid) or RESET (__DMATX__ is invalid)
+  */
+#define IS_UART_DMA_TX(__DMATX__)     (((__DMATX__) == UART_DMA_TX_DISABLE) || \
+                                       ((__DMATX__) == UART_DMA_TX_ENABLE))
+
+/**
+  * @brief Ensure that UART DMA RX state is valid.
+  * @param __DMARX__ UART DMA RX state.
+  * @retval SET (__DMARX__ is valid) or RESET (__DMARX__ is invalid)
+  */
+#define IS_UART_DMA_RX(__DMARX__)     (((__DMARX__) == UART_DMA_RX_DISABLE) || \
+                                       ((__DMARX__) == UART_DMA_RX_ENABLE))
+
+/**
+  * @brief Ensure that UART half-duplex state is valid.
+  * @param __HDSEL__ UART half-duplex state.
+  * @retval SET (__HDSEL__ is valid) or RESET (__HDSEL__ is invalid)
+  */
+#define IS_UART_HALF_DUPLEX(__HDSEL__)     (((__HDSEL__) == UART_HALF_DUPLEX_DISABLE) || \
+                                            ((__HDSEL__) == UART_HALF_DUPLEX_ENABLE))
+
+/**
+  * @brief Ensure that UART wake-up method is valid.
+  * @param __WAKEUP__ UART wake-up method .
+  * @retval SET (__WAKEUP__ is valid) or RESET (__WAKEUP__ is invalid)
+  */
+#define IS_UART_WAKEUPMETHOD(__WAKEUP__) (((__WAKEUP__) == UART_WAKEUPMETHOD_IDLELINE) || \
+                                          ((__WAKEUP__) == UART_WAKEUPMETHOD_ADDRESSMARK))
+
+/**
+  * @brief Ensure that UART request parameter is valid.
+  * @param __PARAM__ UART request parameter.
+  * @retval SET (__PARAM__ is valid) or RESET (__PARAM__ is invalid)
+  */
+#define IS_UART_REQUEST_PARAMETER(__PARAM__) (((__PARAM__) == UART_AUTOBAUD_REQUEST)     || \
+                                              ((__PARAM__) == UART_SENDBREAK_REQUEST)    || \
+                                              ((__PARAM__) == UART_MUTE_MODE_REQUEST)    || \
+                                              ((__PARAM__) == UART_RXDATA_FLUSH_REQUEST) || \
+                                              ((__PARAM__) == UART_TXDATA_FLUSH_REQUEST))
+
+/**
+  * @brief Ensure that UART advanced features initialization is valid.
+  * @param __INIT__ UART advanced features initialization.
+  * @retval SET (__INIT__ is valid) or RESET (__INIT__ is invalid)
+  */
+#define IS_UART_ADVFEATURE_INIT(__INIT__)   ((__INIT__) <= (UART_ADVFEATURE_NO_INIT                | \
+                                                            UART_ADVFEATURE_TXINVERT_INIT          | \
+                                                            UART_ADVFEATURE_RXINVERT_INIT          | \
+                                                            UART_ADVFEATURE_DATAINVERT_INIT        | \
+                                                            UART_ADVFEATURE_SWAP_INIT              | \
+                                                            UART_ADVFEATURE_RXOVERRUNDISABLE_INIT  | \
+                                                            UART_ADVFEATURE_DMADISABLEONERROR_INIT | \
+                                                            UART_ADVFEATURE_AUTOBAUDRATE_INIT      | \
+                                                            UART_ADVFEATURE_MSBFIRST_INIT))
+
+/**
+  * @brief Ensure that UART frame TX inversion setting is valid.
+  * @param __TXINV__ UART frame TX inversion setting.
+  * @retval SET (__TXINV__ is valid) or RESET (__TXINV__ is invalid)
+  */
+#define IS_UART_ADVFEATURE_TXINV(__TXINV__) (((__TXINV__) == UART_ADVFEATURE_TXINV_DISABLE) || \
+                                             ((__TXINV__) == UART_ADVFEATURE_TXINV_ENABLE))
+
+/**
+  * @brief Ensure that UART frame RX inversion setting is valid.
+  * @param __RXINV__ UART frame RX inversion setting.
+  * @retval SET (__RXINV__ is valid) or RESET (__RXINV__ is invalid)
+  */
+#define IS_UART_ADVFEATURE_RXINV(__RXINV__) (((__RXINV__) == UART_ADVFEATURE_RXINV_DISABLE) || \
+                                             ((__RXINV__) == UART_ADVFEATURE_RXINV_ENABLE))
+
+/**
+  * @brief Ensure that UART frame data inversion setting is valid.
+  * @param __DATAINV__ UART frame data inversion setting.
+  * @retval SET (__DATAINV__ is valid) or RESET (__DATAINV__ is invalid)
+  */
+#define IS_UART_ADVFEATURE_DATAINV(__DATAINV__) (((__DATAINV__) == UART_ADVFEATURE_DATAINV_DISABLE) || \
+                                                 ((__DATAINV__) == UART_ADVFEATURE_DATAINV_ENABLE))
+
+/**
+  * @brief Ensure that UART frame RX/TX pins swap setting is valid.
+  * @param __SWAP__ UART frame RX/TX pins swap setting.
+  * @retval SET (__SWAP__ is valid) or RESET (__SWAP__ is invalid)
+  */
+#define IS_UART_ADVFEATURE_SWAP(__SWAP__) (((__SWAP__) == UART_ADVFEATURE_SWAP_DISABLE) || \
+                                           ((__SWAP__) == UART_ADVFEATURE_SWAP_ENABLE))
+
+/**
+  * @brief Ensure that UART frame overrun setting is valid.
+  * @param __OVERRUN__ UART frame overrun setting.
+  * @retval SET (__OVERRUN__ is valid) or RESET (__OVERRUN__ is invalid)
+  */
+#define IS_UART_OVERRUN(__OVERRUN__)     (((__OVERRUN__) == UART_ADVFEATURE_OVERRUN_ENABLE) || \
+                                          ((__OVERRUN__) == UART_ADVFEATURE_OVERRUN_DISABLE))
+
+/**
+  * @brief Ensure that UART auto Baud rate state is valid.
+  * @param __AUTOBAUDRATE__ UART auto Baud rate state.
+  * @retval SET (__AUTOBAUDRATE__ is valid) or RESET (__AUTOBAUDRATE__ is invalid)
+  */
+#define IS_UART_ADVFEATURE_AUTOBAUDRATE(__AUTOBAUDRATE__) (((__AUTOBAUDRATE__) == \
+                                                            UART_ADVFEATURE_AUTOBAUDRATE_DISABLE) || \
+                                                           ((__AUTOBAUDRATE__) == UART_ADVFEATURE_AUTOBAUDRATE_ENABLE))
+
+/**
+  * @brief Ensure that UART DMA enabling or disabling on error setting is valid.
+  * @param __DMA__ UART DMA enabling or disabling on error setting.
+  * @retval SET (__DMA__ is valid) or RESET (__DMA__ is invalid)
+  */
+#define IS_UART_ADVFEATURE_DMAONRXERROR(__DMA__)  (((__DMA__) == UART_ADVFEATURE_DMA_ENABLEONRXERROR) || \
+                                                   ((__DMA__) == UART_ADVFEATURE_DMA_DISABLEONRXERROR))
+
+/**
+  * @brief Ensure that UART frame MSB first setting is valid.
+  * @param __MSBFIRST__ UART frame MSB first setting.
+  * @retval SET (__MSBFIRST__ is valid) or RESET (__MSBFIRST__ is invalid)
+  */
+#define IS_UART_ADVFEATURE_MSBFIRST(__MSBFIRST__) (((__MSBFIRST__) == UART_ADVFEATURE_MSBFIRST_DISABLE) || \
+                                                   ((__MSBFIRST__) == UART_ADVFEATURE_MSBFIRST_ENABLE))
+
+/**
+  * @brief Ensure that UART stop mode state is valid.
+  * @param __STOPMODE__ UART stop mode state.
+  * @retval SET (__STOPMODE__ is valid) or RESET (__STOPMODE__ is invalid)
+  */
+#define IS_UART_ADVFEATURE_STOPMODE(__STOPMODE__) (((__STOPMODE__) == UART_ADVFEATURE_STOPMODE_DISABLE) || \
+                                                   ((__STOPMODE__) == UART_ADVFEATURE_STOPMODE_ENABLE))
+
+/**
+  * @brief Ensure that UART mute mode state is valid.
+  * @param __MUTE__ UART mute mode state.
+  * @retval SET (__MUTE__ is valid) or RESET (__MUTE__ is invalid)
+  */
+#define IS_UART_MUTE_MODE(__MUTE__)       (((__MUTE__) == UART_ADVFEATURE_MUTEMODE_DISABLE) || \
+                                           ((__MUTE__) == UART_ADVFEATURE_MUTEMODE_ENABLE))
+
+/**
+  * @brief Ensure that UART wake-up selection is valid.
+  * @param __WAKE__ UART wake-up selection.
+  * @retval SET (__WAKE__ is valid) or RESET (__WAKE__ is invalid)
+  */
+#define IS_UART_WAKEUP_SELECTION(__WAKE__) (((__WAKE__) == UART_WAKEUP_ON_ADDRESS)           || \
+                                            ((__WAKE__) == UART_WAKEUP_ON_STARTBIT)          || \
+                                            ((__WAKE__) == UART_WAKEUP_ON_READDATA_NONEMPTY))
+
+/**
+  * @brief Ensure that UART driver enable polarity is valid.
+  * @param __POLARITY__ UART driver enable polarity.
+  * @retval SET (__POLARITY__ is valid) or RESET (__POLARITY__ is invalid)
+  */
+#define IS_UART_DE_POLARITY(__POLARITY__)    (((__POLARITY__) == UART_DE_POLARITY_HIGH) || \
+                                              ((__POLARITY__) == UART_DE_POLARITY_LOW))
+
+/**
+  * @brief Ensure that UART Prescaler is valid.
+  * @param __CLOCKPRESCALER__ UART Prescaler value.
+  * @retval SET (__CLOCKPRESCALER__ is valid) or RESET (__CLOCKPRESCALER__ is invalid)
+  */
+#define IS_UART_PRESCALER(__CLOCKPRESCALER__) (((__CLOCKPRESCALER__) == UART_PRESCALER_DIV1)   || \
+                                               ((__CLOCKPRESCALER__) == UART_PRESCALER_DIV2)   || \
+                                               ((__CLOCKPRESCALER__) == UART_PRESCALER_DIV4)   || \
+                                               ((__CLOCKPRESCALER__) == UART_PRESCALER_DIV6)   || \
+                                               ((__CLOCKPRESCALER__) == UART_PRESCALER_DIV8)   || \
+                                               ((__CLOCKPRESCALER__) == UART_PRESCALER_DIV10)  || \
+                                               ((__CLOCKPRESCALER__) == UART_PRESCALER_DIV12)  || \
+                                               ((__CLOCKPRESCALER__) == UART_PRESCALER_DIV16)  || \
+                                               ((__CLOCKPRESCALER__) == UART_PRESCALER_DIV32)  || \
+                                               ((__CLOCKPRESCALER__) == UART_PRESCALER_DIV64)  || \
+                                               ((__CLOCKPRESCALER__) == UART_PRESCALER_DIV128) || \
+                                               ((__CLOCKPRESCALER__) == UART_PRESCALER_DIV256))
+
+/**
+  * @}
+  */
+
+/* Include UART HAL Extended module */
+#include "stm32g4xx_hal_uart_ex.h"
+
+/* Exported functions --------------------------------------------------------*/
+/** @addtogroup UART_Exported_Functions UART Exported Functions
+  * @{
+  */
+
+/** @addtogroup UART_Exported_Functions_Group1 Initialization and de-initialization functions
+  * @{
+  */
+
+/* Initialization and de-initialization functions  ****************************/
+HAL_StatusTypeDef HAL_UART_Init(UART_HandleTypeDef *huart);
+HAL_StatusTypeDef HAL_HalfDuplex_Init(UART_HandleTypeDef *huart);
+HAL_StatusTypeDef HAL_LIN_Init(UART_HandleTypeDef *huart, uint32_t BreakDetectLength);
+HAL_StatusTypeDef HAL_MultiProcessor_Init(UART_HandleTypeDef *huart, uint8_t Address, uint32_t WakeUpMethod);
+HAL_StatusTypeDef HAL_UART_DeInit(UART_HandleTypeDef *huart);
+void HAL_UART_MspInit(UART_HandleTypeDef *huart);
+void HAL_UART_MspDeInit(UART_HandleTypeDef *huart);
+
+/* Callbacks Register/UnRegister functions  ***********************************/
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+HAL_StatusTypeDef HAL_UART_RegisterCallback(UART_HandleTypeDef *huart, HAL_UART_CallbackIDTypeDef CallbackID,
+                                            pUART_CallbackTypeDef pCallback);
+HAL_StatusTypeDef HAL_UART_UnRegisterCallback(UART_HandleTypeDef *huart, HAL_UART_CallbackIDTypeDef CallbackID);
+
+HAL_StatusTypeDef HAL_UART_RegisterRxEventCallback(UART_HandleTypeDef *huart, pUART_RxEventCallbackTypeDef pCallback);
+HAL_StatusTypeDef HAL_UART_UnRegisterRxEventCallback(UART_HandleTypeDef *huart);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+
+/**
+  * @}
+  */
+
+/** @addtogroup UART_Exported_Functions_Group2 IO operation functions
+  * @{
+  */
+
+/* IO operation functions *****************************************************/
+HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size, uint32_t Timeout);
+HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout);
+HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size);
+HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);
+HAL_StatusTypeDef HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size);
+HAL_StatusTypeDef HAL_UART_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);
+HAL_StatusTypeDef HAL_UART_DMAPause(UART_HandleTypeDef *huart);
+HAL_StatusTypeDef HAL_UART_DMAResume(UART_HandleTypeDef *huart);
+HAL_StatusTypeDef HAL_UART_DMAStop(UART_HandleTypeDef *huart);
+/* Transfer Abort functions */
+HAL_StatusTypeDef HAL_UART_Abort(UART_HandleTypeDef *huart);
+HAL_StatusTypeDef HAL_UART_AbortTransmit(UART_HandleTypeDef *huart);
+HAL_StatusTypeDef HAL_UART_AbortReceive(UART_HandleTypeDef *huart);
+HAL_StatusTypeDef HAL_UART_Abort_IT(UART_HandleTypeDef *huart);
+HAL_StatusTypeDef HAL_UART_AbortTransmit_IT(UART_HandleTypeDef *huart);
+HAL_StatusTypeDef HAL_UART_AbortReceive_IT(UART_HandleTypeDef *huart);
+
+void HAL_UART_IRQHandler(UART_HandleTypeDef *huart);
+void HAL_UART_TxHalfCpltCallback(UART_HandleTypeDef *huart);
+void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart);
+void HAL_UART_RxHalfCpltCallback(UART_HandleTypeDef *huart);
+void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart);
+void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart);
+void HAL_UART_AbortCpltCallback(UART_HandleTypeDef *huart);
+void HAL_UART_AbortTransmitCpltCallback(UART_HandleTypeDef *huart);
+void HAL_UART_AbortReceiveCpltCallback(UART_HandleTypeDef *huart);
+
+void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size);
+
+/**
+  * @}
+  */
+
+/** @addtogroup UART_Exported_Functions_Group3 Peripheral Control functions
+  * @{
+  */
+
+/* Peripheral Control functions  ************************************************/
+void HAL_UART_ReceiverTimeout_Config(UART_HandleTypeDef *huart, uint32_t TimeoutValue);
+HAL_StatusTypeDef HAL_UART_EnableReceiverTimeout(UART_HandleTypeDef *huart);
+HAL_StatusTypeDef HAL_UART_DisableReceiverTimeout(UART_HandleTypeDef *huart);
+
+HAL_StatusTypeDef HAL_LIN_SendBreak(UART_HandleTypeDef *huart);
+HAL_StatusTypeDef HAL_MultiProcessor_EnableMuteMode(UART_HandleTypeDef *huart);
+HAL_StatusTypeDef HAL_MultiProcessor_DisableMuteMode(UART_HandleTypeDef *huart);
+void HAL_MultiProcessor_EnterMuteMode(UART_HandleTypeDef *huart);
+HAL_StatusTypeDef HAL_HalfDuplex_EnableTransmitter(UART_HandleTypeDef *huart);
+HAL_StatusTypeDef HAL_HalfDuplex_EnableReceiver(UART_HandleTypeDef *huart);
+
+/**
+  * @}
+  */
+
+/** @addtogroup UART_Exported_Functions_Group4 Peripheral State and Error functions
+  * @{
+  */
+
+/* Peripheral State and Errors functions  **************************************************/
+HAL_UART_StateTypeDef HAL_UART_GetState(const UART_HandleTypeDef *huart);
+uint32_t              HAL_UART_GetError(const UART_HandleTypeDef *huart);
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/* Private functions -----------------------------------------------------------*/
+/** @addtogroup UART_Private_Functions UART Private Functions
+  * @{
+  */
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+void              UART_InitCallbacksToDefault(UART_HandleTypeDef *huart);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+HAL_StatusTypeDef UART_SetConfig(UART_HandleTypeDef *huart);
+HAL_StatusTypeDef UART_CheckIdleState(UART_HandleTypeDef *huart);
+HAL_StatusTypeDef UART_WaitOnFlagUntilTimeout(UART_HandleTypeDef *huart, uint32_t Flag, FlagStatus Status,
+                                              uint32_t Tickstart, uint32_t Timeout);
+void              UART_AdvFeatureConfig(UART_HandleTypeDef *huart);
+HAL_StatusTypeDef UART_Start_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);
+HAL_StatusTypeDef UART_Start_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);
+
+/**
+  * @}
+  */
+
+/* Private variables -----------------------------------------------------------*/
+/** @defgroup UART_Private_variables UART Private variables
+  * @{
+  */
+/* Prescaler Table used in BRR computation macros.
+   Declared as extern here to allow use of private UART macros, outside of HAL UART functions */
+extern const uint16_t UARTPrescTable[12];
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* STM32G4xx_HAL_UART_H */
+
diff --git a/starter-projects/servo/p1-pwm/Drivers/STM32G4xx_HAL_Driver/Inc/stm32g4xx_hal_uart_ex.h b/starter-projects/servo/p1-pwm/Drivers/STM32G4xx_HAL_Driver/Inc/stm32g4xx_hal_uart_ex.h
new file mode 100644
index 0000000..910eb3a
--- /dev/null
+++ b/starter-projects/servo/p1-pwm/Drivers/STM32G4xx_HAL_Driver/Inc/stm32g4xx_hal_uart_ex.h
@@ -0,0 +1,929 @@
+/**
+  ******************************************************************************
+  * @file    stm32g4xx_hal_uart_ex.h
+  * @author  MCD Application Team
+  * @brief   Header file of UART HAL Extended module.
+  ******************************************************************************
+  * @attention
+  *
+  * Copyright (c) 2019 STMicroelectronics.
+  * All rights reserved.
+  *
+  * This software is licensed under terms that can be found in the LICENSE file
+  * in the root directory of this software component.
+  * If no LICENSE file comes with this software, it is provided AS-IS.
+  *
+  ******************************************************************************
+  */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef STM32G4xx_HAL_UART_EX_H
+#define STM32G4xx_HAL_UART_EX_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32g4xx_hal_def.h"
+
+/** @addtogroup STM32G4xx_HAL_Driver
+  * @{
+  */
+
+/** @addtogroup UARTEx
+  * @{
+  */
+
+/* Exported types ------------------------------------------------------------*/
+/** @defgroup UARTEx_Exported_Types UARTEx Exported Types
+  * @{
+  */
+
+/**
+  * @brief  UART wake up from stop mode parameters
+  */
+typedef struct
+{
+  uint32_t WakeUpEvent;        /*!< Specifies which event will activate the Wakeup from Stop mode flag (WUF).
+                                    This parameter can be a value of @ref UART_WakeUp_from_Stop_Selection.
+                                    If set to UART_WAKEUP_ON_ADDRESS, the two other fields below must
+                                    be filled up. */
+
+  uint16_t AddressLength;      /*!< Specifies whether the address is 4 or 7-bit long.
+                                    This parameter can be a value of @ref UARTEx_WakeUp_Address_Length.  */
+
+  uint8_t Address;             /*!< UART/USART node address (7-bit long max). */
+} UART_WakeUpTypeDef;
+
+/**
+  * @}
+  */
+
+/* Exported constants --------------------------------------------------------*/
+/** @defgroup UARTEx_Exported_Constants UARTEx Exported Constants
+  * @{
+  */
+
+/** @defgroup UARTEx_Word_Length UARTEx Word Length
+  * @{
+  */
+#define UART_WORDLENGTH_7B          USART_CR1_M1   /*!< 7-bit long UART frame */
+#define UART_WORDLENGTH_8B          0x00000000U    /*!< 8-bit long UART frame */
+#define UART_WORDLENGTH_9B          USART_CR1_M0   /*!< 9-bit long UART frame */
+/**
+  * @}
+  */
+
+/** @defgroup UARTEx_WakeUp_Address_Length UARTEx WakeUp Address Length
+  * @{
+  */
+#define UART_ADDRESS_DETECT_4B      0x00000000U      /*!< 4-bit long wake-up address */
+#define UART_ADDRESS_DETECT_7B      USART_CR2_ADDM7  /*!< 7-bit long wake-up address */
+/**
+  * @}
+  */
+
+/** @defgroup UARTEx_FIFO_mode UARTEx FIFO mode
+  * @brief    UART FIFO mode
+  * @{
+  */
+#define UART_FIFOMODE_DISABLE       0x00000000U       /*!< FIFO mode disable */
+#define UART_FIFOMODE_ENABLE        USART_CR1_FIFOEN  /*!< FIFO mode enable  */
+/**
+  * @}
+  */
+
+/** @defgroup UARTEx_TXFIFO_threshold_level UARTEx TXFIFO threshold level
+  * @brief    UART TXFIFO threshold level
+  * @{
+  */
+#define UART_TXFIFO_THRESHOLD_1_8   0x00000000U                               /*!< TX FIFO reaches 1/8 of its depth */
+#define UART_TXFIFO_THRESHOLD_1_4   USART_CR3_TXFTCFG_0                       /*!< TX FIFO reaches 1/4 of its depth */
+#define UART_TXFIFO_THRESHOLD_1_2   USART_CR3_TXFTCFG_1                       /*!< TX FIFO reaches 1/2 of its depth */
+#define UART_TXFIFO_THRESHOLD_3_4   (USART_CR3_TXFTCFG_0|USART_CR3_TXFTCFG_1) /*!< TX FIFO reaches 3/4 of its depth */
+#define UART_TXFIFO_THRESHOLD_7_8   USART_CR3_TXFTCFG_2                       /*!< TX FIFO reaches 7/8 of its depth */
+#define UART_TXFIFO_THRESHOLD_8_8   (USART_CR3_TXFTCFG_2|USART_CR3_TXFTCFG_0) /*!< TX FIFO becomes empty            */
+/**
+  * @}
+  */
+
+/** @defgroup UARTEx_RXFIFO_threshold_level UARTEx RXFIFO threshold level
+  * @brief    UART RXFIFO threshold level
+  * @{
+  */
+#define UART_RXFIFO_THRESHOLD_1_8   0x00000000U                               /*!< RX FIFO reaches 1/8 of its depth */
+#define UART_RXFIFO_THRESHOLD_1_4   USART_CR3_RXFTCFG_0                       /*!< RX FIFO reaches 1/4 of its depth */
+#define UART_RXFIFO_THRESHOLD_1_2   USART_CR3_RXFTCFG_1                       /*!< RX FIFO reaches 1/2 of its depth */
+#define UART_RXFIFO_THRESHOLD_3_4   (USART_CR3_RXFTCFG_0|USART_CR3_RXFTCFG_1) /*!< RX FIFO reaches 3/4 of its depth */
+#define UART_RXFIFO_THRESHOLD_7_8   USART_CR3_RXFTCFG_2                       /*!< RX FIFO reaches 7/8 of its depth */
+#define UART_RXFIFO_THRESHOLD_8_8   (USART_CR3_RXFTCFG_2|USART_CR3_RXFTCFG_0) /*!< RX FIFO becomes full             */
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/* Exported macros -----------------------------------------------------------*/
+/* Exported functions --------------------------------------------------------*/
+/** @addtogroup UARTEx_Exported_Functions
+  * @{
+  */
+
+/** @addtogroup UARTEx_Exported_Functions_Group1
+  * @{
+  */
+
+/* Initialization and de-initialization functions  ****************************/
+HAL_StatusTypeDef HAL_RS485Ex_Init(UART_HandleTypeDef *huart, uint32_t Polarity, uint32_t AssertionTime,
+                                   uint32_t DeassertionTime);
+
+/**
+  * @}
+  */
+
+/** @addtogroup UARTEx_Exported_Functions_Group2
+  * @{
+  */
+
+void HAL_UARTEx_WakeupCallback(UART_HandleTypeDef *huart);
+
+void HAL_UARTEx_RxFifoFullCallback(UART_HandleTypeDef *huart);
+void HAL_UARTEx_TxFifoEmptyCallback(UART_HandleTypeDef *huart);
+
+/**
+  * @}
+  */
+
+/** @addtogroup UARTEx_Exported_Functions_Group3
+  * @{
+  */
+
+/* Peripheral Control functions  **********************************************/
+HAL_StatusTypeDef HAL_UARTEx_StopModeWakeUpSourceConfig(UART_HandleTypeDef *huart, UART_WakeUpTypeDef WakeUpSelection);
+HAL_StatusTypeDef HAL_UARTEx_EnableStopMode(UART_HandleTypeDef *huart);
+HAL_StatusTypeDef HAL_UARTEx_DisableStopMode(UART_HandleTypeDef *huart);
+
+HAL_StatusTypeDef HAL_MultiProcessorEx_AddressLength_Set(UART_HandleTypeDef *huart, uint32_t AddressLength);
+
+HAL_StatusTypeDef HAL_UARTEx_EnableFifoMode(UART_HandleTypeDef *huart);
+HAL_StatusTypeDef HAL_UARTEx_DisableFifoMode(UART_HandleTypeDef *huart);
+HAL_StatusTypeDef HAL_UARTEx_SetTxFifoThreshold(UART_HandleTypeDef *huart, uint32_t Threshold);
+HAL_StatusTypeDef HAL_UARTEx_SetRxFifoThreshold(UART_HandleTypeDef *huart, uint32_t Threshold);
+
+HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint16_t *RxLen,
+                                           uint32_t Timeout);
+HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);
+HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);
+
+HAL_UART_RxEventTypeTypeDef HAL_UARTEx_GetRxEventType(const UART_HandleTypeDef *huart);
+
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/* Private macros ------------------------------------------------------------*/
+/** @defgroup UARTEx_Private_Macros UARTEx Private Macros
+  * @{
+  */
+
+/** @brief  Report the UART clock source.
+  * @param  __HANDLE__ specifies the UART Handle.
+  * @param  __CLOCKSOURCE__ output variable.
+  * @retval UART clocking source, written in __CLOCKSOURCE__.
+  */
+#if defined(UART5) && defined(USART3)
+#define UART_GETCLOCKSOURCE(__HANDLE__,__CLOCKSOURCE__)       \
+  do {                                                        \
+    if((__HANDLE__)->Instance == USART1)                      \
+    {                                                         \
+      switch(__HAL_RCC_GET_USART1_SOURCE())                   \
+      {                                                       \
+        case RCC_USART1CLKSOURCE_PCLK2:                       \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_PCLK2;         \
+          break;                                              \
+        case RCC_USART1CLKSOURCE_HSI:                         \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_HSI;           \
+          break;                                              \
+        case RCC_USART1CLKSOURCE_SYSCLK:                      \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_SYSCLK;        \
+          break;                                              \
+        case RCC_USART1CLKSOURCE_LSE:                         \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_LSE;           \
+          break;                                              \
+        default:                                              \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_UNDEFINED;     \
+          break;                                              \
+      }                                                       \
+    }                                                         \
+    else if((__HANDLE__)->Instance == USART2)                 \
+    {                                                         \
+      switch(__HAL_RCC_GET_USART2_SOURCE())                   \
+      {                                                       \
+        case RCC_USART2CLKSOURCE_PCLK1:                       \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_PCLK1;         \
+          break;                                              \
+        case RCC_USART2CLKSOURCE_HSI:                         \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_HSI;           \
+          break;                                              \
+        case RCC_USART2CLKSOURCE_SYSCLK:                      \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_SYSCLK;        \
+          break;                                              \
+        case RCC_USART2CLKSOURCE_LSE:                         \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_LSE;           \
+          break;                                              \
+        default:                                              \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_UNDEFINED;     \
+          break;                                              \
+      }                                                       \
+    }                                                         \
+    else if((__HANDLE__)->Instance == USART3)                 \
+    {                                                         \
+      switch(__HAL_RCC_GET_USART3_SOURCE())                   \
+      {                                                       \
+        case RCC_USART3CLKSOURCE_PCLK1:                       \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_PCLK1;         \
+          break;                                              \
+        case RCC_USART3CLKSOURCE_HSI:                         \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_HSI;           \
+          break;                                              \
+        case RCC_USART3CLKSOURCE_SYSCLK:                      \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_SYSCLK;        \
+          break;                                              \
+        case RCC_USART3CLKSOURCE_LSE:                         \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_LSE;           \
+          break;                                              \
+        default:                                              \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_UNDEFINED;     \
+          break;                                              \
+      }                                                       \
+    }                                                         \
+    else if((__HANDLE__)->Instance == UART4)                  \
+    {                                                         \
+      switch(__HAL_RCC_GET_UART4_SOURCE())                    \
+      {                                                       \
+        case RCC_UART4CLKSOURCE_PCLK1:                        \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_PCLK1;         \
+          break;                                              \
+        case RCC_UART4CLKSOURCE_HSI:                          \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_HSI;           \
+          break;                                              \
+        case RCC_UART4CLKSOURCE_SYSCLK:                       \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_SYSCLK;        \
+          break;                                              \
+        case RCC_UART4CLKSOURCE_LSE:                          \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_LSE;           \
+          break;                                              \
+        default:                                              \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_UNDEFINED;     \
+          break;                                              \
+      }                                                       \
+    }                                                         \
+    else if((__HANDLE__)->Instance == UART5)                  \
+    {                                                         \
+      switch(__HAL_RCC_GET_UART5_SOURCE())                    \
+      {                                                       \
+        case RCC_UART5CLKSOURCE_PCLK1:                        \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_PCLK1;         \
+          break;                                              \
+        case RCC_UART5CLKSOURCE_HSI:                          \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_HSI;           \
+          break;                                              \
+        case RCC_UART5CLKSOURCE_SYSCLK:                       \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_SYSCLK;        \
+          break;                                              \
+        case RCC_UART5CLKSOURCE_LSE:                          \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_LSE;           \
+          break;                                              \
+        default:                                              \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_UNDEFINED;     \
+          break;                                              \
+      }                                                       \
+    }                                                         \
+    else if((__HANDLE__)->Instance == LPUART1)                \
+    {                                                         \
+      switch(__HAL_RCC_GET_LPUART1_SOURCE())                  \
+      {                                                       \
+        case RCC_LPUART1CLKSOURCE_PCLK1:                      \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_PCLK1;         \
+          break;                                              \
+        case RCC_LPUART1CLKSOURCE_HSI:                        \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_HSI;           \
+          break;                                              \
+        case RCC_LPUART1CLKSOURCE_SYSCLK:                     \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_SYSCLK;        \
+          break;                                              \
+        case RCC_LPUART1CLKSOURCE_LSE:                        \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_LSE;           \
+          break;                                              \
+        default:                                              \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_UNDEFINED;     \
+          break;                                              \
+      }                                                       \
+    }                                                         \
+    else                                                      \
+    {                                                         \
+      (__CLOCKSOURCE__) = UART_CLOCKSOURCE_UNDEFINED;         \
+    }                                                         \
+  } while(0U)
+#elif defined(UART5) && !defined(USART3)
+#define UART_GETCLOCKSOURCE(__HANDLE__,__CLOCKSOURCE__)       \
+  do {                                                        \
+    if((__HANDLE__)->Instance == USART1)                      \
+    {                                                         \
+      switch(__HAL_RCC_GET_USART1_SOURCE())                   \
+      {                                                       \
+        case RCC_USART1CLKSOURCE_PCLK2:                       \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_PCLK2;         \
+          break;                                              \
+        case RCC_USART1CLKSOURCE_HSI:                         \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_HSI;           \
+          break;                                              \
+        case RCC_USART1CLKSOURCE_SYSCLK:                      \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_SYSCLK;        \
+          break;                                              \
+        case RCC_USART1CLKSOURCE_LSE:                         \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_LSE;           \
+          break;                                              \
+        default:                                              \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_UNDEFINED;     \
+          break;                                              \
+      }                                                       \
+    }                                                         \
+    else if((__HANDLE__)->Instance == USART2)                 \
+    {                                                         \
+      switch(__HAL_RCC_GET_USART2_SOURCE())                   \
+      {                                                       \
+        case RCC_USART2CLKSOURCE_PCLK1:                       \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_PCLK1;         \
+          break;                                              \
+        case RCC_USART2CLKSOURCE_HSI:                         \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_HSI;           \
+          break;                                              \
+        case RCC_USART2CLKSOURCE_SYSCLK:                      \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_SYSCLK;        \
+          break;                                              \
+        case RCC_USART2CLKSOURCE_LSE:                         \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_LSE;           \
+          break;                                              \
+        default:                                              \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_UNDEFINED;     \
+          break;                                              \
+      }                                                       \
+    }                                                         \
+    else if((__HANDLE__)->Instance == UART4)                  \
+    {                                                         \
+      switch(__HAL_RCC_GET_UART4_SOURCE())                    \
+      {                                                       \
+        case RCC_UART4CLKSOURCE_PCLK1:                        \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_PCLK1;         \
+          break;                                              \
+        case RCC_UART4CLKSOURCE_HSI:                          \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_HSI;           \
+          break;                                              \
+        case RCC_UART4CLKSOURCE_SYSCLK:                       \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_SYSCLK;        \
+          break;                                              \
+        case RCC_UART4CLKSOURCE_LSE:                          \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_LSE;           \
+          break;                                              \
+        default:                                              \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_UNDEFINED;     \
+          break;                                              \
+      }                                                       \
+    }                                                         \
+    else if((__HANDLE__)->Instance == UART5)                  \
+    {                                                         \
+      switch(__HAL_RCC_GET_UART5_SOURCE())                    \
+      {                                                       \
+        case RCC_UART5CLKSOURCE_PCLK1:                        \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_PCLK1;         \
+          break;                                              \
+        case RCC_UART5CLKSOURCE_HSI:                          \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_HSI;           \
+          break;                                              \
+        case RCC_UART5CLKSOURCE_SYSCLK:                       \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_SYSCLK;        \
+          break;                                              \
+        case RCC_UART5CLKSOURCE_LSE:                          \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_LSE;           \
+          break;                                              \
+        default:                                              \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_UNDEFINED;     \
+          break;                                              \
+      }                                                       \
+    }                                                         \
+    else if((__HANDLE__)->Instance == LPUART1)                \
+    {                                                         \
+      switch(__HAL_RCC_GET_LPUART1_SOURCE())                  \
+      {                                                       \
+        case RCC_LPUART1CLKSOURCE_PCLK1:                      \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_PCLK1;         \
+          break;                                              \
+        case RCC_LPUART1CLKSOURCE_HSI:                        \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_HSI;           \
+          break;                                              \
+        case RCC_LPUART1CLKSOURCE_SYSCLK:                     \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_SYSCLK;        \
+          break;                                              \
+        case RCC_LPUART1CLKSOURCE_LSE:                        \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_LSE;           \
+          break;                                              \
+        default:                                              \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_UNDEFINED;     \
+          break;                                              \
+      }                                                       \
+    }                                                         \
+    else                                                      \
+    {                                                         \
+      (__CLOCKSOURCE__) = UART_CLOCKSOURCE_UNDEFINED;         \
+    }                                                         \
+  } while(0U)
+#elif defined(UART4) && defined(USART3)
+#define UART_GETCLOCKSOURCE(__HANDLE__,__CLOCKSOURCE__)       \
+  do {                                                        \
+    if((__HANDLE__)->Instance == USART1)                      \
+    {                                                         \
+      switch(__HAL_RCC_GET_USART1_SOURCE())                   \
+      {                                                       \
+        case RCC_USART1CLKSOURCE_PCLK2:                       \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_PCLK2;         \
+          break;                                              \
+        case RCC_USART1CLKSOURCE_HSI:                         \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_HSI;           \
+          break;                                              \
+        case RCC_USART1CLKSOURCE_SYSCLK:                      \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_SYSCLK;        \
+          break;                                              \
+        case RCC_USART1CLKSOURCE_LSE:                         \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_LSE;           \
+          break;                                              \
+        default:                                              \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_UNDEFINED;     \
+          break;                                              \
+      }                                                       \
+    }                                                         \
+    else if((__HANDLE__)->Instance == USART2)                 \
+    {                                                         \
+      switch(__HAL_RCC_GET_USART2_SOURCE())                   \
+      {                                                       \
+        case RCC_USART2CLKSOURCE_PCLK1:                       \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_PCLK1;         \
+          break;                                              \
+        case RCC_USART2CLKSOURCE_HSI:                         \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_HSI;           \
+          break;                                              \
+        case RCC_USART2CLKSOURCE_SYSCLK:                      \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_SYSCLK;        \
+          break;                                              \
+        case RCC_USART2CLKSOURCE_LSE:                         \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_LSE;           \
+          break;                                              \
+        default:                                              \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_UNDEFINED;     \
+          break;                                              \
+      }                                                       \
+    }                                                         \
+    else if((__HANDLE__)->Instance == USART3)                 \
+    {                                                         \
+      switch(__HAL_RCC_GET_USART3_SOURCE())                   \
+      {                                                       \
+        case RCC_USART3CLKSOURCE_PCLK1:                       \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_PCLK1;         \
+          break;                                              \
+        case RCC_USART3CLKSOURCE_HSI:                         \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_HSI;           \
+          break;                                              \
+        case RCC_USART3CLKSOURCE_SYSCLK:                      \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_SYSCLK;        \
+          break;                                              \
+        case RCC_USART3CLKSOURCE_LSE:                         \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_LSE;           \
+          break;                                              \
+        default:                                              \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_UNDEFINED;     \
+          break;                                              \
+      }                                                       \
+    }                                                         \
+    else if((__HANDLE__)->Instance == UART4)                  \
+    {                                                         \
+      switch(__HAL_RCC_GET_UART4_SOURCE())                    \
+      {                                                       \
+        case RCC_UART4CLKSOURCE_PCLK1:                        \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_PCLK1;         \
+          break;                                              \
+        case RCC_UART4CLKSOURCE_HSI:                          \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_HSI;           \
+          break;                                              \
+        case RCC_UART4CLKSOURCE_SYSCLK:                       \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_SYSCLK;        \
+          break;                                              \
+        case RCC_UART4CLKSOURCE_LSE:                          \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_LSE;           \
+          break;                                              \
+        default:                                              \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_UNDEFINED;     \
+          break;                                              \
+      }                                                       \
+    }                                                         \
+    else if((__HANDLE__)->Instance == LPUART1)                \
+    {                                                         \
+      switch(__HAL_RCC_GET_LPUART1_SOURCE())                  \
+      {                                                       \
+        case RCC_LPUART1CLKSOURCE_PCLK1:                      \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_PCLK1;         \
+          break;                                              \
+        case RCC_LPUART1CLKSOURCE_HSI:                        \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_HSI;           \
+          break;                                              \
+        case RCC_LPUART1CLKSOURCE_SYSCLK:                     \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_SYSCLK;        \
+          break;                                              \
+        case RCC_LPUART1CLKSOURCE_LSE:                        \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_LSE;           \
+          break;                                              \
+        default:                                              \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_UNDEFINED;     \
+          break;                                              \
+      }                                                       \
+    }                                                         \
+    else                                                      \
+    {                                                         \
+      (__CLOCKSOURCE__) = UART_CLOCKSOURCE_UNDEFINED;         \
+    }                                                         \
+  } while(0U)
+#elif defined(UART4) && !defined(USART3)
+#define UART_GETCLOCKSOURCE(__HANDLE__,__CLOCKSOURCE__)       \
+  do {                                                        \
+    if((__HANDLE__)->Instance == USART1)                      \
+    {                                                         \
+      switch(__HAL_RCC_GET_USART1_SOURCE())                   \
+      {                                                       \
+        case RCC_USART1CLKSOURCE_PCLK2:                       \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_PCLK2;         \
+          break;                                              \
+        case RCC_USART1CLKSOURCE_HSI:                         \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_HSI;           \
+          break;                                              \
+        case RCC_USART1CLKSOURCE_SYSCLK:                      \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_SYSCLK;        \
+          break;                                              \
+        case RCC_USART1CLKSOURCE_LSE:                         \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_LSE;           \
+          break;                                              \
+        default:                                              \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_UNDEFINED;     \
+          break;                                              \
+      }                                                       \
+    }                                                         \
+    else if((__HANDLE__)->Instance == USART2)                 \
+    {                                                         \
+      switch(__HAL_RCC_GET_USART2_SOURCE())                   \
+      {                                                       \
+        case RCC_USART2CLKSOURCE_PCLK1:                       \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_PCLK1;         \
+          break;                                              \
+        case RCC_USART2CLKSOURCE_HSI:                         \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_HSI;           \
+          break;                                              \
+        case RCC_USART2CLKSOURCE_SYSCLK:                      \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_SYSCLK;        \
+          break;                                              \
+        case RCC_USART2CLKSOURCE_LSE:                         \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_LSE;           \
+          break;                                              \
+        default:                                              \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_UNDEFINED;     \
+          break;                                              \
+      }                                                       \
+    }                                                         \
+    else if((__HANDLE__)->Instance == UART4)                  \
+    {                                                         \
+      switch(__HAL_RCC_GET_UART4_SOURCE())                    \
+      {                                                       \
+        case RCC_UART4CLKSOURCE_PCLK1:                        \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_PCLK1;         \
+          break;                                              \
+        case RCC_UART4CLKSOURCE_HSI:                          \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_HSI;           \
+          break;                                              \
+        case RCC_UART4CLKSOURCE_SYSCLK:                       \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_SYSCLK;        \
+          break;                                              \
+        case RCC_UART4CLKSOURCE_LSE:                          \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_LSE;           \
+          break;                                              \
+        default:                                              \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_UNDEFINED;     \
+          break;                                              \
+      }                                                       \
+    }                                                         \
+    else if((__HANDLE__)->Instance == LPUART1)                \
+    {                                                         \
+      switch(__HAL_RCC_GET_LPUART1_SOURCE())                  \
+      {                                                       \
+        case RCC_LPUART1CLKSOURCE_PCLK1:                      \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_PCLK1;         \
+          break;                                              \
+        case RCC_LPUART1CLKSOURCE_HSI:                        \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_HSI;           \
+          break;                                              \
+        case RCC_LPUART1CLKSOURCE_SYSCLK:                     \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_SYSCLK;        \
+          break;                                              \
+        case RCC_LPUART1CLKSOURCE_LSE:                        \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_LSE;           \
+          break;                                              \
+        default:                                              \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_UNDEFINED;     \
+          break;                                              \
+      }                                                       \
+    }                                                         \
+    else                                                      \
+    {                                                         \
+      (__CLOCKSOURCE__) = UART_CLOCKSOURCE_UNDEFINED;         \
+    }                                                         \
+  } while(0U)
+#elif defined(USART3)
+#define UART_GETCLOCKSOURCE(__HANDLE__,__CLOCKSOURCE__)       \
+  do {                                                        \
+    if((__HANDLE__)->Instance == USART1)                      \
+    {                                                         \
+      switch(__HAL_RCC_GET_USART1_SOURCE())                   \
+      {                                                       \
+        case RCC_USART1CLKSOURCE_PCLK2:                       \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_PCLK2;         \
+          break;                                              \
+        case RCC_USART1CLKSOURCE_HSI:                         \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_HSI;           \
+          break;                                              \
+        case RCC_USART1CLKSOURCE_SYSCLK:                      \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_SYSCLK;        \
+          break;                                              \
+        case RCC_USART1CLKSOURCE_LSE:                         \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_LSE;           \
+          break;                                              \
+        default:                                              \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_UNDEFINED;     \
+          break;                                              \
+      }                                                       \
+    }                                                         \
+    else if((__HANDLE__)->Instance == USART2)                 \
+    {                                                         \
+      switch(__HAL_RCC_GET_USART2_SOURCE())                   \
+      {                                                       \
+        case RCC_USART2CLKSOURCE_PCLK1:                       \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_PCLK1;         \
+          break;                                              \
+        case RCC_USART2CLKSOURCE_HSI:                         \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_HSI;           \
+          break;                                              \
+        case RCC_USART2CLKSOURCE_SYSCLK:                      \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_SYSCLK;        \
+          break;                                              \
+        case RCC_USART2CLKSOURCE_LSE:                         \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_LSE;           \
+          break;                                              \
+        default:                                              \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_UNDEFINED;     \
+          break;                                              \
+      }                                                       \
+    }                                                         \
+    else if((__HANDLE__)->Instance == USART3)                 \
+    {                                                         \
+      switch(__HAL_RCC_GET_USART3_SOURCE())                   \
+      {                                                       \
+        case RCC_USART3CLKSOURCE_PCLK1:                       \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_PCLK1;         \
+          break;                                              \
+        case RCC_USART3CLKSOURCE_HSI:                         \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_HSI;           \
+          break;                                              \
+        case RCC_USART3CLKSOURCE_SYSCLK:                      \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_SYSCLK;        \
+          break;                                              \
+        case RCC_USART3CLKSOURCE_LSE:                         \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_LSE;           \
+          break;                                              \
+        default:                                              \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_UNDEFINED;     \
+          break;                                              \
+      }                                                       \
+    }                                                         \
+    else if((__HANDLE__)->Instance == LPUART1)                \
+    {                                                         \
+      switch(__HAL_RCC_GET_LPUART1_SOURCE())                  \
+      {                                                       \
+        case RCC_LPUART1CLKSOURCE_PCLK1:                      \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_PCLK1;         \
+          break;                                              \
+        case RCC_LPUART1CLKSOURCE_HSI:                        \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_HSI;           \
+          break;                                              \
+        case RCC_LPUART1CLKSOURCE_SYSCLK:                     \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_SYSCLK;        \
+          break;                                              \
+        case RCC_LPUART1CLKSOURCE_LSE:                        \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_LSE;           \
+          break;                                              \
+        default:                                              \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_UNDEFINED;     \
+          break;                                              \
+      }                                                       \
+    }                                                         \
+    else                                                      \
+    {                                                         \
+      (__CLOCKSOURCE__) = UART_CLOCKSOURCE_UNDEFINED;         \
+    }                                                         \
+  } while(0U)
+#else
+#define UART_GETCLOCKSOURCE(__HANDLE__,__CLOCKSOURCE__)       \
+  do {                                                        \
+    if((__HANDLE__)->Instance == USART1)                      \
+    {                                                         \
+      switch(__HAL_RCC_GET_USART1_SOURCE())                   \
+      {                                                       \
+        case RCC_USART1CLKSOURCE_PCLK2:                       \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_PCLK2;         \
+          break;                                              \
+        case RCC_USART1CLKSOURCE_HSI:                         \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_HSI;           \
+          break;                                              \
+        case RCC_USART1CLKSOURCE_SYSCLK:                      \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_SYSCLK;        \
+          break;                                              \
+        case RCC_USART1CLKSOURCE_LSE:                         \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_LSE;           \
+          break;                                              \
+        default:                                              \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_UNDEFINED;     \
+          break;                                              \
+      }                                                       \
+    }                                                         \
+    else if((__HANDLE__)->Instance == USART2)                 \
+    {                                                         \
+      switch(__HAL_RCC_GET_USART2_SOURCE())                   \
+      {                                                       \
+        case RCC_USART2CLKSOURCE_PCLK1:                       \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_PCLK1;         \
+          break;                                              \
+        case RCC_USART2CLKSOURCE_HSI:                         \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_HSI;           \
+          break;                                              \
+        case RCC_USART2CLKSOURCE_SYSCLK:                      \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_SYSCLK;        \
+          break;                                              \
+        case RCC_USART2CLKSOURCE_LSE:                         \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_LSE;           \
+          break;                                              \
+        default:                                              \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_UNDEFINED;     \
+          break;                                              \
+      }                                                       \
+    }                                                         \
+    else if((__HANDLE__)->Instance == LPUART1)                \
+    {                                                         \
+      switch(__HAL_RCC_GET_LPUART1_SOURCE())                  \
+      {                                                       \
+        case RCC_LPUART1CLKSOURCE_PCLK1:                      \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_PCLK1;         \
+          break;                                              \
+        case RCC_LPUART1CLKSOURCE_HSI:                        \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_HSI;           \
+          break;                                              \
+        case RCC_LPUART1CLKSOURCE_SYSCLK:                     \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_SYSCLK;        \
+          break;                                              \
+        case RCC_LPUART1CLKSOURCE_LSE:                        \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_LSE;           \
+          break;                                              \
+        default:                                              \
+          (__CLOCKSOURCE__) = UART_CLOCKSOURCE_UNDEFINED;     \
+          break;                                              \
+      }                                                       \
+    }                                                         \
+    else                                                      \
+    {                                                         \
+      (__CLOCKSOURCE__) = UART_CLOCKSOURCE_UNDEFINED;         \
+    }                                                         \
+  } while(0U)
+#endif /* UART5 && !USART3 */
+
+/** @brief  Report the UART mask to apply to retrieve the received data
+  *         according to the word length and to the parity bits activation.
+  * @note   If PCE = 1, the parity bit is not included in the data extracted
+  *         by the reception API().
+  *         This masking operation is not carried out in the case of
+  *         DMA transfers.
+  * @param  __HANDLE__ specifies the UART Handle.
+  * @retval None, the mask to apply to UART RDR register is stored in (__HANDLE__)->Mask field.
+  */
+#define UART_MASK_COMPUTATION(__HANDLE__)                             \
+  do {                                                                \
+    if ((__HANDLE__)->Init.WordLength == UART_WORDLENGTH_9B)          \
+    {                                                                 \
+      if ((__HANDLE__)->Init.Parity == UART_PARITY_NONE)              \
+      {                                                               \
+        (__HANDLE__)->Mask = 0x01FFU ;                                \
+      }                                                               \
+      else                                                            \
+      {                                                               \
+        (__HANDLE__)->Mask = 0x00FFU ;                                \
+      }                                                               \
+    }                                                                 \
+    else if ((__HANDLE__)->Init.WordLength == UART_WORDLENGTH_8B)     \
+    {                                                                 \
+      if ((__HANDLE__)->Init.Parity == UART_PARITY_NONE)              \
+      {                                                               \
+        (__HANDLE__)->Mask = 0x00FFU ;                                \
+      }                                                               \
+      else                                                            \
+      {                                                               \
+        (__HANDLE__)->Mask = 0x007FU ;                                \
+      }                                                               \
+    }                                                                 \
+    else if ((__HANDLE__)->Init.WordLength == UART_WORDLENGTH_7B)     \
+    {                                                                 \
+      if ((__HANDLE__)->Init.Parity == UART_PARITY_NONE)              \
+      {                                                               \
+        (__HANDLE__)->Mask = 0x007FU ;                                \
+      }                                                               \
+      else                                                            \
+      {                                                               \
+        (__HANDLE__)->Mask = 0x003FU ;                                \
+      }                                                               \
+    }                                                                 \
+    else                                                              \
+    {                                                                 \
+      (__HANDLE__)->Mask = 0x0000U;                                   \
+    }                                                                 \
+  } while(0U)
+
+/**
+  * @brief Ensure that UART frame length is valid.
+  * @param __LENGTH__ UART frame length.
+  * @retval SET (__LENGTH__ is valid) or RESET (__LENGTH__ is invalid)
+  */
+#define IS_UART_WORD_LENGTH(__LENGTH__) (((__LENGTH__) == UART_WORDLENGTH_7B) || \
+                                         ((__LENGTH__) == UART_WORDLENGTH_8B) || \
+                                         ((__LENGTH__) == UART_WORDLENGTH_9B))
+
+/**
+  * @brief Ensure that UART wake-up address length is valid.
+  * @param __ADDRESS__ UART wake-up address length.
+  * @retval SET (__ADDRESS__ is valid) or RESET (__ADDRESS__ is invalid)
+  */
+#define IS_UART_ADDRESSLENGTH_DETECT(__ADDRESS__) (((__ADDRESS__) == UART_ADDRESS_DETECT_4B) || \
+                                                   ((__ADDRESS__) == UART_ADDRESS_DETECT_7B))
+
+/**
+  * @brief Ensure that UART TXFIFO threshold level is valid.
+  * @param __THRESHOLD__ UART TXFIFO threshold level.
+  * @retval SET (__THRESHOLD__ is valid) or RESET (__THRESHOLD__ is invalid)
+  */
+#define IS_UART_TXFIFO_THRESHOLD(__THRESHOLD__) (((__THRESHOLD__) == UART_TXFIFO_THRESHOLD_1_8) || \
+                                                 ((__THRESHOLD__) == UART_TXFIFO_THRESHOLD_1_4) || \
+                                                 ((__THRESHOLD__) == UART_TXFIFO_THRESHOLD_1_2) || \
+                                                 ((__THRESHOLD__) == UART_TXFIFO_THRESHOLD_3_4) || \
+                                                 ((__THRESHOLD__) == UART_TXFIFO_THRESHOLD_7_8) || \
+                                                 ((__THRESHOLD__) == UART_TXFIFO_THRESHOLD_8_8))
+
+/**
+  * @brief Ensure that UART RXFIFO threshold level is valid.
+  * @param __THRESHOLD__ UART RXFIFO threshold level.
+  * @retval SET (__THRESHOLD__ is valid) or RESET (__THRESHOLD__ is invalid)
+  */
+#define IS_UART_RXFIFO_THRESHOLD(__THRESHOLD__) (((__THRESHOLD__) == UART_RXFIFO_THRESHOLD_1_8) || \
+                                                 ((__THRESHOLD__) == UART_RXFIFO_THRESHOLD_1_4) || \
+                                                 ((__THRESHOLD__) == UART_RXFIFO_THRESHOLD_1_2) || \
+                                                 ((__THRESHOLD__) == UART_RXFIFO_THRESHOLD_3_4) || \
+                                                 ((__THRESHOLD__) == UART_RXFIFO_THRESHOLD_7_8) || \
+                                                 ((__THRESHOLD__) == UART_RXFIFO_THRESHOLD_8_8))
+
+/**
+  * @}
+  */
+
+/* Private functions ---------------------------------------------------------*/
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* STM32G4xx_HAL_UART_EX_H */
+
diff --git a/starter-projects/servo/p1-pwm/Drivers/STM32G4xx_HAL_Driver/Inc/stm32g4xx_hal_usart.h b/starter-projects/servo/p1-pwm/Drivers/STM32G4xx_HAL_Driver/Inc/stm32g4xx_hal_usart.h
new file mode 100644
index 0000000..234aa96
--- /dev/null
+++ b/starter-projects/servo/p1-pwm/Drivers/STM32G4xx_HAL_Driver/Inc/stm32g4xx_hal_usart.h
@@ -0,0 +1,1036 @@
+/**
+  ******************************************************************************
+  * @file    stm32g4xx_hal_usart.h
+  * @author  MCD Application Team
+  * @brief   Header file of USART HAL module.
+  ******************************************************************************
+  * @attention
+  *
+  * Copyright (c) 2019 STMicroelectronics.
+  * All rights reserved.
+  *
+  * This software is licensed under terms that can be found in the LICENSE file
+  * in the root directory of this software component.
+  * If no LICENSE file comes with this software, it is provided AS-IS.
+  *
+  ******************************************************************************
+  */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef STM32G4xx_HAL_USART_H
+#define STM32G4xx_HAL_USART_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32g4xx_hal_def.h"
+
+/** @addtogroup STM32G4xx_HAL_Driver
+  * @{
+  */
+
+/** @addtogroup USART
+  * @{
+  */
+
+/* Exported types ------------------------------------------------------------*/
+/** @defgroup USART_Exported_Types USART Exported Types
+  * @{
+  */
+
+/**
+  * @brief USART Init Structure definition
+  */
+typedef struct
+{
+  uint32_t BaudRate;                  /*!< This member configures the Usart communication baud rate.
+                                           The baud rate is computed using the following formula:
+                                              Baud Rate Register[15:4] = ((2 * fclk_pres) /
+                                              ((huart->Init.BaudRate)))[15:4]
+                                              Baud Rate Register[3]    = 0
+                                              Baud Rate Register[2:0]  =  (((2 * fclk_pres) /
+                                              ((huart->Init.BaudRate)))[3:0]) >> 1
+                                              where fclk_pres is the USART input clock frequency (fclk)
+                                              divided by a prescaler.
+                                           @note  Oversampling by 8 is systematically applied to
+                                                  achieve high baud rates. */
+
+  uint32_t WordLength;                /*!< Specifies the number of data bits transmitted or received in a frame.
+                                           This parameter can be a value of @ref USARTEx_Word_Length. */
+
+  uint32_t StopBits;                  /*!< Specifies the number of stop bits transmitted.
+                                           This parameter can be a value of @ref USART_Stop_Bits. */
+
+  uint32_t Parity;                   /*!< Specifies the parity mode.
+                                           This parameter can be a value of @ref USART_Parity
+                                           @note When parity is enabled, the computed parity is inserted
+                                                 at the MSB position of the transmitted data (9th bit when
+                                                 the word length is set to 9 data bits; 8th bit when the
+                                                 word length is set to 8 data bits). */
+
+  uint32_t Mode;                      /*!< Specifies whether the Receive or Transmit mode is enabled or disabled.
+                                           This parameter can be a value of @ref USART_Mode. */
+
+  uint32_t CLKPolarity;               /*!< Specifies the steady state of the serial clock.
+                                           This parameter can be a value of @ref USART_Clock_Polarity. */
+
+  uint32_t CLKPhase;                  /*!< Specifies the clock transition on which the bit capture is made.
+                                           This parameter can be a value of @ref USART_Clock_Phase. */
+
+  uint32_t CLKLastBit;                /*!< Specifies whether the clock pulse corresponding to the last transmitted
+                                           data bit (MSB) has to be output on the SCLK pin in synchronous mode.
+                                           This parameter can be a value of @ref USART_Last_Bit. */
+
+  uint32_t ClockPrescaler;            /*!< Specifies the prescaler value used to divide the USART clock source.
+                                           This parameter can be a value of @ref USART_ClockPrescaler. */
+} USART_InitTypeDef;
+
+/**
+  * @brief HAL USART State structures definition
+  */
+typedef enum
+{
+  HAL_USART_STATE_RESET             = 0x00U,    /*!< Peripheral is not initialized                  */
+  HAL_USART_STATE_READY             = 0x01U,    /*!< Peripheral Initialized and ready for use       */
+  HAL_USART_STATE_BUSY              = 0x02U,    /*!< an internal process is ongoing                 */
+  HAL_USART_STATE_BUSY_TX           = 0x12U,    /*!< Data Transmission process is ongoing           */
+  HAL_USART_STATE_BUSY_RX           = 0x22U,    /*!< Data Reception process is ongoing              */
+  HAL_USART_STATE_BUSY_TX_RX        = 0x32U,    /*!< Data Transmission Reception process is ongoing */
+  HAL_USART_STATE_TIMEOUT           = 0x03U,    /*!< Timeout state                                  */
+  HAL_USART_STATE_ERROR             = 0x04U     /*!< Error                                          */
+} HAL_USART_StateTypeDef;
+
+/**
+  * @brief  USART clock sources definitions
+  */
+typedef enum
+{
+  USART_CLOCKSOURCE_PCLK1      = 0x00U,    /*!< PCLK1 clock source     */
+  USART_CLOCKSOURCE_PCLK2      = 0x01U,    /*!< PCLK2 clock source     */
+  USART_CLOCKSOURCE_HSI        = 0x02U,    /*!< HSI clock source       */
+  USART_CLOCKSOURCE_SYSCLK     = 0x04U,    /*!< SYSCLK clock source    */
+  USART_CLOCKSOURCE_LSE        = 0x08U,    /*!< LSE clock source       */
+  USART_CLOCKSOURCE_UNDEFINED  = 0x10U     /*!< Undefined clock source */
+} USART_ClockSourceTypeDef;
+
+/**
+  * @brief  USART handle Structure definition
+  */
+typedef struct __USART_HandleTypeDef
+{
+  USART_TypeDef                 *Instance;               /*!< USART registers base address        */
+
+  USART_InitTypeDef             Init;                    /*!< USART communication parameters      */
+
+  const uint8_t                 *pTxBuffPtr;             /*!< Pointer to USART Tx transfer Buffer */
+
+  uint16_t                      TxXferSize;              /*!< USART Tx Transfer size              */
+
+  __IO uint16_t                 TxXferCount;             /*!< USART Tx Transfer Counter           */
+
+  uint8_t                       *pRxBuffPtr;             /*!< Pointer to USART Rx transfer Buffer */
+
+  uint16_t                      RxXferSize;              /*!< USART Rx Transfer size              */
+
+  __IO uint16_t                 RxXferCount;             /*!< USART Rx Transfer Counter           */
+
+  uint16_t                      Mask;                    /*!< USART Rx RDR register mask          */
+
+  uint16_t                      NbRxDataToProcess;       /*!< Number of data to process during RX ISR execution */
+
+  uint16_t                      NbTxDataToProcess;       /*!< Number of data to process during TX ISR execution */
+
+  uint32_t                      SlaveMode;               /*!< Enable/Disable USART SPI Slave Mode. This parameter can be a value
+                                                              of @ref USARTEx_Slave_Mode */
+
+  uint32_t                      FifoMode;                /*!< Specifies if the FIFO mode will be used. This parameter can be a value
+                                                              of @ref USARTEx_FIFO_mode. */
+
+  void (*RxISR)(struct __USART_HandleTypeDef *husart);   /*!< Function pointer on Rx IRQ handler  */
+
+  void (*TxISR)(struct __USART_HandleTypeDef *husart);   /*!< Function pointer on Tx IRQ handler  */
+
+  DMA_HandleTypeDef             *hdmatx;                 /*!< USART Tx DMA Handle parameters      */
+
+  DMA_HandleTypeDef             *hdmarx;                 /*!< USART Rx DMA Handle parameters      */
+
+  HAL_LockTypeDef               Lock;                    /*!< Locking object                      */
+
+  __IO HAL_USART_StateTypeDef   State;                   /*!< USART communication state           */
+
+  __IO uint32_t                 ErrorCode;               /*!< USART Error code                    */
+
+#if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
+  void (* TxHalfCpltCallback)(struct __USART_HandleTypeDef *husart);        /*!< USART Tx Half Complete Callback        */
+  void (* TxCpltCallback)(struct __USART_HandleTypeDef *husart);            /*!< USART Tx Complete Callback             */
+  void (* RxHalfCpltCallback)(struct __USART_HandleTypeDef *husart);        /*!< USART Rx Half Complete Callback        */
+  void (* RxCpltCallback)(struct __USART_HandleTypeDef *husart);            /*!< USART Rx Complete Callback             */
+  void (* TxRxCpltCallback)(struct __USART_HandleTypeDef *husart);          /*!< USART Tx Rx Complete Callback          */
+  void (* ErrorCallback)(struct __USART_HandleTypeDef *husart);             /*!< USART Error Callback                   */
+  void (* AbortCpltCallback)(struct __USART_HandleTypeDef *husart);         /*!< USART Abort Complete Callback          */
+  void (* RxFifoFullCallback)(struct __USART_HandleTypeDef *husart);        /*!< USART Rx Fifo Full Callback            */
+  void (* TxFifoEmptyCallback)(struct __USART_HandleTypeDef *husart);       /*!< USART Tx Fifo Empty Callback           */
+
+  void (* MspInitCallback)(struct __USART_HandleTypeDef *husart);           /*!< USART Msp Init callback                */
+  void (* MspDeInitCallback)(struct __USART_HandleTypeDef *husart);         /*!< USART Msp DeInit callback              */
+#endif  /* USE_HAL_USART_REGISTER_CALLBACKS */
+
+} USART_HandleTypeDef;
+
+#if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
+/**
+  * @brief  HAL USART Callback ID enumeration definition
+  */
+typedef enum
+{
+  HAL_USART_TX_HALFCOMPLETE_CB_ID         = 0x00U,    /*!< USART Tx Half Complete Callback ID        */
+  HAL_USART_TX_COMPLETE_CB_ID             = 0x01U,    /*!< USART Tx Complete Callback ID             */
+  HAL_USART_RX_HALFCOMPLETE_CB_ID         = 0x02U,    /*!< USART Rx Half Complete Callback ID        */
+  HAL_USART_RX_COMPLETE_CB_ID             = 0x03U,    /*!< USART Rx Complete Callback ID             */
+  HAL_USART_TX_RX_COMPLETE_CB_ID          = 0x04U,    /*!< USART Tx Rx Complete Callback ID          */
+  HAL_USART_ERROR_CB_ID                   = 0x05U,    /*!< USART Error Callback ID                   */
+  HAL_USART_ABORT_COMPLETE_CB_ID          = 0x06U,    /*!< USART Abort Complete Callback ID          */
+  HAL_USART_RX_FIFO_FULL_CB_ID            = 0x07U,    /*!< USART Rx Fifo Full Callback ID            */
+  HAL_USART_TX_FIFO_EMPTY_CB_ID           = 0x08U,    /*!< USART Tx Fifo Empty Callback ID           */
+
+  HAL_USART_MSPINIT_CB_ID                 = 0x09U,    /*!< USART MspInit callback ID                 */
+  HAL_USART_MSPDEINIT_CB_ID               = 0x0AU     /*!< USART MspDeInit callback ID               */
+
+} HAL_USART_CallbackIDTypeDef;
+
+/**
+  * @brief  HAL USART Callback pointer definition
+  */
+typedef  void (*pUSART_CallbackTypeDef)(USART_HandleTypeDef *husart);  /*!< pointer to an USART callback function */
+
+#endif /* USE_HAL_USART_REGISTER_CALLBACKS */
+
+/**
+  * @}
+  */
+
+/* Exported constants --------------------------------------------------------*/
+/** @defgroup USART_Exported_Constants USART Exported Constants
+  * @{
+  */
+
+/** @defgroup USART_Error_Definition   USART Error Definition
+  * @{
+  */
+#define HAL_USART_ERROR_NONE             (0x00000000U)    /*!< No error                  */
+#define HAL_USART_ERROR_PE               (0x00000001U)    /*!< Parity error              */
+#define HAL_USART_ERROR_NE               (0x00000002U)    /*!< Noise error               */
+#define HAL_USART_ERROR_FE               (0x00000004U)    /*!< Frame error               */
+#define HAL_USART_ERROR_ORE              (0x00000008U)    /*!< Overrun error             */
+#define HAL_USART_ERROR_DMA              (0x00000010U)    /*!< DMA transfer error        */
+#define HAL_USART_ERROR_UDR              (0x00000020U)    /*!< SPI slave underrun error  */
+#if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
+#define HAL_USART_ERROR_INVALID_CALLBACK (0x00000040U)    /*!< Invalid Callback error    */
+#endif /* USE_HAL_USART_REGISTER_CALLBACKS */
+#define  HAL_USART_ERROR_RTO              (0x00000080U)    /*!< Receiver Timeout error  */
+/**
+  * @}
+  */
+
+/** @defgroup USART_Stop_Bits  USART Number of Stop Bits
+  * @{
+  */
+#define USART_STOPBITS_0_5                   USART_CR2_STOP_0                     /*!< USART frame with 0.5 stop bit  */
+#define USART_STOPBITS_1                     0x00000000U                          /*!< USART frame with 1 stop bit    */
+#define USART_STOPBITS_1_5                  (USART_CR2_STOP_0 | USART_CR2_STOP_1) /*!< USART frame with 1.5 stop bits */
+#define USART_STOPBITS_2                     USART_CR2_STOP_1                     /*!< USART frame with 2 stop bits   */
+/**
+  * @}
+  */
+
+/** @defgroup USART_Parity    USART Parity
+  * @{
+  */
+#define USART_PARITY_NONE                   0x00000000U                      /*!< No parity   */
+#define USART_PARITY_EVEN                   USART_CR1_PCE                    /*!< Even parity */
+#define USART_PARITY_ODD                    (USART_CR1_PCE | USART_CR1_PS)   /*!< Odd parity  */
+/**
+  * @}
+  */
+
+/** @defgroup USART_Mode   USART Mode
+  * @{
+  */
+#define USART_MODE_RX                       USART_CR1_RE                    /*!< RX mode        */
+#define USART_MODE_TX                       USART_CR1_TE                    /*!< TX mode        */
+#define USART_MODE_TX_RX                    (USART_CR1_TE |USART_CR1_RE)    /*!< RX and TX mode */
+/**
+  * @}
+  */
+
+/** @defgroup USART_Clock  USART Clock
+  * @{
+  */
+#define USART_CLOCK_DISABLE                 0x00000000U       /*!< USART clock disable */
+#define USART_CLOCK_ENABLE                  USART_CR2_CLKEN   /*!< USART clock enable  */
+/**
+  * @}
+  */
+
+/** @defgroup USART_Clock_Polarity  USART Clock Polarity
+  * @{
+  */
+#define USART_POLARITY_LOW                  0x00000000U      /*!< Driver enable signal is active high */
+#define USART_POLARITY_HIGH                 USART_CR2_CPOL   /*!< Driver enable signal is active low  */
+/**
+  * @}
+  */
+
+/** @defgroup USART_Clock_Phase   USART Clock Phase
+  * @{
+  */
+#define USART_PHASE_1EDGE                   0x00000000U      /*!< USART frame phase on first clock transition  */
+#define USART_PHASE_2EDGE                   USART_CR2_CPHA   /*!< USART frame phase on second clock transition */
+/**
+  * @}
+  */
+
+/** @defgroup USART_Last_Bit  USART Last Bit
+  * @{
+  */
+#define USART_LASTBIT_DISABLE               0x00000000U      /*!< USART frame last data bit clock pulse not output to SCLK pin */
+#define USART_LASTBIT_ENABLE                USART_CR2_LBCL   /*!< USART frame last data bit clock pulse output to SCLK pin     */
+/**
+  * @}
+  */
+
+/** @defgroup USART_ClockPrescaler  USART Clock Prescaler
+  * @{
+  */
+#define USART_PRESCALER_DIV1    0x00000000U  /*!< fclk_pres = fclk     */
+#define USART_PRESCALER_DIV2    0x00000001U  /*!< fclk_pres = fclk/2   */
+#define USART_PRESCALER_DIV4    0x00000002U  /*!< fclk_pres = fclk/4   */
+#define USART_PRESCALER_DIV6    0x00000003U  /*!< fclk_pres = fclk/6   */
+#define USART_PRESCALER_DIV8    0x00000004U  /*!< fclk_pres = fclk/8   */
+#define USART_PRESCALER_DIV10   0x00000005U  /*!< fclk_pres = fclk/10  */
+#define USART_PRESCALER_DIV12   0x00000006U  /*!< fclk_pres = fclk/12  */
+#define USART_PRESCALER_DIV16   0x00000007U  /*!< fclk_pres = fclk/16  */
+#define USART_PRESCALER_DIV32   0x00000008U  /*!< fclk_pres = fclk/32  */
+#define USART_PRESCALER_DIV64   0x00000009U  /*!< fclk_pres = fclk/64  */
+#define USART_PRESCALER_DIV128  0x0000000AU  /*!< fclk_pres = fclk/128 */
+#define USART_PRESCALER_DIV256  0x0000000BU  /*!< fclk_pres = fclk/256 */
+
+/**
+  * @}
+  */
+
+/** @defgroup USART_Request_Parameters  USART Request Parameters
+  * @{
+  */
+#define USART_RXDATA_FLUSH_REQUEST        USART_RQR_RXFRQ        /*!< Receive Data flush Request  */
+#define USART_TXDATA_FLUSH_REQUEST        USART_RQR_TXFRQ        /*!< Transmit data flush Request */
+/**
+  * @}
+  */
+
+/** @defgroup USART_Flags      USART Flags
+  *        Elements values convention: 0xXXXX
+  *           - 0xXXXX  : Flag mask in the ISR register
+  * @{
+  */
+#define USART_FLAG_TXFT                     USART_ISR_TXFT          /*!< USART TXFIFO threshold flag                */
+#define USART_FLAG_RXFT                     USART_ISR_RXFT          /*!< USART RXFIFO threshold flag                */
+#define USART_FLAG_RXFF                     USART_ISR_RXFF          /*!< USART RXFIFO Full flag                     */
+#define USART_FLAG_TXFE                     USART_ISR_TXFE          /*!< USART TXFIFO Empty flag                    */
+#define USART_FLAG_REACK                    USART_ISR_REACK         /*!< USART receive enable acknowledge flag      */
+#define USART_FLAG_TEACK                    USART_ISR_TEACK         /*!< USART transmit enable acknowledge flag     */
+#define USART_FLAG_BUSY                     USART_ISR_BUSY          /*!< USART busy flag                            */
+#define USART_FLAG_UDR                      USART_ISR_UDR           /*!< SPI slave underrun error flag              */
+#define USART_FLAG_TXE                      USART_ISR_TXE_TXFNF     /*!< USART transmit data register empty         */
+#define USART_FLAG_TXFNF                    USART_ISR_TXE_TXFNF     /*!< USART TXFIFO not full                      */
+#define USART_FLAG_RTOF                     USART_ISR_RTOF          /*!< USART receiver timeout flag                */
+#define USART_FLAG_TC                       USART_ISR_TC            /*!< USART transmission complete                */
+#define USART_FLAG_RXNE                     USART_ISR_RXNE_RXFNE    /*!< USART read data register not empty         */
+#define USART_FLAG_RXFNE                    USART_ISR_RXNE_RXFNE    /*!< USART RXFIFO not empty                     */
+#define USART_FLAG_IDLE                     USART_ISR_IDLE          /*!< USART idle flag                            */
+#define USART_FLAG_ORE                      USART_ISR_ORE           /*!< USART overrun error                        */
+#define USART_FLAG_NE                       USART_ISR_NE            /*!< USART noise error                          */
+#define USART_FLAG_FE                       USART_ISR_FE            /*!< USART frame error                          */
+#define USART_FLAG_PE                       USART_ISR_PE            /*!< USART parity error                         */
+/**
+  * @}
+  */
+
+/** @defgroup USART_Interrupt_definition USART Interrupts Definition
+  *        Elements values convention: 0000ZZZZ0XXYYYYYb
+  *           - YYYYY  : Interrupt source position in the XX register (5bits)
+  *           - XX  : Interrupt source register (2bits)
+  *                 - 01: CR1 register
+  *                 - 10: CR2 register
+  *                 - 11: CR3 register
+  *           - ZZZZ  : Flag position in the ISR register(4bits)
+  * @{
+  */
+
+#define USART_IT_PE                          0x0028U     /*!< USART parity error interruption                 */
+#define USART_IT_TXE                         0x0727U     /*!< USART transmit data register empty interruption */
+#define USART_IT_TXFNF                       0x0727U     /*!< USART TX FIFO not full interruption             */
+#define USART_IT_TC                          0x0626U     /*!< USART transmission complete interruption        */
+#define USART_IT_RXNE                        0x0525U     /*!< USART read data register not empty interruption */
+#define USART_IT_RXFNE                       0x0525U     /*!< USART RXFIFO not empty interruption             */
+#define USART_IT_IDLE                        0x0424U     /*!< USART idle interruption                         */
+#define USART_IT_ERR                         0x0060U     /*!< USART error interruption                        */
+#define USART_IT_ORE                         0x0300U     /*!< USART overrun error interruption                */
+#define USART_IT_NE                          0x0200U     /*!< USART noise error interruption                  */
+#define USART_IT_FE                          0x0100U     /*!< USART frame error interruption                  */
+#define USART_IT_RXFF                        0x183FU     /*!< USART RXFIFO full interruption                  */
+#define USART_IT_TXFE                        0x173EU     /*!< USART TXFIFO empty interruption                 */
+#define USART_IT_RXFT                        0x1A7CU     /*!< USART RXFIFO threshold reached interruption     */
+#define USART_IT_TXFT                        0x1B77U     /*!< USART TXFIFO threshold reached interruption     */
+
+/**
+  * @}
+  */
+
+/** @defgroup USART_IT_CLEAR_Flags    USART Interruption Clear Flags
+  * @{
+  */
+#define USART_CLEAR_PEF                       USART_ICR_PECF            /*!< Parity Error Clear Flag             */
+#define USART_CLEAR_FEF                       USART_ICR_FECF            /*!< Framing Error Clear Flag            */
+#define USART_CLEAR_NEF                       USART_ICR_NECF            /*!< Noise Error detected Clear Flag     */
+#define USART_CLEAR_OREF                      USART_ICR_ORECF           /*!< OverRun Error Clear Flag            */
+#define USART_CLEAR_IDLEF                     USART_ICR_IDLECF          /*!< IDLE line detected Clear Flag       */
+#define USART_CLEAR_TCF                       USART_ICR_TCCF            /*!< Transmission Complete Clear Flag    */
+#define USART_CLEAR_UDRF                      USART_ICR_UDRCF           /*!< SPI slave underrun error Clear Flag */
+#define USART_CLEAR_TXFECF                    USART_ICR_TXFECF          /*!< TXFIFO Empty Clear Flag             */
+#define USART_CLEAR_RTOF                      USART_ICR_RTOCF           /*!< USART receiver timeout clear flag  */
+/**
+  * @}
+  */
+
+/** @defgroup USART_Interruption_Mask    USART Interruption Flags Mask
+  * @{
+  */
+#define USART_IT_MASK                             0x001FU     /*!< USART interruptions flags mask */
+#define USART_CR_MASK                             0x00E0U     /*!< USART control register mask */
+#define USART_CR_POS                              5U          /*!< USART control register position */
+#define USART_ISR_MASK                            0x1F00U     /*!< USART ISR register mask         */
+#define USART_ISR_POS                             8U          /*!< USART ISR register position     */
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/* Exported macros -----------------------------------------------------------*/
+/** @defgroup USART_Exported_Macros USART Exported Macros
+  * @{
+  */
+
+/** @brief Reset USART handle state.
+  * @param  __HANDLE__ USART handle.
+  * @retval None
+  */
+#if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
+#define __HAL_USART_RESET_HANDLE_STATE(__HANDLE__)  do{                                            \
+                                                        (__HANDLE__)->State = HAL_USART_STATE_RESET; \
+                                                        (__HANDLE__)->MspInitCallback = NULL;        \
+                                                        (__HANDLE__)->MspDeInitCallback = NULL;      \
+                                                      } while(0U)
+#else
+#define __HAL_USART_RESET_HANDLE_STATE(__HANDLE__)  ((__HANDLE__)->State = HAL_USART_STATE_RESET)
+#endif /* USE_HAL_USART_REGISTER_CALLBACKS */
+
+/** @brief  Check whether the specified USART flag is set or not.
+  * @param  __HANDLE__ specifies the USART Handle
+  * @param  __FLAG__ specifies the flag to check.
+  *        This parameter can be one of the following values:
+  *            @arg @ref USART_FLAG_TXFT  TXFIFO threshold flag
+  *            @arg @ref USART_FLAG_RXFT  RXFIFO threshold flag
+  *            @arg @ref USART_FLAG_RXFF  RXFIFO Full flag
+  *            @arg @ref USART_FLAG_TXFE  TXFIFO Empty flag
+  *            @arg @ref USART_FLAG_REACK Receive enable acknowledge flag
+  *            @arg @ref USART_FLAG_TEACK Transmit enable acknowledge flag
+  *            @arg @ref USART_FLAG_BUSY  Busy flag
+  *            @arg @ref USART_FLAG_UDR   SPI slave underrun error flag
+  *            @arg @ref USART_FLAG_TXE   Transmit data register empty flag
+  *            @arg @ref USART_FLAG_TXFNF TXFIFO not full flag
+  *            @arg @ref USART_FLAG_TC    Transmission Complete flag
+  *            @arg @ref USART_FLAG_RXNE  Receive data register not empty flag
+  *            @arg @ref USART_FLAG_RXFNE RXFIFO not empty flag
+  *            @arg @ref USART_FLAG_RTOF  Receiver Timeout flag
+  *            @arg @ref USART_FLAG_IDLE  Idle Line detection flag
+  *            @arg @ref USART_FLAG_ORE   OverRun Error flag
+  *            @arg @ref USART_FLAG_NE    Noise Error flag
+  *            @arg @ref USART_FLAG_FE    Framing Error flag
+  *            @arg @ref USART_FLAG_PE    Parity Error flag
+  * @retval The new state of __FLAG__ (TRUE or FALSE).
+  */
+#define __HAL_USART_GET_FLAG(__HANDLE__, __FLAG__) (((__HANDLE__)->Instance->ISR & (__FLAG__)) == (__FLAG__))
+
+/** @brief  Clear the specified USART pending flag.
+  * @param  __HANDLE__ specifies the USART Handle.
+  * @param  __FLAG__ specifies the flag to check.
+  *          This parameter can be any combination of the following values:
+  *            @arg @ref USART_CLEAR_PEF      Parity Error Clear Flag
+  *            @arg @ref USART_CLEAR_FEF      Framing Error Clear Flag
+  *            @arg @ref USART_CLEAR_NEF      Noise detected Clear Flag
+  *            @arg @ref USART_CLEAR_OREF     Overrun Error Clear Flag
+  *            @arg @ref USART_CLEAR_IDLEF    IDLE line detected Clear Flag
+  *            @arg @ref USART_CLEAR_TXFECF   TXFIFO empty clear Flag
+  *            @arg @ref USART_CLEAR_TCF      Transmission Complete Clear Flag
+  *            @arg @ref USART_CLEAR_RTOF     Receiver Timeout clear flag
+  *            @arg @ref USART_CLEAR_UDRF     SPI slave underrun error Clear Flag
+  * @retval None
+  */
+#define __HAL_USART_CLEAR_FLAG(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->ICR = (__FLAG__))
+
+/** @brief  Clear the USART PE pending flag.
+  * @param  __HANDLE__ specifies the USART Handle.
+  * @retval None
+  */
+#define __HAL_USART_CLEAR_PEFLAG(__HANDLE__)   __HAL_USART_CLEAR_FLAG((__HANDLE__), USART_CLEAR_PEF)
+
+/** @brief  Clear the USART FE pending flag.
+  * @param  __HANDLE__ specifies the USART Handle.
+  * @retval None
+  */
+#define __HAL_USART_CLEAR_FEFLAG(__HANDLE__)   __HAL_USART_CLEAR_FLAG((__HANDLE__), USART_CLEAR_FEF)
+
+/** @brief  Clear the USART NE pending flag.
+  * @param  __HANDLE__ specifies the USART Handle.
+  * @retval None
+  */
+#define __HAL_USART_CLEAR_NEFLAG(__HANDLE__)  __HAL_USART_CLEAR_FLAG((__HANDLE__), USART_CLEAR_NEF)
+
+/** @brief  Clear the USART ORE pending flag.
+  * @param  __HANDLE__ specifies the USART Handle.
+  * @retval None
+  */
+#define __HAL_USART_CLEAR_OREFLAG(__HANDLE__)   __HAL_USART_CLEAR_FLAG((__HANDLE__), USART_CLEAR_OREF)
+
+/** @brief  Clear the USART IDLE pending flag.
+  * @param  __HANDLE__ specifies the USART Handle.
+  * @retval None
+  */
+#define __HAL_USART_CLEAR_IDLEFLAG(__HANDLE__)   __HAL_USART_CLEAR_FLAG((__HANDLE__), USART_CLEAR_IDLEF)
+
+/** @brief  Clear the USART TX FIFO empty clear flag.
+  * @param  __HANDLE__ specifies the USART Handle.
+  * @retval None
+  */
+#define __HAL_USART_CLEAR_TXFECF(__HANDLE__)   __HAL_USART_CLEAR_FLAG((__HANDLE__), USART_CLEAR_TXFECF)
+
+/** @brief  Clear SPI slave underrun error flag.
+  * @param  __HANDLE__ specifies the USART Handle.
+  * @retval None
+  */
+#define __HAL_USART_CLEAR_UDRFLAG(__HANDLE__)   __HAL_USART_CLEAR_FLAG((__HANDLE__), USART_CLEAR_UDRF)
+
+/** @brief  Enable the specified USART interrupt.
+  * @param  __HANDLE__ specifies the USART Handle.
+  * @param  __INTERRUPT__ specifies the USART interrupt source to enable.
+  *          This parameter can be one of the following values:
+  *            @arg @ref USART_IT_RXFF  RXFIFO Full interrupt
+  *            @arg @ref USART_IT_TXFE  TXFIFO Empty interrupt
+  *            @arg @ref USART_IT_RXFT  RXFIFO threshold interrupt
+  *            @arg @ref USART_IT_TXFT  TXFIFO threshold interrupt
+  *            @arg @ref USART_IT_TXE   Transmit Data Register empty interrupt
+  *            @arg @ref USART_IT_TXFNF TX FIFO not full interrupt
+  *            @arg @ref USART_IT_TC    Transmission complete interrupt
+  *            @arg @ref USART_IT_RXNE  Receive Data register not empty interrupt
+  *            @arg @ref USART_IT_RXFNE RXFIFO not empty interrupt
+  *            @arg @ref USART_IT_IDLE  Idle line detection interrupt
+  *            @arg @ref USART_IT_PE    Parity Error interrupt
+  *            @arg @ref USART_IT_ERR   Error interrupt(Frame error, noise error, overrun error)
+  * @retval None
+  */
+#define __HAL_USART_ENABLE_IT(__HANDLE__, __INTERRUPT__)\
+  (((((__INTERRUPT__) & USART_CR_MASK) >> USART_CR_POS) == 1U)?\
+   ((__HANDLE__)->Instance->CR1 |= (1U << ((__INTERRUPT__) & USART_IT_MASK))): \
+   ((((__INTERRUPT__) & USART_CR_MASK) >> USART_CR_POS) == 2U)?\
+   ((__HANDLE__)->Instance->CR2 |= (1U << ((__INTERRUPT__) & USART_IT_MASK))): \
+   ((__HANDLE__)->Instance->CR3 |= (1U << ((__INTERRUPT__) & USART_IT_MASK))))
+
+/** @brief  Disable the specified USART interrupt.
+  * @param  __HANDLE__ specifies the USART Handle.
+  * @param  __INTERRUPT__ specifies the USART interrupt source to disable.
+  *          This parameter can be one of the following values:
+  *            @arg @ref USART_IT_RXFF  RXFIFO Full interrupt
+  *            @arg @ref USART_IT_TXFE  TXFIFO Empty interrupt
+  *            @arg @ref USART_IT_RXFT  RXFIFO threshold interrupt
+  *            @arg @ref USART_IT_TXFT  TXFIFO threshold interrupt
+  *            @arg @ref USART_IT_TXE   Transmit Data Register empty interrupt
+  *            @arg @ref USART_IT_TXFNF TX FIFO not full interrupt
+  *            @arg @ref USART_IT_TC    Transmission complete interrupt
+  *            @arg @ref USART_IT_RXNE  Receive Data register not empty interrupt
+  *            @arg @ref USART_IT_RXFNE RXFIFO not empty interrupt
+  *            @arg @ref USART_IT_IDLE  Idle line detection interrupt
+  *            @arg @ref USART_IT_PE    Parity Error interrupt
+  *            @arg @ref USART_IT_ERR   Error interrupt(Frame error, noise error, overrun error)
+  * @retval None
+  */
+#define __HAL_USART_DISABLE_IT(__HANDLE__, __INTERRUPT__)\
+  (((((__INTERRUPT__) & USART_CR_MASK) >> USART_CR_POS) == 1U)?\
+   ((__HANDLE__)->Instance->CR1 &= ~ (1U << ((__INTERRUPT__) & USART_IT_MASK))): \
+   ((((__INTERRUPT__) & USART_CR_MASK) >> USART_CR_POS) == 2U)?\
+   ((__HANDLE__)->Instance->CR2 &= ~ (1U << ((__INTERRUPT__) & USART_IT_MASK))): \
+   ((__HANDLE__)->Instance->CR3 &= ~ (1U << ((__INTERRUPT__) & USART_IT_MASK))))
+
+/** @brief  Check whether the specified USART interrupt has occurred or not.
+  * @param  __HANDLE__ specifies the USART Handle.
+  * @param  __INTERRUPT__ specifies the USART interrupt source to check.
+  *          This parameter can be one of the following values:
+  *            @arg @ref USART_IT_RXFF  RXFIFO Full interrupt
+  *            @arg @ref USART_IT_TXFE  TXFIFO Empty interrupt
+  *            @arg @ref USART_IT_RXFT  RXFIFO threshold interrupt
+  *            @arg @ref USART_IT_TXFT  TXFIFO threshold interrupt
+  *            @arg @ref USART_IT_TXE   Transmit Data Register empty interrupt
+  *            @arg @ref USART_IT_TXFNF TX FIFO not full interrupt
+  *            @arg @ref USART_IT_TC    Transmission complete interrupt
+  *            @arg @ref USART_IT_RXNE  Receive Data register not empty interrupt
+  *            @arg @ref USART_IT_RXFNE RXFIFO not empty interrupt
+  *            @arg @ref USART_IT_IDLE  Idle line detection interrupt
+  *            @arg @ref USART_IT_ORE   OverRun Error interrupt
+  *            @arg @ref USART_IT_NE    Noise Error interrupt
+  *            @arg @ref USART_IT_FE    Framing Error interrupt
+  *            @arg @ref USART_IT_PE    Parity Error interrupt
+  * @retval The new state of __INTERRUPT__ (SET or RESET).
+  */
+#define __HAL_USART_GET_IT(__HANDLE__, __INTERRUPT__) ((((__HANDLE__)->Instance->ISR\
+                                                         & (0x01U << (((__INTERRUPT__) & USART_ISR_MASK)>>\
+                                                                      USART_ISR_POS))) != 0U) ? SET : RESET)
+
+/** @brief  Check whether the specified USART interrupt source is enabled or not.
+  * @param  __HANDLE__ specifies the USART Handle.
+  * @param  __INTERRUPT__ specifies the USART interrupt source to check.
+  *          This parameter can be one of the following values:
+  *            @arg @ref USART_IT_RXFF  RXFIFO Full interrupt
+  *            @arg @ref USART_IT_TXFE  TXFIFO Empty interrupt
+  *            @arg @ref USART_IT_RXFT  RXFIFO threshold interrupt
+  *            @arg @ref USART_IT_TXFT  TXFIFO threshold interrupt
+  *            @arg @ref USART_IT_TXE   Transmit Data Register empty interrupt
+  *            @arg @ref USART_IT_TXFNF TX FIFO not full interrupt
+  *            @arg @ref USART_IT_TC    Transmission complete interrupt
+  *            @arg @ref USART_IT_RXNE  Receive Data register not empty interrupt
+  *            @arg @ref USART_IT_RXFNE RXFIFO not empty interrupt
+  *            @arg @ref USART_IT_IDLE  Idle line detection interrupt
+  *            @arg @ref USART_IT_ORE   OverRun Error interrupt
+  *            @arg @ref USART_IT_NE    Noise Error interrupt
+  *            @arg @ref USART_IT_FE    Framing Error interrupt
+  *            @arg @ref USART_IT_PE    Parity Error interrupt
+  * @retval The new state of __INTERRUPT__ (SET or RESET).
+  */
+#define __HAL_USART_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) ((((((((uint8_t)(__INTERRUPT__)) >> 0x05U) == 0x01U) ?\
+                                                                 (__HANDLE__)->Instance->CR1 : \
+                                                                 (((((uint8_t)(__INTERRUPT__)) >> 0x05U) == 0x02U) ?\
+                                                                  (__HANDLE__)->Instance->CR2 : \
+                                                                  (__HANDLE__)->Instance->CR3)) & (0x01U <<\
+                                                                      (((uint16_t)(__INTERRUPT__)) &\
+                                                                       USART_IT_MASK)))  != 0U) ? SET : RESET)
+
+/** @brief  Clear the specified USART ISR flag, in setting the proper ICR register flag.
+  * @param  __HANDLE__ specifies the USART Handle.
+  * @param  __IT_CLEAR__ specifies the interrupt clear register flag that needs to be set
+  *                       to clear the corresponding interrupt.
+  *          This parameter can be one of the following values:
+  *            @arg @ref USART_CLEAR_PEF      Parity Error Clear Flag
+  *            @arg @ref USART_CLEAR_FEF      Framing Error Clear Flag
+  *            @arg @ref USART_CLEAR_NEF      Noise detected Clear Flag
+  *            @arg @ref USART_CLEAR_OREF     Overrun Error Clear Flag
+  *            @arg @ref USART_CLEAR_IDLEF    IDLE line detected Clear Flag
+  *            @arg @ref USART_CLEAR_RTOF     Receiver timeout clear flag
+  *            @arg @ref USART_CLEAR_TXFECF   TXFIFO empty clear Flag
+  *            @arg @ref USART_CLEAR_TCF      Transmission Complete Clear Flag
+  * @retval None
+  */
+#define __HAL_USART_CLEAR_IT(__HANDLE__, __IT_CLEAR__) ((__HANDLE__)->Instance->ICR = (uint32_t)(__IT_CLEAR__))
+
+/** @brief  Set a specific USART request flag.
+  * @param  __HANDLE__ specifies the USART Handle.
+  * @param  __REQ__ specifies the request flag to set.
+  *          This parameter can be one of the following values:
+  *            @arg @ref USART_RXDATA_FLUSH_REQUEST Receive Data flush Request
+  *            @arg @ref USART_TXDATA_FLUSH_REQUEST Transmit data flush Request
+  *
+  * @retval None
+  */
+#define __HAL_USART_SEND_REQ(__HANDLE__, __REQ__)      ((__HANDLE__)->Instance->RQR |= (uint16_t)(__REQ__))
+
+/** @brief  Enable the USART one bit sample method.
+  * @param  __HANDLE__ specifies the USART Handle.
+  * @retval None
+  */
+#define __HAL_USART_ONE_BIT_SAMPLE_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->CR3|= USART_CR3_ONEBIT)
+
+/** @brief  Disable the USART one bit sample method.
+  * @param  __HANDLE__ specifies the USART Handle.
+  * @retval None
+  */
+#define __HAL_USART_ONE_BIT_SAMPLE_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->CR3 &= ~USART_CR3_ONEBIT)
+
+/** @brief  Enable USART.
+  * @param  __HANDLE__ specifies the USART Handle.
+  * @retval None
+  */
+#define __HAL_USART_ENABLE(__HANDLE__)                 ((__HANDLE__)->Instance->CR1 |= USART_CR1_UE)
+
+/** @brief  Disable USART.
+  * @param  __HANDLE__ specifies the USART Handle.
+  * @retval None
+  */
+#define __HAL_USART_DISABLE(__HANDLE__)                ((__HANDLE__)->Instance->CR1 &= ~USART_CR1_UE)
+
+/**
+  * @}
+  */
+
+/* Private macros --------------------------------------------------------*/
+/** @defgroup USART_Private_Macros   USART Private Macros
+  * @{
+  */
+
+/** @brief  Get USART clock division factor from clock prescaler value.
+  * @param  __CLOCKPRESCALER__ USART prescaler value.
+  * @retval USART clock division factor
+  */
+#define USART_GET_DIV_FACTOR(__CLOCKPRESCALER__) \
+  (((__CLOCKPRESCALER__) == USART_PRESCALER_DIV1)   ? 1U :       \
+   ((__CLOCKPRESCALER__) == USART_PRESCALER_DIV2)   ? 2U :       \
+   ((__CLOCKPRESCALER__) == USART_PRESCALER_DIV4)   ? 4U :       \
+   ((__CLOCKPRESCALER__) == USART_PRESCALER_DIV6)   ? 6U :       \
+   ((__CLOCKPRESCALER__) == USART_PRESCALER_DIV8)   ? 8U :       \
+   ((__CLOCKPRESCALER__) == USART_PRESCALER_DIV10)  ? 10U :      \
+   ((__CLOCKPRESCALER__) == USART_PRESCALER_DIV12)  ? 12U :      \
+   ((__CLOCKPRESCALER__) == USART_PRESCALER_DIV16)  ? 16U :      \
+   ((__CLOCKPRESCALER__) == USART_PRESCALER_DIV32)  ? 32U :      \
+   ((__CLOCKPRESCALER__) == USART_PRESCALER_DIV64)  ? 64U :      \
+   ((__CLOCKPRESCALER__) == USART_PRESCALER_DIV128) ? 128U : 256U)
+
+/** @brief  BRR division operation to set BRR register in 8-bit oversampling mode.
+  * @param  __PCLK__ USART clock.
+  * @param  __BAUD__ Baud rate set by the user.
+  * @param  __CLOCKPRESCALER__ USART prescaler value.
+  * @retval Division result
+  */
+#define USART_DIV_SAMPLING8(__PCLK__, __BAUD__, __CLOCKPRESCALER__)\
+  (((((__PCLK__)/USART_GET_DIV_FACTOR(__CLOCKPRESCALER__))*2U)\
+    + ((__BAUD__)/2U)) / (__BAUD__))
+
+/** @brief  Report the USART clock source.
+  * @param  __HANDLE__ specifies the USART Handle.
+  * @param  __CLOCKSOURCE__ output variable.
+  * @retval the USART clocking source, written in __CLOCKSOURCE__.
+  */
+#if defined(USART3)
+#define USART_GETCLOCKSOURCE(__HANDLE__,__CLOCKSOURCE__)       \
+  do {                                                         \
+    if((__HANDLE__)->Instance == USART1)                       \
+    {                                                          \
+      switch(__HAL_RCC_GET_USART1_SOURCE())                    \
+      {                                                        \
+        case RCC_USART1CLKSOURCE_PCLK2:                        \
+          (__CLOCKSOURCE__) = USART_CLOCKSOURCE_PCLK2;         \
+          break;                                               \
+        case RCC_USART1CLKSOURCE_HSI:                          \
+          (__CLOCKSOURCE__) = USART_CLOCKSOURCE_HSI;           \
+          break;                                               \
+        case RCC_USART1CLKSOURCE_SYSCLK:                       \
+          (__CLOCKSOURCE__) = USART_CLOCKSOURCE_SYSCLK;        \
+          break;                                               \
+        case RCC_USART1CLKSOURCE_LSE:                          \
+          (__CLOCKSOURCE__) = USART_CLOCKSOURCE_LSE;           \
+          break;                                               \
+        default:                                               \
+          (__CLOCKSOURCE__) = USART_CLOCKSOURCE_UNDEFINED;     \
+          break;                                               \
+      }                                                        \
+    }                                                          \
+    else if((__HANDLE__)->Instance == USART2)                  \
+    {                                                          \
+      switch(__HAL_RCC_GET_USART2_SOURCE())                    \
+      {                                                        \
+        case RCC_USART2CLKSOURCE_PCLK1:                        \
+          (__CLOCKSOURCE__) = USART_CLOCKSOURCE_PCLK1;         \
+          break;                                               \
+        case RCC_USART2CLKSOURCE_HSI:                          \
+          (__CLOCKSOURCE__) = USART_CLOCKSOURCE_HSI;           \
+          break;                                               \
+        case RCC_USART2CLKSOURCE_SYSCLK:                       \
+          (__CLOCKSOURCE__) = USART_CLOCKSOURCE_SYSCLK;        \
+          break;                                               \
+        case RCC_USART2CLKSOURCE_LSE:                          \
+          (__CLOCKSOURCE__) = USART_CLOCKSOURCE_LSE;           \
+          break;                                               \
+        default:                                               \
+          (__CLOCKSOURCE__) = USART_CLOCKSOURCE_UNDEFINED;     \
+          break;                                               \
+      }                                                        \
+    }                                                          \
+    else if((__HANDLE__)->Instance == USART3)                  \
+    {                                                          \
+      switch(__HAL_RCC_GET_USART3_SOURCE())                    \
+      {                                                        \
+        case RCC_USART3CLKSOURCE_PCLK1:                        \
+          (__CLOCKSOURCE__) = USART_CLOCKSOURCE_PCLK1;         \
+          break;                                               \
+        case RCC_USART3CLKSOURCE_HSI:                          \
+          (__CLOCKSOURCE__) = USART_CLOCKSOURCE_HSI;           \
+          break;                                               \
+        case RCC_USART3CLKSOURCE_SYSCLK:                       \
+          (__CLOCKSOURCE__) = USART_CLOCKSOURCE_SYSCLK;        \
+          break;                                               \
+        case RCC_USART3CLKSOURCE_LSE:                          \
+          (__CLOCKSOURCE__) = USART_CLOCKSOURCE_LSE;           \
+          break;                                               \
+        default:                                               \
+          (__CLOCKSOURCE__) = USART_CLOCKSOURCE_UNDEFINED;     \
+          break;                                               \
+      }                                                        \
+    }                                                          \
+    else                                                       \
+    {                                                          \
+      (__CLOCKSOURCE__) = USART_CLOCKSOURCE_UNDEFINED;         \
+    }                                                          \
+  } while(0)
+#else
+#define USART_GETCLOCKSOURCE(__HANDLE__,__CLOCKSOURCE__)       \
+  do {                                                         \
+    if((__HANDLE__)->Instance == USART1)                       \
+    {                                                          \
+      switch(__HAL_RCC_GET_USART1_SOURCE())                    \
+      {                                                        \
+        case RCC_USART1CLKSOURCE_PCLK2:                        \
+          (__CLOCKSOURCE__) = USART_CLOCKSOURCE_PCLK2;         \
+          break;                                               \
+        case RCC_USART1CLKSOURCE_HSI:                          \
+          (__CLOCKSOURCE__) = USART_CLOCKSOURCE_HSI;           \
+          break;                                               \
+        case RCC_USART1CLKSOURCE_SYSCLK:                       \
+          (__CLOCKSOURCE__) = USART_CLOCKSOURCE_SYSCLK;        \
+          break;                                               \
+        case RCC_USART1CLKSOURCE_LSE:                          \
+          (__CLOCKSOURCE__) = USART_CLOCKSOURCE_LSE;           \
+          break;                                               \
+        default:                                               \
+          (__CLOCKSOURCE__) = USART_CLOCKSOURCE_UNDEFINED;     \
+          break;                                               \
+      }                                                        \
+    }                                                          \
+    else if((__HANDLE__)->Instance == USART2)                  \
+    {                                                          \
+      switch(__HAL_RCC_GET_USART2_SOURCE())                    \
+      {                                                        \
+        case RCC_USART2CLKSOURCE_PCLK1:                        \
+          (__CLOCKSOURCE__) = USART_CLOCKSOURCE_PCLK1;         \
+          break;                                               \
+        case RCC_USART2CLKSOURCE_HSI:                          \
+          (__CLOCKSOURCE__) = USART_CLOCKSOURCE_HSI;           \
+          break;                                               \
+        case RCC_USART2CLKSOURCE_SYSCLK:                       \
+          (__CLOCKSOURCE__) = USART_CLOCKSOURCE_SYSCLK;        \
+          break;                                               \
+        case RCC_USART2CLKSOURCE_LSE:                          \
+          (__CLOCKSOURCE__) = USART_CLOCKSOURCE_LSE;           \
+          break;                                               \
+        default:                                               \
+          (__CLOCKSOURCE__) = USART_CLOCKSOURCE_UNDEFINED;     \
+          break;                                               \
+      }                                                        \
+    }                                                          \
+    else                                                       \
+    {                                                          \
+      (__CLOCKSOURCE__) = USART_CLOCKSOURCE_UNDEFINED;         \
+    }                                                          \
+  } while(0)
+#endif /* USART3 */
+
+/** @brief  Check USART Baud rate.
+  * @param  __BAUDRATE__ Baudrate specified by the user.
+  *         The maximum Baud Rate is derived from the maximum clock on G4 (i.e. 150 MHz)
+  *         divided by the smallest oversampling used on the USART (i.e. 8)
+  * @retval SET (__BAUDRATE__ is valid) or RESET (__BAUDRATE__ is invalid)  */
+#define IS_USART_BAUDRATE(__BAUDRATE__) ((__BAUDRATE__) <= 18750000U)
+
+/**
+  * @brief Ensure that USART frame number of stop bits is valid.
+  * @param __STOPBITS__ USART frame number of stop bits.
+  * @retval SET (__STOPBITS__ is valid) or RESET (__STOPBITS__ is invalid)
+  */
+#define IS_USART_STOPBITS(__STOPBITS__) (((__STOPBITS__) == USART_STOPBITS_0_5) || \
+                                         ((__STOPBITS__) == USART_STOPBITS_1)   || \
+                                         ((__STOPBITS__) == USART_STOPBITS_1_5) || \
+                                         ((__STOPBITS__) == USART_STOPBITS_2))
+
+/**
+  * @brief Ensure that USART frame parity is valid.
+  * @param __PARITY__ USART frame parity.
+  * @retval SET (__PARITY__ is valid) or RESET (__PARITY__ is invalid)
+  */
+#define IS_USART_PARITY(__PARITY__) (((__PARITY__) == USART_PARITY_NONE) || \
+                                     ((__PARITY__) == USART_PARITY_EVEN) || \
+                                     ((__PARITY__) == USART_PARITY_ODD))
+
+/**
+  * @brief Ensure that USART communication mode is valid.
+  * @param __MODE__ USART communication mode.
+  * @retval SET (__MODE__ is valid) or RESET (__MODE__ is invalid)
+  */
+#define IS_USART_MODE(__MODE__) ((((__MODE__) & 0xFFFFFFF3U) == 0x00U) && ((__MODE__) != 0x00U))
+
+/**
+  * @brief Ensure that USART clock state is valid.
+  * @param __CLOCK__ USART clock state.
+  * @retval SET (__CLOCK__ is valid) or RESET (__CLOCK__ is invalid)
+  */
+#define IS_USART_CLOCK(__CLOCK__) (((__CLOCK__) == USART_CLOCK_DISABLE) || \
+                                   ((__CLOCK__) == USART_CLOCK_ENABLE))
+
+/**
+  * @brief Ensure that USART frame polarity is valid.
+  * @param __CPOL__ USART frame polarity.
+  * @retval SET (__CPOL__ is valid) or RESET (__CPOL__ is invalid)
+  */
+#define IS_USART_POLARITY(__CPOL__) (((__CPOL__) == USART_POLARITY_LOW) || ((__CPOL__) == USART_POLARITY_HIGH))
+
+/**
+  * @brief Ensure that USART frame phase is valid.
+  * @param __CPHA__ USART frame phase.
+  * @retval SET (__CPHA__ is valid) or RESET (__CPHA__ is invalid)
+  */
+#define IS_USART_PHASE(__CPHA__) (((__CPHA__) == USART_PHASE_1EDGE) || ((__CPHA__) == USART_PHASE_2EDGE))
+
+/**
+  * @brief Ensure that USART frame last bit clock pulse setting is valid.
+  * @param __LASTBIT__ USART frame last bit clock pulse setting.
+  * @retval SET (__LASTBIT__ is valid) or RESET (__LASTBIT__ is invalid)
+  */
+#define IS_USART_LASTBIT(__LASTBIT__) (((__LASTBIT__) == USART_LASTBIT_DISABLE) || \
+                                       ((__LASTBIT__) == USART_LASTBIT_ENABLE))
+
+/**
+  * @brief Ensure that USART request parameter is valid.
+  * @param __PARAM__ USART request parameter.
+  * @retval SET (__PARAM__ is valid) or RESET (__PARAM__ is invalid)
+  */
+#define IS_USART_REQUEST_PARAMETER(__PARAM__) (((__PARAM__) == USART_RXDATA_FLUSH_REQUEST) || \
+                                               ((__PARAM__) == USART_TXDATA_FLUSH_REQUEST))
+
+/**
+  * @brief Ensure that USART Prescaler is valid.
+  * @param __CLOCKPRESCALER__ USART Prescaler value.
+  * @retval SET (__CLOCKPRESCALER__ is valid) or RESET (__CLOCKPRESCALER__ is invalid)
+  */
+#define IS_USART_PRESCALER(__CLOCKPRESCALER__) (((__CLOCKPRESCALER__) == USART_PRESCALER_DIV1) || \
+                                                ((__CLOCKPRESCALER__) == USART_PRESCALER_DIV2) || \
+                                                ((__CLOCKPRESCALER__) == USART_PRESCALER_DIV4) || \
+                                                ((__CLOCKPRESCALER__) == USART_PRESCALER_DIV6) || \
+                                                ((__CLOCKPRESCALER__) == USART_PRESCALER_DIV8) || \
+                                                ((__CLOCKPRESCALER__) == USART_PRESCALER_DIV10) || \
+                                                ((__CLOCKPRESCALER__) == USART_PRESCALER_DIV12) || \
+                                                ((__CLOCKPRESCALER__) == USART_PRESCALER_DIV16) || \
+                                                ((__CLOCKPRESCALER__) == USART_PRESCALER_DIV32) || \
+                                                ((__CLOCKPRESCALER__) == USART_PRESCALER_DIV64) || \
+                                                ((__CLOCKPRESCALER__) == USART_PRESCALER_DIV128) || \
+                                                ((__CLOCKPRESCALER__) == USART_PRESCALER_DIV256))
+
+/**
+  * @}
+  */
+
+/* Include USART HAL Extended module */
+#include "stm32g4xx_hal_usart_ex.h"
+
+/* Exported functions --------------------------------------------------------*/
+/** @addtogroup USART_Exported_Functions USART Exported Functions
+  * @{
+  */
+
+/** @addtogroup USART_Exported_Functions_Group1 Initialization and de-initialization functions
+  * @{
+  */
+
+/* Initialization and de-initialization functions  ****************************/
+HAL_StatusTypeDef HAL_USART_Init(USART_HandleTypeDef *husart);
+HAL_StatusTypeDef HAL_USART_DeInit(USART_HandleTypeDef *husart);
+void HAL_USART_MspInit(USART_HandleTypeDef *husart);
+void HAL_USART_MspDeInit(USART_HandleTypeDef *husart);
+
+/* Callbacks Register/UnRegister functions  ***********************************/
+#if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
+HAL_StatusTypeDef HAL_USART_RegisterCallback(USART_HandleTypeDef *husart, HAL_USART_CallbackIDTypeDef CallbackID,
+                                             pUSART_CallbackTypeDef pCallback);
+HAL_StatusTypeDef HAL_USART_UnRegisterCallback(USART_HandleTypeDef *husart, HAL_USART_CallbackIDTypeDef CallbackID);
+#endif /* USE_HAL_USART_REGISTER_CALLBACKS */
+
+/**
+  * @}
+  */
+
+/** @addtogroup USART_Exported_Functions_Group2 IO operation functions
+  * @{
+  */
+
+/* IO operation functions *****************************************************/
+HAL_StatusTypeDef HAL_USART_Transmit(USART_HandleTypeDef *husart, const uint8_t *pTxData, uint16_t Size,
+                                     uint32_t Timeout);
+HAL_StatusTypeDef HAL_USART_Receive(USART_HandleTypeDef *husart, uint8_t *pRxData, uint16_t Size, uint32_t Timeout);
+HAL_StatusTypeDef HAL_USART_TransmitReceive(USART_HandleTypeDef *husart, const uint8_t *pTxData, uint8_t *pRxData,
+                                            uint16_t Size, uint32_t Timeout);
+HAL_StatusTypeDef HAL_USART_Transmit_IT(USART_HandleTypeDef *husart, const uint8_t *pTxData, uint16_t Size);
+HAL_StatusTypeDef HAL_USART_Receive_IT(USART_HandleTypeDef *husart, uint8_t *pRxData, uint16_t Size);
+HAL_StatusTypeDef HAL_USART_TransmitReceive_IT(USART_HandleTypeDef *husart, const uint8_t *pTxData, uint8_t *pRxData,
+                                               uint16_t Size);
+HAL_StatusTypeDef HAL_USART_Transmit_DMA(USART_HandleTypeDef *husart, const uint8_t *pTxData, uint16_t Size);
+HAL_StatusTypeDef HAL_USART_Receive_DMA(USART_HandleTypeDef *husart, uint8_t *pRxData, uint16_t Size);
+HAL_StatusTypeDef HAL_USART_TransmitReceive_DMA(USART_HandleTypeDef *husart, const uint8_t *pTxData, uint8_t *pRxData,
+                                                uint16_t Size);
+HAL_StatusTypeDef HAL_USART_DMAPause(USART_HandleTypeDef *husart);
+HAL_StatusTypeDef HAL_USART_DMAResume(USART_HandleTypeDef *husart);
+HAL_StatusTypeDef HAL_USART_DMAStop(USART_HandleTypeDef *husart);
+/* Transfer Abort functions */
+HAL_StatusTypeDef HAL_USART_Abort(USART_HandleTypeDef *husart);
+HAL_StatusTypeDef HAL_USART_Abort_IT(USART_HandleTypeDef *husart);
+
+void HAL_USART_IRQHandler(USART_HandleTypeDef *husart);
+void HAL_USART_TxHalfCpltCallback(USART_HandleTypeDef *husart);
+void HAL_USART_TxCpltCallback(USART_HandleTypeDef *husart);
+void HAL_USART_RxCpltCallback(USART_HandleTypeDef *husart);
+void HAL_USART_RxHalfCpltCallback(USART_HandleTypeDef *husart);
+void HAL_USART_TxRxCpltCallback(USART_HandleTypeDef *husart);
+void HAL_USART_ErrorCallback(USART_HandleTypeDef *husart);
+void HAL_USART_AbortCpltCallback(USART_HandleTypeDef *husart);
+
+/**
+  * @}
+  */
+
+/** @addtogroup USART_Exported_Functions_Group4 Peripheral State and Error functions
+  * @{
+  */
+
+/* Peripheral State and Error functions ***************************************/
+HAL_USART_StateTypeDef HAL_USART_GetState(const USART_HandleTypeDef *husart);
+uint32_t               HAL_USART_GetError(const USART_HandleTypeDef *husart);
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* STM32G4xx_HAL_USART_H */
+
diff --git a/starter-projects/servo/p1-pwm/Drivers/STM32G4xx_HAL_Driver/Inc/stm32g4xx_hal_usart_ex.h b/starter-projects/servo/p1-pwm/Drivers/STM32G4xx_HAL_Driver/Inc/stm32g4xx_hal_usart_ex.h
new file mode 100644
index 0000000..f435bca
--- /dev/null
+++ b/starter-projects/servo/p1-pwm/Drivers/STM32G4xx_HAL_Driver/Inc/stm32g4xx_hal_usart_ex.h
@@ -0,0 +1,282 @@
+/**
+  ******************************************************************************
+  * @file    stm32g4xx_hal_usart_ex.h
+  * @author  MCD Application Team
+  * @brief   Header file of USART HAL Extended module.
+  ******************************************************************************
+  * @attention
+  *
+  * Copyright (c) 2019 STMicroelectronics.
+  * All rights reserved.
+  *
+  * This software is licensed under terms that can be found in the LICENSE file
+  * in the root directory of this software component.
+  * If no LICENSE file comes with this software, it is provided AS-IS.
+  *
+  ******************************************************************************
+  */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef STM32G4xx_HAL_USART_EX_H
+#define STM32G4xx_HAL_USART_EX_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32g4xx_hal_def.h"
+
+/** @addtogroup STM32G4xx_HAL_Driver
+  * @{
+  */
+
+/** @addtogroup USARTEx
+  * @{
+  */
+
+/* Exported types ------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+/** @defgroup USARTEx_Exported_Constants USARTEx Exported Constants
+  * @{
+  */
+
+/** @defgroup USARTEx_Word_Length USARTEx Word Length
+  * @{
+  */
+#define USART_WORDLENGTH_7B                  (USART_CR1_M1)   /*!< 7-bit long USART frame */
+#define USART_WORDLENGTH_8B                  (0x00000000U)    /*!< 8-bit long USART frame */
+#define USART_WORDLENGTH_9B                  (USART_CR1_M0)   /*!< 9-bit long USART frame */
+/**
+  * @}
+  */
+
+/** @defgroup USARTEx_Slave_Select_management USARTEx Slave Select Management
+  * @{
+  */
+#define USART_NSS_HARD                        0x00000000U          /*!< SPI slave selection depends on NSS input pin              */
+#define USART_NSS_SOFT                        USART_CR2_DIS_NSS    /*!< SPI slave is always selected and NSS input pin is ignored */
+/**
+  * @}
+  */
+
+
+/** @defgroup USARTEx_Slave_Mode USARTEx Synchronous Slave mode enable
+  * @brief    USART SLAVE mode
+  * @{
+  */
+#define USART_SLAVEMODE_DISABLE   0x00000000U     /*!< USART SPI Slave Mode Enable  */
+#define USART_SLAVEMODE_ENABLE    USART_CR2_SLVEN /*!< USART SPI Slave Mode Disable */
+/**
+  * @}
+  */
+
+/** @defgroup USARTEx_FIFO_mode USARTEx FIFO  mode
+  * @brief    USART FIFO  mode
+  * @{
+  */
+#define USART_FIFOMODE_DISABLE        0x00000000U                   /*!< FIFO mode disable */
+#define USART_FIFOMODE_ENABLE         USART_CR1_FIFOEN              /*!< FIFO mode enable  */
+/**
+  * @}
+  */
+
+/** @defgroup USARTEx_TXFIFO_threshold_level USARTEx TXFIFO threshold level
+  * @brief    USART TXFIFO level
+  * @{
+  */
+#define USART_TXFIFO_THRESHOLD_1_8   0x00000000U                               /*!< TXFIFO reaches 1/8 of its depth */
+#define USART_TXFIFO_THRESHOLD_1_4   USART_CR3_TXFTCFG_0                       /*!< TXFIFO reaches 1/4 of its depth */
+#define USART_TXFIFO_THRESHOLD_1_2   USART_CR3_TXFTCFG_1                       /*!< TXFIFO reaches 1/2 of its depth */
+#define USART_TXFIFO_THRESHOLD_3_4   (USART_CR3_TXFTCFG_0|USART_CR3_TXFTCFG_1) /*!< TXFIFO reaches 3/4 of its depth */
+#define USART_TXFIFO_THRESHOLD_7_8   USART_CR3_TXFTCFG_2                       /*!< TXFIFO reaches 7/8 of its depth */
+#define USART_TXFIFO_THRESHOLD_8_8   (USART_CR3_TXFTCFG_2|USART_CR3_TXFTCFG_0) /*!< TXFIFO becomes empty            */
+/**
+  * @}
+  */
+
+/** @defgroup USARTEx_RXFIFO_threshold_level USARTEx RXFIFO threshold level
+  * @brief    USART RXFIFO level
+  * @{
+  */
+#define USART_RXFIFO_THRESHOLD_1_8   0x00000000U                               /*!< RXFIFO FIFO reaches 1/8 of its depth */
+#define USART_RXFIFO_THRESHOLD_1_4   USART_CR3_RXFTCFG_0                       /*!< RXFIFO FIFO reaches 1/4 of its depth */
+#define USART_RXFIFO_THRESHOLD_1_2   USART_CR3_RXFTCFG_1                       /*!< RXFIFO FIFO reaches 1/2 of its depth */
+#define USART_RXFIFO_THRESHOLD_3_4   (USART_CR3_RXFTCFG_0|USART_CR3_RXFTCFG_1) /*!< RXFIFO FIFO reaches 3/4 of its depth */
+#define USART_RXFIFO_THRESHOLD_7_8   USART_CR3_RXFTCFG_2                       /*!< RXFIFO FIFO reaches 7/8 of its depth */
+#define USART_RXFIFO_THRESHOLD_8_8   (USART_CR3_RXFTCFG_2|USART_CR3_RXFTCFG_0) /*!< RXFIFO FIFO becomes full             */
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/* Private macros ------------------------------------------------------------*/
+/** @defgroup USARTEx_Private_Macros USARTEx Private Macros
+  * @{
+  */
+
+/** @brief  Compute the USART mask to apply to retrieve the received data
+  *         according to the word length and to the parity bits activation.
+  * @note   If PCE = 1, the parity bit is not included in the data extracted
+  *         by the reception API().
+  *         This masking operation is not carried out in the case of
+  *         DMA transfers.
+  * @param  __HANDLE__ specifies the USART Handle.
+  * @retval None, the mask to apply to USART RDR register is stored in (__HANDLE__)->Mask field.
+  */
+#define USART_MASK_COMPUTATION(__HANDLE__)                            \
+  do {                                                                \
+    if ((__HANDLE__)->Init.WordLength == USART_WORDLENGTH_9B)         \
+    {                                                                 \
+      if ((__HANDLE__)->Init.Parity == USART_PARITY_NONE)             \
+      {                                                               \
+        (__HANDLE__)->Mask = 0x01FFU;                                 \
+      }                                                               \
+      else                                                            \
+      {                                                               \
+        (__HANDLE__)->Mask = 0x00FFU;                                 \
+      }                                                               \
+    }                                                                 \
+    else if ((__HANDLE__)->Init.WordLength == USART_WORDLENGTH_8B)    \
+    {                                                                 \
+      if ((__HANDLE__)->Init.Parity == USART_PARITY_NONE)             \
+      {                                                               \
+        (__HANDLE__)->Mask = 0x00FFU;                                 \
+      }                                                               \
+      else                                                            \
+      {                                                               \
+        (__HANDLE__)->Mask = 0x007FU;                                 \
+      }                                                               \
+    }                                                                 \
+    else if ((__HANDLE__)->Init.WordLength == USART_WORDLENGTH_7B)    \
+    {                                                                 \
+      if ((__HANDLE__)->Init.Parity == USART_PARITY_NONE)             \
+      {                                                               \
+        (__HANDLE__)->Mask = 0x007FU;                                 \
+      }                                                               \
+      else                                                            \
+      {                                                               \
+        (__HANDLE__)->Mask = 0x003FU;                                 \
+      }                                                               \
+    }                                                                 \
+    else                                                              \
+    {                                                                 \
+      (__HANDLE__)->Mask = 0x0000U;                                   \
+    }                                                                 \
+  } while(0U)
+
+/**
+  * @brief Ensure that USART frame length is valid.
+  * @param __LENGTH__ USART frame length.
+  * @retval SET (__LENGTH__ is valid) or RESET (__LENGTH__ is invalid)
+  */
+#define IS_USART_WORD_LENGTH(__LENGTH__) (((__LENGTH__) == USART_WORDLENGTH_7B) || \
+                                          ((__LENGTH__) == USART_WORDLENGTH_8B) || \
+                                          ((__LENGTH__) == USART_WORDLENGTH_9B))
+
+/**
+  * @brief Ensure that USART Negative Slave Select (NSS) pin management is valid.
+  * @param __NSS__ USART Negative Slave Select pin management.
+  * @retval SET (__NSS__ is valid) or RESET (__NSS__ is invalid)
+  */
+#define IS_USART_NSS(__NSS__) (((__NSS__) == USART_NSS_HARD) || \
+                               ((__NSS__) == USART_NSS_SOFT))
+
+/**
+  * @brief Ensure that USART Slave Mode is valid.
+  * @param __STATE__ USART Slave Mode.
+  * @retval SET (__STATE__ is valid) or RESET (__STATE__ is invalid)
+  */
+#define IS_USART_SLAVEMODE(__STATE__)   (((__STATE__) == USART_SLAVEMODE_DISABLE ) || \
+                                         ((__STATE__) == USART_SLAVEMODE_ENABLE))
+
+/**
+  * @brief Ensure that USART FIFO mode is valid.
+  * @param __STATE__ USART FIFO mode.
+  * @retval SET (__STATE__ is valid) or RESET (__STATE__ is invalid)
+  */
+#define IS_USART_FIFO_MODE_STATE(__STATE__) (((__STATE__) == USART_FIFOMODE_DISABLE ) || \
+                                             ((__STATE__) == USART_FIFOMODE_ENABLE))
+
+/**
+  * @brief Ensure that USART TXFIFO threshold level is valid.
+  * @param __THRESHOLD__ USART TXFIFO threshold level.
+  * @retval SET (__THRESHOLD__ is valid) or RESET (__THRESHOLD__ is invalid)
+  */
+#define IS_USART_TXFIFO_THRESHOLD(__THRESHOLD__)  (((__THRESHOLD__) == USART_TXFIFO_THRESHOLD_1_8)  || \
+                                                   ((__THRESHOLD__) == USART_TXFIFO_THRESHOLD_1_4)  || \
+                                                   ((__THRESHOLD__) == USART_TXFIFO_THRESHOLD_1_2)  || \
+                                                   ((__THRESHOLD__) == USART_TXFIFO_THRESHOLD_3_4)  || \
+                                                   ((__THRESHOLD__) == USART_TXFIFO_THRESHOLD_7_8)  || \
+                                                   ((__THRESHOLD__) == USART_TXFIFO_THRESHOLD_8_8))
+
+/**
+  * @brief Ensure that USART RXFIFO threshold level is valid.
+  * @param __THRESHOLD__ USART RXFIFO threshold level.
+  * @retval SET (__THRESHOLD__ is valid) or RESET (__THRESHOLD__ is invalid)
+  */
+#define IS_USART_RXFIFO_THRESHOLD(__THRESHOLD__)  (((__THRESHOLD__) == USART_RXFIFO_THRESHOLD_1_8)  || \
+                                                   ((__THRESHOLD__) == USART_RXFIFO_THRESHOLD_1_4)  || \
+                                                   ((__THRESHOLD__) == USART_RXFIFO_THRESHOLD_1_2)  || \
+                                                   ((__THRESHOLD__) == USART_RXFIFO_THRESHOLD_3_4)  || \
+                                                   ((__THRESHOLD__) == USART_RXFIFO_THRESHOLD_7_8)  || \
+                                                   ((__THRESHOLD__) == USART_RXFIFO_THRESHOLD_8_8))
+/**
+  * @}
+  */
+
+/* Exported functions --------------------------------------------------------*/
+/** @addtogroup USARTEx_Exported_Functions
+  * @{
+  */
+
+/** @addtogroup USARTEx_Exported_Functions_Group1
+  * @{
+  */
+
+/* IO operation functions *****************************************************/
+void HAL_USARTEx_RxFifoFullCallback(USART_HandleTypeDef *husart);
+void HAL_USARTEx_TxFifoEmptyCallback(USART_HandleTypeDef *husart);
+
+/**
+  * @}
+  */
+
+/** @addtogroup USARTEx_Exported_Functions_Group2
+  * @{
+  */
+
+/* Peripheral Control functions ***********************************************/
+HAL_StatusTypeDef HAL_USARTEx_EnableSlaveMode(USART_HandleTypeDef *husart);
+HAL_StatusTypeDef HAL_USARTEx_DisableSlaveMode(USART_HandleTypeDef *husart);
+HAL_StatusTypeDef HAL_USARTEx_ConfigNSS(USART_HandleTypeDef *husart, uint32_t NSSConfig);
+HAL_StatusTypeDef HAL_USARTEx_EnableFifoMode(USART_HandleTypeDef *husart);
+HAL_StatusTypeDef HAL_USARTEx_DisableFifoMode(USART_HandleTypeDef *husart);
+HAL_StatusTypeDef HAL_USARTEx_SetTxFifoThreshold(USART_HandleTypeDef *husart, uint32_t Threshold);
+HAL_StatusTypeDef HAL_USARTEx_SetRxFifoThreshold(USART_HandleTypeDef *husart, uint32_t Threshold);
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* STM32G4xx_HAL_USART_EX_H */
+
diff --git a/starter-projects/servo/p1-pwm/Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_uart.c b/starter-projects/servo/p1-pwm/Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_uart.c
new file mode 100644
index 0000000..5fd785e
--- /dev/null
+++ b/starter-projects/servo/p1-pwm/Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_uart.c
@@ -0,0 +1,4696 @@
+/**
+  ******************************************************************************
+  * @file    stm32g4xx_hal_uart.c
+  * @author  MCD Application Team
+  * @brief   UART HAL module driver.
+  *          This file provides firmware functions to manage the following
+  *          functionalities of the Universal Asynchronous Receiver Transmitter Peripheral (UART).
+  *           + Initialization and de-initialization functions
+  *           + IO operation functions
+  *           + Peripheral Control functions
+  *
+  *
+  ******************************************************************************
+  * @attention
+  *
+  * Copyright (c) 2019 STMicroelectronics.
+  * All rights reserved.
+  *
+  * This software is licensed under terms that can be found in the LICENSE file
+  * in the root directory of this software component.
+  * If no LICENSE file comes with this software, it is provided AS-IS.
+  *
+  ******************************************************************************
+  @verbatim
+ ===============================================================================
+                        ##### How to use this driver #####
+ ===============================================================================
+  [..]
+    The UART HAL driver can be used as follows:
+
+    (#) Declare a UART_HandleTypeDef handle structure (eg. UART_HandleTypeDef huart).
+    (#) Initialize the UART low level resources by implementing the HAL_UART_MspInit() API:
+        (++) Enable the USARTx interface clock.
+        (++) UART pins configuration:
+            (+++) Enable the clock for the UART GPIOs.
+            (+++) Configure these UART pins as alternate function pull-up.
+        (++) NVIC configuration if you need to use interrupt process (HAL_UART_Transmit_IT()
+             and HAL_UART_Receive_IT() APIs):
+            (+++) Configure the USARTx interrupt priority.
+            (+++) Enable the NVIC USART IRQ handle.
+        (++) UART interrupts handling:
+              -@@-  The specific UART interrupts (Transmission complete interrupt,
+                RXNE interrupt, RX/TX FIFOs related interrupts and Error Interrupts)
+                are managed using the macros __HAL_UART_ENABLE_IT() and __HAL_UART_DISABLE_IT()
+                inside the transmit and receive processes.
+        (++) DMA Configuration if you need to use DMA process (HAL_UART_Transmit_DMA()
+             and HAL_UART_Receive_DMA() APIs):
+            (+++) Declare a DMA handle structure for the Tx/Rx channel.
+            (+++) Enable the DMAx interface clock.
+            (+++) Configure the declared DMA handle structure with the required Tx/Rx parameters.
+            (+++) Configure the DMA Tx/Rx channel.
+            (+++) Associate the initialized DMA handle to the UART DMA Tx/Rx handle.
+            (+++) Configure the priority and enable the NVIC for the transfer complete
+                  interrupt on the DMA Tx/Rx channel.
+
+    (#) Program the Baud Rate, Word Length, Stop Bit, Parity, Prescaler value , Hardware
+        flow control and Mode (Receiver/Transmitter) in the huart handle Init structure.
+
+    (#) If required, program UART advanced features (TX/RX pins swap, auto Baud rate detection,...)
+        in the huart handle AdvancedInit structure.
+
+    (#) For the UART asynchronous mode, initialize the UART registers by calling
+        the HAL_UART_Init() API.
+
+    (#) For the UART Half duplex mode, initialize the UART registers by calling
+        the HAL_HalfDuplex_Init() API.
+
+    (#) For the UART LIN (Local Interconnection Network) mode, initialize the UART registers
+        by calling the HAL_LIN_Init() API.
+
+    (#) For the UART Multiprocessor mode, initialize the UART registers
+        by calling the HAL_MultiProcessor_Init() API.
+
+    (#) For the UART RS485 Driver Enabled mode, initialize the UART registers
+        by calling the HAL_RS485Ex_Init() API.
+
+    [..]
+    (@) These API's (HAL_UART_Init(), HAL_HalfDuplex_Init(), HAL_LIN_Init(), HAL_MultiProcessor_Init(),
+        also configure the low level Hardware GPIO, CLOCK, CORTEX...etc) by
+        calling the customized HAL_UART_MspInit() API.
+
+    ##### Callback registration #####
+    ==================================
+
+    [..]
+    The compilation define USE_HAL_UART_REGISTER_CALLBACKS when set to 1
+    allows the user to configure dynamically the driver callbacks.
+
+    [..]
+    Use Function HAL_UART_RegisterCallback() to register a user callback.
+    Function HAL_UART_RegisterCallback() allows to register following callbacks:
+    (+) TxHalfCpltCallback        : Tx Half Complete Callback.
+    (+) TxCpltCallback            : Tx Complete Callback.
+    (+) RxHalfCpltCallback        : Rx Half Complete Callback.
+    (+) RxCpltCallback            : Rx Complete Callback.
+    (+) ErrorCallback             : Error Callback.
+    (+) AbortCpltCallback         : Abort Complete Callback.
+    (+) AbortTransmitCpltCallback : Abort Transmit Complete Callback.
+    (+) AbortReceiveCpltCallback  : Abort Receive Complete Callback.
+    (+) WakeupCallback            : Wakeup Callback.
+    (+) RxFifoFullCallback        : Rx Fifo Full Callback.
+    (+) TxFifoEmptyCallback       : Tx Fifo Empty Callback.
+    (+) MspInitCallback           : UART MspInit.
+    (+) MspDeInitCallback         : UART MspDeInit.
+    This function takes as parameters the HAL peripheral handle, the Callback ID
+    and a pointer to the user callback function.
+
+    [..]
+    Use function HAL_UART_UnRegisterCallback() to reset a callback to the default
+    weak function.
+    HAL_UART_UnRegisterCallback() takes as parameters the HAL peripheral handle,
+    and the Callback ID.
+    This function allows to reset following callbacks:
+    (+) TxHalfCpltCallback        : Tx Half Complete Callback.
+    (+) TxCpltCallback            : Tx Complete Callback.
+    (+) RxHalfCpltCallback        : Rx Half Complete Callback.
+    (+) RxCpltCallback            : Rx Complete Callback.
+    (+) ErrorCallback             : Error Callback.
+    (+) AbortCpltCallback         : Abort Complete Callback.
+    (+) AbortTransmitCpltCallback : Abort Transmit Complete Callback.
+    (+) AbortReceiveCpltCallback  : Abort Receive Complete Callback.
+    (+) WakeupCallback            : Wakeup Callback.
+    (+) RxFifoFullCallback        : Rx Fifo Full Callback.
+    (+) TxFifoEmptyCallback       : Tx Fifo Empty Callback.
+    (+) MspInitCallback           : UART MspInit.
+    (+) MspDeInitCallback         : UART MspDeInit.
+
+    [..]
+    For specific callback RxEventCallback, use dedicated registration/reset functions:
+    respectively HAL_UART_RegisterRxEventCallback() , HAL_UART_UnRegisterRxEventCallback().
+
+    [..]
+    By default, after the HAL_UART_Init() and when the state is HAL_UART_STATE_RESET
+    all callbacks are set to the corresponding weak functions:
+    examples HAL_UART_TxCpltCallback(), HAL_UART_RxHalfCpltCallback().
+    Exception done for MspInit and MspDeInit functions that are respectively
+    reset to the legacy weak functions in the HAL_UART_Init()
+    and HAL_UART_DeInit() only when these callbacks are null (not registered beforehand).
+    If not, MspInit or MspDeInit are not null, the HAL_UART_Init() and HAL_UART_DeInit()
+    keep and use the user MspInit/MspDeInit callbacks (registered beforehand).
+
+    [..]
+    Callbacks can be registered/unregistered in HAL_UART_STATE_READY state only.
+    Exception done MspInit/MspDeInit that can be registered/unregistered
+    in HAL_UART_STATE_READY or HAL_UART_STATE_RESET state, thus registered (user)
+    MspInit/DeInit callbacks can be used during the Init/DeInit.
+    In that case first register the MspInit/MspDeInit user callbacks
+    using HAL_UART_RegisterCallback() before calling HAL_UART_DeInit()
+    or HAL_UART_Init() function.
+
+    [..]
+    When The compilation define USE_HAL_UART_REGISTER_CALLBACKS is set to 0 or
+    not defined, the callback registration feature is not available
+    and weak callbacks are used.
+
+
+  @endverbatim
+  ******************************************************************************
+  */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32g4xx_hal.h"
+
+/** @addtogroup STM32G4xx_HAL_Driver
+  * @{
+  */
+
+/** @defgroup UART UART
+  * @brief HAL UART module driver
+  * @{
+  */
+
+#ifdef HAL_UART_MODULE_ENABLED
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/** @defgroup UART_Private_Constants UART Private Constants
+  * @{
+  */
+#define USART_CR1_FIELDS  ((uint32_t)(USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | USART_CR1_TE | USART_CR1_RE | \
+                                      USART_CR1_OVER8 | USART_CR1_FIFOEN)) /*!< UART or USART CR1 fields of parameters set by UART_SetConfig API */
+
+#define USART_CR3_FIELDS  ((uint32_t)(USART_CR3_RTSE | USART_CR3_CTSE | USART_CR3_ONEBIT | USART_CR3_TXFTCFG | \
+                                      USART_CR3_RXFTCFG)) /*!< UART or USART CR3 fields of parameters set by UART_SetConfig API */
+
+#define LPUART_BRR_MIN  0x00000300U  /* LPUART BRR minimum authorized value */
+#define LPUART_BRR_MAX  0x000FFFFFU  /* LPUART BRR maximum authorized value */
+
+#define UART_BRR_MIN    0x10U        /* UART BRR minimum authorized value */
+#define UART_BRR_MAX    0x0000FFFFU  /* UART BRR maximum authorized value */
+/**
+  * @}
+  */
+
+/* Private macros ------------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/** @addtogroup UART_Private_Functions
+  * @{
+  */
+static void UART_EndRxTransfer(UART_HandleTypeDef *huart);
+static void UART_EndTxTransfer(UART_HandleTypeDef *huart);
+static void UART_DMATransmitCplt(DMA_HandleTypeDef *hdma);
+static void UART_DMAReceiveCplt(DMA_HandleTypeDef *hdma);
+static void UART_DMARxHalfCplt(DMA_HandleTypeDef *hdma);
+static void UART_DMATxHalfCplt(DMA_HandleTypeDef *hdma);
+static void UART_DMAError(DMA_HandleTypeDef *hdma);
+static void UART_DMAAbortOnError(DMA_HandleTypeDef *hdma);
+static void UART_DMATxAbortCallback(DMA_HandleTypeDef *hdma);
+static void UART_DMARxAbortCallback(DMA_HandleTypeDef *hdma);
+static void UART_DMATxOnlyAbortCallback(DMA_HandleTypeDef *hdma);
+static void UART_DMARxOnlyAbortCallback(DMA_HandleTypeDef *hdma);
+static void UART_TxISR_8BIT(UART_HandleTypeDef *huart);
+static void UART_TxISR_16BIT(UART_HandleTypeDef *huart);
+static void UART_TxISR_8BIT_FIFOEN(UART_HandleTypeDef *huart);
+static void UART_TxISR_16BIT_FIFOEN(UART_HandleTypeDef *huart);
+static void UART_EndTransmit_IT(UART_HandleTypeDef *huart);
+static void UART_RxISR_8BIT(UART_HandleTypeDef *huart);
+static void UART_RxISR_16BIT(UART_HandleTypeDef *huart);
+static void UART_RxISR_8BIT_FIFOEN(UART_HandleTypeDef *huart);
+static void UART_RxISR_16BIT_FIFOEN(UART_HandleTypeDef *huart);
+/**
+  * @}
+  */
+
+/* Private variables ---------------------------------------------------------*/
+/** @addtogroup UART_Private_variables
+  * @{
+  */
+const uint16_t UARTPrescTable[12] = {1U, 2U, 4U, 6U, 8U, 10U, 12U, 16U, 32U, 64U, 128U, 256U};
+/**
+  * @}
+  */
+
+/* Exported Constants --------------------------------------------------------*/
+/* Exported functions --------------------------------------------------------*/
+
+/** @defgroup UART_Exported_Functions UART Exported Functions
+  * @{
+  */
+
+/** @defgroup UART_Exported_Functions_Group1 Initialization and de-initialization functions
+  *  @brief    Initialization and Configuration functions
+  *
+@verbatim
+===============================================================================
+            ##### Initialization and Configuration functions #####
+ ===============================================================================
+    [..]
+    This subsection provides a set of functions allowing to initialize the USARTx or the UARTy
+    in asynchronous mode.
+      (+) For the asynchronous mode the parameters below can be configured:
+        (++) Baud Rate
+        (++) Word Length
+        (++) Stop Bit
+        (++) Parity: If the parity is enabled, then the MSB bit of the data written
+             in the data register is transmitted but is changed by the parity bit.
+        (++) Hardware flow control
+        (++) Receiver/transmitter modes
+        (++) Over Sampling Method
+        (++) One-Bit Sampling Method
+      (+) For the asynchronous mode, the following advanced features can be configured as well:
+        (++) TX and/or RX pin level inversion
+        (++) data logical level inversion
+        (++) RX and TX pins swap
+        (++) RX overrun detection disabling
+        (++) DMA disabling on RX error
+        (++) MSB first on communication line
+        (++) auto Baud rate detection
+    [..]
+    The HAL_UART_Init(), HAL_HalfDuplex_Init(), HAL_LIN_Init()and HAL_MultiProcessor_Init()API
+    follow respectively the UART asynchronous, UART Half duplex, UART LIN mode
+    and UART multiprocessor mode configuration procedures (details for the procedures
+    are available in reference manual).
+
+@endverbatim
+
+  Depending on the frame length defined by the M1 and M0 bits (7-bit,
+  8-bit or 9-bit), the possible UART formats are listed in the
+  following table.
+
+  Table 1. UART frame format.
+    +-----------------------------------------------------------------------+
+    |  M1 bit |  M0 bit |  PCE bit  |             UART frame                |
+    |---------|---------|-----------|---------------------------------------|
+    |    0    |    0    |    0      |    | SB |    8 bit data   | STB |     |
+    |---------|---------|-----------|---------------------------------------|
+    |    0    |    0    |    1      |    | SB | 7 bit data | PB | STB |     |
+    |---------|---------|-----------|---------------------------------------|
+    |    0    |    1    |    0      |    | SB |    9 bit data   | STB |     |
+    |---------|---------|-----------|---------------------------------------|
+    |    0    |    1    |    1      |    | SB | 8 bit data | PB | STB |     |
+    |---------|---------|-----------|---------------------------------------|
+    |    1    |    0    |    0      |    | SB |    7 bit data   | STB |     |
+    |---------|---------|-----------|---------------------------------------|
+    |    1    |    0    |    1      |    | SB | 6 bit data | PB | STB |     |
+    +-----------------------------------------------------------------------+
+
+  * @{
+  */
+
+/**
+  * @brief Initialize the UART mode according to the specified
+  *        parameters in the UART_InitTypeDef and initialize the associated handle.
+  * @param huart UART handle.
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_UART_Init(UART_HandleTypeDef *huart)
+{
+  /* Check the UART handle allocation */
+  if (huart == NULL)
+  {
+    return HAL_ERROR;
+  }
+
+  if (huart->Init.HwFlowCtl != UART_HWCONTROL_NONE)
+  {
+    /* Check the parameters */
+    assert_param(IS_UART_HWFLOW_INSTANCE(huart->Instance));
+  }
+  else
+  {
+    /* Check the parameters */
+    assert_param((IS_UART_INSTANCE(huart->Instance)) || (IS_LPUART_INSTANCE(huart->Instance)));
+  }
+
+  if (huart->gState == HAL_UART_STATE_RESET)
+  {
+    /* Allocate lock resource and initialize it */
+    huart->Lock = HAL_UNLOCKED;
+
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+    UART_InitCallbacksToDefault(huart);
+
+    if (huart->MspInitCallback == NULL)
+    {
+      huart->MspInitCallback = HAL_UART_MspInit;
+    }
+
+    /* Init the low level hardware */
+    huart->MspInitCallback(huart);
+#else
+    /* Init the low level hardware : GPIO, CLOCK */
+    HAL_UART_MspInit(huart);
+#endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
+  }
+
+  huart->gState = HAL_UART_STATE_BUSY;
+
+  __HAL_UART_DISABLE(huart);
+
+  /* Perform advanced settings configuration */
+  /* For some items, configuration requires to be done prior TE and RE bits are set */
+  if (huart->AdvancedInit.AdvFeatureInit != UART_ADVFEATURE_NO_INIT)
+  {
+    UART_AdvFeatureConfig(huart);
+  }
+
+  /* Set the UART Communication parameters */
+  if (UART_SetConfig(huart) == HAL_ERROR)
+  {
+    return HAL_ERROR;
+  }
+
+  /* In asynchronous mode, the following bits must be kept cleared:
+  - LINEN and CLKEN bits in the USART_CR2 register,
+  - SCEN, HDSEL and IREN  bits in the USART_CR3 register.*/
+  CLEAR_BIT(huart->Instance->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN));
+  CLEAR_BIT(huart->Instance->CR3, (USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN));
+
+  __HAL_UART_ENABLE(huart);
+
+  /* TEACK and/or REACK to check before moving huart->gState and huart->RxState to Ready */
+  return (UART_CheckIdleState(huart));
+}
+
+/**
+  * @brief Initialize the half-duplex mode according to the specified
+  *        parameters in the UART_InitTypeDef and creates the associated handle.
+  * @param huart UART handle.
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_HalfDuplex_Init(UART_HandleTypeDef *huart)
+{
+  /* Check the UART handle allocation */
+  if (huart == NULL)
+  {
+    return HAL_ERROR;
+  }
+
+  /* Check UART instance */
+  assert_param(IS_UART_HALFDUPLEX_INSTANCE(huart->Instance));
+
+  if (huart->gState == HAL_UART_STATE_RESET)
+  {
+    /* Allocate lock resource and initialize it */
+    huart->Lock = HAL_UNLOCKED;
+
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+    UART_InitCallbacksToDefault(huart);
+
+    if (huart->MspInitCallback == NULL)
+    {
+      huart->MspInitCallback = HAL_UART_MspInit;
+    }
+
+    /* Init the low level hardware */
+    huart->MspInitCallback(huart);
+#else
+    /* Init the low level hardware : GPIO, CLOCK */
+    HAL_UART_MspInit(huart);
+#endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
+  }
+
+  huart->gState = HAL_UART_STATE_BUSY;
+
+  __HAL_UART_DISABLE(huart);
+
+  /* Perform advanced settings configuration */
+  /* For some items, configuration requires to be done prior TE and RE bits are set */
+  if (huart->AdvancedInit.AdvFeatureInit != UART_ADVFEATURE_NO_INIT)
+  {
+    UART_AdvFeatureConfig(huart);
+  }
+
+  /* Set the UART Communication parameters */
+  if (UART_SetConfig(huart) == HAL_ERROR)
+  {
+    return HAL_ERROR;
+  }
+
+  /* In half-duplex mode, the following bits must be kept cleared:
+  - LINEN and CLKEN bits in the USART_CR2 register,
+  - SCEN and IREN bits in the USART_CR3 register.*/
+  CLEAR_BIT(huart->Instance->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN));
+  CLEAR_BIT(huart->Instance->CR3, (USART_CR3_IREN | USART_CR3_SCEN));
+
+  /* Enable the Half-Duplex mode by setting the HDSEL bit in the CR3 register */
+  SET_BIT(huart->Instance->CR3, USART_CR3_HDSEL);
+
+  __HAL_UART_ENABLE(huart);
+
+  /* TEACK and/or REACK to check before moving huart->gState and huart->RxState to Ready */
+  return (UART_CheckIdleState(huart));
+}
+
+
+/**
+  * @brief Initialize the LIN mode according to the specified
+  *        parameters in the UART_InitTypeDef and creates the associated handle.
+  * @param huart             UART handle.
+  * @param BreakDetectLength Specifies the LIN break detection length.
+  *        This parameter can be one of the following values:
+  *          @arg @ref UART_LINBREAKDETECTLENGTH_10B 10-bit break detection
+  *          @arg @ref UART_LINBREAKDETECTLENGTH_11B 11-bit break detection
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_LIN_Init(UART_HandleTypeDef *huart, uint32_t BreakDetectLength)
+{
+  /* Check the UART handle allocation */
+  if (huart == NULL)
+  {
+    return HAL_ERROR;
+  }
+
+  /* Check the LIN UART instance */
+  assert_param(IS_UART_LIN_INSTANCE(huart->Instance));
+  /* Check the Break detection length parameter */
+  assert_param(IS_UART_LIN_BREAK_DETECT_LENGTH(BreakDetectLength));
+
+  /* LIN mode limited to 16-bit oversampling only */
+  if (huart->Init.OverSampling == UART_OVERSAMPLING_8)
+  {
+    return HAL_ERROR;
+  }
+  /* LIN mode limited to 8-bit data length */
+  if (huart->Init.WordLength != UART_WORDLENGTH_8B)
+  {
+    return HAL_ERROR;
+  }
+
+  if (huart->gState == HAL_UART_STATE_RESET)
+  {
+    /* Allocate lock resource and initialize it */
+    huart->Lock = HAL_UNLOCKED;
+
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+    UART_InitCallbacksToDefault(huart);
+
+    if (huart->MspInitCallback == NULL)
+    {
+      huart->MspInitCallback = HAL_UART_MspInit;
+    }
+
+    /* Init the low level hardware */
+    huart->MspInitCallback(huart);
+#else
+    /* Init the low level hardware : GPIO, CLOCK */
+    HAL_UART_MspInit(huart);
+#endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
+  }
+
+  huart->gState = HAL_UART_STATE_BUSY;
+
+  __HAL_UART_DISABLE(huart);
+
+  /* Perform advanced settings configuration */
+  /* For some items, configuration requires to be done prior TE and RE bits are set */
+  if (huart->AdvancedInit.AdvFeatureInit != UART_ADVFEATURE_NO_INIT)
+  {
+    UART_AdvFeatureConfig(huart);
+  }
+
+  /* Set the UART Communication parameters */
+  if (UART_SetConfig(huart) == HAL_ERROR)
+  {
+    return HAL_ERROR;
+  }
+
+  /* In LIN mode, the following bits must be kept cleared:
+  - LINEN and CLKEN bits in the USART_CR2 register,
+  - SCEN and IREN bits in the USART_CR3 register.*/
+  CLEAR_BIT(huart->Instance->CR2, USART_CR2_CLKEN);
+  CLEAR_BIT(huart->Instance->CR3, (USART_CR3_HDSEL | USART_CR3_IREN | USART_CR3_SCEN));
+
+  /* Enable the LIN mode by setting the LINEN bit in the CR2 register */
+  SET_BIT(huart->Instance->CR2, USART_CR2_LINEN);
+
+  /* Set the USART LIN Break detection length. */
+  MODIFY_REG(huart->Instance->CR2, USART_CR2_LBDL, BreakDetectLength);
+
+  __HAL_UART_ENABLE(huart);
+
+  /* TEACK and/or REACK to check before moving huart->gState and huart->RxState to Ready */
+  return (UART_CheckIdleState(huart));
+}
+
+
+/**
+  * @brief Initialize the multiprocessor mode according to the specified
+  *        parameters in the UART_InitTypeDef and initialize the associated handle.
+  * @param huart        UART handle.
+  * @param Address      UART node address (4-, 6-, 7- or 8-bit long).
+  * @param WakeUpMethod Specifies the UART wakeup method.
+  *        This parameter can be one of the following values:
+  *          @arg @ref UART_WAKEUPMETHOD_IDLELINE WakeUp by an idle line detection
+  *          @arg @ref UART_WAKEUPMETHOD_ADDRESSMARK WakeUp by an address mark
+  * @note  If the user resorts to idle line detection wake up, the Address parameter
+  *        is useless and ignored by the initialization function.
+  * @note  If the user resorts to address mark wake up, the address length detection
+  *        is configured by default to 4 bits only. For the UART to be able to
+  *        manage 6-, 7- or 8-bit long addresses detection, the API
+  *        HAL_MultiProcessorEx_AddressLength_Set() must be called after
+  *        HAL_MultiProcessor_Init().
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_MultiProcessor_Init(UART_HandleTypeDef *huart, uint8_t Address, uint32_t WakeUpMethod)
+{
+  /* Check the UART handle allocation */
+  if (huart == NULL)
+  {
+    return HAL_ERROR;
+  }
+
+  /* Check the wake up method parameter */
+  assert_param(IS_UART_WAKEUPMETHOD(WakeUpMethod));
+
+  if (huart->gState == HAL_UART_STATE_RESET)
+  {
+    /* Allocate lock resource and initialize it */
+    huart->Lock = HAL_UNLOCKED;
+
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+    UART_InitCallbacksToDefault(huart);
+
+    if (huart->MspInitCallback == NULL)
+    {
+      huart->MspInitCallback = HAL_UART_MspInit;
+    }
+
+    /* Init the low level hardware */
+    huart->MspInitCallback(huart);
+#else
+    /* Init the low level hardware : GPIO, CLOCK */
+    HAL_UART_MspInit(huart);
+#endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
+  }
+
+  huart->gState = HAL_UART_STATE_BUSY;
+
+  __HAL_UART_DISABLE(huart);
+
+  /* Perform advanced settings configuration */
+  /* For some items, configuration requires to be done prior TE and RE bits are set */
+  if (huart->AdvancedInit.AdvFeatureInit != UART_ADVFEATURE_NO_INIT)
+  {
+    UART_AdvFeatureConfig(huart);
+  }
+
+  /* Set the UART Communication parameters */
+  if (UART_SetConfig(huart) == HAL_ERROR)
+  {
+    return HAL_ERROR;
+  }
+
+  /* In multiprocessor mode, the following bits must be kept cleared:
+  - LINEN and CLKEN bits in the USART_CR2 register,
+  - SCEN, HDSEL and IREN  bits in the USART_CR3 register. */
+  CLEAR_BIT(huart->Instance->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN));
+  CLEAR_BIT(huart->Instance->CR3, (USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN));
+
+  if (WakeUpMethod == UART_WAKEUPMETHOD_ADDRESSMARK)
+  {
+    /* If address mark wake up method is chosen, set the USART address node */
+    MODIFY_REG(huart->Instance->CR2, USART_CR2_ADD, ((uint32_t)Address << UART_CR2_ADDRESS_LSB_POS));
+  }
+
+  /* Set the wake up method by setting the WAKE bit in the CR1 register */
+  MODIFY_REG(huart->Instance->CR1, USART_CR1_WAKE, WakeUpMethod);
+
+  __HAL_UART_ENABLE(huart);
+
+  /* TEACK and/or REACK to check before moving huart->gState and huart->RxState to Ready */
+  return (UART_CheckIdleState(huart));
+}
+
+
+/**
+  * @brief DeInitialize the UART peripheral.
+  * @param huart UART handle.
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_UART_DeInit(UART_HandleTypeDef *huart)
+{
+  /* Check the UART handle allocation */
+  if (huart == NULL)
+  {
+    return HAL_ERROR;
+  }
+
+  /* Check the parameters */
+  assert_param((IS_UART_INSTANCE(huart->Instance)) || (IS_LPUART_INSTANCE(huart->Instance)));
+
+  huart->gState = HAL_UART_STATE_BUSY;
+
+  __HAL_UART_DISABLE(huart);
+
+  huart->Instance->CR1 = 0x0U;
+  huart->Instance->CR2 = 0x0U;
+  huart->Instance->CR3 = 0x0U;
+
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+  if (huart->MspDeInitCallback == NULL)
+  {
+    huart->MspDeInitCallback = HAL_UART_MspDeInit;
+  }
+  /* DeInit the low level hardware */
+  huart->MspDeInitCallback(huart);
+#else
+  /* DeInit the low level hardware */
+  HAL_UART_MspDeInit(huart);
+#endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
+
+  huart->ErrorCode = HAL_UART_ERROR_NONE;
+  huart->gState = HAL_UART_STATE_RESET;
+  huart->RxState = HAL_UART_STATE_RESET;
+  huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
+  huart->RxEventType = HAL_UART_RXEVENT_TC;
+
+  __HAL_UNLOCK(huart);
+
+  return HAL_OK;
+}
+
+/**
+  * @brief Initialize the UART MSP.
+  * @param huart UART handle.
+  * @retval None
+  */
+__weak void HAL_UART_MspInit(UART_HandleTypeDef *huart)
+{
+  /* Prevent unused argument(s) compilation warning */
+  UNUSED(huart);
+
+  /* NOTE : This function should not be modified, when the callback is needed,
+            the HAL_UART_MspInit can be implemented in the user file
+   */
+}
+
+/**
+  * @brief DeInitialize the UART MSP.
+  * @param huart UART handle.
+  * @retval None
+  */
+__weak void HAL_UART_MspDeInit(UART_HandleTypeDef *huart)
+{
+  /* Prevent unused argument(s) compilation warning */
+  UNUSED(huart);
+
+  /* NOTE : This function should not be modified, when the callback is needed,
+            the HAL_UART_MspDeInit can be implemented in the user file
+   */
+}
+
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+/**
+  * @brief  Register a User UART Callback
+  *         To be used to override the weak predefined callback
+  * @note   The HAL_UART_RegisterCallback() may be called before HAL_UART_Init(), HAL_HalfDuplex_Init(),
+  *         HAL_LIN_Init(), HAL_MultiProcessor_Init() or HAL_RS485Ex_Init() in HAL_UART_STATE_RESET to register
+  *         callbacks for HAL_UART_MSPINIT_CB_ID and HAL_UART_MSPDEINIT_CB_ID
+  * @param  huart uart handle
+  * @param  CallbackID ID of the callback to be registered
+  *         This parameter can be one of the following values:
+  *           @arg @ref HAL_UART_TX_HALFCOMPLETE_CB_ID Tx Half Complete Callback ID
+  *           @arg @ref HAL_UART_TX_COMPLETE_CB_ID Tx Complete Callback ID
+  *           @arg @ref HAL_UART_RX_HALFCOMPLETE_CB_ID Rx Half Complete Callback ID
+  *           @arg @ref HAL_UART_RX_COMPLETE_CB_ID Rx Complete Callback ID
+  *           @arg @ref HAL_UART_ERROR_CB_ID Error Callback ID
+  *           @arg @ref HAL_UART_ABORT_COMPLETE_CB_ID Abort Complete Callback ID
+  *           @arg @ref HAL_UART_ABORT_TRANSMIT_COMPLETE_CB_ID Abort Transmit Complete Callback ID
+  *           @arg @ref HAL_UART_ABORT_RECEIVE_COMPLETE_CB_ID Abort Receive Complete Callback ID
+  *           @arg @ref HAL_UART_WAKEUP_CB_ID Wakeup Callback ID
+  *           @arg @ref HAL_UART_RX_FIFO_FULL_CB_ID Rx Fifo Full Callback ID
+  *           @arg @ref HAL_UART_TX_FIFO_EMPTY_CB_ID Tx Fifo Empty Callback ID
+  *           @arg @ref HAL_UART_MSPINIT_CB_ID MspInit Callback ID
+  *           @arg @ref HAL_UART_MSPDEINIT_CB_ID MspDeInit Callback ID
+  * @param  pCallback pointer to the Callback function
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_UART_RegisterCallback(UART_HandleTypeDef *huart, HAL_UART_CallbackIDTypeDef CallbackID,
+                                            pUART_CallbackTypeDef pCallback)
+{
+  HAL_StatusTypeDef status = HAL_OK;
+
+  if (pCallback == NULL)
+  {
+    huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
+
+    return HAL_ERROR;
+  }
+
+  if (huart->gState == HAL_UART_STATE_READY)
+  {
+    switch (CallbackID)
+    {
+      case HAL_UART_TX_HALFCOMPLETE_CB_ID :
+        huart->TxHalfCpltCallback = pCallback;
+        break;
+
+      case HAL_UART_TX_COMPLETE_CB_ID :
+        huart->TxCpltCallback = pCallback;
+        break;
+
+      case HAL_UART_RX_HALFCOMPLETE_CB_ID :
+        huart->RxHalfCpltCallback = pCallback;
+        break;
+
+      case HAL_UART_RX_COMPLETE_CB_ID :
+        huart->RxCpltCallback = pCallback;
+        break;
+
+      case HAL_UART_ERROR_CB_ID :
+        huart->ErrorCallback = pCallback;
+        break;
+
+      case HAL_UART_ABORT_COMPLETE_CB_ID :
+        huart->AbortCpltCallback = pCallback;
+        break;
+
+      case HAL_UART_ABORT_TRANSMIT_COMPLETE_CB_ID :
+        huart->AbortTransmitCpltCallback = pCallback;
+        break;
+
+      case HAL_UART_ABORT_RECEIVE_COMPLETE_CB_ID :
+        huart->AbortReceiveCpltCallback = pCallback;
+        break;
+
+      case HAL_UART_WAKEUP_CB_ID :
+        huart->WakeupCallback = pCallback;
+        break;
+
+      case HAL_UART_RX_FIFO_FULL_CB_ID :
+        huart->RxFifoFullCallback = pCallback;
+        break;
+
+      case HAL_UART_TX_FIFO_EMPTY_CB_ID :
+        huart->TxFifoEmptyCallback = pCallback;
+        break;
+
+      case HAL_UART_MSPINIT_CB_ID :
+        huart->MspInitCallback = pCallback;
+        break;
+
+      case HAL_UART_MSPDEINIT_CB_ID :
+        huart->MspDeInitCallback = pCallback;
+        break;
+
+      default :
+        huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
+
+        status =  HAL_ERROR;
+        break;
+    }
+  }
+  else if (huart->gState == HAL_UART_STATE_RESET)
+  {
+    switch (CallbackID)
+    {
+      case HAL_UART_MSPINIT_CB_ID :
+        huart->MspInitCallback = pCallback;
+        break;
+
+      case HAL_UART_MSPDEINIT_CB_ID :
+        huart->MspDeInitCallback = pCallback;
+        break;
+
+      default :
+        huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
+
+        status =  HAL_ERROR;
+        break;
+    }
+  }
+  else
+  {
+    huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
+
+    status =  HAL_ERROR;
+  }
+
+  return status;
+}
+
+/**
+  * @brief  Unregister an UART Callback
+  *         UART callaback is redirected to the weak predefined callback
+  * @note   The HAL_UART_UnRegisterCallback() may be called before HAL_UART_Init(), HAL_HalfDuplex_Init(),
+  *         HAL_LIN_Init(), HAL_MultiProcessor_Init() or HAL_RS485Ex_Init() in HAL_UART_STATE_RESET to un-register
+  *         callbacks for HAL_UART_MSPINIT_CB_ID and HAL_UART_MSPDEINIT_CB_ID
+  * @param  huart uart handle
+  * @param  CallbackID ID of the callback to be unregistered
+  *         This parameter can be one of the following values:
+  *           @arg @ref HAL_UART_TX_HALFCOMPLETE_CB_ID Tx Half Complete Callback ID
+  *           @arg @ref HAL_UART_TX_COMPLETE_CB_ID Tx Complete Callback ID
+  *           @arg @ref HAL_UART_RX_HALFCOMPLETE_CB_ID Rx Half Complete Callback ID
+  *           @arg @ref HAL_UART_RX_COMPLETE_CB_ID Rx Complete Callback ID
+  *           @arg @ref HAL_UART_ERROR_CB_ID Error Callback ID
+  *           @arg @ref HAL_UART_ABORT_COMPLETE_CB_ID Abort Complete Callback ID
+  *           @arg @ref HAL_UART_ABORT_TRANSMIT_COMPLETE_CB_ID Abort Transmit Complete Callback ID
+  *           @arg @ref HAL_UART_ABORT_RECEIVE_COMPLETE_CB_ID Abort Receive Complete Callback ID
+  *           @arg @ref HAL_UART_WAKEUP_CB_ID Wakeup Callback ID
+  *           @arg @ref HAL_UART_RX_FIFO_FULL_CB_ID Rx Fifo Full Callback ID
+  *           @arg @ref HAL_UART_TX_FIFO_EMPTY_CB_ID Tx Fifo Empty Callback ID
+  *           @arg @ref HAL_UART_MSPINIT_CB_ID MspInit Callback ID
+  *           @arg @ref HAL_UART_MSPDEINIT_CB_ID MspDeInit Callback ID
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_UART_UnRegisterCallback(UART_HandleTypeDef *huart, HAL_UART_CallbackIDTypeDef CallbackID)
+{
+  HAL_StatusTypeDef status = HAL_OK;
+
+  if (HAL_UART_STATE_READY == huart->gState)
+  {
+    switch (CallbackID)
+    {
+      case HAL_UART_TX_HALFCOMPLETE_CB_ID :
+        huart->TxHalfCpltCallback = HAL_UART_TxHalfCpltCallback;               /* Legacy weak  TxHalfCpltCallback    */
+        break;
+
+      case HAL_UART_TX_COMPLETE_CB_ID :
+        huart->TxCpltCallback = HAL_UART_TxCpltCallback;                       /* Legacy weak TxCpltCallback         */
+        break;
+
+      case HAL_UART_RX_HALFCOMPLETE_CB_ID :
+        huart->RxHalfCpltCallback = HAL_UART_RxHalfCpltCallback;               /* Legacy weak RxHalfCpltCallback     */
+        break;
+
+      case HAL_UART_RX_COMPLETE_CB_ID :
+        huart->RxCpltCallback = HAL_UART_RxCpltCallback;                       /* Legacy weak RxCpltCallback         */
+        break;
+
+      case HAL_UART_ERROR_CB_ID :
+        huart->ErrorCallback = HAL_UART_ErrorCallback;                         /* Legacy weak ErrorCallback          */
+        break;
+
+      case HAL_UART_ABORT_COMPLETE_CB_ID :
+        huart->AbortCpltCallback = HAL_UART_AbortCpltCallback;                 /* Legacy weak AbortCpltCallback      */
+        break;
+
+      case HAL_UART_ABORT_TRANSMIT_COMPLETE_CB_ID :
+        huart->AbortTransmitCpltCallback = HAL_UART_AbortTransmitCpltCallback; /* Legacy weak
+                                                                                  AbortTransmitCpltCallback          */
+        break;
+
+      case HAL_UART_ABORT_RECEIVE_COMPLETE_CB_ID :
+        huart->AbortReceiveCpltCallback = HAL_UART_AbortReceiveCpltCallback;   /* Legacy weak
+                                                                                  AbortReceiveCpltCallback           */
+        break;
+
+      case HAL_UART_WAKEUP_CB_ID :
+        huart->WakeupCallback = HAL_UARTEx_WakeupCallback;                     /* Legacy weak WakeupCallback         */
+        break;
+
+      case HAL_UART_RX_FIFO_FULL_CB_ID :
+        huart->RxFifoFullCallback = HAL_UARTEx_RxFifoFullCallback;             /* Legacy weak RxFifoFullCallback     */
+        break;
+
+      case HAL_UART_TX_FIFO_EMPTY_CB_ID :
+        huart->TxFifoEmptyCallback = HAL_UARTEx_TxFifoEmptyCallback;           /* Legacy weak TxFifoEmptyCallback    */
+        break;
+
+      case HAL_UART_MSPINIT_CB_ID :
+        huart->MspInitCallback = HAL_UART_MspInit;                             /* Legacy weak MspInitCallback        */
+        break;
+
+      case HAL_UART_MSPDEINIT_CB_ID :
+        huart->MspDeInitCallback = HAL_UART_MspDeInit;                         /* Legacy weak MspDeInitCallback      */
+        break;
+
+      default :
+        huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
+
+        status =  HAL_ERROR;
+        break;
+    }
+  }
+  else if (HAL_UART_STATE_RESET == huart->gState)
+  {
+    switch (CallbackID)
+    {
+      case HAL_UART_MSPINIT_CB_ID :
+        huart->MspInitCallback = HAL_UART_MspInit;
+        break;
+
+      case HAL_UART_MSPDEINIT_CB_ID :
+        huart->MspDeInitCallback = HAL_UART_MspDeInit;
+        break;
+
+      default :
+        huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
+
+        status =  HAL_ERROR;
+        break;
+    }
+  }
+  else
+  {
+    huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
+
+    status =  HAL_ERROR;
+  }
+
+  return status;
+}
+
+/**
+  * @brief  Register a User UART Rx Event Callback
+  *         To be used instead of the weak predefined callback
+  * @param  huart     Uart handle
+  * @param  pCallback Pointer to the Rx Event Callback function
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_UART_RegisterRxEventCallback(UART_HandleTypeDef *huart, pUART_RxEventCallbackTypeDef pCallback)
+{
+  HAL_StatusTypeDef status = HAL_OK;
+
+  if (pCallback == NULL)
+  {
+    huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
+
+    return HAL_ERROR;
+  }
+
+  if (huart->RxState == HAL_UART_STATE_READY)
+  {
+    huart->RxEventCallback = pCallback;
+  }
+  else
+  {
+    huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
+
+    status =  HAL_ERROR;
+  }
+
+  return status;
+}
+
+/**
+  * @brief  UnRegister the UART Rx Event Callback
+  *         UART Rx Event Callback is redirected to the weak HAL_UARTEx_RxEventCallback() predefined callback
+  * @param  huart     Uart handle
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_UART_UnRegisterRxEventCallback(UART_HandleTypeDef *huart)
+{
+  HAL_StatusTypeDef status = HAL_OK;
+
+  if (huart->RxState == HAL_UART_STATE_READY)
+  {
+    huart->RxEventCallback = HAL_UARTEx_RxEventCallback; /* Legacy weak UART Rx Event Callback  */
+  }
+  else
+  {
+    huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
+
+    status =  HAL_ERROR;
+  }
+
+  return status;
+}
+
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+
+/**
+  * @}
+  */
+
+/** @defgroup UART_Exported_Functions_Group2 IO operation functions
+  * @brief UART Transmit/Receive functions
+  *
+@verbatim
+ ===============================================================================
+                      ##### IO operation functions #####
+ ===============================================================================
+    This subsection provides a set of functions allowing to manage the UART asynchronous
+    and Half duplex data transfers.
+
+    (#) There are two mode of transfer:
+       (+) Blocking mode: The communication is performed in polling mode.
+           The HAL status of all data processing is returned by the same function
+           after finishing transfer.
+       (+) Non-Blocking mode: The communication is performed using Interrupts
+           or DMA, These API's return the HAL status.
+           The end of the data processing will be indicated through the
+           dedicated UART IRQ when using Interrupt mode or the DMA IRQ when
+           using DMA mode.
+           The HAL_UART_TxCpltCallback(), HAL_UART_RxCpltCallback() user callbacks
+           will be executed respectively at the end of the transmit or Receive process
+           The HAL_UART_ErrorCallback()user callback will be executed when a communication error is detected
+
+    (#) Blocking mode API's are :
+        (+) HAL_UART_Transmit()
+        (+) HAL_UART_Receive()
+
+    (#) Non-Blocking mode API's with Interrupt are :
+        (+) HAL_UART_Transmit_IT()
+        (+) HAL_UART_Receive_IT()
+        (+) HAL_UART_IRQHandler()
+
+    (#) Non-Blocking mode API's with DMA are :
+        (+) HAL_UART_Transmit_DMA()
+        (+) HAL_UART_Receive_DMA()
+        (+) HAL_UART_DMAPause()
+        (+) HAL_UART_DMAResume()
+        (+) HAL_UART_DMAStop()
+
+    (#) A set of Transfer Complete Callbacks are provided in Non_Blocking mode:
+        (+) HAL_UART_TxHalfCpltCallback()
+        (+) HAL_UART_TxCpltCallback()
+        (+) HAL_UART_RxHalfCpltCallback()
+        (+) HAL_UART_RxCpltCallback()
+        (+) HAL_UART_ErrorCallback()
+
+    (#) Non-Blocking mode transfers could be aborted using Abort API's :
+        (+) HAL_UART_Abort()
+        (+) HAL_UART_AbortTransmit()
+        (+) HAL_UART_AbortReceive()
+        (+) HAL_UART_Abort_IT()
+        (+) HAL_UART_AbortTransmit_IT()
+        (+) HAL_UART_AbortReceive_IT()
+
+    (#) For Abort services based on interrupts (HAL_UART_Abortxxx_IT), a set of Abort Complete Callbacks are provided:
+        (+) HAL_UART_AbortCpltCallback()
+        (+) HAL_UART_AbortTransmitCpltCallback()
+        (+) HAL_UART_AbortReceiveCpltCallback()
+
+    (#) A Rx Event Reception Callback (Rx event notification) is available for Non_Blocking modes of enhanced
+        reception services:
+        (+) HAL_UARTEx_RxEventCallback()
+
+    (#) In Non-Blocking mode transfers, possible errors are split into 2 categories.
+        Errors are handled as follows :
+       (+) Error is considered as Recoverable and non blocking : Transfer could go till end, but error severity is
+           to be evaluated by user : this concerns Frame Error, Parity Error or Noise Error
+           in Interrupt mode reception .
+           Received character is then retrieved and stored in Rx buffer, Error code is set to allow user
+           to identify error type, and HAL_UART_ErrorCallback() user callback is executed.
+           Transfer is kept ongoing on UART side.
+           If user wants to abort it, Abort services should be called by user.
+       (+) Error is considered as Blocking : Transfer could not be completed properly and is aborted.
+           This concerns Overrun Error In Interrupt mode reception and all errors in DMA mode.
+           Error code is set to allow user to identify error type, and HAL_UART_ErrorCallback()
+           user callback is executed.
+
+    -@- In the Half duplex communication, it is forbidden to run the transmit
+        and receive process in parallel, the UART state HAL_UART_STATE_BUSY_TX_RX can't be useful.
+
+@endverbatim
+  * @{
+  */
+
+/**
+  * @brief Send an amount of data in blocking mode.
+  * @note   When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
+  *         the sent data is handled as a set of u16. In this case, Size must indicate the number
+  *         of u16 provided through pData.
+  * @note When FIFO mode is enabled, writing a data in the TDR register adds one
+  *       data to the TXFIFO. Write operations to the TDR register are performed
+  *       when TXFNF flag is set. From hardware perspective, TXFNF flag and
+  *       TXE are mapped on the same bit-field.
+  * @param huart   UART handle.
+  * @param pData   Pointer to data buffer (u8 or u16 data elements).
+  * @param Size    Amount of data elements (u8 or u16) to be sent.
+  * @param Timeout Timeout duration.
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size, uint32_t Timeout)
+{
+  const uint8_t  *pdata8bits;
+  const uint16_t *pdata16bits;
+  uint32_t tickstart;
+
+  /* Check that a Tx process is not already ongoing */
+  if (huart->gState == HAL_UART_STATE_READY)
+  {
+    if ((pData == NULL) || (Size == 0U))
+    {
+      return  HAL_ERROR;
+    }
+
+    huart->ErrorCode = HAL_UART_ERROR_NONE;
+    huart->gState = HAL_UART_STATE_BUSY_TX;
+
+    /* Init tickstart for timeout management */
+    tickstart = HAL_GetTick();
+
+    huart->TxXferSize  = Size;
+    huart->TxXferCount = Size;
+
+    /* In case of 9bits/No Parity transfer, pData needs to be handled as a uint16_t pointer */
+    if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
+    {
+      pdata8bits  = NULL;
+      pdata16bits = (const uint16_t *) pData;
+    }
+    else
+    {
+      pdata8bits  = pData;
+      pdata16bits = NULL;
+    }
+
+    while (huart->TxXferCount > 0U)
+    {
+      if (UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
+      {
+
+        huart->gState = HAL_UART_STATE_READY;
+
+        return HAL_TIMEOUT;
+      }
+      if (pdata8bits == NULL)
+      {
+        huart->Instance->TDR = (uint16_t)(*pdata16bits & 0x01FFU);
+        pdata16bits++;
+      }
+      else
+      {
+        huart->Instance->TDR = (uint8_t)(*pdata8bits & 0xFFU);
+        pdata8bits++;
+      }
+      huart->TxXferCount--;
+    }
+
+    if (UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TC, RESET, tickstart, Timeout) != HAL_OK)
+    {
+      huart->gState = HAL_UART_STATE_READY;
+
+      return HAL_TIMEOUT;
+    }
+
+    /* At end of Tx process, restore huart->gState to Ready */
+    huart->gState = HAL_UART_STATE_READY;
+
+    return HAL_OK;
+  }
+  else
+  {
+    return HAL_BUSY;
+  }
+}
+
+/**
+  * @brief Receive an amount of data in blocking mode.
+  * @note   When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
+  *         the received data is handled as a set of u16. In this case, Size must indicate the number
+  *         of u16 available through pData.
+  * @note When FIFO mode is enabled, the RXFNE flag is set as long as the RXFIFO
+  *       is not empty. Read operations from the RDR register are performed when
+  *       RXFNE flag is set. From hardware perspective, RXFNE flag and
+  *       RXNE are mapped on the same bit-field.
+  * @param huart   UART handle.
+  * @param pData   Pointer to data buffer (u8 or u16 data elements).
+  * @param Size    Amount of data elements (u8 or u16) to be received.
+  * @param Timeout Timeout duration.
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout)
+{
+  uint8_t  *pdata8bits;
+  uint16_t *pdata16bits;
+  uint16_t uhMask;
+  uint32_t tickstart;
+
+  /* Check that a Rx process is not already ongoing */
+  if (huart->RxState == HAL_UART_STATE_READY)
+  {
+    if ((pData == NULL) || (Size == 0U))
+    {
+      return  HAL_ERROR;
+    }
+
+    huart->ErrorCode = HAL_UART_ERROR_NONE;
+    huart->RxState = HAL_UART_STATE_BUSY_RX;
+    huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
+
+    /* Init tickstart for timeout management */
+    tickstart = HAL_GetTick();
+
+    huart->RxXferSize  = Size;
+    huart->RxXferCount = Size;
+
+    /* Computation of UART mask to apply to RDR register */
+    UART_MASK_COMPUTATION(huart);
+    uhMask = huart->Mask;
+
+    /* In case of 9bits/No Parity transfer, pRxData needs to be handled as a uint16_t pointer */
+    if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
+    {
+      pdata8bits  = NULL;
+      pdata16bits = (uint16_t *) pData;
+    }
+    else
+    {
+      pdata8bits  = pData;
+      pdata16bits = NULL;
+    }
+
+    /* as long as data have to be received */
+    while (huart->RxXferCount > 0U)
+    {
+      if (UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK)
+      {
+        huart->RxState = HAL_UART_STATE_READY;
+
+        return HAL_TIMEOUT;
+      }
+      if (pdata8bits == NULL)
+      {
+        *pdata16bits = (uint16_t)(huart->Instance->RDR & uhMask);
+        pdata16bits++;
+      }
+      else
+      {
+        *pdata8bits = (uint8_t)(huart->Instance->RDR & (uint8_t)uhMask);
+        pdata8bits++;
+      }
+      huart->RxXferCount--;
+    }
+
+    /* At end of Rx process, restore huart->RxState to Ready */
+    huart->RxState = HAL_UART_STATE_READY;
+
+    return HAL_OK;
+  }
+  else
+  {
+    return HAL_BUSY;
+  }
+}
+
+/**
+  * @brief Send an amount of data in interrupt mode.
+  * @note   When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
+  *         the sent data is handled as a set of u16. In this case, Size must indicate the number
+  *         of u16 provided through pData.
+  * @param huart UART handle.
+  * @param pData Pointer to data buffer (u8 or u16 data elements).
+  * @param Size  Amount of data elements (u8 or u16) to be sent.
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size)
+{
+  /* Check that a Tx process is not already ongoing */
+  if (huart->gState == HAL_UART_STATE_READY)
+  {
+    if ((pData == NULL) || (Size == 0U))
+    {
+      return HAL_ERROR;
+    }
+
+    huart->pTxBuffPtr  = pData;
+    huart->TxXferSize  = Size;
+    huart->TxXferCount = Size;
+    huart->TxISR       = NULL;
+
+    huart->ErrorCode = HAL_UART_ERROR_NONE;
+    huart->gState = HAL_UART_STATE_BUSY_TX;
+
+    /* Configure Tx interrupt processing */
+    if (huart->FifoMode == UART_FIFOMODE_ENABLE)
+    {
+      /* Set the Tx ISR function pointer according to the data word length */
+      if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
+      {
+        huart->TxISR = UART_TxISR_16BIT_FIFOEN;
+      }
+      else
+      {
+        huart->TxISR = UART_TxISR_8BIT_FIFOEN;
+      }
+
+      /* Enable the TX FIFO threshold interrupt */
+      ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_TXFTIE);
+    }
+    else
+    {
+      /* Set the Tx ISR function pointer according to the data word length */
+      if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
+      {
+        huart->TxISR = UART_TxISR_16BIT;
+      }
+      else
+      {
+        huart->TxISR = UART_TxISR_8BIT;
+      }
+
+      /* Enable the Transmit Data Register Empty interrupt */
+      ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_TXEIE_TXFNFIE);
+    }
+
+    return HAL_OK;
+  }
+  else
+  {
+    return HAL_BUSY;
+  }
+}
+
+/**
+  * @brief Receive an amount of data in interrupt mode.
+  * @note   When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
+  *         the received data is handled as a set of u16. In this case, Size must indicate the number
+  *         of u16 available through pData.
+  * @param huart UART handle.
+  * @param pData Pointer to data buffer (u8 or u16 data elements).
+  * @param Size  Amount of data elements (u8 or u16) to be received.
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
+{
+  /* Check that a Rx process is not already ongoing */
+  if (huart->RxState == HAL_UART_STATE_READY)
+  {
+    if ((pData == NULL) || (Size == 0U))
+    {
+      return HAL_ERROR;
+    }
+
+    /* Set Reception type to Standard reception */
+    huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
+
+    if (!(IS_LPUART_INSTANCE(huart->Instance)))
+    {
+      /* Check that USART RTOEN bit is set */
+      if (READ_BIT(huart->Instance->CR2, USART_CR2_RTOEN) != 0U)
+      {
+        /* Enable the UART Receiver Timeout Interrupt */
+        ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_RTOIE);
+      }
+    }
+
+    return (UART_Start_Receive_IT(huart, pData, Size));
+  }
+  else
+  {
+    return HAL_BUSY;
+  }
+}
+
+/**
+  * @brief Send an amount of data in DMA mode.
+  * @note   When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
+  *         the sent data is handled as a set of u16. In this case, Size must indicate the number
+  *         of u16 provided through pData.
+  * @param huart UART handle.
+  * @param pData Pointer to data buffer (u8 or u16 data elements).
+  * @param Size  Amount of data elements (u8 or u16) to be sent.
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size)
+{
+  /* Check that a Tx process is not already ongoing */
+  if (huart->gState == HAL_UART_STATE_READY)
+  {
+    if ((pData == NULL) || (Size == 0U))
+    {
+      return HAL_ERROR;
+    }
+
+    huart->pTxBuffPtr  = pData;
+    huart->TxXferSize  = Size;
+    huart->TxXferCount = Size;
+
+    huart->ErrorCode = HAL_UART_ERROR_NONE;
+    huart->gState = HAL_UART_STATE_BUSY_TX;
+
+    if (huart->hdmatx != NULL)
+    {
+      /* Set the UART DMA transfer complete callback */
+      huart->hdmatx->XferCpltCallback = UART_DMATransmitCplt;
+
+      /* Set the UART DMA Half transfer complete callback */
+      huart->hdmatx->XferHalfCpltCallback = UART_DMATxHalfCplt;
+
+      /* Set the DMA error callback */
+      huart->hdmatx->XferErrorCallback = UART_DMAError;
+
+      /* Set the DMA abort callback */
+      huart->hdmatx->XferAbortCallback = NULL;
+
+      /* Enable the UART transmit DMA channel */
+      if (HAL_DMA_Start_IT(huart->hdmatx, (uint32_t)huart->pTxBuffPtr, (uint32_t)&huart->Instance->TDR, Size) != HAL_OK)
+      {
+        /* Set error code to DMA */
+        huart->ErrorCode = HAL_UART_ERROR_DMA;
+
+        /* Restore huart->gState to ready */
+        huart->gState = HAL_UART_STATE_READY;
+
+        return HAL_ERROR;
+      }
+    }
+    /* Clear the TC flag in the ICR register */
+    __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_TCF);
+
+    /* Enable the DMA transfer for transmit request by setting the DMAT bit
+    in the UART CR3 register */
+    ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_DMAT);
+
+    return HAL_OK;
+  }
+  else
+  {
+    return HAL_BUSY;
+  }
+}
+
+/**
+  * @brief Receive an amount of data in DMA mode.
+  * @note   When the UART parity is enabled (PCE = 1), the received data contain
+  *         the parity bit (MSB position).
+  * @note   When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
+  *         the received data is handled as a set of u16. In this case, Size must indicate the number
+  *         of u16 available through pData.
+  * @param huart UART handle.
+  * @param pData Pointer to data buffer (u8 or u16 data elements).
+  * @param Size  Amount of data elements (u8 or u16) to be received.
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_UART_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
+{
+  /* Check that a Rx process is not already ongoing */
+  if (huart->RxState == HAL_UART_STATE_READY)
+  {
+    if ((pData == NULL) || (Size == 0U))
+    {
+      return HAL_ERROR;
+    }
+
+    /* Set Reception type to Standard reception */
+    huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
+
+    if (!(IS_LPUART_INSTANCE(huart->Instance)))
+    {
+      /* Check that USART RTOEN bit is set */
+      if (READ_BIT(huart->Instance->CR2, USART_CR2_RTOEN) != 0U)
+      {
+        /* Enable the UART Receiver Timeout Interrupt */
+        ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_RTOIE);
+      }
+    }
+
+    return (UART_Start_Receive_DMA(huart, pData, Size));
+  }
+  else
+  {
+    return HAL_BUSY;
+  }
+}
+
+/**
+  * @brief Pause the DMA Transfer.
+  * @param huart UART handle.
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_UART_DMAPause(UART_HandleTypeDef *huart)
+{
+  const HAL_UART_StateTypeDef gstate = huart->gState;
+  const HAL_UART_StateTypeDef rxstate = huart->RxState;
+
+  if ((HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT)) &&
+      (gstate == HAL_UART_STATE_BUSY_TX))
+  {
+    /* Disable the UART DMA Tx request */
+    ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
+  }
+  if ((HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)) &&
+      (rxstate == HAL_UART_STATE_BUSY_RX))
+  {
+    /* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */
+    ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_PEIE);
+    ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
+
+    /* Disable the UART DMA Rx request */
+    ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
+  }
+
+  return HAL_OK;
+}
+
+/**
+  * @brief Resume the DMA Transfer.
+  * @param huart UART handle.
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_UART_DMAResume(UART_HandleTypeDef *huart)
+{
+  if (huart->gState == HAL_UART_STATE_BUSY_TX)
+  {
+    /* Enable the UART DMA Tx request */
+    ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_DMAT);
+  }
+  if (huart->RxState == HAL_UART_STATE_BUSY_RX)
+  {
+    /* Clear the Overrun flag before resuming the Rx transfer */
+    __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF);
+
+    /* Re-enable PE and ERR (Frame error, noise error, overrun error) interrupts */
+    if (huart->Init.Parity != UART_PARITY_NONE)
+    {
+      ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_PEIE);
+    }
+    ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_EIE);
+
+    /* Enable the UART DMA Rx request */
+    ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_DMAR);
+  }
+
+  return HAL_OK;
+}
+
+/**
+  * @brief Stop the DMA Transfer.
+  * @param huart UART handle.
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_UART_DMAStop(UART_HandleTypeDef *huart)
+{
+  /* The Lock is not implemented on this API to allow the user application
+     to call the HAL UART API under callbacks HAL_UART_TxCpltCallback() / HAL_UART_RxCpltCallback() /
+     HAL_UART_TxHalfCpltCallback / HAL_UART_RxHalfCpltCallback:
+     indeed, when HAL_DMA_Abort() API is called, the DMA TX/RX Transfer or Half Transfer complete
+     interrupt is generated if the DMA transfer interruption occurs at the middle or at the end of
+     the stream and the corresponding call back is executed. */
+
+  const HAL_UART_StateTypeDef gstate = huart->gState;
+  const HAL_UART_StateTypeDef rxstate = huart->RxState;
+
+  /* Stop UART DMA Tx request if ongoing */
+  if ((HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT)) &&
+      (gstate == HAL_UART_STATE_BUSY_TX))
+  {
+    ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
+
+    /* Abort the UART DMA Tx channel */
+    if (huart->hdmatx != NULL)
+    {
+      if (HAL_DMA_Abort(huart->hdmatx) != HAL_OK)
+      {
+        if (HAL_DMA_GetError(huart->hdmatx) == HAL_DMA_ERROR_TIMEOUT)
+        {
+          /* Set error code to DMA */
+          huart->ErrorCode = HAL_UART_ERROR_DMA;
+
+          return HAL_TIMEOUT;
+        }
+      }
+    }
+
+    UART_EndTxTransfer(huart);
+  }
+
+  /* Stop UART DMA Rx request if ongoing */
+  if ((HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)) &&
+      (rxstate == HAL_UART_STATE_BUSY_RX))
+  {
+    ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
+
+    /* Abort the UART DMA Rx channel */
+    if (huart->hdmarx != NULL)
+    {
+      if (HAL_DMA_Abort(huart->hdmarx) != HAL_OK)
+      {
+        if (HAL_DMA_GetError(huart->hdmarx) == HAL_DMA_ERROR_TIMEOUT)
+        {
+          /* Set error code to DMA */
+          huart->ErrorCode = HAL_UART_ERROR_DMA;
+
+          return HAL_TIMEOUT;
+        }
+      }
+    }
+
+    UART_EndRxTransfer(huart);
+  }
+
+  return HAL_OK;
+}
+
+/**
+  * @brief  Abort ongoing transfers (blocking mode).
+  * @param  huart UART handle.
+  * @note   This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
+  *         This procedure performs following operations :
+  *           - Disable UART Interrupts (Tx and Rx)
+  *           - Disable the DMA transfer in the peripheral register (if enabled)
+  *           - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode)
+  *           - Set handle State to READY
+  * @note   This procedure is executed in blocking mode : when exiting function, Abort is considered as completed.
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_UART_Abort(UART_HandleTypeDef *huart)
+{
+  /* Disable TXE, TC, RXNE, PE, RXFT, TXFT and ERR (Frame error, noise error, overrun error) interrupts */
+  ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE |
+                                          USART_CR1_TXEIE_TXFNFIE | USART_CR1_TCIE));
+  ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE | USART_CR3_RXFTIE | USART_CR3_TXFTIE);
+
+  /* If Reception till IDLE event was ongoing, disable IDLEIE interrupt */
+  if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
+  {
+    ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_IDLEIE));
+  }
+
+  /* Abort the UART DMA Tx channel if enabled */
+  if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT))
+  {
+    /* Disable the UART DMA Tx request if enabled */
+    ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
+
+    /* Abort the UART DMA Tx channel : use blocking DMA Abort API (no callback) */
+    if (huart->hdmatx != NULL)
+    {
+      /* Set the UART DMA Abort callback to Null.
+         No call back execution at end of DMA abort procedure */
+      huart->hdmatx->XferAbortCallback = NULL;
+
+      if (HAL_DMA_Abort(huart->hdmatx) != HAL_OK)
+      {
+        if (HAL_DMA_GetError(huart->hdmatx) == HAL_DMA_ERROR_TIMEOUT)
+        {
+          /* Set error code to DMA */
+          huart->ErrorCode = HAL_UART_ERROR_DMA;
+
+          return HAL_TIMEOUT;
+        }
+      }
+    }
+  }
+
+  /* Abort the UART DMA Rx channel if enabled */
+  if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
+  {
+    /* Disable the UART DMA Rx request if enabled */
+    ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
+
+    /* Abort the UART DMA Rx channel : use blocking DMA Abort API (no callback) */
+    if (huart->hdmarx != NULL)
+    {
+      /* Set the UART DMA Abort callback to Null.
+         No call back execution at end of DMA abort procedure */
+      huart->hdmarx->XferAbortCallback = NULL;
+
+      if (HAL_DMA_Abort(huart->hdmarx) != HAL_OK)
+      {
+        if (HAL_DMA_GetError(huart->hdmarx) == HAL_DMA_ERROR_TIMEOUT)
+        {
+          /* Set error code to DMA */
+          huart->ErrorCode = HAL_UART_ERROR_DMA;
+
+          return HAL_TIMEOUT;
+        }
+      }
+    }
+  }
+
+  /* Reset Tx and Rx transfer counters */
+  huart->TxXferCount = 0U;
+  huart->RxXferCount = 0U;
+
+  /* Clear the Error flags in the ICR register */
+  __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_PEF | UART_CLEAR_FEF);
+
+  /* Flush the whole TX FIFO (if needed) */
+  if (huart->FifoMode == UART_FIFOMODE_ENABLE)
+  {
+    __HAL_UART_SEND_REQ(huart, UART_TXDATA_FLUSH_REQUEST);
+  }
+
+  /* Discard the received data */
+  __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);
+
+  /* Restore huart->gState and huart->RxState to Ready */
+  huart->gState  = HAL_UART_STATE_READY;
+  huart->RxState = HAL_UART_STATE_READY;
+  huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
+
+  huart->ErrorCode = HAL_UART_ERROR_NONE;
+
+  return HAL_OK;
+}
+
+/**
+  * @brief  Abort ongoing Transmit transfer (blocking mode).
+  * @param  huart UART handle.
+  * @note   This procedure could be used for aborting any ongoing Tx transfer started in Interrupt or DMA mode.
+  *         This procedure performs following operations :
+  *           - Disable UART Interrupts (Tx)
+  *           - Disable the DMA transfer in the peripheral register (if enabled)
+  *           - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode)
+  *           - Set handle State to READY
+  * @note   This procedure is executed in blocking mode : when exiting function, Abort is considered as completed.
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_UART_AbortTransmit(UART_HandleTypeDef *huart)
+{
+  /* Disable TCIE, TXEIE and TXFTIE interrupts */
+  ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TCIE | USART_CR1_TXEIE_TXFNFIE));
+  ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_TXFTIE);
+
+  /* Abort the UART DMA Tx channel if enabled */
+  if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT))
+  {
+    /* Disable the UART DMA Tx request if enabled */
+    ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
+
+    /* Abort the UART DMA Tx channel : use blocking DMA Abort API (no callback) */
+    if (huart->hdmatx != NULL)
+    {
+      /* Set the UART DMA Abort callback to Null.
+         No call back execution at end of DMA abort procedure */
+      huart->hdmatx->XferAbortCallback = NULL;
+
+      if (HAL_DMA_Abort(huart->hdmatx) != HAL_OK)
+      {
+        if (HAL_DMA_GetError(huart->hdmatx) == HAL_DMA_ERROR_TIMEOUT)
+        {
+          /* Set error code to DMA */
+          huart->ErrorCode = HAL_UART_ERROR_DMA;
+
+          return HAL_TIMEOUT;
+        }
+      }
+    }
+  }
+
+  /* Reset Tx transfer counter */
+  huart->TxXferCount = 0U;
+
+  /* Flush the whole TX FIFO (if needed) */
+  if (huart->FifoMode == UART_FIFOMODE_ENABLE)
+  {
+    __HAL_UART_SEND_REQ(huart, UART_TXDATA_FLUSH_REQUEST);
+  }
+
+  /* Restore huart->gState to Ready */
+  huart->gState = HAL_UART_STATE_READY;
+
+  return HAL_OK;
+}
+
+/**
+  * @brief  Abort ongoing Receive transfer (blocking mode).
+  * @param  huart UART handle.
+  * @note   This procedure could be used for aborting any ongoing Rx transfer started in Interrupt or DMA mode.
+  *         This procedure performs following operations :
+  *           - Disable UART Interrupts (Rx)
+  *           - Disable the DMA transfer in the peripheral register (if enabled)
+  *           - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode)
+  *           - Set handle State to READY
+  * @note   This procedure is executed in blocking mode : when exiting function, Abort is considered as completed.
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_UART_AbortReceive(UART_HandleTypeDef *huart)
+{
+  /* Disable PEIE, EIE, RXNEIE and RXFTIE interrupts */
+  ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_PEIE | USART_CR1_RXNEIE_RXFNEIE));
+  ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE | USART_CR3_RXFTIE);
+
+  /* If Reception till IDLE event was ongoing, disable IDLEIE interrupt */
+  if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
+  {
+    ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_IDLEIE));
+  }
+
+  /* Abort the UART DMA Rx channel if enabled */
+  if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
+  {
+    /* Disable the UART DMA Rx request if enabled */
+    ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
+
+    /* Abort the UART DMA Rx channel : use blocking DMA Abort API (no callback) */
+    if (huart->hdmarx != NULL)
+    {
+      /* Set the UART DMA Abort callback to Null.
+         No call back execution at end of DMA abort procedure */
+      huart->hdmarx->XferAbortCallback = NULL;
+
+      if (HAL_DMA_Abort(huart->hdmarx) != HAL_OK)
+      {
+        if (HAL_DMA_GetError(huart->hdmarx) == HAL_DMA_ERROR_TIMEOUT)
+        {
+          /* Set error code to DMA */
+          huart->ErrorCode = HAL_UART_ERROR_DMA;
+
+          return HAL_TIMEOUT;
+        }
+      }
+    }
+  }
+
+  /* Reset Rx transfer counter */
+  huart->RxXferCount = 0U;
+
+  /* Clear the Error flags in the ICR register */
+  __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_PEF | UART_CLEAR_FEF);
+
+  /* Discard the received data */
+  __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);
+
+  /* Restore huart->RxState to Ready */
+  huart->RxState = HAL_UART_STATE_READY;
+  huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
+
+  return HAL_OK;
+}
+
+/**
+  * @brief  Abort ongoing transfers (Interrupt mode).
+  * @param  huart UART handle.
+  * @note   This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
+  *         This procedure performs following operations :
+  *           - Disable UART Interrupts (Tx and Rx)
+  *           - Disable the DMA transfer in the peripheral register (if enabled)
+  *           - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode)
+  *           - Set handle State to READY
+  *           - At abort completion, call user abort complete callback
+  * @note   This procedure is executed in Interrupt mode, meaning that abort procedure could be
+  *         considered as completed only when user abort complete callback is executed (not when exiting function).
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_UART_Abort_IT(UART_HandleTypeDef *huart)
+{
+  uint32_t abortcplt = 1U;
+
+  /* Disable interrupts */
+  ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_PEIE | USART_CR1_TCIE | USART_CR1_RXNEIE_RXFNEIE |
+                                          USART_CR1_TXEIE_TXFNFIE));
+  ATOMIC_CLEAR_BIT(huart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE | USART_CR3_TXFTIE));
+
+  /* If Reception till IDLE event was ongoing, disable IDLEIE interrupt */
+  if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
+  {
+    ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_IDLEIE));
+  }
+
+  /* If DMA Tx and/or DMA Rx Handles are associated to UART Handle, DMA Abort complete callbacks should be initialised
+     before any call to DMA Abort functions */
+  /* DMA Tx Handle is valid */
+  if (huart->hdmatx != NULL)
+  {
+    /* Set DMA Abort Complete callback if UART DMA Tx request if enabled.
+       Otherwise, set it to NULL */
+    if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT))
+    {
+      huart->hdmatx->XferAbortCallback = UART_DMATxAbortCallback;
+    }
+    else
+    {
+      huart->hdmatx->XferAbortCallback = NULL;
+    }
+  }
+  /* DMA Rx Handle is valid */
+  if (huart->hdmarx != NULL)
+  {
+    /* Set DMA Abort Complete callback if UART DMA Rx request if enabled.
+       Otherwise, set it to NULL */
+    if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
+    {
+      huart->hdmarx->XferAbortCallback = UART_DMARxAbortCallback;
+    }
+    else
+    {
+      huart->hdmarx->XferAbortCallback = NULL;
+    }
+  }
+
+  /* Abort the UART DMA Tx channel if enabled */
+  if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT))
+  {
+    /* Disable DMA Tx at UART level */
+    ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
+
+    /* Abort the UART DMA Tx channel : use non blocking DMA Abort API (callback) */
+    if (huart->hdmatx != NULL)
+    {
+      /* UART Tx DMA Abort callback has already been initialised :
+         will lead to call HAL_UART_AbortCpltCallback() at end of DMA abort procedure */
+
+      /* Abort DMA TX */
+      if (HAL_DMA_Abort_IT(huart->hdmatx) != HAL_OK)
+      {
+        huart->hdmatx->XferAbortCallback = NULL;
+      }
+      else
+      {
+        abortcplt = 0U;
+      }
+    }
+  }
+
+  /* Abort the UART DMA Rx channel if enabled */
+  if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
+  {
+    /* Disable the UART DMA Rx request if enabled */
+    ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
+
+    /* Abort the UART DMA Rx channel : use non blocking DMA Abort API (callback) */
+    if (huart->hdmarx != NULL)
+    {
+      /* UART Rx DMA Abort callback has already been initialised :
+         will lead to call HAL_UART_AbortCpltCallback() at end of DMA abort procedure */
+
+      /* Abort DMA RX */
+      if (HAL_DMA_Abort_IT(huart->hdmarx) != HAL_OK)
+      {
+        huart->hdmarx->XferAbortCallback = NULL;
+        abortcplt = 1U;
+      }
+      else
+      {
+        abortcplt = 0U;
+      }
+    }
+  }
+
+  /* if no DMA abort complete callback execution is required => call user Abort Complete callback */
+  if (abortcplt == 1U)
+  {
+    /* Reset Tx and Rx transfer counters */
+    huart->TxXferCount = 0U;
+    huart->RxXferCount = 0U;
+
+    /* Clear ISR function pointers */
+    huart->RxISR = NULL;
+    huart->TxISR = NULL;
+
+    /* Reset errorCode */
+    huart->ErrorCode = HAL_UART_ERROR_NONE;
+
+    /* Clear the Error flags in the ICR register */
+    __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_PEF | UART_CLEAR_FEF);
+
+    /* Flush the whole TX FIFO (if needed) */
+    if (huart->FifoMode == UART_FIFOMODE_ENABLE)
+    {
+      __HAL_UART_SEND_REQ(huart, UART_TXDATA_FLUSH_REQUEST);
+    }
+
+    /* Discard the received data */
+    __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);
+
+    /* Restore huart->gState and huart->RxState to Ready */
+    huart->gState  = HAL_UART_STATE_READY;
+    huart->RxState = HAL_UART_STATE_READY;
+    huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
+
+    /* As no DMA to be aborted, call directly user Abort complete callback */
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+    /* Call registered Abort complete callback */
+    huart->AbortCpltCallback(huart);
+#else
+    /* Call legacy weak Abort complete callback */
+    HAL_UART_AbortCpltCallback(huart);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+  }
+
+  return HAL_OK;
+}
+
+/**
+  * @brief  Abort ongoing Transmit transfer (Interrupt mode).
+  * @param  huart UART handle.
+  * @note   This procedure could be used for aborting any ongoing Tx transfer started in Interrupt or DMA mode.
+  *         This procedure performs following operations :
+  *           - Disable UART Interrupts (Tx)
+  *           - Disable the DMA transfer in the peripheral register (if enabled)
+  *           - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode)
+  *           - Set handle State to READY
+  *           - At abort completion, call user abort complete callback
+  * @note   This procedure is executed in Interrupt mode, meaning that abort procedure could be
+  *         considered as completed only when user abort complete callback is executed (not when exiting function).
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_UART_AbortTransmit_IT(UART_HandleTypeDef *huart)
+{
+  /* Disable interrupts */
+  ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TCIE | USART_CR1_TXEIE_TXFNFIE));
+  ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_TXFTIE);
+
+  /* Abort the UART DMA Tx channel if enabled */
+  if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT))
+  {
+    /* Disable the UART DMA Tx request if enabled */
+    ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
+
+    /* Abort the UART DMA Tx channel : use non blocking DMA Abort API (callback) */
+    if (huart->hdmatx != NULL)
+    {
+      /* Set the UART DMA Abort callback :
+         will lead to call HAL_UART_AbortCpltCallback() at end of DMA abort procedure */
+      huart->hdmatx->XferAbortCallback = UART_DMATxOnlyAbortCallback;
+
+      /* Abort DMA TX */
+      if (HAL_DMA_Abort_IT(huart->hdmatx) != HAL_OK)
+      {
+        /* Call Directly huart->hdmatx->XferAbortCallback function in case of error */
+        huart->hdmatx->XferAbortCallback(huart->hdmatx);
+      }
+    }
+    else
+    {
+      /* Reset Tx transfer counter */
+      huart->TxXferCount = 0U;
+
+      /* Clear TxISR function pointers */
+      huart->TxISR = NULL;
+
+      /* Restore huart->gState to Ready */
+      huart->gState = HAL_UART_STATE_READY;
+
+      /* As no DMA to be aborted, call directly user Abort complete callback */
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+      /* Call registered Abort Transmit Complete Callback */
+      huart->AbortTransmitCpltCallback(huart);
+#else
+      /* Call legacy weak Abort Transmit Complete Callback */
+      HAL_UART_AbortTransmitCpltCallback(huart);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+    }
+  }
+  else
+  {
+    /* Reset Tx transfer counter */
+    huart->TxXferCount = 0U;
+
+    /* Clear TxISR function pointers */
+    huart->TxISR = NULL;
+
+    /* Flush the whole TX FIFO (if needed) */
+    if (huart->FifoMode == UART_FIFOMODE_ENABLE)
+    {
+      __HAL_UART_SEND_REQ(huart, UART_TXDATA_FLUSH_REQUEST);
+    }
+
+    /* Restore huart->gState to Ready */
+    huart->gState = HAL_UART_STATE_READY;
+
+    /* As no DMA to be aborted, call directly user Abort complete callback */
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+    /* Call registered Abort Transmit Complete Callback */
+    huart->AbortTransmitCpltCallback(huart);
+#else
+    /* Call legacy weak Abort Transmit Complete Callback */
+    HAL_UART_AbortTransmitCpltCallback(huart);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+  }
+
+  return HAL_OK;
+}
+
+/**
+  * @brief  Abort ongoing Receive transfer (Interrupt mode).
+  * @param  huart UART handle.
+  * @note   This procedure could be used for aborting any ongoing Rx transfer started in Interrupt or DMA mode.
+  *         This procedure performs following operations :
+  *           - Disable UART Interrupts (Rx)
+  *           - Disable the DMA transfer in the peripheral register (if enabled)
+  *           - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode)
+  *           - Set handle State to READY
+  *           - At abort completion, call user abort complete callback
+  * @note   This procedure is executed in Interrupt mode, meaning that abort procedure could be
+  *         considered as completed only when user abort complete callback is executed (not when exiting function).
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_UART_AbortReceive_IT(UART_HandleTypeDef *huart)
+{
+  /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
+  ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_PEIE | USART_CR1_RXNEIE_RXFNEIE));
+  ATOMIC_CLEAR_BIT(huart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE));
+
+  /* If Reception till IDLE event was ongoing, disable IDLEIE interrupt */
+  if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
+  {
+    ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_IDLEIE));
+  }
+
+  /* Abort the UART DMA Rx channel if enabled */
+  if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
+  {
+    /* Disable the UART DMA Rx request if enabled */
+    ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
+
+    /* Abort the UART DMA Rx channel : use non blocking DMA Abort API (callback) */
+    if (huart->hdmarx != NULL)
+    {
+      /* Set the UART DMA Abort callback :
+         will lead to call HAL_UART_AbortCpltCallback() at end of DMA abort procedure */
+      huart->hdmarx->XferAbortCallback = UART_DMARxOnlyAbortCallback;
+
+      /* Abort DMA RX */
+      if (HAL_DMA_Abort_IT(huart->hdmarx) != HAL_OK)
+      {
+        /* Call Directly huart->hdmarx->XferAbortCallback function in case of error */
+        huart->hdmarx->XferAbortCallback(huart->hdmarx);
+      }
+    }
+    else
+    {
+      /* Reset Rx transfer counter */
+      huart->RxXferCount = 0U;
+
+      /* Clear RxISR function pointer */
+      huart->pRxBuffPtr = NULL;
+
+      /* Clear the Error flags in the ICR register */
+      __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_PEF | UART_CLEAR_FEF);
+
+      /* Discard the received data */
+      __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);
+
+      /* Restore huart->RxState to Ready */
+      huart->RxState = HAL_UART_STATE_READY;
+      huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
+
+      /* As no DMA to be aborted, call directly user Abort complete callback */
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+      /* Call registered Abort Receive Complete Callback */
+      huart->AbortReceiveCpltCallback(huart);
+#else
+      /* Call legacy weak Abort Receive Complete Callback */
+      HAL_UART_AbortReceiveCpltCallback(huart);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+    }
+  }
+  else
+  {
+    /* Reset Rx transfer counter */
+    huart->RxXferCount = 0U;
+
+    /* Clear RxISR function pointer */
+    huart->pRxBuffPtr = NULL;
+
+    /* Clear the Error flags in the ICR register */
+    __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_PEF | UART_CLEAR_FEF);
+
+    /* Restore huart->RxState to Ready */
+    huart->RxState = HAL_UART_STATE_READY;
+    huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
+
+    /* As no DMA to be aborted, call directly user Abort complete callback */
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+    /* Call registered Abort Receive Complete Callback */
+    huart->AbortReceiveCpltCallback(huart);
+#else
+    /* Call legacy weak Abort Receive Complete Callback */
+    HAL_UART_AbortReceiveCpltCallback(huart);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+  }
+
+  return HAL_OK;
+}
+
+/**
+  * @brief Handle UART interrupt request.
+  * @param huart UART handle.
+  * @retval None
+  */
+void HAL_UART_IRQHandler(UART_HandleTypeDef *huart)
+{
+  uint32_t isrflags   = READ_REG(huart->Instance->ISR);
+  uint32_t cr1its     = READ_REG(huart->Instance->CR1);
+  uint32_t cr3its     = READ_REG(huart->Instance->CR3);
+
+  uint32_t errorflags;
+  uint32_t errorcode;
+
+  /* If no error occurs */
+  errorflags = (isrflags & (uint32_t)(USART_ISR_PE | USART_ISR_FE | USART_ISR_ORE | USART_ISR_NE | USART_ISR_RTOF));
+  if (errorflags == 0U)
+  {
+    /* UART in mode Receiver ---------------------------------------------------*/
+    if (((isrflags & USART_ISR_RXNE_RXFNE) != 0U)
+        && (((cr1its & USART_CR1_RXNEIE_RXFNEIE) != 0U)
+            || ((cr3its & USART_CR3_RXFTIE) != 0U)))
+    {
+      if (huart->RxISR != NULL)
+      {
+        huart->RxISR(huart);
+      }
+      return;
+    }
+  }
+
+  /* If some errors occur */
+  if ((errorflags != 0U)
+      && ((((cr3its & (USART_CR3_RXFTIE | USART_CR3_EIE)) != 0U)
+           || ((cr1its & (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE | USART_CR1_RTOIE)) != 0U))))
+  {
+    /* UART parity error interrupt occurred -------------------------------------*/
+    if (((isrflags & USART_ISR_PE) != 0U) && ((cr1its & USART_CR1_PEIE) != 0U))
+    {
+      __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_PEF);
+
+      huart->ErrorCode |= HAL_UART_ERROR_PE;
+    }
+
+    /* UART frame error interrupt occurred --------------------------------------*/
+    if (((isrflags & USART_ISR_FE) != 0U) && ((cr3its & USART_CR3_EIE) != 0U))
+    {
+      __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_FEF);
+
+      huart->ErrorCode |= HAL_UART_ERROR_FE;
+    }
+
+    /* UART noise error interrupt occurred --------------------------------------*/
+    if (((isrflags & USART_ISR_NE) != 0U) && ((cr3its & USART_CR3_EIE) != 0U))
+    {
+      __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_NEF);
+
+      huart->ErrorCode |= HAL_UART_ERROR_NE;
+    }
+
+    /* UART Over-Run interrupt occurred -----------------------------------------*/
+    if (((isrflags & USART_ISR_ORE) != 0U)
+        && (((cr1its & USART_CR1_RXNEIE_RXFNEIE) != 0U) ||
+            ((cr3its & (USART_CR3_RXFTIE | USART_CR3_EIE)) != 0U)))
+    {
+      __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF);
+
+      huart->ErrorCode |= HAL_UART_ERROR_ORE;
+    }
+
+    /* UART Receiver Timeout interrupt occurred ---------------------------------*/
+    if (((isrflags & USART_ISR_RTOF) != 0U) && ((cr1its & USART_CR1_RTOIE) != 0U))
+    {
+      __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_RTOF);
+
+      huart->ErrorCode |= HAL_UART_ERROR_RTO;
+    }
+
+    /* Call UART Error Call back function if need be ----------------------------*/
+    if (huart->ErrorCode != HAL_UART_ERROR_NONE)
+    {
+      /* UART in mode Receiver --------------------------------------------------*/
+      if (((isrflags & USART_ISR_RXNE_RXFNE) != 0U)
+          && (((cr1its & USART_CR1_RXNEIE_RXFNEIE) != 0U)
+              || ((cr3its & USART_CR3_RXFTIE) != 0U)))
+      {
+        if (huart->RxISR != NULL)
+        {
+          huart->RxISR(huart);
+        }
+      }
+
+      /* If Error is to be considered as blocking :
+          - Receiver Timeout error in Reception
+          - Overrun error in Reception
+          - any error occurs in DMA mode reception
+      */
+      errorcode = huart->ErrorCode;
+      if ((HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)) ||
+          ((errorcode & (HAL_UART_ERROR_RTO | HAL_UART_ERROR_ORE)) != 0U))
+      {
+        /* Blocking error : transfer is aborted
+           Set the UART state ready to be able to start again the process,
+           Disable Rx Interrupts, and disable Rx DMA request, if ongoing */
+        UART_EndRxTransfer(huart);
+
+        /* Abort the UART DMA Rx channel if enabled */
+        if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
+        {
+          /* Disable the UART DMA Rx request if enabled */
+          ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
+
+          /* Abort the UART DMA Rx channel */
+          if (huart->hdmarx != NULL)
+          {
+            /* Set the UART DMA Abort callback :
+               will lead to call HAL_UART_ErrorCallback() at end of DMA abort procedure */
+            huart->hdmarx->XferAbortCallback = UART_DMAAbortOnError;
+
+            /* Abort DMA RX */
+            if (HAL_DMA_Abort_IT(huart->hdmarx) != HAL_OK)
+            {
+              /* Call Directly huart->hdmarx->XferAbortCallback function in case of error */
+              huart->hdmarx->XferAbortCallback(huart->hdmarx);
+            }
+          }
+          else
+          {
+            /* Call user error callback */
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+            /*Call registered error callback*/
+            huart->ErrorCallback(huart);
+#else
+            /*Call legacy weak error callback*/
+            HAL_UART_ErrorCallback(huart);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+
+          }
+        }
+        else
+        {
+          /* Call user error callback */
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+          /*Call registered error callback*/
+          huart->ErrorCallback(huart);
+#else
+          /*Call legacy weak error callback*/
+          HAL_UART_ErrorCallback(huart);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+        }
+      }
+      else
+      {
+        /* Non Blocking error : transfer could go on.
+           Error is notified to user through user error callback */
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+        /*Call registered error callback*/
+        huart->ErrorCallback(huart);
+#else
+        /*Call legacy weak error callback*/
+        HAL_UART_ErrorCallback(huart);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+        huart->ErrorCode = HAL_UART_ERROR_NONE;
+      }
+    }
+    return;
+
+  } /* End if some error occurs */
+
+  /* Check current reception Mode :
+     If Reception till IDLE event has been selected : */
+  if ((huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
+      && ((isrflags & USART_ISR_IDLE) != 0U)
+      && ((cr1its & USART_ISR_IDLE) != 0U))
+  {
+    __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_IDLEF);
+
+    /* Check if DMA mode is enabled in UART */
+    if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
+    {
+      /* DMA mode enabled */
+      /* Check received length : If all expected data are received, do nothing,
+         (DMA cplt callback will be called).
+         Otherwise, if at least one data has already been received, IDLE event is to be notified to user */
+      uint16_t nb_remaining_rx_data = (uint16_t) __HAL_DMA_GET_COUNTER(huart->hdmarx);
+      if ((nb_remaining_rx_data > 0U)
+          && (nb_remaining_rx_data < huart->RxXferSize))
+      {
+        /* Reception is not complete */
+        huart->RxXferCount = nb_remaining_rx_data;
+
+        /* In Normal mode, end DMA xfer and HAL UART Rx process*/
+        if (HAL_IS_BIT_CLR(huart->hdmarx->Instance->CCR, DMA_CCR_CIRC))
+        {
+          /* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */
+          ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_PEIE);
+          ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
+
+          /* Disable the DMA transfer for the receiver request by resetting the DMAR bit
+             in the UART CR3 register */
+          ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
+
+          /* At end of Rx process, restore huart->RxState to Ready */
+          huart->RxState = HAL_UART_STATE_READY;
+          huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
+
+          ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);
+
+          /* Last bytes received, so no need as the abort is immediate */
+          (void)HAL_DMA_Abort(huart->hdmarx);
+        }
+
+        /* Initialize type of RxEvent that correspond to RxEvent callback execution;
+           In this case, Rx Event type is Idle Event */
+        huart->RxEventType = HAL_UART_RXEVENT_IDLE;
+
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+        /*Call registered Rx Event callback*/
+        huart->RxEventCallback(huart, (huart->RxXferSize - huart->RxXferCount));
+#else
+        /*Call legacy weak Rx Event callback*/
+        HAL_UARTEx_RxEventCallback(huart, (huart->RxXferSize - huart->RxXferCount));
+#endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
+      }
+      else
+      {
+        /* If DMA is in Circular mode, Idle event is to be reported to user
+           even if occurring after a Transfer Complete event from DMA */
+        if (nb_remaining_rx_data == huart->RxXferSize)
+        {
+          if (HAL_IS_BIT_SET(huart->hdmarx->Instance->CCR, DMA_CCR_CIRC))
+          {
+            /* Initialize type of RxEvent that correspond to RxEvent callback execution;
+               In this case, Rx Event type is Idle Event */
+            huart->RxEventType = HAL_UART_RXEVENT_IDLE;
+
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+            /*Call registered Rx Event callback*/
+            huart->RxEventCallback(huart, huart->RxXferSize);
+#else
+            /*Call legacy weak Rx Event callback*/
+            HAL_UARTEx_RxEventCallback(huart, huart->RxXferSize);
+#endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
+          }
+        }
+      }
+      return;
+    }
+    else
+    {
+      /* DMA mode not enabled */
+      /* Check received length : If all expected data are received, do nothing.
+         Otherwise, if at least one data has already been received, IDLE event is to be notified to user */
+      uint16_t nb_rx_data = huart->RxXferSize - huart->RxXferCount;
+      if ((huart->RxXferCount > 0U)
+          && (nb_rx_data > 0U))
+      {
+        /* Disable the UART Parity Error Interrupt and RXNE interrupts */
+        ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE));
+
+        /* Disable the UART Error Interrupt:(Frame error, noise error, overrun error) and RX FIFO Threshold interrupt */
+        ATOMIC_CLEAR_BIT(huart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE));
+
+        /* Rx process is completed, restore huart->RxState to Ready */
+        huart->RxState = HAL_UART_STATE_READY;
+        huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
+
+        /* Clear RxISR function pointer */
+        huart->RxISR = NULL;
+
+        ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);
+
+        /* Initialize type of RxEvent that correspond to RxEvent callback execution;
+           In this case, Rx Event type is Idle Event */
+        huart->RxEventType = HAL_UART_RXEVENT_IDLE;
+
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+        /*Call registered Rx complete callback*/
+        huart->RxEventCallback(huart, nb_rx_data);
+#else
+        /*Call legacy weak Rx Event callback*/
+        HAL_UARTEx_RxEventCallback(huart, nb_rx_data);
+#endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
+      }
+      return;
+    }
+  }
+
+  /* UART wakeup from Stop mode interrupt occurred ---------------------------*/
+  if (((isrflags & USART_ISR_WUF) != 0U) && ((cr3its & USART_CR3_WUFIE) != 0U))
+  {
+    __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_WUF);
+
+    /* UART Rx state is not reset as a reception process might be ongoing.
+       If UART handle state fields need to be reset to READY, this could be done in Wakeup callback */
+
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+    /* Call registered Wakeup Callback */
+    huart->WakeupCallback(huart);
+#else
+    /* Call legacy weak Wakeup Callback */
+    HAL_UARTEx_WakeupCallback(huart);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+    return;
+  }
+
+  /* UART in mode Transmitter ------------------------------------------------*/
+  if (((isrflags & USART_ISR_TXE_TXFNF) != 0U)
+      && (((cr1its & USART_CR1_TXEIE_TXFNFIE) != 0U)
+          || ((cr3its & USART_CR3_TXFTIE) != 0U)))
+  {
+    if (huart->TxISR != NULL)
+    {
+      huart->TxISR(huart);
+    }
+    return;
+  }
+
+  /* UART in mode Transmitter (transmission end) -----------------------------*/
+  if (((isrflags & USART_ISR_TC) != 0U) && ((cr1its & USART_CR1_TCIE) != 0U))
+  {
+    UART_EndTransmit_IT(huart);
+    return;
+  }
+
+  /* UART TX Fifo Empty occurred ----------------------------------------------*/
+  if (((isrflags & USART_ISR_TXFE) != 0U) && ((cr1its & USART_CR1_TXFEIE) != 0U))
+  {
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+    /* Call registered Tx Fifo Empty Callback */
+    huart->TxFifoEmptyCallback(huart);
+#else
+    /* Call legacy weak Tx Fifo Empty Callback */
+    HAL_UARTEx_TxFifoEmptyCallback(huart);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+    return;
+  }
+
+  /* UART RX Fifo Full occurred ----------------------------------------------*/
+  if (((isrflags & USART_ISR_RXFF) != 0U) && ((cr1its & USART_CR1_RXFFIE) != 0U))
+  {
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+    /* Call registered Rx Fifo Full Callback */
+    huart->RxFifoFullCallback(huart);
+#else
+    /* Call legacy weak Rx Fifo Full Callback */
+    HAL_UARTEx_RxFifoFullCallback(huart);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+    return;
+  }
+}
+
+/**
+  * @brief Tx Transfer completed callback.
+  * @param huart UART handle.
+  * @retval None
+  */
+__weak void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
+{
+  /* Prevent unused argument(s) compilation warning */
+  UNUSED(huart);
+
+  /* NOTE : This function should not be modified, when the callback is needed,
+            the HAL_UART_TxCpltCallback can be implemented in the user file.
+   */
+}
+
+/**
+  * @brief  Tx Half Transfer completed callback.
+  * @param  huart UART handle.
+  * @retval None
+  */
+__weak void HAL_UART_TxHalfCpltCallback(UART_HandleTypeDef *huart)
+{
+  /* Prevent unused argument(s) compilation warning */
+  UNUSED(huart);
+
+  /* NOTE: This function should not be modified, when the callback is needed,
+           the HAL_UART_TxHalfCpltCallback can be implemented in the user file.
+   */
+}
+
+/**
+  * @brief  Rx Transfer completed callback.
+  * @param  huart UART handle.
+  * @retval None
+  */
+__weak void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
+{
+  /* Prevent unused argument(s) compilation warning */
+  UNUSED(huart);
+
+  /* NOTE : This function should not be modified, when the callback is needed,
+            the HAL_UART_RxCpltCallback can be implemented in the user file.
+   */
+}
+
+/**
+  * @brief  Rx Half Transfer completed callback.
+  * @param  huart UART handle.
+  * @retval None
+  */
+__weak void HAL_UART_RxHalfCpltCallback(UART_HandleTypeDef *huart)
+{
+  /* Prevent unused argument(s) compilation warning */
+  UNUSED(huart);
+
+  /* NOTE: This function should not be modified, when the callback is needed,
+           the HAL_UART_RxHalfCpltCallback can be implemented in the user file.
+   */
+}
+
+/**
+  * @brief  UART error callback.
+  * @param  huart UART handle.
+  * @retval None
+  */
+__weak void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
+{
+  /* Prevent unused argument(s) compilation warning */
+  UNUSED(huart);
+
+  /* NOTE : This function should not be modified, when the callback is needed,
+            the HAL_UART_ErrorCallback can be implemented in the user file.
+   */
+}
+
+/**
+  * @brief  UART Abort Complete callback.
+  * @param  huart UART handle.
+  * @retval None
+  */
+__weak void HAL_UART_AbortCpltCallback(UART_HandleTypeDef *huart)
+{
+  /* Prevent unused argument(s) compilation warning */
+  UNUSED(huart);
+
+  /* NOTE : This function should not be modified, when the callback is needed,
+            the HAL_UART_AbortCpltCallback can be implemented in the user file.
+   */
+}
+
+/**
+  * @brief  UART Abort Complete callback.
+  * @param  huart UART handle.
+  * @retval None
+  */
+__weak void HAL_UART_AbortTransmitCpltCallback(UART_HandleTypeDef *huart)
+{
+  /* Prevent unused argument(s) compilation warning */
+  UNUSED(huart);
+
+  /* NOTE : This function should not be modified, when the callback is needed,
+            the HAL_UART_AbortTransmitCpltCallback can be implemented in the user file.
+   */
+}
+
+/**
+  * @brief  UART Abort Receive Complete callback.
+  * @param  huart UART handle.
+  * @retval None
+  */
+__weak void HAL_UART_AbortReceiveCpltCallback(UART_HandleTypeDef *huart)
+{
+  /* Prevent unused argument(s) compilation warning */
+  UNUSED(huart);
+
+  /* NOTE : This function should not be modified, when the callback is needed,
+            the HAL_UART_AbortReceiveCpltCallback can be implemented in the user file.
+   */
+}
+
+/**
+  * @brief  Reception Event Callback (Rx event notification called after use of advanced reception service).
+  * @param  huart UART handle
+  * @param  Size  Number of data available in application reception buffer (indicates a position in
+  *               reception buffer until which, data are available)
+  * @retval None
+  */
+__weak void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
+{
+  /* Prevent unused argument(s) compilation warning */
+  UNUSED(huart);
+  UNUSED(Size);
+
+  /* NOTE : This function should not be modified, when the callback is needed,
+            the HAL_UARTEx_RxEventCallback can be implemented in the user file.
+   */
+}
+
+/**
+  * @}
+  */
+
+/** @defgroup UART_Exported_Functions_Group3 Peripheral Control functions
+  *  @brief   UART control functions
+  *
+@verbatim
+ ===============================================================================
+                      ##### Peripheral Control functions #####
+ ===============================================================================
+    [..]
+    This subsection provides a set of functions allowing to control the UART.
+     (+) HAL_UART_ReceiverTimeout_Config() API allows to configure the receiver timeout value on the fly
+     (+) HAL_UART_EnableReceiverTimeout() API enables the receiver timeout feature
+     (+) HAL_UART_DisableReceiverTimeout() API disables the receiver timeout feature
+     (+) HAL_MultiProcessor_EnableMuteMode() API enables mute mode
+     (+) HAL_MultiProcessor_DisableMuteMode() API disables mute mode
+     (+) HAL_MultiProcessor_EnterMuteMode() API enters mute mode
+     (+) UART_SetConfig() API configures the UART peripheral
+     (+) UART_AdvFeatureConfig() API optionally configures the UART advanced features
+     (+) UART_CheckIdleState() API ensures that TEACK and/or REACK are set after initialization
+     (+) HAL_HalfDuplex_EnableTransmitter() API disables receiver and enables transmitter
+     (+) HAL_HalfDuplex_EnableReceiver() API disables transmitter and enables receiver
+     (+) HAL_LIN_SendBreak() API transmits the break characters
+@endverbatim
+  * @{
+  */
+
+/**
+  * @brief  Update on the fly the receiver timeout value in RTOR register.
+  * @param  huart Pointer to a UART_HandleTypeDef structure that contains
+  *                    the configuration information for the specified UART module.
+  * @param  TimeoutValue receiver timeout value in number of baud blocks. The timeout
+  *                     value must be less or equal to 0x0FFFFFFFF.
+  * @retval None
+  */
+void HAL_UART_ReceiverTimeout_Config(UART_HandleTypeDef *huart, uint32_t TimeoutValue)
+{
+  if (!(IS_LPUART_INSTANCE(huart->Instance)))
+  {
+    assert_param(IS_UART_RECEIVER_TIMEOUT_VALUE(TimeoutValue));
+    MODIFY_REG(huart->Instance->RTOR, USART_RTOR_RTO, TimeoutValue);
+  }
+}
+
+/**
+  * @brief  Enable the UART receiver timeout feature.
+  * @param  huart Pointer to a UART_HandleTypeDef structure that contains
+  *                    the configuration information for the specified UART module.
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_UART_EnableReceiverTimeout(UART_HandleTypeDef *huart)
+{
+  if (!(IS_LPUART_INSTANCE(huart->Instance)))
+  {
+    if (huart->gState == HAL_UART_STATE_READY)
+    {
+      /* Process Locked */
+      __HAL_LOCK(huart);
+
+      huart->gState = HAL_UART_STATE_BUSY;
+
+      /* Set the USART RTOEN bit */
+      SET_BIT(huart->Instance->CR2, USART_CR2_RTOEN);
+
+      huart->gState = HAL_UART_STATE_READY;
+
+      /* Process Unlocked */
+      __HAL_UNLOCK(huart);
+
+      return HAL_OK;
+    }
+    else
+    {
+      return HAL_BUSY;
+    }
+  }
+  else
+  {
+    return HAL_ERROR;
+  }
+}
+
+/**
+  * @brief  Disable the UART receiver timeout feature.
+  * @param  huart Pointer to a UART_HandleTypeDef structure that contains
+  *                    the configuration information for the specified UART module.
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_UART_DisableReceiverTimeout(UART_HandleTypeDef *huart)
+{
+  if (!(IS_LPUART_INSTANCE(huart->Instance)))
+  {
+    if (huart->gState == HAL_UART_STATE_READY)
+    {
+      /* Process Locked */
+      __HAL_LOCK(huart);
+
+      huart->gState = HAL_UART_STATE_BUSY;
+
+      /* Clear the USART RTOEN bit */
+      CLEAR_BIT(huart->Instance->CR2, USART_CR2_RTOEN);
+
+      huart->gState = HAL_UART_STATE_READY;
+
+      /* Process Unlocked */
+      __HAL_UNLOCK(huart);
+
+      return HAL_OK;
+    }
+    else
+    {
+      return HAL_BUSY;
+    }
+  }
+  else
+  {
+    return HAL_ERROR;
+  }
+}
+
+/**
+  * @brief  Enable UART in mute mode (does not mean UART enters mute mode;
+  *         to enter mute mode, HAL_MultiProcessor_EnterMuteMode() API must be called).
+  * @param  huart UART handle.
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_MultiProcessor_EnableMuteMode(UART_HandleTypeDef *huart)
+{
+  __HAL_LOCK(huart);
+
+  huart->gState = HAL_UART_STATE_BUSY;
+
+  /* Enable USART mute mode by setting the MME bit in the CR1 register */
+  ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_MME);
+
+  huart->gState = HAL_UART_STATE_READY;
+
+  return (UART_CheckIdleState(huart));
+}
+
+/**
+  * @brief  Disable UART mute mode (does not mean the UART actually exits mute mode
+  *         as it may not have been in mute mode at this very moment).
+  * @param  huart UART handle.
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_MultiProcessor_DisableMuteMode(UART_HandleTypeDef *huart)
+{
+  __HAL_LOCK(huart);
+
+  huart->gState = HAL_UART_STATE_BUSY;
+
+  /* Disable USART mute mode by clearing the MME bit in the CR1 register */
+  ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_MME);
+
+  huart->gState = HAL_UART_STATE_READY;
+
+  return (UART_CheckIdleState(huart));
+}
+
+/**
+  * @brief Enter UART mute mode (means UART actually enters mute mode).
+  * @note  To exit from mute mode, HAL_MultiProcessor_DisableMuteMode() API must be called.
+  * @param huart UART handle.
+  * @retval None
+  */
+void HAL_MultiProcessor_EnterMuteMode(UART_HandleTypeDef *huart)
+{
+  __HAL_UART_SEND_REQ(huart, UART_MUTE_MODE_REQUEST);
+}
+
+/**
+  * @brief  Enable the UART transmitter and disable the UART receiver.
+  * @param  huart UART handle.
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_HalfDuplex_EnableTransmitter(UART_HandleTypeDef *huart)
+{
+  __HAL_LOCK(huart);
+  huart->gState = HAL_UART_STATE_BUSY;
+
+  /* Clear TE and RE bits */
+  ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TE | USART_CR1_RE));
+
+  /* Enable the USART's transmit interface by setting the TE bit in the USART CR1 register */
+  ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_TE);
+
+  huart->gState = HAL_UART_STATE_READY;
+
+  __HAL_UNLOCK(huart);
+
+  return HAL_OK;
+}
+
+/**
+  * @brief  Enable the UART receiver and disable the UART transmitter.
+  * @param  huart UART handle.
+  * @retval HAL status.
+  */
+HAL_StatusTypeDef HAL_HalfDuplex_EnableReceiver(UART_HandleTypeDef *huart)
+{
+  __HAL_LOCK(huart);
+  huart->gState = HAL_UART_STATE_BUSY;
+
+  /* Clear TE and RE bits */
+  ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TE | USART_CR1_RE));
+
+  /* Enable the USART's receive interface by setting the RE bit in the USART CR1 register */
+  ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_RE);
+
+  huart->gState = HAL_UART_STATE_READY;
+
+  __HAL_UNLOCK(huart);
+
+  return HAL_OK;
+}
+
+
+/**
+  * @brief  Transmit break characters.
+  * @param  huart UART handle.
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_LIN_SendBreak(UART_HandleTypeDef *huart)
+{
+  /* Check the parameters */
+  assert_param(IS_UART_LIN_INSTANCE(huart->Instance));
+
+  __HAL_LOCK(huart);
+
+  huart->gState = HAL_UART_STATE_BUSY;
+
+  /* Send break characters */
+  __HAL_UART_SEND_REQ(huart, UART_SENDBREAK_REQUEST);
+
+  huart->gState = HAL_UART_STATE_READY;
+
+  __HAL_UNLOCK(huart);
+
+  return HAL_OK;
+}
+
+/**
+  * @}
+  */
+
+/** @defgroup UART_Exported_Functions_Group4 Peripheral State and Error functions
+  *  @brief   UART Peripheral State functions
+  *
+@verbatim
+  ==============================================================================
+            ##### Peripheral State and Error functions #####
+  ==============================================================================
+    [..]
+    This subsection provides functions allowing to :
+      (+) Return the UART handle state.
+      (+) Return the UART handle error code
+
+@endverbatim
+  * @{
+  */
+
+/**
+  * @brief Return the UART handle state.
+  * @param  huart Pointer to a UART_HandleTypeDef structure that contains
+  *               the configuration information for the specified UART.
+  * @retval HAL state
+  */
+HAL_UART_StateTypeDef HAL_UART_GetState(const UART_HandleTypeDef *huart)
+{
+  uint32_t temp1;
+  uint32_t temp2;
+  temp1 = huart->gState;
+  temp2 = huart->RxState;
+
+  return (HAL_UART_StateTypeDef)(temp1 | temp2);
+}
+
+/**
+  * @brief  Return the UART handle error code.
+  * @param  huart Pointer to a UART_HandleTypeDef structure that contains
+  *               the configuration information for the specified UART.
+  * @retval UART Error Code
+  */
+uint32_t HAL_UART_GetError(const UART_HandleTypeDef *huart)
+{
+  return huart->ErrorCode;
+}
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/** @defgroup UART_Private_Functions UART Private Functions
+  * @{
+  */
+
+/**
+  * @brief  Initialize the callbacks to their default values.
+  * @param  huart UART handle.
+  * @retval none
+  */
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+void UART_InitCallbacksToDefault(UART_HandleTypeDef *huart)
+{
+  /* Init the UART Callback settings */
+  huart->TxHalfCpltCallback        = HAL_UART_TxHalfCpltCallback;        /* Legacy weak TxHalfCpltCallback        */
+  huart->TxCpltCallback            = HAL_UART_TxCpltCallback;            /* Legacy weak TxCpltCallback            */
+  huart->RxHalfCpltCallback        = HAL_UART_RxHalfCpltCallback;        /* Legacy weak RxHalfCpltCallback        */
+  huart->RxCpltCallback            = HAL_UART_RxCpltCallback;            /* Legacy weak RxCpltCallback            */
+  huart->ErrorCallback             = HAL_UART_ErrorCallback;             /* Legacy weak ErrorCallback             */
+  huart->AbortCpltCallback         = HAL_UART_AbortCpltCallback;         /* Legacy weak AbortCpltCallback         */
+  huart->AbortTransmitCpltCallback = HAL_UART_AbortTransmitCpltCallback; /* Legacy weak AbortTransmitCpltCallback */
+  huart->AbortReceiveCpltCallback  = HAL_UART_AbortReceiveCpltCallback;  /* Legacy weak AbortReceiveCpltCallback  */
+  huart->WakeupCallback            = HAL_UARTEx_WakeupCallback;          /* Legacy weak WakeupCallback            */
+  huart->RxFifoFullCallback        = HAL_UARTEx_RxFifoFullCallback;      /* Legacy weak RxFifoFullCallback        */
+  huart->TxFifoEmptyCallback       = HAL_UARTEx_TxFifoEmptyCallback;     /* Legacy weak TxFifoEmptyCallback       */
+  huart->RxEventCallback           = HAL_UARTEx_RxEventCallback;         /* Legacy weak RxEventCallback           */
+
+}
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+
+/**
+  * @brief Configure the UART peripheral.
+  * @param huart UART handle.
+  * @retval HAL status
+  */
+HAL_StatusTypeDef UART_SetConfig(UART_HandleTypeDef *huart)
+{
+  uint32_t tmpreg;
+  uint16_t brrtemp;
+  UART_ClockSourceTypeDef clocksource;
+  uint32_t usartdiv;
+  HAL_StatusTypeDef ret               = HAL_OK;
+  uint32_t lpuart_ker_ck_pres;
+  uint32_t pclk;
+
+  /* Check the parameters */
+  assert_param(IS_UART_BAUDRATE(huart->Init.BaudRate));
+  assert_param(IS_UART_WORD_LENGTH(huart->Init.WordLength));
+  if (UART_INSTANCE_LOWPOWER(huart))
+  {
+    assert_param(IS_LPUART_STOPBITS(huart->Init.StopBits));
+  }
+  else
+  {
+    assert_param(IS_UART_STOPBITS(huart->Init.StopBits));
+    assert_param(IS_UART_ONE_BIT_SAMPLE(huart->Init.OneBitSampling));
+  }
+
+  assert_param(IS_UART_PARITY(huart->Init.Parity));
+  assert_param(IS_UART_MODE(huart->Init.Mode));
+  assert_param(IS_UART_HARDWARE_FLOW_CONTROL(huart->Init.HwFlowCtl));
+  assert_param(IS_UART_OVERSAMPLING(huart->Init.OverSampling));
+  assert_param(IS_UART_PRESCALER(huart->Init.ClockPrescaler));
+
+  /*-------------------------- USART CR1 Configuration -----------------------*/
+  /* Clear M, PCE, PS, TE, RE and OVER8 bits and configure
+  *  the UART Word Length, Parity, Mode and oversampling:
+  *  set the M bits according to huart->Init.WordLength value
+  *  set PCE and PS bits according to huart->Init.Parity value
+  *  set TE and RE bits according to huart->Init.Mode value
+  *  set OVER8 bit according to huart->Init.OverSampling value */
+  tmpreg = (uint32_t)huart->Init.WordLength | huart->Init.Parity | huart->Init.Mode | huart->Init.OverSampling ;
+  MODIFY_REG(huart->Instance->CR1, USART_CR1_FIELDS, tmpreg);
+
+  /*-------------------------- USART CR2 Configuration -----------------------*/
+  /* Configure the UART Stop Bits: Set STOP[13:12] bits according
+  * to huart->Init.StopBits value */
+  MODIFY_REG(huart->Instance->CR2, USART_CR2_STOP, huart->Init.StopBits);
+
+  /*-------------------------- USART CR3 Configuration -----------------------*/
+  /* Configure
+  * - UART HardWare Flow Control: set CTSE and RTSE bits according
+  *   to huart->Init.HwFlowCtl value
+  * - one-bit sampling method versus three samples' majority rule according
+  *   to huart->Init.OneBitSampling (not applicable to LPUART) */
+  tmpreg = (uint32_t)huart->Init.HwFlowCtl;
+
+  if (!(UART_INSTANCE_LOWPOWER(huart)))
+  {
+    tmpreg |= huart->Init.OneBitSampling;
+  }
+  MODIFY_REG(huart->Instance->CR3, USART_CR3_FIELDS, tmpreg);
+
+  /*-------------------------- USART PRESC Configuration -----------------------*/
+  /* Configure
+  * - UART Clock Prescaler : set PRESCALER according to huart->Init.ClockPrescaler value */
+  MODIFY_REG(huart->Instance->PRESC, USART_PRESC_PRESCALER, huart->Init.ClockPrescaler);
+
+  /*-------------------------- USART BRR Configuration -----------------------*/
+  UART_GETCLOCKSOURCE(huart, clocksource);
+
+  /* Check LPUART instance */
+  if (UART_INSTANCE_LOWPOWER(huart))
+  {
+    /* Retrieve frequency clock */
+    switch (clocksource)
+    {
+      case UART_CLOCKSOURCE_PCLK1:
+        pclk = HAL_RCC_GetPCLK1Freq();
+        break;
+      case UART_CLOCKSOURCE_HSI:
+        pclk = (uint32_t) HSI_VALUE;
+        break;
+      case UART_CLOCKSOURCE_SYSCLK:
+        pclk = HAL_RCC_GetSysClockFreq();
+        break;
+      case UART_CLOCKSOURCE_LSE:
+        pclk = (uint32_t) LSE_VALUE;
+        break;
+      default:
+        pclk = 0U;
+        ret = HAL_ERROR;
+        break;
+    }
+
+    /* If proper clock source reported */
+    if (pclk != 0U)
+    {
+      /* Compute clock after Prescaler */
+      lpuart_ker_ck_pres = (pclk / UARTPrescTable[huart->Init.ClockPrescaler]);
+
+      /* Ensure that Frequency clock is in the range [3 * baudrate, 4096 * baudrate] */
+      if ((lpuart_ker_ck_pres < (3U * huart->Init.BaudRate)) ||
+          (lpuart_ker_ck_pres > (4096U * huart->Init.BaudRate)))
+      {
+        ret = HAL_ERROR;
+      }
+      else
+      {
+        /* Check computed UsartDiv value is in allocated range
+           (it is forbidden to write values lower than 0x300 in the LPUART_BRR register) */
+        usartdiv = (uint32_t)(UART_DIV_LPUART(pclk, huart->Init.BaudRate, huart->Init.ClockPrescaler));
+        if ((usartdiv >= LPUART_BRR_MIN) && (usartdiv <= LPUART_BRR_MAX))
+        {
+          huart->Instance->BRR = usartdiv;
+        }
+        else
+        {
+          ret = HAL_ERROR;
+        }
+      } /* if ( (lpuart_ker_ck_pres < (3 * huart->Init.BaudRate) ) ||
+                (lpuart_ker_ck_pres > (4096 * huart->Init.BaudRate) )) */
+    } /* if (pclk != 0) */
+  }
+  /* Check UART Over Sampling to set Baud Rate Register */
+  else if (huart->Init.OverSampling == UART_OVERSAMPLING_8)
+  {
+    switch (clocksource)
+    {
+      case UART_CLOCKSOURCE_PCLK1:
+        pclk = HAL_RCC_GetPCLK1Freq();
+        break;
+      case UART_CLOCKSOURCE_PCLK2:
+        pclk = HAL_RCC_GetPCLK2Freq();
+        break;
+      case UART_CLOCKSOURCE_HSI:
+        pclk = (uint32_t) HSI_VALUE;
+        break;
+      case UART_CLOCKSOURCE_SYSCLK:
+        pclk = HAL_RCC_GetSysClockFreq();
+        break;
+      case UART_CLOCKSOURCE_LSE:
+        pclk = (uint32_t) LSE_VALUE;
+        break;
+      default:
+        pclk = 0U;
+        ret = HAL_ERROR;
+        break;
+    }
+
+    /* USARTDIV must be greater than or equal to 0d16 */
+    if (pclk != 0U)
+    {
+      usartdiv = (uint32_t)(UART_DIV_SAMPLING8(pclk, huart->Init.BaudRate, huart->Init.ClockPrescaler));
+      if ((usartdiv >= UART_BRR_MIN) && (usartdiv <= UART_BRR_MAX))
+      {
+        brrtemp = (uint16_t)(usartdiv & 0xFFF0U);
+        brrtemp |= (uint16_t)((usartdiv & (uint16_t)0x000FU) >> 1U);
+        huart->Instance->BRR = brrtemp;
+      }
+      else
+      {
+        ret = HAL_ERROR;
+      }
+    }
+  }
+  else
+  {
+    switch (clocksource)
+    {
+      case UART_CLOCKSOURCE_PCLK1:
+        pclk = HAL_RCC_GetPCLK1Freq();
+        break;
+      case UART_CLOCKSOURCE_PCLK2:
+        pclk = HAL_RCC_GetPCLK2Freq();
+        break;
+      case UART_CLOCKSOURCE_HSI:
+        pclk = (uint32_t) HSI_VALUE;
+        break;
+      case UART_CLOCKSOURCE_SYSCLK:
+        pclk = HAL_RCC_GetSysClockFreq();
+        break;
+      case UART_CLOCKSOURCE_LSE:
+        pclk = (uint32_t) LSE_VALUE;
+        break;
+      default:
+        pclk = 0U;
+        ret = HAL_ERROR;
+        break;
+    }
+
+    if (pclk != 0U)
+    {
+      /* USARTDIV must be greater than or equal to 0d16 */
+      usartdiv = (uint32_t)(UART_DIV_SAMPLING16(pclk, huart->Init.BaudRate, huart->Init.ClockPrescaler));
+      if ((usartdiv >= UART_BRR_MIN) && (usartdiv <= UART_BRR_MAX))
+      {
+        huart->Instance->BRR = (uint16_t)usartdiv;
+      }
+      else
+      {
+        ret = HAL_ERROR;
+      }
+    }
+  }
+
+  /* Initialize the number of data to process during RX/TX ISR execution */
+  huart->NbTxDataToProcess = 1;
+  huart->NbRxDataToProcess = 1;
+
+  /* Clear ISR function pointers */
+  huart->RxISR = NULL;
+  huart->TxISR = NULL;
+
+  return ret;
+}
+
+/**
+  * @brief Configure the UART peripheral advanced features.
+  * @param huart UART handle.
+  * @retval None
+  */
+void UART_AdvFeatureConfig(UART_HandleTypeDef *huart)
+{
+  /* Check whether the set of advanced features to configure is properly set */
+  assert_param(IS_UART_ADVFEATURE_INIT(huart->AdvancedInit.AdvFeatureInit));
+
+  /* if required, configure RX/TX pins swap */
+  if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_SWAP_INIT))
+  {
+    assert_param(IS_UART_ADVFEATURE_SWAP(huart->AdvancedInit.Swap));
+    MODIFY_REG(huart->Instance->CR2, USART_CR2_SWAP, huart->AdvancedInit.Swap);
+  }
+
+  /* if required, configure TX pin active level inversion */
+  if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_TXINVERT_INIT))
+  {
+    assert_param(IS_UART_ADVFEATURE_TXINV(huart->AdvancedInit.TxPinLevelInvert));
+    MODIFY_REG(huart->Instance->CR2, USART_CR2_TXINV, huart->AdvancedInit.TxPinLevelInvert);
+  }
+
+  /* if required, configure RX pin active level inversion */
+  if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_RXINVERT_INIT))
+  {
+    assert_param(IS_UART_ADVFEATURE_RXINV(huart->AdvancedInit.RxPinLevelInvert));
+    MODIFY_REG(huart->Instance->CR2, USART_CR2_RXINV, huart->AdvancedInit.RxPinLevelInvert);
+  }
+
+  /* if required, configure data inversion */
+  if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_DATAINVERT_INIT))
+  {
+    assert_param(IS_UART_ADVFEATURE_DATAINV(huart->AdvancedInit.DataInvert));
+    MODIFY_REG(huart->Instance->CR2, USART_CR2_DATAINV, huart->AdvancedInit.DataInvert);
+  }
+
+  /* if required, configure RX overrun detection disabling */
+  if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_RXOVERRUNDISABLE_INIT))
+  {
+    assert_param(IS_UART_OVERRUN(huart->AdvancedInit.OverrunDisable));
+    MODIFY_REG(huart->Instance->CR3, USART_CR3_OVRDIS, huart->AdvancedInit.OverrunDisable);
+  }
+
+  /* if required, configure DMA disabling on reception error */
+  if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_DMADISABLEONERROR_INIT))
+  {
+    assert_param(IS_UART_ADVFEATURE_DMAONRXERROR(huart->AdvancedInit.DMADisableonRxError));
+    MODIFY_REG(huart->Instance->CR3, USART_CR3_DDRE, huart->AdvancedInit.DMADisableonRxError);
+  }
+
+  /* if required, configure auto Baud rate detection scheme */
+  if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_AUTOBAUDRATE_INIT))
+  {
+    assert_param(IS_USART_AUTOBAUDRATE_DETECTION_INSTANCE(huart->Instance));
+    assert_param(IS_UART_ADVFEATURE_AUTOBAUDRATE(huart->AdvancedInit.AutoBaudRateEnable));
+    MODIFY_REG(huart->Instance->CR2, USART_CR2_ABREN, huart->AdvancedInit.AutoBaudRateEnable);
+    /* set auto Baudrate detection parameters if detection is enabled */
+    if (huart->AdvancedInit.AutoBaudRateEnable == UART_ADVFEATURE_AUTOBAUDRATE_ENABLE)
+    {
+      assert_param(IS_UART_ADVFEATURE_AUTOBAUDRATEMODE(huart->AdvancedInit.AutoBaudRateMode));
+      MODIFY_REG(huart->Instance->CR2, USART_CR2_ABRMODE, huart->AdvancedInit.AutoBaudRateMode);
+    }
+  }
+
+  /* if required, configure MSB first on communication line */
+  if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_MSBFIRST_INIT))
+  {
+    assert_param(IS_UART_ADVFEATURE_MSBFIRST(huart->AdvancedInit.MSBFirst));
+    MODIFY_REG(huart->Instance->CR2, USART_CR2_MSBFIRST, huart->AdvancedInit.MSBFirst);
+  }
+}
+
+/**
+  * @brief Check the UART Idle State.
+  * @param huart UART handle.
+  * @retval HAL status
+  */
+HAL_StatusTypeDef UART_CheckIdleState(UART_HandleTypeDef *huart)
+{
+  uint32_t tickstart;
+
+  /* Initialize the UART ErrorCode */
+  huart->ErrorCode = HAL_UART_ERROR_NONE;
+
+  /* Init tickstart for timeout management */
+  tickstart = HAL_GetTick();
+
+  /* Check if the Transmitter is enabled */
+  if ((huart->Instance->CR1 & USART_CR1_TE) == USART_CR1_TE)
+  {
+    /* Wait until TEACK flag is set */
+    if (UART_WaitOnFlagUntilTimeout(huart, USART_ISR_TEACK, RESET, tickstart, HAL_UART_TIMEOUT_VALUE) != HAL_OK)
+    {
+      /* Disable TXE interrupt for the interrupt process */
+      ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TXEIE_TXFNFIE));
+
+      huart->gState = HAL_UART_STATE_READY;
+
+      __HAL_UNLOCK(huart);
+
+      /* Timeout occurred */
+      return HAL_TIMEOUT;
+    }
+  }
+
+  /* Check if the Receiver is enabled */
+  if ((huart->Instance->CR1 & USART_CR1_RE) == USART_CR1_RE)
+  {
+    /* Wait until REACK flag is set */
+    if (UART_WaitOnFlagUntilTimeout(huart, USART_ISR_REACK, RESET, tickstart, HAL_UART_TIMEOUT_VALUE) != HAL_OK)
+    {
+      /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error)
+      interrupts for the interrupt process */
+      ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE));
+      ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
+
+      huart->RxState = HAL_UART_STATE_READY;
+
+      __HAL_UNLOCK(huart);
+
+      /* Timeout occurred */
+      return HAL_TIMEOUT;
+    }
+  }
+
+  /* Initialize the UART State */
+  huart->gState = HAL_UART_STATE_READY;
+  huart->RxState = HAL_UART_STATE_READY;
+  huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
+  huart->RxEventType = HAL_UART_RXEVENT_TC;
+
+  __HAL_UNLOCK(huart);
+
+  return HAL_OK;
+}
+
+/**
+  * @brief  This function handles UART Communication Timeout. It waits
+  *                  until a flag is no longer in the specified status.
+  * @param huart     UART handle.
+  * @param Flag      Specifies the UART flag to check
+  * @param Status    The actual Flag status (SET or RESET)
+  * @param Tickstart Tick start value
+  * @param Timeout   Timeout duration
+  * @retval HAL status
+  */
+HAL_StatusTypeDef UART_WaitOnFlagUntilTimeout(UART_HandleTypeDef *huart, uint32_t Flag, FlagStatus Status,
+                                              uint32_t Tickstart, uint32_t Timeout)
+{
+  /* Wait until flag is set */
+  while ((__HAL_UART_GET_FLAG(huart, Flag) ? SET : RESET) == Status)
+  {
+    /* Check for the Timeout */
+    if (Timeout != HAL_MAX_DELAY)
+    {
+      if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U))
+      {
+
+        return HAL_TIMEOUT;
+      }
+
+      if ((READ_BIT(huart->Instance->CR1, USART_CR1_RE) != 0U) && (Flag != UART_FLAG_TXE) && (Flag != UART_FLAG_TC))
+      {
+        if (__HAL_UART_GET_FLAG(huart, UART_FLAG_ORE) == SET)
+        {
+          /* Clear Overrun Error flag*/
+          __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF);
+
+          /* Blocking error : transfer is aborted
+          Set the UART state ready to be able to start again the process,
+          Disable Rx Interrupts if ongoing */
+          UART_EndRxTransfer(huart);
+
+          huart->ErrorCode = HAL_UART_ERROR_ORE;
+
+          /* Process Unlocked */
+          __HAL_UNLOCK(huart);
+
+          return HAL_ERROR;
+        }
+        if (__HAL_UART_GET_FLAG(huart, UART_FLAG_RTOF) == SET)
+        {
+          /* Clear Receiver Timeout flag*/
+          __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_RTOF);
+
+          /* Blocking error : transfer is aborted
+          Set the UART state ready to be able to start again the process,
+          Disable Rx Interrupts if ongoing */
+          UART_EndRxTransfer(huart);
+
+          huart->ErrorCode = HAL_UART_ERROR_RTO;
+
+          /* Process Unlocked */
+          __HAL_UNLOCK(huart);
+
+          return HAL_TIMEOUT;
+        }
+      }
+    }
+  }
+  return HAL_OK;
+}
+
+/**
+  * @brief  Start Receive operation in interrupt mode.
+  * @note   This function could be called by all HAL UART API providing reception in Interrupt mode.
+  * @note   When calling this function, parameters validity is considered as already checked,
+  *         i.e. Rx State, buffer address, ...
+  *         UART Handle is assumed as Locked.
+  * @param  huart UART handle.
+  * @param  pData Pointer to data buffer (u8 or u16 data elements).
+  * @param  Size  Amount of data elements (u8 or u16) to be received.
+  * @retval HAL status
+  */
+HAL_StatusTypeDef UART_Start_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
+{
+  huart->pRxBuffPtr  = pData;
+  huart->RxXferSize  = Size;
+  huart->RxXferCount = Size;
+  huart->RxISR       = NULL;
+
+  /* Computation of UART mask to apply to RDR register */
+  UART_MASK_COMPUTATION(huart);
+
+  huart->ErrorCode = HAL_UART_ERROR_NONE;
+  huart->RxState = HAL_UART_STATE_BUSY_RX;
+
+  /* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */
+  ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_EIE);
+
+  /* Configure Rx interrupt processing */
+  if ((huart->FifoMode == UART_FIFOMODE_ENABLE) && (Size >= huart->NbRxDataToProcess))
+  {
+    /* Set the Rx ISR function pointer according to the data word length */
+    if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
+    {
+      huart->RxISR = UART_RxISR_16BIT_FIFOEN;
+    }
+    else
+    {
+      huart->RxISR = UART_RxISR_8BIT_FIFOEN;
+    }
+
+    /* Enable the UART Parity Error interrupt and RX FIFO Threshold interrupt */
+    if (huart->Init.Parity != UART_PARITY_NONE)
+    {
+      ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_PEIE);
+    }
+    ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_RXFTIE);
+  }
+  else
+  {
+    /* Set the Rx ISR function pointer according to the data word length */
+    if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
+    {
+      huart->RxISR = UART_RxISR_16BIT;
+    }
+    else
+    {
+      huart->RxISR = UART_RxISR_8BIT;
+    }
+
+    /* Enable the UART Parity Error interrupt and Data Register Not Empty interrupt */
+    if (huart->Init.Parity != UART_PARITY_NONE)
+    {
+      ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_PEIE | USART_CR1_RXNEIE_RXFNEIE);
+    }
+    else
+    {
+      ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_RXNEIE_RXFNEIE);
+    }
+  }
+  return HAL_OK;
+}
+
+/**
+  * @brief  Start Receive operation in DMA mode.
+  * @note   This function could be called by all HAL UART API providing reception in DMA mode.
+  * @note   When calling this function, parameters validity is considered as already checked,
+  *         i.e. Rx State, buffer address, ...
+  *         UART Handle is assumed as Locked.
+  * @param  huart UART handle.
+  * @param  pData Pointer to data buffer (u8 or u16 data elements).
+  * @param  Size  Amount of data elements (u8 or u16) to be received.
+  * @retval HAL status
+  */
+HAL_StatusTypeDef UART_Start_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
+{
+  huart->pRxBuffPtr = pData;
+  huart->RxXferSize = Size;
+
+  huart->ErrorCode = HAL_UART_ERROR_NONE;
+  huart->RxState = HAL_UART_STATE_BUSY_RX;
+
+  if (huart->hdmarx != NULL)
+  {
+    /* Set the UART DMA transfer complete callback */
+    huart->hdmarx->XferCpltCallback = UART_DMAReceiveCplt;
+
+    /* Set the UART DMA Half transfer complete callback */
+    huart->hdmarx->XferHalfCpltCallback = UART_DMARxHalfCplt;
+
+    /* Set the DMA error callback */
+    huart->hdmarx->XferErrorCallback = UART_DMAError;
+
+    /* Set the DMA abort callback */
+    huart->hdmarx->XferAbortCallback = NULL;
+
+    /* Enable the DMA channel */
+    if (HAL_DMA_Start_IT(huart->hdmarx, (uint32_t)&huart->Instance->RDR, (uint32_t)huart->pRxBuffPtr, Size) != HAL_OK)
+    {
+      /* Set error code to DMA */
+      huart->ErrorCode = HAL_UART_ERROR_DMA;
+
+      /* Restore huart->RxState to ready */
+      huart->RxState = HAL_UART_STATE_READY;
+
+      return HAL_ERROR;
+    }
+  }
+
+  /* Enable the UART Parity Error Interrupt */
+  if (huart->Init.Parity != UART_PARITY_NONE)
+  {
+    ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_PEIE);
+  }
+
+  /* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */
+  ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_EIE);
+
+  /* Enable the DMA transfer for the receiver request by setting the DMAR bit
+  in the UART CR3 register */
+  ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_DMAR);
+
+  return HAL_OK;
+}
+
+
+/**
+  * @brief  End ongoing Tx transfer on UART peripheral (following error detection or Transmit completion).
+  * @param  huart UART handle.
+  * @retval None
+  */
+static void UART_EndTxTransfer(UART_HandleTypeDef *huart)
+{
+  /* Disable TXEIE, TCIE, TXFT interrupts */
+  ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TXEIE_TXFNFIE | USART_CR1_TCIE));
+  ATOMIC_CLEAR_BIT(huart->Instance->CR3, (USART_CR3_TXFTIE));
+
+  /* At end of Tx process, restore huart->gState to Ready */
+  huart->gState = HAL_UART_STATE_READY;
+}
+
+
+/**
+  * @brief  End ongoing Rx transfer on UART peripheral (following error detection or Reception completion).
+  * @param  huart UART handle.
+  * @retval None
+  */
+static void UART_EndRxTransfer(UART_HandleTypeDef *huart)
+{
+  /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
+  ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE));
+  ATOMIC_CLEAR_BIT(huart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE));
+
+  /* In case of reception waiting for IDLE event, disable also the IDLE IE interrupt source */
+  if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
+  {
+    ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);
+  }
+
+  /* At end of Rx process, restore huart->RxState to Ready */
+  huart->RxState = HAL_UART_STATE_READY;
+  huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
+
+  /* Reset RxIsr function pointer */
+  huart->RxISR = NULL;
+}
+
+
+/**
+  * @brief DMA UART transmit process complete callback.
+  * @param hdma DMA handle.
+  * @retval None
+  */
+static void UART_DMATransmitCplt(DMA_HandleTypeDef *hdma)
+{
+  UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent);
+
+  /* DMA Normal mode */
+  if (HAL_IS_BIT_CLR(hdma->Instance->CCR, DMA_CCR_CIRC))
+  {
+    huart->TxXferCount = 0U;
+
+    /* Disable the DMA transfer for transmit request by resetting the DMAT bit
+       in the UART CR3 register */
+    ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
+
+    /* Enable the UART Transmit Complete Interrupt */
+    ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_TCIE);
+  }
+  /* DMA Circular mode */
+  else
+  {
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+    /*Call registered Tx complete callback*/
+    huart->TxCpltCallback(huart);
+#else
+    /*Call legacy weak Tx complete callback*/
+    HAL_UART_TxCpltCallback(huart);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+  }
+}
+
+/**
+  * @brief DMA UART transmit process half complete callback.
+  * @param hdma DMA handle.
+  * @retval None
+  */
+static void UART_DMATxHalfCplt(DMA_HandleTypeDef *hdma)
+{
+  UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent);
+
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+  /*Call registered Tx Half complete callback*/
+  huart->TxHalfCpltCallback(huart);
+#else
+  /*Call legacy weak Tx Half complete callback*/
+  HAL_UART_TxHalfCpltCallback(huart);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+}
+
+/**
+  * @brief DMA UART receive process complete callback.
+  * @param hdma DMA handle.
+  * @retval None
+  */
+static void UART_DMAReceiveCplt(DMA_HandleTypeDef *hdma)
+{
+  UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent);
+
+  /* DMA Normal mode */
+  if (HAL_IS_BIT_CLR(hdma->Instance->CCR, DMA_CCR_CIRC))
+  {
+    huart->RxXferCount = 0U;
+
+    /* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */
+    ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_PEIE);
+    ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
+
+    /* Disable the DMA transfer for the receiver request by resetting the DMAR bit
+       in the UART CR3 register */
+    ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
+
+    /* At end of Rx process, restore huart->RxState to Ready */
+    huart->RxState = HAL_UART_STATE_READY;
+
+    /* If Reception till IDLE event has been selected, Disable IDLE Interrupt */
+    if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
+    {
+      ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);
+    }
+  }
+
+  /* Initialize type of RxEvent that correspond to RxEvent callback execution;
+     In this case, Rx Event type is Transfer Complete */
+  huart->RxEventType = HAL_UART_RXEVENT_TC;
+
+  /* Check current reception Mode :
+     If Reception till IDLE event has been selected : use Rx Event callback */
+  if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
+  {
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+    /*Call registered Rx Event callback*/
+    huart->RxEventCallback(huart, huart->RxXferSize);
+#else
+    /*Call legacy weak Rx Event callback*/
+    HAL_UARTEx_RxEventCallback(huart, huart->RxXferSize);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+  }
+  else
+  {
+    /* In other cases : use Rx Complete callback */
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+    /*Call registered Rx complete callback*/
+    huart->RxCpltCallback(huart);
+#else
+    /*Call legacy weak Rx complete callback*/
+    HAL_UART_RxCpltCallback(huart);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+  }
+}
+
+/**
+  * @brief DMA UART receive process half complete callback.
+  * @param hdma DMA handle.
+  * @retval None
+  */
+static void UART_DMARxHalfCplt(DMA_HandleTypeDef *hdma)
+{
+  UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent);
+
+  /* Initialize type of RxEvent that correspond to RxEvent callback execution;
+     In this case, Rx Event type is Half Transfer */
+  huart->RxEventType = HAL_UART_RXEVENT_HT;
+
+  /* Check current reception Mode :
+     If Reception till IDLE event has been selected : use Rx Event callback */
+  if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
+  {
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+    /*Call registered Rx Event callback*/
+    huart->RxEventCallback(huart, huart->RxXferSize / 2U);
+#else
+    /*Call legacy weak Rx Event callback*/
+    HAL_UARTEx_RxEventCallback(huart, huart->RxXferSize / 2U);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+  }
+  else
+  {
+    /* In other cases : use Rx Half Complete callback */
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+    /*Call registered Rx Half complete callback*/
+    huart->RxHalfCpltCallback(huart);
+#else
+    /*Call legacy weak Rx Half complete callback*/
+    HAL_UART_RxHalfCpltCallback(huart);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+  }
+}
+
+/**
+  * @brief DMA UART communication error callback.
+  * @param hdma DMA handle.
+  * @retval None
+  */
+static void UART_DMAError(DMA_HandleTypeDef *hdma)
+{
+  UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent);
+
+  const HAL_UART_StateTypeDef gstate = huart->gState;
+  const HAL_UART_StateTypeDef rxstate = huart->RxState;
+
+  /* Stop UART DMA Tx request if ongoing */
+  if ((HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT)) &&
+      (gstate == HAL_UART_STATE_BUSY_TX))
+  {
+    huart->TxXferCount = 0U;
+    UART_EndTxTransfer(huart);
+  }
+
+  /* Stop UART DMA Rx request if ongoing */
+  if ((HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)) &&
+      (rxstate == HAL_UART_STATE_BUSY_RX))
+  {
+    huart->RxXferCount = 0U;
+    UART_EndRxTransfer(huart);
+  }
+
+  huart->ErrorCode |= HAL_UART_ERROR_DMA;
+
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+  /*Call registered error callback*/
+  huart->ErrorCallback(huart);
+#else
+  /*Call legacy weak error callback*/
+  HAL_UART_ErrorCallback(huart);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+}
+
+/**
+  * @brief  DMA UART communication abort callback, when initiated by HAL services on Error
+  *         (To be called at end of DMA Abort procedure following error occurrence).
+  * @param  hdma DMA handle.
+  * @retval None
+  */
+static void UART_DMAAbortOnError(DMA_HandleTypeDef *hdma)
+{
+  UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent);
+  huart->RxXferCount = 0U;
+  huart->TxXferCount = 0U;
+
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+  /*Call registered error callback*/
+  huart->ErrorCallback(huart);
+#else
+  /*Call legacy weak error callback*/
+  HAL_UART_ErrorCallback(huart);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+}
+
+/**
+  * @brief  DMA UART Tx communication abort callback, when initiated by user
+  *         (To be called at end of DMA Tx Abort procedure following user abort request).
+  * @note   When this callback is executed, User Abort complete call back is called only if no
+  *         Abort still ongoing for Rx DMA Handle.
+  * @param  hdma DMA handle.
+  * @retval None
+  */
+static void UART_DMATxAbortCallback(DMA_HandleTypeDef *hdma)
+{
+  UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent);
+
+  huart->hdmatx->XferAbortCallback = NULL;
+
+  /* Check if an Abort process is still ongoing */
+  if (huart->hdmarx != NULL)
+  {
+    if (huart->hdmarx->XferAbortCallback != NULL)
+    {
+      return;
+    }
+  }
+
+  /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */
+  huart->TxXferCount = 0U;
+  huart->RxXferCount = 0U;
+
+  /* Reset errorCode */
+  huart->ErrorCode = HAL_UART_ERROR_NONE;
+
+  /* Clear the Error flags in the ICR register */
+  __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_PEF | UART_CLEAR_FEF);
+
+  /* Flush the whole TX FIFO (if needed) */
+  if (huart->FifoMode == UART_FIFOMODE_ENABLE)
+  {
+    __HAL_UART_SEND_REQ(huart, UART_TXDATA_FLUSH_REQUEST);
+  }
+
+  /* Restore huart->gState and huart->RxState to Ready */
+  huart->gState  = HAL_UART_STATE_READY;
+  huart->RxState = HAL_UART_STATE_READY;
+  huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
+
+  /* Call user Abort complete callback */
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+  /* Call registered Abort complete callback */
+  huart->AbortCpltCallback(huart);
+#else
+  /* Call legacy weak Abort complete callback */
+  HAL_UART_AbortCpltCallback(huart);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+}
+
+
+/**
+  * @brief  DMA UART Rx communication abort callback, when initiated by user
+  *         (To be called at end of DMA Rx Abort procedure following user abort request).
+  * @note   When this callback is executed, User Abort complete call back is called only if no
+  *         Abort still ongoing for Tx DMA Handle.
+  * @param  hdma DMA handle.
+  * @retval None
+  */
+static void UART_DMARxAbortCallback(DMA_HandleTypeDef *hdma)
+{
+  UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent);
+
+  huart->hdmarx->XferAbortCallback = NULL;
+
+  /* Check if an Abort process is still ongoing */
+  if (huart->hdmatx != NULL)
+  {
+    if (huart->hdmatx->XferAbortCallback != NULL)
+    {
+      return;
+    }
+  }
+
+  /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */
+  huart->TxXferCount = 0U;
+  huart->RxXferCount = 0U;
+
+  /* Reset errorCode */
+  huart->ErrorCode = HAL_UART_ERROR_NONE;
+
+  /* Clear the Error flags in the ICR register */
+  __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_PEF | UART_CLEAR_FEF);
+
+  /* Discard the received data */
+  __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);
+
+  /* Restore huart->gState and huart->RxState to Ready */
+  huart->gState  = HAL_UART_STATE_READY;
+  huart->RxState = HAL_UART_STATE_READY;
+  huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
+
+  /* Call user Abort complete callback */
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+  /* Call registered Abort complete callback */
+  huart->AbortCpltCallback(huart);
+#else
+  /* Call legacy weak Abort complete callback */
+  HAL_UART_AbortCpltCallback(huart);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+}
+
+
+/**
+  * @brief  DMA UART Tx communication abort callback, when initiated by user by a call to
+  *         HAL_UART_AbortTransmit_IT API (Abort only Tx transfer)
+  *         (This callback is executed at end of DMA Tx Abort procedure following user abort request,
+  *         and leads to user Tx Abort Complete callback execution).
+  * @param  hdma DMA handle.
+  * @retval None
+  */
+static void UART_DMATxOnlyAbortCallback(DMA_HandleTypeDef *hdma)
+{
+  UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent);
+
+  huart->TxXferCount = 0U;
+
+  /* Flush the whole TX FIFO (if needed) */
+  if (huart->FifoMode == UART_FIFOMODE_ENABLE)
+  {
+    __HAL_UART_SEND_REQ(huart, UART_TXDATA_FLUSH_REQUEST);
+  }
+
+  /* Restore huart->gState to Ready */
+  huart->gState = HAL_UART_STATE_READY;
+
+  /* Call user Abort complete callback */
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+  /* Call registered Abort Transmit Complete Callback */
+  huart->AbortTransmitCpltCallback(huart);
+#else
+  /* Call legacy weak Abort Transmit Complete Callback */
+  HAL_UART_AbortTransmitCpltCallback(huart);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+}
+
+/**
+  * @brief  DMA UART Rx communication abort callback, when initiated by user by a call to
+  *         HAL_UART_AbortReceive_IT API (Abort only Rx transfer)
+  *         (This callback is executed at end of DMA Rx Abort procedure following user abort request,
+  *         and leads to user Rx Abort Complete callback execution).
+  * @param  hdma DMA handle.
+  * @retval None
+  */
+static void UART_DMARxOnlyAbortCallback(DMA_HandleTypeDef *hdma)
+{
+  UART_HandleTypeDef *huart = (UART_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
+
+  huart->RxXferCount = 0U;
+
+  /* Clear the Error flags in the ICR register */
+  __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_PEF | UART_CLEAR_FEF);
+
+  /* Discard the received data */
+  __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);
+
+  /* Restore huart->RxState to Ready */
+  huart->RxState = HAL_UART_STATE_READY;
+  huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
+
+  /* Call user Abort complete callback */
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+  /* Call registered Abort Receive Complete Callback */
+  huart->AbortReceiveCpltCallback(huart);
+#else
+  /* Call legacy weak Abort Receive Complete Callback */
+  HAL_UART_AbortReceiveCpltCallback(huart);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+}
+
+/**
+  * @brief TX interrupt handler for 7 or 8 bits data word length .
+  * @note   Function is called under interruption only, once
+  *         interruptions have been enabled by HAL_UART_Transmit_IT().
+  * @param huart UART handle.
+  * @retval None
+  */
+static void UART_TxISR_8BIT(UART_HandleTypeDef *huart)
+{
+  /* Check that a Tx process is ongoing */
+  if (huart->gState == HAL_UART_STATE_BUSY_TX)
+  {
+    if (huart->TxXferCount == 0U)
+    {
+      /* Disable the UART Transmit Data Register Empty Interrupt */
+      ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_TXEIE_TXFNFIE);
+
+      /* Enable the UART Transmit Complete Interrupt */
+      ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_TCIE);
+    }
+    else
+    {
+      huart->Instance->TDR = (uint8_t)(*huart->pTxBuffPtr & (uint8_t)0xFF);
+      huart->pTxBuffPtr++;
+      huart->TxXferCount--;
+    }
+  }
+}
+
+/**
+  * @brief TX interrupt handler for 9 bits data word length.
+  * @note   Function is called under interruption only, once
+  *         interruptions have been enabled by HAL_UART_Transmit_IT().
+  * @param huart UART handle.
+  * @retval None
+  */
+static void UART_TxISR_16BIT(UART_HandleTypeDef *huart)
+{
+  const uint16_t *tmp;
+
+  /* Check that a Tx process is ongoing */
+  if (huart->gState == HAL_UART_STATE_BUSY_TX)
+  {
+    if (huart->TxXferCount == 0U)
+    {
+      /* Disable the UART Transmit Data Register Empty Interrupt */
+      ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_TXEIE_TXFNFIE);
+
+      /* Enable the UART Transmit Complete Interrupt */
+      ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_TCIE);
+    }
+    else
+    {
+      tmp = (const uint16_t *) huart->pTxBuffPtr;
+      huart->Instance->TDR = (((uint32_t)(*tmp)) & 0x01FFUL);
+      huart->pTxBuffPtr += 2U;
+      huart->TxXferCount--;
+    }
+  }
+}
+
+/**
+  * @brief TX interrupt handler for 7 or 8 bits data word length and FIFO mode is enabled.
+  * @note   Function is called under interruption only, once
+  *         interruptions have been enabled by HAL_UART_Transmit_IT().
+  * @param huart UART handle.
+  * @retval None
+  */
+static void UART_TxISR_8BIT_FIFOEN(UART_HandleTypeDef *huart)
+{
+  uint16_t  nb_tx_data;
+
+  /* Check that a Tx process is ongoing */
+  if (huart->gState == HAL_UART_STATE_BUSY_TX)
+  {
+    for (nb_tx_data = huart->NbTxDataToProcess ; nb_tx_data > 0U ; nb_tx_data--)
+    {
+      if (huart->TxXferCount == 0U)
+      {
+        /* Disable the TX FIFO threshold interrupt */
+        ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_TXFTIE);
+
+        /* Enable the UART Transmit Complete Interrupt */
+        ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_TCIE);
+
+        break; /* force exit loop */
+      }
+      else if (READ_BIT(huart->Instance->ISR, USART_ISR_TXE_TXFNF) != 0U)
+      {
+        huart->Instance->TDR = (uint8_t)(*huart->pTxBuffPtr & (uint8_t)0xFF);
+        huart->pTxBuffPtr++;
+        huart->TxXferCount--;
+      }
+      else
+      {
+        /* Nothing to do */
+      }
+    }
+  }
+}
+
+/**
+  * @brief TX interrupt handler for 9 bits data word length and FIFO mode is enabled.
+  * @note   Function is called under interruption only, once
+  *         interruptions have been enabled by HAL_UART_Transmit_IT().
+  * @param huart UART handle.
+  * @retval None
+  */
+static void UART_TxISR_16BIT_FIFOEN(UART_HandleTypeDef *huart)
+{
+  const uint16_t *tmp;
+  uint16_t  nb_tx_data;
+
+  /* Check that a Tx process is ongoing */
+  if (huart->gState == HAL_UART_STATE_BUSY_TX)
+  {
+    for (nb_tx_data = huart->NbTxDataToProcess ; nb_tx_data > 0U ; nb_tx_data--)
+    {
+      if (huart->TxXferCount == 0U)
+      {
+        /* Disable the TX FIFO threshold interrupt */
+        ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_TXFTIE);
+
+        /* Enable the UART Transmit Complete Interrupt */
+        ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_TCIE);
+
+        break; /* force exit loop */
+      }
+      else if (READ_BIT(huart->Instance->ISR, USART_ISR_TXE_TXFNF) != 0U)
+      {
+        tmp = (const uint16_t *) huart->pTxBuffPtr;
+        huart->Instance->TDR = (((uint32_t)(*tmp)) & 0x01FFUL);
+        huart->pTxBuffPtr += 2U;
+        huart->TxXferCount--;
+      }
+      else
+      {
+        /* Nothing to do */
+      }
+    }
+  }
+}
+
+/**
+  * @brief  Wrap up transmission in non-blocking mode.
+  * @param  huart pointer to a UART_HandleTypeDef structure that contains
+  *                the configuration information for the specified UART module.
+  * @retval None
+  */
+static void UART_EndTransmit_IT(UART_HandleTypeDef *huart)
+{
+  /* Disable the UART Transmit Complete Interrupt */
+  ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_TCIE);
+
+  /* Tx process is ended, restore huart->gState to Ready */
+  huart->gState = HAL_UART_STATE_READY;
+
+  /* Cleat TxISR function pointer */
+  huart->TxISR = NULL;
+
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+  /*Call registered Tx complete callback*/
+  huart->TxCpltCallback(huart);
+#else
+  /*Call legacy weak Tx complete callback*/
+  HAL_UART_TxCpltCallback(huart);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+}
+
+/**
+  * @brief RX interrupt handler for 7 or 8 bits data word length .
+  * @param huart UART handle.
+  * @retval None
+  */
+static void UART_RxISR_8BIT(UART_HandleTypeDef *huart)
+{
+  uint16_t uhMask = huart->Mask;
+  uint16_t  uhdata;
+
+  /* Check that a Rx process is ongoing */
+  if (huart->RxState == HAL_UART_STATE_BUSY_RX)
+  {
+    uhdata = (uint16_t) READ_REG(huart->Instance->RDR);
+    *huart->pRxBuffPtr = (uint8_t)(uhdata & (uint8_t)uhMask);
+    huart->pRxBuffPtr++;
+    huart->RxXferCount--;
+
+    if (huart->RxXferCount == 0U)
+    {
+      /* Disable the UART Parity Error Interrupt and RXNE interrupts */
+      ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE));
+
+      /* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) */
+      ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
+
+      /* Rx process is completed, restore huart->RxState to Ready */
+      huart->RxState = HAL_UART_STATE_READY;
+
+      /* Clear RxISR function pointer */
+      huart->RxISR = NULL;
+
+      /* Initialize type of RxEvent to Transfer Complete */
+      huart->RxEventType = HAL_UART_RXEVENT_TC;
+
+      if (!(IS_LPUART_INSTANCE(huart->Instance)))
+      {
+        /* Check that USART RTOEN bit is set */
+        if (READ_BIT(huart->Instance->CR2, USART_CR2_RTOEN) != 0U)
+        {
+          /* Enable the UART Receiver Timeout Interrupt */
+          ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_RTOIE);
+        }
+      }
+
+      /* Check current reception Mode :
+         If Reception till IDLE event has been selected : */
+      if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
+      {
+        /* Set reception type to Standard */
+        huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
+
+        /* Disable IDLE interrupt */
+        ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);
+
+        if (__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE) == SET)
+        {
+          /* Clear IDLE Flag */
+          __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_IDLEF);
+        }
+
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+        /*Call registered Rx Event callback*/
+        huart->RxEventCallback(huart, huart->RxXferSize);
+#else
+        /*Call legacy weak Rx Event callback*/
+        HAL_UARTEx_RxEventCallback(huart, huart->RxXferSize);
+#endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
+      }
+      else
+      {
+        /* Standard reception API called */
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+        /*Call registered Rx complete callback*/
+        huart->RxCpltCallback(huart);
+#else
+        /*Call legacy weak Rx complete callback*/
+        HAL_UART_RxCpltCallback(huart);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+      }
+    }
+  }
+  else
+  {
+    /* Clear RXNE interrupt flag */
+    __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);
+  }
+}
+
+/**
+  * @brief RX interrupt handler for 9 bits data word length .
+  * @note   Function is called under interruption only, once
+  *         interruptions have been enabled by HAL_UART_Receive_IT()
+  * @param huart UART handle.
+  * @retval None
+  */
+static void UART_RxISR_16BIT(UART_HandleTypeDef *huart)
+{
+  uint16_t *tmp;
+  uint16_t uhMask = huart->Mask;
+  uint16_t  uhdata;
+
+  /* Check that a Rx process is ongoing */
+  if (huart->RxState == HAL_UART_STATE_BUSY_RX)
+  {
+    uhdata = (uint16_t) READ_REG(huart->Instance->RDR);
+    tmp = (uint16_t *) huart->pRxBuffPtr ;
+    *tmp = (uint16_t)(uhdata & uhMask);
+    huart->pRxBuffPtr += 2U;
+    huart->RxXferCount--;
+
+    if (huart->RxXferCount == 0U)
+    {
+      /* Disable the UART Parity Error Interrupt and RXNE interrupt*/
+      ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE));
+
+      /* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) */
+      ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
+
+      /* Rx process is completed, restore huart->RxState to Ready */
+      huart->RxState = HAL_UART_STATE_READY;
+
+      /* Clear RxISR function pointer */
+      huart->RxISR = NULL;
+
+      /* Initialize type of RxEvent to Transfer Complete */
+      huart->RxEventType = HAL_UART_RXEVENT_TC;
+
+      if (!(IS_LPUART_INSTANCE(huart->Instance)))
+      {
+        /* Check that USART RTOEN bit is set */
+        if (READ_BIT(huart->Instance->CR2, USART_CR2_RTOEN) != 0U)
+        {
+          /* Enable the UART Receiver Timeout Interrupt */
+          ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_RTOIE);
+        }
+      }
+
+      /* Check current reception Mode :
+         If Reception till IDLE event has been selected : */
+      if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
+      {
+        /* Set reception type to Standard */
+        huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
+
+        /* Disable IDLE interrupt */
+        ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);
+
+        if (__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE) == SET)
+        {
+          /* Clear IDLE Flag */
+          __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_IDLEF);
+        }
+
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+        /*Call registered Rx Event callback*/
+        huart->RxEventCallback(huart, huart->RxXferSize);
+#else
+        /*Call legacy weak Rx Event callback*/
+        HAL_UARTEx_RxEventCallback(huart, huart->RxXferSize);
+#endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
+      }
+      else
+      {
+        /* Standard reception API called */
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+        /*Call registered Rx complete callback*/
+        huart->RxCpltCallback(huart);
+#else
+        /*Call legacy weak Rx complete callback*/
+        HAL_UART_RxCpltCallback(huart);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+      }
+    }
+  }
+  else
+  {
+    /* Clear RXNE interrupt flag */
+    __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);
+  }
+}
+
+/**
+  * @brief RX interrupt handler for 7 or 8  bits data word length and FIFO mode is enabled.
+  * @note   Function is called under interruption only, once
+  *         interruptions have been enabled by HAL_UART_Receive_IT()
+  * @param huart UART handle.
+  * @retval None
+  */
+static void UART_RxISR_8BIT_FIFOEN(UART_HandleTypeDef *huart)
+{
+  uint16_t  uhMask = huart->Mask;
+  uint16_t  uhdata;
+  uint16_t  nb_rx_data;
+  uint16_t  rxdatacount;
+  uint32_t  isrflags = READ_REG(huart->Instance->ISR);
+  uint32_t  cr1its   = READ_REG(huart->Instance->CR1);
+  uint32_t  cr3its   = READ_REG(huart->Instance->CR3);
+
+  /* Check that a Rx process is ongoing */
+  if (huart->RxState == HAL_UART_STATE_BUSY_RX)
+  {
+    nb_rx_data = huart->NbRxDataToProcess;
+    while ((nb_rx_data > 0U) && ((isrflags & USART_ISR_RXNE_RXFNE) != 0U))
+    {
+      uhdata = (uint16_t) READ_REG(huart->Instance->RDR);
+      *huart->pRxBuffPtr = (uint8_t)(uhdata & (uint8_t)uhMask);
+      huart->pRxBuffPtr++;
+      huart->RxXferCount--;
+      isrflags = READ_REG(huart->Instance->ISR);
+
+      /* If some non blocking errors occurred */
+      if ((isrflags & (USART_ISR_PE | USART_ISR_FE | USART_ISR_NE)) != 0U)
+      {
+        /* UART parity error interrupt occurred -------------------------------------*/
+        if (((isrflags & USART_ISR_PE) != 0U) && ((cr1its & USART_CR1_PEIE) != 0U))
+        {
+          __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_PEF);
+
+          huart->ErrorCode |= HAL_UART_ERROR_PE;
+        }
+
+        /* UART frame error interrupt occurred --------------------------------------*/
+        if (((isrflags & USART_ISR_FE) != 0U) && ((cr3its & USART_CR3_EIE) != 0U))
+        {
+          __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_FEF);
+
+          huart->ErrorCode |= HAL_UART_ERROR_FE;
+        }
+
+        /* UART noise error interrupt occurred --------------------------------------*/
+        if (((isrflags & USART_ISR_NE) != 0U) && ((cr3its & USART_CR3_EIE) != 0U))
+        {
+          __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_NEF);
+
+          huart->ErrorCode |= HAL_UART_ERROR_NE;
+        }
+
+        /* Call UART Error Call back function if need be ----------------------------*/
+        if (huart->ErrorCode != HAL_UART_ERROR_NONE)
+        {
+          /* Non Blocking error : transfer could go on.
+          Error is notified to user through user error callback */
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+          /*Call registered error callback*/
+          huart->ErrorCallback(huart);
+#else
+          /*Call legacy weak error callback*/
+          HAL_UART_ErrorCallback(huart);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+          huart->ErrorCode = HAL_UART_ERROR_NONE;
+        }
+      }
+
+      if (huart->RxXferCount == 0U)
+      {
+        /* Disable the UART Parity Error Interrupt and RXFT interrupt*/
+        ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_PEIE);
+
+        /* Disable the UART Error Interrupt: (Frame error, noise error, overrun error)
+           and RX FIFO Threshold interrupt */
+        ATOMIC_CLEAR_BIT(huart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE));
+
+        /* Rx process is completed, restore huart->RxState to Ready */
+        huart->RxState = HAL_UART_STATE_READY;
+
+        /* Clear RxISR function pointer */
+        huart->RxISR = NULL;
+
+        /* Initialize type of RxEvent to Transfer Complete */
+        huart->RxEventType = HAL_UART_RXEVENT_TC;
+
+        if (!(IS_LPUART_INSTANCE(huart->Instance)))
+        {
+          /* Check that USART RTOEN bit is set */
+          if (READ_BIT(huart->Instance->CR2, USART_CR2_RTOEN) != 0U)
+          {
+            /* Enable the UART Receiver Timeout Interrupt */
+            ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_RTOIE);
+          }
+        }
+
+        /* Check current reception Mode :
+           If Reception till IDLE event has been selected : */
+        if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
+        {
+          /* Set reception type to Standard */
+          huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
+
+          /* Disable IDLE interrupt */
+          ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);
+
+          if (__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE) == SET)
+          {
+            /* Clear IDLE Flag */
+            __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_IDLEF);
+          }
+
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+          /*Call registered Rx Event callback*/
+          huart->RxEventCallback(huart, huart->RxXferSize);
+#else
+          /*Call legacy weak Rx Event callback*/
+          HAL_UARTEx_RxEventCallback(huart, huart->RxXferSize);
+#endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
+        }
+        else
+        {
+          /* Standard reception API called */
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+          /*Call registered Rx complete callback*/
+          huart->RxCpltCallback(huart);
+#else
+          /*Call legacy weak Rx complete callback*/
+          HAL_UART_RxCpltCallback(huart);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+        }
+        break;
+      }
+    }
+
+    /* When remaining number of bytes to receive is less than the RX FIFO
+    threshold, next incoming frames are processed as if FIFO mode was
+    disabled (i.e. one interrupt per received frame).
+    */
+    rxdatacount = huart->RxXferCount;
+    if ((rxdatacount != 0U) && (rxdatacount < huart->NbRxDataToProcess))
+    {
+      /* Disable the UART RXFT interrupt*/
+      ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_RXFTIE);
+
+      /* Update the RxISR function pointer */
+      huart->RxISR = UART_RxISR_8BIT;
+
+      /* Enable the UART Data Register Not Empty interrupt */
+      ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_RXNEIE_RXFNEIE);
+    }
+  }
+  else
+  {
+    /* Clear RXNE interrupt flag */
+    __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);
+  }
+}
+
+/**
+  * @brief RX interrupt handler for 9 bits data word length and FIFO mode is enabled.
+  * @note   Function is called under interruption only, once
+  *         interruptions have been enabled by HAL_UART_Receive_IT()
+  * @param huart UART handle.
+  * @retval None
+  */
+static void UART_RxISR_16BIT_FIFOEN(UART_HandleTypeDef *huart)
+{
+  uint16_t *tmp;
+  uint16_t  uhMask = huart->Mask;
+  uint16_t  uhdata;
+  uint16_t  nb_rx_data;
+  uint16_t  rxdatacount;
+  uint32_t  isrflags = READ_REG(huart->Instance->ISR);
+  uint32_t  cr1its   = READ_REG(huart->Instance->CR1);
+  uint32_t  cr3its   = READ_REG(huart->Instance->CR3);
+
+  /* Check that a Rx process is ongoing */
+  if (huart->RxState == HAL_UART_STATE_BUSY_RX)
+  {
+    nb_rx_data = huart->NbRxDataToProcess;
+    while ((nb_rx_data > 0U) && ((isrflags & USART_ISR_RXNE_RXFNE) != 0U))
+    {
+      uhdata = (uint16_t) READ_REG(huart->Instance->RDR);
+      tmp = (uint16_t *) huart->pRxBuffPtr ;
+      *tmp = (uint16_t)(uhdata & uhMask);
+      huart->pRxBuffPtr += 2U;
+      huart->RxXferCount--;
+      isrflags = READ_REG(huart->Instance->ISR);
+
+      /* If some non blocking errors occurred */
+      if ((isrflags & (USART_ISR_PE | USART_ISR_FE | USART_ISR_NE)) != 0U)
+      {
+        /* UART parity error interrupt occurred -------------------------------------*/
+        if (((isrflags & USART_ISR_PE) != 0U) && ((cr1its & USART_CR1_PEIE) != 0U))
+        {
+          __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_PEF);
+
+          huart->ErrorCode |= HAL_UART_ERROR_PE;
+        }
+
+        /* UART frame error interrupt occurred --------------------------------------*/
+        if (((isrflags & USART_ISR_FE) != 0U) && ((cr3its & USART_CR3_EIE) != 0U))
+        {
+          __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_FEF);
+
+          huart->ErrorCode |= HAL_UART_ERROR_FE;
+        }
+
+        /* UART noise error interrupt occurred --------------------------------------*/
+        if (((isrflags & USART_ISR_NE) != 0U) && ((cr3its & USART_CR3_EIE) != 0U))
+        {
+          __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_NEF);
+
+          huart->ErrorCode |= HAL_UART_ERROR_NE;
+        }
+
+        /* Call UART Error Call back function if need be ----------------------------*/
+        if (huart->ErrorCode != HAL_UART_ERROR_NONE)
+        {
+          /* Non Blocking error : transfer could go on.
+          Error is notified to user through user error callback */
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+          /*Call registered error callback*/
+          huart->ErrorCallback(huart);
+#else
+          /*Call legacy weak error callback*/
+          HAL_UART_ErrorCallback(huart);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+          huart->ErrorCode = HAL_UART_ERROR_NONE;
+        }
+      }
+
+      if (huart->RxXferCount == 0U)
+      {
+        /* Disable the UART Parity Error Interrupt and RXFT interrupt*/
+        ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_PEIE);
+
+        /* Disable the UART Error Interrupt: (Frame error, noise error, overrun error)
+           and RX FIFO Threshold interrupt */
+        ATOMIC_CLEAR_BIT(huart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE));
+
+        /* Rx process is completed, restore huart->RxState to Ready */
+        huart->RxState = HAL_UART_STATE_READY;
+
+        /* Clear RxISR function pointer */
+        huart->RxISR = NULL;
+
+        /* Initialize type of RxEvent to Transfer Complete */
+        huart->RxEventType = HAL_UART_RXEVENT_TC;
+
+        if (!(IS_LPUART_INSTANCE(huart->Instance)))
+        {
+          /* Check that USART RTOEN bit is set */
+          if (READ_BIT(huart->Instance->CR2, USART_CR2_RTOEN) != 0U)
+          {
+            /* Enable the UART Receiver Timeout Interrupt */
+            ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_RTOIE);
+          }
+        }
+
+        /* Check current reception Mode :
+           If Reception till IDLE event has been selected : */
+        if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
+        {
+          /* Set reception type to Standard */
+          huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
+
+          /* Disable IDLE interrupt */
+          ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);
+
+          if (__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE) == SET)
+          {
+            /* Clear IDLE Flag */
+            __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_IDLEF);
+          }
+
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+          /*Call registered Rx Event callback*/
+          huart->RxEventCallback(huart, huart->RxXferSize);
+#else
+          /*Call legacy weak Rx Event callback*/
+          HAL_UARTEx_RxEventCallback(huart, huart->RxXferSize);
+#endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
+        }
+        else
+        {
+          /* Standard reception API called */
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+          /*Call registered Rx complete callback*/
+          huart->RxCpltCallback(huart);
+#else
+          /*Call legacy weak Rx complete callback*/
+          HAL_UART_RxCpltCallback(huart);
+#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
+        }
+        break;
+      }
+    }
+
+    /* When remaining number of bytes to receive is less than the RX FIFO
+    threshold, next incoming frames are processed as if FIFO mode was
+    disabled (i.e. one interrupt per received frame).
+    */
+    rxdatacount = huart->RxXferCount;
+    if ((rxdatacount != 0U) && (rxdatacount < huart->NbRxDataToProcess))
+    {
+      /* Disable the UART RXFT interrupt*/
+      ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_RXFTIE);
+
+      /* Update the RxISR function pointer */
+      huart->RxISR = UART_RxISR_16BIT;
+
+      /* Enable the UART Data Register Not Empty interrupt */
+      ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_RXNEIE_RXFNEIE);
+    }
+  }
+  else
+  {
+    /* Clear RXNE interrupt flag */
+    __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);
+  }
+}
+
+/**
+  * @}
+  */
+
+#endif /* HAL_UART_MODULE_ENABLED */
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
diff --git a/starter-projects/servo/p1-pwm/Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_uart_ex.c b/starter-projects/servo/p1-pwm/Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_uart_ex.c
new file mode 100644
index 0000000..407c66b
--- /dev/null
+++ b/starter-projects/servo/p1-pwm/Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_uart_ex.c
@@ -0,0 +1,1042 @@
+/**
+  ******************************************************************************
+  * @file    stm32g4xx_hal_uart_ex.c
+  * @author  MCD Application Team
+  * @brief   Extended UART HAL module driver.
+  *          This file provides firmware functions to manage the following extended
+  *          functionalities of the Universal Asynchronous Receiver Transmitter Peripheral (UART).
+  *           + Initialization and de-initialization functions
+  *           + Peripheral Control functions
+  *
+  *
+  ******************************************************************************
+  * @attention
+  *
+  * Copyright (c) 2019 STMicroelectronics.
+  * All rights reserved.
+  *
+  * This software is licensed under terms that can be found in the LICENSE file
+  * in the root directory of this software component.
+  * If no LICENSE file comes with this software, it is provided AS-IS.
+  *
+  ******************************************************************************
+  @verbatim
+  ==============================================================================
+               ##### UART peripheral extended features  #####
+  ==============================================================================
+
+    (#) Declare a UART_HandleTypeDef handle structure.
+
+    (#) For the UART RS485 Driver Enable mode, initialize the UART registers
+        by calling the HAL_RS485Ex_Init() API.
+
+    (#) FIFO mode enabling/disabling and RX/TX FIFO threshold programming.
+
+        -@- When UART operates in FIFO mode, FIFO mode must be enabled prior
+            starting RX/TX transfers. Also RX/TX FIFO thresholds must be
+            configured prior starting RX/TX transfers.
+
+  @endverbatim
+  ******************************************************************************
+  */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32g4xx_hal.h"
+
+/** @addtogroup STM32G4xx_HAL_Driver
+  * @{
+  */
+
+/** @defgroup UARTEx UARTEx
+  * @brief UART Extended HAL module driver
+  * @{
+  */
+
+#ifdef HAL_UART_MODULE_ENABLED
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/** @defgroup UARTEX_Private_Constants UARTEx Private Constants
+  * @{
+  */
+/* UART RX FIFO depth */
+#define RX_FIFO_DEPTH 8U
+
+/* UART TX FIFO depth */
+#define TX_FIFO_DEPTH 8U
+/**
+  * @}
+  */
+
+/* Private macros ------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/** @defgroup UARTEx_Private_Functions UARTEx Private Functions
+  * @{
+  */
+static void UARTEx_Wakeup_AddressConfig(UART_HandleTypeDef *huart, UART_WakeUpTypeDef WakeUpSelection);
+static void UARTEx_SetNbDataToProcess(UART_HandleTypeDef *huart);
+/**
+  * @}
+  */
+
+/* Exported functions --------------------------------------------------------*/
+
+/** @defgroup UARTEx_Exported_Functions  UARTEx Exported Functions
+  * @{
+  */
+
+/** @defgroup UARTEx_Exported_Functions_Group1 Initialization and de-initialization functions
+  * @brief    Extended Initialization and Configuration Functions
+  *
+@verbatim
+===============================================================================
+            ##### Initialization and Configuration functions #####
+ ===============================================================================
+    [..]
+    This subsection provides a set of functions allowing to initialize the USARTx or the UARTy
+    in asynchronous mode.
+      (+) For the asynchronous mode the parameters below can be configured:
+        (++) Baud Rate
+        (++) Word Length
+        (++) Stop Bit
+        (++) Parity: If the parity is enabled, then the MSB bit of the data written
+             in the data register is transmitted but is changed by the parity bit.
+        (++) Hardware flow control
+        (++) Receiver/transmitter modes
+        (++) Over Sampling Method
+        (++) One-Bit Sampling Method
+      (+) For the asynchronous mode, the following advanced features can be configured as well:
+        (++) TX and/or RX pin level inversion
+        (++) data logical level inversion
+        (++) RX and TX pins swap
+        (++) RX overrun detection disabling
+        (++) DMA disabling on RX error
+        (++) MSB first on communication line
+        (++) auto Baud rate detection
+    [..]
+    The HAL_RS485Ex_Init() API follows the UART RS485 mode configuration
+     procedures (details for the procedures are available in reference manual).
+
+@endverbatim
+
+  Depending on the frame length defined by the M1 and M0 bits (7-bit,
+  8-bit or 9-bit), the possible UART formats are listed in the
+  following table.
+
+    Table 1. UART frame format.
+    +-----------------------------------------------------------------------+
+    |  M1 bit |  M0 bit |  PCE bit  |             UART frame                |
+    |---------|---------|-----------|---------------------------------------|
+    |    0    |    0    |    0      |    | SB |    8 bit data   | STB |     |
+    |---------|---------|-----------|---------------------------------------|
+    |    0    |    0    |    1      |    | SB | 7 bit data | PB | STB |     |
+    |---------|---------|-----------|---------------------------------------|
+    |    0    |    1    |    0      |    | SB |    9 bit data   | STB |     |
+    |---------|---------|-----------|---------------------------------------|
+    |    0    |    1    |    1      |    | SB | 8 bit data | PB | STB |     |
+    |---------|---------|-----------|---------------------------------------|
+    |    1    |    0    |    0      |    | SB |    7 bit data   | STB |     |
+    |---------|---------|-----------|---------------------------------------|
+    |    1    |    0    |    1      |    | SB | 6 bit data | PB | STB |     |
+    +-----------------------------------------------------------------------+
+
+  * @{
+  */
+
+/**
+  * @brief Initialize the RS485 Driver enable feature according to the specified
+  *         parameters in the UART_InitTypeDef and creates the associated handle.
+  * @param huart            UART handle.
+  * @param Polarity         Select the driver enable polarity.
+  *          This parameter can be one of the following values:
+  *          @arg @ref UART_DE_POLARITY_HIGH DE signal is active high
+  *          @arg @ref UART_DE_POLARITY_LOW  DE signal is active low
+  * @param AssertionTime    Driver Enable assertion time:
+  *       5-bit value defining the time between the activation of the DE (Driver Enable)
+  *       signal and the beginning of the start bit. It is expressed in sample time
+  *       units (1/8 or 1/16 bit time, depending on the oversampling rate)
+  * @param DeassertionTime  Driver Enable deassertion time:
+  *       5-bit value defining the time between the end of the last stop bit, in a
+  *       transmitted message, and the de-activation of the DE (Driver Enable) signal.
+  *       It is expressed in sample time units (1/8 or 1/16 bit time, depending on the
+  *       oversampling rate).
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_RS485Ex_Init(UART_HandleTypeDef *huart, uint32_t Polarity, uint32_t AssertionTime,
+                                   uint32_t DeassertionTime)
+{
+  uint32_t temp;
+
+  /* Check the UART handle allocation */
+  if (huart == NULL)
+  {
+    return HAL_ERROR;
+  }
+  /* Check the Driver Enable UART instance */
+  assert_param(IS_UART_DRIVER_ENABLE_INSTANCE(huart->Instance));
+
+  /* Check the Driver Enable polarity */
+  assert_param(IS_UART_DE_POLARITY(Polarity));
+
+  /* Check the Driver Enable assertion time */
+  assert_param(IS_UART_ASSERTIONTIME(AssertionTime));
+
+  /* Check the Driver Enable deassertion time */
+  assert_param(IS_UART_DEASSERTIONTIME(DeassertionTime));
+
+  if (huart->gState == HAL_UART_STATE_RESET)
+  {
+    /* Allocate lock resource and initialize it */
+    huart->Lock = HAL_UNLOCKED;
+
+#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+    UART_InitCallbacksToDefault(huart);
+
+    if (huart->MspInitCallback == NULL)
+    {
+      huart->MspInitCallback = HAL_UART_MspInit;
+    }
+
+    /* Init the low level hardware */
+    huart->MspInitCallback(huart);
+#else
+    /* Init the low level hardware : GPIO, CLOCK, CORTEX */
+    HAL_UART_MspInit(huart);
+#endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
+  }
+
+  huart->gState = HAL_UART_STATE_BUSY;
+
+  /* Disable the Peripheral */
+  __HAL_UART_DISABLE(huart);
+
+  /* Perform advanced settings configuration */
+  /* For some items, configuration requires to be done prior TE and RE bits are set */
+  if (huart->AdvancedInit.AdvFeatureInit != UART_ADVFEATURE_NO_INIT)
+  {
+    UART_AdvFeatureConfig(huart);
+  }
+
+  /* Set the UART Communication parameters */
+  if (UART_SetConfig(huart) == HAL_ERROR)
+  {
+    return HAL_ERROR;
+  }
+
+  /* Enable the Driver Enable mode by setting the DEM bit in the CR3 register */
+  SET_BIT(huart->Instance->CR3, USART_CR3_DEM);
+
+  /* Set the Driver Enable polarity */
+  MODIFY_REG(huart->Instance->CR3, USART_CR3_DEP, Polarity);
+
+  /* Set the Driver Enable assertion and deassertion times */
+  temp = (AssertionTime << UART_CR1_DEAT_ADDRESS_LSB_POS);
+  temp |= (DeassertionTime << UART_CR1_DEDT_ADDRESS_LSB_POS);
+  MODIFY_REG(huart->Instance->CR1, (USART_CR1_DEDT | USART_CR1_DEAT), temp);
+
+  /* Enable the Peripheral */
+  __HAL_UART_ENABLE(huart);
+
+  /* TEACK and/or REACK to check before moving huart->gState and huart->RxState to Ready */
+  return (UART_CheckIdleState(huart));
+}
+
+/**
+  * @}
+  */
+
+/** @defgroup UARTEx_Exported_Functions_Group2 IO operation functions
+  *  @brief Extended functions
+  *
+@verbatim
+ ===============================================================================
+                      ##### IO operation functions #####
+ ===============================================================================
+    This subsection provides a set of Wakeup and FIFO mode related callback functions.
+
+    (#) Wakeup from Stop mode Callback:
+        (+) HAL_UARTEx_WakeupCallback()
+
+    (#) TX/RX Fifos Callbacks:
+        (+) HAL_UARTEx_RxFifoFullCallback()
+        (+) HAL_UARTEx_TxFifoEmptyCallback()
+
+@endverbatim
+  * @{
+  */
+
+/**
+  * @brief UART wakeup from Stop mode callback.
+  * @param huart UART handle.
+  * @retval None
+  */
+__weak void HAL_UARTEx_WakeupCallback(UART_HandleTypeDef *huart)
+{
+  /* Prevent unused argument(s) compilation warning */
+  UNUSED(huart);
+
+  /* NOTE : This function should not be modified, when the callback is needed,
+            the HAL_UARTEx_WakeupCallback can be implemented in the user file.
+   */
+}
+
+/**
+  * @brief  UART RX Fifo full callback.
+  * @param  huart UART handle.
+  * @retval None
+  */
+__weak void HAL_UARTEx_RxFifoFullCallback(UART_HandleTypeDef *huart)
+{
+  /* Prevent unused argument(s) compilation warning */
+  UNUSED(huart);
+
+  /* NOTE : This function should not be modified, when the callback is needed,
+            the HAL_UARTEx_RxFifoFullCallback can be implemented in the user file.
+   */
+}
+
+/**
+  * @brief  UART TX Fifo empty callback.
+  * @param  huart UART handle.
+  * @retval None
+  */
+__weak void HAL_UARTEx_TxFifoEmptyCallback(UART_HandleTypeDef *huart)
+{
+  /* Prevent unused argument(s) compilation warning */
+  UNUSED(huart);
+
+  /* NOTE : This function should not be modified, when the callback is needed,
+            the HAL_UARTEx_TxFifoEmptyCallback can be implemented in the user file.
+   */
+}
+
+/**
+  * @}
+  */
+
+/** @defgroup UARTEx_Exported_Functions_Group3 Peripheral Control functions
+  * @brief    Extended Peripheral Control functions
+  *
+@verbatim
+ ===============================================================================
+                      ##### Peripheral Control functions #####
+ ===============================================================================
+    [..] This section provides the following functions:
+     (+) HAL_MultiProcessorEx_AddressLength_Set() API optionally sets the UART node address
+         detection length to more than 4 bits for multiprocessor address mark wake up.
+     (+) HAL_UARTEx_StopModeWakeUpSourceConfig() API defines the wake-up from stop mode
+         trigger: address match, Start Bit detection or RXNE bit status.
+     (+) HAL_UARTEx_EnableStopMode() API enables the UART to wake up the MCU from stop mode
+     (+) HAL_UARTEx_DisableStopMode() API disables the above functionality
+     (+) HAL_UARTEx_EnableFifoMode() API enables the FIFO mode
+     (+) HAL_UARTEx_DisableFifoMode() API disables the FIFO mode
+     (+) HAL_UARTEx_SetTxFifoThreshold() API sets the TX FIFO threshold
+     (+) HAL_UARTEx_SetRxFifoThreshold() API sets the RX FIFO threshold
+
+    [..] This subsection also provides a set of additional functions providing enhanced reception
+    services to user. (For example, these functions allow application to handle use cases
+    where number of data to be received is unknown).
+
+    (#) Compared to standard reception services which only consider number of received
+        data elements as reception completion criteria, these functions also consider additional events
+        as triggers for updating reception status to caller :
+       (+) Detection of inactivity period (RX line has not been active for a given period).
+          (++) RX inactivity detected by IDLE event, i.e. RX line has been in idle state (normally high state)
+               for 1 frame time, after last received byte.
+          (++) RX inactivity detected by RTO, i.e. line has been in idle state
+               for a programmable time, after last received byte.
+       (+) Detection that a specific character has been received.
+
+    (#) There are two mode of transfer:
+       (+) Blocking mode: The reception is performed in polling mode, until either expected number of data is received,
+           or till IDLE event occurs. Reception is handled only during function execution.
+           When function exits, no data reception could occur. HAL status and number of actually received data elements,
+           are returned by function after finishing transfer.
+       (+) Non-Blocking mode: The reception is performed using Interrupts or DMA.
+           These API's return the HAL status.
+           The end of the data processing will be indicated through the
+           dedicated UART IRQ when using Interrupt mode or the DMA IRQ when using DMA mode.
+           The HAL_UARTEx_RxEventCallback() user callback will be executed during Receive process
+           The HAL_UART_ErrorCallback()user callback will be executed when a reception error is detected.
+
+    (#) Blocking mode API:
+        (+) HAL_UARTEx_ReceiveToIdle()
+
+    (#) Non-Blocking mode API with Interrupt:
+        (+) HAL_UARTEx_ReceiveToIdle_IT()
+
+    (#) Non-Blocking mode API with DMA:
+        (+) HAL_UARTEx_ReceiveToIdle_DMA()
+
+@endverbatim
+  * @{
+  */
+
+/**
+  * @brief By default in multiprocessor mode, when the wake up method is set
+  *        to address mark, the UART handles only 4-bit long addresses detection;
+  *        this API allows to enable longer addresses detection (6-, 7- or 8-bit
+  *        long).
+  * @note  Addresses detection lengths are: 6-bit address detection in 7-bit data mode,
+  *        7-bit address detection in 8-bit data mode, 8-bit address detection in 9-bit data mode.
+  * @param huart         UART handle.
+  * @param AddressLength This parameter can be one of the following values:
+  *          @arg @ref UART_ADDRESS_DETECT_4B 4-bit long address
+  *          @arg @ref UART_ADDRESS_DETECT_7B 6-, 7- or 8-bit long address
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_MultiProcessorEx_AddressLength_Set(UART_HandleTypeDef *huart, uint32_t AddressLength)
+{
+  /* Check the UART handle allocation */
+  if (huart == NULL)
+  {
+    return HAL_ERROR;
+  }
+
+  /* Check the address length parameter */
+  assert_param(IS_UART_ADDRESSLENGTH_DETECT(AddressLength));
+
+  huart->gState = HAL_UART_STATE_BUSY;
+
+  /* Disable the Peripheral */
+  __HAL_UART_DISABLE(huart);
+
+  /* Set the address length */
+  MODIFY_REG(huart->Instance->CR2, USART_CR2_ADDM7, AddressLength);
+
+  /* Enable the Peripheral */
+  __HAL_UART_ENABLE(huart);
+
+  /* TEACK and/or REACK to check before moving huart->gState to Ready */
+  return (UART_CheckIdleState(huart));
+}
+
+/**
+  * @brief Set Wakeup from Stop mode interrupt flag selection.
+  * @note It is the application responsibility to enable the interrupt used as
+  *       usart_wkup interrupt source before entering low-power mode.
+  * @param huart           UART handle.
+  * @param WakeUpSelection Address match, Start Bit detection or RXNE/RXFNE bit status.
+  *          This parameter can be one of the following values:
+  *          @arg @ref UART_WAKEUP_ON_ADDRESS
+  *          @arg @ref UART_WAKEUP_ON_STARTBIT
+  *          @arg @ref UART_WAKEUP_ON_READDATA_NONEMPTY
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_UARTEx_StopModeWakeUpSourceConfig(UART_HandleTypeDef *huart, UART_WakeUpTypeDef WakeUpSelection)
+{
+  HAL_StatusTypeDef status = HAL_OK;
+  uint32_t tickstart;
+
+  /* check the wake-up from stop mode UART instance */
+  assert_param(IS_UART_WAKEUP_FROMSTOP_INSTANCE(huart->Instance));
+  /* check the wake-up selection parameter */
+  assert_param(IS_UART_WAKEUP_SELECTION(WakeUpSelection.WakeUpEvent));
+
+  /* Process Locked */
+  __HAL_LOCK(huart);
+
+  huart->gState = HAL_UART_STATE_BUSY;
+
+  /* Disable the Peripheral */
+  __HAL_UART_DISABLE(huart);
+
+  /* Set the wake-up selection scheme */
+  MODIFY_REG(huart->Instance->CR3, USART_CR3_WUS, WakeUpSelection.WakeUpEvent);
+
+  if (WakeUpSelection.WakeUpEvent == UART_WAKEUP_ON_ADDRESS)
+  {
+    UARTEx_Wakeup_AddressConfig(huart, WakeUpSelection);
+  }
+
+  /* Enable the Peripheral */
+  __HAL_UART_ENABLE(huart);
+
+  /* Init tickstart for timeout management */
+  tickstart = HAL_GetTick();
+
+  /* Wait until REACK flag is set */
+  if (UART_WaitOnFlagUntilTimeout(huart, USART_ISR_REACK, RESET, tickstart, HAL_UART_TIMEOUT_VALUE) != HAL_OK)
+  {
+    status = HAL_TIMEOUT;
+  }
+  else
+  {
+    /* Initialize the UART State */
+    huart->gState = HAL_UART_STATE_READY;
+  }
+
+  /* Process Unlocked */
+  __HAL_UNLOCK(huart);
+
+  return status;
+}
+
+/**
+  * @brief Enable UART Stop Mode.
+  * @note The UART is able to wake up the MCU from Stop 1 mode as long as UART clock is HSI or LSE.
+  * @param huart UART handle.
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_UARTEx_EnableStopMode(UART_HandleTypeDef *huart)
+{
+  /* Process Locked */
+  __HAL_LOCK(huart);
+
+  /* Set UESM bit */
+  ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_UESM);
+
+  /* Process Unlocked */
+  __HAL_UNLOCK(huart);
+
+  return HAL_OK;
+}
+
+/**
+  * @brief Disable UART Stop Mode.
+  * @param huart UART handle.
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_UARTEx_DisableStopMode(UART_HandleTypeDef *huart)
+{
+  /* Process Locked */
+  __HAL_LOCK(huart);
+
+  /* Clear UESM bit */
+  ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_UESM);
+
+  /* Process Unlocked */
+  __HAL_UNLOCK(huart);
+
+  return HAL_OK;
+}
+
+/**
+  * @brief  Enable the FIFO mode.
+  * @param huart      UART handle.
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_UARTEx_EnableFifoMode(UART_HandleTypeDef *huart)
+{
+  uint32_t tmpcr1;
+
+  /* Check parameters */
+  assert_param(IS_UART_FIFO_INSTANCE(huart->Instance));
+
+  /* Process Locked */
+  __HAL_LOCK(huart);
+
+  huart->gState = HAL_UART_STATE_BUSY;
+
+  /* Save actual UART configuration */
+  tmpcr1 = READ_REG(huart->Instance->CR1);
+
+  /* Disable UART */
+  __HAL_UART_DISABLE(huart);
+
+  /* Enable FIFO mode */
+  SET_BIT(tmpcr1, USART_CR1_FIFOEN);
+  huart->FifoMode = UART_FIFOMODE_ENABLE;
+
+  /* Restore UART configuration */
+  WRITE_REG(huart->Instance->CR1, tmpcr1);
+
+  /* Determine the number of data to process during RX/TX ISR execution */
+  UARTEx_SetNbDataToProcess(huart);
+
+  huart->gState = HAL_UART_STATE_READY;
+
+  /* Process Unlocked */
+  __HAL_UNLOCK(huart);
+
+  return HAL_OK;
+}
+
+/**
+  * @brief  Disable the FIFO mode.
+  * @param huart      UART handle.
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_UARTEx_DisableFifoMode(UART_HandleTypeDef *huart)
+{
+  uint32_t tmpcr1;
+
+  /* Check parameters */
+  assert_param(IS_UART_FIFO_INSTANCE(huart->Instance));
+
+  /* Process Locked */
+  __HAL_LOCK(huart);
+
+  huart->gState = HAL_UART_STATE_BUSY;
+
+  /* Save actual UART configuration */
+  tmpcr1 = READ_REG(huart->Instance->CR1);
+
+  /* Disable UART */
+  __HAL_UART_DISABLE(huart);
+
+  /* Disable FIFO mode */
+  CLEAR_BIT(tmpcr1, USART_CR1_FIFOEN);
+  huart->FifoMode = UART_FIFOMODE_DISABLE;
+
+  /* Restore UART configuration */
+  WRITE_REG(huart->Instance->CR1, tmpcr1);
+
+  huart->gState = HAL_UART_STATE_READY;
+
+  /* Process Unlocked */
+  __HAL_UNLOCK(huart);
+
+  return HAL_OK;
+}
+
+/**
+  * @brief  Set the TXFIFO threshold.
+  * @param huart      UART handle.
+  * @param Threshold  TX FIFO threshold value
+  *          This parameter can be one of the following values:
+  *            @arg @ref UART_TXFIFO_THRESHOLD_1_8
+  *            @arg @ref UART_TXFIFO_THRESHOLD_1_4
+  *            @arg @ref UART_TXFIFO_THRESHOLD_1_2
+  *            @arg @ref UART_TXFIFO_THRESHOLD_3_4
+  *            @arg @ref UART_TXFIFO_THRESHOLD_7_8
+  *            @arg @ref UART_TXFIFO_THRESHOLD_8_8
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_UARTEx_SetTxFifoThreshold(UART_HandleTypeDef *huart, uint32_t Threshold)
+{
+  uint32_t tmpcr1;
+
+  /* Check parameters */
+  assert_param(IS_UART_FIFO_INSTANCE(huart->Instance));
+  assert_param(IS_UART_TXFIFO_THRESHOLD(Threshold));
+
+  /* Process Locked */
+  __HAL_LOCK(huart);
+
+  huart->gState = HAL_UART_STATE_BUSY;
+
+  /* Save actual UART configuration */
+  tmpcr1 = READ_REG(huart->Instance->CR1);
+
+  /* Disable UART */
+  __HAL_UART_DISABLE(huart);
+
+  /* Update TX threshold configuration */
+  MODIFY_REG(huart->Instance->CR3, USART_CR3_TXFTCFG, Threshold);
+
+  /* Determine the number of data to process during RX/TX ISR execution */
+  UARTEx_SetNbDataToProcess(huart);
+
+  /* Restore UART configuration */
+  WRITE_REG(huart->Instance->CR1, tmpcr1);
+
+  huart->gState = HAL_UART_STATE_READY;
+
+  /* Process Unlocked */
+  __HAL_UNLOCK(huart);
+
+  return HAL_OK;
+}
+
+/**
+  * @brief  Set the RXFIFO threshold.
+  * @param huart      UART handle.
+  * @param Threshold  RX FIFO threshold value
+  *          This parameter can be one of the following values:
+  *            @arg @ref UART_RXFIFO_THRESHOLD_1_8
+  *            @arg @ref UART_RXFIFO_THRESHOLD_1_4
+  *            @arg @ref UART_RXFIFO_THRESHOLD_1_2
+  *            @arg @ref UART_RXFIFO_THRESHOLD_3_4
+  *            @arg @ref UART_RXFIFO_THRESHOLD_7_8
+  *            @arg @ref UART_RXFIFO_THRESHOLD_8_8
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_UARTEx_SetRxFifoThreshold(UART_HandleTypeDef *huart, uint32_t Threshold)
+{
+  uint32_t tmpcr1;
+
+  /* Check the parameters */
+  assert_param(IS_UART_FIFO_INSTANCE(huart->Instance));
+  assert_param(IS_UART_RXFIFO_THRESHOLD(Threshold));
+
+  /* Process Locked */
+  __HAL_LOCK(huart);
+
+  huart->gState = HAL_UART_STATE_BUSY;
+
+  /* Save actual UART configuration */
+  tmpcr1 = READ_REG(huart->Instance->CR1);
+
+  /* Disable UART */
+  __HAL_UART_DISABLE(huart);
+
+  /* Update RX threshold configuration */
+  MODIFY_REG(huart->Instance->CR3, USART_CR3_RXFTCFG, Threshold);
+
+  /* Determine the number of data to process during RX/TX ISR execution */
+  UARTEx_SetNbDataToProcess(huart);
+
+  /* Restore UART configuration */
+  WRITE_REG(huart->Instance->CR1, tmpcr1);
+
+  huart->gState = HAL_UART_STATE_READY;
+
+  /* Process Unlocked */
+  __HAL_UNLOCK(huart);
+
+  return HAL_OK;
+}
+
+/**
+  * @brief Receive an amount of data in blocking mode till either the expected number of data
+  *        is received or an IDLE event occurs.
+  * @note  HAL_OK is returned if reception is completed (expected number of data has been received)
+  *        or if reception is stopped after IDLE event (less than the expected number of data has been received)
+  *        In this case, RxLen output parameter indicates number of data available in reception buffer.
+  * @note  When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
+  *        the received data is handled as a set of uint16_t. In this case, Size must indicate the number
+  *        of uint16_t available through pData.
+  * @note When FIFO mode is enabled, the RXFNE flag is set as long as the RXFIFO
+  *       is not empty. Read operations from the RDR register are performed when
+  *       RXFNE flag is set. From hardware perspective, RXFNE flag and
+  *       RXNE are mapped on the same bit-field.
+  * @param huart   UART handle.
+  * @param pData   Pointer to data buffer (uint8_t or uint16_t data elements).
+  * @param Size    Amount of data elements (uint8_t or uint16_t) to be received.
+  * @param RxLen   Number of data elements finally received
+  *                (could be lower than Size, in case reception ends on IDLE event)
+  * @param Timeout Timeout duration expressed in ms (covers the whole reception sequence).
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint16_t *RxLen,
+                                           uint32_t Timeout)
+{
+  uint8_t  *pdata8bits;
+  uint16_t *pdata16bits;
+  uint16_t uhMask;
+  uint32_t tickstart;
+
+  /* Check that a Rx process is not already ongoing */
+  if (huart->RxState == HAL_UART_STATE_READY)
+  {
+    if ((pData == NULL) || (Size == 0U))
+    {
+      return  HAL_ERROR;
+    }
+
+    huart->ErrorCode = HAL_UART_ERROR_NONE;
+    huart->RxState = HAL_UART_STATE_BUSY_RX;
+    huart->ReceptionType = HAL_UART_RECEPTION_TOIDLE;
+    huart->RxEventType = HAL_UART_RXEVENT_TC;
+
+    /* Init tickstart for timeout management */
+    tickstart = HAL_GetTick();
+
+    huart->RxXferSize  = Size;
+    huart->RxXferCount = Size;
+
+    /* Computation of UART mask to apply to RDR register */
+    UART_MASK_COMPUTATION(huart);
+    uhMask = huart->Mask;
+
+    /* In case of 9bits/No Parity transfer, pRxData needs to be handled as a uint16_t pointer */
+    if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
+    {
+      pdata8bits  = NULL;
+      pdata16bits = (uint16_t *) pData;
+    }
+    else
+    {
+      pdata8bits  = pData;
+      pdata16bits = NULL;
+    }
+
+    /* Initialize output number of received elements */
+    *RxLen = 0U;
+
+    /* as long as data have to be received */
+    while (huart->RxXferCount > 0U)
+    {
+      /* Check if IDLE flag is set */
+      if (__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE))
+      {
+        /* Clear IDLE flag in ISR */
+        __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_IDLEF);
+
+        /* If Set, but no data ever received, clear flag without exiting loop */
+        /* If Set, and data has already been received, this means Idle Event is valid : End reception */
+        if (*RxLen > 0U)
+        {
+          huart->RxEventType = HAL_UART_RXEVENT_IDLE;
+          huart->RxState = HAL_UART_STATE_READY;
+
+          return HAL_OK;
+        }
+      }
+
+      /* Check if RXNE flag is set */
+      if (__HAL_UART_GET_FLAG(huart, UART_FLAG_RXNE))
+      {
+        if (pdata8bits == NULL)
+        {
+          *pdata16bits = (uint16_t)(huart->Instance->RDR & uhMask);
+          pdata16bits++;
+        }
+        else
+        {
+          *pdata8bits = (uint8_t)(huart->Instance->RDR & (uint8_t)uhMask);
+          pdata8bits++;
+        }
+        /* Increment number of received elements */
+        *RxLen += 1U;
+        huart->RxXferCount--;
+      }
+
+      /* Check for the Timeout */
+      if (Timeout != HAL_MAX_DELAY)
+      {
+        if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
+        {
+          huart->RxState = HAL_UART_STATE_READY;
+
+          return HAL_TIMEOUT;
+        }
+      }
+    }
+
+    /* Set number of received elements in output parameter : RxLen */
+    *RxLen = huart->RxXferSize - huart->RxXferCount;
+    /* At end of Rx process, restore huart->RxState to Ready */
+    huart->RxState = HAL_UART_STATE_READY;
+
+    return HAL_OK;
+  }
+  else
+  {
+    return HAL_BUSY;
+  }
+}
+
+/**
+  * @brief Receive an amount of data in interrupt mode till either the expected number of data
+  *        is received or an IDLE event occurs.
+  * @note  Reception is initiated by this function call. Further progress of reception is achieved thanks
+  *        to UART interrupts raised by RXNE and IDLE events. Callback is called at end of reception indicating
+  *        number of received data elements.
+  * @note  When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
+  *        the received data is handled as a set of uint16_t. In this case, Size must indicate the number
+  *        of uint16_t available through pData.
+  * @param huart UART handle.
+  * @param pData Pointer to data buffer (uint8_t or uint16_t data elements).
+  * @param Size  Amount of data elements (uint8_t or uint16_t) to be received.
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
+{
+  HAL_StatusTypeDef status = HAL_OK;
+
+  /* Check that a Rx process is not already ongoing */
+  if (huart->RxState == HAL_UART_STATE_READY)
+  {
+    if ((pData == NULL) || (Size == 0U))
+    {
+      return HAL_ERROR;
+    }
+
+    /* Set Reception type to reception till IDLE Event*/
+    huart->ReceptionType = HAL_UART_RECEPTION_TOIDLE;
+    huart->RxEventType = HAL_UART_RXEVENT_TC;
+
+    (void)UART_Start_Receive_IT(huart, pData, Size);
+
+    if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
+    {
+      __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_IDLEF);
+      ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);
+    }
+    else
+    {
+      /* In case of errors already pending when reception is started,
+         Interrupts may have already been raised and lead to reception abortion.
+         (Overrun error for instance).
+         In such case Reception Type has been reset to HAL_UART_RECEPTION_STANDARD. */
+      status = HAL_ERROR;
+    }
+
+    return status;
+  }
+  else
+  {
+    return HAL_BUSY;
+  }
+}
+
+/**
+  * @brief Receive an amount of data in DMA mode till either the expected number
+  *        of data is received or an IDLE event occurs.
+  * @note  Reception is initiated by this function call. Further progress of reception is achieved thanks
+  *        to DMA services, transferring automatically received data elements in user reception buffer and
+  *        calling registered callbacks at half/end of reception. UART IDLE events are also used to consider
+  *        reception phase as ended. In all cases, callback execution will indicate number of received data elements.
+  * @note  When the UART parity is enabled (PCE = 1), the received data contain
+  *        the parity bit (MSB position).
+  * @note  When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
+  *        the received data is handled as a set of uint16_t. In this case, Size must indicate the number
+  *        of uint16_t available through pData.
+  * @param huart UART handle.
+  * @param pData Pointer to data buffer (uint8_t or uint16_t data elements).
+  * @param Size  Amount of data elements (uint8_t or uint16_t) to be received.
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
+{
+  HAL_StatusTypeDef status;
+
+  /* Check that a Rx process is not already ongoing */
+  if (huart->RxState == HAL_UART_STATE_READY)
+  {
+    if ((pData == NULL) || (Size == 0U))
+    {
+      return HAL_ERROR;
+    }
+
+    /* Set Reception type to reception till IDLE Event*/
+    huart->ReceptionType = HAL_UART_RECEPTION_TOIDLE;
+    huart->RxEventType = HAL_UART_RXEVENT_TC;
+
+    status =  UART_Start_Receive_DMA(huart, pData, Size);
+
+    /* Check Rx process has been successfully started */
+    if (status == HAL_OK)
+    {
+      if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)
+      {
+        __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_IDLEF);
+        ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);
+      }
+      else
+      {
+        /* In case of errors already pending when reception is started,
+           Interrupts may have already been raised and lead to reception abortion.
+           (Overrun error for instance).
+           In such case Reception Type has been reset to HAL_UART_RECEPTION_STANDARD. */
+        status = HAL_ERROR;
+      }
+    }
+
+    return status;
+  }
+  else
+  {
+    return HAL_BUSY;
+  }
+}
+
+/**
+  * @brief Provide Rx Event type that has lead to RxEvent callback execution.
+  * @note  When HAL_UARTEx_ReceiveToIdle_IT() or HAL_UARTEx_ReceiveToIdle_DMA() API are called, progress
+  *        of reception process is provided to application through calls of Rx Event callback (either default one
+  *        HAL_UARTEx_RxEventCallback() or user registered one). As several types of events could occur (IDLE event,
+  *        Half Transfer, or Transfer Complete), this function allows to retrieve the Rx Event type that has lead
+  *        to Rx Event callback execution.
+  * @note  This function is expected to be called within the user implementation of Rx Event Callback,
+  *        in order to provide the accurate value :
+  *        In Interrupt Mode :
+  *           - HAL_UART_RXEVENT_TC : when Reception has been completed (expected nb of data has been received)
+  *           - HAL_UART_RXEVENT_IDLE : when Idle event occurred prior reception has been completed (nb of
+  *             received data is lower than expected one)
+  *        In DMA Mode :
+  *           - HAL_UART_RXEVENT_TC : when Reception has been completed (expected nb of data has been received)
+  *           - HAL_UART_RXEVENT_HT : when half of expected nb of data has been received
+  *           - HAL_UART_RXEVENT_IDLE : when Idle event occurred prior reception has been completed (nb of
+  *             received data is lower than expected one).
+  *        In DMA mode, RxEvent callback could be called several times;
+  *        When DMA is configured in Normal Mode, HT event does not stop Reception process;
+  *        When DMA is configured in Circular Mode, HT, TC or IDLE events don't stop Reception process;
+  * @param  huart UART handle.
+  * @retval Rx Event Type (return vale will be a value of @ref UART_RxEvent_Type_Values)
+  */
+HAL_UART_RxEventTypeTypeDef HAL_UARTEx_GetRxEventType(const UART_HandleTypeDef *huart)
+{
+  /* Return Rx Event type value, as stored in UART handle */
+  return (huart->RxEventType);
+}
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/** @addtogroup UARTEx_Private_Functions
+  * @{
+  */
+
+/**
+  * @brief Initialize the UART wake-up from stop mode parameters when triggered by address detection.
+  * @param huart           UART handle.
+  * @param WakeUpSelection UART wake up from stop mode parameters.
+  * @retval None
+  */
+static void UARTEx_Wakeup_AddressConfig(UART_HandleTypeDef *huart, UART_WakeUpTypeDef WakeUpSelection)
+{
+  assert_param(IS_UART_ADDRESSLENGTH_DETECT(WakeUpSelection.AddressLength));
+
+  /* Set the USART address length */
+  MODIFY_REG(huart->Instance->CR2, USART_CR2_ADDM7, WakeUpSelection.AddressLength);
+
+  /* Set the USART address node */
+  MODIFY_REG(huart->Instance->CR2, USART_CR2_ADD, ((uint32_t)WakeUpSelection.Address << UART_CR2_ADDRESS_LSB_POS));
+}
+
+/**
+  * @brief Calculate the number of data to process in RX/TX ISR.
+  * @note The RX FIFO depth and the TX FIFO depth is extracted from
+  *       the UART configuration registers.
+  * @param huart UART handle.
+  * @retval None
+  */
+static void UARTEx_SetNbDataToProcess(UART_HandleTypeDef *huart)
+{
+  uint8_t rx_fifo_depth;
+  uint8_t tx_fifo_depth;
+  uint8_t rx_fifo_threshold;
+  uint8_t tx_fifo_threshold;
+  static const uint8_t numerator[] = {1U, 1U, 1U, 3U, 7U, 1U, 0U, 0U};
+  static const uint8_t denominator[] = {8U, 4U, 2U, 4U, 8U, 1U, 1U, 1U};
+
+  if (huart->FifoMode == UART_FIFOMODE_DISABLE)
+  {
+    huart->NbTxDataToProcess = 1U;
+    huart->NbRxDataToProcess = 1U;
+  }
+  else
+  {
+    rx_fifo_depth = RX_FIFO_DEPTH;
+    tx_fifo_depth = TX_FIFO_DEPTH;
+    rx_fifo_threshold = (uint8_t)(READ_BIT(huart->Instance->CR3, USART_CR3_RXFTCFG) >> USART_CR3_RXFTCFG_Pos);
+    tx_fifo_threshold = (uint8_t)(READ_BIT(huart->Instance->CR3, USART_CR3_TXFTCFG) >> USART_CR3_TXFTCFG_Pos);
+    huart->NbTxDataToProcess = ((uint16_t)tx_fifo_depth * numerator[tx_fifo_threshold]) /
+                               (uint16_t)denominator[tx_fifo_threshold];
+    huart->NbRxDataToProcess = ((uint16_t)rx_fifo_depth * numerator[rx_fifo_threshold]) /
+                               (uint16_t)denominator[rx_fifo_threshold];
+  }
+}
+/**
+  * @}
+  */
+
+#endif /* HAL_UART_MODULE_ENABLED */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
diff --git a/starter-projects/servo/p1-pwm/Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_usart.c b/starter-projects/servo/p1-pwm/Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_usart.c
new file mode 100644
index 0000000..cc9cc83
--- /dev/null
+++ b/starter-projects/servo/p1-pwm/Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_usart.c
@@ -0,0 +1,3701 @@
+/**
+  ******************************************************************************
+  * @file    stm32g4xx_hal_usart.c
+  * @author  MCD Application Team
+  * @brief   USART HAL module driver.
+  *          This file provides firmware functions to manage the following
+  *          functionalities of the Universal Synchronous/Asynchronous Receiver Transmitter
+  *          Peripheral (USART).
+  *           + Initialization and de-initialization functions
+  *           + IO operation functions
+  *           + Peripheral Control functions
+  *           + Peripheral State and Error functions
+  *
+  ******************************************************************************
+  * @attention
+  *
+  * Copyright (c) 2019 STMicroelectronics.
+  * All rights reserved.
+  *
+  * This software is licensed under terms that can be found in the LICENSE file
+  * in the root directory of this software component.
+  * If no LICENSE file comes with this software, it is provided AS-IS.
+  *
+  ******************************************************************************
+  @verbatim
+ ===============================================================================
+                        ##### How to use this driver #####
+ ===============================================================================
+    [..]
+      The USART HAL driver can be used as follows:
+
+      (#) Declare a USART_HandleTypeDef handle structure (eg. USART_HandleTypeDef husart).
+      (#) Initialize the USART low level resources by implementing the HAL_USART_MspInit() API:
+          (++) Enable the USARTx interface clock.
+          (++) USART pins configuration:
+            (+++) Enable the clock for the USART GPIOs.
+            (+++) Configure these USART pins as alternate function pull-up.
+          (++) NVIC configuration if you need to use interrupt process (HAL_USART_Transmit_IT(),
+                HAL_USART_Receive_IT() and HAL_USART_TransmitReceive_IT() APIs):
+            (+++) Configure the USARTx interrupt priority.
+            (+++) Enable the NVIC USART IRQ handle.
+            (++) USART interrupts handling:
+              -@@-   The specific USART interrupts (Transmission complete interrupt,
+                  RXNE interrupt and Error Interrupts) will be managed using the macros
+                  __HAL_USART_ENABLE_IT() and __HAL_USART_DISABLE_IT() inside the transmit and receive process.
+          (++) DMA Configuration if you need to use DMA process (HAL_USART_Transmit_DMA()
+               HAL_USART_Receive_DMA() and HAL_USART_TransmitReceive_DMA() APIs):
+            (+++) Declare a DMA handle structure for the Tx/Rx channel.
+            (+++) Enable the DMAx interface clock.
+            (+++) Configure the declared DMA handle structure with the required Tx/Rx parameters.
+            (+++) Configure the DMA Tx/Rx channel.
+            (+++) Associate the initialized DMA handle to the USART DMA Tx/Rx handle.
+            (+++) Configure the priority and enable the NVIC for the transfer
+                  complete interrupt on the DMA Tx/Rx channel.
+
+      (#) Program the Baud Rate, Word Length, Stop Bit, Parity, and Mode
+          (Receiver/Transmitter) in the husart handle Init structure.
+
+      (#) Initialize the USART registers by calling the HAL_USART_Init() API:
+          (++) This API configures also the low level Hardware GPIO, CLOCK, CORTEX...etc)
+               by calling the customized HAL_USART_MspInit(&husart) API.
+
+    [..]
+     (@) To configure and enable/disable the USART to wake up the MCU from stop mode, resort to UART API's
+        HAL_UARTEx_StopModeWakeUpSourceConfig(), HAL_UARTEx_EnableStopMode() and
+        HAL_UARTEx_DisableStopMode() in casting the USART handle to UART type UART_HandleTypeDef.
+
+    ##### Callback registration #####
+    ==================================
+
+    [..]
+    The compilation define USE_HAL_USART_REGISTER_CALLBACKS when set to 1
+    allows the user to configure dynamically the driver callbacks.
+
+    [..]
+    Use Function HAL_USART_RegisterCallback() to register a user callback.
+    Function HAL_USART_RegisterCallback() allows to register following callbacks:
+    (+) TxHalfCpltCallback        : Tx Half Complete Callback.
+    (+) TxCpltCallback            : Tx Complete Callback.
+    (+) RxHalfCpltCallback        : Rx Half Complete Callback.
+    (+) RxCpltCallback            : Rx Complete Callback.
+    (+) TxRxCpltCallback          : Tx Rx Complete Callback.
+    (+) ErrorCallback             : Error Callback.
+    (+) AbortCpltCallback         : Abort Complete Callback.
+    (+) RxFifoFullCallback        : Rx Fifo Full Callback.
+    (+) TxFifoEmptyCallback       : Tx Fifo Empty Callback.
+    (+) MspInitCallback           : USART MspInit.
+    (+) MspDeInitCallback         : USART MspDeInit.
+    This function takes as parameters the HAL peripheral handle, the Callback ID
+    and a pointer to the user callback function.
+
+    [..]
+    Use function HAL_USART_UnRegisterCallback() to reset a callback to the default
+    weak function.
+    HAL_USART_UnRegisterCallback() takes as parameters the HAL peripheral handle,
+    and the Callback ID.
+    This function allows to reset following callbacks:
+    (+) TxHalfCpltCallback        : Tx Half Complete Callback.
+    (+) TxCpltCallback            : Tx Complete Callback.
+    (+) RxHalfCpltCallback        : Rx Half Complete Callback.
+    (+) RxCpltCallback            : Rx Complete Callback.
+    (+) TxRxCpltCallback          : Tx Rx Complete Callback.
+    (+) ErrorCallback             : Error Callback.
+    (+) AbortCpltCallback         : Abort Complete Callback.
+    (+) RxFifoFullCallback        : Rx Fifo Full Callback.
+    (+) TxFifoEmptyCallback       : Tx Fifo Empty Callback.
+    (+) MspInitCallback           : USART MspInit.
+    (+) MspDeInitCallback         : USART MspDeInit.
+
+    [..]
+    By default, after the HAL_USART_Init() and when the state is HAL_USART_STATE_RESET
+    all callbacks are set to the corresponding weak functions:
+    examples HAL_USART_TxCpltCallback(), HAL_USART_RxHalfCpltCallback().
+    Exception done for MspInit and MspDeInit functions that are respectively
+    reset to the legacy weak functions in the HAL_USART_Init()
+    and HAL_USART_DeInit() only when these callbacks are null (not registered beforehand).
+    If not, MspInit or MspDeInit are not null, the HAL_USART_Init() and HAL_USART_DeInit()
+    keep and use the user MspInit/MspDeInit callbacks (registered beforehand).
+
+    [..]
+    Callbacks can be registered/unregistered in HAL_USART_STATE_READY state only.
+    Exception done MspInit/MspDeInit that can be registered/unregistered
+    in HAL_USART_STATE_READY or HAL_USART_STATE_RESET state, thus registered (user)
+    MspInit/DeInit callbacks can be used during the Init/DeInit.
+    In that case first register the MspInit/MspDeInit user callbacks
+    using HAL_USART_RegisterCallback() before calling HAL_USART_DeInit()
+    or HAL_USART_Init() function.
+
+    [..]
+    When The compilation define USE_HAL_USART_REGISTER_CALLBACKS is set to 0 or
+    not defined, the callback registration feature is not available
+    and weak callbacks are used.
+
+
+  @endverbatim
+  ******************************************************************************
+  */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32g4xx_hal.h"
+
+/** @addtogroup STM32G4xx_HAL_Driver
+  * @{
+  */
+
+/** @defgroup USART USART
+  * @brief HAL USART Synchronous SPI module driver
+  * @{
+  */
+
+#ifdef HAL_USART_MODULE_ENABLED
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/** @defgroup USART_Private_Constants USART Private Constants
+  * @{
+  */
+#define USART_DUMMY_DATA          ((uint16_t) 0xFFFF)           /*!< USART transmitted dummy data                     */
+#define USART_TEACK_REACK_TIMEOUT             1000U             /*!< USART TX or RX enable acknowledge time-out value */
+#define USART_CR1_FIELDS          ((uint32_t)(USART_CR1_M |  USART_CR1_PCE | USART_CR1_PS    | \
+                                              USART_CR1_TE | USART_CR1_RE  | USART_CR1_OVER8 | \
+                                              USART_CR1_FIFOEN ))                                  /*!< USART CR1 fields of parameters set by USART_SetConfig API */
+
+#define USART_CR2_FIELDS          ((uint32_t)(USART_CR2_CPHA | USART_CR2_CPOL | USART_CR2_CLKEN | \
+                                              USART_CR2_LBCL | USART_CR2_STOP | USART_CR2_SLVEN | \
+                                              USART_CR2_DIS_NSS))                                  /*!< USART CR2 fields of parameters set by USART_SetConfig API */
+
+#define USART_CR3_FIELDS          ((uint32_t)(USART_CR3_TXFTCFG | USART_CR3_RXFTCFG ))             /*!< USART or USART CR3 fields of parameters set by USART_SetConfig API */
+
+#define USART_BRR_MIN    0x10U        /* USART BRR minimum authorized value */
+#define USART_BRR_MAX    0xFFFFU      /* USART BRR maximum authorized value */
+/**
+  * @}
+  */
+
+/* Private macros ------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/** @addtogroup USART_Private_Functions
+  * @{
+  */
+#if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
+void USART_InitCallbacksToDefault(USART_HandleTypeDef *husart);
+#endif /* USE_HAL_USART_REGISTER_CALLBACKS */
+static void USART_EndTransfer(USART_HandleTypeDef *husart);
+static void USART_DMATransmitCplt(DMA_HandleTypeDef *hdma);
+static void USART_DMAReceiveCplt(DMA_HandleTypeDef *hdma);
+static void USART_DMATxHalfCplt(DMA_HandleTypeDef *hdma);
+static void USART_DMARxHalfCplt(DMA_HandleTypeDef *hdma);
+static void USART_DMAError(DMA_HandleTypeDef *hdma);
+static void USART_DMAAbortOnError(DMA_HandleTypeDef *hdma);
+static void USART_DMATxAbortCallback(DMA_HandleTypeDef *hdma);
+static void USART_DMARxAbortCallback(DMA_HandleTypeDef *hdma);
+static HAL_StatusTypeDef USART_WaitOnFlagUntilTimeout(USART_HandleTypeDef *husart, uint32_t Flag, FlagStatus Status,
+                                                      uint32_t Tickstart, uint32_t Timeout);
+static HAL_StatusTypeDef USART_SetConfig(USART_HandleTypeDef *husart);
+static HAL_StatusTypeDef USART_CheckIdleState(USART_HandleTypeDef *husart);
+static void USART_TxISR_8BIT(USART_HandleTypeDef *husart);
+static void USART_TxISR_16BIT(USART_HandleTypeDef *husart);
+static void USART_TxISR_8BIT_FIFOEN(USART_HandleTypeDef *husart);
+static void USART_TxISR_16BIT_FIFOEN(USART_HandleTypeDef *husart);
+static void USART_EndTransmit_IT(USART_HandleTypeDef *husart);
+static void USART_RxISR_8BIT(USART_HandleTypeDef *husart);
+static void USART_RxISR_16BIT(USART_HandleTypeDef *husart);
+static void USART_RxISR_8BIT_FIFOEN(USART_HandleTypeDef *husart);
+static void USART_RxISR_16BIT_FIFOEN(USART_HandleTypeDef *husart);
+
+
+/**
+  * @}
+  */
+
+/* Exported functions --------------------------------------------------------*/
+
+/** @defgroup USART_Exported_Functions USART Exported Functions
+  * @{
+  */
+
+/** @defgroup USART_Exported_Functions_Group1 Initialization and de-initialization functions
+  * @brief    Initialization and Configuration functions
+  *
+@verbatim
+ ===============================================================================
+            ##### Initialization and Configuration functions #####
+ ===============================================================================
+    [..]
+    This subsection provides a set of functions allowing to initialize the USART
+    in synchronous SPI master/slave mode.
+      (+) For the synchronous SPI mode only these parameters can be configured:
+        (++) Baud Rate
+        (++) Word Length
+        (++) Stop Bit
+        (++) Parity: If the parity is enabled, then the MSB bit of the data written
+             in the data register is transmitted but is changed by the parity bit.
+        (++) USART polarity
+        (++) USART phase
+        (++) USART LastBit
+        (++) Receiver/transmitter modes
+
+    [..]
+    The HAL_USART_Init() function follows the USART synchronous SPI configuration
+    procedure (details for the procedure are available in reference manual).
+
+@endverbatim
+
+  Depending on the frame length defined by the M1 and M0 bits (7-bit,
+  8-bit or 9-bit), the possible USART formats are listed in the
+  following table.
+
+    Table 1. USART frame format.
+    +-----------------------------------------------------------------------+
+    |  M1 bit |  M0 bit |  PCE bit  |            USART frame                |
+    |---------|---------|-----------|---------------------------------------|
+    |    0    |    0    |    0      |    | SB |    8 bit data   | STB |     |
+    |---------|---------|-----------|---------------------------------------|
+    |    0    |    0    |    1      |    | SB | 7 bit data | PB | STB |     |
+    |---------|---------|-----------|---------------------------------------|
+    |    0    |    1    |    0      |    | SB |    9 bit data   | STB |     |
+    |---------|---------|-----------|---------------------------------------|
+    |    0    |    1    |    1      |    | SB | 8 bit data | PB | STB |     |
+    |---------|---------|-----------|---------------------------------------|
+    |    1    |    0    |    0      |    | SB |    7 bit data   | STB |     |
+    |---------|---------|-----------|---------------------------------------|
+    |    1    |    0    |    1      |    | SB | 6 bit data | PB | STB |     |
+    +-----------------------------------------------------------------------+
+
+  * @{
+  */
+
+/**
+  * @brief  Initialize the USART mode according to the specified
+  *         parameters in the USART_InitTypeDef and initialize the associated handle.
+  * @param  husart USART handle.
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_USART_Init(USART_HandleTypeDef *husart)
+{
+  /* Check the USART handle allocation */
+  if (husart == NULL)
+  {
+    return HAL_ERROR;
+  }
+
+  /* Check the parameters */
+  assert_param(IS_USART_INSTANCE(husart->Instance));
+
+  if (husart->State == HAL_USART_STATE_RESET)
+  {
+    /* Allocate lock resource and initialize it */
+    husart->Lock = HAL_UNLOCKED;
+
+#if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
+    USART_InitCallbacksToDefault(husart);
+
+    if (husart->MspInitCallback == NULL)
+    {
+      husart->MspInitCallback = HAL_USART_MspInit;
+    }
+
+    /* Init the low level hardware */
+    husart->MspInitCallback(husart);
+#else
+    /* Init the low level hardware : GPIO, CLOCK */
+    HAL_USART_MspInit(husart);
+#endif /* USE_HAL_USART_REGISTER_CALLBACKS */
+  }
+
+  husart->State = HAL_USART_STATE_BUSY;
+
+  /* Disable the Peripheral */
+  __HAL_USART_DISABLE(husart);
+
+  /* Set the Usart Communication parameters */
+  if (USART_SetConfig(husart) == HAL_ERROR)
+  {
+    return HAL_ERROR;
+  }
+
+  /* In Synchronous SPI mode, the following bits must be kept cleared:
+  - LINEN bit in the USART_CR2 register
+  - HDSEL, SCEN and IREN bits in the USART_CR3 register.
+  */
+  husart->Instance->CR2 &= ~USART_CR2_LINEN;
+  husart->Instance->CR3 &= ~(USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN);
+
+  /* Enable the Peripheral */
+  __HAL_USART_ENABLE(husart);
+
+  /* TEACK and/or REACK to check before moving husart->State to Ready */
+  return (USART_CheckIdleState(husart));
+}
+
+/**
+  * @brief DeInitialize the USART peripheral.
+  * @param  husart USART handle.
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_USART_DeInit(USART_HandleTypeDef *husart)
+{
+  /* Check the USART handle allocation */
+  if (husart == NULL)
+  {
+    return HAL_ERROR;
+  }
+
+  /* Check the parameters */
+  assert_param(IS_USART_INSTANCE(husart->Instance));
+
+  husart->State = HAL_USART_STATE_BUSY;
+
+  husart->Instance->CR1 = 0x0U;
+  husart->Instance->CR2 = 0x0U;
+  husart->Instance->CR3 = 0x0U;
+
+#if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
+  if (husart->MspDeInitCallback == NULL)
+  {
+    husart->MspDeInitCallback = HAL_USART_MspDeInit;
+  }
+  /* DeInit the low level hardware */
+  husart->MspDeInitCallback(husart);
+#else
+  /* DeInit the low level hardware */
+  HAL_USART_MspDeInit(husart);
+#endif /* USE_HAL_USART_REGISTER_CALLBACKS */
+
+  husart->ErrorCode = HAL_USART_ERROR_NONE;
+  husart->State = HAL_USART_STATE_RESET;
+
+  /* Process Unlock */
+  __HAL_UNLOCK(husart);
+
+  return HAL_OK;
+}
+
+/**
+  * @brief Initialize the USART MSP.
+  * @param husart USART handle.
+  * @retval None
+  */
+__weak void HAL_USART_MspInit(USART_HandleTypeDef *husart)
+{
+  /* Prevent unused argument(s) compilation warning */
+  UNUSED(husart);
+
+  /* NOTE : This function should not be modified, when the callback is needed,
+            the HAL_USART_MspInit can be implemented in the user file
+   */
+}
+
+/**
+  * @brief DeInitialize the USART MSP.
+  * @param husart USART handle.
+  * @retval None
+  */
+__weak void HAL_USART_MspDeInit(USART_HandleTypeDef *husart)
+{
+  /* Prevent unused argument(s) compilation warning */
+  UNUSED(husart);
+
+  /* NOTE : This function should not be modified, when the callback is needed,
+            the HAL_USART_MspDeInit can be implemented in the user file
+   */
+}
+
+#if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
+/**
+  * @brief  Register a User USART Callback
+  *         To be used to override the weak predefined callback
+  * @note   The HAL_USART_RegisterCallback() may be called before HAL_USART_Init() in HAL_USART_STATE_RESET
+  *         to register callbacks for HAL_USART_MSPINIT_CB_ID and HAL_USART_MSPDEINIT_CB_ID
+  * @param  husart usart handle
+  * @param  CallbackID ID of the callback to be registered
+  *         This parameter can be one of the following values:
+  *           @arg @ref HAL_USART_TX_HALFCOMPLETE_CB_ID Tx Half Complete Callback ID
+  *           @arg @ref HAL_USART_TX_COMPLETE_CB_ID Tx Complete Callback ID
+  *           @arg @ref HAL_USART_RX_HALFCOMPLETE_CB_ID Rx Half Complete Callback ID
+  *           @arg @ref HAL_USART_RX_COMPLETE_CB_ID Rx Complete Callback ID
+  *           @arg @ref HAL_USART_TX_RX_COMPLETE_CB_ID Rx Complete Callback ID
+  *           @arg @ref HAL_USART_ERROR_CB_ID Error Callback ID
+  *           @arg @ref HAL_USART_ABORT_COMPLETE_CB_ID Abort Complete Callback ID
+  *           @arg @ref HAL_USART_RX_FIFO_FULL_CB_ID Rx Fifo Full Callback ID
+  *           @arg @ref HAL_USART_TX_FIFO_EMPTY_CB_ID Tx Fifo Empty Callback ID
+  *           @arg @ref HAL_USART_MSPINIT_CB_ID MspInit Callback ID
+  *           @arg @ref HAL_USART_MSPDEINIT_CB_ID MspDeInit Callback ID
+  * @param  pCallback pointer to the Callback function
+  * @retval HAL status
++  */
+HAL_StatusTypeDef HAL_USART_RegisterCallback(USART_HandleTypeDef *husart, HAL_USART_CallbackIDTypeDef CallbackID,
+                                             pUSART_CallbackTypeDef pCallback)
+{
+  HAL_StatusTypeDef status = HAL_OK;
+
+  if (pCallback == NULL)
+  {
+    /* Update the error code */
+    husart->ErrorCode |= HAL_USART_ERROR_INVALID_CALLBACK;
+
+    return HAL_ERROR;
+  }
+
+  if (husart->State == HAL_USART_STATE_READY)
+  {
+    switch (CallbackID)
+    {
+      case HAL_USART_TX_HALFCOMPLETE_CB_ID :
+        husart->TxHalfCpltCallback = pCallback;
+        break;
+
+      case HAL_USART_TX_COMPLETE_CB_ID :
+        husart->TxCpltCallback = pCallback;
+        break;
+
+      case HAL_USART_RX_HALFCOMPLETE_CB_ID :
+        husart->RxHalfCpltCallback = pCallback;
+        break;
+
+      case HAL_USART_RX_COMPLETE_CB_ID :
+        husart->RxCpltCallback = pCallback;
+        break;
+
+      case HAL_USART_TX_RX_COMPLETE_CB_ID :
+        husart->TxRxCpltCallback = pCallback;
+        break;
+
+      case HAL_USART_ERROR_CB_ID :
+        husart->ErrorCallback = pCallback;
+        break;
+
+      case HAL_USART_ABORT_COMPLETE_CB_ID :
+        husart->AbortCpltCallback = pCallback;
+        break;
+
+      case HAL_USART_RX_FIFO_FULL_CB_ID :
+        husart->RxFifoFullCallback = pCallback;
+        break;
+
+      case HAL_USART_TX_FIFO_EMPTY_CB_ID :
+        husart->TxFifoEmptyCallback = pCallback;
+        break;
+
+      case HAL_USART_MSPINIT_CB_ID :
+        husart->MspInitCallback = pCallback;
+        break;
+
+      case HAL_USART_MSPDEINIT_CB_ID :
+        husart->MspDeInitCallback = pCallback;
+        break;
+
+      default :
+        /* Update the error code */
+        husart->ErrorCode |= HAL_USART_ERROR_INVALID_CALLBACK;
+
+        /* Return error status */
+        status =  HAL_ERROR;
+        break;
+    }
+  }
+  else if (husart->State == HAL_USART_STATE_RESET)
+  {
+    switch (CallbackID)
+    {
+      case HAL_USART_MSPINIT_CB_ID :
+        husart->MspInitCallback = pCallback;
+        break;
+
+      case HAL_USART_MSPDEINIT_CB_ID :
+        husart->MspDeInitCallback = pCallback;
+        break;
+
+      default :
+        /* Update the error code */
+        husart->ErrorCode |= HAL_USART_ERROR_INVALID_CALLBACK;
+
+        /* Return error status */
+        status =  HAL_ERROR;
+        break;
+    }
+  }
+  else
+  {
+    /* Update the error code */
+    husart->ErrorCode |= HAL_USART_ERROR_INVALID_CALLBACK;
+
+    /* Return error status */
+    status =  HAL_ERROR;
+  }
+
+  return status;
+}
+
+/**
+  * @brief  Unregister an USART Callback
+  *         USART callaback is redirected to the weak predefined callback
+  * @note   The HAL_USART_UnRegisterCallback() may be called before HAL_USART_Init() in HAL_USART_STATE_RESET
+  *         to un-register callbacks for HAL_USART_MSPINIT_CB_ID and HAL_USART_MSPDEINIT_CB_ID
+  * @param  husart usart handle
+  * @param  CallbackID ID of the callback to be unregistered
+  *         This parameter can be one of the following values:
+  *           @arg @ref HAL_USART_TX_HALFCOMPLETE_CB_ID Tx Half Complete Callback ID
+  *           @arg @ref HAL_USART_TX_COMPLETE_CB_ID Tx Complete Callback ID
+  *           @arg @ref HAL_USART_RX_HALFCOMPLETE_CB_ID Rx Half Complete Callback ID
+  *           @arg @ref HAL_USART_RX_COMPLETE_CB_ID Rx Complete Callback ID
+  *           @arg @ref HAL_USART_TX_RX_COMPLETE_CB_ID Rx Complete Callback ID
+  *           @arg @ref HAL_USART_ERROR_CB_ID Error Callback ID
+  *           @arg @ref HAL_USART_ABORT_COMPLETE_CB_ID Abort Complete Callback ID
+  *           @arg @ref HAL_USART_RX_FIFO_FULL_CB_ID Rx Fifo Full Callback ID
+  *           @arg @ref HAL_USART_TX_FIFO_EMPTY_CB_ID Tx Fifo Empty Callback ID
+  *           @arg @ref HAL_USART_MSPINIT_CB_ID MspInit Callback ID
+  *           @arg @ref HAL_USART_MSPDEINIT_CB_ID MspDeInit Callback ID
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_USART_UnRegisterCallback(USART_HandleTypeDef *husart, HAL_USART_CallbackIDTypeDef CallbackID)
+{
+  HAL_StatusTypeDef status = HAL_OK;
+
+  if (HAL_USART_STATE_READY == husart->State)
+  {
+    switch (CallbackID)
+    {
+      case HAL_USART_TX_HALFCOMPLETE_CB_ID :
+        husart->TxHalfCpltCallback = HAL_USART_TxHalfCpltCallback;               /* Legacy weak  TxHalfCpltCallback  */
+        break;
+
+      case HAL_USART_TX_COMPLETE_CB_ID :
+        husart->TxCpltCallback = HAL_USART_TxCpltCallback;                       /* Legacy weak TxCpltCallback       */
+        break;
+
+      case HAL_USART_RX_HALFCOMPLETE_CB_ID :
+        husart->RxHalfCpltCallback = HAL_USART_RxHalfCpltCallback;               /* Legacy weak RxHalfCpltCallback   */
+        break;
+
+      case HAL_USART_RX_COMPLETE_CB_ID :
+        husart->RxCpltCallback = HAL_USART_RxCpltCallback;                       /* Legacy weak RxCpltCallback       */
+        break;
+
+      case HAL_USART_TX_RX_COMPLETE_CB_ID :
+        husart->TxRxCpltCallback = HAL_USART_TxRxCpltCallback;                   /* Legacy weak TxRxCpltCallback     */
+        break;
+
+      case HAL_USART_ERROR_CB_ID :
+        husart->ErrorCallback = HAL_USART_ErrorCallback;                         /* Legacy weak ErrorCallback        */
+        break;
+
+      case HAL_USART_ABORT_COMPLETE_CB_ID :
+        husart->AbortCpltCallback = HAL_USART_AbortCpltCallback;                 /* Legacy weak AbortCpltCallback    */
+        break;
+
+      case HAL_USART_RX_FIFO_FULL_CB_ID :
+        husart->RxFifoFullCallback = HAL_USARTEx_RxFifoFullCallback;             /* Legacy weak RxFifoFullCallback   */
+        break;
+
+      case HAL_USART_TX_FIFO_EMPTY_CB_ID :
+        husart->TxFifoEmptyCallback = HAL_USARTEx_TxFifoEmptyCallback;           /* Legacy weak TxFifoEmptyCallback  */
+        break;
+
+      case HAL_USART_MSPINIT_CB_ID :
+        husart->MspInitCallback = HAL_USART_MspInit;                             /* Legacy weak MspInitCallback      */
+        break;
+
+      case HAL_USART_MSPDEINIT_CB_ID :
+        husart->MspDeInitCallback = HAL_USART_MspDeInit;                         /* Legacy weak MspDeInitCallback    */
+        break;
+
+      default :
+        /* Update the error code */
+        husart->ErrorCode |= HAL_USART_ERROR_INVALID_CALLBACK;
+
+        /* Return error status */
+        status =  HAL_ERROR;
+        break;
+    }
+  }
+  else if (HAL_USART_STATE_RESET == husart->State)
+  {
+    switch (CallbackID)
+    {
+      case HAL_USART_MSPINIT_CB_ID :
+        husart->MspInitCallback = HAL_USART_MspInit;
+        break;
+
+      case HAL_USART_MSPDEINIT_CB_ID :
+        husart->MspDeInitCallback = HAL_USART_MspDeInit;
+        break;
+
+      default :
+        /* Update the error code */
+        husart->ErrorCode |= HAL_USART_ERROR_INVALID_CALLBACK;
+
+        /* Return error status */
+        status =  HAL_ERROR;
+        break;
+    }
+  }
+  else
+  {
+    /* Update the error code */
+    husart->ErrorCode |= HAL_USART_ERROR_INVALID_CALLBACK;
+
+    /* Return error status */
+    status =  HAL_ERROR;
+  }
+
+  return status;
+}
+#endif /* USE_HAL_USART_REGISTER_CALLBACKS */
+
+
+/**
+  * @}
+  */
+
+/** @defgroup USART_Exported_Functions_Group2 IO operation functions
+  * @brief   USART Transmit and Receive functions
+  *
+@verbatim
+ ===============================================================================
+                      ##### IO operation functions #####
+ ===============================================================================
+    [..] This subsection provides a set of functions allowing to manage the USART synchronous SPI
+    data transfers.
+
+    [..] The USART Synchronous SPI supports master and slave modes (SCLK as output or input).
+
+    [..]
+
+    (#) There are two modes of transfer:
+        (++) Blocking mode: The communication is performed in polling mode.
+             The HAL status of all data processing is returned by the same function
+             after finishing transfer.
+        (++) No-Blocking mode: The communication is performed using Interrupts
+             or DMA, These API's return the HAL status.
+             The end of the data processing will be indicated through the
+             dedicated USART IRQ when using Interrupt mode or the DMA IRQ when
+             using DMA mode.
+             The HAL_USART_TxCpltCallback(), HAL_USART_RxCpltCallback() and HAL_USART_TxRxCpltCallback() user callbacks
+             will be executed respectively at the end of the transmit or Receive process
+             The HAL_USART_ErrorCallback()user callback will be executed when a communication error is detected
+
+    (#) Blocking mode API's are :
+        (++) HAL_USART_Transmit() in simplex mode
+        (++) HAL_USART_Receive() in full duplex receive only
+        (++) HAL_USART_TransmitReceive() in full duplex mode
+
+    (#) Non-Blocking mode API's with Interrupt are :
+        (++) HAL_USART_Transmit_IT() in simplex mode
+        (++) HAL_USART_Receive_IT() in full duplex receive only
+        (++) HAL_USART_TransmitReceive_IT() in full duplex mode
+        (++) HAL_USART_IRQHandler()
+
+    (#) No-Blocking mode API's  with DMA are :
+        (++) HAL_USART_Transmit_DMA() in simplex mode
+        (++) HAL_USART_Receive_DMA() in full duplex receive only
+        (++) HAL_USART_TransmitReceive_DMA() in full duplex mode
+        (++) HAL_USART_DMAPause()
+        (++) HAL_USART_DMAResume()
+        (++) HAL_USART_DMAStop()
+
+    (#) A set of Transfer Complete Callbacks are provided in Non_Blocking mode:
+        (++) HAL_USART_TxCpltCallback()
+        (++) HAL_USART_RxCpltCallback()
+        (++) HAL_USART_TxHalfCpltCallback()
+        (++) HAL_USART_RxHalfCpltCallback()
+        (++) HAL_USART_ErrorCallback()
+        (++) HAL_USART_TxRxCpltCallback()
+
+    (#) Non-Blocking mode transfers could be aborted using Abort API's :
+        (++) HAL_USART_Abort()
+        (++) HAL_USART_Abort_IT()
+
+    (#) For Abort services based on interrupts (HAL_USART_Abort_IT), a Abort Complete Callbacks is provided:
+        (++) HAL_USART_AbortCpltCallback()
+
+    (#) In Non-Blocking mode transfers, possible errors are split into 2 categories.
+        Errors are handled as follows :
+        (++) Error is considered as Recoverable and non blocking : Transfer could go till end, but error severity is
+             to be evaluated by user : this concerns Frame Error,
+             Parity Error or Noise Error in Interrupt mode reception .
+             Received character is then retrieved and stored in Rx buffer, Error code is set to allow user to identify
+             error type, and HAL_USART_ErrorCallback() user callback is executed.
+             Transfer is kept ongoing on USART side.
+             If user wants to abort it, Abort services should be called by user.
+        (++) Error is considered as Blocking : Transfer could not be completed properly and is aborted.
+             This concerns Overrun Error In Interrupt mode reception and all errors in DMA mode.
+             Error code is set to allow user to identify error type,
+             and HAL_USART_ErrorCallback() user callback is executed.
+
+@endverbatim
+  * @{
+  */
+
+/**
+  * @brief  Simplex send an amount of data in blocking mode.
+  * @note   When USART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
+  *         the sent data is handled as a set of u16. In this case, Size must indicate the number
+  *         of u16 provided through pTxData.
+  * @param  husart USART handle.
+  * @param  pTxData Pointer to data buffer (u8 or u16 data elements).
+  * @param  Size Amount of data elements (u8 or u16) to be sent.
+  * @param  Timeout Timeout duration.
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_USART_Transmit(USART_HandleTypeDef *husart, const uint8_t *pTxData, uint16_t Size,
+                                     uint32_t Timeout)
+{
+  const uint8_t  *ptxdata8bits;
+  const uint16_t *ptxdata16bits;
+  uint32_t tickstart;
+
+  if (husart->State == HAL_USART_STATE_READY)
+  {
+    if ((pTxData == NULL) || (Size == 0U))
+    {
+      return  HAL_ERROR;
+    }
+
+    /* Process Locked */
+    __HAL_LOCK(husart);
+
+    husart->ErrorCode = HAL_USART_ERROR_NONE;
+    husart->State = HAL_USART_STATE_BUSY_TX;
+
+    /* Init tickstart for timeout management */
+    tickstart = HAL_GetTick();
+
+    husart->TxXferSize = Size;
+    husart->TxXferCount = Size;
+
+    /* In case of 9bits/No Parity transfer, pTxData needs to be handled as a uint16_t pointer */
+    if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
+    {
+      ptxdata8bits  = NULL;
+      ptxdata16bits = (const uint16_t *) pTxData;
+    }
+    else
+    {
+      ptxdata8bits  = pTxData;
+      ptxdata16bits = NULL;
+    }
+
+    /* Check the remaining data to be sent */
+    while (husart->TxXferCount > 0U)
+    {
+      if (USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
+      {
+        return HAL_TIMEOUT;
+      }
+      if (ptxdata8bits == NULL)
+      {
+        husart->Instance->TDR = (uint16_t)(*ptxdata16bits & 0x01FFU);
+        ptxdata16bits++;
+      }
+      else
+      {
+        husart->Instance->TDR = (uint8_t)(*ptxdata8bits & 0xFFU);
+        ptxdata8bits++;
+      }
+
+      husart->TxXferCount--;
+    }
+
+    if (USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TC, RESET, tickstart, Timeout) != HAL_OK)
+    {
+      return HAL_TIMEOUT;
+    }
+
+    /* Clear Transmission Complete Flag */
+    __HAL_USART_CLEAR_FLAG(husart, USART_CLEAR_TCF);
+
+    /* Clear overrun flag and discard the received data */
+    __HAL_USART_CLEAR_OREFLAG(husart);
+    __HAL_USART_SEND_REQ(husart, USART_RXDATA_FLUSH_REQUEST);
+    __HAL_USART_SEND_REQ(husart, USART_TXDATA_FLUSH_REQUEST);
+
+    /* At end of Tx process, restore husart->State to Ready */
+    husart->State = HAL_USART_STATE_READY;
+
+    /* Process Unlocked */
+    __HAL_UNLOCK(husart);
+
+    return HAL_OK;
+  }
+  else
+  {
+    return HAL_BUSY;
+  }
+}
+
+/**
+  * @brief Receive an amount of data in blocking mode.
+  * @note   To receive synchronous data, dummy data are simultaneously transmitted.
+  * @note   When USART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
+  *         the received data is handled as a set of u16. In this case, Size must indicate the number
+  *         of u16 available through pRxData.
+  * @param husart USART handle.
+  * @param pRxData Pointer to data buffer (u8 or u16 data elements).
+  * @param Size Amount of data elements (u8 or u16) to be received.
+  * @param Timeout Timeout duration.
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_USART_Receive(USART_HandleTypeDef *husart, uint8_t *pRxData, uint16_t Size, uint32_t Timeout)
+{
+  uint8_t  *prxdata8bits;
+  uint16_t *prxdata16bits;
+  uint16_t uhMask;
+  uint32_t tickstart;
+
+  if (husart->State == HAL_USART_STATE_READY)
+  {
+    if ((pRxData == NULL) || (Size == 0U))
+    {
+      return  HAL_ERROR;
+    }
+
+    /* Process Locked */
+    __HAL_LOCK(husart);
+
+    husart->ErrorCode = HAL_USART_ERROR_NONE;
+    husart->State = HAL_USART_STATE_BUSY_RX;
+
+    /* Init tickstart for timeout management */
+    tickstart = HAL_GetTick();
+
+    husart->RxXferSize = Size;
+    husart->RxXferCount = Size;
+
+    /* Computation of USART mask to apply to RDR register */
+    USART_MASK_COMPUTATION(husart);
+    uhMask = husart->Mask;
+
+    /* In case of 9bits/No Parity transfer, pRxData needs to be handled as a uint16_t pointer */
+    if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
+    {
+      prxdata8bits  = NULL;
+      prxdata16bits = (uint16_t *) pRxData;
+    }
+    else
+    {
+      prxdata8bits  = pRxData;
+      prxdata16bits = NULL;
+    }
+
+    /* as long as data have to be received */
+    while (husart->RxXferCount > 0U)
+    {
+      if (husart->SlaveMode == USART_SLAVEMODE_DISABLE)
+      {
+        /* Wait until TXE flag is set to send dummy byte in order to generate the
+        * clock for the slave to send data.
+        * Whatever the frame length (7, 8 or 9-bit long), the same dummy value
+        * can be written for all the cases. */
+        if (USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
+        {
+          return HAL_TIMEOUT;
+        }
+        husart->Instance->TDR = (USART_DUMMY_DATA & (uint16_t)0x0FF);
+      }
+
+      /* Wait for RXNE Flag */
+      if (USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK)
+      {
+        return HAL_TIMEOUT;
+      }
+
+      if (prxdata8bits == NULL)
+      {
+        *prxdata16bits = (uint16_t)(husart->Instance->RDR & uhMask);
+        prxdata16bits++;
+      }
+      else
+      {
+        *prxdata8bits = (uint8_t)(husart->Instance->RDR & (uint8_t)(uhMask & 0xFFU));
+        prxdata8bits++;
+      }
+
+      husart->RxXferCount--;
+
+    }
+
+    /* Clear SPI slave underrun flag and discard transmit data */
+    if (husart->SlaveMode == USART_SLAVEMODE_ENABLE)
+    {
+      __HAL_USART_CLEAR_UDRFLAG(husart);
+      __HAL_USART_SEND_REQ(husart, USART_TXDATA_FLUSH_REQUEST);
+    }
+
+    /* At end of Rx process, restore husart->State to Ready */
+    husart->State = HAL_USART_STATE_READY;
+
+    /* Process Unlocked */
+    __HAL_UNLOCK(husart);
+
+    return HAL_OK;
+  }
+  else
+  {
+    return HAL_BUSY;
+  }
+}
+
+/**
+  * @brief Full-Duplex Send and Receive an amount of data in blocking mode.
+  * @note   When USART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
+  *         the sent data and the received data are handled as sets of u16. In this case, Size must indicate the number
+  *         of u16 available through pTxData and through pRxData.
+  * @param  husart USART handle.
+  * @param  pTxData pointer to TX data buffer (u8 or u16 data elements).
+  * @param  pRxData pointer to RX data buffer (u8 or u16 data elements).
+  * @param  Size amount of data elements (u8 or u16) to be sent (same amount to be received).
+  * @param  Timeout Timeout duration.
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_USART_TransmitReceive(USART_HandleTypeDef *husart, const uint8_t *pTxData, uint8_t *pRxData,
+                                            uint16_t Size, uint32_t Timeout)
+{
+  uint8_t  *prxdata8bits;
+  uint16_t *prxdata16bits;
+  const uint8_t  *ptxdata8bits;
+  const uint16_t *ptxdata16bits;
+  uint16_t uhMask;
+  uint16_t rxdatacount;
+  uint32_t tickstart;
+
+  if (husart->State == HAL_USART_STATE_READY)
+  {
+    if ((pTxData == NULL) || (pRxData == NULL) || (Size == 0U))
+    {
+      return  HAL_ERROR;
+    }
+
+    /* Process Locked */
+    __HAL_LOCK(husart);
+
+    husart->ErrorCode = HAL_USART_ERROR_NONE;
+    husart->State = HAL_USART_STATE_BUSY_RX;
+
+    /* Init tickstart for timeout management */
+    tickstart = HAL_GetTick();
+
+    husart->RxXferSize = Size;
+    husart->TxXferSize = Size;
+    husart->TxXferCount = Size;
+    husart->RxXferCount = Size;
+
+    /* Computation of USART mask to apply to RDR register */
+    USART_MASK_COMPUTATION(husart);
+    uhMask = husart->Mask;
+
+    /* In case of 9bits/No Parity transfer, pRxData needs to be handled as a uint16_t pointer */
+    if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
+    {
+      prxdata8bits  = NULL;
+      ptxdata8bits  = NULL;
+      ptxdata16bits = (const uint16_t *) pTxData;
+      prxdata16bits = (uint16_t *) pRxData;
+    }
+    else
+    {
+      prxdata8bits  = pRxData;
+      ptxdata8bits  = pTxData;
+      ptxdata16bits = NULL;
+      prxdata16bits = NULL;
+    }
+
+    if ((husart->TxXferCount == 0x01U) || (husart->SlaveMode == USART_SLAVEMODE_ENABLE))
+    {
+      /* Wait until TXE flag is set to send data */
+      if (USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
+      {
+        return HAL_TIMEOUT;
+      }
+      if (ptxdata8bits == NULL)
+      {
+        husart->Instance->TDR = (uint16_t)(*ptxdata16bits & uhMask);
+        ptxdata16bits++;
+      }
+      else
+      {
+        husart->Instance->TDR = (uint8_t)(*ptxdata8bits & (uint8_t)(uhMask & 0xFFU));
+        ptxdata8bits++;
+      }
+
+      husart->TxXferCount--;
+    }
+
+    /* Check the remain data to be sent */
+    /* rxdatacount is a temporary variable for MISRAC2012-Rule-13.5 */
+    rxdatacount = husart->RxXferCount;
+    while ((husart->TxXferCount > 0U) || (rxdatacount > 0U))
+    {
+      if (husart->TxXferCount > 0U)
+      {
+        /* Wait until TXE flag is set to send data */
+        if (USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
+        {
+          return HAL_TIMEOUT;
+        }
+        if (ptxdata8bits == NULL)
+        {
+          husart->Instance->TDR = (uint16_t)(*ptxdata16bits & uhMask);
+          ptxdata16bits++;
+        }
+        else
+        {
+          husart->Instance->TDR = (uint8_t)(*ptxdata8bits & (uint8_t)(uhMask & 0xFFU));
+          ptxdata8bits++;
+        }
+
+        husart->TxXferCount--;
+      }
+
+      if (husart->RxXferCount > 0U)
+      {
+        /* Wait for RXNE Flag */
+        if (USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK)
+        {
+          return HAL_TIMEOUT;
+        }
+
+        if (prxdata8bits == NULL)
+        {
+          *prxdata16bits = (uint16_t)(husart->Instance->RDR & uhMask);
+          prxdata16bits++;
+        }
+        else
+        {
+          *prxdata8bits = (uint8_t)(husart->Instance->RDR & (uint8_t)(uhMask & 0xFFU));
+          prxdata8bits++;
+        }
+
+        husart->RxXferCount--;
+      }
+      rxdatacount = husart->RxXferCount;
+    }
+
+    /* At end of TxRx process, restore husart->State to Ready */
+    husart->State = HAL_USART_STATE_READY;
+
+    /* Process Unlocked */
+    __HAL_UNLOCK(husart);
+
+    return HAL_OK;
+  }
+  else
+  {
+    return HAL_BUSY;
+  }
+}
+
+/**
+  * @brief  Send an amount of data in interrupt mode.
+  * @note   When USART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
+  *         the sent data is handled as a set of u16. In this case, Size must indicate the number
+  *         of u16 provided through pTxData.
+  * @param  husart USART handle.
+  * @param  pTxData pointer to data buffer (u8 or u16 data elements).
+  * @param  Size amount of data elements (u8 or u16) to be sent.
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_USART_Transmit_IT(USART_HandleTypeDef *husart, const uint8_t *pTxData, uint16_t Size)
+{
+  if (husart->State == HAL_USART_STATE_READY)
+  {
+    if ((pTxData == NULL) || (Size == 0U))
+    {
+      return HAL_ERROR;
+    }
+
+    /* Process Locked */
+    __HAL_LOCK(husart);
+
+    husart->pTxBuffPtr  = pTxData;
+    husart->TxXferSize  = Size;
+    husart->TxXferCount = Size;
+    husart->TxISR       = NULL;
+
+    husart->ErrorCode = HAL_USART_ERROR_NONE;
+    husart->State     = HAL_USART_STATE_BUSY_TX;
+
+    /* The USART Error Interrupts: (Frame error, noise error, overrun error)
+    are not managed by the USART Transmit Process to avoid the overrun interrupt
+    when the usart mode is configured for transmit and receive "USART_MODE_TX_RX"
+    to benefit for the frame error and noise interrupts the usart mode should be
+    configured only for transmit "USART_MODE_TX" */
+
+    /* Configure Tx interrupt processing */
+    if (husart->FifoMode == USART_FIFOMODE_ENABLE)
+    {
+      /* Set the Tx ISR function pointer according to the data word length */
+      if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
+      {
+        husart->TxISR = USART_TxISR_16BIT_FIFOEN;
+      }
+      else
+      {
+        husart->TxISR = USART_TxISR_8BIT_FIFOEN;
+      }
+
+      /* Process Unlocked */
+      __HAL_UNLOCK(husart);
+
+      /* Enable the TX FIFO threshold interrupt */
+      __HAL_USART_ENABLE_IT(husart, USART_IT_TXFT);
+    }
+    else
+    {
+      /* Set the Tx ISR function pointer according to the data word length */
+      if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
+      {
+        husart->TxISR = USART_TxISR_16BIT;
+      }
+      else
+      {
+        husart->TxISR = USART_TxISR_8BIT;
+      }
+
+      /* Process Unlocked */
+      __HAL_UNLOCK(husart);
+
+      /* Enable the USART Transmit Data Register Empty Interrupt */
+      __HAL_USART_ENABLE_IT(husart, USART_IT_TXE);
+    }
+
+    return HAL_OK;
+  }
+  else
+  {
+    return HAL_BUSY;
+  }
+}
+
+/**
+  * @brief Receive an amount of data in interrupt mode.
+  * @note   To receive synchronous data, dummy data are simultaneously transmitted.
+  * @note   When USART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
+  *         the received data is handled as a set of u16. In this case, Size must indicate the number
+  *         of u16 available through pRxData.
+  * @param  husart USART handle.
+  * @param  pRxData pointer to data buffer (u8 or u16 data elements).
+  * @param  Size amount of data elements (u8 or u16) to be received.
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_USART_Receive_IT(USART_HandleTypeDef *husart, uint8_t *pRxData, uint16_t Size)
+{
+  uint16_t nb_dummy_data;
+
+  if (husart->State == HAL_USART_STATE_READY)
+  {
+    if ((pRxData == NULL) || (Size == 0U))
+    {
+      return HAL_ERROR;
+    }
+
+    /* Process Locked */
+    __HAL_LOCK(husart);
+
+    husart->pRxBuffPtr  = pRxData;
+    husart->RxXferSize  = Size;
+    husart->RxXferCount = Size;
+    husart->RxISR       = NULL;
+
+    USART_MASK_COMPUTATION(husart);
+
+    husart->ErrorCode = HAL_USART_ERROR_NONE;
+    husart->State = HAL_USART_STATE_BUSY_RX;
+
+    /* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */
+    SET_BIT(husart->Instance->CR3, USART_CR3_EIE);
+
+    /* Configure Rx interrupt processing */
+    if ((husart->FifoMode == USART_FIFOMODE_ENABLE) && (Size >= husart->NbRxDataToProcess))
+    {
+      /* Set the Rx ISR function pointer according to the data word length */
+      if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
+      {
+        husart->RxISR = USART_RxISR_16BIT_FIFOEN;
+      }
+      else
+      {
+        husart->RxISR = USART_RxISR_8BIT_FIFOEN;
+      }
+
+      /* Process Unlocked */
+      __HAL_UNLOCK(husart);
+
+      /* Enable the USART Parity Error interrupt and RX FIFO Threshold interrupt */
+      if (husart->Init.Parity != USART_PARITY_NONE)
+      {
+        SET_BIT(husart->Instance->CR1, USART_CR1_PEIE);
+      }
+      SET_BIT(husart->Instance->CR3, USART_CR3_RXFTIE);
+    }
+    else
+    {
+      /* Set the Rx ISR function pointer according to the data word length */
+      if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
+      {
+        husart->RxISR = USART_RxISR_16BIT;
+      }
+      else
+      {
+        husart->RxISR = USART_RxISR_8BIT;
+      }
+
+      /* Process Unlocked */
+      __HAL_UNLOCK(husart);
+
+      /* Enable the USART Parity Error and Data Register not empty Interrupts */
+      if (husart->Init.Parity != USART_PARITY_NONE)
+      {
+        SET_BIT(husart->Instance->CR1, USART_CR1_PEIE | USART_CR1_RXNEIE_RXFNEIE);
+      }
+      else
+      {
+        SET_BIT(husart->Instance->CR1, USART_CR1_RXNEIE_RXFNEIE);
+      }
+    }
+
+    if (husart->SlaveMode == USART_SLAVEMODE_DISABLE)
+    {
+      /* Send dummy data in order to generate the clock for the Slave to send the next data.
+         When FIFO mode is disabled only one data must be transferred.
+         When FIFO mode is enabled data must be transmitted until the RX FIFO reaches its threshold.
+      */
+      if ((husart->FifoMode == USART_FIFOMODE_ENABLE) && (Size >= husart->NbRxDataToProcess))
+      {
+        for (nb_dummy_data = husart->NbRxDataToProcess ; nb_dummy_data > 0U ; nb_dummy_data--)
+        {
+          husart->Instance->TDR = (USART_DUMMY_DATA & (uint16_t)0x00FF);
+        }
+      }
+      else
+      {
+        husart->Instance->TDR = (USART_DUMMY_DATA & (uint16_t)0x00FF);
+      }
+    }
+
+    return HAL_OK;
+  }
+  else
+  {
+    return HAL_BUSY;
+  }
+}
+
+/**
+  * @brief Full-Duplex Send and Receive an amount of data in interrupt mode.
+  * @note   When USART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
+  *         the sent data and the received data are handled as sets of u16. In this case, Size must indicate the number
+  *         of u16 available through pTxData and through pRxData.
+  * @param  husart USART handle.
+  * @param  pTxData pointer to TX data buffer (u8 or u16 data elements).
+  * @param  pRxData pointer to RX data buffer (u8 or u16 data elements).
+  * @param  Size amount of data elements (u8 or u16) to be sent (same amount to be received).
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_USART_TransmitReceive_IT(USART_HandleTypeDef *husart, const uint8_t *pTxData, uint8_t *pRxData,
+                                               uint16_t Size)
+{
+
+  if (husart->State == HAL_USART_STATE_READY)
+  {
+    if ((pTxData == NULL) || (pRxData == NULL) || (Size == 0U))
+    {
+      return HAL_ERROR;
+    }
+
+    /* Process Locked */
+    __HAL_LOCK(husart);
+
+    husart->pRxBuffPtr = pRxData;
+    husart->RxXferSize = Size;
+    husart->RxXferCount = Size;
+    husart->pTxBuffPtr = pTxData;
+    husart->TxXferSize = Size;
+    husart->TxXferCount = Size;
+
+    /* Computation of USART mask to apply to RDR register */
+    USART_MASK_COMPUTATION(husart);
+
+    husart->ErrorCode = HAL_USART_ERROR_NONE;
+    husart->State = HAL_USART_STATE_BUSY_TX_RX;
+
+    /* Configure TxRx interrupt processing */
+    if ((husart->FifoMode == USART_FIFOMODE_ENABLE) && (Size >= husart->NbRxDataToProcess))
+    {
+      /* Set the Rx ISR function pointer according to the data word length */
+      if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
+      {
+        husart->TxISR = USART_TxISR_16BIT_FIFOEN;
+        husart->RxISR = USART_RxISR_16BIT_FIFOEN;
+      }
+      else
+      {
+        husart->TxISR = USART_TxISR_8BIT_FIFOEN;
+        husart->RxISR = USART_RxISR_8BIT_FIFOEN;
+      }
+
+      /* Process Locked */
+      __HAL_UNLOCK(husart);
+
+      /* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */
+      SET_BIT(husart->Instance->CR3, USART_CR3_EIE);
+
+      if (husart->Init.Parity != USART_PARITY_NONE)
+      {
+        /* Enable the USART Parity Error interrupt  */
+        SET_BIT(husart->Instance->CR1, USART_CR1_PEIE);
+      }
+
+      /* Enable the TX and  RX FIFO Threshold interrupts */
+      SET_BIT(husart->Instance->CR3, (USART_CR3_TXFTIE | USART_CR3_RXFTIE));
+    }
+    else
+    {
+      if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
+      {
+        husart->TxISR = USART_TxISR_16BIT;
+        husart->RxISR = USART_RxISR_16BIT;
+      }
+      else
+      {
+        husart->TxISR = USART_TxISR_8BIT;
+        husart->RxISR = USART_RxISR_8BIT;
+      }
+
+      /* Process Locked */
+      __HAL_UNLOCK(husart);
+
+      /* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */
+      SET_BIT(husart->Instance->CR3, USART_CR3_EIE);
+
+      /* Enable the USART Parity Error and USART Data Register not empty Interrupts */
+      if (husart->Init.Parity != USART_PARITY_NONE)
+      {
+        SET_BIT(husart->Instance->CR1, USART_CR1_PEIE | USART_CR1_RXNEIE_RXFNEIE);
+      }
+      else
+      {
+        SET_BIT(husart->Instance->CR1, USART_CR1_RXNEIE_RXFNEIE);
+      }
+
+      /* Enable the USART Transmit Data Register Empty Interrupt */
+      SET_BIT(husart->Instance->CR1, USART_CR1_TXEIE_TXFNFIE);
+    }
+
+    return HAL_OK;
+  }
+  else
+  {
+    return HAL_BUSY;
+  }
+}
+
+/**
+  * @brief Send an amount of data in DMA mode.
+  * @note   When USART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
+  *         the sent data is handled as a set of u16. In this case, Size must indicate the number
+  *         of u16 provided through pTxData.
+  * @param  husart USART handle.
+  * @param  pTxData pointer to data buffer (u8 or u16 data elements).
+  * @param  Size amount of data elements (u8 or u16) to be sent.
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_USART_Transmit_DMA(USART_HandleTypeDef *husart, const uint8_t *pTxData, uint16_t Size)
+{
+  HAL_StatusTypeDef status = HAL_OK;
+  const uint32_t *tmp;
+
+  if (husart->State == HAL_USART_STATE_READY)
+  {
+    if ((pTxData == NULL) || (Size == 0U))
+    {
+      return HAL_ERROR;
+    }
+
+    /* Process Locked */
+    __HAL_LOCK(husart);
+
+    husart->pTxBuffPtr = pTxData;
+    husart->TxXferSize = Size;
+    husart->TxXferCount = Size;
+
+    husart->ErrorCode = HAL_USART_ERROR_NONE;
+    husart->State = HAL_USART_STATE_BUSY_TX;
+
+    if (husart->hdmatx != NULL)
+    {
+      /* Set the USART DMA transfer complete callback */
+      husart->hdmatx->XferCpltCallback = USART_DMATransmitCplt;
+
+      /* Set the USART DMA Half transfer complete callback */
+      husart->hdmatx->XferHalfCpltCallback = USART_DMATxHalfCplt;
+
+      /* Set the DMA error callback */
+      husart->hdmatx->XferErrorCallback = USART_DMAError;
+
+      /* Enable the USART transmit DMA channel */
+      tmp = (const uint32_t *)&pTxData;
+      status = HAL_DMA_Start_IT(husart->hdmatx, *(const uint32_t *)tmp, (uint32_t)&husart->Instance->TDR, Size);
+    }
+
+    if (status == HAL_OK)
+    {
+      /* Clear the TC flag in the ICR register */
+      __HAL_USART_CLEAR_FLAG(husart, USART_CLEAR_TCF);
+
+      /* Process Unlocked */
+      __HAL_UNLOCK(husart);
+
+      /* Enable the DMA transfer for transmit request by setting the DMAT bit
+         in the USART CR3 register */
+      SET_BIT(husart->Instance->CR3, USART_CR3_DMAT);
+
+      return HAL_OK;
+    }
+    else
+    {
+      /* Set error code to DMA */
+      husart->ErrorCode = HAL_USART_ERROR_DMA;
+
+      /* Process Unlocked */
+      __HAL_UNLOCK(husart);
+
+      /* Restore husart->State to ready */
+      husart->State = HAL_USART_STATE_READY;
+
+      return HAL_ERROR;
+    }
+  }
+  else
+  {
+    return HAL_BUSY;
+  }
+}
+
+/**
+  * @brief Receive an amount of data in DMA mode.
+  * @note   When the USART parity is enabled (PCE = 1), the received data contain
+  *         the parity bit (MSB position).
+  * @note   The USART DMA transmit channel must be configured in order to generate the clock for the slave.
+  * @note   When USART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
+  *         the received data is handled as a set of u16. In this case, Size must indicate the number
+  *         of u16 available through pRxData.
+  * @param  husart USART handle.
+  * @param  pRxData pointer to data buffer (u8 or u16 data elements).
+  * @param  Size amount of data elements (u8 or u16) to be received.
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_USART_Receive_DMA(USART_HandleTypeDef *husart, uint8_t *pRxData, uint16_t Size)
+{
+  HAL_StatusTypeDef status = HAL_OK;
+  uint32_t *tmp = (uint32_t *)&pRxData;
+
+  /* Check that a Rx process is not already ongoing */
+  if (husart->State == HAL_USART_STATE_READY)
+  {
+    if ((pRxData == NULL) || (Size == 0U))
+    {
+      return HAL_ERROR;
+    }
+
+    /* Process Locked */
+    __HAL_LOCK(husart);
+
+    husart->pRxBuffPtr = pRxData;
+    husart->RxXferSize = Size;
+    husart->pTxBuffPtr = pRxData;
+    husart->TxXferSize = Size;
+
+    husart->ErrorCode = HAL_USART_ERROR_NONE;
+    husart->State = HAL_USART_STATE_BUSY_RX;
+
+    if (husart->hdmarx != NULL)
+    {
+      /* Set the USART DMA Rx transfer complete callback */
+      husart->hdmarx->XferCpltCallback = USART_DMAReceiveCplt;
+
+      /* Set the USART DMA Half transfer complete callback */
+      husart->hdmarx->XferHalfCpltCallback = USART_DMARxHalfCplt;
+
+      /* Set the USART DMA Rx transfer error callback */
+      husart->hdmarx->XferErrorCallback = USART_DMAError;
+
+      /* Enable the USART receive DMA channel */
+      status = HAL_DMA_Start_IT(husart->hdmarx, (uint32_t)&husart->Instance->RDR, *(uint32_t *)tmp, Size);
+    }
+
+    if ((status == HAL_OK) &&
+        (husart->SlaveMode == USART_SLAVEMODE_DISABLE))
+    {
+      /* Enable the USART transmit DMA channel: the transmit channel is used in order
+         to generate in the non-blocking mode the clock to the slave device,
+         this mode isn't a simplex receive mode but a full-duplex receive mode */
+
+      /* Set the USART DMA Tx Complete and Error callback to Null */
+      if (husart->hdmatx != NULL)
+      {
+        husart->hdmatx->XferErrorCallback = NULL;
+        husart->hdmatx->XferHalfCpltCallback = NULL;
+        husart->hdmatx->XferCpltCallback = NULL;
+        status = HAL_DMA_Start_IT(husart->hdmatx, *(uint32_t *)tmp, (uint32_t)&husart->Instance->TDR, Size);
+      }
+    }
+
+    if (status == HAL_OK)
+    {
+      /* Process Unlocked */
+      __HAL_UNLOCK(husart);
+
+      if (husart->Init.Parity != USART_PARITY_NONE)
+      {
+        /* Enable the USART Parity Error Interrupt */
+        SET_BIT(husart->Instance->CR1, USART_CR1_PEIE);
+      }
+
+      /* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */
+      SET_BIT(husart->Instance->CR3, USART_CR3_EIE);
+
+      /* Enable the DMA transfer for the receiver request by setting the DMAR bit
+         in the USART CR3 register */
+      SET_BIT(husart->Instance->CR3, USART_CR3_DMAR);
+
+      /* Enable the DMA transfer for transmit request by setting the DMAT bit
+         in the USART CR3 register */
+      SET_BIT(husart->Instance->CR3, USART_CR3_DMAT);
+
+      return HAL_OK;
+    }
+    else
+    {
+      if (husart->hdmarx != NULL)
+      {
+        status = HAL_DMA_Abort(husart->hdmarx);
+      }
+
+      /* No need to check on error code */
+      UNUSED(status);
+
+      /* Set error code to DMA */
+      husart->ErrorCode = HAL_USART_ERROR_DMA;
+
+      /* Process Unlocked */
+      __HAL_UNLOCK(husart);
+
+      /* Restore husart->State to ready */
+      husart->State = HAL_USART_STATE_READY;
+
+      return HAL_ERROR;
+    }
+  }
+  else
+  {
+    return HAL_BUSY;
+  }
+}
+
+/**
+  * @brief Full-Duplex Transmit Receive an amount of data in non-blocking mode.
+  * @note   When the USART parity is enabled (PCE = 1) the data received contain the parity bit.
+  * @note   When USART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
+  *         the sent data and the received data are handled as sets of u16. In this case, Size must indicate the number
+  *         of u16 available through pTxData and through pRxData.
+  * @param  husart USART handle.
+  * @param  pTxData pointer to TX data buffer (u8 or u16 data elements).
+  * @param  pRxData pointer to RX data buffer (u8 or u16 data elements).
+  * @param  Size amount of data elements (u8 or u16) to be received/sent.
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_USART_TransmitReceive_DMA(USART_HandleTypeDef *husart, const uint8_t *pTxData, uint8_t *pRxData,
+                                                uint16_t Size)
+{
+  HAL_StatusTypeDef status;
+  const uint32_t *tmp;
+
+  if (husart->State == HAL_USART_STATE_READY)
+  {
+    if ((pTxData == NULL) || (pRxData == NULL) || (Size == 0U))
+    {
+      return HAL_ERROR;
+    }
+
+    /* Process Locked */
+    __HAL_LOCK(husart);
+
+    husart->pRxBuffPtr = pRxData;
+    husart->RxXferSize = Size;
+    husart->pTxBuffPtr = pTxData;
+    husart->TxXferSize = Size;
+
+    husart->ErrorCode = HAL_USART_ERROR_NONE;
+    husart->State = HAL_USART_STATE_BUSY_TX_RX;
+
+    if ((husart->hdmarx != NULL) && (husart->hdmatx != NULL))
+    {
+      /* Set the USART DMA Rx transfer complete callback */
+      husart->hdmarx->XferCpltCallback = USART_DMAReceiveCplt;
+
+      /* Set the USART DMA Half transfer complete callback */
+      husart->hdmarx->XferHalfCpltCallback = USART_DMARxHalfCplt;
+
+      /* Set the USART DMA Tx transfer complete callback */
+      husart->hdmatx->XferCpltCallback = USART_DMATransmitCplt;
+
+      /* Set the USART DMA Half transfer complete callback */
+      husart->hdmatx->XferHalfCpltCallback = USART_DMATxHalfCplt;
+
+      /* Set the USART DMA Tx transfer error callback */
+      husart->hdmatx->XferErrorCallback = USART_DMAError;
+
+      /* Set the USART DMA Rx transfer error callback */
+      husart->hdmarx->XferErrorCallback = USART_DMAError;
+
+      /* Enable the USART receive DMA channel */
+      tmp = (uint32_t *)&pRxData;
+      status = HAL_DMA_Start_IT(husart->hdmarx, (uint32_t)&husart->Instance->RDR, *(const uint32_t *)tmp, Size);
+
+      /* Enable the USART transmit DMA channel */
+      if (status == HAL_OK)
+      {
+        tmp = (const uint32_t *)&pTxData;
+        status = HAL_DMA_Start_IT(husart->hdmatx, *(const uint32_t *)tmp, (uint32_t)&husart->Instance->TDR, Size);
+      }
+    }
+    else
+    {
+      status = HAL_ERROR;
+    }
+
+    if (status == HAL_OK)
+    {
+      /* Process Unlocked */
+      __HAL_UNLOCK(husart);
+
+      if (husart->Init.Parity != USART_PARITY_NONE)
+      {
+        /* Enable the USART Parity Error Interrupt */
+        SET_BIT(husart->Instance->CR1, USART_CR1_PEIE);
+      }
+
+      /* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */
+      SET_BIT(husart->Instance->CR3, USART_CR3_EIE);
+
+      /* Clear the TC flag in the ICR register */
+      __HAL_USART_CLEAR_FLAG(husart, USART_CLEAR_TCF);
+
+      /* Enable the DMA transfer for the receiver request by setting the DMAR bit
+         in the USART CR3 register */
+      SET_BIT(husart->Instance->CR3, USART_CR3_DMAR);
+
+      /* Enable the DMA transfer for transmit request by setting the DMAT bit
+         in the USART CR3 register */
+      SET_BIT(husart->Instance->CR3, USART_CR3_DMAT);
+
+      return HAL_OK;
+    }
+    else
+    {
+      if (husart->hdmarx != NULL)
+      {
+        status = HAL_DMA_Abort(husart->hdmarx);
+      }
+
+      /* No need to check on error code */
+      UNUSED(status);
+
+      /* Set error code to DMA */
+      husart->ErrorCode = HAL_USART_ERROR_DMA;
+
+      /* Process Unlocked */
+      __HAL_UNLOCK(husart);
+
+      /* Restore husart->State to ready */
+      husart->State = HAL_USART_STATE_READY;
+
+      return HAL_ERROR;
+    }
+  }
+  else
+  {
+    return HAL_BUSY;
+  }
+}
+
+/**
+  * @brief Pause the DMA Transfer.
+  * @param  husart USART handle.
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_USART_DMAPause(USART_HandleTypeDef *husart)
+{
+  const HAL_USART_StateTypeDef state = husart->State;
+
+  /* Process Locked */
+  __HAL_LOCK(husart);
+
+  if ((HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAT)) &&
+      (state == HAL_USART_STATE_BUSY_TX))
+  {
+    /* Disable the USART DMA Tx request */
+    CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAT);
+  }
+  else if ((state == HAL_USART_STATE_BUSY_RX) ||
+           (state == HAL_USART_STATE_BUSY_TX_RX))
+  {
+    if (HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAT))
+    {
+      /* Disable the USART DMA Tx request */
+      CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAT);
+    }
+    if (HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAR))
+    {
+      /* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */
+      CLEAR_BIT(husart->Instance->CR1, USART_CR1_PEIE);
+      CLEAR_BIT(husart->Instance->CR3, USART_CR3_EIE);
+
+      /* Disable the USART DMA Rx request */
+      CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAR);
+    }
+  }
+  else
+  {
+    /* Nothing to do */
+  }
+
+  /* Process Unlocked */
+  __HAL_UNLOCK(husart);
+
+  return HAL_OK;
+}
+
+/**
+  * @brief Resume the DMA Transfer.
+  * @param  husart USART handle.
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_USART_DMAResume(USART_HandleTypeDef *husart)
+{
+  const HAL_USART_StateTypeDef state = husart->State;
+
+  /* Process Locked */
+  __HAL_LOCK(husart);
+
+  if (state == HAL_USART_STATE_BUSY_TX)
+  {
+    /* Enable the USART DMA Tx request */
+    SET_BIT(husart->Instance->CR3, USART_CR3_DMAT);
+  }
+  else if ((state == HAL_USART_STATE_BUSY_RX) ||
+           (state == HAL_USART_STATE_BUSY_TX_RX))
+  {
+    /* Clear the Overrun flag before resuming the Rx transfer*/
+    __HAL_USART_CLEAR_FLAG(husart, USART_CLEAR_OREF);
+
+    /* Re-enable PE and ERR (Frame error, noise error, overrun error) interrupts */
+    if (husart->Init.Parity != USART_PARITY_NONE)
+    {
+      SET_BIT(husart->Instance->CR1, USART_CR1_PEIE);
+    }
+    SET_BIT(husart->Instance->CR3, USART_CR3_EIE);
+
+    /* Enable the USART DMA Rx request  before the DMA Tx request */
+    SET_BIT(husart->Instance->CR3, USART_CR3_DMAR);
+
+    /* Enable the USART DMA Tx request */
+    SET_BIT(husart->Instance->CR3, USART_CR3_DMAT);
+  }
+  else
+  {
+    /* Nothing to do */
+  }
+
+  /* Process Unlocked */
+  __HAL_UNLOCK(husart);
+
+  return HAL_OK;
+}
+
+/**
+  * @brief Stop the DMA Transfer.
+  * @param  husart USART handle.
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_USART_DMAStop(USART_HandleTypeDef *husart)
+{
+  /* The Lock is not implemented on this API to allow the user application
+     to call the HAL USART API under callbacks HAL_USART_TxCpltCallback() / HAL_USART_RxCpltCallback() /
+     HAL_USART_TxHalfCpltCallback / HAL_USART_RxHalfCpltCallback:
+     indeed, when HAL_DMA_Abort() API is called, the DMA TX/RX Transfer or Half Transfer complete
+     interrupt is generated if the DMA transfer interruption occurs at the middle or at the end of
+     the stream and the corresponding call back is executed. */
+
+  /* Disable the USART Tx/Rx DMA requests */
+  CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAT);
+  CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAR);
+
+  /* Abort the USART DMA tx channel */
+  if (husart->hdmatx != NULL)
+  {
+    if (HAL_DMA_Abort(husart->hdmatx) != HAL_OK)
+    {
+      if (HAL_DMA_GetError(husart->hdmatx) == HAL_DMA_ERROR_TIMEOUT)
+      {
+        /* Set error code to DMA */
+        husart->ErrorCode = HAL_USART_ERROR_DMA;
+
+        return HAL_TIMEOUT;
+      }
+    }
+  }
+  /* Abort the USART DMA rx channel */
+  if (husart->hdmarx != NULL)
+  {
+    if (HAL_DMA_Abort(husart->hdmarx) != HAL_OK)
+    {
+      if (HAL_DMA_GetError(husart->hdmarx) == HAL_DMA_ERROR_TIMEOUT)
+      {
+        /* Set error code to DMA */
+        husart->ErrorCode = HAL_USART_ERROR_DMA;
+
+        return HAL_TIMEOUT;
+      }
+    }
+  }
+
+  USART_EndTransfer(husart);
+  husart->State = HAL_USART_STATE_READY;
+
+  return HAL_OK;
+}
+
+/**
+  * @brief  Abort ongoing transfers (blocking mode).
+  * @param  husart USART handle.
+  * @note   This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
+  *         This procedure performs following operations :
+  *           - Disable USART Interrupts (Tx and Rx)
+  *           - Disable the DMA transfer in the peripheral register (if enabled)
+  *           - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode)
+  *           - Set handle State to READY
+  * @note   This procedure is executed in blocking mode : when exiting function, Abort is considered as completed.
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_USART_Abort(USART_HandleTypeDef *husart)
+{
+  /* Disable TXEIE, TCIE, RXNE, RXFT, TXFT, PE and ERR (Frame error, noise error, overrun error) interrupts */
+  CLEAR_BIT(husart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE | USART_CR1_TXEIE_TXFNFIE |
+                                    USART_CR1_TCIE));
+  CLEAR_BIT(husart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE | USART_CR3_TXFTIE));
+
+  /* Abort the USART DMA Tx channel if enabled */
+  if (HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAT))
+  {
+    /* Disable the USART DMA Tx request if enabled */
+    CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAT);
+
+    /* Abort the USART DMA Tx channel : use blocking DMA Abort API (no callback) */
+    if (husart->hdmatx != NULL)
+    {
+      /* Set the USART DMA Abort callback to Null.
+         No call back execution at end of DMA abort procedure */
+      husart->hdmatx->XferAbortCallback = NULL;
+
+      if (HAL_DMA_Abort(husart->hdmatx) != HAL_OK)
+      {
+        if (HAL_DMA_GetError(husart->hdmatx) == HAL_DMA_ERROR_TIMEOUT)
+        {
+          /* Set error code to DMA */
+          husart->ErrorCode = HAL_USART_ERROR_DMA;
+
+          return HAL_TIMEOUT;
+        }
+      }
+    }
+  }
+
+  /* Abort the USART DMA Rx channel if enabled */
+  if (HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAR))
+  {
+    /* Disable the USART DMA Rx request if enabled */
+    CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAR);
+
+    /* Abort the USART DMA Rx channel : use blocking DMA Abort API (no callback) */
+    if (husart->hdmarx != NULL)
+    {
+      /* Set the USART DMA Abort callback to Null.
+         No call back execution at end of DMA abort procedure */
+      husart->hdmarx->XferAbortCallback = NULL;
+
+      if (HAL_DMA_Abort(husart->hdmarx) != HAL_OK)
+      {
+        if (HAL_DMA_GetError(husart->hdmarx) == HAL_DMA_ERROR_TIMEOUT)
+        {
+          /* Set error code to DMA */
+          husart->ErrorCode = HAL_USART_ERROR_DMA;
+
+          return HAL_TIMEOUT;
+        }
+      }
+    }
+  }
+
+  /* Reset Tx and Rx transfer counters */
+  husart->TxXferCount = 0U;
+  husart->RxXferCount = 0U;
+
+  /* Clear the Error flags in the ICR register */
+  __HAL_USART_CLEAR_FLAG(husart, USART_CLEAR_OREF | USART_CLEAR_NEF | USART_CLEAR_PEF | USART_CLEAR_FEF);
+
+  /* Flush the whole TX FIFO (if needed) */
+  if (husart->FifoMode == USART_FIFOMODE_ENABLE)
+  {
+    __HAL_USART_SEND_REQ(husart, USART_TXDATA_FLUSH_REQUEST);
+  }
+
+  /* Discard the received data */
+  __HAL_USART_SEND_REQ(husart, USART_RXDATA_FLUSH_REQUEST);
+
+  /* Restore husart->State to Ready */
+  husart->State  = HAL_USART_STATE_READY;
+
+  /* Reset Handle ErrorCode to No Error */
+  husart->ErrorCode = HAL_USART_ERROR_NONE;
+
+  return HAL_OK;
+}
+
+/**
+  * @brief  Abort ongoing transfers (Interrupt mode).
+  * @param  husart USART handle.
+  * @note   This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
+  *         This procedure performs following operations :
+  *           - Disable USART Interrupts (Tx and Rx)
+  *           - Disable the DMA transfer in the peripheral register (if enabled)
+  *           - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode)
+  *           - Set handle State to READY
+  *           - At abort completion, call user abort complete callback
+  * @note   This procedure is executed in Interrupt mode, meaning that abort procedure could be
+  *         considered as completed only when user abort complete callback is executed (not when exiting function).
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_USART_Abort_IT(USART_HandleTypeDef *husart)
+{
+  uint32_t abortcplt = 1U;
+
+  /* Disable TXEIE, TCIE, RXNE, RXFT, TXFT, PE and ERR (Frame error, noise error, overrun error) interrupts */
+  CLEAR_BIT(husart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE | USART_CR1_TXEIE_TXFNFIE |
+                                    USART_CR1_TCIE));
+  CLEAR_BIT(husart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE | USART_CR3_TXFTIE));
+
+  /* If DMA Tx and/or DMA Rx Handles are associated to USART Handle, DMA Abort complete callbacks should be initialised
+     before any call to DMA Abort functions */
+  /* DMA Tx Handle is valid */
+  if (husart->hdmatx != NULL)
+  {
+    /* Set DMA Abort Complete callback if USART DMA Tx request if enabled.
+       Otherwise, set it to NULL */
+    if (HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAT))
+    {
+      husart->hdmatx->XferAbortCallback = USART_DMATxAbortCallback;
+    }
+    else
+    {
+      husart->hdmatx->XferAbortCallback = NULL;
+    }
+  }
+  /* DMA Rx Handle is valid */
+  if (husart->hdmarx != NULL)
+  {
+    /* Set DMA Abort Complete callback if USART DMA Rx request if enabled.
+       Otherwise, set it to NULL */
+    if (HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAR))
+    {
+      husart->hdmarx->XferAbortCallback = USART_DMARxAbortCallback;
+    }
+    else
+    {
+      husart->hdmarx->XferAbortCallback = NULL;
+    }
+  }
+
+  /* Abort the USART DMA Tx channel if enabled */
+  if (HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAT))
+  {
+    /* Disable DMA Tx at USART level */
+    CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAT);
+
+    /* Abort the USART DMA Tx channel : use non blocking DMA Abort API (callback) */
+    if (husart->hdmatx != NULL)
+    {
+      /* USART Tx DMA Abort callback has already been initialised :
+         will lead to call HAL_USART_AbortCpltCallback() at end of DMA abort procedure */
+
+      /* Abort DMA TX */
+      if (HAL_DMA_Abort_IT(husart->hdmatx) != HAL_OK)
+      {
+        husart->hdmatx->XferAbortCallback = NULL;
+      }
+      else
+      {
+        abortcplt = 0U;
+      }
+    }
+  }
+
+  /* Abort the USART DMA Rx channel if enabled */
+  if (HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAR))
+  {
+    /* Disable the USART DMA Rx request if enabled */
+    CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAR);
+
+    /* Abort the USART DMA Rx channel : use non blocking DMA Abort API (callback) */
+    if (husart->hdmarx != NULL)
+    {
+      /* USART Rx DMA Abort callback has already been initialised :
+         will lead to call HAL_USART_AbortCpltCallback() at end of DMA abort procedure */
+
+      /* Abort DMA RX */
+      if (HAL_DMA_Abort_IT(husart->hdmarx) != HAL_OK)
+      {
+        husart->hdmarx->XferAbortCallback = NULL;
+        abortcplt = 1U;
+      }
+      else
+      {
+        abortcplt = 0U;
+      }
+    }
+  }
+
+  /* if no DMA abort complete callback execution is required => call user Abort Complete callback */
+  if (abortcplt == 1U)
+  {
+    /* Reset Tx and Rx transfer counters */
+    husart->TxXferCount = 0U;
+    husart->RxXferCount = 0U;
+
+    /* Reset errorCode */
+    husart->ErrorCode = HAL_USART_ERROR_NONE;
+
+    /* Clear the Error flags in the ICR register */
+    __HAL_USART_CLEAR_FLAG(husart, USART_CLEAR_OREF | USART_CLEAR_NEF | USART_CLEAR_PEF | USART_CLEAR_FEF);
+
+    /* Flush the whole TX FIFO (if needed) */
+    if (husart->FifoMode == USART_FIFOMODE_ENABLE)
+    {
+      __HAL_USART_SEND_REQ(husart, USART_TXDATA_FLUSH_REQUEST);
+    }
+
+    /* Discard the received data */
+    __HAL_USART_SEND_REQ(husart, USART_RXDATA_FLUSH_REQUEST);
+
+    /* Restore husart->State to Ready */
+    husart->State  = HAL_USART_STATE_READY;
+
+    /* As no DMA to be aborted, call directly user Abort complete callback */
+#if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
+    /* Call registered Abort Complete Callback */
+    husart->AbortCpltCallback(husart);
+#else
+    /* Call legacy weak Abort Complete Callback */
+    HAL_USART_AbortCpltCallback(husart);
+#endif /* USE_HAL_USART_REGISTER_CALLBACKS */
+  }
+
+  return HAL_OK;
+}
+
+/**
+  * @brief  Handle USART interrupt request.
+  * @param  husart USART handle.
+  * @retval None
+  */
+void HAL_USART_IRQHandler(USART_HandleTypeDef *husart)
+{
+  uint32_t isrflags   = READ_REG(husart->Instance->ISR);
+  uint32_t cr1its     = READ_REG(husart->Instance->CR1);
+  uint32_t cr3its     = READ_REG(husart->Instance->CR3);
+
+  uint32_t errorflags;
+  uint32_t errorcode;
+
+  /* If no error occurs */
+  errorflags = (isrflags & (uint32_t)(USART_ISR_PE | USART_ISR_FE | USART_ISR_ORE | USART_ISR_NE | USART_ISR_RTOF |
+                                      USART_ISR_UDR));
+  if (errorflags == 0U)
+  {
+    /* USART in mode Receiver ---------------------------------------------------*/
+    if (((isrflags & USART_ISR_RXNE_RXFNE) != 0U)
+        && (((cr1its & USART_CR1_RXNEIE_RXFNEIE) != 0U)
+            || ((cr3its & USART_CR3_RXFTIE) != 0U)))
+    {
+      if (husart->RxISR != NULL)
+      {
+        husart->RxISR(husart);
+      }
+      return;
+    }
+  }
+
+  /* If some errors occur */
+  if ((errorflags != 0U)
+      && (((cr3its & (USART_CR3_RXFTIE | USART_CR3_EIE)) != 0U)
+          || ((cr1its & (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE)) != 0U)))
+  {
+    /* USART parity error interrupt occurred -------------------------------------*/
+    if (((isrflags & USART_ISR_PE) != 0U) && ((cr1its & USART_CR1_PEIE) != 0U))
+    {
+      __HAL_USART_CLEAR_IT(husart, USART_CLEAR_PEF);
+
+      husart->ErrorCode |= HAL_USART_ERROR_PE;
+    }
+
+    /* USART frame error interrupt occurred --------------------------------------*/
+    if (((isrflags & USART_ISR_FE) != 0U) && ((cr3its & USART_CR3_EIE) != 0U))
+    {
+      __HAL_USART_CLEAR_IT(husart, USART_CLEAR_FEF);
+
+      husart->ErrorCode |= HAL_USART_ERROR_FE;
+    }
+
+    /* USART noise error interrupt occurred --------------------------------------*/
+    if (((isrflags & USART_ISR_NE) != 0U) && ((cr3its & USART_CR3_EIE) != 0U))
+    {
+      __HAL_USART_CLEAR_IT(husart, USART_CLEAR_NEF);
+
+      husart->ErrorCode |= HAL_USART_ERROR_NE;
+    }
+
+    /* USART Over-Run interrupt occurred -----------------------------------------*/
+    if (((isrflags & USART_ISR_ORE) != 0U)
+        && (((cr1its & USART_CR1_RXNEIE_RXFNEIE) != 0U) ||
+            ((cr3its & (USART_CR3_RXFTIE | USART_CR3_EIE)) != 0U)))
+    {
+      __HAL_USART_CLEAR_IT(husart, USART_CLEAR_OREF);
+
+      husart->ErrorCode |= HAL_USART_ERROR_ORE;
+    }
+
+    /* USART Receiver Timeout interrupt occurred ---------------------------------*/
+    if (((isrflags & USART_ISR_RTOF) != 0U) && ((cr1its & USART_CR1_RTOIE) != 0U))
+    {
+      __HAL_USART_CLEAR_IT(husart, USART_CLEAR_RTOF);
+
+      husart->ErrorCode |= HAL_USART_ERROR_RTO;
+    }
+
+    /* USART SPI slave underrun error interrupt occurred -------------------------*/
+    if (((isrflags & USART_ISR_UDR) != 0U) && ((cr3its & USART_CR3_EIE) != 0U))
+    {
+      /* Ignore SPI slave underrun errors when reception is going on */
+      if (husart->State == HAL_USART_STATE_BUSY_RX)
+      {
+        __HAL_USART_CLEAR_UDRFLAG(husart);
+        return;
+      }
+      else
+      {
+        __HAL_USART_CLEAR_UDRFLAG(husart);
+        husart->ErrorCode |= HAL_USART_ERROR_UDR;
+      }
+    }
+
+    /* Call USART Error Call back function if need be --------------------------*/
+    if (husart->ErrorCode != HAL_USART_ERROR_NONE)
+    {
+      /* USART in mode Receiver ---------------------------------------------------*/
+      if (((isrflags & USART_ISR_RXNE_RXFNE) != 0U)
+          && (((cr1its & USART_CR1_RXNEIE_RXFNEIE) != 0U)
+              || ((cr3its & USART_CR3_RXFTIE) != 0U)))
+      {
+        if (husart->RxISR != NULL)
+        {
+          husart->RxISR(husart);
+        }
+      }
+
+      /* If Overrun error occurs, or if any error occurs in DMA mode reception,
+         consider error as blocking */
+      errorcode = husart->ErrorCode & HAL_USART_ERROR_ORE;
+      if ((HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAR)) ||
+          (errorcode != 0U))
+      {
+        /* Blocking error : transfer is aborted
+           Set the USART state ready to be able to start again the process,
+           Disable Interrupts, and disable DMA requests, if ongoing */
+        USART_EndTransfer(husart);
+
+        /* Abort the USART DMA Rx channel if enabled */
+        if (HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAR))
+        {
+          /* Disable the USART DMA Rx request if enabled */
+          CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAR | USART_CR3_DMAR);
+
+          /* Abort the USART DMA Tx channel */
+          if (husart->hdmatx != NULL)
+          {
+            /* Set the USART Tx DMA Abort callback to NULL : no callback
+               executed at end of DMA abort procedure */
+            husart->hdmatx->XferAbortCallback = NULL;
+
+            /* Abort DMA TX */
+            (void)HAL_DMA_Abort_IT(husart->hdmatx);
+          }
+
+          /* Abort the USART DMA Rx channel */
+          if (husart->hdmarx != NULL)
+          {
+            /* Set the USART Rx DMA Abort callback :
+               will lead to call HAL_USART_ErrorCallback() at end of DMA abort procedure */
+            husart->hdmarx->XferAbortCallback = USART_DMAAbortOnError;
+
+            /* Abort DMA RX */
+            if (HAL_DMA_Abort_IT(husart->hdmarx) != HAL_OK)
+            {
+              /* Call Directly husart->hdmarx->XferAbortCallback function in case of error */
+              husart->hdmarx->XferAbortCallback(husart->hdmarx);
+            }
+          }
+          else
+          {
+            /* Call user error callback */
+#if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
+            /* Call registered Error Callback */
+            husart->ErrorCallback(husart);
+#else
+            /* Call legacy weak Error Callback */
+            HAL_USART_ErrorCallback(husart);
+#endif /* USE_HAL_USART_REGISTER_CALLBACKS */
+          }
+        }
+        else
+        {
+          /* Call user error callback */
+#if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
+          /* Call registered Error Callback */
+          husart->ErrorCallback(husart);
+#else
+          /* Call legacy weak Error Callback */
+          HAL_USART_ErrorCallback(husart);
+#endif /* USE_HAL_USART_REGISTER_CALLBACKS */
+        }
+      }
+      else
+      {
+        /* Non Blocking error : transfer could go on.
+           Error is notified to user through user error callback */
+#if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
+        /* Call registered Error Callback */
+        husart->ErrorCallback(husart);
+#else
+        /* Call legacy weak Error Callback */
+        HAL_USART_ErrorCallback(husart);
+#endif /* USE_HAL_USART_REGISTER_CALLBACKS */
+        husart->ErrorCode = HAL_USART_ERROR_NONE;
+      }
+    }
+    return;
+
+  } /* End if some error occurs */
+
+
+  /* USART in mode Transmitter ------------------------------------------------*/
+  if (((isrflags & USART_ISR_TXE_TXFNF) != 0U)
+      && (((cr1its & USART_CR1_TXEIE_TXFNFIE) != 0U)
+          || ((cr3its & USART_CR3_TXFTIE) != 0U)))
+  {
+    if (husart->TxISR != NULL)
+    {
+      husart->TxISR(husart);
+    }
+    return;
+  }
+
+  /* USART in mode Transmitter (transmission end) -----------------------------*/
+  if (((isrflags & USART_ISR_TC) != 0U) && ((cr1its & USART_CR1_TCIE) != 0U))
+  {
+    USART_EndTransmit_IT(husart);
+    return;
+  }
+
+  /* USART TX Fifo Empty occurred ----------------------------------------------*/
+  if (((isrflags & USART_ISR_TXFE) != 0U) && ((cr1its & USART_CR1_TXFEIE) != 0U))
+  {
+#if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
+    /* Call registered Tx Fifo Empty Callback */
+    husart->TxFifoEmptyCallback(husart);
+#else
+    /* Call legacy weak Tx Fifo Empty Callback */
+    HAL_USARTEx_TxFifoEmptyCallback(husart);
+#endif /* USE_HAL_USART_REGISTER_CALLBACKS */
+    return;
+  }
+
+  /* USART RX Fifo Full occurred ----------------------------------------------*/
+  if (((isrflags & USART_ISR_RXFF) != 0U) && ((cr1its & USART_CR1_RXFFIE) != 0U))
+  {
+#if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
+    /* Call registered Rx Fifo Full Callback */
+    husart->RxFifoFullCallback(husart);
+#else
+    /* Call legacy weak Rx Fifo Full Callback */
+    HAL_USARTEx_RxFifoFullCallback(husart);
+#endif /* USE_HAL_USART_REGISTER_CALLBACKS */
+    return;
+  }
+}
+
+/**
+  * @brief Tx Transfer completed callback.
+  * @param husart USART handle.
+  * @retval None
+  */
+__weak void HAL_USART_TxCpltCallback(USART_HandleTypeDef *husart)
+{
+  /* Prevent unused argument(s) compilation warning */
+  UNUSED(husart);
+
+  /* NOTE : This function should not be modified, when the callback is needed,
+            the HAL_USART_TxCpltCallback can be implemented in the user file.
+   */
+}
+
+/**
+  * @brief  Tx Half Transfer completed callback.
+  * @param husart USART handle.
+  * @retval None
+  */
+__weak void HAL_USART_TxHalfCpltCallback(USART_HandleTypeDef *husart)
+{
+  /* Prevent unused argument(s) compilation warning */
+  UNUSED(husart);
+
+  /* NOTE: This function should not be modified, when the callback is needed,
+           the HAL_USART_TxHalfCpltCallback can be implemented in the user file.
+   */
+}
+
+/**
+  * @brief  Rx Transfer completed callback.
+  * @param husart USART handle.
+  * @retval None
+  */
+__weak void HAL_USART_RxCpltCallback(USART_HandleTypeDef *husart)
+{
+  /* Prevent unused argument(s) compilation warning */
+  UNUSED(husart);
+
+  /* NOTE: This function should not be modified, when the callback is needed,
+           the HAL_USART_RxCpltCallback can be implemented in the user file.
+   */
+}
+
+/**
+  * @brief Rx Half Transfer completed callback.
+  * @param husart USART handle.
+  * @retval None
+  */
+__weak void HAL_USART_RxHalfCpltCallback(USART_HandleTypeDef *husart)
+{
+  /* Prevent unused argument(s) compilation warning */
+  UNUSED(husart);
+
+  /* NOTE : This function should not be modified, when the callback is needed,
+            the HAL_USART_RxHalfCpltCallback can be implemented in the user file
+   */
+}
+
+/**
+  * @brief Tx/Rx Transfers completed callback for the non-blocking process.
+  * @param husart USART handle.
+  * @retval None
+  */
+__weak void HAL_USART_TxRxCpltCallback(USART_HandleTypeDef *husart)
+{
+  /* Prevent unused argument(s) compilation warning */
+  UNUSED(husart);
+
+  /* NOTE : This function should not be modified, when the callback is needed,
+            the HAL_USART_TxRxCpltCallback can be implemented in the user file
+   */
+}
+
+/**
+  * @brief USART error callback.
+  * @param husart USART handle.
+  * @retval None
+  */
+__weak void HAL_USART_ErrorCallback(USART_HandleTypeDef *husart)
+{
+  /* Prevent unused argument(s) compilation warning */
+  UNUSED(husart);
+
+  /* NOTE : This function should not be modified, when the callback is needed,
+            the HAL_USART_ErrorCallback can be implemented in the user file.
+   */
+}
+
+/**
+  * @brief  USART Abort Complete callback.
+  * @param  husart USART handle.
+  * @retval None
+  */
+__weak void HAL_USART_AbortCpltCallback(USART_HandleTypeDef *husart)
+{
+  /* Prevent unused argument(s) compilation warning */
+  UNUSED(husart);
+
+  /* NOTE : This function should not be modified, when the callback is needed,
+            the HAL_USART_AbortCpltCallback can be implemented in the user file.
+   */
+}
+
+/**
+  * @}
+  */
+
+/** @defgroup USART_Exported_Functions_Group4 Peripheral State and Error functions
+  *  @brief   USART Peripheral State and Error functions
+  *
+@verbatim
+  ==============================================================================
+            ##### Peripheral State and Error functions #####
+  ==============================================================================
+    [..]
+    This subsection provides functions allowing to :
+      (+) Return the USART handle state
+      (+) Return the USART handle error code
+
+@endverbatim
+  * @{
+  */
+
+
+/**
+  * @brief Return the USART handle state.
+  * @param husart pointer to a USART_HandleTypeDef structure that contains
+  *              the configuration information for the specified USART.
+  * @retval USART handle state
+  */
+HAL_USART_StateTypeDef HAL_USART_GetState(const USART_HandleTypeDef *husart)
+{
+  return husart->State;
+}
+
+/**
+  * @brief Return the USART error code.
+  * @param husart pointer to a USART_HandleTypeDef structure that contains
+  *              the configuration information for the specified USART.
+  * @retval USART handle Error Code
+  */
+uint32_t HAL_USART_GetError(const USART_HandleTypeDef *husart)
+{
+  return husart->ErrorCode;
+}
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/** @defgroup USART_Private_Functions USART Private Functions
+  * @{
+  */
+
+/**
+  * @brief  Initialize the callbacks to their default values.
+  * @param  husart USART handle.
+  * @retval none
+  */
+#if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
+void USART_InitCallbacksToDefault(USART_HandleTypeDef *husart)
+{
+  /* Init the USART Callback settings */
+  husart->TxHalfCpltCallback        = HAL_USART_TxHalfCpltCallback;        /* Legacy weak TxHalfCpltCallback        */
+  husart->TxCpltCallback            = HAL_USART_TxCpltCallback;            /* Legacy weak TxCpltCallback            */
+  husart->RxHalfCpltCallback        = HAL_USART_RxHalfCpltCallback;        /* Legacy weak RxHalfCpltCallback        */
+  husart->RxCpltCallback            = HAL_USART_RxCpltCallback;            /* Legacy weak RxCpltCallback            */
+  husart->TxRxCpltCallback          = HAL_USART_TxRxCpltCallback;          /* Legacy weak TxRxCpltCallback          */
+  husart->ErrorCallback             = HAL_USART_ErrorCallback;             /* Legacy weak ErrorCallback             */
+  husart->AbortCpltCallback         = HAL_USART_AbortCpltCallback;         /* Legacy weak AbortCpltCallback         */
+  husart->RxFifoFullCallback        = HAL_USARTEx_RxFifoFullCallback;      /* Legacy weak RxFifoFullCallback        */
+  husart->TxFifoEmptyCallback       = HAL_USARTEx_TxFifoEmptyCallback;     /* Legacy weak TxFifoEmptyCallback       */
+}
+#endif /* USE_HAL_USART_REGISTER_CALLBACKS */
+
+/**
+  * @brief  End ongoing transfer on USART peripheral (following error detection or Transfer completion).
+  * @param  husart USART handle.
+  * @retval None
+  */
+static void USART_EndTransfer(USART_HandleTypeDef *husart)
+{
+  /* Disable TXEIE, TCIE, RXNE, RXFT, TXFT, PE and ERR (Frame error, noise error, overrun error) interrupts */
+  CLEAR_BIT(husart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE | USART_CR1_TXEIE_TXFNFIE |
+                                    USART_CR1_TCIE));
+  CLEAR_BIT(husart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE | USART_CR3_TXFTIE));
+
+  /* At end of process, restore husart->State to Ready */
+  husart->State = HAL_USART_STATE_READY;
+}
+
+/**
+  * @brief DMA USART transmit process complete callback.
+  * @param  hdma DMA handle.
+  * @retval None
+  */
+static void USART_DMATransmitCplt(DMA_HandleTypeDef *hdma)
+{
+  USART_HandleTypeDef *husart = (USART_HandleTypeDef *)(hdma->Parent);
+
+  /* DMA Normal mode */
+  if (HAL_IS_BIT_CLR(hdma->Instance->CCR, DMA_CCR_CIRC))
+  {
+    husart->TxXferCount = 0U;
+
+    if (husart->State == HAL_USART_STATE_BUSY_TX)
+    {
+      /* Disable the DMA transfer for transmit request by resetting the DMAT bit
+         in the USART CR3 register */
+      CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAT);
+
+      /* Enable the USART Transmit Complete Interrupt */
+      __HAL_USART_ENABLE_IT(husart, USART_IT_TC);
+    }
+  }
+  /* DMA Circular mode */
+  else
+  {
+    if (husart->State == HAL_USART_STATE_BUSY_TX)
+    {
+#if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
+      /* Call registered Tx Complete Callback */
+      husart->TxCpltCallback(husart);
+#else
+      /* Call legacy weak Tx Complete Callback */
+      HAL_USART_TxCpltCallback(husart);
+#endif /* USE_HAL_USART_REGISTER_CALLBACKS */
+    }
+  }
+}
+
+/**
+  * @brief DMA USART transmit process half complete callback.
+  * @param  hdma DMA handle.
+  * @retval None
+  */
+static void USART_DMATxHalfCplt(DMA_HandleTypeDef *hdma)
+{
+  USART_HandleTypeDef *husart = (USART_HandleTypeDef *)(hdma->Parent);
+
+#if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
+  /* Call registered Tx Half Complete Callback */
+  husart->TxHalfCpltCallback(husart);
+#else
+  /* Call legacy weak Tx Half Complete Callback */
+  HAL_USART_TxHalfCpltCallback(husart);
+#endif /* USE_HAL_USART_REGISTER_CALLBACKS */
+}
+
+/**
+  * @brief DMA USART receive process complete callback.
+  * @param  hdma DMA handle.
+  * @retval None
+  */
+static void USART_DMAReceiveCplt(DMA_HandleTypeDef *hdma)
+{
+  USART_HandleTypeDef *husart = (USART_HandleTypeDef *)(hdma->Parent);
+
+  /* DMA Normal mode */
+  if (HAL_IS_BIT_CLR(hdma->Instance->CCR, DMA_CCR_CIRC))
+  {
+    husart->RxXferCount = 0U;
+
+    /* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */
+    CLEAR_BIT(husart->Instance->CR1, USART_CR1_PEIE);
+    CLEAR_BIT(husart->Instance->CR3, USART_CR3_EIE);
+
+    /* Disable the DMA RX transfer for the receiver request by resetting the DMAR bit
+       in USART CR3 register */
+    CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAR);
+    /* similarly, disable the DMA TX transfer that was started to provide the
+       clock to the slave device */
+    CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAT);
+
+    if (husart->State == HAL_USART_STATE_BUSY_RX)
+    {
+#if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
+      /* Call registered Rx Complete Callback */
+      husart->RxCpltCallback(husart);
+#else
+      /* Call legacy weak Rx Complete Callback */
+      HAL_USART_RxCpltCallback(husart);
+#endif /* USE_HAL_USART_REGISTER_CALLBACKS */
+    }
+    /* The USART state is HAL_USART_STATE_BUSY_TX_RX */
+    else
+    {
+#if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
+      /* Call registered Tx Rx Complete Callback */
+      husart->TxRxCpltCallback(husart);
+#else
+      /* Call legacy weak Tx Rx Complete Callback */
+      HAL_USART_TxRxCpltCallback(husart);
+#endif /* USE_HAL_USART_REGISTER_CALLBACKS */
+    }
+    husart->State = HAL_USART_STATE_READY;
+  }
+  /* DMA circular mode */
+  else
+  {
+    if (husart->State == HAL_USART_STATE_BUSY_RX)
+    {
+#if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
+      /* Call registered Rx Complete Callback */
+      husart->RxCpltCallback(husart);
+#else
+      /* Call legacy weak Rx Complete Callback */
+      HAL_USART_RxCpltCallback(husart);
+#endif /* USE_HAL_USART_REGISTER_CALLBACKS */
+    }
+    /* The USART state is HAL_USART_STATE_BUSY_TX_RX */
+    else
+    {
+#if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
+      /* Call registered Tx Rx Complete Callback */
+      husart->TxRxCpltCallback(husart);
+#else
+      /* Call legacy weak Tx Rx Complete Callback */
+      HAL_USART_TxRxCpltCallback(husart);
+#endif /* USE_HAL_USART_REGISTER_CALLBACKS */
+    }
+  }
+}
+
+/**
+  * @brief DMA USART receive process half complete callback.
+  * @param  hdma DMA handle.
+  * @retval None
+  */
+static void USART_DMARxHalfCplt(DMA_HandleTypeDef *hdma)
+{
+  USART_HandleTypeDef *husart = (USART_HandleTypeDef *)(hdma->Parent);
+
+#if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
+  /* Call registered Rx Half Complete Callback */
+  husart->RxHalfCpltCallback(husart);
+#else
+  /* Call legacy weak Rx Half Complete Callback */
+  HAL_USART_RxHalfCpltCallback(husart);
+#endif /* USE_HAL_USART_REGISTER_CALLBACKS */
+}
+
+/**
+  * @brief DMA USART communication error callback.
+  * @param  hdma DMA handle.
+  * @retval None
+  */
+static void USART_DMAError(DMA_HandleTypeDef *hdma)
+{
+  USART_HandleTypeDef *husart = (USART_HandleTypeDef *)(hdma->Parent);
+
+  husart->RxXferCount = 0U;
+  husart->TxXferCount = 0U;
+  USART_EndTransfer(husart);
+
+  husart->ErrorCode |= HAL_USART_ERROR_DMA;
+  husart->State = HAL_USART_STATE_READY;
+
+#if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
+  /* Call registered Error Callback */
+  husart->ErrorCallback(husart);
+#else
+  /* Call legacy weak Error Callback */
+  HAL_USART_ErrorCallback(husart);
+#endif /* USE_HAL_USART_REGISTER_CALLBACKS */
+}
+
+/**
+  * @brief  DMA USART communication abort callback, when initiated by HAL services on Error
+  *         (To be called at end of DMA Abort procedure following error occurrence).
+  * @param  hdma DMA handle.
+  * @retval None
+  */
+static void USART_DMAAbortOnError(DMA_HandleTypeDef *hdma)
+{
+  USART_HandleTypeDef *husart = (USART_HandleTypeDef *)(hdma->Parent);
+  husart->RxXferCount = 0U;
+  husart->TxXferCount = 0U;
+
+#if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
+  /* Call registered Error Callback */
+  husart->ErrorCallback(husart);
+#else
+  /* Call legacy weak Error Callback */
+  HAL_USART_ErrorCallback(husart);
+#endif /* USE_HAL_USART_REGISTER_CALLBACKS */
+}
+
+/**
+  * @brief  DMA USART Tx communication abort callback, when initiated by user
+  *         (To be called at end of DMA Tx Abort procedure following user abort request).
+  * @note   When this callback is executed, User Abort complete call back is called only if no
+  *         Abort still ongoing for Rx DMA Handle.
+  * @param  hdma DMA handle.
+  * @retval None
+  */
+static void USART_DMATxAbortCallback(DMA_HandleTypeDef *hdma)
+{
+  USART_HandleTypeDef *husart = (USART_HandleTypeDef *)(hdma->Parent);
+
+  husart->hdmatx->XferAbortCallback = NULL;
+
+  /* Check if an Abort process is still ongoing */
+  if (husart->hdmarx != NULL)
+  {
+    if (husart->hdmarx->XferAbortCallback != NULL)
+    {
+      return;
+    }
+  }
+
+  /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */
+  husart->TxXferCount = 0U;
+  husart->RxXferCount = 0U;
+
+  /* Reset errorCode */
+  husart->ErrorCode = HAL_USART_ERROR_NONE;
+
+  /* Clear the Error flags in the ICR register */
+  __HAL_USART_CLEAR_FLAG(husart, USART_CLEAR_OREF | USART_CLEAR_NEF | USART_CLEAR_PEF | USART_CLEAR_FEF);
+
+  /* Restore husart->State to Ready */
+  husart->State = HAL_USART_STATE_READY;
+
+  /* Call user Abort complete callback */
+#if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
+  /* Call registered Abort Complete Callback */
+  husart->AbortCpltCallback(husart);
+#else
+  /* Call legacy weak Abort Complete Callback */
+  HAL_USART_AbortCpltCallback(husart);
+#endif /* USE_HAL_USART_REGISTER_CALLBACKS */
+
+}
+
+
+/**
+  * @brief  DMA USART Rx communication abort callback, when initiated by user
+  *         (To be called at end of DMA Rx Abort procedure following user abort request).
+  * @note   When this callback is executed, User Abort complete call back is called only if no
+  *         Abort still ongoing for Tx DMA Handle.
+  * @param  hdma DMA handle.
+  * @retval None
+  */
+static void USART_DMARxAbortCallback(DMA_HandleTypeDef *hdma)
+{
+  USART_HandleTypeDef *husart = (USART_HandleTypeDef *)(hdma->Parent);
+
+  husart->hdmarx->XferAbortCallback = NULL;
+
+  /* Check if an Abort process is still ongoing */
+  if (husart->hdmatx != NULL)
+  {
+    if (husart->hdmatx->XferAbortCallback != NULL)
+    {
+      return;
+    }
+  }
+
+  /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */
+  husart->TxXferCount = 0U;
+  husart->RxXferCount = 0U;
+
+  /* Reset errorCode */
+  husart->ErrorCode = HAL_USART_ERROR_NONE;
+
+  /* Clear the Error flags in the ICR register */
+  __HAL_USART_CLEAR_FLAG(husart, USART_CLEAR_OREF | USART_CLEAR_NEF | USART_CLEAR_PEF | USART_CLEAR_FEF);
+
+  /* Restore husart->State to Ready */
+  husart->State  = HAL_USART_STATE_READY;
+
+  /* Call user Abort complete callback */
+#if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
+  /* Call registered Abort Complete Callback */
+  husart->AbortCpltCallback(husart);
+#else
+  /* Call legacy weak Abort Complete Callback */
+  HAL_USART_AbortCpltCallback(husart);
+#endif /* USE_HAL_USART_REGISTER_CALLBACKS */
+}
+
+
+/**
+  * @brief  Handle USART Communication Timeout. It waits
+  *         until a flag is no longer in the specified status.
+  * @param  husart USART handle.
+  * @param  Flag Specifies the USART flag to check.
+  * @param  Status the actual Flag status (SET or RESET).
+  * @param  Tickstart Tick start value
+  * @param  Timeout timeout duration.
+  * @retval HAL status
+  */
+static HAL_StatusTypeDef USART_WaitOnFlagUntilTimeout(USART_HandleTypeDef *husart, uint32_t Flag, FlagStatus Status,
+                                                      uint32_t Tickstart, uint32_t Timeout)
+{
+  /* Wait until flag is set */
+  while ((__HAL_USART_GET_FLAG(husart, Flag) ? SET : RESET) == Status)
+  {
+    /* Check for the Timeout */
+    if (Timeout != HAL_MAX_DELAY)
+    {
+      if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U))
+      {
+        husart->State = HAL_USART_STATE_READY;
+
+        /* Process Unlocked */
+        __HAL_UNLOCK(husart);
+
+        return HAL_TIMEOUT;
+      }
+    }
+  }
+  return HAL_OK;
+}
+
+/**
+  * @brief Configure the USART peripheral.
+  * @param husart USART handle.
+  * @retval HAL status
+  */
+static HAL_StatusTypeDef USART_SetConfig(USART_HandleTypeDef *husart)
+{
+  uint32_t tmpreg;
+  USART_ClockSourceTypeDef clocksource;
+  HAL_StatusTypeDef ret                = HAL_OK;
+  uint16_t brrtemp;
+  uint32_t usartdiv                    = 0x00000000;
+  uint32_t pclk;
+
+  /* Check the parameters */
+  assert_param(IS_USART_POLARITY(husart->Init.CLKPolarity));
+  assert_param(IS_USART_PHASE(husart->Init.CLKPhase));
+  assert_param(IS_USART_LASTBIT(husart->Init.CLKLastBit));
+  assert_param(IS_USART_BAUDRATE(husart->Init.BaudRate));
+  assert_param(IS_USART_WORD_LENGTH(husart->Init.WordLength));
+  assert_param(IS_USART_STOPBITS(husart->Init.StopBits));
+  assert_param(IS_USART_PARITY(husart->Init.Parity));
+  assert_param(IS_USART_MODE(husart->Init.Mode));
+  assert_param(IS_USART_PRESCALER(husart->Init.ClockPrescaler));
+
+  /*-------------------------- USART CR1 Configuration -----------------------*/
+  /* Clear M, PCE, PS, TE and RE bits and configure
+  *  the USART Word Length, Parity and Mode:
+  *  set the M bits according to husart->Init.WordLength value
+  *  set PCE and PS bits according to husart->Init.Parity value
+  *  set TE and RE bits according to husart->Init.Mode value
+  *  force OVER8 to 1 to allow to reach the maximum speed (Fclock/8) */
+  tmpreg = (uint32_t)husart->Init.WordLength | husart->Init.Parity | husart->Init.Mode | USART_CR1_OVER8;
+  MODIFY_REG(husart->Instance->CR1, USART_CR1_FIELDS, tmpreg);
+
+  /*---------------------------- USART CR2 Configuration ---------------------*/
+  /* Clear and configure the USART Clock, CPOL, CPHA, LBCL STOP and SLVEN bits:
+   * set CPOL bit according to husart->Init.CLKPolarity value
+   * set CPHA bit according to husart->Init.CLKPhase value
+   * set LBCL bit according to husart->Init.CLKLastBit value (used in USART Synchronous SPI master mode only)
+   * set STOP[13:12] bits according to husart->Init.StopBits value */
+  tmpreg = (uint32_t)(USART_CLOCK_ENABLE);
+  tmpreg |= (uint32_t)husart->Init.CLKLastBit;
+  tmpreg |= ((uint32_t)husart->Init.CLKPolarity | (uint32_t)husart->Init.CLKPhase);
+  tmpreg |= (uint32_t)husart->Init.StopBits;
+  MODIFY_REG(husart->Instance->CR2, USART_CR2_FIELDS, tmpreg);
+
+  /*-------------------------- USART PRESC Configuration -----------------------*/
+  /* Configure
+   * - USART Clock Prescaler : set PRESCALER according to husart->Init.ClockPrescaler value */
+  MODIFY_REG(husart->Instance->PRESC, USART_PRESC_PRESCALER, husart->Init.ClockPrescaler);
+
+  /*-------------------------- USART BRR Configuration -----------------------*/
+  /* BRR is filled-up according to OVER8 bit setting which is forced to 1     */
+  USART_GETCLOCKSOURCE(husart, clocksource);
+
+  switch (clocksource)
+  {
+    case USART_CLOCKSOURCE_PCLK1:
+      pclk = HAL_RCC_GetPCLK1Freq();
+      usartdiv = (uint32_t)(USART_DIV_SAMPLING8(pclk, husart->Init.BaudRate, husart->Init.ClockPrescaler));
+      break;
+    case USART_CLOCKSOURCE_PCLK2:
+      pclk = HAL_RCC_GetPCLK2Freq();
+      usartdiv = (uint32_t)(USART_DIV_SAMPLING8(pclk, husart->Init.BaudRate, husart->Init.ClockPrescaler));
+      break;
+    case USART_CLOCKSOURCE_HSI:
+      usartdiv = (uint32_t)(USART_DIV_SAMPLING8(HSI_VALUE, husart->Init.BaudRate, husart->Init.ClockPrescaler));
+      break;
+    case USART_CLOCKSOURCE_SYSCLK:
+      pclk = HAL_RCC_GetSysClockFreq();
+      usartdiv = (uint32_t)(USART_DIV_SAMPLING8(pclk, husart->Init.BaudRate, husart->Init.ClockPrescaler));
+      break;
+    case USART_CLOCKSOURCE_LSE:
+      usartdiv = (uint32_t)(USART_DIV_SAMPLING8(LSE_VALUE, husart->Init.BaudRate, husart->Init.ClockPrescaler));
+      break;
+    default:
+      ret = HAL_ERROR;
+      break;
+  }
+
+  /* USARTDIV must be greater than or equal to 0d16 and smaller than or equal to ffff */
+  if ((usartdiv >= USART_BRR_MIN) && (usartdiv <= USART_BRR_MAX))
+  {
+    brrtemp = (uint16_t)(usartdiv & 0xFFF0U);
+    brrtemp |= (uint16_t)((usartdiv & (uint16_t)0x000FU) >> 1U);
+    husart->Instance->BRR = brrtemp;
+  }
+  else
+  {
+    ret = HAL_ERROR;
+  }
+
+  /* Initialize the number of data to process during RX/TX ISR execution */
+  husart->NbTxDataToProcess = 1U;
+  husart->NbRxDataToProcess = 1U;
+
+  /* Clear ISR function pointers */
+  husart->RxISR   = NULL;
+  husart->TxISR   = NULL;
+
+  return ret;
+}
+
+/**
+  * @brief Check the USART Idle State.
+  * @param husart USART handle.
+  * @retval HAL status
+  */
+static HAL_StatusTypeDef USART_CheckIdleState(USART_HandleTypeDef *husart)
+{
+  uint32_t tickstart;
+
+  /* Initialize the USART ErrorCode */
+  husart->ErrorCode = HAL_USART_ERROR_NONE;
+
+  /* Init tickstart for timeout management */
+  tickstart = HAL_GetTick();
+
+  /* Check if the Transmitter is enabled */
+  if ((husart->Instance->CR1 & USART_CR1_TE) == USART_CR1_TE)
+  {
+    /* Wait until TEACK flag is set */
+    if (USART_WaitOnFlagUntilTimeout(husart, USART_ISR_TEACK, RESET, tickstart, USART_TEACK_REACK_TIMEOUT) != HAL_OK)
+    {
+      /* Timeout occurred */
+      return HAL_TIMEOUT;
+    }
+  }
+  /* Check if the Receiver is enabled */
+  if ((husart->Instance->CR1 & USART_CR1_RE) == USART_CR1_RE)
+  {
+    /* Wait until REACK flag is set */
+    if (USART_WaitOnFlagUntilTimeout(husart, USART_ISR_REACK, RESET, tickstart, USART_TEACK_REACK_TIMEOUT) != HAL_OK)
+    {
+      /* Timeout occurred */
+      return HAL_TIMEOUT;
+    }
+  }
+
+  /* Initialize the USART state*/
+  husart->State = HAL_USART_STATE_READY;
+
+  /* Process Unlocked */
+  __HAL_UNLOCK(husart);
+
+  return HAL_OK;
+}
+
+/**
+  * @brief  Simplex send an amount of data in non-blocking mode.
+  * @note   Function called under interruption only, once
+  *         interruptions have been enabled by HAL_USART_Transmit_IT().
+  * @note   The USART errors are not managed to avoid the overrun error.
+  * @note   ISR function executed when FIFO mode is disabled and when the
+  *         data word length is less than 9 bits long.
+  * @param  husart USART handle.
+  * @retval None
+  */
+static void USART_TxISR_8BIT(USART_HandleTypeDef *husart)
+{
+  const HAL_USART_StateTypeDef state = husart->State;
+
+  /* Check that a Tx process is ongoing */
+  if ((state == HAL_USART_STATE_BUSY_TX) ||
+      (state == HAL_USART_STATE_BUSY_TX_RX))
+  {
+    if (husart->TxXferCount == 0U)
+    {
+      /* Disable the USART Transmit data register empty interrupt */
+      __HAL_USART_DISABLE_IT(husart, USART_IT_TXE);
+
+      /* Enable the USART Transmit Complete Interrupt */
+      __HAL_USART_ENABLE_IT(husart, USART_IT_TC);
+    }
+    else
+    {
+      husart->Instance->TDR = (uint8_t)(*husart->pTxBuffPtr & (uint8_t)0xFF);
+      husart->pTxBuffPtr++;
+      husart->TxXferCount--;
+    }
+  }
+}
+
+/**
+  * @brief  Simplex send an amount of data in non-blocking mode.
+  * @note   Function called under interruption only, once
+  *         interruptions have been enabled by HAL_USART_Transmit_IT().
+  * @note   The USART errors are not managed to avoid the overrun error.
+  * @note   ISR function executed when FIFO mode is disabled and when the
+  *         data word length is 9 bits long.
+  * @param  husart USART handle.
+  * @retval None
+  */
+static void USART_TxISR_16BIT(USART_HandleTypeDef *husart)
+{
+  const HAL_USART_StateTypeDef state = husart->State;
+  const uint16_t *tmp;
+
+  if ((state == HAL_USART_STATE_BUSY_TX) ||
+      (state == HAL_USART_STATE_BUSY_TX_RX))
+  {
+    if (husart->TxXferCount == 0U)
+    {
+      /* Disable the USART Transmit data register empty interrupt */
+      __HAL_USART_DISABLE_IT(husart, USART_IT_TXE);
+
+      /* Enable the USART Transmit Complete Interrupt */
+      __HAL_USART_ENABLE_IT(husart, USART_IT_TC);
+    }
+    else
+    {
+      tmp = (const uint16_t *) husart->pTxBuffPtr;
+      husart->Instance->TDR = (uint16_t)(*tmp & 0x01FFU);
+      husart->pTxBuffPtr += 2U;
+      husart->TxXferCount--;
+    }
+  }
+}
+
+/**
+  * @brief  Simplex send an amount of data in non-blocking mode.
+  * @note   Function called under interruption only, once
+  *         interruptions have been enabled by HAL_USART_Transmit_IT().
+  * @note   The USART errors are not managed to avoid the overrun error.
+  * @note   ISR function executed when FIFO mode is enabled and when the
+  *         data word length is less than 9 bits long.
+  * @param  husart USART handle.
+  * @retval None
+  */
+static void USART_TxISR_8BIT_FIFOEN(USART_HandleTypeDef *husart)
+{
+  const HAL_USART_StateTypeDef state = husart->State;
+  uint16_t  nb_tx_data;
+
+  /* Check that a Tx process is ongoing */
+  if ((state == HAL_USART_STATE_BUSY_TX) ||
+      (state == HAL_USART_STATE_BUSY_TX_RX))
+  {
+    for (nb_tx_data = husart->NbTxDataToProcess ; nb_tx_data > 0U ; nb_tx_data--)
+    {
+      if (husart->TxXferCount == 0U)
+      {
+        /* Disable the TX FIFO threshold interrupt */
+        __HAL_USART_DISABLE_IT(husart, USART_IT_TXFT);
+
+        /* Enable the USART Transmit Complete Interrupt */
+        __HAL_USART_ENABLE_IT(husart, USART_IT_TC);
+
+        break; /* force exit loop */
+      }
+      else if (__HAL_USART_GET_FLAG(husart, USART_FLAG_TXFNF) == SET)
+      {
+        husart->Instance->TDR = (uint8_t)(*husart->pTxBuffPtr & (uint8_t)0xFF);
+        husart->pTxBuffPtr++;
+        husart->TxXferCount--;
+      }
+      else
+      {
+        /* Nothing to do */
+      }
+    }
+  }
+}
+
+/**
+  * @brief  Simplex send an amount of data in non-blocking mode.
+  * @note   Function called under interruption only, once
+  *         interruptions have been enabled by HAL_USART_Transmit_IT().
+  * @note   The USART errors are not managed to avoid the overrun error.
+  * @note   ISR function executed when FIFO mode is enabled and when the
+  *         data word length is 9 bits long.
+  * @param  husart USART handle.
+  * @retval None
+  */
+static void USART_TxISR_16BIT_FIFOEN(USART_HandleTypeDef *husart)
+{
+  const HAL_USART_StateTypeDef state = husart->State;
+  const uint16_t *tmp;
+  uint16_t  nb_tx_data;
+
+  /* Check that a Tx process is ongoing */
+  if ((state == HAL_USART_STATE_BUSY_TX) ||
+      (state == HAL_USART_STATE_BUSY_TX_RX))
+  {
+    for (nb_tx_data = husart->NbTxDataToProcess ; nb_tx_data > 0U ; nb_tx_data--)
+    {
+      if (husart->TxXferCount == 0U)
+      {
+        /* Disable the TX FIFO threshold interrupt */
+        __HAL_USART_DISABLE_IT(husart, USART_IT_TXFT);
+
+        /* Enable the USART Transmit Complete Interrupt */
+        __HAL_USART_ENABLE_IT(husart, USART_IT_TC);
+
+        break; /* force exit loop */
+      }
+      else if (__HAL_USART_GET_FLAG(husart, USART_FLAG_TXFNF) == SET)
+      {
+        tmp = (const uint16_t *) husart->pTxBuffPtr;
+        husart->Instance->TDR = (uint16_t)(*tmp & 0x01FFU);
+        husart->pTxBuffPtr += 2U;
+        husart->TxXferCount--;
+      }
+      else
+      {
+        /* Nothing to do */
+      }
+    }
+  }
+}
+
+/**
+  * @brief  Wraps up transmission in non-blocking mode.
+  * @param  husart Pointer to a USART_HandleTypeDef structure that contains
+  *                the configuration information for the specified USART module.
+  * @retval None
+  */
+static void USART_EndTransmit_IT(USART_HandleTypeDef *husart)
+{
+  /* Disable the USART Transmit Complete Interrupt */
+  __HAL_USART_DISABLE_IT(husart, USART_IT_TC);
+
+  /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error) */
+  __HAL_USART_DISABLE_IT(husart, USART_IT_ERR);
+
+  /* Clear TxISR function pointer */
+  husart->TxISR = NULL;
+
+  if (husart->State == HAL_USART_STATE_BUSY_TX)
+  {
+    /* Clear overrun flag and discard the received data */
+    __HAL_USART_CLEAR_OREFLAG(husart);
+    __HAL_USART_SEND_REQ(husart, USART_RXDATA_FLUSH_REQUEST);
+
+    /* Tx process is completed, restore husart->State to Ready */
+    husart->State = HAL_USART_STATE_READY;
+
+#if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
+    /* Call registered Tx Complete Callback */
+    husart->TxCpltCallback(husart);
+#else
+    /* Call legacy weak Tx Complete Callback */
+    HAL_USART_TxCpltCallback(husart);
+#endif /* USE_HAL_USART_REGISTER_CALLBACKS */
+  }
+  else if (husart->RxXferCount == 0U)
+  {
+    /* TxRx process is completed, restore husart->State to Ready */
+    husart->State = HAL_USART_STATE_READY;
+
+#if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
+    /* Call registered Tx Rx Complete Callback */
+    husart->TxRxCpltCallback(husart);
+#else
+    /* Call legacy weak Tx Rx Complete Callback */
+    HAL_USART_TxRxCpltCallback(husart);
+#endif /* USE_HAL_USART_REGISTER_CALLBACKS */
+  }
+  else
+  {
+    /* Nothing to do */
+  }
+}
+
+
+/**
+  * @brief  Simplex receive an amount of data in non-blocking mode.
+  * @note   Function called under interruption only, once
+  *         interruptions have been enabled by HAL_USART_Receive_IT().
+  * @note   ISR function executed when FIFO mode is disabled and when the
+  *         data word length is less than 9 bits long.
+  * @param  husart USART handle
+  * @retval None
+  */
+static void USART_RxISR_8BIT(USART_HandleTypeDef *husart)
+{
+  const HAL_USART_StateTypeDef state = husart->State;
+  uint16_t txdatacount;
+  uint16_t uhMask = husart->Mask;
+  uint32_t txftie;
+
+  if ((state == HAL_USART_STATE_BUSY_RX) ||
+      (state == HAL_USART_STATE_BUSY_TX_RX))
+  {
+    *husart->pRxBuffPtr = (uint8_t)(husart->Instance->RDR & (uint8_t)uhMask);
+    husart->pRxBuffPtr++;
+    husart->RxXferCount--;
+
+    if (husart->RxXferCount == 0U)
+    {
+      /* Disable the USART Parity Error Interrupt and RXNE interrupt*/
+      CLEAR_BIT(husart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE));
+
+      /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error) */
+      CLEAR_BIT(husart->Instance->CR3, USART_CR3_EIE);
+
+      /* Clear RxISR function pointer */
+      husart->RxISR = NULL;
+
+      /* txftie and txdatacount are temporary variables for MISRAC2012-Rule-13.5 */
+      txftie = READ_BIT(husart->Instance->CR3, USART_CR3_TXFTIE);
+      txdatacount = husart->TxXferCount;
+
+      if (state == HAL_USART_STATE_BUSY_RX)
+      {
+        /* Clear SPI slave underrun flag and discard transmit data */
+        if (husart->SlaveMode == USART_SLAVEMODE_ENABLE)
+        {
+          __HAL_USART_CLEAR_UDRFLAG(husart);
+          __HAL_USART_SEND_REQ(husart, USART_TXDATA_FLUSH_REQUEST);
+        }
+
+        /* Rx process is completed, restore husart->State to Ready */
+        husart->State = HAL_USART_STATE_READY;
+
+#if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
+        /* Call registered Rx Complete Callback */
+        husart->RxCpltCallback(husart);
+#else
+        /* Call legacy weak Rx Complete Callback */
+        HAL_USART_RxCpltCallback(husart);
+#endif /* USE_HAL_USART_REGISTER_CALLBACKS */
+      }
+      else if ((READ_BIT(husart->Instance->CR1, USART_CR1_TCIE) != USART_CR1_TCIE) &&
+               (txftie != USART_CR3_TXFTIE) &&
+               (txdatacount == 0U))
+      {
+        /* TxRx process is completed, restore husart->State to Ready */
+        husart->State = HAL_USART_STATE_READY;
+
+#if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
+        /* Call registered Tx Rx Complete Callback */
+        husart->TxRxCpltCallback(husart);
+#else
+        /* Call legacy weak Tx Rx Complete Callback */
+        HAL_USART_TxRxCpltCallback(husart);
+#endif /* USE_HAL_USART_REGISTER_CALLBACKS */
+      }
+      else
+      {
+        /* Nothing to do */
+      }
+    }
+    else if ((state == HAL_USART_STATE_BUSY_RX) &&
+             (husart->SlaveMode == USART_SLAVEMODE_DISABLE))
+    {
+      /* Send dummy byte in order to generate the clock for the Slave to Send the next data */
+      husart->Instance->TDR = (USART_DUMMY_DATA & (uint16_t)0x00FF);
+    }
+    else
+    {
+      /* Nothing to do */
+    }
+  }
+}
+
+/**
+  * @brief  Simplex receive an amount of data in non-blocking mode.
+  * @note   Function called under interruption only, once
+  *         interruptions have been enabled by HAL_USART_Receive_IT().
+  * @note   ISR function executed when FIFO mode is disabled and when the
+  *         data word length is 9 bits long.
+  * @param  husart USART handle
+  * @retval None
+  */
+static void USART_RxISR_16BIT(USART_HandleTypeDef *husart)
+{
+  const HAL_USART_StateTypeDef state = husart->State;
+  uint16_t txdatacount;
+  uint16_t *tmp;
+  uint16_t uhMask = husart->Mask;
+  uint32_t txftie;
+
+  if ((state == HAL_USART_STATE_BUSY_RX) ||
+      (state == HAL_USART_STATE_BUSY_TX_RX))
+  {
+    tmp = (uint16_t *) husart->pRxBuffPtr;
+    *tmp = (uint16_t)(husart->Instance->RDR & uhMask);
+    husart->pRxBuffPtr += 2U;
+    husart->RxXferCount--;
+
+    if (husart->RxXferCount == 0U)
+    {
+      /* Disable the USART Parity Error Interrupt and RXNE interrupt*/
+      CLEAR_BIT(husart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE));
+
+      /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error) */
+      CLEAR_BIT(husart->Instance->CR3, USART_CR3_EIE);
+
+      /* Clear RxISR function pointer */
+      husart->RxISR = NULL;
+
+      /* txftie and txdatacount are temporary variables for MISRAC2012-Rule-13.5 */
+      txftie = READ_BIT(husart->Instance->CR3, USART_CR3_TXFTIE);
+      txdatacount = husart->TxXferCount;
+
+      if (state == HAL_USART_STATE_BUSY_RX)
+      {
+        /* Clear SPI slave underrun flag and discard transmit data */
+        if (husart->SlaveMode == USART_SLAVEMODE_ENABLE)
+        {
+          __HAL_USART_CLEAR_UDRFLAG(husart);
+          __HAL_USART_SEND_REQ(husart, USART_TXDATA_FLUSH_REQUEST);
+        }
+
+        /* Rx process is completed, restore husart->State to Ready */
+        husart->State = HAL_USART_STATE_READY;
+
+#if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
+        /* Call registered Rx Complete Callback */
+        husart->RxCpltCallback(husart);
+#else
+        /* Call legacy weak Rx Complete Callback */
+        HAL_USART_RxCpltCallback(husart);
+#endif /* USE_HAL_USART_REGISTER_CALLBACKS */
+      }
+      else if ((READ_BIT(husart->Instance->CR1, USART_CR1_TCIE) != USART_CR1_TCIE) &&
+               (txftie != USART_CR3_TXFTIE) &&
+               (txdatacount == 0U))
+      {
+        /* TxRx process is completed, restore husart->State to Ready */
+        husart->State = HAL_USART_STATE_READY;
+
+#if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
+        /* Call registered Tx Rx Complete Callback */
+        husart->TxRxCpltCallback(husart);
+#else
+        /* Call legacy weak Tx Rx Complete Callback */
+        HAL_USART_TxRxCpltCallback(husart);
+#endif /* USE_HAL_USART_REGISTER_CALLBACKS */
+      }
+      else
+      {
+        /* Nothing to do */
+      }
+    }
+    else if ((state == HAL_USART_STATE_BUSY_RX) &&
+             (husart->SlaveMode == USART_SLAVEMODE_DISABLE))
+    {
+      /* Send dummy byte in order to generate the clock for the Slave to Send the next data */
+      husart->Instance->TDR = (USART_DUMMY_DATA & (uint16_t)0x00FF);
+    }
+    else
+    {
+      /* Nothing to do */
+    }
+  }
+}
+
+/**
+  * @brief  Simplex receive an amount of data in non-blocking mode.
+  * @note   Function called under interruption only, once
+  *         interruptions have been enabled by HAL_USART_Receive_IT().
+  * @note   ISR function executed when FIFO mode is enabled and when the
+  *         data word length is less than 9 bits long.
+  * @param  husart USART handle
+  * @retval None
+  */
+static void USART_RxISR_8BIT_FIFOEN(USART_HandleTypeDef *husart)
+{
+  HAL_USART_StateTypeDef state = husart->State;
+  uint16_t txdatacount;
+  uint16_t rxdatacount;
+  uint16_t uhMask = husart->Mask;
+  uint16_t nb_rx_data;
+  uint32_t txftie;
+
+  /* Check that a Rx process is ongoing */
+  if ((state == HAL_USART_STATE_BUSY_RX) ||
+      (state == HAL_USART_STATE_BUSY_TX_RX))
+  {
+    for (nb_rx_data = husart->NbRxDataToProcess ; nb_rx_data > 0U ; nb_rx_data--)
+    {
+      if (__HAL_USART_GET_FLAG(husart, USART_FLAG_RXFNE) == SET)
+      {
+        *husart->pRxBuffPtr = (uint8_t)(husart->Instance->RDR & (uint8_t)(uhMask & 0xFFU));
+        husart->pRxBuffPtr++;
+        husart->RxXferCount--;
+
+        if (husart->RxXferCount == 0U)
+        {
+          /* Disable the USART Parity Error Interrupt */
+          CLEAR_BIT(husart->Instance->CR1, USART_CR1_PEIE);
+
+          /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error)
+             and RX FIFO Threshold interrupt */
+          CLEAR_BIT(husart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE));
+
+          /* Clear RxISR function pointer */
+          husart->RxISR = NULL;
+
+          /* txftie and txdatacount are temporary variables for MISRAC2012-Rule-13.5 */
+          txftie = READ_BIT(husart->Instance->CR3, USART_CR3_TXFTIE);
+          txdatacount = husart->TxXferCount;
+
+          if (state == HAL_USART_STATE_BUSY_RX)
+          {
+            /* Clear SPI slave underrun flag and discard transmit data */
+            if (husart->SlaveMode == USART_SLAVEMODE_ENABLE)
+            {
+              __HAL_USART_CLEAR_UDRFLAG(husart);
+              __HAL_USART_SEND_REQ(husart, USART_TXDATA_FLUSH_REQUEST);
+            }
+
+            /* Rx process is completed, restore husart->State to Ready */
+            husart->State = HAL_USART_STATE_READY;
+            state = HAL_USART_STATE_READY;
+
+#if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
+            /* Call registered Rx Complete Callback */
+            husart->RxCpltCallback(husart);
+#else
+            /* Call legacy weak Rx Complete Callback */
+            HAL_USART_RxCpltCallback(husart);
+#endif /* USE_HAL_USART_REGISTER_CALLBACKS */
+          }
+          else if ((READ_BIT(husart->Instance->CR1, USART_CR1_TCIE) != USART_CR1_TCIE) &&
+                   (txftie != USART_CR3_TXFTIE) &&
+                   (txdatacount == 0U))
+          {
+            /* TxRx process is completed, restore husart->State to Ready */
+            husart->State = HAL_USART_STATE_READY;
+            state = HAL_USART_STATE_READY;
+
+#if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
+            /* Call registered Tx Rx Complete Callback */
+            husart->TxRxCpltCallback(husart);
+#else
+            /* Call legacy weak Tx Rx Complete Callback */
+            HAL_USART_TxRxCpltCallback(husart);
+#endif /* USE_HAL_USART_REGISTER_CALLBACKS */
+          }
+          else
+          {
+            /* Nothing to do */
+          }
+        }
+        else if ((state == HAL_USART_STATE_BUSY_RX) &&
+                 (husart->SlaveMode == USART_SLAVEMODE_DISABLE))
+        {
+          /* Send dummy byte in order to generate the clock for the Slave to Send the next data */
+          husart->Instance->TDR = (USART_DUMMY_DATA & (uint16_t)0x00FF);
+        }
+        else
+        {
+          /* Nothing to do */
+        }
+      }
+    }
+
+    /* When remaining number of bytes to receive is less than the RX FIFO
+    threshold, next incoming frames are processed as if FIFO mode was
+    disabled (i.e. one interrupt per received frame).
+    */
+    rxdatacount = husart->RxXferCount;
+    if (((rxdatacount != 0U)) && (rxdatacount < husart->NbRxDataToProcess))
+    {
+      /* Disable the USART RXFT interrupt*/
+      CLEAR_BIT(husart->Instance->CR3, USART_CR3_RXFTIE);
+
+      /* Update the RxISR function pointer */
+      husart->RxISR = USART_RxISR_8BIT;
+
+      /* Enable the USART Data Register Not Empty interrupt */
+      SET_BIT(husart->Instance->CR1, USART_CR1_RXNEIE_RXFNEIE);
+
+      if ((husart->TxXferCount == 0U) &&
+          (state == HAL_USART_STATE_BUSY_TX_RX) &&
+          (husart->SlaveMode == USART_SLAVEMODE_DISABLE))
+      {
+        /* Send dummy byte in order to generate the clock for the Slave to Send the next data */
+        husart->Instance->TDR = (USART_DUMMY_DATA & (uint16_t)0x00FF);
+      }
+    }
+  }
+  else
+  {
+    /* Clear RXNE interrupt flag */
+    __HAL_USART_SEND_REQ(husart, USART_RXDATA_FLUSH_REQUEST);
+  }
+}
+
+/**
+  * @brief  Simplex receive an amount of data in non-blocking mode.
+  * @note   Function called under interruption only, once
+  *         interruptions have been enabled by HAL_USART_Receive_IT().
+  * @note   ISR function executed when FIFO mode is enabled and when the
+  *         data word length is 9 bits long.
+  * @param  husart USART handle
+  * @retval None
+  */
+static void USART_RxISR_16BIT_FIFOEN(USART_HandleTypeDef *husart)
+{
+  HAL_USART_StateTypeDef state = husart->State;
+  uint16_t txdatacount;
+  uint16_t rxdatacount;
+  uint16_t *tmp;
+  uint16_t uhMask = husart->Mask;
+  uint16_t nb_rx_data;
+  uint32_t txftie;
+
+  /* Check that a Tx process is ongoing */
+  if ((state == HAL_USART_STATE_BUSY_RX) ||
+      (state == HAL_USART_STATE_BUSY_TX_RX))
+  {
+    for (nb_rx_data = husart->NbRxDataToProcess ; nb_rx_data > 0U ; nb_rx_data--)
+    {
+      if (__HAL_USART_GET_FLAG(husart, USART_FLAG_RXFNE) == SET)
+      {
+        tmp = (uint16_t *) husart->pRxBuffPtr;
+        *tmp = (uint16_t)(husart->Instance->RDR & uhMask);
+        husart->pRxBuffPtr += 2U;
+        husart->RxXferCount--;
+
+        if (husart->RxXferCount == 0U)
+        {
+          /* Disable the USART Parity Error Interrupt */
+          CLEAR_BIT(husart->Instance->CR1, USART_CR1_PEIE);
+
+          /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error)
+             and RX FIFO Threshold interrupt */
+          CLEAR_BIT(husart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE));
+
+          /* Clear RxISR function pointer */
+          husart->RxISR = NULL;
+
+          /* txftie and txdatacount are temporary variables for MISRAC2012-Rule-13.5 */
+          txftie = READ_BIT(husart->Instance->CR3, USART_CR3_TXFTIE);
+          txdatacount = husart->TxXferCount;
+
+          if (state == HAL_USART_STATE_BUSY_RX)
+          {
+            /* Clear SPI slave underrun flag and discard transmit data */
+            if (husart->SlaveMode == USART_SLAVEMODE_ENABLE)
+            {
+              __HAL_USART_CLEAR_UDRFLAG(husart);
+              __HAL_USART_SEND_REQ(husart, USART_TXDATA_FLUSH_REQUEST);
+            }
+
+            /* Rx process is completed, restore husart->State to Ready */
+            husart->State = HAL_USART_STATE_READY;
+            state = HAL_USART_STATE_READY;
+
+#if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
+            /* Call registered Rx Complete Callback */
+            husart->RxCpltCallback(husart);
+#else
+            /* Call legacy weak Rx Complete Callback */
+            HAL_USART_RxCpltCallback(husart);
+#endif /* USE_HAL_USART_REGISTER_CALLBACKS */
+          }
+          else if ((READ_BIT(husart->Instance->CR1, USART_CR1_TCIE) != USART_CR1_TCIE) &&
+                   (txftie != USART_CR3_TXFTIE) &&
+                   (txdatacount == 0U))
+          {
+            /* TxRx process is completed, restore husart->State to Ready */
+            husart->State = HAL_USART_STATE_READY;
+            state = HAL_USART_STATE_READY;
+
+#if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
+            /* Call registered Tx Rx Complete Callback */
+            husart->TxRxCpltCallback(husart);
+#else
+            /* Call legacy weak Tx Rx Complete Callback */
+            HAL_USART_TxRxCpltCallback(husart);
+#endif /* USE_HAL_USART_REGISTER_CALLBACKS */
+          }
+          else
+          {
+            /* Nothing to do */
+          }
+        }
+        else if ((state == HAL_USART_STATE_BUSY_RX) &&
+                 (husart->SlaveMode == USART_SLAVEMODE_DISABLE))
+        {
+          /* Send dummy byte in order to generate the clock for the Slave to Send the next data */
+          husart->Instance->TDR = (USART_DUMMY_DATA & (uint16_t)0x00FF);
+        }
+        else
+        {
+          /* Nothing to do */
+        }
+      }
+    }
+
+    /* When remaining number of bytes to receive is less than the RX FIFO
+    threshold, next incoming frames are processed as if FIFO mode was
+    disabled (i.e. one interrupt per received frame).
+    */
+    rxdatacount = husart->RxXferCount;
+    if (((rxdatacount != 0U)) && (rxdatacount < husart->NbRxDataToProcess))
+    {
+      /* Disable the USART RXFT interrupt*/
+      CLEAR_BIT(husart->Instance->CR3, USART_CR3_RXFTIE);
+
+      /* Update the RxISR function pointer */
+      husart->RxISR = USART_RxISR_16BIT;
+
+      /* Enable the USART Data Register Not Empty interrupt */
+      SET_BIT(husart->Instance->CR1, USART_CR1_RXNEIE_RXFNEIE);
+
+      if ((husart->TxXferCount == 0U) &&
+          (state == HAL_USART_STATE_BUSY_TX_RX) &&
+          (husart->SlaveMode == USART_SLAVEMODE_DISABLE))
+      {
+        /* Send dummy byte in order to generate the clock for the Slave to Send the next data */
+        husart->Instance->TDR = (USART_DUMMY_DATA & (uint16_t)0x00FF);
+      }
+    }
+  }
+  else
+  {
+    /* Clear RXNE interrupt flag */
+    __HAL_USART_SEND_REQ(husart, USART_RXDATA_FLUSH_REQUEST);
+  }
+}
+
+/**
+  * @}
+  */
+
+#endif /* HAL_USART_MODULE_ENABLED */
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
diff --git a/starter-projects/servo/p1-pwm/Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_usart_ex.c b/starter-projects/servo/p1-pwm/Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_usart_ex.c
new file mode 100644
index 0000000..0321599
--- /dev/null
+++ b/starter-projects/servo/p1-pwm/Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_usart_ex.c
@@ -0,0 +1,541 @@
+/**
+  ******************************************************************************
+  * @file    stm32g4xx_hal_usart_ex.c
+  * @author  MCD Application Team
+  * @brief   Extended USART HAL module driver.
+  *          This file provides firmware functions to manage the following extended
+  *          functionalities of the Universal Synchronous Receiver Transmitter Peripheral (USART).
+  *           + Peripheral Control functions
+  *
+  *
+  ******************************************************************************
+  * @attention
+  *
+  * Copyright (c) 2019 STMicroelectronics.
+  * All rights reserved.
+  *
+  * This software is licensed under terms that can be found in the LICENSE file
+  * in the root directory of this software component.
+  * If no LICENSE file comes with this software, it is provided AS-IS.
+  *
+  ******************************************************************************
+  @verbatim
+  ==============================================================================
+               ##### USART peripheral extended features  #####
+  ==============================================================================
+
+    (#) FIFO mode enabling/disabling and RX/TX FIFO threshold programming.
+
+        -@- When USART operates in FIFO mode, FIFO mode must be enabled prior
+            starting RX/TX transfers. Also RX/TX FIFO thresholds must be
+            configured prior starting RX/TX transfers.
+
+    (#) Slave mode enabling/disabling and NSS pin configuration.
+
+        -@- When USART operates in Slave mode, Slave mode must be enabled prior
+            starting RX/TX transfers.
+
+  @endverbatim
+  ******************************************************************************
+  */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32g4xx_hal.h"
+
+/** @addtogroup STM32G4xx_HAL_Driver
+  * @{
+  */
+
+/** @defgroup USARTEx USARTEx
+  * @brief USART Extended HAL module driver
+  * @{
+  */
+
+#ifdef HAL_USART_MODULE_ENABLED
+
+/* Private typedef -----------------------------------------------------------*/
+/** @defgroup USARTEx_Private_Constants USARTEx Private Constants
+  * @{
+  */
+/* USART RX FIFO depth */
+#define RX_FIFO_DEPTH 8U
+
+/* USART TX FIFO depth */
+#define TX_FIFO_DEPTH 8U
+/**
+  * @}
+  */
+
+/* Private define ------------------------------------------------------------*/
+/* Private macros ------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/** @defgroup USARTEx_Private_Functions USARTEx Private Functions
+  * @{
+  */
+static void USARTEx_SetNbDataToProcess(USART_HandleTypeDef *husart);
+/**
+  * @}
+  */
+
+/* Exported functions --------------------------------------------------------*/
+
+/** @defgroup USARTEx_Exported_Functions  USARTEx Exported Functions
+  * @{
+  */
+
+/** @defgroup USARTEx_Exported_Functions_Group1 IO operation functions
+  * @brief Extended USART Transmit/Receive functions
+  *
+@verbatim
+ ===============================================================================
+                      ##### IO operation functions #####
+ ===============================================================================
+    This subsection provides a set of FIFO mode related callback functions.
+
+    (#) TX/RX Fifos Callbacks:
+        (+) HAL_USARTEx_RxFifoFullCallback()
+        (+) HAL_USARTEx_TxFifoEmptyCallback()
+
+@endverbatim
+  * @{
+  */
+
+/**
+  * @brief  USART RX Fifo full callback.
+  * @param  husart USART handle.
+  * @retval None
+  */
+__weak void HAL_USARTEx_RxFifoFullCallback(USART_HandleTypeDef *husart)
+{
+  /* Prevent unused argument(s) compilation warning */
+  UNUSED(husart);
+
+  /* NOTE : This function should not be modified, when the callback is needed,
+            the HAL_USARTEx_RxFifoFullCallback can be implemented in the user file.
+   */
+}
+
+/**
+  * @brief  USART TX Fifo empty callback.
+  * @param  husart USART handle.
+  * @retval None
+  */
+__weak void HAL_USARTEx_TxFifoEmptyCallback(USART_HandleTypeDef *husart)
+{
+  /* Prevent unused argument(s) compilation warning */
+  UNUSED(husart);
+
+  /* NOTE : This function should not be modified, when the callback is needed,
+            the HAL_USARTEx_TxFifoEmptyCallback can be implemented in the user file.
+   */
+}
+
+/**
+  * @}
+  */
+
+/** @defgroup USARTEx_Exported_Functions_Group2 Peripheral Control functions
+  * @brief    Extended Peripheral Control functions
+  *
+@verbatim
+ ===============================================================================
+                      ##### Peripheral Control functions #####
+ ===============================================================================
+    [..] This section provides the following functions:
+     (+) HAL_USARTEx_EnableSPISlaveMode() API enables the SPI slave mode
+     (+) HAL_USARTEx_DisableSPISlaveMode() API disables the SPI slave mode
+     (+) HAL_USARTEx_ConfigNSS API configures the Slave Select input pin (NSS)
+     (+) HAL_USARTEx_EnableFifoMode() API enables the FIFO mode
+     (+) HAL_USARTEx_DisableFifoMode() API disables the FIFO mode
+     (+) HAL_USARTEx_SetTxFifoThreshold() API sets the TX FIFO threshold
+     (+) HAL_USARTEx_SetRxFifoThreshold() API sets the RX FIFO threshold
+
+
+@endverbatim
+  * @{
+  */
+
+/**
+  * @brief  Enable the SPI slave mode.
+  * @note When the USART operates in SPI slave mode, it handles data flow using
+  *       the serial interface clock derived from the external SCLK signal
+  *       provided by the external master SPI device.
+  * @note In SPI slave mode, the USART must be enabled before starting the master
+  *       communications (or between frames while the clock is stable). Otherwise,
+  *       if the USART slave is enabled while the master is in the middle of a
+  *       frame, it will become desynchronized with the master.
+  * @note The data register of the slave needs to be ready before the first edge
+  *       of the communication clock or before the end of the ongoing communication,
+  *       otherwise the SPI slave will transmit zeros.
+  * @param husart      USART handle.
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_USARTEx_EnableSlaveMode(USART_HandleTypeDef *husart)
+{
+  uint32_t tmpcr1;
+
+  /* Check parameters */
+  assert_param(IS_UART_SPI_SLAVE_INSTANCE(husart->Instance));
+
+  /* Process Locked */
+  __HAL_LOCK(husart);
+
+  husart->State = HAL_USART_STATE_BUSY;
+
+  /* Save actual USART configuration */
+  tmpcr1 = READ_REG(husart->Instance->CR1);
+
+  /* Disable USART */
+  __HAL_USART_DISABLE(husart);
+
+  /* In SPI slave mode mode, the following bits must be kept cleared:
+  - LINEN and CLKEN bit in the USART_CR2 register
+  - HDSEL, SCEN and IREN bits in the USART_CR3 register.*/
+  CLEAR_BIT(husart->Instance->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN));
+  CLEAR_BIT(husart->Instance->CR3, (USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN));
+
+  /* Enable SPI slave mode */
+  SET_BIT(husart->Instance->CR2, USART_CR2_SLVEN);
+
+  /* Restore USART configuration */
+  WRITE_REG(husart->Instance->CR1, tmpcr1);
+
+  husart->SlaveMode = USART_SLAVEMODE_ENABLE;
+
+  husart->State = HAL_USART_STATE_READY;
+
+  /* Enable USART */
+  __HAL_USART_ENABLE(husart);
+
+  /* Process Unlocked */
+  __HAL_UNLOCK(husart);
+
+  return HAL_OK;
+}
+
+/**
+  * @brief  Disable the SPI slave mode.
+  * @param husart      USART handle.
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_USARTEx_DisableSlaveMode(USART_HandleTypeDef *husart)
+{
+  uint32_t tmpcr1;
+
+  /* Check parameters */
+  assert_param(IS_UART_SPI_SLAVE_INSTANCE(husart->Instance));
+
+  /* Process Locked */
+  __HAL_LOCK(husart);
+
+  husart->State = HAL_USART_STATE_BUSY;
+
+  /* Save actual USART configuration */
+  tmpcr1 = READ_REG(husart->Instance->CR1);
+
+  /* Disable USART */
+  __HAL_USART_DISABLE(husart);
+
+  /* Disable SPI slave mode */
+  CLEAR_BIT(husart->Instance->CR2, USART_CR2_SLVEN);
+
+  /* Restore USART configuration */
+  WRITE_REG(husart->Instance->CR1, tmpcr1);
+
+  husart->SlaveMode = USART_SLAVEMODE_DISABLE;
+
+  husart->State = HAL_USART_STATE_READY;
+
+  /* Process Unlocked */
+  __HAL_UNLOCK(husart);
+
+  return HAL_OK;
+}
+
+/**
+  * @brief  Configure the Slave Select input pin (NSS).
+  * @note Software NSS management: SPI slave will always be selected and NSS
+  *       input pin will be ignored.
+  * @note Hardware NSS management: the SPI slave selection depends on NSS
+  *       input pin. The slave is selected when NSS is low and deselected when
+  *       NSS is high.
+  * @param husart      USART handle.
+  * @param NSSConfig   NSS configuration.
+  *          This parameter can be one of the following values:
+  *            @arg @ref USART_NSS_HARD
+  *            @arg @ref USART_NSS_SOFT
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_USARTEx_ConfigNSS(USART_HandleTypeDef *husart, uint32_t NSSConfig)
+{
+  uint32_t tmpcr1;
+
+  /* Check parameters */
+  assert_param(IS_UART_SPI_SLAVE_INSTANCE(husart->Instance));
+  assert_param(IS_USART_NSS(NSSConfig));
+
+  /* Process Locked */
+  __HAL_LOCK(husart);
+
+  husart->State = HAL_USART_STATE_BUSY;
+
+  /* Save actual USART configuration */
+  tmpcr1 = READ_REG(husart->Instance->CR1);
+
+  /* Disable USART */
+  __HAL_USART_DISABLE(husart);
+
+  /* Program DIS_NSS bit in the USART_CR2 register */
+  MODIFY_REG(husart->Instance->CR2, USART_CR2_DIS_NSS, NSSConfig);
+
+  /* Restore USART configuration */
+  WRITE_REG(husart->Instance->CR1, tmpcr1);
+
+  husart->State = HAL_USART_STATE_READY;
+
+  /* Process Unlocked */
+  __HAL_UNLOCK(husart);
+
+  return HAL_OK;
+}
+
+/**
+  * @brief  Enable the FIFO mode.
+  * @param husart      USART handle.
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_USARTEx_EnableFifoMode(USART_HandleTypeDef *husart)
+{
+  uint32_t tmpcr1;
+
+  /* Check parameters */
+  assert_param(IS_UART_FIFO_INSTANCE(husart->Instance));
+
+  /* Process Locked */
+  __HAL_LOCK(husart);
+
+  husart->State = HAL_USART_STATE_BUSY;
+
+  /* Save actual USART configuration */
+  tmpcr1 = READ_REG(husart->Instance->CR1);
+
+  /* Disable USART */
+  __HAL_USART_DISABLE(husart);
+
+  /* Enable FIFO mode */
+  SET_BIT(tmpcr1, USART_CR1_FIFOEN);
+  husart->FifoMode = USART_FIFOMODE_ENABLE;
+
+  /* Restore USART configuration */
+  WRITE_REG(husart->Instance->CR1, tmpcr1);
+
+  /* Determine the number of data to process during RX/TX ISR execution */
+  USARTEx_SetNbDataToProcess(husart);
+
+  husart->State = HAL_USART_STATE_READY;
+
+  /* Process Unlocked */
+  __HAL_UNLOCK(husart);
+
+  return HAL_OK;
+}
+
+/**
+  * @brief  Disable the FIFO mode.
+  * @param husart      USART handle.
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_USARTEx_DisableFifoMode(USART_HandleTypeDef *husart)
+{
+  uint32_t tmpcr1;
+
+  /* Check parameters */
+  assert_param(IS_UART_FIFO_INSTANCE(husart->Instance));
+
+  /* Process Locked */
+  __HAL_LOCK(husart);
+
+  husart->State = HAL_USART_STATE_BUSY;
+
+  /* Save actual USART configuration */
+  tmpcr1 = READ_REG(husart->Instance->CR1);
+
+  /* Disable USART */
+  __HAL_USART_DISABLE(husart);
+
+  /* Disable FIFO mode */
+  CLEAR_BIT(tmpcr1, USART_CR1_FIFOEN);
+  husart->FifoMode = USART_FIFOMODE_DISABLE;
+
+  /* Restore USART configuration */
+  WRITE_REG(husart->Instance->CR1, tmpcr1);
+
+  husart->State = HAL_USART_STATE_READY;
+
+  /* Process Unlocked */
+  __HAL_UNLOCK(husart);
+
+  return HAL_OK;
+}
+
+/**
+  * @brief  Set the TXFIFO threshold.
+  * @param husart      USART handle.
+  * @param Threshold  TX FIFO threshold value
+  *          This parameter can be one of the following values:
+  *            @arg @ref USART_TXFIFO_THRESHOLD_1_8
+  *            @arg @ref USART_TXFIFO_THRESHOLD_1_4
+  *            @arg @ref USART_TXFIFO_THRESHOLD_1_2
+  *            @arg @ref USART_TXFIFO_THRESHOLD_3_4
+  *            @arg @ref USART_TXFIFO_THRESHOLD_7_8
+  *            @arg @ref USART_TXFIFO_THRESHOLD_8_8
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_USARTEx_SetTxFifoThreshold(USART_HandleTypeDef *husart, uint32_t Threshold)
+{
+  uint32_t tmpcr1;
+
+  /* Check parameters */
+  assert_param(IS_UART_FIFO_INSTANCE(husart->Instance));
+  assert_param(IS_USART_TXFIFO_THRESHOLD(Threshold));
+
+  /* Process Locked */
+  __HAL_LOCK(husart);
+
+  husart->State = HAL_USART_STATE_BUSY;
+
+  /* Save actual USART configuration */
+  tmpcr1 = READ_REG(husart->Instance->CR1);
+
+  /* Disable USART */
+  __HAL_USART_DISABLE(husart);
+
+  /* Update TX threshold configuration */
+  MODIFY_REG(husart->Instance->CR3, USART_CR3_TXFTCFG, Threshold);
+
+  /* Determine the number of data to process during RX/TX ISR execution */
+  USARTEx_SetNbDataToProcess(husart);
+
+  /* Restore USART configuration */
+  WRITE_REG(husart->Instance->CR1, tmpcr1);
+
+  husart->State = HAL_USART_STATE_READY;
+
+  /* Process Unlocked */
+  __HAL_UNLOCK(husart);
+
+  return HAL_OK;
+}
+
+/**
+  * @brief  Set the RXFIFO threshold.
+  * @param husart      USART handle.
+  * @param Threshold  RX FIFO threshold value
+  *          This parameter can be one of the following values:
+  *            @arg @ref USART_RXFIFO_THRESHOLD_1_8
+  *            @arg @ref USART_RXFIFO_THRESHOLD_1_4
+  *            @arg @ref USART_RXFIFO_THRESHOLD_1_2
+  *            @arg @ref USART_RXFIFO_THRESHOLD_3_4
+  *            @arg @ref USART_RXFIFO_THRESHOLD_7_8
+  *            @arg @ref USART_RXFIFO_THRESHOLD_8_8
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_USARTEx_SetRxFifoThreshold(USART_HandleTypeDef *husart, uint32_t Threshold)
+{
+  uint32_t tmpcr1;
+
+  /* Check the parameters */
+  assert_param(IS_UART_FIFO_INSTANCE(husart->Instance));
+  assert_param(IS_USART_RXFIFO_THRESHOLD(Threshold));
+
+  /* Process Locked */
+  __HAL_LOCK(husart);
+
+  husart->State = HAL_USART_STATE_BUSY;
+
+  /* Save actual USART configuration */
+  tmpcr1 = READ_REG(husart->Instance->CR1);
+
+  /* Disable USART */
+  __HAL_USART_DISABLE(husart);
+
+  /* Update RX threshold configuration */
+  MODIFY_REG(husart->Instance->CR3, USART_CR3_RXFTCFG, Threshold);
+
+  /* Determine the number of data to process during RX/TX ISR execution */
+  USARTEx_SetNbDataToProcess(husart);
+
+  /* Restore USART configuration */
+  WRITE_REG(husart->Instance->CR1, tmpcr1);
+
+  husart->State = HAL_USART_STATE_READY;
+
+  /* Process Unlocked */
+  __HAL_UNLOCK(husart);
+
+  return HAL_OK;
+}
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/** @addtogroup USARTEx_Private_Functions
+  * @{
+  */
+
+/**
+  * @brief Calculate the number of data to process in RX/TX ISR.
+  * @note The RX FIFO depth and the TX FIFO depth is extracted from
+  *       the USART configuration registers.
+  * @param husart USART handle.
+  * @retval None
+  */
+static void USARTEx_SetNbDataToProcess(USART_HandleTypeDef *husart)
+{
+  uint8_t rx_fifo_depth;
+  uint8_t tx_fifo_depth;
+  uint8_t rx_fifo_threshold;
+  uint8_t tx_fifo_threshold;
+  /* 2 0U/1U added for MISRAC2012-Rule-18.1_b and MISRAC2012-Rule-18.1_d */
+  static const uint8_t numerator[]   = {1U, 1U, 1U, 3U, 7U, 1U, 0U, 0U};
+  static const uint8_t denominator[] = {8U, 4U, 2U, 4U, 8U, 1U, 1U, 1U};
+
+  if (husart->FifoMode == USART_FIFOMODE_DISABLE)
+  {
+    husart->NbTxDataToProcess = 1U;
+    husart->NbRxDataToProcess = 1U;
+  }
+  else
+  {
+    rx_fifo_depth = RX_FIFO_DEPTH;
+    tx_fifo_depth = TX_FIFO_DEPTH;
+    rx_fifo_threshold = (uint8_t)((READ_BIT(husart->Instance->CR3,
+                                            USART_CR3_RXFTCFG) >> USART_CR3_RXFTCFG_Pos) & 0xFFU);
+    tx_fifo_threshold = (uint8_t)((READ_BIT(husart->Instance->CR3,
+                                            USART_CR3_TXFTCFG) >> USART_CR3_TXFTCFG_Pos) & 0xFFU);
+    husart->NbTxDataToProcess = ((uint16_t)tx_fifo_depth * numerator[tx_fifo_threshold]) /
+                                (uint16_t)denominator[tx_fifo_threshold];
+    husart->NbRxDataToProcess = ((uint16_t)rx_fifo_depth * numerator[rx_fifo_threshold]) /
+                                (uint16_t)denominator[rx_fifo_threshold];
+  }
+}
+/**
+  * @}
+  */
+
+#endif /* HAL_USART_MODULE_ENABLED */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
diff --git a/starter-projects/servo/p1-pwm/servo-p1-pwm.ioc b/starter-projects/servo/p1-pwm/servo-p1-pwm-cpp.ioc
similarity index 68%
rename from starter-projects/servo/p1-pwm/servo-p1-pwm.ioc
rename to starter-projects/servo/p1-pwm/servo-p1-pwm-cpp.ioc
index 3f22e54..1ca19c1 100644
--- a/starter-projects/servo/p1-pwm/servo-p1-pwm.ioc
+++ b/starter-projects/servo/p1-pwm/servo-p1-pwm-cpp.ioc
@@ -1,177 +1,179 @@
-#MicroXplorer Configuration settings - do not modify
-BSP_IP_NAME=NUCLEO-G431RB
-CAD.formats=
-CAD.pinconfig=
-CAD.provider=
-File.Version=6
-GPIO.groupedBy=Group By Peripherals
-KeepUserPlacement=false
-Mcu.CPN=STM32G431RBT6
-Mcu.Family=STM32G4
-Mcu.IP0=NVIC
-Mcu.IP1=RCC
-Mcu.IP2=SYS
-Mcu.IP3=NUCLEO-G431RB
-Mcu.IPNb=4
-Mcu.Name=STM32G431R(6-8-B)Tx
-Mcu.Package=LQFP64
-Mcu.Pin0=PC13
-Mcu.Pin1=PC14-OSC32_IN
-Mcu.Pin10=PB3
-Mcu.Pin11=VP_SYS_VS_Systick
-Mcu.Pin12=VP_SYS_VS_DBSignals
-Mcu.Pin2=PC15-OSC32_OUT
-Mcu.Pin3=PF0-OSC_IN
-Mcu.Pin4=PF1-OSC_OUT
-Mcu.Pin5=PA2
-Mcu.Pin6=PA3
-Mcu.Pin7=PA5
-Mcu.Pin8=PA13
-Mcu.Pin9=PA14
-Mcu.PinsNb=13
-Mcu.ThirdPartyNb=0
-Mcu.UserConstants=
-Mcu.UserName=STM32G431RBTx
-MxCube.Version=6.12.0
-MxDb.Version=DB.6.0.120
-NVIC.BusFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
-NVIC.DebugMonitor_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
-NVIC.ForceEnableDMAVector=true
-NVIC.HardFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
-NVIC.MemoryManagement_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
-NVIC.NonMaskableInt_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
-NVIC.PendSV_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
-NVIC.PriorityGroup=NVIC_PRIORITYGROUP_4
-NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
-NVIC.SysTick_IRQn=true\:0\:0\:false\:false\:true\:false\:true\:false
-NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
-PA13.GPIOParameters=GPIO_Label
-PA13.GPIO_Label=T_SWDIO
-PA13.Locked=true
-PA13.Signal=SYS_JTMS-SWDIO
-PA14.GPIOParameters=GPIO_Label
-PA14.GPIO_Label=T_SWCLK
-PA14.Locked=true
-PA14.Signal=SYS_JTCK-SWCLK
-PA2.GPIOParameters=GPIO_Label
-PA2.GPIO_Label=LPUART1_TX [STLINKV3E_VCP_RX]
-PA2.Locked=true
-PA2.Signal=LPUART1_TX
-PA3.GPIOParameters=GPIO_Label
-PA3.GPIO_Label=LPUART1_RX [STLINKV3E_VCP_TX]
-PA3.Locked=true
-PA3.Signal=LPUART1_RX
-PA5.GPIOParameters=GPIO_Label
-PA5.GPIO_Label=LD2 [green]
-PA5.Locked=true
-PA5.Signal=GPIO_Output
-PB3.GPIOParameters=GPIO_Label
-PB3.GPIO_Label=T_SWO
-PB3.Locked=true
-PB3.Signal=SYS_JTDO-SWO
-PC13.GPIOParameters=GPIO_Label
-PC13.GPIO_Label=B1 [blue push button]
-PC13.Locked=true
-PC13.Signal=GPXTI13
-PC14-OSC32_IN.GPIOParameters=GPIO_Label
-PC14-OSC32_IN.GPIO_Label=RCC_OSC32_OUT
-PC14-OSC32_IN.Locked=true
-PC14-OSC32_IN.Signal=RCC_OSC32_IN
-PC15-OSC32_OUT.GPIOParameters=GPIO_Label
-PC15-OSC32_OUT.GPIO_Label=RCC_OSC32_OUT
-PC15-OSC32_OUT.Locked=true
-PC15-OSC32_OUT.Signal=RCC_OSC32_OUT
-PF0-OSC_IN.GPIOParameters=GPIO_Label
-PF0-OSC_IN.GPIO_Label=RCC_OSC_IN
-PF0-OSC_IN.Locked=true
-PF0-OSC_IN.Signal=RCC_OSC_IN
-PF1-OSC_OUT.GPIOParameters=GPIO_Label
-PF1-OSC_OUT.GPIO_Label=RCC_OSC_OUT
-PF1-OSC_OUT.Locked=true
-PF1-OSC_OUT.Signal=RCC_OSC_OUT
-PinOutPanel.RotationAngle=0
-ProjectManager.AskForMigrate=true
-ProjectManager.BackupPrevious=false
-ProjectManager.CompilerOptimize=6
-ProjectManager.ComputerToolchain=false
-ProjectManager.CoupleFile=false
-ProjectManager.CustomerFirmwarePackage=
-ProjectManager.DefaultFWLocation=true
-ProjectManager.DeletePrevious=true
-ProjectManager.DeviceId=STM32G431RBTx
-ProjectManager.FirmwarePackage=STM32Cube FW_G4 V1.6.0
-ProjectManager.FreePins=false
-ProjectManager.HalAssertFull=false
-ProjectManager.HeapSize=0x200
-ProjectManager.KeepUserCode=true
-ProjectManager.LastFirmware=true
-ProjectManager.LibraryCopy=1
-ProjectManager.MainLocation=Core/Src
-ProjectManager.NoMain=false
-ProjectManager.PreviousToolchain=
-ProjectManager.ProjectBuild=false
-ProjectManager.ProjectFileName=servo-p1-pwm.ioc
-ProjectManager.ProjectName=servo-p1-pwm
-ProjectManager.ProjectStructure=
-ProjectManager.RegisterCallBack=
-ProjectManager.StackSize=0x400
-ProjectManager.TargetToolchain=STM32CubeIDE
-ProjectManager.ToolChainLocation=
-ProjectManager.UAScriptAfterPath=
-ProjectManager.UAScriptBeforePath=
-ProjectManager.UnderRoot=true
-ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_GPIO_Init-GPIO-false-HAL-true
-RCC.ADC12Freq_Value=72000000
-RCC.AHBFreq_Value=72000000
-RCC.APB1Freq_Value=72000000
-RCC.APB1TimFreq_Value=72000000
-RCC.APB2Freq_Value=72000000
-RCC.APB2TimFreq_Value=72000000
-RCC.CRSFreq_Value=48000000
-RCC.CortexFreq_Value=72000000
-RCC.EXTERNAL_CLOCK_VALUE=12288000
-RCC.FCLKCortexFreq_Value=72000000
-RCC.FDCANFreq_Value=72000000
-RCC.FamilyName=M
-RCC.HCLKFreq_Value=72000000
-RCC.HSE_VALUE=24000000
-RCC.HSI48_VALUE=48000000
-RCC.HSI_VALUE=16000000
-RCC.I2C1Freq_Value=72000000
-RCC.I2C2Freq_Value=72000000
-RCC.I2C3Freq_Value=72000000
-RCC.I2SFreq_Value=72000000
-RCC.IPParameters=ADC12Freq_Value,AHBFreq_Value,APB1Freq_Value,APB1TimFreq_Value,APB2Freq_Value,APB2TimFreq_Value,CRSFreq_Value,CortexFreq_Value,EXTERNAL_CLOCK_VALUE,FCLKCortexFreq_Value,FDCANFreq_Value,FamilyName,HCLKFreq_Value,HSE_VALUE,HSI48_VALUE,HSI_VALUE,I2C1Freq_Value,I2C2Freq_Value,I2C3Freq_Value,I2SFreq_Value,LPTIM1Freq_Value,LPUART1Freq_Value,LSCOPinFreq_Value,LSE_VALUE,LSI_VALUE,MCO1PinFreq_Value,PLLN,PLLPoutputFreq_Value,PLLQoutputFreq_Value,PLLRCLKFreq_Value,PWRFreq_Value,RNGFreq_Value,RTCClockSelection,RTCFreq_Value,SAI1Freq_Value,SYSCLKFreq_VALUE,SYSCLKSource,UART4Freq_Value,USART1Freq_Value,USART2Freq_Value,USART3Freq_Value,USBFreq_Value,VCOInputFreq_Value,VCOOutputFreq_Value
-RCC.LPTIM1Freq_Value=72000000
-RCC.LPUART1Freq_Value=72000000
-RCC.LSCOPinFreq_Value=32000
-RCC.LSE_VALUE=32768
-RCC.LSI_VALUE=32000
-RCC.MCO1PinFreq_Value=16000000
-RCC.PLLN=9
-RCC.PLLPoutputFreq_Value=72000000
-RCC.PLLQoutputFreq_Value=72000000
-RCC.PLLRCLKFreq_Value=72000000
-RCC.PWRFreq_Value=72000000
-RCC.RNGFreq_Value=72000000
-RCC.RTCClockSelection=RCC_RTCCLKSOURCE_LSE
-RCC.RTCFreq_Value=32768
-RCC.SAI1Freq_Value=72000000
-RCC.SYSCLKFreq_VALUE=72000000
-RCC.SYSCLKSource=RCC_SYSCLKSOURCE_PLLCLK
-RCC.UART4Freq_Value=72000000
-RCC.USART1Freq_Value=72000000
-RCC.USART2Freq_Value=72000000
-RCC.USART3Freq_Value=72000000
-RCC.USBFreq_Value=72000000
-RCC.VCOInputFreq_Value=16000000
-RCC.VCOOutputFreq_Value=144000000
-SH.GPXTI13.0=GPIO_EXTI13
-SH.GPXTI13.ConfNb=1
-VP_SYS_VS_DBSignals.Mode=DisableDeadBatterySignals
-VP_SYS_VS_DBSignals.Signal=SYS_VS_DBSignals
-VP_SYS_VS_Systick.Mode=SysTick
-VP_SYS_VS_Systick.Signal=SYS_VS_Systick
-board=NUCLEO-G431RB
-boardIOC=true
-isbadioc=false
+#MicroXplorer Configuration settings - do not modify
+BSP_IP_NAME=NUCLEO-G431RB
+CAD.formats=
+CAD.pinconfig=
+CAD.provider=
+File.Version=6
+GPIO.groupedBy=Group By Peripherals
+KeepUserPlacement=false
+Mcu.CPN=STM32G431RBT6
+Mcu.Family=STM32G4
+Mcu.IP0=NUCLEO-G431RB
+Mcu.IP1=NUCLEO-G431RB
+Mcu.IP2=NVIC
+Mcu.IP3=RCC
+Mcu.IP4=SYS
+Mcu.IPNb=6
+Mcu.Name=STM32G431R(6-8-B)Tx
+Mcu.Package=LQFP64
+Mcu.Pin0=PC13
+Mcu.Pin1=PC14-OSC32_IN
+Mcu.Pin10=PB3
+Mcu.Pin11=VP_SYS_VS_Systick
+Mcu.Pin12=VP_SYS_VS_DBSignals
+Mcu.Pin13=VP_NUCLEO-G431RB_VS_BSP_COMMON
+Mcu.Pin2=PC15-OSC32_OUT
+Mcu.Pin3=PF0-OSC_IN
+Mcu.Pin4=PF1-OSC_OUT
+Mcu.Pin5=PA2
+Mcu.Pin6=PA3
+Mcu.Pin7=PA5
+Mcu.Pin8=PA13
+Mcu.Pin9=PA14
+Mcu.PinsNb=14
+Mcu.ThirdPartyNb=0
+Mcu.UserConstants=
+Mcu.UserName=STM32G431RBTx
+MxCube.Version=6.12.0
+MxDb.Version=DB.6.0.120
+NUCLEO-G431RB.BUTTON=1
+NUCLEO-G431RB.IPParameters=LD1,BUTTON,VCP
+NUCLEO-G431RB.LD1=true
+NUCLEO-G431RB.VCP=true
+NVIC.BusFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
+NVIC.DebugMonitor_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
+NVIC.EXTI15_10_IRQn=true\:0\:0\:false\:false\:true\:false\:true\:true
+NVIC.ForceEnableDMAVector=true
+NVIC.HardFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
+NVIC.MemoryManagement_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
+NVIC.NonMaskableInt_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
+NVIC.PendSV_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
+NVIC.PriorityGroup=NVIC_PRIORITYGROUP_4
+NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
+NVIC.SysTick_IRQn=true\:0\:0\:false\:false\:true\:false\:true\:false
+NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
+PA13.GPIOParameters=GPIO_Label
+PA13.GPIO_Label=T_SWDIO
+PA13.Locked=true
+PA13.Signal=SYS_JTMS-SWDIO
+PA14.GPIOParameters=GPIO_Label
+PA14.GPIO_Label=T_SWCLK
+PA14.Locked=true
+PA14.Signal=SYS_JTCK-SWCLK
+PA2.Locked=true
+PA2.Signal=LPUART1_TX
+PA3.Locked=true
+PA3.Signal=LPUART1_RX
+PA5.Locked=true
+PA5.Signal=GPIO_Output
+PB3.GPIOParameters=GPIO_Label
+PB3.GPIO_Label=T_SWO
+PB3.Locked=true
+PB3.Signal=SYS_JTDO-SWO
+PC13.Locked=true
+PC13.Signal=GPXTI13
+PC14-OSC32_IN.GPIOParameters=GPIO_Label
+PC14-OSC32_IN.GPIO_Label=RCC_OSC32_OUT
+PC14-OSC32_IN.Locked=true
+PC14-OSC32_IN.Signal=RCC_OSC32_IN
+PC15-OSC32_OUT.GPIOParameters=GPIO_Label
+PC15-OSC32_OUT.GPIO_Label=RCC_OSC32_OUT
+PC15-OSC32_OUT.Locked=true
+PC15-OSC32_OUT.Signal=RCC_OSC32_OUT
+PF0-OSC_IN.GPIOParameters=GPIO_Label
+PF0-OSC_IN.GPIO_Label=RCC_OSC_IN
+PF0-OSC_IN.Locked=true
+PF0-OSC_IN.Signal=RCC_OSC_IN
+PF1-OSC_OUT.GPIOParameters=GPIO_Label
+PF1-OSC_OUT.GPIO_Label=RCC_OSC_OUT
+PF1-OSC_OUT.Locked=true
+PF1-OSC_OUT.Signal=RCC_OSC_OUT
+PinOutPanel.RotationAngle=0
+ProjectManager.AskForMigrate=true
+ProjectManager.BackupPrevious=false
+ProjectManager.CompilerOptimize=6
+ProjectManager.ComputerToolchain=false
+ProjectManager.CoupleFile=false
+ProjectManager.CustomerFirmwarePackage=
+ProjectManager.DefaultFWLocation=true
+ProjectManager.DeletePrevious=true
+ProjectManager.DeviceId=STM32G431RBTx
+ProjectManager.FirmwarePackage=STM32Cube FW_G4 V1.6.0
+ProjectManager.FreePins=false
+ProjectManager.HalAssertFull=false
+ProjectManager.HeapSize=0x200
+ProjectManager.KeepUserCode=true
+ProjectManager.LastFirmware=true
+ProjectManager.LibraryCopy=1
+ProjectManager.MainLocation=Core/Src
+ProjectManager.NoMain=false
+ProjectManager.PreviousToolchain=
+ProjectManager.ProjectBuild=false
+ProjectManager.ProjectFileName=servo-p1-pwm-cpp.ioc
+ProjectManager.ProjectName=servo-p1-pwm-cpp
+ProjectManager.ProjectStructure=
+ProjectManager.RegisterCallBack=
+ProjectManager.StackSize=0x400
+ProjectManager.TargetToolchain=STM32CubeIDE
+ProjectManager.ToolChainLocation=
+ProjectManager.UAScriptAfterPath=
+ProjectManager.UAScriptBeforePath=
+ProjectManager.UnderRoot=true
+ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_GPIO_Init-GPIO-false-HAL-true,false-0--NUCLEO-G431RB-true-HAL-true
+RCC.ADC12Freq_Value=170000000
+RCC.AHBFreq_Value=170000000
+RCC.APB1Freq_Value=170000000
+RCC.APB1TimFreq_Value=170000000
+RCC.APB2Freq_Value=170000000
+RCC.APB2TimFreq_Value=170000000
+RCC.CRSFreq_Value=48000000
+RCC.CortexFreq_Value=170000000
+RCC.EXTERNAL_CLOCK_VALUE=12288000
+RCC.FCLKCortexFreq_Value=170000000
+RCC.FDCANFreq_Value=170000000
+RCC.FamilyName=M
+RCC.HCLKFreq_Value=170000000
+RCC.HSE_VALUE=24000000
+RCC.HSI48_VALUE=48000000
+RCC.HSI_VALUE=16000000
+RCC.I2C1Freq_Value=170000000
+RCC.I2C2Freq_Value=170000000
+RCC.I2C3Freq_Value=170000000
+RCC.I2SFreq_Value=170000000
+RCC.IPParameters=ADC12Freq_Value,AHBFreq_Value,APB1Freq_Value,APB1TimFreq_Value,APB2Freq_Value,APB2TimFreq_Value,CRSFreq_Value,CortexFreq_Value,EXTERNAL_CLOCK_VALUE,FCLKCortexFreq_Value,FDCANFreq_Value,FamilyName,HCLKFreq_Value,HSE_VALUE,HSI48_VALUE,HSI_VALUE,I2C1Freq_Value,I2C2Freq_Value,I2C3Freq_Value,I2SFreq_Value,LPTIM1Freq_Value,LPUART1Freq_Value,LSCOPinFreq_Value,LSE_VALUE,LSI_VALUE,MCO1PinFreq_Value,PLLM,PLLN,PLLPoutputFreq_Value,PLLQoutputFreq_Value,PLLRCLKFreq_Value,PWRFreq_Value,RNGFreq_Value,RTCClockSelection,RTCFreq_Value,SAI1Freq_Value,SYSCLKFreq_VALUE,SYSCLKSource,UART4Freq_Value,USART1Freq_Value,USART2Freq_Value,USART3Freq_Value,USBFreq_Value,VCOInputFreq_Value,VCOOutputFreq_Value
+RCC.LPTIM1Freq_Value=170000000
+RCC.LPUART1Freq_Value=170000000
+RCC.LSCOPinFreq_Value=32000
+RCC.LSE_VALUE=32768
+RCC.LSI_VALUE=32000
+RCC.MCO1PinFreq_Value=16000000
+RCC.PLLM=RCC_PLLM_DIV4
+RCC.PLLN=85
+RCC.PLLPoutputFreq_Value=170000000
+RCC.PLLQoutputFreq_Value=170000000
+RCC.PLLRCLKFreq_Value=170000000
+RCC.PWRFreq_Value=170000000
+RCC.RNGFreq_Value=170000000
+RCC.RTCClockSelection=RCC_RTCCLKSOURCE_LSE
+RCC.RTCFreq_Value=32768
+RCC.SAI1Freq_Value=170000000
+RCC.SYSCLKFreq_VALUE=170000000
+RCC.SYSCLKSource=RCC_SYSCLKSOURCE_PLLCLK
+RCC.UART4Freq_Value=170000000
+RCC.USART1Freq_Value=170000000
+RCC.USART2Freq_Value=170000000
+RCC.USART3Freq_Value=170000000
+RCC.USBFreq_Value=170000000
+RCC.VCOInputFreq_Value=4000000
+RCC.VCOOutputFreq_Value=340000000
+SH.GPXTI13.0=GPIO_EXTI13
+SH.GPXTI13.ConfNb=1
+VP_NUCLEO-G431RB_VS_BSP_COMMON.Mode=COMMON
+VP_NUCLEO-G431RB_VS_BSP_COMMON.Signal=NUCLEO-G431RB_VS_BSP_COMMON
+VP_SYS_VS_DBSignals.Mode=DisableDeadBatterySignals
+VP_SYS_VS_DBSignals.Signal=SYS_VS_DBSignals
+VP_SYS_VS_Systick.Mode=SysTick
+VP_SYS_VS_Systick.Signal=SYS_VS_Systick
+board=NUCLEO-G431RB
+boardIOC=true
+isbadioc=false