MX 2 лет назад
Родитель
Сommit
cfd853939e
100 измененных файлов с 7517 добавлено и 27797 удалено
  1. 3 1
      ReadMe.md
  2. BIN
      apps/GPIO/esp_flasher.fap
  3. BIN
      apps/GPIO/flipperscope.fap
  4. BIN
      apps/GPIO/scope.fap
  5. BIN
      apps/NFC/seader.fap
  6. BIN
      apps/Sub-GHz/esubghz_chat.fap
  7. BIN
      apps/Sub-GHz/tpms.fap
  8. 3 0
      non_catalog_apps/esubghz_chat/.gitignore
  9. 674 0
      non_catalog_apps/esubghz_chat/LICENSE
  10. 75 0
      non_catalog_apps/esubghz_chat/README.md
  11. 15 0
      non_catalog_apps/esubghz_chat/application.fam
  12. BIN
      non_catalog_apps/esubghz_chat/assets/Pin_back_arrow_10x8.png
  13. BIN
      non_catalog_apps/esubghz_chat/assets/WarningDolphin_45x42.png
  14. BIN
      non_catalog_apps/esubghz_chat/chat_10px.png
  15. 483 0
      non_catalog_apps/esubghz_chat/crypto/aes.c
  16. 81 0
      non_catalog_apps/esubghz_chat/crypto/aes.h
  17. 511 0
      non_catalog_apps/esubghz_chat/crypto/gcm.c
  18. 187 0
      non_catalog_apps/esubghz_chat/crypto/gcm.h
  19. 1132 0
      non_catalog_apps/esubghz_chat/esubghz_chat.c
  20. 4 20
      non_catalog_apps/flipperscope/application.fam
  21. 0 352
      non_catalog_apps/flipperscope/lib/adc/inc/stm32wbxx_hal_conf.h
  22. 0 2422
      non_catalog_apps/flipperscope/lib/adc/inc/stm32wbxx_hal_tim.h
  23. 0 304
      non_catalog_apps/flipperscope/lib/adc/inc/stm32wbxx_nucleo.h
  24. 0 851
      non_catalog_apps/flipperscope/lib/adc/stm32wbxx_hal.c
  25. 0 3973
      non_catalog_apps/flipperscope/lib/adc/stm32wbxx_hal_adc.c
  26. 0 1826
      non_catalog_apps/flipperscope/lib/adc/stm32wbxx_hal_adc_ex.c
  27. 0 479
      non_catalog_apps/flipperscope/lib/adc/stm32wbxx_hal_cortex.c
  28. 0 1118
      non_catalog_apps/flipperscope/lib/adc/stm32wbxx_hal_dma.c
  29. 0 551
      non_catalog_apps/flipperscope/lib/adc/stm32wbxx_hal_gpio.c
  30. 0 720
      non_catalog_apps/flipperscope/lib/adc/stm32wbxx_hal_pwr.c
  31. 0 1824
      non_catalog_apps/flipperscope/lib/adc/stm32wbxx_hal_rcc.c
  32. 0 2328
      non_catalog_apps/flipperscope/lib/adc/stm32wbxx_hal_rcc_ex.c
  33. 0 7903
      non_catalog_apps/flipperscope/lib/adc/stm32wbxx_hal_tim.c
  34. 0 2842
      non_catalog_apps/flipperscope/lib/adc/stm32wbxx_hal_tim_ex.c
  35. BIN
      non_catalog_apps/flipperscope/photos/freq.jpg
  36. BIN
      non_catalog_apps/flipperscope/photos/rigol.jpg
  37. BIN
      non_catalog_apps/flipperscope/photos/sig.jpg
  38. BIN
      non_catalog_apps/flipperscope/photos/volt.jpg
  39. 368 0
      non_catalog_apps/flipperscope/scenes/adc.c
  40. 1 2
      non_catalog_apps/flipperscope/scenes/scope_scene_about.c
  41. 223 159
      non_catalog_apps/flipperscope/scenes/scope_scene_run.c
  42. 0 1
      non_catalog_apps/flipperscope/scenes/scope_types.h
  43. 2 7
      non_catalog_apps/flipperscope/scope_app_i.h
  44. 1 0
      non_catalog_apps/flipperzero-esp-flasher/application.fam
  45. 5 0
      non_catalog_apps/flipperzero-esp-flasher/docs/changelog.md
  46. 5 0
      non_catalog_apps/flipperzero-esp-flasher/esp_flasher_app.c
  47. 1 1
      non_catalog_apps/flipperzero-esp-flasher/esp_flasher_app.h
  48. 5 0
      non_catalog_apps/flipperzero-esp-flasher/esp_flasher_app_i.h
  49. 74 3
      non_catalog_apps/flipperzero-esp-flasher/esp_flasher_worker.c
  50. 4 0
      non_catalog_apps/flipperzero-esp-flasher/esp_flasher_worker.h
  51. 22 0
      non_catalog_apps/flipperzero-esp-flasher/scenes/esp_flasher_scene_start.c
  52. 20 20
      non_catalog_apps/seader/ccid.c
  53. 7 7
      non_catalog_apps/seader/ccid.h
  54. 13 0
      non_catalog_apps/seader/scenes/seader_scene_card_menu.c
  55. 251 3
      non_catalog_apps/seader/seader_credential.c
  56. 3 0
      non_catalog_apps/seader/seader_credential.h
  57. 139 79
      non_catalog_apps/seader/seader_worker.c
  58. 1 1
      non_catalog_apps/seader/uart.c
  59. 15 0
      non_catalog_apps/tpms_receiver/Readme.md
  60. 13 0
      non_catalog_apps/tpms_receiver/application.fam
  61. 69 0
      non_catalog_apps/tpms_receiver/helpers/radio_device_loader.c
  62. 17 0
      non_catalog_apps/tpms_receiver/helpers/radio_device_loader.h
  63. 14 0
      non_catalog_apps/tpms_receiver/helpers/tpms_event.h
  64. 58 0
      non_catalog_apps/tpms_receiver/helpers/tpms_types.h
  65. BIN
      non_catalog_apps/tpms_receiver/images/Fishing_123x52.png
  66. BIN
      non_catalog_apps/tpms_receiver/images/Lock_7x8.png
  67. BIN
      non_catalog_apps/tpms_receiver/images/Pin_back_arrow_10x8.png
  68. BIN
      non_catalog_apps/tpms_receiver/images/Press_7x16.png
  69. BIN
      non_catalog_apps/tpms_receiver/images/Quest_7x8.png
  70. BIN
      non_catalog_apps/tpms_receiver/images/Scanning_123x52.png
  71. BIN
      non_catalog_apps/tpms_receiver/images/Therm_7x16.png
  72. BIN
      non_catalog_apps/tpms_receiver/images/Timer_11x11.png
  73. BIN
      non_catalog_apps/tpms_receiver/images/Unlock_7x8.png
  74. BIN
      non_catalog_apps/tpms_receiver/images/WarningDolphin_45x42.png
  75. BIN
      non_catalog_apps/tpms_receiver/images/station_icon.png
  76. 9 0
      non_catalog_apps/tpms_receiver/protocols/protocol_items.c
  77. 6 0
      non_catalog_apps/tpms_receiver/protocols/protocol_items.h
  78. 295 0
      non_catalog_apps/tpms_receiver/protocols/schrader_gg4.c
  79. 80 0
      non_catalog_apps/tpms_receiver/protocols/schrader_gg4.h
  80. 228 0
      non_catalog_apps/tpms_receiver/protocols/tpms_generic.c
  81. 77 0
      non_catalog_apps/tpms_receiver/protocols/tpms_generic.h
  82. 30 0
      non_catalog_apps/tpms_receiver/scenes/tpms_scene.c
  83. 29 0
      non_catalog_apps/tpms_receiver/scenes/tpms_scene.h
  84. 57 0
      non_catalog_apps/tpms_receiver/scenes/tpms_scene_about.c
  85. 6 0
      non_catalog_apps/tpms_receiver/scenes/tpms_scene_config.h
  86. 221 0
      non_catalog_apps/tpms_receiver/scenes/tpms_scene_receiver.c
  87. 218 0
      non_catalog_apps/tpms_receiver/scenes/tpms_scene_receiver_config.c
  88. 50 0
      non_catalog_apps/tpms_receiver/scenes/tpms_scene_receiver_info.c
  89. 91 0
      non_catalog_apps/tpms_receiver/scenes/tpms_scene_relearn.c
  90. 62 0
      non_catalog_apps/tpms_receiver/scenes/tpms_scene_start.c
  91. BIN
      non_catalog_apps/tpms_receiver/tpms_10px.png
  92. 185 0
      non_catalog_apps/tpms_receiver/tpms_app.c
  93. 153 0
      non_catalog_apps/tpms_receiver/tpms_app_i.c
  94. 77 0
      non_catalog_apps/tpms_receiver/tpms_app_i.h
  95. 232 0
      non_catalog_apps/tpms_receiver/tpms_history.c
  96. 112 0
      non_catalog_apps/tpms_receiver/tpms_history.h
  97. 509 0
      non_catalog_apps/tpms_receiver/views/tpms_receiver.c
  98. 42 0
      non_catalog_apps/tpms_receiver/views/tpms_receiver.h
  99. 233 0
      non_catalog_apps/tpms_receiver/views/tpms_receiver_info.c
  100. 16 0
      non_catalog_apps/tpms_receiver/views/tpms_receiver_info.h

+ 3 - 1
ReadMe.md

@@ -20,7 +20,7 @@ Sources of "integrated/bundled" apps are added now in this repo too, to allow pu
 
 The Flipper and its community wouldn't be as rich as it is without your contributions and support. Thank you for all you have done.
 
-### Apps checked & updated at `18 Jul 02:22 GMT +3`
+### Apps checked & updated at `24 Jul 01:07 GMT +3`
 
 ## Games
 - [Pong (By nmrr)](https://github.com/nmrr/flipperzero-pong) - Modified by [SimplyMinimal](https://github.com/SimplyMinimal/FlipperZero-Pong)
@@ -129,6 +129,8 @@ The Flipper and its community wouldn't be as rich as it is without your contribu
 - [CLI-GUI Bridge (By ranchordo)](https://github.com/ranchordo/flipperzero-cli-bridge) -> (Fixed by @Willy-JL)
 - [Seader (By bettse)](https://github.com/bettse/seader/tree/main) - `Interface with a SAM from the Flipper Zero over UART`
 - [RFID Beacon (By nmrr)](https://github.com/nmrr/flipperzero-rfidbeacon) - `A letter/number Morse beacon on 125 kHz`
+- [Enhanced Sub-GHz Chat (By twisted-pear)](https://github.com/twisted-pear/esubghz_chat)
+- [TPMS Reader (By wosk)](https://github.com/wosk/flipperzero-tpms/tree/main)
 
 --- 
 

BIN
apps/GPIO/esp_flasher.fap


BIN
apps/GPIO/flipperscope.fap


BIN
apps/GPIO/scope.fap


BIN
apps/NFC/seader.fap


BIN
apps/Sub-GHz/esubghz_chat.fap


BIN
apps/Sub-GHz/tpms.fap


+ 3 - 0
non_catalog_apps/esubghz_chat/.gitignore

@@ -0,0 +1,3 @@
+*~
+*.swp
+*.swo

+ 674 - 0
non_catalog_apps/esubghz_chat/LICENSE

@@ -0,0 +1,674 @@
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+  The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works.  By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users.  We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors.  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+  To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights.  Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received.  You must make sure that they, too, receive
+or can get the source code.  And you must show them these terms so they
+know their rights.
+
+  Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+  For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software.  For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+  Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so.  This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software.  The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable.  Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products.  If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+  Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary.  To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                       TERMS AND CONDITIONS
+
+  0. Definitions.
+
+  "This License" refers to version 3 of the GNU General Public License.
+
+  "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+  "The Program" refers to any copyrightable work licensed under this
+License.  Each licensee is addressed as "you".  "Licensees" and
+"recipients" may be individuals or organizations.
+
+  To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy.  The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+  A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+  To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy.  Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+  To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies.  Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+  An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License.  If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+  1. Source Code.
+
+  The "source code" for a work means the preferred form of the work
+for making modifications to it.  "Object code" means any non-source
+form of a work.
+
+  A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+  The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form.  A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+  The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities.  However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work.  For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+  The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+  The Corresponding Source for a work in source code form is that
+same work.
+
+  2. Basic Permissions.
+
+  All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met.  This License explicitly affirms your unlimited
+permission to run the unmodified Program.  The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work.  This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+  You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force.  You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright.  Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+  Conveying under any other circumstances is permitted solely under
+the conditions stated below.  Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+  No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+  When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+  4. Conveying Verbatim Copies.
+
+  You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+  You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+  5. Conveying Modified Source Versions.
+
+  You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+    a) The work must carry prominent notices stating that you modified
+    it, and giving a relevant date.
+
+    b) The work must carry prominent notices stating that it is
+    released under this License and any conditions added under section
+    7.  This requirement modifies the requirement in section 4 to
+    "keep intact all notices".
+
+    c) You must license the entire work, as a whole, under this
+    License to anyone who comes into possession of a copy.  This
+    License will therefore apply, along with any applicable section 7
+    additional terms, to the whole of the work, and all its parts,
+    regardless of how they are packaged.  This License gives no
+    permission to license the work in any other way, but it does not
+    invalidate such permission if you have separately received it.
+
+    d) If the work has interactive user interfaces, each must display
+    Appropriate Legal Notices; however, if the Program has interactive
+    interfaces that do not display Appropriate Legal Notices, your
+    work need not make them do so.
+
+  A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit.  Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+  6. Conveying Non-Source Forms.
+
+  You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+    a) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by the
+    Corresponding Source fixed on a durable physical medium
+    customarily used for software interchange.
+
+    b) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by a
+    written offer, valid for at least three years and valid for as
+    long as you offer spare parts or customer support for that product
+    model, to give anyone who possesses the object code either (1) a
+    copy of the Corresponding Source for all the software in the
+    product that is covered by this License, on a durable physical
+    medium customarily used for software interchange, for a price no
+    more than your reasonable cost of physically performing this
+    conveying of source, or (2) access to copy the
+    Corresponding Source from a network server at no charge.
+
+    c) Convey individual copies of the object code with a copy of the
+    written offer to provide the Corresponding Source.  This
+    alternative is allowed only occasionally and noncommercially, and
+    only if you received the object code with such an offer, in accord
+    with subsection 6b.
+
+    d) Convey the object code by offering access from a designated
+    place (gratis or for a charge), and offer equivalent access to the
+    Corresponding Source in the same way through the same place at no
+    further charge.  You need not require recipients to copy the
+    Corresponding Source along with the object code.  If the place to
+    copy the object code is a network server, the Corresponding Source
+    may be on a different server (operated by you or a third party)
+    that supports equivalent copying facilities, provided you maintain
+    clear directions next to the object code saying where to find the
+    Corresponding Source.  Regardless of what server hosts the
+    Corresponding Source, you remain obligated to ensure that it is
+    available for as long as needed to satisfy these requirements.
+
+    e) Convey the object code using peer-to-peer transmission, provided
+    you inform other peers where the object code and Corresponding
+    Source of the work are being offered to the general public at no
+    charge under subsection 6d.
+
+  A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+  A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling.  In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage.  For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product.  A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+  "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source.  The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+  If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information.  But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+  The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed.  Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+  Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+  7. Additional Terms.
+
+  "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law.  If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+  When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it.  (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.)  You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+  Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+    a) Disclaiming warranty or limiting liability differently from the
+    terms of sections 15 and 16 of this License; or
+
+    b) Requiring preservation of specified reasonable legal notices or
+    author attributions in that material or in the Appropriate Legal
+    Notices displayed by works containing it; or
+
+    c) Prohibiting misrepresentation of the origin of that material, or
+    requiring that modified versions of such material be marked in
+    reasonable ways as different from the original version; or
+
+    d) Limiting the use for publicity purposes of names of licensors or
+    authors of the material; or
+
+    e) Declining to grant rights under trademark law for use of some
+    trade names, trademarks, or service marks; or
+
+    f) Requiring indemnification of licensors and authors of that
+    material by anyone who conveys the material (or modified versions of
+    it) with contractual assumptions of liability to the recipient, for
+    any liability that these contractual assumptions directly impose on
+    those licensors and authors.
+
+  All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10.  If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term.  If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+  If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+  Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+  8. Termination.
+
+  You may not propagate or modify a covered work except as expressly
+provided under this License.  Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+  However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+  Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+  Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License.  If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+  9. Acceptance Not Required for Having Copies.
+
+  You are not required to accept this License in order to receive or
+run a copy of the Program.  Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance.  However,
+nothing other than this License grants you permission to propagate or
+modify any covered work.  These actions infringe copyright if you do
+not accept this License.  Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+  10. Automatic Licensing of Downstream Recipients.
+
+  Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License.  You are not responsible
+for enforcing compliance by third parties with this License.
+
+  An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations.  If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+  You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License.  For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+  11. Patents.
+
+  A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based.  The
+work thus licensed is called the contributor's "contributor version".
+
+  A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version.  For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+  Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+  In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement).  To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+  If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients.  "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+  If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+  A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License.  You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+  Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+  12. No Surrender of Others' Freedom.
+
+  If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all.  For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+  13. Use with the GNU Affero General Public License.
+
+  Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work.  The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+  14. Revised Versions of this License.
+
+  The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+  Each version is given a distinguishing version number.  If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation.  If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+  If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+  Later license versions may give you additional or different
+permissions.  However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+  15. Disclaimer of Warranty.
+
+  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. Limitation of Liability.
+
+  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+  17. Interpretation of Sections 15 and 16.
+
+  If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+  If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+    <program>  Copyright (C) <year>  <name of author>
+    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+  You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<https://www.gnu.org/licenses/>.
+
+  The GNU General Public License does not permit incorporating your program
+into proprietary programs.  If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.  But first, please read
+<https://www.gnu.org/licenses/why-not-lgpl.html>.

+ 75 - 0
non_catalog_apps/esubghz_chat/README.md

@@ -0,0 +1,75 @@
+# Enhanced Sub-GHz Chat
+
+This is a plugin for the Flipper Zero that reimplements the Sub-GHz chat
+feature that is available on the CLI. In addition it allows for basic
+encryption of messages.
+
+The plugin has been tested on the official firmware (version 0.87.0) and on
+Unleashed (version unlshd-057). Due to limitations of the official firmware,
+the behavior is slightly different there.
+
+Currently the use of an external antenna is not supported.
+
+## Warning
+
+This plugin is in the early stages of development. It will inevitably have
+bugs. You have been warned.
+
+## Usage
+
+Once opened the plugin will ask for a frequency to operate on which must be
+entered in HZ.
+
+On the next screen the plugin will ask for a password to derive the
+cryptographic key from. If nothing (on Unleashed) or a single space (on OFW) is
+entered, the encryption is disabled.
+
+Finally the a message can be input. After the message is confirmed, the plugin
+will switch to the chat view, where sent and received messages are displayed.
+To view the chat view without entering a message, enter nothing (on Unleashed)
+or a single space (on OFW). To go back to entering a message press the back
+button.
+
+In the chat view the keyboard can be locked by pressing and holding the OK
+button for a few seconds. To unlock the keyboard again quickly press the back
+button three times.
+
+Pressing the back button when entering the frequency, the password or a message
+will terminate the plugin.
+
+## Interoperability
+
+When encryption is disabled, the plugin can interoperate with the Sub-GHz chat
+available on the Flipper's CLI. However, the CLI sends a sequence of escape
+characters that are not interpreted by this plugin and will be displayed in the
+chat view.
+
+## Encryption
+
+Messages are encrypted using 256 bit AES in GCM mode. Each message gets its own
+random IV. On reception the tag generated by GCM is verified and the message
+discarded if it doesn't match.
+
+The key for the encryption is derived from the password by applying SHA-256 to
+the password once.
+
+Note that deriving the key with SHA-256 means that the security of your
+messages depends entirely on the strength of the password. The plugin does not
+use an elaborate key derivation function (KDF) to strengthen the password. A
+weak passwords means weak encryption.
+
+Furthermore, the key is the same among all participants. That means that each
+user with the key can impersonate every other user.
+
+The same key is used for all messages. This means that no forward-secrecy is
+provided. If the key is compromised, all previous messages are compromised as
+well.
+
+If you do not understand the implications of the caveats mentioned here, do not
+expect to gain any security by using encryption.
+
+## Acknowledgements
+
+The implementations of AES and GCM are taken directly from
+https://github.com/mko-x/SharedAES-GCM. They were released to the public domain
+by Markus Kosmal.

+ 15 - 0
non_catalog_apps/esubghz_chat/application.fam

@@ -0,0 +1,15 @@
+App(
+    appid="esubghz_chat",
+    name="Enhanced Sub-Ghz Chat",
+    apptype=FlipperAppType.EXTERNAL,
+    entry_point="esubghz_chat",
+    requires=[
+        "gui",
+        "subghz",
+    ],
+    stack_size=8 * 1024,
+    fap_category="Sub-GHz",
+    fap_icon="chat_10px.png",
+    fap_icon_assets="assets",
+    fap_icon_assets_symbol="esubghz_chat",
+)

BIN
non_catalog_apps/esubghz_chat/assets/Pin_back_arrow_10x8.png


BIN
non_catalog_apps/esubghz_chat/assets/WarningDolphin_45x42.png


BIN
non_catalog_apps/esubghz_chat/chat_10px.png


+ 483 - 0
non_catalog_apps/esubghz_chat/crypto/aes.c

@@ -0,0 +1,483 @@
+/******************************************************************************
+*
+* THIS SOURCE CODE IS HEREBY PLACED INTO THE PUBLIC DOMAIN FOR THE GOOD OF ALL
+*
+* This is a simple and straightforward implementation of the AES Rijndael
+* 128-bit block cipher designed by Vincent Rijmen and Joan Daemen. The focus
+* of this work was correctness & accuracy.  It is written in 'C' without any
+* particular focus upon optimization or speed. It should be endian (memory
+* byte order) neutral since the few places that care are handled explicitly.
+*
+* This implementation of Rijndael was created by Steven M. Gibson of GRC.com.
+*
+* It is intended for general purpose use, but was written in support of GRC's
+* reference implementation of the SQRL (Secure Quick Reliable Login) client.
+*
+* See:    http://csrc.nist.gov/archive/aes/rijndael/wsdindex.html
+*
+* NO COPYRIGHT IS CLAIMED IN THIS WORK, HOWEVER, NEITHER IS ANY WARRANTY MADE
+* REGARDING ITS FITNESS FOR ANY PARTICULAR PURPOSE. USE IT AT YOUR OWN RISK.
+*
+*******************************************************************************/
+
+#include "aes.h"
+
+static int aes_tables_inited = 0;   // run-once flag for performing key
+                                    // expasion table generation (see below)
+/*
+ *  The following static local tables must be filled-in before the first use of
+ *  the GCM or AES ciphers. They are used for the AES key expansion/scheduling
+ *  and once built are read-only and thread safe. The "gcm_initialize" function
+ *  must be called once during system initialization to populate these arrays
+ *  for subsequent use by the AES key scheduler. If they have not been built
+ *  before attempted use, an error will be returned to the caller.
+ *
+ *  NOTE: GCM Encryption/Decryption does NOT REQUIRE AES decryption. Since
+ *  GCM uses AES in counter-mode, where the AES cipher output is XORed with
+ *  the GCM input, we ONLY NEED AES encryption.  Thus, to save space AES
+ *  decryption is typically disabled by setting AES_DECRYPTION to 0 in aes.h.
+ */
+                            // We always need our forward tables
+static uchar FSb[256];      // Forward substitution box (FSb)
+static uint32_t FT0[256];   // Forward key schedule assembly tables
+static uint32_t FT1[256];
+static uint32_t FT2[256];
+static uint32_t FT3[256];
+
+#if AES_DECRYPTION          // We ONLY need reverse for decryption
+static uchar RSb[256];      // Reverse substitution box (RSb)
+static uint32_t RT0[256];   // Reverse key schedule assembly tables
+static uint32_t RT1[256];
+static uint32_t RT2[256];
+static uint32_t RT3[256];
+#endif                      /* AES_DECRYPTION */
+
+static uint32_t RCON[10];   // AES round constants
+
+/* 
+ * Platform Endianness Neutralizing Load and Store Macro definitions
+ * AES wants platform-neutral Little Endian (LE) byte ordering
+ */
+#define GET_UINT32_LE(n,b,i) {                  \
+    (n) = ( (uint32_t) (b)[(i)    ]       )     \
+        | ( (uint32_t) (b)[(i) + 1] <<  8 )     \
+        | ( (uint32_t) (b)[(i) + 2] << 16 )     \
+        | ( (uint32_t) (b)[(i) + 3] << 24 ); }
+
+#define PUT_UINT32_LE(n,b,i) {                  \
+    (b)[(i)    ] = (uchar) ( (n)       );       \
+    (b)[(i) + 1] = (uchar) ( (n) >>  8 );       \
+    (b)[(i) + 2] = (uchar) ( (n) >> 16 );       \
+    (b)[(i) + 3] = (uchar) ( (n) >> 24 ); }
+
+/*
+ *  AES forward and reverse encryption round processing macros
+ */
+#define AES_FROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3)     \
+{                                               \
+    X0 = *RK++ ^ FT0[ ( Y0       ) & 0xFF ] ^   \
+                 FT1[ ( Y1 >>  8 ) & 0xFF ] ^   \
+                 FT2[ ( Y2 >> 16 ) & 0xFF ] ^   \
+                 FT3[ ( Y3 >> 24 ) & 0xFF ];    \
+                                                \
+    X1 = *RK++ ^ FT0[ ( Y1       ) & 0xFF ] ^   \
+                 FT1[ ( Y2 >>  8 ) & 0xFF ] ^   \
+                 FT2[ ( Y3 >> 16 ) & 0xFF ] ^   \
+                 FT3[ ( Y0 >> 24 ) & 0xFF ];    \
+                                                \
+    X2 = *RK++ ^ FT0[ ( Y2       ) & 0xFF ] ^   \
+                 FT1[ ( Y3 >>  8 ) & 0xFF ] ^   \
+                 FT2[ ( Y0 >> 16 ) & 0xFF ] ^   \
+                 FT3[ ( Y1 >> 24 ) & 0xFF ];    \
+                                                \
+    X3 = *RK++ ^ FT0[ ( Y3       ) & 0xFF ] ^   \
+                 FT1[ ( Y0 >>  8 ) & 0xFF ] ^   \
+                 FT2[ ( Y1 >> 16 ) & 0xFF ] ^   \
+                 FT3[ ( Y2 >> 24 ) & 0xFF ];    \
+}
+
+#define AES_RROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3)     \
+{                                               \
+    X0 = *RK++ ^ RT0[ ( Y0       ) & 0xFF ] ^   \
+                 RT1[ ( Y3 >>  8 ) & 0xFF ] ^   \
+                 RT2[ ( Y2 >> 16 ) & 0xFF ] ^   \
+                 RT3[ ( Y1 >> 24 ) & 0xFF ];    \
+                                                \
+    X1 = *RK++ ^ RT0[ ( Y1       ) & 0xFF ] ^   \
+                 RT1[ ( Y0 >>  8 ) & 0xFF ] ^   \
+                 RT2[ ( Y3 >> 16 ) & 0xFF ] ^   \
+                 RT3[ ( Y2 >> 24 ) & 0xFF ];    \
+                                                \
+    X2 = *RK++ ^ RT0[ ( Y2       ) & 0xFF ] ^   \
+                 RT1[ ( Y1 >>  8 ) & 0xFF ] ^   \
+                 RT2[ ( Y0 >> 16 ) & 0xFF ] ^   \
+                 RT3[ ( Y3 >> 24 ) & 0xFF ];    \
+                                                \
+    X3 = *RK++ ^ RT0[ ( Y3       ) & 0xFF ] ^   \
+                 RT1[ ( Y2 >>  8 ) & 0xFF ] ^   \
+                 RT2[ ( Y1 >> 16 ) & 0xFF ] ^   \
+                 RT3[ ( Y0 >> 24 ) & 0xFF ];    \
+}
+
+/*
+ *  These macros improve the readability of the key
+ *  generation initialization code by collapsing
+ *  repetitive common operations into logical pieces.
+ */
+#define ROTL8(x) ( ( x << 8 ) & 0xFFFFFFFF ) | ( x >> 24 )
+#define XTIME(x) ( ( x << 1 ) ^ ( ( x & 0x80 ) ? 0x1B : 0x00 ) )
+#define MUL(x,y) ( ( x && y ) ? pow[(log[x]+log[y]) % 255] : 0 )
+#define MIX(x,y) { y = ( (y << 1) | (y >> 7) ) & 0xFF; x ^= y; }
+#define CPY128   { *RK++ = *SK++; *RK++ = *SK++; \
+                   *RK++ = *SK++; *RK++ = *SK++; }
+
+/******************************************************************************
+ *
+ *  AES_INIT_KEYGEN_TABLES
+ *
+ *  Fills the AES key expansion tables allocated above with their static
+ *  data. This is not "per key" data, but static system-wide read-only
+ *  table data. THIS FUNCTION IS NOT THREAD SAFE. It must be called once
+ *  at system initialization to setup the tables for all subsequent use.
+ *
+ ******************************************************************************/
+void aes_init_keygen_tables( void )
+{
+    int i, x, y, z;     // general purpose iteration and computation locals
+    int pow[256];
+    int log[256];
+
+    if (aes_tables_inited) return;
+
+    // fill the 'pow' and 'log' tables over GF(2^8)
+    for( i = 0, x = 1; i < 256; i++ )   {
+        pow[i] = x;
+        log[x] = i;
+        x = ( x ^ XTIME( x ) ) & 0xFF;
+    }
+    // compute the round constants
+    for( i = 0, x = 1; i < 10; i++ )    {
+        RCON[i] = (uint32_t) x;
+        x = XTIME( x ) & 0xFF;
+    }
+    // fill the forward and reverse substitution boxes
+    FSb[0x00] = 0x63;
+#if AES_DECRYPTION  // whether AES decryption is supported
+    RSb[0x63] = 0x00;
+#endif /* AES_DECRYPTION */
+
+    for( i = 1; i < 256; i++ )          {
+        x = y = pow[255 - log[i]];
+        MIX(x,y);
+        MIX(x,y);
+        MIX(x,y);
+        MIX(x,y); 
+        FSb[i] = (uchar) ( x ^= 0x63 );
+#if AES_DECRYPTION  // whether AES decryption is supported
+        RSb[x] = (uchar) i;
+#endif /* AES_DECRYPTION */
+
+    }
+    // generate the forward and reverse key expansion tables
+    for( i = 0; i < 256; i++ )          {
+        x = FSb[i];
+        y = XTIME( x ) & 0xFF;
+        z =  ( y ^ x ) & 0xFF;
+
+        FT0[i] = ( (uint32_t) y       ) ^ ( (uint32_t) x <<  8 ) ^
+                 ( (uint32_t) x << 16 ) ^ ( (uint32_t) z << 24 );
+
+        FT1[i] = ROTL8( FT0[i] );
+        FT2[i] = ROTL8( FT1[i] );
+        FT3[i] = ROTL8( FT2[i] );
+
+#if AES_DECRYPTION  // whether AES decryption is supported
+        x = RSb[i];
+
+        RT0[i] = ( (uint32_t) MUL( 0x0E, x )       ) ^
+                 ( (uint32_t) MUL( 0x09, x ) <<  8 ) ^
+                 ( (uint32_t) MUL( 0x0D, x ) << 16 ) ^
+                 ( (uint32_t) MUL( 0x0B, x ) << 24 );
+
+        RT1[i] = ROTL8( RT0[i] );
+        RT2[i] = ROTL8( RT1[i] );
+        RT3[i] = ROTL8( RT2[i] );
+#endif /* AES_DECRYPTION */
+    }
+    aes_tables_inited = 1;  // flag that the tables have been generated
+}                           // to permit subsequent use of the AES cipher
+
+/******************************************************************************
+ *
+ *  AES_SET_ENCRYPTION_KEY
+ *
+ *  This is called by 'aes_setkey' when we're establishing a key for
+ *  subsequent encryption.  We give it a pointer to the encryption
+ *  context, a pointer to the key, and the key's length in bytes.
+ *  Valid lengths are: 16, 24 or 32 bytes (128, 192, 256 bits).
+ *
+ ******************************************************************************/
+int aes_set_encryption_key( aes_context *ctx,
+                            const uchar *key,
+                            uint keysize )
+{
+    uint i;                 // general purpose iteration local
+    uint32_t *RK = ctx->rk; // initialize our RoundKey buffer pointer
+
+    for( i = 0; i < (keysize >> 2); i++ ) {
+        GET_UINT32_LE( RK[i], key, i << 2 );
+    }
+
+    switch( ctx->rounds )
+    {
+        case 10:
+            for( i = 0; i < 10; i++, RK += 4 ) {
+                RK[4]  = RK[0] ^ RCON[i] ^
+                ( (uint32_t) FSb[ ( RK[3] >>  8 ) & 0xFF ]       ) ^
+                ( (uint32_t) FSb[ ( RK[3] >> 16 ) & 0xFF ] <<  8 ) ^
+                ( (uint32_t) FSb[ ( RK[3] >> 24 ) & 0xFF ] << 16 ) ^
+                ( (uint32_t) FSb[ ( RK[3]       ) & 0xFF ] << 24 );
+
+                RK[5]  = RK[1] ^ RK[4];
+                RK[6]  = RK[2] ^ RK[5];
+                RK[7]  = RK[3] ^ RK[6];
+            }
+            break;
+
+        case 12:
+            for( i = 0; i < 8; i++, RK += 6 ) {
+                RK[6]  = RK[0] ^ RCON[i] ^
+                ( (uint32_t) FSb[ ( RK[5] >>  8 ) & 0xFF ]       ) ^
+                ( (uint32_t) FSb[ ( RK[5] >> 16 ) & 0xFF ] <<  8 ) ^
+                ( (uint32_t) FSb[ ( RK[5] >> 24 ) & 0xFF ] << 16 ) ^
+                ( (uint32_t) FSb[ ( RK[5]       ) & 0xFF ] << 24 );
+
+                RK[7]  = RK[1] ^ RK[6];
+                RK[8]  = RK[2] ^ RK[7];
+                RK[9]  = RK[3] ^ RK[8];
+                RK[10] = RK[4] ^ RK[9];
+                RK[11] = RK[5] ^ RK[10];
+            }
+            break;
+
+        case 14:
+            for( i = 0; i < 7; i++, RK += 8 ) {
+                RK[8]  = RK[0] ^ RCON[i] ^
+                ( (uint32_t) FSb[ ( RK[7] >>  8 ) & 0xFF ]       ) ^
+                ( (uint32_t) FSb[ ( RK[7] >> 16 ) & 0xFF ] <<  8 ) ^
+                ( (uint32_t) FSb[ ( RK[7] >> 24 ) & 0xFF ] << 16 ) ^
+                ( (uint32_t) FSb[ ( RK[7]       ) & 0xFF ] << 24 );
+
+                RK[9]  = RK[1] ^ RK[8];
+                RK[10] = RK[2] ^ RK[9];
+                RK[11] = RK[3] ^ RK[10];
+
+                RK[12] = RK[4] ^
+                ( (uint32_t) FSb[ ( RK[11]       ) & 0xFF ]       ) ^
+                ( (uint32_t) FSb[ ( RK[11] >>  8 ) & 0xFF ] <<  8 ) ^
+                ( (uint32_t) FSb[ ( RK[11] >> 16 ) & 0xFF ] << 16 ) ^
+                ( (uint32_t) FSb[ ( RK[11] >> 24 ) & 0xFF ] << 24 );
+
+                RK[13] = RK[5] ^ RK[12];
+                RK[14] = RK[6] ^ RK[13];
+                RK[15] = RK[7] ^ RK[14];
+            }
+            break;
+
+	default:
+	    return -1;
+    }
+    return( 0 );
+}
+
+#if AES_DECRYPTION  // whether AES decryption is supported
+
+/******************************************************************************
+ *
+ *  AES_SET_DECRYPTION_KEY
+ *
+ *  This is called by 'aes_setkey' when we're establishing a
+ *  key for subsequent decryption.  We give it a pointer to
+ *  the encryption context, a pointer to the key, and the key's
+ *  length in bits. Valid lengths are: 128, 192, or 256 bits.
+ *
+ ******************************************************************************/
+int aes_set_decryption_key( aes_context *ctx,
+                            const uchar *key,
+                            uint keysize )
+{
+    int i, j;
+    aes_context cty;            // a calling aes context for set_encryption_key
+    uint32_t *RK = ctx->rk;     // initialize our RoundKey buffer pointer
+    uint32_t *SK;
+    int ret;
+
+    cty.rounds = ctx->rounds;   // initialize our local aes context
+    cty.rk = cty.buf;           // round count and key buf pointer
+
+    if (( ret = aes_set_encryption_key( &cty, key, keysize )) != 0 )
+        return( ret );
+
+    SK = cty.rk + cty.rounds * 4;
+
+    CPY128  // copy a 128-bit block from *SK to *RK
+
+    for( i = ctx->rounds - 1, SK -= 8; i > 0; i--, SK -= 8 ) {
+        for( j = 0; j < 4; j++, SK++ ) {
+            *RK++ = RT0[ FSb[ ( *SK       ) & 0xFF ] ] ^
+                    RT1[ FSb[ ( *SK >>  8 ) & 0xFF ] ] ^
+                    RT2[ FSb[ ( *SK >> 16 ) & 0xFF ] ] ^
+                    RT3[ FSb[ ( *SK >> 24 ) & 0xFF ] ];
+        }
+    }
+    CPY128  // copy a 128-bit block from *SK to *RK
+    memset( &cty, 0, sizeof( aes_context ) );   // clear local aes context
+    return( 0 );
+}
+
+#endif /* AES_DECRYPTION */
+
+/******************************************************************************
+ *
+ *  AES_SETKEY
+ *
+ *  Invoked to establish the key schedule for subsequent encryption/decryption
+ *
+ ******************************************************************************/
+int aes_setkey( aes_context *ctx,   // AES context provided by our caller
+                int mode,           // ENCRYPT or DECRYPT flag
+                const uchar *key,   // pointer to the key
+                uint keysize )      // key length in bytes
+{
+    // since table initialization is not thread safe, we could either add
+    // system-specific mutexes and init the AES key generation tables on
+    // demand, or ask the developer to simply call "gcm_initialize" once during
+    // application startup before threading begins. That's what we choose.
+    if( !aes_tables_inited ) return ( -1 );  // fail the call when not inited.
+    
+    ctx->mode = mode;       // capture the key type we're creating
+    ctx->rk = ctx->buf;     // initialize our round key pointer
+
+    switch( keysize )       // set the rounds count based upon the keysize
+    {
+        case 16: ctx->rounds = 10; break;   // 16-byte, 128-bit key
+        case 24: ctx->rounds = 12; break;   // 24-byte, 192-bit key
+        case 32: ctx->rounds = 14; break;   // 32-byte, 256-bit key
+	default: return(-1);
+    }
+
+#if AES_DECRYPTION
+    if( mode == DECRYPT )   // expand our key for encryption or decryption
+        return( aes_set_decryption_key( ctx, key, keysize ) );
+    else     /* ENCRYPT */
+#endif /* AES_DECRYPTION */
+        return( aes_set_encryption_key( ctx, key, keysize ) );
+}
+
+/******************************************************************************
+ *
+ *  AES_CIPHER
+ *
+ *  Perform AES encryption and decryption.
+ *  The AES context will have been setup with the encryption mode
+ *  and all keying information appropriate for the task.
+ *
+ ******************************************************************************/
+int aes_cipher( aes_context *ctx,
+                    const uchar input[16],
+                    uchar output[16] )
+{
+    int i;
+    uint32_t *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3;   // general purpose locals
+
+    RK = ctx->rk;
+
+    GET_UINT32_LE( X0, input,  0 ); X0 ^= *RK++;    // load our 128-bit
+    GET_UINT32_LE( X1, input,  4 ); X1 ^= *RK++;    // input buffer in a storage
+    GET_UINT32_LE( X2, input,  8 ); X2 ^= *RK++;    // memory endian-neutral way
+    GET_UINT32_LE( X3, input, 12 ); X3 ^= *RK++;
+
+#if AES_DECRYPTION  // whether AES decryption is supported
+
+    if( ctx->mode == DECRYPT )
+    {
+        for( i = (ctx->rounds >> 1) - 1; i > 0; i-- )
+        {
+            AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 );
+            AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 );
+        }
+
+        AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 );
+
+        X0 = *RK++ ^ \
+                ( (uint32_t) RSb[ ( Y0       ) & 0xFF ]       ) ^
+                ( (uint32_t) RSb[ ( Y3 >>  8 ) & 0xFF ] <<  8 ) ^
+                ( (uint32_t) RSb[ ( Y2 >> 16 ) & 0xFF ] << 16 ) ^
+                ( (uint32_t) RSb[ ( Y1 >> 24 ) & 0xFF ] << 24 );
+
+        X1 = *RK++ ^ \
+                ( (uint32_t) RSb[ ( Y1       ) & 0xFF ]       ) ^
+                ( (uint32_t) RSb[ ( Y0 >>  8 ) & 0xFF ] <<  8 ) ^
+                ( (uint32_t) RSb[ ( Y3 >> 16 ) & 0xFF ] << 16 ) ^
+                ( (uint32_t) RSb[ ( Y2 >> 24 ) & 0xFF ] << 24 );
+
+        X2 = *RK++ ^ \
+                ( (uint32_t) RSb[ ( Y2       ) & 0xFF ]       ) ^
+                ( (uint32_t) RSb[ ( Y1 >>  8 ) & 0xFF ] <<  8 ) ^
+                ( (uint32_t) RSb[ ( Y0 >> 16 ) & 0xFF ] << 16 ) ^
+                ( (uint32_t) RSb[ ( Y3 >> 24 ) & 0xFF ] << 24 );
+
+        X3 = *RK++ ^ \
+                ( (uint32_t) RSb[ ( Y3       ) & 0xFF ]       ) ^
+                ( (uint32_t) RSb[ ( Y2 >>  8 ) & 0xFF ] <<  8 ) ^
+                ( (uint32_t) RSb[ ( Y1 >> 16 ) & 0xFF ] << 16 ) ^
+                ( (uint32_t) RSb[ ( Y0 >> 24 ) & 0xFF ] << 24 );
+    }
+    else /* ENCRYPT */
+    {
+#endif /* AES_DECRYPTION */
+
+        for( i = (ctx->rounds >> 1) - 1; i > 0; i-- )
+        {
+            AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 );
+            AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 );
+        }
+
+        AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 );
+
+        X0 = *RK++ ^ \
+                ( (uint32_t) FSb[ ( Y0       ) & 0xFF ]       ) ^
+                ( (uint32_t) FSb[ ( Y1 >>  8 ) & 0xFF ] <<  8 ) ^
+                ( (uint32_t) FSb[ ( Y2 >> 16 ) & 0xFF ] << 16 ) ^
+                ( (uint32_t) FSb[ ( Y3 >> 24 ) & 0xFF ] << 24 );
+
+        X1 = *RK++ ^ \
+                ( (uint32_t) FSb[ ( Y1       ) & 0xFF ]       ) ^
+                ( (uint32_t) FSb[ ( Y2 >>  8 ) & 0xFF ] <<  8 ) ^
+                ( (uint32_t) FSb[ ( Y3 >> 16 ) & 0xFF ] << 16 ) ^
+                ( (uint32_t) FSb[ ( Y0 >> 24 ) & 0xFF ] << 24 );
+
+        X2 = *RK++ ^ \
+                ( (uint32_t) FSb[ ( Y2       ) & 0xFF ]       ) ^
+                ( (uint32_t) FSb[ ( Y3 >>  8 ) & 0xFF ] <<  8 ) ^
+                ( (uint32_t) FSb[ ( Y0 >> 16 ) & 0xFF ] << 16 ) ^
+                ( (uint32_t) FSb[ ( Y1 >> 24 ) & 0xFF ] << 24 );
+
+        X3 = *RK++ ^ \
+                ( (uint32_t) FSb[ ( Y3       ) & 0xFF ]       ) ^
+                ( (uint32_t) FSb[ ( Y0 >>  8 ) & 0xFF ] <<  8 ) ^
+                ( (uint32_t) FSb[ ( Y1 >> 16 ) & 0xFF ] << 16 ) ^
+                ( (uint32_t) FSb[ ( Y2 >> 24 ) & 0xFF ] << 24 );
+
+#if AES_DECRYPTION  // whether AES decryption is supported
+    }
+#endif /* AES_DECRYPTION */
+
+    PUT_UINT32_LE( X0, output,  0 );
+    PUT_UINT32_LE( X1, output,  4 );
+    PUT_UINT32_LE( X2, output,  8 );
+    PUT_UINT32_LE( X3, output, 12 );
+
+    return( 0 );
+}
+/* end of aes.c */

+ 81 - 0
non_catalog_apps/esubghz_chat/crypto/aes.h

@@ -0,0 +1,81 @@
+/******************************************************************************
+*
+* THIS SOURCE CODE IS HEREBY PLACED INTO THE PUBLIC DOMAIN FOR THE GOOD OF ALL
+*
+* This is a simple and straightforward implementation of the AES Rijndael
+* 128-bit block cipher designed by Vincent Rijmen and Joan Daemen. The focus
+* of this work was correctness & accuracy.  It is written in 'C' without any
+* particular focus upon optimization or speed. It should be endian (memory
+* byte order) neutral since the few places that care are handled explicitly.
+*
+* This implementation of Rijndael was created by Steven M. Gibson of GRC.com.
+*
+* It is intended for general purpose use, but was written in support of GRC's
+* reference implementation of the SQRL (Secure Quick Reliable Login) client.
+*
+* See:    http://csrc.nist.gov/archive/aes/rijndael/wsdindex.html
+*
+* NO COPYRIGHT IS CLAIMED IN THIS WORK, HOWEVER, NEITHER IS ANY WARRANTY MADE
+* REGARDING ITS FITNESS FOR ANY PARTICULAR PURPOSE. USE IT AT YOUR OWN RISK.
+*
+*******************************************************************************/
+
+#ifndef AES_HEADER
+#define AES_HEADER
+
+/******************************************************************************/
+#define AES_DECRYPTION  0       // whether AES decryption is supported
+/******************************************************************************/
+
+#include <string.h>
+
+#define ENCRYPT         1       // specify whether we're encrypting
+#define DECRYPT         0       // or decrypting
+
+#if defined(_MSC_VER)
+    #include <basetsd.h>
+    typedef UINT32 uint32_t;
+#else
+    #include <inttypes.h>
+#endif
+
+typedef unsigned char uchar;    // add some convienent shorter types
+typedef unsigned int uint;
+
+
+/******************************************************************************
+ *  AES_INIT_KEYGEN_TABLES : MUST be called once before any AES use
+ ******************************************************************************/
+void aes_init_keygen_tables( void );
+
+
+/******************************************************************************
+ *  AES_CONTEXT : cipher context / holds inter-call data
+ ******************************************************************************/
+typedef struct {
+    int mode;           // 1 for Encryption, 0 for Decryption
+    int rounds;         // keysize-based rounds count
+    uint32_t *rk;       // pointer to current round key
+    uint32_t buf[68];   // key expansion buffer
+} aes_context;
+
+
+/******************************************************************************
+ *  AES_SETKEY : called to expand the key for encryption or decryption
+ ******************************************************************************/
+int aes_setkey( aes_context *ctx,       // pointer to context
+                int mode,               // 1 or 0 for Encrypt/Decrypt
+                const uchar *key,       // AES input key
+                uint keysize );         // size in bytes (must be 16, 24, 32 for
+		                        // 128, 192 or 256-bit keys respectively)
+                                        // returns 0 for success
+
+/******************************************************************************
+ *  AES_CIPHER : called to encrypt or decrypt ONE 128-bit block of data
+ ******************************************************************************/
+int aes_cipher( aes_context *ctx,       // pointer to context
+                const uchar input[16],  // 128-bit block to en/decipher
+                uchar output[16] );     // 128-bit output result block
+                                        // returns 0 for success
+
+#endif /* AES_HEADER */

+ 511 - 0
non_catalog_apps/esubghz_chat/crypto/gcm.c

@@ -0,0 +1,511 @@
+/******************************************************************************
+*
+* THIS SOURCE CODE IS HEREBY PLACED INTO THE PUBLIC DOMAIN FOR THE GOOD OF ALL
+*
+* This is a simple and straightforward implementation of AES-GCM authenticated
+* encryption. The focus of this work was correctness & accuracy. It is written
+* in straight 'C' without any particular focus upon optimization or speed. It
+* should be endian (memory byte order) neutral since the few places that care
+* are handled explicitly.
+*
+* This implementation of AES-GCM was created by Steven M. Gibson of GRC.com.
+*
+* It is intended for general purpose use, but was written in support of GRC's
+* reference implementation of the SQRL (Secure Quick Reliable Login) client.
+*
+* See:    http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf
+*         http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/
+*         gcm/gcm-revised-spec.pdf
+*
+* NO COPYRIGHT IS CLAIMED IN THIS WORK, HOWEVER, NEITHER IS ANY WARRANTY MADE
+* REGARDING ITS FITNESS FOR ANY PARTICULAR PURPOSE. USE IT AT YOUR OWN RISK.
+*
+*******************************************************************************/
+
+#include "gcm.h"
+#include "aes.h"
+
+/******************************************************************************
+ *                      ==== IMPLEMENTATION WARNING ====
+ *
+ *  This code was developed for use within SQRL's fixed environmnent. Thus, it
+ *  is somewhat less "general purpose" than it would be if it were designed as
+ *  a general purpose AES-GCM library. Specifically, it bothers with almost NO
+ *  error checking on parameter limits, buffer bounds, etc. It assumes that it
+ *  is being invoked by its author or by someone who understands the values it
+ *  expects to receive. Its behavior will be undefined otherwise.
+ *
+ *  All functions that might fail are defined to return 'ints' to indicate a
+ *  problem. Most do not do so now. But this allows for error propagation out
+ *  of internal functions if robust error checking should ever be desired.
+ *
+ ******************************************************************************/
+
+/* Calculating the "GHASH"
+ *
+ * There are many ways of calculating the so-called GHASH in software, each with
+ * a traditional size vs performance tradeoff.  The GHASH (Galois field hash) is
+ * an intriguing construction which takes two 128-bit strings (also the cipher's
+ * block size and the fundamental operation size for the system) and hashes them
+ * into a third 128-bit result.
+ *
+ * Many implementation solutions have been worked out that use large precomputed
+ * table lookups in place of more time consuming bit fiddling, and this approach
+ * can be scaled easily upward or downward as needed to change the time/space
+ * tradeoff. It's been studied extensively and there's a solid body of theory and
+ * practice.  For example, without using any lookup tables an implementation
+ * might obtain 119 cycles per byte throughput, whereas using a simple, though
+ * large, key-specific 64 kbyte 8-bit lookup table the performance jumps to 13
+ * cycles per byte.
+ *
+ * And Intel's processors have, since 2010, included an instruction which does
+ * the entire 128x128->128 bit job in just several 64x64->128 bit pieces.
+ *
+ * Since SQRL is interactive, and only processing a few 128-bit blocks, I've
+ * settled upon a relatively slower but appealing small-table compromise which
+ * folds a bunch of not only time consuming but also bit twiddling into a simple
+ * 16-entry table which is attributed to Victor Shoup's 1996 work while at
+ * Bellcore: "On Fast and Provably Secure MessageAuthentication Based on
+ * Universal Hashing."  See: http://www.shoup.net/papers/macs.pdf
+ * See, also section 4.1 of the "gcm-revised-spec" cited above.
+ */
+
+/*
+ *  This 16-entry table of pre-computed constants is used by the
+ *  GHASH multiplier to improve over a strictly table-free but
+ *  significantly slower 128x128 bit multiple within GF(2^128).
+ */
+static const uint64_t last4[16] = {
+    0x0000, 0x1c20, 0x3840, 0x2460, 0x7080, 0x6ca0, 0x48c0, 0x54e0,
+    0xe100, 0xfd20, 0xd940, 0xc560, 0x9180, 0x8da0, 0xa9c0, 0xb5e0  };
+
+/*
+ * Platform Endianness Neutralizing Load and Store Macro definitions
+ * GCM wants platform-neutral Big Endian (BE) byte ordering
+ */
+#define GET_UINT32_BE(n,b,i) {                      \
+    (n) = ( (uint32_t) (b)[(i)    ] << 24 )         \
+        | ( (uint32_t) (b)[(i) + 1] << 16 )         \
+        | ( (uint32_t) (b)[(i) + 2] <<  8 )         \
+        | ( (uint32_t) (b)[(i) + 3]       ); }
+
+#define PUT_UINT32_BE(n,b,i) {                      \
+    (b)[(i)    ] = (uchar) ( (n) >> 24 );   \
+    (b)[(i) + 1] = (uchar) ( (n) >> 16 );   \
+    (b)[(i) + 2] = (uchar) ( (n) >>  8 );   \
+    (b)[(i) + 3] = (uchar) ( (n)       ); }
+
+
+/******************************************************************************
+ *
+ *  GCM_INITIALIZE
+ *
+ *  Must be called once to initialize the GCM library.
+ *
+ *  At present, this only calls the AES keygen table generator, which expands
+ *  the AES keying tables for use. This is NOT A THREAD-SAFE function, so it
+ *  MUST be called during system initialization before a multi-threading
+ *  environment is running.
+ *
+ ******************************************************************************/
+int gcm_initialize( void )
+{
+    aes_init_keygen_tables();
+    return( 0 );
+}
+
+
+/******************************************************************************
+ *
+ *  GCM_MULT
+ *
+ *  Performs a GHASH operation on the 128-bit input vector 'x', setting
+ *  the 128-bit output vector to 'x' times H using our precomputed tables.
+ *  'x' and 'output' are seen as elements of GCM's GF(2^128) Galois field.
+ *
+ ******************************************************************************/
+static void gcm_mult( gcm_context *ctx,     // pointer to established context
+                      const uchar x[16],    // pointer to 128-bit input vector
+                      uchar output[16] )    // pointer to 128-bit output vector
+{
+    int i;
+    uchar lo, hi, rem;
+    uint64_t zh, zl;
+
+    lo = (uchar)( x[15] & 0x0f );
+    hi = (uchar)( x[15] >> 4 );
+    zh = ctx->HH[lo];
+    zl = ctx->HL[lo];
+
+    for( i = 15; i >= 0; i-- ) {
+        lo = (uchar) ( x[i] & 0x0f );
+        hi = (uchar) ( x[i] >> 4 );
+
+        if( i != 15 ) {
+            rem = (uchar) ( zl & 0x0f );
+            zl = ( zh << 60 ) | ( zl >> 4 );
+            zh = ( zh >> 4 );
+            zh ^= (uint64_t) last4[rem] << 48;
+            zh ^= ctx->HH[lo];
+            zl ^= ctx->HL[lo];
+        }
+        rem = (uchar) ( zl & 0x0f );
+        zl = ( zh << 60 ) | ( zl >> 4 );
+        zh = ( zh >> 4 );
+        zh ^= (uint64_t) last4[rem] << 48;
+        zh ^= ctx->HH[hi];
+        zl ^= ctx->HL[hi];
+    }
+    PUT_UINT32_BE( zh >> 32, output, 0 );
+    PUT_UINT32_BE( zh, output, 4 );
+    PUT_UINT32_BE( zl >> 32, output, 8 );
+    PUT_UINT32_BE( zl, output, 12 );
+}
+
+
+/******************************************************************************
+ *
+ *  GCM_SETKEY
+ *
+ *  This is called to set the AES-GCM key. It initializes the AES key
+ *  and populates the gcm context's pre-calculated HTables.
+ *
+ ******************************************************************************/
+int gcm_setkey( gcm_context *ctx,   // pointer to caller-provided gcm context
+                const uchar *key,   // pointer to the AES encryption key
+                const uint keysize) // size in bytes (must be 16, 24, 32 for
+		                    // 128, 192 or 256-bit keys respectively)
+{
+    int ret, i, j;
+    uint64_t hi, lo;
+    uint64_t vl, vh;
+    unsigned char h[16];
+
+    memset( ctx, 0, sizeof(gcm_context) );  // zero caller-provided GCM context
+    memset( h, 0, 16 );                     // initialize the block to encrypt
+
+    // encrypt the null 128-bit block to generate a key-based value
+    // which is then used to initialize our GHASH lookup tables
+    if(( ret = aes_setkey( &ctx->aes_ctx, ENCRYPT, key, keysize )) != 0 )
+        return( ret );
+    if(( ret = aes_cipher( &ctx->aes_ctx, h, h )) != 0 )
+        return( ret );
+
+    GET_UINT32_BE( hi, h,  0  );    // pack h as two 64-bit ints, big-endian
+    GET_UINT32_BE( lo, h,  4  );
+    vh = (uint64_t) hi << 32 | lo;
+
+    GET_UINT32_BE( hi, h,  8  );
+    GET_UINT32_BE( lo, h,  12 );
+    vl = (uint64_t) hi << 32 | lo;
+
+    ctx->HL[8] = vl;                // 8 = 1000 corresponds to 1 in GF(2^128)
+    ctx->HH[8] = vh;
+    ctx->HH[0] = 0;                 // 0 corresponds to 0 in GF(2^128)
+    ctx->HL[0] = 0;
+
+    for( i = 4; i > 0; i >>= 1 ) {
+        uint32_t T = (uint32_t) ( vl & 1 ) * 0xe1000000U;
+        vl  = ( vh << 63 ) | ( vl >> 1 );
+        vh  = ( vh >> 1 ) ^ ( (uint64_t) T << 32);
+        ctx->HL[i] = vl;
+        ctx->HH[i] = vh;
+    }
+    for (i = 2; i < 16; i <<= 1 ) {
+        uint64_t *HiL = ctx->HL + i, *HiH = ctx->HH + i;
+        vh = *HiH;
+        vl = *HiL;
+        for( j = 1; j < i; j++ ) {
+            HiH[j] = vh ^ ctx->HH[j];
+            HiL[j] = vl ^ ctx->HL[j];
+        }
+    }
+    return( 0 );
+}
+
+
+/******************************************************************************
+ *
+ *    GCM processing occurs four phases: SETKEY, START, UPDATE and FINISH.
+ *
+ *  SETKEY: 
+ *  
+ *   START: Sets the Encryption/Decryption mode.
+ *          Accepts the initialization vector and additional data.
+ *
+ *  UPDATE: Encrypts or decrypts the plaintext or ciphertext.
+ *
+ *  FINISH: Performs a final GHASH to generate the authentication tag.
+ *
+ ******************************************************************************
+ *
+ *  GCM_START
+ *
+ *  Given a user-provided GCM context, this initializes it, sets the encryption
+ *  mode, and preprocesses the initialization vector and additional AEAD data.
+ *
+ ******************************************************************************/
+int gcm_start( gcm_context *ctx,    // pointer to user-provided GCM context
+               int mode,            // GCM_ENCRYPT or GCM_DECRYPT
+               const uchar *iv,     // pointer to initialization vector
+               size_t iv_len,       // IV length in bytes (should == 12)
+               const uchar *add,    // ptr to additional AEAD data (NULL if none)
+               size_t add_len )     // length of additional AEAD data (bytes)
+{
+    int ret;            // our error return if the AES encrypt fails
+    uchar work_buf[16]; // XOR source built from provided IV if len != 16
+    const uchar *p;     // general purpose array pointer
+    size_t use_len;     // byte count to process, up to 16 bytes
+    size_t i;           // local loop iterator
+
+    // since the context might be reused under the same key
+    // we zero the working buffers for this next new process
+    memset( ctx->y,   0x00, sizeof(ctx->y  ) );
+    memset( ctx->buf, 0x00, sizeof(ctx->buf) );
+    ctx->len = 0;
+    ctx->add_len = 0;
+
+    ctx->mode = mode;               // set the GCM encryption/decryption mode
+    ctx->aes_ctx.mode = ENCRYPT;    // GCM *always* runs AES in ENCRYPTION mode
+
+    if( iv_len == 12 ) {                // GCM natively uses a 12-byte, 96-bit IV
+        memcpy( ctx->y, iv, iv_len );   // copy the IV to the top of the 'y' buff
+        ctx->y[15] = 1;                 // start "counting" from 1 (not 0)
+    }
+    else    // if we don't have a 12-byte IV, we GHASH whatever we've been given
+    {   
+        memset( work_buf, 0x00, 16 );               // clear the working buffer
+        PUT_UINT32_BE( iv_len * 8, work_buf, 12 );  // place the IV into buffer
+
+        p = iv;
+        while( iv_len > 0 ) {
+            use_len = ( iv_len < 16 ) ? iv_len : 16;
+            for( i = 0; i < use_len; i++ ) ctx->y[i] ^= p[i];
+            gcm_mult( ctx, ctx->y, ctx->y );
+            iv_len -= use_len;
+            p += use_len;
+        }
+        for( i = 0; i < 16; i++ ) ctx->y[i] ^= work_buf[i];
+        gcm_mult( ctx, ctx->y, ctx->y );
+    }
+    if( ( ret = aes_cipher( &ctx->aes_ctx, ctx->y, ctx->base_ectr ) ) != 0 )
+        return( ret );
+
+    ctx->add_len = add_len;
+    p = add;
+    while( add_len > 0 ) {
+        use_len = ( add_len < 16 ) ? add_len : 16;
+        for( i = 0; i < use_len; i++ ) ctx->buf[i] ^= p[i];
+        gcm_mult( ctx, ctx->buf, ctx->buf );
+        add_len -= use_len;
+        p += use_len;
+    }
+    return( 0 );
+}
+
+/******************************************************************************
+ *
+ *  GCM_UPDATE
+ *
+ *  This is called once or more to process bulk plaintext or ciphertext data.
+ *  We give this some number of bytes of input and it returns the same number
+ *  of output bytes. If called multiple times (which is fine) all but the final
+ *  invocation MUST be called with length mod 16 == 0. (Only the final call can
+ *  have a partial block length of < 128 bits.)
+ *
+ ******************************************************************************/
+int gcm_update( gcm_context *ctx,       // pointer to user-provided GCM context
+                size_t length,          // length, in bytes, of data to process
+                const uchar *input,     // pointer to source data
+                uchar *output )         // pointer to destination data
+{
+    int ret;            // our error return if the AES encrypt fails
+    uchar ectr[16];     // counter-mode cipher output for XORing
+    size_t use_len;     // byte count to process, up to 16 bytes
+    size_t i;           // local loop iterator
+
+    ctx->len += length; // bump the GCM context's running length count
+
+    while( length > 0 ) {
+        // clamp the length to process at 16 bytes
+        use_len = ( length < 16 ) ? length : 16;
+
+        // increment the context's 128-bit IV||Counter 'y' vector
+        for( i = 16; i > 12; i-- ) if( ++ctx->y[i - 1] != 0 ) break;
+
+        // encrypt the context's 'y' vector under the established key
+        if( ( ret = aes_cipher( &ctx->aes_ctx, ctx->y, ectr ) ) != 0 )
+            return( ret );
+
+        // encrypt or decrypt the input to the output
+        if( ctx->mode == ENCRYPT )  
+        {
+             for( i = 0; i < use_len; i++ ) {
+                // XOR the cipher's ouptut vector (ectr) with our input
+                output[i] = (uchar) ( ectr[i] ^ input[i] );
+                // now we mix in our data into the authentication hash.
+                // if we're ENcrypting we XOR in the post-XOR (output) 
+                // results, but if we're DEcrypting we XOR in the input 
+                // data
+                ctx->buf[i] ^= output[i];
+            }
+        }
+            else                        
+        {
+            for( i = 0; i < use_len; i++ ) {
+                // but if we're DEcrypting we XOR in the input data first, 
+                // i.e. before saving to ouput data, otherwise if the input 
+                // and output buffer are the same (inplace decryption) we 
+                // would not get the correct auth tag
+
+       	        ctx->buf[i] ^= input[i];
+
+                // XOR the cipher's ouptut vector (ectr) with our input
+                output[i] = (uchar) ( ectr[i] ^ input[i] );
+             }
+        }
+        gcm_mult( ctx, ctx->buf, ctx->buf );    // perform a GHASH operation
+
+        length -= use_len;  // drop the remaining byte count to process
+        input  += use_len;  // bump our input pointer forward
+        output += use_len;  // bump our output pointer forward
+    }
+    return( 0 );
+}
+
+/******************************************************************************
+ *
+ *  GCM_FINISH
+ *
+ *  This is called once after all calls to GCM_UPDATE to finalize the GCM.
+ *  It performs the final GHASH to produce the resulting authentication TAG.
+ *
+ ******************************************************************************/
+int gcm_finish( gcm_context *ctx,   // pointer to user-provided GCM context
+                uchar *tag,         // pointer to buffer which receives the tag
+                size_t tag_len )    // length, in bytes, of the tag-receiving buf
+{
+    uchar work_buf[16];
+    uint64_t orig_len     = ctx->len * 8;
+    uint64_t orig_add_len = ctx->add_len * 8;
+    size_t i;
+
+    if( tag_len != 0 ) memcpy( tag, ctx->base_ectr, tag_len );
+
+    if( orig_len || orig_add_len ) {
+        memset( work_buf, 0x00, 16 );
+
+        PUT_UINT32_BE( ( orig_add_len >> 32 ), work_buf, 0  );
+        PUT_UINT32_BE( ( orig_add_len       ), work_buf, 4  );
+        PUT_UINT32_BE( ( orig_len     >> 32 ), work_buf, 8  );
+        PUT_UINT32_BE( ( orig_len           ), work_buf, 12 );
+
+        for( i = 0; i < 16; i++ ) ctx->buf[i] ^= work_buf[i];
+        gcm_mult( ctx, ctx->buf, ctx->buf );
+        for( i = 0; i < tag_len; i++ ) tag[i] ^= ctx->buf[i];
+    }
+    return( 0 );
+}
+
+
+/******************************************************************************
+ *
+ *  GCM_CRYPT_AND_TAG
+ *
+ *  This either encrypts or decrypts the user-provided data and, either
+ *  way, generates an authentication tag of the requested length. It must be
+ *  called with a GCM context whose key has already been set with GCM_SETKEY.
+ *
+ *  The user would typically call this explicitly to ENCRYPT a buffer of data
+ *  and optional associated data, and produce its an authentication tag.
+ *
+ *  To reverse the process the user would typically call the companion
+ *  GCM_AUTH_DECRYPT function to decrypt data and verify a user-provided
+ *  authentication tag.  The GCM_AUTH_DECRYPT function calls this function
+ *  to perform its decryption and tag generation, which it then compares.
+ *
+ ******************************************************************************/
+int gcm_crypt_and_tag(
+        gcm_context *ctx,       // gcm context with key already setup
+        int mode,               // cipher direction: GCM_ENCRYPT or GCM_DECRYPT
+        const uchar *iv,        // pointer to the 12-byte initialization vector
+        size_t iv_len,          // byte length if the IV. should always be 12
+        const uchar *add,       // pointer to the non-ciphered additional data
+        size_t add_len,         // byte length of the additional AEAD data
+        const uchar *input,     // pointer to the cipher data source
+        uchar *output,          // pointer to the cipher data destination
+        size_t length,          // byte length of the cipher data
+        uchar *tag,             // pointer to the tag to be generated
+        size_t tag_len )        // byte length of the tag to be generated
+{   /*
+       assuming that the caller has already invoked gcm_setkey to
+       prepare the gcm context with the keying material, we simply
+       invoke each of the three GCM sub-functions in turn...
+    */
+    gcm_start  ( ctx, mode, iv, iv_len, add, add_len );
+    gcm_update ( ctx, length, input, output );
+    gcm_finish ( ctx, tag, tag_len );
+    return( 0 );
+}
+
+
+/******************************************************************************
+ *
+ *  GCM_AUTH_DECRYPT
+ *
+ *  This DECRYPTS a user-provided data buffer with optional associated data.
+ *  It then verifies a user-supplied authentication tag against the tag just
+ *  re-created during decryption to verify that the data has not been altered.
+ *
+ *  This function calls GCM_CRYPT_AND_TAG (above) to perform the decryption
+ *  and authentication tag generation.
+ *
+ ******************************************************************************/
+int gcm_auth_decrypt(
+        gcm_context *ctx,       // gcm context with key already setup
+        const uchar *iv,        // pointer to the 12-byte initialization vector
+        size_t iv_len,          // byte length if the IV. should always be 12
+        const uchar *add,       // pointer to the non-ciphered additional data
+        size_t add_len,         // byte length of the additional AEAD data
+        const uchar *input,     // pointer to the cipher data source
+        uchar *output,          // pointer to the cipher data destination
+        size_t length,          // byte length of the cipher data
+        const uchar *tag,       // pointer to the tag to be authenticated
+        size_t tag_len )        // byte length of the tag <= 16
+{
+    uchar check_tag[16];        // the tag generated and returned by decryption
+    int diff;                   // an ORed flag to detect authentication errors
+    size_t i;                   // our local iterator
+    /*
+       we use GCM_DECRYPT_AND_TAG (above) to perform our decryption
+       (which is an identical XORing to reverse the previous one)
+       and also to re-generate the matching authentication tag
+    */
+    gcm_crypt_and_tag(  ctx, DECRYPT, iv, iv_len, add, add_len,
+                        input, output, length, check_tag, tag_len );
+
+    // now we verify the authentication tag in 'constant time'
+    for( diff = 0, i = 0; i < tag_len; i++ )
+        diff |= tag[i] ^ check_tag[i];
+
+    if( diff != 0 ) {                   // see whether any bits differed?
+        memset( output, 0, length );    // if so... wipe the output data
+        return( GCM_AUTH_FAILURE );     // return GCM_AUTH_FAILURE
+    }
+    return( 0 );
+}
+
+/******************************************************************************
+ *
+ *  GCM_ZERO_CTX
+ *
+ *  The GCM context contains both the GCM context and the AES context.
+ *  This includes keying and key-related material which is security-
+ *  sensitive, so it MUST be zeroed after use. This function does that.
+ *
+ ******************************************************************************/
+void gcm_zero_ctx( gcm_context *ctx )
+{
+    // zero the context originally provided to us
+    memset( ctx, 0, sizeof( gcm_context ) );
+}

+ 187 - 0
non_catalog_apps/esubghz_chat/crypto/gcm.h

@@ -0,0 +1,187 @@
+/******************************************************************************
+*
+* THIS SOURCE CODE IS HEREBY PLACED INTO THE PUBLIC DOMAIN FOR THE GOOD OF ALL
+*
+* This is a simple and straightforward implementation of AES-GCM authenticated
+* encryption. The focus of this work was correctness & accuracy. It is written
+* in straight 'C' without any particular focus upon optimization or speed. It
+* should be endian (memory byte order) neutral since the few places that care
+* are handled explicitly.
+*
+* This implementation of AES-GCM was created by Steven M. Gibson of GRC.com.
+*
+* It is intended for general purpose use, but was written in support of GRC's
+* reference implementation of the SQRL (Secure Quick Reliable Login) client.
+*
+* See:    http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf
+*         http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/ \
+*         gcm/gcm-revised-spec.pdf
+*
+* NO COPYRIGHT IS CLAIMED IN THIS WORK, HOWEVER, NEITHER IS ANY WARRANTY MADE
+* REGARDING ITS FITNESS FOR ANY PARTICULAR PURPOSE. USE IT AT YOUR OWN RISK.
+*
+*******************************************************************************/
+#ifndef GCM_HEADER
+#define GCM_HEADER
+
+#define GCM_AUTH_FAILURE    0x55555555  // authentication failure
+
+#include "aes.h"                        // gcm_context includes aes_context
+
+#if defined(_MSC_VER)
+    #include <basetsd.h>
+    typedef unsigned int size_t;// use the right type for length declarations
+    typedef UINT32 uint32_t;
+    typedef UINT64 uint64_t;
+#else
+    #include <stdint.h>
+#endif
+
+
+/******************************************************************************
+ *  GCM_CONTEXT : GCM context / holds keytables, instance data, and AES ctx
+ ******************************************************************************/
+typedef struct {
+    int mode;               // cipher direction: encrypt/decrypt
+    uint64_t len;           // cipher data length processed so far
+    uint64_t add_len;       // total add data length
+    uint64_t HL[16];        // precalculated lo-half HTable
+    uint64_t HH[16];        // precalculated hi-half HTable
+    uchar base_ectr[16];    // first counter-mode cipher output for tag
+    uchar y[16];            // the current cipher-input IV|Counter value
+    uchar buf[16];          // buf working value
+    aes_context aes_ctx;    // cipher context used
+} gcm_context;
+
+
+/******************************************************************************
+ *  GCM_CONTEXT : MUST be called once before ANY use of this library
+ ******************************************************************************/
+int gcm_initialize( void );
+
+
+/******************************************************************************
+ *  GCM_SETKEY : sets the GCM (and AES) keying material for use
+ ******************************************************************************/
+int gcm_setkey( gcm_context *ctx,   // caller-provided context ptr
+                const uchar *key,   // pointer to cipher key
+                const uint keysize  // size in bytes (must be 16, 24, 32 for
+		                    // 128, 192 or 256-bit keys respectively)
+); // returns 0 for success
+
+
+/******************************************************************************
+ *
+ *  GCM_CRYPT_AND_TAG
+ *
+ *  This either encrypts or decrypts the user-provided data and, either
+ *  way, generates an authentication tag of the requested length. It must be
+ *  called with a GCM context whose key has already been set with GCM_SETKEY.
+ *
+ *  The user would typically call this explicitly to ENCRYPT a buffer of data
+ *  and optional associated data, and produce its an authentication tag.
+ *
+ *  To reverse the process the user would typically call the companion
+ *  GCM_AUTH_DECRYPT function to decrypt data and verify a user-provided
+ *  authentication tag.  The GCM_AUTH_DECRYPT function calls this function
+ *  to perform its decryption and tag generation, which it then compares.
+ *
+ ******************************************************************************/
+int gcm_crypt_and_tag(
+        gcm_context *ctx,       // gcm context with key already setup
+        int mode,               // cipher direction: ENCRYPT (1) or DECRYPT (0)
+        const uchar *iv,        // pointer to the 12-byte initialization vector
+        size_t iv_len,          // byte length if the IV. should always be 12
+        const uchar *add,       // pointer to the non-ciphered additional data
+        size_t add_len,         // byte length of the additional AEAD data
+        const uchar *input,     // pointer to the cipher data source
+        uchar *output,          // pointer to the cipher data destination
+        size_t length,          // byte length of the cipher data
+        uchar *tag,             // pointer to the tag to be generated
+        size_t tag_len );       // byte length of the tag to be generated
+
+
+/******************************************************************************
+ *
+ *  GCM_AUTH_DECRYPT
+ *
+ *  This DECRYPTS a user-provided data buffer with optional associated data.
+ *  It then verifies a user-supplied authentication tag against the tag just
+ *  re-created during decryption to verify that the data has not been altered.
+ *
+ *  This function calls GCM_CRYPT_AND_TAG (above) to perform the decryption
+ *  and authentication tag generation.
+ *
+ ******************************************************************************/
+int gcm_auth_decrypt(
+        gcm_context *ctx,       // gcm context with key already setup
+        const uchar *iv,        // pointer to the 12-byte initialization vector
+        size_t iv_len,          // byte length if the IV. should always be 12
+        const uchar *add,       // pointer to the non-ciphered additional data
+        size_t add_len,         // byte length of the additional AEAD data
+        const uchar *input,     // pointer to the cipher data source
+        uchar *output,          // pointer to the cipher data destination
+        size_t length,          // byte length of the cipher data
+        const uchar *tag,       // pointer to the tag to be authenticated
+        size_t tag_len );       // byte length of the tag <= 16
+
+
+/******************************************************************************
+ *
+ *  GCM_START
+ *
+ *  Given a user-provided GCM context, this initializes it, sets the encryption
+ *  mode, and preprocesses the initialization vector and additional AEAD data.
+ *
+ ******************************************************************************/
+int gcm_start( gcm_context *ctx,    // pointer to user-provided GCM context
+               int mode,            // ENCRYPT (1) or DECRYPT (0)
+               const uchar *iv,     // pointer to initialization vector
+               size_t iv_len,       // IV length in bytes (should == 12)
+               const uchar *add,    // pointer to additional AEAD data (NULL if none)
+               size_t add_len );    // length of additional AEAD data (bytes)
+
+
+/******************************************************************************
+ *
+ *  GCM_UPDATE
+ *
+ *  This is called once or more to process bulk plaintext or ciphertext data.
+ *  We give this some number of bytes of input and it returns the same number
+ *  of output bytes. If called multiple times (which is fine) all but the final
+ *  invocation MUST be called with length mod 16 == 0. (Only the final call can
+ *  have a partial block length of < 128 bits.)
+ *
+ ******************************************************************************/
+int gcm_update( gcm_context *ctx,       // pointer to user-provided GCM context
+                size_t length,          // length, in bytes, of data to process
+                const uchar *input,     // pointer to source data
+                uchar *output );        // pointer to destination data
+
+
+/******************************************************************************
+ *
+ *  GCM_FINISH
+ *
+ *  This is called once after all calls to GCM_UPDATE to finalize the GCM.
+ *  It performs the final GHASH to produce the resulting authentication TAG.
+ *
+ ******************************************************************************/
+int gcm_finish( gcm_context *ctx,   // pointer to user-provided GCM context
+                uchar *tag,         // ptr to tag buffer - NULL if tag_len = 0
+                size_t tag_len );   // length, in bytes, of the tag-receiving buf
+
+
+/******************************************************************************
+ *
+ *  GCM_ZERO_CTX
+ *
+ *  The GCM context contains both the GCM context and the AES context.
+ *  This includes keying and key-related material which is security-
+ *  sensitive, so it MUST be zeroed after use. This function does that.
+ *
+ ******************************************************************************/
+void gcm_zero_ctx( gcm_context *ctx );
+
+
+#endif /* GCM_HEADER */

+ 1132 - 0
non_catalog_apps/esubghz_chat/esubghz_chat.c

@@ -0,0 +1,1132 @@
+#include <furi.h>
+#include <furi_hal.h>
+#include <gui/elements.h>
+#include <gui/gui.h>
+#include <gui/modules/text_box.h>
+#include <gui/modules/text_input.h>
+#include <gui/view_dispatcher_i.h>
+#include <gui/view_port_i.h>
+#include <gui/scene_manager.h>
+#include <toolbox/sha256.h>
+#include <notification/notification_messages.h>
+#include <lib/subghz/devices/cc1101_int/cc1101_int_interconnect.h>
+#include <lib/subghz/subghz_tx_rx_worker.h>
+
+#include "esubghz_chat_icons.h"
+
+#include "crypto/gcm.h"
+
+#define APPLICATION_NAME "ESubGhzChat"
+
+#define DEFAULT_FREQ 433920000
+
+#define KEY_BITS 256
+#define IV_BYTES 12
+#define TAG_BYTES 16
+
+#define RX_TX_BUFFER_SIZE 1024
+
+#define CHAT_BOX_STORE_SIZE 4096
+#define TEXT_INPUT_STORE_SIZE 256
+
+#define TICK_INTERVAL 50
+#define MESSAGE_COMPLETION_TIMEOUT 500
+#define TIMEOUT_BETWEEN_MESSAGES 500
+#define CHAT_LEAVE_DELAY 10
+
+#define KBD_UNLOCK_CNT 3
+#define KBD_UNLOCK_TIMEOUT 1000
+
+typedef struct {
+	SceneManager *scene_manager;
+	ViewDispatcher *view_dispatcher;
+	NotificationApp *notification;
+
+	// UI elements
+	TextBox *chat_box;
+	FuriString *chat_box_store;
+	TextInput *text_input;
+	char text_input_store[TEXT_INPUT_STORE_SIZE + 1];
+
+	// for Sub-GHz
+	uint32_t frequency;
+	SubGhzTxRxWorker *subghz_worker;
+	const SubGhzDevice *subghz_device;
+
+	// message assembly before TX
+	FuriString *name_prefix;
+	FuriString *msg_input;
+
+	// encryption
+	bool encrypted;
+	gcm_context gcm_ctx;
+
+	// RX and TX buffers
+	uint8_t rx_buffer[RX_TX_BUFFER_SIZE];
+	uint8_t tx_buffer[RX_TX_BUFFER_SIZE];
+	char rx_str_buffer[RX_TX_BUFFER_SIZE + 1];
+	volatile uint32_t last_time_rx_data;
+
+	// for locking
+	ViewPortDrawCallback orig_draw_cb;
+	ViewPortInputCallback orig_input_cb;
+	bool kbd_locked;
+	uint32_t kbd_lock_msg_ticks;
+	uint8_t kbd_lock_count;
+	bool kbd_ok_input_ongoing;
+} ESubGhzChatState;
+
+typedef enum {
+	ESubGhzChatScene_FreqInput,
+	ESubGhzChatScene_PassInput,
+	ESubGhzChatScene_ChatInput,
+	ESubGhzChatScene_ChatBox,
+	ESubGhzChatScene_MAX
+} ESubGhzChatScene;
+
+typedef enum {
+	ESubGhzChatView_Input,
+	ESubGhzChatView_ChatBox,
+} ESubGhzChatView;
+
+typedef enum {
+	ESubGhzChatEvent_FreqEntered,
+	ESubGhzChatEvent_PassEntered,
+	ESubGhzChatEvent_MsgEntered
+} ESubGhzChatEvent;
+
+/* Function to clear sensitive memory. */
+static void esubghz_chat_explicit_bzero(void *s, size_t len)
+{
+	memset(s, 0, len);
+	asm volatile("" ::: "memory");
+}
+
+/* Callback for RX events from the Sub-GHz worker. Records the current ticks as
+ * the time of the last reception. */
+static void have_read_cb(void* context)
+{
+	furi_assert(context);
+	ESubGhzChatState* state = context;
+
+	state->last_time_rx_data = furi_get_tick();
+}
+
+/* Decrypts a message for post_rx(). */
+static bool post_rx_decrypt(ESubGhzChatState *state, size_t rx_size)
+{
+	if (rx_size < IV_BYTES + TAG_BYTES + 1) {
+		return false;
+	}
+
+	int ret = gcm_auth_decrypt(&(state->gcm_ctx),
+			state->rx_buffer, IV_BYTES,
+			NULL, 0,
+			state->rx_buffer + IV_BYTES,
+			(uint8_t *) state->rx_str_buffer,
+			rx_size - (IV_BYTES + TAG_BYTES),
+			state->rx_buffer + rx_size - TAG_BYTES,
+			TAG_BYTES);
+	state->rx_str_buffer[rx_size - (IV_BYTES + TAG_BYTES)] = 0;
+
+	return (ret == 0);
+}
+
+/* Post RX handler, decrypts received messages, displays them in the text box
+ * and sends a notification. */
+static void post_rx(ESubGhzChatState *state, size_t rx_size)
+{
+	furi_assert(state);
+
+	if (rx_size == 0) {
+		return;
+	}
+
+	furi_check(rx_size <= RX_TX_BUFFER_SIZE);
+
+	/* decrypt if necessary */
+	if (!state->encrypted) {
+		memcpy(state->rx_str_buffer, state->rx_buffer, rx_size);
+		state->rx_str_buffer[rx_size] = 0;
+
+		/* remove trailing newline if it is there, for compat with CLI
+		 * Sub-GHz chat */
+		if (state->rx_str_buffer[rx_size - 1] == '\n') {
+			state->rx_str_buffer[rx_size - 1] = 0;
+		}
+	} else {
+		/* if decryption fails output an error message */
+		if (!post_rx_decrypt(state, rx_size)) {
+			strcpy(state->rx_str_buffer, "ERR: Decryption failed!");
+		}
+	}
+
+	/* append message to text box */
+	furi_string_cat_printf(state->chat_box_store, "\n%s",
+			state->rx_str_buffer);
+
+	/* send notification (make the flipper vibrate) */
+	notification_message(state->notification, &sequence_single_vibro);
+
+	/* reset text box contents and focus */
+	text_box_set_text(state->chat_box,
+			furi_string_get_cstr(state->chat_box_store));
+	text_box_set_focus(state->chat_box, TextBoxFocusEnd);
+}
+
+/* Reads the message from msg_input, encrypts it if necessary and then
+ * transmits it. */
+static void tx_msg_input(ESubGhzChatState *state)
+{
+	/* encrypt message if necessary */
+	size_t msg_len = strlen(furi_string_get_cstr(state->msg_input));
+	size_t tx_size = msg_len;
+	if (state->encrypted) {
+		tx_size += IV_BYTES + TAG_BYTES;
+		furi_check(tx_size <= sizeof(state->tx_buffer));
+
+		furi_hal_random_fill_buf(state->tx_buffer, IV_BYTES);
+		gcm_crypt_and_tag(&(state->gcm_ctx), ENCRYPT,
+				state->tx_buffer, IV_BYTES,
+				NULL, 0,
+				(unsigned char *)
+				furi_string_get_cstr(state->msg_input),
+				state->tx_buffer + IV_BYTES,
+				msg_len,
+				state->tx_buffer + IV_BYTES + msg_len,
+				TAG_BYTES);
+	} else {
+		tx_size += 2;
+		furi_check(tx_size <= sizeof(state->tx_buffer));
+		memcpy(state->tx_buffer,
+				furi_string_get_cstr(state->msg_input),
+				msg_len);
+
+		/* append \r\n for compat with Sub-GHz CLI chat */
+		state->tx_buffer[msg_len] = '\r';
+		state->tx_buffer[msg_len + 1] = '\n';
+	}
+
+	/* transmit */
+	subghz_tx_rx_worker_write(state->subghz_worker, state->tx_buffer,
+			tx_size);
+}
+
+/* Sends FreqEntered event to scene manager and displays the frequency in the
+ * text box. */
+static void freq_input_cb(void *context)
+{
+	furi_assert(context);
+	ESubGhzChatState* state = context;
+
+	furi_string_cat_printf(state->chat_box_store, "Frequency: %lu",
+			state->frequency);
+
+	scene_manager_handle_custom_event(state->scene_manager,
+			ESubGhzChatEvent_FreqEntered);
+}
+
+/* Validates the entered frequency. */
+static bool freq_input_validator(const char *text, FuriString *error,
+		void *context)
+{
+	furi_assert(text);
+	furi_assert(error);
+
+	furi_assert(context);
+	ESubGhzChatState* state = context;
+
+        int ret = sscanf(text, "%lu", &(state->frequency));
+	if (ret != 1) {
+		furi_string_printf(error, "Please enter\nfrequency\nin Hz!");
+		return false;
+	}
+
+	if (!subghz_devices_is_frequency_valid(state->subghz_device,
+				state->frequency)) {
+		furi_string_printf(error, "Frequency\n%lu\n is invalid!",
+				state->frequency);
+		return false;
+	}
+
+#ifdef FW_ORIGIN_Official
+	if (!furi_hal_region_is_frequency_allowed(state->frequency)) {
+#else /* FW_ORIGIN_Official */
+	if (!furi_hal_subghz_is_tx_allowed(state->frequency)) {
+#endif /* FW_ORIGIN_Official */
+		furi_string_printf(error, "TX forbidden\non frequency\n%lu!",
+				state->frequency);
+		return false;
+	}
+
+	return true;
+}
+
+/* Sends PassEntered event to scene manager and displays whether or not
+ * encryption has been enabled in the text box. Also clears the text input
+ * buffer to remove the password and starts the Sub-GHz worker. After starting
+ * the worker a join message is transmitted. */
+static void pass_input_cb(void *context)
+{
+	furi_assert(context);
+	ESubGhzChatState* state = context;
+
+	furi_string_cat_printf(state->chat_box_store, "\nEncrypted: %s",
+			(state->encrypted ? "yes" : "no"));
+
+	/* clear the text input buffer to remove the password */
+	esubghz_chat_explicit_bzero(state->text_input_store,
+			sizeof(state->text_input_store));
+
+	subghz_tx_rx_worker_start(state->subghz_worker, state->subghz_device,
+			state->frequency);
+
+	/* concatenate the name prefix and join message */
+	furi_string_set(state->msg_input, state->name_prefix);
+	furi_string_cat_str(state->msg_input, " joined chat.");
+
+	/* encrypt and transmit message */
+	tx_msg_input(state);
+
+	/* clear message input buffer */
+	furi_string_set_char(state->msg_input, 0, 0);
+
+	scene_manager_handle_custom_event(state->scene_manager,
+			ESubGhzChatEvent_PassEntered);
+}
+
+/* If a password was entered this derives a key from the password using a
+ * single pass of SHA256 and initiates the AES-GCM context for encryption. If
+ * the initiation fails, the password is rejected. */
+static bool pass_input_validator(const char *text, FuriString *error,
+		void *context)
+{
+	furi_assert(text);
+	furi_assert(error);
+
+	furi_assert(context);
+	ESubGhzChatState* state = context;
+
+#ifdef FW_ORIGIN_Official
+	if (strlen(text) == 0) {
+		furi_string_printf(error, "Enter a\npassword!");
+		return false;
+	}
+
+	if (strcmp(text, " ") == 0) {
+#else /* FW_ORIGIN_Official */
+	if (strlen(text) == 0) {
+#endif /* FW_ORIGIN_Official */
+		state->encrypted = false;
+		return true;
+	}
+
+	unsigned char key[KEY_BITS / 8];
+
+	/* derive a key from the password */
+	sha256((unsigned char *) text, strlen(text), key);
+
+	/* initiate the AES-GCM context */
+	int ret = gcm_setkey(&(state->gcm_ctx), key, KEY_BITS / 8);
+
+	/* cleanup */
+	esubghz_chat_explicit_bzero(key, sizeof(key));
+
+	if (ret != 0) {
+		esubghz_chat_explicit_bzero(&(state->gcm_ctx),
+				sizeof(state->gcm_ctx));
+		furi_string_printf(error, "Failed to\nset key!");
+		return false;
+	}
+
+	state->encrypted = true;
+
+	return true;
+}
+
+/* If no message was entred this simply emits a MsgEntered event to the scene
+ * manager to switch to the text box. If a message was entered it is appended
+ * to the name string. The result is encrypted, if encryption is enabled, and
+ * then copied into the TX buffer. The contents of the TX buffer are then
+ * transmitted. The sent message is appended to the text box and a MsgEntered
+ * event is sent to the scene manager to switch to the text box view. */
+static void chat_input_cb(void *context)
+{
+	furi_assert(context);
+	ESubGhzChatState* state = context;
+
+	/* no message, just switch to the text box view */
+#ifdef FW_ORIGIN_Official
+	if (strcmp(state->text_input_store, " ") == 0) {
+#else /* FW_ORIGIN_Official */
+	if (strlen(state->text_input_store) == 0) {
+#endif /* FW_ORIGIN_Official */
+		scene_manager_handle_custom_event(state->scene_manager,
+				ESubGhzChatEvent_MsgEntered);
+		return;
+	}
+
+	/* concatenate the name prefix and the actual message */
+	furi_string_set(state->msg_input, state->name_prefix);
+	furi_string_cat_str(state->msg_input, ": ");
+	furi_string_cat_str(state->msg_input, state->text_input_store);
+
+	/* append the message to the chat box */
+	furi_string_cat_printf(state->chat_box_store, "\n%s",
+		furi_string_get_cstr(state->msg_input));
+
+	/* encrypt and transmit message */
+	tx_msg_input(state);
+
+	/* clear message input buffer */
+	furi_string_set_char(state->msg_input, 0, 0);
+
+	/* switch to text box view */
+	scene_manager_handle_custom_event(state->scene_manager,
+			ESubGhzChatEvent_MsgEntered);
+}
+
+/* Prepares the frequency input scene. */
+static void scene_on_enter_freq_input(void* context)
+{
+	FURI_LOG_T(APPLICATION_NAME, "scene_on_enter_freq_input");
+
+	furi_assert(context);
+	ESubGhzChatState* state = context;
+
+	snprintf(state->text_input_store, TEXT_INPUT_STORE_SIZE, "%lu",
+			(uint32_t) DEFAULT_FREQ);
+	text_input_reset(state->text_input);
+	text_input_set_result_callback(
+			state->text_input,
+			freq_input_cb,
+			state,
+			state->text_input_store,
+			sizeof(state->text_input_store),
+			true);
+	text_input_set_validator(
+			state->text_input,
+			freq_input_validator,
+			state);
+	text_input_set_header_text(
+			state->text_input,
+			"Frequency");
+
+	view_dispatcher_switch_to_view(state->view_dispatcher, ESubGhzChatView_Input);
+}
+
+/* Handles scene manager events for the frequency input scene. */
+static bool scene_on_event_freq_input(void* context, SceneManagerEvent event)
+{
+	FURI_LOG_T(APPLICATION_NAME, "scene_on_event_freq_input");
+
+	furi_assert(context);
+	ESubGhzChatState* state = context;
+
+	bool consumed = false;
+
+	switch(event.type) {
+	case SceneManagerEventTypeCustom:
+		switch(event.event) {
+		/* switch to password input scene */
+		case ESubGhzChatEvent_FreqEntered:
+			scene_manager_next_scene(state->scene_manager,
+					ESubGhzChatScene_PassInput);
+			consumed = true;
+			break;
+		}
+		break;
+
+	case SceneManagerEventTypeBack:
+		/* stop the application if the user presses back here */
+		view_dispatcher_stop(state->view_dispatcher);
+		consumed = true;
+		break;
+
+	default:
+		consumed = false;
+		break;
+	}
+
+	return consumed;
+}
+
+/* Cleans up the frequency input scene. */
+static void scene_on_exit_freq_input(void* context)
+{
+	FURI_LOG_T(APPLICATION_NAME, "scene_on_exit_freq_input");
+
+	furi_assert(context);
+	ESubGhzChatState* state = context;
+
+	text_input_reset(state->text_input);
+}
+
+/* Prepares the password input scene. */
+static void scene_on_enter_pass_input(void* context)
+{
+	FURI_LOG_T(APPLICATION_NAME, "scene_on_enter_pass_input");
+
+	furi_assert(context);
+	ESubGhzChatState* state = context;
+
+	state->text_input_store[0] = 0;
+	text_input_reset(state->text_input);
+	text_input_set_result_callback(
+			state->text_input,
+			pass_input_cb,
+			state,
+			state->text_input_store,
+			sizeof(state->text_input_store),
+			true);
+	text_input_set_validator(
+			state->text_input,
+			pass_input_validator,
+			state);
+	text_input_set_header_text(
+			state->text_input,
+#ifdef FW_ORIGIN_Official
+			"Password (space for no encr.)");
+#else /* FW_ORIGIN_Official */
+			"Password (empty for no encr.)");
+	text_input_set_minimum_length(state->text_input, 0);
+#endif /* FW_ORIGIN_Official */
+
+	view_dispatcher_switch_to_view(state->view_dispatcher, ESubGhzChatView_Input);
+}
+
+/* Handles scene manager events for the password input scene. */
+static bool scene_on_event_pass_input(void* context, SceneManagerEvent event)
+{
+	FURI_LOG_T(APPLICATION_NAME, "scene_on_event_pass_input");
+
+	furi_assert(context);
+	ESubGhzChatState* state = context;
+
+	bool consumed = false;
+
+	switch(event.type) {
+	case SceneManagerEventTypeCustom:
+		switch(event.event) {
+		/* switch to message input scene */
+		case ESubGhzChatEvent_PassEntered:
+			scene_manager_next_scene(state->scene_manager,
+					ESubGhzChatScene_ChatInput);
+			consumed = true;
+			break;
+		}
+		break;
+
+	case SceneManagerEventTypeBack:
+		/* stop the application if the user presses back here */
+		view_dispatcher_stop(state->view_dispatcher);
+		consumed = true;
+		break;
+
+	default:
+		consumed = false;
+		break;
+	}
+
+	return consumed;
+}
+
+/* Cleans up the password input scene. */
+static void scene_on_exit_pass_input(void* context)
+{
+	FURI_LOG_T(APPLICATION_NAME, "scene_on_exit_pass_input");
+
+	furi_assert(context);
+	ESubGhzChatState* state = context;
+
+	text_input_reset(state->text_input);
+}
+
+/* Prepares the message input scene. */
+static void scene_on_enter_chat_input(void* context)
+{
+	FURI_LOG_T(APPLICATION_NAME, "scene_on_enter_chat_input");
+
+	furi_assert(context);
+	ESubGhzChatState* state = context;
+
+	state->text_input_store[0] = 0;
+	text_input_reset(state->text_input);
+	text_input_set_result_callback(
+			state->text_input,
+			chat_input_cb,
+			state,
+			state->text_input_store,
+			sizeof(state->text_input_store),
+			true);
+	text_input_set_validator(
+			state->text_input,
+			NULL,
+			NULL);
+	text_input_set_header_text(
+			state->text_input,
+#ifdef FW_ORIGIN_Official
+			"Message (space for none)");
+#else /* FW_ORIGIN_Official */
+			"Message");
+	text_input_set_minimum_length(state->text_input, 0);
+#endif /* FW_ORIGIN_Official */
+
+	view_dispatcher_switch_to_view(state->view_dispatcher, ESubGhzChatView_Input);
+}
+
+/* Handles scene manager events for the message input scene. */
+static bool scene_on_event_chat_input(void* context, SceneManagerEvent event)
+{
+	FURI_LOG_T(APPLICATION_NAME, "scene_on_event_chat_input");
+
+	furi_assert(context);
+	ESubGhzChatState* state = context;
+
+	bool consumed = false;
+
+	switch(event.type) {
+	case SceneManagerEventTypeCustom:
+		switch(event.event) {
+		/* switch to text box scene */
+		case ESubGhzChatEvent_MsgEntered:
+			scene_manager_next_scene(state->scene_manager,
+					ESubGhzChatScene_ChatBox);
+			consumed = true;
+			break;
+		}
+		break;
+
+	case SceneManagerEventTypeBack:
+		/* stop the application and send a leave message if the user
+		 * presses back here */
+
+		/* concatenate the name prefix and leave message */
+		furi_string_set(state->msg_input, state->name_prefix);
+		furi_string_cat_str(state->msg_input, " left chat.");
+
+		/* encrypt and transmit message */
+		tx_msg_input(state);
+
+		/* clear message input buffer */
+		furi_string_set_char(state->msg_input, 0, 0);
+
+		/* wait for leave message to be delivered */
+                furi_delay_ms(CHAT_LEAVE_DELAY);
+
+		view_dispatcher_stop(state->view_dispatcher);
+		consumed = true;
+		break;
+
+	default:
+		consumed = false;
+		break;
+	}
+
+	return consumed;
+}
+
+/* Cleans up the password input scene. */
+static void scene_on_exit_chat_input(void* context)
+{
+	FURI_LOG_T(APPLICATION_NAME, "scene_on_exit_chat_input");
+
+	furi_assert(context);
+	ESubGhzChatState* state = context;
+
+	text_input_reset(state->text_input);
+}
+
+/* Prepares the text box scene. */
+static void scene_on_enter_chat_box(void* context)
+{
+	FURI_LOG_T(APPLICATION_NAME, "scene_on_enter_chat_box");
+
+	furi_assert(context);
+	ESubGhzChatState* state = context;
+
+	text_box_reset(state->chat_box);
+	text_box_set_text(state->chat_box,
+			furi_string_get_cstr(state->chat_box_store));
+	text_box_set_focus(state->chat_box, TextBoxFocusEnd);
+
+	view_dispatcher_switch_to_view(state->view_dispatcher, ESubGhzChatView_ChatBox);
+}
+
+/* Handles scene manager events for the text box scene. No events are handled
+ * here. */
+static bool scene_on_event_chat_box(void* context, SceneManagerEvent event)
+{
+	UNUSED(event);
+
+	FURI_LOG_T(APPLICATION_NAME, "scene_on_event_chat_box");
+
+	furi_assert(context);
+
+	return false;
+}
+
+/* Cleans up the text box scene. */
+static void scene_on_exit_chat_box(void* context)
+{
+	FURI_LOG_T(APPLICATION_NAME, "scene_on_exit_chat_box");
+
+	furi_assert(context);
+	ESubGhzChatState* state = context;
+
+	text_box_reset(state->chat_box);
+}
+
+/* Scene entry handlers. */
+static void (*const esubghz_chat_scene_on_enter_handlers[])(void*) = {
+	scene_on_enter_freq_input,
+	scene_on_enter_pass_input,
+	scene_on_enter_chat_input,
+	scene_on_enter_chat_box
+};
+
+/* Scene event handlers. */
+static bool (*const esubghz_chat_scene_on_event_handlers[])(void*, SceneManagerEvent) = {
+	scene_on_event_freq_input,
+	scene_on_event_pass_input,
+	scene_on_event_chat_input,
+	scene_on_event_chat_box
+};
+
+/* Scene exit handlers. */
+static void (*const esubghz_chat_scene_on_exit_handlers[])(void*) = {
+	scene_on_exit_freq_input,
+	scene_on_exit_pass_input,
+	scene_on_exit_chat_input,
+	scene_on_exit_chat_box
+};
+
+/* Handlers for the scene manager. */
+static const SceneManagerHandlers esubghz_chat_scene_event_handlers = {
+	.on_enter_handlers = esubghz_chat_scene_on_enter_handlers,
+	.on_event_handlers = esubghz_chat_scene_on_event_handlers,
+	.on_exit_handlers = esubghz_chat_scene_on_exit_handlers,
+	.scene_num = ESubGhzChatScene_MAX};
+
+/* Whether or not to display the locked message. */
+static bool kbd_lock_msg_display(ESubGhzChatState *state)
+{
+	return (state->kbd_lock_msg_ticks != 0);
+}
+
+/* Whether or not to hide the locked message again. */
+static bool kbd_lock_msg_reset_timeout(ESubGhzChatState *state)
+{
+	if (state->kbd_lock_msg_ticks == 0) {
+		return false;
+	}
+
+	if (furi_get_tick() - state->kbd_lock_msg_ticks > KBD_UNLOCK_TIMEOUT) {
+		return true;
+	}
+
+	return false;
+}
+
+/* Resets the timeout for the locked message and turns off the backlight if
+ * specified. */
+static void kbd_lock_msg_reset(ESubGhzChatState *state, bool backlight_off)
+{
+	state->kbd_lock_msg_ticks = 0;
+	state->kbd_lock_count = 0;
+
+	if (backlight_off) {
+		notification_message(state->notification,
+				&sequence_display_backlight_off);
+	}
+}
+
+/* Locks the keyboard. */
+static void kbd_lock(ESubGhzChatState *state)
+{
+	state->kbd_locked = true;
+	kbd_lock_msg_reset(state, true);
+}
+
+/* Unlocks the keyboard. */
+static void kbd_unlock(ESubGhzChatState *state)
+{
+	state->kbd_locked = false;
+	kbd_lock_msg_reset(state, false);
+}
+
+/* Custom event callback for view dispatcher. Just calls scene manager. */
+static bool esubghz_chat_custom_event_callback(void* context, uint32_t event)
+{
+	FURI_LOG_T(APPLICATION_NAME, "esubghz_chat_custom_event_callback");
+	furi_assert(context);
+	ESubGhzChatState* state = context;
+	return scene_manager_handle_custom_event(state->scene_manager, event);
+}
+
+/* Navigation event callback for view dispatcher. Just calls scene manager. */
+static bool esubghz_chat_navigation_event_callback(void* context)
+{
+	FURI_LOG_T(APPLICATION_NAME, "esubghz_chat_navigation_event_callback");
+	furi_assert(context);
+	ESubGhzChatState* state = context;
+	return scene_manager_handle_back_event(state->scene_manager);
+}
+
+/* Tick event callback for view dispatcher. Called every TICK_INTERVAL. Resets
+ * the locked message if necessary. Retrieves a received message from the
+ * Sub-GHz worker and calls post_rx(). Then calls the scene manager. */
+static void esubghz_chat_tick_event_callback(void* context)
+{
+	FURI_LOG_T(APPLICATION_NAME, "esubghz_chat_tick_event_callback");
+
+	furi_assert(context);
+	ESubGhzChatState* state = context;
+
+	/* reset locked message if necessary */
+	if (kbd_lock_msg_reset_timeout(state)) {
+		kbd_lock_msg_reset(state, true);
+	}
+
+	/* if the maximum message size was reached or the
+	 * MESSAGE_COMPLETION_TIMEOUT has expired, retrieve a message and call
+	 * post_rx() */
+	size_t avail = 0;
+	while ((avail = subghz_tx_rx_worker_available(state->subghz_worker)) >
+			0) {
+		volatile uint32_t since_last_rx = furi_get_tick() -
+			state->last_time_rx_data;
+		if (avail < RX_TX_BUFFER_SIZE && since_last_rx <
+				MESSAGE_COMPLETION_TIMEOUT) {
+			break;
+		}
+
+		size_t rx_size = subghz_tx_rx_worker_read(state->subghz_worker,
+				state->rx_buffer, RX_TX_BUFFER_SIZE);
+		post_rx(state, rx_size);
+	}
+
+	/* call scene manager */
+	scene_manager_handle_tick_event(state->scene_manager);
+}
+
+/* Hooks into the view port's draw callback to overlay the keyboard locked
+ * message. */
+static void esubghz_hooked_draw_callback(Canvas* canvas, void* context)
+{
+	FURI_LOG_T(APPLICATION_NAME, "esubghz_hooked_draw_callback");
+
+	furi_assert(canvas);
+
+	furi_assert(context);
+	ESubGhzChatState* state = context;
+
+	/* call original callback */
+	state->orig_draw_cb(canvas, state->view_dispatcher);
+
+	/* display if the keyboard is locked */
+	if (state->kbd_locked) {
+		canvas_set_font(canvas, FontPrimary);
+		elements_multiline_text_framed(canvas, 42, 30, "Locked");
+	}
+
+	/* display the unlock message if necessary */
+	if (kbd_lock_msg_display(state)) {
+		canvas_set_font(canvas, FontSecondary);
+		elements_bold_rounded_frame(canvas, 14, 8, 99, 48);
+		elements_multiline_text(canvas, 65, 26, "To unlock\npress:");
+		canvas_draw_icon(canvas, 65, 42, &I_Pin_back_arrow_10x8);
+		canvas_draw_icon(canvas, 80, 42, &I_Pin_back_arrow_10x8);
+		canvas_draw_icon(canvas, 95, 42, &I_Pin_back_arrow_10x8);
+		canvas_draw_icon(canvas, 16, 13, &I_WarningDolphin_45x42);
+	}
+}
+
+/* Hooks into the view port's input callback to handle the user locking the
+ * keyboard. */
+static void esubghz_hooked_input_callback(InputEvent* event, void* context)
+{
+	FURI_LOG_T(APPLICATION_NAME, "esubghz_hooked_input_callback");
+
+	furi_assert(event);
+
+	furi_assert(context);
+	ESubGhzChatState* state = context;
+
+	/* if the keyboard is locked no key presses are forwarded */
+	if (state->kbd_locked) {
+		/* key has been pressed, display the unlock message and
+		 * initiate the timer */
+		if (state->kbd_lock_count == 0) {
+			state->kbd_lock_msg_ticks = furi_get_tick();
+		}
+
+		/* back button has been pressed, increase the lock counter */
+		if (event->key == InputKeyBack && event->type ==
+				InputTypeShort) {
+			state->kbd_lock_count++;
+		}
+
+		/* unlock the keyboard */
+		if (state->kbd_lock_count >= KBD_UNLOCK_CNT) {
+			kbd_unlock(state);
+		}
+
+		/* do not handle the event */
+		return;
+	}
+
+	if (event->key == InputKeyOk) {
+		/* if we are in the chat view and no input is ongoing, allow
+		 * locking */
+		if (state->view_dispatcher->current_view ==
+				text_box_get_view(state->chat_box) &&
+				!(state->kbd_ok_input_ongoing)) {
+			/* lock keyboard upon long press of Ok button */
+			if (event->type == InputTypeLong) {
+				kbd_lock(state);
+			}
+
+			/* do not handle any Ok key events to prevent blocking
+			 * of other keys */
+			return;
+		}
+
+		/* handle ongoing inputs when chaning to chat view */
+		if (event->type == InputTypePress) {
+			state->kbd_ok_input_ongoing = true;
+		} else if (event->type == InputTypeRelease) {
+			state->kbd_ok_input_ongoing = false;
+		}
+	}
+
+	/* call original callback */
+	state->orig_input_cb(event, state->view_dispatcher);
+}
+
+static bool helper_strings_alloc(ESubGhzChatState *state)
+{
+	furi_assert(state);
+
+	state->name_prefix = furi_string_alloc();
+	if (state->name_prefix == NULL) {
+		return false;
+	}
+
+	state->msg_input = furi_string_alloc();
+	if (state->msg_input == NULL) {
+		furi_string_free(state->name_prefix);
+		return false;
+	}
+
+	return true;
+}
+
+static void helper_strings_free(ESubGhzChatState *state)
+{
+	furi_assert(state);
+
+	furi_string_free(state->name_prefix);
+	furi_string_free(state->msg_input);
+}
+
+static bool chat_box_alloc(ESubGhzChatState *state)
+{
+	furi_assert(state);
+
+	state->chat_box = text_box_alloc();
+	if (state->chat_box == NULL) {
+		return false;
+	}
+
+	state->chat_box_store = furi_string_alloc();
+	if (state->chat_box_store == NULL) {
+		text_box_free(state->chat_box);
+		return false;
+	}
+
+	furi_string_reserve(state->chat_box_store, CHAT_BOX_STORE_SIZE);
+	furi_string_set_char(state->chat_box_store, 0, 0);
+	text_box_set_text(state->chat_box,
+			furi_string_get_cstr(state->chat_box_store));
+	text_box_set_focus(state->chat_box, TextBoxFocusEnd);
+
+	return true;
+}
+
+static void chat_box_free(ESubGhzChatState *state)
+{
+	furi_assert(state);
+
+	text_box_free(state->chat_box);
+	furi_string_free(state->chat_box_store);
+}
+
+int32_t esubghz_chat(void)
+{
+	/* init the GCM and AES tables */
+	gcm_initialize();
+
+	int32_t err = -1;
+
+	FURI_LOG_I(APPLICATION_NAME, "Starting...");
+
+	/* allocate necessary structs and buffers */
+
+	ESubGhzChatState *state = malloc(sizeof(ESubGhzChatState));
+	if (state == NULL) {
+		goto err_alloc;
+	}
+	memset(state, 0, sizeof(*state));
+
+	state->scene_manager = scene_manager_alloc(
+			&esubghz_chat_scene_event_handlers, state);
+	if (state->scene_manager == NULL) {
+		goto err_alloc_sm;
+	}
+
+	state->view_dispatcher = view_dispatcher_alloc();
+	if (state->view_dispatcher == NULL) {
+		goto err_alloc_vd;
+	}
+
+	if (!helper_strings_alloc(state)) {
+		goto err_alloc_hs;
+	}
+
+	state->text_input = text_input_alloc();
+	if (state->text_input == NULL) {
+		goto err_alloc_ti;
+	}
+
+	if (!chat_box_alloc(state)) {
+		goto err_alloc_cb;
+	}
+
+	state->subghz_worker = subghz_tx_rx_worker_alloc();
+	if (state->subghz_worker == NULL) {
+		goto err_alloc_worker;
+	}
+
+	/* set the have_read callback of the Sub-GHz worker */
+	subghz_tx_rx_worker_set_callback_have_read(state->subghz_worker,
+			have_read_cb, state);
+
+	/* enter suppress charge mode */
+	furi_hal_power_suppress_charge_enter();
+
+	/* init internal device */
+	subghz_devices_init();
+	state->subghz_device = subghz_devices_get_by_name(SUBGHZ_DEVICE_CC1101_INT_NAME);
+
+	/* set chat name prefix */
+	furi_string_printf(state->name_prefix, "%s",
+			furi_hal_version_get_name_ptr());
+
+	/* get notification record, we use this to make the flipper vibrate */
+	/* no error handling here, don't know how */
+	state->notification = furi_record_open(RECORD_NOTIFICATION);
+
+	/* hook into the view port's draw and input callbacks */
+	state->orig_draw_cb = state->view_dispatcher->view_port->draw_callback;
+	state->orig_input_cb = state->view_dispatcher->view_port->input_callback;
+	view_port_draw_callback_set(state->view_dispatcher->view_port,
+			esubghz_hooked_draw_callback, state);
+	view_port_input_callback_set(state->view_dispatcher->view_port,
+			esubghz_hooked_input_callback, state);
+
+	view_dispatcher_enable_queue(state->view_dispatcher);
+
+	/* set callbacks for view dispatcher */
+	view_dispatcher_set_event_callback_context(state->view_dispatcher, state);
+	view_dispatcher_set_custom_event_callback(
+			state->view_dispatcher,
+			esubghz_chat_custom_event_callback);
+	view_dispatcher_set_navigation_event_callback(
+			state->view_dispatcher,
+			esubghz_chat_navigation_event_callback);
+	view_dispatcher_set_tick_event_callback(
+			state->view_dispatcher,
+			esubghz_chat_tick_event_callback,
+			TICK_INTERVAL);
+
+	/* add our two views to the view dispatcher */
+	view_dispatcher_add_view(state->view_dispatcher, ESubGhzChatView_Input,
+			text_input_get_view(state->text_input));
+	view_dispatcher_add_view(state->view_dispatcher, ESubGhzChatView_ChatBox,
+			text_box_get_view(state->chat_box));
+
+	/* get the GUI record and attach the view dispatcher to the GUI */
+	/* no error handling here, don't know how */
+	Gui *gui = furi_record_open(RECORD_GUI);
+	view_dispatcher_attach_to_gui(state->view_dispatcher, gui,
+			ViewDispatcherTypeFullscreen);
+
+	/* switch to the frequency input scene */
+	scene_manager_next_scene(state->scene_manager, ESubGhzChatScene_FreqInput);
+
+	/* run the view dispatcher, this call only returns when we close the
+	 * application */
+	view_dispatcher_run(state->view_dispatcher);
+
+	/* if it is running, stop the Sub-GHz worker */
+	if (subghz_tx_rx_worker_is_running(state->subghz_worker)) {
+		subghz_tx_rx_worker_stop(state->subghz_worker);
+	}
+
+	err = 0;
+
+	/* close GUI record */
+	furi_record_close(RECORD_GUI);
+
+	/* remove our two views from the view dispatcher */
+	view_dispatcher_remove_view(state->view_dispatcher,
+			ESubGhzChatView_Input);
+	view_dispatcher_remove_view(state->view_dispatcher,
+			ESubGhzChatView_ChatBox);
+
+	/* close notification record */
+	furi_record_close(RECORD_NOTIFICATION);
+
+	/* clear the key and potential password */
+	esubghz_chat_explicit_bzero(state->text_input_store,
+			sizeof(state->text_input_store));
+	esubghz_chat_explicit_bzero(&(state->gcm_ctx), sizeof(state->gcm_ctx));
+
+	/* deinit devices */
+	subghz_devices_deinit();
+
+	/* exit suppress charge mode */
+	furi_hal_power_suppress_charge_exit();
+
+	/* free everything we allocated */
+
+	subghz_tx_rx_worker_free(state->subghz_worker);
+
+err_alloc_worker:
+	chat_box_free(state);
+
+err_alloc_cb:
+	text_input_free(state->text_input);
+
+err_alloc_ti:
+	helper_strings_free(state);
+
+err_alloc_hs:
+	view_dispatcher_free(state->view_dispatcher);
+
+err_alloc_vd:
+	scene_manager_free(state->scene_manager);
+
+err_alloc_sm:
+	free(state);
+
+err_alloc:
+	if (err != 0) {
+		FURI_LOG_E(APPLICATION_NAME, "Failed to launch (alloc error)!");
+	} else {
+		FURI_LOG_I(APPLICATION_NAME, "Clean exit.");
+	}
+
+	return err;
+}

+ 4 - 20
non_catalog_apps/flipperscope/application.fam

@@ -1,29 +1,13 @@
 App(
-    appid="scope",
+    appid="flipperscope",
     name="Scope",
+    fap_author="anfractuosity",
     apptype=FlipperAppType.EXTERNAL,
     entry_point="scope_main",
     requires=["gui"],
     stack_size=1 * 1024,
     fap_category="GPIO",
     fap_icon="scope_10px.png",
-    fap_private_libs=[
-        Lib(
-            name="adc",
-            fap_include_paths=["inc"],
-            sources=[
-                "stm32wbxx_hal_adc.c",
-                "stm32wbxx_hal_adc_ex.c",
-                "stm32wbxx_hal_rcc_ex.c",
-                "stm32wbxx_hal_gpio.c",
-                "stm32wbxx_hal_pwr.c",
-                "stm32wbxx_hal.c",
-                "stm32wbxx_hal_tim.c",
-                "stm32wbxx_hal_tim_ex.c",
-                "stm32wbxx_hal_cortex.c",
-                "stm32wbxx_hal_dma.c",
-                "stm32wbxx_hal_rcc.c",
-            ],
-        )
-    ],
+    fap_version="0.1",
+    fap_description="Oscilloscope application - apply signal to pin 16/PC0, with a voltage ranging from 0V to 2.5V and ground to pin 18/GND",
 )

+ 0 - 352
non_catalog_apps/flipperscope/lib/adc/inc/stm32wbxx_hal_conf.h

@@ -1,352 +0,0 @@
-/* USER CODE BEGIN Header */
-/**
-  ******************************************************************************
-  * @file    stm32wbxx_hal_conf.h
-  * @author  MCD Application Team
-  * @brief   HAL configuration file.
-  ******************************************************************************
-  * @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.
-  *
-  ******************************************************************************
-  */
-/* USER CODE END Header */
-
-/* Define to prevent recursive inclusion -------------------------------------*/
-#ifndef __STM32WBxx_HAL_CONF_H
-#define __STM32WBxx_HAL_CONF_H
-
-#ifdef __cplusplus
- extern "C" {
-#endif
-
-/* Exported types ------------------------------------------------------------*/
-/* Exported constants --------------------------------------------------------*/
-
-/* ########################## Module Selection ############################## */
-/**
-  * @brief This is the list of modules to be used in the HAL driver
-  */
-#define HAL_MODULE_ENABLED
-#define HAL_ADC_MODULE_ENABLED
-/*#define HAL_CRYP_MODULE_ENABLED   */
-/*#define HAL_COMP_MODULE_ENABLED   */
-/*#define HAL_CRC_MODULE_ENABLED   */
-/*#define HAL_HSEM_MODULE_ENABLED   */
-/*#define HAL_I2C_MODULE_ENABLED   */
-/*#define HAL_IPCC_MODULE_ENABLED   */
-/*#define HAL_IRDA_MODULE_ENABLED   */
-/*#define HAL_IWDG_MODULE_ENABLED   */
-/*#define HAL_LCD_MODULE_ENABLED   */
-/*#define HAL_LPTIM_MODULE_ENABLED   */
-/*#define HAL_PCD_MODULE_ENABLED   */
-/*#define HAL_PKA_MODULE_ENABLED   */
-/*#define HAL_QSPI_MODULE_ENABLED   */
-/*#define HAL_RNG_MODULE_ENABLED   */
-/*#define HAL_RTC_MODULE_ENABLED   */
-/*#define HAL_SAI_MODULE_ENABLED   */
-/*#define HAL_SMBUS_MODULE_ENABLED   */
-/*#define HAL_SMARTCARD_MODULE_ENABLED   */
-/*#define HAL_SPI_MODULE_ENABLED   */
-#define HAL_TIM_MODULE_ENABLED
-/*#define HAL_TSC_MODULE_ENABLED   */
-/*#define HAL_UART_MODULE_ENABLED   */
-/*#define HAL_USART_MODULE_ENABLED   */
-/*#define HAL_WWDG_MODULE_ENABLED   */
-#define HAL_EXTI_MODULE_ENABLED
-#define HAL_CORTEX_MODULE_ENABLED
-#define HAL_DMA_MODULE_ENABLED
-#define HAL_FLASH_MODULE_ENABLED
-#define HAL_GPIO_MODULE_ENABLED
-#define HAL_PWR_MODULE_ENABLED
-#define HAL_RCC_MODULE_ENABLED
-
-#define USE_HAL_ADC_REGISTER_CALLBACKS       0u
-#define USE_HAL_COMP_REGISTER_CALLBACKS      0u
-#define USE_HAL_CRYP_REGISTER_CALLBACKS      0u
-#define USE_HAL_I2C_REGISTER_CALLBACKS       0u
-#define USE_HAL_IRDA_REGISTER_CALLBACKS      0u
-#define USE_HAL_LPTIM_REGISTER_CALLBACKS     0u
-#define USE_HAL_PCD_REGISTER_CALLBACKS       0u
-#define USE_HAL_PKA_REGISTER_CALLBACKS       0u
-#define USE_HAL_QSPI_REGISTER_CALLBACKS      0u
-#define USE_HAL_RNG_REGISTER_CALLBACKS       0u
-#define USE_HAL_RTC_REGISTER_CALLBACKS       0u
-#define USE_HAL_SAI_REGISTER_CALLBACKS       0u
-#define USE_HAL_SMARTCARD_REGISTER_CALLBACKS 0u
-#define USE_HAL_SMBUS_REGISTER_CALLBACKS     0u
-#define USE_HAL_SPI_REGISTER_CALLBACKS       0u
-#define USE_HAL_TIM_REGISTER_CALLBACKS       0u
-#define USE_HAL_TSC_REGISTER_CALLBACKS       0u
-#define USE_HAL_UART_REGISTER_CALLBACKS      0u
-#define USE_HAL_USART_REGISTER_CALLBACKS     0u
-#define USE_HAL_WWDG_REGISTER_CALLBACKS      0u
-
-/* ########################## Oscillator Values adaptation ####################*/
-/**
-  * @brief Adjust the value of External High Speed oscillator (HSE) used in your application.
-  *        This value is used by the RCC HAL module to compute the system frequency
-  *        (when HSE is used as system clock source, directly or through the PLL).
-  */
-#if !defined  (HSE_VALUE)
-#define HSE_VALUE    8000000U             /*!< Value of the External oscillator in Hz */
-#endif /* HSE_VALUE */
-
-#if !defined  (HSE_STARTUP_TIMEOUT)
-  #define HSE_STARTUP_TIMEOUT    ((uint32_t)100)   /*!< Time out for HSE start up, in ms */
-#endif /* HSE_STARTUP_TIMEOUT */
-
-/**
-  * @brief Internal Multiple Speed oscillator (MSI) default value.
-  *        This value is the default MSI range value after Reset.
-  */
-#if !defined  (MSI_VALUE)
-  #define MSI_VALUE    ((uint32_t)4000000) /*!< Value of the Internal oscillator in Hz*/
-#endif /* MSI_VALUE */
-
-/**
-  * @brief Internal High Speed oscillator (HSI) value.
-  *        This value is used by the RCC HAL module to compute the system frequency
-  *        (when HSI is used as system clock source, directly or through the PLL).
-  */
-#if !defined  (HSI_VALUE)
-#define HSI_VALUE    16000000U            /*!< Value of the Internal oscillator in Hz*/
-#endif /* HSI_VALUE */
-
-/**
-  * @brief Internal Low Speed oscillator (LSI1) value.
-  */
-#if !defined  (LSI1_VALUE)
- #define LSI1_VALUE  ((uint32_t)32000)       /*!< LSI1 Typical Value in Hz*/
-#endif /* LSI1_VALUE */                      /*!< Value of the Internal Low Speed oscillator in Hz
-                                             The real value may vary depending on the variations
-                                             in voltage and temperature.*/
-/**
-  * @brief Internal Low Speed oscillator (LSI2) value.
-  */
-#if !defined  (LSI2_VALUE)
- #define LSI2_VALUE  ((uint32_t)32000)       /*!< LSI2 Typical Value in Hz*/
-#endif /* LSI2_VALUE */                      /*!< Value of the Internal Low Speed oscillator in Hz
-                                             The real value may vary depending on the variations
-                                             in voltage and temperature.*/
-
-/**
-  * @brief External Low Speed oscillator (LSE) value.
-  *        This value is used by the UART, RTC HAL module to compute the system frequency
-  */
-#if !defined  (LSE_VALUE)
-#define LSE_VALUE    32768U               /*!< Value of the External oscillator in Hz*/
-#endif /* LSE_VALUE */
-
-/**
-  * @brief Internal Multiple Speed oscillator (HSI48) default value.
-  *        This value is the default HSI48 range value after Reset.
-  */
-#if !defined (HSI48_VALUE)
-  #define HSI48_VALUE    ((uint32_t)48000000) /*!< Value of the Internal oscillator in Hz*/
-#endif /* HSI48_VALUE */
-
-#if !defined  (LSE_STARTUP_TIMEOUT)
-#define LSE_STARTUP_TIMEOUT    5000U      /*!< Time out for LSE start up, in ms */
-#endif /* HSE_STARTUP_TIMEOUT */
-
-/**
-  * @brief External clock source for SAI1 peripheral
-  *        This value is used by the RCC HAL module to compute the SAI1 & SAI2 clock source
-  *        frequency.
-  */
-#if !defined (EXTERNAL_SAI1_CLOCK_VALUE)
-  #define EXTERNAL_SAI1_CLOCK_VALUE    ((uint32_t)2097000) /*!< Value of the SAI1 External clock source in Hz*/
-#endif /* EXTERNAL_SAI1_CLOCK_VALUE */
-
-/* Tip: To avoid modifying this file each time you need to use different HSE,
-   ===  you can define the HSE value in your toolchain compiler preprocessor. */
-
-/* ########################### System Configuration ######################### */
-/**
-  * @brief This is the HAL system configuration section
-  */
-
-#define  VDD_VALUE				3300U                   /*!< Value of VDD in mv */
-#define  TICK_INT_PRIORITY            0U      /*!< tick interrupt priority */
-#define  USE_RTOS                     0U
-#define  PREFETCH_ENABLE              1U
-#define  INSTRUCTION_CACHE_ENABLE     1U
-#define  DATA_CACHE_ENABLE            1U
-
-/* ########################## Assert Selection ############################## */
-/**
-  * @brief Uncomment the line below to expanse the "assert_param" macro in the
-  *        HAL drivers code
-  */
-/* #define USE_FULL_ASSERT    1U */
-
-/* ################## SPI peripheral configuration ########################## */
-
-/* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver
- * Activated: CRC code is present inside driver
- * Deactivated: CRC code cleaned from driver
- */
-
-#define USE_SPI_CRC                   0U
-
-/* Includes ------------------------------------------------------------------*/
-/**
-  * @brief Include module's header file
-  */
-#ifdef HAL_DMA_MODULE_ENABLED
-  #include "stm32wbxx_hal_dma.h"
-#endif /* HAL_DMA_MODULE_ENABLED */
-
-#ifdef HAL_ADC_MODULE_ENABLED
-  #include "stm32wbxx_hal_adc.h"
-#endif /* HAL_ADC_MODULE_ENABLED */
-
-#ifdef HAL_COMP_MODULE_ENABLED
-  #include "stm32wbxx_hal_comp.h"
-#endif /* HAL_COMP_MODULE_ENABLED */
-
-#ifdef HAL_CORTEX_MODULE_ENABLED
-  #include "stm32wbxx_hal_cortex.h"
-#endif /* HAL_CORTEX_MODULE_ENABLED */
-
-#ifdef HAL_CRC_MODULE_ENABLED
-  #include "stm32wbxx_hal_crc.h"
-#endif /* HAL_CRC_MODULE_ENABLED */
-
-#ifdef HAL_CRYP_MODULE_ENABLED
-  #include "stm32wbxx_hal_cryp.h"
-#endif /* HAL_CRYP_MODULE_ENABLED */
-
-#ifdef HAL_EXTI_MODULE_ENABLED
-  #include "stm32wbxx_hal_exti.h"
-#endif /* HAL_EXTI_MODULE_ENABLED */
-
-#ifdef HAL_FLASH_MODULE_ENABLED
-  #include "stm32wbxx_hal_flash.h"
-#endif /* HAL_FLASH_MODULE_ENABLED */
-
-#ifdef HAL_GPIO_MODULE_ENABLED
-  #include "stm32wbxx_hal_gpio.h"
-#endif /* HAL_GPIO_MODULE_ENABLED */
-
-#ifdef HAL_HSEM_MODULE_ENABLED
-  #include "stm32wbxx_hal_hsem.h"
-#endif /* HAL_HSEM_MODULE_ENABLED */
-
-#ifdef HAL_I2C_MODULE_ENABLED
- #include "stm32wbxx_hal_i2c.h"
-#endif /* HAL_I2C_MODULE_ENABLED */
-
-#ifdef HAL_IPCC_MODULE_ENABLED
- #include "stm32wbxx_hal_ipcc.h"
-#endif /* HAL_IPCC_MODULE_ENABLED */
-
-#ifdef HAL_IRDA_MODULE_ENABLED
- #include "stm32wbxx_hal_irda.h"
-#endif /* HAL_IRDA_MODULE_ENABLED */
-
-#ifdef HAL_IWDG_MODULE_ENABLED
- #include "stm32wbxx_hal_iwdg.h"
-#endif /* HAL_IWDG_MODULE_ENABLED */
-
-#ifdef HAL_LCD_MODULE_ENABLED
- #include "stm32wbxx_hal_lcd.h"
-#endif /* HAL_LCD_MODULE_ENABLED */
-
-#ifdef HAL_LPTIM_MODULE_ENABLED
-  #include "stm32wbxx_hal_lptim.h"
-#endif /* HAL_LPTIM_MODULE_ENABLED */
-
-#ifdef HAL_PCD_MODULE_ENABLED
-  #include "stm32wbxx_hal_pcd.h"
-#endif /* HAL_PCD_MODULE_ENABLED */
-
-#ifdef HAL_PKA_MODULE_ENABLED
-  #include "stm32wbxx_hal_pka.h"
-#endif /* HAL_PKA_MODULE_ENABLED */
-
-#ifdef HAL_PWR_MODULE_ENABLED
- #include "stm32wbxx_hal_pwr.h"
-#endif /* HAL_PWR_MODULE_ENABLED */
-
-#ifdef HAL_QSPI_MODULE_ENABLED
- #include "stm32wbxx_hal_qspi.h"
-#endif /* HAL_QSPI_MODULE_ENABLED */
-
-#ifdef HAL_RCC_MODULE_ENABLED
-  #include "stm32wbxx_hal_rcc.h"
-#endif /* HAL_RCC_MODULE_ENABLED */
-
-#ifdef HAL_RNG_MODULE_ENABLED
-  #include "stm32wbxx_hal_rng.h"
-#endif /* HAL_RNG_MODULE_ENABLED */
-
-#ifdef HAL_RTC_MODULE_ENABLED
- #include "stm32wbxx_hal_rtc.h"
-#endif /* HAL_RTC_MODULE_ENABLED */
-
-#ifdef HAL_SAI_MODULE_ENABLED
- #include "stm32wbxx_hal_sai.h"
-#endif /* HAL_SAI_MODULE_ENABLED */
-
-#ifdef HAL_SMARTCARD_MODULE_ENABLED
- #include "stm32wbxx_hal_smartcard.h"
-#endif /* HAL_SMARTCARD_MODULE_ENABLED */
-
-#ifdef HAL_SMBUS_MODULE_ENABLED
- #include "stm32wbxx_hal_smbus.h"
-#endif /* HAL_SMBUS_MODULE_ENABLED */
-
-#ifdef HAL_SPI_MODULE_ENABLED
- #include "stm32wbxx_hal_spi.h"
-#endif /* HAL_SPI_MODULE_ENABLED */
-
-#ifdef HAL_TIM_MODULE_ENABLED
- #include "stm32wbxx_hal_tim.h"
-#endif /* HAL_TIM_MODULE_ENABLED */
-
-#ifdef HAL_TSC_MODULE_ENABLED
-  #include "stm32wbxx_hal_tsc.h"
-#endif /* HAL_TSC_MODULE_ENABLED */
-
-#ifdef HAL_UART_MODULE_ENABLED
- #include "stm32wbxx_hal_uart.h"
-#endif /* HAL_UART_MODULE_ENABLED */
-
-#ifdef HAL_USART_MODULE_ENABLED
- #include "stm32wbxx_hal_usart.h"
-#endif /* HAL_USART_MODULE_ENABLED */
-
-#ifdef HAL_WWDG_MODULE_ENABLED
- #include "stm32wbxx_hal_wwdg.h"
-#endif /* HAL_WWDG_MODULE_ENABLED */
-
-/* Exported macro ------------------------------------------------------------*/
-#ifdef  USE_FULL_ASSERT
-/**
-  * @brief  The assert_param macro is used for function's parameters check.
-  * @param expr If expr is false, it calls assert_failed function
-  *         which reports the name of the source file and the source
-  *         line number of the call that failed.
-  *         If expr is true, it returns no value.
-  * @retval None
-  */
-  #define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__))
-/* Exported functions ------------------------------------------------------- */
-  void assert_failed(uint8_t* file, uint32_t line);
-#else
-  #define assert_param(expr) ((void)0U)
-#endif /* USE_FULL_ASSERT */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __STM32WBxx_HAL_CONF_H */

+ 0 - 2422
non_catalog_apps/flipperscope/lib/adc/inc/stm32wbxx_hal_tim.h

@@ -1,2422 +0,0 @@
-/**
-  ******************************************************************************
-  * @file    stm32wbxx_hal_tim.h
-  * @author  MCD Application Team
-  * @brief   Header file of TIM 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 STM32WBxx_HAL_TIM_H
-#define STM32WBxx_HAL_TIM_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32wbxx_hal_def.h"
-
-/** @addtogroup STM32WBxx_HAL_Driver
-  * @{
-  */
-
-/** @addtogroup TIM
-  * @{
-  */
-
-/* Exported types ------------------------------------------------------------*/
-/** @defgroup TIM_Exported_Types TIM Exported Types
-  * @{
-  */
-
-/**
-  * @brief  TIM Time base Configuration Structure definition
-  */
-typedef struct
-{
-  uint32_t Prescaler;         /*!< Specifies the prescaler value used to divide the TIM clock.
-                                   This parameter can be a number between Min_Data = 0x0000 and Max_Data = 0xFFFF */
-
-  uint32_t CounterMode;       /*!< Specifies the counter mode.
-                                   This parameter can be a value of @ref TIM_Counter_Mode */
-
-  uint32_t Period;            /*!< Specifies the period value to be loaded into the active
-                                   Auto-Reload Register at the next update event.
-                                   This parameter can be a number between Min_Data = 0x0000 and Max_Data = 0xFFFF.  */
-
-  uint32_t ClockDivision;     /*!< Specifies the clock division.
-                                   This parameter can be a value of @ref TIM_ClockDivision */
-
-  uint32_t RepetitionCounter;  /*!< Specifies the repetition counter value. Each time the RCR downcounter
-                                    reaches zero, an update event is generated and counting restarts
-                                    from the RCR value (N).
-                                    This means in PWM mode that (N+1) corresponds to:
-                                        - the number of PWM periods in edge-aligned mode
-                                        - the number of half PWM period in center-aligned mode
-                                     GP timers: this parameter must be a number between Min_Data = 0x00 and
-                                     Max_Data = 0xFF.
-                                     Advanced timers: this parameter must be a number between Min_Data = 0x0000 and
-                                     Max_Data = 0xFFFF. */
-
-  uint32_t AutoReloadPreload;  /*!< Specifies the auto-reload preload.
-                                   This parameter can be a value of @ref TIM_AutoReloadPreload */
-} TIM_Base_InitTypeDef;
-
-/**
-  * @brief  TIM Output Compare Configuration Structure definition
-  */
-typedef struct
-{
-  uint32_t OCMode;        /*!< Specifies the TIM mode.
-                               This parameter can be a value of @ref TIM_Output_Compare_and_PWM_modes */
-
-  uint32_t Pulse;         /*!< Specifies the pulse value to be loaded into the Capture Compare Register.
-                               This parameter can be a number between Min_Data = 0x0000 and Max_Data = 0xFFFF */
-
-  uint32_t OCPolarity;    /*!< Specifies the output polarity.
-                               This parameter can be a value of @ref TIM_Output_Compare_Polarity */
-
-  uint32_t OCNPolarity;   /*!< Specifies the complementary output polarity.
-                               This parameter can be a value of @ref TIM_Output_Compare_N_Polarity
-                               @note This parameter is valid only for timer instances supporting break feature. */
-
-  uint32_t OCFastMode;    /*!< Specifies the Fast mode state.
-                               This parameter can be a value of @ref TIM_Output_Fast_State
-                               @note This parameter is valid only in PWM1 and PWM2 mode. */
-
-
-  uint32_t OCIdleState;   /*!< Specifies the TIM Output Compare pin state during Idle state.
-                               This parameter can be a value of @ref TIM_Output_Compare_Idle_State
-                               @note This parameter is valid only for timer instances supporting break feature. */
-
-  uint32_t OCNIdleState;  /*!< Specifies the TIM Output Compare pin state during Idle state.
-                               This parameter can be a value of @ref TIM_Output_Compare_N_Idle_State
-                               @note This parameter is valid only for timer instances supporting break feature. */
-} TIM_OC_InitTypeDef;
-
-/**
-  * @brief  TIM One Pulse Mode Configuration Structure definition
-  */
-typedef struct
-{
-  uint32_t OCMode;        /*!< Specifies the TIM mode.
-                               This parameter can be a value of @ref TIM_Output_Compare_and_PWM_modes */
-
-  uint32_t Pulse;         /*!< Specifies the pulse value to be loaded into the Capture Compare Register.
-                               This parameter can be a number between Min_Data = 0x0000 and Max_Data = 0xFFFF */
-
-  uint32_t OCPolarity;    /*!< Specifies the output polarity.
-                               This parameter can be a value of @ref TIM_Output_Compare_Polarity */
-
-  uint32_t OCNPolarity;   /*!< Specifies the complementary output polarity.
-                               This parameter can be a value of @ref TIM_Output_Compare_N_Polarity
-                               @note This parameter is valid only for timer instances supporting break feature. */
-
-  uint32_t OCIdleState;   /*!< Specifies the TIM Output Compare pin state during Idle state.
-                               This parameter can be a value of @ref TIM_Output_Compare_Idle_State
-                               @note This parameter is valid only for timer instances supporting break feature. */
-
-  uint32_t OCNIdleState;  /*!< Specifies the TIM Output Compare pin state during Idle state.
-                               This parameter can be a value of @ref TIM_Output_Compare_N_Idle_State
-                               @note This parameter is valid only for timer instances supporting break feature. */
-
-  uint32_t ICPolarity;    /*!< Specifies the active edge of the input signal.
-                               This parameter can be a value of @ref TIM_Input_Capture_Polarity */
-
-  uint32_t ICSelection;   /*!< Specifies the input.
-                              This parameter can be a value of @ref TIM_Input_Capture_Selection */
-
-  uint32_t ICFilter;      /*!< Specifies the input capture filter.
-                              This parameter can be a number between Min_Data = 0x0 and Max_Data = 0xF */
-} TIM_OnePulse_InitTypeDef;
-
-/**
-  * @brief  TIM Input Capture Configuration Structure definition
-  */
-typedef struct
-{
-  uint32_t  ICPolarity;  /*!< Specifies the active edge of the input signal.
-                              This parameter can be a value of @ref TIM_Input_Capture_Polarity */
-
-  uint32_t ICSelection;  /*!< Specifies the input.
-                              This parameter can be a value of @ref TIM_Input_Capture_Selection */
-
-  uint32_t ICPrescaler;  /*!< Specifies the Input Capture Prescaler.
-                              This parameter can be a value of @ref TIM_Input_Capture_Prescaler */
-
-  uint32_t ICFilter;     /*!< Specifies the input capture filter.
-                              This parameter can be a number between Min_Data = 0x0 and Max_Data = 0xF */
-} TIM_IC_InitTypeDef;
-
-/**
-  * @brief  TIM Encoder Configuration Structure definition
-  */
-typedef struct
-{
-  uint32_t EncoderMode;   /*!< Specifies the active edge of the input signal.
-                               This parameter can be a value of @ref TIM_Encoder_Mode */
-
-  uint32_t IC1Polarity;   /*!< Specifies the active edge of the input signal.
-                               This parameter can be a value of @ref TIM_Encoder_Input_Polarity */
-
-  uint32_t IC1Selection;  /*!< Specifies the input.
-                               This parameter can be a value of @ref TIM_Input_Capture_Selection */
-
-  uint32_t IC1Prescaler;  /*!< Specifies the Input Capture Prescaler.
-                               This parameter can be a value of @ref TIM_Input_Capture_Prescaler */
-
-  uint32_t IC1Filter;     /*!< Specifies the input capture filter.
-                               This parameter can be a number between Min_Data = 0x0 and Max_Data = 0xF */
-
-  uint32_t IC2Polarity;   /*!< Specifies the active edge of the input signal.
-                               This parameter can be a value of @ref TIM_Encoder_Input_Polarity */
-
-  uint32_t IC2Selection;  /*!< Specifies the input.
-                              This parameter can be a value of @ref TIM_Input_Capture_Selection */
-
-  uint32_t IC2Prescaler;  /*!< Specifies the Input Capture Prescaler.
-                               This parameter can be a value of @ref TIM_Input_Capture_Prescaler */
-
-  uint32_t IC2Filter;     /*!< Specifies the input capture filter.
-                               This parameter can be a number between Min_Data = 0x0 and Max_Data = 0xF */
-} TIM_Encoder_InitTypeDef;
-
-/**
-  * @brief  Clock Configuration Handle Structure definition
-  */
-typedef struct
-{
-  uint32_t ClockSource;     /*!< TIM clock sources
-                                 This parameter can be a value of @ref TIM_Clock_Source */
-  uint32_t ClockPolarity;   /*!< TIM clock polarity
-                                 This parameter can be a value of @ref TIM_Clock_Polarity */
-  uint32_t ClockPrescaler;  /*!< TIM clock prescaler
-                                 This parameter can be a value of @ref TIM_Clock_Prescaler */
-  uint32_t ClockFilter;     /*!< TIM clock filter
-                                 This parameter can be a number between Min_Data = 0x0 and Max_Data = 0xF */
-} TIM_ClockConfigTypeDef;
-
-/**
-  * @brief  TIM Clear Input Configuration Handle Structure definition
-  */
-typedef struct
-{
-  uint32_t ClearInputState;      /*!< TIM clear Input state
-                                      This parameter can be ENABLE or DISABLE */
-  uint32_t ClearInputSource;     /*!< TIM clear Input sources
-                                      This parameter can be a value of @ref TIM_ClearInput_Source */
-  uint32_t ClearInputPolarity;   /*!< TIM Clear Input polarity
-                                      This parameter can be a value of @ref TIM_ClearInput_Polarity */
-  uint32_t ClearInputPrescaler;  /*!< TIM Clear Input prescaler
-                                      This parameter must be 0: When OCRef clear feature is used with ETR source,
-                                      ETR prescaler must be off */
-  uint32_t ClearInputFilter;     /*!< TIM Clear Input filter
-                                      This parameter can be a number between Min_Data = 0x0 and Max_Data = 0xF */
-} TIM_ClearInputConfigTypeDef;
-
-/**
-  * @brief  TIM Master configuration Structure definition
-  * @note   Advanced timers provide TRGO2 internal line which is redirected
-  *         to the ADC
-  */
-typedef struct
-{
-  uint32_t  MasterOutputTrigger;   /*!< Trigger output (TRGO) selection
-                                        This parameter can be a value of @ref TIM_Master_Mode_Selection */
-  uint32_t  MasterOutputTrigger2;  /*!< Trigger output2 (TRGO2) selection
-                                        This parameter can be a value of @ref TIM_Master_Mode_Selection_2 */
-  uint32_t  MasterSlaveMode;       /*!< Master/slave mode selection
-                                        This parameter can be a value of @ref TIM_Master_Slave_Mode
-                                        @note When the Master/slave mode is enabled, the effect of
-                                        an event on the trigger input (TRGI) is delayed to allow a
-                                        perfect synchronization between the current timer and its
-                                        slaves (through TRGO). It is not mandatory in case of timer
-                                        synchronization mode. */
-} TIM_MasterConfigTypeDef;
-
-/**
-  * @brief  TIM Slave configuration Structure definition
-  */
-typedef struct
-{
-  uint32_t  SlaveMode;         /*!< Slave mode selection
-                                    This parameter can be a value of @ref TIM_Slave_Mode */
-  uint32_t  InputTrigger;      /*!< Input Trigger source
-                                    This parameter can be a value of @ref TIM_Trigger_Selection */
-  uint32_t  TriggerPolarity;   /*!< Input Trigger polarity
-                                    This parameter can be a value of @ref TIM_Trigger_Polarity */
-  uint32_t  TriggerPrescaler;  /*!< Input trigger prescaler
-                                    This parameter can be a value of @ref TIM_Trigger_Prescaler */
-  uint32_t  TriggerFilter;     /*!< Input trigger filter
-                                    This parameter can be a number between Min_Data = 0x0 and Max_Data = 0xF  */
-
-} TIM_SlaveConfigTypeDef;
-
-/**
-  * @brief  TIM Break input(s) and Dead time configuration Structure definition
-  * @note   2 break inputs can be configured (BKIN and BKIN2) with configurable
-  *        filter and polarity.
-  */
-typedef struct
-{
-  uint32_t OffStateRunMode;      /*!< TIM off state in run mode, This parameter can be a value of @ref TIM_OSSR_Off_State_Selection_for_Run_mode_state */
-
-  uint32_t OffStateIDLEMode;     /*!< TIM off state in IDLE mode, This parameter can be a value of @ref TIM_OSSI_Off_State_Selection_for_Idle_mode_state */
-
-  uint32_t LockLevel;            /*!< TIM Lock level, This parameter can be a value of @ref TIM_Lock_level */
-
-  uint32_t DeadTime;             /*!< TIM dead Time, This parameter can be a number between Min_Data = 0x00 and Max_Data = 0xFF */
-
-  uint32_t BreakState;           /*!< TIM Break State, This parameter can be a value of @ref TIM_Break_Input_enable_disable */
-
-  uint32_t BreakPolarity;        /*!< TIM Break input polarity, This parameter can be a value of @ref TIM_Break_Polarity */
-
-  uint32_t BreakFilter;          /*!< Specifies the break input filter.This parameter can be a number between Min_Data = 0x0 and Max_Data = 0xF */
-
-  uint32_t BreakAFMode;          /*!< Specifies the alternate function mode of the break input.This parameter can be a value of @ref TIM_Break_Input_AF_Mode */
-
-  uint32_t Break2State;          /*!< TIM Break2 State, This parameter can be a value of @ref TIM_Break2_Input_enable_disable */
-
-  uint32_t Break2Polarity;       /*!< TIM Break2 input polarity, This parameter can be a value of @ref TIM_Break2_Polarity */
-
-  uint32_t Break2Filter;         /*!< TIM break2 input filter.This parameter can be a number between Min_Data = 0x0 and Max_Data = 0xF */
-
-  uint32_t Break2AFMode;         /*!< Specifies the alternate function mode of the break2 input.This parameter can be a value of @ref TIM_Break2_Input_AF_Mode */
-
-  uint32_t AutomaticOutput;      /*!< TIM Automatic Output Enable state, This parameter can be a value of @ref TIM_AOE_Bit_Set_Reset */
-
-} TIM_BreakDeadTimeConfigTypeDef;
-
-/**
-  * @brief  HAL State structures definition
-  */
-typedef enum
-{
-  HAL_TIM_STATE_RESET             = 0x00U,    /*!< Peripheral not yet initialized or disabled  */
-  HAL_TIM_STATE_READY             = 0x01U,    /*!< Peripheral Initialized and ready for use    */
-  HAL_TIM_STATE_BUSY              = 0x02U,    /*!< An internal process is ongoing              */
-  HAL_TIM_STATE_TIMEOUT           = 0x03U,    /*!< Timeout state                               */
-  HAL_TIM_STATE_ERROR             = 0x04U     /*!< Reception process is ongoing                */
-} HAL_TIM_StateTypeDef;
-
-/**
-  * @brief  TIM Channel States definition
-  */
-typedef enum
-{
-  HAL_TIM_CHANNEL_STATE_RESET             = 0x00U,    /*!< TIM Channel initial state                         */
-  HAL_TIM_CHANNEL_STATE_READY             = 0x01U,    /*!< TIM Channel ready for use                         */
-  HAL_TIM_CHANNEL_STATE_BUSY              = 0x02U,    /*!< An internal process is ongoing on the TIM channel */
-} HAL_TIM_ChannelStateTypeDef;
-
-/**
-  * @brief  DMA Burst States definition
-  */
-typedef enum
-{
-  HAL_DMA_BURST_STATE_RESET             = 0x00U,    /*!< DMA Burst initial state */
-  HAL_DMA_BURST_STATE_READY             = 0x01U,    /*!< DMA Burst ready for use */
-  HAL_DMA_BURST_STATE_BUSY              = 0x02U,    /*!< Ongoing DMA Burst       */
-} HAL_TIM_DMABurstStateTypeDef;
-
-/**
-  * @brief  HAL Active channel structures definition
-  */
-typedef enum
-{
-  HAL_TIM_ACTIVE_CHANNEL_1        = 0x01U,    /*!< The active channel is 1     */
-  HAL_TIM_ACTIVE_CHANNEL_2        = 0x02U,    /*!< The active channel is 2     */
-  HAL_TIM_ACTIVE_CHANNEL_3        = 0x04U,    /*!< The active channel is 3     */
-  HAL_TIM_ACTIVE_CHANNEL_4        = 0x08U,    /*!< The active channel is 4     */
-  HAL_TIM_ACTIVE_CHANNEL_5        = 0x10U,    /*!< The active channel is 5     */
-  HAL_TIM_ACTIVE_CHANNEL_6        = 0x20U,    /*!< The active channel is 6     */
-  HAL_TIM_ACTIVE_CHANNEL_CLEARED  = 0x00U     /*!< All active channels cleared */
-} HAL_TIM_ActiveChannel;
-
-/**
-  * @brief  TIM Time Base Handle Structure definition
-  */
-#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
-typedef struct __TIM_HandleTypeDef
-#else
-typedef struct
-#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
-{
-  TIM_TypeDef                        *Instance;         /*!< Register base address                             */
-  TIM_Base_InitTypeDef               Init;              /*!< TIM Time Base required parameters                 */
-  HAL_TIM_ActiveChannel              Channel;           /*!< Active channel                                    */
-  DMA_HandleTypeDef                  *hdma[7];          /*!< DMA Handlers array
-                                                             This array is accessed by a @ref DMA_Handle_index */
-  HAL_LockTypeDef                    Lock;              /*!< Locking object                                    */
-  __IO HAL_TIM_StateTypeDef          State;             /*!< TIM operation state                               */
-  __IO HAL_TIM_ChannelStateTypeDef   ChannelState[6];   /*!< TIM channel operation state                       */
-  __IO HAL_TIM_ChannelStateTypeDef   ChannelNState[4];  /*!< TIM complementary channel operation state         */
-  __IO HAL_TIM_DMABurstStateTypeDef  DMABurstState;     /*!< DMA burst operation state                         */
-
-#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
-  void (* Base_MspInitCallback)(struct __TIM_HandleTypeDef *htim);              /*!< TIM Base Msp Init Callback                              */
-  void (* Base_MspDeInitCallback)(struct __TIM_HandleTypeDef *htim);            /*!< TIM Base Msp DeInit Callback                            */
-  void (* IC_MspInitCallback)(struct __TIM_HandleTypeDef *htim);                /*!< TIM IC Msp Init Callback                                */
-  void (* IC_MspDeInitCallback)(struct __TIM_HandleTypeDef *htim);              /*!< TIM IC Msp DeInit Callback                              */
-  void (* OC_MspInitCallback)(struct __TIM_HandleTypeDef *htim);                /*!< TIM OC Msp Init Callback                                */
-  void (* OC_MspDeInitCallback)(struct __TIM_HandleTypeDef *htim);              /*!< TIM OC Msp DeInit Callback                              */
-  void (* PWM_MspInitCallback)(struct __TIM_HandleTypeDef *htim);               /*!< TIM PWM Msp Init Callback                               */
-  void (* PWM_MspDeInitCallback)(struct __TIM_HandleTypeDef *htim);             /*!< TIM PWM Msp DeInit Callback                             */
-  void (* OnePulse_MspInitCallback)(struct __TIM_HandleTypeDef *htim);          /*!< TIM One Pulse Msp Init Callback                         */
-  void (* OnePulse_MspDeInitCallback)(struct __TIM_HandleTypeDef *htim);        /*!< TIM One Pulse Msp DeInit Callback                       */
-  void (* Encoder_MspInitCallback)(struct __TIM_HandleTypeDef *htim);           /*!< TIM Encoder Msp Init Callback                           */
-  void (* Encoder_MspDeInitCallback)(struct __TIM_HandleTypeDef *htim);         /*!< TIM Encoder Msp DeInit Callback                         */
-  void (* HallSensor_MspInitCallback)(struct __TIM_HandleTypeDef *htim);        /*!< TIM Hall Sensor Msp Init Callback                       */
-  void (* HallSensor_MspDeInitCallback)(struct __TIM_HandleTypeDef *htim);      /*!< TIM Hall Sensor Msp DeInit Callback                     */
-  void (* PeriodElapsedCallback)(struct __TIM_HandleTypeDef *htim);             /*!< TIM Period Elapsed Callback                             */
-  void (* PeriodElapsedHalfCpltCallback)(struct __TIM_HandleTypeDef *htim);     /*!< TIM Period Elapsed half complete Callback               */
-  void (* TriggerCallback)(struct __TIM_HandleTypeDef *htim);                   /*!< TIM Trigger Callback                                    */
-  void (* TriggerHalfCpltCallback)(struct __TIM_HandleTypeDef *htim);           /*!< TIM Trigger half complete Callback                      */
-  void (* IC_CaptureCallback)(struct __TIM_HandleTypeDef *htim);                /*!< TIM Input Capture Callback                              */
-  void (* IC_CaptureHalfCpltCallback)(struct __TIM_HandleTypeDef *htim);        /*!< TIM Input Capture half complete Callback                */
-  void (* OC_DelayElapsedCallback)(struct __TIM_HandleTypeDef *htim);           /*!< TIM Output Compare Delay Elapsed Callback               */
-  void (* PWM_PulseFinishedCallback)(struct __TIM_HandleTypeDef *htim);         /*!< TIM PWM Pulse Finished Callback                         */
-  void (* PWM_PulseFinishedHalfCpltCallback)(struct __TIM_HandleTypeDef *htim); /*!< TIM PWM Pulse Finished half complete Callback           */
-  void (* ErrorCallback)(struct __TIM_HandleTypeDef *htim);                     /*!< TIM Error Callback                                      */
-  void (* CommutationCallback)(struct __TIM_HandleTypeDef *htim);               /*!< TIM Commutation Callback                                */
-  void (* CommutationHalfCpltCallback)(struct __TIM_HandleTypeDef *htim);       /*!< TIM Commutation half complete Callback                  */
-  void (* BreakCallback)(struct __TIM_HandleTypeDef *htim);                     /*!< TIM Break Callback                                      */
-  void (* Break2Callback)(struct __TIM_HandleTypeDef *htim);                    /*!< TIM Break2 Callback                                     */
-#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
-} TIM_HandleTypeDef;
-
-#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
-/**
-  * @brief  HAL TIM Callback ID enumeration definition
-  */
-typedef enum
-{
-  HAL_TIM_BASE_MSPINIT_CB_ID              = 0x00U   /*!< TIM Base MspInit Callback ID                              */
-  , HAL_TIM_BASE_MSPDEINIT_CB_ID          = 0x01U   /*!< TIM Base MspDeInit Callback ID                            */
-  , HAL_TIM_IC_MSPINIT_CB_ID              = 0x02U   /*!< TIM IC MspInit Callback ID                                */
-  , HAL_TIM_IC_MSPDEINIT_CB_ID            = 0x03U   /*!< TIM IC MspDeInit Callback ID                              */
-  , HAL_TIM_OC_MSPINIT_CB_ID              = 0x04U   /*!< TIM OC MspInit Callback ID                                */
-  , HAL_TIM_OC_MSPDEINIT_CB_ID            = 0x05U   /*!< TIM OC MspDeInit Callback ID                              */
-  , HAL_TIM_PWM_MSPINIT_CB_ID             = 0x06U   /*!< TIM PWM MspInit Callback ID                               */
-  , HAL_TIM_PWM_MSPDEINIT_CB_ID           = 0x07U   /*!< TIM PWM MspDeInit Callback ID                             */
-  , HAL_TIM_ONE_PULSE_MSPINIT_CB_ID       = 0x08U   /*!< TIM One Pulse MspInit Callback ID                         */
-  , HAL_TIM_ONE_PULSE_MSPDEINIT_CB_ID     = 0x09U   /*!< TIM One Pulse MspDeInit Callback ID                       */
-  , HAL_TIM_ENCODER_MSPINIT_CB_ID         = 0x0AU   /*!< TIM Encoder MspInit Callback ID                           */
-  , HAL_TIM_ENCODER_MSPDEINIT_CB_ID       = 0x0BU   /*!< TIM Encoder MspDeInit Callback ID                         */
-  , HAL_TIM_HALL_SENSOR_MSPINIT_CB_ID     = 0x0CU   /*!< TIM Hall Sensor MspDeInit Callback ID                     */
-  , HAL_TIM_HALL_SENSOR_MSPDEINIT_CB_ID   = 0x0DU   /*!< TIM Hall Sensor MspDeInit Callback ID                     */
-  , HAL_TIM_PERIOD_ELAPSED_CB_ID          = 0x0EU   /*!< TIM Period Elapsed Callback ID                             */
-  , HAL_TIM_PERIOD_ELAPSED_HALF_CB_ID     = 0x0FU   /*!< TIM Period Elapsed half complete Callback ID               */
-  , HAL_TIM_TRIGGER_CB_ID                 = 0x10U   /*!< TIM Trigger Callback ID                                    */
-  , HAL_TIM_TRIGGER_HALF_CB_ID            = 0x11U   /*!< TIM Trigger half complete Callback ID                      */
-
-  , HAL_TIM_IC_CAPTURE_CB_ID              = 0x12U   /*!< TIM Input Capture Callback ID                              */
-  , HAL_TIM_IC_CAPTURE_HALF_CB_ID         = 0x13U   /*!< TIM Input Capture half complete Callback ID                */
-  , HAL_TIM_OC_DELAY_ELAPSED_CB_ID        = 0x14U   /*!< TIM Output Compare Delay Elapsed Callback ID               */
-  , HAL_TIM_PWM_PULSE_FINISHED_CB_ID      = 0x15U   /*!< TIM PWM Pulse Finished Callback ID           */
-  , HAL_TIM_PWM_PULSE_FINISHED_HALF_CB_ID = 0x16U   /*!< TIM PWM Pulse Finished half complete Callback ID           */
-  , HAL_TIM_ERROR_CB_ID                   = 0x17U   /*!< TIM Error Callback ID                                      */
-  , HAL_TIM_COMMUTATION_CB_ID             = 0x18U   /*!< TIM Commutation Callback ID                                */
-  , HAL_TIM_COMMUTATION_HALF_CB_ID        = 0x19U   /*!< TIM Commutation half complete Callback ID                  */
-  , HAL_TIM_BREAK_CB_ID                   = 0x1AU   /*!< TIM Break Callback ID                                      */
-  , HAL_TIM_BREAK2_CB_ID                  = 0x1BU   /*!< TIM Break2 Callback ID                                     */
-} HAL_TIM_CallbackIDTypeDef;
-
-/**
-  * @brief  HAL TIM Callback pointer definition
-  */
-typedef  void (*pTIM_CallbackTypeDef)(TIM_HandleTypeDef *htim);  /*!< pointer to the TIM callback function */
-
-#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
-
-/**
-  * @}
-  */
-/* End of exported types -----------------------------------------------------*/
-
-/* Exported constants --------------------------------------------------------*/
-/** @defgroup TIM_Exported_Constants TIM Exported Constants
-  * @{
-  */
-
-/** @defgroup TIM_ClearInput_Source TIM Clear Input Source
-  * @{
-  */
-#define TIM_CLEARINPUTSOURCE_NONE           0x00000000U         /*!< OCREF_CLR is disabled */
-#define TIM_CLEARINPUTSOURCE_ETR            0x00000001U         /*!< OCREF_CLR is connected to ETRF input */
-#define TIM_CLEARINPUTSOURCE_COMP1          TIM1_AF1_ETRSEL_0   /*!< OCREF_CLR_INT is connected to COMP1 output */
-#define TIM_CLEARINPUTSOURCE_COMP2          TIM1_AF1_ETRSEL_1   /*!< OCREF_CLR_INT is connected to COMP2 output */
-/**
-  * @}
-  */
-
-/** @defgroup TIM_DMA_Base_address TIM DMA Base Address
-  * @{
-  */
-#define TIM_DMABASE_CR1                    0x00000000U
-#define TIM_DMABASE_CR2                    0x00000001U
-#define TIM_DMABASE_SMCR                   0x00000002U
-#define TIM_DMABASE_DIER                   0x00000003U
-#define TIM_DMABASE_SR                     0x00000004U
-#define TIM_DMABASE_EGR                    0x00000005U
-#define TIM_DMABASE_CCMR1                  0x00000006U
-#define TIM_DMABASE_CCMR2                  0x00000007U
-#define TIM_DMABASE_CCER                   0x00000008U
-#define TIM_DMABASE_CNT                    0x00000009U
-#define TIM_DMABASE_PSC                    0x0000000AU
-#define TIM_DMABASE_ARR                    0x0000000BU
-#define TIM_DMABASE_RCR                    0x0000000CU
-#define TIM_DMABASE_CCR1                   0x0000000DU
-#define TIM_DMABASE_CCR2                   0x0000000EU
-#define TIM_DMABASE_CCR3                   0x0000000FU
-#define TIM_DMABASE_CCR4                   0x00000010U
-#define TIM_DMABASE_BDTR                   0x00000011U
-#define TIM_DMABASE_DCR                    0x00000012U
-#define TIM_DMABASE_DMAR                   0x00000013U
-#define TIM_DMABASE_OR                     0x00000014U
-#define TIM_DMABASE_CCMR3                  0x00000015U
-#define TIM_DMABASE_CCR5                   0x00000016U
-#define TIM_DMABASE_CCR6                   0x00000017U
-#define TIM_DMABASE_AF1                    0x00000018U
-#define TIM_DMABASE_AF2                    0x00000019U
-/**
-  * @}
-  */
-
-/** @defgroup TIM_Event_Source TIM Event Source
-  * @{
-  */
-#define TIM_EVENTSOURCE_UPDATE              TIM_EGR_UG     /*!< Reinitialize the counter and generates an update of the registers */
-#define TIM_EVENTSOURCE_CC1                 TIM_EGR_CC1G   /*!< A capture/compare event is generated on channel 1 */
-#define TIM_EVENTSOURCE_CC2                 TIM_EGR_CC2G   /*!< A capture/compare event is generated on channel 2 */
-#define TIM_EVENTSOURCE_CC3                 TIM_EGR_CC3G   /*!< A capture/compare event is generated on channel 3 */
-#define TIM_EVENTSOURCE_CC4                 TIM_EGR_CC4G   /*!< A capture/compare event is generated on channel 4 */
-#define TIM_EVENTSOURCE_COM                 TIM_EGR_COMG   /*!< A commutation event is generated */
-#define TIM_EVENTSOURCE_TRIGGER             TIM_EGR_TG     /*!< A trigger event is generated */
-#define TIM_EVENTSOURCE_BREAK               TIM_EGR_BG     /*!< A break event is generated */
-#define TIM_EVENTSOURCE_BREAK2              TIM_EGR_B2G    /*!< A break 2 event is generated */
-/**
-  * @}
-  */
-
-/** @defgroup TIM_Input_Channel_Polarity TIM Input Channel polarity
-  * @{
-  */
-#define  TIM_INPUTCHANNELPOLARITY_RISING      0x00000000U                       /*!< Polarity for TIx source */
-#define  TIM_INPUTCHANNELPOLARITY_FALLING     TIM_CCER_CC1P                     /*!< Polarity for TIx source */
-#define  TIM_INPUTCHANNELPOLARITY_BOTHEDGE    (TIM_CCER_CC1P | TIM_CCER_CC1NP)  /*!< Polarity for TIx source */
-/**
-  * @}
-  */
-
-/** @defgroup TIM_ETR_Polarity TIM ETR Polarity
-  * @{
-  */
-#define TIM_ETRPOLARITY_INVERTED              TIM_SMCR_ETP                      /*!< Polarity for ETR source */
-#define TIM_ETRPOLARITY_NONINVERTED           0x00000000U                       /*!< Polarity for ETR source */
-/**
-  * @}
-  */
-
-/** @defgroup TIM_ETR_Prescaler TIM ETR Prescaler
-  * @{
-  */
-#define TIM_ETRPRESCALER_DIV1                 0x00000000U                       /*!< No prescaler is used */
-#define TIM_ETRPRESCALER_DIV2                 TIM_SMCR_ETPS_0                   /*!< ETR input source is divided by 2 */
-#define TIM_ETRPRESCALER_DIV4                 TIM_SMCR_ETPS_1                   /*!< ETR input source is divided by 4 */
-#define TIM_ETRPRESCALER_DIV8                 TIM_SMCR_ETPS                     /*!< ETR input source is divided by 8 */
-/**
-  * @}
-  */
-
-/** @defgroup TIM_Counter_Mode TIM Counter Mode
-  * @{
-  */
-#define TIM_COUNTERMODE_UP                 0x00000000U                          /*!< Counter used as up-counter   */
-#define TIM_COUNTERMODE_DOWN               TIM_CR1_DIR                          /*!< Counter used as down-counter */
-#define TIM_COUNTERMODE_CENTERALIGNED1     TIM_CR1_CMS_0                        /*!< Center-aligned mode 1        */
-#define TIM_COUNTERMODE_CENTERALIGNED2     TIM_CR1_CMS_1                        /*!< Center-aligned mode 2        */
-#define TIM_COUNTERMODE_CENTERALIGNED3     TIM_CR1_CMS                          /*!< Center-aligned mode 3        */
-/**
-  * @}
-  */
-
-/** @defgroup TIM_Update_Interrupt_Flag_Remap TIM Update Interrupt Flag Remap
-  * @{
-  */
-#define TIM_UIFREMAP_DISABLE               0x00000000U                          /*!< Update interrupt flag remap disabled */
-#define TIM_UIFREMAP_ENABLE                TIM_CR1_UIFREMAP                     /*!< Update interrupt flag remap enabled */
-/**
-  * @}
-  */
-
-/** @defgroup TIM_ClockDivision TIM Clock Division
-  * @{
-  */
-#define TIM_CLOCKDIVISION_DIV1             0x00000000U                          /*!< Clock division: tDTS=tCK_INT   */
-#define TIM_CLOCKDIVISION_DIV2             TIM_CR1_CKD_0                        /*!< Clock division: tDTS=2*tCK_INT */
-#define TIM_CLOCKDIVISION_DIV4             TIM_CR1_CKD_1                        /*!< Clock division: tDTS=4*tCK_INT */
-/**
-  * @}
-  */
-
-/** @defgroup TIM_Output_Compare_State TIM Output Compare State
-  * @{
-  */
-#define TIM_OUTPUTSTATE_DISABLE            0x00000000U                          /*!< Capture/Compare 1 output disabled */
-#define TIM_OUTPUTSTATE_ENABLE             TIM_CCER_CC1E                        /*!< Capture/Compare 1 output enabled */
-/**
-  * @}
-  */
-
-/** @defgroup TIM_AutoReloadPreload TIM Auto-Reload Preload
-  * @{
-  */
-#define TIM_AUTORELOAD_PRELOAD_DISABLE                0x00000000U               /*!< TIMx_ARR register is not buffered */
-#define TIM_AUTORELOAD_PRELOAD_ENABLE                 TIM_CR1_ARPE              /*!< TIMx_ARR register is buffered */
-
-/**
-  * @}
-  */
-
-/** @defgroup TIM_Output_Fast_State TIM Output Fast State
-  * @{
-  */
-#define TIM_OCFAST_DISABLE                 0x00000000U                          /*!< Output Compare fast disable */
-#define TIM_OCFAST_ENABLE                  TIM_CCMR1_OC1FE                      /*!< Output Compare fast enable  */
-/**
-  * @}
-  */
-
-/** @defgroup TIM_Output_Compare_N_State TIM Complementary Output Compare State
-  * @{
-  */
-#define TIM_OUTPUTNSTATE_DISABLE           0x00000000U                          /*!< OCxN is disabled  */
-#define TIM_OUTPUTNSTATE_ENABLE            TIM_CCER_CC1NE                       /*!< OCxN is enabled   */
-/**
-  * @}
-  */
-
-/** @defgroup TIM_Output_Compare_Polarity TIM Output Compare Polarity
-  * @{
-  */
-#define TIM_OCPOLARITY_HIGH                0x00000000U                          /*!< Capture/Compare output polarity  */
-#define TIM_OCPOLARITY_LOW                 TIM_CCER_CC1P                        /*!< Capture/Compare output polarity  */
-/**
-  * @}
-  */
-
-/** @defgroup TIM_Output_Compare_N_Polarity TIM Complementary Output Compare Polarity
-  * @{
-  */
-#define TIM_OCNPOLARITY_HIGH               0x00000000U                          /*!< Capture/Compare complementary output polarity */
-#define TIM_OCNPOLARITY_LOW                TIM_CCER_CC1NP                       /*!< Capture/Compare complementary output polarity */
-/**
-  * @}
-  */
-
-/** @defgroup TIM_Output_Compare_Idle_State TIM Output Compare Idle State
-  * @{
-  */
-#define TIM_OCIDLESTATE_SET                TIM_CR2_OIS1                         /*!< Output Idle state: OCx=1 when MOE=0 */
-#define TIM_OCIDLESTATE_RESET              0x00000000U                          /*!< Output Idle state: OCx=0 when MOE=0 */
-/**
-  * @}
-  */
-
-/** @defgroup TIM_Output_Compare_N_Idle_State TIM Complementary Output Compare Idle State
-  * @{
-  */
-#define TIM_OCNIDLESTATE_SET               TIM_CR2_OIS1N                        /*!< Complementary output Idle state: OCxN=1 when MOE=0 */
-#define TIM_OCNIDLESTATE_RESET             0x00000000U                          /*!< Complementary output Idle state: OCxN=0 when MOE=0 */
-/**
-  * @}
-  */
-
-/** @defgroup TIM_Input_Capture_Polarity TIM Input Capture Polarity
-  * @{
-  */
-#define  TIM_ICPOLARITY_RISING             TIM_INPUTCHANNELPOLARITY_RISING      /*!< Capture triggered by rising edge on timer input                  */
-#define  TIM_ICPOLARITY_FALLING            TIM_INPUTCHANNELPOLARITY_FALLING     /*!< Capture triggered by falling edge on timer input                 */
-#define  TIM_ICPOLARITY_BOTHEDGE           TIM_INPUTCHANNELPOLARITY_BOTHEDGE    /*!< Capture triggered by both rising and falling edges on timer input*/
-/**
-  * @}
-  */
-
-/** @defgroup TIM_Encoder_Input_Polarity TIM Encoder Input Polarity
-  * @{
-  */
-#define  TIM_ENCODERINPUTPOLARITY_RISING   TIM_INPUTCHANNELPOLARITY_RISING      /*!< Encoder input with rising edge polarity  */
-#define  TIM_ENCODERINPUTPOLARITY_FALLING  TIM_INPUTCHANNELPOLARITY_FALLING     /*!< Encoder input with falling edge polarity */
-/**
-  * @}
-  */
-
-/** @defgroup TIM_Input_Capture_Selection TIM Input Capture Selection
-  * @{
-  */
-#define TIM_ICSELECTION_DIRECTTI           TIM_CCMR1_CC1S_0                     /*!< TIM Input 1, 2, 3 or 4 is selected to be connected to IC1, IC2, IC3 or IC4, respectively */
-#define TIM_ICSELECTION_INDIRECTTI         TIM_CCMR1_CC1S_1                     /*!< TIM Input 1, 2, 3 or 4 is selected to be connected to IC2, IC1, IC4 or IC3, respectively */
-#define TIM_ICSELECTION_TRC                TIM_CCMR1_CC1S                       /*!< TIM Input 1, 2, 3 or 4 is selected to be connected to TRC */
-/**
-  * @}
-  */
-
-/** @defgroup TIM_Input_Capture_Prescaler TIM Input Capture Prescaler
-  * @{
-  */
-#define TIM_ICPSC_DIV1                     0x00000000U                          /*!< Capture performed each time an edge is detected on the capture input */
-#define TIM_ICPSC_DIV2                     TIM_CCMR1_IC1PSC_0                   /*!< Capture performed once every 2 events                                */
-#define TIM_ICPSC_DIV4                     TIM_CCMR1_IC1PSC_1                   /*!< Capture performed once every 4 events                                */
-#define TIM_ICPSC_DIV8                     TIM_CCMR1_IC1PSC                     /*!< Capture performed once every 8 events                                */
-/**
-  * @}
-  */
-
-/** @defgroup TIM_One_Pulse_Mode TIM One Pulse Mode
-  * @{
-  */
-#define TIM_OPMODE_SINGLE                  TIM_CR1_OPM                          /*!< Counter stops counting at the next update event */
-#define TIM_OPMODE_REPETITIVE              0x00000000U                          /*!< Counter is not stopped at update event          */
-/**
-  * @}
-  */
-
-/** @defgroup TIM_Encoder_Mode TIM Encoder Mode
-  * @{
-  */
-#define TIM_ENCODERMODE_TI1                      TIM_SMCR_SMS_0                                                      /*!< Quadrature encoder mode 1, x2 mode, counts up/down on TI1FP1 edge depending on TI2FP2 level  */
-#define TIM_ENCODERMODE_TI2                      TIM_SMCR_SMS_1                                                      /*!< Quadrature encoder mode 2, x2 mode, counts up/down on TI2FP2 edge depending on TI1FP1 level. */
-#define TIM_ENCODERMODE_TI12                     (TIM_SMCR_SMS_1 | TIM_SMCR_SMS_0)                                   /*!< Quadrature encoder mode 3, x4 mode, counts up/down on both TI1FP1 and TI2FP2 edges depending on the level of the other input. */
-/**
-  * @}
-  */
-
-/** @defgroup TIM_Interrupt_definition TIM interrupt Definition
-  * @{
-  */
-#define TIM_IT_UPDATE                      TIM_DIER_UIE                         /*!< Update interrupt            */
-#define TIM_IT_CC1                         TIM_DIER_CC1IE                       /*!< Capture/Compare 1 interrupt */
-#define TIM_IT_CC2                         TIM_DIER_CC2IE                       /*!< Capture/Compare 2 interrupt */
-#define TIM_IT_CC3                         TIM_DIER_CC3IE                       /*!< Capture/Compare 3 interrupt */
-#define TIM_IT_CC4                         TIM_DIER_CC4IE                       /*!< Capture/Compare 4 interrupt */
-#define TIM_IT_COM                         TIM_DIER_COMIE                       /*!< Commutation interrupt       */
-#define TIM_IT_TRIGGER                     TIM_DIER_TIE                         /*!< Trigger interrupt           */
-#define TIM_IT_BREAK                       TIM_DIER_BIE                         /*!< Break interrupt             */
-/**
-  * @}
-  */
-
-/** @defgroup TIM_Commutation_Source  TIM Commutation Source
-  * @{
-  */
-#define TIM_COMMUTATION_TRGI              TIM_CR2_CCUS                          /*!< When Capture/compare control bits are preloaded, they are updated by setting the COMG bit or when an rising edge occurs on trigger input */
-#define TIM_COMMUTATION_SOFTWARE          0x00000000U                           /*!< When Capture/compare control bits are preloaded, they are updated by setting the COMG bit */
-/**
-  * @}
-  */
-
-/** @defgroup TIM_DMA_sources TIM DMA Sources
-  * @{
-  */
-#define TIM_DMA_UPDATE                     TIM_DIER_UDE                         /*!< DMA request is triggered by the update event */
-#define TIM_DMA_CC1                        TIM_DIER_CC1DE                       /*!< DMA request is triggered by the capture/compare macth 1 event */
-#define TIM_DMA_CC2                        TIM_DIER_CC2DE                       /*!< DMA request is triggered by the capture/compare macth 2 event event */
-#define TIM_DMA_CC3                        TIM_DIER_CC3DE                       /*!< DMA request is triggered by the capture/compare macth 3 event event */
-#define TIM_DMA_CC4                        TIM_DIER_CC4DE                       /*!< DMA request is triggered by the capture/compare macth 4 event event */
-#define TIM_DMA_COM                        TIM_DIER_COMDE                       /*!< DMA request is triggered by the commutation event */
-#define TIM_DMA_TRIGGER                    TIM_DIER_TDE                         /*!< DMA request is triggered by the trigger event */
-/**
-  * @}
-  */
-
-/** @defgroup TIM_CC_DMA_Request CCx DMA request selection
-  * @{
-  */
-#define TIM_CCDMAREQUEST_CC                 0x00000000U                         /*!< CCx DMA request sent when capture or compare match event occurs */
-#define TIM_CCDMAREQUEST_UPDATE             TIM_CR2_CCDS                        /*!< CCx DMA requests sent when update event occurs */
-/**
-  * @}
-  */
-
-/** @defgroup TIM_Flag_definition TIM Flag Definition
-  * @{
-  */
-#define TIM_FLAG_UPDATE                    TIM_SR_UIF                           /*!< Update interrupt flag         */
-#define TIM_FLAG_CC1                       TIM_SR_CC1IF                         /*!< Capture/Compare 1 interrupt flag */
-#define TIM_FLAG_CC2                       TIM_SR_CC2IF                         /*!< Capture/Compare 2 interrupt flag */
-#define TIM_FLAG_CC3                       TIM_SR_CC3IF                         /*!< Capture/Compare 3 interrupt flag */
-#define TIM_FLAG_CC4                       TIM_SR_CC4IF                         /*!< Capture/Compare 4 interrupt flag */
-#define TIM_FLAG_CC5                       TIM_SR_CC5IF                         /*!< Capture/Compare 5 interrupt flag */
-#define TIM_FLAG_CC6                       TIM_SR_CC6IF                         /*!< Capture/Compare 6 interrupt flag */
-#define TIM_FLAG_COM                       TIM_SR_COMIF                         /*!< Commutation interrupt flag    */
-#define TIM_FLAG_TRIGGER                   TIM_SR_TIF                           /*!< Trigger interrupt flag        */
-#define TIM_FLAG_BREAK                     TIM_SR_BIF                           /*!< Break interrupt flag          */
-#define TIM_FLAG_BREAK2                    TIM_SR_B2IF                          /*!< Break 2 interrupt flag        */
-#define TIM_FLAG_SYSTEM_BREAK              TIM_SR_SBIF                          /*!< System Break interrupt flag   */
-#define TIM_FLAG_CC1OF                     TIM_SR_CC1OF                         /*!< Capture 1 overcapture flag    */
-#define TIM_FLAG_CC2OF                     TIM_SR_CC2OF                         /*!< Capture 2 overcapture flag    */
-#define TIM_FLAG_CC3OF                     TIM_SR_CC3OF                         /*!< Capture 3 overcapture flag    */
-#define TIM_FLAG_CC4OF                     TIM_SR_CC4OF                         /*!< Capture 4 overcapture flag    */
-/**
-  * @}
-  */
-
-/** @defgroup TIM_Channel TIM Channel
-  * @{
-  */
-#define TIM_CHANNEL_1                      0x00000000U                          /*!< Capture/compare channel 1 identifier      */
-#define TIM_CHANNEL_2                      0x00000004U                          /*!< Capture/compare channel 2 identifier      */
-#define TIM_CHANNEL_3                      0x00000008U                          /*!< Capture/compare channel 3 identifier      */
-#define TIM_CHANNEL_4                      0x0000000CU                          /*!< Capture/compare channel 4 identifier      */
-#define TIM_CHANNEL_5                      0x00000010U                          /*!< Compare channel 5 identifier              */
-#define TIM_CHANNEL_6                      0x00000014U                          /*!< Compare channel 6 identifier              */
-#define TIM_CHANNEL_ALL                    0x0000003CU                          /*!< Global Capture/compare channel identifier  */
-/**
-  * @}
-  */
-
-/** @defgroup TIM_Clock_Source TIM Clock Source
-  * @{
-  */
-#define TIM_CLOCKSOURCE_INTERNAL    TIM_SMCR_ETPS_0      /*!< Internal clock source                                 */
-#define TIM_CLOCKSOURCE_ETRMODE1    TIM_TS_ETRF          /*!< External clock source mode 1 (ETRF)                   */
-#define TIM_CLOCKSOURCE_ETRMODE2    TIM_SMCR_ETPS_1      /*!< External clock source mode 2                          */
-#define TIM_CLOCKSOURCE_TI1ED       TIM_TS_TI1F_ED       /*!< External clock source mode 1 (TTI1FP1 + edge detect.) */
-#define TIM_CLOCKSOURCE_TI1         TIM_TS_TI1FP1        /*!< External clock source mode 1 (TTI1FP1)                */
-#define TIM_CLOCKSOURCE_TI2         TIM_TS_TI2FP2        /*!< External clock source mode 1 (TTI2FP2)                */
-#define TIM_CLOCKSOURCE_ITR0        TIM_TS_ITR0          /*!< External clock source mode 1 (ITR0)                   */
-#define TIM_CLOCKSOURCE_ITR1        TIM_TS_ITR1          /*!< External clock source mode 1 (ITR1)                   */
-#define TIM_CLOCKSOURCE_ITR2        TIM_TS_ITR2          /*!< External clock source mode 1 (ITR2)                   */
-#define TIM_CLOCKSOURCE_ITR3        TIM_TS_ITR3          /*!< External clock source mode 1 (ITR3)                   */
-/**
-  * @}
-  */
-
-/** @defgroup TIM_Clock_Polarity TIM Clock Polarity
-  * @{
-  */
-#define TIM_CLOCKPOLARITY_INVERTED           TIM_ETRPOLARITY_INVERTED           /*!< Polarity for ETRx clock sources */
-#define TIM_CLOCKPOLARITY_NONINVERTED        TIM_ETRPOLARITY_NONINVERTED        /*!< Polarity for ETRx clock sources */
-#define TIM_CLOCKPOLARITY_RISING             TIM_INPUTCHANNELPOLARITY_RISING    /*!< Polarity for TIx clock sources */
-#define TIM_CLOCKPOLARITY_FALLING            TIM_INPUTCHANNELPOLARITY_FALLING   /*!< Polarity for TIx clock sources */
-#define TIM_CLOCKPOLARITY_BOTHEDGE           TIM_INPUTCHANNELPOLARITY_BOTHEDGE  /*!< Polarity for TIx clock sources */
-/**
-  * @}
-  */
-
-/** @defgroup TIM_Clock_Prescaler TIM Clock Prescaler
-  * @{
-  */
-#define TIM_CLOCKPRESCALER_DIV1                 TIM_ETRPRESCALER_DIV1           /*!< No prescaler is used                                                     */
-#define TIM_CLOCKPRESCALER_DIV2                 TIM_ETRPRESCALER_DIV2           /*!< Prescaler for External ETR Clock: Capture performed once every 2 events. */
-#define TIM_CLOCKPRESCALER_DIV4                 TIM_ETRPRESCALER_DIV4           /*!< Prescaler for External ETR Clock: Capture performed once every 4 events. */
-#define TIM_CLOCKPRESCALER_DIV8                 TIM_ETRPRESCALER_DIV8           /*!< Prescaler for External ETR Clock: Capture performed once every 8 events. */
-/**
-  * @}
-  */
-
-/** @defgroup TIM_ClearInput_Polarity TIM Clear Input Polarity
-  * @{
-  */
-#define TIM_CLEARINPUTPOLARITY_INVERTED           TIM_ETRPOLARITY_INVERTED      /*!< Polarity for ETRx pin */
-#define TIM_CLEARINPUTPOLARITY_NONINVERTED        TIM_ETRPOLARITY_NONINVERTED   /*!< Polarity for ETRx pin */
-/**
-  * @}
-  */
-
-/** @defgroup TIM_ClearInput_Prescaler TIM Clear Input Prescaler
-  * @{
-  */
-#define TIM_CLEARINPUTPRESCALER_DIV1              TIM_ETRPRESCALER_DIV1         /*!< No prescaler is used                                                   */
-#define TIM_CLEARINPUTPRESCALER_DIV2              TIM_ETRPRESCALER_DIV2         /*!< Prescaler for External ETR pin: Capture performed once every 2 events. */
-#define TIM_CLEARINPUTPRESCALER_DIV4              TIM_ETRPRESCALER_DIV4         /*!< Prescaler for External ETR pin: Capture performed once every 4 events. */
-#define TIM_CLEARINPUTPRESCALER_DIV8              TIM_ETRPRESCALER_DIV8         /*!< Prescaler for External ETR pin: Capture performed once every 8 events. */
-/**
-  * @}
-  */
-
-/** @defgroup TIM_OSSR_Off_State_Selection_for_Run_mode_state TIM OSSR OffState Selection for Run mode state
-  * @{
-  */
-#define TIM_OSSR_ENABLE                          TIM_BDTR_OSSR                  /*!< When inactive, OC/OCN outputs are enabled (still controlled by the timer)           */
-#define TIM_OSSR_DISABLE                         0x00000000U                    /*!< When inactive, OC/OCN outputs are disabled (not controlled any longer by the timer) */
-/**
-  * @}
-  */
-
-/** @defgroup TIM_OSSI_Off_State_Selection_for_Idle_mode_state TIM OSSI OffState Selection for Idle mode state
-  * @{
-  */
-#define TIM_OSSI_ENABLE                          TIM_BDTR_OSSI                  /*!< When inactive, OC/OCN outputs are enabled (still controlled by the timer)           */
-#define TIM_OSSI_DISABLE                         0x00000000U                    /*!< When inactive, OC/OCN outputs are disabled (not controlled any longer by the timer) */
-/**
-  * @}
-  */
-/** @defgroup TIM_Lock_level  TIM Lock level
-  * @{
-  */
-#define TIM_LOCKLEVEL_OFF                  0x00000000U                          /*!< LOCK OFF     */
-#define TIM_LOCKLEVEL_1                    TIM_BDTR_LOCK_0                      /*!< LOCK Level 1 */
-#define TIM_LOCKLEVEL_2                    TIM_BDTR_LOCK_1                      /*!< LOCK Level 2 */
-#define TIM_LOCKLEVEL_3                    TIM_BDTR_LOCK                        /*!< LOCK Level 3 */
-/**
-  * @}
-  */
-
-/** @defgroup TIM_Break_Input_enable_disable TIM Break Input Enable
-  * @{
-  */
-#define TIM_BREAK_ENABLE                   TIM_BDTR_BKE                         /*!< Break input BRK is enabled  */
-#define TIM_BREAK_DISABLE                  0x00000000U                          /*!< Break input BRK is disabled */
-/**
-  * @}
-  */
-
-/** @defgroup TIM_Break_Polarity TIM Break Input Polarity
-  * @{
-  */
-#define TIM_BREAKPOLARITY_LOW              0x00000000U                          /*!< Break input BRK is active low  */
-#define TIM_BREAKPOLARITY_HIGH             TIM_BDTR_BKP                         /*!< Break input BRK is active high */
-/**
-  * @}
-  */
-
-/** @defgroup TIM_Break_Input_AF_Mode TIM Break Input Alternate Function Mode
-  * @{
-  */
-#define TIM_BREAK_AFMODE_INPUT             0x00000000U                          /*!< Break input BRK in input mode */
-#define TIM_BREAK_AFMODE_BIDIRECTIONAL     TIM_BDTR_BKBID                       /*!< Break input BRK in bidirectional mode */
-/**
-  * @}
-  */
-
-/** @defgroup TIM_Break2_Input_enable_disable TIM Break input 2 Enable
-  * @{
-  */
-#define TIM_BREAK2_DISABLE                 0x00000000U                          /*!< Break input BRK2 is disabled  */
-#define TIM_BREAK2_ENABLE                  TIM_BDTR_BK2E                        /*!< Break input BRK2 is enabled  */
-/**
-  * @}
-  */
-
-/** @defgroup TIM_Break2_Polarity TIM Break Input 2 Polarity
-  * @{
-  */
-#define TIM_BREAK2POLARITY_LOW             0x00000000U                          /*!< Break input BRK2 is active low   */
-#define TIM_BREAK2POLARITY_HIGH            TIM_BDTR_BK2P                        /*!< Break input BRK2 is active high  */
-/**
-  * @}
-  */
-
-/** @defgroup TIM_Break2_Input_AF_Mode TIM Break2 Input Alternate Function Mode
-  * @{
-  */
-#define TIM_BREAK2_AFMODE_INPUT            0x00000000U                          /*!< Break2 input BRK2 in input mode */
-#define TIM_BREAK2_AFMODE_BIDIRECTIONAL    TIM_BDTR_BK2BID                      /*!< Break2 input BRK2 in bidirectional mode */
-/**
-  * @}
-  */
-
-/** @defgroup TIM_AOE_Bit_Set_Reset TIM Automatic Output Enable
-  * @{
-  */
-#define TIM_AUTOMATICOUTPUT_DISABLE        0x00000000U                          /*!< MOE can be set only by software */
-#define TIM_AUTOMATICOUTPUT_ENABLE         TIM_BDTR_AOE                         /*!< MOE can be set by software or automatically at the next update event (if none of the break inputs BRK and BRK2 is active) */
-/**
-  * @}
-  */
-
-/** @defgroup TIM_Group_Channel5 TIM Group Channel 5 and Channel 1, 2 or 3
-  * @{
-  */
-#define TIM_GROUPCH5_NONE                  0x00000000U                          /*!< No effect of OC5REF on OC1REFC, OC2REFC and OC3REFC */
-#define TIM_GROUPCH5_OC1REFC               TIM_CCR5_GC5C1                       /*!< OC1REFC is the logical AND of OC1REFC and OC5REF    */
-#define TIM_GROUPCH5_OC2REFC               TIM_CCR5_GC5C2                       /*!< OC2REFC is the logical AND of OC2REFC and OC5REF    */
-#define TIM_GROUPCH5_OC3REFC               TIM_CCR5_GC5C3                       /*!< OC3REFC is the logical AND of OC3REFC and OC5REF    */
-/**
-  * @}
-  */
-
-/** @defgroup TIM_Master_Mode_Selection TIM Master Mode Selection
-  * @{
-  */
-#define TIM_TRGO_RESET            0x00000000U                                      /*!< TIMx_EGR.UG bit is used as trigger output (TRGO)              */
-#define TIM_TRGO_ENABLE           TIM_CR2_MMS_0                                    /*!< TIMx_CR1.CEN bit is used as trigger output (TRGO)             */
-#define TIM_TRGO_UPDATE           TIM_CR2_MMS_1                                    /*!< Update event is used as trigger output (TRGO)                 */
-#define TIM_TRGO_OC1              (TIM_CR2_MMS_1 | TIM_CR2_MMS_0)                  /*!< Capture or a compare match 1 is used as trigger output (TRGO) */
-#define TIM_TRGO_OC1REF           TIM_CR2_MMS_2                                    /*!< OC1REF signal is used as trigger output (TRGO)                */
-#define TIM_TRGO_OC2REF           (TIM_CR2_MMS_2 | TIM_CR2_MMS_0)                  /*!< OC2REF signal is used as trigger output(TRGO)                 */
-#define TIM_TRGO_OC3REF           (TIM_CR2_MMS_2 | TIM_CR2_MMS_1)                  /*!< OC3REF signal is used as trigger output(TRGO)                 */
-#define TIM_TRGO_OC4REF           (TIM_CR2_MMS_2 | TIM_CR2_MMS_1 | TIM_CR2_MMS_0)  /*!< OC4REF signal is used as trigger output(TRGO)                 */
-/**
-  * @}
-  */
-
-/** @defgroup TIM_Master_Mode_Selection_2 TIM Master Mode Selection 2 (TRGO2)
-  * @{
-  */
-#define TIM_TRGO2_RESET                          0x00000000U                                                         /*!< TIMx_EGR.UG bit is used as trigger output (TRGO2)              */
-#define TIM_TRGO2_ENABLE                         TIM_CR2_MMS2_0                                                      /*!< TIMx_CR1.CEN bit is used as trigger output (TRGO2)             */
-#define TIM_TRGO2_UPDATE                         TIM_CR2_MMS2_1                                                      /*!< Update event is used as trigger output (TRGO2)                 */
-#define TIM_TRGO2_OC1                            (TIM_CR2_MMS2_1 | TIM_CR2_MMS2_0)                                   /*!< Capture or a compare match 1 is used as trigger output (TRGO2) */
-#define TIM_TRGO2_OC1REF                         TIM_CR2_MMS2_2                                                      /*!< OC1REF signal is used as trigger output (TRGO2)                */
-#define TIM_TRGO2_OC2REF                         (TIM_CR2_MMS2_2 | TIM_CR2_MMS2_0)                                   /*!< OC2REF signal is used as trigger output (TRGO2)                */
-#define TIM_TRGO2_OC3REF                         (TIM_CR2_MMS2_2 | TIM_CR2_MMS2_1)                                   /*!< OC3REF signal is used as trigger output (TRGO2)                */
-#define TIM_TRGO2_OC4REF                         (TIM_CR2_MMS2_2 | TIM_CR2_MMS2_1 | TIM_CR2_MMS2_0)                  /*!< OC4REF signal is used as trigger output (TRGO2)                */
-#define TIM_TRGO2_OC5REF                         TIM_CR2_MMS2_3                                                      /*!< OC5REF signal is used as trigger output (TRGO2)                */
-#define TIM_TRGO2_OC6REF                         (TIM_CR2_MMS2_3 | TIM_CR2_MMS2_0)                                   /*!< OC6REF signal is used as trigger output (TRGO2)                */
-#define TIM_TRGO2_OC4REF_RISINGFALLING           (TIM_CR2_MMS2_3 | TIM_CR2_MMS2_1)                                   /*!< OC4REF rising or falling edges generate pulses on TRGO2        */
-#define TIM_TRGO2_OC6REF_RISINGFALLING           (TIM_CR2_MMS2_3 | TIM_CR2_MMS2_1 | TIM_CR2_MMS2_0)                  /*!< OC6REF rising or falling edges generate pulses on TRGO2        */
-#define TIM_TRGO2_OC4REF_RISING_OC6REF_RISING    (TIM_CR2_MMS2_3 | TIM_CR2_MMS2_2)                                   /*!< OC4REF or OC6REF rising edges generate pulses on TRGO2         */
-#define TIM_TRGO2_OC4REF_RISING_OC6REF_FALLING   (TIM_CR2_MMS2_3 | TIM_CR2_MMS2_2 | TIM_CR2_MMS2_0)                  /*!< OC4REF rising or OC6REF falling edges generate pulses on TRGO2 */
-#define TIM_TRGO2_OC5REF_RISING_OC6REF_RISING    (TIM_CR2_MMS2_3 | TIM_CR2_MMS2_2 |TIM_CR2_MMS2_1)                   /*!< OC5REF or OC6REF rising edges generate pulses on TRGO2         */
-#define TIM_TRGO2_OC5REF_RISING_OC6REF_FALLING   (TIM_CR2_MMS2_3 | TIM_CR2_MMS2_2 | TIM_CR2_MMS2_1 | TIM_CR2_MMS2_0) /*!< OC5REF or OC6REF rising edges generate pulses on TRGO2         */
-/**
-  * @}
-  */
-
-/** @defgroup TIM_Master_Slave_Mode TIM Master/Slave Mode
-  * @{
-  */
-#define TIM_MASTERSLAVEMODE_ENABLE         TIM_SMCR_MSM                         /*!< No action */
-#define TIM_MASTERSLAVEMODE_DISABLE        0x00000000U                          /*!< Master/slave mode is selected */
-/**
-  * @}
-  */
-
-/** @defgroup TIM_Slave_Mode TIM Slave mode
-  * @{
-  */
-#define TIM_SLAVEMODE_DISABLE                0x00000000U                                        /*!< Slave mode disabled           */
-#define TIM_SLAVEMODE_RESET                  TIM_SMCR_SMS_2                                     /*!< Reset Mode                    */
-#define TIM_SLAVEMODE_GATED                  (TIM_SMCR_SMS_2 | TIM_SMCR_SMS_0)                  /*!< Gated Mode                    */
-#define TIM_SLAVEMODE_TRIGGER                (TIM_SMCR_SMS_2 | TIM_SMCR_SMS_1)                  /*!< Trigger Mode                  */
-#define TIM_SLAVEMODE_EXTERNAL1              (TIM_SMCR_SMS_2 | TIM_SMCR_SMS_1 | TIM_SMCR_SMS_0) /*!< External Clock Mode 1         */
-#define TIM_SLAVEMODE_COMBINED_RESETTRIGGER  TIM_SMCR_SMS_3                                     /*!< Combined reset + trigger mode */
-/**
-  * @}
-  */
-
-/** @defgroup TIM_Output_Compare_and_PWM_modes TIM Output Compare and PWM Modes
-  * @{
-  */
-#define TIM_OCMODE_TIMING                   0x00000000U                                              /*!< Frozen                                 */
-#define TIM_OCMODE_ACTIVE                   TIM_CCMR1_OC1M_0                                         /*!< Set channel to active level on match   */
-#define TIM_OCMODE_INACTIVE                 TIM_CCMR1_OC1M_1                                         /*!< Set channel to inactive level on match */
-#define TIM_OCMODE_TOGGLE                   (TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_0)                    /*!< Toggle                                 */
-#define TIM_OCMODE_PWM1                     (TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_1)                    /*!< PWM mode 1                             */
-#define TIM_OCMODE_PWM2                     (TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_0) /*!< PWM mode 2                             */
-#define TIM_OCMODE_FORCED_ACTIVE            (TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_0)                    /*!< Force active level                     */
-#define TIM_OCMODE_FORCED_INACTIVE          TIM_CCMR1_OC1M_2                                         /*!< Force inactive level                   */
-#define TIM_OCMODE_RETRIGERRABLE_OPM1      TIM_CCMR1_OC1M_3                                          /*!< Retrigerrable OPM mode 1               */
-#define TIM_OCMODE_RETRIGERRABLE_OPM2      (TIM_CCMR1_OC1M_3 | TIM_CCMR1_OC1M_0)                     /*!< Retrigerrable OPM mode 2               */
-#define TIM_OCMODE_COMBINED_PWM1           (TIM_CCMR1_OC1M_3 | TIM_CCMR1_OC1M_2)                     /*!< Combined PWM mode 1                    */
-#define TIM_OCMODE_COMBINED_PWM2           (TIM_CCMR1_OC1M_3 | TIM_CCMR1_OC1M_0 | TIM_CCMR1_OC1M_2)  /*!< Combined PWM mode 2                    */
-#define TIM_OCMODE_ASSYMETRIC_PWM1         (TIM_CCMR1_OC1M_3 | TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2)  /*!< Asymmetric PWM mode 1                  */
-#define TIM_OCMODE_ASSYMETRIC_PWM2         TIM_CCMR1_OC1M                                            /*!< Asymmetric PWM mode 2                  */
-/**
-  * @}
-  */
-
-/** @defgroup TIM_Trigger_Selection TIM Trigger Selection
-  * @{
-  */
-#define TIM_TS_ITR0          0x00000000U                                                       /*!< Internal Trigger 0 (ITR0)              */
-#define TIM_TS_ITR1          TIM_SMCR_TS_0                                                     /*!< Internal Trigger 1 (ITR1)              */
-#define TIM_TS_ITR2          TIM_SMCR_TS_1                                                     /*!< Internal Trigger 2 (ITR2)              */
-#define TIM_TS_ITR3          (TIM_SMCR_TS_0 | TIM_SMCR_TS_1)                                   /*!< Internal Trigger 3 (ITR3)              */
-#define TIM_TS_TI1F_ED       TIM_SMCR_TS_2                                                     /*!< TI1 Edge Detector (TI1F_ED)            */
-#define TIM_TS_TI1FP1        (TIM_SMCR_TS_0 | TIM_SMCR_TS_2)                                   /*!< Filtered Timer Input 1 (TI1FP1)        */
-#define TIM_TS_TI2FP2        (TIM_SMCR_TS_1 | TIM_SMCR_TS_2)                                   /*!< Filtered Timer Input 2 (TI2FP2)        */
-#define TIM_TS_ETRF          (TIM_SMCR_TS_0 | TIM_SMCR_TS_1 | TIM_SMCR_TS_2)                   /*!< Filtered External Trigger input (ETRF) */
-#define TIM_TS_NONE          0x0000FFFFU                                                       /*!< No trigger selected                    */
-/**
-  * @}
-  */
-
-/** @defgroup TIM_Trigger_Polarity TIM Trigger Polarity
-  * @{
-  */
-#define TIM_TRIGGERPOLARITY_INVERTED           TIM_ETRPOLARITY_INVERTED               /*!< Polarity for ETRx trigger sources             */
-#define TIM_TRIGGERPOLARITY_NONINVERTED        TIM_ETRPOLARITY_NONINVERTED            /*!< Polarity for ETRx trigger sources             */
-#define TIM_TRIGGERPOLARITY_RISING             TIM_INPUTCHANNELPOLARITY_RISING        /*!< Polarity for TIxFPx or TI1_ED trigger sources */
-#define TIM_TRIGGERPOLARITY_FALLING            TIM_INPUTCHANNELPOLARITY_FALLING       /*!< Polarity for TIxFPx or TI1_ED trigger sources */
-#define TIM_TRIGGERPOLARITY_BOTHEDGE           TIM_INPUTCHANNELPOLARITY_BOTHEDGE      /*!< Polarity for TIxFPx or TI1_ED trigger sources */
-/**
-  * @}
-  */
-
-/** @defgroup TIM_Trigger_Prescaler TIM Trigger Prescaler
-  * @{
-  */
-#define TIM_TRIGGERPRESCALER_DIV1             TIM_ETRPRESCALER_DIV1             /*!< No prescaler is used                                                       */
-#define TIM_TRIGGERPRESCALER_DIV2             TIM_ETRPRESCALER_DIV2             /*!< Prescaler for External ETR Trigger: Capture performed once every 2 events. */
-#define TIM_TRIGGERPRESCALER_DIV4             TIM_ETRPRESCALER_DIV4             /*!< Prescaler for External ETR Trigger: Capture performed once every 4 events. */
-#define TIM_TRIGGERPRESCALER_DIV8             TIM_ETRPRESCALER_DIV8             /*!< Prescaler for External ETR Trigger: Capture performed once every 8 events. */
-/**
-  * @}
-  */
-
-/** @defgroup TIM_TI1_Selection TIM TI1 Input Selection
-  * @{
-  */
-#define TIM_TI1SELECTION_CH1               0x00000000U                          /*!< The TIMx_CH1 pin is connected to TI1 input */
-#define TIM_TI1SELECTION_XORCOMBINATION    TIM_CR2_TI1S                         /*!< The TIMx_CH1, CH2 and CH3 pins are connected to the TI1 input (XOR combination) */
-/**
-  * @}
-  */
-
-/** @defgroup TIM_DMA_Burst_Length TIM DMA Burst Length
-  * @{
-  */
-#define TIM_DMABURSTLENGTH_1TRANSFER       0x00000000U                          /*!< The transfer is done to 1 register starting from TIMx_CR1 + TIMx_DCR.DBA   */
-#define TIM_DMABURSTLENGTH_2TRANSFERS      0x00000100U                          /*!< The transfer is done to 2 registers starting from TIMx_CR1 + TIMx_DCR.DBA  */
-#define TIM_DMABURSTLENGTH_3TRANSFERS      0x00000200U                          /*!< The transfer is done to 3 registers starting from TIMx_CR1 + TIMx_DCR.DBA  */
-#define TIM_DMABURSTLENGTH_4TRANSFERS      0x00000300U                          /*!< The transfer is done to 4 registers starting from TIMx_CR1 + TIMx_DCR.DBA  */
-#define TIM_DMABURSTLENGTH_5TRANSFERS      0x00000400U                          /*!< The transfer is done to 5 registers starting from TIMx_CR1 + TIMx_DCR.DBA  */
-#define TIM_DMABURSTLENGTH_6TRANSFERS      0x00000500U                          /*!< The transfer is done to 6 registers starting from TIMx_CR1 + TIMx_DCR.DBA  */
-#define TIM_DMABURSTLENGTH_7TRANSFERS      0x00000600U                          /*!< The transfer is done to 7 registers starting from TIMx_CR1 + TIMx_DCR.DBA  */
-#define TIM_DMABURSTLENGTH_8TRANSFERS      0x00000700U                          /*!< The transfer is done to 8 registers starting from TIMx_CR1 + TIMx_DCR.DBA  */
-#define TIM_DMABURSTLENGTH_9TRANSFERS      0x00000800U                          /*!< The transfer is done to 9 registers starting from TIMx_CR1 + TIMx_DCR.DBA  */
-#define TIM_DMABURSTLENGTH_10TRANSFERS     0x00000900U                          /*!< The transfer is done to 10 registers starting from TIMx_CR1 + TIMx_DCR.DBA */
-#define TIM_DMABURSTLENGTH_11TRANSFERS     0x00000A00U                          /*!< The transfer is done to 11 registers starting from TIMx_CR1 + TIMx_DCR.DBA */
-#define TIM_DMABURSTLENGTH_12TRANSFERS     0x00000B00U                          /*!< The transfer is done to 12 registers starting from TIMx_CR1 + TIMx_DCR.DBA */
-#define TIM_DMABURSTLENGTH_13TRANSFERS     0x00000C00U                          /*!< The transfer is done to 13 registers starting from TIMx_CR1 + TIMx_DCR.DBA */
-#define TIM_DMABURSTLENGTH_14TRANSFERS     0x00000D00U                          /*!< The transfer is done to 14 registers starting from TIMx_CR1 + TIMx_DCR.DBA */
-#define TIM_DMABURSTLENGTH_15TRANSFERS     0x00000E00U                          /*!< The transfer is done to 15 registers starting from TIMx_CR1 + TIMx_DCR.DBA */
-#define TIM_DMABURSTLENGTH_16TRANSFERS     0x00000F00U                          /*!< The transfer is done to 16 registers starting from TIMx_CR1 + TIMx_DCR.DBA */
-#define TIM_DMABURSTLENGTH_17TRANSFERS     0x00001000U                          /*!< The transfer is done to 17 registers starting from TIMx_CR1 + TIMx_DCR.DBA */
-#define TIM_DMABURSTLENGTH_18TRANSFERS     0x00001100U                          /*!< The transfer is done to 18 registers starting from TIMx_CR1 + TIMx_DCR.DBA */
-/**
-  * @}
-  */
-
-/** @defgroup DMA_Handle_index TIM DMA Handle Index
-  * @{
-  */
-#define TIM_DMA_ID_UPDATE                ((uint16_t) 0x0000)       /*!< Index of the DMA handle used for Update DMA requests */
-#define TIM_DMA_ID_CC1                   ((uint16_t) 0x0001)       /*!< Index of the DMA handle used for Capture/Compare 1 DMA requests */
-#define TIM_DMA_ID_CC2                   ((uint16_t) 0x0002)       /*!< Index of the DMA handle used for Capture/Compare 2 DMA requests */
-#define TIM_DMA_ID_CC3                   ((uint16_t) 0x0003)       /*!< Index of the DMA handle used for Capture/Compare 3 DMA requests */
-#define TIM_DMA_ID_CC4                   ((uint16_t) 0x0004)       /*!< Index of the DMA handle used for Capture/Compare 4 DMA requests */
-#define TIM_DMA_ID_COMMUTATION           ((uint16_t) 0x0005)       /*!< Index of the DMA handle used for Commutation DMA requests */
-#define TIM_DMA_ID_TRIGGER               ((uint16_t) 0x0006)       /*!< Index of the DMA handle used for Trigger DMA requests */
-/**
-  * @}
-  */
-
-/** @defgroup Channel_CC_State TIM Capture/Compare Channel State
-  * @{
-  */
-#define TIM_CCx_ENABLE                   0x00000001U                            /*!< Input or output channel is enabled */
-#define TIM_CCx_DISABLE                  0x00000000U                            /*!< Input or output channel is disabled */
-#define TIM_CCxN_ENABLE                  0x00000004U                            /*!< Complementary output channel is enabled */
-#define TIM_CCxN_DISABLE                 0x00000000U                            /*!< Complementary output channel is enabled */
-/**
-  * @}
-  */
-
-/** @defgroup TIM_Break_System TIM Break System
-  * @{
-  */
-#define TIM_BREAK_SYSTEM_ECC                 SYSCFG_CFGR2_ECCL   /*!< Enables and locks the ECC error signal with Break Input of TIM1/8/15/16/17 */
-#define TIM_BREAK_SYSTEM_PVD                 SYSCFG_CFGR2_PVDL   /*!< Enables and locks the PVD connection with TIM1/8/15/16/17 Break Input and also the PVDE and PLS bits of the Power Control Interface */
-#define TIM_BREAK_SYSTEM_SRAM2_PARITY_ERROR  SYSCFG_CFGR2_SPL    /*!< Enables and locks the SRAM2_PARITY error signal with Break Input of TIM1/8/15/16/17 */
-#define TIM_BREAK_SYSTEM_LOCKUP              SYSCFG_CFGR2_CLL    /*!< Enables and locks the LOCKUP output of CortexM4 with Break Input of TIM1/8/15/16/17 */
-/**
-  * @}
-  */
-
-/**
-  * @}
-  */
-/* End of exported constants -------------------------------------------------*/
-
-/* Exported macros -----------------------------------------------------------*/
-/** @defgroup TIM_Exported_Macros TIM Exported Macros
-  * @{
-  */
-
-/** @brief  Reset TIM handle state.
-  * @param  __HANDLE__ TIM handle.
-  * @retval None
-  */
-#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
-#define __HAL_TIM_RESET_HANDLE_STATE(__HANDLE__) do {                                                               \
-                                                      (__HANDLE__)->State            = HAL_TIM_STATE_RESET;         \
-                                                      (__HANDLE__)->ChannelState[0]  = HAL_TIM_CHANNEL_STATE_RESET; \
-                                                      (__HANDLE__)->ChannelState[1]  = HAL_TIM_CHANNEL_STATE_RESET; \
-                                                      (__HANDLE__)->ChannelState[2]  = HAL_TIM_CHANNEL_STATE_RESET; \
-                                                      (__HANDLE__)->ChannelState[3]  = HAL_TIM_CHANNEL_STATE_RESET; \
-                                                      (__HANDLE__)->ChannelState[4]  = HAL_TIM_CHANNEL_STATE_RESET; \
-                                                      (__HANDLE__)->ChannelState[5]  = HAL_TIM_CHANNEL_STATE_RESET; \
-                                                      (__HANDLE__)->ChannelNState[0] = HAL_TIM_CHANNEL_STATE_RESET; \
-                                                      (__HANDLE__)->ChannelNState[1] = HAL_TIM_CHANNEL_STATE_RESET; \
-                                                      (__HANDLE__)->ChannelNState[2] = HAL_TIM_CHANNEL_STATE_RESET; \
-                                                      (__HANDLE__)->ChannelNState[3] = HAL_TIM_CHANNEL_STATE_RESET; \
-                                                      (__HANDLE__)->DMABurstState    = HAL_DMA_BURST_STATE_RESET;   \
-                                                      (__HANDLE__)->Base_MspInitCallback         = NULL;            \
-                                                      (__HANDLE__)->Base_MspDeInitCallback       = NULL;            \
-                                                      (__HANDLE__)->IC_MspInitCallback           = NULL;            \
-                                                      (__HANDLE__)->IC_MspDeInitCallback         = NULL;            \
-                                                      (__HANDLE__)->OC_MspInitCallback           = NULL;            \
-                                                      (__HANDLE__)->OC_MspDeInitCallback         = NULL;            \
-                                                      (__HANDLE__)->PWM_MspInitCallback          = NULL;            \
-                                                      (__HANDLE__)->PWM_MspDeInitCallback        = NULL;            \
-                                                      (__HANDLE__)->OnePulse_MspInitCallback     = NULL;            \
-                                                      (__HANDLE__)->OnePulse_MspDeInitCallback   = NULL;            \
-                                                      (__HANDLE__)->Encoder_MspInitCallback      = NULL;            \
-                                                      (__HANDLE__)->Encoder_MspDeInitCallback    = NULL;            \
-                                                      (__HANDLE__)->HallSensor_MspInitCallback   = NULL;            \
-                                                      (__HANDLE__)->HallSensor_MspDeInitCallback = NULL;            \
-                                                     } while(0)
-#else
-#define __HAL_TIM_RESET_HANDLE_STATE(__HANDLE__) do {                                                               \
-                                                      (__HANDLE__)->State            = HAL_TIM_STATE_RESET;         \
-                                                      (__HANDLE__)->ChannelState[0]  = HAL_TIM_CHANNEL_STATE_RESET; \
-                                                      (__HANDLE__)->ChannelState[1]  = HAL_TIM_CHANNEL_STATE_RESET; \
-                                                      (__HANDLE__)->ChannelState[2]  = HAL_TIM_CHANNEL_STATE_RESET; \
-                                                      (__HANDLE__)->ChannelState[3]  = HAL_TIM_CHANNEL_STATE_RESET; \
-                                                      (__HANDLE__)->ChannelState[4]  = HAL_TIM_CHANNEL_STATE_RESET; \
-                                                      (__HANDLE__)->ChannelState[5]  = HAL_TIM_CHANNEL_STATE_RESET; \
-                                                      (__HANDLE__)->ChannelNState[0] = HAL_TIM_CHANNEL_STATE_RESET; \
-                                                      (__HANDLE__)->ChannelNState[1] = HAL_TIM_CHANNEL_STATE_RESET; \
-                                                      (__HANDLE__)->ChannelNState[2] = HAL_TIM_CHANNEL_STATE_RESET; \
-                                                      (__HANDLE__)->ChannelNState[3] = HAL_TIM_CHANNEL_STATE_RESET; \
-                                                      (__HANDLE__)->DMABurstState    = HAL_DMA_BURST_STATE_RESET;   \
-                                                     } while(0)
-#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
-
-/**
-  * @brief  Enable the TIM peripheral.
-  * @param  __HANDLE__ TIM handle
-  * @retval None
-  */
-#define __HAL_TIM_ENABLE(__HANDLE__)                 ((__HANDLE__)->Instance->CR1|=(TIM_CR1_CEN))
-
-/**
-  * @brief  Enable the TIM main Output.
-  * @param  __HANDLE__ TIM handle
-  * @retval None
-  */
-#define __HAL_TIM_MOE_ENABLE(__HANDLE__)             ((__HANDLE__)->Instance->BDTR|=(TIM_BDTR_MOE))
-
-/**
-  * @brief  Disable the TIM peripheral.
-  * @param  __HANDLE__ TIM handle
-  * @retval None
-  */
-#define __HAL_TIM_DISABLE(__HANDLE__) \
-  do { \
-    if (((__HANDLE__)->Instance->CCER & TIM_CCER_CCxE_MASK) == 0UL) \
-    { \
-      if(((__HANDLE__)->Instance->CCER & TIM_CCER_CCxNE_MASK) == 0UL) \
-      { \
-        (__HANDLE__)->Instance->CR1 &= ~(TIM_CR1_CEN); \
-      } \
-    } \
-  } while(0)
-
-/**
-  * @brief  Disable the TIM main Output.
-  * @param  __HANDLE__ TIM handle
-  * @retval None
-  * @note The Main Output Enable of a timer instance is disabled only if all the CCx and CCxN channels have been
-  *       disabled
-  */
-#define __HAL_TIM_MOE_DISABLE(__HANDLE__) \
-  do { \
-    if (((__HANDLE__)->Instance->CCER & TIM_CCER_CCxE_MASK) == 0UL) \
-    { \
-      if(((__HANDLE__)->Instance->CCER & TIM_CCER_CCxNE_MASK) == 0UL) \
-      { \
-        (__HANDLE__)->Instance->BDTR &= ~(TIM_BDTR_MOE); \
-      } \
-    } \
-  } while(0)
-
-/**
-  * @brief  Disable the TIM main Output.
-  * @param  __HANDLE__ TIM handle
-  * @retval None
-  * @note The Main Output Enable of a timer instance is disabled unconditionally
-  */
-#define __HAL_TIM_MOE_DISABLE_UNCONDITIONALLY(__HANDLE__)  (__HANDLE__)->Instance->BDTR &= ~(TIM_BDTR_MOE)
-
-/** @brief  Enable the specified TIM interrupt.
-  * @param  __HANDLE__ specifies the TIM Handle.
-  * @param  __INTERRUPT__ specifies the TIM interrupt source to enable.
-  *          This parameter can be one of the following values:
-  *            @arg TIM_IT_UPDATE: Update interrupt
-  *            @arg TIM_IT_CC1:   Capture/Compare 1 interrupt
-  *            @arg TIM_IT_CC2:  Capture/Compare 2 interrupt
-  *            @arg TIM_IT_CC3:  Capture/Compare 3 interrupt
-  *            @arg TIM_IT_CC4:  Capture/Compare 4 interrupt
-  *            @arg TIM_IT_COM:   Commutation interrupt
-  *            @arg TIM_IT_TRIGGER: Trigger interrupt
-  *            @arg TIM_IT_BREAK: Break interrupt
-  * @retval None
-  */
-#define __HAL_TIM_ENABLE_IT(__HANDLE__, __INTERRUPT__)    ((__HANDLE__)->Instance->DIER |= (__INTERRUPT__))
-
-/** @brief  Disable the specified TIM interrupt.
-  * @param  __HANDLE__ specifies the TIM Handle.
-  * @param  __INTERRUPT__ specifies the TIM interrupt source to disable.
-  *          This parameter can be one of the following values:
-  *            @arg TIM_IT_UPDATE: Update interrupt
-  *            @arg TIM_IT_CC1:   Capture/Compare 1 interrupt
-  *            @arg TIM_IT_CC2:  Capture/Compare 2 interrupt
-  *            @arg TIM_IT_CC3:  Capture/Compare 3 interrupt
-  *            @arg TIM_IT_CC4:  Capture/Compare 4 interrupt
-  *            @arg TIM_IT_COM:   Commutation interrupt
-  *            @arg TIM_IT_TRIGGER: Trigger interrupt
-  *            @arg TIM_IT_BREAK: Break interrupt
-  * @retval None
-  */
-#define __HAL_TIM_DISABLE_IT(__HANDLE__, __INTERRUPT__)   ((__HANDLE__)->Instance->DIER &= ~(__INTERRUPT__))
-
-/** @brief  Enable the specified DMA request.
-  * @param  __HANDLE__ specifies the TIM Handle.
-  * @param  __DMA__ specifies the TIM DMA request to enable.
-  *          This parameter can be one of the following values:
-  *            @arg TIM_DMA_UPDATE: Update DMA request
-  *            @arg TIM_DMA_CC1:   Capture/Compare 1 DMA request
-  *            @arg TIM_DMA_CC2:  Capture/Compare 2 DMA request
-  *            @arg TIM_DMA_CC3:  Capture/Compare 3 DMA request
-  *            @arg TIM_DMA_CC4:  Capture/Compare 4 DMA request
-  *            @arg TIM_DMA_COM:   Commutation DMA request
-  *            @arg TIM_DMA_TRIGGER: Trigger DMA request
-  * @retval None
-  */
-#define __HAL_TIM_ENABLE_DMA(__HANDLE__, __DMA__)         ((__HANDLE__)->Instance->DIER |= (__DMA__))
-
-/** @brief  Disable the specified DMA request.
-  * @param  __HANDLE__ specifies the TIM Handle.
-  * @param  __DMA__ specifies the TIM DMA request to disable.
-  *          This parameter can be one of the following values:
-  *            @arg TIM_DMA_UPDATE: Update DMA request
-  *            @arg TIM_DMA_CC1:   Capture/Compare 1 DMA request
-  *            @arg TIM_DMA_CC2:  Capture/Compare 2 DMA request
-  *            @arg TIM_DMA_CC3:  Capture/Compare 3 DMA request
-  *            @arg TIM_DMA_CC4:  Capture/Compare 4 DMA request
-  *            @arg TIM_DMA_COM:   Commutation DMA request
-  *            @arg TIM_DMA_TRIGGER: Trigger DMA request
-  * @retval None
-  */
-#define __HAL_TIM_DISABLE_DMA(__HANDLE__, __DMA__)        ((__HANDLE__)->Instance->DIER &= ~(__DMA__))
-
-/** @brief  Check whether the specified TIM interrupt flag is set or not.
-  * @param  __HANDLE__ specifies the TIM Handle.
-  * @param  __FLAG__ specifies the TIM interrupt flag to check.
-  *        This parameter can be one of the following values:
-  *            @arg TIM_FLAG_UPDATE: Update interrupt flag
-  *            @arg TIM_FLAG_CC1: Capture/Compare 1 interrupt flag
-  *            @arg TIM_FLAG_CC2: Capture/Compare 2 interrupt flag
-  *            @arg TIM_FLAG_CC3: Capture/Compare 3 interrupt flag
-  *            @arg TIM_FLAG_CC4: Capture/Compare 4 interrupt flag
-  *            @arg TIM_FLAG_CC5: Compare 5 interrupt flag
-  *            @arg TIM_FLAG_CC6: Compare 6 interrupt flag
-  *            @arg TIM_FLAG_COM:  Commutation interrupt flag
-  *            @arg TIM_FLAG_TRIGGER: Trigger interrupt flag
-  *            @arg TIM_FLAG_BREAK: Break interrupt flag
-  *            @arg TIM_FLAG_BREAK2: Break 2 interrupt flag
-  *            @arg TIM_FLAG_SYSTEM_BREAK: System Break interrupt flag
-  *            @arg TIM_FLAG_CC1OF: Capture/Compare 1 overcapture flag
-  *            @arg TIM_FLAG_CC2OF: Capture/Compare 2 overcapture flag
-  *            @arg TIM_FLAG_CC3OF: Capture/Compare 3 overcapture flag
-  *            @arg TIM_FLAG_CC4OF: Capture/Compare 4 overcapture flag
-  * @retval The new state of __FLAG__ (TRUE or FALSE).
-  */
-#define __HAL_TIM_GET_FLAG(__HANDLE__, __FLAG__)          (((__HANDLE__)->Instance->SR &(__FLAG__)) == (__FLAG__))
-
-/** @brief  Clear the specified TIM interrupt flag.
-  * @param  __HANDLE__ specifies the TIM Handle.
-  * @param  __FLAG__ specifies the TIM interrupt flag to clear.
-  *        This parameter can be one of the following values:
-  *            @arg TIM_FLAG_UPDATE: Update interrupt flag
-  *            @arg TIM_FLAG_CC1: Capture/Compare 1 interrupt flag
-  *            @arg TIM_FLAG_CC2: Capture/Compare 2 interrupt flag
-  *            @arg TIM_FLAG_CC3: Capture/Compare 3 interrupt flag
-  *            @arg TIM_FLAG_CC4: Capture/Compare 4 interrupt flag
-  *            @arg TIM_FLAG_CC5: Compare 5 interrupt flag
-  *            @arg TIM_FLAG_CC6: Compare 6 interrupt flag
-  *            @arg TIM_FLAG_COM:  Commutation interrupt flag
-  *            @arg TIM_FLAG_TRIGGER: Trigger interrupt flag
-  *            @arg TIM_FLAG_BREAK: Break interrupt flag
-  *            @arg TIM_FLAG_BREAK2: Break 2 interrupt flag
-  *            @arg TIM_FLAG_SYSTEM_BREAK: System Break interrupt flag
-  *            @arg TIM_FLAG_CC1OF: Capture/Compare 1 overcapture flag
-  *            @arg TIM_FLAG_CC2OF: Capture/Compare 2 overcapture flag
-  *            @arg TIM_FLAG_CC3OF: Capture/Compare 3 overcapture flag
-  *            @arg TIM_FLAG_CC4OF: Capture/Compare 4 overcapture flag
-  * @retval The new state of __FLAG__ (TRUE or FALSE).
-  */
-#define __HAL_TIM_CLEAR_FLAG(__HANDLE__, __FLAG__)        ((__HANDLE__)->Instance->SR = ~(__FLAG__))
-
-/**
-  * @brief  Check whether the specified TIM interrupt source is enabled or not.
-  * @param  __HANDLE__ TIM handle
-  * @param  __INTERRUPT__ specifies the TIM interrupt source to check.
-  *          This parameter can be one of the following values:
-  *            @arg TIM_IT_UPDATE: Update interrupt
-  *            @arg TIM_IT_CC1:   Capture/Compare 1 interrupt
-  *            @arg TIM_IT_CC2:  Capture/Compare 2 interrupt
-  *            @arg TIM_IT_CC3:  Capture/Compare 3 interrupt
-  *            @arg TIM_IT_CC4:  Capture/Compare 4 interrupt
-  *            @arg TIM_IT_COM:   Commutation interrupt
-  *            @arg TIM_IT_TRIGGER: Trigger interrupt
-  *            @arg TIM_IT_BREAK: Break interrupt
-  * @retval The state of TIM_IT (SET or RESET).
-  */
-#define __HAL_TIM_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) ((((__HANDLE__)->Instance->DIER & (__INTERRUPT__)) \
-                                                             == (__INTERRUPT__)) ? SET : RESET)
-
-/** @brief Clear the TIM interrupt pending bits.
-  * @param  __HANDLE__ TIM handle
-  * @param  __INTERRUPT__ specifies the interrupt pending bit to clear.
-  *          This parameter can be one of the following values:
-  *            @arg TIM_IT_UPDATE: Update interrupt
-  *            @arg TIM_IT_CC1:   Capture/Compare 1 interrupt
-  *            @arg TIM_IT_CC2:  Capture/Compare 2 interrupt
-  *            @arg TIM_IT_CC3:  Capture/Compare 3 interrupt
-  *            @arg TIM_IT_CC4:  Capture/Compare 4 interrupt
-  *            @arg TIM_IT_COM:   Commutation interrupt
-  *            @arg TIM_IT_TRIGGER: Trigger interrupt
-  *            @arg TIM_IT_BREAK: Break interrupt
-  * @retval None
-  */
-#define __HAL_TIM_CLEAR_IT(__HANDLE__, __INTERRUPT__)      ((__HANDLE__)->Instance->SR = ~(__INTERRUPT__))
-
-/**
-  * @brief  Force a continuous copy of the update interrupt flag (UIF) into the timer counter register (bit 31).
-  * @note This allows both the counter value and a potential roll-over condition signalled by the UIFCPY flag to be read
-  *       in an atomic way.
-  * @param  __HANDLE__ TIM handle.
-  * @retval None
-mode.
-  */
-#define __HAL_TIM_UIFREMAP_ENABLE(__HANDLE__)    (((__HANDLE__)->Instance->CR1 |= TIM_CR1_UIFREMAP))
-
-/**
-  * @brief  Disable update interrupt flag (UIF) remapping.
-  * @param  __HANDLE__ TIM handle.
-  * @retval None
-mode.
-  */
-#define __HAL_TIM_UIFREMAP_DISABLE(__HANDLE__)    (((__HANDLE__)->Instance->CR1 &= ~TIM_CR1_UIFREMAP))
-
-/**
-  * @brief  Get update interrupt flag (UIF) copy status.
-  * @param  __COUNTER__ Counter value.
-  * @retval The state of UIFCPY (TRUE or FALSE).
-mode.
-  */
-#define __HAL_TIM_GET_UIFCPY(__COUNTER__)    (((__COUNTER__) & (TIM_CNT_UIFCPY)) == (TIM_CNT_UIFCPY))
-
-/**
-  * @brief  Indicates whether or not the TIM Counter is used as downcounter.
-  * @param  __HANDLE__ TIM handle.
-  * @retval False (Counter used as upcounter) or True (Counter used as downcounter)
-  * @note This macro is particularly useful to get the counting mode when the timer operates in Center-aligned mode
-  *       or Encoder mode.
-  */
-#define __HAL_TIM_IS_TIM_COUNTING_DOWN(__HANDLE__)    (((__HANDLE__)->Instance->CR1 &(TIM_CR1_DIR)) == (TIM_CR1_DIR))
-
-/**
-  * @brief  Set the TIM Prescaler on runtime.
-  * @param  __HANDLE__ TIM handle.
-  * @param  __PRESC__ specifies the Prescaler new value.
-  * @retval None
-  */
-#define __HAL_TIM_SET_PRESCALER(__HANDLE__, __PRESC__)       ((__HANDLE__)->Instance->PSC = (__PRESC__))
-
-/**
-  * @brief  Set the TIM Counter Register value on runtime.
-  * Note Please check if the bit 31 of CNT register is used as UIF copy or not, this may affect the counter range in
-  *      case of 32 bits counter TIM instance.
-  *      Bit 31 of CNT can be enabled/disabled using __HAL_TIM_UIFREMAP_ENABLE()/__HAL_TIM_UIFREMAP_DISABLE() macros.
-  * @param  __HANDLE__ TIM handle.
-  * @param  __COUNTER__ specifies the Counter register new value.
-  * @retval None
-  */
-#define __HAL_TIM_SET_COUNTER(__HANDLE__, __COUNTER__)  ((__HANDLE__)->Instance->CNT = (__COUNTER__))
-
-/**
-  * @brief  Get the TIM Counter Register value on runtime.
-  * @param  __HANDLE__ TIM handle.
-  * @retval 16-bit or 32-bit value of the timer counter register (TIMx_CNT)
-  */
-#define __HAL_TIM_GET_COUNTER(__HANDLE__)  ((__HANDLE__)->Instance->CNT)
-
-/**
-  * @brief  Set the TIM Autoreload Register value on runtime without calling another time any Init function.
-  * @param  __HANDLE__ TIM handle.
-  * @param  __AUTORELOAD__ specifies the Counter register new value.
-  * @retval None
-  */
-#define __HAL_TIM_SET_AUTORELOAD(__HANDLE__, __AUTORELOAD__) \
-  do{                                                    \
-    (__HANDLE__)->Instance->ARR = (__AUTORELOAD__);  \
-    (__HANDLE__)->Init.Period = (__AUTORELOAD__);    \
-  } while(0)
-
-/**
-  * @brief  Get the TIM Autoreload Register value on runtime.
-  * @param  __HANDLE__ TIM handle.
-  * @retval 16-bit or 32-bit value of the timer auto-reload register(TIMx_ARR)
-  */
-#define __HAL_TIM_GET_AUTORELOAD(__HANDLE__)  ((__HANDLE__)->Instance->ARR)
-
-/**
-  * @brief  Set the TIM Clock Division value on runtime without calling another time any Init function.
-  * @param  __HANDLE__ TIM handle.
-  * @param  __CKD__ specifies the clock division value.
-  *          This parameter can be one of the following value:
-  *            @arg TIM_CLOCKDIVISION_DIV1: tDTS=tCK_INT
-  *            @arg TIM_CLOCKDIVISION_DIV2: tDTS=2*tCK_INT
-  *            @arg TIM_CLOCKDIVISION_DIV4: tDTS=4*tCK_INT
-  * @retval None
-  */
-#define __HAL_TIM_SET_CLOCKDIVISION(__HANDLE__, __CKD__) \
-  do{                                                   \
-    (__HANDLE__)->Instance->CR1 &= (~TIM_CR1_CKD);  \
-    (__HANDLE__)->Instance->CR1 |= (__CKD__);       \
-    (__HANDLE__)->Init.ClockDivision = (__CKD__);   \
-  } while(0)
-
-/**
-  * @brief  Get the TIM Clock Division value on runtime.
-  * @param  __HANDLE__ TIM handle.
-  * @retval The clock division can be one of the following values:
-  *            @arg TIM_CLOCKDIVISION_DIV1: tDTS=tCK_INT
-  *            @arg TIM_CLOCKDIVISION_DIV2: tDTS=2*tCK_INT
-  *            @arg TIM_CLOCKDIVISION_DIV4: tDTS=4*tCK_INT
-  */
-#define __HAL_TIM_GET_CLOCKDIVISION(__HANDLE__)  ((__HANDLE__)->Instance->CR1 & TIM_CR1_CKD)
-
-/**
-  * @brief  Set the TIM Input Capture prescaler on runtime without calling another time HAL_TIM_IC_ConfigChannel()
-  *         function.
-  * @param  __HANDLE__ TIM handle.
-  * @param  __CHANNEL__ TIM Channels to be configured.
-  *          This parameter can be one of the following values:
-  *            @arg TIM_CHANNEL_1: TIM Channel 1 selected
-  *            @arg TIM_CHANNEL_2: TIM Channel 2 selected
-  *            @arg TIM_CHANNEL_3: TIM Channel 3 selected
-  *            @arg TIM_CHANNEL_4: TIM Channel 4 selected
-  * @param  __ICPSC__ specifies the Input Capture4 prescaler new value.
-  *          This parameter can be one of the following values:
-  *            @arg TIM_ICPSC_DIV1: no prescaler
-  *            @arg TIM_ICPSC_DIV2: capture is done once every 2 events
-  *            @arg TIM_ICPSC_DIV4: capture is done once every 4 events
-  *            @arg TIM_ICPSC_DIV8: capture is done once every 8 events
-  * @retval None
-  */
-#define __HAL_TIM_SET_ICPRESCALER(__HANDLE__, __CHANNEL__, __ICPSC__) \
-  do{                                                    \
-    TIM_RESET_ICPRESCALERVALUE((__HANDLE__), (__CHANNEL__));  \
-    TIM_SET_ICPRESCALERVALUE((__HANDLE__), (__CHANNEL__), (__ICPSC__)); \
-  } while(0)
-
-/**
-  * @brief  Get the TIM Input Capture prescaler on runtime.
-  * @param  __HANDLE__ TIM handle.
-  * @param  __CHANNEL__ TIM Channels to be configured.
-  *          This parameter can be one of the following values:
-  *            @arg TIM_CHANNEL_1: get input capture 1 prescaler value
-  *            @arg TIM_CHANNEL_2: get input capture 2 prescaler value
-  *            @arg TIM_CHANNEL_3: get input capture 3 prescaler value
-  *            @arg TIM_CHANNEL_4: get input capture 4 prescaler value
-  * @retval The input capture prescaler can be one of the following values:
-  *            @arg TIM_ICPSC_DIV1: no prescaler
-  *            @arg TIM_ICPSC_DIV2: capture is done once every 2 events
-  *            @arg TIM_ICPSC_DIV4: capture is done once every 4 events
-  *            @arg TIM_ICPSC_DIV8: capture is done once every 8 events
-  */
-#define __HAL_TIM_GET_ICPRESCALER(__HANDLE__, __CHANNEL__)  \
-  (((__CHANNEL__) == TIM_CHANNEL_1) ? ((__HANDLE__)->Instance->CCMR1 & TIM_CCMR1_IC1PSC) :\
-   ((__CHANNEL__) == TIM_CHANNEL_2) ? (((__HANDLE__)->Instance->CCMR1 & TIM_CCMR1_IC2PSC) >> 8U) :\
-   ((__CHANNEL__) == TIM_CHANNEL_3) ? ((__HANDLE__)->Instance->CCMR2 & TIM_CCMR2_IC3PSC) :\
-   (((__HANDLE__)->Instance->CCMR2 & TIM_CCMR2_IC4PSC)) >> 8U)
-
-/**
-  * @brief  Set the TIM Capture Compare Register value on runtime without calling another time ConfigChannel function.
-  * @param  __HANDLE__ TIM handle.
-  * @param  __CHANNEL__ TIM Channels to be configured.
-  *          This parameter can be one of the following values:
-  *            @arg TIM_CHANNEL_1: TIM Channel 1 selected
-  *            @arg TIM_CHANNEL_2: TIM Channel 2 selected
-  *            @arg TIM_CHANNEL_3: TIM Channel 3 selected
-  *            @arg TIM_CHANNEL_4: TIM Channel 4 selected
-  *            @arg TIM_CHANNEL_5: TIM Channel 5 selected
-  *            @arg TIM_CHANNEL_6: TIM Channel 6 selected
-  * @param  __COMPARE__ specifies the Capture Compare register new value.
-  * @retval None
-  */
-#define __HAL_TIM_SET_COMPARE(__HANDLE__, __CHANNEL__, __COMPARE__) \
-  (((__CHANNEL__) == TIM_CHANNEL_1) ? ((__HANDLE__)->Instance->CCR1 = (__COMPARE__)) :\
-   ((__CHANNEL__) == TIM_CHANNEL_2) ? ((__HANDLE__)->Instance->CCR2 = (__COMPARE__)) :\
-   ((__CHANNEL__) == TIM_CHANNEL_3) ? ((__HANDLE__)->Instance->CCR3 = (__COMPARE__)) :\
-   ((__CHANNEL__) == TIM_CHANNEL_4) ? ((__HANDLE__)->Instance->CCR4 = (__COMPARE__)) :\
-   ((__CHANNEL__) == TIM_CHANNEL_5) ? ((__HANDLE__)->Instance->CCR5 = (__COMPARE__)) :\
-   ((__HANDLE__)->Instance->CCR6 = (__COMPARE__)))
-
-/**
-  * @brief  Get the TIM Capture Compare Register value on runtime.
-  * @param  __HANDLE__ TIM handle.
-  * @param  __CHANNEL__ TIM Channel associated with the capture compare register
-  *          This parameter can be one of the following values:
-  *            @arg TIM_CHANNEL_1: get capture/compare 1 register value
-  *            @arg TIM_CHANNEL_2: get capture/compare 2 register value
-  *            @arg TIM_CHANNEL_3: get capture/compare 3 register value
-  *            @arg TIM_CHANNEL_4: get capture/compare 4 register value
-  *            @arg TIM_CHANNEL_5: get capture/compare 5 register value
-  *            @arg TIM_CHANNEL_6: get capture/compare 6 register value
-  * @retval 16-bit or 32-bit value of the capture/compare register (TIMx_CCRy)
-  */
-#define __HAL_TIM_GET_COMPARE(__HANDLE__, __CHANNEL__) \
-  (((__CHANNEL__) == TIM_CHANNEL_1) ? ((__HANDLE__)->Instance->CCR1) :\
-   ((__CHANNEL__) == TIM_CHANNEL_2) ? ((__HANDLE__)->Instance->CCR2) :\
-   ((__CHANNEL__) == TIM_CHANNEL_3) ? ((__HANDLE__)->Instance->CCR3) :\
-   ((__CHANNEL__) == TIM_CHANNEL_4) ? ((__HANDLE__)->Instance->CCR4) :\
-   ((__CHANNEL__) == TIM_CHANNEL_5) ? ((__HANDLE__)->Instance->CCR5) :\
-   ((__HANDLE__)->Instance->CCR6))
-
-/**
-  * @brief  Set the TIM Output compare preload.
-  * @param  __HANDLE__ TIM handle.
-  * @param  __CHANNEL__ TIM Channels to be configured.
-  *          This parameter can be one of the following values:
-  *            @arg TIM_CHANNEL_1: TIM Channel 1 selected
-  *            @arg TIM_CHANNEL_2: TIM Channel 2 selected
-  *            @arg TIM_CHANNEL_3: TIM Channel 3 selected
-  *            @arg TIM_CHANNEL_4: TIM Channel 4 selected
-  *            @arg TIM_CHANNEL_5: TIM Channel 5 selected
-  *            @arg TIM_CHANNEL_6: TIM Channel 6 selected
-  * @retval None
-  */
-#define __HAL_TIM_ENABLE_OCxPRELOAD(__HANDLE__, __CHANNEL__)    \
-  (((__CHANNEL__) == TIM_CHANNEL_1) ? ((__HANDLE__)->Instance->CCMR1 |= TIM_CCMR1_OC1PE) :\
-   ((__CHANNEL__) == TIM_CHANNEL_2) ? ((__HANDLE__)->Instance->CCMR1 |= TIM_CCMR1_OC2PE) :\
-   ((__CHANNEL__) == TIM_CHANNEL_3) ? ((__HANDLE__)->Instance->CCMR2 |= TIM_CCMR2_OC3PE) :\
-   ((__CHANNEL__) == TIM_CHANNEL_4) ? ((__HANDLE__)->Instance->CCMR2 |= TIM_CCMR2_OC4PE) :\
-   ((__CHANNEL__) == TIM_CHANNEL_5) ? ((__HANDLE__)->Instance->CCMR3 |= TIM_CCMR3_OC5PE) :\
-   ((__HANDLE__)->Instance->CCMR3 |= TIM_CCMR3_OC6PE))
-
-/**
-  * @brief  Reset the TIM Output compare preload.
-  * @param  __HANDLE__ TIM handle.
-  * @param  __CHANNEL__ TIM Channels to be configured.
-  *          This parameter can be one of the following values:
-  *            @arg TIM_CHANNEL_1: TIM Channel 1 selected
-  *            @arg TIM_CHANNEL_2: TIM Channel 2 selected
-  *            @arg TIM_CHANNEL_3: TIM Channel 3 selected
-  *            @arg TIM_CHANNEL_4: TIM Channel 4 selected
-  *            @arg TIM_CHANNEL_5: TIM Channel 5 selected
-  *            @arg TIM_CHANNEL_6: TIM Channel 6 selected
-  * @retval None
-  */
-#define __HAL_TIM_DISABLE_OCxPRELOAD(__HANDLE__, __CHANNEL__)    \
-  (((__CHANNEL__) == TIM_CHANNEL_1) ? ((__HANDLE__)->Instance->CCMR1 &= ~TIM_CCMR1_OC1PE) :\
-   ((__CHANNEL__) == TIM_CHANNEL_2) ? ((__HANDLE__)->Instance->CCMR1 &= ~TIM_CCMR1_OC2PE) :\
-   ((__CHANNEL__) == TIM_CHANNEL_3) ? ((__HANDLE__)->Instance->CCMR2 &= ~TIM_CCMR2_OC3PE) :\
-   ((__CHANNEL__) == TIM_CHANNEL_4) ? ((__HANDLE__)->Instance->CCMR2 &= ~TIM_CCMR2_OC4PE) :\
-   ((__CHANNEL__) == TIM_CHANNEL_5) ? ((__HANDLE__)->Instance->CCMR3 &= ~TIM_CCMR3_OC5PE) :\
-   ((__HANDLE__)->Instance->CCMR3 &= ~TIM_CCMR3_OC6PE))
-
-/**
-  * @brief  Enable fast mode for a given channel.
-  * @param  __HANDLE__ TIM handle.
-  * @param  __CHANNEL__ TIM Channels to be configured.
-  *          This parameter can be one of the following values:
-  *            @arg TIM_CHANNEL_1: TIM Channel 1 selected
-  *            @arg TIM_CHANNEL_2: TIM Channel 2 selected
-  *            @arg TIM_CHANNEL_3: TIM Channel 3 selected
-  *            @arg TIM_CHANNEL_4: TIM Channel 4 selected
-  *            @arg TIM_CHANNEL_5: TIM Channel 5 selected
-  *            @arg TIM_CHANNEL_6: TIM Channel 6 selected
-  * @note  When fast mode is enabled an active edge on the trigger input acts
-  *        like a compare match on CCx output. Delay to sample the trigger
-  *        input and to activate CCx output is reduced to 3 clock cycles.
-  * @note  Fast mode acts only if the channel is configured in PWM1 or PWM2 mode.
-  * @retval None
-  */
-#define __HAL_TIM_ENABLE_OCxFAST(__HANDLE__, __CHANNEL__)    \
-  (((__CHANNEL__) == TIM_CHANNEL_1) ? ((__HANDLE__)->Instance->CCMR1 |= TIM_CCMR1_OC1FE) :\
-   ((__CHANNEL__) == TIM_CHANNEL_2) ? ((__HANDLE__)->Instance->CCMR1 |= TIM_CCMR1_OC2FE) :\
-   ((__CHANNEL__) == TIM_CHANNEL_3) ? ((__HANDLE__)->Instance->CCMR2 |= TIM_CCMR2_OC3FE) :\
-   ((__CHANNEL__) == TIM_CHANNEL_4) ? ((__HANDLE__)->Instance->CCMR2 |= TIM_CCMR2_OC4FE) :\
-   ((__CHANNEL__) == TIM_CHANNEL_5) ? ((__HANDLE__)->Instance->CCMR3 |= TIM_CCMR3_OC5FE) :\
-   ((__HANDLE__)->Instance->CCMR3 |= TIM_CCMR3_OC6FE))
-
-/**
-  * @brief  Disable fast mode for a given channel.
-  * @param  __HANDLE__ TIM handle.
-  * @param  __CHANNEL__ TIM Channels to be configured.
-  *          This parameter can be one of the following values:
-  *            @arg TIM_CHANNEL_1: TIM Channel 1 selected
-  *            @arg TIM_CHANNEL_2: TIM Channel 2 selected
-  *            @arg TIM_CHANNEL_3: TIM Channel 3 selected
-  *            @arg TIM_CHANNEL_4: TIM Channel 4 selected
-  *            @arg TIM_CHANNEL_5: TIM Channel 5 selected
-  *            @arg TIM_CHANNEL_6: TIM Channel 6 selected
-  * @note  When fast mode is disabled CCx output behaves normally depending
-  *        on counter and CCRx values even when the trigger is ON. The minimum
-  *        delay to activate CCx output when an active edge occurs on the
-  *        trigger input is 5 clock cycles.
-  * @retval None
-  */
-#define __HAL_TIM_DISABLE_OCxFAST(__HANDLE__, __CHANNEL__)    \
-  (((__CHANNEL__) == TIM_CHANNEL_1) ? ((__HANDLE__)->Instance->CCMR1 &= ~TIM_CCMR1_OC1FE) :\
-   ((__CHANNEL__) == TIM_CHANNEL_2) ? ((__HANDLE__)->Instance->CCMR1 &= ~TIM_CCMR1_OC2FE) :\
-   ((__CHANNEL__) == TIM_CHANNEL_3) ? ((__HANDLE__)->Instance->CCMR2 &= ~TIM_CCMR2_OC3FE) :\
-   ((__CHANNEL__) == TIM_CHANNEL_4) ? ((__HANDLE__)->Instance->CCMR2 &= ~TIM_CCMR2_OC4FE) :\
-   ((__CHANNEL__) == TIM_CHANNEL_5) ? ((__HANDLE__)->Instance->CCMR3 &= ~TIM_CCMR3_OC5FE) :\
-   ((__HANDLE__)->Instance->CCMR3 &= ~TIM_CCMR3_OC6FE))
-
-/**
-  * @brief  Set the Update Request Source (URS) bit of the TIMx_CR1 register.
-  * @param  __HANDLE__ TIM handle.
-  * @note  When the URS bit of the TIMx_CR1 register is set, only counter
-  *        overflow/underflow generates an update interrupt or DMA request (if
-  *        enabled)
-  * @retval None
-  */
-#define __HAL_TIM_URS_ENABLE(__HANDLE__)  ((__HANDLE__)->Instance->CR1|= TIM_CR1_URS)
-
-/**
-  * @brief  Reset the Update Request Source (URS) bit of the TIMx_CR1 register.
-  * @param  __HANDLE__ TIM handle.
-  * @note  When the URS bit of the TIMx_CR1 register is reset, any of the
-  *        following events generate an update interrupt or DMA request (if
-  *        enabled):
-  *           _ Counter overflow underflow
-  *           _ Setting the UG bit
-  *           _ Update generation through the slave mode controller
-  * @retval None
-  */
-#define __HAL_TIM_URS_DISABLE(__HANDLE__)  ((__HANDLE__)->Instance->CR1&=~TIM_CR1_URS)
-
-/**
-  * @brief  Set the TIM Capture x input polarity on runtime.
-  * @param  __HANDLE__ TIM handle.
-  * @param  __CHANNEL__ TIM Channels to be configured.
-  *          This parameter can be one of the following values:
-  *            @arg TIM_CHANNEL_1: TIM Channel 1 selected
-  *            @arg TIM_CHANNEL_2: TIM Channel 2 selected
-  *            @arg TIM_CHANNEL_3: TIM Channel 3 selected
-  *            @arg TIM_CHANNEL_4: TIM Channel 4 selected
-  * @param  __POLARITY__ Polarity for TIx source
-  *            @arg TIM_INPUTCHANNELPOLARITY_RISING: Rising Edge
-  *            @arg TIM_INPUTCHANNELPOLARITY_FALLING: Falling Edge
-  *            @arg TIM_INPUTCHANNELPOLARITY_BOTHEDGE: Rising and Falling Edge
-  * @retval None
-  */
-#define __HAL_TIM_SET_CAPTUREPOLARITY(__HANDLE__, __CHANNEL__, __POLARITY__)    \
-  do{                                                                     \
-    TIM_RESET_CAPTUREPOLARITY((__HANDLE__), (__CHANNEL__));               \
-    TIM_SET_CAPTUREPOLARITY((__HANDLE__), (__CHANNEL__), (__POLARITY__)); \
-  }while(0)
-
-/** @brief  Select the Capture/compare DMA request source.
-  * @param  __HANDLE__ specifies the TIM Handle.
-  * @param  __CCDMA__ specifies Capture/compare DMA request source
-  *          This parameter can be one of the following values:
-  *            @arg TIM_CCDMAREQUEST_CC: CCx DMA request generated on Capture/Compare event
-  *            @arg TIM_CCDMAREQUEST_UPDATE: CCx DMA request generated on Update event
-  * @retval None
-  */
-#define __HAL_TIM_SELECT_CCDMAREQUEST(__HANDLE__, __CCDMA__)    \
-  MODIFY_REG((__HANDLE__)->Instance->CR2, TIM_CR2_CCDS, (__CCDMA__))
-
-/**
-  * @}
-  */
-/* End of exported macros ----------------------------------------------------*/
-
-/* Private constants ---------------------------------------------------------*/
-/** @defgroup TIM_Private_Constants TIM Private Constants
-  * @{
-  */
-/* The counter of a timer instance is disabled only if all the CCx and CCxN
-   channels have been disabled */
-#define TIM_CCER_CCxE_MASK  ((uint32_t)(TIM_CCER_CC1E | TIM_CCER_CC2E | TIM_CCER_CC3E | TIM_CCER_CC4E))
-#define TIM_CCER_CCxNE_MASK ((uint32_t)(TIM_CCER_CC1NE | TIM_CCER_CC2NE | TIM_CCER_CC3NE))
-/**
-  * @}
-  */
-/* End of private constants --------------------------------------------------*/
-
-/* Private macros ------------------------------------------------------------*/
-/** @defgroup TIM_Private_Macros TIM Private Macros
-  * @{
-  */
-#define IS_TIM_CLEARINPUT_SOURCE(__MODE__)  (((__MODE__) == TIM_CLEARINPUTSOURCE_ETR)      || \
-                                             ((__MODE__) == TIM_CLEARINPUTSOURCE_COMP1)    || \
-                                             ((__MODE__) == TIM_CLEARINPUTSOURCE_COMP2)    || \
-                                             ((__MODE__) == TIM_CLEARINPUTSOURCE_NONE))
-
-#define IS_TIM_DMA_BASE(__BASE__) (((__BASE__) == TIM_DMABASE_CR1)    || \
-                                   ((__BASE__) == TIM_DMABASE_CR2)    || \
-                                   ((__BASE__) == TIM_DMABASE_SMCR)   || \
-                                   ((__BASE__) == TIM_DMABASE_DIER)   || \
-                                   ((__BASE__) == TIM_DMABASE_SR)     || \
-                                   ((__BASE__) == TIM_DMABASE_EGR)    || \
-                                   ((__BASE__) == TIM_DMABASE_CCMR1)  || \
-                                   ((__BASE__) == TIM_DMABASE_CCMR2)  || \
-                                   ((__BASE__) == TIM_DMABASE_CCER)   || \
-                                   ((__BASE__) == TIM_DMABASE_CNT)    || \
-                                   ((__BASE__) == TIM_DMABASE_PSC)    || \
-                                   ((__BASE__) == TIM_DMABASE_ARR)    || \
-                                   ((__BASE__) == TIM_DMABASE_RCR)    || \
-                                   ((__BASE__) == TIM_DMABASE_CCR1)   || \
-                                   ((__BASE__) == TIM_DMABASE_CCR2)   || \
-                                   ((__BASE__) == TIM_DMABASE_CCR3)   || \
-                                   ((__BASE__) == TIM_DMABASE_CCR4)   || \
-                                   ((__BASE__) == TIM_DMABASE_BDTR)   || \
-                                   ((__BASE__) == TIM_DMABASE_OR)     || \
-                                   ((__BASE__) == TIM_DMABASE_CCMR3)  || \
-                                   ((__BASE__) == TIM_DMABASE_CCR5)   || \
-                                   ((__BASE__) == TIM_DMABASE_CCR6)   || \
-                                   ((__BASE__) == TIM_DMABASE_AF1)    || \
-                                   ((__BASE__) == TIM_DMABASE_AF2))
-
-#define IS_TIM_EVENT_SOURCE(__SOURCE__) ((((__SOURCE__) & 0xFFFFFE00U) == 0x00000000U) && ((__SOURCE__) != 0x00000000U))
-
-#define IS_TIM_COUNTER_MODE(__MODE__)      (((__MODE__) == TIM_COUNTERMODE_UP)              || \
-                                            ((__MODE__) == TIM_COUNTERMODE_DOWN)            || \
-                                            ((__MODE__) == TIM_COUNTERMODE_CENTERALIGNED1)  || \
-                                            ((__MODE__) == TIM_COUNTERMODE_CENTERALIGNED2)  || \
-                                            ((__MODE__) == TIM_COUNTERMODE_CENTERALIGNED3))
-
-#define IS_TIM_UIFREMAP_MODE(__MODE__)     (((__MODE__) == TIM_UIFREMAP_DISABLE) || \
-                                            ((__MODE__) == TIM_UIFREMAP_ENABLE))
-
-#define IS_TIM_CLOCKDIVISION_DIV(__DIV__)  (((__DIV__) == TIM_CLOCKDIVISION_DIV1) || \
-                                            ((__DIV__) == TIM_CLOCKDIVISION_DIV2) || \
-                                            ((__DIV__) == TIM_CLOCKDIVISION_DIV4))
-
-#define IS_TIM_AUTORELOAD_PRELOAD(PRELOAD) (((PRELOAD) == TIM_AUTORELOAD_PRELOAD_DISABLE) || \
-                                            ((PRELOAD) == TIM_AUTORELOAD_PRELOAD_ENABLE))
-
-#define IS_TIM_FAST_STATE(__STATE__)       (((__STATE__) == TIM_OCFAST_DISABLE) || \
-                                            ((__STATE__) == TIM_OCFAST_ENABLE))
-
-#define IS_TIM_OC_POLARITY(__POLARITY__)   (((__POLARITY__) == TIM_OCPOLARITY_HIGH) || \
-                                            ((__POLARITY__) == TIM_OCPOLARITY_LOW))
-
-#define IS_TIM_OCN_POLARITY(__POLARITY__)  (((__POLARITY__) == TIM_OCNPOLARITY_HIGH) || \
-                                            ((__POLARITY__) == TIM_OCNPOLARITY_LOW))
-
-#define IS_TIM_OCIDLE_STATE(__STATE__)     (((__STATE__) == TIM_OCIDLESTATE_SET) || \
-                                            ((__STATE__) == TIM_OCIDLESTATE_RESET))
-
-#define IS_TIM_OCNIDLE_STATE(__STATE__)    (((__STATE__) == TIM_OCNIDLESTATE_SET) || \
-                                            ((__STATE__) == TIM_OCNIDLESTATE_RESET))
-
-#define IS_TIM_ENCODERINPUT_POLARITY(__POLARITY__)   (((__POLARITY__) == TIM_ENCODERINPUTPOLARITY_RISING)   || \
-                                                      ((__POLARITY__) == TIM_ENCODERINPUTPOLARITY_FALLING))
-
-#define IS_TIM_IC_POLARITY(__POLARITY__)   (((__POLARITY__) == TIM_ICPOLARITY_RISING)   || \
-                                            ((__POLARITY__) == TIM_ICPOLARITY_FALLING)  || \
-                                            ((__POLARITY__) == TIM_ICPOLARITY_BOTHEDGE))
-
-#define IS_TIM_IC_SELECTION(__SELECTION__) (((__SELECTION__) == TIM_ICSELECTION_DIRECTTI) || \
-                                            ((__SELECTION__) == TIM_ICSELECTION_INDIRECTTI) || \
-                                            ((__SELECTION__) == TIM_ICSELECTION_TRC))
-
-#define IS_TIM_IC_PRESCALER(__PRESCALER__) (((__PRESCALER__) == TIM_ICPSC_DIV1) || \
-                                            ((__PRESCALER__) == TIM_ICPSC_DIV2) || \
-                                            ((__PRESCALER__) == TIM_ICPSC_DIV4) || \
-                                            ((__PRESCALER__) == TIM_ICPSC_DIV8))
-
-#define IS_TIM_OPM_MODE(__MODE__)          (((__MODE__) == TIM_OPMODE_SINGLE) || \
-                                            ((__MODE__) == TIM_OPMODE_REPETITIVE))
-
-#define IS_TIM_ENCODER_MODE(__MODE__)      (((__MODE__) == TIM_ENCODERMODE_TI1) || \
-                                            ((__MODE__) == TIM_ENCODERMODE_TI2) || \
-                                            ((__MODE__) == TIM_ENCODERMODE_TI12))
-
-#define IS_TIM_DMA_SOURCE(__SOURCE__) ((((__SOURCE__) & 0xFFFF80FFU) == 0x00000000U) && ((__SOURCE__) != 0x00000000U))
-
-#define IS_TIM_CHANNELS(__CHANNEL__)       (((__CHANNEL__) == TIM_CHANNEL_1) || \
-                                            ((__CHANNEL__) == TIM_CHANNEL_2) || \
-                                            ((__CHANNEL__) == TIM_CHANNEL_3) || \
-                                            ((__CHANNEL__) == TIM_CHANNEL_4) || \
-                                            ((__CHANNEL__) == TIM_CHANNEL_5) || \
-                                            ((__CHANNEL__) == TIM_CHANNEL_6) || \
-                                            ((__CHANNEL__) == TIM_CHANNEL_ALL))
-
-#define IS_TIM_OPM_CHANNELS(__CHANNEL__)   (((__CHANNEL__) == TIM_CHANNEL_1) || \
-                                            ((__CHANNEL__) == TIM_CHANNEL_2))
-
-#define IS_TIM_PERIOD(__HANDLE__, __PERIOD__) \
-  ((IS_TIM_32B_COUNTER_INSTANCE(((__HANDLE__)->Instance)) == 0U) ? (((__PERIOD__) > 0U) && ((__PERIOD__) <= 0x0000FFFFU)) : ((__PERIOD__) > 0U))
-
-#define IS_TIM_COMPLEMENTARY_CHANNELS(__CHANNEL__) (((__CHANNEL__) == TIM_CHANNEL_1) || \
-                                                    ((__CHANNEL__) == TIM_CHANNEL_2) || \
-                                                    ((__CHANNEL__) == TIM_CHANNEL_3))
-
-#define IS_TIM_CLOCKSOURCE(__CLOCK__) (((__CLOCK__) == TIM_CLOCKSOURCE_INTERNAL) || \
-                                       ((__CLOCK__) == TIM_CLOCKSOURCE_ETRMODE1) || \
-                                       ((__CLOCK__) == TIM_CLOCKSOURCE_ETRMODE2) || \
-                                       ((__CLOCK__) == TIM_CLOCKSOURCE_TI1ED)    || \
-                                       ((__CLOCK__) == TIM_CLOCKSOURCE_TI1)      || \
-                                       ((__CLOCK__) == TIM_CLOCKSOURCE_TI2)      || \
-                                       ((__CLOCK__) == TIM_CLOCKSOURCE_ITR0)     || \
-                                       ((__CLOCK__) == TIM_CLOCKSOURCE_ITR1)     || \
-                                       ((__CLOCK__) == TIM_CLOCKSOURCE_ITR2)     || \
-                                       ((__CLOCK__) == TIM_CLOCKSOURCE_ITR3))
-
-#define IS_TIM_CLOCKPOLARITY(__POLARITY__) (((__POLARITY__) == TIM_CLOCKPOLARITY_INVERTED)    || \
-                                            ((__POLARITY__) == TIM_CLOCKPOLARITY_NONINVERTED) || \
-                                            ((__POLARITY__) == TIM_CLOCKPOLARITY_RISING)      || \
-                                            ((__POLARITY__) == TIM_CLOCKPOLARITY_FALLING)     || \
-                                            ((__POLARITY__) == TIM_CLOCKPOLARITY_BOTHEDGE))
-
-#define IS_TIM_CLOCKPRESCALER(__PRESCALER__) (((__PRESCALER__) == TIM_CLOCKPRESCALER_DIV1) || \
-                                              ((__PRESCALER__) == TIM_CLOCKPRESCALER_DIV2) || \
-                                              ((__PRESCALER__) == TIM_CLOCKPRESCALER_DIV4) || \
-                                              ((__PRESCALER__) == TIM_CLOCKPRESCALER_DIV8))
-
-#define IS_TIM_CLOCKFILTER(__ICFILTER__)      ((__ICFILTER__) <= 0xFU)
-
-#define IS_TIM_CLEARINPUT_POLARITY(__POLARITY__) (((__POLARITY__) == TIM_CLEARINPUTPOLARITY_INVERTED) || \
-                                                  ((__POLARITY__) == TIM_CLEARINPUTPOLARITY_NONINVERTED))
-
-#define IS_TIM_CLEARINPUT_PRESCALER(__PRESCALER__) (((__PRESCALER__) == TIM_CLEARINPUTPRESCALER_DIV1) || \
-                                                    ((__PRESCALER__) == TIM_CLEARINPUTPRESCALER_DIV2) || \
-                                                    ((__PRESCALER__) == TIM_CLEARINPUTPRESCALER_DIV4) || \
-                                                    ((__PRESCALER__) == TIM_CLEARINPUTPRESCALER_DIV8))
-
-#define IS_TIM_CLEARINPUT_FILTER(__ICFILTER__) ((__ICFILTER__) <= 0xFU)
-
-#define IS_TIM_OSSR_STATE(__STATE__)       (((__STATE__) == TIM_OSSR_ENABLE) || \
-                                            ((__STATE__) == TIM_OSSR_DISABLE))
-
-#define IS_TIM_OSSI_STATE(__STATE__)       (((__STATE__) == TIM_OSSI_ENABLE) || \
-                                            ((__STATE__) == TIM_OSSI_DISABLE))
-
-#define IS_TIM_LOCK_LEVEL(__LEVEL__)       (((__LEVEL__) == TIM_LOCKLEVEL_OFF) || \
-                                            ((__LEVEL__) == TIM_LOCKLEVEL_1)   || \
-                                            ((__LEVEL__) == TIM_LOCKLEVEL_2)   || \
-                                            ((__LEVEL__) == TIM_LOCKLEVEL_3))
-
-#define IS_TIM_BREAK_FILTER(__BRKFILTER__) ((__BRKFILTER__) <= 0xFUL)
-
-
-#define IS_TIM_BREAK_STATE(__STATE__)      (((__STATE__) == TIM_BREAK_ENABLE) || \
-                                            ((__STATE__) == TIM_BREAK_DISABLE))
-
-#define IS_TIM_BREAK_POLARITY(__POLARITY__) (((__POLARITY__) == TIM_BREAKPOLARITY_LOW) || \
-                                             ((__POLARITY__) == TIM_BREAKPOLARITY_HIGH))
-
-#define IS_TIM_BREAK_AFMODE(__AFMODE__) (((__AFMODE__) == TIM_BREAK_AFMODE_INPUT) || \
-                                         ((__AFMODE__) == TIM_BREAK_AFMODE_BIDIRECTIONAL))
-
-
-#define IS_TIM_BREAK2_STATE(__STATE__)     (((__STATE__) == TIM_BREAK2_ENABLE) || \
-                                            ((__STATE__) == TIM_BREAK2_DISABLE))
-
-#define IS_TIM_BREAK2_POLARITY(__POLARITY__) (((__POLARITY__) == TIM_BREAK2POLARITY_LOW) || \
-                                              ((__POLARITY__) == TIM_BREAK2POLARITY_HIGH))
-
-#define IS_TIM_BREAK2_AFMODE(__AFMODE__) (((__AFMODE__) == TIM_BREAK2_AFMODE_INPUT) || \
-                                          ((__AFMODE__) == TIM_BREAK2_AFMODE_BIDIRECTIONAL))
-
-
-#define IS_TIM_AUTOMATIC_OUTPUT_STATE(__STATE__) (((__STATE__) == TIM_AUTOMATICOUTPUT_ENABLE) || \
-                                                  ((__STATE__) == TIM_AUTOMATICOUTPUT_DISABLE))
-
-#define IS_TIM_GROUPCH5(__OCREF__) ((((__OCREF__) & 0x1FFFFFFFU) == 0x00000000U))
-
-#define IS_TIM_TRGO_SOURCE(__SOURCE__) (((__SOURCE__) == TIM_TRGO_RESET)  || \
-                                        ((__SOURCE__) == TIM_TRGO_ENABLE) || \
-                                        ((__SOURCE__) == TIM_TRGO_UPDATE) || \
-                                        ((__SOURCE__) == TIM_TRGO_OC1)    || \
-                                        ((__SOURCE__) == TIM_TRGO_OC1REF) || \
-                                        ((__SOURCE__) == TIM_TRGO_OC2REF) || \
-                                        ((__SOURCE__) == TIM_TRGO_OC3REF) || \
-                                        ((__SOURCE__) == TIM_TRGO_OC4REF))
-
-#define IS_TIM_TRGO2_SOURCE(__SOURCE__) (((__SOURCE__) == TIM_TRGO2_RESET)                        || \
-                                         ((__SOURCE__) == TIM_TRGO2_ENABLE)                       || \
-                                         ((__SOURCE__) == TIM_TRGO2_UPDATE)                       || \
-                                         ((__SOURCE__) == TIM_TRGO2_OC1)                          || \
-                                         ((__SOURCE__) == TIM_TRGO2_OC1REF)                       || \
-                                         ((__SOURCE__) == TIM_TRGO2_OC2REF)                       || \
-                                         ((__SOURCE__) == TIM_TRGO2_OC3REF)                       || \
-                                         ((__SOURCE__) == TIM_TRGO2_OC3REF)                       || \
-                                         ((__SOURCE__) == TIM_TRGO2_OC4REF)                       || \
-                                         ((__SOURCE__) == TIM_TRGO2_OC5REF)                       || \
-                                         ((__SOURCE__) == TIM_TRGO2_OC6REF)                       || \
-                                         ((__SOURCE__) == TIM_TRGO2_OC4REF_RISINGFALLING)         || \
-                                         ((__SOURCE__) == TIM_TRGO2_OC6REF_RISINGFALLING)         || \
-                                         ((__SOURCE__) == TIM_TRGO2_OC4REF_RISING_OC6REF_RISING)  || \
-                                         ((__SOURCE__) == TIM_TRGO2_OC4REF_RISING_OC6REF_FALLING) || \
-                                         ((__SOURCE__) == TIM_TRGO2_OC5REF_RISING_OC6REF_RISING)  || \
-                                         ((__SOURCE__) == TIM_TRGO2_OC5REF_RISING_OC6REF_FALLING))
-
-#define IS_TIM_MSM_STATE(__STATE__)      (((__STATE__) == TIM_MASTERSLAVEMODE_ENABLE) || \
-                                          ((__STATE__) == TIM_MASTERSLAVEMODE_DISABLE))
-
-#define IS_TIM_SLAVE_MODE(__MODE__) (((__MODE__) == TIM_SLAVEMODE_DISABLE)   || \
-                                     ((__MODE__) == TIM_SLAVEMODE_RESET)     || \
-                                     ((__MODE__) == TIM_SLAVEMODE_GATED)     || \
-                                     ((__MODE__) == TIM_SLAVEMODE_TRIGGER)   || \
-                                     ((__MODE__) == TIM_SLAVEMODE_EXTERNAL1) || \
-                                     ((__MODE__) == TIM_SLAVEMODE_COMBINED_RESETTRIGGER))
-
-#define IS_TIM_PWM_MODE(__MODE__) (((__MODE__) == TIM_OCMODE_PWM1)               || \
-                                   ((__MODE__) == TIM_OCMODE_PWM2)               || \
-                                   ((__MODE__) == TIM_OCMODE_COMBINED_PWM1)      || \
-                                   ((__MODE__) == TIM_OCMODE_COMBINED_PWM2)      || \
-                                   ((__MODE__) == TIM_OCMODE_ASSYMETRIC_PWM1)    || \
-                                   ((__MODE__) == TIM_OCMODE_ASSYMETRIC_PWM2))
-
-#define IS_TIM_OC_MODE(__MODE__)  (((__MODE__) == TIM_OCMODE_TIMING)             || \
-                                   ((__MODE__) == TIM_OCMODE_ACTIVE)             || \
-                                   ((__MODE__) == TIM_OCMODE_INACTIVE)           || \
-                                   ((__MODE__) == TIM_OCMODE_TOGGLE)             || \
-                                   ((__MODE__) == TIM_OCMODE_FORCED_ACTIVE)      || \
-                                   ((__MODE__) == TIM_OCMODE_FORCED_INACTIVE)    || \
-                                   ((__MODE__) == TIM_OCMODE_RETRIGERRABLE_OPM1) || \
-                                   ((__MODE__) == TIM_OCMODE_RETRIGERRABLE_OPM2))
-
-#define IS_TIM_TRIGGER_SELECTION(__SELECTION__) (((__SELECTION__) == TIM_TS_ITR0)    || \
-                                                 ((__SELECTION__) == TIM_TS_ITR1)    || \
-                                                 ((__SELECTION__) == TIM_TS_ITR2)    || \
-                                                 ((__SELECTION__) == TIM_TS_ITR3)    || \
-                                                 ((__SELECTION__) == TIM_TS_TI1F_ED) || \
-                                                 ((__SELECTION__) == TIM_TS_TI1FP1)  || \
-                                                 ((__SELECTION__) == TIM_TS_TI2FP2)  || \
-                                                 ((__SELECTION__) == TIM_TS_ETRF))
-
-#define IS_TIM_INTERNAL_TRIGGEREVENT_SELECTION(__SELECTION__) (((__SELECTION__) == TIM_TS_ITR0) || \
-                                                               ((__SELECTION__) == TIM_TS_ITR1) || \
-                                                               ((__SELECTION__) == TIM_TS_ITR2) || \
-                                                               ((__SELECTION__) == TIM_TS_ITR3) || \
-                                                               ((__SELECTION__) == TIM_TS_NONE))
-
-#define IS_TIM_TRIGGERPOLARITY(__POLARITY__)   (((__POLARITY__) == TIM_TRIGGERPOLARITY_INVERTED   ) || \
-                                                ((__POLARITY__) == TIM_TRIGGERPOLARITY_NONINVERTED) || \
-                                                ((__POLARITY__) == TIM_TRIGGERPOLARITY_RISING     ) || \
-                                                ((__POLARITY__) == TIM_TRIGGERPOLARITY_FALLING    ) || \
-                                                ((__POLARITY__) == TIM_TRIGGERPOLARITY_BOTHEDGE   ))
-
-#define IS_TIM_TRIGGERPRESCALER(__PRESCALER__) (((__PRESCALER__) == TIM_TRIGGERPRESCALER_DIV1) || \
-                                                ((__PRESCALER__) == TIM_TRIGGERPRESCALER_DIV2) || \
-                                                ((__PRESCALER__) == TIM_TRIGGERPRESCALER_DIV4) || \
-                                                ((__PRESCALER__) == TIM_TRIGGERPRESCALER_DIV8))
-
-#define IS_TIM_TRIGGERFILTER(__ICFILTER__) ((__ICFILTER__) <= 0xFU)
-
-#define IS_TIM_TI1SELECTION(__TI1SELECTION__)  (((__TI1SELECTION__) == TIM_TI1SELECTION_CH1) || \
-                                                ((__TI1SELECTION__) == TIM_TI1SELECTION_XORCOMBINATION))
-
-#define IS_TIM_DMA_LENGTH(__LENGTH__)      (((__LENGTH__) == TIM_DMABURSTLENGTH_1TRANSFER)   || \
-                                            ((__LENGTH__) == TIM_DMABURSTLENGTH_2TRANSFERS)  || \
-                                            ((__LENGTH__) == TIM_DMABURSTLENGTH_3TRANSFERS)  || \
-                                            ((__LENGTH__) == TIM_DMABURSTLENGTH_4TRANSFERS)  || \
-                                            ((__LENGTH__) == TIM_DMABURSTLENGTH_5TRANSFERS)  || \
-                                            ((__LENGTH__) == TIM_DMABURSTLENGTH_6TRANSFERS)  || \
-                                            ((__LENGTH__) == TIM_DMABURSTLENGTH_7TRANSFERS)  || \
-                                            ((__LENGTH__) == TIM_DMABURSTLENGTH_8TRANSFERS)  || \
-                                            ((__LENGTH__) == TIM_DMABURSTLENGTH_9TRANSFERS)  || \
-                                            ((__LENGTH__) == TIM_DMABURSTLENGTH_10TRANSFERS) || \
-                                            ((__LENGTH__) == TIM_DMABURSTLENGTH_11TRANSFERS) || \
-                                            ((__LENGTH__) == TIM_DMABURSTLENGTH_12TRANSFERS) || \
-                                            ((__LENGTH__) == TIM_DMABURSTLENGTH_13TRANSFERS) || \
-                                            ((__LENGTH__) == TIM_DMABURSTLENGTH_14TRANSFERS) || \
-                                            ((__LENGTH__) == TIM_DMABURSTLENGTH_15TRANSFERS) || \
-                                            ((__LENGTH__) == TIM_DMABURSTLENGTH_16TRANSFERS) || \
-                                            ((__LENGTH__) == TIM_DMABURSTLENGTH_17TRANSFERS) || \
-                                            ((__LENGTH__) == TIM_DMABURSTLENGTH_18TRANSFERS))
-
-#define IS_TIM_DMA_DATA_LENGTH(LENGTH) (((LENGTH) >= 0x1U) && ((LENGTH) < 0x10000U))
-
-#define IS_TIM_IC_FILTER(__ICFILTER__)   ((__ICFILTER__) <= 0xFU)
-
-#define IS_TIM_DEADTIME(__DEADTIME__)    ((__DEADTIME__) <= 0xFFU)
-
-#define IS_TIM_BREAK_SYSTEM(__CONFIG__)    (((__CONFIG__) == TIM_BREAK_SYSTEM_ECC)                  || \
-                                            ((__CONFIG__) == TIM_BREAK_SYSTEM_PVD)                  || \
-                                            ((__CONFIG__) == TIM_BREAK_SYSTEM_SRAM2_PARITY_ERROR)   || \
-                                            ((__CONFIG__) == TIM_BREAK_SYSTEM_LOCKUP))
-
-#define IS_TIM_SLAVEMODE_TRIGGER_ENABLED(__TRIGGER__) (((__TRIGGER__) == TIM_SLAVEMODE_TRIGGER) || \
-                                                       ((__TRIGGER__) == TIM_SLAVEMODE_COMBINED_RESETTRIGGER))
-
-#define TIM_SET_ICPRESCALERVALUE(__HANDLE__, __CHANNEL__, __ICPSC__) \
-  (((__CHANNEL__) == TIM_CHANNEL_1) ? ((__HANDLE__)->Instance->CCMR1 |= (__ICPSC__)) :\
-   ((__CHANNEL__) == TIM_CHANNEL_2) ? ((__HANDLE__)->Instance->CCMR1 |= ((__ICPSC__) << 8U)) :\
-   ((__CHANNEL__) == TIM_CHANNEL_3) ? ((__HANDLE__)->Instance->CCMR2 |= (__ICPSC__)) :\
-   ((__HANDLE__)->Instance->CCMR2 |= ((__ICPSC__) << 8U)))
-
-#define TIM_RESET_ICPRESCALERVALUE(__HANDLE__, __CHANNEL__) \
-  (((__CHANNEL__) == TIM_CHANNEL_1) ? ((__HANDLE__)->Instance->CCMR1 &= ~TIM_CCMR1_IC1PSC) :\
-   ((__CHANNEL__) == TIM_CHANNEL_2) ? ((__HANDLE__)->Instance->CCMR1 &= ~TIM_CCMR1_IC2PSC) :\
-   ((__CHANNEL__) == TIM_CHANNEL_3) ? ((__HANDLE__)->Instance->CCMR2 &= ~TIM_CCMR2_IC3PSC) :\
-   ((__HANDLE__)->Instance->CCMR2 &= ~TIM_CCMR2_IC4PSC))
-
-#define TIM_SET_CAPTUREPOLARITY(__HANDLE__, __CHANNEL__, __POLARITY__) \
-  (((__CHANNEL__) == TIM_CHANNEL_1) ? ((__HANDLE__)->Instance->CCER |= (__POLARITY__)) :\
-   ((__CHANNEL__) == TIM_CHANNEL_2) ? ((__HANDLE__)->Instance->CCER |= ((__POLARITY__) << 4U)) :\
-   ((__CHANNEL__) == TIM_CHANNEL_3) ? ((__HANDLE__)->Instance->CCER |= ((__POLARITY__) << 8U)) :\
-   ((__HANDLE__)->Instance->CCER |= (((__POLARITY__) << 12U))))
-
-#define TIM_RESET_CAPTUREPOLARITY(__HANDLE__, __CHANNEL__) \
-  (((__CHANNEL__) == TIM_CHANNEL_1) ? ((__HANDLE__)->Instance->CCER &= ~(TIM_CCER_CC1P | TIM_CCER_CC1NP)) :\
-   ((__CHANNEL__) == TIM_CHANNEL_2) ? ((__HANDLE__)->Instance->CCER &= ~(TIM_CCER_CC2P | TIM_CCER_CC2NP)) :\
-   ((__CHANNEL__) == TIM_CHANNEL_3) ? ((__HANDLE__)->Instance->CCER &= ~(TIM_CCER_CC3P | TIM_CCER_CC3NP)) :\
-   ((__HANDLE__)->Instance->CCER &= ~(TIM_CCER_CC4P | TIM_CCER_CC4NP)))
-
-#define TIM_CHANNEL_STATE_GET(__HANDLE__, __CHANNEL__)\
-  (((__CHANNEL__) == TIM_CHANNEL_1) ? (__HANDLE__)->ChannelState[0] :\
-   ((__CHANNEL__) == TIM_CHANNEL_2) ? (__HANDLE__)->ChannelState[1] :\
-   ((__CHANNEL__) == TIM_CHANNEL_3) ? (__HANDLE__)->ChannelState[2] :\
-   ((__CHANNEL__) == TIM_CHANNEL_4) ? (__HANDLE__)->ChannelState[3] :\
-   ((__CHANNEL__) == TIM_CHANNEL_5) ? (__HANDLE__)->ChannelState[4] :\
-   (__HANDLE__)->ChannelState[5])
-
-#define TIM_CHANNEL_STATE_SET(__HANDLE__, __CHANNEL__, __CHANNEL_STATE__) \
-  (((__CHANNEL__) == TIM_CHANNEL_1) ? ((__HANDLE__)->ChannelState[0] = (__CHANNEL_STATE__)) :\
-   ((__CHANNEL__) == TIM_CHANNEL_2) ? ((__HANDLE__)->ChannelState[1] = (__CHANNEL_STATE__)) :\
-   ((__CHANNEL__) == TIM_CHANNEL_3) ? ((__HANDLE__)->ChannelState[2] = (__CHANNEL_STATE__)) :\
-   ((__CHANNEL__) == TIM_CHANNEL_4) ? ((__HANDLE__)->ChannelState[3] = (__CHANNEL_STATE__)) :\
-   ((__CHANNEL__) == TIM_CHANNEL_5) ? ((__HANDLE__)->ChannelState[4] = (__CHANNEL_STATE__)) :\
-   ((__HANDLE__)->ChannelState[5] = (__CHANNEL_STATE__)))
-
-#define TIM_CHANNEL_STATE_SET_ALL(__HANDLE__,  __CHANNEL_STATE__) do { \
-                                                                       (__HANDLE__)->ChannelState[0]  = \
-                                                                       (__CHANNEL_STATE__);  \
-                                                                       (__HANDLE__)->ChannelState[1]  = \
-                                                                       (__CHANNEL_STATE__);  \
-                                                                       (__HANDLE__)->ChannelState[2]  = \
-                                                                       (__CHANNEL_STATE__);  \
-                                                                       (__HANDLE__)->ChannelState[3]  = \
-                                                                       (__CHANNEL_STATE__);  \
-                                                                       (__HANDLE__)->ChannelState[4]  = \
-                                                                       (__CHANNEL_STATE__);  \
-                                                                       (__HANDLE__)->ChannelState[5]  = \
-                                                                       (__CHANNEL_STATE__);  \
-                                                                     } while(0)
-
-#define TIM_CHANNEL_N_STATE_GET(__HANDLE__, __CHANNEL__)\
-  (((__CHANNEL__) == TIM_CHANNEL_1) ? (__HANDLE__)->ChannelNState[0] :\
-   ((__CHANNEL__) == TIM_CHANNEL_2) ? (__HANDLE__)->ChannelNState[1] :\
-   ((__CHANNEL__) == TIM_CHANNEL_3) ? (__HANDLE__)->ChannelNState[2] :\
-   (__HANDLE__)->ChannelNState[3])
-
-#define TIM_CHANNEL_N_STATE_SET(__HANDLE__, __CHANNEL__, __CHANNEL_STATE__) \
-  (((__CHANNEL__) == TIM_CHANNEL_1) ? ((__HANDLE__)->ChannelNState[0] = (__CHANNEL_STATE__)) :\
-   ((__CHANNEL__) == TIM_CHANNEL_2) ? ((__HANDLE__)->ChannelNState[1] = (__CHANNEL_STATE__)) :\
-   ((__CHANNEL__) == TIM_CHANNEL_3) ? ((__HANDLE__)->ChannelNState[2] = (__CHANNEL_STATE__)) :\
-   ((__HANDLE__)->ChannelNState[3] = (__CHANNEL_STATE__)))
-
-#define TIM_CHANNEL_N_STATE_SET_ALL(__HANDLE__,  __CHANNEL_STATE__) do { \
-                                                                         (__HANDLE__)->ChannelNState[0] = \
-                                                                         (__CHANNEL_STATE__);  \
-                                                                         (__HANDLE__)->ChannelNState[1] = \
-                                                                         (__CHANNEL_STATE__);  \
-                                                                         (__HANDLE__)->ChannelNState[2] = \
-                                                                         (__CHANNEL_STATE__);  \
-                                                                         (__HANDLE__)->ChannelNState[3] = \
-                                                                         (__CHANNEL_STATE__);  \
-                                                                       } while(0)
-
-/**
-  * @}
-  */
-/* End of private macros -----------------------------------------------------*/
-
-/* Include TIM HAL Extended module */
-#include "stm32wbxx_hal_tim_ex.h"
-
-/* Exported functions --------------------------------------------------------*/
-/** @addtogroup TIM_Exported_Functions TIM Exported Functions
-  * @{
-  */
-
-/** @addtogroup TIM_Exported_Functions_Group1 TIM Time Base functions
-  *  @brief   Time Base functions
-  * @{
-  */
-/* Time Base functions ********************************************************/
-HAL_StatusTypeDef HAL_TIM_Base_Init(TIM_HandleTypeDef *htim);
-HAL_StatusTypeDef HAL_TIM_Base_DeInit(TIM_HandleTypeDef *htim);
-void HAL_TIM_Base_MspInit(TIM_HandleTypeDef *htim);
-void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef *htim);
-/* Blocking mode: Polling */
-HAL_StatusTypeDef HAL_TIM_Base_Start(TIM_HandleTypeDef *htim);
-HAL_StatusTypeDef HAL_TIM_Base_Stop(TIM_HandleTypeDef *htim);
-/* Non-Blocking mode: Interrupt */
-HAL_StatusTypeDef HAL_TIM_Base_Start_IT(TIM_HandleTypeDef *htim);
-HAL_StatusTypeDef HAL_TIM_Base_Stop_IT(TIM_HandleTypeDef *htim);
-/* Non-Blocking mode: DMA */
-HAL_StatusTypeDef HAL_TIM_Base_Start_DMA(TIM_HandleTypeDef *htim, const uint32_t *pData, uint16_t Length);
-HAL_StatusTypeDef HAL_TIM_Base_Stop_DMA(TIM_HandleTypeDef *htim);
-/**
-  * @}
-  */
-
-/** @addtogroup TIM_Exported_Functions_Group2 TIM Output Compare functions
-  *  @brief   TIM Output Compare functions
-  * @{
-  */
-/* Timer Output Compare functions *********************************************/
-HAL_StatusTypeDef HAL_TIM_OC_Init(TIM_HandleTypeDef *htim);
-HAL_StatusTypeDef HAL_TIM_OC_DeInit(TIM_HandleTypeDef *htim);
-void HAL_TIM_OC_MspInit(TIM_HandleTypeDef *htim);
-void HAL_TIM_OC_MspDeInit(TIM_HandleTypeDef *htim);
-/* Blocking mode: Polling */
-HAL_StatusTypeDef HAL_TIM_OC_Start(TIM_HandleTypeDef *htim, uint32_t Channel);
-HAL_StatusTypeDef HAL_TIM_OC_Stop(TIM_HandleTypeDef *htim, uint32_t Channel);
-/* Non-Blocking mode: Interrupt */
-HAL_StatusTypeDef HAL_TIM_OC_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel);
-HAL_StatusTypeDef HAL_TIM_OC_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel);
-/* Non-Blocking mode: DMA */
-HAL_StatusTypeDef HAL_TIM_OC_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, const uint32_t *pData,
-                                       uint16_t Length);
-HAL_StatusTypeDef HAL_TIM_OC_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel);
-/**
-  * @}
-  */
-
-/** @addtogroup TIM_Exported_Functions_Group3 TIM PWM functions
-  *  @brief   TIM PWM functions
-  * @{
-  */
-/* Timer PWM functions ********************************************************/
-HAL_StatusTypeDef HAL_TIM_PWM_Init(TIM_HandleTypeDef *htim);
-HAL_StatusTypeDef HAL_TIM_PWM_DeInit(TIM_HandleTypeDef *htim);
-void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef *htim);
-void HAL_TIM_PWM_MspDeInit(TIM_HandleTypeDef *htim);
-/* Blocking mode: Polling */
-HAL_StatusTypeDef HAL_TIM_PWM_Start(TIM_HandleTypeDef *htim, uint32_t Channel);
-HAL_StatusTypeDef HAL_TIM_PWM_Stop(TIM_HandleTypeDef *htim, uint32_t Channel);
-/* Non-Blocking mode: Interrupt */
-HAL_StatusTypeDef HAL_TIM_PWM_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel);
-HAL_StatusTypeDef HAL_TIM_PWM_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel);
-/* Non-Blocking mode: DMA */
-HAL_StatusTypeDef HAL_TIM_PWM_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, const uint32_t *pData,
-                                        uint16_t Length);
-HAL_StatusTypeDef HAL_TIM_PWM_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel);
-/**
-  * @}
-  */
-
-/** @addtogroup TIM_Exported_Functions_Group4 TIM Input Capture functions
-  *  @brief   TIM Input Capture functions
-  * @{
-  */
-/* Timer Input Capture functions **********************************************/
-HAL_StatusTypeDef HAL_TIM_IC_Init(TIM_HandleTypeDef *htim);
-HAL_StatusTypeDef HAL_TIM_IC_DeInit(TIM_HandleTypeDef *htim);
-void HAL_TIM_IC_MspInit(TIM_HandleTypeDef *htim);
-void HAL_TIM_IC_MspDeInit(TIM_HandleTypeDef *htim);
-/* Blocking mode: Polling */
-HAL_StatusTypeDef HAL_TIM_IC_Start(TIM_HandleTypeDef *htim, uint32_t Channel);
-HAL_StatusTypeDef HAL_TIM_IC_Stop(TIM_HandleTypeDef *htim, uint32_t Channel);
-/* Non-Blocking mode: Interrupt */
-HAL_StatusTypeDef HAL_TIM_IC_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel);
-HAL_StatusTypeDef HAL_TIM_IC_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel);
-/* Non-Blocking mode: DMA */
-HAL_StatusTypeDef HAL_TIM_IC_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, uint32_t *pData, uint16_t Length);
-HAL_StatusTypeDef HAL_TIM_IC_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel);
-/**
-  * @}
-  */
-
-/** @addtogroup TIM_Exported_Functions_Group5 TIM One Pulse functions
-  *  @brief   TIM One Pulse functions
-  * @{
-  */
-/* Timer One Pulse functions **************************************************/
-HAL_StatusTypeDef HAL_TIM_OnePulse_Init(TIM_HandleTypeDef *htim, uint32_t OnePulseMode);
-HAL_StatusTypeDef HAL_TIM_OnePulse_DeInit(TIM_HandleTypeDef *htim);
-void HAL_TIM_OnePulse_MspInit(TIM_HandleTypeDef *htim);
-void HAL_TIM_OnePulse_MspDeInit(TIM_HandleTypeDef *htim);
-/* Blocking mode: Polling */
-HAL_StatusTypeDef HAL_TIM_OnePulse_Start(TIM_HandleTypeDef *htim, uint32_t OutputChannel);
-HAL_StatusTypeDef HAL_TIM_OnePulse_Stop(TIM_HandleTypeDef *htim, uint32_t OutputChannel);
-/* Non-Blocking mode: Interrupt */
-HAL_StatusTypeDef HAL_TIM_OnePulse_Start_IT(TIM_HandleTypeDef *htim, uint32_t OutputChannel);
-HAL_StatusTypeDef HAL_TIM_OnePulse_Stop_IT(TIM_HandleTypeDef *htim, uint32_t OutputChannel);
-/**
-  * @}
-  */
-
-/** @addtogroup TIM_Exported_Functions_Group6 TIM Encoder functions
-  *  @brief   TIM Encoder functions
-  * @{
-  */
-/* Timer Encoder functions ****************************************************/
-HAL_StatusTypeDef HAL_TIM_Encoder_Init(TIM_HandleTypeDef *htim,  TIM_Encoder_InitTypeDef *sConfig);
-HAL_StatusTypeDef HAL_TIM_Encoder_DeInit(TIM_HandleTypeDef *htim);
-void HAL_TIM_Encoder_MspInit(TIM_HandleTypeDef *htim);
-void HAL_TIM_Encoder_MspDeInit(TIM_HandleTypeDef *htim);
-/* Blocking mode: Polling */
-HAL_StatusTypeDef HAL_TIM_Encoder_Start(TIM_HandleTypeDef *htim, uint32_t Channel);
-HAL_StatusTypeDef HAL_TIM_Encoder_Stop(TIM_HandleTypeDef *htim, uint32_t Channel);
-/* Non-Blocking mode: Interrupt */
-HAL_StatusTypeDef HAL_TIM_Encoder_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel);
-HAL_StatusTypeDef HAL_TIM_Encoder_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel);
-/* Non-Blocking mode: DMA */
-HAL_StatusTypeDef HAL_TIM_Encoder_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, uint32_t *pData1,
-                                            uint32_t *pData2, uint16_t Length);
-HAL_StatusTypeDef HAL_TIM_Encoder_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel);
-/**
-  * @}
-  */
-
-/** @addtogroup TIM_Exported_Functions_Group7 TIM IRQ handler management
-  *  @brief   IRQ handler management
-  * @{
-  */
-/* Interrupt Handler functions  ***********************************************/
-void HAL_TIM_IRQHandler(TIM_HandleTypeDef *htim);
-/**
-  * @}
-  */
-
-/** @defgroup TIM_Exported_Functions_Group8 TIM Peripheral Control functions
-  *  @brief   Peripheral Control functions
-  * @{
-  */
-/* Control functions  *********************************************************/
-HAL_StatusTypeDef HAL_TIM_OC_ConfigChannel(TIM_HandleTypeDef *htim, const TIM_OC_InitTypeDef *sConfig,
-                                           uint32_t Channel);
-HAL_StatusTypeDef HAL_TIM_PWM_ConfigChannel(TIM_HandleTypeDef *htim, const TIM_OC_InitTypeDef *sConfig,
-                                            uint32_t Channel);
-HAL_StatusTypeDef HAL_TIM_IC_ConfigChannel(TIM_HandleTypeDef *htim, const TIM_IC_InitTypeDef *sConfig,
-                                           uint32_t Channel);
-HAL_StatusTypeDef HAL_TIM_OnePulse_ConfigChannel(TIM_HandleTypeDef *htim, TIM_OnePulse_InitTypeDef *sConfig,
-                                                 uint32_t OutputChannel,  uint32_t InputChannel);
-HAL_StatusTypeDef HAL_TIM_ConfigOCrefClear(TIM_HandleTypeDef *htim,
-                                           const TIM_ClearInputConfigTypeDef *sClearInputConfig,
-                                           uint32_t Channel);
-HAL_StatusTypeDef HAL_TIM_ConfigClockSource(TIM_HandleTypeDef *htim, const TIM_ClockConfigTypeDef *sClockSourceConfig);
-HAL_StatusTypeDef HAL_TIM_ConfigTI1Input(TIM_HandleTypeDef *htim, uint32_t TI1_Selection);
-HAL_StatusTypeDef HAL_TIM_SlaveConfigSynchro(TIM_HandleTypeDef *htim, const TIM_SlaveConfigTypeDef *sSlaveConfig);
-HAL_StatusTypeDef HAL_TIM_SlaveConfigSynchro_IT(TIM_HandleTypeDef *htim, const TIM_SlaveConfigTypeDef *sSlaveConfig);
-HAL_StatusTypeDef HAL_TIM_DMABurst_WriteStart(TIM_HandleTypeDef *htim, uint32_t BurstBaseAddress,
-                                              uint32_t BurstRequestSrc, const uint32_t  *BurstBuffer, uint32_t  BurstLength);
-HAL_StatusTypeDef HAL_TIM_DMABurst_MultiWriteStart(TIM_HandleTypeDef *htim, uint32_t BurstBaseAddress,
-                                                   uint32_t BurstRequestSrc, const uint32_t *BurstBuffer,
-                                                   uint32_t BurstLength,  uint32_t DataLength);
-HAL_StatusTypeDef HAL_TIM_DMABurst_WriteStop(TIM_HandleTypeDef *htim, uint32_t BurstRequestSrc);
-HAL_StatusTypeDef HAL_TIM_DMABurst_ReadStart(TIM_HandleTypeDef *htim, uint32_t BurstBaseAddress,
-                                             uint32_t BurstRequestSrc, uint32_t  *BurstBuffer, uint32_t  BurstLength);
-HAL_StatusTypeDef HAL_TIM_DMABurst_MultiReadStart(TIM_HandleTypeDef *htim, uint32_t BurstBaseAddress,
-                                                  uint32_t BurstRequestSrc, uint32_t  *BurstBuffer,
-                                                  uint32_t  BurstLength, uint32_t  DataLength);
-HAL_StatusTypeDef HAL_TIM_DMABurst_ReadStop(TIM_HandleTypeDef *htim, uint32_t BurstRequestSrc);
-HAL_StatusTypeDef HAL_TIM_GenerateEvent(TIM_HandleTypeDef *htim, uint32_t EventSource);
-uint32_t HAL_TIM_ReadCapturedValue(const TIM_HandleTypeDef *htim, uint32_t Channel);
-/**
-  * @}
-  */
-
-/** @defgroup TIM_Exported_Functions_Group9 TIM Callbacks functions
-  *  @brief   TIM Callbacks functions
-  * @{
-  */
-/* Callback in non blocking modes (Interrupt and DMA) *************************/
-void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim);
-void HAL_TIM_PeriodElapsedHalfCpltCallback(TIM_HandleTypeDef *htim);
-void HAL_TIM_OC_DelayElapsedCallback(TIM_HandleTypeDef *htim);
-void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim);
-void HAL_TIM_IC_CaptureHalfCpltCallback(TIM_HandleTypeDef *htim);
-void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim);
-void HAL_TIM_PWM_PulseFinishedHalfCpltCallback(TIM_HandleTypeDef *htim);
-void HAL_TIM_TriggerCallback(TIM_HandleTypeDef *htim);
-void HAL_TIM_TriggerHalfCpltCallback(TIM_HandleTypeDef *htim);
-void HAL_TIM_ErrorCallback(TIM_HandleTypeDef *htim);
-
-/* Callbacks Register/UnRegister functions  ***********************************/
-#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
-HAL_StatusTypeDef HAL_TIM_RegisterCallback(TIM_HandleTypeDef *htim, HAL_TIM_CallbackIDTypeDef CallbackID,
-                                           pTIM_CallbackTypeDef pCallback);
-HAL_StatusTypeDef HAL_TIM_UnRegisterCallback(TIM_HandleTypeDef *htim, HAL_TIM_CallbackIDTypeDef CallbackID);
-#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
-
-/**
-  * @}
-  */
-
-/** @defgroup TIM_Exported_Functions_Group10 TIM Peripheral State functions
-  *  @brief  Peripheral State functions
-  * @{
-  */
-/* Peripheral State functions  ************************************************/
-HAL_TIM_StateTypeDef HAL_TIM_Base_GetState(const TIM_HandleTypeDef *htim);
-HAL_TIM_StateTypeDef HAL_TIM_OC_GetState(const TIM_HandleTypeDef *htim);
-HAL_TIM_StateTypeDef HAL_TIM_PWM_GetState(const TIM_HandleTypeDef *htim);
-HAL_TIM_StateTypeDef HAL_TIM_IC_GetState(const TIM_HandleTypeDef *htim);
-HAL_TIM_StateTypeDef HAL_TIM_OnePulse_GetState(const TIM_HandleTypeDef *htim);
-HAL_TIM_StateTypeDef HAL_TIM_Encoder_GetState(const TIM_HandleTypeDef *htim);
-
-/* Peripheral Channel state functions  ************************************************/
-HAL_TIM_ActiveChannel HAL_TIM_GetActiveChannel(const TIM_HandleTypeDef *htim);
-HAL_TIM_ChannelStateTypeDef HAL_TIM_GetChannelState(const TIM_HandleTypeDef *htim,  uint32_t Channel);
-HAL_TIM_DMABurstStateTypeDef HAL_TIM_DMABurstState(const TIM_HandleTypeDef *htim);
-/**
-  * @}
-  */
-
-/**
-  * @}
-  */
-/* End of exported functions -------------------------------------------------*/
-
-/* Private functions----------------------------------------------------------*/
-/** @defgroup TIM_Private_Functions TIM Private Functions
-  * @{
-  */
-void TIM_Base_SetConfig(TIM_TypeDef *TIMx, const TIM_Base_InitTypeDef *Structure);
-void TIM_TI1_SetConfig(TIM_TypeDef *TIMx, uint32_t TIM_ICPolarity, uint32_t TIM_ICSelection, uint32_t TIM_ICFilter);
-void TIM_OC2_SetConfig(TIM_TypeDef *TIMx, const TIM_OC_InitTypeDef *OC_Config);
-void TIM_ETR_SetConfig(TIM_TypeDef *TIMx, uint32_t TIM_ExtTRGPrescaler,
-                       uint32_t TIM_ExtTRGPolarity, uint32_t ExtTRGFilter);
-
-void TIM_DMADelayPulseHalfCplt(DMA_HandleTypeDef *hdma);
-void TIM_DMAError(DMA_HandleTypeDef *hdma);
-void TIM_DMACaptureCplt(DMA_HandleTypeDef *hdma);
-void TIM_DMACaptureHalfCplt(DMA_HandleTypeDef *hdma);
-void TIM_CCxChannelCmd(TIM_TypeDef *TIMx, uint32_t Channel, uint32_t ChannelState);
-
-#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
-void TIM_ResetCallback(TIM_HandleTypeDef *htim);
-#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
-
-/**
-  * @}
-  */
-/* End of private functions --------------------------------------------------*/
-
-/**
-  * @}
-  */
-
-/**
-  * @}
-  */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* STM32WBxx_HAL_TIM_H */

+ 0 - 304
non_catalog_apps/flipperscope/lib/adc/inc/stm32wbxx_nucleo.h

@@ -1,304 +0,0 @@
-/** 
-  ******************************************************************************
-  * @file    stm32wbxx_nucleo.h
-  * @author  MCD Application Team
-  * @brief   This file contains definitions for:
-  *          - LEDs and push-button available on STM32WBXX-Nucleo Kit 
-  *            from STMicroelectronics
-  ******************************************************************************
-  * @attention
-  *
-  * Copyright (c) 2019-2021 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 __STM32WBXX_NUCLEO_H
-#define __STM32WBXX_NUCLEO_H
-
-#ifdef __cplusplus
- extern "C" {
-#endif
-
-/** @addtogroup BSP
-  * @{
-  */
-
-/** @addtogroup STM32WBXX_NUCLEO
-  * @{
-  */
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32wbxx_hal.h"
-   
-/** @defgroup STM32WBXX_NUCLEO_Exported_Types Exported Types
-  * @{
-  */
-typedef enum 
-{
-  LED1 = 0,
-  LED2 = 1,
-  LED3 = 2,
-  /* Color led aliases */
-  LED_BLUE   = LED1,
-  LED_GREEN  = LED2,
-  LED_RED    = LED3
-}Led_TypeDef;
-
-typedef enum 
-{  
-  BUTTON_SW1 = 0,
-  BUTTON_SW2 = 1,
-  BUTTON_SW3 = 2,
-}Button_TypeDef;
-
-typedef enum 
-{  
-  BUTTON_MODE_GPIO = 0,
-  BUTTON_MODE_EXTI = 1
-}ButtonMode_TypeDef;
-
-typedef enum 
-{ 
-  JOY_NONE  = 0,
-  JOY_SEL   = 1,
-  JOY_DOWN  = 2,
-  JOY_LEFT  = 3,
-  JOY_RIGHT = 4,
-  JOY_UP    = 5
-} JOYState_TypeDef;
-
-/**
-  * @}
-  */ 
-
-/** @defgroup STM32WBXX_NUCLEO_Exported_Constants Exported Constants
-  * @{
-  */ 
-
-/** 
-  * @brief Define for STM32WBXX_NUCLEO board  
-  */ 
-#if !defined (USE_STM32WBXX_NUCLEO)
- #define USE_STM32WBXX_NUCLEO
-#endif
-
-/** @defgroup STM32WBXX_NUCLEO_LED LED Constants
-  * @{
-  */
-#define LEDn                                    3
-
-#define LED1_PIN                                GPIO_PIN_5
-#define LED1_GPIO_PORT                          GPIOB
-#define LED1_GPIO_CLK_ENABLE()                  __HAL_RCC_GPIOB_CLK_ENABLE()
-#define LED1_GPIO_CLK_DISABLE()                 __HAL_RCC_GPIOB_CLK_DISABLE()
-
-#define LED2_PIN                                GPIO_PIN_0
-#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()
-
-#define LED3_PIN                                GPIO_PIN_1
-#define LED3_GPIO_PORT                          GPIOB
-#define LED3_GPIO_CLK_ENABLE()                  __HAL_RCC_GPIOB_CLK_ENABLE()
-#define LED3_GPIO_CLK_DISABLE()                 __HAL_RCC_GPIOB_CLK_DISABLE()
-
-#define LEDx_GPIO_CLK_ENABLE(__INDEX__)         __HAL_RCC_GPIOB_CLK_ENABLE() /* All Led on same port */
-#define LEDx_GPIO_CLK_DISABLE(__INDEX__)        __HAL_RCC_GPIOB_CLK_DISABLE() /* All Led on same port */
-/**
-  * @}
-  */ 
-  
-/** @defgroup STM32WBXX_NUCLEO_BUTTON BUTTON Constants
-  * @{
-  */  
-#define BUTTONn                                 3
-
-/**
- * @brief Key push-button
- */
-#define BUTTON_SW1_PIN                          GPIO_PIN_4
-#define BUTTON_SW1_GPIO_PORT                    GPIOC
-#define BUTTON_SW1_GPIO_CLK_ENABLE()            __HAL_RCC_GPIOC_CLK_ENABLE()
-#define BUTTON_SW1_GPIO_CLK_DISABLE()           __HAL_RCC_GPIOC_CLK_DISABLE()
-#define BUTTON_SW1_EXTI_LINE                    GPIO_PIN_4
-#ifdef CORE_CM0PLUS
-#define BUTTON_SW1_EXTI_IRQn                    EXTI15_4_IRQn
-#else
-#define BUTTON_SW1_EXTI_IRQn                    EXTI4_IRQn
-#endif
-
-#define BUTTON_SW2_PIN                          GPIO_PIN_0
-#define BUTTON_SW2_GPIO_PORT                    GPIOD
-#define BUTTON_SW2_GPIO_CLK_ENABLE()            __HAL_RCC_GPIOD_CLK_ENABLE()
-#define BUTTON_SW2_GPIO_CLK_DISABLE()           __HAL_RCC_GPIOD_CLK_DISABLE()
-#define BUTTON_SW2_EXTI_LINE                    GPIO_PIN_0
-#ifdef CORE_CM0PLUS
-#define BUTTON_SW2_EXTI_IRQn                    EXTI1_0_IRQn
-#else
-#define BUTTON_SW2_EXTI_IRQn                    EXTI0_IRQn
-#endif
-
-#define BUTTON_SW3_PIN                          GPIO_PIN_1
-#define BUTTON_SW3_GPIO_PORT                    GPIOD
-#define BUTTON_SW3_GPIO_CLK_ENABLE()            __HAL_RCC_GPIOD_CLK_ENABLE()
-#define BUTTON_SW3_GPIO_CLK_DISABLE()           __HAL_RCC_GPIOD_CLK_DISABLE()
-#define BUTTON_SW3_EXTI_LINE                    GPIO_PIN_1
-#ifdef CORE_CM0PLUS
-#define BUTTON_SW3_EXTI_IRQn                    EXTI1_0_IRQn
-#else
-#define BUTTON_SW3_EXTI_IRQn                    EXTI1_IRQn
-#endif
-
-#define BUTTONx_GPIO_CLK_ENABLE(__INDEX__)    do { if ((__INDEX__) == BUTTON_SW1) BUTTON_SW1_GPIO_CLK_ENABLE(); else \
-                                              if ((__INDEX__) == BUTTON_SW2) BUTTON_SW2_GPIO_CLK_ENABLE(); else \
-                                              if ((__INDEX__) == BUTTON_SW3) BUTTON_SW3_GPIO_CLK_ENABLE();} while(0)
-
-#define BUTTONx_GPIO_CLK_DISABLE(__INDEX__)    do { if ((__INDEX__) == BUTTON_SW1) BUTTON_SW1_GPIO_CLK_DISABLE(); else \
-                                              if ((__INDEX__) == BUTTON_SW2) BUTTON_SW2_GPIO_CLK_DISABLE(); else \
-                                              if ((__INDEX__) == BUTTON_SW3) BUTTON_SW3_GPIO_CLK_DISABLE();} while(0)
-
-/**
-  * @}
-  */
-
-/** @addtogroup STM32WBXX_NUCLEO_BUS BUS Constants
-  * @{
-  */
-/*###################### SPI1 ###################################*/
-#define NUCLEO_SPIx                                 SPI1
-#define NUCLEO_SPIx_CLK_ENABLE()                    __HAL_RCC_SPI1_CLK_ENABLE()
-
-#define NUCLEO_SPIx_SCK_AF                          GPIO_AF5_SPI1
-#define NUCLEO_SPIx_SCK_GPIO_PORT                   GPIOA
-#define NUCLEO_SPIx_SCK_PIN                         GPIO_PIN_5
-#define NUCLEO_SPIx_SCK_GPIO_CLK_ENABLE()           __HAL_RCC_GPIOA_CLK_ENABLE()
-#define NUCLEO_SPIx_SCK_GPIO_CLK_DISABLE()          __HAL_RCC_GPIOA_CLK_DISABLE()
-
-#define NUCLEO_SPIx_MISO_MOSI_AF                    GPIO_AF5_SPI1
-#define NUCLEO_SPIx_MISO_MOSI_GPIO_PORT             GPIOA
-#define NUCLEO_SPIx_MISO_MOSI_GPIO_CLK_ENABLE()     __HAL_RCC_GPIOA_CLK_ENABLE()
-#define NUCLEO_SPIx_MISO_MOSI_GPIO_CLK_DISABLE()    __HAL_RCC_GPIOA_CLK_DISABLE()
-#define NUCLEO_SPIx_MISO_PIN                        GPIO_PIN_6
-#define NUCLEO_SPIx_MOSI_PIN                        GPIO_PIN_7
-/* Maximum Timeout values for flags waiting loops. These timeouts are not based
-   on accurate values, they just guarantee that the application will not remain
-   stuck if the SPI communication is corrupted.
-   You may modify these timeout values depending on CPU frequency and application
-   conditions (interrupts routines ...). */   
-#define NUCLEO_SPIx_TIMEOUT_MAX                   1000
-
-
-/**
-  * @brief  SD Control Lines management
-  */  
-#define SD_CS_LOW()       HAL_GPIO_WritePin(SD_CS_GPIO_PORT, SD_CS_PIN, GPIO_PIN_RESET)
-#define SD_CS_HIGH()      HAL_GPIO_WritePin(SD_CS_GPIO_PORT, SD_CS_PIN, GPIO_PIN_SET)
-    
-/**
-  * @brief  LCD Control Lines management
-  */
-#define LCD_CS_LOW()      HAL_GPIO_WritePin(LCD_CS_GPIO_PORT, LCD_CS_PIN, GPIO_PIN_RESET)
-#define LCD_CS_HIGH()     HAL_GPIO_WritePin(LCD_CS_GPIO_PORT, LCD_CS_PIN, GPIO_PIN_SET)
-#define LCD_DC_LOW()      HAL_GPIO_WritePin(LCD_DC_GPIO_PORT, LCD_DC_PIN, GPIO_PIN_RESET)
-#define LCD_DC_HIGH()     HAL_GPIO_WritePin(LCD_DC_GPIO_PORT, LCD_DC_PIN, GPIO_PIN_SET)
-
-/**
-  * @brief  SD Control Interface pins
-  */
-#define SD_CS_PIN                                 GPIO_PIN_10
-#define SD_CS_GPIO_PORT                           GPIOC
-#define SD_CS_GPIO_CLK_ENABLE()                   __HAL_RCC_GPIOC_CLK_ENABLE()
-#define SD_CS_GPIO_CLK_DISABLE()                  __HAL_RCC_GPIOC_CLK_DISABLE()
-
-/**
-  * @brief  LCD Control Interface pins
-  */
-#define LCD_CS_PIN                                 GPIO_PIN_4
-#define LCD_CS_GPIO_PORT                           GPIOA
-#define LCD_CS_GPIO_CLK_ENABLE()                   __HAL_RCC_GPIOA_CLK_ENABLE()
-#define LCD_CS_GPIO_CLK_DISABLE()                  __HAL_RCC_GPIOA_CLK_DISABLE()
-
-/**
-  * @brief  LCD Data/Command Interface pins
-  */
-#define LCD_DC_PIN                                 GPIO_PIN_12
-#define LCD_DC_GPIO_PORT                           GPIOC
-#define LCD_DC_GPIO_CLK_ENABLE()                   __HAL_RCC_GPIOC_CLK_ENABLE()
-#define LCD_DC_GPIO_CLK_DISABLE()                  __HAL_RCC_GPIOC_CLK_DISABLE()
-     
-/*##################### ADC1 ###################################*/
-/**
-  * @brief  ADC Interface pins
-  *         used to detect motion of Joystick available on Adafruit 1.8" TFT shield
-  */
-#define NUCLEO_ADCx                                 ADC1
-#define NUCLEO_ADCx_CLK_ENABLE()                    __HAL_RCC_ADC_CLK_ENABLE()
-    
-#define NUCLEO_ADCx_GPIO_PORT                       GPIOA
-#define NUCLEO_ADCx_GPIO_PIN                        GPIO_PIN_0
-#define NUCLEO_ADCx_GPIO_CLK_ENABLE()               __HAL_RCC_GPIOA_CLK_ENABLE()
-#define NUCLEO_ADCx_GPIO_CLK_DISABLE()              __HAL_RCC_GPIOA_CLK_DISABLE()
-
-/**
-  * @}
-  */
-
-/**
-  * @}
-  */
-
-/** @addtogroup STM32WBXX_NUCLEO_Exported_Functions
-  * @{
-  */
-uint32_t         BSP_GetVersion(void);  
-
-/** @addtogroup STM32WBXX_NUCLEO_LED_Functions
-  * @{
-  */
-void             BSP_LED_Init(Led_TypeDef Led);
-void             BSP_LED_DeInit(Led_TypeDef Led);
-void             BSP_LED_On(Led_TypeDef Led);
-void             BSP_LED_Off(Led_TypeDef Led);
-void             BSP_LED_Toggle(Led_TypeDef Led);
-/**
-  * @}
-  */
-
-/** @addtogroup STM32WBXX_NUCLEO_BUTTON_Functions
-  * @{
-  */
-void             BSP_PB_Init(Button_TypeDef Button, ButtonMode_TypeDef ButtonMode);
-void             BSP_PB_DeInit(Button_TypeDef Button);
-uint32_t         BSP_PB_GetState(Button_TypeDef Button);
-#ifdef HAL_ADC_MODULE_ENABLED
-uint8_t          BSP_JOY_Init(void);
-JOYState_TypeDef BSP_JOY_GetState(void);
-#endif /* HAL_ADC_MODULE_ENABLED */
-/**
-  * @}
-  */
-
-/**
-  * @}
-  */
-
-/**
-  * @}
-  */
-
-/**
-  * @}
-  */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __STM32WBXX_NUCLEO_H */

+ 0 - 851
non_catalog_apps/flipperscope/lib/adc/stm32wbxx_hal.c

@@ -1,851 +0,0 @@
-/**
-  ******************************************************************************
-  * @file    stm32wbxx_hal.c
-  * @author  MCD Application Team
-  * @brief   HAL module driver.
-  *          This is the common part of the HAL initialization
-  ******************************************************************************
-  * @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 common HAL driver contains a set of generic and common APIs that can be
-    used by the PPP peripheral drivers and the user to start using the HAL.
-    [..]
-    The HAL contains two APIs' categories:
-         (+) Common HAL APIs
-         (+) Services HAL APIs
-
-  @endverbatim
-  ******************************************************************************
-  */
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32wbxx_hal.h"
-
-/** @addtogroup STM32WBxx_HAL_Driver
-  * @{
-  */
-
-/** @addtogroup HAL
-  * @brief HAL module driver
-  * @{
-  */
-
-#ifdef HAL_MODULE_ENABLED
-
-/* Private typedef -----------------------------------------------------------*/
-/* Private define ------------------------------------------------------------*/
-
-/** @defgroup HAL_Private_Constants HAL Private Constants
-  * @{
-  */
-/**
-  * @brief STM32WBxx HAL Driver version number
-   */
-#define __STM32WBxx_HAL_VERSION_MAIN   (0x01U) /*!< [31:24] main version */
-#define __STM32WBxx_HAL_VERSION_SUB1   (0x0CU) /*!< [23:16] sub1 version */
-#define __STM32WBxx_HAL_VERSION_SUB2   (0x00U) /*!< [15:8]  sub2 version */
-#define __STM32WBxx_HAL_VERSION_RC     (0x00U) /*!< [7:0]  release candidate */
-#define __STM32WBxx_HAL_VERSION         ((__STM32WBxx_HAL_VERSION_MAIN << 24U)\
-                                         |(__STM32WBxx_HAL_VERSION_SUB1 << 16U)\
-                                         |(__STM32WBxx_HAL_VERSION_SUB2 << 8U )\
-                                         |(__STM32WBxx_HAL_VERSION_RC))
-
-#if defined(VREFBUF)
-#define VREFBUF_TIMEOUT_VALUE     10U   /* 10 ms */
-#endif /* VREFBUF */
-
-/**
-  * @}
-  */
-
-/* Private macro -------------------------------------------------------------*/
-/* Exported variables ---------------------------------------------------------*/
-/** @defgroup HAL_Exported_Variables HAL Exported Variables
-  * @{
-  */
-__IO uint32_t uwTick;
-uint32_t uwTickPrio = (1UL << __NVIC_PRIO_BITS); /* Invalid PRIO */
-HAL_TickFreqTypeDef uwTickFreq = HAL_TICK_FREQ_DEFAULT;  /* 1KHz */
-/**
-  * @}
-  */
-
-/* Private function prototypes -----------------------------------------------*/
-/* Exported functions --------------------------------------------------------*/
-
-/** @addtogroup HAL_Exported_Functions
-  * @{
-  */
-
-/** @addtogroup HAL_Exported_Functions_Group1
-  *  @brief    HAL Initialization and Configuration functions
-  *
-@verbatim
- ===============================================================================
-           ##### HAL Initialization and Configuration functions #####
- ===============================================================================
-    [..]  This section provides functions allowing to:
-      (+) Initialize the Flash interface the NVIC allocation and initial time base
-          clock configuration.
-      (+) De-initialize common part of the HAL.
-      (+) Configure the time base source to have 1ms time base with a dedicated
-          Tick interrupt priority.
-        (++) SysTick timer is used by default as source of time base, but user
-             can eventually implement his proper time base source (a general purpose
-             timer for example or other time source), keeping in mind that Time base
-             duration should be kept 1ms since PPP_TIMEOUT_VALUEs are defined and
-             handled in milliseconds basis.
-        (++) Time base configuration function (HAL_InitTick ()) is called automatically
-             at the beginning of the program after reset by HAL_Init() or at any time
-             when clock is configured, by HAL_RCC_ClockConfig().
-        (++) Source of time base is configured  to generate interrupts at regular
-             time intervals. Care must be taken if HAL_Delay() is called from a
-             peripheral ISR process, the Tick interrupt line must have higher priority
-            (numerically lower) than the peripheral interrupt. Otherwise the caller
-            ISR process will be blocked.
-       (++) functions affecting time base configurations are declared as __weak
-             to make  override possible  in case of other  implementations in user file.
-@endverbatim
-  * @{
-  */
-
-/**
-  * @brief  This function is used to initialize the HAL Library; it must be the first
-  *         instruction to be executed in the main program (before to call any other
-  *         HAL function), it performs the following:
-  *           Configure the Flash prefetch, instruction and Data caches.
-  *           Configures the SysTick to generate an interrupt each 1 millisecond,
-  *           which is clocked by the MSI (at this stage, the clock is not yet
-  *           configured and thus the system is running from the internal MSI at 4 MHz).
-  *           Set NVIC Group Priority to 4.
-  *           Calls the HAL_MspInit() callback function defined in user file
-  *           "stm32wbxx_hal_msp.c" to do the global low level hardware initialization
-  *
-  * @note   SysTick is used as time base for the HAL_Delay() function, the application
-  *         need to ensure that the SysTick time base is always set to 1 millisecond
-  *         to have correct HAL operation.
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_Init(void)
-{
-  HAL_StatusTypeDef  status = HAL_OK;
-  /* Configure Flash prefetch, Instruction cache, Data cache */
-  /* Default configuration at reset is:                      */
-  /* - Prefetch disabled                                     */
-  /* - Instruction cache enabled                             */
-  /* - Data cache enabled                                    */
-#if (INSTRUCTION_CACHE_ENABLE == 0U)
-  __HAL_FLASH_INSTRUCTION_CACHE_DISABLE();
-#endif /* INSTRUCTION_CACHE_ENABLE */
-
-#if (DATA_CACHE_ENABLE == 0U)
-  __HAL_FLASH_DATA_CACHE_DISABLE();
-#endif /* DATA_CACHE_ENABLE */
-
-#if (PREFETCH_ENABLE != 0U)
-  __HAL_FLASH_PREFETCH_BUFFER_ENABLE();
-#endif /* PREFETCH_ENABLE */
-
-  /* Set Interrupt Group Priority */
-  HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);
-
-  /* Use SysTick as time base source and configure 1ms tick (default clock after Reset is MSI) */
-  if (HAL_InitTick(TICK_INT_PRIORITY) != HAL_OK)
-  {
-    status = HAL_ERROR;
-  }
-  else
-  {
-    /* Init the low level hardware */
-    HAL_MspInit();
-  }
-
-  /* Return function status */
-  return status;
-}
-
-/**
-  * @brief  This function de-Initializes common part of the HAL and stops the source of time base.
-  * @note   This function is optional.
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_DeInit(void)
-{
-  /* Reset of all peripherals */
-  __HAL_RCC_APB1_FORCE_RESET();
-  __HAL_RCC_APB1_RELEASE_RESET();
-
-  __HAL_RCC_APB2_FORCE_RESET();
-  __HAL_RCC_APB2_RELEASE_RESET();
-
-  __HAL_RCC_APB3_FORCE_RESET();
-  __HAL_RCC_APB3_RELEASE_RESET();
-
-  __HAL_RCC_AHB1_FORCE_RESET();
-  __HAL_RCC_AHB1_RELEASE_RESET();
-
-  __HAL_RCC_AHB2_FORCE_RESET();
-  __HAL_RCC_AHB2_RELEASE_RESET();
-
-  __HAL_RCC_AHB3_FORCE_RESET();
-  __HAL_RCC_AHB3_RELEASE_RESET();
-
-  /* De-Init the low level hardware */
-  HAL_MspDeInit();
-
-  /* Return function status */
-  return HAL_OK;
-}
-
-/**
-  * @brief  Initialize the MSP.
-  * @retval None
-  */
-__weak void HAL_MspInit(void)
-{
-  /* NOTE : This function should not be modified, when the callback is needed,
-            the HAL_MspInit could be implemented in the user file
-   */
-}
-
-/**
-  * @brief  DeInitializes the MSP.
-  * @retval None
-  */
-__weak void HAL_MspDeInit(void)
-{
-  /* NOTE : This function should not be modified, when the callback is needed,
-            the HAL_MspDeInit could be implemented in the user file
-   */
-}
-
-/**
-  * @brief This function configures the source of the time base:
-  *        The time source is configured  to have 1ms time base with a dedicated
-  *        Tick interrupt priority.
-  * @note This function is called  automatically at the beginning of program after
-  *       reset by HAL_Init() or at any time when clock is reconfigured  by HAL_RCC_ClockConfig().
-  * @note In the default implementation, SysTick timer is the source of time base.
-  *       It is used to generate interrupts at regular time intervals.
-  *       Care must be taken if HAL_Delay() is called from a peripheral ISR process,
-  *       The SysTick interrupt must have higher priority (numerically lower)
-  *       than the peripheral interrupt. Otherwise the caller ISR process will be blocked.
-  *       The function is declared as __weak  to be overwritten  in case of other
-  *       implementation  in user file.
-  * @param TickPriority Tick interrupt priority.
-  * @retval HAL status
-  */
-__weak HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority)
-{
-  HAL_StatusTypeDef  status = HAL_OK;
-
-  if ((uint32_t)uwTickFreq != 0U)
-  {
-    /*Configure the SysTick to have interrupt in 1ms time basis*/
-    if (HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq() / (1000U / (uint32_t)uwTickFreq)) == 0U)
-    {
-      /* Configure the SysTick IRQ priority */
-      if (TickPriority < (1UL << __NVIC_PRIO_BITS))
-      {
-        HAL_NVIC_SetPriority(SysTick_IRQn, TickPriority, 0U);
-        uwTickPrio = TickPriority;
-      }
-      else
-      {
-        status = HAL_ERROR;
-      }
-    }
-    else
-    {
-      status = HAL_ERROR;
-    }
-  }
-  else
-  {
-    status = HAL_ERROR;
-  }
-
-  /* Return function status */
-  return status;
-}
-
-/**
-  * @}
-  */
-
-/** @addtogroup HAL_Exported_Functions_Group2
-  *  @brief    HAL Control functions
-  *
-@verbatim
- ===============================================================================
-                      ##### HAL Control functions #####
- ===============================================================================
-    [..]  This section provides functions allowing to:
-      (+) Provide a tick value in millisecond
-      (+) Provide a blocking delay in millisecond
-      (+) Suspend the time base source interrupt
-      (+) Resume the time base source interrupt
-      (+) Get the HAL API driver version
-      (+) Get the device revision identifier
-      (+) Get the device identifier
-      (+) Get the unique device identifier
-
-@endverbatim
-  * @{
-  */
-
-/**
-  * @brief This function is called to increment  a global variable "uwTick"
-  *        used as application time base.
-  * @note In the default implementation, this variable is incremented each 1ms
-  *       in SysTick ISR.
-  * @note This function is declared as __weak to be overwritten in case of other
-  *      implementations in user file.
-  * @retval None
-  */
-__weak void HAL_IncTick(void)
-{
-  uwTick += (uint32_t)uwTickFreq;
-}
-
-/**
-  * @brief Provides a tick value in millisecond.
-  * @note This function is declared as __weak to be overwritten in case of other
-  *       implementations in user file.
-  * @retval tick value
-  */
-__weak uint32_t HAL_GetTick(void)
-{
-  return uwTick;
-}
-
-/**
-  * @brief This function returns a tick priority.
-  * @retval tick priority
-  */
-uint32_t HAL_GetTickPrio(void)
-{
-  return uwTickPrio;
-}
-
-/**
-  * @brief Set new tick Freq.
-  * @retval Status
-  */
-HAL_StatusTypeDef HAL_SetTickFreq(HAL_TickFreqTypeDef Freq)
-{
-  HAL_StatusTypeDef status  = HAL_OK;
-  HAL_TickFreqTypeDef prevTickFreq;
-
-  assert_param(IS_TICKFREQ(Freq));
-
-  if (uwTickFreq != Freq)
-  {
-    /* Back up uwTickFreq frequency */
-    prevTickFreq = uwTickFreq;
-
-    /* Update uwTickFreq global variable used by HAL_InitTick() */
-    uwTickFreq = Freq;
-
-    /* Apply the new tick Freq  */
-    status = HAL_InitTick(uwTickPrio);
-
-    if (status != HAL_OK)
-    {
-      /* Restore previous tick frequency */
-      uwTickFreq = prevTickFreq;
-    }
-  }
-
-  return status;
-}
-
-/**
-  * @brief Return tick frequency.
-  * @retval tick period in Hz
-  */
-HAL_TickFreqTypeDef HAL_GetTickFreq(void)
-{
-  return uwTickFreq;
-}
-
-/**
-  * @brief This function provides minimum delay (in milliseconds) based
-  *        on variable incremented.
-  * @note In the default implementation , SysTick timer is the source of time base.
-  *       It is used to generate interrupts at regular time intervals where uwTick
-  *       is incremented.
-  * @note This function is declared as __weak to be overwritten in case of other
-  *       implementations in user file.
-  * @param Delay  specifies the delay time length, in milliseconds.
-  * @retval None
-  */
-__weak void HAL_Delay(uint32_t Delay)
-{
-  uint32_t tickstart = HAL_GetTick();
-  uint32_t wait = Delay;
-
-  /* Add a freq to guarantee minimum wait */
-  if (wait < HAL_MAX_DELAY)
-  {
-    wait += (uint32_t)(uwTickFreq);
-  }
-
-  while ((HAL_GetTick() - tickstart) < wait)
-  {
-  }
-}
-
-
-/**
-  * @brief Suspend Tick increment.
-  * @note In the default implementation , SysTick timer is the source of time base. It is
-  *       used to generate interrupts at regular time intervals. Once HAL_SuspendTick()
-  *       is called, the SysTick interrupt will be disabled and so Tick increment
-  *       is suspended.
-  * @note This function is declared as __weak to be overwritten in case of other
-  *       implementations in user file.
-  * @retval None
-  */
-__weak void HAL_SuspendTick(void)
-{
-  /* Disable SysTick Interrupt */
-  CLEAR_BIT(SysTick->CTRL, SysTick_CTRL_TICKINT_Msk);
-}
-
-/**
-  * @brief Resume Tick increment.
-  * @note In the default implementation , SysTick timer is the source of time base. It is
-  *       used to generate interrupts at regular time intervals. Once HAL_ResumeTick()
-  *       is called, the SysTick interrupt will be enabled and so Tick increment
-  *       is resumed.
-  * @note This function is declared as __weak to be overwritten in case of other
-  *       implementations in user file.
-  * @retval None
-  */
-__weak void HAL_ResumeTick(void)
-{
-  /* Enable SysTick Interrupt */
-  SET_BIT(SysTick->CTRL, SysTick_CTRL_TICKINT_Msk);
-}
-
-/**
-  * @brief  Returns the HAL revision
-  * @retval version : 0xXYZR (8bits for each decimal, R for RC)
-  */
-uint32_t HAL_GetHalVersion(void)
-{
-  return __STM32WBxx_HAL_VERSION;
-}
-
-/**
-  * @brief  Returns the device revision identifier.
-  * @retval Device revision identifier
-  */
-uint32_t HAL_GetREVID(void)
-{
-  return (LL_DBGMCU_GetRevisionID());
-}
-
-/**
-  * @brief  Returns the device identifier.
-  * @retval Device identifier
-  */
-uint32_t HAL_GetDEVID(void)
-{
-  return (LL_DBGMCU_GetDeviceID());
-}
-
-/**
-  * @brief  Return the first word of the unique device identifier (UID based on 96 bits)
-  * @retval Device identifier
-  */
-uint32_t HAL_GetUIDw0(void)
-{
-  return (READ_REG(*((uint32_t *)UID_BASE)));
-}
-
-/**
-  * @brief  Return the second word of the unique device identifier (UID based on 96 bits)
-  * @retval Device identifier
-  */
-uint32_t HAL_GetUIDw1(void)
-{
-  return (READ_REG(*((uint32_t *)(UID_BASE + 4U))));
-}
-
-/**
-  * @brief  Return the third word of the unique device identifier (UID based on 96 bits)
-  * @retval Device identifier
-  */
-uint32_t HAL_GetUIDw2(void)
-{
-  return (READ_REG(*((uint32_t *)(UID_BASE + 8U))));
-}
-
-/**
-  * @}
-  */
-
-/** @addtogroup HAL_Exported_Functions_Group3
-  *  @brief    HAL Debug functions
-  *
-@verbatim
- ===============================================================================
-                      ##### HAL Debug functions #####
- ===============================================================================
-    [..]  This section provides functions allowing to:
-      (+) Enable/Disable Debug module during SLEEP mode
-      (+) Enable/Disable Debug module during STOP mode
-      (+) Enable/Disable Debug module during STANDBY mode
-
-@endverbatim
-  * @{
-  */
-
-/**
-  * @brief  Enable the Debug Module during SLEEP mode
-  * @retval None
-  */
-void HAL_DBGMCU_EnableDBGSleepMode(void)
-{
-  LL_DBGMCU_EnableDBGSleepMode();
-}
-
-/**
-  * @brief  Disable the Debug Module during SLEEP mode
-  * @retval None
-  */
-void HAL_DBGMCU_DisableDBGSleepMode(void)
-{
-  LL_DBGMCU_DisableDBGSleepMode();
-}
-
-/**
-  * @brief  Enable the Debug Module during STOP mode
-  * @retval None
-  */
-void HAL_DBGMCU_EnableDBGStopMode(void)
-{
-  LL_DBGMCU_EnableDBGStopMode();
-}
-
-/**
-  * @brief  Disable the Debug Module during STOP mode
-  * @retval None
-  */
-void HAL_DBGMCU_DisableDBGStopMode(void)
-{
-  LL_DBGMCU_DisableDBGStopMode();
-}
-
-/**
-  * @brief  Enable the Debug Module during STANDBY mode
-  * @retval None
-  */
-void HAL_DBGMCU_EnableDBGStandbyMode(void)
-{
-  LL_DBGMCU_EnableDBGStandbyMode();
-}
-
-/**
-  * @brief  Disable the Debug Module during STANDBY mode
-  * @retval None
-  */
-void HAL_DBGMCU_DisableDBGStandbyMode(void)
-{
-  LL_DBGMCU_DisableDBGStandbyMode();
-}
-
-/**
-  * @}
-  */
-
-/** @defgroup HAL_Exported_Functions_Group4 HAL System Configuration functions
-  *  @brief    HAL System Configuration functions
-  *
-@verbatim
- ===============================================================================
-                 ##### HAL system configuration functions #####
- ===============================================================================
-    [..]  This section provides functions allowing to:
-      (+) Start a hardware SRAM2 erase operation
-      (+) Disable CPU2 SRAM fetch (execution)
-      (+) Configure the Voltage reference buffer
-      (+) Enable/Disable the Voltage reference buffer
-      (+) Enable/Disable the I/O analog switch voltage booster
-      (+) Enable/Disable the access for security IP (AES1, AES2, PKA, RNG)
-      (+) Enable/Disable the access for security IP (AES2, PKA, RNG)
-
-@endverbatim
-  * @{
-  */
-
-/**
-  * @brief  Start a hardware SRAM2 erase operation.
-  * @note   As long as SRAM2 is not erased the SRAM2ER bit will be set.
-  *         This bit is automatically reset at the end of the SRAM2 erase operation.
-  * @retval None
-  */
-void HAL_SYSCFG_SRAM2Erase(void)
-{
-  /* unlock the write protection of the SRAM2ER bit */
-  __HAL_SYSCFG_SRAM2_WRP_UNLOCK();
-  /* Starts a hardware SRAM2 erase operation*/
-  __HAL_SYSCFG_SRAM2_ERASE();
-}
-
-/**
-  * @brief  Disable CPU2 SRAM fetch (execution) (This bit can be set by Firmware
-  *         and will only be reset by a Hardware reset, including a reset after Standby.)
-  * @note Firmware writing 0 has no effect.
-  * @retval None
-  */
-void HAL_SYSCFG_DisableSRAMFetch(void)
-{
-  LL_SYSCFG_DisableSRAMFetch();
-}
-
-/**
-  * @brief  Check if CPU2 SRAM fetch is enabled
-  * @retval State of bit (1 or 0).
-  */
-uint32_t HAL_SYSCFG_IsEnabledSRAMFetch(void)
-{
-  return (LL_SYSCFG_IsEnabledSRAMFetch());
-}
-
-#if defined(VREFBUF)
-/**
-  * @brief Configure the internal voltage reference buffer voltage scale.
-  * @param VoltageScaling  specifies the output voltage to achieve
-  *          This parameter can be one of the following values:
-  *            @arg @ref SYSCFG_VREFBUF_VOLTAGE_SCALE0 : VREF_OUT1 around 2.048 V.
-  *                                                This requires VDDA equal to or higher than 2.4 V.
-  *            @arg @ref SYSCFG_VREFBUF_VOLTAGE_SCALE1 : VREF_OUT1 around 2.5 V.
-  *                                                This requires VDDA equal to or higher than 2.8 V.
-  * @note   Retrieve the TrimmingValue from factory located at
-  *         VREFBUF_SC0_CAL_ADDR or VREFBUF_SC1_CAL_ADDR addresses.
-  * @retval None
-  */
-void HAL_SYSCFG_VREFBUF_VoltageScalingConfig(uint32_t VoltageScaling)
-{
-  uint32_t TrimmingValue;
-
-  /* Check the parameters */
-  assert_param(IS_SYSCFG_VREFBUF_VOLTAGE_SCALE(VoltageScaling));
-
-  LL_VREFBUF_SetVoltageScaling(VoltageScaling);
-
-  /* Restrieve Calibration data and store them into trimming field */
-  if (VoltageScaling == SYSCFG_VREFBUF_VOLTAGE_SCALE0)
-  {
-    TrimmingValue = ((uint32_t) * VREFBUF_SC0_CAL_ADDR) & 0x3FU;
-  }
-  else
-  {
-    TrimmingValue = ((uint32_t) * VREFBUF_SC1_CAL_ADDR) & 0x3FU;
-  }
-  assert_param(IS_SYSCFG_VREFBUF_TRIMMING(TrimmingValue));
-
-  HAL_SYSCFG_VREFBUF_TrimmingConfig(TrimmingValue);
-}
-
-/**
-  * @brief Configure the internal voltage reference buffer high impedance mode.
-  * @param Mode  specifies the high impedance mode
-  *          This parameter can be one of the following values:
-  *            @arg @ref SYSCFG_VREFBUF_HIGH_IMPEDANCE_DISABLE : VREF+ pin is internally connect to VREFINT output.
-  *            @arg @ref SYSCFG_VREFBUF_HIGH_IMPEDANCE_ENABLE : VREF+ pin is high impedance.
-  * @retval HAL_OK/HAL_TIMEOUT
-  */
-void HAL_SYSCFG_VREFBUF_HighImpedanceConfig(uint32_t Mode)
-{
-
-  /* Check the parameters */
-  assert_param(IS_SYSCFG_VREFBUF_HIGH_IMPEDANCE(Mode));
-
-  MODIFY_REG(VREFBUF->CSR, VREFBUF_CSR_HIZ, Mode);
-}
-
-/**
-  * @brief Tune the Internal Voltage Reference buffer (VREFBUF).
-  * @note  Each VrefBuf voltage scale is calibrated in production for each device,
-  *        data stored in flash memory.
-  *        Function @ref HAL_SYSCFG_VREFBUF_VoltageScalingConfig retrieves and
-  *        applies this calibration data as trimming value at each scale change.
-  *        Therefore, optionally, function @ref HAL_SYSCFG_VREFBUF_TrimmingConfig
-  *        can be used in a second time to fine tune the trimming.
-  * @param TrimmingValue specifies trimming code for VREFBUF calibration
-  *          This parameter can be a number between Min_Data = 0x00 and Max_Data = 0x3F
-  * @retval None
-  */
-void HAL_SYSCFG_VREFBUF_TrimmingConfig(uint32_t TrimmingValue)
-{
-  /* Check the parameters */
-  assert_param(IS_SYSCFG_VREFBUF_TRIMMING(TrimmingValue));
-
-  LL_VREFBUF_SetTrimming(TrimmingValue);
-
-}
-
-/**
-  * @brief  Enable the Internal Voltage Reference buffer (VREFBUF).
-  * @retval HAL_OK/HAL_TIMEOUT
-  */
-HAL_StatusTypeDef HAL_SYSCFG_EnableVREFBUF(void)
-{
-  uint32_t tickstart;
-
-  LL_VREFBUF_Enable();
-
-  /* Get Start Tick*/
-  tickstart = HAL_GetTick();
-
-  /* Wait for VRR bit  */
-  while (READ_BIT(VREFBUF->CSR, VREFBUF_CSR_VRR) == 0U)
-  {
-    if ((HAL_GetTick() - tickstart) > VREFBUF_TIMEOUT_VALUE)
-    {
-      return HAL_TIMEOUT;
-    }
-  }
-
-  return HAL_OK;
-}
-
-/**
-  * @brief  Disable the Internal Voltage Reference buffer (VREFBUF).
-  *
-  * @retval None
-  */
-void HAL_SYSCFG_DisableVREFBUF(void)
-{
-  LL_VREFBUF_Disable();
-}
-#endif /* VREFBUF */
-
-/**
-  * @brief  Enable the I/O analog switch voltage booster
-  *
-  * @retval None
-  */
-void HAL_SYSCFG_EnableIOBooster(void)
-{
-  LL_SYSCFG_EnableAnalogBooster();
-}
-
-/**
-  * @brief  Disable the I/O analog switch voltage booster
-  *
-  * @retval None
-  */
-void HAL_SYSCFG_DisableIOBooster(void)
-{
-  LL_SYSCFG_DisableAnalogBooster();
-}
-
-#if defined(SYSCFG_CFGR1_ANASWVDD)
-/**
-  * @brief  Enable the I/O analog switch supplied by VDD
-  * @note   To be used when I/O analog switch voltage booster is not enabled
-  * @retval None
-  */
-void HAL_SYSCFG_EnableIOVdd(void)
-{
-  LL_SYSCFG_EnableAnalogGpioSwitch();
-}
-
-/**
-  * @brief  Disable the I/O analog switch supplied by VDD
-  *
-  * @retval None
-  */
-void HAL_SYSCFG_DisableIOVdd(void)
-{
-  LL_SYSCFG_DisableAnalogGpioSwitch();
-}
-#endif /* SYSCFG_CFGR1_ANASWVDD */
-
-/**
-  * @brief  Enable the access for security IP
-  * @note   When the system is secure (ESE = 1), this register provides write access security and can
-  *         only be written by the CPU2. A write access from the CPU1 will be ignored and a bus error
-  *         is generated.
-  * @param  SecurityAccess This parameter can be a combination of the following values:
-  *         @arg @ref HAL_SYSCFG_SECURE_ACCESS_AES1
-  *         @arg @ref HAL_SYSCFG_SECURE_ACCESS_AES2
-  *         @arg @ref HAL_SYSCFG_SECURE_ACCESS_PKA
-  *         @arg @ref HAL_SYSCFG_SECURE_ACCESS_RNG
-  * @retval None
-  */
-void HAL_SYSCFG_EnableSecurityAccess(uint32_t SecurityAccess)
-{
-  /* Check the parameters */
-  assert_param(IS_SYSCFG_SECURITY_ACCESS(SecurityAccess));
-
-  LL_SYSCFG_EnableSecurityAccess(SecurityAccess);
-}
-
-/**
-  * @brief  Disable the access for security IP
-  * @note   When the system is secure (ESE = 1), this register provides write access security and can
-  *         only be written by the CPU2. A write access from the CPU1 will be ignored and a bus error
-  *         is generated.
-  * @param  SecurityAccess This parameter can be a combination of the following values:
-  *         @arg @ref HAL_SYSCFG_SECURE_ACCESS_AES1
-  *         @arg @ref HAL_SYSCFG_SECURE_ACCESS_AES2
-  *         @arg @ref HAL_SYSCFG_SECURE_ACCESS_PKA
-  *         @arg @ref HAL_SYSCFG_SECURE_ACCESS_RNG
-  * @retval None
-  */
-void HAL_SYSCFG_DisableSecurityAccess(uint32_t SecurityAccess)
-{
-  /* Check the parameters */
-  assert_param(IS_SYSCFG_SECURITY_ACCESS(SecurityAccess));
-
-  LL_SYSCFG_DisableSecurityAccess(SecurityAccess);
-}
-
-/**
-  * @brief  Indicate if access for security IP is enabled
-  * @param  SecurityAccess This parameter can be one of the following values:
-  *         @arg @ref HAL_SYSCFG_SECURE_ACCESS_AES1
-  *         @arg @ref HAL_SYSCFG_SECURE_ACCESS_AES2
-  *         @arg @ref HAL_SYSCFG_SECURE_ACCESS_PKA
-  *         @arg @ref HAL_SYSCFG_SECURE_ACCESS_RNG
-  * @retval State of bit (1 or 0).
-  */
-uint32_t HAL_SYSCFG_IsEnabledSecurityAccess(uint32_t SecurityAccess)
-{
-  return (LL_SYSCFG_IsEnabledSecurityAccess(SecurityAccess));
-}
-/**
-  * @}
-  */
-
-/**
-  * @}
-  */
-
-#endif /* HAL_MODULE_ENABLED */
-/**
-  * @}
-  */
-
-/**
-  * @}
-  */

+ 0 - 3973
non_catalog_apps/flipperscope/lib/adc/stm32wbxx_hal_adc.c

@@ -1,3973 +0,0 @@
-/**
-  ******************************************************************************
-  * @file    stm32wbxx_hal_adc.c
-  * @author  MCD Application Team
-  * @brief   This file provides firmware functions to manage the following
-  *          functionalities of the Analog to Digital Converter (ADC)
-  *          peripheral:
-  *           + Initialization and de-initialization functions
-  *             ++ Initialization and Configuration of ADC
-  *           + Operation functions
-  *             ++ Start, stop, get result of conversions of regular
-  *                group, using 3 possible modes: polling, interruption or DMA.
-  *           + Control functions
-  *             ++ Channels configuration on regular group
-  *             ++ Analog Watchdog configuration
-  *           + State functions
-  *             ++ ADC state machine management
-  *             ++ Interrupts and flags management
-  *          Other functions (extended functions) are available in file
-  *          "stm32wbxx_hal_adc_ex.c".
-  ******************************************************************************
-  * @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
-  ==============================================================================
-                     ##### ADC peripheral features #####
-  ==============================================================================
-  [..]
-  (+) 12-bit, 10-bit, 8-bit or 6-bit configurable resolution.
-
-  (+) Interrupt generation at the end of regular conversion and in case of
-      analog watchdog or overrun events.
-
-  (+) Single and continuous conversion modes.
-
-  (+) Scan mode for conversion of several channels sequentially.
-
-  (+) Data alignment with in-built data coherency.
-
-  (+) Programmable sampling time (channel wise)
-
-  (+) External trigger (timer or EXTI) with configurable polarity
-
-  (+) DMA request generation for transfer of conversions data of regular group.
-
-  (+) ADC channels selectable single/differential input.
-
-  (+) ADC offset shared on 4 offset instances.
-  (+) ADC calibration
-
-  (+) ADC conversion of regular group.
-
-  (+) ADC supply requirements: 1.62 V to 3.6 V.
-
-  (+) ADC input range: from Vref- (connected to Vssa) to Vref+ (connected to
-      Vdda or to an external voltage reference).
-
-
-                     ##### How to use this driver #####
-  ==============================================================================
-    [..]
-
-     *** Configuration of top level parameters related to ADC ***
-     ============================================================
-     [..]
-
-    (#) Enable the ADC interface
-        (++) As prerequisite, ADC clock must be configured at RCC top level.
-
-        (++) Two clock settings are mandatory:
-             (+++) ADC clock (core clock, also possibly conversion clock).
-
-             (+++) ADC clock (conversions clock).
-                   Two possible clock sources: synchronous clock derived from AHB2 clock
-                   or asynchronous clock derived from system clock, PLLSAI1 (output divider R) or the PLL system (output divider P)
-                   running up to 64MHz.
-
-             (+++) Example:
-                   Into HAL_ADC_MspInit() (recommended code location) or with
-                   other device clock parameters configuration:
-               (+++) __HAL_RCC_ADC_CLK_ENABLE();                  (mandatory)
-
-               RCC_ADCCLKSOURCE_PLL enable:                       (optional: if asynchronous clock selected)
-               (+++) RCC_PeriphClkInitTypeDef   RCC_PeriphClkInit;
-               (+++) PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC;
-               (+++) PeriphClkInit.AdcClockSelection    = RCC_ADCCLKSOURCE_PLL;
-               (+++) HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit);
-
-        (++) ADC clock source and clock prescaler are configured at ADC level with
-             parameter "ClockPrescaler" using function HAL_ADC_Init().
-
-    (#) ADC pins configuration
-         (++) Enable the clock for the ADC GPIOs
-              using macro __HAL_RCC_GPIOx_CLK_ENABLE()
-         (++) Configure these ADC pins in analog mode
-              using function HAL_GPIO_Init()
-
-    (#) Optionally, in case of usage of ADC with interruptions:
-         (++) Configure the NVIC for ADC
-              using function HAL_NVIC_EnableIRQ(ADCx_IRQn)
-         (++) Insert the ADC interruption handler function HAL_ADC_IRQHandler()
-              into the function of corresponding ADC interruption vector
-              ADCx_IRQHandler().
-
-    (#) Optionally, in case of usage of DMA:
-         (++) Configure the DMA (DMA channel, mode normal or circular, ...)
-              using function HAL_DMA_Init().
-         (++) Configure the NVIC for DMA
-              using function HAL_NVIC_EnableIRQ(DMAx_Channelx_IRQn)
-         (++) Insert the ADC interruption handler function HAL_ADC_IRQHandler()
-              into the function of corresponding DMA interruption vector
-              DMAx_Channelx_IRQHandler().
-
-     *** Configuration of ADC, group regular, channels parameters ***
-     ================================================================
-     [..]
-
-    (#) Configure the ADC parameters (resolution, data alignment, ...)
-        and regular group parameters (conversion trigger, sequencer, ...)
-        using function HAL_ADC_Init().
-
-    (#) Configure the channels for regular group parameters (channel number,
-        channel rank into sequencer, ..., into regular group)
-        using function HAL_ADC_ConfigChannel().
-
-    (#) Optionally, configure the analog watchdog parameters (channels
-        monitored, thresholds, ...)
-        using function HAL_ADC_AnalogWDGConfig().
-
-     *** Execution of ADC conversions ***
-     ====================================
-     [..]
-
-    (#) Optionally, perform an automatic ADC calibration to improve the
-        conversion accuracy
-        using function HAL_ADCEx_Calibration_Start().
-
-    (#) ADC driver can be used among three modes: polling, interruption,
-        transfer by DMA.
-
-        (++) ADC conversion by polling:
-          (+++) Activate the ADC peripheral and start conversions
-                using function HAL_ADC_Start()
-          (+++) Wait for ADC conversion completion
-                using function HAL_ADC_PollForConversion()
-          (+++) Retrieve conversion results
-                using function HAL_ADC_GetValue()
-          (+++) Stop conversion and disable the ADC peripheral
-                using function HAL_ADC_Stop()
-
-        (++) ADC conversion by interruption:
-          (+++) Activate the ADC peripheral and start conversions
-                using function HAL_ADC_Start_IT()
-          (+++) Wait for ADC conversion completion by call of function
-                HAL_ADC_ConvCpltCallback()
-                (this function must be implemented in user program)
-          (+++) Retrieve conversion results
-                using function HAL_ADC_GetValue()
-          (+++) Stop conversion and disable the ADC peripheral
-                using function HAL_ADC_Stop_IT()
-
-        (++) ADC conversion with transfer by DMA:
-          (+++) Activate the ADC peripheral and start conversions
-                using function HAL_ADC_Start_DMA()
-          (+++) Wait for ADC conversion completion by call of function
-                HAL_ADC_ConvCpltCallback() or HAL_ADC_ConvHalfCpltCallback()
-                (these functions must be implemented in user program)
-          (+++) Conversion results are automatically transferred by DMA into
-                destination variable address.
-          (+++) Stop conversion and disable the ADC peripheral
-                using function HAL_ADC_Stop_DMA()
-
-     [..]
-
-    (@) Callback functions must be implemented in user program:
-      (+@) HAL_ADC_ErrorCallback()
-      (+@) HAL_ADC_LevelOutOfWindowCallback() (callback of analog watchdog)
-      (+@) HAL_ADC_ConvCpltCallback()
-      (+@) HAL_ADC_ConvHalfCpltCallback
-
-     *** Deinitialization of ADC ***
-     ============================================================
-     [..]
-
-    (#) Disable the ADC interface
-      (++) ADC clock can be hard reset and disabled at RCC top level.
-        (++) Hard reset of ADC peripherals
-             using macro __ADCx_FORCE_RESET(), __ADCx_RELEASE_RESET().
-        (++) ADC clock disable
-             using the equivalent macro/functions as configuration step.
-             (+++) Example:
-                   Into HAL_ADC_MspDeInit() (recommended code location) or with
-                   other device clock parameters configuration:
-               (+++) RCC_OscInitStructure.OscillatorType = RCC_OSCILLATORTYPE_HSI14;
-               (+++) RCC_OscInitStructure.HSI14State = RCC_HSI14_OFF; (if not used for system clock)
-               (+++) HAL_RCC_OscConfig(&RCC_OscInitStructure);
-
-    (#) ADC pins configuration
-         (++) Disable the clock for the ADC GPIOs
-              using macro __HAL_RCC_GPIOx_CLK_DISABLE()
-
-    (#) Optionally, in case of usage of ADC with interruptions:
-         (++) Disable the NVIC for ADC
-              using function HAL_NVIC_EnableIRQ(ADCx_IRQn)
-
-    (#) Optionally, in case of usage of DMA:
-         (++) Deinitialize the DMA
-              using function HAL_DMA_Init().
-         (++) Disable the NVIC for DMA
-              using function HAL_NVIC_EnableIRQ(DMAx_Channelx_IRQn)
-
-    [..]
-
-    *** Callback registration ***
-    =============================================
-    [..]
-
-     The compilation flag USE_HAL_ADC_REGISTER_CALLBACKS, when set to 1,
-     allows the user to configure dynamically the driver callbacks.
-     Use Functions HAL_ADC_RegisterCallback()
-     to register an interrupt callback.
-    [..]
-
-     Function HAL_ADC_RegisterCallback() allows to register following callbacks:
-       (+) ConvCpltCallback               : ADC conversion complete callback
-       (+) ConvHalfCpltCallback           : ADC conversion DMA half-transfer callback
-       (+) LevelOutOfWindowCallback       : ADC analog watchdog 1 callback
-       (+) ErrorCallback                  : ADC error callback
-       (+) InjectedConvCpltCallback       : ADC group injected conversion complete callback
-       (+) InjectedQueueOverflowCallback  : ADC group injected context queue overflow callback
-       (+) LevelOutOfWindow2Callback      : ADC analog watchdog 2 callback
-       (+) LevelOutOfWindow3Callback      : ADC analog watchdog 3 callback
-       (+) EndOfSamplingCallback          : ADC end of sampling callback
-       (+) MspInitCallback                : ADC Msp Init callback
-       (+) MspDeInitCallback              : ADC Msp DeInit callback
-     This function takes as parameters the HAL peripheral handle, the Callback ID
-     and a pointer to the user callback function.
-    [..]
-
-     Use function HAL_ADC_UnRegisterCallback to reset a callback to the default
-     weak function.
-    [..]
-
-     HAL_ADC_UnRegisterCallback takes as parameters the HAL peripheral handle,
-     and the Callback ID.
-     This function allows to reset following callbacks:
-       (+) ConvCpltCallback               : ADC conversion complete callback
-       (+) ConvHalfCpltCallback           : ADC conversion DMA half-transfer callback
-       (+) LevelOutOfWindowCallback       : ADC analog watchdog 1 callback
-       (+) ErrorCallback                  : ADC error callback
-       (+) InjectedConvCpltCallback       : ADC group injected conversion complete callback
-       (+) InjectedQueueOverflowCallback  : ADC group injected context queue overflow callback
-       (+) LevelOutOfWindow2Callback      : ADC analog watchdog 2 callback
-       (+) LevelOutOfWindow3Callback      : ADC analog watchdog 3 callback
-       (+) EndOfSamplingCallback          : ADC end of sampling callback
-       (+) MspInitCallback                : ADC Msp Init callback
-       (+) MspDeInitCallback              : ADC Msp DeInit callback
-     [..]
-
-     By default, after the HAL_ADC_Init() and when the state is HAL_ADC_STATE_RESET
-     all callbacks are set to the corresponding weak functions:
-     examples HAL_ADC_ConvCpltCallback(), HAL_ADC_ErrorCallback().
-     Exception done for MspInit and MspDeInit functions that are
-     reset to the legacy weak functions in the HAL_ADC_Init()/ HAL_ADC_DeInit() only when
-     these callbacks are null (not registered beforehand).
-    [..]
-
-     If MspInit or MspDeInit are not null, the HAL_ADC_Init()/ HAL_ADC_DeInit()
-     keep and use the user MspInit/MspDeInit callbacks (registered beforehand) whatever the state.
-     [..]
-
-     Callbacks can be registered/unregistered in HAL_ADC_STATE_READY state only.
-     Exception done MspInit/MspDeInit functions that can be registered/unregistered
-     in HAL_ADC_STATE_READY or HAL_ADC_STATE_RESET state,
-     thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit.
-    [..]
-
-     Then, the user first registers the MspInit/MspDeInit user callbacks
-     using HAL_ADC_RegisterCallback() before calling HAL_ADC_DeInit()
-     or HAL_ADC_Init() function.
-     [..]
-
-     When the compilation flag USE_HAL_ADC_REGISTER_CALLBACKS is set to 0 or
-     not defined, the callback registration feature is not available and all callbacks
-     are set to the corresponding weak functions.
-
-  @endverbatim
-  ******************************************************************************
-  */
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32wbxx_hal.h"
-
-/** @addtogroup STM32WBxx_HAL_Driver
-  * @{
-  */
-
-/** @defgroup ADC ADC
-  * @brief ADC HAL module driver
-  * @{
-  */
-
-#ifdef HAL_ADC_MODULE_ENABLED
-
-/* Private typedef -----------------------------------------------------------*/
-/* Private define ------------------------------------------------------------*/
-
-/** @defgroup ADC_Private_Constants ADC Private Constants
-  * @{
-  */
-
-#define ADC_CFGR_FIELDS_1  ((ADC_CFGR_RES    | ADC_CFGR_ALIGN   |\
-                             ADC_CFGR_CONT   | ADC_CFGR_OVRMOD  |\
-                             ADC_CFGR_DISCEN | ADC_CFGR_DISCNUM |\
-                             ADC_CFGR_EXTEN  | ADC_CFGR_EXTSEL))   /*!< ADC_CFGR fields of parameters that can be updated
-                                                                        when no regular conversion is on-going */
-
-/* Timeout values for ADC operations (enable settling time,                   */
-/*   disable settling time, ...).                                             */
-/*   Values defined to be higher than worst cases: low clock frequency,       */
-/*   maximum prescalers.                                                      */
-#define ADC_ENABLE_TIMEOUT              (2UL)    /*!< ADC enable time-out value  */
-#define ADC_DISABLE_TIMEOUT             (2UL)    /*!< ADC disable time-out value */
-
-/* Timeout to wait for current conversion on going to be completed.           */
-/* Timeout fixed to longest ADC conversion possible, for 1 channel:           */
-/*   - maximum sampling time (640.5 adc_clk)                                  */
-/*   - ADC resolution (Tsar 12 bits= 12.5 adc_clk)                            */
-/*   - System clock / ADC clock <= 4096 (hypothesis of maximum clock ratio)   */
-/*   - ADC oversampling ratio 256                                             */
-/*   Calculation: 653 * 4096 * 256 CPU clock cycles max                       */
-/* Unit: cycles of CPU clock.                                                 */
-#define ADC_CONVERSION_TIME_MAX_CPU_CYCLES (653UL * 4096UL * 256UL)  /*!< ADC conversion completion time-out value */
-
-#if defined(ADC_SUPPORT_2_5_MSPS)
-/* Register CHSELR bits corresponding to ranks 2 to 8 .                     */
-#define ADC_CHSELR_SQ2_TO_SQ8           (ADC_CHSELR_SQ2 | ADC_CHSELR_SQ3 | ADC_CHSELR_SQ4 | ADC_CHSELR_SQ5 | ADC_CHSELR_SQ6 | ADC_CHSELR_SQ7 | ADC_CHSELR_SQ8)
-#endif /* ADC_SUPPORT_2_5_MSPS */
-
-
-/**
-  * @}
-  */
-
-/* Private macro -------------------------------------------------------------*/
-/* Private variables ---------------------------------------------------------*/
-/* Private function prototypes -----------------------------------------------*/
-/* Exported functions --------------------------------------------------------*/
-
-/** @defgroup ADC_Exported_Functions ADC Exported Functions
-  * @{
-  */
-
-/** @defgroup ADC_Exported_Functions_Group1 Initialization and de-initialization functions
-  * @brief    ADC Initialization and Configuration functions
-  *
-@verbatim
- ===============================================================================
-              ##### Initialization and de-initialization functions #####
- ===============================================================================
-    [..]  This section provides functions allowing to:
-      (+) Initialize and configure the ADC.
-      (+) De-initialize the ADC.
-@endverbatim
-  * @{
-  */
-
-/**
-  * @brief  Initialize the ADC peripheral and regular group according to
-  *         parameters specified in structure "ADC_InitTypeDef".
-  * @note   As prerequisite, ADC clock must be configured at RCC top level
-  *         (refer to description of RCC configuration for ADC
-  *         in header of this file).
-  * @note   Possibility to update parameters on the fly:
-  *         This function initializes the ADC MSP (HAL_ADC_MspInit()) only when
-  *         coming from ADC state reset. Following calls to this function can
-  *         be used to reconfigure some parameters of ADC_InitTypeDef
-  *         structure on the fly, without modifying MSP configuration. If ADC
-  *         MSP has to be modified again, HAL_ADC_DeInit() must be called
-  *         before HAL_ADC_Init().
-  *         The setting of these parameters is conditioned to ADC state.
-  *         For parameters constraints, see comments of structure
-  *         "ADC_InitTypeDef".
-  * @note   This function configures the ADC within 2 scopes: scope of entire
-  *         ADC and scope of regular group. For parameters details, see comments
-  *         of structure "ADC_InitTypeDef".
-  * @param hadc ADC handle
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_ADC_Init(ADC_HandleTypeDef *hadc)
-{
-  HAL_StatusTypeDef tmp_hal_status = HAL_OK;
-  uint32_t tmpCFGR = 0UL;
-  uint32_t tmp_adc_reg_is_conversion_on_going;
-  __IO uint32_t wait_loop_index = 0UL;
-#if defined(ADC_SUPPORT_2_5_MSPS)
-  uint32_t tmpCFGR2 = 0UL;
-#else
-  uint32_t tmp_adc_is_conversion_on_going_regular;
-  uint32_t tmp_adc_is_conversion_on_going_injected;
-#endif /* ADC_SUPPORT_2_5_MSPS */
-
-  /* Check ADC handle */
-  if (hadc == NULL)
-  {
-    return HAL_ERROR;
-  }
-
-  /* Check the parameters */
-  assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
-  assert_param(IS_ADC_CLOCKPRESCALER(hadc->Init.ClockPrescaler));
-  assert_param(IS_ADC_RESOLUTION(hadc->Init.Resolution));
-  assert_param(IS_ADC_DATA_ALIGN(hadc->Init.DataAlign));
-  assert_param(IS_ADC_SCAN_MODE(hadc->Init.ScanConvMode));
-  assert_param(IS_FUNCTIONAL_STATE(hadc->Init.ContinuousConvMode));
-  assert_param(IS_ADC_EXTTRIG_EDGE(hadc->Init.ExternalTrigConvEdge));
-  assert_param(IS_ADC_EXTTRIG(hadc, hadc->Init.ExternalTrigConv));
-  assert_param(IS_FUNCTIONAL_STATE(hadc->Init.DMAContinuousRequests));
-  assert_param(IS_ADC_EOC_SELECTION(hadc->Init.EOCSelection));
-  assert_param(IS_ADC_OVERRUN(hadc->Init.Overrun));
-  assert_param(IS_FUNCTIONAL_STATE(hadc->Init.LowPowerAutoWait));
-#if defined(ADC_SUPPORT_2_5_MSPS)
-  assert_param(IS_FUNCTIONAL_STATE(hadc->Init.LowPowerAutoPowerOff));
-  assert_param(IS_ADC_SAMPLE_TIME(hadc->Init.SamplingTimeCommon1));
-  assert_param(IS_ADC_SAMPLE_TIME(hadc->Init.SamplingTimeCommon2));
-  
-  assert_param(IS_ADC_TRIGGER_FREQ(hadc->Init.TriggerFrequencyMode));
-
-  if(hadc->Init.ScanConvMode != ADC_SCAN_DISABLE)
-  {
-    assert_param(IS_FUNCTIONAL_STATE(hadc->Init.DiscontinuousConvMode));
-    
-    if(hadc->Init.ScanConvMode == ADC_SCAN_ENABLE)
-    {
-      assert_param(IS_ADC_REGULAR_NB_CONV(hadc->Init.NbrOfConversion));
-    }
-  }
-#else
-  assert_param(IS_FUNCTIONAL_STATE(hadc->Init.OversamplingMode));
-
-  if (hadc->Init.ScanConvMode != ADC_SCAN_DISABLE)
-  {
-    assert_param(IS_ADC_REGULAR_NB_CONV(hadc->Init.NbrOfConversion));
-    assert_param(IS_FUNCTIONAL_STATE(hadc->Init.DiscontinuousConvMode));
-
-    if (hadc->Init.DiscontinuousConvMode == ENABLE)
-    {
-      assert_param(IS_ADC_REGULAR_DISCONT_NUMBER(hadc->Init.NbrOfDiscConversion));
-    }
-  }
-
-  /* DISCEN and CONT bits cannot be set at the same time */
-  assert_param(!((hadc->Init.DiscontinuousConvMode == ENABLE) && (hadc->Init.ContinuousConvMode == ENABLE)));
-#endif /* ADC_SUPPORT_2_5_MSPS */
-
-  /* Actions performed only if ADC is coming from state reset:                */
-  /* - Initialization of ADC MSP                                              */
-  if (hadc->State == HAL_ADC_STATE_RESET)
-  {
-#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1)
-    /* Init the ADC Callback settings */
-    hadc->ConvCpltCallback              = HAL_ADC_ConvCpltCallback;                 /* Legacy weak callback */
-    hadc->ConvHalfCpltCallback          = HAL_ADC_ConvHalfCpltCallback;             /* Legacy weak callback */
-    hadc->LevelOutOfWindowCallback      = HAL_ADC_LevelOutOfWindowCallback;         /* Legacy weak callback */
-    hadc->ErrorCallback                 = HAL_ADC_ErrorCallback;                    /* Legacy weak callback */
-#if !defined(ADC_SUPPORT_2_5_MSPS)
-    hadc->InjectedConvCpltCallback      = HAL_ADCEx_InjectedConvCpltCallback;       /* Legacy weak callback */
-    hadc->InjectedQueueOverflowCallback = HAL_ADCEx_InjectedQueueOverflowCallback;  /* Legacy weak callback */
-#endif  /* !ADC_SUPPORT_2_5_MSPS */
-    hadc->LevelOutOfWindow2Callback     = HAL_ADCEx_LevelOutOfWindow2Callback;      /* Legacy weak callback */
-    hadc->LevelOutOfWindow3Callback     = HAL_ADCEx_LevelOutOfWindow3Callback;      /* Legacy weak callback */
-    hadc->EndOfSamplingCallback         = HAL_ADCEx_EndOfSamplingCallback;          /* Legacy weak callback */
-
-    if (hadc->MspInitCallback == NULL)
-    {
-      hadc->MspInitCallback = HAL_ADC_MspInit; /* Legacy weak MspInit  */
-    }
-
-    /* Init the low level hardware */
-    hadc->MspInitCallback(hadc);
-#else
-    /* Init the low level hardware */
-    HAL_ADC_MspInit(hadc);
-#endif /* USE_HAL_ADC_REGISTER_CALLBACKS */
-
-    /* Set ADC error code to none */
-    ADC_CLEAR_ERRORCODE(hadc);
-
-    /* Initialize Lock */
-    hadc->Lock = HAL_UNLOCKED;
-  }
-
-  /* - Exit from deep power-down mode and ADC voltage regulator enable        */
-#if defined(ADC_SUPPORT_2_5_MSPS)
-  /* Feature "deep power-down" not available on ADC peripheral of this STM32WB device */
-#else
-  if (LL_ADC_IsDeepPowerDownEnabled(hadc->Instance) != 0UL)
-  {
-    /* Disable ADC deep power down mode */
-    LL_ADC_DisableDeepPowerDown(hadc->Instance);
-
-    /* System was in deep power down mode, calibration must
-     be relaunched or a previously saved calibration factor
-     re-applied once the ADC voltage regulator is enabled */
-  }
-#endif /* ADC_SUPPORT_2_5_MSPS */
-
-  if (LL_ADC_IsInternalRegulatorEnabled(hadc->Instance) == 0UL)
-  {
-    /* Enable ADC internal voltage regulator */
-    LL_ADC_EnableInternalRegulator(hadc->Instance);
-
-    /* Note: Variable divided by 2 to compensate partially              */
-    /*       CPU processing cycles, scaling in us split to not          */
-    /*       exceed 32 bits register capacity and handle low frequency. */
-    wait_loop_index = ((LL_ADC_DELAY_INTERNAL_REGUL_STAB_US / 10UL) * ((SystemCoreClock / (100000UL * 2UL)) + 1UL));
-    while (wait_loop_index != 0UL)
-    {
-      wait_loop_index--;
-    }
-  }
-
-  /* Verification that ADC voltage regulator is correctly enabled, whether    */
-  /* or not ADC is coming from state reset (if any potential problem of       */
-  /* clocking, voltage regulator would not be enabled).                       */
-  if (LL_ADC_IsInternalRegulatorEnabled(hadc->Instance) == 0UL)
-  {
-    /* Update ADC state machine to error */
-    SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL);
-
-    /* Set ADC error code to ADC peripheral internal error */
-    SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL);
-
-    tmp_hal_status = HAL_ERROR;
-  }
-
-  /* Configuration of ADC parameters if previous preliminary actions are      */
-  /* correctly completed and if there is no conversion on going on regular    */
-  /* group (ADC may already be enabled at this point if HAL_ADC_Init() is     */
-  /* called to update a parameter on the fly).                                */
-  tmp_adc_reg_is_conversion_on_going = LL_ADC_REG_IsConversionOngoing(hadc->Instance);
-
-  if (((hadc->State & HAL_ADC_STATE_ERROR_INTERNAL) == 0UL)
-      && (tmp_adc_reg_is_conversion_on_going == 0UL)
-     )
-  {
-    /* Set ADC state */
-    ADC_STATE_CLR_SET(hadc->State,
-                      HAL_ADC_STATE_REG_BUSY,
-                      HAL_ADC_STATE_BUSY_INTERNAL);
-
-#if  defined(ADC_SUPPORT_2_5_MSPS)
-    /* Configuration of common ADC parameters                                 */
-    
-    /* Parameters update conditioned to ADC state:                            */
-    /* Parameters that can be updated only when ADC is disabled:              */
-    /*  - Internal voltage regulator (no parameter in HAL ADC init structure) */
-    /*  - Clock configuration                                                 */
-    /*  - ADC resolution                                                      */
-    /* Note: If low power mode AutoPowerOff is enabled, ADC enable            */
-    /*       and disable phases are performed automatically by hardware       */
-    /*       (in this case, flag ADC_FLAG_RDY is not set).                    */
-    if (LL_ADC_IsEnabled(hadc->Instance) == 0UL)
-    {
-      /* Some parameters of this register are not reset, since they are set   */
-      /* by other functions and must be kept in case of usage of this         */
-      /* function on the fly (update of a parameter of ADC_InitTypeDef        */
-      /* without needing to reconfigure all other ADC groups/channels         */
-      /* parameters):                                                         */
-      /*   - internal measurement paths: Vbat, temperature sensor, Vref       */
-      /*     (set into HAL_ADC_ConfigChannel() )                              */
-      
-      /* Configuration of ADC resolution                                      */
-      MODIFY_REG(hadc->Instance->CFGR1,
-                 ADC_CFGR1_RES        ,
-                 hadc->Init.Resolution );
-      
-      /* Configuration of ADC:                                                */
-      /*  - clock                                                             */
-      /*  - oversampling enable                                               */
-      /*  - oversampling ratio                                                */
-      /*  - oversampling shift                                                */
-      /*  - oversampling discontinuous mode (triggered mode)                  */
-      /*  - trigger frequency mode                                            */
-      tmpCFGR2 |= ( (hadc->Init.ClockPrescaler & ADC_CFGR2_CKMODE) |
-                    hadc->Init.TriggerFrequencyMode
-                    );
-      
-      MODIFY_REG(hadc->Instance->CFGR2,
-                 ADC_CFGR2_CKMODE |
-                 ADC_CFGR2_LFTRIG     ,
-                 tmpCFGR2              );
-      
-      /* Configuration of ADC clock mode: asynchronous clock source           */
-      /* with selectable prescaler.                                           */
-      if (((hadc->Init.ClockPrescaler) != ADC_CLOCK_SYNC_PCLK_DIV1) &&
-          ((hadc->Init.ClockPrescaler) != ADC_CLOCK_SYNC_PCLK_DIV2) &&
-          ((hadc->Init.ClockPrescaler) != ADC_CLOCK_SYNC_PCLK_DIV4))
-      {
-        MODIFY_REG(ADC1_COMMON->CCR                         ,
-                   ADC_CCR_PRESC                            ,
-                   hadc->Init.ClockPrescaler & ADC_CCR_PRESC );
-      }
-    }
-
-    /* Configuration of ADC:                                                  */
-    /*  - discontinuous mode                                                  */
-    /*  - LowPowerAutoWait mode                                               */
-    /*  - LowPowerAutoPowerOff mode                                           */
-    /*  - continuous conversion mode                                          */
-    /*  - overrun                                                             */
-    /*  - external trigger to start conversion                                */
-    /*  - external trigger polarity                                           */
-    /*  - data alignment                                                      */
-    /*  - resolution                                                          */
-    /*  - scan direction                                                      */
-    /*  - DMA continuous request                                              */
-    tmpCFGR |= (ADC_CFGR_AUTOWAIT((uint32_t)hadc->Init.LowPowerAutoWait)        |
-                ADC_CFGR_AUTOOFF((uint32_t)hadc->Init.LowPowerAutoPowerOff)     |
-                ADC_CFGR_CONTINUOUS((uint32_t)hadc->Init.ContinuousConvMode)    |
-                ADC_CFGR_OVERRUN(hadc->Init.Overrun)                            |
-                hadc->Init.DataAlign                                            |
-                ADC_SCAN_SEQ_MODE(hadc->Init.ScanConvMode)                      |
-                ADC_CFGR_DMACONTREQ((uint32_t)hadc->Init.DMAContinuousRequests)  );
-
-    /* Update setting of discontinuous mode only if continuous mode is disabled */
-    if (hadc->Init.DiscontinuousConvMode == ENABLE)
-    {
-      if (hadc->Init.ContinuousConvMode == DISABLE)
-      {
-        /* Enable the selected ADC group regular discontinuous mode */
-        tmpCFGR |= ADC_CFGR1_DISCEN;
-      }
-      else
-      {
-        /* ADC regular group discontinuous was intended to be enabled,        */
-        /* but ADC regular group modes continuous and sequencer discontinuous */
-        /* cannot be enabled simultaneously.                                  */
-        
-        /* Update ADC state machine to error */
-        SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG);
-        
-        /* Set ADC error code to ADC peripheral internal error */
-        SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL);
-      }
-    }
-
-    /* Enable external trigger if trigger selection is different of software  */
-    /* start.                                                                 */
-    /* Note: This configuration keeps the hardware feature of parameter       */
-    /*       ExternalTrigConvEdge "trigger edge none" equivalent to           */
-    /*       software start.                                                  */
-    if (hadc->Init.ExternalTrigConv != ADC_SOFTWARE_START)
-    {
-      tmpCFGR |= ( (hadc->Init.ExternalTrigConv & ADC_CFGR1_EXTSEL) |
-                     hadc->Init.ExternalTrigConvEdge );
-    }
-
-    /* Update ADC configuration register with previous settings */
-    MODIFY_REG(hadc->Instance->CFGR1,
-               ADC_CFGR1_DISCEN    |
-               ADC_CFGR1_AUTOFF    |
-               ADC_CFGR1_CHSELRMOD |
-               ADC_CFGR1_WAIT      |
-               ADC_CFGR1_CONT      |
-               ADC_CFGR1_OVRMOD    |
-               ADC_CFGR1_EXTSEL    |
-               ADC_CFGR1_EXTEN     |
-               ADC_CFGR1_ALIGN     |
-               ADC_CFGR1_SCANDIR   |
-               ADC_CFGR1_DMACFG,
-               tmpCFGR);
-
-    /* Channel sampling time configuration */
-    LL_ADC_SetSamplingTimeCommonChannels(hadc->Instance, LL_ADC_SAMPLINGTIME_COMMON_1, hadc->Init.SamplingTimeCommon1);
-    LL_ADC_SetSamplingTimeCommonChannels(hadc->Instance, LL_ADC_SAMPLINGTIME_COMMON_2, hadc->Init.SamplingTimeCommon2);
-
-    /* Configuration of regular group sequencer:                              */
-    /* - if scan mode is disabled, regular channels sequence length is set to */
-    /*   0x00: 1 channel converted (channel on regular rank 1)                */
-    /*   Parameter "NbrOfConversion" is discarded.                            */
-    /*   Note: Scan mode is not present by hardware on this device, but       */
-    /*   emulated by software for alignment over all STM32 devices.           */
-    /* - if scan mode is enabled, regular channels sequence length is set to  */
-    /*   parameter "NbrOfConversion".                                         */
-    /*   Channels must be configured into each rank using function            */
-    /*   "HAL_ADC_ConfigChannel()".                                           */
-    if(hadc->Init.ScanConvMode == ADC_SCAN_DISABLE)
-    {
-      /* Set sequencer scan length by clearing ranks above rank 1             */
-      /* and do not modify rank 1 value.                                      */
-      SET_BIT(hadc->Instance->CHSELR,
-              ADC_CHSELR_SQ2_TO_SQ8);
-    }
-    else if(hadc->Init.ScanConvMode == ADC_SCAN_ENABLE)
-    {
-      /* Set ADC group regular sequencer:                                   */
-      /*  - Set ADC group regular sequencer to value memorized              */
-      /*    in HAL ADC handle                                               */
-      /*    Note: This value maybe be initialized at a unknown value,       */
-      /*          therefore after the first call of "HAL_ADC_Init()",       */
-      /*          each rank corresponding to parameter "NbrOfConversion"    */
-      /*          must be set using "HAL_ADC_ConfigChannel()".              */
-      /*  - Set sequencer scan length by clearing ranks above maximum rank  */
-      /*    and do not modify other ranks value.                            */
-      MODIFY_REG(hadc->Instance->CHSELR,
-                  ADC_CHSELR_SQ_ALL,
-                  ((ADC_CHSELR_SQ2_TO_SQ8 << (((hadc->Init.NbrOfConversion - 1UL) * ADC_REGULAR_RANK_2) & 0x1FUL)) |
-                   (hadc->ADCGroupRegularSequencerRanks))
-                );
-    }
-
-    /* Check back that ADC registers have effectively been configured to      */
-    /* ensure of no potential problem of ADC core peripheral clocking.        */
-    /* Check through register CFGR1 (excluding analog watchdog configuration: */
-    /* set into separate dedicated function, and bits of ADC resolution set   */
-    /* out of temporary variable 'tmpCFGR').                                  */
-    if ((hadc->Instance->CFGR1 & ~(ADC_CFGR1_AWD1CH | ADC_CFGR1_AWD1EN | ADC_CFGR1_AWD1SGL | ADC_CFGR1_RES))
-         == tmpCFGR)
-    {
-      /* Set ADC error code to none */
-      ADC_CLEAR_ERRORCODE(hadc);
-
-      /* Set the ADC state */
-      ADC_STATE_CLR_SET(hadc->State,
-                        HAL_ADC_STATE_BUSY_INTERNAL,
-                        HAL_ADC_STATE_READY);
-    }
-    else
-    {
-      /* Update ADC state machine to error */
-      ADC_STATE_CLR_SET(hadc->State,
-                        HAL_ADC_STATE_BUSY_INTERNAL,
-                        HAL_ADC_STATE_ERROR_INTERNAL);
-
-      /* Set ADC error code to ADC peripheral internal error */
-      SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL);
-
-      tmp_hal_status = HAL_ERROR;
-    }
-
-#else
-    /* Configuration of common ADC parameters                                 */
-
-    /* Parameters update conditioned to ADC state:                            */
-    /* Parameters that can be updated only when ADC is disabled:              */
-    /*  - clock configuration                                                 */
-    if (LL_ADC_IsEnabled(hadc->Instance) == 0UL)
-    {
-      if (__LL_ADC_IS_ENABLED_ALL_COMMON_INSTANCE(__LL_ADC_COMMON_INSTANCE(hadc->Instance)) == 0UL)
-      {
-        /* Reset configuration of ADC common register CCR:                      */
-        /*                                                                      */
-        /*   - ADC clock mode and ACC prescaler (CKMODE and PRESC bits)are set  */
-        /*     according to adc->Init.ClockPrescaler. It selects the clock      */
-        /*    source and sets the clock division factor.                        */
-        /*                                                                      */
-        /* Some parameters of this register are not reset, since they are set   */
-        /* by other functions and must be kept in case of usage of this         */
-        /* function on the fly (update of a parameter of ADC_InitTypeDef        */
-        /* without needing to reconfigure all other ADC groups/channels         */
-        /* parameters):                                                         */
-        /*   - when multimode feature is available, multimode-related           */
-        /*     parameters: MDMA, DMACFG, DELAY, DUAL (set by API                */
-        /*     HAL_ADCEx_MultiModeConfigChannel() )                             */
-        /*   - internal measurement paths: Vbat, temperature sensor, Vref       */
-        /*     (set into HAL_ADC_ConfigChannel() or                             */
-        /*     HAL_ADCEx_InjectedConfigChannel() )                              */
-        LL_ADC_SetCommonClock(__LL_ADC_COMMON_INSTANCE(hadc->Instance), hadc->Init.ClockPrescaler);
-      }
-    }
-
-    /* Configuration of ADC:                                                  */
-    /*  - resolution                               Init.Resolution            */
-    /*  - data alignment                           Init.DataAlign             */
-    /*  - external trigger to start conversion     Init.ExternalTrigConv      */
-    /*  - external trigger polarity                Init.ExternalTrigConvEdge  */
-    /*  - continuous conversion mode               Init.ContinuousConvMode    */
-    /*  - overrun                                  Init.Overrun               */
-    /*  - discontinuous mode                       Init.DiscontinuousConvMode */
-    /*  - discontinuous mode channel count         Init.NbrOfDiscConversion   */
-    tmpCFGR |= (ADC_CFGR_CONTINUOUS((uint32_t)hadc->Init.ContinuousConvMode)           |
-                hadc->Init.Overrun                                                     |
-                hadc->Init.DataAlign                                                   |
-                hadc->Init.Resolution                                                  |
-                ADC_CFGR_REG_DISCONTINUOUS((uint32_t)hadc->Init.DiscontinuousConvMode));
-
-    if (hadc->Init.DiscontinuousConvMode == ENABLE)
-    {
-      tmpCFGR |= ADC_CFGR_DISCONTINUOUS_NUM(hadc->Init.NbrOfDiscConversion);
-    }
-
-    /* Enable external trigger if trigger selection is different of software  */
-    /* start.                                                                 */
-    /* Note: This configuration keeps the hardware feature of parameter       */
-    /*       ExternalTrigConvEdge "trigger edge none" equivalent to           */
-    /*       software start.                                                  */
-    if (hadc->Init.ExternalTrigConv != ADC_SOFTWARE_START)
-    {
-      tmpCFGR |= ((hadc->Init.ExternalTrigConv & ADC_CFGR_EXTSEL)
-                  | hadc->Init.ExternalTrigConvEdge
-                 );
-    }
-
-    /* Update Configuration Register CFGR */
-    MODIFY_REG(hadc->Instance->CFGR, ADC_CFGR_FIELDS_1, tmpCFGR);
-
-    /* Parameters update conditioned to ADC state:                            */
-    /* Parameters that can be updated when ADC is disabled or enabled without */
-    /* conversion on going on regular and injected groups:                    */
-    /*  - DMA continuous request          Init.DMAContinuousRequests          */
-    /*  - LowPowerAutoWait feature        Init.LowPowerAutoWait               */
-    /*  - Oversampling parameters         Init.Oversampling                   */
-    tmp_adc_is_conversion_on_going_regular = LL_ADC_REG_IsConversionOngoing(hadc->Instance);
-    tmp_adc_is_conversion_on_going_injected = LL_ADC_INJ_IsConversionOngoing(hadc->Instance);
-    if ((tmp_adc_is_conversion_on_going_regular == 0UL)
-        && (tmp_adc_is_conversion_on_going_injected == 0UL)
-       )
-    {
-      tmpCFGR = (ADC_CFGR_DFSDM(hadc)                                            |
-                 ADC_CFGR_AUTOWAIT((uint32_t)hadc->Init.LowPowerAutoWait)        |
-                 ADC_CFGR_DMACONTREQ((uint32_t)hadc->Init.DMAContinuousRequests));
-
-      MODIFY_REG(hadc->Instance->CFGR, ADC_CFGR_FIELDS_2, tmpCFGR);
-
-      if (hadc->Init.OversamplingMode == ENABLE)
-      {
-        assert_param(IS_ADC_OVERSAMPLING_RATIO(hadc->Init.Oversampling.Ratio));
-        assert_param(IS_ADC_RIGHT_BIT_SHIFT(hadc->Init.Oversampling.RightBitShift));
-        assert_param(IS_ADC_TRIGGERED_OVERSAMPLING_MODE(hadc->Init.Oversampling.TriggeredMode));
-        assert_param(IS_ADC_REGOVERSAMPLING_MODE(hadc->Init.Oversampling.OversamplingStopReset));
-
-        /* Configuration of Oversampler:                                      */
-        /*  - Oversampling Ratio                                              */
-        /*  - Right bit shift                                                 */
-        /*  - Triggered mode                                                  */
-        /*  - Oversampling mode (continued/resumed)                           */
-        MODIFY_REG(hadc->Instance->CFGR2,
-                   ADC_CFGR2_OVSR  |
-                   ADC_CFGR2_OVSS  |
-                   ADC_CFGR2_TROVS |
-                   ADC_CFGR2_ROVSM,
-                   ADC_CFGR2_ROVSE                       |
-                   hadc->Init.Oversampling.Ratio         |
-                   hadc->Init.Oversampling.RightBitShift |
-                   hadc->Init.Oversampling.TriggeredMode |
-                   hadc->Init.Oversampling.OversamplingStopReset
-                  );
-      }
-      else
-      {
-        /* Disable ADC oversampling scope on ADC group regular */
-        CLEAR_BIT(hadc->Instance->CFGR2, ADC_CFGR2_ROVSE);
-      }
-
-    }
-
-    /* Configuration of regular group sequencer:                              */
-    /* - if scan mode is disabled, regular channels sequence length is set to */
-    /*   0x00: 1 channel converted (channel on regular rank 1)                */
-    /*   Parameter "NbrOfConversion" is discarded.                            */
-    /*   Note: Scan mode is not present by hardware on this device, but       */
-    /*   emulated by software for alignment over all STM32 devices.           */
-    /* - if scan mode is enabled, regular channels sequence length is set to  */
-    /*   parameter "NbrOfConversion".                                         */
-
-    if (hadc->Init.ScanConvMode == ADC_SCAN_ENABLE)
-    {
-      /* Set number of ranks in regular group sequencer */
-      MODIFY_REG(hadc->Instance->SQR1, ADC_SQR1_L, (hadc->Init.NbrOfConversion - (uint8_t)1));
-    }
-    else
-    {
-      CLEAR_BIT(hadc->Instance->SQR1, ADC_SQR1_L);
-    }
-
-    /* Initialize the ADC state */
-    /* Clear HAL_ADC_STATE_BUSY_INTERNAL bit, set HAL_ADC_STATE_READY bit */
-    ADC_STATE_CLR_SET(hadc->State, HAL_ADC_STATE_BUSY_INTERNAL, HAL_ADC_STATE_READY);
-#endif /* ADC_SUPPORT_2_5_MSPS */
-  }
-  else
-  {
-    /* Update ADC state machine to error */
-    SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL);
-
-    tmp_hal_status = HAL_ERROR;
-  }
-
-  /* Return function status */
-  return tmp_hal_status;
-}
-
-/**
-  * @brief  Deinitialize the ADC peripheral registers to their default reset
-  *         values, with deinitialization of the ADC MSP.
-  * @note   For devices with several ADCs: reset of ADC common registers is done
-  *         only if all ADCs sharing the same common group are disabled.
-  *         (function "HAL_ADC_MspDeInit()" is also called under the same conditions:
-  *         all ADC instances use the same core clock at RCC level, disabling
-  *         the core clock reset all ADC instances).
-  *         If this is not the case, reset of these common parameters reset is
-  *         bypassed without error reporting: it can be the intended behavior in
-  *         case of reset of a single ADC while the other ADCs sharing the same
-  *         common group is still running.
-  * @note   By default, HAL_ADC_DeInit() set ADC in mode deep power-down:
-  *         this saves more power by reducing leakage currents
-  *         and is particularly interesting before entering MCU low-power modes.
-  * @param hadc ADC handle
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_ADC_DeInit(ADC_HandleTypeDef *hadc)
-{
-  HAL_StatusTypeDef tmp_hal_status;
-
-  /* Check ADC handle */
-  if (hadc == NULL)
-  {
-    return HAL_ERROR;
-  }
-
-  /* Check the parameters */
-  assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
-
-  /* Set ADC state */
-  SET_BIT(hadc->State, HAL_ADC_STATE_BUSY_INTERNAL);
-
-  /* Stop potential conversion on going */
-#if  defined(ADC_SUPPORT_2_5_MSPS)
-  tmp_hal_status = ADC_ConversionStop(hadc, ADC_REGULAR_GROUP);
-#else
-  tmp_hal_status = ADC_ConversionStop(hadc, ADC_REGULAR_INJECTED_GROUP);
-#endif /* ADC_SUPPORT_2_5_MSPS */
-
-#if  defined(ADC_SUPPORT_2_5_MSPS)
-/* Feature "ADC group injected" not available on ADC peripheral of this STM32WB device */
-#else
-  /* Disable ADC peripheral if conversions are effectively stopped            */
-  /* Flush register JSQR: reset the queue sequencer when injected             */
-  /* queue sequencer is enabled and ADC disabled.                             */
-  /* The software and hardware triggers of the injected sequence are both     */
-  /* internally disabled just after the completion of the last valid          */
-  /* injected sequence.                                                       */
-  SET_BIT(hadc->Instance->CFGR, ADC_CFGR_JQM);
-#endif
-
-  /* Disable ADC peripheral if conversions are effectively stopped */
-  if (tmp_hal_status == HAL_OK)
-  {
-    /* Disable the ADC peripheral */
-    tmp_hal_status = ADC_Disable(hadc);
-
-    /* Check if ADC is effectively disabled */
-    if (tmp_hal_status == HAL_OK)
-    {
-      /* Change ADC state */
-      hadc->State = HAL_ADC_STATE_READY;
-    }
-  }
-
-  /* Note: HAL ADC deInit is done independently of ADC conversion stop        */
-  /*       and disable return status. In case of status fail, attempt to      */
-  /*       perform deinitialization anyway and it is up user code in          */
-  /*       in HAL_ADC_MspDeInit() to reset the ADC peripheral using           */
-  /*       system RCC hard reset.                                             */
-
-  /* ========== Reset ADC registers ========== */
-#if  defined(ADC_SUPPORT_2_5_MSPS)
-  /* Reset register IER */
-  __HAL_ADC_DISABLE_IT(hadc, (ADC_IT_AWD3  | ADC_IT_AWD2 |
-                              ADC_IT_AWD1  | ADC_IT_OVR  |
-                              ADC_IT_EOS   | ADC_IT_EOC  |
-                              ADC_IT_EOSMP | ADC_IT_RDY   ) );
-
-  /* Reset register ISR */
-  __HAL_ADC_CLEAR_FLAG(hadc, (ADC_FLAG_AWD3  | ADC_FLAG_AWD2 |
-                              ADC_FLAG_AWD1  | ADC_FLAG_OVR  |
-                              ADC_FLAG_EOS   | ADC_FLAG_EOC  |
-                              ADC_FLAG_EOSMP | ADC_FLAG_RDY   ) );
-
-  /* Reset register CR */
-  /* Bits ADC_CR_ADCAL, ADC_CR_ADSTP, ADC_CR_ADSTART are in access mode     */
-  /* "read-set": no direct reset applicable.                                */
-  
-  /* Reset register CFGR1 */
-  hadc->Instance->CFGR1 &= ~(ADC_CFGR1_AWD1CH  | ADC_CFGR1_AWD1EN | ADC_CFGR1_AWD1SGL | ADC_CFGR1_DISCEN |
-                             ADC_CFGR1_AUTOFF  | ADC_CFGR1_WAIT   | ADC_CFGR1_CONT    | ADC_CFGR1_OVRMOD |
-                             ADC_CFGR1_EXTEN   | ADC_CFGR1_EXTSEL | ADC_CFGR1_ALIGN   | ADC_CFGR1_RES    |
-                             ADC_CFGR1_SCANDIR | ADC_CFGR1_DMACFG | ADC_CFGR1_DMAEN   |
-                             ADC_CFGR1_CHSELRMOD);
-
-  /* Reset register CFGR2 */
-  /* Note: Update of ADC clock mode is conditioned to ADC state disabled:   */
-  /*       already done above.                                              */
-  hadc->Instance->CFGR2 &= ~ADC_CFGR2_CKMODE;
-
-  /* Reset register SMPR */
-  hadc->Instance->SMPR &= ~ADC_SMPR_SMP1;
-
-  /* Reset register TR */
-  hadc->Instance->TR &= ~(ADC_TR_HT | ADC_TR_LT);
-
-  /* Reset register CHSELR */
-  hadc->Instance->CHSELR &= ~(ADC_CHSELR_SQ_ALL);
-
-  /* Reset register DR */
-  /* bits in access mode read only, no direct reset applicable */
-
-#else
-  /* Reset register IER */
-  __HAL_ADC_DISABLE_IT(hadc, (
-#if defined(ADC_SUPPORT_2_5_MSPS)
-                              ADC_IT_AWD3  | ADC_IT_AWD2 | ADC_IT_AWD1 |
-                              ADC_IT_EOCAL | ADC_IT_CCRDY |
-#else
-                              ADC_IT_AWD3  | ADC_IT_AWD2 | ADC_IT_AWD1 |
-                              ADC_IT_JEOS  | ADC_IT_JEOC | ADC_IT_JQOVF |
-#endif /* ADC_SUPPORT_2_5_MSPS */
-                              ADC_IT_EOS   | ADC_IT_EOC  | ADC_IT_OVR   |
-                              ADC_IT_EOSMP | ADC_IT_RDY));
-
-  /* Reset register ISR */
-  __HAL_ADC_CLEAR_FLAG(hadc, (
-#if defined(ADC_SUPPORT_2_5_MSPS)
-                              ADC_FLAG_AWD3  | ADC_FLAG_AWD2 | ADC_FLAG_AWD1 |
-                              ADC_FLAG_EOCAL | ADC_FLAG_CCRDY |
-#else
-                              ADC_FLAG_AWD3  | ADC_FLAG_AWD2 | ADC_FLAG_AWD1 |
-                              ADC_FLAG_JEOS  | ADC_FLAG_JEOC | ADC_FLAG_JQOVF |
-#endif /* ADC_SUPPORT_2_5_MSPS */
-                              ADC_FLAG_EOS   | ADC_FLAG_EOC  | ADC_FLAG_OVR  |
-                              ADC_FLAG_EOSMP | ADC_FLAG_RDY));
-
-  /* Reset register CR */
-  /* Bits ADC_CR_JADSTP, ADC_CR_ADSTP, ADC_CR_JADSTART, ADC_CR_ADSTART,
-     ADC_CR_ADCAL, ADC_CR_ADDIS and ADC_CR_ADEN are in access mode "read-set":
-     no direct reset applicable.
-     Update CR register to reset value where doable by software */
-  CLEAR_BIT(hadc->Instance->CR, ADC_CR_ADVREGEN | ADC_CR_ADCALDIF);
-  SET_BIT(hadc->Instance->CR, ADC_CR_DEEPPWD);
-
-  /* Reset register CFGR */
-  CLEAR_BIT(hadc->Instance->CFGR, ADC_CFGR_FIELDS);
-  SET_BIT(hadc->Instance->CFGR, ADC_CFGR_JQDIS);
-
-  /* Reset register CFGR2 */
-  CLEAR_BIT(hadc->Instance->CFGR2, ADC_CFGR2_ROVSM  | ADC_CFGR2_TROVS   | ADC_CFGR2_OVSS |
-            ADC_CFGR2_OVSR  | ADC_CFGR2_JOVSE | ADC_CFGR2_ROVSE);
-
-  /* Reset register SMPR1 */
-  CLEAR_BIT(hadc->Instance->SMPR1, ADC_SMPR1_FIELDS);
-
-  /* Reset register SMPR2 */
-  CLEAR_BIT(hadc->Instance->SMPR2, ADC_SMPR2_SMP18 | ADC_SMPR2_SMP17 | ADC_SMPR2_SMP16 |
-            ADC_SMPR2_SMP15 | ADC_SMPR2_SMP14 | ADC_SMPR2_SMP13 |
-            ADC_SMPR2_SMP12 | ADC_SMPR2_SMP11 | ADC_SMPR2_SMP10);
-
-  /* Reset register TR1 */
-  CLEAR_BIT(hadc->Instance->TR1, ADC_TR1_HT1 | ADC_TR1_LT1);
-
-  /* Reset register TR2 */
-  CLEAR_BIT(hadc->Instance->TR2, ADC_TR2_HT2 | ADC_TR2_LT2);
-
-  /* Reset register TR3 */
-  CLEAR_BIT(hadc->Instance->TR3, ADC_TR3_HT3 | ADC_TR3_LT3);
-
-  /* Reset register SQR1 */
-  CLEAR_BIT(hadc->Instance->SQR1, ADC_SQR1_SQ4 | ADC_SQR1_SQ3 | ADC_SQR1_SQ2 |
-            ADC_SQR1_SQ1 | ADC_SQR1_L);
-
-  /* Reset register SQR2 */
-  CLEAR_BIT(hadc->Instance->SQR2, ADC_SQR2_SQ9 | ADC_SQR2_SQ8 | ADC_SQR2_SQ7 |
-            ADC_SQR2_SQ6 | ADC_SQR2_SQ5);
-
-  /* Reset register SQR3 */
-  CLEAR_BIT(hadc->Instance->SQR3, ADC_SQR3_SQ14 | ADC_SQR3_SQ13 | ADC_SQR3_SQ12 |
-            ADC_SQR3_SQ11 | ADC_SQR3_SQ10);
-
-  /* Reset register SQR4 */
-  CLEAR_BIT(hadc->Instance->SQR4, ADC_SQR4_SQ16 | ADC_SQR4_SQ15);
-
-  /* Register JSQR was reset when the ADC was disabled */
-
-  /* Reset register DR */
-  /* bits in access mode read only, no direct reset applicable*/
-
-  /* Reset register OFR1 */
-  CLEAR_BIT(hadc->Instance->OFR1, ADC_OFR1_OFFSET1_EN | ADC_OFR1_OFFSET1_CH | ADC_OFR1_OFFSET1);
-  /* Reset register OFR2 */
-  CLEAR_BIT(hadc->Instance->OFR2, ADC_OFR2_OFFSET2_EN | ADC_OFR2_OFFSET2_CH | ADC_OFR2_OFFSET2);
-  /* Reset register OFR3 */
-  CLEAR_BIT(hadc->Instance->OFR3, ADC_OFR3_OFFSET3_EN | ADC_OFR3_OFFSET3_CH | ADC_OFR3_OFFSET3);
-  /* Reset register OFR4 */
-  CLEAR_BIT(hadc->Instance->OFR4, ADC_OFR4_OFFSET4_EN | ADC_OFR4_OFFSET4_CH | ADC_OFR4_OFFSET4);
-
-  /* Reset registers JDR1, JDR2, JDR3, JDR4 */
-  /* bits in access mode read only, no direct reset applicable*/
-
-  /* Reset register AWD2CR */
-  CLEAR_BIT(hadc->Instance->AWD2CR, ADC_AWD2CR_AWD2CH);
-
-  /* Reset register AWD3CR */
-  CLEAR_BIT(hadc->Instance->AWD3CR, ADC_AWD3CR_AWD3CH);
-
-  /* Reset register DIFSEL */
-  CLEAR_BIT(hadc->Instance->DIFSEL, ADC_DIFSEL_DIFSEL);
-
-  /* Reset register CALFACT */
-  CLEAR_BIT(hadc->Instance->CALFACT, ADC_CALFACT_CALFACT_D | ADC_CALFACT_CALFACT_S);
-#endif /* ADC_SUPPORT_2_5_MSPS */
-
-
-  /* ========== Reset common ADC registers ========== */
-
-  /* Software is allowed to change common parameters only when all the other
-     ADCs are disabled.   */
-  if (__LL_ADC_IS_ENABLED_ALL_COMMON_INSTANCE(__LL_ADC_COMMON_INSTANCE(hadc->Instance)) == 0UL)
-  {
-    /* Reset configuration of ADC common register CCR:
-      - clock mode: CKMODE, PRESCEN
-      - multimode related parameters (when this feature is available): MDMA,
-        DMACFG, DELAY, DUAL (set by HAL_ADCEx_MultiModeConfigChannel() API)
-      - internal measurement paths: Vbat, temperature sensor, Vref (set into
-        HAL_ADC_ConfigChannel() or HAL_ADCEx_InjectedConfigChannel() )
-    */
-    ADC_CLEAR_COMMON_CONTROL_REGISTER(hadc);
-  }
-
-  /* DeInit the low level hardware.
-
-     For example:
-    __HAL_RCC_ADC_FORCE_RESET();
-    __HAL_RCC_ADC_RELEASE_RESET();
-    __HAL_RCC_ADC_CLK_DISABLE();
-
-    Keep in mind that all ADCs use the same clock: disabling
-    the clock will reset all ADCs.
-
-  */
-#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1)
-  if (hadc->MspDeInitCallback == NULL)
-  {
-    hadc->MspDeInitCallback = HAL_ADC_MspDeInit; /* Legacy weak MspDeInit  */
-  }
-
-  /* DeInit the low level hardware: RCC clock, NVIC */
-  hadc->MspDeInitCallback(hadc);
-#else
-  /* DeInit the low level hardware: RCC clock, NVIC */
-  HAL_ADC_MspDeInit(hadc);
-#endif /* USE_HAL_ADC_REGISTER_CALLBACKS */
-
-  /* Set ADC error code to none */
-  ADC_CLEAR_ERRORCODE(hadc);
-
-#if  defined(ADC_SUPPORT_2_5_MSPS)
-  /* Reset HAL ADC handle variable */
-  hadc->ADCGroupRegularSequencerRanks = 0x00000000UL;
-#else
-  /* Reset injected channel configuration parameters */
-  hadc->InjectionConfig.ContextQueue = 0;
-  hadc->InjectionConfig.ChannelCount = 0;
-#endif /* ADC_SUPPORT_2_5_MSPS */
-
-  /* Set ADC state */
-  hadc->State = HAL_ADC_STATE_RESET;
-
-  /* Process unlocked */
-  __HAL_UNLOCK(hadc);
-
-  /* Return function status */
-  return tmp_hal_status;
-}
-
-/**
-  * @brief  Initialize the ADC MSP.
-  * @param hadc ADC handle
-  * @retval None
-  */
-__weak void HAL_ADC_MspInit(ADC_HandleTypeDef *hadc)
-{
-  /* Prevent unused argument(s) compilation warning */
-  UNUSED(hadc);
-
-  /* NOTE : This function should not be modified. When the callback is needed,
-            function HAL_ADC_MspInit must be implemented in the user file.
-   */
-}
-
-/**
-  * @brief  DeInitialize the ADC MSP.
-  * @param hadc ADC handle
-  * @note   All ADC instances use the same core clock at RCC level, disabling
-  *         the core clock reset all ADC instances).
-  * @retval None
-  */
-__weak void HAL_ADC_MspDeInit(ADC_HandleTypeDef *hadc)
-{
-  /* Prevent unused argument(s) compilation warning */
-  UNUSED(hadc);
-
-  /* NOTE : This function should not be modified. When the callback is needed,
-            function HAL_ADC_MspDeInit must be implemented in the user file.
-   */
-}
-
-#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1)
-/**
-  * @brief  Register a User ADC Callback
-  *         To be used instead of the weak predefined callback
-  * @param  hadc Pointer to a ADC_HandleTypeDef structure that contains
-  *                the configuration information for the specified ADC.
-  * @param  CallbackID ID of the callback to be registered
-  *         This parameter can be one of the following values:
-  *          @arg @ref HAL_ADC_CONVERSION_COMPLETE_CB_ID      ADC conversion complete callback ID
-  *          @arg @ref HAL_ADC_CONVERSION_HALF_CB_ID          ADC conversion DMA half-transfer callback ID
-  *          @arg @ref HAL_ADC_LEVEL_OUT_OF_WINDOW_1_CB_ID    ADC analog watchdog 1 callback ID
-  *          @arg @ref HAL_ADC_ERROR_CB_ID                    ADC error callback ID
-  *          @arg @ref HAL_ADC_INJ_CONVERSION_COMPLETE_CB_ID  ADC group injected conversion complete callback ID
-  *          @arg @ref HAL_ADC_INJ_QUEUE_OVEFLOW_CB_ID        ADC group injected context queue overflow callback ID
-  *          @arg @ref HAL_ADC_LEVEL_OUT_OF_WINDOW_2_CB_ID    ADC analog watchdog 2 callback ID
-  *          @arg @ref HAL_ADC_LEVEL_OUT_OF_WINDOW_3_CB_ID    ADC analog watchdog 3 callback ID
-  *          @arg @ref HAL_ADC_END_OF_SAMPLING_CB_ID          ADC end of sampling callback ID
-  *          @arg @ref HAL_ADC_MSPINIT_CB_ID                  ADC Msp Init callback ID
-  *          @arg @ref HAL_ADC_MSPDEINIT_CB_ID                ADC Msp DeInit callback ID
-  *          @arg @ref HAL_ADC_MSPINIT_CB_ID MspInit callback ID
-  *          @arg @ref HAL_ADC_MSPDEINIT_CB_ID MspDeInit callback ID
-  * @param  pCallback pointer to the Callback function
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_ADC_RegisterCallback(ADC_HandleTypeDef *hadc, HAL_ADC_CallbackIDTypeDef CallbackID, pADC_CallbackTypeDef pCallback)
-{
-  HAL_StatusTypeDef status = HAL_OK;
-
-  if (pCallback == NULL)
-  {
-    /* Update the error code */
-    hadc->ErrorCode |= HAL_ADC_ERROR_INVALID_CALLBACK;
-
-    return HAL_ERROR;
-  }
-
-  if ((hadc->State & HAL_ADC_STATE_READY) != 0UL)
-  {
-    switch (CallbackID)
-    {
-      case HAL_ADC_CONVERSION_COMPLETE_CB_ID :
-        hadc->ConvCpltCallback = pCallback;
-        break;
-
-      case HAL_ADC_CONVERSION_HALF_CB_ID :
-        hadc->ConvHalfCpltCallback = pCallback;
-        break;
-
-      case HAL_ADC_LEVEL_OUT_OF_WINDOW_1_CB_ID :
-        hadc->LevelOutOfWindowCallback = pCallback;
-        break;
-
-      case HAL_ADC_ERROR_CB_ID :
-        hadc->ErrorCallback = pCallback;
-        break;
-
-      case HAL_ADC_INJ_CONVERSION_COMPLETE_CB_ID :
-        hadc->InjectedConvCpltCallback = pCallback;
-        break;
-
-      case HAL_ADC_INJ_QUEUE_OVEFLOW_CB_ID :
-        hadc->InjectedQueueOverflowCallback = pCallback;
-        break;
-
-      case HAL_ADC_LEVEL_OUT_OF_WINDOW_2_CB_ID :
-        hadc->LevelOutOfWindow2Callback = pCallback;
-        break;
-
-      case HAL_ADC_LEVEL_OUT_OF_WINDOW_3_CB_ID :
-        hadc->LevelOutOfWindow3Callback = pCallback;
-        break;
-
-      case HAL_ADC_END_OF_SAMPLING_CB_ID :
-        hadc->EndOfSamplingCallback = pCallback;
-        break;
-
-      case HAL_ADC_MSPINIT_CB_ID :
-        hadc->MspInitCallback = pCallback;
-        break;
-
-      case HAL_ADC_MSPDEINIT_CB_ID :
-        hadc->MspDeInitCallback = pCallback;
-        break;
-
-      default :
-        /* Update the error code */
-        hadc->ErrorCode |= HAL_ADC_ERROR_INVALID_CALLBACK;
-
-        /* Return error status */
-        status = HAL_ERROR;
-        break;
-    }
-  }
-  else if (HAL_ADC_STATE_RESET == hadc->State)
-  {
-    switch (CallbackID)
-    {
-      case HAL_ADC_MSPINIT_CB_ID :
-        hadc->MspInitCallback = pCallback;
-        break;
-
-      case HAL_ADC_MSPDEINIT_CB_ID :
-        hadc->MspDeInitCallback = pCallback;
-        break;
-
-      default :
-        /* Update the error code */
-        hadc->ErrorCode |= HAL_ADC_ERROR_INVALID_CALLBACK;
-
-        /* Return error status */
-        status = HAL_ERROR;
-        break;
-    }
-  }
-  else
-  {
-    /* Update the error code */
-    hadc->ErrorCode |= HAL_ADC_ERROR_INVALID_CALLBACK;
-
-    /* Return error status */
-    status =  HAL_ERROR;
-  }
-
-  return status;
-}
-
-/**
-  * @brief  Unregister a ADC Callback
-  *         ADC callback is redirected to the weak predefined callback
-  * @param  hadc Pointer to a ADC_HandleTypeDef structure that contains
-  *                the configuration information for the specified ADC.
-  * @param  CallbackID ID of the callback to be unregistered
-  *         This parameter can be one of the following values:
-  *          @arg @ref HAL_ADC_CONVERSION_COMPLETE_CB_ID      ADC conversion complete callback ID
-  *          @arg @ref HAL_ADC_CONVERSION_HALF_CB_ID          ADC conversion DMA half-transfer callback ID
-  *          @arg @ref HAL_ADC_LEVEL_OUT_OF_WINDOW_1_CB_ID    ADC analog watchdog 1 callback ID
-  *          @arg @ref HAL_ADC_ERROR_CB_ID                    ADC error callback ID
-  *          @arg @ref HAL_ADC_INJ_CONVERSION_COMPLETE_CB_ID  ADC group injected conversion complete callback ID
-  *          @arg @ref HAL_ADC_INJ_QUEUE_OVEFLOW_CB_ID        ADC group injected context queue overflow callback ID
-  *          @arg @ref HAL_ADC_LEVEL_OUT_OF_WINDOW_2_CB_ID    ADC analog watchdog 2 callback ID
-  *          @arg @ref HAL_ADC_LEVEL_OUT_OF_WINDOW_3_CB_ID    ADC analog watchdog 3 callback ID
-  *          @arg @ref HAL_ADC_END_OF_SAMPLING_CB_ID          ADC end of sampling callback ID
-  *          @arg @ref HAL_ADC_MSPINIT_CB_ID                  ADC Msp Init callback ID
-  *          @arg @ref HAL_ADC_MSPDEINIT_CB_ID                ADC Msp DeInit callback ID
-  *          @arg @ref HAL_ADC_MSPINIT_CB_ID MspInit callback ID
-  *          @arg @ref HAL_ADC_MSPDEINIT_CB_ID MspDeInit callback ID
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_ADC_UnRegisterCallback(ADC_HandleTypeDef *hadc, HAL_ADC_CallbackIDTypeDef CallbackID)
-{
-  HAL_StatusTypeDef status = HAL_OK;
-
-  if ((hadc->State & HAL_ADC_STATE_READY) != 0UL)
-  {
-    switch (CallbackID)
-    {
-      case HAL_ADC_CONVERSION_COMPLETE_CB_ID :
-        hadc->ConvCpltCallback = HAL_ADC_ConvCpltCallback;
-        break;
-
-      case HAL_ADC_CONVERSION_HALF_CB_ID :
-        hadc->ConvHalfCpltCallback = HAL_ADC_ConvHalfCpltCallback;
-        break;
-
-      case HAL_ADC_LEVEL_OUT_OF_WINDOW_1_CB_ID :
-        hadc->LevelOutOfWindowCallback = HAL_ADC_LevelOutOfWindowCallback;
-        break;
-
-      case HAL_ADC_ERROR_CB_ID :
-        hadc->ErrorCallback = HAL_ADC_ErrorCallback;
-        break;
-
-#if  defined(ADC_SUPPORT_2_5_MSPS)
-/* Feature "ADC group injected" not available on ADC peripheral of this STM32WB device */
-#else
-      case HAL_ADC_INJ_CONVERSION_COMPLETE_CB_ID :
-        hadc->InjectedConvCpltCallback = HAL_ADCEx_InjectedConvCpltCallback;
-        break;
-
-      case HAL_ADC_INJ_QUEUE_OVEFLOW_CB_ID :
-        hadc->InjectedQueueOverflowCallback = HAL_ADCEx_InjectedQueueOverflowCallback;
-        break;
-#endif /* ADC_SUPPORT_2_5_MSPS */
-
-      case HAL_ADC_LEVEL_OUT_OF_WINDOW_2_CB_ID :
-        hadc->LevelOutOfWindow2Callback = HAL_ADCEx_LevelOutOfWindow2Callback;
-        break;
-
-      case HAL_ADC_LEVEL_OUT_OF_WINDOW_3_CB_ID :
-        hadc->LevelOutOfWindow3Callback = HAL_ADCEx_LevelOutOfWindow3Callback;
-        break;
-
-      case HAL_ADC_END_OF_SAMPLING_CB_ID :
-        hadc->EndOfSamplingCallback = HAL_ADCEx_EndOfSamplingCallback;
-        break;
-
-      case HAL_ADC_MSPINIT_CB_ID :
-        hadc->MspInitCallback = HAL_ADC_MspInit; /* Legacy weak MspInit              */
-        break;
-
-      case HAL_ADC_MSPDEINIT_CB_ID :
-        hadc->MspDeInitCallback = HAL_ADC_MspDeInit; /* Legacy weak MspDeInit            */
-        break;
-
-      default :
-        /* Update the error code */
-        hadc->ErrorCode |= HAL_ADC_ERROR_INVALID_CALLBACK;
-
-        /* Return error status */
-        status =  HAL_ERROR;
-        break;
-    }
-  }
-  else if (HAL_ADC_STATE_RESET == hadc->State)
-  {
-    switch (CallbackID)
-    {
-      case HAL_ADC_MSPINIT_CB_ID :
-        hadc->MspInitCallback = HAL_ADC_MspInit;                   /* Legacy weak MspInit              */
-        break;
-
-      case HAL_ADC_MSPDEINIT_CB_ID :
-        hadc->MspDeInitCallback = HAL_ADC_MspDeInit;               /* Legacy weak MspDeInit            */
-        break;
-
-      default :
-        /* Update the error code */
-        hadc->ErrorCode |= HAL_ADC_ERROR_INVALID_CALLBACK;
-
-        /* Return error status */
-        status =  HAL_ERROR;
-        break;
-    }
-  }
-  else
-  {
-    /* Update the error code */
-    hadc->ErrorCode |= HAL_ADC_ERROR_INVALID_CALLBACK;
-
-    /* Return error status */
-    status =  HAL_ERROR;
-  }
-
-  return status;
-}
-
-#endif /* USE_HAL_ADC_REGISTER_CALLBACKS */
-
-/**
-  * @}
-  */
-
-/** @defgroup ADC_Exported_Functions_Group2 ADC Input and Output operation functions
-  * @brief    ADC IO operation functions
-  *
-@verbatim
- ===============================================================================
-                      ##### IO operation functions #####
- ===============================================================================
-    [..]  This section provides functions allowing to:
-      (+) Start conversion of regular group.
-      (+) Stop conversion of regular group.
-      (+) Poll for conversion complete on regular group.
-      (+) Poll for conversion event.
-      (+) Get result of regular channel conversion.
-      (+) Start conversion of regular group and enable interruptions.
-      (+) Stop conversion of regular group and disable interruptions.
-      (+) Handle ADC interrupt request
-      (+) Start conversion of regular group and enable DMA transfer.
-      (+) Stop conversion of regular group and disable ADC DMA transfer.
-@endverbatim
-  * @{
-  */
-
-/**
-  * @brief  Enable ADC, start conversion of regular group.
-  * @note   Interruptions enabled in this function: None.
-  * @param hadc ADC handle
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_ADC_Start(ADC_HandleTypeDef *hadc)
-{
-  HAL_StatusTypeDef tmp_hal_status;
-
-  /* Check the parameters */
-  assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
-
-  /* Perform ADC enable and conversion start if no conversion is on going */
-  if (LL_ADC_REG_IsConversionOngoing(hadc->Instance) == 0UL)
-  {
-    /* Process locked */
-    __HAL_LOCK(hadc);
-
-    /* Enable the ADC peripheral */
-    tmp_hal_status = ADC_Enable(hadc);
-
-    /* Start conversion if ADC is effectively enabled */
-    if (tmp_hal_status == HAL_OK)
-    {
-      /* Set ADC state                                                        */
-      /* - Clear state bitfield related to regular group conversion results   */
-      /* - Set state bitfield related to regular operation                    */
-      ADC_STATE_CLR_SET(hadc->State,
-                        HAL_ADC_STATE_READY | HAL_ADC_STATE_REG_EOC | HAL_ADC_STATE_REG_OVR | HAL_ADC_STATE_REG_EOSMP,
-                        HAL_ADC_STATE_REG_BUSY);
-
-      /* Set ADC error code */
-#if defined(ADC_SUPPORT_2_5_MSPS)
-      /* Reset all ADC error code fields */
-      ADC_CLEAR_ERRORCODE(hadc);
-#else
-      /* Check if a conversion is on going on ADC group injected */
-      if (HAL_IS_BIT_SET(hadc->State, HAL_ADC_STATE_INJ_BUSY))
-      {
-        /* Reset ADC error code fields related to regular conversions only */
-        CLEAR_BIT(hadc->ErrorCode, (HAL_ADC_ERROR_OVR | HAL_ADC_ERROR_DMA));
-      }
-      else
-      {
-        /* Reset all ADC error code fields */
-        ADC_CLEAR_ERRORCODE(hadc);
-      }
-#endif /* ADC_SUPPORT_2_5_MSPS */
-
-      /* Clear ADC group regular conversion flag and overrun flag               */
-      /* (To ensure of no unknown state from potential previous ADC operations) */
-      __HAL_ADC_CLEAR_FLAG(hadc, (ADC_FLAG_EOC | ADC_FLAG_EOS | ADC_FLAG_OVR));
-
-      /* Process unlocked */
-      /* Unlock before starting ADC conversions: in case of potential         */
-      /* interruption, to let the process to ADC IRQ Handler.                 */
-      __HAL_UNLOCK(hadc);
-
-      /* Enable conversion of regular group.                                  */
-      /* If software start has been selected, conversion starts immediately.  */
-      /* If external trigger has been selected, conversion will start at next */
-      /* trigger event.                                                       */
-      /* Start ADC group regular conversion */
-      LL_ADC_REG_StartConversion(hadc->Instance);
-    }
-    else
-    {
-      /* Process unlocked */
-      __HAL_UNLOCK(hadc);
-    }
-  }
-  else
-  {
-    tmp_hal_status = HAL_BUSY;
-  }
-
-  /* Return function status */
-  return tmp_hal_status;
-}
-
-/**
-  * @brief  Stop ADC conversion of regular group (and injected channels in
-  *         case of auto_injection mode), disable ADC peripheral.
-  * @note:  ADC peripheral disable is forcing stop of potential
-  *         conversion on injected group. If injected group is under use, it
-  *         should be preliminarily stopped using HAL_ADCEx_InjectedStop function.
-  * @param hadc ADC handle
-  * @retval HAL status.
-  */
-HAL_StatusTypeDef HAL_ADC_Stop(ADC_HandleTypeDef *hadc)
-{
-  HAL_StatusTypeDef tmp_hal_status;
-
-  /* Check the parameters */
-  assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
-
-  /* Process locked */
-  __HAL_LOCK(hadc);
-
-#if defined(ADC_SUPPORT_2_5_MSPS)
-  /* 1. Stop potential conversion on going, on ADC group regular */
-  tmp_hal_status = ADC_ConversionStop(hadc, ADC_REGULAR_GROUP);
-#else
-  /* 1. Stop potential conversion on going, on ADC groups regular and injected */
-  tmp_hal_status = ADC_ConversionStop(hadc, ADC_REGULAR_INJECTED_GROUP);
-#endif /* ADC_SUPPORT_2_5_MSPS */
-
-  /* Disable ADC peripheral if conversions are effectively stopped */
-  if (tmp_hal_status == HAL_OK)
-  {
-    /* 2. Disable the ADC peripheral */
-    tmp_hal_status = ADC_Disable(hadc);
-
-    /* Check if ADC is effectively disabled */
-    if (tmp_hal_status == HAL_OK)
-    {
-      /* Set ADC state */
-#if defined(ADC_SUPPORT_2_5_MSPS)
-      ADC_STATE_CLR_SET(hadc->State,
-                        HAL_ADC_STATE_REG_BUSY,
-                        HAL_ADC_STATE_READY);
-#else
-      ADC_STATE_CLR_SET(hadc->State,
-                        HAL_ADC_STATE_REG_BUSY | HAL_ADC_STATE_INJ_BUSY,
-                        HAL_ADC_STATE_READY);
-#endif /* ADC_SUPPORT_2_5_MSPS */
-    }
-  }
-
-  /* Process unlocked */
-  __HAL_UNLOCK(hadc);
-
-  /* Return function status */
-  return tmp_hal_status;
-}
-
-/**
-  * @brief  Wait for regular group conversion to be completed.
-  * @note   ADC conversion flags EOS (end of sequence) and EOC (end of
-  *         conversion) are cleared by this function, with an exception:
-  *         if low power feature "LowPowerAutoWait" is enabled, flags are
-  *         not cleared to not interfere with this feature until data register
-  *         is read using function HAL_ADC_GetValue().
-  * @note   This function cannot be used in a particular setup: ADC configured
-  *         in DMA mode and polling for end of each conversion (ADC init
-  *         parameter "EOCSelection" set to ADC_EOC_SINGLE_CONV).
-  *         In this case, DMA resets the flag EOC and polling cannot be
-  *         performed on each conversion. Nevertheless, polling can still
-  *         be performed on the complete sequence (ADC init
-  *         parameter "EOCSelection" set to ADC_EOC_SEQ_CONV).
-  * @param hadc ADC handle
-  * @param Timeout Timeout value in millisecond.
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_ADC_PollForConversion(ADC_HandleTypeDef *hadc, uint32_t Timeout)
-{
-  uint32_t tickstart;
-  uint32_t tmp_Flag_End;
-
-  /* Check the parameters */
-  assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
-
-  /* If end of conversion selected to end of sequence conversions */
-  if (hadc->Init.EOCSelection == ADC_EOC_SEQ_CONV)
-  {
-    tmp_Flag_End = ADC_FLAG_EOS;
-  }
-  /* If end of conversion selected to end of unitary conversion */
-  else /* ADC_EOC_SINGLE_CONV */
-  {
-    /* Verification that ADC configuration is compliant with polling for      */
-    /* each conversion:                                                       */
-    /* Particular case is ADC configured in DMA mode and ADC sequencer with   */
-    /* several ranks and polling for end of each conversion.                  */
-    /* For code simplicity sake, this particular case is generalized to       */
-    /* ADC configured in DMA mode and and polling for end of each conversion. */
-#if  defined(ADC_SUPPORT_2_5_MSPS)
-    if(READ_BIT(hadc->Instance->CFGR1, ADC_CFGR1_DMAEN) != 0UL)
-#else
-    if(READ_BIT(hadc->Instance->CFGR, ADC_CFGR_DMAEN) != 0UL)
-#endif /* ADC_SUPPORT_2_5_MSPS */
-    {
-      /* Update ADC state machine to error */
-      SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG);
-
-      return HAL_ERROR;
-    }
-    else
-    {
-      tmp_Flag_End = (ADC_FLAG_EOC);
-    }
-  }
-
-  /* Get tick count */
-  tickstart = HAL_GetTick();
-
-  /* Wait until End of unitary conversion or sequence conversions flag is raised */
-  while ((hadc->Instance->ISR & tmp_Flag_End) == 0UL)
-  {
-    /* Check if timeout is disabled (set to infinite wait) */
-    if (Timeout != HAL_MAX_DELAY)
-    {
-      if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0UL))
-      {
-        /* New check to avoid false timeout detection in case of preemption */
-        if ((hadc->Instance->ISR & tmp_Flag_End) == 0UL)
-        {
-          /* Update ADC state machine to timeout */
-          SET_BIT(hadc->State, HAL_ADC_STATE_TIMEOUT);
-
-          /* Process unlocked */
-          __HAL_UNLOCK(hadc);
-
-          return HAL_TIMEOUT;
-        }
-      }
-    }
-  }
-
-  /* Update ADC state machine */
-  SET_BIT(hadc->State, HAL_ADC_STATE_REG_EOC);
-
-  /* Determine whether any further conversion upcoming on group regular       */
-  /* by external trigger, continuous mode or scan sequence on going.          */
-  if ((LL_ADC_REG_IsTriggerSourceSWStart(hadc->Instance) != 0UL)
-      && (hadc->Init.ContinuousConvMode == DISABLE)
-     )
-  {
-    /* Check whether end of sequence is reached */
-    if (__HAL_ADC_GET_FLAG(hadc, ADC_FLAG_EOS))
-    {
-      /* Set ADC state */
-      CLEAR_BIT(hadc->State, HAL_ADC_STATE_REG_BUSY);
-
-      if ((hadc->State & HAL_ADC_STATE_INJ_BUSY) == 0UL)
-      {
-        SET_BIT(hadc->State, HAL_ADC_STATE_READY);
-      }
-    }
-  }
-
-  /* Clear polled flag */
-  if (tmp_Flag_End == ADC_FLAG_EOS)
-  {
-    __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_EOS);
-  }
-  else
-  {
-    /* Clear end of conversion EOC flag of regular group if low power feature */
-    /* "LowPowerAutoWait " is disabled, to not interfere with this feature    */
-    /* until data register is read using function HAL_ADC_GetValue().         */
-#if  defined(ADC_SUPPORT_2_5_MSPS)
-    if (READ_BIT(hadc->Instance->CFGR1, ADC_CFGR1_WAIT) == 0UL)
-#else
-    if (READ_BIT(hadc->Instance->CFGR, ADC_CFGR_AUTDLY) == 0UL)
-#endif /* ADC_SUPPORT_2_5_MSPS */
-    {
-      __HAL_ADC_CLEAR_FLAG(hadc, (ADC_FLAG_EOC | ADC_FLAG_EOS));
-    }
-  }
-
-  /* Return function status */
-  return HAL_OK;
-}
-
-/**
-  * @brief  Poll for ADC event.
-  * @param hadc ADC handle
-  * @param EventType the ADC event type.
-  *          This parameter can be one of the following values:
-  *            @arg @ref ADC_EOSMP_EVENT  ADC End of Sampling event
-  *            @arg @ref ADC_AWD1_EVENT   ADC Analog watchdog 1 event (main analog watchdog, present on all STM32 devices)
-  *            @arg @ref ADC_AWD2_EVENT   ADC Analog watchdog 2 event (additional analog watchdog, not present on all STM32 families)
-  *            @arg @ref ADC_AWD3_EVENT   ADC Analog watchdog 3 event (additional analog watchdog, not present on all STM32 families)
-  *            @arg @ref ADC_OVR_EVENT    ADC Overrun event
-  *            @arg @ref ADC_JQOVF_EVENT  ADC Injected context queue overflow event (1)
-  *
-  *         (1) On STM32WB series, parameter not available on devices: STM32WB10xx, STM32WB15xx, STM32WB1Mxx.
-  * @param Timeout Timeout value in millisecond.
-  * @note   The relevant flag is cleared if found to be set, except for ADC_FLAG_OVR.
-  *         Indeed, the latter is reset only if hadc->Init.Overrun field is set
-  *         to ADC_OVR_DATA_OVERWRITTEN. Otherwise, data register may be potentially overwritten
-  *         by a new converted data as soon as OVR is cleared.
-  *         To reset OVR flag once the preserved data is retrieved, the user can resort
-  *         to macro __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_OVR);
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_ADC_PollForEvent(ADC_HandleTypeDef *hadc, uint32_t EventType, uint32_t Timeout)
-{
-  uint32_t tickstart;
-
-  /* Check the parameters */
-  assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
-  assert_param(IS_ADC_EVENT_TYPE(EventType));
-
-  /* Get tick count */
-  tickstart = HAL_GetTick();
-
-  /* Check selected event flag */
-  while (__HAL_ADC_GET_FLAG(hadc, EventType) == 0UL)
-  {
-    /* Check if timeout is disabled (set to infinite wait) */
-    if (Timeout != HAL_MAX_DELAY)
-    {
-      if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0UL))
-      {
-        /* New check to avoid false timeout detection in case of preemption */
-        if (__HAL_ADC_GET_FLAG(hadc, EventType) == 0UL)
-        {
-          /* Update ADC state machine to timeout */
-          SET_BIT(hadc->State, HAL_ADC_STATE_TIMEOUT);
-
-          /* Process unlocked */
-          __HAL_UNLOCK(hadc);
-
-          return HAL_TIMEOUT;
-        }
-      }
-    }
-  }
-
-  switch (EventType)
-  {
-    /* End Of Sampling event */
-    case ADC_EOSMP_EVENT:
-      /* Set ADC state */
-      SET_BIT(hadc->State, HAL_ADC_STATE_REG_EOSMP);
-
-      /* Clear the End Of Sampling flag */
-      __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_EOSMP);
-
-      break;
-
-    /* Analog watchdog (level out of window) event */
-    /* Note: In case of several analog watchdog enabled, if needed to know      */
-    /* which one triggered and on which ADCx, test ADC state of analog watchdog */
-    /* flags HAL_ADC_STATE_AWD1/2/3 using function "HAL_ADC_GetState()".        */
-    /* For example:                                                             */
-    /*  " if ((HAL_ADC_GetState(hadc1) & HAL_ADC_STATE_AWD1) != 0UL) "          */
-    /*  " if ((HAL_ADC_GetState(hadc1) & HAL_ADC_STATE_AWD2) != 0UL) "          */
-    /*  " if ((HAL_ADC_GetState(hadc1) & HAL_ADC_STATE_AWD3) != 0UL) "          */
-
-    /* Check analog watchdog 1 flag */
-    case ADC_AWD_EVENT:
-      /* Set ADC state */
-      SET_BIT(hadc->State, HAL_ADC_STATE_AWD1);
-
-      /* Clear ADC analog watchdog flag */
-      __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_AWD1);
-
-      break;
-
-    /* Check analog watchdog 2 flag */
-    case ADC_AWD2_EVENT:
-      /* Set ADC state */
-      SET_BIT(hadc->State, HAL_ADC_STATE_AWD2);
-
-      /* Clear ADC analog watchdog flag */
-      __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_AWD2);
-
-      break;
-
-    /* Check analog watchdog 3 flag */
-    case ADC_AWD3_EVENT:
-      /* Set ADC state */
-      SET_BIT(hadc->State, HAL_ADC_STATE_AWD3);
-
-      /* Clear ADC analog watchdog flag */
-      __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_AWD3);
-
-      break;
-
-#if  defined(ADC_SUPPORT_2_5_MSPS)
-/* Feature "ADC group injected" not available on ADC peripheral of this STM32WB device */
-#else
-    /* Injected context queue overflow event */
-    case ADC_JQOVF_EVENT:
-      /* Set ADC state */
-      SET_BIT(hadc->State, HAL_ADC_STATE_INJ_JQOVF);
-
-      /* Set ADC error code to Injected context queue overflow */
-      SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_JQOVF);
-
-      /* Clear ADC Injected context queue overflow flag */
-      __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_JQOVF);
-
-      break;
-#endif /* ADC_SUPPORT_2_5_MSPS */
-
-    /* Overrun event */
-    default: /* Case ADC_OVR_EVENT */
-      /* If overrun is set to overwrite previous data, overrun event is not     */
-      /* considered as an error.                                                */
-      /* (cf ref manual "Managing conversions without using the DMA and without */
-      /* overrun ")                                                             */
-      if (hadc->Init.Overrun == ADC_OVR_DATA_PRESERVED)
-      {
-        /* Set ADC state */
-        SET_BIT(hadc->State, HAL_ADC_STATE_REG_OVR);
-
-        /* Set ADC error code to overrun */
-        SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_OVR);
-      }
-      else
-      {
-        /* Clear ADC Overrun flag only if Overrun is set to ADC_OVR_DATA_OVERWRITTEN
-           otherwise, data register is potentially overwritten by new converted data as soon
-           as OVR is cleared. */
-        __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_OVR);
-      }
-      break;
-  }
-
-  /* Return function status */
-  return HAL_OK;
-}
-
-/**
-  * @brief  Enable ADC, start conversion of regular group with interruption.
-  * @note   Interruptions enabled in this function according to initialization
-  *         setting : EOC (end of conversion), EOS (end of sequence),
-  *         OVR overrun.
-  *         Each of these interruptions has its dedicated callback function.
-  * @note   To guarantee a proper reset of all interruptions once all the needed
-  *         conversions are obtained, HAL_ADC_Stop_IT() must be called to ensure
-  *         a correct stop of the IT-based conversions.
-  * @note   By default, HAL_ADC_Start_IT() does not enable the End Of Sampling
-  *         interruption. If required (e.g. in case of oversampling with trigger
-  *         mode), the user must:
-  *          1. first clear the EOSMP flag if set with macro __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_EOSMP)
-  *          2. then enable the EOSMP interrupt with macro __HAL_ADC_ENABLE_IT(hadc, ADC_IT_EOSMP)
-  *          before calling HAL_ADC_Start_IT().
-  * @param hadc ADC handle
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_ADC_Start_IT(ADC_HandleTypeDef *hadc)
-{
-  HAL_StatusTypeDef tmp_hal_status;
-
-  /* Check the parameters */
-  assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
-
-  /* Perform ADC enable and conversion start if no conversion is on going */
-  if (LL_ADC_REG_IsConversionOngoing(hadc->Instance) == 0UL)
-  {
-    /* Process locked */
-    __HAL_LOCK(hadc);
-
-    /* Enable the ADC peripheral */
-    tmp_hal_status = ADC_Enable(hadc);
-
-    /* Start conversion if ADC is effectively enabled */
-    if (tmp_hal_status == HAL_OK)
-    {
-      /* Set ADC state                                                        */
-      /* - Clear state bitfield related to regular group conversion results   */
-      /* - Set state bitfield related to regular operation                    */
-      ADC_STATE_CLR_SET(hadc->State,
-                        HAL_ADC_STATE_READY | HAL_ADC_STATE_REG_EOC | HAL_ADC_STATE_REG_OVR | HAL_ADC_STATE_REG_EOSMP,
-                        HAL_ADC_STATE_REG_BUSY);
-
-      /* Set ADC error code */
-#if defined(ADC_SUPPORT_2_5_MSPS)
-      /* Reset all ADC error code fields */
-      ADC_CLEAR_ERRORCODE(hadc);
-#else
-      /* Check if a conversion is on going on ADC group injected */
-      if ((hadc->State & HAL_ADC_STATE_INJ_BUSY) != 0UL)
-      {
-        /* Reset ADC error code fields related to regular conversions only */
-        CLEAR_BIT(hadc->ErrorCode, (HAL_ADC_ERROR_OVR | HAL_ADC_ERROR_DMA));
-      }
-      else
-      {
-        /* Reset all ADC error code fields */
-        ADC_CLEAR_ERRORCODE(hadc);
-      }
-#endif /* ADC_SUPPORT_2_5_MSPS */
-
-      /* Clear ADC group regular conversion flag and overrun flag               */
-      /* (To ensure of no unknown state from potential previous ADC operations) */
-      __HAL_ADC_CLEAR_FLAG(hadc, (ADC_FLAG_EOC | ADC_FLAG_EOS | ADC_FLAG_OVR));
-
-      /* Process unlocked */
-      /* Unlock before starting ADC conversions: in case of potential         */
-      /* interruption, to let the process to ADC IRQ Handler.                 */
-      __HAL_UNLOCK(hadc);
-
-      /* Disable all interruptions before enabling the desired ones */
-      __HAL_ADC_DISABLE_IT(hadc, (ADC_IT_EOC | ADC_IT_EOS | ADC_IT_OVR));
-
-      /* Enable ADC end of conversion interrupt */
-      switch (hadc->Init.EOCSelection)
-      {
-        case ADC_EOC_SEQ_CONV:
-          __HAL_ADC_ENABLE_IT(hadc, ADC_IT_EOS);
-          break;
-        /* case ADC_EOC_SINGLE_CONV */
-        default:
-          __HAL_ADC_ENABLE_IT(hadc, ADC_IT_EOC);
-          break;
-      }
-
-      /* Enable ADC overrun interrupt */
-      /* If hadc->Init.Overrun is set to ADC_OVR_DATA_PRESERVED, only then is
-         ADC_IT_OVR enabled; otherwise data overwrite is considered as normal
-         behavior and no CPU time is lost for a non-processed interruption */
-      if (hadc->Init.Overrun == ADC_OVR_DATA_PRESERVED)
-      {
-        __HAL_ADC_ENABLE_IT(hadc, ADC_IT_OVR);
-      }
-
-      /* Enable conversion of regular group.                                  */
-      /* If software start has been selected, conversion starts immediately.  */
-      /* If external trigger has been selected, conversion will start at next */
-      /* trigger event.                                                       */
-      /* Start ADC group regular conversion */
-      LL_ADC_REG_StartConversion(hadc->Instance);
-    }
-    else
-    {
-      /* Process unlocked */
-      __HAL_UNLOCK(hadc);
-    }
-
-  }
-  else
-  {
-    tmp_hal_status = HAL_BUSY;
-  }
-
-  /* Return function status */
-  return tmp_hal_status;
-}
-
-/**
-  * @brief  Stop ADC conversion of regular group (and injected group in
-  *         case of auto_injection mode), disable interrution of
-  *         end-of-conversion, disable ADC peripheral.
-  * @param hadc ADC handle
-  * @retval HAL status.
-  */
-HAL_StatusTypeDef HAL_ADC_Stop_IT(ADC_HandleTypeDef *hadc)
-{
-  HAL_StatusTypeDef tmp_hal_status;
-
-  /* Check the parameters */
-  assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
-
-  /* Process locked */
-  __HAL_LOCK(hadc);
-
-#if defined(ADC_SUPPORT_2_5_MSPS)
-  /* 1. Stop potential conversion on going, on ADC group regular */
-  tmp_hal_status = ADC_ConversionStop(hadc, ADC_REGULAR_GROUP);
-#else
-  /* 1. Stop potential conversion on going, on ADC groups regular and injected */
-  tmp_hal_status = ADC_ConversionStop(hadc, ADC_REGULAR_INJECTED_GROUP);
-#endif /* ADC_SUPPORT_2_5_MSPS */
-
-  /* Disable ADC peripheral if conversions are effectively stopped */
-  if (tmp_hal_status == HAL_OK)
-  {
-    /* Disable ADC end of conversion interrupt for regular group */
-    /* Disable ADC overrun interrupt */
-    __HAL_ADC_DISABLE_IT(hadc, (ADC_IT_EOC | ADC_IT_EOS | ADC_IT_OVR));
-
-    /* 2. Disable the ADC peripheral */
-    tmp_hal_status = ADC_Disable(hadc);
-
-    /* Check if ADC is effectively disabled */
-    if (tmp_hal_status == HAL_OK)
-    {
-      /* Set ADC state */
-#if defined(ADC_SUPPORT_2_5_MSPS)
-      ADC_STATE_CLR_SET(hadc->State,
-                        HAL_ADC_STATE_REG_BUSY,
-                        HAL_ADC_STATE_READY);
-#else
-      ADC_STATE_CLR_SET(hadc->State,
-                        HAL_ADC_STATE_REG_BUSY | HAL_ADC_STATE_INJ_BUSY,
-                        HAL_ADC_STATE_READY);
-#endif /* ADC_SUPPORT_2_5_MSPS */
-    }
-  }
-
-  /* Process unlocked */
-  __HAL_UNLOCK(hadc);
-
-  /* Return function status */
-  return tmp_hal_status;
-}
-
-/**
-  * @brief  Enable ADC, start conversion of regular group and transfer result through DMA.
-  * @note   Interruptions enabled in this function:
-  *         overrun (if applicable), DMA half transfer, DMA transfer complete.
-  *         Each of these interruptions has its dedicated callback function.
-  * @param hadc ADC handle
-  * @param pData Destination Buffer address.
-  * @param Length Number of data to be transferred from ADC peripheral to memory
-  * @retval HAL status.
-  */
-HAL_StatusTypeDef HAL_ADC_Start_DMA(ADC_HandleTypeDef *hadc, uint32_t *pData, uint32_t Length)
-{
-  HAL_StatusTypeDef tmp_hal_status;
-
-  /* Check the parameters */
-  assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
-
-  /* Perform ADC enable and conversion start if no conversion is on going */
-  if (LL_ADC_REG_IsConversionOngoing(hadc->Instance) == 0UL)
-  {
-    /* Process locked */
-    __HAL_LOCK(hadc);
-
-      /* Enable the ADC peripheral */
-      tmp_hal_status = ADC_Enable(hadc);
-
-      /* Start conversion if ADC is effectively enabled */
-      if (tmp_hal_status == HAL_OK)
-      {
-        /* Set ADC state                                                        */
-        /* - Clear state bitfield related to regular group conversion results   */
-        /* - Set state bitfield related to regular operation                    */
-        ADC_STATE_CLR_SET(hadc->State,
-                          HAL_ADC_STATE_READY | HAL_ADC_STATE_REG_EOC | HAL_ADC_STATE_REG_OVR | HAL_ADC_STATE_REG_EOSMP,
-                          HAL_ADC_STATE_REG_BUSY);
-
-#if defined(ADC_SUPPORT_2_5_MSPS)
-        /* Reset all ADC error code fields */
-        ADC_CLEAR_ERRORCODE(hadc);
-#else
-        /* Check if a conversion is on going on ADC group injected */
-        if ((hadc->State & HAL_ADC_STATE_INJ_BUSY) != 0UL)
-        {
-          /* Reset ADC error code fields related to regular conversions only */
-          CLEAR_BIT(hadc->ErrorCode, (HAL_ADC_ERROR_OVR | HAL_ADC_ERROR_DMA));
-        }
-        else
-        {
-          /* Reset all ADC error code fields */
-          ADC_CLEAR_ERRORCODE(hadc);
-        }
-#endif /* ADC_SUPPORT_2_5_MSPS */
-
-        /* Set the DMA transfer complete callback */
-        hadc->DMA_Handle->XferCpltCallback = ADC_DMAConvCplt;
-
-        /* Set the DMA half transfer complete callback */
-        hadc->DMA_Handle->XferHalfCpltCallback = ADC_DMAHalfConvCplt;
-
-        /* Set the DMA error callback */
-        hadc->DMA_Handle->XferErrorCallback = ADC_DMAError;
-
-
-        /* Manage ADC and DMA start: ADC overrun interruption, DMA start,     */
-        /* ADC start (in case of SW start):                                   */
-
-        /* Clear regular group conversion flag and overrun flag               */
-        /* (To ensure of no unknown state from potential previous ADC         */
-        /* operations)                                                        */
-        __HAL_ADC_CLEAR_FLAG(hadc, (ADC_FLAG_EOC | ADC_FLAG_EOS | ADC_FLAG_OVR));
-
-        /* Process unlocked */
-        /* Unlock before starting ADC conversions: in case of potential         */
-        /* interruption, to let the process to ADC IRQ Handler.                 */
-        __HAL_UNLOCK(hadc);
-
-        /* With DMA, overrun event is always considered as an error even if
-           hadc->Init.Overrun is set to ADC_OVR_DATA_OVERWRITTEN. Therefore,
-           ADC_IT_OVR is enabled. */
-        __HAL_ADC_ENABLE_IT(hadc, ADC_IT_OVR);
-
-        /* Enable ADC DMA mode */
-#if  defined(ADC_SUPPORT_2_5_MSPS)
-        SET_BIT(hadc->Instance->CFGR1, ADC_CFGR1_DMAEN);
-#else
-        SET_BIT(hadc->Instance->CFGR, ADC_CFGR_DMAEN);
-#endif /* ADC_SUPPORT_2_5_MSPS */
-
-        /* Start the DMA channel */
-        tmp_hal_status = HAL_DMA_Start_IT(hadc->DMA_Handle, (uint32_t)&hadc->Instance->DR, (uint32_t)pData, Length);
-
-        /* Enable conversion of regular group.                                  */
-        /* If software start has been selected, conversion starts immediately.  */
-        /* If external trigger has been selected, conversion will start at next */
-        /* trigger event.                                                       */
-        /* Start ADC group regular conversion */
-        LL_ADC_REG_StartConversion(hadc->Instance);
-      }
-      else
-      {
-        /* Process unlocked */
-        __HAL_UNLOCK(hadc);
-      }
-  }
-  else
-  {
-    tmp_hal_status = HAL_BUSY;
-  }
-
-  /* Return function status */
-  return tmp_hal_status;
-}
-
-/**
-  * @brief  Stop ADC conversion of regular group (and injected group in
-  *         case of auto_injection mode), disable ADC DMA transfer, disable
-  *         ADC peripheral.
-  * @note:  ADC peripheral disable is forcing stop of potential
-  *         conversion on ADC group injected. If ADC group injected is under use, it
-  *         should be preliminarily stopped using HAL_ADCEx_InjectedStop function.
-  * @param hadc ADC handle
-  * @retval HAL status.
-  */
-HAL_StatusTypeDef HAL_ADC_Stop_DMA(ADC_HandleTypeDef *hadc)
-{
-  HAL_StatusTypeDef tmp_hal_status;
-
-  /* Check the parameters */
-  assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
-
-  /* Process locked */
-  __HAL_LOCK(hadc);
-
-  /* 1. Stop potential ADC group regular conversion on going */
-#if defined(ADC_SUPPORT_2_5_MSPS)
-  tmp_hal_status = ADC_ConversionStop(hadc, ADC_REGULAR_GROUP);
-#else
-  tmp_hal_status = ADC_ConversionStop(hadc, ADC_REGULAR_INJECTED_GROUP);
-#endif /* ADC_SUPPORT_2_5_MSPS */
-
-  /* Disable ADC peripheral if conversions are effectively stopped */
-  if (tmp_hal_status == HAL_OK)
-  {
-    /* Disable ADC DMA (ADC DMA configuration of continuous requests is kept) */
-#if  defined(ADC_SUPPORT_2_5_MSPS)
-    CLEAR_BIT(hadc->Instance->CFGR1, ADC_CFGR1_DMAEN);
-#else
-    CLEAR_BIT(hadc->Instance->CFGR, ADC_CFGR_DMAEN);
-#endif /* ADC_SUPPORT_2_5_MSPS */
-
-    /* Disable the DMA channel (in case of DMA in circular mode or stop       */
-    /* while DMA transfer is on going)                                        */
-    if (hadc->DMA_Handle->State == HAL_DMA_STATE_BUSY)
-    {
-      tmp_hal_status = HAL_DMA_Abort(hadc->DMA_Handle);
-
-      /* Check if DMA channel effectively disabled */
-      if (tmp_hal_status != HAL_OK)
-      {
-        /* Update ADC state machine to error */
-        SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_DMA);
-      }
-    }
-
-    /* Disable ADC overrun interrupt */
-    __HAL_ADC_DISABLE_IT(hadc, ADC_IT_OVR);
-
-    /* 2. Disable the ADC peripheral */
-    /* Update "tmp_hal_status" only if DMA channel disabling passed,          */
-    /* to keep in memory a potential failing status.                          */
-    if (tmp_hal_status == HAL_OK)
-    {
-      tmp_hal_status = ADC_Disable(hadc);
-    }
-    else
-    {
-      (void)ADC_Disable(hadc);
-    }
-
-    /* Check if ADC is effectively disabled */
-    if (tmp_hal_status == HAL_OK)
-    {
-      /* Set ADC state */
-#if defined(ADC_SUPPORT_2_5_MSPS)
-      ADC_STATE_CLR_SET(hadc->State,
-                        HAL_ADC_STATE_REG_BUSY,
-                        HAL_ADC_STATE_READY);
-#else
-      ADC_STATE_CLR_SET(hadc->State,
-                        HAL_ADC_STATE_REG_BUSY | HAL_ADC_STATE_INJ_BUSY,
-                        HAL_ADC_STATE_READY);
-#endif /* ADC_SUPPORT_2_5_MSPS */
-    }
-
-  }
-
-  /* Process unlocked */
-  __HAL_UNLOCK(hadc);
-
-  /* Return function status */
-  return tmp_hal_status;
-}
-
-/**
-  * @brief  Get ADC regular group conversion result.
-  * @note   Reading register DR automatically clears ADC flag EOC
-  *         (ADC group regular end of unitary conversion).
-  * @note   This function does not clear ADC flag EOS
-  *         (ADC group regular end of sequence conversion).
-  *         Occurrence of flag EOS rising:
-  *          - If sequencer is composed of 1 rank, flag EOS is equivalent
-  *            to flag EOC.
-  *          - If sequencer is composed of several ranks, during the scan
-  *            sequence flag EOC only is raised, at the end of the scan sequence
-  *            both flags EOC and EOS are raised.
-  *         To clear this flag, either use function:
-  *         in programming model IT: @ref HAL_ADC_IRQHandler(), in programming
-  *         model polling: @ref HAL_ADC_PollForConversion()
-  *         or @ref __HAL_ADC_CLEAR_FLAG(&hadc, ADC_FLAG_EOS).
-  * @param hadc ADC handle
-  * @retval ADC group regular conversion data
-  */
-uint32_t HAL_ADC_GetValue(const ADC_HandleTypeDef *hadc)
-{
-  /* Check the parameters */
-  assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
-
-  /* Note: EOC flag is not cleared here by software because automatically     */
-  /*       cleared by hardware when reading register DR.                      */
-
-  /* Return ADC converted value */
-  return hadc->Instance->DR;
-}
-
-/**
-  * @brief  Handle ADC interrupt request.
-  * @param hadc ADC handle
-  * @retval None
-  */
-void HAL_ADC_IRQHandler(ADC_HandleTypeDef *hadc)
-{
-  uint32_t overrun_error = 0UL; /* flag set if overrun occurrence has to be considered as an error */
-  uint32_t tmp_isr = hadc->Instance->ISR;
-  uint32_t tmp_ier = hadc->Instance->IER;
-#if !defined(ADC_SUPPORT_2_5_MSPS)
-  uint32_t tmp_adc_inj_is_trigger_source_sw_start;
-  uint32_t tmp_adc_reg_is_trigger_source_sw_start;
-  uint32_t tmp_cfgr;
-#endif  /* !ADC_SUPPORT_2_5_MSPS */
-
-  /* Check the parameters */
-  assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
-  assert_param(IS_ADC_EOC_SELECTION(hadc->Init.EOCSelection));
-
-  /* ========== Check End of Sampling flag for ADC group regular ========== */
-  if (((tmp_isr & ADC_FLAG_EOSMP) == ADC_FLAG_EOSMP) && ((tmp_ier & ADC_IT_EOSMP) == ADC_IT_EOSMP))
-  {
-    /* Update state machine on end of sampling status if not in error state */
-    if ((hadc->State & HAL_ADC_STATE_ERROR_INTERNAL) == 0UL)
-    {
-      /* Set ADC state */
-      SET_BIT(hadc->State, HAL_ADC_STATE_REG_EOSMP);
-    }
-
-    /* End Of Sampling callback */
-#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1)
-    hadc->EndOfSamplingCallback(hadc);
-#else
-    HAL_ADCEx_EndOfSamplingCallback(hadc);
-#endif /* USE_HAL_ADC_REGISTER_CALLBACKS */
-
-    /* Clear regular group conversion flag */
-    __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_EOSMP);
-  }
-
-  /* ====== Check ADC group regular end of unitary conversion sequence conversions ===== */
-  if ((((tmp_isr & ADC_FLAG_EOC) == ADC_FLAG_EOC) && ((tmp_ier & ADC_IT_EOC) == ADC_IT_EOC)) ||
-      (((tmp_isr & ADC_FLAG_EOS) == ADC_FLAG_EOS) && ((tmp_ier & ADC_IT_EOS) == ADC_IT_EOS)))
-  {
-    /* Update state machine on conversion status if not in error state */
-    if ((hadc->State & HAL_ADC_STATE_ERROR_INTERNAL) == 0UL)
-    {
-      /* Set ADC state */
-      SET_BIT(hadc->State, HAL_ADC_STATE_REG_EOC);
-    }
-
-    /* Determine whether any further conversion upcoming on group regular     */
-    /* by external trigger, continuous mode or scan sequence on going         */
-    /* to disable interruption.                                               */
-    if (LL_ADC_REG_IsTriggerSourceSWStart(hadc->Instance) != 0UL)
-    {
-      /* Carry on if continuous mode is disabled */
-#if  defined(ADC_SUPPORT_2_5_MSPS)
-      if (READ_BIT (hadc->Instance->CFGR1, ADC_CFGR1_CONT) != ADC_CFGR1_CONT)
-#else
-      if (READ_BIT (hadc->Instance->CFGR, ADC_CFGR_CONT) != ADC_CFGR_CONT)
-#endif /* ADC_SUPPORT_2_5_MSPS */
-      {
-        /* If End of Sequence is reached, disable interrupts */
-        if (__HAL_ADC_GET_FLAG(hadc, ADC_FLAG_EOS))
-        {
-          /* Allowed to modify bits ADC_IT_EOC/ADC_IT_EOS only if bit         */
-          /* ADSTART==0 (no conversion on going)                              */
-          if (LL_ADC_REG_IsConversionOngoing(hadc->Instance) == 0UL)
-          {
-            /* Disable ADC end of sequence conversion interrupt */
-            /* Note: Overrun interrupt was enabled with EOC interrupt in      */
-            /* HAL_Start_IT(), but is not disabled here because can be used   */
-            /* by overrun IRQ process below.                                  */
-            __HAL_ADC_DISABLE_IT(hadc, ADC_IT_EOC | ADC_IT_EOS);
-
-            /* Set ADC state */
-            CLEAR_BIT(hadc->State, HAL_ADC_STATE_REG_BUSY);
-
-            if ((hadc->State & HAL_ADC_STATE_INJ_BUSY) == 0UL)
-            {
-              SET_BIT(hadc->State, HAL_ADC_STATE_READY);
-            }
-          }
-          else
-          {
-            /* Change ADC state to error state */
-            SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL);
-
-            /* Set ADC error code to ADC peripheral internal error */
-            SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL);
-          }
-        }
-      }
-    }
-
-    /* Conversion complete callback */
-    /* Note: Into callback function "HAL_ADC_ConvCpltCallback()",             */
-    /*       to determine if conversion has been triggered from EOC or EOS,   */
-    /*       possibility to use:                                              */
-    /*        " if( __HAL_ADC_GET_FLAG(&hadc, ADC_FLAG_EOS)) "                */
-#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1)
-    hadc->ConvCpltCallback(hadc);
-#else
-    HAL_ADC_ConvCpltCallback(hadc);
-#endif /* USE_HAL_ADC_REGISTER_CALLBACKS */
-
-    /* Clear regular group conversion flag */
-    /* Note: in case of overrun set to ADC_OVR_DATA_PRESERVED, end of         */
-    /*       conversion flags clear induces the release of the preserved data.*/
-    /*       Therefore, if the preserved data value is needed, it must be     */
-    /*       read preliminarily into HAL_ADC_ConvCpltCallback().              */
-    __HAL_ADC_CLEAR_FLAG(hadc, (ADC_FLAG_EOC | ADC_FLAG_EOS));
-  }
-
-#if  defined(ADC_SUPPORT_2_5_MSPS)
-/* Feature "ADC group injected" not available on ADC peripheral of this STM32WB device */
-#else
-  /* ====== Check ADC group injected end of unitary conversion sequence conversions ===== */
-  if ((((tmp_isr & ADC_FLAG_JEOC) == ADC_FLAG_JEOC) && ((tmp_ier & ADC_IT_JEOC) == ADC_IT_JEOC)) ||
-      (((tmp_isr & ADC_FLAG_JEOS) == ADC_FLAG_JEOS) && ((tmp_ier & ADC_IT_JEOS) == ADC_IT_JEOS)))
-  {
-    /* Update state machine on conversion status if not in error state */
-    if ((hadc->State & HAL_ADC_STATE_ERROR_INTERNAL) == 0UL)
-    {
-      /* Set ADC state */
-      SET_BIT(hadc->State, HAL_ADC_STATE_INJ_EOC);
-    }
-
-    /* Retrieve ADC configuration */
-    tmp_adc_inj_is_trigger_source_sw_start = LL_ADC_INJ_IsTriggerSourceSWStart(hadc->Instance);
-    tmp_adc_reg_is_trigger_source_sw_start = LL_ADC_REG_IsTriggerSourceSWStart(hadc->Instance);
-    tmp_cfgr = READ_REG(hadc->Instance->CFGR);
-
-    /* Disable interruption if no further conversion upcoming by injected     */
-    /* external trigger or by automatic injected conversion with regular      */
-    /* group having no further conversion upcoming (same conditions as        */
-    /* regular group interruption disabling above),                           */
-    /* and if injected scan sequence is completed.                            */
-    if (tmp_adc_inj_is_trigger_source_sw_start != 0UL)
-    {
-      if ((READ_BIT(tmp_cfgr, ADC_CFGR_JAUTO) == 0UL) ||
-          ((tmp_adc_reg_is_trigger_source_sw_start != 0UL) &&
-           (READ_BIT(tmp_cfgr, ADC_CFGR_CONT) == 0UL)))
-      {
-        /* If End of Sequence is reached, disable interrupts */
-        if (__HAL_ADC_GET_FLAG(hadc, ADC_FLAG_JEOS))
-        {
-          /* Particular case if injected contexts queue is enabled:             */
-          /* when the last context has been fully processed, JSQR is reset      */
-          /* by the hardware. Even if no injected conversion is planned to come */
-          /* (queue empty, triggers are ignored), it can start again            */
-          /* immediately after setting a new context (JADSTART is still set).   */
-          /* Therefore, state of HAL ADC injected group is kept to busy.        */
-          if (READ_BIT(hadc->Instance->CFGR, ADC_CFGR_JQM) == 0UL)
-          {
-            /* Allowed to modify bits ADC_IT_JEOC/ADC_IT_JEOS only if bit       */
-            /* JADSTART==0 (no conversion on going)                             */
-            if (LL_ADC_INJ_IsConversionOngoing(hadc->Instance) == 0UL)
-            {
-              /* Disable ADC end of sequence conversion interrupt  */
-              __HAL_ADC_DISABLE_IT(hadc, ADC_IT_JEOC | ADC_IT_JEOS);
-
-              /* Set ADC state */
-              CLEAR_BIT(hadc->State, HAL_ADC_STATE_INJ_BUSY);
-
-              if ((hadc->State & HAL_ADC_STATE_REG_BUSY) == 0UL)
-              {
-                SET_BIT(hadc->State, HAL_ADC_STATE_READY);
-              }
-            }
-            else
-            {
-              /* Update ADC state machine to error */
-              SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL);
-
-              /* Set ADC error code to ADC peripheral internal error */
-              SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL);
-            }
-          }
-        }
-      }
-    }
-
-    /* Injected Conversion complete callback */
-    /* Note:  HAL_ADCEx_InjectedConvCpltCallback can resort to
-              if( __HAL_ADC_GET_FLAG(&hadc, ADC_FLAG_JEOS)) or
-              if( __HAL_ADC_GET_FLAG(&hadc, ADC_FLAG_JEOC)) to determine whether
-              interruption has been triggered by end of conversion or end of
-              sequence.    */
-#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1)
-    hadc->InjectedConvCpltCallback(hadc);
-#else
-    HAL_ADCEx_InjectedConvCpltCallback(hadc);
-#endif /* USE_HAL_ADC_REGISTER_CALLBACKS */
-
-    /* Clear injected group conversion flag */
-    __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_JEOC | ADC_FLAG_JEOS);
-  }
-#endif /* ADC_SUPPORT_2_5_MSPS */
-
-  /* ========== Check Analog watchdog 1 flag ========== */
-  if (((tmp_isr & ADC_FLAG_AWD1) == ADC_FLAG_AWD1) && ((tmp_ier & ADC_IT_AWD1) == ADC_IT_AWD1))
-  {
-    /* Set ADC state */
-    SET_BIT(hadc->State, HAL_ADC_STATE_AWD1);
-
-    /* Level out of window 1 callback */
-#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1)
-    hadc->LevelOutOfWindowCallback(hadc);
-#else
-    HAL_ADC_LevelOutOfWindowCallback(hadc);
-#endif /* USE_HAL_ADC_REGISTER_CALLBACKS */
-
-    /* Clear ADC analog watchdog flag */
-    __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_AWD1);
-  }
-
-  /* ========== Check analog watchdog 2 flag ========== */
-  if (((tmp_isr & ADC_FLAG_AWD2) == ADC_FLAG_AWD2) && ((tmp_ier & ADC_IT_AWD2) == ADC_IT_AWD2))
-  {
-    /* Set ADC state */
-    SET_BIT(hadc->State, HAL_ADC_STATE_AWD2);
-
-    /* Level out of window 2 callback */
-#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1)
-    hadc->LevelOutOfWindow2Callback(hadc);
-#else
-    HAL_ADCEx_LevelOutOfWindow2Callback(hadc);
-#endif /* USE_HAL_ADC_REGISTER_CALLBACKS */
-
-    /* Clear ADC analog watchdog flag */
-    __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_AWD2);
-  }
-
-  /* ========== Check analog watchdog 3 flag ========== */
-  if (((tmp_isr & ADC_FLAG_AWD3) == ADC_FLAG_AWD3) && ((tmp_ier & ADC_IT_AWD3) == ADC_IT_AWD3))
-  {
-    /* Set ADC state */
-    SET_BIT(hadc->State, HAL_ADC_STATE_AWD3);
-
-    /* Level out of window 3 callback */
-#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1)
-    hadc->LevelOutOfWindow3Callback(hadc);
-#else
-    HAL_ADCEx_LevelOutOfWindow3Callback(hadc);
-#endif /* USE_HAL_ADC_REGISTER_CALLBACKS */
-
-    /* Clear ADC analog watchdog flag */
-    __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_AWD3);
-  }
-
-  /* ========== Check Overrun flag ========== */
-  if (((tmp_isr & ADC_FLAG_OVR) == ADC_FLAG_OVR) && ((tmp_ier & ADC_IT_OVR) == ADC_IT_OVR))
-  {
-    /* If overrun is set to overwrite previous data (default setting),        */
-    /* overrun event is not considered as an error.                           */
-    /* (cf ref manual "Managing conversions without using the DMA and without */
-    /* overrun ")                                                             */
-    /* Exception for usage with DMA overrun event always considered as an     */
-    /* error.                                                                 */
-    if (hadc->Init.Overrun == ADC_OVR_DATA_PRESERVED)
-    {
-      overrun_error = 1UL;
-    }
-    else
-    {
-      /* Check DMA configuration */
-      if (LL_ADC_REG_GetDMATransfer(hadc->Instance) != LL_ADC_REG_DMA_TRANSFER_NONE)
-      {
-        overrun_error = 1UL;
-      }
-    }
-
-    if (overrun_error == 1UL)
-    {
-      /* Change ADC state to error state */
-      SET_BIT(hadc->State, HAL_ADC_STATE_REG_OVR);
-
-      /* Set ADC error code to overrun */
-      SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_OVR);
-
-      /* Error callback */
-      /* Note: In case of overrun, ADC conversion data is preserved until     */
-      /*       flag OVR is reset.                                             */
-      /*       Therefore, old ADC conversion data can be retrieved in         */
-      /*       function "HAL_ADC_ErrorCallback()".                            */
-#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1)
-      hadc->ErrorCallback(hadc);
-#else
-      HAL_ADC_ErrorCallback(hadc);
-#endif /* USE_HAL_ADC_REGISTER_CALLBACKS */
-    }
-
-    /* Clear ADC overrun flag */
-    __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_OVR);
-  }
-
-#if  defined(ADC_SUPPORT_2_5_MSPS)
-/* Feature "ADC group injected" not available on ADC peripheral of this STM32WB device */
-#else
-  /* ========== Check Injected context queue overflow flag ========== */
-  if (((tmp_isr & ADC_FLAG_JQOVF) == ADC_FLAG_JQOVF) && ((tmp_ier & ADC_IT_JQOVF) == ADC_IT_JQOVF))
-  {
-    /* Change ADC state to overrun state */
-    SET_BIT(hadc->State, HAL_ADC_STATE_INJ_JQOVF);
-
-    /* Set ADC error code to Injected context queue overflow */
-    SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_JQOVF);
-
-    /* Clear the Injected context queue overflow flag */
-    __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_JQOVF);
-
-    /* Injected context queue overflow callback */
-#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1)
-    hadc->InjectedQueueOverflowCallback(hadc);
-#else
-    HAL_ADCEx_InjectedQueueOverflowCallback(hadc);
-#endif /* USE_HAL_ADC_REGISTER_CALLBACKS */
-  }
-#endif /* ADC_SUPPORT_2_5_MSPS */
-
-}
-
-/**
-  * @brief  Conversion complete callback in non-blocking mode.
-  * @param hadc ADC handle
-  * @retval None
-  */
-__weak void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc)
-{
-  /* Prevent unused argument(s) compilation warning */
-  UNUSED(hadc);
-
-  /* NOTE : This function should not be modified. When the callback is needed,
-            function HAL_ADC_ConvCpltCallback must be implemented in the user file.
-   */
-}
-
-/**
-  * @brief  Conversion DMA half-transfer callback in non-blocking mode.
-  * @param hadc ADC handle
-  * @retval None
-  */
-__weak void HAL_ADC_ConvHalfCpltCallback(ADC_HandleTypeDef *hadc)
-{
-  /* Prevent unused argument(s) compilation warning */
-  UNUSED(hadc);
-
-  /* NOTE : This function should not be modified. When the callback is needed,
-            function HAL_ADC_ConvHalfCpltCallback must be implemented in the user file.
-  */
-}
-
-/**
-  * @brief  Analog watchdog 1 callback in non-blocking mode.
-  * @param hadc ADC handle
-  * @retval None
-  */
-__weak void HAL_ADC_LevelOutOfWindowCallback(ADC_HandleTypeDef *hadc)
-{
-  /* Prevent unused argument(s) compilation warning */
-  UNUSED(hadc);
-
-  /* NOTE : This function should not be modified. When the callback is needed,
-            function HAL_ADC_LevelOutOfWindowCallback must be implemented in the user file.
-  */
-}
-
-/**
-  * @brief  ADC error callback in non-blocking mode
-  *         (ADC conversion with interruption or transfer by DMA).
-  * @note   In case of error due to overrun when using ADC with DMA transfer
-  *         (HAL ADC handle parameter "ErrorCode" to state "HAL_ADC_ERROR_OVR"):
-  *         - Reinitialize the DMA using function "HAL_ADC_Stop_DMA()".
-  *         - If needed, restart a new ADC conversion using function
-  *           "HAL_ADC_Start_DMA()"
-  *           (this function is also clearing overrun flag)
-  * @param hadc ADC handle
-  * @retval None
-  */
-__weak void HAL_ADC_ErrorCallback(ADC_HandleTypeDef *hadc)
-{
-  /* Prevent unused argument(s) compilation warning */
-  UNUSED(hadc);
-
-  /* NOTE : This function should not be modified. When the callback is needed,
-            function HAL_ADC_ErrorCallback must be implemented in the user file.
-  */
-}
-
-/**
-  * @}
-  */
-
-/** @defgroup ADC_Exported_Functions_Group3 Peripheral Control functions
-  * @brief    Peripheral Control functions
-  *
-@verbatim
- ===============================================================================
-             ##### Peripheral Control functions #####
- ===============================================================================
-    [..]  This section provides functions allowing to:
-      (+) Configure channels on regular group
-      (+) Configure the analog watchdog
-
-@endverbatim
-  * @{
-  */
-
-/**
-  * @brief  Configure a channel to be assigned to ADC group regular.
-  * @note   In case of usage of internal measurement channels:
-  *         Vbat/VrefInt/TempSensor.
-  *         These internal paths can be disabled using function
-  *         HAL_ADC_DeInit().
-  * @note   Possibility to update parameters on the fly:
-  *         This function initializes channel into ADC group regular,
-  *         following calls to this function can be used to reconfigure
-  *         some parameters of structure "ADC_ChannelConfTypeDef" on the fly,
-  *         without resetting the ADC.
-  *         The setting of these parameters is conditioned to ADC state:
-  *         Refer to comments of structure "ADC_ChannelConfTypeDef".
-  * @param hadc ADC handle
-  * @param sConfig Structure of ADC channel assigned to ADC group regular.
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_ADC_ConfigChannel(ADC_HandleTypeDef *hadc, const ADC_ChannelConfTypeDef *sConfig)
-{
-#if  defined(ADC_SUPPORT_2_5_MSPS)
-  HAL_StatusTypeDef tmp_hal_status = HAL_OK;
-  uint32_t tmp_config_internal_channel;
-  __IO uint32_t wait_loop_index = 0UL;
-  
-  /* Check the parameters */
-  assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
-  assert_param(IS_ADC_CHANNEL(hadc, sConfig->Channel));
-  assert_param(IS_ADC_SAMPLING_TIME_COMMON(sConfig->SamplingTime));
-  
-  if((hadc->Init.ScanConvMode == ADC_SCAN_SEQ_FIXED)          ||
-     (hadc->Init.ScanConvMode == ADC_SCAN_SEQ_FIXED_BACKWARD)   )
-  {
-    assert_param(IS_ADC_REGULAR_RANK_SEQ_FIXED(sConfig->Rank));
-  }
-  else
-  {
-    assert_param(IS_ADC_REGULAR_NB_CONV(hadc->Init.NbrOfConversion));
-    
-    assert_param(IS_ADC_REGULAR_RANK(sConfig->Rank));
-  }
-  
-  /* Process locked */
-  __HAL_LOCK(hadc);
-  
-  /* Parameters update conditioned to ADC state:                              */
-  /* Parameters that can be updated when ADC is disabled or enabled without   */
-  /* conversion on going on regular group:                                    */
-  /*  - Channel number                                                        */
-  /*  - Channel sampling time                                                 */
-  /*  - Management of internal measurement channels: VrefInt/TempSensor/Vbat  */
-  if (LL_ADC_REG_IsConversionOngoing(hadc->Instance) == 0UL)
-  {
-    /* Configure channel: depending on rank setting, add it or remove it from */
-    /* ADC sequencer.                                                         */
-    /* If sequencer set to not fully configurable with channel rank set to    */
-    /* none, remove the channel from the sequencer.                           */
-    /* Otherwise (sequencer set to fully configurable or to to not fully      */
-    /* configurable with channel rank to be set), configure the selected      */
-    /* channel.                                                               */
-    if(sConfig->Rank != ADC_RANK_NONE)
-    {
-      /* Regular sequence configuration */
-      /* Note: ADC channel configuration requires few ADC clock cycles        */
-      /*       to be ready. Processing of ADC settings in this function       */
-      /*       induce that a specific wait time is not necessary.             */
-      /*       For more details on ADC channel configuration ready,           */
-      /*       refer to function "LL_ADC_IsActiveFlag_CCRDY()".               */
-      if((hadc->Init.ScanConvMode == ADC_SCAN_SEQ_FIXED)         ||
-         (hadc->Init.ScanConvMode == ADC_SCAN_SEQ_FIXED_BACKWARD)  )
-      {
-        /* Sequencer set to not fully configurable:                           */
-        /* Set the channel by enabling the corresponding bitfield.            */
-        LL_ADC_REG_SetSequencerChAdd(hadc->Instance, sConfig->Channel);
-      }
-      else
-      {
-        /* Sequencer set to fully configurable:                               */
-        /* Set the channel by entering it into the selected rank.             */
-        
-        /* Memorize the channel set into variable in HAL ADC handle */
-        MODIFY_REG(hadc->ADCGroupRegularSequencerRanks,
-                   ADC_CHSELR_SQ1 << (sConfig->Rank & 0x1FUL),
-                   __LL_ADC_CHANNEL_TO_DECIMAL_NB(sConfig->Channel) << (sConfig->Rank & 0x1FUL));
-        
-        /* If the selected rank is below ADC group regular sequencer length,  */
-        /* apply the configuration in ADC register.                           */
-        /* Note: Otherwise, configuration is not applied.                     */
-        /*       To apply it, parameter'NbrOfConversion' must be increased.   */        
-        if(((sConfig->Rank >> 2UL) + 1UL) <= hadc->Init.NbrOfConversion)
-        {
-          LL_ADC_REG_SetSequencerRanks(hadc->Instance, sConfig->Rank, sConfig->Channel);
-        }
-      }
-      
-      /* Set sampling time of the selected ADC channel */
-      LL_ADC_SetChannelSamplingTime(hadc->Instance, sConfig->Channel, sConfig->SamplingTime);
-      
-      /* Management of internal measurement channels: VrefInt/TempSensor/Vbat */
-      /* internal measurement paths enable: If internal channel selected,     */
-      /* enable dedicated internal buffers and path.                          */
-      /* Note: these internal measurement paths can be disabled using         */
-      /*       HAL_ADC_DeInit() or removing the channel from sequencer with   */
-      /*       channel configuration parameter "Rank".                        */
-      if(__LL_ADC_IS_CHANNEL_INTERNAL(sConfig->Channel))
-      {
-        tmp_config_internal_channel = LL_ADC_GetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(hadc->Instance));
-        
-        /* If the requested internal measurement path has already been enabled,   */
-        /* bypass the configuration processing.                                   */
-        if ((sConfig->Channel == ADC_CHANNEL_TEMPSENSOR) && ((tmp_config_internal_channel & LL_ADC_PATH_INTERNAL_TEMPSENSOR) == 0UL))
-        {
-          LL_ADC_SetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(hadc->Instance), LL_ADC_PATH_INTERNAL_TEMPSENSOR | tmp_config_internal_channel);
-          
-          /* Delay for temperature sensor stabilization time */
-          /* Wait loop initialization and execution */
-          /* Note: Variable divided by 2 to compensate partially              */
-          /*       CPU processing cycles, scaling in us split to not          */
-          /*       exceed 32 bits register capacity and handle low frequency. */
-          wait_loop_index = ((LL_ADC_DELAY_TEMPSENSOR_STAB_US / 10UL) * ((SystemCoreClock / (100000UL * 2UL)) + 1UL));
-          while(wait_loop_index != 0UL)
-          {
-            wait_loop_index--;
-          }
-        }
-        else if ((sConfig->Channel == ADC_CHANNEL_VBAT) && ((tmp_config_internal_channel & LL_ADC_PATH_INTERNAL_VBAT) == 0UL))
-        {
-          LL_ADC_SetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(hadc->Instance), LL_ADC_PATH_INTERNAL_VBAT | tmp_config_internal_channel);
-        }
-        else if ((sConfig->Channel == ADC_CHANNEL_VREFINT) && ((tmp_config_internal_channel & LL_ADC_PATH_INTERNAL_VREFINT) == 0UL))
-        {
-          LL_ADC_SetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(hadc->Instance), LL_ADC_PATH_INTERNAL_VREFINT | tmp_config_internal_channel);
-        }
-        else
-        {
-          /* nothing to do */
-        }
-      }
-    }
-    else
-    {
-      /* Regular sequencer configuration */
-      /* Note: Case of sequencer set to fully configurable:                   */
-      /*       Sequencer rank cannot be disabled, only affected to            */
-      /*       another channel.                                               */
-      /*       To remove a rank, use parameter 'NbrOfConversion".             */
-      if((hadc->Init.ScanConvMode == ADC_SCAN_SEQ_FIXED)         ||
-         (hadc->Init.ScanConvMode == ADC_SCAN_SEQ_FIXED_BACKWARD)  )
-      {
-        /* Sequencer set to not fully configurable:                           */
-        /* Reset the channel by disabling the corresponding bitfield.         */
-        LL_ADC_REG_SetSequencerChRem(hadc->Instance, sConfig->Channel);
-      }
-      
-      /* Management of internal measurement channels: Vbat/VrefInt/TempSensor.  */
-      /* If internal channel selected, enable dedicated internal buffers and    */
-      /* paths.                                                                 */
-      if(__LL_ADC_IS_CHANNEL_INTERNAL(sConfig->Channel))
-      {
-        tmp_config_internal_channel = LL_ADC_GetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(hadc->Instance));
-        
-        if (sConfig->Channel == ADC_CHANNEL_TEMPSENSOR)
-        {
-          LL_ADC_SetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(hadc->Instance), ~LL_ADC_PATH_INTERNAL_TEMPSENSOR & tmp_config_internal_channel);
-        }
-        else if (sConfig->Channel == ADC_CHANNEL_VBAT)
-        {
-          LL_ADC_SetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(hadc->Instance), ~LL_ADC_PATH_INTERNAL_VBAT & tmp_config_internal_channel);
-        }
-        else if (sConfig->Channel == ADC_CHANNEL_VREFINT)
-        {
-          LL_ADC_SetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(hadc->Instance), ~LL_ADC_PATH_INTERNAL_VREFINT & tmp_config_internal_channel);
-        }
-        else
-        {
-          /* nothing to do */
-        }
-      }
-    }
-  }
-  
-  /* If a conversion is on going on regular group, no update on regular       */
-  /* channel could be done on neither of the channel configuration structure  */
-  /* parameters.                                                              */
-  else
-  {
-    /* Update ADC state machine to error */
-    SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG);
-    
-    tmp_hal_status = HAL_ERROR;
-  }
-  
-  /* Process unlocked */
-  __HAL_UNLOCK(hadc);
-  
-#else
-  HAL_StatusTypeDef tmp_hal_status = HAL_OK;
-  uint32_t tmpOffsetShifted;
-  uint32_t tmp_config_internal_channel;
-  __IO uint32_t wait_loop_index = 0;
-#if !defined(ADC_SUPPORT_2_5_MSPS)
-  uint32_t tmp_adc_is_conversion_on_going_regular;
-  uint32_t tmp_adc_is_conversion_on_going_injected;
-#endif /* !ADC_SUPPORT_2_5_MSPS */
-
-  /* Check the parameters */
-  assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
-  assert_param(IS_ADC_REGULAR_RANK(sConfig->Rank));
-  assert_param(IS_ADC_SAMPLE_TIME(sConfig->SamplingTime));
-  assert_param(IS_ADC_SINGLE_DIFFERENTIAL(sConfig->SingleDiff));
-  assert_param(IS_ADC_OFFSET_NUMBER(sConfig->OffsetNumber));
-  assert_param(IS_ADC_RANGE(ADC_GET_RESOLUTION(hadc), sConfig->Offset));
-
-  /* if ROVSE is set, the value of the OFFSETy_EN bit in ADCx_OFRy register is
-     ignored (considered as reset) */
-  assert_param(!((sConfig->OffsetNumber != ADC_OFFSET_NONE) && (hadc->Init.OversamplingMode == ENABLE)));
-
-  /* Verification of channel number */
-  if (sConfig->SingleDiff != ADC_DIFFERENTIAL_ENDED)
-  {
-    assert_param(IS_ADC_CHANNEL(hadc, sConfig->Channel));
-  }
-  else
-  {
-    assert_param(IS_ADC_DIFF_CHANNEL(hadc, sConfig->Channel));
-  }
-
-  /* Process locked */
-  __HAL_LOCK(hadc);
-
-  /* Parameters update conditioned to ADC state:                              */
-  /* Parameters that can be updated when ADC is disabled or enabled without   */
-  /* conversion on going on regular group:                                    */
-  /*  - Channel number                                                        */
-  /*  - Channel rank                                                          */
-  if (LL_ADC_REG_IsConversionOngoing(hadc->Instance) == 0UL)
-  {
-    /* Set ADC group regular sequence: channel on the selected scan sequence rank */
-    LL_ADC_REG_SetSequencerRanks(hadc->Instance, sConfig->Rank, sConfig->Channel);
-
-    /* Parameters update conditioned to ADC state:                              */
-    /* Parameters that can be updated when ADC is disabled or enabled without   */
-    /* conversion on going on regular group:                                    */
-    /*  - Channel sampling time                                                 */
-    /*  - Channel offset                                                        */
-#if defined(ADC_SUPPORT_2_5_MSPS)
-  if (LL_ADC_REG_IsConversionOngoing(hadc->Instance) == 0UL)
-#else
-    tmp_adc_is_conversion_on_going_regular = LL_ADC_REG_IsConversionOngoing(hadc->Instance);
-    tmp_adc_is_conversion_on_going_injected = LL_ADC_INJ_IsConversionOngoing(hadc->Instance);
-    if ((tmp_adc_is_conversion_on_going_regular == 0UL)
-        && (tmp_adc_is_conversion_on_going_injected == 0UL)
-       )
-#endif /* ADC_SUPPORT_2_5_MSPS */
-    {
-      /* Set sampling time of the selected ADC channel */
-      LL_ADC_SetChannelSamplingTime(hadc->Instance, sConfig->Channel, sConfig->SamplingTime);
-
-      /* Configure the offset: offset enable/disable, channel, offset value */
-
-      /* Shift the offset with respect to the selected ADC resolution. */
-      /* Offset has to be left-aligned on bit 11, the LSB (right bits) are set to 0 */
-      tmpOffsetShifted = ADC_OFFSET_SHIFT_RESOLUTION(hadc, (uint32_t)sConfig->Offset);
-
-      if (sConfig->OffsetNumber != ADC_OFFSET_NONE)
-      {
-        /* Set ADC selected offset number */
-        LL_ADC_SetOffset(hadc->Instance, sConfig->OffsetNumber, sConfig->Channel, tmpOffsetShifted);
-
-      }
-      else
-      {
-        /* Scan each offset register to check if the selected channel is targeted. */
-        /* If this is the case, the corresponding offset number is disabled.       */
-        if(__LL_ADC_CHANNEL_TO_DECIMAL_NB(LL_ADC_GetOffsetChannel(hadc->Instance, LL_ADC_OFFSET_1)) == __LL_ADC_CHANNEL_TO_DECIMAL_NB(sConfig->Channel))
-        {
-          LL_ADC_SetOffsetState(hadc->Instance, LL_ADC_OFFSET_1, LL_ADC_OFFSET_DISABLE);
-        }
-        if(__LL_ADC_CHANNEL_TO_DECIMAL_NB(LL_ADC_GetOffsetChannel(hadc->Instance, LL_ADC_OFFSET_2)) == __LL_ADC_CHANNEL_TO_DECIMAL_NB(sConfig->Channel))
-        {
-          LL_ADC_SetOffsetState(hadc->Instance, LL_ADC_OFFSET_2, LL_ADC_OFFSET_DISABLE);
-        }
-        if(__LL_ADC_CHANNEL_TO_DECIMAL_NB(LL_ADC_GetOffsetChannel(hadc->Instance, LL_ADC_OFFSET_3)) == __LL_ADC_CHANNEL_TO_DECIMAL_NB(sConfig->Channel))
-        {
-          LL_ADC_SetOffsetState(hadc->Instance, LL_ADC_OFFSET_3, LL_ADC_OFFSET_DISABLE);
-        }
-        if(__LL_ADC_CHANNEL_TO_DECIMAL_NB(LL_ADC_GetOffsetChannel(hadc->Instance, LL_ADC_OFFSET_4)) == __LL_ADC_CHANNEL_TO_DECIMAL_NB(sConfig->Channel))
-        {
-          LL_ADC_SetOffsetState(hadc->Instance, LL_ADC_OFFSET_4, LL_ADC_OFFSET_DISABLE);
-        }
-      }
-    }
-
-    /* Parameters update conditioned to ADC state:                              */
-    /* Parameters that can be updated only when ADC is disabled:                */
-    /*  - Single or differential mode                                           */
-    /*  - Internal measurement channels: Vbat/VrefInt/TempSensor                */
-    if (LL_ADC_IsEnabled(hadc->Instance) == 0UL)
-    {
-      /* Set mode single-ended or differential input of the selected ADC channel */
-      LL_ADC_SetChannelSingleDiff(hadc->Instance, sConfig->Channel, sConfig->SingleDiff);
-
-      /* Configuration of differential mode */
-      if (sConfig->SingleDiff == ADC_DIFFERENTIAL_ENDED)
-      {
-        /* Set sampling time of the selected ADC channel */
-        /* Note: ADC channel number masked with value "0x1F" to ensure shift value within 32 bits range */
-        LL_ADC_SetChannelSamplingTime(hadc->Instance,
-                                      (uint32_t)(__LL_ADC_DECIMAL_NB_TO_CHANNEL((__LL_ADC_CHANNEL_TO_DECIMAL_NB((uint32_t)sConfig->Channel) + 1UL) & 0x1FUL)),
-                                      sConfig->SamplingTime);
-      }
-
-      /* Management of internal measurement channels: Vbat/VrefInt/TempSensor.  */
-      /* If internal channel selected, enable dedicated internal buffers and    */
-      /* paths.                                                                 */
-      /* Note: these internal measurement paths can be disabled using           */
-      /* HAL_ADC_DeInit().                                                      */
-
-      if(__LL_ADC_IS_CHANNEL_INTERNAL(sConfig->Channel))
-      {
-        /* Configuration of common ADC parameters                                 */
-
-        tmp_config_internal_channel = LL_ADC_GetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(hadc->Instance));
-
-        /* Software is allowed to change common parameters only when all ADCs   */
-        /* of the common group are disabled.                                    */
-        if (__LL_ADC_IS_ENABLED_ALL_COMMON_INSTANCE(__LL_ADC_COMMON_INSTANCE(hadc->Instance)) == 0UL)
-        {
-          /* If the requested internal measurement path has already been enabled, */
-          /* bypass the configuration processing.                                 */
-          if ((sConfig->Channel == ADC_CHANNEL_TEMPSENSOR) && ((tmp_config_internal_channel & LL_ADC_PATH_INTERNAL_TEMPSENSOR) == 0UL))
-          {
-            if (ADC_TEMPERATURE_SENSOR_INSTANCE(hadc))
-            {
-              LL_ADC_SetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(hadc->Instance), LL_ADC_PATH_INTERNAL_TEMPSENSOR | tmp_config_internal_channel);
-
-              /* Delay for temperature sensor stabilization time */
-              /* Wait loop initialization and execution */
-              /* Note: Variable divided by 2 to compensate partially              */
-              /*       CPU processing cycles, scaling in us split to not          */
-              /*       exceed 32 bits register capacity and handle low frequency. */
-              wait_loop_index = ((LL_ADC_DELAY_TEMPSENSOR_STAB_US / 10UL) * ((SystemCoreClock / (100000UL * 2UL)) + 1UL));
-              while(wait_loop_index != 0UL)
-              {
-                wait_loop_index--;
-              }
-            }
-          }
-          else if ((sConfig->Channel == ADC_CHANNEL_VBAT) && ((tmp_config_internal_channel & LL_ADC_PATH_INTERNAL_VBAT) == 0UL))
-          {
-            if (ADC_BATTERY_VOLTAGE_INSTANCE(hadc))
-            {
-              LL_ADC_SetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(hadc->Instance), LL_ADC_PATH_INTERNAL_VBAT | tmp_config_internal_channel);
-            }
-          }
-          else if ((sConfig->Channel == ADC_CHANNEL_VREFINT) && ((tmp_config_internal_channel & LL_ADC_PATH_INTERNAL_VREFINT) == 0UL))
-          {
-            if (ADC_VREFINT_INSTANCE(hadc))
-            {
-              LL_ADC_SetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(hadc->Instance), LL_ADC_PATH_INTERNAL_VREFINT | tmp_config_internal_channel);
-            }
-          }
-          else
-          {
-            /* nothing to do */
-          }
-        }
-        /* If the requested internal measurement path has already been          */
-        /* enabled and other ADC of the common group are enabled, internal      */
-        /* measurement paths cannot be enabled.                                 */
-        else
-        {
-          /* Update ADC state machine to error */
-          SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG);
-
-          tmp_hal_status = HAL_ERROR;
-        }
-      }
-    }
-  }
-
-  /* If a conversion is on going on regular group, no update on regular       */
-  /* channel could be done on neither of the channel configuration structure  */
-  /* parameters.                                                              */
-  else
-  {
-    /* Update ADC state machine to error */
-    SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG);
-
-    tmp_hal_status = HAL_ERROR;
-  }
-
-  /* Process unlocked */
-  __HAL_UNLOCK(hadc);
-#endif /* ADC_SUPPORT_2_5_MSPS */
-
-  /* Return function status */
-  return tmp_hal_status;
-}
-
-/**
-  * @brief  Configure the analog watchdog.
-  * @note   Possibility to update parameters on the fly:
-  *         This function initializes the selected analog watchdog, successive
-  *         calls to this function can be used to reconfigure some parameters
-  *         of structure "ADC_AnalogWDGConfTypeDef" on the fly, without resetting
-  *         the ADC.
-  *         The setting of these parameters is conditioned to ADC state.
-  *         For parameters constraints, see comments of structure
-  *         "ADC_AnalogWDGConfTypeDef".
-  * @note   On this STM32 series, analog watchdog thresholds cannot be modified
-  *         while ADC conversion is on going.
-  * @param hadc ADC handle
-  * @param AnalogWDGConfig Structure of ADC analog watchdog configuration
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_ADC_AnalogWDGConfig(ADC_HandleTypeDef *hadc, const ADC_AnalogWDGConfTypeDef *AnalogWDGConfig)
-{
-  HAL_StatusTypeDef tmp_hal_status = HAL_OK;
-  uint32_t tmpAWDHighThresholdShifted;
-  uint32_t tmpAWDLowThresholdShifted;
-#if !defined(ADC_SUPPORT_2_5_MSPS)
-  uint32_t tmp_adc_is_conversion_on_going_regular;
-  uint32_t tmp_adc_is_conversion_on_going_injected;
-#endif /* !ADC_SUPPORT_2_5_MSPS */
-
-  /* Check the parameters */
-  assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
-  assert_param(IS_ADC_ANALOG_WATCHDOG_NUMBER(AnalogWDGConfig->WatchdogNumber));
-  assert_param(IS_ADC_ANALOG_WATCHDOG_MODE(AnalogWDGConfig->WatchdogMode));
-  assert_param(IS_FUNCTIONAL_STATE(AnalogWDGConfig->ITMode));
-
-#if defined(ADC_SUPPORT_2_5_MSPS)
-  if(AnalogWDGConfig->WatchdogMode == ADC_ANALOGWATCHDOG_SINGLE_REG)
-#else
-  if ((AnalogWDGConfig->WatchdogMode == ADC_ANALOGWATCHDOG_SINGLE_REG)     ||
-      (AnalogWDGConfig->WatchdogMode == ADC_ANALOGWATCHDOG_SINGLE_INJEC)   ||
-      (AnalogWDGConfig->WatchdogMode == ADC_ANALOGWATCHDOG_SINGLE_REGINJEC))
-#endif /* ADC_SUPPORT_2_5_MSPS */
-  {
-    assert_param(IS_ADC_CHANNEL(hadc, AnalogWDGConfig->Channel));
-  }
-
-  /* Verify thresholds range */
-#if  defined(ADC_SUPPORT_2_5_MSPS)
-  /* Verify if thresholds are within the selected ADC resolution */
-  assert_param(IS_ADC_RANGE(ADC_GET_RESOLUTION(hadc), AnalogWDGConfig->HighThreshold));
-  assert_param(IS_ADC_RANGE(ADC_GET_RESOLUTION(hadc), AnalogWDGConfig->LowThreshold));
-#else
-  if (hadc->Init.OversamplingMode == ENABLE)
-  {
-    /* Case of oversampling enabled: depending on ratio and shift configuration,
-       analog watchdog thresholds can be higher than ADC resolution.
-       Verify if thresholds are within maximum thresholds range. */
-    assert_param(IS_ADC_RANGE(ADC_RESOLUTION_12B, AnalogWDGConfig->HighThreshold));
-    assert_param(IS_ADC_RANGE(ADC_RESOLUTION_12B, AnalogWDGConfig->LowThreshold));
-  }
-  else
-  {
-    /* Verify if thresholds are within the selected ADC resolution */
-    assert_param(IS_ADC_RANGE(ADC_GET_RESOLUTION(hadc), AnalogWDGConfig->HighThreshold));
-    assert_param(IS_ADC_RANGE(ADC_GET_RESOLUTION(hadc), AnalogWDGConfig->LowThreshold));
-  }
-#endif
-
-  /* Process locked */
-  __HAL_LOCK(hadc);
-
-  /* Parameters update conditioned to ADC state:                              */
-  /* Parameters that can be updated when ADC is disabled or enabled without   */
-  /* conversion on going on ADC groups regular and injected:                  */
-  /*  - Analog watchdog channels                                              */
-  /*  - Analog watchdog thresholds                                            */
-#if defined(ADC_SUPPORT_2_5_MSPS)
-  if (LL_ADC_REG_IsConversionOngoing(hadc->Instance) == 0UL)
-#else
-  tmp_adc_is_conversion_on_going_regular = LL_ADC_REG_IsConversionOngoing(hadc->Instance);
-  tmp_adc_is_conversion_on_going_injected = LL_ADC_INJ_IsConversionOngoing(hadc->Instance);
-  if ((tmp_adc_is_conversion_on_going_regular == 0UL)
-      && (tmp_adc_is_conversion_on_going_injected == 0UL)
-     )
-#endif /* ADC_SUPPORT_2_5_MSPS */
-  {
-    /* Analog watchdog configuration */
-    if (AnalogWDGConfig->WatchdogNumber == ADC_ANALOGWATCHDOG_1)
-    {
-      /* Configuration of analog watchdog:                                    */
-      /*  - Set the analog watchdog enable mode: one or overall group of      */
-      /*    channels, on groups regular and-or injected.                      */
-      switch (AnalogWDGConfig->WatchdogMode)
-      {
-        case ADC_ANALOGWATCHDOG_SINGLE_REG:
-          LL_ADC_SetAnalogWDMonitChannels(hadc->Instance, LL_ADC_AWD1, __LL_ADC_ANALOGWD_CHANNEL_GROUP(AnalogWDGConfig->Channel,
-                                          LL_ADC_GROUP_REGULAR));
-          break;
-
-#if  defined(ADC_SUPPORT_2_5_MSPS)
-/* Feature "ADC group injected" not available on ADC peripheral of this STM32WB device */
-#else
-        case ADC_ANALOGWATCHDOG_SINGLE_INJEC:
-          LL_ADC_SetAnalogWDMonitChannels(hadc->Instance, LL_ADC_AWD1, __LL_ADC_ANALOGWD_CHANNEL_GROUP(AnalogWDGConfig->Channel,
-                                          LL_ADC_GROUP_INJECTED));
-          break;
-
-        case ADC_ANALOGWATCHDOG_SINGLE_REGINJEC:
-          LL_ADC_SetAnalogWDMonitChannels(hadc->Instance, LL_ADC_AWD1, __LL_ADC_ANALOGWD_CHANNEL_GROUP(AnalogWDGConfig->Channel,
-                                          LL_ADC_GROUP_REGULAR_INJECTED));
-          break;
-#endif /* ADC_SUPPORT_2_5_MSPS */
-
-        case ADC_ANALOGWATCHDOG_ALL_REG:
-          LL_ADC_SetAnalogWDMonitChannels(hadc->Instance, LL_ADC_AWD1, LL_ADC_AWD_ALL_CHANNELS_REG);
-          break;
-
-#if  defined(ADC_SUPPORT_2_5_MSPS)
-/* Feature "ADC group injected" not available on ADC peripheral of this STM32WB device */
-#else
-        case ADC_ANALOGWATCHDOG_ALL_INJEC:
-          LL_ADC_SetAnalogWDMonitChannels(hadc->Instance, LL_ADC_AWD1, LL_ADC_AWD_ALL_CHANNELS_INJ);
-          break;
-
-        case ADC_ANALOGWATCHDOG_ALL_REGINJEC:
-          LL_ADC_SetAnalogWDMonitChannels(hadc->Instance, LL_ADC_AWD1, LL_ADC_AWD_ALL_CHANNELS_REG_INJ);
-          break;
-#endif /* ADC_SUPPORT_2_5_MSPS */
-
-        default: /* ADC_ANALOGWATCHDOG_NONE */
-          LL_ADC_SetAnalogWDMonitChannels(hadc->Instance, LL_ADC_AWD1, LL_ADC_AWD_DISABLE);
-          break;
-      }
-
-      /* Shift the offset in function of the selected ADC resolution:         */
-      /* Thresholds have to be left-aligned on bit 11, the LSB (right bits)   */
-      /* are set to 0                                                         */
-      tmpAWDHighThresholdShifted = ADC_AWD1THRESHOLD_SHIFT_RESOLUTION(hadc, AnalogWDGConfig->HighThreshold);
-      tmpAWDLowThresholdShifted  = ADC_AWD1THRESHOLD_SHIFT_RESOLUTION(hadc, AnalogWDGConfig->LowThreshold);
-
-      /* Set ADC analog watchdog thresholds value of both thresholds high and low */
-      LL_ADC_ConfigAnalogWDThresholds(hadc->Instance, AnalogWDGConfig->WatchdogNumber, tmpAWDHighThresholdShifted, tmpAWDLowThresholdShifted);
-
-      /* Update state, clear previous result related to AWD1 */
-      CLEAR_BIT(hadc->State, HAL_ADC_STATE_AWD1);
-
-      /* Clear flag ADC analog watchdog */
-      /* Note: Flag cleared Clear the ADC Analog watchdog flag to be ready  */
-      /* to use for HAL_ADC_IRQHandler() or HAL_ADC_PollForEvent()          */
-      /* (in case left enabled by previous ADC operations).                 */
-      LL_ADC_ClearFlag_AWD1(hadc->Instance);
-
-      /* Configure ADC analog watchdog interrupt */
-      if (AnalogWDGConfig->ITMode == ENABLE)
-      {
-        LL_ADC_EnableIT_AWD1(hadc->Instance);
-      }
-      else
-      {
-        LL_ADC_DisableIT_AWD1(hadc->Instance);
-      }
-    }
-#if  defined(ADC_SUPPORT_2_5_MSPS)
-    /* Feature "ADC analog watchdog 2 and 3" not available on ADC peripheral of this STM32WB device */
-#else
-    /* Case of ADC_ANALOGWATCHDOG_2 or ADC_ANALOGWATCHDOG_3 */
-    else
-    {
-      switch (AnalogWDGConfig->WatchdogMode)
-      {
-        case ADC_ANALOGWATCHDOG_SINGLE_REG:
-#if !defined(ADC_SUPPORT_2_5_MSPS)
-        case ADC_ANALOGWATCHDOG_SINGLE_INJEC:
-        case ADC_ANALOGWATCHDOG_SINGLE_REGINJEC:
-#endif /* !ADC_SUPPORT_2_5_MSPS */
-          /* Update AWD by bitfield to keep the possibility to monitor        */
-          /* several channels by successive calls of this function.           */
-          if (AnalogWDGConfig->WatchdogNumber == ADC_ANALOGWATCHDOG_2)
-          {
-            SET_BIT(hadc->Instance->AWD2CR, (1UL << (__LL_ADC_CHANNEL_TO_DECIMAL_NB(AnalogWDGConfig->Channel) & 0x1FUL)));
-          }
-          else
-          {
-            SET_BIT(hadc->Instance->AWD3CR, (1UL << (__LL_ADC_CHANNEL_TO_DECIMAL_NB(AnalogWDGConfig->Channel) & 0x1FUL)));
-          }
-          break;
-
-        case ADC_ANALOGWATCHDOG_ALL_REG:
-#if !defined(ADC_SUPPORT_2_5_MSPS)
-        case ADC_ANALOGWATCHDOG_ALL_INJEC:
-        case ADC_ANALOGWATCHDOG_ALL_REGINJEC:
-#endif /* !ADC_SUPPORT_2_5_MSPS */
-#if defined(ADC_SUPPORT_2_5_MSPS)
-          LL_ADC_SetAnalogWDMonitChannels(hadc->Instance, AnalogWDGConfig->WatchdogNumber, LL_ADC_AWD_ALL_CHANNELS_REG);
-#else
-          LL_ADC_SetAnalogWDMonitChannels(hadc->Instance, AnalogWDGConfig->WatchdogNumber, LL_ADC_AWD_ALL_CHANNELS_REG_INJ);
-#endif /* ADC_SUPPORT_2_5_MSPS */
-          break;
-
-        default: /* ADC_ANALOGWATCHDOG_NONE */
-          LL_ADC_SetAnalogWDMonitChannels(hadc->Instance, AnalogWDGConfig->WatchdogNumber, LL_ADC_AWD_DISABLE);
-          break;
-      }
-
-      /* Shift the thresholds in function of the selected ADC resolution      */
-      /* have to be left-aligned on bit 7, the LSB (right bits) are set to 0  */
-      tmpAWDHighThresholdShifted = ADC_AWD23THRESHOLD_SHIFT_RESOLUTION(hadc, AnalogWDGConfig->HighThreshold);
-      tmpAWDLowThresholdShifted  = ADC_AWD23THRESHOLD_SHIFT_RESOLUTION(hadc, AnalogWDGConfig->LowThreshold);
-
-      /* Set ADC analog watchdog thresholds value of both thresholds high and low */
-      LL_ADC_ConfigAnalogWDThresholds(hadc->Instance, AnalogWDGConfig->WatchdogNumber, tmpAWDHighThresholdShifted, tmpAWDLowThresholdShifted);
-
-      if (AnalogWDGConfig->WatchdogNumber == ADC_ANALOGWATCHDOG_2)
-      {
-        /* Update state, clear previous result related to AWD2 */
-        CLEAR_BIT(hadc->State, HAL_ADC_STATE_AWD2);
-
-        /* Clear flag ADC analog watchdog */
-        /* Note: Flag cleared Clear the ADC Analog watchdog flag to be ready  */
-        /* to use for HAL_ADC_IRQHandler() or HAL_ADC_PollForEvent()          */
-        /* (in case left enabled by previous ADC operations).                 */
-        LL_ADC_ClearFlag_AWD2(hadc->Instance);
-
-        /* Configure ADC analog watchdog interrupt */
-        if (AnalogWDGConfig->ITMode == ENABLE)
-        {
-          LL_ADC_EnableIT_AWD2(hadc->Instance);
-        }
-        else
-        {
-          LL_ADC_DisableIT_AWD2(hadc->Instance);
-        }
-      }
-      /* (AnalogWDGConfig->WatchdogNumber == ADC_ANALOGWATCHDOG_3) */
-      else
-      {
-        /* Update state, clear previous result related to AWD3 */
-        CLEAR_BIT(hadc->State, HAL_ADC_STATE_AWD3);
-
-        /* Clear flag ADC analog watchdog */
-        /* Note: Flag cleared Clear the ADC Analog watchdog flag to be ready  */
-        /* to use for HAL_ADC_IRQHandler() or HAL_ADC_PollForEvent()          */
-        /* (in case left enabled by previous ADC operations).                 */
-        LL_ADC_ClearFlag_AWD3(hadc->Instance);
-
-        /* Configure ADC analog watchdog interrupt */
-        if (AnalogWDGConfig->ITMode == ENABLE)
-        {
-          LL_ADC_EnableIT_AWD3(hadc->Instance);
-        }
-        else
-        {
-          LL_ADC_DisableIT_AWD3(hadc->Instance);
-        }
-      }
-    }
-#endif /* ADC_SUPPORT_2_5_MSPS */
-
-  }
-  /* If a conversion is on going on ADC group regular or injected, no update  */
-  /* could be done on neither of the AWD configuration structure parameters.  */
-  else
-  {
-    /* Update ADC state machine to error */
-    SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG);
-
-    tmp_hal_status = HAL_ERROR;
-  }
-  /* Process unlocked */
-  __HAL_UNLOCK(hadc);
-
-  /* Return function status */
-  return tmp_hal_status;
-}
-
-
-/**
-  * @}
-  */
-
-/** @defgroup ADC_Exported_Functions_Group4 Peripheral State functions
-  *  @brief    ADC Peripheral State functions
-  *
-@verbatim
- ===============================================================================
-            ##### Peripheral state and errors functions #####
- ===============================================================================
-    [..]
-    This subsection provides functions to get in run-time the status of the
-    peripheral.
-      (+) Check the ADC state
-      (+) Check the ADC error code
-
-@endverbatim
-  * @{
-  */
-
-/**
-  * @brief  Return the ADC handle state.
-  * @note   ADC state machine is managed by bitfields, ADC status must be
-  *         compared with states bits.
-  *         For example:
-  *           " if ((HAL_ADC_GetState(hadc1) & HAL_ADC_STATE_REG_BUSY) != 0UL) "
-  *           " if ((HAL_ADC_GetState(hadc1) & HAL_ADC_STATE_AWD1) != 0UL) "
-  * @param hadc ADC handle
-  * @retval ADC handle state (bitfield on 32 bits)
-  */
-uint32_t HAL_ADC_GetState(const ADC_HandleTypeDef *hadc)
-{
-  /* Check the parameters */
-  assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
-
-  /* Return ADC handle state */
-  return hadc->State;
-}
-
-/**
-  * @brief  Return the ADC error code.
-  * @param hadc ADC handle
-  * @retval ADC error code (bitfield on 32 bits)
-  */
-uint32_t HAL_ADC_GetError(const ADC_HandleTypeDef *hadc)
-{
-  /* Check the parameters */
-  assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
-
-  return hadc->ErrorCode;
-}
-
-/**
-  * @}
-  */
-
-/**
-  * @}
-  */
-
-/** @defgroup ADC_Private_Functions ADC Private Functions
-  * @{
-  */
-
-/**
-  * @brief  Stop ADC conversion.
-  * @param hadc ADC handle
-  * @param ConversionGroup ADC group regular and/or injected.
-  *          This parameter can be one of the following values:
-  *            @arg @ref ADC_REGULAR_GROUP               ADC regular conversion type.
-  *            @arg @ref ADC_INJECTED_GROUP         (1)  ADC injected conversion type.
-  *            @arg @ref ADC_REGULAR_INJECTED_GROUP (1)  ADC regular and injected conversion type.
-  *
-  *         (1) On STM32WB series, parameter not available on devices: STM32WB10xx, STM32WB15xx, STM32WB1Mxx.
-  * @retval HAL status.
-  */
-HAL_StatusTypeDef ADC_ConversionStop(ADC_HandleTypeDef *hadc, uint32_t ConversionGroup)
-{
-#if  defined(ADC_SUPPORT_2_5_MSPS)
-  UNUSED(ConversionGroup);
-  
-  uint32_t tickstart;
-  
-  /* Check the parameters */
-  assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
-  
-  /* Verification if ADC is not already stopped on regular group to bypass    */
-  /* this function if not needed.                                             */
-  if (LL_ADC_REG_IsConversionOngoing(hadc->Instance) != 0UL)
-  {
-    /* Stop potential conversion on going on regular group */
-    /* Software is allowed to set ADSTP only when ADSTART=1 and ADDIS=0 */
-    if (LL_ADC_IsDisableOngoing(hadc->Instance) == 0UL)
-    {
-      /* Stop ADC group regular conversion */
-      LL_ADC_REG_StopConversion(hadc->Instance);
-    }
-    
-    /* Wait for conversion effectively stopped */
-    /* Get tick count */
-    tickstart = HAL_GetTick();
-    
-    while((hadc->Instance->CR & ADC_CR_ADSTART) != 0UL)
-    {
-      if((HAL_GetTick() - tickstart) > ADC_STOP_CONVERSION_TIMEOUT)
-      {
-        /* Update ADC state machine to error */
-        SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL);
-      
-        /* Set ADC error code to ADC peripheral internal error */
-        SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL);
-        
-        return HAL_ERROR;
-      }
-    }
-    
-  }
-#else
-  uint32_t tickstart;
-  uint32_t Conversion_Timeout_CPU_cycles = 0UL;
-  uint32_t conversion_group_reassigned = ConversionGroup;
-  uint32_t tmp_ADC_CR_ADSTART_JADSTART;
-  uint32_t tmp_adc_is_conversion_on_going_regular;
-  uint32_t tmp_adc_is_conversion_on_going_injected;
-
-  /* Check the parameters */
-  assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
-  assert_param(IS_ADC_CONVERSION_GROUP(ConversionGroup));
-
-  /* Verification if ADC is not already stopped (on regular and injected      */
-  /* groups) to bypass this function if not needed.                           */
-  tmp_adc_is_conversion_on_going_regular = LL_ADC_REG_IsConversionOngoing(hadc->Instance);
-  tmp_adc_is_conversion_on_going_injected = LL_ADC_INJ_IsConversionOngoing(hadc->Instance);
-  if ((tmp_adc_is_conversion_on_going_regular != 0UL)
-      || (tmp_adc_is_conversion_on_going_injected != 0UL)
-     )
-  {
-    /* Particular case of continuous auto-injection mode combined with        */
-    /* auto-delay mode.                                                       */
-    /* In auto-injection mode, regular group stop ADC_CR_ADSTP is used (not   */
-    /* injected group stop ADC_CR_JADSTP).                                    */
-    /* Procedure to be followed: Wait until JEOS=1, clear JEOS, set ADSTP=1   */
-    /* (see reference manual).                                                */
-    if (((hadc->Instance->CFGR & ADC_CFGR_JAUTO) != 0UL)
-        && (hadc->Init.ContinuousConvMode == ENABLE)
-        && (hadc->Init.LowPowerAutoWait == ENABLE)
-       )
-    {
-      /* Use stop of regular group */
-      conversion_group_reassigned = ADC_REGULAR_GROUP;
-
-      /* Wait until JEOS=1 (maximum Timeout: 4 injected conversions) */
-      while (__HAL_ADC_GET_FLAG(hadc, ADC_FLAG_JEOS) == 0UL)
-      {
-        if (Conversion_Timeout_CPU_cycles >= (ADC_CONVERSION_TIME_MAX_CPU_CYCLES * 4UL))
-        {
-          /* Update ADC state machine to error */
-          SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL);
-
-          /* Set ADC error code to ADC peripheral internal error */
-          SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL);
-
-          return HAL_ERROR;
-        }
-        Conversion_Timeout_CPU_cycles ++;
-      }
-
-      /* Clear JEOS */
-      __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_JEOS);
-    }
-
-    /* Stop potential conversion on going on ADC group regular */
-    if (conversion_group_reassigned != ADC_INJECTED_GROUP)
-    {
-      /* Software is allowed to set ADSTP only when ADSTART=1 and ADDIS=0 */
-      if (LL_ADC_REG_IsConversionOngoing(hadc->Instance) != 0UL)
-      {
-        if (LL_ADC_IsDisableOngoing(hadc->Instance) == 0UL)
-        {
-          /* Stop ADC group regular conversion */
-          LL_ADC_REG_StopConversion(hadc->Instance);
-        }
-      }
-    }
-
-    /* Stop potential conversion on going on ADC group injected */
-    if (conversion_group_reassigned != ADC_REGULAR_GROUP)
-    {
-      /* Software is allowed to set JADSTP only when JADSTART=1 and ADDIS=0 */
-      if (LL_ADC_INJ_IsConversionOngoing(hadc->Instance) != 0UL)
-      {
-        if (LL_ADC_IsDisableOngoing(hadc->Instance) == 0UL)
-        {
-          /* Stop ADC group injected conversion */
-          LL_ADC_INJ_StopConversion(hadc->Instance);
-        }
-      }
-    }
-
-    /* Selection of start and stop bits with respect to the regular or injected group */
-    switch (conversion_group_reassigned)
-    {
-      case ADC_REGULAR_INJECTED_GROUP:
-        tmp_ADC_CR_ADSTART_JADSTART = (ADC_CR_ADSTART | ADC_CR_JADSTART);
-        break;
-      case ADC_INJECTED_GROUP:
-        tmp_ADC_CR_ADSTART_JADSTART = ADC_CR_JADSTART;
-        break;
-      /* Case ADC_REGULAR_GROUP only*/
-      default:
-        tmp_ADC_CR_ADSTART_JADSTART = ADC_CR_ADSTART;
-        break;
-    }
-
-    /* Wait for conversion effectively stopped */
-    tickstart = HAL_GetTick();
-
-    while ((hadc->Instance->CR & tmp_ADC_CR_ADSTART_JADSTART) != 0UL)
-    {
-      if ((HAL_GetTick() - tickstart) > ADC_STOP_CONVERSION_TIMEOUT)
-      {
-        /* New check to avoid false timeout detection in case of preemption */
-        if ((hadc->Instance->CR & tmp_ADC_CR_ADSTART_JADSTART) != 0UL)
-        {
-          /* Update ADC state machine to error */
-          SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL);
-
-          /* Set ADC error code to ADC peripheral internal error */
-          SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL);
-
-          return HAL_ERROR;
-        }
-      }
-    }
-
-  }
-#endif /* ADC_SUPPORT_2_5_MSPS */
-
-  /* Return HAL status */
-  return HAL_OK;
-}
-
-
-
-/**
-  * @brief  Enable the selected ADC.
-  * @note   Prerequisite condition to use this function: ADC must be disabled
-  *         and voltage regulator must be enabled (done into HAL_ADC_Init()).
-  * @param hadc ADC handle
-  * @retval HAL status.
-  */
-HAL_StatusTypeDef ADC_Enable(ADC_HandleTypeDef *hadc)
-{
-  uint32_t tickstart;
-  __IO uint32_t wait_loop_index = 0UL;
-
-  /* ADC enable and wait for ADC ready (in case of ADC is disabled or         */
-  /* enabling phase not yet completed: flag ADC ready not yet set).           */
-  /* Timeout implemented to not be stuck if ADC cannot be enabled (possible   */
-  /* causes: ADC clock not running, ...).                                     */
-  if (LL_ADC_IsEnabled(hadc->Instance) == 0UL)
-  {
-    /* Check if conditions to enable the ADC are fulfilled */
-#if  defined(ADC_SUPPORT_2_5_MSPS)
-    if ((hadc->Instance->CR & (ADC_CR_ADCAL | ADC_CR_ADSTP | ADC_CR_ADSTART | ADC_CR_ADDIS | ADC_CR_ADEN)) != 0UL)
-#else
-    if ((hadc->Instance->CR & (ADC_CR_ADCAL | ADC_CR_JADSTP | ADC_CR_ADSTP | ADC_CR_JADSTART | ADC_CR_ADSTART | ADC_CR_ADDIS | ADC_CR_ADEN)) != 0UL)
-#endif /* ADC_SUPPORT_2_5_MSPS */
-    {
-      /* Update ADC state machine to error */
-      SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL);
-
-      /* Set ADC error code to ADC peripheral internal error */
-      SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL);
-
-      return HAL_ERROR;
-    }
-
-    /* Enable the ADC peripheral */
-    LL_ADC_Enable(hadc->Instance);
-
-    if((LL_ADC_GetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(hadc->Instance)) & LL_ADC_PATH_INTERNAL_TEMPSENSOR) != 0UL)
-    {
-      /* Delay for temperature sensor buffer stabilization time */
-      /* Wait loop initialization and execution */
-      /* Note: Variable divided by 2 to compensate partially              */
-      /*       CPU processing cycles, scaling in us split to not          */
-      /*       exceed 32 bits register capacity and handle low frequency. */
-      wait_loop_index = ((LL_ADC_DELAY_TEMPSENSOR_BUFFER_STAB_US / 10UL) * ((SystemCoreClock / (100000UL * 2UL)) + 1UL));
-      while(wait_loop_index != 0UL)
-      {
-        wait_loop_index--;
-      }
-    }
-
-#if defined(ADC_SUPPORT_2_5_MSPS)
-    /* If low power mode AutoPowerOff is enabled, power-on/off phases are     */
-    /* performed automatically by hardware and flag ADC ready is not set.     */
-    if (hadc->Init.LowPowerAutoPowerOff != ENABLE)
-#endif /*ADC_SUPPORT_2_5_MSPS */
-    {
-      /* Wait for ADC effectively enabled */
-      tickstart = HAL_GetTick();
-      
-      while(__HAL_ADC_GET_FLAG(hadc, ADC_FLAG_RDY) == 0UL)
-      {
-        /*  If ADEN bit is set less than 4 ADC clock cycles after the ADCAL bit 
-            has been cleared (after a calibration), ADEN bit is reset by the 
-            calibration logic.
-            The workaround is to continue setting ADEN until ADRDY is becomes 1.
-            Additionally, ADC_ENABLE_TIMEOUT is defined to encompass this
-            4 ADC clock cycle duration */
-        /* Note: Test of ADC enabled required due to hardware constraint to     */
-        /*       not enable ADC if already enabled.                             */
-        if(LL_ADC_IsEnabled(hadc->Instance) == 0UL)
-        {
-          LL_ADC_Enable(hadc->Instance);
-        }
-        
-        if((HAL_GetTick() - tickstart) > ADC_ENABLE_TIMEOUT)
-        {
-          /* Update ADC state machine to error */
-          SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL);
-          
-          /* Set ADC error code to ADC peripheral internal error */
-          SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL);
-          
-          return HAL_ERROR;
-        }
-      }
-    }
-  }
-
-  /* Return HAL status */
-  return HAL_OK;
-}
-
-/**
-  * @brief  Disable the selected ADC.
-  * @note   Prerequisite condition to use this function: ADC conversions must be
-  *         stopped.
-  * @param hadc ADC handle
-  * @retval HAL status.
-  */
-HAL_StatusTypeDef ADC_Disable(ADC_HandleTypeDef *hadc)
-{
-  uint32_t tickstart;
-  const uint32_t tmp_adc_is_disable_on_going = LL_ADC_IsDisableOngoing(hadc->Instance);
-
-  /* Verification if ADC is not already disabled:                             */
-  /* Note: forbidden to disable ADC (set bit ADC_CR_ADDIS) if ADC is already  */
-  /*       disabled.                                                          */
-  if ((LL_ADC_IsEnabled(hadc->Instance) != 0UL)
-      && (tmp_adc_is_disable_on_going == 0UL)
-     )
-  {
-    /* Check if conditions to disable the ADC are fulfilled */
-#if  defined(ADC_SUPPORT_2_5_MSPS)
-    if ((hadc->Instance->CR & (ADC_CR_ADSTART | ADC_CR_ADEN)) == ADC_CR_ADEN)
-#else
-    if ((hadc->Instance->CR & (ADC_CR_JADSTART | ADC_CR_ADSTART | ADC_CR_ADEN)) == ADC_CR_ADEN)
-#endif /* ADC_SUPPORT_2_5_MSPS */
-    {
-      /* Disable the ADC peripheral */
-      LL_ADC_Disable(hadc->Instance);
-      __HAL_ADC_CLEAR_FLAG(hadc, (ADC_FLAG_EOSMP | ADC_FLAG_RDY));
-    }
-    else
-    {
-      /* Update ADC state machine to error */
-      SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL);
-
-      /* Set ADC error code to ADC peripheral internal error */
-      SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL);
-
-      return HAL_ERROR;
-    }
-
-    /* Wait for ADC effectively disabled */
-    /* Get tick count */
-    tickstart = HAL_GetTick();
-
-    while ((hadc->Instance->CR & ADC_CR_ADEN) != 0UL)
-    {
-      if ((HAL_GetTick() - tickstart) > ADC_DISABLE_TIMEOUT)
-      {
-        /* New check to avoid false timeout detection in case of preemption */
-        if ((hadc->Instance->CR & ADC_CR_ADEN) != 0UL)
-        {
-          /* Update ADC state machine to error */
-          SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL);
-
-          /* Set ADC error code to ADC peripheral internal error */
-          SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL);
-
-          return HAL_ERROR;
-        }
-      }
-    }
-  }
-
-  /* Return HAL status */
-  return HAL_OK;
-}
-
-/**
-  * @brief  DMA transfer complete callback.
-  * @param hdma pointer to DMA handle.
-  * @retval None
-  */
-void ADC_DMAConvCplt(DMA_HandleTypeDef *hdma)
-{
-  /* Retrieve ADC handle corresponding to current DMA handle */
-  ADC_HandleTypeDef *hadc = (ADC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
-
-  /* Update state machine on conversion status if not in error state */
-  if ((hadc->State & (HAL_ADC_STATE_ERROR_INTERNAL | HAL_ADC_STATE_ERROR_DMA)) == 0UL)
-  {
-    /* Set ADC state */
-    SET_BIT(hadc->State, HAL_ADC_STATE_REG_EOC);
-
-    /* Determine whether any further conversion upcoming on group regular     */
-    /* by external trigger, continuous mode or scan sequence on going         */
-    /* to disable interruption.                                               */
-    /* Is it the end of the regular sequence ? */
-#if  defined(ADC_SUPPORT_2_5_MSPS)
-    if(   (LL_ADC_REG_IsTriggerSourceSWStart(hadc->Instance) != 0UL)
-       && (hadc->Init.ContinuousConvMode == DISABLE)
-      )
-    {
-      /* If End of Sequence is reached, disable interrupts */
-      if( __HAL_ADC_GET_FLAG(hadc, ADC_FLAG_EOS) )
-      {
-        /* Allowed to modify bits ADC_IT_EOC/ADC_IT_EOS only if bit           */
-        /* ADSTART==0 (no conversion on going)                                */
-        if (LL_ADC_REG_IsConversionOngoing(hadc->Instance) == 0UL)
-        {
-          /* Disable ADC end of single conversion interrupt on group regular */
-          /* Note: Overrun interrupt was enabled with EOC interrupt in        */
-          /* HAL_Start_IT(), but is not disabled here because can be used     */
-          /* by overrun IRQ process below.                                    */
-          __HAL_ADC_DISABLE_IT(hadc, ADC_IT_EOC | ADC_IT_EOS);
-          
-          /* Set ADC state */
-          ADC_STATE_CLR_SET(hadc->State,
-                            HAL_ADC_STATE_REG_BUSY,
-                            HAL_ADC_STATE_READY);
-        }
-        else
-        {
-          /* Change ADC state to error state */
-          SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG);
-          
-          /* Set ADC error code to ADC peripheral internal error */
-          SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL);
-        }
-      }
-    }
-    
-#else
-    if ((hadc->Instance->ISR & ADC_FLAG_EOS) != 0UL)
-    {
-      /* Are conversions software-triggered ? */
-      if (LL_ADC_REG_IsTriggerSourceSWStart(hadc->Instance) != 0UL)
-      {
-        /* Is CONT bit set ? */
-        if (READ_BIT(hadc->Instance->CFGR, ADC_CFGR_CONT) == 0UL)
-        {
-          /* CONT bit is not set, no more conversions expected */
-          CLEAR_BIT(hadc->State, HAL_ADC_STATE_REG_BUSY);
-          if ((hadc->State & HAL_ADC_STATE_INJ_BUSY) == 0UL)
-          {
-            SET_BIT(hadc->State, HAL_ADC_STATE_READY);
-          }
-        }
-      }
-    }
-    else
-    {
-      /* DMA End of Transfer interrupt was triggered but conversions sequence
-         is not over. If DMACFG is set to 0, conversions are stopped. */
-      if (READ_BIT(hadc->Instance->CFGR, ADC_CFGR_DMACFG) == 0UL)
-      {
-        /* DMACFG bit is not set, conversions are stopped. */
-        CLEAR_BIT(hadc->State, HAL_ADC_STATE_REG_BUSY);
-        if ((hadc->State & HAL_ADC_STATE_INJ_BUSY) == 0UL)
-        {
-          SET_BIT(hadc->State, HAL_ADC_STATE_READY);
-        }
-      }
-    }
-#endif /* ADC_SUPPORT_2_5_MSPS */
-
-    /* Conversion complete callback */
-#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1)
-    hadc->ConvCpltCallback(hadc);
-#else
-    HAL_ADC_ConvCpltCallback(hadc);
-#endif /* USE_HAL_ADC_REGISTER_CALLBACKS */
-  }
-  else /* DMA and-or internal error occurred */
-  {
-    if ((hadc->State & HAL_ADC_STATE_ERROR_INTERNAL) != 0UL)
-    {
-      /* Call HAL ADC Error Callback function */
-#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1)
-      hadc->ErrorCallback(hadc);
-#else
-      HAL_ADC_ErrorCallback(hadc);
-#endif /* USE_HAL_ADC_REGISTER_CALLBACKS */
-    }
-    else
-    {
-      /* Call ADC DMA error callback */
-      hadc->DMA_Handle->XferErrorCallback(hdma);
-    }
-  }
-}
-
-/**
-  * @brief  DMA half transfer complete callback.
-  * @param hdma pointer to DMA handle.
-  * @retval None
-  */
-void ADC_DMAHalfConvCplt(DMA_HandleTypeDef *hdma)
-{
-  /* Retrieve ADC handle corresponding to current DMA handle */
-  ADC_HandleTypeDef *hadc = (ADC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
-
-  /* Half conversion callback */
-#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1)
-  hadc->ConvHalfCpltCallback(hadc);
-#else
-  HAL_ADC_ConvHalfCpltCallback(hadc);
-#endif /* USE_HAL_ADC_REGISTER_CALLBACKS */
-}
-
-/**
-  * @brief  DMA error callback.
-  * @param hdma pointer to DMA handle.
-  * @retval None
-  */
-void ADC_DMAError(DMA_HandleTypeDef *hdma)
-{
-  /* Retrieve ADC handle corresponding to current DMA handle */
-  ADC_HandleTypeDef *hadc = (ADC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
-
-  /* Set ADC state */
-  SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_DMA);
-
-  /* Set ADC error code to DMA error */
-  SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_DMA);
-
-  /* Error callback */
-#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1)
-  hadc->ErrorCallback(hadc);
-#else
-  HAL_ADC_ErrorCallback(hadc);
-#endif /* USE_HAL_ADC_REGISTER_CALLBACKS */
-}
-
-/**
-  * @}
-  */
-
-#endif /* HAL_ADC_MODULE_ENABLED */
-/**
-  * @}
-  */
-
-/**
-  * @}
-  */

+ 0 - 1826
non_catalog_apps/flipperscope/lib/adc/stm32wbxx_hal_adc_ex.c

@@ -1,1826 +0,0 @@
-/**
-  ******************************************************************************
-  * @file    stm32wbxx_hal_adc_ex.c
-  * @author  MCD Application Team
-  * @brief   This file provides firmware functions to manage the following
-  *          functionalities of the Analog to Digital Converter (ADC)
-  *          peripheral:
-  *           + Operation functions
-  *             ++ Start, stop, get result of conversions of ADC group injected,
-  *                using 2 possible modes: polling, interruption (not available on devices: STM32WB10xx, STM32WB15xx, STM32WB1Mxx ).
-  *             ++ Calibration
-  *               +++ ADC automatic self-calibration
-  *               +++ Calibration factors get or set
-  *           + Control functions
-  *             ++ Channels configuration on ADC group injected (not available on devices: STM32WB10xx, STM32WB15xx, STM32WB1Mxx )
-  *           + State functions
-  *             ++ ADC group injected contexts queue management (not available on devices: STM32WB10xx, STM32WB15xx, STM32WB1Mxx )
-  *          Other functions (generic functions) are available in file
-  *          "stm32wbxx_hal_adc.c".
-  ******************************************************************************
-  * @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
-  [..]
-  (@) Sections "ADC peripheral features" and "How to use this driver" are
-      available in file of generic functions "stm32wbxx_hal_adc.c".
-  [..]
-  @endverbatim
-  ******************************************************************************
-  */
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32wbxx_hal.h"
-
-/** @addtogroup STM32WBxx_HAL_Driver
-  * @{
-  */
-
-/** @defgroup ADCEx ADCEx
-  * @brief ADC Extended HAL module driver
-  * @{
-  */
-
-#ifdef HAL_ADC_MODULE_ENABLED
-
-/* Private typedef -----------------------------------------------------------*/
-/* Private define ------------------------------------------------------------*/
-
-/** @defgroup ADCEx_Private_Constants ADC Extended Private Constants
-  * @{
-  */
-
-#define ADC_JSQR_FIELDS  ((ADC_JSQR_JL | ADC_JSQR_JEXTSEL | ADC_JSQR_JEXTEN |\
-                           ADC_JSQR_JSQ1  | ADC_JSQR_JSQ2 |\
-                           ADC_JSQR_JSQ3 | ADC_JSQR_JSQ4 ))  /*!< ADC_JSQR fields of parameters that can be updated anytime
-                                                                  once the ADC is enabled */
-
-/* Fixed timeout value for ADC calibration.                                   */
-/* Values defined to be higher than worst cases: maximum ratio between ADC    */
-/* and CPU clock frequencies.                                                 */
-/* Example of profile low frequency : ADC frequency at 46.9kHz (ADC clock     */
-/* source PLL SAI 12MHz, ADC clock prescaler 256), CPU frequency 64MHz.       */
-/* Calibration time max = 116 / fADC (refer to datasheet)                     */
-/*                      = 158 379 CPU cycles                                  */
-#define ADC_CALIBRATION_TIMEOUT         (158379UL)   /*!< ADC calibration time-out value (unit: CPU cycles) */
-#define ADC_DISABLE_TIMEOUT             (2UL)
-
-/**
-  * @}
-  */
-
-/* Private macro -------------------------------------------------------------*/
-/* Private variables ---------------------------------------------------------*/
-/* Private function prototypes -----------------------------------------------*/
-/* Exported functions --------------------------------------------------------*/
-
-/** @defgroup ADCEx_Exported_Functions ADC Extended Exported Functions
-  * @{
-  */
-
-/** @defgroup ADCEx_Exported_Functions_Group1 Extended Input and Output operation functions
-  * @brief    Extended IO operation functions
-  *
-@verbatim
- ===============================================================================
-                      ##### IO operation functions #####
- ===============================================================================
-    [..]  This section provides functions allowing to:
-
-      (+) Perform the ADC self-calibration for single or differential ending.
-      (+) Get calibration factors for single or differential ending.
-      (+) Set calibration factors for single or differential ending.
-
-      (+) Start conversion of ADC group injected (not available on devices: STM32WB10xx, STM32WB15xx, STM32WB1Mxx ).
-      (+) Stop conversion of ADC group injected (not available on devices: STM32WB10xx, STM32WB15xx, STM32WB1Mxx ).
-      (+) Poll for conversion complete on ADC group injected (not available on devices: STM32WB10xx, STM32WB15xx, STM32WB1Mxx ).
-      (+) Get result of ADC group injected channel conversion (not available on devices: STM32WB10xx, STM32WB15xx, STM32WB1Mxx ).
-      (+) Start conversion of ADC group injected and enable interruptions (not available on devices: STM32WB10xx, STM32WB15xx, STM32WB1Mxx ).
-      (+) Stop conversion of ADC group injected and disable interruptions (not available on devices: STM32WB10xx, STM32WB15xx, STM32WB1Mxx ).
-
-@endverbatim
-  * @{
-  */
-
-/**
-  * @brief  Perform an ADC automatic self-calibration
-  *         Calibration prerequisite: ADC must be disabled (execute this
-  *         function before HAL_ADC_Start() or after HAL_ADC_Stop() ).
-  * @param  hadc       ADC handle
-  * @param  SingleDiff Selection of single-ended or differential input
-  *         This parameter can be one of the following values:
-  *           @arg @ref ADC_SINGLE_ENDED       Channel in mode input single ended
-  *           @arg @ref ADC_DIFFERENTIAL_ENDED Channel in mode input differential ended (1)
-  *
-  *         (1) On STM32WB series, parameter not available on devices: STM32WB10xx, STM32WB15xx, STM32WB1Mxx.
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_ADCEx_Calibration_Start(ADC_HandleTypeDef *hadc, uint32_t SingleDiff)
-{
-#if defined(ADC_SUPPORT_2_5_MSPS)
-  UNUSED(SingleDiff);
-
-  uint32_t calibration_index;
-  uint32_t calibration_factor_accumulated = 0;
-  uint32_t backup_setting_cfgr1;
-  uint32_t tickstart;
-  uint32_t adc_clk_async_presc;
-  __IO uint32_t delay_cpu_cycles;
-#endif /* ADC_SUPPORT_2_5_MSPS */
-
-  HAL_StatusTypeDef tmp_hal_status;
-  __IO uint32_t wait_loop_index = 0UL;
-
-  /* Check the parameters */
-  assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
-  assert_param(IS_ADC_SINGLE_DIFFERENTIAL(SingleDiff));
-
-  /* Process locked */
-  __HAL_LOCK(hadc);
-
-  /* Calibration prerequisite: ADC must be disabled. */
-
-  /* Disable the ADC (if not already disabled) */
-  tmp_hal_status = ADC_Disable(hadc);
-
-  /* Check if ADC is effectively disabled */
-  if (tmp_hal_status == HAL_OK)
-  {
-    /* Set ADC state */
-#if defined(ADC_SUPPORT_2_5_MSPS)
-    ADC_STATE_CLR_SET(hadc->State,
-                      HAL_ADC_STATE_REG_BUSY,
-                      HAL_ADC_STATE_BUSY_INTERNAL);
-#else
-    ADC_STATE_CLR_SET(hadc->State,
-                      HAL_ADC_STATE_REG_BUSY | HAL_ADC_STATE_INJ_BUSY,
-                      HAL_ADC_STATE_BUSY_INTERNAL);
-#endif /* ADC_SUPPORT_2_5_MSPS */
-
-    /* Start ADC calibration in mode single-ended or differential */
-#if defined(ADC_SUPPORT_2_5_MSPS)
-    /* Manage settings impacting calibration */
-    /* - Disable ADC mode auto power-off */
-    /* - Disable ADC DMA transfer request during calibration */
-    /* Note: Specificity of this STM32 series: Calibration factor is          */
-    /*       available in data register and also transferred by DMA.          */
-    /*       To not insert ADC calibration factor among ADC conversion data   */
-    /*       in array variable, DMA transfer must be disabled during          */
-    /*       calibration.                                                     */
-    backup_setting_cfgr1 = READ_BIT(hadc->Instance->CFGR1, ADC_CFGR1_DMAEN | ADC_CFGR1_DMACFG | ADC_CFGR1_AUTOFF);
-    CLEAR_BIT(hadc->Instance->CFGR1, ADC_CFGR1_DMAEN | ADC_CFGR1_DMACFG | ADC_CFGR1_AUTOFF);
-
-    /* ADC calibration procedure */
-    /* Note: Perform an averaging of 8 calibrations for optimized accuracy */
-    for (calibration_index = 0UL; calibration_index < 8UL; calibration_index++)
-    {
-      /* Start ADC calibration */
-      LL_ADC_StartCalibration(hadc->Instance);
-
-#else
-    LL_ADC_StartCalibration(hadc->Instance, SingleDiff);
-#endif /* ADC_SUPPORT_2_5_MSPS */
-
-    /* Wait for calibration completion */
-    while (LL_ADC_IsCalibrationOnGoing(hadc->Instance) != 0UL)
-    {
-      wait_loop_index++;
-      if (wait_loop_index >= ADC_CALIBRATION_TIMEOUT)
-      {
-        /* Update ADC state machine to error */
-        ADC_STATE_CLR_SET(hadc->State,
-                          HAL_ADC_STATE_BUSY_INTERNAL,
-                          HAL_ADC_STATE_ERROR_INTERNAL);
-
-        /* Process unlocked */
-        __HAL_UNLOCK(hadc);
-
-        return HAL_ERROR;
-      }
-    }
-#if defined(ADC_SUPPORT_2_5_MSPS)
-      calibration_factor_accumulated += LL_ADC_GetCalibrationFactor(hadc->Instance);
-    }
-    /* Compute average */
-    calibration_factor_accumulated /= calibration_index;
-    /* Apply calibration factor (requires ADC enable and disable process) */
-    LL_ADC_Enable(hadc->Instance);
-
-    /* Case of ADC clocked at low frequency: Delay required between ADC enable and disable actions */
-    if(LL_ADC_GetClock(hadc->Instance) == LL_ADC_CLOCK_ASYNC)
-    {
-      adc_clk_async_presc = LL_ADC_GetCommonClock(__LL_ADC_COMMON_INSTANCE(hadc->Instance));
-
-      if(adc_clk_async_presc >= LL_ADC_CLOCK_ASYNC_DIV16)
-      {
-        /* Delay loop initialization and execution */
-        /* Delay depends on ADC clock prescaler: Compute ADC clock asynchronous prescaler to decimal format */
-        delay_cpu_cycles = (1U << ((adc_clk_async_presc >> ADC_CCR_PRESC_Pos) - 3U));
-        /* Divide variable by 2 to compensate partially CPU processing cycles */
-        delay_cpu_cycles >>= 1U;
-
-        while(delay_cpu_cycles != 0)
-        {
-          delay_cpu_cycles--;
-        }
-      }
-    }
-
-    LL_ADC_SetCalibrationFactor(hadc->Instance, calibration_factor_accumulated);
-    LL_ADC_Disable(hadc->Instance);
-
-    /* Wait for ADC effectively disabled before changing configuration */
-    /* Get tick count */
-    tickstart = HAL_GetTick();
-
-    while (LL_ADC_IsEnabled(hadc->Instance) != 0UL)
-    {
-      if ((HAL_GetTick() - tickstart) > ADC_DISABLE_TIMEOUT)
-      {
-        /* New check to avoid false timeout detection in case of preemption */
-        if (LL_ADC_IsEnabled(hadc->Instance) != 0UL)
-        {
-          /* Update ADC state machine to error */
-          SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL);
-
-          /* Set ADC error code to ADC peripheral internal error */
-          SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL);
-
-          return HAL_ERROR;
-        }
-      }
-    }
-
-    /* Restore configuration after calibration */
-    SET_BIT(hadc->Instance->CFGR1, backup_setting_cfgr1);
-#endif /* ADC_SUPPORT_2_5_MSPS */
-
-    /* Set ADC state */
-    ADC_STATE_CLR_SET(hadc->State,
-                      HAL_ADC_STATE_BUSY_INTERNAL,
-                      HAL_ADC_STATE_READY);
-  }
-  else
-  {
-    SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL);
-
-    /* Note: No need to update variable "tmp_hal_status" here: already set    */
-    /*       to state "HAL_ERROR" by function disabling the ADC.              */
-  }
-
-  /* Process unlocked */
-  __HAL_UNLOCK(hadc);
-
-  /* Return function status */
-  return tmp_hal_status;
-}
-
-/**
-  * @brief  Get the calibration factor.
-  * @param hadc ADC handle.
-  * @param SingleDiff This parameter can be only:
-  *           @arg @ref ADC_SINGLE_ENDED       Channel in mode input single ended
-  *           @arg @ref ADC_DIFFERENTIAL_ENDED Channel in mode input differential ended (1)
-  *
-  *         (1) On STM32WB series, parameter not available on devices: STM32WB10xx, STM32WB15xx, STM32WB1Mxx.
-  * @retval Calibration value.
-  */
-uint32_t HAL_ADCEx_Calibration_GetValue(const ADC_HandleTypeDef *hadc, uint32_t SingleDiff)
-{
-#if defined(ADC_SUPPORT_2_5_MSPS)
-  UNUSED(SingleDiff);
-#endif /* ADC_SUPPORT_2_5_MSPS */
-  
-  /* Check the parameters */
-  assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
-  assert_param(IS_ADC_SINGLE_DIFFERENTIAL(SingleDiff));
-
-  /* Return the selected ADC calibration value */
-#if defined(ADC_SUPPORT_2_5_MSPS)
-  return LL_ADC_GetCalibrationFactor(hadc->Instance);
-#else
-  return LL_ADC_GetCalibrationFactor(hadc->Instance, SingleDiff);
-#endif /* ADC_SUPPORT_2_5_MSPS */
-}
-
-/**
-  * @brief  Set the calibration factor to overwrite automatic conversion result.
-  *         ADC must be enabled and no conversion is ongoing.
-  * @param hadc ADC handle
-  * @param SingleDiff This parameter can be only:
-  *           @arg @ref ADC_SINGLE_ENDED       Channel in mode input single ended
-  *           @arg @ref ADC_DIFFERENTIAL_ENDED Channel in mode input differential ended (1)
-  *
-  *         (1) On STM32WB series, parameter not available on devices: STM32WB10xx, STM32WB15xx, STM32WB1Mxx.
-  * @param CalibrationFactor Calibration factor (coded on 7 bits maximum)
-  * @retval HAL state
-  */
-HAL_StatusTypeDef HAL_ADCEx_Calibration_SetValue(ADC_HandleTypeDef *hadc, uint32_t SingleDiff, uint32_t CalibrationFactor)
-{
-#if defined(ADC_SUPPORT_2_5_MSPS)
-  UNUSED(SingleDiff);
-#endif /* ADC_SUPPORT_2_5_MSPS */
-
-  HAL_StatusTypeDef tmp_hal_status = HAL_OK;
-  uint32_t tmp_adc_is_conversion_on_going_regular;
-#if  defined(ADC_SUPPORT_2_5_MSPS)
-/* Feature "ADC group injected" not available on ADC peripheral of this STM32WB device */
-#else
-  uint32_t tmp_adc_is_conversion_on_going_injected;
-#endif /* ADC_SUPPORT_2_5_MSPS */
-
-  /* Check the parameters */
-  assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
-  assert_param(IS_ADC_SINGLE_DIFFERENTIAL(SingleDiff));
-  assert_param(IS_ADC_CALFACT(CalibrationFactor));
-
-  /* Process locked */
-  __HAL_LOCK(hadc);
-
-  /* Verification of hardware constraints before modifying the calibration    */
-  /* factors register: ADC must be enabled, no conversion on going.           */
-  tmp_adc_is_conversion_on_going_regular = LL_ADC_REG_IsConversionOngoing(hadc->Instance);
-#if  defined(ADC_SUPPORT_2_5_MSPS)
-/* Feature "ADC group injected" not available on ADC peripheral of this STM32WB device */
-#else
-  tmp_adc_is_conversion_on_going_injected = LL_ADC_INJ_IsConversionOngoing(hadc->Instance);
-#endif /* ADC_SUPPORT_2_5_MSPS */
-
-  if ((LL_ADC_IsEnabled(hadc->Instance) != 0UL)
-      && (tmp_adc_is_conversion_on_going_regular == 0UL)
-#if  defined(ADC_SUPPORT_2_5_MSPS)
-/* Feature "ADC group injected" not available on ADC peripheral of this STM32WB device */
-#else
-      && (tmp_adc_is_conversion_on_going_injected == 0UL)
-#endif /* ADC_SUPPORT_2_5_MSPS */
-     )
-  {
-    /* Set the selected ADC calibration value */
-#if defined(ADC_SUPPORT_2_5_MSPS)
-    LL_ADC_SetCalibrationFactor(hadc->Instance, CalibrationFactor);
-#else
-    LL_ADC_SetCalibrationFactor(hadc->Instance, SingleDiff, CalibrationFactor);
-#endif /* ADC_SUPPORT_2_5_MSPS */
-  }
-  else
-  {
-    /* Update ADC state machine */
-    SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG);
-    /* Update ADC error code */
-    SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL);
-
-    /* Update ADC state machine to error */
-    tmp_hal_status = HAL_ERROR;
-  }
-
-  /* Process unlocked */
-  __HAL_UNLOCK(hadc);
-
-  /* Return function status */
-  return tmp_hal_status;
-}
-
-#if  defined(ADC_SUPPORT_2_5_MSPS)
-/* Feature "ADC group injected" not available on ADC peripheral of this STM32WB device */
-#else
-/**
-  * @brief  Enable ADC, start conversion of injected group.
-  * @note   Interruptions enabled in this function: None.
-  * @param hadc ADC handle.
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_ADCEx_InjectedStart(ADC_HandleTypeDef *hadc)
-{
-  HAL_StatusTypeDef tmp_hal_status;
-  uint32_t tmp_config_injected_queue;
-
-  /* Check the parameters */
-  assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
-
-  if (LL_ADC_INJ_IsConversionOngoing(hadc->Instance) != 0UL)
-  {
-    return HAL_BUSY;
-  }
-  else
-  {
-    /* In case of software trigger detection enabled, JQDIS must be set
-      (which can be done only if ADSTART and JADSTART are both cleared).
-       If JQDIS is not set at that point, returns an error
-       - since software trigger detection is disabled. User needs to
-       resort to HAL_ADCEx_DisableInjectedQueue() API to set JQDIS.
-       - or (if JQDIS is intentionally reset) since JEXTEN = 0 which means
-         the queue is empty */
-    tmp_config_injected_queue = READ_BIT(hadc->Instance->CFGR, ADC_CFGR_JQDIS);
-
-    if ((READ_BIT(hadc->Instance->JSQR, ADC_JSQR_JEXTEN) == 0UL)
-        && (tmp_config_injected_queue == 0UL)
-       )
-    {
-      SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG);
-      return HAL_ERROR;
-    }
-
-    /* Process locked */
-    __HAL_LOCK(hadc);
-
-    /* Enable the ADC peripheral */
-    tmp_hal_status = ADC_Enable(hadc);
-
-    /* Start conversion if ADC is effectively enabled */
-    if (tmp_hal_status == HAL_OK)
-    {
-      /* Check if a regular conversion is ongoing */
-      if ((hadc->State & HAL_ADC_STATE_REG_BUSY) != 0UL)
-      {
-        /* Reset ADC error code field related to injected conversions only */
-        CLEAR_BIT(hadc->ErrorCode, HAL_ADC_ERROR_JQOVF);
-      }
-      else
-      {
-        /* Set ADC error code to none */
-        ADC_CLEAR_ERRORCODE(hadc);
-      }
-
-      /* Set ADC state                                                        */
-      /* - Clear state bitfield related to injected group conversion results  */
-      /* - Set state bitfield related to injected operation                   */
-      ADC_STATE_CLR_SET(hadc->State,
-                        HAL_ADC_STATE_READY | HAL_ADC_STATE_INJ_EOC,
-                        HAL_ADC_STATE_INJ_BUSY);
-
-      /* Clear ADC group injected group conversion flag */
-      /* (To ensure of no unknown state from potential previous ADC operations) */
-      __HAL_ADC_CLEAR_FLAG(hadc, (ADC_FLAG_JEOC | ADC_FLAG_JEOS));
-
-      /* Process unlocked */
-      /* Unlock before starting ADC conversions: in case of potential         */
-      /* interruption, to let the process to ADC IRQ Handler.                 */
-      __HAL_UNLOCK(hadc);
-
-      /* Enable conversion of injected group, if automatic injected conversion  */
-      /* is disabled.                                                           */
-      /* If software start has been selected, conversion starts immediately.    */
-      /* If external trigger has been selected, conversion will start at next   */
-      /* trigger event.                                                         */
-      if(LL_ADC_INJ_GetTrigAuto(hadc->Instance) == LL_ADC_INJ_TRIG_INDEPENDENT)
-      {
-        /* Start ADC group injected conversion */
-        LL_ADC_INJ_StartConversion(hadc->Instance);
-      }
-    }
-    else
-    {
-      /* Process unlocked */
-      __HAL_UNLOCK(hadc);
-    }
-
-    /* Return function status */
-    return tmp_hal_status;
-  }
-}
-
-/**
-  * @brief  Stop conversion of injected channels. Disable ADC peripheral if
-  *         no regular conversion is on going.
-  * @note   If ADC must be disabled and if conversion is on going on
-  *         regular group, function HAL_ADC_Stop must be used to stop both
-  *         injected and regular groups, and disable the ADC.
-  * @note   If injected group mode auto-injection is enabled,
-  *         function HAL_ADC_Stop must be used.
-  * @param hadc ADC handle.
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_ADCEx_InjectedStop(ADC_HandleTypeDef *hadc)
-{
-  HAL_StatusTypeDef tmp_hal_status;
-
-  /* Check the parameters */
-  assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
-
-  /* Process locked */
-  __HAL_LOCK(hadc);
-
-  /* 1. Stop potential conversion on going on injected group only. */
-  tmp_hal_status = ADC_ConversionStop(hadc, ADC_INJECTED_GROUP);
-
-  /* Disable ADC peripheral if injected conversions are effectively stopped   */
-  /* and if no conversion on regular group is on-going                       */
-  if (tmp_hal_status == HAL_OK)
-  {
-    if (LL_ADC_REG_IsConversionOngoing(hadc->Instance) == 0UL)
-    {
-      /* 2. Disable the ADC peripheral */
-      tmp_hal_status = ADC_Disable(hadc);
-
-      /* Check if ADC is effectively disabled */
-      if (tmp_hal_status == HAL_OK)
-      {
-        /* Set ADC state */
-        ADC_STATE_CLR_SET(hadc->State,
-                          HAL_ADC_STATE_REG_BUSY | HAL_ADC_STATE_INJ_BUSY,
-                          HAL_ADC_STATE_READY);
-      }
-    }
-    /* Conversion on injected group is stopped, but ADC not disabled since    */
-    /* conversion on regular group is still running.                          */
-    else
-    {
-      /* Set ADC state */
-      CLEAR_BIT(hadc->State, HAL_ADC_STATE_INJ_BUSY);
-    }
-  }
-
-  /* Process unlocked */
-  __HAL_UNLOCK(hadc);
-
-  /* Return function status */
-  return tmp_hal_status;
-}
-
-/**
-  * @brief  Wait for injected group conversion to be completed.
-  * @param hadc ADC handle
-  * @param Timeout Timeout value in millisecond.
-  * @note   Depending on hadc->Init.EOCSelection, JEOS or JEOC is
-  *         checked and cleared depending on AUTDLY bit status.
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_ADCEx_InjectedPollForConversion(ADC_HandleTypeDef *hadc, uint32_t Timeout)
-{
-  uint32_t tickstart;
-  uint32_t tmp_Flag_End;
-  uint32_t tmp_adc_inj_is_trigger_source_sw_start;
-  uint32_t tmp_adc_reg_is_trigger_source_sw_start;
-  uint32_t tmp_cfgr;
-
-  /* Check the parameters */
-  assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
-
-  /* If end of sequence selected */
-  if (hadc->Init.EOCSelection == ADC_EOC_SEQ_CONV)
-  {
-    tmp_Flag_End = ADC_FLAG_JEOS;
-  }
-  else /* end of conversion selected */
-  {
-    tmp_Flag_End = ADC_FLAG_JEOC;
-  }
-
-  /* Get timeout */
-  tickstart = HAL_GetTick();
-
-  /* Wait until End of Conversion or Sequence flag is raised */
-  while ((hadc->Instance->ISR & tmp_Flag_End) == 0UL)
-  {
-    /* Check if timeout is disabled (set to infinite wait) */
-    if (Timeout != HAL_MAX_DELAY)
-    {
-      if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0UL))
-      {
-        /* New check to avoid false timeout detection in case of preemption */
-        if ((hadc->Instance->ISR & tmp_Flag_End) == 0UL)
-        {
-          /* Update ADC state machine to timeout */
-          SET_BIT(hadc->State, HAL_ADC_STATE_TIMEOUT);
-
-          /* Process unlocked */
-          __HAL_UNLOCK(hadc);
-
-          return HAL_TIMEOUT;
-        }
-      }
-    }
-  }
-
-  /* Retrieve ADC configuration */
-  tmp_adc_inj_is_trigger_source_sw_start = LL_ADC_INJ_IsTriggerSourceSWStart(hadc->Instance);
-  tmp_adc_reg_is_trigger_source_sw_start = LL_ADC_REG_IsTriggerSourceSWStart(hadc->Instance);
-  tmp_cfgr = READ_REG(hadc->Instance->CFGR);
-
-  /* Update ADC state machine */
-  SET_BIT(hadc->State, HAL_ADC_STATE_INJ_EOC);
-
-  /* Determine whether any further conversion upcoming on group injected      */
-  /* by external trigger or by automatic injected conversion                  */
-  /* from group regular.                                                      */
-  if ((tmp_adc_inj_is_trigger_source_sw_start != 0UL)            ||
-      ((READ_BIT(tmp_cfgr, ADC_CFGR_JAUTO) == 0UL)      &&
-       ((tmp_adc_reg_is_trigger_source_sw_start != 0UL)  &&
-        (READ_BIT(tmp_cfgr, ADC_CFGR_CONT) == 0UL))))
-  {
-    /* Check whether end of sequence is reached */
-    if (__HAL_ADC_GET_FLAG(hadc, ADC_FLAG_JEOS))
-    {
-      /* Particular case if injected contexts queue is enabled:             */
-      /* when the last context has been fully processed, JSQR is reset      */
-      /* by the hardware. Even if no injected conversion is planned to come */
-      /* (queue empty, triggers are ignored), it can start again            */
-      /* immediately after setting a new context (JADSTART is still set).   */
-      /* Therefore, state of HAL ADC injected group is kept to busy.        */
-      if (READ_BIT(hadc->Instance->CFGR, ADC_CFGR_JQM) == 0UL)
-      {
-        /* Set ADC state */
-        CLEAR_BIT(hadc->State, HAL_ADC_STATE_INJ_BUSY);
-
-        if ((hadc->State & HAL_ADC_STATE_REG_BUSY) == 0UL)
-        {
-          SET_BIT(hadc->State, HAL_ADC_STATE_READY);
-        }
-      }
-    }
-  }
-
-  /* Clear polled flag */
-  if (tmp_Flag_End == ADC_FLAG_JEOS)
-  {
-    /* Clear end of sequence JEOS flag of injected group if low power feature */
-    /* "LowPowerAutoWait " is disabled, to not interfere with this feature.   */
-    /* For injected groups, no new conversion will start before JEOS is       */
-    /* cleared.                                                               */
-    if (READ_BIT(hadc->Instance->CFGR, ADC_CFGR_AUTDLY) == 0UL)
-    {
-      __HAL_ADC_CLEAR_FLAG(hadc, (ADC_FLAG_JEOC | ADC_FLAG_JEOS));
-    }
-  }
-  else
-  {
-    __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_JEOC);
-  }
-
-  /* Return API HAL status */
-  return HAL_OK;
-}
-
-/**
-  * @brief  Enable ADC, start conversion of injected group with interruption.
-  * @note   Interruptions enabled in this function according to initialization
-  *         setting : JEOC (end of conversion) or JEOS (end of sequence)
-  * @param hadc ADC handle.
-  * @retval HAL status.
-  */
-HAL_StatusTypeDef HAL_ADCEx_InjectedStart_IT(ADC_HandleTypeDef *hadc)
-{
-  HAL_StatusTypeDef tmp_hal_status;
-  uint32_t tmp_config_injected_queue;
-
-  /* Check the parameters */
-  assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
-
-  if (LL_ADC_INJ_IsConversionOngoing(hadc->Instance) != 0UL)
-  {
-    return HAL_BUSY;
-  }
-  else
-  {
-    /* In case of software trigger detection enabled, JQDIS must be set
-      (which can be done only if ADSTART and JADSTART are both cleared).
-       If JQDIS is not set at that point, returns an error
-       - since software trigger detection is disabled. User needs to
-       resort to HAL_ADCEx_DisableInjectedQueue() API to set JQDIS.
-       - or (if JQDIS is intentionally reset) since JEXTEN = 0 which means
-         the queue is empty */
-    tmp_config_injected_queue = READ_BIT(hadc->Instance->CFGR, ADC_CFGR_JQDIS);
-
-    if ((READ_BIT(hadc->Instance->JSQR, ADC_JSQR_JEXTEN) == 0UL)
-        && (tmp_config_injected_queue == 0UL)
-       )
-    {
-      SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG);
-      return HAL_ERROR;
-    }
-
-    /* Process locked */
-    __HAL_LOCK(hadc);
-
-    /* Enable the ADC peripheral */
-    tmp_hal_status = ADC_Enable(hadc);
-
-    /* Start conversion if ADC is effectively enabled */
-    if (tmp_hal_status == HAL_OK)
-    {
-      /* Check if a regular conversion is ongoing */
-      if ((hadc->State & HAL_ADC_STATE_REG_BUSY) != 0UL)
-      {
-        /* Reset ADC error code field related to injected conversions only */
-        CLEAR_BIT(hadc->ErrorCode, HAL_ADC_ERROR_JQOVF);
-      }
-      else
-      {
-        /* Set ADC error code to none */
-        ADC_CLEAR_ERRORCODE(hadc);
-      }
-
-      /* Set ADC state                                                        */
-      /* - Clear state bitfield related to injected group conversion results  */
-      /* - Set state bitfield related to injected operation                   */
-      ADC_STATE_CLR_SET(hadc->State,
-                        HAL_ADC_STATE_READY | HAL_ADC_STATE_INJ_EOC,
-                        HAL_ADC_STATE_INJ_BUSY);
-
-      /* Clear ADC group injected group conversion flag */
-      /* (To ensure of no unknown state from potential previous ADC operations) */
-      __HAL_ADC_CLEAR_FLAG(hadc, (ADC_FLAG_JEOC | ADC_FLAG_JEOS));
-
-      /* Process unlocked */
-      /* Unlock before starting ADC conversions: in case of potential         */
-      /* interruption, to let the process to ADC IRQ Handler.                 */
-      __HAL_UNLOCK(hadc);
-
-      /* Enable ADC Injected context queue overflow interrupt if this feature   */
-      /* is enabled.                                                            */
-      if ((hadc->Instance->CFGR & ADC_CFGR_JQM) != 0UL)
-      {
-        __HAL_ADC_ENABLE_IT(hadc, ADC_FLAG_JQOVF);
-      }
-
-      /* Enable ADC end of conversion interrupt */
-      switch (hadc->Init.EOCSelection)
-      {
-        case ADC_EOC_SEQ_CONV:
-          __HAL_ADC_DISABLE_IT(hadc, ADC_IT_JEOC);
-          __HAL_ADC_ENABLE_IT(hadc, ADC_IT_JEOS);
-          break;
-        /* case ADC_EOC_SINGLE_CONV */
-        default:
-          __HAL_ADC_DISABLE_IT(hadc, ADC_IT_JEOS);
-          __HAL_ADC_ENABLE_IT(hadc, ADC_IT_JEOC);
-          break;
-      }
-
-      /* Enable conversion of injected group, if automatic injected conversion  */
-      /* is disabled.                                                           */
-      /* If software start has been selected, conversion starts immediately.    */
-      /* If external trigger has been selected, conversion will start at next   */
-      /* trigger event.                                                         */
-      if(LL_ADC_INJ_GetTrigAuto(hadc->Instance) == LL_ADC_INJ_TRIG_INDEPENDENT)
-      {
-        /* Start ADC group injected conversion */
-        LL_ADC_INJ_StartConversion(hadc->Instance);
-      }
-    }
-    else
-    {
-      /* Process unlocked */
-      __HAL_UNLOCK(hadc);
-    }
-
-    /* Return function status */
-    return tmp_hal_status;
-  }
-}
-
-/**
-  * @brief  Stop conversion of injected channels, disable interruption of
-  *         end-of-conversion. Disable ADC peripheral if no regular conversion
-  *         is on going.
-  * @note   If ADC must be disabled and if conversion is on going on
-  *         regular group, function HAL_ADC_Stop must be used to stop both
-  *         injected and regular groups, and disable the ADC.
-  * @note   If injected group mode auto-injection is enabled,
-  *         function HAL_ADC_Stop must be used.
-  * @note   In case of auto-injection mode, HAL_ADC_Stop() must be used.
-  * @param hadc ADC handle
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_ADCEx_InjectedStop_IT(ADC_HandleTypeDef *hadc)
-{
-  HAL_StatusTypeDef tmp_hal_status;
-
-  /* Check the parameters */
-  assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
-
-  /* Process locked */
-  __HAL_LOCK(hadc);
-
-  /* 1. Stop potential conversion on going on injected group only. */
-  tmp_hal_status = ADC_ConversionStop(hadc, ADC_INJECTED_GROUP);
-
-  /* Disable ADC peripheral if injected conversions are effectively stopped   */
-  /* and if no conversion on the other group (regular group) is intended to   */
-  /* continue.                                                                */
-  if (tmp_hal_status == HAL_OK)
-  {
-    /* Disable ADC end of conversion interrupt for injected channels */
-    __HAL_ADC_DISABLE_IT(hadc, (ADC_IT_JEOC | ADC_IT_JEOS | ADC_FLAG_JQOVF));
-
-    if (LL_ADC_REG_IsConversionOngoing(hadc->Instance) == 0UL)
-    {
-      /* 2. Disable the ADC peripheral */
-      tmp_hal_status = ADC_Disable(hadc);
-
-      /* Check if ADC is effectively disabled */
-      if (tmp_hal_status == HAL_OK)
-      {
-        /* Set ADC state */
-        ADC_STATE_CLR_SET(hadc->State,
-                          HAL_ADC_STATE_REG_BUSY | HAL_ADC_STATE_INJ_BUSY,
-                          HAL_ADC_STATE_READY);
-      }
-    }
-    /* Conversion on injected group is stopped, but ADC not disabled since    */
-    /* conversion on regular group is still running.                          */
-    else
-    {
-      /* Set ADC state */
-      CLEAR_BIT(hadc->State, HAL_ADC_STATE_INJ_BUSY);
-    }
-  }
-
-  /* Process unlocked */
-  __HAL_UNLOCK(hadc);
-
-  /* Return function status */
-  return tmp_hal_status;
-}
-#endif /* ADC_SUPPORT_2_5_MSPS */
-
-#if  defined(ADC_SUPPORT_2_5_MSPS)
-/* Feature "ADC group injected" not available on ADC peripheral of this STM32WB device */
-#else
-/**
-  * @brief  Get ADC injected group conversion result.
-  * @note   Reading register JDRx automatically clears ADC flag JEOC
-  *         (ADC group injected end of unitary conversion).
-  * @note   This function does not clear ADC flag JEOS
-  *         (ADC group injected end of sequence conversion)
-  *         Occurrence of flag JEOS rising:
-  *          - If sequencer is composed of 1 rank, flag JEOS is equivalent
-  *            to flag JEOC.
-  *          - If sequencer is composed of several ranks, during the scan
-  *            sequence flag JEOC only is raised, at the end of the scan sequence
-  *            both flags JEOC and EOS are raised.
-  *         Flag JEOS must not be cleared by this function because
-  *         it would not be compliant with low power features
-  *         (feature low power auto-wait, not available on all STM32 families).
-  *         To clear this flag, either use function:
-  *         in programming model IT: @ref HAL_ADC_IRQHandler(), in programming
-  *         model polling: @ref HAL_ADCEx_InjectedPollForConversion()
-  *         or @ref __HAL_ADC_CLEAR_FLAG(&hadc, ADC_FLAG_JEOS).
-  * @param hadc ADC handle
-  * @param InjectedRank the converted ADC injected rank.
-  *          This parameter can be one of the following values:
-  *            @arg @ref ADC_INJECTED_RANK_1 ADC group injected rank 1
-  *            @arg @ref ADC_INJECTED_RANK_2 ADC group injected rank 2
-  *            @arg @ref ADC_INJECTED_RANK_3 ADC group injected rank 3
-  *            @arg @ref ADC_INJECTED_RANK_4 ADC group injected rank 4
-  * @retval ADC group injected conversion data
-  */
-uint32_t HAL_ADCEx_InjectedGetValue(const ADC_HandleTypeDef *hadc, uint32_t InjectedRank)
-{
-  uint32_t tmp_jdr;
-
-  /* Check the parameters */
-  assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
-  assert_param(IS_ADC_INJECTED_RANK(InjectedRank));
-
-  /* Get ADC converted value */
-  switch (InjectedRank)
-  {
-    case ADC_INJECTED_RANK_4:
-      tmp_jdr = hadc->Instance->JDR4;
-      break;
-    case ADC_INJECTED_RANK_3:
-      tmp_jdr = hadc->Instance->JDR3;
-      break;
-    case ADC_INJECTED_RANK_2:
-      tmp_jdr = hadc->Instance->JDR2;
-      break;
-    case ADC_INJECTED_RANK_1:
-    default:
-      tmp_jdr = hadc->Instance->JDR1;
-      break;
-  }
-
-  /* Return ADC converted value */
-  return tmp_jdr;
-}
-
-/**
-  * @brief  Injected conversion complete callback in non-blocking mode.
-  * @param hadc ADC handle
-  * @retval None
-  */
-__weak void HAL_ADCEx_InjectedConvCpltCallback(ADC_HandleTypeDef *hadc)
-{
-  /* Prevent unused argument(s) compilation warning */
-  UNUSED(hadc);
-
-  /* NOTE : This function should not be modified. When the callback is needed,
-            function HAL_ADCEx_InjectedConvCpltCallback must be implemented in the user file.
-  */
-}
-
-/**
-  * @brief  Injected context queue overflow callback.
-  * @note   This callback is called if injected context queue is enabled
-            (parameter "QueueInjectedContext" in injected channel configuration)
-            and if a new injected context is set when queue is full (maximum 2
-            contexts).
-  * @param hadc ADC handle
-  * @retval None
-  */
-__weak void HAL_ADCEx_InjectedQueueOverflowCallback(ADC_HandleTypeDef *hadc)
-{
-  /* Prevent unused argument(s) compilation warning */
-  UNUSED(hadc);
-
-  /* NOTE : This function should not be modified. When the callback is needed,
-            function HAL_ADCEx_InjectedQueueOverflowCallback must be implemented in the user file.
-  */
-}
-#endif /* ADC_SUPPORT_2_5_MSPS */
-
-/**
-  * @brief  Analog watchdog 2 callback in non-blocking mode.
-  * @param hadc ADC handle
-  * @retval None
-  */
-__weak void HAL_ADCEx_LevelOutOfWindow2Callback(ADC_HandleTypeDef *hadc)
-{
-  /* Prevent unused argument(s) compilation warning */
-  UNUSED(hadc);
-
-  /* NOTE : This function should not be modified. When the callback is needed,
-            function HAL_ADCEx_LevelOutOfWindow2Callback must be implemented in the user file.
-  */
-}
-
-/**
-  * @brief  Analog watchdog 3 callback in non-blocking mode.
-  * @param hadc ADC handle
-  * @retval None
-  */
-__weak void HAL_ADCEx_LevelOutOfWindow3Callback(ADC_HandleTypeDef *hadc)
-{
-  /* Prevent unused argument(s) compilation warning */
-  UNUSED(hadc);
-
-  /* NOTE : This function should not be modified. When the callback is needed,
-            function HAL_ADCEx_LevelOutOfWindow3Callback must be implemented in the user file.
-  */
-}
-
-
-/**
-  * @brief  End Of Sampling callback in non-blocking mode.
-  * @param hadc ADC handle
-  * @retval None
-  */
-__weak void HAL_ADCEx_EndOfSamplingCallback(ADC_HandleTypeDef *hadc)
-{
-  /* Prevent unused argument(s) compilation warning */
-  UNUSED(hadc);
-
-  /* NOTE : This function should not be modified. When the callback is needed,
-            function HAL_ADCEx_EndOfSamplingCallback must be implemented in the user file.
-  */
-}
-
-#if  defined(ADC_SUPPORT_2_5_MSPS)
-/* Feature "ADC group injected" not available on ADC peripheral of this STM32WB device */
-#else
-/**
-  * @brief  Stop ADC conversion of regular group (and injected channels in
-  *         case of auto_injection mode), disable ADC peripheral if no
-  *         conversion is on going on injected group.
-  * @param hadc ADC handle
-  * @retval HAL status.
-  */
-HAL_StatusTypeDef HAL_ADCEx_RegularStop(ADC_HandleTypeDef *hadc)
-{
-  HAL_StatusTypeDef tmp_hal_status;
-
-  /* Check the parameters */
-  assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
-
-  /* Process locked */
-  __HAL_LOCK(hadc);
-
-  /* 1. Stop potential regular conversion on going */
-  tmp_hal_status = ADC_ConversionStop(hadc, ADC_REGULAR_GROUP);
-
-  /* Disable ADC peripheral if regular conversions are effectively stopped
-     and if no injected conversions are on-going */
-  if (tmp_hal_status == HAL_OK)
-  {
-    /* Clear HAL_ADC_STATE_REG_BUSY bit */
-    CLEAR_BIT(hadc->State, HAL_ADC_STATE_REG_BUSY);
-
-    if (LL_ADC_INJ_IsConversionOngoing(hadc->Instance) == 0UL)
-    {
-      /* 2. Disable the ADC peripheral */
-      tmp_hal_status = ADC_Disable(hadc);
-
-      /* Check if ADC is effectively disabled */
-      if (tmp_hal_status == HAL_OK)
-      {
-        /* Set ADC state */
-        ADC_STATE_CLR_SET(hadc->State,
-                          HAL_ADC_STATE_INJ_BUSY,
-                          HAL_ADC_STATE_READY);
-      }
-    }
-    /* Conversion on injected group is stopped, but ADC not disabled since    */
-    /* conversion on regular group is still running.                          */
-    else
-    {
-      SET_BIT(hadc->State, HAL_ADC_STATE_INJ_BUSY);
-    }
-  }
-
-  /* Process unlocked */
-  __HAL_UNLOCK(hadc);
-
-  /* Return function status */
-  return tmp_hal_status;
-}
-
-
-/**
-  * @brief  Stop ADC conversion of ADC groups regular and injected,
-  *         disable interrution of end-of-conversion,
-  *         disable ADC peripheral if no conversion is on going
-  *         on injected group.
-  * @param hadc ADC handle
-  * @retval HAL status.
-  */
-HAL_StatusTypeDef HAL_ADCEx_RegularStop_IT(ADC_HandleTypeDef *hadc)
-{
-  HAL_StatusTypeDef tmp_hal_status;
-
-  /* Check the parameters */
-  assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
-
-  /* Process locked */
-  __HAL_LOCK(hadc);
-
-  /* 1. Stop potential regular conversion on going */
-  tmp_hal_status = ADC_ConversionStop(hadc, ADC_REGULAR_GROUP);
-
-  /* Disable ADC peripheral if conversions are effectively stopped
-    and if no injected conversion is on-going */
-  if (tmp_hal_status == HAL_OK)
-  {
-    /* Clear HAL_ADC_STATE_REG_BUSY bit */
-    CLEAR_BIT(hadc->State, HAL_ADC_STATE_REG_BUSY);
-
-    /* Disable all regular-related interrupts */
-    __HAL_ADC_DISABLE_IT(hadc, (ADC_IT_EOC | ADC_IT_EOS | ADC_IT_OVR));
-
-    /* 2. Disable ADC peripheral if no injected conversions are on-going */
-    if (LL_ADC_INJ_IsConversionOngoing(hadc->Instance) == 0UL)
-    {
-      tmp_hal_status = ADC_Disable(hadc);
-      /* if no issue reported */
-      if (tmp_hal_status == HAL_OK)
-      {
-        /* Set ADC state */
-        ADC_STATE_CLR_SET(hadc->State,
-                          HAL_ADC_STATE_INJ_BUSY,
-                          HAL_ADC_STATE_READY);
-      }
-    }
-    else
-    {
-      SET_BIT(hadc->State, HAL_ADC_STATE_INJ_BUSY);
-    }
-  }
-
-  /* Process unlocked */
-  __HAL_UNLOCK(hadc);
-
-  /* Return function status */
-  return tmp_hal_status;
-}
-
-/**
-  * @brief  Stop ADC conversion of regular group (and injected group in
-  *         case of auto_injection mode), disable ADC DMA transfer, disable
-  *         ADC peripheral if no conversion is on going
-  *         on injected group.
-  * @param hadc ADC handle
-  * @retval HAL status.
-  */
-HAL_StatusTypeDef HAL_ADCEx_RegularStop_DMA(ADC_HandleTypeDef *hadc)
-{
-  HAL_StatusTypeDef tmp_hal_status;
-
-  /* Check the parameters */
-  assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
-
-  /* Process locked */
-  __HAL_LOCK(hadc);
-
-  /* 1. Stop potential regular conversion on going */
-  tmp_hal_status = ADC_ConversionStop(hadc, ADC_REGULAR_GROUP);
-
-  /* Disable ADC peripheral if conversions are effectively stopped
-     and if no injected conversion is on-going */
-  if (tmp_hal_status == HAL_OK)
-  {
-    /* Clear HAL_ADC_STATE_REG_BUSY bit */
-    CLEAR_BIT(hadc->State, HAL_ADC_STATE_REG_BUSY);
-
-    /* Disable ADC DMA (ADC DMA configuration ADC_CFGR_DMACFG is kept) */
-    CLEAR_BIT(hadc->Instance->CFGR, ADC_CFGR_DMAEN);
-
-    /* Disable the DMA channel (in case of DMA in circular mode or stop while */
-    /* while DMA transfer is on going)                                        */
-    tmp_hal_status = HAL_DMA_Abort(hadc->DMA_Handle);
-
-    /* Check if DMA channel effectively disabled */
-    if (tmp_hal_status != HAL_OK)
-    {
-      /* Update ADC state machine to error */
-      SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_DMA);
-    }
-
-    /* Disable ADC overrun interrupt */
-    __HAL_ADC_DISABLE_IT(hadc, ADC_IT_OVR);
-
-    /* 2. Disable the ADC peripheral */
-    /* Update "tmp_hal_status" only if DMA channel disabling passed,          */
-    /* to keep in memory a potential failing status.                          */
-    if (LL_ADC_INJ_IsConversionOngoing(hadc->Instance) == 0UL)
-    {
-      if (tmp_hal_status == HAL_OK)
-      {
-        tmp_hal_status = ADC_Disable(hadc);
-      }
-      else
-      {
-        (void)ADC_Disable(hadc);
-      }
-
-      /* Check if ADC is effectively disabled */
-      if (tmp_hal_status == HAL_OK)
-      {
-        /* Set ADC state */
-        ADC_STATE_CLR_SET(hadc->State,
-                          HAL_ADC_STATE_INJ_BUSY,
-                          HAL_ADC_STATE_READY);
-      }
-    }
-    else
-    {
-      SET_BIT(hadc->State, HAL_ADC_STATE_INJ_BUSY);
-    }
-  }
-
-  /* Process unlocked */
-  __HAL_UNLOCK(hadc);
-
-  /* Return function status */
-  return tmp_hal_status;
-}
-#endif /* ADC_SUPPORT_2_5_MSPS */
-
-/**
-  * @}
-  */
-
-#if  defined(ADC_SUPPORT_2_5_MSPS)
-/* Feature "ADC group injected" not available on ADC peripheral of this STM32WB device */
-#else
-/** @defgroup ADCEx_Exported_Functions_Group2 ADC Extended Peripheral Control functions
-  * @brief    ADC Extended Peripheral Control functions
-  *
-@verbatim
- ===============================================================================
-             ##### Peripheral Control functions #####
- ===============================================================================
-    [..]  This section provides functions allowing to:
-      (+) Configure channels on injected group
-      (+) Enable or Disable Injected Queue
-      (+) Disable ADC voltage regulator
-      (+) Enter ADC deep-power-down mode
-
-@endverbatim
-  * @{
-  */
-
-/**
-  * @brief  Configure a channel to be assigned to ADC group injected.
-  * @note   Possibility to update parameters on the fly:
-  *         This function initializes injected group, following calls to this
-  *         function can be used to reconfigure some parameters of structure
-  *         "ADC_InjectionConfTypeDef" on the fly, without resetting the ADC.
-  *         The setting of these parameters is conditioned to ADC state:
-  *         Refer to comments of structure "ADC_InjectionConfTypeDef".
-  * @note   In case of usage of internal measurement channels:
-  *         Vbat/VrefInt/TempSensor.
-  *         These internal paths can be disabled using function
-  *         HAL_ADC_DeInit().
-  * @note   Caution: For Injected Context Queue use, a context must be fully
-  *         defined before start of injected conversion. All channels are configured
-  *         consecutively for the same ADC instance. Therefore, the number of calls to
-  *         HAL_ADCEx_InjectedConfigChannel() must be equal to the value of parameter
-  *         InjectedNbrOfConversion for each context.
-  *  - Example 1: If 1 context is intended to be used (or if there is no use of the
-  *    Injected Queue Context feature) and if the context contains 3 injected ranks
-  *    (InjectedNbrOfConversion = 3), HAL_ADCEx_InjectedConfigChannel() must be
-  *    called once for each channel (i.e. 3 times) before starting a conversion.
-  *    This function must not be called to configure a 4th injected channel:
-  *    it would start a new context into context queue.
-  *  - Example 2: If 2 contexts are intended to be used and each of them contains
-  *    3 injected ranks (InjectedNbrOfConversion = 3),
-  *    HAL_ADCEx_InjectedConfigChannel() must be called once for each channel and
-  *    for each context (3 channels x 2 contexts = 6 calls). Conversion can
-  *    start once the 1st context is set, that is after the first three
-  *    HAL_ADCEx_InjectedConfigChannel() calls. The 2nd context can be set on the fly.
-  * @param hadc ADC handle
-  * @param sConfigInjected Structure of ADC injected group and ADC channel for
-  *         injected group.
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_ADCEx_InjectedConfigChannel(ADC_HandleTypeDef *hadc, const ADC_InjectionConfTypeDef *sConfigInjected)
-{
-  HAL_StatusTypeDef tmp_hal_status = HAL_OK;
-  uint32_t tmpOffsetShifted;
-  uint32_t tmp_config_internal_channel;
-  uint32_t tmp_adc_is_conversion_on_going_regular;
-  uint32_t tmp_adc_is_conversion_on_going_injected;
-  __IO uint32_t wait_loop_index = 0;
-
-  uint32_t tmp_JSQR_ContextQueueBeingBuilt = 0U;
-
-  /* Check the parameters */
-  assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
-  assert_param(IS_ADC_SAMPLE_TIME(sConfigInjected->InjectedSamplingTime));
-  assert_param(IS_ADC_SINGLE_DIFFERENTIAL(sConfigInjected->InjectedSingleDiff));
-  assert_param(IS_FUNCTIONAL_STATE(sConfigInjected->AutoInjectedConv));
-  assert_param(IS_FUNCTIONAL_STATE(sConfigInjected->QueueInjectedContext));
-  assert_param(IS_ADC_EXTTRIGINJEC_EDGE(sConfigInjected->ExternalTrigInjecConvEdge));
-  assert_param(IS_ADC_EXTTRIGINJEC(hadc, sConfigInjected->ExternalTrigInjecConv));
-  assert_param(IS_ADC_OFFSET_NUMBER(sConfigInjected->InjectedOffsetNumber));
-  assert_param(IS_ADC_RANGE(ADC_GET_RESOLUTION(hadc), sConfigInjected->InjectedOffset));
-  assert_param(IS_FUNCTIONAL_STATE(sConfigInjected->InjecOversamplingMode));
-
-  if (hadc->Init.ScanConvMode != ADC_SCAN_DISABLE)
-  {
-    assert_param(IS_ADC_INJECTED_RANK(sConfigInjected->InjectedRank));
-    assert_param(IS_ADC_INJECTED_NB_CONV(sConfigInjected->InjectedNbrOfConversion));
-    assert_param(IS_FUNCTIONAL_STATE(sConfigInjected->InjectedDiscontinuousConvMode));
-  }
-
-
-  /* if JOVSE is set, the value of the OFFSETy_EN bit in ADCx_OFRy register is
-     ignored (considered as reset) */
-  assert_param(!((sConfigInjected->InjectedOffsetNumber != ADC_OFFSET_NONE) && (sConfigInjected->InjecOversamplingMode == ENABLE)));
-
-  /* JDISCEN and JAUTO bits can't be set at the same time  */
-  assert_param(!((sConfigInjected->InjectedDiscontinuousConvMode == ENABLE) && (sConfigInjected->AutoInjectedConv == ENABLE)));
-
-  /*  DISCEN and JAUTO bits can't be set at the same time */
-  assert_param(!((hadc->Init.DiscontinuousConvMode == ENABLE) && (sConfigInjected->AutoInjectedConv == ENABLE)));
-
-  /* Verification of channel number */
-  if (sConfigInjected->InjectedSingleDiff != ADC_DIFFERENTIAL_ENDED)
-  {
-    assert_param(IS_ADC_CHANNEL(hadc, sConfigInjected->InjectedChannel));
-  }
-  else
-  {
-    assert_param(IS_ADC_DIFF_CHANNEL(hadc, sConfigInjected->InjectedChannel));
-  }
-
-  /* Process locked */
-  __HAL_LOCK(hadc);
-
-  /* Configuration of injected group sequencer:                               */
-  /* Hardware constraint: Must fully define injected context register JSQR    */
-  /* before make it entering into injected sequencer queue.                   */
-  /*                                                                          */
-  /* - if scan mode is disabled:                                              */
-  /*    * Injected channels sequence length is set to 0x00: 1 channel         */
-  /*      converted (channel on injected rank 1)                              */
-  /*      Parameter "InjectedNbrOfConversion" is discarded.                   */
-  /*    * Injected context register JSQR setting is simple: register is fully */
-  /*      defined on one call of this function (for injected rank 1) and can  */
-  /*      be entered into queue directly.                                     */
-  /* - if scan mode is enabled:                                               */
-  /*    * Injected channels sequence length is set to parameter               */
-  /*      "InjectedNbrOfConversion".                                          */
-  /*    * Injected context register JSQR setting more complex: register is    */
-  /*      fully defined over successive calls of this function, for each      */
-  /*      injected channel rank. It is entered into queue only when all       */
-  /*      injected ranks have been set.                                       */
-  /*   Note: Scan mode is not present by hardware on this device, but used    */
-  /*   by software for alignment over all STM32 devices.                      */
-
-  if ((hadc->Init.ScanConvMode == ADC_SCAN_DISABLE)  ||
-      (sConfigInjected->InjectedNbrOfConversion == 1U))
-  {
-    /* Configuration of context register JSQR:                                */
-    /*  - number of ranks in injected group sequencer: fixed to 1st rank      */
-    /*    (scan mode disabled, only rank 1 used)                              */
-    /*  - external trigger to start conversion                                */
-    /*  - external trigger polarity                                           */
-    /*  - channel set to rank 1 (scan mode disabled, only rank 1 can be used) */
-
-    if (sConfigInjected->InjectedRank == ADC_INJECTED_RANK_1)
-    {
-      /* Enable external trigger if trigger selection is different of         */
-      /* software start.                                                      */
-      /* Note: This configuration keeps the hardware feature of parameter     */
-      /*       ExternalTrigInjecConvEdge "trigger edge none" equivalent to    */
-      /*       software start.                                                */
-      if (sConfigInjected->ExternalTrigInjecConv != ADC_INJECTED_SOFTWARE_START)
-      {
-        tmp_JSQR_ContextQueueBeingBuilt = (ADC_JSQR_RK(sConfigInjected->InjectedChannel, ADC_INJECTED_RANK_1)
-                                           | (sConfigInjected->ExternalTrigInjecConv & ADC_JSQR_JEXTSEL)
-                                           | sConfigInjected->ExternalTrigInjecConvEdge
-                                          );
-      }
-      else
-      {
-        tmp_JSQR_ContextQueueBeingBuilt = (ADC_JSQR_RK(sConfigInjected->InjectedChannel, ADC_INJECTED_RANK_1));
-      }
-
-      MODIFY_REG(hadc->Instance->JSQR, ADC_JSQR_FIELDS, tmp_JSQR_ContextQueueBeingBuilt);
-      /* For debug and informative reasons, hadc handle saves JSQR setting */
-      hadc->InjectionConfig.ContextQueue = tmp_JSQR_ContextQueueBeingBuilt;
-
-    }
-  }
-  else
-  {
-    /* Case of scan mode enabled, several channels to set into injected group */
-    /* sequencer.                                                             */
-    /*                                                                        */
-    /* Procedure to define injected context register JSQR over successive     */
-    /* calls of this function, for each injected channel rank:                */
-    /* 1. Start new context and set parameters related to all injected        */
-    /*    channels: injected sequence length and trigger.                     */
-
-    /* if hadc->InjectionConfig.ChannelCount is equal to 0, this is the first */
-    /*   call of the context under setting                                    */
-    if (hadc->InjectionConfig.ChannelCount == 0U)
-    {
-      /* Initialize number of channels that will be configured on the context */
-      /*  being built                                                         */
-      hadc->InjectionConfig.ChannelCount = sConfigInjected->InjectedNbrOfConversion;
-      /* Handle hadc saves the context under build up over each HAL_ADCEx_InjectedConfigChannel()
-         call, this context will be written in JSQR register at the last call.
-         At this point, the context is merely reset  */
-      hadc->InjectionConfig.ContextQueue = 0x00000000U;
-
-      /* Configuration of context register JSQR:                              */
-      /*  - number of ranks in injected group sequencer                       */
-      /*  - external trigger to start conversion                              */
-      /*  - external trigger polarity                                         */
-
-      /* Enable external trigger if trigger selection is different of         */
-      /* software start.                                                      */
-      /* Note: This configuration keeps the hardware feature of parameter     */
-      /*       ExternalTrigInjecConvEdge "trigger edge none" equivalent to    */
-      /*       software start.                                                */
-      if (sConfigInjected->ExternalTrigInjecConv != ADC_INJECTED_SOFTWARE_START)
-      {
-        tmp_JSQR_ContextQueueBeingBuilt = ((sConfigInjected->InjectedNbrOfConversion - 1U)
-                                           | (sConfigInjected->ExternalTrigInjecConv & ADC_JSQR_JEXTSEL)
-                                           | sConfigInjected->ExternalTrigInjecConvEdge
-                                          );
-      }
-      else
-      {
-        tmp_JSQR_ContextQueueBeingBuilt = ((sConfigInjected->InjectedNbrOfConversion - 1U));
-      }
-
-    }
-
-    /* 2. Continue setting of context under definition with parameter       */
-    /*    related to each channel: channel rank sequence                    */
-    /* Clear the old JSQx bits for the selected rank */
-    tmp_JSQR_ContextQueueBeingBuilt &= ~ADC_JSQR_RK(ADC_SQR3_SQ10, sConfigInjected->InjectedRank);
-
-    /* Set the JSQx bits for the selected rank */
-    tmp_JSQR_ContextQueueBeingBuilt |= ADC_JSQR_RK(sConfigInjected->InjectedChannel, sConfigInjected->InjectedRank);
-
-    /* Decrease channel count  */
-    hadc->InjectionConfig.ChannelCount--;
-
-    /* 3. tmp_JSQR_ContextQueueBeingBuilt is fully built for this HAL_ADCEx_InjectedConfigChannel()
-          call, aggregate the setting to those already built during the previous
-          HAL_ADCEx_InjectedConfigChannel() calls (for the same context of course)  */
-    hadc->InjectionConfig.ContextQueue |= tmp_JSQR_ContextQueueBeingBuilt;
-
-    /* 4. End of context setting: if this is the last channel set, then write context
-        into register JSQR and make it enter into queue                   */
-    if (hadc->InjectionConfig.ChannelCount == 0U)
-    {
-      MODIFY_REG(hadc->Instance->JSQR, ADC_JSQR_FIELDS, hadc->InjectionConfig.ContextQueue);
-    }
-  }
-
-  /* Parameters update conditioned to ADC state:                              */
-  /* Parameters that can be updated when ADC is disabled or enabled without   */
-  /* conversion on going on injected group:                                   */
-  /*  - Injected context queue: Queue disable (active context is kept) or     */
-  /*    enable (context decremented, up to 2 contexts queued)                 */
-  /*  - Injected discontinuous mode: can be enabled only if auto-injected     */
-  /*    mode is disabled.                                                     */
-  if (LL_ADC_INJ_IsConversionOngoing(hadc->Instance) == 0UL)
-  {
-    /* If auto-injected mode is disabled: no constraint                       */
-    if (sConfigInjected->AutoInjectedConv == DISABLE)
-    {
-      MODIFY_REG(hadc->Instance->CFGR,
-                 ADC_CFGR_JQM | ADC_CFGR_JDISCEN,
-                 ADC_CFGR_INJECT_CONTEXT_QUEUE((uint32_t)sConfigInjected->QueueInjectedContext)           |
-                 ADC_CFGR_INJECT_DISCCONTINUOUS((uint32_t)sConfigInjected->InjectedDiscontinuousConvMode));
-    }
-    /* If auto-injected mode is enabled: Injected discontinuous setting is    */
-    /* discarded.                                                             */
-    else
-    {
-      MODIFY_REG(hadc->Instance->CFGR,
-                 ADC_CFGR_JQM | ADC_CFGR_JDISCEN,
-                 ADC_CFGR_INJECT_CONTEXT_QUEUE((uint32_t)sConfigInjected->QueueInjectedContext));
-    }
-
-  }
-
-  /* Parameters update conditioned to ADC state:                              */
-  /* Parameters that can be updated when ADC is disabled or enabled without   */
-  /* conversion on going on regular and injected groups:                      */
-  /*  - Automatic injected conversion: can be enabled if injected group       */
-  /*    external triggers are disabled.                                       */
-  /*  - Channel sampling time                                                 */
-  /*  - Channel offset                                                        */
-  tmp_adc_is_conversion_on_going_regular = LL_ADC_REG_IsConversionOngoing(hadc->Instance);
-  tmp_adc_is_conversion_on_going_injected = LL_ADC_INJ_IsConversionOngoing(hadc->Instance);
-
-  if ((tmp_adc_is_conversion_on_going_regular == 0UL)
-      && (tmp_adc_is_conversion_on_going_injected == 0UL)
-     )
-  {
-    /* If injected group external triggers are disabled (set to injected      */
-    /* software start): no constraint                                         */
-    if ((sConfigInjected->ExternalTrigInjecConv == ADC_INJECTED_SOFTWARE_START)
-        || (sConfigInjected->ExternalTrigInjecConvEdge == ADC_EXTERNALTRIGINJECCONV_EDGE_NONE))
-    {
-      if (sConfigInjected->AutoInjectedConv == ENABLE)
-      {
-        SET_BIT(hadc->Instance->CFGR, ADC_CFGR_JAUTO);
-      }
-      else
-      {
-        CLEAR_BIT(hadc->Instance->CFGR, ADC_CFGR_JAUTO);
-      }
-    }
-    /* If Automatic injected conversion was intended to be set and could not  */
-    /* due to injected group external triggers enabled, error is reported.    */
-    else
-    {
-      if (sConfigInjected->AutoInjectedConv == ENABLE)
-      {
-        /* Update ADC state machine to error */
-        SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG);
-
-        tmp_hal_status = HAL_ERROR;
-      }
-      else
-      {
-        CLEAR_BIT(hadc->Instance->CFGR, ADC_CFGR_JAUTO);
-      }
-    }
-
-    if (sConfigInjected->InjecOversamplingMode == ENABLE)
-    {
-      assert_param(IS_ADC_OVERSAMPLING_RATIO(sConfigInjected->InjecOversampling.Ratio));
-      assert_param(IS_ADC_RIGHT_BIT_SHIFT(sConfigInjected->InjecOversampling.RightBitShift));
-
-      /*  JOVSE must be reset in case of triggered regular mode  */
-      assert_param(!(READ_BIT(hadc->Instance->CFGR2, ADC_CFGR2_ROVSE | ADC_CFGR2_TROVS) == (ADC_CFGR2_ROVSE | ADC_CFGR2_TROVS)));
-
-      /* Configuration of Injected Oversampler:                                 */
-      /*  - Oversampling Ratio                                                  */
-      /*  - Right bit shift                                                     */
-
-      /* Enable OverSampling mode */
-      MODIFY_REG(hadc->Instance->CFGR2,
-                 ADC_CFGR2_JOVSE |
-                 ADC_CFGR2_OVSR  |
-                 ADC_CFGR2_OVSS,
-                 ADC_CFGR2_JOVSE                                  |
-                 sConfigInjected->InjecOversampling.Ratio         |
-                 sConfigInjected->InjecOversampling.RightBitShift
-                );
-    }
-    else
-    {
-      /* Disable Regular OverSampling */
-      CLEAR_BIT(hadc->Instance->CFGR2, ADC_CFGR2_JOVSE);
-    }
-
-      /* Set sampling time of the selected ADC channel */
-      LL_ADC_SetChannelSamplingTime(hadc->Instance, sConfigInjected->InjectedChannel, sConfigInjected->InjectedSamplingTime);
-
-    /* Configure the offset: offset enable/disable, channel, offset value */
-
-    /* Shift the offset with respect to the selected ADC resolution. */
-    /* Offset has to be left-aligned on bit 11, the LSB (right bits) are set to 0 */
-    tmpOffsetShifted = ADC_OFFSET_SHIFT_RESOLUTION(hadc, sConfigInjected->InjectedOffset);
-
-    if (sConfigInjected->InjectedOffsetNumber != ADC_OFFSET_NONE)
-    {
-      /* Set ADC selected offset number */
-      LL_ADC_SetOffset(hadc->Instance, sConfigInjected->InjectedOffsetNumber, sConfigInjected->InjectedChannel,
-                       tmpOffsetShifted);
-
-    }
-    else
-    {
-      /* Scan each offset register to check if the selected channel is targeted. */
-      /* If this is the case, the corresponding offset number is disabled.       */
-      if(__LL_ADC_CHANNEL_TO_DECIMAL_NB(LL_ADC_GetOffsetChannel(hadc->Instance, LL_ADC_OFFSET_1)) == __LL_ADC_CHANNEL_TO_DECIMAL_NB(sConfigInjected->InjectedChannel))
-      {
-        LL_ADC_SetOffsetState(hadc->Instance, LL_ADC_OFFSET_1, LL_ADC_OFFSET_DISABLE);
-      }
-      if(__LL_ADC_CHANNEL_TO_DECIMAL_NB(LL_ADC_GetOffsetChannel(hadc->Instance, LL_ADC_OFFSET_2)) == __LL_ADC_CHANNEL_TO_DECIMAL_NB(sConfigInjected->InjectedChannel))
-      {
-        LL_ADC_SetOffsetState(hadc->Instance, LL_ADC_OFFSET_2, LL_ADC_OFFSET_DISABLE);
-      }
-      if(__LL_ADC_CHANNEL_TO_DECIMAL_NB(LL_ADC_GetOffsetChannel(hadc->Instance, LL_ADC_OFFSET_3)) == __LL_ADC_CHANNEL_TO_DECIMAL_NB(sConfigInjected->InjectedChannel))
-      {
-        LL_ADC_SetOffsetState(hadc->Instance, LL_ADC_OFFSET_3, LL_ADC_OFFSET_DISABLE);
-      }
-      if(__LL_ADC_CHANNEL_TO_DECIMAL_NB(LL_ADC_GetOffsetChannel(hadc->Instance, LL_ADC_OFFSET_4)) == __LL_ADC_CHANNEL_TO_DECIMAL_NB(sConfigInjected->InjectedChannel))
-      {
-        LL_ADC_SetOffsetState(hadc->Instance, LL_ADC_OFFSET_4, LL_ADC_OFFSET_DISABLE);
-      }
-    }
-
-  }
-
-  /* Parameters update conditioned to ADC state:                              */
-  /* Parameters that can be updated only when ADC is disabled:                */
-  /*  - Single or differential mode                                           */
-  /*  - Internal measurement channels: Vbat/VrefInt/TempSensor                */
-  if (LL_ADC_IsEnabled(hadc->Instance) == 0UL)
-  {
-    /* Set mode single-ended or differential input of the selected ADC channel */
-    LL_ADC_SetChannelSingleDiff(hadc->Instance, sConfigInjected->InjectedChannel, sConfigInjected->InjectedSingleDiff);
-
-    /* Configuration of differential mode */
-    /* Note: ADC channel number masked with value "0x1F" to ensure shift value within 32 bits range */
-    if (sConfigInjected->InjectedSingleDiff == ADC_DIFFERENTIAL_ENDED)
-    {
-      /* Set sampling time of the selected ADC channel */
-      LL_ADC_SetChannelSamplingTime(hadc->Instance, (uint32_t)(__LL_ADC_DECIMAL_NB_TO_CHANNEL((__LL_ADC_CHANNEL_TO_DECIMAL_NB((uint32_t)sConfigInjected->InjectedChannel) + 1UL) & 0x1FUL)), sConfigInjected->InjectedSamplingTime);
-    }
-
-    /* Management of internal measurement channels: Vbat/VrefInt/TempSensor   */
-    /* internal measurement paths enable: If internal channel selected,       */
-    /* enable dedicated internal buffers and path.                            */
-    /* Note: these internal measurement paths can be disabled using           */
-    /* HAL_ADC_DeInit().                                                      */
-
-    if(__LL_ADC_IS_CHANNEL_INTERNAL(sConfigInjected->InjectedChannel))
-    {
-      /* Configuration of common ADC parameters (continuation)                */
-      /* Software is allowed to change common parameters only when all ADCs   */
-      /* of the common group are disabled.                                    */
-      if (__LL_ADC_IS_ENABLED_ALL_COMMON_INSTANCE(__LL_ADC_COMMON_INSTANCE(hadc->Instance)) == 0UL)
-      {
-        tmp_config_internal_channel = LL_ADC_GetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(hadc->Instance));
-
-        /* If the requested internal measurement path has already been enabled, */
-        /* bypass the configuration processing.                                 */
-        if ((sConfigInjected->InjectedChannel == ADC_CHANNEL_TEMPSENSOR) && ((tmp_config_internal_channel & LL_ADC_PATH_INTERNAL_TEMPSENSOR) == 0UL))
-        {
-          if (ADC_TEMPERATURE_SENSOR_INSTANCE(hadc))
-          {
-            LL_ADC_SetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(hadc->Instance), LL_ADC_PATH_INTERNAL_TEMPSENSOR | tmp_config_internal_channel);
-
-            /* Delay for temperature sensor stabilization time */
-            /* Wait loop initialization and execution */
-            /* Note: Variable divided by 2 to compensate partially              */
-            /*       CPU processing cycles, scaling in us split to not          */
-            /*       exceed 32 bits register capacity and handle low frequency. */
-            wait_loop_index = ((LL_ADC_DELAY_TEMPSENSOR_STAB_US / 10UL) * (SystemCoreClock / (100000UL * 2UL)));
-            while(wait_loop_index != 0UL)
-            {
-              wait_loop_index--;
-            }
-          }
-        }
-        else if ((sConfigInjected->InjectedChannel == ADC_CHANNEL_VBAT) && ((tmp_config_internal_channel & LL_ADC_PATH_INTERNAL_VBAT) == 0UL))
-        {
-          if (ADC_BATTERY_VOLTAGE_INSTANCE(hadc))
-          {
-            LL_ADC_SetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(hadc->Instance), LL_ADC_PATH_INTERNAL_VBAT | tmp_config_internal_channel);
-          }
-        }
-        else if ((sConfigInjected->InjectedChannel == ADC_CHANNEL_VREFINT) && ((tmp_config_internal_channel & LL_ADC_PATH_INTERNAL_VREFINT) == 0UL))
-        {
-          if (ADC_VREFINT_INSTANCE(hadc))
-          {
-            LL_ADC_SetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(hadc->Instance), LL_ADC_PATH_INTERNAL_VREFINT | tmp_config_internal_channel);
-          }
-        }
-        else
-        {
-          /* nothing to do */
-        }
-      }
-      /* If the requested internal measurement path has already been enabled  */
-      /* and other ADC of the common group are enabled, internal              */
-      /* measurement paths cannot be enabled.                                 */
-      else
-      {
-        /* Update ADC state machine to error */
-        SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG);
-
-        tmp_hal_status = HAL_ERROR;
-      }
-    }
-
-  }
-
-  /* Process unlocked */
-  __HAL_UNLOCK(hadc);
-
-  /* Return function status */
-  return tmp_hal_status;
-}
-#endif /* ADC_SUPPORT_2_5_MSPS */
-
-#if  defined(ADC_SUPPORT_2_5_MSPS)
-/* Feature "ADC group injected" not available on ADC peripheral of this STM32WB device */
-#else
-/**
-  * @brief  Enable Injected Queue
-  * @note   This function resets CFGR register JQDIS bit in order to enable the
-  *         Injected Queue. JQDIS can be written only when ADSTART and JDSTART
-  *         are both equal to 0 to ensure that no regular nor injected
-  *         conversion is ongoing.
-  * @param hadc ADC handle
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_ADCEx_EnableInjectedQueue(ADC_HandleTypeDef *hadc)
-{
-  HAL_StatusTypeDef tmp_hal_status;
-  uint32_t tmp_adc_is_conversion_on_going_regular;
-  uint32_t tmp_adc_is_conversion_on_going_injected;
-
-  /* Check the parameters */
-  assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
-
-  tmp_adc_is_conversion_on_going_regular = LL_ADC_REG_IsConversionOngoing(hadc->Instance);
-  tmp_adc_is_conversion_on_going_injected = LL_ADC_INJ_IsConversionOngoing(hadc->Instance);
-
-  /* Parameter can be set only if no conversion is on-going */
-  if ((tmp_adc_is_conversion_on_going_regular == 0UL)
-      && (tmp_adc_is_conversion_on_going_injected == 0UL)
-     )
-  {
-    CLEAR_BIT(hadc->Instance->CFGR, ADC_CFGR_JQDIS);
-
-    /* Update state, clear previous result related to injected queue overflow */
-    CLEAR_BIT(hadc->State, HAL_ADC_STATE_INJ_JQOVF);
-
-    tmp_hal_status = HAL_OK;
-  }
-  else
-  {
-    tmp_hal_status = HAL_ERROR;
-  }
-
-  return tmp_hal_status;
-}
-
-/**
-  * @brief  Disable Injected Queue
-  * @note   This function sets CFGR register JQDIS bit in order to disable the
-  *         Injected Queue. JQDIS can be written only when ADSTART and JDSTART
-  *         are both equal to 0 to ensure that no regular nor injected
-  *         conversion is ongoing.
-  * @param hadc ADC handle
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_ADCEx_DisableInjectedQueue(ADC_HandleTypeDef *hadc)
-{
-  HAL_StatusTypeDef tmp_hal_status;
-  uint32_t tmp_adc_is_conversion_on_going_regular;
-  uint32_t tmp_adc_is_conversion_on_going_injected;
-
-  /* Check the parameters */
-  assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
-
-  tmp_adc_is_conversion_on_going_regular = LL_ADC_REG_IsConversionOngoing(hadc->Instance);
-  tmp_adc_is_conversion_on_going_injected = LL_ADC_INJ_IsConversionOngoing(hadc->Instance);
-
-  /* Parameter can be set only if no conversion is on-going */
-  if ((tmp_adc_is_conversion_on_going_regular == 0UL)
-      && (tmp_adc_is_conversion_on_going_injected == 0UL)
-     )
-  {
-    LL_ADC_INJ_SetQueueMode(hadc->Instance, LL_ADC_INJ_QUEUE_DISABLE);
-    tmp_hal_status = HAL_OK;
-  }
-  else
-  {
-    tmp_hal_status = HAL_ERROR;
-  }
-
-  return tmp_hal_status;
-}
-#endif /* ADC_SUPPORT_2_5_MSPS */
-
-/**
-  * @brief  Disable ADC voltage regulator.
-  * @note   Disabling voltage regulator allows to save power. This operation can
-  *         be carried out only when ADC is disabled.
-  * @note   To enable again the voltage regulator, the user is expected to
-  *         resort to HAL_ADC_Init() API.
-  * @param hadc ADC handle
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_ADCEx_DisableVoltageRegulator(ADC_HandleTypeDef *hadc)
-{
-  HAL_StatusTypeDef tmp_hal_status;
-
-  /* Check the parameters */
-  assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
-
-  /* Setting of this feature is conditioned to ADC state: ADC must be ADC disabled */
-  if (LL_ADC_IsEnabled(hadc->Instance) == 0UL)
-  {
-    LL_ADC_DisableInternalRegulator(hadc->Instance);
-    tmp_hal_status = HAL_OK;
-  }
-  else
-  {
-    tmp_hal_status = HAL_ERROR;
-  }
-
-  return tmp_hal_status;
-}
-
-#if defined(ADC_SUPPORT_2_5_MSPS)
-/* Feature " ADC deep power-down" not available on ADC peripheral of this STM32WB device */
-#else
-/**
-  * @brief  Enter ADC deep power-down mode
-  * @note   This mode is achieved in setting DEEPPWD bit and allows to save power
-  *         in reducing leakage currents. It is particularly interesting before
-  *         entering stop modes.
-  * @note   Setting DEEPPWD automatically clears ADVREGEN bit and disables the
-  *         ADC voltage regulator. This means that this API encompasses
-  *         HAL_ADCEx_DisableVoltageRegulator(). Additionally, the internal
-  *         calibration is lost.
-  * @note   To exit the ADC deep-power-down mode, the user is expected to
-  *         resort to HAL_ADC_Init() API as well as to relaunch a calibration
-  *         with HAL_ADCEx_Calibration_Start() API or to re-apply a previously
-  *         saved calibration factor.
-  * @param hadc ADC handle
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_ADCEx_EnterADCDeepPowerDownMode(ADC_HandleTypeDef *hadc)
-{
-  HAL_StatusTypeDef tmp_hal_status;
-
-  /* Check the parameters */
-  assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
-
-  /* Setting of this feature is conditioned to ADC state: ADC must be ADC disabled */
-  if (LL_ADC_IsEnabled(hadc->Instance) == 0UL)
-  {
-    LL_ADC_EnableDeepPowerDown(hadc->Instance);
-    tmp_hal_status = HAL_OK;
-  }
-  else
-  {
-    tmp_hal_status = HAL_ERROR;
-  }
-
-  return tmp_hal_status;
-}
-#endif /* ADC_SUPPORT_2_5_MSPS */
-
-/**
-  * @}
-  */
-
-/**
-  * @}
-  */
-
-#endif /* HAL_ADC_MODULE_ENABLED */
-/**
-  * @}
-  */
-
-/**
-  * @}
-  */

+ 0 - 479
non_catalog_apps/flipperscope/lib/adc/stm32wbxx_hal_cortex.c

@@ -1,479 +0,0 @@
-/**
-  ******************************************************************************
-  * @file    stm32wbxx_hal_cortex.c
-  * @author  MCD Application Team
-  * @brief   CORTEX HAL module driver.
-  *          This file provides firmware functions to manage the following
-  *          functionalities of the CORTEX:
-  *           + Initialization and Configuration 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 #####
-  ==============================================================================
-    [..]
-    *** How to configure Interrupts using CORTEX HAL driver ***
-    ===========================================================
-    [..]
-    This section provides functions allowing to configure the NVIC interrupts (IRQ).
-    The Cortex M0+ exceptions are managed by CMSIS functions.
-      (#) Enable and Configure the priority of the selected IRQ Channels.
-             The priority can be 0..3.
-
-        -@- Lower priority values gives higher priority.
-        -@- Priority Order:
-            (#@) Lowest priority.
-            (#@) Lowest hardware priority (IRQn position).
-
-      (#)  Configure the priority of the selected IRQ Channels using HAL_NVIC_SetPriority()
-
-      (#)  Enable the selected IRQ Channels using HAL_NVIC_EnableIRQ()
-      
-      -@-  Negative value of IRQn_Type are not allowed.
-
-    *** How to configure Systick using CORTEX HAL driver ***
-    ========================================================
-    [..]
-    Setup SysTick Timer for time base.
-
-   (+) The HAL_SYSTICK_Config() function calls the SysTick_Config() function which
-       is a CMSIS function that:
-        (++) Configures the SysTick Reload register with value passed as function parameter.
-        (++) Configures the SysTick IRQ priority to the lowest value (0x03).
-        (++) Resets the SysTick Counter register.
-        (++) Configures the SysTick Counter clock source to be Core Clock Source (HCLK).
-        (++) Enables the SysTick Interrupt.
-        (++) Starts the SysTick Counter.
-
-   (+) You can change the SysTick Clock source to be HCLK_Div8 by calling the macro
-       __HAL_CORTEX_SYSTICKCLK_CONFIG(SYSTICK_CLKSOURCE_HCLK_DIV8) just after the
-       HAL_SYSTICK_Config() function call. The __HAL_CORTEX_SYSTICKCLK_CONFIG() macro is defined
-       inside the stm32wbxx_hal_cortex.h file.
-
-   (+) You can change the SysTick IRQ priority by calling the
-       HAL_NVIC_SetPriority(SysTick_IRQn,...) function just after the HAL_SYSTICK_Config() function
-       call. The HAL_NVIC_SetPriority() call the NVIC_SetPriority() function which is a CMSIS function.
-
-   (+) To adjust the SysTick time base, use the following formula:
-
-       Reload Value = SysTick Counter Clock (Hz) x  Desired Time base (s)
-       (++) Reload Value is the parameter to be passed for HAL_SYSTICK_Config() function
-       (++) Reload Value should not exceed 0xFFFFFF
-
-  @endverbatim
-  ******************************************************************************
-  */
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32wbxx_hal.h"
-
-/** @addtogroup STM32WBxx_HAL_Driver
-  * @{
-  */
-
-/** @addtogroup CORTEX
-  * @{
-  */
-
-#ifdef HAL_CORTEX_MODULE_ENABLED
-
-/* Private types -------------------------------------------------------------*/
-/* Private variables ---------------------------------------------------------*/
-/* Private constants ---------------------------------------------------------*/
-/* Private macros ------------------------------------------------------------*/
-/* Private functions ---------------------------------------------------------*/
-/* Exported functions --------------------------------------------------------*/
-
-/** @addtogroup CORTEX_Exported_Functions
-  * @{
-  */
-
-
-/** @addtogroup CORTEX_Exported_Functions_Group1
-  *  @brief    Initialization and Configuration functions
-  *
-@verbatim
-  ==============================================================================
-              ##### Initialization and Configuration functions #####
-  ==============================================================================
-    [..]
-      This section provides the CORTEX HAL driver functions allowing to configure Interrupts
-      SysTick functionalities
-
-@endverbatim
-  * @{
-  */
-
-/**
-  * @brief  Set the priority grouping field (pre-emption priority and subpriority)
-  *         using the required unlock sequence.
-  * @param  PriorityGroup The priority grouping bits length.
-  *         This parameter can be one of the following values:
-  *         @arg NVIC_PRIORITYGROUP_0: 0 bit  for pre-emption priority,
-  *                                    4 bits for subpriority
-  *         @arg NVIC_PRIORITYGROUP_1: 1 bit  for pre-emption priority,
-  *                                    3 bits for subpriority
-  *         @arg NVIC_PRIORITYGROUP_2: 2 bits for pre-emption priority,
-  *                                    2 bits for subpriority
-  *         @arg NVIC_PRIORITYGROUP_3: 3 bits for pre-emption priority,
-  *                                    1 bit  for subpriority
-  *         @arg NVIC_PRIORITYGROUP_4: 4 bits for pre-emption priority,
-  *                                    0 bit  for subpriority
-  * @note   When the NVIC_PriorityGroup_0 is selected, IRQ pre-emption is no more possible.
-  *         The pending IRQ priority will be managed only by the subpriority.
-  * @retval None
-  */
-void HAL_NVIC_SetPriorityGrouping(uint32_t PriorityGroup)
-{
-  /* Check the parameters */
-  assert_param(IS_NVIC_PRIORITY_GROUP(PriorityGroup));
-
-  /* Set the PRIGROUP[10:8] bits according to the PriorityGroup parameter value */
-  NVIC_SetPriorityGrouping(PriorityGroup);
-}
-
-/**
-  * @brief  Set the priority of an interrupt.
-  * @param IRQn External interrupt number.
-  *         This parameter can be an enumerator of IRQn_Type enumeration
-  *         (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32wbxxxx.h))
-  * @param PreemptPriority The pre-emption priority for the IRQn channel.
-  *         This parameter can be a value between 0 and 15
-  *         A lower priority value indicates a higher priority
-  * @param SubPriority the subpriority level for the IRQ channel.
-  *         This parameter can be a value between 0 and 15
-  *         A lower priority value indicates a higher priority.
-  * @retval None
-  */
-void HAL_NVIC_SetPriority(IRQn_Type IRQn, uint32_t PreemptPriority, uint32_t SubPriority)
-{
-  uint32_t prioritygroup;
-
-  /* Check the parameters */
-  assert_param(IS_NVIC_SUB_PRIORITY(SubPriority));
-  assert_param(IS_NVIC_PREEMPTION_PRIORITY(PreemptPriority));
-
-  prioritygroup = NVIC_GetPriorityGrouping();
-
-  NVIC_SetPriority(IRQn, NVIC_EncodePriority(prioritygroup, PreemptPriority, SubPriority));
-}
-
-/**
-  * @brief  Enable a device specific interrupt in the NVIC interrupt controller.
-  * @param  IRQn External interrupt number.
-  *         This parameter can be an enumerator of IRQn_Type enumeration
-  *         (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32wbxxxx.h))
-  * @retval None
-  */
-void HAL_NVIC_EnableIRQ(IRQn_Type IRQn)
-{
-  /* Check the parameters */
-  assert_param(IS_NVIC_DEVICE_IRQ(IRQn));
-
-  /* Enable interrupt */
-  NVIC_EnableIRQ(IRQn);
-}
-
-/**
-  * @brief  Disable a device specific interrupt in the NVIC interrupt controller.
-  * @param  IRQn External interrupt number.
-  *         This parameter can be an enumerator of IRQn_Type enumeration
-  *         (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32wbxxxx.h))
-  * @retval None
-  */
-void HAL_NVIC_DisableIRQ(IRQn_Type IRQn)
-{
-  /* Check the parameters */
-  assert_param(IS_NVIC_DEVICE_IRQ(IRQn));
-
-  /* Disable interrupt */
-  NVIC_DisableIRQ(IRQn);
-}
-
-/**
-  * @brief  Initiate a system reset request to reset the MCU.
-  * @retval None
-  */
-void HAL_NVIC_SystemReset(void)
-{
-  /* System Reset */
-  NVIC_SystemReset();
-}
-
-/**
-  * @brief  Initialize the System Timer with interrupt enabled and start the System Tick Timer (SysTick):
-  *         Counter is in free running mode to generate periodic interrupts.
-  * @param TicksNumb Specifies the ticks Number of ticks between two interrupts.
-  * @retval status:  - 0  Function succeeded.
-  *                  - 1  Function failed.
-  */
-uint32_t HAL_SYSTICK_Config(uint32_t TicksNumb)
-{
-  return SysTick_Config(TicksNumb);
-}
-/**
-  * @}
-  */
-
-/** @addtogroup CORTEX_Exported_Functions_Group2
-  *  @brief   Cortex control functions
-  *
-@verbatim
-  ==============================================================================
-                      ##### Peripheral Control functions #####
-  ==============================================================================
-    [..]
-      This subsection provides a set of functions allowing to control the CORTEX
-      (NVIC, SYSTICK, MPU) functionalities.
-
-
-@endverbatim
-  * @{
-  */
-
-
-/**
-  * @brief  Get the priority grouping field from the NVIC Interrupt Controller.
-  * @retval Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field)
-  */
-uint32_t HAL_NVIC_GetPriorityGrouping(void)
-{
-  /* Get the PRIGROUP[10:8] field value */
-  return NVIC_GetPriorityGrouping();
-}
-
-/**
-  * @brief  Get the priority of an interrupt.
-  * @param IRQn External interrupt number.
-  *         This parameter can be an enumerator of IRQn_Type enumeration
-  *         (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32wbxxxx.h))
-  * @param PriorityGroup the priority grouping bits length.
-  *         This parameter can be one of the following values:
-  *           @arg NVIC_PRIORITYGROUP_0: 0 bit for pre-emption priority,
-  *                                      4 bits for subpriority
-  *           @arg NVIC_PRIORITYGROUP_1: 1 bit for pre-emption priority,
-  *                                      3 bits for subpriority
-  *           @arg NVIC_PRIORITYGROUP_2: 2 bits for pre-emption priority,
-  *                                      2 bits for subpriority
-  *           @arg NVIC_PRIORITYGROUP_3: 3 bits for pre-emption priority,
-  *                                      1 bit for subpriority
-  *           @arg NVIC_PRIORITYGROUP_4: 4 bits for pre-emption priority,
-  *                                      0 bit for subpriority
-  * @param pPreemptPriority Pointer on the Preemptive priority value (starting from 0).
-  * @param pSubPriority Pointer on the Subpriority value (starting from 0).
-  * @retval None
-  */
-void HAL_NVIC_GetPriority(IRQn_Type IRQn, uint32_t PriorityGroup, uint32_t *pPreemptPriority, uint32_t *pSubPriority)
-{
-  /* Check the parameters */
-  assert_param(IS_NVIC_PRIORITY_GROUP(PriorityGroup));
-  /* Get priority for Cortex-M system or device specific interrupts */
-  NVIC_DecodePriority(NVIC_GetPriority(IRQn), PriorityGroup, pPreemptPriority, pSubPriority);
-}
-
-/**
-  * @brief  Set Pending bit of an external interrupt.
-  * @param  IRQn External interrupt number
-  *         This parameter can be an enumerator of IRQn_Type enumeration
-  *         (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32wbxxxx.h))
-  * @retval None
-  */
-void HAL_NVIC_SetPendingIRQ(IRQn_Type IRQn)
-{
-  /* Check the parameters */
-  assert_param(IS_NVIC_DEVICE_IRQ(IRQn));
-
-  /* Set interrupt pending */
-  NVIC_SetPendingIRQ(IRQn);
-}
-
-/**
-  * @brief  Get Pending Interrupt (read the pending register in the NVIC
-  *         and return the pending bit for the specified interrupt).
-  * @param  IRQn External interrupt number.
-  *         This parameter can be an enumerator of IRQn_Type enumeration
-  *         (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32wbxxxx.h))
-  * @retval status: - 0  Interrupt status is not pending.
-  *                 - 1  Interrupt status is pending.
-  */
-uint32_t HAL_NVIC_GetPendingIRQ(IRQn_Type IRQn)
-{
-  /* Check the parameters */
-  assert_param(IS_NVIC_DEVICE_IRQ(IRQn));
-
-  /* Return 1 if pending else 0 */
-  return NVIC_GetPendingIRQ(IRQn);
-}
-
-/**
-  * @brief  Clear the pending bit of an external interrupt.
-  * @param  IRQn External interrupt number.
-  *         This parameter can be an enumerator of IRQn_Type enumeration
-  *         (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32wbxxxx.h))
-  * @retval None
-  */
-void HAL_NVIC_ClearPendingIRQ(IRQn_Type IRQn)
-{
-  /* Check the parameters */
-  assert_param(IS_NVIC_DEVICE_IRQ(IRQn));
-
-  /* Clear pending interrupt */
-  NVIC_ClearPendingIRQ(IRQn);
-}
-
-/**
-  * @brief  Configure the SysTick clock source.
-  * @param CLKSource specifies the SysTick clock source.
-  *         This parameter can be one of the following values:
-  *             @arg SYSTICK_CLKSOURCE_HCLK_DIV8: AHB clock divided by 8 selected as SysTick clock source.
-  *             @arg SYSTICK_CLKSOURCE_HCLK: AHB clock selected as SysTick clock source.
-  * @retval None
-  */
-void HAL_SYSTICK_CLKSourceConfig(uint32_t CLKSource)
-{
-  /* Check the parameters */
-  assert_param(IS_SYSTICK_CLK_SOURCE(CLKSource));
-  if (CLKSource == SYSTICK_CLKSOURCE_HCLK)
-  {
-    SysTick->CTRL |= SYSTICK_CLKSOURCE_HCLK;
-  }
-  else
-  {
-    SysTick->CTRL &= ~SYSTICK_CLKSOURCE_HCLK;
-  }
-}
-
-/**
-  * @brief  Handle SYSTICK interrupt request.
-  * @retval None
-  */
-void HAL_SYSTICK_IRQHandler(void)
-{
-  HAL_SYSTICK_Callback();
-}
-
-/**
-  * @brief  SYSTICK callback.
-  * @retval None
-  */
-__weak void HAL_SYSTICK_Callback(void)
-{
-  /* NOTE : This function should not be modified, when the callback is needed,
-            the HAL_SYSTICK_Callback could be implemented in the user file
-   */
-}
-
-#if (__MPU_PRESENT == 1U)
-/**
-  * @brief  Disables the MPU
-  * @retval None
-  */
-void HAL_MPU_Disable(void)
-{
-  /* Make sure outstanding transfers are done */
-  __DMB();
-
-  /* Disable fault exceptions */
-  SCB->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk;
-  
-  /* Disable the MPU and clear the control register*/
-  MPU->CTRL = 0U;
-}
-
-/**
-  * @brief  Enable the MPU.
-  * @param  MPU_Control: Specifies the control mode of the MPU during hard fault,
-  *          NMI, FAULTMASK and privileged access to the default memory
-  *          This parameter can be one of the following values:
-  *            @arg MPU_HFNMI_PRIVDEF_NONE
-  *            @arg MPU_HARDFAULT_NMI
-  *            @arg MPU_PRIVILEGED_DEFAULT
-  *            @arg MPU_HFNMI_PRIVDEF
-  * @retval None
-  */
-void HAL_MPU_Enable(uint32_t MPU_Control)
-{
-  /* Enable the MPU */
-  MPU->CTRL = (MPU_Control | MPU_CTRL_ENABLE_Msk);
-  
-  /* Enable fault exceptions */
-  SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk;
-  
-  /* Ensure MPU setting take effects */
-  __DSB();
-  __ISB();
-}
-
-/**
-  * @brief  Initialize and configure the Region and the memory to be protected.
-  * @param MPU_Init Pointer to a MPU_Region_InitTypeDef structure that contains
-  *                the initialization and configuration information.
-  * @retval None
-  */
-void HAL_MPU_ConfigRegion(MPU_Region_InitTypeDef *MPU_Init)
-{
-  /* Check the parameters */
-  assert_param(IS_MPU_REGION_NUMBER(MPU_Init->Number));
-  assert_param(IS_MPU_REGION_ENABLE(MPU_Init->Enable));
-
-  /* Set the Region number */
-  MPU->RNR = MPU_Init->Number;
-
-  if ((MPU_Init->Enable) != 0U)
-  {
-    /* Check the parameters */
-    assert_param(IS_MPU_INSTRUCTION_ACCESS(MPU_Init->DisableExec));
-    assert_param(IS_MPU_REGION_PERMISSION_ATTRIBUTE(MPU_Init->AccessPermission));
-    assert_param(IS_MPU_TEX_LEVEL(MPU_Init->TypeExtField));
-    assert_param(IS_MPU_ACCESS_SHAREABLE(MPU_Init->IsShareable));
-    assert_param(IS_MPU_ACCESS_CACHEABLE(MPU_Init->IsCacheable));
-    assert_param(IS_MPU_ACCESS_BUFFERABLE(MPU_Init->IsBufferable));
-    assert_param(IS_MPU_SUB_REGION_DISABLE(MPU_Init->SubRegionDisable));
-    assert_param(IS_MPU_REGION_SIZE(MPU_Init->Size));
-
-    MPU->RBAR = MPU_Init->BaseAddress;
-    MPU->RASR = ((uint32_t)MPU_Init->DisableExec             << MPU_RASR_XN_Pos)   |
-                ((uint32_t)MPU_Init->AccessPermission        << MPU_RASR_AP_Pos)   |
-                ((uint32_t)MPU_Init->TypeExtField            << MPU_RASR_TEX_Pos)  |
-                ((uint32_t)MPU_Init->IsShareable             << MPU_RASR_S_Pos)    |
-                ((uint32_t)MPU_Init->IsCacheable             << MPU_RASR_C_Pos)    |
-                ((uint32_t)MPU_Init->IsBufferable            << MPU_RASR_B_Pos)    |
-                ((uint32_t)MPU_Init->SubRegionDisable        << MPU_RASR_SRD_Pos)  |
-                ((uint32_t)MPU_Init->Size                    << MPU_RASR_SIZE_Pos) |
-                ((uint32_t)MPU_Init->Enable                  << MPU_RASR_ENABLE_Pos);
-  }
-  else
-  {
-    MPU->RBAR = 0x00U;
-    MPU->RASR = 0x00U;
-  }
-}
-#endif /* __MPU_PRESENT */
-
-/**
-  * @}
-  */
-
-/**
-  * @}
-  */
-
-#endif /* HAL_CORTEX_MODULE_ENABLED */
-/**
-  * @}
-  */
-
-/**
-  * @}
-  */

+ 0 - 1118
non_catalog_apps/flipperscope/lib/adc/stm32wbxx_hal_dma.c

@@ -1,1118 +0,0 @@
-/**
-  ******************************************************************************
-  * @file    stm32wbxx_hal_dma.c
-  * @author  MCD Application Team
-  * @brief   DMA HAL module driver.
-  *         This file provides firmware functions to manage the following
-  *         functionalities of the Direct Memory Access (DMA) peripheral:
-  *           + Initialization and de-initialization functions
-  *           + IO operation functions
-  *           + Peripheral State and errors 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 #####
-  ==============================================================================
-  [..]
-   (#) Enable and configure the peripheral to be connected to the DMA Channel
-       (except for internal SRAM / FLASH memories: no initialization is
-       necessary). Please refer to the Reference manual for connection between peripherals
-       and DMA requests.
-
-   (#) For a given Channel, program the required configuration through the following parameters:
-       Channel request, Transfer Direction, Source and Destination data formats,
-       Circular or Normal mode, Channel Priority level, Source and Destination Increment mode
-       using HAL_DMA_Init() function.
-
-       Prior to HAL_DMA_Init the peripheral clock shall be enabled for both DMA & DMAMUX
-       thanks to:
-      (##) DMA1 or DMA2: __HAL_RCC_DMA1_CLK_ENABLE() or  __HAL_RCC_DMA2_CLK_ENABLE() ;
-      (##) DMAMUX1:      __HAL_RCC_DMAMUX1_CLK_ENABLE();
-
-   (#) Use HAL_DMA_GetState() function to return the DMA state and HAL_DMA_GetError() in case of error
-       detection.
-
-   (#) Use HAL_DMA_Abort() function to abort the current transfer
-
-     -@-   In Memory-to-Memory transfer mode, Circular mode is not allowed.
-
-     *** Polling mode IO operation ***
-     =================================
-    [..]
-          (+) Use HAL_DMA_Start() to start DMA transfer after the configuration of Source
-              address and destination address and the Length of data to be transferred
-          (+) Use HAL_DMA_PollForTransfer() to poll for the end of current transfer, in this
-              case a fixed Timeout can be configured by User depending from his application.
-
-     *** Interrupt mode IO operation ***
-     ===================================
-    [..]
-          (+) Configure the DMA interrupt priority using HAL_NVIC_SetPriority()
-          (+) Enable the DMA IRQ handler using HAL_NVIC_EnableIRQ()
-          (+) Use HAL_DMA_Start_IT() to start DMA transfer after the configuration of
-              Source address and destination address and the Length of data to be transferred.
-              In this case the DMA interrupt is configured
-          (+) Use HAL_DMA_IRQHandler() called under DMA_IRQHandler() Interrupt subroutine
-          (+) At the end of data transfer HAL_DMA_IRQHandler() function is executed and user can
-              add his own function to register callbacks with HAL_DMA_RegisterCallback().
-
-     *** DMA HAL driver macros list ***
-     =============================================
-      [..]
-       Below the list of macros in DMA HAL driver.
-
-       (+) __HAL_DMA_ENABLE: Enable the specified DMA Channel.
-       (+) __HAL_DMA_DISABLE: Disable the specified DMA Channel.
-       (+) __HAL_DMA_GET_FLAG: Get the DMA Channel pending flags.
-       (+) __HAL_DMA_CLEAR_FLAG: Clear the DMA Channel pending flags.
-       (+) __HAL_DMA_ENABLE_IT: Enable the specified DMA Channel interrupts.
-       (+) __HAL_DMA_DISABLE_IT: Disable the specified DMA Channel interrupts.
-       (+) __HAL_DMA_GET_IT_SOURCE: Check whether the specified DMA Channel interrupt is enabled or not.
-
-     [..]
-      (@) You can refer to the DMA HAL driver header file for more useful macros
-
-  @endverbatim
-  ******************************************************************************
-  */
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32wbxx_hal.h"
-
-/** @addtogroup STM32WBxx_HAL_Driver
-  * @{
-  */
-
-/** @defgroup DMA DMA
-  * @brief DMA HAL module driver
-  * @{
-  */
-
-#ifdef HAL_DMA_MODULE_ENABLED
-
-/* Private typedef -----------------------------------------------------------*/
-/* Private define ------------------------------------------------------------*/
-/* Private macro -------------------------------------------------------------*/
-/* Private variables ---------------------------------------------------------*/
-/* Private function prototypes -----------------------------------------------*/
-/** @defgroup DMA_Private_Functions DMA Private Functions
-  * @{
-  */
-static void DMA_SetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength);
-static void DMA_CalcDMAMUXChannelBaseAndMask(DMA_HandleTypeDef *hdma);
-static void DMA_CalcDMAMUXRequestGenBaseAndMask(DMA_HandleTypeDef *hdma);
-
-/**
-  * @}
-  */
-
-/* Exported functions ---------------------------------------------------------*/
-
-/** @defgroup DMA_Exported_Functions DMA Exported Functions
-  * @{
-  */
-
-/** @defgroup DMA_Exported_Functions_Group1 Initialization and de-initialization functions
- *  @brief   Initialization and de-initialization functions
- *
-@verbatim
- ===============================================================================
-             ##### Initialization and de-initialization functions  #####
- ===============================================================================
-    [..]
-    This section provides functions allowing to initialize the DMA Channel source
-    and destination addresses, incrementation and data sizes, transfer direction,
-    circular/normal mode selection, memory-to-memory mode selection and Channel priority value.
-    [..]
-    The HAL_DMA_Init() function follows the DMA configuration procedures as described in
-    reference manual.
-
-@endverbatim
-  * @{
-  */
-
-/**
-  * @brief  Initialize the DMA according to the specified
-  *         parameters in the DMA_InitTypeDef and initialize the associated handle.
-  * @param hdma Pointer to a DMA_HandleTypeDef structure that contains
-  *               the configuration information for the specified DMA Channel.
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_DMA_Init(DMA_HandleTypeDef *hdma)
-{
-  uint32_t tmp;
-
-  /* Check the DMA handle allocation */
-  if (hdma == NULL)
-  {
-    return HAL_ERROR;
-  }
-
-  /* Check the parameters */
-  assert_param(IS_DMA_ALL_INSTANCE(hdma->Instance));
-  assert_param(IS_DMA_DIRECTION(hdma->Init.Direction));
-  assert_param(IS_DMA_PERIPHERAL_INC_STATE(hdma->Init.PeriphInc));
-  assert_param(IS_DMA_MEMORY_INC_STATE(hdma->Init.MemInc));
-  assert_param(IS_DMA_PERIPHERAL_DATA_SIZE(hdma->Init.PeriphDataAlignment));
-  assert_param(IS_DMA_MEMORY_DATA_SIZE(hdma->Init.MemDataAlignment));
-  assert_param(IS_DMA_MODE(hdma->Init.Mode));
-  assert_param(IS_DMA_PRIORITY(hdma->Init.Priority));
-
-  assert_param(IS_DMA_ALL_REQUEST(hdma->Init.Request));
-
-#if defined(DMA2)
-  /* Compute the channel index */
-  if ((uint32_t)(hdma->Instance) < (uint32_t)(DMA2_Channel1))
-  {
-    /* DMA1 */
-    hdma->ChannelIndex = (((uint32_t)hdma->Instance - (uint32_t)DMA1_Channel1) / ((uint32_t)DMA1_Channel2 - (uint32_t)DMA1_Channel1)) << 2U;
-    hdma->DmaBaseAddress = DMA1;
-  }
-  else
-  {
-    /* DMA2 */
-    hdma->ChannelIndex = (((uint32_t)hdma->Instance - (uint32_t)DMA2_Channel1) / ((uint32_t)DMA2_Channel2 - (uint32_t)DMA2_Channel1)) << 2U;
-    hdma->DmaBaseAddress = DMA2;
-  }
-#else
-  /* DMA1 */
-  hdma->ChannelIndex = (((uint32_t)hdma->Instance - (uint32_t)DMA1_Channel1) / ((uint32_t)DMA1_Channel2 - (uint32_t)DMA1_Channel1)) << 2U;
-  hdma->DmaBaseAddress = DMA1;
-#endif
-
-  /* Change DMA peripheral state */
-  hdma->State = HAL_DMA_STATE_BUSY;
-
-  /* Get the CR register value */
-  tmp = hdma->Instance->CCR;
-
-  /* Clear PL, MSIZE, PSIZE, MINC, PINC, CIRC, DIR and MEM2MEM bits */
-  tmp &= ((uint32_t)~(DMA_CCR_PL    | DMA_CCR_MSIZE  | DMA_CCR_PSIZE  |
-                      DMA_CCR_MINC  | DMA_CCR_PINC   | DMA_CCR_CIRC   |
-                      DMA_CCR_DIR   | DMA_CCR_MEM2MEM));
-
-  /* Prepare the DMA Channel configuration */
-  tmp |=  hdma->Init.Direction        |
-          hdma->Init.PeriphInc           | hdma->Init.MemInc           |
-          hdma->Init.PeriphDataAlignment | hdma->Init.MemDataAlignment |
-          hdma->Init.Mode                | hdma->Init.Priority;
-
-  /* Write to DMA Channel CR register */
-  hdma->Instance->CCR = tmp;
-
-  /* Initialize parameters for DMAMUX channel :
-     DMAmuxChannel, DMAmuxChannelStatus and DMAmuxChannelStatusMask
-  */
-  DMA_CalcDMAMUXChannelBaseAndMask(hdma);
-
-  if (hdma->Init.Direction == DMA_MEMORY_TO_MEMORY)
-  {
-    /* if memory to memory force the request to 0*/
-    hdma->Init.Request = DMA_REQUEST_MEM2MEM;
-  }
-
-  /* Set peripheral request  to DMAMUX channel */
-  hdma->DMAmuxChannel->CCR = (hdma->Init.Request & DMAMUX_CxCR_DMAREQ_ID);
-
-  /* Clear the DMAMUX synchro overrun flag */
-  hdma->DMAmuxChannelStatus->CFR = hdma->DMAmuxChannelStatusMask;
-
-  if (((hdma->Init.Request >  0U) && (hdma->Init.Request <= DMA_REQUEST_GENERATOR3)))
-  {
-    /* Initialize parameters for DMAMUX request generator :
-       DMAmuxRequestGen, DMAmuxRequestGenStatus and DMAmuxRequestGenStatusMask
-    */
-    DMA_CalcDMAMUXRequestGenBaseAndMask(hdma);
-
-    /* Reset the DMAMUX request generator register*/
-    hdma->DMAmuxRequestGen->RGCR = 0U;
-
-    /* Clear the DMAMUX request generator overrun flag */
-    hdma->DMAmuxRequestGenStatus->RGCFR = hdma->DMAmuxRequestGenStatusMask;
-  }
-  else
-  {
-    hdma->DMAmuxRequestGen = 0U;
-    hdma->DMAmuxRequestGenStatus = 0U;
-    hdma->DMAmuxRequestGenStatusMask = 0U;
-  }
-
-  /* Initialize the error code */
-  hdma->ErrorCode = HAL_DMA_ERROR_NONE;
-
-  /* Initialize the DMA state*/
-  hdma->State  = HAL_DMA_STATE_READY;
-
-  /* Allocate lock resource and initialize it */
-  hdma->Lock = HAL_UNLOCKED;
-
-  return HAL_OK;
-}
-
-/**
-  * @brief  DeInitialize the DMA peripheral.
-  * @param hdma Pointer to a DMA_HandleTypeDef structure that contains
-  *               the configuration information for the specified DMA Channel.
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_DMA_DeInit(DMA_HandleTypeDef *hdma)
-{
-
-  /* Check the DMA handle allocation */
-  if (NULL == hdma)
-  {
-    return HAL_ERROR;
-  }
-
-  /* Check the parameters */
-  assert_param(IS_DMA_ALL_INSTANCE(hdma->Instance));
-
-  /* Disable the selected DMA Channelx */
-  __HAL_DMA_DISABLE(hdma);
-
-#if defined(DMA2)
-  /* Compute the channel index */
-  if ((uint32_t)(hdma->Instance) < (uint32_t)(DMA2_Channel1))
-  {
-    /* DMA1 */
-    hdma->ChannelIndex = (((uint32_t)hdma->Instance - (uint32_t)DMA1_Channel1) / ((uint32_t)DMA1_Channel2 - (uint32_t)DMA1_Channel1)) << 2U;
-    hdma->DmaBaseAddress = DMA1;
-  }
-  else
-  {
-    /* DMA2 */
-    hdma->ChannelIndex = (((uint32_t)hdma->Instance - (uint32_t)DMA2_Channel1) / ((uint32_t)DMA2_Channel2 - (uint32_t)DMA2_Channel1)) << 2U;
-    hdma->DmaBaseAddress = DMA2;
-  }
-#else
-  /* DMA1 */
-  hdma->ChannelIndex = (((uint32_t)hdma->Instance - (uint32_t)DMA1_Channel1) / ((uint32_t)DMA1_Channel2 - (uint32_t)DMA1_Channel1)) << 2U;
-  hdma->DmaBaseAddress = DMA1;
-#endif
-
-  /* Reset DMA Channel control register */
-  hdma->Instance->CCR  = 0U;
-
-  /* Clear all flags */
-  hdma->DmaBaseAddress->IFCR = (DMA_ISR_GIF1 << (hdma->ChannelIndex & 0x1cU));
-
-  /* Initialize parameters for DMAMUX channel :
-     DMAmuxChannel, DMAmuxChannelStatus and DMAmuxChannelStatusMask */
-
-  DMA_CalcDMAMUXChannelBaseAndMask(hdma);
-
-  /* Reset the DMAMUX channel that corresponds to the DMA channel */
-  hdma->DMAmuxChannel->CCR = 0U;
-
-  /* Clear the DMAMUX synchro overrun flag */
-  hdma->DMAmuxChannelStatus->CFR = hdma->DMAmuxChannelStatusMask;
-
-  /* Reset Request generator parameters if any */
-  if (((hdma->Init.Request >  0U) && (hdma->Init.Request <= DMA_REQUEST_GENERATOR3)))
-  {
-    /* Initialize parameters for DMAMUX request generator :
-       DMAmuxRequestGen, DMAmuxRequestGenStatus and DMAmuxRequestGenStatusMask
-    */
-    DMA_CalcDMAMUXRequestGenBaseAndMask(hdma);
-
-    /* Reset the DMAMUX request generator register*/
-    hdma->DMAmuxRequestGen->RGCR = 0U;
-
-    /* Clear the DMAMUX request generator overrun flag */
-    hdma->DMAmuxRequestGenStatus->RGCFR = hdma->DMAmuxRequestGenStatusMask;
-  }
-
-  hdma->DMAmuxRequestGen = 0U;
-  hdma->DMAmuxRequestGenStatus = 0U;
-  hdma->DMAmuxRequestGenStatusMask = 0U;
-
-  /* Clean callbacks */
-  hdma->XferCpltCallback = NULL;
-  hdma->XferHalfCpltCallback = NULL;
-  hdma->XferErrorCallback = NULL;
-  hdma->XferAbortCallback = NULL;
-
-  /* Initialize the error code */
-  hdma->ErrorCode = HAL_DMA_ERROR_NONE;
-
-  /* Initialize the DMA state */
-  hdma->State = HAL_DMA_STATE_RESET;
-
-  /* Release Lock */
-  __HAL_UNLOCK(hdma);
-
-  return HAL_OK;
-}
-
-/**
-  * @}
-  */
-
-/** @defgroup DMA_Exported_Functions_Group2 Input and Output operation functions
- *  @brief   Input and Output operation functions
- *
-@verbatim
- ===============================================================================
-                      #####  IO operation functions  #####
- ===============================================================================
-    [..]  This section provides functions allowing to:
-      (+) Configure the source, destination address and data length and Start DMA transfer
-      (+) Configure the source, destination address and data length and
-          Start DMA transfer with interrupt
-      (+) Abort DMA transfer
-      (+) Poll for transfer complete
-      (+) Handle DMA interrupt request
-
-@endverbatim
-  * @{
-  */
-
-/**
-  * @brief  Start the DMA Transfer.
-  * @param hdma Pointer to a DMA_HandleTypeDef structure that contains
-  *               the configuration information for the specified DMA Channel.
-  * @param SrcAddress The source memory Buffer address
-  * @param DstAddress The destination memory Buffer address
-  * @param DataLength The length of data to be transferred from source to destination
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_DMA_Start(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
-{
-  HAL_StatusTypeDef status = HAL_OK;
-
-  /* Check the parameters */
-  assert_param(IS_DMA_BUFFER_SIZE(DataLength));
-
-  /* Process locked */
-  __HAL_LOCK(hdma);
-
-  if (HAL_DMA_STATE_READY == hdma->State)
-  {
-    /* Change DMA peripheral state */
-    hdma->State = HAL_DMA_STATE_BUSY;
-    hdma->ErrorCode = HAL_DMA_ERROR_NONE;
-
-    /* Disable the peripheral */
-    __HAL_DMA_DISABLE(hdma);
-
-    /* Configure the source, destination address and the data length & clear flags*/
-    DMA_SetConfig(hdma, SrcAddress, DstAddress, DataLength);
-
-    /* Enable the Peripheral */
-    __HAL_DMA_ENABLE(hdma);
-  }
-  else
-  {
-    /* Process Unlocked */
-    __HAL_UNLOCK(hdma);
-    status = HAL_BUSY;
-  }
-  return status;
-}
-
-/**
-  * @brief  Start the DMA Transfer with interrupt enabled.
-  * @param hdma Pointer to a DMA_HandleTypeDef structure that contains
-  *               the configuration information for the specified DMA Channel.
-  * @param SrcAddress The source memory Buffer address
-  * @param DstAddress The destination memory Buffer address
-  * @param DataLength The length of data to be transferred from source to destination
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_DMA_Start_IT(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
-{
-  HAL_StatusTypeDef status = HAL_OK;
-
-  /* Check the parameters */
-  assert_param(IS_DMA_BUFFER_SIZE(DataLength));
-
-  /* Process locked */
-  __HAL_LOCK(hdma);
-
-  if (HAL_DMA_STATE_READY == hdma->State)
-  {
-    /* Change DMA peripheral state */
-    hdma->State = HAL_DMA_STATE_BUSY;
-    hdma->ErrorCode = HAL_DMA_ERROR_NONE;
-
-    /* Disable the peripheral */
-    __HAL_DMA_DISABLE(hdma);
-
-    /* Configure the source, destination address and the data length & clear flags*/
-    DMA_SetConfig(hdma, SrcAddress, DstAddress, DataLength);
-
-    /* Enable the transfer complete interrupt */
-    /* Enable the transfer Error interrupt */
-    if (NULL != hdma->XferHalfCpltCallback)
-    {
-      /* Enable the Half transfer complete interrupt as well */
-      __HAL_DMA_ENABLE_IT(hdma, (DMA_IT_TC | DMA_IT_HT | DMA_IT_TE));
-    }
-    else
-    {
-      __HAL_DMA_DISABLE_IT(hdma, DMA_IT_HT);
-      __HAL_DMA_ENABLE_IT(hdma, (DMA_IT_TC | DMA_IT_TE));
-    }
-
-    /* Check if DMAMUX Synchronization is enabled*/
-    if ((hdma->DMAmuxChannel->CCR & DMAMUX_CxCR_SE) != 0U)
-    {
-      /* Enable DMAMUX sync overrun IT*/
-      hdma->DMAmuxChannel->CCR |= DMAMUX_CxCR_SOIE;
-    }
-
-    if (hdma->DMAmuxRequestGen != 0U)
-    {
-      /* if using DMAMUX request generator, enable the DMAMUX request generator overrun IT*/
-      /* enable the request gen overrun IT*/
-      hdma->DMAmuxRequestGen->RGCR |= DMAMUX_RGxCR_OIE;
-    }
-
-    /* Enable the Peripheral */
-    __HAL_DMA_ENABLE(hdma);
-  }
-  else
-  {
-    /* Process Unlocked */
-    __HAL_UNLOCK(hdma);
-
-    /* Remain BUSY */
-    status = HAL_BUSY;
-  }
-  return status;
-}
-
-/**
-  * @brief  Abort the DMA Transfer.
-  * @param hdma Pointer to a DMA_HandleTypeDef structure that contains
-  *               the configuration information for the specified DMA Channel.
-    * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_DMA_Abort(DMA_HandleTypeDef *hdma)
-{
-
-  /* Check the DMA peripheral handle */
-  if (NULL == hdma)
-  {
-    return HAL_ERROR;
-  }
-
-  /* Check the DMA peripheral state */
-  if(hdma->State != HAL_DMA_STATE_BUSY)
-  {
-    hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER;
-
-    /* Process Unlocked */
-    __HAL_UNLOCK(hdma);
-
-    return HAL_ERROR;
-  }
-  else
-  {
-    /* Disable DMA IT */
-    __HAL_DMA_DISABLE_IT(hdma, (DMA_IT_TC | DMA_IT_HT | DMA_IT_TE));
-
-    /* disable the DMAMUX sync overrun IT*/
-    hdma->DMAmuxChannel->CCR &= ~DMAMUX_CxCR_SOIE;
-
-    /* Disable the channel */
-    __HAL_DMA_DISABLE(hdma);
-
-    /* Clear all flags */
-    hdma->DmaBaseAddress->IFCR = (DMA_ISR_GIF1 << (hdma->ChannelIndex & 0x1cU));
-
-    /* Clear the DMAMUX synchro overrun flag */
-    hdma->DMAmuxChannelStatus->CFR = hdma->DMAmuxChannelStatusMask;
-
-    if (hdma->DMAmuxRequestGen != 0U)
-    {
-      /* if using DMAMUX request generator, disable the DMAMUX request generator overrun IT*/
-      /* disable the request gen overrun IT*/
-      hdma->DMAmuxRequestGen->RGCR &= ~DMAMUX_RGxCR_OIE;
-
-      /* Clear the DMAMUX request generator overrun flag */
-      hdma->DMAmuxRequestGenStatus->RGCFR = hdma->DMAmuxRequestGenStatusMask;
-    }
-
-    /* Change the DMA state */
-    hdma->State = HAL_DMA_STATE_READY;
-
-    /* Process Unlocked */
-    __HAL_UNLOCK(hdma);
-  }
-
-  return HAL_OK;
-}
-
-/**
-  * @brief  Aborts the DMA Transfer in Interrupt mode.
-  * @param  hdma  Pointer to a DMA_HandleTypeDef structure that contains
-  *                 the configuration information for the specified DMA Channel.
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_DMA_Abort_IT(DMA_HandleTypeDef *hdma)
-{
-  HAL_StatusTypeDef status = HAL_OK;
-
-  if (HAL_DMA_STATE_BUSY != hdma->State)
-  {
-    /* no transfer ongoing */
-    hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER;
-
-    status = HAL_ERROR;
-  }
-  else
-  {
-    /* Disable DMA IT */
-    __HAL_DMA_DISABLE_IT(hdma, (DMA_IT_TC | DMA_IT_HT | DMA_IT_TE));
-
-    /* Disable the channel */
-    __HAL_DMA_DISABLE(hdma);
-
-    /* disable the DMAMUX sync overrun IT*/
-    hdma->DMAmuxChannel->CCR &= ~DMAMUX_CxCR_SOIE;
-
-    /* Clear all flags */
-    hdma->DmaBaseAddress->IFCR = (DMA_ISR_GIF1 << (hdma->ChannelIndex & 0x1cU));
-
-    /* Clear the DMAMUX synchro overrun flag */
-    hdma->DMAmuxChannelStatus->CFR = hdma->DMAmuxChannelStatusMask;
-
-    if (hdma->DMAmuxRequestGen != 0U)
-    {
-      /* if using DMAMUX request generator, disable the DMAMUX request generator overrun IT*/
-      /* disable the request gen overrun IT*/
-      hdma->DMAmuxRequestGen->RGCR &= ~DMAMUX_RGxCR_OIE;
-
-      /* Clear the DMAMUX request generator overrun flag */
-      hdma->DMAmuxRequestGenStatus->RGCFR = hdma->DMAmuxRequestGenStatusMask;
-    }
-
-    /* Change the DMA state */
-    hdma->State = HAL_DMA_STATE_READY;
-
-    /* Process Unlocked */
-    __HAL_UNLOCK(hdma);
-
-    /* Call User Abort callback */
-    if (hdma->XferAbortCallback != NULL)
-    {
-      hdma->XferAbortCallback(hdma);
-    }
-  }
-  return status;
-}
-
-/**
-  * @brief  Polling for transfer complete.
-  * @param hdma Pointer to a DMA_HandleTypeDef structure that contains
-  *                  the configuration information for the specified DMA Channel.
-  * @param CompleteLevel Specifies the DMA level complete.
-  * @param Timeout Timeout duration.
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_DMA_PollForTransfer(DMA_HandleTypeDef *hdma, HAL_DMA_LevelCompleteTypeDef CompleteLevel, uint32_t Timeout)
-{
-  uint32_t temp;
-  uint32_t tickstart;
-
-  if (HAL_DMA_STATE_BUSY != hdma->State)
-  {
-    /* no transfer ongoing */
-    hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER;
-    __HAL_UNLOCK(hdma);
-    return HAL_ERROR;
-  }
-
-  /* Polling mode not supported in circular mode */
-  if ((hdma->Instance->CCR & DMA_CCR_CIRC) != 0U)
-  {
-    hdma->ErrorCode = HAL_DMA_ERROR_NOT_SUPPORTED;
-    return HAL_ERROR;
-  }
-
-  /* Get the level transfer complete flag */
-  if (HAL_DMA_FULL_TRANSFER == CompleteLevel)
-  {
-    /* Transfer Complete flag */
-    temp = DMA_FLAG_TC1 << (hdma->ChannelIndex & 0x1cU);
-  }
-  else
-  {
-    /* Half Transfer Complete flag */
-    temp = DMA_FLAG_HT1 << (hdma->ChannelIndex  & 0x1cU);
-  }
-
-  /* Get tick */
-  tickstart = HAL_GetTick();
-
-  while((hdma->DmaBaseAddress->ISR & temp) == 0U)
-  {
-    if((hdma->DmaBaseAddress->ISR & (DMA_FLAG_TE1 << (hdma->ChannelIndex& 0x1CU))) != 0U)
-    {
-      /* When a DMA transfer error occurs */
-      /* A hardware clear of its EN bits is performed */
-      /* Clear all flags */
-      hdma->DmaBaseAddress->IFCR = (DMA_ISR_GIF1 << (hdma->ChannelIndex & 0x1cU));
-
-      /* Update error code */
-      hdma->ErrorCode = HAL_DMA_ERROR_TE;
-
-      /* Change the DMA state */
-      hdma->State = HAL_DMA_STATE_READY;
-
-      /* Process Unlocked */
-      __HAL_UNLOCK(hdma);
-
-      return HAL_ERROR;
-    }
-    /* Check for the Timeout */
-    if (Timeout != HAL_MAX_DELAY)
-    {
-      if(((HAL_GetTick() - tickstart ) > Timeout)||(Timeout == 0U))
-      {
-        /* Update error code */
-        hdma->ErrorCode = HAL_DMA_ERROR_TIMEOUT;
-
-        /* Change the DMA state */
-        hdma->State = HAL_DMA_STATE_READY;
-
-        /* Process Unlocked */
-        __HAL_UNLOCK(hdma);
-
-        return HAL_ERROR;
-      }
-    }
-  }
-
-  /*Check for DMAMUX Request generator (if used) overrun status */
-  if (hdma->DMAmuxRequestGen != 0U)
-  {
-    /* if using DMAMUX request generator Check for DMAMUX request generator overrun */
-    if ((hdma->DMAmuxRequestGenStatus->RGSR & hdma->DMAmuxRequestGenStatusMask) != 0U)
-    {
-      /* Disable the request gen overrun interrupt */
-      hdma->DMAmuxRequestGen->RGCR |= DMAMUX_RGxCR_OIE;
-
-      /* Clear the DMAMUX request generator overrun flag */
-      hdma->DMAmuxRequestGenStatus->RGCFR = hdma->DMAmuxRequestGenStatusMask;
-
-      /* Update error code */
-      hdma->ErrorCode |= HAL_DMA_ERROR_REQGEN;
-    }
-  }
-
-  /* Check for DMAMUX Synchronization overrun */
-  if ((hdma->DMAmuxChannelStatus->CSR & hdma->DMAmuxChannelStatusMask) != 0U)
-  {
-    /* Clear the DMAMUX synchro overrun flag */
-    hdma->DMAmuxChannelStatus->CFR = hdma->DMAmuxChannelStatusMask;
-
-    /* Update error code */
-    hdma->ErrorCode |= HAL_DMA_ERROR_SYNC;
-  }
-
-  if (HAL_DMA_FULL_TRANSFER == CompleteLevel)
-  {
-    /* Clear the transfer complete flag */
-    hdma->DmaBaseAddress->IFCR = (DMA_FLAG_TC1 << (hdma->ChannelIndex & 0x1cU));
-
-    /* Process unlocked */
-    __HAL_UNLOCK(hdma);
-
-    /* The selected Channelx EN bit is cleared (DMA is disabled and
-    all transfers are complete) */
-    hdma->State = HAL_DMA_STATE_READY;
-  }
-  else
-  {
-    /* Clear the half transfer complete flag */
-    hdma->DmaBaseAddress->IFCR = (DMA_FLAG_HT1 << (hdma->ChannelIndex & 0x1cU));
-  }
-
-  return HAL_OK;
-}
-
-/**
-  * @brief  Handle DMA interrupt request.
-  * @param hdma Pointer to a DMA_HandleTypeDef structure that contains
-  *               the configuration information for the specified DMA Channel.
-  * @retval None
-  */
-void HAL_DMA_IRQHandler(DMA_HandleTypeDef *hdma)
-{
-  uint32_t flag_it = hdma->DmaBaseAddress->ISR;
-  uint32_t source_it = hdma->Instance->CCR;
-
-  /* Half Transfer Complete Interrupt management ******************************/
-  if (((flag_it & (DMA_FLAG_HT1 << (hdma->ChannelIndex & 0x1cU))) != 0U) && ((source_it & DMA_IT_HT) != 0U))
-  {
-    /* Disable the half transfer interrupt if the DMA mode is not CIRCULAR */
-    if ((hdma->Instance->CCR & DMA_CCR_CIRC) == 0U)
-    {
-      /* Disable the half transfer interrupt */
-      __HAL_DMA_DISABLE_IT(hdma, DMA_IT_HT);
-    }
-    /* Clear the half transfer complete flag */
-    hdma->DmaBaseAddress->IFCR = (DMA_ISR_HTIF1 << (hdma->ChannelIndex & 0x1CU));
-
-    /* DMA peripheral state is not updated in Half Transfer */
-    /* but in Transfer Complete case */
-
-    if (hdma->XferHalfCpltCallback != NULL)
-    {
-      /* Half transfer callback */
-      hdma->XferHalfCpltCallback(hdma);
-    }
-  }
-
-  /* Transfer Complete Interrupt management ***********************************/
-  else if (((flag_it & (DMA_FLAG_TC1 << (hdma->ChannelIndex & 0x1cU))) != 0U) && ((source_it & DMA_IT_TC) != 0U))
-  {
-    if ((hdma->Instance->CCR & DMA_CCR_CIRC) == 0U)
-    {
-      /* Disable the transfer complete and error interrupt */
-      __HAL_DMA_DISABLE_IT(hdma, DMA_IT_TE | DMA_IT_TC);
-
-      /* Change the DMA state */
-      hdma->State = HAL_DMA_STATE_READY;
-    }
-    /* Clear the transfer complete flag */
-    hdma->DmaBaseAddress->IFCR = (DMA_ISR_TCIF1 << (hdma->ChannelIndex & 0x1cU));
-
-    /* Process Unlocked */
-    __HAL_UNLOCK(hdma);
-
-    if (hdma->XferCpltCallback != NULL)
-    {
-      /* Transfer complete callback */
-      hdma->XferCpltCallback(hdma);
-    }
-  }
-
-  /* Transfer Error Interrupt management **************************************/
-  else if (((flag_it & (DMA_FLAG_TE1 << (hdma->ChannelIndex & 0x1cU)))!= 0U) && ((source_it & DMA_IT_TE) != 0U))
-  {
-    /* When a DMA transfer error occurs */
-    /* A hardware clear of its EN bits is performed */
-    /* Disable ALL DMA IT */
-    __HAL_DMA_DISABLE_IT(hdma, (DMA_IT_TC | DMA_IT_HT | DMA_IT_TE));
-
-    /* Clear all flags */
-    hdma->DmaBaseAddress->IFCR = (DMA_ISR_GIF1 << (hdma->ChannelIndex & 0x1cU));
-
-    /* Update error code */
-    hdma->ErrorCode = HAL_DMA_ERROR_TE;
-
-    /* Change the DMA state */
-    hdma->State = HAL_DMA_STATE_READY;
-
-    /* Process Unlocked */
-    __HAL_UNLOCK(hdma);
-
-    if (hdma->XferErrorCallback != NULL)
-    {
-      /* Transfer error callback */
-      hdma->XferErrorCallback(hdma);
-    }
-  }
-  else
-  {
-    /* Nothing To Do */
-  }
-  return;
-}
-
-/**
-  * @brief  Register callbacks
-  * @param hdma Pointer to a DMA_HandleTypeDef structure that contains
-  *                               the configuration information for the specified DMA Channel.
-  * @param CallbackID User Callback identifier
-  *                               a HAL_DMA_CallbackIDTypeDef ENUM as parameter.
-  * @param pCallback Pointer to private callback function which has pointer to
-  *                               a DMA_HandleTypeDef structure as parameter.
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_DMA_RegisterCallback(DMA_HandleTypeDef *hdma, HAL_DMA_CallbackIDTypeDef CallbackID, void (* pCallback)(DMA_HandleTypeDef *_hdma))
-{
-  HAL_StatusTypeDef status = HAL_OK;
-
-  /* Process locked */
-  __HAL_LOCK(hdma);
-
-  if (HAL_DMA_STATE_READY == hdma->State)
-  {
-    switch (CallbackID)
-    {
-      case  HAL_DMA_XFER_CPLT_CB_ID:
-        hdma->XferCpltCallback = pCallback;
-        break;
-
-      case  HAL_DMA_XFER_HALFCPLT_CB_ID:
-        hdma->XferHalfCpltCallback = pCallback;
-        break;
-
-      case  HAL_DMA_XFER_ERROR_CB_ID:
-        hdma->XferErrorCallback = pCallback;
-        break;
-
-      case  HAL_DMA_XFER_ABORT_CB_ID:
-        hdma->XferAbortCallback = pCallback;
-        break;
-
-      default:
-        status = HAL_ERROR;
-        break;
-    }
-  }
-  else
-  {
-    status = HAL_ERROR;
-  }
-
-  /* Release Lock */
-  __HAL_UNLOCK(hdma);
-
-  return status;
-}
-
-/**
-  * @brief  UnRegister callbacks
-  * @param hdma Pointer to a DMA_HandleTypeDef structure that contains
-  *                               the configuration information for the specified DMA Channel.
-  * @param CallbackID User Callback identifier
-  *                               a HAL_DMA_CallbackIDTypeDef ENUM as parameter.
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_DMA_UnRegisterCallback(DMA_HandleTypeDef *hdma, HAL_DMA_CallbackIDTypeDef CallbackID)
-{
-  HAL_StatusTypeDef status = HAL_OK;
-
-  /* Process locked */
-  __HAL_LOCK(hdma);
-
-  if (HAL_DMA_STATE_READY == hdma->State)
-  {
-    switch (CallbackID)
-    {
-      case  HAL_DMA_XFER_CPLT_CB_ID:
-        hdma->XferCpltCallback = NULL;
-        break;
-
-      case  HAL_DMA_XFER_HALFCPLT_CB_ID:
-        hdma->XferHalfCpltCallback = NULL;
-        break;
-
-      case  HAL_DMA_XFER_ERROR_CB_ID:
-        hdma->XferErrorCallback = NULL;
-        break;
-
-      case  HAL_DMA_XFER_ABORT_CB_ID:
-        hdma->XferAbortCallback = NULL;
-        break;
-
-      case   HAL_DMA_XFER_ALL_CB_ID:
-        hdma->XferCpltCallback = NULL;
-        hdma->XferHalfCpltCallback = NULL;
-        hdma->XferErrorCallback = NULL;
-        hdma->XferAbortCallback = NULL;
-        break;
-
-      default:
-        status = HAL_ERROR;
-        break;
-    }
-  }
-  else
-  {
-    status = HAL_ERROR;
-  }
-
-  /* Release Lock */
-  __HAL_UNLOCK(hdma);
-
-  return status;
-}
-
-/**
-  * @}
-  */
-
-
-
-/** @defgroup DMA_Exported_Functions_Group3 Peripheral State and Errors functions
- *  @brief    Peripheral State and Errors functions
- *
-@verbatim
- ===============================================================================
-            ##### Peripheral State and Errors functions #####
- ===============================================================================
-    [..]
-    This subsection provides functions allowing to
-      (+) Check the DMA state
-      (+) Get error code
-
-@endverbatim
-  * @{
-  */
-
-/**
-  * @brief  Return the DMA handle state.
-  * @param hdma Pointer to a DMA_HandleTypeDef structure that contains
-  *               the configuration information for the specified DMA Channel.
-  * @retval HAL state
-  */
-HAL_DMA_StateTypeDef HAL_DMA_GetState(DMA_HandleTypeDef *hdma)
-{
-  /* Return DMA handle state */
-  return hdma->State;
-}
-
-/**
-  * @brief  Return the DMA error code.
-  * @param  hdma Pointer to a DMA_HandleTypeDef structure that contains
-  *              the configuration information for the specified DMA Channel.
-  * @retval DMA Error Code
-  */
-uint32_t HAL_DMA_GetError(DMA_HandleTypeDef *hdma)
-{
-  return hdma->ErrorCode;
-}
-
-/**
-  * @}
-  */
-
-/**
-  * @}
-  */
-
-/** @addtogroup DMA_Private_Functions
-  * @{
-  */
-
-/**
-  * @brief  Sets the DMA Transfer parameter.
-  * @param hdma Pointer to a DMA_HandleTypeDef structure that contains
-  *                     the configuration information for the specified DMA Channel.
-  * @param SrcAddress The source memory Buffer address
-  * @param DstAddress The destination memory Buffer address
-  * @param DataLength The length of data to be transferred from source to destination
-  * @retval HAL status
-  */
-static void DMA_SetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
-{
-  /* Clear the DMAMUX synchro overrun flag */
-  hdma->DMAmuxChannelStatus->CFR = hdma->DMAmuxChannelStatusMask;
-
-  if (hdma->DMAmuxRequestGen != 0U)
-  {
-    /* Clear the DMAMUX request generator overrun flag */
-    hdma->DMAmuxRequestGenStatus->RGCFR = hdma->DMAmuxRequestGenStatusMask;
-  }
-
-  /* Clear all flags */
-  hdma->DmaBaseAddress->IFCR = (DMA_ISR_GIF1 << (hdma->ChannelIndex & 0x1cU));
-
-  /* Configure DMA Channel data length */
-  hdma->Instance->CNDTR = DataLength;
-
-  /* Memory to Peripheral */
-  if ((hdma->Init.Direction) == DMA_MEMORY_TO_PERIPH)
-  {
-    /* Configure DMA Channel destination address */
-    hdma->Instance->CPAR = DstAddress;
-
-    /* Configure DMA Channel source address */
-    hdma->Instance->CMAR = SrcAddress;
-  }
-  /* Peripheral to Memory */
-  else
-  {
-    /* Configure DMA Channel source address */
-    hdma->Instance->CPAR = SrcAddress;
-
-    /* Configure DMA Channel destination address */
-    hdma->Instance->CMAR = DstAddress;
-  }
-}
-
-/**
-  * @brief  Updates the DMA handle with the DMAMUX  channel and status mask depending on channel number
-  * @param  hdma Pointer to a DMA_HandleTypeDef structure that contains
-  *                     the configuration information for the specified DMA Channel.
-  * @retval None
-  */
-static void DMA_CalcDMAMUXChannelBaseAndMask(DMA_HandleTypeDef *hdma)
-{
-  uint32_t channel_number;
-
-  /* check if instance is not outside the DMA channel range */
-#if defined(DMA2)
-  if ((uint32_t)hdma->Instance < (uint32_t)DMA2_Channel1)
-  {
-    /* DMA1 */
-    hdma->DMAmuxChannel = (DMAMUX1_Channel0 + (hdma->ChannelIndex >> 2U));
-  }
-  else
-  {
-    /* DMA2 */
-    hdma->DMAmuxChannel = (DMAMUX1_Channel7 + (hdma->ChannelIndex >> 2U));
-  }
-#else
-  /* DMA1 */
-  hdma->DMAmuxChannel = (DMAMUX1_Channel0 + (hdma->ChannelIndex >> 2U));
-#endif
-  channel_number = (((uint32_t)hdma->Instance & 0xFFU) - 8U) / 20U;
-  hdma->DMAmuxChannelStatus = DMAMUX1_ChannelStatus;
-
-  /* Initialize the field DMAmuxChannelStatusMask with the corresponding index of the DMAMUX channel selected for the current ChannelIndex */
-  hdma->DMAmuxChannelStatusMask = 1UL << (channel_number & 0x1FU);
-}
-
-/**
-  * @brief  Updates the DMA handle with the DMAMUX  request generator params
-  * @param  hdma Pointer to a DMA_HandleTypeDef structure that contains
-  *                     the configuration information for the specified DMA Channel.
-  * @retval None
-  */
-
-static void DMA_CalcDMAMUXRequestGenBaseAndMask(DMA_HandleTypeDef *hdma)
-{
-  uint32_t request =  hdma->Init.Request & DMAMUX_CxCR_DMAREQ_ID;
-
-  /* DMA Channels are connected to DMAMUX1 request generator blocks*/
-  hdma->DMAmuxRequestGen = (DMAMUX_RequestGen_TypeDef *)((uint32_t)(((uint32_t)DMAMUX1_RequestGenerator0) + ((request - 1U) * 4U)));
-
-  hdma->DMAmuxRequestGenStatus = DMAMUX1_RequestGenStatus;
-
-  /* here "Request" is either DMA_REQUEST_GENERATOR0 to DMA_REQUEST_GENERATOR3, i.e. <= 4*/
-  hdma->DMAmuxRequestGenStatusMask = 1UL << ((request - 1U) & 0x3U);
-}
-
-/**
-  * @}
-  */
-
-/**
-  * @}
-  */
-
-#endif /* HAL_DMA_MODULE_ENABLED */
-/**
-  * @}
-  */
-
-/**
-  * @}
-  */

+ 0 - 551
non_catalog_apps/flipperscope/lib/adc/stm32wbxx_hal_gpio.c

@@ -1,551 +0,0 @@
-/**
-  ******************************************************************************
-  * @file    stm32wbxx_hal_gpio.c
-  * @author  MCD Application Team
-  * @brief   GPIO HAL module driver.
-  *          This file provides firmware functions to manage the following
-  *          functionalities of the General Purpose Input/Output (GPIO) peripheral:
-  *           + Initialization and de-initialization functions
-  *           + IO operation 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
-  ==============================================================================
-                    ##### GPIO Peripheral features #####
-  ==============================================================================
-  [..]
-    (+) Each port bit of the general-purpose I/O (GPIO) ports can be individually
-        configured by software in several modes:
-        (++) Input mode
-        (++) Analog mode
-        (++) Output mode
-        (++) Alternate function mode
-        (++) External interrupt/event lines
-
-    (+) During and just after reset, the alternate functions and external interrupt
-        lines are not active and the I/O ports are configured in input floating mode.
-
-    (+) All GPIO pins have weak internal pull-up and pull-down resistors, which can be
-        activated or not.
-
-    (+) In Output or Alternate mode, each IO can be configured on open-drain or push-pull
-        type and the IO speed can be selected depending on the VDD value.
-
-    (+) The microcontroller IO pins are connected to onboard peripherals/modules through a
-        multiplexer that allows only one peripheral alternate function (AF) connected
-       to an IO pin at a time. In this way, there can be no conflict between peripherals
-       sharing the same IO pin.
-
-    (+) All ports have external interrupt/event capability. To use external interrupt
-        lines, the port must be configured in input mode. All available GPIO pins are
-        connected to the 16 external interrupt/event lines from EXTI0 to EXTI15.
-
-    (+) The external interrupt/event controller consists of up to 28 edge detectors
-        (16 lines are connected to GPIO) for generating event/interrupt requests (each
-        input line can be independently configured to select the type (interrupt or event)
-        and the corresponding trigger event (rising or falling or both). Each line can
-        also be masked independently.
-
-                     ##### How to use this driver #####
-  ==============================================================================
-  [..]
-    (#) Enable the GPIO AHB clock using the following function: __HAL_RCC_GPIOx_CLK_ENABLE().
-
-    (#) Configure the GPIO pin(s) using HAL_GPIO_Init().
-        (++) Configure the IO mode using "Mode" member from GPIO_InitTypeDef structure
-        (++) Activate Pull-up, Pull-down resistor using "Pull" member from GPIO_InitTypeDef
-             structure.
-        (++) In case of Output or alternate function mode selection: the speed is
-             configured through "Speed" member from GPIO_InitTypeDef structure.
-        (++) In alternate mode is selection, the alternate function connected to the IO
-             is configured through "Alternate" member from GPIO_InitTypeDef structure.
-        (++) Analog mode is required when a pin is to be used as ADC channel
-             or DAC output.
-        (++) In case of external interrupt/event selection the "Mode" member from
-             GPIO_InitTypeDef structure select the type (interrupt or event) and
-             the corresponding trigger event (rising or falling or both).
-
-    (#) In case of external interrupt/event mode selection, configure NVIC IRQ priority
-        mapped to the EXTI line using HAL_NVIC_SetPriority() and enable it using
-        HAL_NVIC_EnableIRQ().
-
-    (#) To get the level of a pin configured in input mode use HAL_GPIO_ReadPin().
-
-    (#) To set/reset the level of a pin configured in output mode use
-        HAL_GPIO_WritePin()/HAL_GPIO_TogglePin().
-
-    (#) To set the level of several pins and reset level of several other pins in
-        same cycle, use HAL_GPIO_WriteMultipleStatePin().
-
-   (#) To lock pin configuration until next reset use HAL_GPIO_LockPin().
-
-    (#) During and just after reset, the alternate functions are not
-        active and the GPIO pins are configured in input floating mode (except JTAG
-        pins).
-
-    (#) The LSE oscillator pins OSC32_IN and OSC32_OUT can be used as general purpose
-        (PC14 and PC15, respectively) when the LSE oscillator is off. The LSE has
-        priority over the GPIO function.
-
-    (#) The HSE oscillator pins OSC_IN/OSC_OUT can be used as
-        general purpose PH0 and PH1, respectively, when the HSE oscillator is off.
-        The HSE has priority over the GPIO function.
-
-  @endverbatim
-  ******************************************************************************
-  */
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32wbxx_hal.h"
-
-/** @addtogroup STM32WBxx_HAL_Driver
-  * @{
-  */
-
-/** @addtogroup GPIO
-  * @{
-  */
-/** MISRA C:2012 deviation rule has been granted for following rules:
-  * Rule-12.2 - Medium: RHS argument is in interval [0,INF] which is out of
-  * range of the shift operator in following API :
-  * HAL_GPIO_Init
-  * HAL_GPIO_DeInit
-  */
-
-#ifdef HAL_GPIO_MODULE_ENABLED
-
-/* Private typedef -----------------------------------------------------------*/
-/* Private defines ------------------------------------------------------------*/
-/** @addtogroup GPIO_Private_Constants GPIO Private Constants
-  * @{
-  */
-#define GPIO_NUMBER           (16u)
-/**
-  * @}
-  */
-
-/* Private macros ------------------------------------------------------------*/
-/* Private variables ---------------------------------------------------------*/
-/* Private function prototypes -----------------------------------------------*/
-/* Exported functions --------------------------------------------------------*/
-
-/** @addtogroup GPIO_Exported_Functions
-  * @{
-  */
-
-/** @addtogroup GPIO_Exported_Functions_Group1
-  *  @brief    Initialization and Configuration functions
-  *
-@verbatim
- ===============================================================================
-              ##### Initialization and de-initialization functions #####
- ===============================================================================
-
-@endverbatim
-  * @{
-  */
-
-/**
-  * @brief  Initialize the GPIOx peripheral according to the specified parameters in the GPIO_Init.
-  * @param GPIOx where x can be (A..H) to select the GPIO peripheral for STM32WBxx family
-  * @param GPIO_Init pointer to a GPIO_InitTypeDef structure that contains
-  *         the configuration information for the specified GPIO peripheral.
-  * @retval None
-  */
-void HAL_GPIO_Init(GPIO_TypeDef  *GPIOx, GPIO_InitTypeDef *GPIO_Init)
-{
-  uint32_t position = 0x00u;
-  uint32_t iocurrent;
-  uint32_t temp;
-
-  /* Check the parameters */
-  assert_param(IS_GPIO_ALL_INSTANCE(GPIOx));
-  assert_param(IS_GPIO_PIN(GPIO_Init->Pin));
-  assert_param(IS_GPIO_MODE(GPIO_Init->Mode));
-  assert_param(IS_GPIO_PULL(GPIO_Init->Pull));
-
-  /* Configure the port pins */
-  while (((GPIO_Init->Pin) >> position) != 0x00u)
-  {
-    /* Get current io position */
-    iocurrent = (GPIO_Init->Pin) & (1uL << position);
-
-    if (iocurrent != 0x00u)
-    {
-      /*--------------------- GPIO Mode Configuration ------------------------*/
-      /* In case of Output or Alternate function mode selection */
-      if (((GPIO_Init->Mode & GPIO_MODE) == MODE_OUTPUT) || ((GPIO_Init->Mode & GPIO_MODE) == MODE_AF))
-      {
-        /* Check the Speed parameter */
-        assert_param(IS_GPIO_SPEED(GPIO_Init->Speed));
-        /* Configure the IO Speed */
-        temp = GPIOx->OSPEEDR;
-        temp &= ~(GPIO_OSPEEDR_OSPEED0 << (position * 2u));
-        temp |= (GPIO_Init->Speed << (position * 2u));
-        GPIOx->OSPEEDR = temp;
-
-        /* Configure the IO Output Type */
-        temp = GPIOx->OTYPER;
-        temp &= ~(GPIO_OTYPER_OT0 << position) ;
-        temp |= (((GPIO_Init->Mode & OUTPUT_TYPE) >> OUTPUT_TYPE_Pos) << position);
-        GPIOx->OTYPER = temp;
-      }
-
-      /* Activate the Pull-up or Pull down resistor for the current IO */
-      if ((GPIO_Init->Mode & GPIO_MODE) != MODE_ANALOG)
-      {
-        temp = GPIOx->PUPDR;
-        temp &= ~(GPIO_PUPDR_PUPD0 << (position * 2U));
-        temp |= ((GPIO_Init->Pull) << (position * 2U));
-        GPIOx->PUPDR = temp;
-      }
-
-      /* In case of Alternate function mode selection */
-      if ((GPIO_Init->Mode & GPIO_MODE) == MODE_AF)
-      {
-        /* Check the Alternate function parameters */
-        assert_param(IS_GPIO_AF_INSTANCE(GPIOx));
-        assert_param(IS_GPIO_AF(GPIO_Init->Alternate));
-
-        /* Configure Alternate function mapped with the current IO */
-        temp = GPIOx->AFR[position >> 3u];
-        temp &= ~(0xFu << ((position & 0x07u) * 4u));
-        temp |= ((GPIO_Init->Alternate) << ((position & 0x07u) * 4u));
-        GPIOx->AFR[position >> 3u] = temp;
-      }
-
-      /* Configure IO Direction mode (Input, Output, Alternate or Analog) */
-      temp = GPIOx->MODER;
-      temp &= ~(GPIO_MODER_MODE0 << (position * 2u));
-      temp |= ((GPIO_Init->Mode & GPIO_MODE) << (position * 2u));
-      GPIOx->MODER = temp;
-
-      /*--------------------- EXTI Mode Configuration ------------------------*/
-      /* Configure the External Interrupt or event for the current IO */
-      if ((GPIO_Init->Mode & EXTI_MODE) != 0x00u)
-      {
-        temp = SYSCFG->EXTICR[position >> 2u];
-        temp &= ~(0x0FuL << (4u * (position & 0x03u)));
-        temp |= (GPIO_GET_INDEX(GPIOx) << (4u * (position & 0x03u)));
-        SYSCFG->EXTICR[position >> 2u] = temp;
-
-        /* Clear Rising Falling edge configuration */
-        temp = EXTI->RTSR1;
-        temp &= ~(iocurrent);
-        if ((GPIO_Init->Mode & TRIGGER_RISING) != 0x00u)
-        {
-          temp |= iocurrent;
-        }
-        EXTI->RTSR1 = temp;
-
-        temp = EXTI->FTSR1;
-        temp &= ~(iocurrent);
-        if ((GPIO_Init->Mode & TRIGGER_FALLING) != 0x00u)
-        {
-          temp |= iocurrent;
-        }
-        EXTI->FTSR1 = temp;
-
-        /* Clear EXTI line configuration */
-        temp = EXTI->IMR1;
-        temp &= ~(iocurrent);
-        if ((GPIO_Init->Mode & EXTI_IT) != 0x00u)
-        {
-          temp |= iocurrent;
-        }
-        EXTI->IMR1 = temp;
-
-        temp = EXTI->EMR1;
-        temp &= ~(iocurrent);
-        if ((GPIO_Init->Mode & EXTI_EVT) != 0x00u)
-        {
-          temp |= iocurrent;
-        }
-        EXTI->EMR1 = temp;
-      }
-    }
-
-    position++;
-  }
-}
-
-/**
-  * @brief  De-initialize the GPIOx peripheral registers to their default reset values.
-  * @param GPIOx where x can be (A..H) to select the GPIO peripheral for STM32WBxx family
-  * @param GPIO_Pin specifies the port bit to be written.
-  *         This parameter can be one of GPIO_PIN_x where x can be (0..15).
-  * @retval None
-  */
-void HAL_GPIO_DeInit(GPIO_TypeDef  *GPIOx, uint32_t GPIO_Pin)
-{
-  uint32_t position = 0x00u;
-  uint32_t iocurrent;
-  uint32_t tmp;
-
-  /* Check the parameters */
-  assert_param(IS_GPIO_ALL_INSTANCE(GPIOx));
-  assert_param(IS_GPIO_PIN(GPIO_Pin));
-
-  /* Configure the port pins */
-  while ((GPIO_Pin >> position) != 0x00u)
-  {
-    /* Get current io position */
-    iocurrent = (GPIO_Pin) & (1uL << position);
-
-    if (iocurrent != 0x00u)
-    {
-      /*------------------------- EXTI Mode Configuration --------------------*/
-      /* Clear the External Interrupt or Event for the current IO */
-
-      tmp = SYSCFG->EXTICR[position >> 2u];
-      tmp &= (0x0FUL << (4u * (position & 0x03u)));
-      if (tmp == (GPIO_GET_INDEX(GPIOx) << (4u * (position & 0x03u))))
-      {
-        /* Clear EXTI line configuration */
-        EXTI->IMR1 &= ~(iocurrent);
-        EXTI->EMR1 &= ~(iocurrent);
-
-        /* Clear Rising Falling edge configuration */
-        EXTI->RTSR1 &= ~(iocurrent);
-        EXTI->FTSR1 &= ~(iocurrent);
-
-        tmp = 0x0FuL << (4u * (position & 0x03u));
-        SYSCFG->EXTICR[position >> 2u] &= ~tmp;
-      }
-
-      /*------------------------- GPIO Mode Configuration --------------------*/
-      /* Configure IO in Analog Mode */
-      GPIOx->MODER |= (GPIO_MODER_MODE0 << (position * 2u));
-
-      /* Configure the default Alternate Function in current IO */
-      GPIOx->AFR[position >> 3u] &= ~(0xFu << ((position & 0x07u) * 4u)) ;
-
-      /* Deactivate the Pull-up and Pull-down resistor for the current IO */
-      GPIOx->PUPDR &= ~(GPIO_PUPDR_PUPD0 << (position * 2u));
-
-      /* Configure the default value IO Output Type */
-      GPIOx->OTYPER  &= ~(GPIO_OTYPER_OT0 << position) ;
-
-      /* Configure the default value for IO Speed */
-      GPIOx->OSPEEDR &= ~(GPIO_OSPEEDR_OSPEED0 << (position * 2u));
-    }
-
-    position++;
-  }
-}
-
-/**
-  * @}
-  */
-
-/** @addtogroup GPIO_Exported_Functions_Group2
-  *  @brief GPIO Read, Write, Toggle, Lock and EXTI management functions.
-  *
-@verbatim
- ===============================================================================
-                       ##### IO operation functions #####
- ===============================================================================
-
-@endverbatim
-  * @{
-  */
-
-/**
-  * @brief  Read the specified input port pin.
-  * @param GPIOx where x can be (A..F) to select the GPIO peripheral for STM32WBxx family
-  * @param GPIO_Pin specifies the port bit to read.
-  *         This parameter can be GPIO_PIN_x where x can be (0..15).
-  * @retval The input port pin value.
-  */
-GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)
-{
-  GPIO_PinState bitstatus;
-
-  /* Check the parameters */
-  assert_param(IS_GPIO_PIN(GPIO_Pin));
-
-  if ((GPIOx->IDR & GPIO_Pin) != 0x00u)
-  {
-    bitstatus = GPIO_PIN_SET;
-  }
-  else
-  {
-    bitstatus = GPIO_PIN_RESET;
-  }
-  return bitstatus;
-}
-
-/**
-  * @brief  Set or clear the selected data port bit.
-  * @note   This function uses GPIOx_BSRR and GPIOx_BRR registers to allow atomic read/modify
-  *         accesses. In this way, there is no risk of an IRQ occurring between
-  *         the read and the modify access.
-  * @param GPIOx where x can be (A..F) to select the GPIO peripheral for STM32WBxx family
-  * @param GPIO_Pin specifies the port bit to be written.
-  *         This parameter can be one of GPIO_PIN_x where x can be (0..15).
-  * @param PinState specifies the value to be written to the selected bit.
-  *         This parameter can be one of the GPIO_PinState enum values:
-  *            @arg GPIO_PIN_RESET: to clear the port pin
-  *            @arg GPIO_PIN_SET: to set the port pin
-  * @retval None
-  */
-void HAL_GPIO_WritePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState)
-{
-  /* Check the parameters */
-  assert_param(IS_GPIO_PIN(GPIO_Pin));
-  assert_param(IS_GPIO_PIN_ACTION(PinState));
-
-  if (PinState != GPIO_PIN_RESET)
-  {
-    GPIOx->BSRR = (uint32_t)GPIO_Pin;
-  }
-  else
-  {
-    GPIOx->BRR = (uint32_t)GPIO_Pin;
-  }
-}
-
-/**
-  * @brief  Set and clear several pins of a dedicated port in same cycle.
-  * @note   This function uses GPIOx_BSRR and GPIOx_BRR registers to allow atomic read/modify
-  *         accesses.
-  * @param  GPIOx where x can be (A..F) to select the GPIO peripheral for STM32WLxx family
-  * @param  PinReset specifies the port bits to be reset
-  *         This parameter can be any combination of GPIO_Pin_x where x can be (0..15) or zero.
-  * @param  PinSet specifies the port bits to be set
-  *         This parameter can be any combination of GPIO_Pin_x where x can be (0..15) or zero.
-  * @note   Both PinReset and PinSet combinations shall not get any common bit, else
-  *         assert would be triggered.
-  * @note   At least one of the two parameters used to set or reset shall be different from zero.
-  * @retval None
-  */
-void HAL_GPIO_WriteMultipleStatePin(GPIO_TypeDef *GPIOx, uint16_t PinReset, uint16_t PinSet)
-{
-  uint32_t tmp;
-
-  /* Check the parameters */
-  /* Make sure at least one parameter is different from zero and that there is no common pin */
-  assert_param(IS_GPIO_PIN((uint32_t)PinReset | (uint32_t)PinSet));
-  assert_param(IS_GPIO_COMMON_PIN(PinReset, PinSet));
-
-  tmp = (((uint32_t)PinReset << 16) | PinSet);
-  GPIOx->BSRR = tmp;
-}
-
-/**
-  * @brief  Toggle the specified GPIO pin.
-  * @param GPIOx where x can be (A..H) to select the GPIO peripheral for STM32WBxx family
-  * @param GPIO_Pin specifies the pin to be toggled.
-  * @retval None
-  */
-void HAL_GPIO_TogglePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)
-{
-  uint32_t odr;
-
-  /* Check the parameters */
-  assert_param(IS_GPIO_PIN(GPIO_Pin));
-
-  /* get current Output Data Register value */
-  odr = GPIOx->ODR;
-
-  /* Set selected pins that were at low level, and reset ones that were high */
-  GPIOx->BSRR = ((odr & GPIO_Pin) << GPIO_NUMBER) | (~odr & GPIO_Pin);
-}
-
-/**
-  * @brief  Lock GPIO Pins configuration registers.
-  * @note   The locked registers are GPIOx_MODER, GPIOx_OTYPER, GPIOx_OSPEEDR,
-  *         GPIOx_PUPDR, GPIOx_AFRL and GPIOx_AFRH.
-  * @note   The configuration of the locked GPIO pins can no longer be modified
-  *         until the next reset.
-  * @param GPIOx where x can be (A..H) to select the GPIO peripheral for STM32WBxx family
-  * @param GPIO_Pin specifies the port bits to be locked.
-  *         This parameter can be any combination of GPIO_Pin_x where x can be (0..15).
-  * @retval None
-  */
-HAL_StatusTypeDef HAL_GPIO_LockPin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)
-{
-  __IO uint32_t tmp = GPIO_LCKR_LCKK;
-
-  /* Check the parameters */
-  assert_param(IS_GPIO_LOCK_INSTANCE(GPIOx));
-  assert_param(IS_GPIO_PIN(GPIO_Pin));
-
-  /* Apply lock key write sequence */
-  tmp |= GPIO_Pin;
-  /* Set LCKx bit(s): LCKK='1' + LCK[15-0] */
-  GPIOx->LCKR = tmp;
-  /* Reset LCKx bit(s): LCKK='0' + LCK[15-0] */
-  GPIOx->LCKR = GPIO_Pin;
-  /* Set LCKx bit(s): LCKK='1' + LCK[15-0] */
-  GPIOx->LCKR = tmp;
-  /* Read LCKK register. This read is mandatory to complete key lock sequence */
-  tmp = GPIOx->LCKR;
-
-  /* read again in order to confirm lock is active */
-  if ((GPIOx->LCKR & GPIO_LCKR_LCKK) != 0x00u)
-  {
-    return HAL_OK;
-  }
-  else
-  {
-    return HAL_ERROR;
-  }
-}
-
-/**
-  * @brief  Handle EXTI interrupt request.
-  * @param GPIO_Pin Specifies the port pin connected to corresponding EXTI line.
-  * @retval None
-  */
-void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin)
-{
-  /* EXTI line interrupt detected */
-  if (__HAL_GPIO_EXTI_GET_IT(GPIO_Pin) != 0x00u)
-  {
-    __HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin);
-    HAL_GPIO_EXTI_Callback(GPIO_Pin);
-  }
-}
-
-/**
-  * @brief  EXTI line detection callback.
-  * @param GPIO_Pin Specifies the port pin connected to corresponding EXTI line.
-  * @retval None
-  */
-__weak void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
-{
-  /* Prevent unused argument(s) compilation warning */
-  UNUSED(GPIO_Pin);
-
-  /* NOTE: This function should not be modified, when the callback is needed,
-           the HAL_GPIO_EXTI_Callback could be implemented in the user file
-   */
-}
-
-/**
-  * @}
-  */
-
-
-/**
-  * @}
-  */
-
-#endif /* HAL_GPIO_MODULE_ENABLED */
-/**
-  * @}
-  */
-
-/**
-  * @}
-  */

+ 0 - 720
non_catalog_apps/flipperscope/lib/adc/stm32wbxx_hal_pwr.c

@@ -1,720 +0,0 @@
-/**
-  ******************************************************************************
-  * @file    stm32wbxx_hal_pwr.c
-  * @author  MCD Application Team
-  * @brief   PWR HAL module driver.
-  *          This file provides firmware functions to manage the following
-  *          functionalities of the Power Controller (PWR) peripheral:
-  *           + Initialization/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.
-  *
-  ******************************************************************************
-  */
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32wbxx_hal.h"
-
-/** @addtogroup STM32WBxx_HAL_Driver
-  * @{
-  */
-
-/** @addtogroup PWR
-  * @{
-  */
-
-#ifdef HAL_PWR_MODULE_ENABLED
-
-/* Private typedef -----------------------------------------------------------*/
-/* Private define ------------------------------------------------------------*/ 
-/* Private macro -------------------------------------------------------------*/
-/* Private variables ---------------------------------------------------------*/
-/* Private constants ---------------------------------------------------------*/
-/** @addtogroup PWR_Private_Defines
-  * @{
-  */
-
-/** @defgroup PWR_Register_Reset_Values  PWR Register Reset Values
-  * @{
-  */
-/* Definitions of PWR registers reset value */
-#define PWR_CR1_RESET_VALUE   (0x00000200U)
-#define PWR_CR2_RESET_VALUE   (0x00000000U)
-#define PWR_CR3_RESET_VALUE   (0x00008000U)
-#define PWR_CR4_RESET_VALUE   (0x00000000U)
-#define PWR_CR5_RESET_VALUE   (0x00004204U)
-#define PWR_PUCRA_RESET_VALUE (0x00000000U)
-#define PWR_PDCRA_RESET_VALUE (0x00000000U)
-#define PWR_PUCRB_RESET_VALUE (0x00000000U)
-#define PWR_PDCRB_RESET_VALUE (0x00000000U)
-#define PWR_PUCRC_RESET_VALUE (0x00000000U)
-#define PWR_PDCRC_RESET_VALUE (0x00000000U)
-#define PWR_PUCRD_RESET_VALUE (0x00000000U)
-#define PWR_PDCRD_RESET_VALUE (0x00000000U)
-#define PWR_PUCRE_RESET_VALUE (0x00000000U)
-#define PWR_PDCRE_RESET_VALUE (0x00000000U)
-#define PWR_PUCRH_RESET_VALUE (0x00000000U)
-#define PWR_PDCRH_RESET_VALUE (0x00000000U)
-#define PWR_C2CR1_RESET_VALUE (0x00000000U)
-#define PWR_C2CR3_RESET_VALUE (0x00008000U)
-/**
-  * @}
-  */
-
- /**
-  * @}
-  */
-
-/* Private function prototypes -----------------------------------------------*/
-/* Exported functions --------------------------------------------------------*/
-/** @addtogroup PWR_Exported_Functions  PWR Exported Functions
-  * @{
-  */
-
-/** @addtogroup PWR_Exported_Functions_Group1  Initialization and de-initialization functions
-  * @brief  Initialization and de-initialization functions
-  *
-@verbatim
- ===============================================================================
-              ##### Initialization and de-initialization functions #####
- ===============================================================================
-    [..]
-
-@endverbatim
-  * @{
-  */
-
-/**
-  * @brief  Deinitialize the HAL PWR peripheral registers to their default reset values.
-  * @retval None
-  */
-void HAL_PWR_DeInit(void)
-{
-  /* Apply reset values to all PWR registers */
-  /* Note: Update of each register required since PWR global reset is not     */
-  /*       available at RCC level on this STM32 series.                       */
-  LL_PWR_WriteReg(CR1, PWR_CR1_RESET_VALUE);
-  LL_PWR_WriteReg(CR2, PWR_CR2_RESET_VALUE);
-  LL_PWR_WriteReg(CR3, PWR_CR3_RESET_VALUE);
-  LL_PWR_WriteReg(CR4, PWR_CR4_RESET_VALUE);
-  LL_PWR_WriteReg(CR5, PWR_CR5_RESET_VALUE);
-  LL_PWR_WriteReg(PUCRA, PWR_PUCRA_RESET_VALUE);
-  LL_PWR_WriteReg(PDCRA, PWR_PDCRA_RESET_VALUE);
-  LL_PWR_WriteReg(PUCRB, PWR_PUCRB_RESET_VALUE);
-  LL_PWR_WriteReg(PDCRB, PWR_PDCRB_RESET_VALUE);
-  LL_PWR_WriteReg(PUCRC, PWR_PUCRC_RESET_VALUE);
-  LL_PWR_WriteReg(PDCRC, PWR_PDCRC_RESET_VALUE);
-#if defined(GPIOD)
-  LL_PWR_WriteReg(PUCRD, PWR_PUCRD_RESET_VALUE);
-  LL_PWR_WriteReg(PDCRD, PWR_PDCRD_RESET_VALUE);
-#endif
-  LL_PWR_WriteReg(PUCRE, PWR_PUCRE_RESET_VALUE);
-  LL_PWR_WriteReg(PDCRE, PWR_PDCRE_RESET_VALUE);
-  LL_PWR_WriteReg(PUCRH, PWR_PUCRH_RESET_VALUE);
-  LL_PWR_WriteReg(PDCRH, PWR_PDCRH_RESET_VALUE);
-  LL_PWR_WriteReg(C2CR1, PWR_C2CR1_RESET_VALUE);
-  LL_PWR_WriteReg(C2CR3, PWR_C2CR3_RESET_VALUE);
-  
-  /* Clear all flags */
-  LL_PWR_WriteReg(SCR,
-                    LL_PWR_SCR_CC2HF
-                  | LL_PWR_SCR_CBLEAF
-                  | LL_PWR_SCR_CCRPEF
-#if defined(PWR_CR3_E802A)
-                  | LL_PWR_SCR_C802AF
-                  | LL_PWR_SCR_C802WUF
-#endif
-                  | LL_PWR_SCR_CBLEWUF
-#if defined(PWR_CR5_SMPSEN)
-                  | LL_PWR_SCR_CBORHF
-                  | LL_PWR_SCR_CSMPSFBF
-#endif
-                  | LL_PWR_SCR_CWUF
-                 );
-  
-  LL_PWR_WriteReg(EXTSCR,
-                    LL_PWR_EXTSCR_CCRPF
-                  | LL_PWR_EXTSCR_C2CSSF
-                  | LL_PWR_EXTSCR_C1CSSF
-                 );
-}
-
-
-/**
-  * @brief  Enable access to the backup domain 
-  *         (RTC registers, RTC backup data registers).
-  * @note   After reset, the backup domain is protected against 
-  *         possible unwanted write accesses.
-  * @note   RTCSEL that sets the RTC clock source selection is in the RTC back-up domain.
-  *         In order to set or modify the RTC clock, the backup domain access must be
-  *         disabled. 
-  * @note   LSEON bit that switches on and off the LSE crystal belongs as well to the
-  *         back-up domain.
-  * @retval None
-  */
-void HAL_PWR_EnableBkUpAccess(void)
-{
-  SET_BIT(PWR->CR1, PWR_CR1_DBP);
-}
-
-/**
-  * @brief  Disable access to the backup domain
-  *         (RTC registers, RTC backup data registers).
-  * @retval None
-  */
-void HAL_PWR_DisableBkUpAccess(void)
-{
-  CLEAR_BIT(PWR->CR1, PWR_CR1_DBP);
-}
-
-/**
-  * @}
-  */
-
-
-/** @addtogroup PWR_Exported_Functions_Group2  Peripheral Control functions
-  *  @brief Low Power modes configuration functions
-  *
-@verbatim
-
- ===============================================================================
-                 ##### Peripheral Control functions #####
- ===============================================================================
-
-    [..]
-     *** PVD configuration ***
-    =========================
-    [..]
-      (+) The PVD is used to monitor the VDD power supply by comparing it to a
-          threshold selected by the PVD Level (PLS[2:0] bits in PWR_CR2 register).
-      (+) PVDO flag is available to indicate if VDD/VDDA is higher or lower
-          than the PVD threshold. This event is internally connected to the EXTI
-          line16 and can generate an interrupt if enabled. This is done through
-          __HAL_PVD_EXTI_ENABLE_IT() macro.
-      (+) The PVD is stopped in Standby mode.
-
-    *** WakeUp pin configuration ***
-    ================================
-    [..]
-      (+) WakeUp pins are used to wakeup the system from Standby mode or Shutdown mode. 
-          The polarity of these pins can be set to configure event detection on high 
-          level (rising edge) or low level (falling edge).
-
-    *** Low Power modes configuration ***
-    =====================================
-    [..]
-      The devices feature 8 low-power modes:
-
-      (+) Low-power Run mode: core and peripherals are running, main regulator off, low power regulator on.
-
-      (+) Sleep mode: Cortex-M4 core stopped, peripherals kept running, main and low power regulators on.
-      (+) Low-power Sleep mode: Cortex-M4 core stopped, peripherals kept running, main regulator off, low power regulator on.
-
-      (+) Stop 0 mode: all clocks are stopped except LSI and LSE, main and low power regulators on.
-      (+) Stop 1 mode: all clocks are stopped except LSI and LSE, main regulator off, low power regulator on.
-      (+) Stop 2 mode: all clocks are stopped except LSI and LSE, main regulator off, low power regulator on, reduced set of waking up IPs compared to Stop 1 mode.
-
-      (+) Standby mode with SRAM2a: all clocks are stopped except LSI and LSE, SRAM2a content preserved, main regulator off, low power regulator on.
-          Note: On devices STM32WB15xx, STM32WB10xx, STM32WB1Mxx retention is extended to SRAM1, SRAM2a, SRAM2b.
-      (+) Standby mode without SRAM2a: all clocks are stopped except LSI and LSE, main and low power regulators off.
-
-      (+) Shutdown mode: all clocks are stopped except LSE, main and low power regulators off.
-
-
-   *** Low-power run mode ***
-   ==========================
-    [..]
-      (+) Entry: (from main run mode)
-          (++) set LPR bit with HAL_PWREx_EnableLowPowerRunMode() API after having decreased the system clock below 2 MHz. 
-      (+) Exit:
-          (++) clear LPR bit then wait for REGLP bit to be reset with HAL_PWREx_DisableLowPowerRunMode() API. Only
-               then can the system clock frequency be increased above 2 MHz.
-
-   *** Sleep mode / Low-power sleep mode ***
-   =========================================
-    [..]
-      (+) Entry:
-          The Sleep mode / Low-power Sleep mode is entered thru HAL_PWR_EnterSLEEPMode() API
-          in specifying whether or not the regulator is forced to low-power mode and if exit is interrupt or event-triggered. 
-          (++) PWR_MAINREGULATOR_ON: Sleep mode (regulator in main mode).
-          (++) PWR_LOWPOWERREGULATOR_ON: Low-power sleep (regulator in low power mode).
-          In the latter case, the system clock frequency must have been decreased below 2 MHz beforehand.
-          (++) PWR_SLEEPENTRY_WFI: enter SLEEP mode with WFI instruction
-          (++) PWR_SLEEPENTRY_WFE: enter SLEEP mode with WFE instruction
-
-      (+) WFI Exit:
-        (++) Any peripheral interrupt acknowledged by the nested vectored interrupt
-             controller (NVIC) or any wake-up event.
-
-      (+) WFE Exit:
-        (++) Any wake-up event such as an EXTI line configured in event mode.
-
-    [..]  When exiting the Low-power sleep mode by issuing an interrupt or a wakeup event, 
-          the MCU is in Low-power Run mode. 
-
-   *** Stop 0, Stop 1 and Stop 2 modes ***
-   ===============================
-    [..]
-      (+) Entry:                                                 
-          The Stop 0, Stop 1 or Stop 2 modes are entered thru the following API's:
-          (++) HAL_PWREx_EnterSTOP0Mode() for mode 0, HAL_PWREx_EnterSTOP1Mode() for mode 1, HAL_PWREx_EnterSTOP2Mode() for mode 2
-               or for porting reasons HAL_PWR_EnterSTOPMode().
-               Note: Low power Stop2 mode is not available on devices STM32WB15xx, STM32WB10xx, STM32WB1Mxx.
-
-      (+) Regulator setting (applicable to HAL_PWR_EnterSTOPMode() only):
-          (++) PWR_MAINREGULATOR_ON: Regulator in main mode (STOP0 mode)
-          (++) PWR_LOWPOWERREGULATOR_ON: Regulator in low-power mode (STOP1 mode)
-      (+) Exit (interrupt or event-triggered, specified when entering STOP mode):
-          (++) PWR_STOPENTRY_WFI: enter Stop mode with WFI instruction
-          (++) PWR_STOPENTRY_WFE: enter Stop mode with WFE instruction
-      (+) WFI Exit:
-          (++) Any EXTI Line (Internal or External) configured in Interrupt mode.
-          (++) Some specific communication peripherals (USART, LPUART, I2C) interrupts 
-               when programmed in wakeup mode. 
-      (+) WFE Exit:
-          (++) Any EXTI Line (Internal or External) configured in Event mode.
-       
-       [..]                      
-          When exiting Stop 0 and Stop 1 modes, the MCU is either in Run mode or in Low-power Run mode
-          depending on the LPR bit setting. 
-          When exiting Stop 2 mode, the MCU is in Run mode. 
-
-   *** Standby mode ***
-   ====================
-    [..] The Standby mode offers two options: 
-      (+) option a) all clocks off except LSI and LSE, RRS bit set (keeps voltage regulator in low power mode).
-          SRAM and registers contents are lost except for the SRAM2 content, the RTC registers, RTC backup registers 
-          and Standby circuitry.      
-      (+) option b) all clocks off except LSI and LSE, RRS bit cleared (voltage regulator then disabled).
-          SRAM and register contents are lost except for the RTC registers, RTC backup registers 
-          and Standby circuitry.
-
-      (++) Entry:
-          (+++) The Standby mode is entered thru HAL_PWR_EnterSTANDBYMode() API. 
-                SRAM1 and register contents are lost except for registers in the Backup domain and 
-                Standby circuitry. SRAM2 content can be preserved if the bit RRS is set in PWR_CR3 register. 
-                To enable this feature, the user can resort to HAL_PWREx_EnableBKRAMContentRetention() API
-                to set RRS bit.
-      (++) Exit:
-          (+++) WKUP pin rising edge, RTC alarm or wakeup, tamper event, time-stamp event, 
-                external reset in NRST pin, IWDG reset.
-    [..] After waking up from Standby mode, program execution restarts in the same way as after a Reset.
-          
-
-    *** Shutdown mode ***
-   ======================
-    [..]
-      In Shutdown mode, 
-        voltage regulator is disabled, all clocks are off except LSE, RRS bit is cleared.
-        SRAM and registers contents are lost except for backup domain registers.
-      (+) Entry:
-          The Shutdown mode is entered thru HAL_PWREx_EnterSHUTDOWNMode() API.
-      (+) Exit:
-          (++) WKUP pin rising edge, RTC alarm or wakeup, tamper event, time-stamp event, 
-               external reset in NRST pin.
-    [..] After waking up from Shutdown mode, program execution restarts in the same way as after a Reset.
-
-
-   *** Auto-wakeup (AWU) from low-power mode ***
-   =============================================
-    [..]
-      The MCU can be woken up from low-power mode by an RTC Alarm event, an RTC
-      Wakeup event, a tamper event or a time-stamp event, without depending on
-      an external interrupt (Auto-wakeup mode).
-
-      (+) RTC auto-wakeup (AWU) from the Stop, Standby and Shutdown modes
-  
-
-        (++) To wake up from the Stop mode with an RTC alarm event, it is necessary to
-             configure the RTC to generate the RTC alarm using the HAL_RTC_SetAlarm_IT() function.
-
-        (++) To wake up from the Stop mode with an RTC Tamper or time stamp event, it
-             is necessary to configure the RTC to detect the tamper or time stamp event using the
-             HAL_RTCEx_SetTimeStamp_IT() or HAL_RTCEx_SetTamper_IT() functions.
-
-        (++) To wake up from the Stop mode with an RTC WakeUp event, it is necessary to
-              configure the RTC to generate the RTC WakeUp event using the HAL_RTCEx_SetWakeUpTimer_IT() function.
-
-@endverbatim
-  * @{
-  */
-
-/**
-  * @brief  Configure the voltage threshold detected by the Power Voltage Detector (PVD).
-  * @param sConfigPVD pointer to a PWR_PVDTypeDef structure that contains the PVD 
-  *         configuration information.
-  * @note   Refer to the electrical characteristics of your device datasheet for
-  *         more details about the voltage thresholds corresponding to each
-  *         detection level.
-  * @note   If "sConfigPVD->Mode" is set to PVD_MODE_IT,
-  *         wake-up target is set by default to wake-up target CPU1.
-  *         To select wake-up target to CPU2, additional configuration must be
-  *         performed using macro "__HAL_PWR_PVD_EXTIC2_ENABLE_IT()"
-  *         (and optionally, to select CPU2 only (not both CPU1 and CPU2):
-  *         "__HAL_PWR_PVD_EXTI_DISABLE_IT()").
-  * @retval None
-  */
-HAL_StatusTypeDef HAL_PWR_ConfigPVD(PWR_PVDTypeDef *sConfigPVD)
-{
-  /* Check the parameters */
-  assert_param(IS_PWR_PVD_LEVEL(sConfigPVD->PVDLevel));
-  assert_param(IS_PWR_PVD_MODE(sConfigPVD->Mode));
-
-  /* Set PLS bits according to PVDLevel value */
-  MODIFY_REG(PWR->CR2, PWR_CR2_PLS, sConfigPVD->PVDLevel);
-  
-  /* Clear any previous config. Keep it clear if no event or IT mode is selected */
-  
-  /* Note: On STM32WB series, power PVD event is not available on AIEC lines   */
-  /*       (only interruption is available through AIEC line 16).             */
-  __HAL_PWR_PVD_EXTI_DISABLE_IT();      /*CPU1*/
-  __HAL_PWR_PVD_EXTIC2_DISABLE_IT();    /*CPU2*/
-    
-  __HAL_PWR_PVD_EXTI_DISABLE_RISING_EDGE();
-  __HAL_PWR_PVD_EXTI_DISABLE_FALLING_EDGE(); 
-
-  /* Configure interrupt mode */
-  if((sConfigPVD->Mode & PVD_MODE_IT) == PVD_MODE_IT)
-  {
-    /* Set CPU1 as wakeup target */
-    __HAL_PWR_PVD_EXTI_ENABLE_IT();
-  }
-  
-  /* Configure the edge */
-  if((sConfigPVD->Mode & PVD_RISING_EDGE) == PVD_RISING_EDGE)
-  {
-    __HAL_PWR_PVD_EXTI_ENABLE_RISING_EDGE();
-  }
-  
-  if((sConfigPVD->Mode & PVD_FALLING_EDGE) == PVD_FALLING_EDGE)
-  {
-    __HAL_PWR_PVD_EXTI_ENABLE_FALLING_EDGE();
-  }
-
-  return HAL_OK;
-}
-
-/**
-  * @brief Enables the Power Voltage Detector(PVD).
-  * @retval None
-  */
-void HAL_PWR_EnablePVD(void)
-{
-  /* Enable the power voltage detector */
-  SET_BIT(PWR->CR2, PWR_CR2_PVDE);
-}
-
-/**
-  * @brief Disables the Power Voltage Detector(PVD).
-  * @retval None
-  */
-void HAL_PWR_DisablePVD(void)
-{
-  /* Disable the power voltage detector */
-  CLEAR_BIT(PWR->CR2, PWR_CR2_PVDE);
-}
-
-
-/**
-  * @brief Enable the WakeUp PINx functionality.
-  * @param WakeUpPinPolarity Specifies which Wake-Up pin to enable.
-  *         This parameter can be one of the following legacy values which set the default polarity 
-  *         i.e. detection on high level (rising edge):
-  *           @arg @ref PWR_WAKEUP_PIN1, PWR_WAKEUP_PIN2, PWR_WAKEUP_PIN3, PWR_WAKEUP_PIN4, PWR_WAKEUP_PIN5
-  *             
-  *         or one of the following value where the user can explicitly specify the enabled pin and
-  *         the chosen polarity:  
-  *           @arg @ref PWR_WAKEUP_PIN1_HIGH or PWR_WAKEUP_PIN1_LOW
-  *           @arg @ref PWR_WAKEUP_PIN2_HIGH or PWR_WAKEUP_PIN2_LOW
-  *           @arg @ref PWR_WAKEUP_PIN3_HIGH or PWR_WAKEUP_PIN3_LOW
-  *           @arg @ref PWR_WAKEUP_PIN4_HIGH or PWR_WAKEUP_PIN4_LOW
-  *           @arg @ref PWR_WAKEUP_PIN5_HIGH or PWR_WAKEUP_PIN5_LOW
-  * @note  PWR_WAKEUP_PINx and PWR_WAKEUP_PINx_HIGH are equivalent.               
-  * @retval None
-  */
-void HAL_PWR_EnableWakeUpPin(uint32_t WakeUpPinPolarity)
-{
-  assert_param(IS_PWR_WAKEUP_PIN(WakeUpPinPolarity)); 
-  
-  /* Specifies the Wake-Up pin polarity for the event detection 
-    (rising or falling edge) */
-  MODIFY_REG(PWR->CR4, (PWR_CR3_EWUP & WakeUpPinPolarity), (WakeUpPinPolarity >> PWR_WUP_POLARITY_SHIFT)); 
-  
-  /* Enable wake-up pin */
-  SET_BIT(PWR->CR3, (PWR_CR3_EWUP & WakeUpPinPolarity));
-}
-
-/**
-  * @brief  Disable the WakeUp PINx functionality.
-  * @param WakeUpPinx Specifies the Power Wake-Up pin to disable.
-  *         This parameter can be one of the following values:
-  *           @arg PWR_WAKEUP_PIN1: An event on PA0   PIN wakes-up the system from Standby mode.
-  *           @arg PWR_WAKEUP_PIN2: An event on PC13  PIN wakes-up the system from Standby mode.
-  *           @arg PWR_WAKEUP_PIN3: An event on PC12  PIN wakes-up the system from Standby mode.
-  *           @arg PWR_WAKEUP_PIN4: An event on PA2   PIN wakes-up the system from Standby mode.
-  *           @arg PWR_WAKEUP_PIN5: An event on PC5   PIN wakes-up the system from Standby mode.
-  * @retval None
-  */
-void HAL_PWR_DisableWakeUpPin(uint32_t WakeUpPinx)
-{
-  assert_param(IS_PWR_WAKEUP_PIN(WakeUpPinx));
-
-  CLEAR_BIT(PWR->CR3, (PWR_CR3_EWUP & WakeUpPinx));
-}
-
-/**
-  * @brief Enter Sleep or Low-power Sleep mode.
-  * @note  In Sleep/Low-power Sleep mode, all I/O pins keep the same state as in Run mode.
-  * @param Regulator Specifies the regulator state in Sleep/Low-power Sleep mode.
-  *          This parameter can be one of the following values:
-  *            @arg @ref PWR_MAINREGULATOR_ON Sleep mode (regulator in main mode)
-  *            @arg @ref PWR_LOWPOWERREGULATOR_ON Low-power Sleep mode (regulator in low-power mode) 
-  * @note  Low-power Sleep mode is entered from Low-power Run mode. Therefore, if not yet 
-  *        in Low-power Run mode before calling HAL_PWR_EnterSLEEPMode() with Regulator set 
-  *        to PWR_LOWPOWERREGULATOR_ON, the user can optionally configure the
-  *        Flash in power-down mode in setting the SLEEP_PD bit in FLASH_ACR register.
-  *        Additionally, the clock frequency must be reduced below 2 MHz.
-  *        Setting SLEEP_PD in FLASH_ACR then appropriately reducing the clock frequency must 
-  *        be done before calling HAL_PWR_EnterSLEEPMode() API. 
-  * @note  When exiting Low-power Sleep mode, the MCU is in Low-power Run mode. To move in 
-  *        Run mode, the user must resort to HAL_PWREx_DisableLowPowerRunMode() API.
-  * @param SLEEPEntry Specifies if Sleep mode is entered with WFI or WFE instruction.
-  *           This parameter can be one of the following values:
-  *            @arg @ref PWR_SLEEPENTRY_WFI enter Sleep or Low-power Sleep mode with WFI instruction
-  *            @arg @ref PWR_SLEEPENTRY_WFE enter Sleep or Low-power Sleep mode with WFE instruction
-  * @note  When WFI entry is used, tick interrupt have to be disabled if not desired as 
-  *        the interrupt wake up source.
-  * @retval None
-  */
-void HAL_PWR_EnterSLEEPMode(uint32_t Regulator, uint8_t SLEEPEntry)
-{
-  /* Check the parameters */
-  assert_param(IS_PWR_REGULATOR(Regulator));
-  assert_param(IS_PWR_SLEEP_ENTRY(SLEEPEntry));
-
-  /* Set Regulator parameter */
-  if (Regulator == PWR_MAINREGULATOR_ON)
-  {
-    /* If in low-power run mode at this point, exit it */
-    if (HAL_IS_BIT_SET(PWR->SR2, PWR_SR2_REGLPF))
-    {
-      if (HAL_PWREx_DisableLowPowerRunMode() != HAL_OK)
-      {
-        return ;
-      }
-    } 
-    /* Regulator now in main mode. */
-  }
-  else
-  {
-    /* If in run mode, first move to low-power run mode.
-       The system clock frequency must be below 2 MHz at this point. */
-    if (HAL_IS_BIT_SET(PWR->SR2, PWR_SR2_REGLPF) == RESET)
-    {
-      HAL_PWREx_EnableLowPowerRunMode();  
-    } 
-  } 
-    
-  /* Clear SLEEPDEEP bit of Cortex System Control Register */
-  CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
-
-  /* Select SLEEP mode entry -------------------------------------------------*/
-  if(SLEEPEntry == PWR_SLEEPENTRY_WFI)
-  {
-    /* Request Wait For Interrupt */
-    __WFI();
-  }
-  else
-  {
-    /* Request Wait For Event */
-    __SEV();
-    __WFE();
-    __WFE();
-  }
-}
-
-
-/**
-  * @brief Enter Stop mode
-  * @note  This API is named HAL_PWR_EnterSTOPMode to ensure compatibility with legacy code running
-  *        on devices where only "Stop mode" is mentioned with main or low power regulator ON.
-  * @note  In Stop mode, all I/O pins keep the same state as in Run mode.
-  * @note  All clocks in the VCORE domain are stopped; the PLL, the MSI, 
-  *        the HSI and the HSE oscillators are disabled. Some peripherals with the wakeup capability 
-  *        (I2Cx, USARTx and LPUART) can switch on the HSI to receive a frame, and switch off the HSI 
-  *        after receiving the frame if it is not a wakeup frame. In this case, the HSI clock is propagated 
-  *        only to the peripheral requesting it.
-  *        SRAM1, SRAM2 and register contents are preserved.
-  *        The BOR is available.
-  *        The voltage regulator can be configured either in normal (Stop 0) or low-power mode (Stop 1).  
-  * @note  When exiting Stop 0 or Stop 1 mode by issuing an interrupt or a wakeup event,
-  *         the HSI RC oscillator is selected as system clock if STOPWUCK bit in RCC_CFGR register
-  *         is set; the MSI oscillator is selected if STOPWUCK is cleared.  
-  * @note  When the voltage regulator operates in low power mode (Stop 1), an additional
-  *         startup delay is incurred when waking up.
-  *         By keeping the internal regulator ON during Stop mode (Stop 0), the consumption
-  *         is higher although the startup time is reduced.
-  * @note  Case of Stop0 mode with SMPS: Before entering Stop 0 mode with SMPS Step Down converter enabled,
-  *        the HSI16 must be kept on by enabling HSI kernel clock (set HSIKERON register bit).
-  * @note  According to system power policy, system entering in Stop mode
-  *        is depending on other CPU power mode.
-  * @param Regulator Specifies the regulator state in Stop mode.
-  *          This parameter can be one of the following values:
-  *            @arg @ref PWR_MAINREGULATOR_ON  Stop 0 mode (main regulator ON)
-  *            @arg @ref PWR_LOWPOWERREGULATOR_ON  Stop 1 mode (low power regulator ON) 
-  * @param STOPEntry Specifies Stop 0, Stop 1 or Stop 2 mode is entered with WFI or WFE instruction.
-  *          This parameter can be one of the following values:
-  *            @arg @ref PWR_STOPENTRY_WFI  Enter Stop 0 or Stop 1 mode with WFI instruction.
-  *            @arg @ref PWR_STOPENTRY_WFE  Enter Stop 0 or Stop 1 mode with WFE instruction.
-  * @retval None
-  */
-void HAL_PWR_EnterSTOPMode(uint32_t Regulator, uint8_t STOPEntry)
-{
-  /* Check the parameters */
-  assert_param(IS_PWR_REGULATOR(Regulator));
-  
-  if(Regulator == PWR_LOWPOWERREGULATOR_ON)
-  {
-    HAL_PWREx_EnterSTOP1Mode(STOPEntry);
-  }
-  else
-  {
-    HAL_PWREx_EnterSTOP0Mode(STOPEntry);
-  }
-}
-
-
-/**
-  * @brief Enter Standby mode.
-  * @note  In Standby mode, the PLL, the HSI, the MSI and the HSE oscillators are switched 
-  *        off. The voltage regulator is disabled, except when BKRAM content is preserved
-  *        in which case the regulator is in low-power mode.
-  *        SRAM and register contents are lost except for registers in the Backup domain and
-  *        Standby circuitry. BKRAM content can be preserved if the bit RRS is set in PWR_CR3 register.
-  *        To enable this feature, the user can resort to HAL_PWREx_EnableBKRAMContentRetention() API
-  *        to set RRS bit.
-  *        The BOR is available.
-  * @note  The I/Os can be configured either with a pull-up or pull-down or can be kept in analog state.
-  *        HAL_PWREx_EnableGPIOPullUp() and HAL_PWREx_EnableGPIOPullDown() respectively enable Pull Up and
-  *        Pull Down state, HAL_PWREx_DisableGPIOPullUp() and HAL_PWREx_DisableGPIOPullDown() disable the
-  *        same.
-  *        These states are effective in Standby mode only if APC bit is set through
-  *        HAL_PWREx_EnablePullUpPullDownConfig() API.
-  * @note  According to system power policy, system entering in Standby mode
-  *        is depending on other CPU power mode.
-  * @retval None
-  */
-void HAL_PWR_EnterSTANDBYMode(void)
-{
-  /* Set Stand-by mode */
-  MODIFY_REG(PWR->CR1, PWR_CR1_LPMS, PWR_LOWPOWERMODE_STANDBY);
-
-  /* Set SLEEPDEEP bit of Cortex System Control Register */
-  SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
-
-/* This option is used to ensure that store operations are completed */
-#if defined ( __CC_ARM)
-  __force_stores();
-#endif
-
-  /* Request Wait For Interrupt */
-  __WFI();
-
-  /* Following code is executed after wake up if system did not go to STANDBY
-     mode according to system power policy */
-
-  /* Reset SLEEPDEEP bit of Cortex System Control Register */
-  CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
-}
-
-/**
-  * @brief  Indicate Sleep-On-Exit when returning from Handler mode to Thread mode. 
-  * @note   Set SLEEPONEXIT bit of SCR register. When this bit is set, the processor 
-  *         re-enters SLEEP mode when an interruption handling is over.
-  *         Setting this bit is useful when the processor is expected to run only on
-  *         interruptions handling.         
-  * @retval None
-  */
-void HAL_PWR_EnableSleepOnExit(void)
-{
-  /* Set SLEEPONEXIT bit of Cortex System Control Register */
-  SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPONEXIT_Msk));
-}
-
-/**
-  * @brief  Disable Sleep-On-Exit feature when returning from Handler mode to Thread mode. 
-  * @note   Clear SLEEPONEXIT bit of SCR register. When this bit is set, the processor 
-  *         re-enters SLEEP mode when an interruption handling is over.
-  * @retval None
-  */
-void HAL_PWR_DisableSleepOnExit(void)
-{
-  /* Clear SLEEPONEXIT bit of Cortex System Control Register */
-  CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPONEXIT_Msk));
-}
-
-
-/**
-  * @brief Enable CORTEX M4 SEVONPEND bit. 
-  * @note Set SEVONPEND bit of SCR register. When this bit is set, this causes 
-  *       WFE to wake up when an interrupt moves from inactive to pended.
-  * @retval None
-  */
-void HAL_PWR_EnableSEVOnPend(void)
-{
-  /* Set SEVONPEND bit of Cortex System Control Register */
-  SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SEVONPEND_Msk));
-}
-
-
-/**
-  * @brief Disable CORTEX M4 SEVONPEND bit. 
-  * @note Clear SEVONPEND bit of SCR register. When this bit is set, this causes 
-  *       WFE to wake up when an interrupt moves from inactive to pended.         
-  * @retval None
-  */
-void HAL_PWR_DisableSEVOnPend(void)
-{
-  /* Clear SEVONPEND bit of Cortex System Control Register */
-  CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SEVONPEND_Msk));
-}
-
-
-/**
-  * @brief  PWR PVD interrupt callback
-  * @retval None
-  */
-__weak void HAL_PWR_PVDCallback(void)
-{
-  /* NOTE : This function should not be modified; when the callback is needed,
-            the HAL_PWR_PVDCallback can be implemented in the user file
-  */
-}
-
-/**
-  * @}
-  */
-
-/**
-  * @}
-  */
-
-#endif /* HAL_PWR_MODULE_ENABLED */
-/**
-  * @}
-  */
-
-/**
-  * @}
-  */
-
-

+ 0 - 1824
non_catalog_apps/flipperscope/lib/adc/stm32wbxx_hal_rcc.c

@@ -1,1824 +0,0 @@
-/**
-  ******************************************************************************
-  * @file    stm32wbxx_hal_rcc.c
-  * @author  MCD Application Team
-  * @brief   RCC HAL module driver.
-  *          This file provides firmware functions to manage the following
-  *          functionalities of the Reset and Clock Control (RCC) peripheral:
-  *           + 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
-  ==============================================================================
-                      ##### RCC specific features #####
-  ==============================================================================
-    [..]
-      After reset the device is running from Multiple Speed Internal oscillator
-      (4 MHz) with Flash 0 wait state. Flash prefetch buffer, D-Cache
-      and I-Cache are disabled, and all peripherals are off except internal
-      SRAM, Flash and JTAG.
-
-      (+) There is no prescaler on High speed (AHBs) and Low speed (APBs) buses:
-          all peripherals mapped on these buses are running at MSI speed.
-      (+) The clock for all peripherals is switched off, except the SRAM and FLASH.
-      (+) All GPIOs are in analog mode, except the JTAG pins which
-          are assigned to be used for debug purpose.
-
-    [..]
-      Once the device started from reset, the user application has to:
-      (+) Configure the clock source to be used to drive the System clock
-          (if the application needs higher frequency/performance)
-      (+) Configure the System clock frequency and Flash settings
-      (+) Configure the AHB and APB buses prescalers
-      (+) Enable the clock for the peripheral(s) to be used
-      (+) Configure the clock source(s) for peripherals which clocks are not
-          derived from the System clock (SAI1, RTC, ADC, USB/RNG, USART1, LPUART1, LPTIMx, I2Cx, SMPS)
-
-  @endverbatim
-  ******************************************************************************
-  */
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32wbxx_hal.h"
-
-/** @addtogroup STM32WBxx_HAL_Driver
-  * @{
-  */
-
-/** @defgroup RCC RCC
-  * @brief RCC HAL module driver
-  * @{
-  */
-
-#ifdef HAL_RCC_MODULE_ENABLED
-
-/* Private typedef -----------------------------------------------------------*/
-/* Private define ------------------------------------------------------------*/
-/** @defgroup RCC_Private_Constants RCC Private Constants
-  * @{
-  */
-#define HSE_TIMEOUT_VALUE          HSE_STARTUP_TIMEOUT
-#define HSI_TIMEOUT_VALUE          (2U)    /* 2 ms (minimum Tick + 1)   */
-#define MSI_TIMEOUT_VALUE          (2U)    /* 2 ms (minimum Tick + 1)   */
-#define LSI1_TIMEOUT_VALUE         (2U)    /* 2 ms (minimum Tick + 1)   */
-#define LSI2_TIMEOUT_VALUE         (3U)    /* to be adjusted with DS    */
-#define HSI48_TIMEOUT_VALUE        (2U)    /* 2 ms (minimum Tick + 1)   */
-#define PLL_TIMEOUT_VALUE          (2U)    /* 2 ms (minimum Tick + 1)   */
-#if defined(SAI1)
-#define PLLSAI1_TIMEOUT_VALUE      (2U)    /* 2 ms (minimum Tick + 1)   */
-#endif /* SAI1 */
-#define PRESCALER_TIMEOUT_VALUE    (2U)    /* 2 ms (minimum Tick + 1)   */
-#define LATENCY_TIMEOUT_VALUE      (2U)    /* 2 ms (minimum Tick + 1)   */
-#define CLOCKSWITCH_TIMEOUT_VALUE  (5000U) /* 5 s                       */
-
-#define PLLSOURCE_NONE             (0U)
-#define MEGA_HZ                    (1000000U) /* Division factor to convert Hz in Mhz */
-/**
-  * @}
-  */
-
-/* Private macro -------------------------------------------------------------*/
-/** @defgroup RCC_Private_Macros RCC Private Macros
-  * @{
-  */
-
-#define RCC_GET_MCO_GPIO_PIN(__RCC_MCOx__)   ((__RCC_MCOx__) & GPIO_PIN_MASK)
-
-#define RCC_GET_MCO_GPIO_AF(__RCC_MCOx__)    (((__RCC_MCOx__) & RCC_MCO_GPIOAF_MASK) >> RCC_MCO_GPIOAF_POS)
-
-#define RCC_GET_MCO_GPIO_INDEX(__RCC_MCOx__) (((__RCC_MCOx__) & RCC_MCO_GPIOPORT_MASK) >> RCC_MCO_GPIOPORT_POS)
-
-#define RCC_GET_MCO_GPIO_PORT(__RCC_MCOx__)  (IOPORT_BASE + ((0x00000400UL) * RCC_GET_MCO_GPIO_INDEX((__RCC_MCOx__))))
-
-#define RCC_PLL_OSCSOURCE_CONFIG(__HAL_RCC_PLLSOURCE__) \
-  (MODIFY_REG(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC, (uint32_t)(__HAL_RCC_PLLSOURCE__)))
-
-#define __COUNTOF(_A_)   (sizeof(_A_) / sizeof(*(_A_)))
-/**
-  * @}
-  */
-
-/* Private variables ---------------------------------------------------------*/
-/** @defgroup RCC_Private_Variables RCC Private Variables
-  * @{
-  */
-
-
-/**
-  * @}
-  */
-
-/* Private function prototypes -----------------------------------------------*/
-/** @defgroup RCC_Private_Functions RCC Private Functions
-  * @{
-  */
-static HAL_StatusTypeDef RCC_SetFlashLatencyFromMSIRange(uint32_t MSI_Range);
-static HAL_StatusTypeDef RCC_SetFlashLatency(uint32_t Flash_ClkSrcFreq, uint32_t VCORE_Voltage);
-/**
-  * @}
-  */
-
-/* Exported functions --------------------------------------------------------*/
-
-/** @defgroup RCC_Exported_Functions RCC Exported Functions
-  * @{
-  */
-
-/** @defgroup RCC_Exported_Functions_Group1 Initialization and de-initialization functions
-  *  @brief    Initialization and Configuration functions
-  *
-  @verbatim
- ===============================================================================
-           ##### Initialization and de-initialization functions #####
- ===============================================================================
-    [..]
-      This section provides functions allowing to configure the internal and external oscillators
-      (HSE, HSI, LSE, MSI, LSI1, LSI2, PLL, CSS and MCO) and the System buses clocks (SYSCLK, HCLK1, HCLK2, HCLK4, PCLK1
-       and PCLK2).
-
-    [..] Internal/external clock and PLL configuration
-         (+) HSI (high-speed internal): 16 MHz factory-trimmed RC used directly or through
-             the PLL as System clock source.
-
-         (+) MSI (Multiple Speed Internal): Its frequency is software trimmable from 100KHZ to 48MHZ.
-             It can be used to generate the clock for the USB FS (48 MHz).
-             The number of flash wait states is automatically adjusted when MSI range is updated with
-             HAL_RCC_OscConfig() and the MSI is used as System clock source.
-
-         (+) LSI1/LSI2 (low-speed internal): 32 KHz low consumption RC used as IWDG and/or RTC
-             clock source.
-
-         (+) HSE (high-speed external): 32 MHz crystal oscillator used directly or
-             through the PLL as System clock source. Can be used also optionally as RTC clock source.
-
-         (+) LSE (low-speed external): 32.768 KHz oscillator used optionally as RTC clock source
-             or the RF system Auto-wakeup from Stop and Standby modes.
-
-         (+) PLL (clocked by HSI, HSE or MSI) providing up to three independent output clocks:
-           (++) The first output is used to generate the high speed system clock (up to 64MHz).
-           (++) The second output is used to generate the clock for the USB FS (48 MHz),
-                the random analog generator (<=48 MHz)
-           (++) The third output is used to generate an accurate clock to achieve
-                high-quality audio performance on SAI interface.
-
-         (+) PLLSAI1 (clocked by HSI, HSE or MSI) providing up to three independent output clocks:
-           (++) The first output is used to generate SAR ADC clock.
-           (++) The second output is used to generate the clock for the USB FS (48 MHz),
-                the random analog generator (<=48 MHz).
-           (++) The Third output is used to generate an accurate clock to achieve
-                high-quality audio performance on SAI interface.
-
-
-         (+) CSS (Clock security system): once enabled, if a HSE clock failure occurs
-            (HSE used directly or through PLL as System clock source), the System clock
-             is automatically switched to MSI or the HSI oscillator (depending on the
-             STOPWUCK configuration) and an interrupt is generated if enabled.
-             The interrupt is linked to the CPU1 and CPU2 NMI (Non-Maskable Interrupt) exception vector.
-
-         (+) LSECSS: once enabled, if a LSE clock failure occurs, the LSE
-             clock is no longer supplied to the RTC but no hardware action is made to the registers. If the
-             MSI was in PLL-mode, this mode is disabled.
-             In Standby mode a wakeup is generated. In other modes an interrupt can be sent to wakeup
-             the software
-
-         (+) MCO (microcontroller clock output): used to output MSI, LSI1, LSI2, HSI, LSE, HSE (before and
-             after stabilization), SYSCLK, HSI48 or main PLL clock (through a configurable prescaler)
-             on PA8, PB6 & PA15 pins.
-
-    [..] System, AHB and APB buses clocks configuration
-         (+) Several clock sources can be used to drive the System clock (SYSCLK): MSI, HSI,
-             HSE and main PLL.
-             The AHB clock (HCLK1) is derived from System clock through configurable
-             prescaler and used to clock the CPU, memory and peripherals mapped
-             on AHB bus (DMA, GPIO...). APB1 (PCLK1) and APB2 (PCLK2) clocks are derived
-             from AHB clock through configurable prescalers and used to clock
-             the peripherals mapped on these buses. You can use
-             HAL_RCC_GetSysClockFreq() function to retrieve the frequencies of these clocks.
-             The AHB4 clock (HCLK4) is derived from System clock through configurable
-             prescaler and used to clock the FLASH
-
-         -@- All the peripheral clocks are derived from the System clock (SYSCLK) except:
-
-           (+@) SAI: the SAI clock can be derived either from a specific PLL (PLLSAI1) or (PLLSYS) or
-                from an external clock mapped on the SAI_CKIN pin.
-                You have to use HAL_RCCEx_PeriphCLKConfig() function to configure this clock.
-           (+@) RTC: the RTC clock can be derived either from the LSI, LSE or HSE clock
-                divided by 32.
-                You have to use __HAL_RCC_RTC_ENABLE() and HAL_RCCEx_PeriphCLKConfig() function
-                to configure this clock.
-           (+@) USB FS and RNG: USB FS requires a frequency equal to 48 MHz
-                to work correctly, while RNG peripherals requires a frequency
-                equal or lower than to 48 MHz. This clock is derived of the main PLL or PLLSAI1
-                through PLLQ divider. You have to enable the peripheral clock and use
-                HAL_RCCEx_PeriphCLKConfig() function to configure this clock.
-           (+@) IWDG clock which is always the LSI clock.
-
-
-         (+) The maximum frequency of the SYSCLK, HCLK1, HCLK4, PCLK1 and PCLK2 is 64 MHz.
-             The maximum frequency of the HCLK2 is 32 MHz.
-             The clock source frequency should be adapted depending on the device voltage range
-             as listed in the Reference Manual "Clock source frequency versus voltage scaling" chapter.
-
-  @endverbatim
-
-           Table 1. HCLK4 clock frequency.
-           +-------------------------------------------------------+
-           | Latency         |    HCLK4 clock frequency (MHz)      |
-           |                 |-------------------------------------|
-           |                 | voltage range 1  | voltage range 2  |
-           |                 |      1.2 V       |     1.0 V        |
-           |-----------------|------------------|------------------|
-           |0WS(1 CPU cycles)|   HCLK4 <= 18    |   HCLK4 <= 6     |
-           |-----------------|------------------|------------------|
-           |1WS(2 CPU cycles)|   HCLK4 <= 36    |   HCLK4 <= 12    |
-           |-----------------|------------------|------------------|
-           |2WS(3 CPU cycles)|   HCLK4 <= 54    |   HCLK4 <= 16    |
-           |-----------------|------------------|------------------|
-           |3WS(4 CPU cycles)|   HCLK4 <= 64    |   HCLK4 <= n.a.  |
-           |-----------------|------------------|------------------|
-
-  * @{
-  */
-
-/**
-  * @brief  Reset the RCC clock configuration to the default reset state.
-  * @note   The default reset state of the clock configuration is given below:
-  *           - MSI ON and used as system clock source
-  *           - HSE, HSI, PLL, PLLSAI1
-  *           - HCLK1, HCLK2, HCLK4, PCLK1 and PCLK2 prescalers set to 1.
-  *           - CSS, MCO OFF
-  *           - All interrupts disabled
-  * @note   This function doesn't modify the configuration of the
-  *           - Peripheral clocks
-  *           - LSI, LSE and RTC clocks
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_RCC_DeInit(void)
-{
-  uint32_t tickstart;
-
-  /* Get Start Tick*/
-  tickstart = HAL_GetTick();
-
-  /* MSI PLL OFF */
-  LL_RCC_MSI_DisablePLLMode();
-
-  /* Set MSION bit */
-  LL_RCC_MSI_Enable();
-
-  /* Wait till MSI is ready */
-  while (LL_RCC_MSI_IsReady() == 0U)
-  {
-    if ((HAL_GetTick() - tickstart) > MSI_TIMEOUT_VALUE)
-    {
-      return HAL_TIMEOUT;
-    }
-  }
-
-  /* Set MSIRANGE default value */
-  LL_RCC_MSI_SetRange(LL_RCC_MSIRANGE_6);
-
-  /* Set MSITRIM bits to the reset value*/
-  LL_RCC_MSI_SetCalibTrimming(0);
-
-  /* Set HSITRIM bits to the reset value*/
-  LL_RCC_HSI_SetCalibTrimming(0x40U);
-
-  /* Get Start Tick*/
-  tickstart = HAL_GetTick();
-
-  /* Reset CFGR register (MSI is selected as system clock source) */
-  CLEAR_REG(RCC->CFGR);
-
-  /* Wait till MSI is ready */
-  while (READ_BIT(RCC->CFGR, RCC_CFGR_SWS) != 0U)
-  {
-    if ((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE)
-    {
-      return HAL_TIMEOUT;
-    }
-  }
-
-  /* Reset HSION, HSIKERON, HSIASFS, HSEON, PLLON, PLLSAI11ON, HSEPRE bits */
-#if defined(SAI1)
-  CLEAR_BIT(RCC->CR, RCC_CR_HSION | RCC_CR_HSIKERON | RCC_CR_HSIASFS | RCC_CR_HSEON | RCC_CR_HSEPRE | RCC_CR_PLLON |
-            RCC_CR_PLLSAI1ON);
-#else
-  CLEAR_BIT(RCC->CR, RCC_CR_HSION | RCC_CR_HSIKERON | RCC_CR_HSIASFS | RCC_CR_HSEON | RCC_CR_HSEPRE | RCC_CR_PLLON);
-#endif /* SAI1 */
-
-  /* Get Start Tick*/
-  tickstart = HAL_GetTick();
-
-  /* Wait till PLL is ready */
-  while (LL_RCC_PLL_IsReady() != 0U)
-  {
-    if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
-    {
-      return HAL_TIMEOUT;
-    }
-  }
-
-  /* once PLL is OFF, reset PLLCFGR register to default value */
-  WRITE_REG(RCC->PLLCFGR, RCC_PLLCFGR_PLLR_0 | RCC_PLLCFGR_PLLQ_0 | RCC_PLLCFGR_PLLP_1 | RCC_PLLCFGR_PLLN_0);
-
-#if defined(SAI1)
-  /* Get Start Tick*/
-  tickstart = HAL_GetTick();
-
-  /* Wait till PLL is ready */
-  while (LL_RCC_PLLSAI1_IsReady() != 0U)
-  {
-    if ((HAL_GetTick() - tickstart) > PLLSAI1_TIMEOUT_VALUE)
-    {
-      return HAL_TIMEOUT;
-    }
-  }
-  /* once PLLSAI1 is OFF, reset PLLSAI1CFGR register to default value */
-  WRITE_REG(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLR_0 | RCC_PLLSAI1CFGR_PLLQ_0 |
-            RCC_PLLSAI1CFGR_PLLP_1 | RCC_PLLSAI1CFGR_PLLN_0);
-#endif /* SAI1 */
-
-  /* Disable all interrupts */
-  CLEAR_REG(RCC->CIER);
-
-  /* Clear all interrupt flags */
-  WRITE_REG(RCC->CICR, 0xFFFFFFFFU);
-
-  /* EXTCFGR reset*/
-  LL_RCC_WriteReg(EXTCFGR, 0x00030000U);
-
-  /* Update the SystemCoreClock global variable */
-  SystemCoreClock = MSI_VALUE;
-
-  /* Adapt Systick interrupt period */
-  if (HAL_InitTick(uwTickPrio) != HAL_OK)
-  {
-    return HAL_ERROR;
-  }
-  else
-  {
-    return HAL_OK;
-  }
-}
-
-/**
-  * @brief  Initialize the RCC Oscillators according to the specified parameters in the
-  *         @ref RCC_OscInitTypeDef.
-  * @param  RCC_OscInitStruct  pointer to a @ref RCC_OscInitTypeDef structure that
-  *         contains the configuration information for the RCC Oscillators.
-  * @note   The PLL is not disabled when used as system clock.
-  * @note   The PLL source is not updated when used as PLLSAI1 clock source.
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_RCC_OscConfig(RCC_OscInitTypeDef  *RCC_OscInitStruct)
-{
-  uint32_t tickstart;
-
-  /* Check Null pointer */
-  if (RCC_OscInitStruct == NULL)
-  {
-    return HAL_ERROR;
-  }
-
-  /* Check the parameters */
-  assert_param(IS_RCC_OSCILLATORTYPE(RCC_OscInitStruct->OscillatorType));
-
-  /*----------------------------- MSI Configuration --------------------------*/
-  if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_MSI) == RCC_OSCILLATORTYPE_MSI)
-  {
-    /* Check the parameters */
-    assert_param(IS_RCC_MSI(RCC_OscInitStruct->MSIState));
-    assert_param(IS_RCC_MSICALIBRATION_VALUE(RCC_OscInitStruct->MSICalibrationValue));
-    assert_param(IS_RCC_MSI_CLOCK_RANGE(RCC_OscInitStruct->MSIClockRange));
-
-    /* When the MSI is used as system clock it will not be disabled */
-    const uint32_t temp_sysclksrc = __HAL_RCC_GET_SYSCLK_SOURCE();
-    const uint32_t temp_plloscsrc = __HAL_RCC_GET_PLL_OSCSOURCE();
-    if ((temp_sysclksrc == RCC_SYSCLKSOURCE_STATUS_MSI) ||
-        ((temp_sysclksrc == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && (temp_plloscsrc == RCC_PLLSOURCE_MSI)))
-    {
-      if (RCC_OscInitStruct->MSIState == RCC_MSI_OFF)
-      {
-        return HAL_ERROR;
-      }
-      /* Otherwise, just the calibration and MSI range change are allowed */
-      else
-      {
-        /* To correctly read data from FLASH memory, the number of wait states (LATENCY)
-           must be correctly programmed according to the frequency of the AHB4 clock
-           and the supply voltage of the device. */
-        if (RCC_OscInitStruct->MSIClockRange > __HAL_RCC_GET_MSI_RANGE())
-        {
-          /* First increase number of wait states update if necessary */
-          if (RCC_SetFlashLatencyFromMSIRange(RCC_OscInitStruct->MSIClockRange) != HAL_OK)
-          {
-            return HAL_ERROR;
-          }
-
-          /* Selects the Multiple Speed oscillator (MSI) clock range .*/
-          __HAL_RCC_MSI_RANGE_CONFIG(RCC_OscInitStruct->MSIClockRange);
-          /* Adjusts the Multiple Speed oscillator (MSI) calibration value.*/
-          __HAL_RCC_MSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->MSICalibrationValue);
-        }
-        else
-        {
-          /* Else, keep current flash latency while decreasing applies */
-          /* Selects the Multiple Speed oscillator (MSI) clock range .*/
-          __HAL_RCC_MSI_RANGE_CONFIG(RCC_OscInitStruct->MSIClockRange);
-          /* Adjusts the Multiple Speed oscillator (MSI) calibration value.*/
-          __HAL_RCC_MSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->MSICalibrationValue);
-
-          /* Decrease number of wait states update if necessary */
-          if (RCC_SetFlashLatencyFromMSIRange(RCC_OscInitStruct->MSIClockRange) != HAL_OK)
-          {
-            return HAL_ERROR;
-          }
-        }
-
-        /* Update the SystemCoreClock global variable */
-        SystemCoreClock = HAL_RCC_GetHCLKFreq();
-
-        if (HAL_InitTick(uwTickPrio) != HAL_OK)
-        {
-          return HAL_ERROR;
-        }
-      }
-    }
-    else
-    {
-      /* Check the MSI State */
-      if (RCC_OscInitStruct->MSIState != RCC_MSI_OFF)
-      {
-        /* Enable the Internal High Speed oscillator (MSI). */
-        __HAL_RCC_MSI_ENABLE();
-
-        /* Get timeout */
-        tickstart = HAL_GetTick();
-
-        /* Wait till MSI is ready */
-        while (LL_RCC_MSI_IsReady() == 0U)
-        {
-          if ((HAL_GetTick() - tickstart) > MSI_TIMEOUT_VALUE)
-          {
-            return HAL_TIMEOUT;
-          }
-        }
-
-        /* Selects the Multiple Speed oscillator (MSI) clock range .*/
-        __HAL_RCC_MSI_RANGE_CONFIG(RCC_OscInitStruct->MSIClockRange);
-        /* Adjusts the Multiple Speed oscillator (MSI) calibration value.*/
-        __HAL_RCC_MSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->MSICalibrationValue);
-
-      }
-      else
-      {
-        /* Disable the Internal High Speed oscillator (MSI). */
-        __HAL_RCC_MSI_DISABLE();
-
-        /* Get timeout */
-        tickstart = HAL_GetTick();
-
-        /* Wait till MSI is disabled */
-        while (LL_RCC_MSI_IsReady() != 0U)
-        {
-          if ((HAL_GetTick() - tickstart) > MSI_TIMEOUT_VALUE)
-          {
-            return HAL_TIMEOUT;
-          }
-        }
-      }
-    }
-  }
-
-  /*------------------------------- HSE Configuration ------------------------*/
-  if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSE) == RCC_OSCILLATORTYPE_HSE)
-  {
-    /* Check the parameters */
-    assert_param(IS_RCC_HSE(RCC_OscInitStruct->HSEState));
-
-    /* When the HSE is used as system clock or clock source for PLL in these cases it is not allowed to be disabled */
-    const uint32_t temp_sysclksrc = __HAL_RCC_GET_SYSCLK_SOURCE();
-    const uint32_t temp_plloscsrc = __HAL_RCC_GET_PLL_OSCSOURCE();
-    if ((temp_sysclksrc == RCC_SYSCLKSOURCE_STATUS_HSE) ||
-        ((temp_sysclksrc == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && (temp_plloscsrc == RCC_PLLSOURCE_HSE)))
-    {
-      if (RCC_OscInitStruct->HSEState == RCC_HSE_OFF)
-      {
-        return HAL_ERROR;
-      }
-    }
-    else
-    {
-      /* Set the new HSE configuration ---------------------------------------*/
-      __HAL_RCC_HSE_CONFIG(RCC_OscInitStruct->HSEState);
-
-      /* Check the HSE State */
-      if (RCC_OscInitStruct->HSEState != RCC_HSE_OFF)
-      {
-        /* Get Start Tick*/
-        tickstart = HAL_GetTick();
-
-        /* Wait till HSE is ready */
-        while (LL_RCC_HSE_IsReady() == 0U)
-        {
-          if ((HAL_GetTick() - tickstart) > HSE_TIMEOUT_VALUE)
-          {
-            return HAL_TIMEOUT;
-          }
-        }
-      }
-      else
-      {
-        /* Get Start Tick*/
-        tickstart = HAL_GetTick();
-
-        /* Wait till HSE is disabled */
-        while (LL_RCC_HSE_IsReady() != 0U)
-        {
-          if ((HAL_GetTick() - tickstart) > HSE_TIMEOUT_VALUE)
-          {
-            return HAL_TIMEOUT;
-          }
-        }
-      }
-    }
-  }
-
-  /*----------------------------- HSI Configuration --------------------------*/
-  if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSI) == RCC_OSCILLATORTYPE_HSI)
-  {
-    /* Check the parameters */
-    assert_param(IS_RCC_HSI(RCC_OscInitStruct->HSIState));
-    assert_param(IS_RCC_HSI_CALIBRATION_VALUE(RCC_OscInitStruct->HSICalibrationValue));
-
-    /* Check if HSI is used as system clock or as PLL source when PLL is selected as system clock */
-    const uint32_t temp_sysclksrc = __HAL_RCC_GET_SYSCLK_SOURCE();
-    const uint32_t temp_plloscsrc = __HAL_RCC_GET_PLL_OSCSOURCE();
-    if ((temp_sysclksrc == RCC_SYSCLKSOURCE_STATUS_HSI) ||
-        ((temp_sysclksrc == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && (temp_plloscsrc == RCC_PLLSOURCE_HSI)))
-    {
-      /* When HSI is used as system clock it will not be disabled */
-      if (RCC_OscInitStruct->HSIState == RCC_HSI_OFF)
-      {
-        return HAL_ERROR;
-      }
-      /* Otherwise, just the calibration is allowed */
-      else
-      {
-        /* Adjusts the Internal High Speed oscillator (HSI) calibration value.*/
-        __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSICalibrationValue);
-      }
-    }
-    else
-    {
-      /* Check the HSI State */
-      if (RCC_OscInitStruct->HSIState != RCC_HSI_OFF)
-      {
-        /* Enable the Internal High Speed oscillator (HSI). */
-        __HAL_RCC_HSI_ENABLE();
-
-        /* Get Start Tick*/
-        tickstart = HAL_GetTick();
-
-        /* Wait till HSI is ready */
-        while (LL_RCC_HSI_IsReady() == 0U)
-        {
-          if ((HAL_GetTick() - tickstart) > HSI_TIMEOUT_VALUE)
-          {
-            return HAL_TIMEOUT;
-          }
-        }
-
-        /* Adjusts the Internal High Speed oscillator (HSI) calibration value.*/
-        __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSICalibrationValue);
-      }
-      else
-      {
-        /* Disable the Internal High Speed oscillator (HSI). */
-        __HAL_RCC_HSI_DISABLE();
-
-        /* Get Start Tick*/
-        tickstart = HAL_GetTick();
-
-        /* Wait till HSI is disabled */
-        while (LL_RCC_HSI_IsReady() != 0U)
-        {
-          if ((HAL_GetTick() - tickstart) > HSI_TIMEOUT_VALUE)
-          {
-            return HAL_TIMEOUT;
-          }
-        }
-      }
-    }
-  }
-  /*------------------------------ LSI Configuration (LSI1 or LSI2) -------------------------*/
-
-  if ((((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSI1) == RCC_OSCILLATORTYPE_LSI1) || \
-      (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSI2) == RCC_OSCILLATORTYPE_LSI2))
-  {
-    /* Check the parameters */
-    assert_param(IS_RCC_LSI(RCC_OscInitStruct->LSIState));
-
-    /* Check the LSI State */
-    if (RCC_OscInitStruct->LSIState != RCC_LSI_OFF)
-    {
-      /*------------------------------ LSI2 selected by default (when Switch ON) -------------------------*/
-      if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSI2) == RCC_OSCILLATORTYPE_LSI2)
-      {
-        assert_param(IS_RCC_LSI2_CALIBRATION_VALUE(RCC_OscInitStruct->LSI2CalibrationValue));
-
-        /* 1. Check LSI1 state and enable if required */
-        if (LL_RCC_LSI1_IsReady() == 0U)
-        {
-          /* This is required to enable LSI1 before enabling LSI2 */
-          __HAL_RCC_LSI1_ENABLE();
-
-          /* Get Start Tick*/
-          tickstart = HAL_GetTick();
-
-          /* Wait till LSI1 is ready */
-          while (LL_RCC_LSI1_IsReady() == 0U)
-          {
-            if ((HAL_GetTick() - tickstart) > LSI1_TIMEOUT_VALUE)
-            {
-              return HAL_TIMEOUT;
-            }
-          }
-        }
-
-        /* 2. Enable the Internal Low Speed oscillator (LSI2) and set trimming value */
-        __HAL_RCC_LSI2_ENABLE();
-
-        /* Get Start Tick*/
-        tickstart = HAL_GetTick();
-
-        /* Wait till LSI2 is ready */
-        while (LL_RCC_LSI2_IsReady() == 0U)
-        {
-          if ((HAL_GetTick() - tickstart) > LSI2_TIMEOUT_VALUE)
-          {
-            return HAL_TIMEOUT;
-          }
-        }
-        /* Adjusts the Internal Low Spee oscillator (LSI2) calibration value */
-        __HAL_RCC_LSI2_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->LSI2CalibrationValue);
-
-        /* 3. Disable LSI1 */
-
-        /* LSI1 was initially not enable, require to disable it */
-        __HAL_RCC_LSI1_DISABLE();
-
-        /* Get Start Tick*/
-        tickstart = HAL_GetTick();
-
-        /* Wait till LSI1 is disabled */
-        while (LL_RCC_LSI1_IsReady() != 0U)
-        {
-          if ((HAL_GetTick() - tickstart) > LSI1_TIMEOUT_VALUE)
-          {
-            return HAL_TIMEOUT;
-          }
-        }
-      }
-      else
-      {
-        /*------------------------------ LSI1 selected (only if LSI2 OFF)-------------------------*/
-
-        /* 1. Enable the Internal Low Speed oscillator (LSI1). */
-        __HAL_RCC_LSI1_ENABLE();
-
-        /* Get Start Tick*/
-        tickstart = HAL_GetTick();
-
-        /* Wait till LSI1 is ready */
-        while (LL_RCC_LSI1_IsReady() == 0U)
-        {
-          if ((HAL_GetTick() - tickstart) > LSI1_TIMEOUT_VALUE)
-          {
-            return HAL_TIMEOUT;
-          }
-        }
-        /*2. Switch OFF LSI2*/
-
-        /* Disable the Internal Low Speed oscillator (LSI2). */
-        __HAL_RCC_LSI2_DISABLE();
-
-        /* Wait till LSI2 is disabled */
-        while (LL_RCC_LSI2_IsReady() != 0U)
-        {
-          if ((HAL_GetTick() - tickstart) > LSI2_TIMEOUT_VALUE)
-          {
-            return HAL_TIMEOUT;
-          }
-        }
-      }
-    }
-    else
-    {
-
-      /* Disable the Internal Low Speed oscillator (LSI2). */
-      __HAL_RCC_LSI2_DISABLE();
-
-      /* Get Start Tick*/
-      tickstart = HAL_GetTick();
-
-      /* Wait till LSI2 is disabled */
-      while (LL_RCC_LSI2_IsReady() != 0U)
-      {
-        if ((HAL_GetTick() - tickstart) > LSI2_TIMEOUT_VALUE)
-        {
-          return HAL_TIMEOUT;
-        }
-      }
-
-      /* Disable the Internal Low Speed oscillator (LSI1). */
-      __HAL_RCC_LSI1_DISABLE();
-
-      /* Get Start Tick*/
-      tickstart = HAL_GetTick();
-
-      /* Wait till LSI1 is disabled */
-      while (LL_RCC_LSI1_IsReady() != 0U)
-      {
-        if ((HAL_GetTick() - tickstart) > LSI1_TIMEOUT_VALUE)
-        {
-          return HAL_TIMEOUT;
-        }
-      }
-    }
-  }
-
-  /*------------------------------ LSE Configuration -------------------------*/
-  if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSE) == RCC_OSCILLATORTYPE_LSE)
-  {
-    /* Check the parameters */
-    assert_param(IS_RCC_LSE(RCC_OscInitStruct->LSEState));
-
-    /* Update LSE configuration in Backup Domain control register    */
-    /* Requires to enable write access to Backup Domain of necessary */
-
-    if (HAL_IS_BIT_CLR(PWR->CR1, PWR_CR1_DBP))
-    {
-      /* Enable write access to Backup domain */
-      HAL_PWR_EnableBkUpAccess();
-
-      /* Wait for Backup domain Write protection disable */
-      tickstart = HAL_GetTick();
-
-      while (HAL_IS_BIT_CLR(PWR->CR1, PWR_CR1_DBP))
-      {
-        if ((HAL_GetTick() - tickstart) > RCC_DBP_TIMEOUT_VALUE)
-        {
-          return HAL_TIMEOUT;
-        }
-      }
-    }
-
-    /* Set the new LSE configuration -----------------------------------------*/
-    __HAL_RCC_LSE_CONFIG(RCC_OscInitStruct->LSEState);
-
-    /* Check the LSE State */
-    if (RCC_OscInitStruct->LSEState != RCC_LSE_OFF)
-    {
-      /* Get Start Tick*/
-      tickstart = HAL_GetTick();
-
-      /* Wait till LSE is ready */
-      while (LL_RCC_LSE_IsReady() == 0U)
-      {
-        if ((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE)
-        {
-          return HAL_TIMEOUT;
-        }
-      }
-    }
-    else
-    {
-      /* Get Start Tick*/
-      tickstart = HAL_GetTick();
-
-      /* Wait till LSE is disabled */
-      while (LL_RCC_LSE_IsReady() != 0U)
-      {
-        if ((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE)
-        {
-          return HAL_TIMEOUT;
-        }
-      }
-    }
-
-  }
-#if defined(RCC_HSI48_SUPPORT)
-  /*------------------------------ HSI48 Configuration -----------------------*/
-  if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSI48) == RCC_OSCILLATORTYPE_HSI48)
-  {
-    /* Check the parameters */
-    assert_param(IS_RCC_HSI48(RCC_OscInitStruct->HSI48State));
-
-    /* Check the HSI State */
-    if (RCC_OscInitStruct->HSI48State != RCC_HSI48_OFF)
-    {
-      /* Enable the Internal Low Speed oscillator (HSI48). */
-      __HAL_RCC_HSI48_ENABLE();
-
-      /* Get Start Tick*/
-      tickstart = HAL_GetTick();
-
-      /* Wait till HSI48 is ready */
-      while (LL_RCC_HSI48_IsReady() == 0U)
-      {
-        if ((HAL_GetTick() - tickstart) > HSI48_TIMEOUT_VALUE)
-        {
-          return HAL_TIMEOUT;
-        }
-      }
-    }
-    else
-    {
-      /* Disable the Internal Low Speed oscillator (HSI48). */
-      __HAL_RCC_HSI48_DISABLE();
-
-      /* Get Start Tick*/
-      tickstart = HAL_GetTick();
-
-      /* Wait till HSI48 is disabled */
-      while (LL_RCC_HSI48_IsReady() != 0U)
-      {
-        if ((HAL_GetTick() - tickstart) > HSI48_TIMEOUT_VALUE)
-        {
-          return HAL_TIMEOUT;
-        }
-      }
-    }
-  }
-#endif /* RCC_HSI48_SUPPORT */
-  /*-------------------------------- PLL Configuration -----------------------*/
-  /* Check the parameters */
-  assert_param(IS_RCC_PLL(RCC_OscInitStruct->PLL.PLLState));
-
-  if (RCC_OscInitStruct->PLL.PLLState != RCC_PLL_NONE)
-  {
-    const uint32_t temp_sysclksrc = __HAL_RCC_GET_SYSCLK_SOURCE();
-    const uint32_t temp_pllconfig = RCC->PLLCFGR;
-
-    /* PLL On ? */
-    if (RCC_OscInitStruct->PLL.PLLState == RCC_PLL_ON)
-    {
-      /* Check the parameters */
-      assert_param(IS_RCC_PLLSOURCE(RCC_OscInitStruct->PLL.PLLSource));
-      assert_param(IS_RCC_PLLM_VALUE(RCC_OscInitStruct->PLL.PLLM));
-      assert_param(IS_RCC_PLLN_VALUE(RCC_OscInitStruct->PLL.PLLN));
-      assert_param(IS_RCC_PLLP_VALUE(RCC_OscInitStruct->PLL.PLLP));
-      assert_param(IS_RCC_PLLQ_VALUE(RCC_OscInitStruct->PLL.PLLQ));
-      assert_param(IS_RCC_PLLR_VALUE(RCC_OscInitStruct->PLL.PLLR));
-
-      /* Do nothing if PLL configuration is unchanged */
-      if ((READ_BIT(temp_pllconfig, RCC_PLLCFGR_PLLSRC) != RCC_OscInitStruct->PLL.PLLSource) ||
-          (READ_BIT(temp_pllconfig, RCC_PLLCFGR_PLLM) != RCC_OscInitStruct->PLL.PLLM) ||
-          ((READ_BIT(temp_pllconfig, RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos) != RCC_OscInitStruct->PLL.PLLN) ||
-          (READ_BIT(temp_pllconfig, RCC_PLLCFGR_PLLP) != RCC_OscInitStruct->PLL.PLLP) ||
-          (READ_BIT(temp_pllconfig, RCC_PLLCFGR_PLLQ) != RCC_OscInitStruct->PLL.PLLQ) ||
-          (READ_BIT(temp_pllconfig, RCC_PLLCFGR_PLLR) != RCC_OscInitStruct->PLL.PLLR))
-      {
-        /* Check if the PLL is used as system clock or not */
-        if (temp_sysclksrc != RCC_SYSCLKSOURCE_STATUS_PLLCLK)
-        {
-#if defined(SAI1)
-          /* Check if main PLL can be updated */
-          /* Not possible if the source is shared by other enabled PLLSAIx */
-          if (READ_BIT(RCC->CR, RCC_CR_PLLSAI1ON) != 0U)
-
-          {
-            return HAL_ERROR;
-          }
-          else
-#endif /* SAI1 */
-          {
-            /* Disable the main PLL. */
-            __HAL_RCC_PLL_DISABLE();
-
-            /* Get Start Tick*/
-            tickstart = HAL_GetTick();
-
-            /* Wait till PLL is ready */
-            while (READ_BIT(RCC->CR, RCC_CR_PLLRDY) != 0U)
-            {
-              if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
-              {
-                return HAL_TIMEOUT;
-              }
-            }
-
-            /* Configure the main PLL clock source, multiplication and division factors. */
-            __HAL_RCC_PLL_CONFIG(RCC_OscInitStruct->PLL.PLLSource,
-                                 RCC_OscInitStruct->PLL.PLLM,
-                                 RCC_OscInitStruct->PLL.PLLN,
-                                 RCC_OscInitStruct->PLL.PLLP,
-                                 RCC_OscInitStruct->PLL.PLLQ,
-                                 RCC_OscInitStruct->PLL.PLLR);
-
-            /* Enable the main PLL. */
-            __HAL_RCC_PLL_ENABLE();
-
-            /* Enable PLL System Clock output. */
-            __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_SYSCLK);
-
-            /* Get Start Tick*/
-            tickstart = HAL_GetTick();
-
-            /* Wait till PLL is ready */
-            while (READ_BIT(RCC->CR, RCC_CR_PLLRDY) == 0U)
-            {
-              if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
-              {
-                return HAL_TIMEOUT;
-              }
-            }
-          }
-        }
-        else
-        {
-          /* PLL is already used as System core clock */
-          return HAL_ERROR;
-        }
-      }
-      else
-      {
-        /* PLL configuration is unchanged */
-        /* Re-enable PLL if it was disabled (ie. low power mode) */
-        if (READ_BIT(RCC->CR, RCC_CR_PLLRDY) == 0U)
-        {
-          /* Enable the main PLL. */
-          __HAL_RCC_PLL_ENABLE();
-
-          /* Enable PLL System Clock output. */
-          __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_SYSCLK);
-
-          /* Get Start Tick*/
-          tickstart = HAL_GetTick();
-
-          /* Wait till PLL is ready */
-          while (READ_BIT(RCC->CR, RCC_CR_PLLRDY) == 0U)
-          {
-            if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
-            {
-              return HAL_TIMEOUT;
-            }
-          }
-        }
-      }
-    }
-    else
-    {
-      /* Check that PLL is not used as system clock or not */
-      if (temp_sysclksrc != RCC_SYSCLKSOURCE_STATUS_PLLCLK)
-      {
-        /* Disable the main PLL. */
-        __HAL_RCC_PLL_DISABLE();
-
-        /* Get Start Tick*/
-        tickstart = HAL_GetTick();
-
-        /* Wait till PLL is disabled */
-        while (READ_BIT(RCC->CR, RCC_CR_PLLRDY) != 0U)
-        {
-          if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
-          {
-            return HAL_TIMEOUT;
-          }
-        }
-
-        /* Disable the PLL source and outputs to save power when PLL is off */
-#if defined(SAI1) && defined(USB)
-        CLEAR_BIT(RCC->PLLCFGR, (RCC_PLLCFGR_PLLSRC | RCC_PLLCFGR_PLLPEN | RCC_PLLCFGR_PLLQEN | RCC_PLLCFGR_PLLREN));
-#else
-        CLEAR_BIT(RCC->PLLCFGR, (RCC_PLLCFGR_PLLSRC | RCC_PLLCFGR_PLLREN));
-#endif /* SAI1 && USB */
-      }
-      else
-      {
-        /* PLL is already used as System core clock */
-        return HAL_ERROR;
-      }
-    }
-  }
-  return HAL_OK;
-}
-
-
-/**
-  * @brief  Initialize the CPU, AHB and APB buses clocks according to the specified
-  *         parameters in the RCC_ClkInitStruct.
-  * @param  RCC_ClkInitStruct  pointer to a @ref RCC_ClkInitTypeDef structure that
-  *         contains the configuration information for the RCC peripheral.
-  * @param  FLatency  FLASH Latency
-  *          This parameter can be one of the following values:
-  *            @arg FLASH_LATENCY_0   FLASH 0 Latency cycle
-  *            @arg FLASH_LATENCY_1   FLASH 1 Latency cycle
-  *            @arg FLASH_LATENCY_2   FLASH 2 Latency cycle
-  *            @arg FLASH_LATENCY_3   FLASH 3 Latency cycle
-  *
-  * @note   The SystemCoreClock CMSIS variable is used to store System Clock Frequency
-  *         and updated by @ref HAL_RCC_GetHCLKFreq() function called within this function
-  *
-  * @note   The MSI is used by default as system clock source after
-  *         startup from Reset, wake-up from STANDBY mode. After restart from Reset,
-  *         the MSI frequency is set to its default value 4 MHz.
-  *
-  * @note   The HSI can be selected as system clock source after
-  *         from STOP modes or in case of failure of the HSE used directly or indirectly
-  *         as system clock (if the Clock Security System CSS is enabled).
-  *
-  * @note   A switch from one clock source to another occurs only if the target
-  *         clock source is ready (clock stable after startup delay or PLL locked).
-  *         If a clock source which is not yet ready is selected, the switch will
-  *         occur when the clock source is ready.
-  *
-  * @note   You can use @ref HAL_RCC_GetClockConfig() function to know which clock is
-  *         currently used as system clock source.
-  *
-  * @note   Depending on the device voltage range, the software has to set correctly
-  *         HPRE[3:0] bits to ensure that HCLK1 not exceed the maximum allowed frequency
-  *         (for more details refer to section above "Initialization/de-initialization functions")
-  * @retval None
-  */
-HAL_StatusTypeDef HAL_RCC_ClockConfig(RCC_ClkInitTypeDef  *RCC_ClkInitStruct, uint32_t FLatency)
-{
-  uint32_t tickstart;
-
-  /* Check Null pointer */
-  if (RCC_ClkInitStruct == NULL)
-  {
-    return HAL_ERROR;
-  }
-
-  /* Check the parameters */
-  assert_param(IS_RCC_CLOCKTYPE(RCC_ClkInitStruct->ClockType));
-  assert_param(IS_FLASH_LATENCY(FLatency));
-
-  /* To correctly read data from FLASH memory, the number of wait states (LATENCY)
-    must be correctly programmed according to the frequency of the FLASH clock
-    (HCLK4) and the supply voltage of the device. */
-
-  /* Increasing the number of wait states because of higher CPU frequency */
-  if (FLatency > __HAL_FLASH_GET_LATENCY())
-  {
-    /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */
-    __HAL_FLASH_SET_LATENCY(FLatency);
-
-    /* Get Start Tick*/
-    tickstart = HAL_GetTick();
-
-    /* Check that the new number of wait states is taken into account to access the Flash
-       memory by reading the FLASH_ACR register */
-    while (__HAL_FLASH_GET_LATENCY() != FLatency)
-    {
-      if ((HAL_GetTick() - tickstart) > LATENCY_TIMEOUT_VALUE)
-      {
-        return HAL_TIMEOUT;
-      }
-    }
-  }
-
-  /*-------------------------- HCLK1 Configuration --------------------------*/
-  if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_HCLK) == RCC_CLOCKTYPE_HCLK)
-  {
-    assert_param(IS_RCC_HCLKx(RCC_ClkInitStruct->AHBCLKDivider));
-    LL_RCC_SetAHBPrescaler(RCC_ClkInitStruct->AHBCLKDivider);
-
-    /* HCLK1 prescaler flag when value applied */
-    tickstart = HAL_GetTick();
-    while (LL_RCC_IsActiveFlag_HPRE() == 0U)
-    {
-      if ((HAL_GetTick() - tickstart) > PRESCALER_TIMEOUT_VALUE)
-      {
-        return HAL_TIMEOUT;
-      }
-    }
-  }
-
-  /*-------------------------- HCLK2 Configuration --------------------------*/
-  if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_HCLK2) == RCC_CLOCKTYPE_HCLK2)
-  {
-    assert_param(IS_RCC_HCLKx(RCC_ClkInitStruct->AHBCLK2Divider));
-    LL_C2_RCC_SetAHBPrescaler(RCC_ClkInitStruct->AHBCLK2Divider);
-
-    /* HCLK2 prescaler flag when value applied */
-    tickstart = HAL_GetTick();
-    while (LL_RCC_IsActiveFlag_C2HPRE() == 0U)
-    {
-      if ((HAL_GetTick() - tickstart) > PRESCALER_TIMEOUT_VALUE)
-      {
-        return HAL_TIMEOUT;
-      }
-    }
-  }
-  /*-------------------------- HCLK4 Configuration --------------------------*/
-  if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_HCLK4) == RCC_CLOCKTYPE_HCLK4)
-  {
-    assert_param(IS_RCC_HCLKx(RCC_ClkInitStruct->AHBCLK4Divider));
-    LL_RCC_SetAHB4Prescaler(RCC_ClkInitStruct->AHBCLK4Divider);
-
-    /* AHB shared prescaler flag when value applied */
-    tickstart = HAL_GetTick();
-    while (LL_RCC_IsActiveFlag_SHDHPRE() == 0U)
-    {
-      if ((HAL_GetTick() - tickstart) > PRESCALER_TIMEOUT_VALUE)
-      {
-        return HAL_TIMEOUT;
-      }
-    }
-  }
-
-  /*-------------------------- PCLK1 Configuration ---------------------------*/
-  if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK1) == RCC_CLOCKTYPE_PCLK1)
-  {
-    assert_param(IS_RCC_PCLKx(RCC_ClkInitStruct->APB1CLKDivider));
-    LL_RCC_SetAPB1Prescaler(RCC_ClkInitStruct->APB1CLKDivider);
-
-    /* APB1 prescaler flag when value applied */
-    tickstart = HAL_GetTick();
-    while (LL_RCC_IsActiveFlag_PPRE1() == 0U)
-    {
-      if ((HAL_GetTick() - tickstart) > PRESCALER_TIMEOUT_VALUE)
-      {
-        return HAL_TIMEOUT;
-      }
-    }
-  }
-
-  /*-------------------------- PCLK2 Configuration ---------------------------*/
-  if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK2) == RCC_CLOCKTYPE_PCLK2)
-  {
-    assert_param(IS_RCC_PCLKx(RCC_ClkInitStruct->APB2CLKDivider));
-    LL_RCC_SetAPB2Prescaler((RCC_ClkInitStruct->APB2CLKDivider) << 3U);
-
-    /* APB2 prescaler flag when value applied */
-    tickstart = HAL_GetTick();
-    while (LL_RCC_IsActiveFlag_PPRE2() == 0U)
-    {
-      if ((HAL_GetTick() - tickstart) > PRESCALER_TIMEOUT_VALUE)
-      {
-        return HAL_TIMEOUT;
-      }
-    }
-  }
-
-  /*------------------------- SYSCLK Configuration ---------------------------*/
-  if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_SYSCLK) == RCC_CLOCKTYPE_SYSCLK)
-  {
-    assert_param(IS_RCC_SYSCLKSOURCE(RCC_ClkInitStruct->SYSCLKSource));
-
-    /* HSE is selected as System Clock Source */
-    if (RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSE)
-    {
-      /* Check the HSE ready flag */
-      if (LL_RCC_HSE_IsReady() == 0U)
-      {
-        return HAL_ERROR;
-      }
-    }
-    /* PLL is selected as System Clock Source */
-    else if (RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_PLLCLK)
-    {
-      /* Check the PLL ready flag */
-      if (LL_RCC_PLL_IsReady() == 0U)
-      {
-        return HAL_ERROR;
-      }
-    }
-    /* MSI is selected as System Clock Source */
-    else if (RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_MSI)
-    {
-      /* Check the MSI ready flag */
-      if (LL_RCC_MSI_IsReady() == 0U)
-      {
-        return HAL_ERROR;
-      }
-    }
-    /* HSI is selected as System Clock Source */
-    else
-    {
-      /* Check the HSI ready flag */
-      if (LL_RCC_HSI_IsReady() == 0U)
-      {
-        return HAL_ERROR;
-      }
-
-    }
-
-    /* apply system clock switch */
-    LL_RCC_SetSysClkSource(RCC_ClkInitStruct->SYSCLKSource);
-
-    /* Get Start Tick*/
-    tickstart = HAL_GetTick();
-
-    /* check system clock source switch status */
-    while (__HAL_RCC_GET_SYSCLK_SOURCE() != (RCC_ClkInitStruct->SYSCLKSource << RCC_CFGR_SWS_Pos))
-    {
-      if ((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE)
-      {
-        return HAL_TIMEOUT;
-      }
-    }
-  }
-
-  /* Decreasing the number of wait states because of lower CPU frequency */
-  if (FLatency < __HAL_FLASH_GET_LATENCY())
-  {
-    /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */
-    __HAL_FLASH_SET_LATENCY(FLatency);
-
-    /* Get Start Tick*/
-    tickstart = HAL_GetTick();
-
-    /* Check that the new number of wait states is taken into account to access the Flash
-    memory by reading the FLASH_ACR register */
-    while (__HAL_FLASH_GET_LATENCY() != FLatency)
-    {
-      if ((HAL_GetTick() - tickstart) > LATENCY_TIMEOUT_VALUE)
-      {
-        return HAL_TIMEOUT;
-      }
-    }
-  }
-
-  /*---------------------------------------------------------------------------*/
-
-  /* Update the SystemCoreClock global variable */
-  SystemCoreClock = HAL_RCC_GetHCLKFreq();
-
-  /* Configure the source of time base considering new system clocks settings*/
-  return HAL_InitTick(HAL_GetTickPrio());
-}
-
-/**
-  * @}
-  */
-
-/** @defgroup RCC_Exported_Functions_Group2 Peripheral Control functions
-  *  @brief   RCC clocks control functions
-  *
-@verbatim
- ===============================================================================
-                      ##### Peripheral Control functions #####
- ===============================================================================
-    [..]
-    This subsection provides a set of functions allowing to:
-
-    (+) Output clock to MCO pin.
-    (+) Retrieve current clock frequencies.
-    (+) Enable the Clock Security System.
-
-@endverbatim
-  * @{
-  */
-
-/**
-  * @brief  Select the clock source to output on MCO1 pin(PA8) or MCO2 pin (PB6) or MCO3 pin (PA15).
-  * @note   PA8, PB6 or PA15 should be configured in alternate function mode.
-  * @param  RCC_MCOx  specifies the output direction for the clock source.
-  *            @arg @ref RCC_MCO1_PA8  Clock source to output on MCO1 pin(PA8)
-  *            @arg @ref RCC_MCO2_PB6  Clock source to output on MCO2 pin(PB6)
-  *            @arg @ref RCC_MCO3_PA15  Clock source to output on MCO3 pin(PA15)
-  * @param  RCC_MCOSource  specifies the clock source to output.
-  *          This parameter can be one of the following values:
-  *            @arg @ref RCC_MCO1SOURCE_NOCLOCK  MCO output disabled, no clock on MCO
-  *            @arg @ref RCC_MCO1SOURCE_SYSCLK  system clock selected as MCO source
-  *            @arg @ref RCC_MCO1SOURCE_MSI    MSI clock selected as MCO source
-  *            @arg @ref RCC_MCO1SOURCE_HSI    HSI clock selected as MCO source
-  *            @arg @ref RCC_MCO1SOURCE_HSE    HSE clock selected as MCO source
-  *            @arg @ref RCC_MCO1SOURCE_PLLCLK  main PLL clock selected as MCO source
-  *            @arg @ref RCC_MCO1SOURCE_LSI1   LSI1 clock selected as MCO source
-  *            @arg @ref RCC_MCO1SOURCE_LSI2   LSI2 clock selected as MCO source
-  *            @arg @ref RCC_MCO1SOURCE_LSE    LSE clock selected as MCO source
-  *            @arg @ref RCC_MCO1SOURCE_HSI48  HSI48 clock selected as MCO source for devices with HSI48
-  *            @arg @ref RCC_MCO1SOURCE_HSE_BEFORE_STAB  HSE clock before stabilization selected as MCO source
-  * @param  RCC_MCODiv  specifies the MCO prescaler.
-  *          This parameter can be one of the following values:
-  *            @arg @ref RCC_MCODIV_1  no division applied to MCO clock
-  *            @arg @ref RCC_MCODIV_2  division by 2 applied to MCO clock
-  *            @arg @ref RCC_MCODIV_4  division by 4 applied to MCO clock
-  *            @arg @ref RCC_MCODIV_8  division by 8 applied to MCO clock
-  *            @arg @ref RCC_MCODIV_16  division by 16 applied to MCO clock
-  * @retval None
-  */
-void HAL_RCC_MCOConfig(uint32_t RCC_MCOx, uint32_t RCC_MCOSource, uint32_t RCC_MCODiv)
-{
-  GPIO_InitTypeDef gpio_initstruct;
-  uint32_t mcoindex;
-  uint32_t mco_gpio_index;
-  GPIO_TypeDef *mco_gpio_port;
-
-  /* Check the parameters */
-  assert_param(IS_RCC_MCO(RCC_MCOx));
-
-  /* Common GPIO init parameters */
-  gpio_initstruct.Mode      = GPIO_MODE_AF_PP;
-  gpio_initstruct.Speed     = GPIO_SPEED_FREQ_VERY_HIGH;
-  gpio_initstruct.Pull      = GPIO_NOPULL;
-
-  /* Get MCOx selection */
-  mcoindex = RCC_MCOx & RCC_MCO_INDEX_MASK;
-
-  /* Get MCOx GPIO Port */
-  mco_gpio_port = (GPIO_TypeDef *) RCC_GET_MCO_GPIO_PORT(RCC_MCOx);
-
-  /* MCOx Clock Enable */
-  mco_gpio_index = RCC_GET_MCO_GPIO_INDEX(RCC_MCOx);
-  SET_BIT(RCC->AHB2ENR, (1UL << mco_gpio_index));
-
-  /* Configure the MCOx pin in alternate function mode */
-  gpio_initstruct.Pin = RCC_GET_MCO_GPIO_PIN(RCC_MCOx);
-  gpio_initstruct.Alternate = RCC_GET_MCO_GPIO_AF(RCC_MCOx);
-  HAL_GPIO_Init(mco_gpio_port, &gpio_initstruct);
-
-  if (mcoindex == RCC_MCO1_INDEX)
-  {
-    assert_param(IS_RCC_MCODIV(RCC_MCODiv));
-    assert_param(IS_RCC_MCO1SOURCE(RCC_MCOSource));
-    /* Mask MCOSEL[] and MCOPRE[] bits then set MCO clock source and prescaler */
-    LL_RCC_ConfigMCO(RCC_MCOSource, RCC_MCODiv);
-  }
-  else if (mcoindex == RCC_MCO2_INDEX)
-  {
-    assert_param(IS_RCC_MCODIV(RCC_MCODiv));
-    assert_param(IS_RCC_MCO2SOURCE(RCC_MCOSource));
-    /* Mask MCOSEL[] and MCOPRE[] bits then set MCO clock source and prescaler */
-    LL_RCC_ConfigMCO(RCC_MCOSource, RCC_MCODiv);
-  }
-#if defined(RCC_MCO3_SUPPORT)
-  else if (mcoindex == RCC_MCO3_INDEX)
-  {
-    assert_param(IS_RCC_MCODIV(RCC_MCODiv));
-    assert_param(IS_RCC_MCO3SOURCE(RCC_MCOSource));
-    /* Mask MCOSEL[] and MCOPRE[] bits then set MCO clock source and prescaler */
-    LL_RCC_ConfigMCO(RCC_MCOSource, RCC_MCODiv);
-  }
-#endif /* RCC_MCO3_SUPPORT */
-  else
-  {}
-}
-
-/**
-  * @brief  Return the SYSCLK frequency.
-  *
-  * @note   The system computed by this function is not the real
-  *         frequency in the chip. It is calculated based on the predefined
-  *         constant and the selected clock source:
-  * @note     If SYSCLK source is MSI, function returns values based on MSI range
-  * @note     If SYSCLK source is HSI, function returns values based on HSI_VALUE(*)
-  * @note     If SYSCLK source is HSE, function returns values based on HSE_VALUE(**)
-  * @note     If SYSCLK source is PLL, function returns values based on HSE_VALUE(**),
-  *           HSI_VALUE(*) or MSI Value multiplied/divided by the PLL factors.
-  * @note     (*) HSI_VALUE is a constant defined in stm32wbxx_hal_conf.h file (default value
-  *               16 MHz) but the real value may vary depending on the variations
-  *               in voltage and temperature.
-  * @note     (**) HSE_VALUE is a constant defined in stm32wbxx_hal_conf.h file (default value
-  *                32 MHz), user has to ensure that HSE_VALUE is same as the real
-  *                frequency of the crystal used. Otherwise, this function may
-  *                have wrong result.
-  *
-  * @note   The result of this function could be not correct when using fractional
-  *         value for HSE crystal.
-  *
-  * @note   This function can be used by the user application to compute the
-  *         baudrate for the communication peripherals or configure other parameters.
-  *
-  * @note   Each time SYSCLK changes, this function must be called to update the
-  *         right SYSCLK value. Otherwise, any configuration based on this function will be incorrect.
-  *
-  *
-  * @retval SYSCLK frequency
-  */
-uint32_t HAL_RCC_GetSysClockFreq(void)
-{
-  uint32_t pllsource;
-  uint32_t sysclockfreq;
-  uint32_t pllinputfreq;
-  const uint32_t temp_sysclksrc = __HAL_RCC_GET_SYSCLK_SOURCE();
-
-  if (temp_sysclksrc == RCC_SYSCLKSOURCE_STATUS_MSI)
-  {
-    /* Retrieve MSI frequency range in HZ*/
-    /* MSI used as system clock source */
-    sysclockfreq = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_GetRange());
-  }
-  else if (temp_sysclksrc == RCC_SYSCLKSOURCE_STATUS_HSI)
-  {
-    /* HSI used as system clock source */
-    sysclockfreq = HSI_VALUE;
-  }
-  else if (temp_sysclksrc == RCC_SYSCLKSOURCE_STATUS_HSE)
-  {
-    /* HSE used as system clock source */
-    if (LL_RCC_HSE_IsEnabledDiv2() == 1U)
-    {
-      sysclockfreq = HSE_VALUE / 2U;
-    }
-    else
-    {
-      sysclockfreq = HSE_VALUE;
-    }
-  }
-  else
-  {
-    /* PLL used as system clock  source */
-    pllsource = LL_RCC_PLL_GetMainSource();
-    switch (pllsource)
-    {
-      case RCC_PLLSOURCE_HSI:  /* HSI used as PLL clock source */
-        pllinputfreq = HSI_VALUE;
-        break;
-      case RCC_PLLSOURCE_HSE:  /* HSE used as PLL clock source */
-        if (LL_RCC_HSE_IsEnabledDiv2() == 1U)
-        {
-          pllinputfreq = HSE_VALUE / 2U;
-        }
-        else
-        {
-          pllinputfreq = HSE_VALUE;
-        }
-        break;
-      case RCC_PLLSOURCE_MSI:  /* MSI used as PLL clock source */
-      default:
-        pllinputfreq = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_GetRange());
-        break;
-    }
-    sysclockfreq = __LL_RCC_CALC_PLLCLK_FREQ(pllinputfreq, LL_RCC_PLL_GetDivider(), LL_RCC_PLL_GetN(),
-                                             LL_RCC_PLL_GetR());
-  }
-
-  return sysclockfreq;
-}
-
-/**
-  * @brief  Return the HCLK frequency.
-  * @retval HCLK frequency in Hz
-  */
-uint32_t HAL_RCC_GetHCLKFreq(void)
-{
-  /* Get SysClock and Compute HCLK1 frequency ---------------------------*/
-  return ((uint32_t)(__LL_RCC_CALC_HCLK1_FREQ(HAL_RCC_GetSysClockFreq(), LL_RCC_GetAHBPrescaler())));
-}
-
-/**
-  * @brief  Return the HCLK2 frequency.
-  * @retval HCLK2 frequency in Hz
-  */
-uint32_t HAL_RCC_GetHCLK2Freq(void)
-{
-  /* Get SysClock and Compute HCLK2 frequency ---------------------------*/
-  return ((uint32_t)(__LL_RCC_CALC_HCLK2_FREQ(HAL_RCC_GetSysClockFreq(), LL_C2_RCC_GetAHBPrescaler())));
-}
-
-/**
-  * @brief  Return the HCLK4 frequency.
-  * @retval HCLK4 frequency in Hz
-  */
-uint32_t HAL_RCC_GetHCLK4Freq(void)
-{
-  /* Get SysClock and Compute AHB4 frequency ---------------------------*/
-  return ((uint32_t)(__LL_RCC_CALC_HCLK4_FREQ(HAL_RCC_GetSysClockFreq(), LL_RCC_GetAHB4Prescaler())));
-}
-
-/**
-  * @brief  Return the PCLK1 frequency.
-  * @note   Each time PCLK1 changes, this function must be called to update the
-  *         right PCLK1 value. Otherwise, any configuration based on this function will be incorrect.
-  * @retval PCLK1 frequency in Hz
-  */
-uint32_t HAL_RCC_GetPCLK1Freq(void)
-{
-  /* Get HCLK source and Compute PCLK1 frequency ---------------------------*/
-  return ((uint32_t)(__LL_RCC_CALC_PCLK1_FREQ(HAL_RCC_GetHCLKFreq(), LL_RCC_GetAPB1Prescaler())));
-}
-
-/**
-  * @brief  Return the PCLK2 frequency.
-  * @note   Each time PCLK2 changes, this function must be called to update the
-  *         right PCLK2 value. Otherwise, any configuration based on this function will be incorrect.
-  * @retval PCLK2 frequency in Hz
-  */
-uint32_t HAL_RCC_GetPCLK2Freq(void)
-{
-  /* Get HCLK source and Compute PCLK2 frequency ---------------------------*/
-  return ((uint32_t)(__LL_RCC_CALC_PCLK2_FREQ(HAL_RCC_GetHCLKFreq(), LL_RCC_GetAPB2Prescaler())));
-}
-
-/**
-  * @brief  Configure the RCC_OscInitStruct according to the internal
-  *         RCC configuration registers.
-  * @param  RCC_OscInitStruct  pointer to an RCC_OscInitTypeDef structure that
-  *         will be configured.
-  * @retval None
-  */
-void HAL_RCC_GetOscConfig(RCC_OscInitTypeDef  *RCC_OscInitStruct)
-{
-  uint32_t regvalue;
-  uint32_t regICSRvalue;
-  uint32_t regPLLCFGRvalue;
-
-  /* Check the parameters */
-  assert_param(RCC_OscInitStruct != (void *)NULL);
-
-  /* Set all possible values for the Oscillator type parameter ---------------*/
-  RCC_OscInitStruct->OscillatorType = RCC_OSCILLATORTYPE_HSE | RCC_OSCILLATORTYPE_HSI | RCC_OSCILLATORTYPE_MSI | \
-                                      RCC_OSCILLATORTYPE_LSE | RCC_OSCILLATORTYPE_LSI1 | RCC_OSCILLATORTYPE_LSI2;
-
-#if defined(RCC_HSI48_SUPPORT)
-  RCC_OscInitStruct->OscillatorType |= RCC_OSCILLATORTYPE_HSI48;
-#endif /* RCC_HSI48_SUPPORT */
-
-  /* Get register values */
-  regvalue = RCC->CR; /* Control register */
-  regICSRvalue = RCC->ICSCR; /* Get Internal Clock Sources Calibration register */
-  regPLLCFGRvalue = RCC->PLLCFGR; /* Get PLL Configuration register */
-
-  /* Get the HSE configuration -----------------------------------------------*/
-  RCC_OscInitStruct->HSEState = (regvalue & RCC_CR_HSEON);
-
-  /* Get the MSI configuration -----------------------------------------------*/
-  RCC_OscInitStruct->MSIState            = (regvalue & RCC_CR_MSION);
-  RCC_OscInitStruct->MSICalibrationValue = (regICSRvalue & RCC_ICSCR_MSITRIM) >> RCC_ICSCR_MSITRIM_Pos;
-  RCC_OscInitStruct->MSIClockRange       = (regvalue & RCC_CR_MSIRANGE);
-
-  /* Get the HSI configuration -----------------------------------------------*/
-  RCC_OscInitStruct->HSIState            = (regvalue & RCC_CR_HSION);
-  RCC_OscInitStruct->HSICalibrationValue = ((regICSRvalue & RCC_ICSCR_HSITRIM) >> RCC_ICSCR_HSITRIM_Pos);
-
-  /* Get the PLL configuration -----------------------------------------------*/
-  RCC_OscInitStruct->PLL.PLLState  = ((regvalue & RCC_CR_PLLON) >> RCC_CR_PLLON_Pos) + 1U;
-  RCC_OscInitStruct->PLL.PLLSource = (regPLLCFGRvalue & RCC_PLLCFGR_PLLSRC);
-  RCC_OscInitStruct->PLL.PLLM      = (regPLLCFGRvalue & RCC_PLLCFGR_PLLM);
-  RCC_OscInitStruct->PLL.PLLN      = ((regPLLCFGRvalue & RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos);
-  RCC_OscInitStruct->PLL.PLLP      = (regPLLCFGRvalue & RCC_PLLCFGR_PLLP);
-  RCC_OscInitStruct->PLL.PLLQ      = (regPLLCFGRvalue & RCC_PLLCFGR_PLLQ);
-  RCC_OscInitStruct->PLL.PLLR      = (regPLLCFGRvalue & RCC_PLLCFGR_PLLR);
-
-  /* Get Backup Domain register */
-  regvalue = RCC->BDCR;
-
-  /* Get the LSE configuration -----------------------------------------------*/
-  RCC_OscInitStruct->LSEState = (regvalue & RCC_LSE_BYPASS);
-
-  /* Get Control/Status register */
-  regvalue = RCC->CSR;
-
-  /* Get the LSI configuration -----------------------------------------------*/
-  RCC_OscInitStruct->LSIState = ((regvalue & RCC_LSI_ON) > 0U)?RCC_LSI_ON:0U;
-
-#if defined(RCC_HSI48_SUPPORT)
-  /* Get Control/Status register */
-  regvalue = RCC->CRRCR;
-
-  /* Get the HSI48 configuration ---------------------------------------------*/
-  RCC_OscInitStruct->HSI48State = (regvalue & RCC_CRRCR_HSI48ON);
-#endif /* RCC_HSI48_SUPPORT */
-
-}
-
-/**
-  * @brief  Configure the RCC_ClkInitStruct according to the internal
-  *         RCC configuration registers.
-  * @param  RCC_ClkInitStruct Pointer to a @ref RCC_ClkInitTypeDef structure that
-  *                           will be configured.
-  * @param  pFLatency         Pointer on the Flash Latency.
-  * @retval None
-  */
-void HAL_RCC_GetClockConfig(RCC_ClkInitTypeDef  *RCC_ClkInitStruct, uint32_t *pFLatency)
-{
-  /* Check the parameters */
-  assert_param(RCC_ClkInitStruct != (void *)NULL);
-  assert_param(pFLatency != (void *)NULL);
-
-  /* Set all possible values for the Clock type parameter --------------------*/
-  RCC_ClkInitStruct->ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 |
-                                  RCC_CLOCKTYPE_PCLK2 | RCC_CLOCKTYPE_HCLK2 | RCC_CLOCKTYPE_HCLK4);
-
-  /* Get the SYSCLK configuration --------------------------------------------*/
-  RCC_ClkInitStruct->SYSCLKSource = LL_RCC_GetSysClkSource();
-
-  /* Get the HCLK configuration ----------------------------------------------*/
-  RCC_ClkInitStruct->AHBCLKDivider = LL_RCC_GetAHBPrescaler();
-
-  /* Get the APB1 configuration ----------------------------------------------*/
-  RCC_ClkInitStruct->APB1CLKDivider = LL_RCC_GetAPB1Prescaler();
-
-  /* Get the APB2 configuration ----------------------------------------------*/
-  RCC_ClkInitStruct->APB2CLKDivider = LL_RCC_GetAPB2Prescaler();
-
-  /* Get the AHBCLK2Divider configuration ------------------------------------*/
-  RCC_ClkInitStruct->AHBCLK2Divider = LL_C2_RCC_GetAHBPrescaler();
-
-  /* Get the AHBCLK4Divider configuration ------------------------------------*/
-  RCC_ClkInitStruct->AHBCLK4Divider = LL_RCC_GetAHB4Prescaler();
-
-  /* Get the Flash Wait State (Latency) configuration ------------------------*/
-  *pFLatency = __HAL_FLASH_GET_LATENCY();
-}
-
-/**
-  * @brief  Enable the Clock Security System.
-  * @note   If a failure is detected on the HSE oscillator clock, this oscillator
-  *         is automatically disabled and an interrupt is generated to inform the
-  *         software about the failure (Clock Security System Interrupt, CSSI),
-  *         allowing the MCU to perform rescue operations. The CSSI is linked to
-  *         CPU1 and CPU2 NMI (Non-Maskable Interrupt) exception vector.
-  * @note   The Clock Security System can only be cleared by reset.
-  * @retval None
-  */
-void HAL_RCC_EnableCSS(void)
-{
-  LL_RCC_HSE_EnableCSS();
-}
-
-/**
-  * @brief Handle the RCC HSE Clock Security System interrupt request.
-  * @note  This API should be called under the NMI_Handler().
-  * @retval None
-  */
-void HAL_RCC_NMI_IRQHandler(void)
-{
-  /* Check RCC CSSF interrupt flag  */
-  if (__HAL_RCC_GET_IT(RCC_IT_HSECSS))
-  {
-    /* RCC Clock Security System interrupt user callback */
-    HAL_RCC_CSSCallback();
-
-    /* Clear RCC CSS pending bit */
-    __HAL_RCC_CLEAR_IT(RCC_IT_HSECSS);
-  }
-}
-
-/**
-  * @brief Handle the RCC HSE Clock Security System interrupt callback.
-  * @retval none
-  */
-__weak void HAL_RCC_CSSCallback(void)
-{
-  /* NOTE : This function should not be modified, when the callback is needed,
-            the @ref HAL_RCC_CSSCallback should be implemented in the user file
-   */
-}
-
-/**
-  * @brief  Get and clear reset flags
-  * @param  None
-  * @note   Once reset flags are retrieved, this API is clearing them in order
-  *         to isolate next reset reason.
-  * @retval can be a combination of @ref RCC_Reset_Flag
-  */
-uint32_t HAL_RCC_GetResetSource(void)
-{
-  uint32_t reset;
-
-  /* Get all reset flags */
-  reset = RCC->CSR & RCC_RESET_FLAG_ALL;
-
-  /* Clear Reset flags */
-  RCC->CSR |= RCC_CSR_RMVF;
-
-  return reset;
-}
-
-/**
-  * @}
-  */
-
-/**
-  * @}
-  */
-
-/* Private function prototypes -----------------------------------------------*/
-/** @addtogroup RCC_Private_Functions
-  * @{
-  */
-
-/**
-  * @brief  Update number of Flash wait states in line with MSI range and current
-            voltage range.
-  * @param  MSI_Range  MSI range value from @ref RCC_MSIRANGE_0 to @ref RCC_MSIRANGE_11
-  * @retval HAL status
-  */
-static HAL_StatusTypeDef RCC_SetFlashLatencyFromMSIRange(uint32_t MSI_Range)
-{
-  uint32_t flash_clksrcfreq;
-  uint32_t msifreq;
-
-  /* Check the parameters */
-  assert_param(IS_RCC_MSI_CLOCK_RANGE(MSI_Range));
-
-  /* MSI frequency range in Hz */
-  if (MSI_Range > RCC_MSIRANGE_11)
-  {
-    msifreq = __LL_RCC_CALC_MSI_FREQ(RCC_MSIRANGE_11);
-  }
-  else
-  {
-    msifreq = __LL_RCC_CALC_MSI_FREQ(MSI_Range);
-  }
-
-  flash_clksrcfreq = __LL_RCC_CALC_HCLK4_FREQ(msifreq, LL_RCC_GetAHB4Prescaler());
-
-#if defined(PWR_CR1_VOS)
-  return RCC_SetFlashLatency((flash_clksrcfreq / MEGA_HZ), HAL_PWREx_GetVoltageRange());
-#else
-  return RCC_SetFlashLatency((flash_clksrcfreq / MEGA_HZ), PWR_REGULATOR_VOLTAGE_SCALE1);
-#endif /* PWR_CR1_VOS */
-}
-
-
-/**
-  * @brief  Update number of Flash wait states.
-  * @param  Flash_ClkSrcFreq  Flash Clock Source (in MHz)
-  * @param  VCORE_Voltage     Current Vcore voltage (PWR_REGULATOR_VOLTAGE_SCALE1 or PWR_REGULATOR_VOLTAGE_SCALE2)
-  * @retval HAL status
-  */
-static HAL_StatusTypeDef RCC_SetFlashLatency(uint32_t Flash_ClkSrcFreq, uint32_t VCORE_Voltage)
-{
-  /* Flash Clock source (HCLK4) range in MHz with a VCORE is range1 */
-  const uint32_t FLASH_CLK_SRC_RANGE_VOS1[] = {18UL, 36UL, 54UL, 64UL};
-#if defined(PWR_CR1_VOS)
-  /* Flash Clock source (HCLK4) range in MHz with a VCORE is range2 */
-  const uint32_t FLASH_CLK_SRC_RANGE_VOS2[] = {6UL, 12UL, 16UL};
-#endif /* PWR_CR1_VOS */
-  /* Flash Latency range */
-  const uint32_t FLASH_LATENCY_RANGE[] = {FLASH_LATENCY_0, FLASH_LATENCY_1, FLASH_LATENCY_2, FLASH_LATENCY_3};
-  uint32_t latency   = FLASH_LATENCY_0;  /* default value 0WS */
-  uint32_t tickstart;
-
-#if defined(PWR_CR1_VOS)
-  if (VCORE_Voltage == PWR_REGULATOR_VOLTAGE_SCALE1)
-  {
-    for (uint32_t index = 0; index < __COUNTOF(FLASH_CLK_SRC_RANGE_VOS1); index++)
-    {
-      if (Flash_ClkSrcFreq <= FLASH_CLK_SRC_RANGE_VOS1[index])
-      {
-        latency = FLASH_LATENCY_RANGE[index];
-        break;
-      }
-    }
-  }
-  else  /* PWR_REGULATOR_VOLTAGE_SCALE2 */
-  {
-    for (uint32_t index = 0; index < __COUNTOF(FLASH_CLK_SRC_RANGE_VOS2); index++)
-    {
-      if (Flash_ClkSrcFreq <= FLASH_CLK_SRC_RANGE_VOS2[index])
-      {
-        latency = FLASH_LATENCY_RANGE[index];
-        break;
-      }
-    }
-  }
-#else
-  for (uint32_t index = 0; index < __COUNTOF(FLASH_CLK_SRC_RANGE_VOS1); index++)
-  {
-    if (Flash_ClkSrcFreq <= FLASH_CLK_SRC_RANGE_VOS1[index])
-    {
-      latency = FLASH_LATENCY_RANGE[index];
-      break;
-    }
-  }
-#endif /* PWR_CR1_VOS */
-
-  __HAL_FLASH_SET_LATENCY(latency);
-
-  /* Get Start Tick*/
-  tickstart = HAL_GetTick();
-
-  /* Check that the new number of wait states is taken into account to access the Flash
-     memory by reading the FLASH_ACR register */
-  while (__HAL_FLASH_GET_LATENCY() != latency)
-  {
-    if ((HAL_GetTick() - tickstart) > LATENCY_TIMEOUT_VALUE)
-    {
-      return HAL_TIMEOUT;
-    }
-  }
-  return HAL_OK;
-}
-
-/**
-  * @}
-  */
-
-#endif /* HAL_RCC_MODULE_ENABLED */
-/**
-  * @}
-  */
-
-/**
-  * @}
-  */

+ 0 - 2328
non_catalog_apps/flipperscope/lib/adc/stm32wbxx_hal_rcc_ex.c

@@ -1,2328 +0,0 @@
-/**
-  ******************************************************************************
-  * @file    stm32wbxx_hal_rcc_ex.c
-  * @author  MCD Application Team
-  * @brief   Extended RCC HAL module driver.
-  *          This file provides firmware functions to manage the following
-  *          functionalities RCC extended peripheral:
-  *           + Extended Peripheral Control functions
-  *           + Extended Clock management functions
-  *           + Extended Clock Recovery System 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.
-  *
-  ******************************************************************************
-  */
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32wbxx_hal.h"
-
-/** @addtogroup STM32WBxx_HAL_Driver
-  * @{
-  */
-
-/** @defgroup RCCEx RCCEx
-  * @brief RCC Extended HAL module driver
-  * @{
-  */
-
-#ifdef HAL_RCC_MODULE_ENABLED
-
-/* Private typedef -----------------------------------------------------------*/
-/* Private defines -----------------------------------------------------------*/
-/** @defgroup RCCEx_Private_Constants RCCEx Private Constants
-  * @{
-  */
-#if defined(SAI1)
-#define PLLSAI1_TIMEOUT_VALUE    (2U)    /* 2 ms (minimum Tick + 1) */
-#endif /* SAI1 */
-#define PLL_TIMEOUT_VALUE        (2U)    /* 2 ms (minimum Tick + 1) */
-
-#define CLOCKSMPS_TIMEOUT_VALUE  (5000U) /* 5 s */
-
-#define __LSCO1_CLK_ENABLE()   __HAL_RCC_GPIOA_CLK_ENABLE()
-#define LSCO1_GPIO_PORT        GPIOA
-#define LSCO1_PIN              GPIO_PIN_2
-
-#define __LSCO2_CLK_ENABLE()   __HAL_RCC_GPIOH_CLK_ENABLE()
-#define LSCO2_GPIO_PORT        GPIOH
-#define LSCO2_PIN              GPIO_PIN_3
-
-#if defined(RCC_LSCO3_SUPPORT)
-#define __LSCO3_CLK_ENABLE()   __HAL_RCC_GPIOC_CLK_ENABLE()
-#define LSCO3_GPIO_PORT        GPIOC
-#define LSCO3_PIN              GPIO_PIN_12
-#endif /* RCC_LSCO3_SUPPORT */
-
-#define LSI2_TIMEOUT_VALUE         (3U)   /* to be adjusted with DS    */
-
-/**
-  * @}
-  */
-
-/* Private macros ------------------------------------------------------------*/
-/* Private variables ---------------------------------------------------------*/
-/* Private function prototypes -----------------------------------------------*/
-/** @defgroup RCCEx_Private_Functions RCCEx Private Functions
-  * @{
-  */
-#if defined(SAI1)
-static HAL_StatusTypeDef RCCEx_PLLSAI1_ConfigNP(RCC_PLLSAI1InitTypeDef *PLLSAI1);
-static HAL_StatusTypeDef RCCEx_PLLSAI1_ConfigNQ(RCC_PLLSAI1InitTypeDef *PLLSAI1);
-static HAL_StatusTypeDef RCCEx_PLLSAI1_ConfigNR(RCC_PLLSAI1InitTypeDef *PLLSAI1);
-#endif /* SAI1 */
-
-static uint32_t          RCC_PLL_GetFreqDomain_P(void);
-static uint32_t          RCC_PLL_GetFreqDomain_Q(void);
-
-#if defined(SAI1)
-static uint32_t          RCC_PLLSAI1_GetFreqDomain_R(void);
-static uint32_t          RCC_PLLSAI1_GetFreqDomain_P(void);
-static uint32_t          RCC_PLLSAI1_GetFreqDomain_Q(void);
-#endif /* SAI1 */
-
-/**
-  * @}
-  */
-
-/* Exported functions --------------------------------------------------------*/
-
-/** @defgroup RCCEx_Exported_Functions RCCEx Exported Functions
-  * @{
-  */
-
-/** @defgroup RCCEx_Exported_Functions_Group1 Extended Peripheral Control functions
-  *  @brief  Extended Peripheral Control functions
-  *
-@verbatim
- ===============================================================================
-                ##### Extended Peripheral Control functions  #####
- ===============================================================================
-    [..]
-    This subsection provides a set of functions allowing to control the RCC Clocks
-    frequencies.
-    [..]
-    (@) Important note: Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to
-        select the RTC clock source; in this case the Backup domain will be reset in
-        order to modify the RTC Clock source, as consequence RTC registers (including
-        the backup registers) and RCC_BDCR register are set to their reset values.
-
-@endverbatim
-  * @{
-  */
-
-/**
-  * @brief  Initialize the RCC extended peripherals clocks according to the specified
-  *         parameters in the @ref RCC_PeriphCLKInitTypeDef.
-  * @param  PeriphClkInit  pointer to a @ref RCC_PeriphCLKInitTypeDef structure that
-  *         contains a field PeriphClockSelection which can be a combination of the following values:
-  *
-  *            @arg @ref RCC_PERIPHCLK_USART1   USART1 peripheral clock
-  *            @arg @ref RCC_PERIPHCLK_LPUART1  LPUART1 peripheral clock
-  *            @arg @ref RCC_PERIPHCLK_I2C1     I2C1 peripheral clock
-  *            @arg @ref RCC_PERIPHCLK_I2C3     I2C3 peripheral clock
-  *            @arg @ref RCC_PERIPHCLK_LPTIM1   LPTIM1 peripheral clock
-  *            @arg @ref RCC_PERIPHCLK_LPTIM2   LPTIM2 peripheral clock
-  *            @arg @ref RCC_PERIPHCLK_SAI1     SAI1 peripheral clock
-  *            @arg @ref RCC_PERIPHCLK_USB      USB peripheral clock
-  *            @arg @ref RCC_PERIPHCLK_RNG      RNG peripheral clock
-  *            @arg @ref RCC_PERIPHCLK_ADC      ADC peripheral clock
-  *            @arg @ref RCC_PERIPHCLK_RTC      RTC peripheral clock
-  *            @arg @ref RCC_PERIPHCLK_RFWAKEUP RFWKP peripheral clock
-  *            @arg @ref RCC_PERIPHCLK_SMPS     SMPS peripheral clock
-  *
-  *
-  * @note   Care must be taken when @ref HAL_RCCEx_PeriphCLKConfig() is used to select
-  *         the RTC clock source: in this case the access to Backup domain is enabled.
-  *
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef  *PeriphClkInit)
-{
-  uint32_t tickstart;
-  HAL_StatusTypeDef ret     = HAL_OK;      /* Intermediate status */
-  HAL_StatusTypeDef status  = HAL_OK;   /* Final status */
-
-  /* Check the parameters */
-  assert_param(IS_RCC_PERIPHCLOCK(PeriphClkInit->PeriphClockSelection));
-
-#if defined(SAI1)
-  /*-------------------------- SAI1 clock source configuration ---------------------*/
-  if ((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI1) == RCC_PERIPHCLK_SAI1))
-  {
-    /* Check the parameters */
-    assert_param(IS_RCC_SAI1CLK(PeriphClkInit->Sai1ClockSelection));
-
-    switch (PeriphClkInit->Sai1ClockSelection)
-    {
-      case RCC_SAI1CLKSOURCE_PLL:      /* PLL is used as clock source for SAI1 */
-        /* Enable SAI1 Clock output generated form System PLL . */
-        __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_SAI1CLK);
-
-        /* SAI1 clock source config set later after clock selection check */
-        break;
-
-      case RCC_SAI1CLKSOURCE_PLLSAI1: /* PLLSAI1 is used as clock source for SAI1 */
-        /* PLLSAI1 parameters N & P configuration and clock output (PLLSAI1ClockOut) */
-        ret = RCCEx_PLLSAI1_ConfigNP(&(PeriphClkInit->PLLSAI1));
-        /* SAI1 clock source config set later after clock selection check */
-        break;
-
-      case RCC_SAI1CLKSOURCE_PIN:      /* External clock is used as source of SAI1 clock*/
-        /* SAI1 clock source config set later after clock selection check */
-        break;
-
-      case RCC_SAI1CLKSOURCE_HSI:
-
-        break;
-
-      default:
-        ret = HAL_ERROR;
-        break;
-    }
-
-    if (ret == HAL_OK)
-    {
-      /* Set the source of SAI1 clock*/
-      __HAL_RCC_SAI1_CONFIG(PeriphClkInit->Sai1ClockSelection);
-    }
-    else
-    {
-      /* set overall return value */
-      status = ret;
-    }
-  }
-#endif /* SAI1 */
-
-  /*-------------------------- RTC clock source configuration ----------------------*/
-  if ((PeriphClkInit->PeriphClockSelection & RCC_PERIPHCLK_RTC) == RCC_PERIPHCLK_RTC)
-  {
-    uint32_t rtcclocksource = LL_RCC_GetRTCClockSource();
-
-    /* Check for RTC Parameters used to output RTCCLK */
-    assert_param(IS_RCC_RTCCLKSOURCE(PeriphClkInit->RTCClockSelection));
-
-    /* Configure the clock source only if a different source is expected */
-    if (rtcclocksource != PeriphClkInit->RTCClockSelection)
-    {
-      /* Enable write access to Backup domain */
-      HAL_PWR_EnableBkUpAccess();
-
-      /* If a clock source is not yet selected */
-      if (rtcclocksource == RCC_RTCCLKSOURCE_NONE)
-      {
-        /* Directly set the configuration of the clock source selection */
-        LL_RCC_SetRTCClockSource(PeriphClkInit->RTCClockSelection);
-      }
-      else /* A clock source is already selected */
-      {
-        /* Store the content of BDCR register before the reset of Backup Domain */
-        uint32_t bdcr = LL_RCC_ReadReg(BDCR);
-
-        /* RTC Clock selection can be changed only if the Backup Domain is reset */
-        LL_RCC_ForceBackupDomainReset();
-        LL_RCC_ReleaseBackupDomainReset();
-
-        /* Set the value of the clock source selection */
-        MODIFY_REG(bdcr, RCC_BDCR_RTCSEL, PeriphClkInit->RTCClockSelection);
-
-        /* Restore the content of BDCR register */
-        LL_RCC_WriteReg(BDCR, bdcr);
-
-        /* Wait for LSE reactivation if LSE was enable prior to Backup Domain reset */
-        if (LL_RCC_LSE_IsEnabled() == 1U)
-        {
-          /* Get Start Tick*/
-          tickstart = HAL_GetTick();
-
-          /* Wait till LSE is ready */
-          while (LL_RCC_LSE_IsReady() != 1U)
-          {
-            if ((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE)
-            {
-              ret = HAL_TIMEOUT;
-              break;
-            }
-          }
-        }
-      }
-
-      /* set overall return value */
-      status = ret;
-    }
-    else
-    {
-      /* set overall return value */
-      status = ret;
-    }
-
-  }
-
-  /*-------------------------- USART1 clock source configuration -------------------*/
-  if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USART1) == RCC_PERIPHCLK_USART1)
-  {
-    /* Check the parameters */
-    assert_param(IS_RCC_USART1CLKSOURCE(PeriphClkInit->Usart1ClockSelection));
-
-    /* Configure the USART1 clock source */
-    __HAL_RCC_USART1_CONFIG(PeriphClkInit->Usart1ClockSelection);
-  }
-
-#if defined(LPUART1)
-  /*-------------------------- LPUART1 clock source configuration ------------------*/
-  if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LPUART1) == RCC_PERIPHCLK_LPUART1)
-  {
-    /* Check the parameters */
-    assert_param(IS_RCC_LPUART1CLKSOURCE(PeriphClkInit->Lpuart1ClockSelection));
-
-    /* Configure the LPUAR1 clock source */
-    __HAL_RCC_LPUART1_CONFIG(PeriphClkInit->Lpuart1ClockSelection);
-  }
-#endif /* LPUART1 */
-
-  /*-------------------------- LPTIM1 clock source configuration -------------------*/
-  if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LPTIM1) == (RCC_PERIPHCLK_LPTIM1))
-  {
-    assert_param(IS_RCC_LPTIM1CLK(PeriphClkInit->Lptim1ClockSelection));
-    __HAL_RCC_LPTIM1_CONFIG(PeriphClkInit->Lptim1ClockSelection);
-  }
-
-  /*-------------------------- LPTIM2 clock source configuration -------------------*/
-  if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LPTIM2) == (RCC_PERIPHCLK_LPTIM2))
-  {
-    assert_param(IS_RCC_LPTIM2CLK(PeriphClkInit->Lptim2ClockSelection));
-    __HAL_RCC_LPTIM2_CONFIG(PeriphClkInit->Lptim2ClockSelection);
-  }
-
-  /*-------------------------- I2C1 clock source configuration ---------------------*/
-  if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2C1) == RCC_PERIPHCLK_I2C1)
-  {
-    /* Check the parameters */
-    assert_param(IS_RCC_I2C1CLKSOURCE(PeriphClkInit->I2c1ClockSelection));
-
-    /* Configure the I2C1 clock source */
-    __HAL_RCC_I2C1_CONFIG(PeriphClkInit->I2c1ClockSelection);
-  }
-
-#if defined(I2C3)
-  /*-------------------------- I2C3 clock source configuration ---------------------*/
-  if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2C3) == RCC_PERIPHCLK_I2C3)
-  {
-    /* Check the parameters */
-    assert_param(IS_RCC_I2C3CLKSOURCE(PeriphClkInit->I2c3ClockSelection));
-
-    /* Configure the I2C3 clock source */
-    __HAL_RCC_I2C3_CONFIG(PeriphClkInit->I2c3ClockSelection);
-  }
-#endif /* I2C3 */
-
-#if defined(USB)
-  /*-------------------------- USB clock source configuration ----------------------*/
-  if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USB) == (RCC_PERIPHCLK_USB))
-  {
-    assert_param(IS_RCC_USBCLKSOURCE(PeriphClkInit->UsbClockSelection));
-    __HAL_RCC_USB_CONFIG(PeriphClkInit->UsbClockSelection);
-
-    if (PeriphClkInit->UsbClockSelection == RCC_USBCLKSOURCE_PLL)
-    {
-      /* Enable PLLQ output */
-      __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_USBCLK);
-    }
-#if defined(SAI1)
-    if (PeriphClkInit->UsbClockSelection == RCC_USBCLKSOURCE_PLLSAI1)
-    {
-      /* PLLSAI1 parameters N & Q configuration and clock output (PLLSAI1ClockOut) */
-      ret = RCCEx_PLLSAI1_ConfigNQ(&(PeriphClkInit->PLLSAI1));
-
-      if (ret != HAL_OK)
-      {
-        /* set overall return value */
-        status = ret;
-      }
-    }
-#endif /* SAI1 */
-  }
-#endif /* USB */
-
-  /*-------------------------- RNG clock source configuration ----------------------*/
-  if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RNG) == (RCC_PERIPHCLK_RNG))
-  {
-    /* Check the parameters */
-    assert_param(IS_RCC_RNGCLKSOURCE(PeriphClkInit->RngClockSelection));
-
-    /* Configure the RNG clock source */
-    __HAL_RCC_RNG_CONFIG(PeriphClkInit->RngClockSelection);
-
-    if (PeriphClkInit->RngClockSelection == RCC_RNGCLKSOURCE_PLL)
-    {
-      /* Enable PLLQ output */
-      __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_RNGCLK);
-    }
-  }
-
-  /*-------------------------- ADC clock source configuration ----------------------*/
-  if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_ADC) == RCC_PERIPHCLK_ADC)
-  {
-    /* Check the parameters */
-    assert_param(IS_RCC_ADCCLKSOURCE(PeriphClkInit->AdcClockSelection));
-
-    /* Configure the ADC interface clock source */
-    __HAL_RCC_ADC_CONFIG(PeriphClkInit->AdcClockSelection);
-
-    if (PeriphClkInit->AdcClockSelection == RCC_ADCCLKSOURCE_PLL)
-    {
-      /* Enable RCC_PLL_RNGCLK output */
-      __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_ADCCLK);
-    }
-
-#if defined(SAI1)
-    if (PeriphClkInit->AdcClockSelection == RCC_ADCCLKSOURCE_PLLSAI1)
-    {
-      /* PLLSAI1 parameters N & R configuration and clock output (PLLSAI1ClockOut) */
-      ret = RCCEx_PLLSAI1_ConfigNR(&(PeriphClkInit->PLLSAI1));
-
-      if (ret != HAL_OK)
-      {
-        /* set overall return value */
-        status = ret;
-      }
-    }
-#endif /* SAI1 */
-  }
-
-  /*-------------------------- RFWKP clock source configuration ----------------------*/
-  if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RFWAKEUP) == RCC_PERIPHCLK_RFWAKEUP)
-  {
-    /* Check the parameters */
-    assert_param(IS_RCC_RFWKPCLKSOURCE(PeriphClkInit->RFWakeUpClockSelection));
-
-    /* Configure the RFWKP interface clock source */
-    __HAL_RCC_RFWAKEUP_CONFIG(PeriphClkInit->RFWakeUpClockSelection);
-
-  }
-
-#if defined(RCC_SMPS_SUPPORT)
-  /*-------------------------- SMPS clock source configuration ----------------------*/
-  if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SMPS) == RCC_PERIPHCLK_SMPS)
-  {
-    /* Check the parameters */
-    assert_param(IS_RCC_SMPSCLKDIV(PeriphClkInit->SmpsDivSelection));
-    assert_param(IS_RCC_SMPSCLKSOURCE(PeriphClkInit->SmpsClockSelection));
-
-    /* Configure the SMPS interface clock division factor */
-    __HAL_RCC_SMPS_DIV_CONFIG(PeriphClkInit->SmpsDivSelection);
-
-    /* Configure the SMPS interface clock source */
-    __HAL_RCC_SMPS_CONFIG(PeriphClkInit->SmpsClockSelection);
-  }
-#endif /* RCC_SMPS_SUPPORT */
-
-  return status;
-}
-
-
-/**
-  * @brief  Get the RCC_ClkInitStruct according to the internal RCC configuration registers.
-  * @param  PeriphClkInit  pointer to an RCC_PeriphCLKInitTypeDef structure that
-  *         returns the configuration information for the Extended Peripherals
-  *         clocks(SAI1, LPTIM1, LPTIM2, I2C1, I2C3, LPUART1,
-  *         USART1, RTC, ADCx, USB, RNG, RFWKP, SMPS).
-  * @retval None
-  */
-void HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef  *PeriphClkInit)
-{
-  /* Set all possible values for the extended clock type parameter------------*/
-
-  PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_USART1 | RCC_PERIPHCLK_I2C1   | \
-                                        RCC_PERIPHCLK_LPTIM1 | RCC_PERIPHCLK_LPTIM2 | \
-                                        RCC_PERIPHCLK_RNG    | RCC_PERIPHCLK_ADC    | \
-                                        RCC_PERIPHCLK_RTC    | RCC_PERIPHCLK_RFWAKEUP;
-#if defined(LPUART1)
-  PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_LPUART1;
-#endif /* LPUART1 */
-
-#if defined(I2C3)
-  PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_I2C3;
-#endif /* I2C3 */
-
-#if defined(SAI1)
-  PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_SAI1;
-#endif /* SAI1 */
-
-#if defined(USB)
-  PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_USB;
-#endif /* USB */
-
-#if defined(RCC_SMPS_SUPPORT)
-  PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_SMPS;
-#endif /* RCC_SMPS_SUPPORT */
-
-
-#if defined(SAI1)
-  /* Get the PLLSAI1 Clock configuration -----------------------------------------------*/
-  PeriphClkInit->PLLSAI1.PLLN = LL_RCC_PLLSAI1_GetN();
-  PeriphClkInit->PLLSAI1.PLLP = LL_RCC_PLLSAI1_GetP();
-  PeriphClkInit->PLLSAI1.PLLR = LL_RCC_PLLSAI1_GetR();
-  PeriphClkInit->PLLSAI1.PLLQ = LL_RCC_PLLSAI1_GetQ();
-#endif /* SAI1 */
-
-  /* Get the USART1 clock source ---------------------------------------------*/
-  PeriphClkInit->Usart1ClockSelection   = __HAL_RCC_GET_USART1_SOURCE();
-
-#if defined(LPUART1)
-  /* Get the LPUART1 clock source --------------------------------------------*/
-  PeriphClkInit->Lpuart1ClockSelection  = __HAL_RCC_GET_LPUART1_SOURCE();
-#endif /* LPUART1 */
-
-  /* Get the I2C1 clock source -----------------------------------------------*/
-  PeriphClkInit->I2c1ClockSelection     = __HAL_RCC_GET_I2C1_SOURCE();
-
-#if defined(I2C3)
-  /* Get the I2C3 clock source -----------------------------------------------*/
-  PeriphClkInit->I2c3ClockSelection     = __HAL_RCC_GET_I2C3_SOURCE();
-#endif /* I2C3 */
-
-  /* Get the LPTIM1 clock source ---------------------------------------------*/
-  PeriphClkInit->Lptim1ClockSelection   = __HAL_RCC_GET_LPTIM1_SOURCE();
-
-  /* Get the LPTIM2 clock source ---------------------------------------------*/
-  PeriphClkInit->Lptim2ClockSelection   = __HAL_RCC_GET_LPTIM2_SOURCE();
-
-#if defined(SAI1)
-  /* Get the SAI1 clock source -----------------------------------------------*/
-  PeriphClkInit->Sai1ClockSelection     = __HAL_RCC_GET_SAI1_SOURCE();
-#endif /* SAI1 */
-
-  /* Get the RTC clock source ------------------------------------------------*/
-  PeriphClkInit->RTCClockSelection      = __HAL_RCC_GET_RTC_SOURCE();
-
-#if defined(USB)
-  /* Get the USB clock source ------------------------------------------------*/
-  PeriphClkInit->UsbClockSelection      = __HAL_RCC_GET_USB_SOURCE();
-#endif /* USB */
-
-  /* Get the RNG clock source ------------------------------------------------*/
-  PeriphClkInit->RngClockSelection      = HAL_RCCEx_GetRngCLKSource();
-
-  /* Get the ADC clock source ------------------------------------------------*/
-  PeriphClkInit->AdcClockSelection      = __HAL_RCC_GET_ADC_SOURCE();
-
-  /* Get the RFWKP clock source ----------------------------------------------*/
-  PeriphClkInit->RFWakeUpClockSelection = __HAL_RCC_GET_RFWAKEUP_SOURCE();
-
-#if defined(RCC_SMPS_SUPPORT)
-  /* Get the SMPS clock division factor --------------------------------------*/
-  PeriphClkInit->SmpsDivSelection       = __HAL_RCC_GET_SMPS_DIV();
-
-  /* Get the SMPS clock source -----------------------------------------------*/
-  PeriphClkInit->SmpsClockSelection     = __HAL_RCC_GET_SMPS_SOURCE();
-#endif /* RCC_SMPS_SUPPORT */
-
-}
-
-/**
-  * @brief  Return the peripheral clock frequency for peripherals with clock source
-  * @note   Return 0 if peripheral clock identifier not managed by this API
-  * @param  PeriphClk  Peripheral clock identifier
-  *         This parameter can be one of the following values:
-  *            @arg @ref RCC_PERIPHCLK_RTC  RTC peripheral clock
-  *            @arg @ref RCC_PERIPHCLK_ADC  ADC peripheral clock
-  *            @arg @ref RCC_PERIPHCLK_I2C1  I2C1 peripheral clock
-  *            @arg @ref RCC_PERIPHCLK_I2C3  I2C3 peripheral clock
-  *            @arg @ref RCC_PERIPHCLK_LPTIM1  LPTIM1 peripheral clock
-  *            @arg @ref RCC_PERIPHCLK_LPTIM2  LPTIM2 peripheral clock
-  *            @arg @ref RCC_PERIPHCLK_LPUART1  LPUART1 peripheral clock
-  *            @arg @ref RCC_PERIPHCLK_RNG  RNG peripheral clock
-  *            @arg @ref RCC_PERIPHCLK_SAI1  SAI1 peripheral clock
-  *            @arg @ref RCC_PERIPHCLK_USART1  USART1 peripheral clock
-  *            @arg @ref RCC_PERIPHCLK_USB  USB peripheral clock
-  *            @arg @ref RCC_PERIPHCLK_RFWAKEUP  RFWKP peripheral clock
-  *            @arg @ref RCC_PERIPHCLK_SMPS  SMPS peripheral clock
-  * @retval Frequency in Hz
-  */
-uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk)
-{
-  uint32_t frequency = 0U;
-
-#if defined(RCC_SMPS_SUPPORT)
-  uint32_t smps_prescaler_index = ((LL_RCC_GetSMPSPrescaler()) >> RCC_SMPSCR_SMPSDIV_Pos);
-#endif /* RCC_SMPS_SUPPORT */
-
-  /* Check the parameters */
-  assert_param(IS_RCC_PERIPHCLOCK(PeriphClk));
-
-  if (PeriphClk == RCC_PERIPHCLK_RTC)
-  {
-    uint32_t rtcClockSource = LL_RCC_GetRTCClockSource();
-
-    if (rtcClockSource == LL_RCC_RTC_CLKSOURCE_LSE) /* LSE clock used as RTC clock source */
-    {
-      if (LL_RCC_LSE_IsReady() == 1U)
-      {
-        frequency = LSE_VALUE;
-      }
-      else
-      {
-        /* Nothing to do as frequency already initialized to 0U */
-      }
-    }
-    else if (rtcClockSource == LL_RCC_RTC_CLKSOURCE_LSI) /* LSI clock used as RTC clock source */
-    {
-      const uint32_t temp_lsi1ready = LL_RCC_LSI1_IsReady();
-      const uint32_t temp_lsi2ready = LL_RCC_LSI2_IsReady();
-      if ((temp_lsi1ready == 1U) || (temp_lsi2ready == 1U))
-      {
-        frequency = LSI_VALUE;
-      }
-      else
-      {
-        /* Nothing to do as frequency already initialized to 0U */
-      }
-    }
-    else if (rtcClockSource == LL_RCC_RTC_CLKSOURCE_HSE_DIV32) /* HSE clock used as RTC clock source */
-    {
-      frequency = HSE_VALUE / 32U;
-    }
-    else /* No clock used as RTC clock source */
-    {
-      /* Nothing to do as frequency already initialized to 0U */
-    }
-  }
-#if defined(SAI1)
-  else if (PeriphClk == RCC_PERIPHCLK_SAI1)
-  {
-    switch (LL_RCC_GetSAIClockSource(LL_RCC_SAI1_CLKSOURCE))
-    {
-      case LL_RCC_SAI1_CLKSOURCE_HSI:        /* HSI clock used as SAI1 clock source */
-        if (LL_RCC_HSI_IsReady() == 1U)
-        {
-          frequency = HSI_VALUE;
-        }
-        else
-        {
-          /* Nothing to do as frequency already initialized to 0U */
-        }
-        break;
-
-      case LL_RCC_SAI1_CLKSOURCE_PLLSAI1:    /* PLLSAI1 clock used as SAI1 clock source */
-        if (LL_RCC_PLLSAI1_IsReady() == 1U)
-        {
-          frequency = RCC_PLLSAI1_GetFreqDomain_P();
-        }
-        else
-        {
-          /* Nothing to do as frequency already initialized to 0U */
-        }
-        break;
-
-      case LL_RCC_SAI1_CLKSOURCE_PLL:        /* PLL clock used as SAI1 clock source */
-        if (LL_RCC_PLL_IsReady() == 1U)
-        {
-          frequency = RCC_PLL_GetFreqDomain_P();
-        }
-        else
-        {
-          /* Nothing to do as frequency already initialized to 0U */
-        }
-        break;
-
-      default: /* External input clock used as SAI1 clock source */
-        frequency = EXTERNAL_SAI1_CLOCK_VALUE;
-        break;
-    }
-  }
-#endif /* SAI1 */
-  else if (PeriphClk == RCC_PERIPHCLK_RNG)
-  {
-    uint32_t rngClockSource = HAL_RCCEx_GetRngCLKSource();
-
-    if (rngClockSource == RCC_RNGCLKSOURCE_LSI)             /* LSI clock used as RNG clock source */
-    {
-      const uint32_t temp_lsi1ready = LL_RCC_LSI1_IsReady();
-      const uint32_t temp_lsi2ready = LL_RCC_LSI2_IsReady();
-      if ((temp_lsi1ready == 1U) || (temp_lsi2ready == 1U))
-      {
-        frequency = LSI_VALUE;
-      }
-      else
-      {
-        /* Nothing to do as frequency already initialized to 0U */
-      }
-    }
-    else if (rngClockSource == RCC_RNGCLKSOURCE_LSE)        /* LSE clock used as RNG clock source */
-    {
-      if (LL_RCC_LSE_IsReady() == 1U)
-      {
-        frequency = LSE_VALUE;
-      }
-      else
-      {
-        /* Nothing to do as frequency already initialized to 0U */
-      }
-    }
-    else if (rngClockSource == RCC_RNGCLKSOURCE_PLL)        /* PLL clock divided by 3 used as RNG clock source */
-    {
-      if (LL_RCC_PLL_IsReady() == 1U)
-      {
-        frequency = (RCC_PLL_GetFreqDomain_Q() / 3U);
-      }
-      else
-      {
-        /* Nothing to do as frequency already initialized to 0U */
-      }
-    }
-    else if (rngClockSource == RCC_RNGCLKSOURCE_MSI)        /* MSI clock divided by 3 used as RNG clock source */
-    {
-      if (LL_RCC_MSI_IsReady() == 1U)
-      {
-        frequency = (__LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_GetRange()) / 3U);
-      }
-      else
-      {
-        /* Nothing to do as frequency already initialized to 0U */
-      }
-    }
-#if defined(SAI1)
-    else if (rngClockSource == RCC_RNGCLKSOURCE_PLLSAI1)    /* PLLSAI1 clock used as SAI1 clock source */
-    {
-      if (LL_RCC_PLLSAI1_IsReady() == 1U)
-      {
-        frequency = RCC_PLLSAI1_GetFreqDomain_Q();
-      }
-      else
-      {
-        /* Nothing to do as frequency already initialized to 0U */
-      }
-    }
-#endif /* SAI1 */
-    else                                                    /* HSI48 clock divided by 3 used as RNG clock source */
-    {
-#if defined(RCC_HSI48_SUPPORT)
-      if (LL_RCC_HSI48_IsReady() == 1U)
-      {
-        frequency = HSI48_VALUE / 3U;
-      }
-      else
-      {
-        /* Nothing to do as frequency already initialized to 0U */
-      }
-#else
-      /* Nothing to do as frequency already initialized to 0U */
-#endif /* RCC_HSI48_SUPPORT */
-    }
-  }
-#if defined(USB)
-  else if (PeriphClk == RCC_PERIPHCLK_USB)
-  {
-    switch (LL_RCC_GetUSBClockSource(LL_RCC_USB_CLKSOURCE))
-    {
-#if defined(SAI1)
-      case LL_RCC_USB_CLKSOURCE_PLLSAI1:       /* PLLSAI1 clock used as USB clock source */
-        if (LL_RCC_PLLSAI1_IsReady() == 1U)
-        {
-          frequency = RCC_PLLSAI1_GetFreqDomain_Q();
-        }
-        else
-        {
-          /* Nothing to do as frequency already initialized to 0U */
-        }
-        break;
-#endif /* SAI1 */
-
-      case LL_RCC_USB_CLKSOURCE_PLL:           /* PLL clock used as USB clock source */
-        if (LL_RCC_PLL_IsReady() == 1U)
-        {
-          frequency = RCC_PLL_GetFreqDomain_Q();
-        }
-        else
-        {
-          /* Nothing to do as frequency already initialized to 0U */
-        }
-        break;
-
-      case LL_RCC_USB_CLKSOURCE_MSI:           /* MSI clock used as USB clock source */
-        if (LL_RCC_MSI_IsReady() == 1U)
-        {
-          frequency = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_GetRange());
-        }
-        else
-        {
-          /* Nothing to do as frequency already initialized to 0U */
-        }
-        break;
-
-      default: /* HSI48 clock used as USB clock source */
-        if (LL_RCC_HSI48_IsReady() == 1U)
-        {
-          frequency = HSI48_VALUE;
-        }
-        else
-        {
-          /* Nothing to do as frequency already initialized to 0U */
-        }
-        break;
-    }
-  }
-#endif /* USB */
-  else if (PeriphClk == RCC_PERIPHCLK_USART1)
-  {
-    switch (LL_RCC_GetUSARTClockSource(LL_RCC_USART1_CLKSOURCE))
-    {
-      case LL_RCC_USART1_CLKSOURCE_SYSCLK: /* USART1 Clock is System Clock */
-        frequency = HAL_RCC_GetSysClockFreq();
-        break;
-
-      case LL_RCC_USART1_CLKSOURCE_HSI:    /* USART1 Clock is HSI Osc. */
-        if (LL_RCC_HSI_IsReady() == 1U)
-        {
-          frequency = HSI_VALUE;
-        }
-        else
-        {
-          /* Nothing to do as frequency already initialized to 0U */
-        }
-        break;
-
-      case LL_RCC_USART1_CLKSOURCE_LSE:    /* USART1 Clock is LSE Osc. */
-        if (LL_RCC_LSE_IsReady() == 1U)
-        {
-          frequency = LSE_VALUE;
-        }
-        else
-        {
-          /* Nothing to do as frequency already initialized to 0U */
-        }
-        break;
-
-      default: /* USART1 Clock is PCLK2 */
-        frequency = __LL_RCC_CALC_PCLK2_FREQ(__LL_RCC_CALC_HCLK1_FREQ(HAL_RCC_GetSysClockFreq(),
-                                                                      LL_RCC_GetAHBPrescaler()),
-                                             LL_RCC_GetAPB2Prescaler());
-        break;
-    }
-  }
-#if defined(LPUART1)
-  else if (PeriphClk == RCC_PERIPHCLK_LPUART1)
-  {
-    switch (LL_RCC_GetLPUARTClockSource(LL_RCC_LPUART1_CLKSOURCE))
-    {
-      case LL_RCC_LPUART1_CLKSOURCE_SYSCLK: /* LPUART1 Clock is System Clock */
-        frequency = HAL_RCC_GetSysClockFreq();
-        break;
-
-      case LL_RCC_LPUART1_CLKSOURCE_HSI:    /* LPUART1 Clock is HSI Osc. */
-        if (LL_RCC_HSI_IsReady() == 1U)
-        {
-          frequency = HSI_VALUE;
-        }
-        else
-        {
-          /* Nothing to do as frequency already initialized to 0U */
-        }
-        break;
-
-      case LL_RCC_LPUART1_CLKSOURCE_LSE:    /* LPUART1 Clock is LSE Osc. */
-        if (LL_RCC_LSE_IsReady() == 1U)
-        {
-          frequency = LSE_VALUE;
-        }
-        else
-        {
-          /* Nothing to do as frequency already initialized to 0U */
-        }
-        break;
-
-      default: /* LPUART1 Clock is PCLK1 */
-        frequency = __LL_RCC_CALC_PCLK1_FREQ(__LL_RCC_CALC_HCLK1_FREQ(HAL_RCC_GetSysClockFreq(),
-                                                                      LL_RCC_GetAHBPrescaler()),
-                                             LL_RCC_GetAPB1Prescaler());
-        break;
-    }
-  }
-#endif /* LPUART1 */
-  else if (PeriphClk == RCC_PERIPHCLK_ADC)
-  {
-    switch (LL_RCC_GetADCClockSource(LL_RCC_ADC_CLKSOURCE))
-    {
-#if defined(STM32WB55xx) || defined (STM32WB5Mxx) || defined(STM32WB35xx)
-      case LL_RCC_ADC_CLKSOURCE_PLLSAI1:       /* PLLSAI1 clock used as ADC clock source */
-        if (LL_RCC_PLLSAI1_IsReady() == 1U)
-        {
-          frequency = RCC_PLLSAI1_GetFreqDomain_R();
-        }
-        else
-        {
-          /* Nothing to do as frequency already initialized to 0U */
-        }
-        break;
-#elif defined(STM32WB15xx) || defined(STM32WB1Mxx)
-      case LL_RCC_ADC_CLKSOURCE_HSI:           /* HSI clock used as ADC clock source */
-        if (LL_RCC_HSI_IsReady() == 1U)
-        {
-          frequency = HSI_VALUE;
-        }
-        else
-        {
-          /* Nothing to do as frequency already initialized to 0U */
-        }
-        break;
-#endif /* STM32WB55xx || STM32WB5Mxx || STM32WB35xx */
-      case LL_RCC_ADC_CLKSOURCE_SYSCLK:        /* SYSCLK clock used as ADC clock source */
-        frequency = HAL_RCC_GetSysClockFreq();
-        break;
-      case LL_RCC_ADC_CLKSOURCE_PLL:           /* PLL clock used as ADC clock source */
-        if (LL_RCC_PLL_IsReady() == 1U)
-        {
-          frequency = RCC_PLL_GetFreqDomain_P();
-        }
-        else
-        {
-          /* Nothing to do as frequency already initialized to 0U */
-        }
-        break;
-
-      default: /* No clock used as ADC clock source */
-        break;
-    }
-  }
-  else if (PeriphClk == RCC_PERIPHCLK_I2C1)
-  {
-    switch (LL_RCC_GetI2CClockSource(LL_RCC_I2C1_CLKSOURCE))
-    {
-      case LL_RCC_I2C1_CLKSOURCE_SYSCLK: /* I2C1 Clock is System Clock */
-        frequency = HAL_RCC_GetSysClockFreq();
-        break;
-
-      case LL_RCC_I2C1_CLKSOURCE_HSI:    /* I2C1 Clock is HSI Osc. */
-        if (LL_RCC_HSI_IsReady() == 1U)
-        {
-          frequency = HSI_VALUE;
-        }
-        else
-        {
-          /* Nothing to do as frequency already initialized to 0U */
-        }
-        break;
-
-      default: /* I2C1 Clock is PCLK1 */
-        frequency = __LL_RCC_CALC_PCLK1_FREQ(__LL_RCC_CALC_HCLK1_FREQ(HAL_RCC_GetSysClockFreq(),
-                                                                      LL_RCC_GetAHBPrescaler()),
-                                             LL_RCC_GetAPB1Prescaler());
-        break;
-    }
-  }
-#if defined(I2C3)
-  else if (PeriphClk == RCC_PERIPHCLK_I2C3)
-  {
-    switch (LL_RCC_GetI2CClockSource(LL_RCC_I2C3_CLKSOURCE))
-    {
-      case LL_RCC_I2C3_CLKSOURCE_SYSCLK: /* I2C3 Clock is System Clock */
-        frequency = HAL_RCC_GetSysClockFreq();
-        break;
-
-      case LL_RCC_I2C3_CLKSOURCE_HSI: /* I2C3 Clock is HSI Osc. */
-        if (LL_RCC_HSI_IsReady() == 1U)
-        {
-          frequency = HSI_VALUE;
-        }
-        else
-        {
-          /* Nothing to do as frequency already initialized to 0U */
-        }
-        break;
-
-      default: /* I2C3 Clock is PCLK1 */
-        frequency = __LL_RCC_CALC_PCLK1_FREQ(__LL_RCC_CALC_HCLK1_FREQ(HAL_RCC_GetSysClockFreq(),
-                                                                      LL_RCC_GetAHBPrescaler()),
-                                             LL_RCC_GetAPB1Prescaler());
-        break;
-    }
-  }
-#endif /* I2C3 */
-  else if (PeriphClk == RCC_PERIPHCLK_LPTIM1)
-  {
-    uint32_t lptimClockSource = LL_RCC_GetLPTIMClockSource(LL_RCC_LPTIM1_CLKSOURCE);
-
-    if (lptimClockSource == LL_RCC_LPTIM1_CLKSOURCE_LSI) /* LPTIM1 Clock is LSI Osc. */
-    {
-      const uint32_t temp_lsi1ready = LL_RCC_LSI1_IsReady();
-      const uint32_t temp_lsi2ready = LL_RCC_LSI2_IsReady();
-      if ((temp_lsi1ready == 1U) || (temp_lsi2ready == 1U))
-      {
-        frequency = LSI_VALUE;
-      }
-      else
-      {
-        /* Nothing to do as frequency already initialized to 0U */
-      }
-    }
-    else if (lptimClockSource == LL_RCC_LPTIM1_CLKSOURCE_HSI) /* LPTIM1 Clock is HSI Osc. */
-    {
-      if (LL_RCC_HSI_IsReady() == 1U)
-      {
-        frequency = HSI_VALUE;
-      }
-      else
-      {
-        /* Nothing to do as frequency already initialized to 0U */
-      }
-    }
-    else if (lptimClockSource == LL_RCC_LPTIM1_CLKSOURCE_LSE) /* LPTIM1 Clock is LSE Osc. */
-    {
-      if (LL_RCC_LSE_IsReady() == 1U)
-      {
-        frequency = LSE_VALUE;
-      }
-      else
-      {
-        /* Nothing to do as frequency already initialized to 0U */
-      }
-    }
-    else /* LPTIM1 Clock is PCLK1 */
-    {
-      frequency = __LL_RCC_CALC_PCLK1_FREQ(__LL_RCC_CALC_HCLK1_FREQ(HAL_RCC_GetSysClockFreq(),
-                                                                    LL_RCC_GetAHBPrescaler()),
-                                           LL_RCC_GetAPB1Prescaler());
-    }
-  }
-  else if (PeriphClk == RCC_PERIPHCLK_LPTIM2)
-  {
-    uint32_t lptimClockSource = LL_RCC_GetLPTIMClockSource(LL_RCC_LPTIM2_CLKSOURCE);
-
-    if (lptimClockSource == LL_RCC_LPTIM2_CLKSOURCE_LSI) /* LPTIM2 Clock is LSI Osc. */
-    {
-      const uint32_t temp_lsi1ready = LL_RCC_LSI1_IsReady();
-      const uint32_t temp_lsi2ready = LL_RCC_LSI2_IsReady();
-      if ((temp_lsi1ready == 1U) || (temp_lsi2ready == 1U))
-      {
-        frequency = LSI_VALUE;
-      }
-      else
-      {
-        /* Nothing to do as frequency already initialized to 0U */
-      }
-    }
-    else if (lptimClockSource == LL_RCC_LPTIM2_CLKSOURCE_HSI) /* LPTIM2 Clock is HSI Osc. */
-    {
-      if (LL_RCC_HSI_IsReady() == 1U)
-      {
-        frequency = HSI_VALUE;
-      }
-      else
-      {
-        /* Nothing to do as frequency already initialized to 0U */
-      }
-    }
-    else if (lptimClockSource == LL_RCC_LPTIM2_CLKSOURCE_LSE) /* LPTIM2 Clock is LSE Osc. */
-    {
-      if (LL_RCC_LSE_IsReady() == 1U)
-      {
-        frequency = LSE_VALUE;
-      }
-      else
-      {
-        /* Nothing to do as frequency already initialized to 0U */
-      }
-    }
-    else /* LPTIM2 Clock is PCLK1 */
-    {
-      frequency = __LL_RCC_CALC_PCLK1_FREQ(__LL_RCC_CALC_HCLK1_FREQ(HAL_RCC_GetSysClockFreq(),
-                                                                    LL_RCC_GetAHBPrescaler()),
-                                           LL_RCC_GetAPB1Prescaler());
-    }
-  }
-  else if (PeriphClk == RCC_PERIPHCLK_RFWAKEUP)
-  {
-    uint32_t rfwkpClockSource = LL_RCC_GetRFWKPClockSource();
-
-    if (rfwkpClockSource == LL_RCC_RFWKP_CLKSOURCE_LSE) /* LSE clock used as RF Wakeup clock source */
-    {
-      if (LL_RCC_LSE_IsReady() == 1U)
-      {
-        frequency = LSE_VALUE;
-      }
-      else
-      {
-        /* Nothing to do as frequency already initialized to 0U */
-      }
-    }
-    else if (rfwkpClockSource == LL_RCC_RFWKP_CLKSOURCE_HSE_DIV1024) /* HSE clock used as RF Wakeup clock source */
-    {
-      frequency = HSE_VALUE / 1024U;
-    }
-    else /* No clock used as RF Wakeup clock source */
-    {
-      /* Nothing to do as frequency already initialized to 0U */
-    }
-  }
-#if defined(RCC_SMPS_SUPPORT)
-  else if (PeriphClk == RCC_PERIPHCLK_SMPS)
-  {
-    uint32_t smpsClockSource = LL_RCC_GetSMPSClockSource();
-
-    if (smpsClockSource == LL_RCC_SMPS_CLKSOURCE_STATUS_HSI) /* SMPS Clock source is HSI Osc. */
-    {
-      if (LL_RCC_HSI_IsReady() == 1U)
-      {
-        frequency = HSI_VALUE / SmpsPrescalerTable[smps_prescaler_index][0];
-        frequency = frequency >> 1U; /* Systematic Div by 2 */
-      }
-      else
-      {
-        /* Nothing to do as frequency already initialized to 0U */
-      }
-    }
-    else if (smpsClockSource == LL_RCC_SMPS_CLKSOURCE_STATUS_HSE) /* SMPS Clock source is HSE Osc. */
-    {
-      if (LL_RCC_HSE_IsReady() == 1U)
-      {
-        frequency = HSE_VALUE / SmpsPrescalerTable[smps_prescaler_index][5];
-        frequency = frequency >> 1U; /* Systematic Div by 2 */
-      }
-      else
-      {
-        /* Nothing to do as frequency already initialized to 0U */
-      }
-    }
-    else if (smpsClockSource == LL_RCC_SMPS_CLKSOURCE_STATUS_MSI) /* SMPS Clock source is MSI Osc. */
-    {
-      switch (LL_RCC_MSI_GetRange())
-      {
-        case LL_RCC_MSIRANGE_8:
-          frequency = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSIRANGE_8) / SmpsPrescalerTable[smps_prescaler_index][4];
-          break;
-        case LL_RCC_MSIRANGE_9:
-          frequency = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSIRANGE_9) / SmpsPrescalerTable[smps_prescaler_index][3];
-          break;
-        case LL_RCC_MSIRANGE_10:
-          frequency = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSIRANGE_10) / SmpsPrescalerTable[smps_prescaler_index][2];
-          break;
-        case LL_RCC_MSIRANGE_11:
-          frequency = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSIRANGE_11) / SmpsPrescalerTable[smps_prescaler_index][1];
-          break;
-        default:
-          break;
-      }
-      frequency = frequency >> 1U; /* Systematic Div by 2 */
-    }
-    else /* SMPS has no Clock */
-    {
-      /* Nothing to do as frequency already initialized to 0U */
-    }
-  }
-#endif /* RCC_SMPS_SUPPORT */
-
-  return (frequency);
-}
-
-/**
-  * @brief  Return the RNG clock source
-  * @retval The RNG clock source can be one of the following values:
-  *            @arg @ref RCC_RNGCLKSOURCE_HSI48 HSI48 clock divided by 3 selected as RNG clock
-  *            @arg @ref RCC_RNGCLKSOURCE_PLL      PLL "Q" clock divided by 3  selected as RNG clock
-  *            @arg @ref RCC_RNGCLKSOURCE_MSI      MSI clock divided by 3 selected as RNG clock
-  *            @arg @ref RCC_RNGCLKSOURCE_PLLSAI1  PLLSAI1 "Q" clock selected as RNG clock (*)
-  *            @arg @ref RCC_RNGCLKSOURCE_LSI      LSI clock selected as RNG clock
-  *            @arg @ref RCC_RNGCLKSOURCE_LSE      LSE clock selected as RNG clock
-  *
-  *         (*) Value not defined in all devices.
-  *
-  */
-uint32_t HAL_RCCEx_GetRngCLKSource(void)
-{
-  uint32_t rng_clock_source = LL_RCC_GetRNGClockSource(LL_RCC_RNG_CLKSOURCE);
-  uint32_t clk48_clock_source;
-
-  /* RNG clock source originates from 48 MHz RC oscillator */
-  if (rng_clock_source == RCC_RNGCLKSOURCE_CLK48)
-  {
-    clk48_clock_source = LL_RCC_GetCLK48ClockSource(LL_RCC_CLK48_CLKSOURCE);
-    rng_clock_source = (CLK48_MASK | clk48_clock_source);
-  }
-
-  return rng_clock_source;
-}
-
-/**
-  * @}
-  */
-
-/** @defgroup RCCEx_Exported_Functions_Group2 Extended Clock management functions
-  * @brief  Extended Clock management functions
-  *
-@verbatim
- ===============================================================================
-                ##### Extended clock management functions  #####
- ===============================================================================
-    [..]
-    This subsection provides a set of functions allowing to control the
-    activation or deactivation of MSI PLL-mode, PLLSAI1, PLLSAI12, LSE CSS,
-    Low speed clock output and clock after wake-up from STOP mode.
-@endverbatim
-  * @{
-  */
-
-#if defined(SAI1)
-/**
-  * @brief  Enable PLLSAI1.
-  * @param  PLLSAI1Init  pointer to an RCC_PLLSAI1InitTypeDef structure that
-  *         contains the configuration information for the PLLSAI1
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_RCCEx_EnablePLLSAI1(RCC_PLLSAI1InitTypeDef  *PLLSAI1Init)
-{
-  uint32_t tickstart;
-  HAL_StatusTypeDef status = HAL_OK;
-
-  /* check for PLLSAI1 Parameters used to output PLLSAI1CLK */
-  assert_param(IS_RCC_PLLN_VALUE(PLLSAI1Init->PLLN));
-  assert_param(IS_RCC_PLLP_VALUE(PLLSAI1Init->PLLP));
-  assert_param(IS_RCC_PLLQ_VALUE(PLLSAI1Init->PLLQ));
-  assert_param(IS_RCC_PLLR_VALUE(PLLSAI1Init->PLLR));
-  assert_param(IS_RCC_PLLSAI1CLOCKOUT_VALUE(PLLSAI1Init->PLLSAI1ClockOut));
-
-  /* Disable the PLLSAI1 */
-  __HAL_RCC_PLLSAI1_DISABLE();
-
-  /* Get Start Tick*/
-  tickstart = HAL_GetTick();
-
-  /* Wait till PLLSAI1 is ready to be updated */
-  while (LL_RCC_PLLSAI1_IsReady() != 0U)
-  {
-    if ((HAL_GetTick() - tickstart) > PLLSAI1_TIMEOUT_VALUE)
-    {
-      status = HAL_TIMEOUT;
-      break;
-    }
-  }
-
-  if (status == HAL_OK)
-  {
-    /* Configure the PLLSAI1 Multiplication factor N */
-    /* Configure the PLLSAI1 Division factors P, Q and R */
-    __HAL_RCC_PLLSAI1_CONFIG(PLLSAI1Init->PLLN, PLLSAI1Init->PLLP, PLLSAI1Init->PLLQ, PLLSAI1Init->PLLR);
-    /* Configure the PLLSAI1 Clock output(s) */
-    __HAL_RCC_PLLSAI1CLKOUT_ENABLE(PLLSAI1Init->PLLSAI1ClockOut);
-
-    /* Enable the PLLSAI1 again by setting PLLSAI1ON to 1*/
-    __HAL_RCC_PLLSAI1_ENABLE();
-
-    /* Get Start Tick*/
-    tickstart = HAL_GetTick();
-
-    /* Wait till PLLSAI1 is ready */
-    while (LL_RCC_PLLSAI1_IsReady() != 1U)
-    {
-      if ((HAL_GetTick() - tickstart) > PLLSAI1_TIMEOUT_VALUE)
-      {
-        status = HAL_TIMEOUT;
-        break;
-      }
-    }
-  }
-
-  return status;
-}
-
-/**
-  * @brief  Disable PLLSAI1.
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_RCCEx_DisablePLLSAI1(void)
-{
-  uint32_t tickstart;
-  HAL_StatusTypeDef status = HAL_OK;
-
-  /* Disable the PLLSAI1 */
-  __HAL_RCC_PLLSAI1_DISABLE();
-
-  /* Get Start Tick*/
-  tickstart = HAL_GetTick();
-
-  /* Wait till PLLSAI1 is ready */
-  while (LL_RCC_PLLSAI1_IsReady() != 0U)
-  {
-    if ((HAL_GetTick() - tickstart) > PLLSAI1_TIMEOUT_VALUE)
-    {
-      status = HAL_TIMEOUT;
-      break;
-    }
-  }
-
-  /* Disable the PLLSAI1 Clock outputs */
-  __HAL_RCC_PLLSAI1CLKOUT_DISABLE(RCC_PLLSAI1_SAI1CLK | RCC_PLLSAI1_USBCLK | RCC_PLLSAI1_ADCCLK);
-
-  return status;
-}
-#endif /* SAI1 */
-
-/***********************************************************************************************/
-
-/**
-  * @brief  Configure the oscillator clock source for wakeup from Stop and CSS backup clock.
-  * @param  WakeUpClk  Wakeup clock
-  *         This parameter can be one of the following values:
-  *            @arg @ref RCC_STOP_WAKEUPCLOCK_MSI  MSI oscillator selection
-  *            @arg @ref RCC_STOP_WAKEUPCLOCK_HSI  HSI oscillator selection
-  * @note   This function shall not be called after the Clock Security System on HSE has been
-  *         enabled.
-  * @retval None
-  */
-void HAL_RCCEx_WakeUpStopCLKConfig(uint32_t WakeUpClk)
-{
-  assert_param(IS_RCC_STOP_WAKEUPCLOCK(WakeUpClk));
-
-  __HAL_RCC_WAKEUPSTOP_CLK_CONFIG(WakeUpClk);
-}
-
-/**
-  * @brief  Enable the LSE Clock Security System.
-  * @note   Prior to enable the LSE Clock Security System, LSE oscillator is to be enabled
-  *         with HAL_RCC_OscConfig() and the LSE oscillator clock is to be selected as RTC
-  *         clock with HAL_RCCEx_PeriphCLKConfig().
-  * @retval None
-  */
-void HAL_RCCEx_EnableLSECSS(void)
-{
-  LL_RCC_LSE_EnableCSS();
-}
-
-/**
-  * @brief  Disable the LSE Clock Security System.
-  * @note   LSE Clock Security System can only be disabled after a LSE failure detection.
-  * @retval None
-  */
-void HAL_RCCEx_DisableLSECSS(void)
-{
-  LL_RCC_LSE_DisableCSS();
-
-  /* Disable LSE CSS IT if any */
-  __HAL_RCC_DISABLE_IT(RCC_IT_LSECSS);
-}
-
-/**
-  * @brief  Enable the LSE Clock Security System Interrupt & corresponding EXTI line.
-  * @note   LSE Clock Security System Interrupt is mapped on RTC EXTI line 18
-  * @retval None
-  */
-void HAL_RCCEx_EnableLSECSS_IT(void)
-{
-  /* Enable LSE CSS */
-  LL_RCC_LSE_EnableCSS();
-
-  /* Enable LSE CSS IT */
-  __HAL_RCC_ENABLE_IT(RCC_IT_LSECSS);
-
-  /* Enable IT on EXTI Line 18 */
-  __HAL_RCC_LSECSS_EXTI_ENABLE_IT();
-  __HAL_RCC_LSECSS_EXTI_ENABLE_RISING_EDGE();
-}
-
-/**
-  * @brief Handle the RCC LSE Clock Security System interrupt request.
-  * @retval None
-  */
-void HAL_RCCEx_LSECSS_IRQHandler(void)
-{
-  /* Check RCC LSE CSSF flag  */
-  if (__HAL_RCC_GET_IT(RCC_IT_LSECSS))
-  {
-    /* RCC LSE Clock Security System interrupt user callback */
-    HAL_RCCEx_LSECSS_Callback();
-
-    /* Clear RCC LSE CSS pending bit */
-    __HAL_RCC_CLEAR_IT(RCC_IT_LSECSS);
-  }
-}
-
-/**
-  * @brief  RCCEx LSE Clock Security System interrupt callback.
-  * @retval none
-  */
-__weak void HAL_RCCEx_LSECSS_Callback(void)
-{
-  /* NOTE : This function should not be modified, when the callback is needed,
-            the HAL_RCCEx_LSECSS_Callback should be implemented in the user file
-   */
-}
-
-/**
-  * @brief  Select the clock source to output on LSCO1 pin(PA2) or LSC02 pin (PH3) or LSCO3 pin (PC12).
-  * @note   PA2, PH3 or PC12 should be configured in alternate function mode.
-  * @param  RCC_LSCOx  specifies the output direction for the clock source.
-  *            @arg @ref RCC_LSCO1  Clock source to output on LSCO1 pin(PA2)
-  *            @arg @ref RCC_LSCO2  Clock source to output on LSCO2 pin(PH3)
-  *            @arg @ref RCC_LSCO3  Clock source to output on LSCO3 pin(PC12)
-  * @param  RCC_LSCOSource  specifies the clock source to output.
-  *          This parameter can be one of the following values:
-  *            @arg @ref RCC_LSCOSOURCE_LSI  LSI clock selected as LSCO source
-  *            @arg @ref RCC_LSCOSOURCE_LSE  LSE clock selected as LSCO source
-  * @retval None
-  * @note   LSCO should be disable with @ref HAL_RCCEx_DisableLSCO
-  */
-void HAL_RCCEx_LSCOConfig(uint32_t RCC_LSCOx, uint32_t RCC_LSCOSource)
-{
-  GPIO_InitTypeDef GPIO_InitStruct;
-  FlagStatus backupchanged;
-
-  /* Check the parameters */
-  assert_param(IS_RCC_LSCO(RCC_LSCOx));
-  assert_param(IS_RCC_LSCOSOURCE(RCC_LSCOSource));
-
-  /* Common GPIO init parameters */
-  GPIO_InitStruct.Mode      = GPIO_MODE_AF_PP;
-  GPIO_InitStruct.Speed     = GPIO_SPEED_FREQ_VERY_HIGH;
-  GPIO_InitStruct.Pull      = GPIO_NOPULL;
-
-  /* RCC_LSCO1 */
-  if (RCC_LSCOx == RCC_LSCO1)
-  {
-    /* LSCO1 Clock Enable */
-    __LSCO1_CLK_ENABLE();
-    /* Configure the LSCO1 pin in alternate function mode */
-    GPIO_InitStruct.Pin       = LSCO1_PIN;
-    GPIO_InitStruct.Alternate = GPIO_AF0_LSCO;
-    HAL_GPIO_Init(LSCO1_GPIO_PORT, &GPIO_InitStruct);
-  }
-  else if (RCC_LSCOx == RCC_LSCO2)
-  {
-    /* LSCO2 Clock Enable */
-    __LSCO2_CLK_ENABLE();
-    /* Configure the LSCO2 pin in alternate function mode */
-    GPIO_InitStruct.Pin       = LSCO2_PIN;
-    GPIO_InitStruct.Alternate = GPIO_AF0_LSCO;
-    HAL_GPIO_Init(LSCO2_GPIO_PORT, &GPIO_InitStruct);
-
-  }
-#if defined(RCC_LSCO3_SUPPORT)
-  else if (RCC_LSCOx == RCC_LSCO3)
-  {
-    /* LSCO3 Clock Enable */
-    __LSCO3_CLK_ENABLE();
-    /* Configure the LSCO3 pin in alternate function mode */
-    GPIO_InitStruct.Pin       = LSCO3_PIN;
-    GPIO_InitStruct.Alternate = GPIO_AF6_LSCO;
-    HAL_GPIO_Init(LSCO3_GPIO_PORT, &GPIO_InitStruct);
-  }
-#endif /* RCC_LSCO3_SUPPORT */
-  else
-  {
-    ;
-  }
-
-  /* Update LSCOSEL clock source in Backup Domain control register */
-  if (HAL_IS_BIT_CLR(PWR->CR1, PWR_CR1_DBP))
-  {
-    HAL_PWR_EnableBkUpAccess();
-    backupchanged = SET;
-  }
-  else
-  {
-    backupchanged = RESET;
-  }
-
-  MODIFY_REG(RCC->BDCR, RCC_BDCR_LSCOSEL | RCC_BDCR_LSCOEN, RCC_LSCOSource | RCC_BDCR_LSCOEN);
-
-  if (backupchanged == SET)
-  {
-    HAL_PWR_DisableBkUpAccess();
-  }
-
-}
-
-/**
-  * @brief  Select the Low Speed clock source to output on LSCO pin (PA2).
-  * @param  LSCOSource  specifies the Low Speed clock source to output.
-  *          This parameter can be one of the following values:
-  *            @arg @ref RCC_LSCOSOURCE_LSI  LSI clock selected as LSCO source
-  *            @arg @ref RCC_LSCOSOURCE_LSE  LSE clock selected as LSCO source
-  * @retval None
-  */
-void HAL_RCCEx_EnableLSCO(uint32_t LSCOSource)
-{
-  /* Check the parameters */
-  assert_param(IS_RCC_LSCOSOURCE(LSCOSource));
-
-  /* Update LSCO selection according to parameter and enable LSCO */
-  MODIFY_REG(RCC->BDCR, RCC_BDCR_LSCOSEL, LSCOSource | RCC_BDCR_LSCOEN);
-}
-
-/**
-  * @brief  Disable the Low Speed clock output.
-  * @retval None
-  */
-void HAL_RCCEx_DisableLSCO(void)
-{
-  LL_RCC_LSCO_Disable();
-}
-
-/**
-  * @brief  Enable the PLL-mode of the MSI.
-  * @note   Prior to enable the PLL-mode of the MSI for automatic hardware
-  *         calibration LSE oscillator is to be enabled with @ref HAL_RCC_OscConfig().
-  * @retval None
-  */
-void HAL_RCCEx_EnableMSIPLLMode(void)
-{
-  LL_RCC_MSI_EnablePLLMode() ;
-}
-
-/**
-  * @brief  Disable the PLL-mode of the MSI.
-  * @note   PLL-mode of the MSI is automatically reset when LSE oscillator is disabled.
-  * @retval None
-  */
-void HAL_RCCEx_DisableMSIPLLMode(void)
-{
-  LL_RCC_MSI_DisablePLLMode() ;
-}
-
-/**
-  * @brief Set trimming value
-  * @param OscillatorType Specifies the oscillator to be trimmed
-  *   This parameter can be one of the following values:
-  *     @arg @ref RCC_OSCILLATORTYPE_LSI2 LSI2 oscillator selected.
-  *       When disabling and re-enabling the LSI2 there is no need for re-trimming
-  *       Trimming is only needed once after a NRST reset.
-  *       Trimming values comes from factory trimmed flash location (0x1FFF7548).
-  * @note The LSI2 oscillator must be disabled before calling this trimming function through @ref HAL_RCC_OscConfig
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_RCCEx_TrimOsc(uint32_t OscillatorType)
-{
-#define FTLSI2TRIM (0xFUL)
-  HAL_StatusTypeDef status = HAL_OK;
-
-  assert_param(IS_RCC_TRIMOSC(OscillatorType));
-
-  if (OscillatorType == RCC_OSCILLATORTYPE_LSI2)
-  {
-    if (LL_RCC_LSI2_IsReady() == 1U)
-    {
-      status = HAL_ERROR;
-    }
-    else
-    {
-      /* Copy the LSI2 trimming information from the factory trimmed Flash location */
-      uint32_t factoryTrimming = ((*(uint32_t *)(0x1FFF7548)) & FTLSI2TRIM);
-      LL_RCC_LSI2_SetTrimming(factoryTrimming);
-    }
-  }
-  else
-  {
-    status = HAL_ERROR;
-  }
-  return status;
-}
-
-/**
-  * @}
-  */
-
-#if defined(CRS)
-/** @defgroup RCCEx_Exported_Functions_Group3 Extended Clock Recovery System Control functions
-  *  @brief  Extended Clock Recovery System Control functions
-  *
-@verbatim
- ===============================================================================
-                ##### Extended Clock Recovery System Control functions  #####
- ===============================================================================
-    [..]
-      For devices with Clock Recovery System feature (CRS), RCC Extended HAL driver can be used as follows:
-
-      (#) In System clock config, HSI48 needs to be enabled
-
-      (#) Enable CRS clock in IP MSP init which will use CRS functions
-
-      (#) Call CRS functions as follows:
-          (##) Prepare synchronization configuration necessary for HSI48 calibration
-              (+++) Default values can be set for frequency Error Measurement (reload and error limit)
-                        and also HSI48 oscillator smooth trimming.
-              (+++) Macro __HAL_RCC_CRS_RELOADVALUE_CALCULATE can be also used to calculate
-                        directly reload value with target and synchronization frequencies values
-          (##) Call function HAL_RCCEx_CRSConfig which
-              (+++) Resets CRS registers to their default values.
-              (+++) Configures CRS registers with synchronization configuration
-              (+++) Enables automatic calibration and frequency error counter feature
-           Note: When using USB LPM (Link Power Management) and the device is in Sleep mode, the
-           periodic USB SOF will not be generated by the host. No SYNC signal will therefore be
-           provided to the CRS to calibrate the HSI48 on the run. To guarantee the required clock
-           precision after waking up from Sleep mode, the LSE or reference clock on the GPIOs
-           should be used as SYNC signal.
-
-          (##) A polling function is provided to wait for complete synchronization
-              (+++) Call function HAL_RCCEx_CRSWaitSynchronization()
-              (+++) According to CRS status, user can decide to adjust again the calibration or continue
-                        application if synchronization is OK
-
-      (#) User can retrieve information related to synchronization in calling function
-            HAL_RCCEx_CRSGetSynchronizationInfo()
-
-      (#) Regarding synchronization status and synchronization information, user can try a new calibration
-           in changing synchronization configuration and call again HAL_RCCEx_CRSConfig.
-           Note: When the SYNC event is detected during the downcounting phase (before reaching the zero value),
-           it means that the actual frequency is lower than the target (and so, that the TRIM value should be
-           incremented), while when it is detected during the upcounting phase it means that the actual frequency
-           is higher (and that the TRIM value should be decremented).
-
-      (#) In interrupt mode, user can resort to the available macros (__HAL_RCC_CRS_XXX_IT). Interrupts will go
-          through CRS Handler (CRS_IRQn/CRS_IRQHandler)
-              (++) Call function HAL_RCCEx_CRSConfig()
-              (++) Enable CRS_IRQn (thanks to NVIC functions)
-              (++) Enable CRS interrupt (__HAL_RCC_CRS_ENABLE_IT)
-              (++) Implement CRS status management in the following user callbacks called from
-                   HAL_RCCEx_CRS_IRQHandler():
-                   (+++) HAL_RCCEx_CRS_SyncOkCallback()
-                   (+++) HAL_RCCEx_CRS_SyncWarnCallback()
-                   (+++) HAL_RCCEx_CRS_ExpectedSyncCallback()
-                   (+++) HAL_RCCEx_CRS_ErrorCallback()
-
-      (#) To force a SYNC EVENT, user can use the function HAL_RCCEx_CRSSoftwareSynchronizationGenerate().
-          This function can be called before calling HAL_RCCEx_CRSConfig (for instance in Systick handler)
-
-@endverbatim
-  * @{
-  */
-
-/**
-  * @brief  Start automatic synchronization for polling mode
-  * @param  pInit Pointer on RCC_CRSInitTypeDef structure
-  * @retval None
-  */
-void HAL_RCCEx_CRSConfig(RCC_CRSInitTypeDef *pInit)
-{
-  uint32_t value;
-
-  /* Check the parameters */
-  assert_param(IS_RCC_CRS_SYNC_DIV(pInit->Prescaler));
-  assert_param(IS_RCC_CRS_SYNC_SOURCE(pInit->Source));
-  assert_param(IS_RCC_CRS_SYNC_POLARITY(pInit->Polarity));
-  assert_param(IS_RCC_CRS_RELOADVALUE(pInit->ReloadValue));
-  assert_param(IS_RCC_CRS_ERRORLIMIT(pInit->ErrorLimitValue));
-  assert_param(IS_RCC_CRS_HSI48CALIBRATION(pInit->HSI48CalibrationValue));
-
-  /* CONFIGURATION */
-
-  /* Before configuration, reset CRS registers to their default values*/
-  __HAL_RCC_CRS_FORCE_RESET();
-  __HAL_RCC_CRS_RELEASE_RESET();
-
-  /* Set the SYNCDIV[2:0] bits according to Prescaler value */
-  /* Set the SYNCSRC[1:0] bits according to Source value */
-  /* Set the SYNCSPOL bit according to Polarity value */
-  value = (pInit->Prescaler | pInit->Source | pInit->Polarity);
-  /* Set the RELOAD[15:0] bits according to ReloadValue value */
-  value |= pInit->ReloadValue;
-  /* Set the FELIM[7:0] bits according to ErrorLimitValue value */
-  value |= (pInit->ErrorLimitValue << CRS_CFGR_FELIM_Pos);
-  WRITE_REG(CRS->CFGR, value);
-
-  /* Adjust HSI48 oscillator smooth trimming */
-  /* Set the TRIM[5:0] bits according to RCC_CRS_HSI48CalibrationValue value */
-  MODIFY_REG(CRS->CR, CRS_CR_TRIM, (pInit->HSI48CalibrationValue << CRS_CR_TRIM_Pos));
-
-  /* START AUTOMATIC SYNCHRONIZATION*/
-
-  /* Enable Automatic trimming & Frequency error counter */
-  SET_BIT(CRS->CR, CRS_CR_AUTOTRIMEN | CRS_CR_CEN);
-}
-
-/**
-  * @brief  Generate the software synchronization event
-  * @retval None
-  */
-void HAL_RCCEx_CRSSoftwareSynchronizationGenerate(void)
-{
-  LL_CRS_GenerateEvent_SWSYNC();
-}
-
-/**
-  * @brief  Return synchronization info
-  * @param  pSynchroInfo Pointer on @ref RCC_CRSSynchroInfoTypeDef structure
-  * @retval None
-  */
-void HAL_RCCEx_CRSGetSynchronizationInfo(RCC_CRSSynchroInfoTypeDef *pSynchroInfo)
-{
-  /* Check the parameter */
-  assert_param(pSynchroInfo != (void *)NULL);
-
-  /* Get the reload value */
-  pSynchroInfo->ReloadValue = LL_CRS_GetReloadCounter();
-
-  /* Get HSI48 oscillator smooth trimming */
-  pSynchroInfo->HSI48CalibrationValue = LL_CRS_GetHSI48SmoothTrimming();
-
-  /* Get Frequency error capture */
-  pSynchroInfo->FreqErrorCapture = LL_CRS_GetFreqErrorCapture();
-
-  /* Get Frequency error direction */
-  pSynchroInfo->FreqErrorDirection = LL_CRS_GetFreqErrorDirection();
-}
-
-/**
-  * @brief  Wait for CRS Synchronization status.
-  * @param  Timeout  Duration of the timeout
-  * @note   Timeout is based on the maximum time to receive a SYNC event based on synchronization
-  *         frequency.
-  * @note   If Timeout set to HAL_MAX_DELAY, HAL_TIMEOUT will be never returned.
-  * @retval Combination of Synchronization status
-  *          This parameter can be a combination of the following values:
-  *            @arg @ref RCC_CRS_TIMEOUT
-  *            @arg @ref RCC_CRS_SYNCOK
-  *            @arg @ref RCC_CRS_SYNCWARN
-  *            @arg @ref RCC_CRS_SYNCERR
-  *            @arg @ref RCC_CRS_SYNCMISS
-  *            @arg @ref RCC_CRS_TRIMOVF
-  */
-uint32_t HAL_RCCEx_CRSWaitSynchronization(uint32_t Timeout)
-{
-  uint32_t crsstatus = RCC_CRS_NONE;
-  uint32_t tickstart;
-
-  /* Get timeout */
-  tickstart = HAL_GetTick();
-
-  /* Wait for CRS flag or timeout detection */
-  do
-  {
-    if (Timeout != HAL_MAX_DELAY)
-    {
-      if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
-      {
-        crsstatus = RCC_CRS_TIMEOUT;
-      }
-    }
-    /* Check CRS SYNCOK flag  */
-    if (__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_SYNCOK))
-    {
-      /* CRS SYNC event OK */
-      crsstatus |= RCC_CRS_SYNCOK;
-
-      /* Clear CRS SYNC event OK bit */
-      __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_SYNCOK);
-    }
-
-    /* Check CRS SYNCWARN flag  */
-    if (__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_SYNCWARN))
-    {
-      /* CRS SYNC warning */
-      crsstatus |= RCC_CRS_SYNCWARN;
-
-      /* Clear CRS SYNCWARN bit */
-      __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_SYNCWARN);
-    }
-
-    /* Check CRS TRIM overflow flag  */
-    if (__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_TRIMOVF))
-    {
-      /* CRS SYNC Error */
-      crsstatus |= RCC_CRS_TRIMOVF;
-
-      /* Clear CRS Error bit */
-      __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_TRIMOVF);
-    }
-
-    /* Check CRS Error flag  */
-    if (__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_SYNCERR))
-    {
-      /* CRS SYNC Error */
-      crsstatus |= RCC_CRS_SYNCERR;
-
-      /* Clear CRS Error bit */
-      __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_SYNCERR);
-    }
-
-    /* Check CRS SYNC Missed flag  */
-    if (__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_SYNCMISS))
-    {
-      /* CRS SYNC Missed */
-      crsstatus |= RCC_CRS_SYNCMISS;
-
-      /* Clear CRS SYNC Missed bit */
-      __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_SYNCMISS);
-    }
-
-    /* Check CRS Expected SYNC flag  */
-    if (__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_ESYNC))
-    {
-      /* frequency error counter reached a zero value */
-      __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_ESYNC);
-    }
-  } while (RCC_CRS_NONE == crsstatus);
-
-  return crsstatus;
-}
-
-/**
-  * @brief Handle the Clock Recovery System interrupt request.
-  * @retval None
-  */
-void HAL_RCCEx_CRS_IRQHandler(void)
-{
-  uint32_t crserror = RCC_CRS_NONE;
-  /* Get current IT flags and IT sources values */
-  uint32_t itflags = READ_REG(CRS->ISR);
-  uint32_t itsources = READ_REG(CRS->CR);
-
-  /* Check CRS SYNCOK flag  */
-  if (((itflags & RCC_CRS_FLAG_SYNCOK) != 0U) && ((itsources & RCC_CRS_IT_SYNCOK) != 0U))
-  {
-    /* Clear CRS SYNC event OK flag */
-    LL_CRS_ClearFlag_SYNCOK();
-
-    /* user callback */
-    HAL_RCCEx_CRS_SyncOkCallback();
-  }
-  /* Check CRS SYNCWARN flag  */
-  else if (((itflags & RCC_CRS_FLAG_SYNCWARN) != 0U) && ((itsources & RCC_CRS_IT_SYNCWARN) != 0U))
-  {
-    /* Clear CRS SYNCWARN flag */
-    LL_CRS_ClearFlag_SYNCWARN();
-
-    /* user callback */
-    HAL_RCCEx_CRS_SyncWarnCallback();
-  }
-  /* Check CRS Expected SYNC flag  */
-  else if (((itflags & RCC_CRS_FLAG_ESYNC) != 0U) && ((itsources & RCC_CRS_IT_ESYNC) != 0U))
-  {
-    /* frequency error counter reached a zero value */
-    LL_CRS_ClearFlag_ESYNC();
-
-    /* user callback */
-    HAL_RCCEx_CRS_ExpectedSyncCallback();
-  }
-  /* Check CRS Error flags  */
-  else
-  {
-    if (((itflags & RCC_CRS_FLAG_ERR) != 0U) && ((itsources & RCC_CRS_IT_ERR) != 0U))
-    {
-      if ((itflags & RCC_CRS_FLAG_SYNCERR) != 0U)
-      {
-        crserror |= RCC_CRS_SYNCERR;
-      }
-      if ((itflags & RCC_CRS_FLAG_SYNCMISS) != 0U)
-      {
-        crserror |= RCC_CRS_SYNCMISS;
-      }
-      if ((itflags & RCC_CRS_FLAG_TRIMOVF) != 0U)
-      {
-        crserror |= RCC_CRS_TRIMOVF;
-      }
-
-      /* Clear CRS Error flags */
-      LL_CRS_ClearFlag_ERR();
-
-      /* user error callback */
-      HAL_RCCEx_CRS_ErrorCallback(crserror);
-    }
-  }
-}
-
-/**
-  * @brief  RCCEx Clock Recovery System SYNCOK interrupt callback.
-  * @retval none
-  */
-__weak void HAL_RCCEx_CRS_SyncOkCallback(void)
-{
-  /* NOTE : This function should not be modified, when the callback is needed,
-            the @ref HAL_RCCEx_CRS_SyncOkCallback should be implemented in the user file
-   */
-}
-
-/**
-  * @brief  RCCEx Clock Recovery System SYNCWARN interrupt callback.
-  * @retval none
-  */
-__weak void HAL_RCCEx_CRS_SyncWarnCallback(void)
-{
-  /* NOTE : This function should not be modified, when the callback is needed,
-            the HAL_RCCEx_CRS_SyncWarnCallback should be implemented in the user file
-   */
-}
-
-/**
-  * @brief  RCCEx Clock Recovery System Expected SYNC interrupt callback.
-  * @retval none
-  */
-__weak void HAL_RCCEx_CRS_ExpectedSyncCallback(void)
-{
-  /* NOTE : This function should not be modified, when the callback is needed,
-            the HAL_RCCEx_CRS_ExpectedSyncCallback should be implemented in the user file
-   */
-}
-
-/**
-  * @brief  RCCEx Clock Recovery System Error interrupt callback.
-  * @param  Error Combination of Error status.
-  *         This parameter can be a combination of the following values:
-  *           @arg @ref RCC_CRS_SYNCERR
-  *           @arg @ref RCC_CRS_SYNCMISS
-  *           @arg @ref RCC_CRS_TRIMOVF
-  * @retval none
-  */
-__weak void HAL_RCCEx_CRS_ErrorCallback(uint32_t Error)
-{
-  /* Prevent unused argument(s) compilation warning */
-  UNUSED(Error);
-
-  /* NOTE : This function should not be modified, when the callback is needed,
-            the @ref HAL_RCCEx_CRS_ErrorCallback should be implemented in the user file
-   */
-}
-
-/**
-  * @}
-  */
-#endif /* CRS */
-
-/**
-  * @}
-  */
-
-/** @addtogroup RCCEx_Private_Functions
-  * @{
-  */
-
-#if defined(SAI1)
-/**
-  * @brief  Configure the parameters N & P of PLLSAI1 and enable PLLSAI1 output clock(s).
-  * @param  PLLSAI1  pointer to an RCC_PLLSAI1InitTypeDef structure that
-  *         contains the configuration parameters N & P as well as PLLSAI1 output clock(s)
-  *
-  * @note   PLLSAI1 is temporary disable to apply new parameters
-  *
-  * @retval HAL status
-  */
-static HAL_StatusTypeDef RCCEx_PLLSAI1_ConfigNP(RCC_PLLSAI1InitTypeDef *PLLSAI1)
-{
-  uint32_t tickstart;
-  HAL_StatusTypeDef status = HAL_OK;
-
-  /* check for PLLSAI1 Parameters used to output PLLSAI1CLK */
-  assert_param(IS_RCC_PLLN_VALUE(PLLSAI1->PLLN));
-  assert_param(IS_RCC_PLLP_VALUE(PLLSAI1->PLLP));
-  assert_param(IS_RCC_PLLSAI1CLOCKOUT_VALUE(PLLSAI1->PLLSAI1ClockOut));
-
-  /* Disable the PLLSAI1 */
-  __HAL_RCC_PLLSAI1_DISABLE();
-
-  /* Get Start Tick*/
-  tickstart = HAL_GetTick();
-
-  /* Wait till PLLSAI1 is ready to be updated */
-  while (LL_RCC_PLLSAI1_IsReady() != 0U)
-  {
-    if ((HAL_GetTick() - tickstart) > PLLSAI1_TIMEOUT_VALUE)
-    {
-      status = HAL_TIMEOUT;
-      break;
-    }
-  }
-
-  if (status == HAL_OK)
-  {
-    /* Configure the PLLSAI1 Multiplication factor N */
-    __HAL_RCC_PLLSAI1_MULN_CONFIG(PLLSAI1->PLLN);
-
-    /* Configure the PLLSAI1 Division factor P */
-    __HAL_RCC_PLLSAI1_DIVP_CONFIG(PLLSAI1->PLLP);
-
-    /* Enable the PLLSAI1 again by setting PLLSAI1ON to 1*/
-    __HAL_RCC_PLLSAI1_ENABLE();
-
-    /* Get Start Tick*/
-    tickstart = HAL_GetTick();
-
-    /* Wait till PLLSAI1 is ready */
-    while (LL_RCC_PLLSAI1_IsReady() != 1U)
-    {
-      if ((HAL_GetTick() - tickstart) > PLLSAI1_TIMEOUT_VALUE)
-      {
-        status = HAL_TIMEOUT;
-        break;
-      }
-    }
-
-    if (status == HAL_OK)
-    {
-      /* Configure the PLLSAI1 Clock output(s) */
-      __HAL_RCC_PLLSAI1CLKOUT_ENABLE(PLLSAI1->PLLSAI1ClockOut);
-    }
-  }
-
-  return status;
-}
-
-/**
-  * @brief  Configure the parameters N & Q of PLLSAI1 and enable PLLSAI1 output clock(s).
-  * @param  PLLSAI1  pointer to an RCC_PLLSAI1InitTypeDef structure that
-  *         contains the configuration parameters N & Q as well as PLLSAI1 output clock(s)
-  *
-  * @note   PLLSAI1 is temporary disable to apply new parameters
-  *
-  * @retval HAL status
-  */
-static HAL_StatusTypeDef RCCEx_PLLSAI1_ConfigNQ(RCC_PLLSAI1InitTypeDef *PLLSAI1)
-{
-  uint32_t tickstart;
-  HAL_StatusTypeDef status = HAL_OK;
-
-  /* check for PLLSAI1 Parameters used to output PLLSAI1CLK */
-  assert_param(IS_RCC_PLLN_VALUE(PLLSAI1->PLLN));
-  assert_param(IS_RCC_PLLQ_VALUE(PLLSAI1->PLLQ));
-  assert_param(IS_RCC_PLLSAI1CLOCKOUT_VALUE(PLLSAI1->PLLSAI1ClockOut));
-
-  /* Disable the PLLSAI1 */
-  __HAL_RCC_PLLSAI1_DISABLE();
-
-  /* Get Start Tick*/
-  tickstart = HAL_GetTick();
-
-  /* Wait till PLLSAI1 is ready to be updated */
-  while (LL_RCC_PLLSAI1_IsReady() != 0U)
-  {
-    if ((HAL_GetTick() - tickstart) > PLLSAI1_TIMEOUT_VALUE)
-    {
-      status = HAL_TIMEOUT;
-      break;
-    }
-  }
-
-  if (status == HAL_OK)
-  {
-    /* Configure the PLLSAI1 Multiplication factor N */
-    __HAL_RCC_PLLSAI1_MULN_CONFIG(PLLSAI1->PLLN);
-    /* Configure the PLLSAI1 Division factor Q */
-    __HAL_RCC_PLLSAI1_DIVQ_CONFIG(PLLSAI1->PLLQ);
-
-    /* Enable the PLLSAI1 again by setting PLLSAI1ON to 1*/
-    __HAL_RCC_PLLSAI1_ENABLE();
-
-    /* Get Start Tick*/
-    tickstart = HAL_GetTick();
-
-    /* Wait till PLLSAI1 is ready */
-    while (LL_RCC_PLLSAI1_IsReady() != 1U)
-    {
-      if ((HAL_GetTick() - tickstart) > PLLSAI1_TIMEOUT_VALUE)
-      {
-        status = HAL_TIMEOUT;
-        break;
-      }
-    }
-
-    if (status == HAL_OK)
-    {
-      /* Configure the PLLSAI1 Clock output(s) */
-      __HAL_RCC_PLLSAI1CLKOUT_ENABLE(PLLSAI1->PLLSAI1ClockOut);
-    }
-  }
-
-  return status;
-}
-
-/**
-  * @brief  Configure the parameters N & R of PLLSAI1 and enable PLLSAI1 output clock(s).
-  * @param  PLLSAI1  pointer to an RCC_PLLSAI1InitTypeDef structure that
-  *         contains the configuration parameters N & R as well as PLLSAI1 output clock(s)
-  *
-  * @note   PLLSAI1 is temporary disable to apply new parameters
-  *
-  * @retval HAL status
-  */
-static HAL_StatusTypeDef RCCEx_PLLSAI1_ConfigNR(RCC_PLLSAI1InitTypeDef *PLLSAI1)
-{
-  uint32_t tickstart;
-  HAL_StatusTypeDef status = HAL_OK;
-
-  /* check for PLLSAI1 Parameters used to output PLLSAI1CLK */
-  assert_param(IS_RCC_PLLN_VALUE(PLLSAI1->PLLN));
-  assert_param(IS_RCC_PLLR_VALUE(PLLSAI1->PLLR));
-  assert_param(IS_RCC_PLLSAI1CLOCKOUT_VALUE(PLLSAI1->PLLSAI1ClockOut));
-
-  /* Disable the PLLSAI1 */
-  __HAL_RCC_PLLSAI1_DISABLE();
-
-  /* Get Start Tick*/
-  tickstart = HAL_GetTick();
-
-  /* Wait till PLLSAI1 is ready to be updated */
-  while (LL_RCC_PLLSAI1_IsReady() != 0U)
-  {
-    if ((HAL_GetTick() - tickstart) > PLLSAI1_TIMEOUT_VALUE)
-    {
-      status = HAL_TIMEOUT;
-      break;
-    }
-  }
-
-  if (status == HAL_OK)
-  {
-    /* Configure the PLLSAI1 Multiplication factor N */
-    __HAL_RCC_PLLSAI1_MULN_CONFIG(PLLSAI1->PLLN);
-    /* Configure the PLLSAI1 Division factor R */
-    __HAL_RCC_PLLSAI1_DIVR_CONFIG(PLLSAI1->PLLR);
-
-    /* Enable the PLLSAI1 again by setting PLLSAI1ON to 1*/
-    __HAL_RCC_PLLSAI1_ENABLE();
-
-    /* Get Start Tick*/
-    tickstart = HAL_GetTick();
-
-    /* Wait till PLLSAI1 is ready */
-    while (LL_RCC_PLLSAI1_IsReady() != 1U)
-    {
-      if ((HAL_GetTick() - tickstart) > PLLSAI1_TIMEOUT_VALUE)
-      {
-        status = HAL_TIMEOUT;
-        break;
-      }
-    }
-
-    if (status == HAL_OK)
-    {
-      /* Configure the PLLSAI1 Clock output(s) */
-      __HAL_RCC_PLLSAI1CLKOUT_ENABLE(PLLSAI1->PLLSAI1ClockOut);
-    }
-  }
-
-  return status;
-}
-#endif /* SAI1 */
-
-/**
-  * @brief  Return PLL clock (PLLPCLK) frequency used for SAI domain
-  * @retval PLLPCLK clock frequency (in Hz)
-  */
-static uint32_t RCC_PLL_GetFreqDomain_P(void)
-{
-  uint32_t pllinputfreq;
-  uint32_t pllsource;
-
-  /* PLL_VCO = (HSE_VALUE or HSI_VALUE or MSI Value / PLLM) * PLLN
-     SAI Domain clock = PLL_VCO / PLLP
-  */
-  pllsource = LL_RCC_PLL_GetMainSource();
-
-  switch (pllsource)
-  {
-    case LL_RCC_PLLSOURCE_MSI:  /* MSI used as PLL clock source */
-      pllinputfreq = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_GetRange());
-      break;
-
-    case LL_RCC_PLLSOURCE_HSI:  /* HSI used as PLL clock source */
-      pllinputfreq = HSI_VALUE;
-      break;
-
-    case LL_RCC_PLLSOURCE_HSE:  /* HSE used as PLL clock source */
-      if (LL_RCC_HSE_IsEnabledDiv2() == 1U)
-      {
-        pllinputfreq = HSE_VALUE / 2U;
-      }
-      else
-      {
-        pllinputfreq = HSE_VALUE;
-      }
-      break;
-
-    default:
-      pllinputfreq = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_GetRange());
-      break;
-  }
-  return __LL_RCC_CALC_PLLCLK_ADC_FREQ(pllinputfreq, LL_RCC_PLL_GetDivider(),
-                                       LL_RCC_PLL_GetN(), LL_RCC_PLL_GetP());
-}
-
-/**
-  * @brief  Return PLL clock (PLLQCLK) frequency used for 48 MHz domain
-  * @retval PLLQCLK clock frequency (in Hz)
-  */
-static uint32_t RCC_PLL_GetFreqDomain_Q(void)
-{
-  uint32_t pllinputfreq;
-  uint32_t pllsource;
-
-  /* PLL_VCO = (HSE_VALUE or HSI_VALUE or MSI Value/ PLLM) * PLLN
-     48M Domain clock = PLL_VCO / PLLQ
-  */
-  pllsource = LL_RCC_PLL_GetMainSource();
-
-  switch (pllsource)
-  {
-    case LL_RCC_PLLSOURCE_MSI:  /* MSI used as PLL clock source */
-      pllinputfreq = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_GetRange());
-      break;
-
-    case LL_RCC_PLLSOURCE_HSI:  /* HSI used as PLL clock source */
-      pllinputfreq = HSI_VALUE;
-      break;
-
-    case LL_RCC_PLLSOURCE_HSE:  /* HSE used as PLL clock source */
-      if (LL_RCC_HSE_IsEnabledDiv2() == 1U)
-      {
-        pllinputfreq = HSE_VALUE / 2U;
-      }
-      else
-      {
-        pllinputfreq = HSE_VALUE;
-      }
-
-      break;
-
-    default:
-      pllinputfreq = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_GetRange());
-      break;
-  }
-  return __LL_RCC_CALC_PLLCLK_48M_FREQ(pllinputfreq, LL_RCC_PLL_GetDivider(),
-                                       LL_RCC_PLL_GetN(), LL_RCC_PLL_GetQ());
-}
-
-#if defined(SAI1)
-/**
-  * @brief  Return PLLSAI1 clock (PLLSAI1RCLK) frequency used for ADC domain
-  * @retval PLLSAI1RCLK clock frequency (in Hz)
-  */
-static uint32_t RCC_PLLSAI1_GetFreqDomain_R(void)
-{
-  uint32_t pllinputfreq;
-  uint32_t pllsource;
-
-  /* PLLSAI1_VCO = (HSE_VALUE or HSI_VALUE or MSI Value/ PLLM) * PLLSAI1N */
-  /* 48M Domain clock  = PLLSAI1_VCO / PLLSAI1R */
-  pllsource = LL_RCC_PLL_GetMainSource();
-
-  switch (pllsource)
-  {
-    case LL_RCC_PLLSOURCE_MSI:  /* MSI used as PLLSAI1 clock source */
-      pllinputfreq = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_GetRange());
-      break;
-
-    case LL_RCC_PLLSOURCE_HSI:  /* HSI used as PLLSAI1 clock source */
-      pllinputfreq = HSI_VALUE;
-      break;
-
-    case LL_RCC_PLLSOURCE_HSE:  /* HSE used as PLLSAI1 clock source */
-      if (LL_RCC_HSE_IsEnabledDiv2() == 1U)
-      {
-        pllinputfreq = HSE_VALUE / 2U;
-      }
-      else
-      {
-        pllinputfreq = HSE_VALUE;
-      }
-      break;
-
-    default:
-      pllinputfreq = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_GetRange());
-      break;
-  }
-  return __LL_RCC_CALC_PLLSAI1_ADC_FREQ(pllinputfreq, LL_RCC_PLL_GetDivider(),
-                                        LL_RCC_PLLSAI1_GetN(), LL_RCC_PLLSAI1_GetR());
-}
-
-/**
-  * @brief  Return PLLSAI1 clock (PLLSAI1PCLK) frequency used for SAI domain
-  * @retval PLLSAI1PCLK clock frequency (in Hz)
-  */
-static uint32_t RCC_PLLSAI1_GetFreqDomain_P(void)
-{
-  uint32_t pllinputfreq;
-  uint32_t pllsource;
-
-  /* PLLSAI1_VCO = (HSE_VALUE or HSI_VALUE or MSI Value/ PLLM) * PLLSAI1N */
-  /* SAI Domain clock  = PLLSAI1_VCO / PLLSAI1P */
-  pllsource = LL_RCC_PLL_GetMainSource();
-
-  switch (pllsource)
-  {
-    case LL_RCC_PLLSOURCE_MSI:  /* MSI used as PLLSAI1 clock source */
-      pllinputfreq = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_GetRange());
-      break;
-
-    case LL_RCC_PLLSOURCE_HSI:  /* HSI used as PLLSAI1 clock source */
-      pllinputfreq = HSI_VALUE;
-      break;
-
-    case LL_RCC_PLLSOURCE_HSE:  /* HSE used as PLLSAI1 clock source */
-      if (LL_RCC_HSE_IsEnabledDiv2() == 1U)
-      {
-        pllinputfreq = HSE_VALUE / 2U;
-      }
-      else
-      {
-        pllinputfreq = HSE_VALUE;
-      }
-      break;
-
-    default:
-      pllinputfreq = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_GetRange());
-      break;
-  }
-  return __LL_RCC_CALC_PLLSAI1_SAI_FREQ(pllinputfreq, LL_RCC_PLL_GetDivider(),
-                                        LL_RCC_PLLSAI1_GetN(), LL_RCC_PLLSAI1_GetP());
-}
-
-/**
-  * @brief  Return PLLSAI1 clock (PLLSAI1QCLK) frequency used for 48Mhz domain
-  * @retval PLLSAI1QCLK clock frequency (in Hz)
-  */
-static uint32_t RCC_PLLSAI1_GetFreqDomain_Q(void)
-{
-  uint32_t pllinputfreq;
-  uint32_t pllsource;
-
-  /* PLLSAI1_VCO = (HSE_VALUE or HSI_VALUE or MSI Value/ PLLM) * PLLSAI1N */
-  /* 48M Domain clock  = PLLSAI1_VCO / PLLSAI1Q */
-  pllsource = LL_RCC_PLL_GetMainSource();
-
-  switch (pllsource)
-  {
-    case LL_RCC_PLLSOURCE_MSI:  /* MSI used as PLLSAI1 clock source */
-      pllinputfreq = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_GetRange());
-      break;
-
-    case LL_RCC_PLLSOURCE_HSI:  /* HSI used as PLLSAI1 clock source */
-      pllinputfreq = HSI_VALUE;
-      break;
-
-    case LL_RCC_PLLSOURCE_HSE:  /* HSE used as PLLSAI1 clock source */
-      if (LL_RCC_HSE_IsEnabledDiv2() == 1U)
-      {
-        pllinputfreq = HSE_VALUE / 2U;
-      }
-      else
-      {
-        pllinputfreq = HSE_VALUE;
-      }
-      break;
-
-    default:
-      pllinputfreq = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_GetRange());
-      break;
-  }
-  return __LL_RCC_CALC_PLLSAI1_48M_FREQ(pllinputfreq, LL_RCC_PLL_GetDivider(),
-                                        LL_RCC_PLLSAI1_GetN(), LL_RCC_PLLSAI1_GetQ());
-}
-#endif /* SAI1 */
-
-/**
-  * @}
-  */
-
-#endif /* HAL_RCC_MODULE_ENABLED */
-
-/**
-  * @}
-  */
-
-/**
-  * @}
-  */

+ 0 - 7903
non_catalog_apps/flipperscope/lib/adc/stm32wbxx_hal_tim.c

@@ -1,7903 +0,0 @@
-/**
-  ******************************************************************************
-  * @file    stm32wbxx_hal_tim.c
-  * @author  MCD Application Team
-  * @brief   TIM HAL module driver.
-  *          This file provides firmware functions to manage the following
-  *          functionalities of the Timer (TIM) peripheral:
-  *           + TIM Time Base Initialization
-  *           + TIM Time Base Start
-  *           + TIM Time Base Start Interruption
-  *           + TIM Time Base Start DMA
-  *           + TIM Output Compare/PWM Initialization
-  *           + TIM Output Compare/PWM Channel Configuration
-  *           + TIM Output Compare/PWM  Start
-  *           + TIM Output Compare/PWM  Start Interruption
-  *           + TIM Output Compare/PWM Start DMA
-  *           + TIM Input Capture Initialization
-  *           + TIM Input Capture Channel Configuration
-  *           + TIM Input Capture Start
-  *           + TIM Input Capture Start Interruption
-  *           + TIM Input Capture Start DMA
-  *           + TIM One Pulse Initialization
-  *           + TIM One Pulse Channel Configuration
-  *           + TIM One Pulse Start
-  *           + TIM Encoder Interface Initialization
-  *           + TIM Encoder Interface Start
-  *           + TIM Encoder Interface Start Interruption
-  *           + TIM Encoder Interface Start DMA
-  *           + Commutation Event configuration with Interruption and DMA
-  *           + TIM OCRef clear configuration
-  *           + TIM External Clock configuration
-  ******************************************************************************
-  * @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
-  ==============================================================================
-                      ##### TIMER Generic features #####
-  ==============================================================================
-  [..] The Timer features include:
-       (#) 16-bit up, down, up/down auto-reload counter.
-       (#) 16-bit programmable prescaler allowing dividing (also on the fly) the
-           counter clock frequency either by any factor between 1 and 65536.
-       (#) Up to 4 independent channels for:
-           (++) Input Capture
-           (++) Output Compare
-           (++) PWM generation (Edge and Center-aligned Mode)
-           (++) One-pulse mode output
-       (#) Synchronization circuit to control the timer with external signals and to interconnect
-            several timers together.
-       (#) Supports incremental encoder for positioning purposes
-
-            ##### How to use this driver #####
-  ==============================================================================
-    [..]
-     (#) Initialize the TIM low level resources by implementing the following functions
-         depending on the selected feature:
-           (++) Time Base : HAL_TIM_Base_MspInit()
-           (++) Input Capture : HAL_TIM_IC_MspInit()
-           (++) Output Compare : HAL_TIM_OC_MspInit()
-           (++) PWM generation : HAL_TIM_PWM_MspInit()
-           (++) One-pulse mode output : HAL_TIM_OnePulse_MspInit()
-           (++) Encoder mode output : HAL_TIM_Encoder_MspInit()
-
-     (#) Initialize the TIM low level resources :
-        (##) Enable the TIM interface clock using __HAL_RCC_TIMx_CLK_ENABLE();
-        (##) TIM pins configuration
-            (+++) Enable the clock for the TIM GPIOs using the following function:
-             __HAL_RCC_GPIOx_CLK_ENABLE();
-            (+++) Configure these TIM pins in Alternate function mode using HAL_GPIO_Init();
-
-     (#) The external Clock can be configured, if needed (the default clock is the
-         internal clock from the APBx), using the following function:
-         HAL_TIM_ConfigClockSource, the clock configuration should be done before
-         any start function.
-
-     (#) Configure the TIM in the desired functioning mode using one of the
-       Initialization function of this driver:
-       (++) HAL_TIM_Base_Init: to use the Timer to generate a simple time base
-       (++) HAL_TIM_OC_Init and HAL_TIM_OC_ConfigChannel: to use the Timer to generate an
-            Output Compare signal.
-       (++) HAL_TIM_PWM_Init and HAL_TIM_PWM_ConfigChannel: to use the Timer to generate a
-            PWM signal.
-       (++) HAL_TIM_IC_Init and HAL_TIM_IC_ConfigChannel: to use the Timer to measure an
-            external signal.
-       (++) HAL_TIM_OnePulse_Init and HAL_TIM_OnePulse_ConfigChannel: to use the Timer
-            in One Pulse Mode.
-       (++) HAL_TIM_Encoder_Init: to use the Timer Encoder Interface.
-
-     (#) Activate the TIM peripheral using one of the start functions depending from the feature used:
-           (++) Time Base : HAL_TIM_Base_Start(), HAL_TIM_Base_Start_DMA(), HAL_TIM_Base_Start_IT()
-           (++) Input Capture :  HAL_TIM_IC_Start(), HAL_TIM_IC_Start_DMA(), HAL_TIM_IC_Start_IT()
-           (++) Output Compare : HAL_TIM_OC_Start(), HAL_TIM_OC_Start_DMA(), HAL_TIM_OC_Start_IT()
-           (++) PWM generation : HAL_TIM_PWM_Start(), HAL_TIM_PWM_Start_DMA(), HAL_TIM_PWM_Start_IT()
-           (++) One-pulse mode output : HAL_TIM_OnePulse_Start(), HAL_TIM_OnePulse_Start_IT()
-           (++) Encoder mode output : HAL_TIM_Encoder_Start(), HAL_TIM_Encoder_Start_DMA(), HAL_TIM_Encoder_Start_IT().
-
-     (#) The DMA Burst is managed with the two following functions:
-         HAL_TIM_DMABurst_WriteStart()
-         HAL_TIM_DMABurst_ReadStart()
-
-    *** Callback registration ***
-  =============================================
-
-  [..]
-  The compilation define  USE_HAL_TIM_REGISTER_CALLBACKS when set to 1
-  allows the user to configure dynamically the driver callbacks.
-
-  [..]
-  Use Function HAL_TIM_RegisterCallback() to register a callback.
-  HAL_TIM_RegisterCallback() takes as parameters the HAL peripheral handle,
-  the Callback ID and a pointer to the user callback function.
-
-  [..]
-  Use function HAL_TIM_UnRegisterCallback() to reset a callback to the default
-  weak function.
-  HAL_TIM_UnRegisterCallback takes as parameters the HAL peripheral handle,
-  and the Callback ID.
-
-  [..]
-  These functions allow to register/unregister following callbacks:
-    (+) Base_MspInitCallback              : TIM Base Msp Init Callback.
-    (+) Base_MspDeInitCallback            : TIM Base Msp DeInit Callback.
-    (+) IC_MspInitCallback                : TIM IC Msp Init Callback.
-    (+) IC_MspDeInitCallback              : TIM IC Msp DeInit Callback.
-    (+) OC_MspInitCallback                : TIM OC Msp Init Callback.
-    (+) OC_MspDeInitCallback              : TIM OC Msp DeInit Callback.
-    (+) PWM_MspInitCallback               : TIM PWM Msp Init Callback.
-    (+) PWM_MspDeInitCallback             : TIM PWM Msp DeInit Callback.
-    (+) OnePulse_MspInitCallback          : TIM One Pulse Msp Init Callback.
-    (+) OnePulse_MspDeInitCallback        : TIM One Pulse Msp DeInit Callback.
-    (+) Encoder_MspInitCallback           : TIM Encoder Msp Init Callback.
-    (+) Encoder_MspDeInitCallback         : TIM Encoder Msp DeInit Callback.
-    (+) HallSensor_MspInitCallback        : TIM Hall Sensor Msp Init Callback.
-    (+) HallSensor_MspDeInitCallback      : TIM Hall Sensor Msp DeInit Callback.
-    (+) PeriodElapsedCallback             : TIM Period Elapsed Callback.
-    (+) PeriodElapsedHalfCpltCallback     : TIM Period Elapsed half complete Callback.
-    (+) TriggerCallback                   : TIM Trigger Callback.
-    (+) TriggerHalfCpltCallback           : TIM Trigger half complete Callback.
-    (+) IC_CaptureCallback                : TIM Input Capture Callback.
-    (+) IC_CaptureHalfCpltCallback        : TIM Input Capture half complete Callback.
-    (+) OC_DelayElapsedCallback           : TIM Output Compare Delay Elapsed Callback.
-    (+) PWM_PulseFinishedCallback         : TIM PWM Pulse Finished Callback.
-    (+) PWM_PulseFinishedHalfCpltCallback : TIM PWM Pulse Finished half complete Callback.
-    (+) ErrorCallback                     : TIM Error Callback.
-    (+) CommutationCallback               : TIM Commutation Callback.
-    (+) CommutationHalfCpltCallback       : TIM Commutation half complete Callback.
-    (+) BreakCallback                     : TIM Break Callback.
-    (+) Break2Callback                    : TIM Break2 Callback.
-
-  [..]
-By default, after the Init and when the state is HAL_TIM_STATE_RESET
-all interrupt callbacks are set to the corresponding weak functions:
-  examples HAL_TIM_TriggerCallback(), HAL_TIM_ErrorCallback().
-
-  [..]
-  Exception done for MspInit and MspDeInit functions that are reset to the legacy weak
-  functionalities in the Init / DeInit only when these callbacks are null
-  (not registered beforehand). If not, MspInit or MspDeInit are not null, the Init / DeInit
-    keep and use the user MspInit / MspDeInit callbacks(registered beforehand)
-
-  [..]
-    Callbacks can be registered / unregistered in HAL_TIM_STATE_READY state only.
-    Exception done MspInit / MspDeInit that can be registered / unregistered
-    in HAL_TIM_STATE_READY or HAL_TIM_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_TIM_RegisterCallback() before calling DeInit or Init function.
-
-  [..]
-      When The compilation define USE_HAL_TIM_REGISTER_CALLBACKS is set to 0 or
-      not defined, the callback registration feature is not available and all callbacks
-      are set to the corresponding weak functions.
-
-  @endverbatim
-  ******************************************************************************
-  */
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32wbxx_hal.h"
-
-/** @addtogroup STM32WBxx_HAL_Driver
-  * @{
-  */
-
-/** @defgroup TIM TIM
-  * @brief TIM HAL module driver
-  * @{
-  */
-
-#ifdef HAL_TIM_MODULE_ENABLED
-
-/* Private typedef -----------------------------------------------------------*/
-/* Private define ------------------------------------------------------------*/
-/** @addtogroup TIM_Private_Constants
-  * @{
-  */
-#define TIMx_AF1_ETRSEL TIM1_AF1_ETRSEL
-/**
-  * @}
-  */
-
-/* Private macros ------------------------------------------------------------*/
-/* Private variables ---------------------------------------------------------*/
-/* Private function prototypes -----------------------------------------------*/
-/** @addtogroup TIM_Private_Functions
-  * @{
-  */
-static void TIM_OC1_SetConfig(TIM_TypeDef *TIMx, const TIM_OC_InitTypeDef *OC_Config);
-static void TIM_OC3_SetConfig(TIM_TypeDef *TIMx, const TIM_OC_InitTypeDef *OC_Config);
-static void TIM_OC4_SetConfig(TIM_TypeDef *TIMx, const TIM_OC_InitTypeDef *OC_Config);
-static void TIM_OC5_SetConfig(TIM_TypeDef *TIMx, const TIM_OC_InitTypeDef *OC_Config);
-static void TIM_OC6_SetConfig(TIM_TypeDef *TIMx, const TIM_OC_InitTypeDef *OC_Config);
-static void TIM_TI1_ConfigInputStage(TIM_TypeDef *TIMx, uint32_t TIM_ICPolarity, uint32_t TIM_ICFilter);
-static void TIM_TI2_SetConfig(TIM_TypeDef *TIMx, uint32_t TIM_ICPolarity, uint32_t TIM_ICSelection,
-                              uint32_t TIM_ICFilter);
-static void TIM_TI2_ConfigInputStage(TIM_TypeDef *TIMx, uint32_t TIM_ICPolarity, uint32_t TIM_ICFilter);
-static void TIM_TI3_SetConfig(TIM_TypeDef *TIMx, uint32_t TIM_ICPolarity, uint32_t TIM_ICSelection,
-                              uint32_t TIM_ICFilter);
-static void TIM_TI4_SetConfig(TIM_TypeDef *TIMx, uint32_t TIM_ICPolarity, uint32_t TIM_ICSelection,
-                              uint32_t TIM_ICFilter);
-static void TIM_ITRx_SetConfig(TIM_TypeDef *TIMx, uint32_t InputTriggerSource);
-static void TIM_DMAPeriodElapsedCplt(DMA_HandleTypeDef *hdma);
-static void TIM_DMAPeriodElapsedHalfCplt(DMA_HandleTypeDef *hdma);
-static void TIM_DMADelayPulseCplt(DMA_HandleTypeDef *hdma);
-static void TIM_DMATriggerCplt(DMA_HandleTypeDef *hdma);
-static void TIM_DMATriggerHalfCplt(DMA_HandleTypeDef *hdma);
-static HAL_StatusTypeDef TIM_SlaveTimer_SetConfig(TIM_HandleTypeDef *htim,
-                                                  const TIM_SlaveConfigTypeDef *sSlaveConfig);
-/**
-  * @}
-  */
-/* Exported functions --------------------------------------------------------*/
-
-/** @defgroup TIM_Exported_Functions TIM Exported Functions
-  * @{
-  */
-
-/** @defgroup TIM_Exported_Functions_Group1 TIM Time Base functions
-  *  @brief    Time Base functions
-  *
-@verbatim
-  ==============================================================================
-              ##### Time Base functions #####
-  ==============================================================================
-  [..]
-    This section provides functions allowing to:
-    (+) Initialize and configure the TIM base.
-    (+) De-initialize the TIM base.
-    (+) Start the Time Base.
-    (+) Stop the Time Base.
-    (+) Start the Time Base and enable interrupt.
-    (+) Stop the Time Base and disable interrupt.
-    (+) Start the Time Base and enable DMA transfer.
-    (+) Stop the Time Base and disable DMA transfer.
-
-@endverbatim
-  * @{
-  */
-/**
-  * @brief  Initializes the TIM Time base Unit according to the specified
-  *         parameters in the TIM_HandleTypeDef and initialize the associated handle.
-  * @note   Switching from Center Aligned counter mode to Edge counter mode (or reverse)
-  *         requires a timer reset to avoid unexpected direction
-  *         due to DIR bit readonly in center aligned mode.
-  *         Ex: call @ref HAL_TIM_Base_DeInit() before HAL_TIM_Base_Init()
-  * @param  htim TIM Base handle
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_TIM_Base_Init(TIM_HandleTypeDef *htim)
-{
-  /* Check the TIM handle allocation */
-  if (htim == NULL)
-  {
-    return HAL_ERROR;
-  }
-
-  /* Check the parameters */
-  assert_param(IS_TIM_INSTANCE(htim->Instance));
-  assert_param(IS_TIM_COUNTER_MODE(htim->Init.CounterMode));
-  assert_param(IS_TIM_CLOCKDIVISION_DIV(htim->Init.ClockDivision));
-  assert_param(IS_TIM_PERIOD(htim, htim->Init.Period));
-  assert_param(IS_TIM_AUTORELOAD_PRELOAD(htim->Init.AutoReloadPreload));
-
-  if (htim->State == HAL_TIM_STATE_RESET)
-  {
-    /* Allocate lock resource and initialize it */
-    htim->Lock = HAL_UNLOCKED;
-
-#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
-    /* Reset interrupt callbacks to legacy weak callbacks */
-    TIM_ResetCallback(htim);
-
-    if (htim->Base_MspInitCallback == NULL)
-    {
-      htim->Base_MspInitCallback = HAL_TIM_Base_MspInit;
-    }
-    /* Init the low level hardware : GPIO, CLOCK, NVIC */
-    htim->Base_MspInitCallback(htim);
-#else
-    /* Init the low level hardware : GPIO, CLOCK, NVIC */
-    HAL_TIM_Base_MspInit(htim);
-#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
-  }
-
-  /* Set the TIM state */
-  htim->State = HAL_TIM_STATE_BUSY;
-
-  /* Set the Time Base configuration */
-  TIM_Base_SetConfig(htim->Instance, &htim->Init);
-
-  /* Initialize the DMA burst operation state */
-  htim->DMABurstState = HAL_DMA_BURST_STATE_READY;
-
-  /* Initialize the TIM channels state */
-  TIM_CHANNEL_STATE_SET_ALL(htim, HAL_TIM_CHANNEL_STATE_READY);
-  TIM_CHANNEL_N_STATE_SET_ALL(htim, HAL_TIM_CHANNEL_STATE_READY);
-
-  /* Initialize the TIM state*/
-  htim->State = HAL_TIM_STATE_READY;
-
-  return HAL_OK;
-}
-
-/**
-  * @brief  DeInitializes the TIM Base peripheral
-  * @param  htim TIM Base handle
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_TIM_Base_DeInit(TIM_HandleTypeDef *htim)
-{
-  /* Check the parameters */
-  assert_param(IS_TIM_INSTANCE(htim->Instance));
-
-  htim->State = HAL_TIM_STATE_BUSY;
-
-  /* Disable the TIM Peripheral Clock */
-  __HAL_TIM_DISABLE(htim);
-
-#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
-  if (htim->Base_MspDeInitCallback == NULL)
-  {
-    htim->Base_MspDeInitCallback = HAL_TIM_Base_MspDeInit;
-  }
-  /* DeInit the low level hardware */
-  htim->Base_MspDeInitCallback(htim);
-#else
-  /* DeInit the low level hardware: GPIO, CLOCK, NVIC */
-  HAL_TIM_Base_MspDeInit(htim);
-#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
-
-  /* Change the DMA burst operation state */
-  htim->DMABurstState = HAL_DMA_BURST_STATE_RESET;
-
-  /* Change the TIM channels state */
-  TIM_CHANNEL_STATE_SET_ALL(htim, HAL_TIM_CHANNEL_STATE_RESET);
-  TIM_CHANNEL_N_STATE_SET_ALL(htim, HAL_TIM_CHANNEL_STATE_RESET);
-
-  /* Change TIM state */
-  htim->State = HAL_TIM_STATE_RESET;
-
-  /* Release Lock */
-  __HAL_UNLOCK(htim);
-
-  return HAL_OK;
-}
-
-/**
-  * @brief  Initializes the TIM Base MSP.
-  * @param  htim TIM Base handle
-  * @retval None
-  */
-__weak void HAL_TIM_Base_MspInit(TIM_HandleTypeDef *htim)
-{
-  /* Prevent unused argument(s) compilation warning */
-  UNUSED(htim);
-
-  /* NOTE : This function should not be modified, when the callback is needed,
-            the HAL_TIM_Base_MspInit could be implemented in the user file
-   */
-}
-
-/**
-  * @brief  DeInitializes TIM Base MSP.
-  * @param  htim TIM Base handle
-  * @retval None
-  */
-__weak void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef *htim)
-{
-  /* Prevent unused argument(s) compilation warning */
-  UNUSED(htim);
-
-  /* NOTE : This function should not be modified, when the callback is needed,
-            the HAL_TIM_Base_MspDeInit could be implemented in the user file
-   */
-}
-
-
-/**
-  * @brief  Starts the TIM Base generation.
-  * @param  htim TIM Base handle
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_TIM_Base_Start(TIM_HandleTypeDef *htim)
-{
-  uint32_t tmpsmcr;
-
-  /* Check the parameters */
-  assert_param(IS_TIM_INSTANCE(htim->Instance));
-
-  /* Check the TIM state */
-  if (htim->State != HAL_TIM_STATE_READY)
-  {
-    return HAL_ERROR;
-  }
-
-  /* Set the TIM state */
-  htim->State = HAL_TIM_STATE_BUSY;
-
-  /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */
-  if (IS_TIM_SLAVE_INSTANCE(htim->Instance))
-  {
-    tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS;
-    if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr))
-    {
-      __HAL_TIM_ENABLE(htim);
-    }
-  }
-  else
-  {
-    __HAL_TIM_ENABLE(htim);
-  }
-
-  /* Return function status */
-  return HAL_OK;
-}
-
-/**
-  * @brief  Stops the TIM Base generation.
-  * @param  htim TIM Base handle
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_TIM_Base_Stop(TIM_HandleTypeDef *htim)
-{
-  /* Check the parameters */
-  assert_param(IS_TIM_INSTANCE(htim->Instance));
-
-  /* Disable the Peripheral */
-  __HAL_TIM_DISABLE(htim);
-
-  /* Set the TIM state */
-  htim->State = HAL_TIM_STATE_READY;
-
-  /* Return function status */
-  return HAL_OK;
-}
-
-/**
-  * @brief  Starts the TIM Base generation in interrupt mode.
-  * @param  htim TIM Base handle
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_TIM_Base_Start_IT(TIM_HandleTypeDef *htim)
-{
-  uint32_t tmpsmcr;
-
-  /* Check the parameters */
-  assert_param(IS_TIM_INSTANCE(htim->Instance));
-
-  /* Check the TIM state */
-  if (htim->State != HAL_TIM_STATE_READY)
-  {
-    return HAL_ERROR;
-  }
-
-  /* Set the TIM state */
-  htim->State = HAL_TIM_STATE_BUSY;
-
-  /* Enable the TIM Update interrupt */
-  __HAL_TIM_ENABLE_IT(htim, TIM_IT_UPDATE);
-
-  /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */
-  if (IS_TIM_SLAVE_INSTANCE(htim->Instance))
-  {
-    tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS;
-    if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr))
-    {
-      __HAL_TIM_ENABLE(htim);
-    }
-  }
-  else
-  {
-    __HAL_TIM_ENABLE(htim);
-  }
-
-  /* Return function status */
-  return HAL_OK;
-}
-
-/**
-  * @brief  Stops the TIM Base generation in interrupt mode.
-  * @param  htim TIM Base handle
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_TIM_Base_Stop_IT(TIM_HandleTypeDef *htim)
-{
-  /* Check the parameters */
-  assert_param(IS_TIM_INSTANCE(htim->Instance));
-
-  /* Disable the TIM Update interrupt */
-  __HAL_TIM_DISABLE_IT(htim, TIM_IT_UPDATE);
-
-  /* Disable the Peripheral */
-  __HAL_TIM_DISABLE(htim);
-
-  /* Set the TIM state */
-  htim->State = HAL_TIM_STATE_READY;
-
-  /* Return function status */
-  return HAL_OK;
-}
-
-/**
-  * @brief  Starts the TIM Base generation in DMA mode.
-  * @param  htim TIM Base handle
-  * @param  pData The source Buffer address.
-  * @param  Length The length of data to be transferred from memory to peripheral.
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_TIM_Base_Start_DMA(TIM_HandleTypeDef *htim, const uint32_t *pData, uint16_t Length)
-{
-  uint32_t tmpsmcr;
-
-  /* Check the parameters */
-  assert_param(IS_TIM_DMA_INSTANCE(htim->Instance));
-
-  /* Set the TIM state */
-  if (htim->State == HAL_TIM_STATE_BUSY)
-  {
-    return HAL_BUSY;
-  }
-  else if (htim->State == HAL_TIM_STATE_READY)
-  {
-    if ((pData == NULL) || (Length == 0U))
-    {
-      return HAL_ERROR;
-    }
-    else
-    {
-      htim->State = HAL_TIM_STATE_BUSY;
-    }
-  }
-  else
-  {
-    return HAL_ERROR;
-  }
-
-  /* Set the DMA Period elapsed callbacks */
-  htim->hdma[TIM_DMA_ID_UPDATE]->XferCpltCallback = TIM_DMAPeriodElapsedCplt;
-  htim->hdma[TIM_DMA_ID_UPDATE]->XferHalfCpltCallback = TIM_DMAPeriodElapsedHalfCplt;
-
-  /* Set the DMA error callback */
-  htim->hdma[TIM_DMA_ID_UPDATE]->XferErrorCallback = TIM_DMAError ;
-
-  /* Enable the DMA channel */
-  if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_UPDATE], (uint32_t)pData, (uint32_t)&htim->Instance->ARR,
-                       Length) != HAL_OK)
-  {
-    /* Return error status */
-    return HAL_ERROR;
-  }
-
-  /* Enable the TIM Update DMA request */
-  __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_UPDATE);
-
-  /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */
-  if (IS_TIM_SLAVE_INSTANCE(htim->Instance))
-  {
-    tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS;
-    if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr))
-    {
-      __HAL_TIM_ENABLE(htim);
-    }
-  }
-  else
-  {
-    __HAL_TIM_ENABLE(htim);
-  }
-
-  /* Return function status */
-  return HAL_OK;
-}
-
-/**
-  * @brief  Stops the TIM Base generation in DMA mode.
-  * @param  htim TIM Base handle
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_TIM_Base_Stop_DMA(TIM_HandleTypeDef *htim)
-{
-  /* Check the parameters */
-  assert_param(IS_TIM_DMA_INSTANCE(htim->Instance));
-
-  /* Disable the TIM Update DMA request */
-  __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_UPDATE);
-
-  (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_UPDATE]);
-
-  /* Disable the Peripheral */
-  __HAL_TIM_DISABLE(htim);
-
-  /* Set the TIM state */
-  htim->State = HAL_TIM_STATE_READY;
-
-  /* Return function status */
-  return HAL_OK;
-}
-
-/**
-  * @}
-  */
-
-/** @defgroup TIM_Exported_Functions_Group2 TIM Output Compare functions
-  *  @brief    TIM Output Compare functions
-  *
-@verbatim
-  ==============================================================================
-                  ##### TIM Output Compare functions #####
-  ==============================================================================
-  [..]
-    This section provides functions allowing to:
-    (+) Initialize and configure the TIM Output Compare.
-    (+) De-initialize the TIM Output Compare.
-    (+) Start the TIM Output Compare.
-    (+) Stop the TIM Output Compare.
-    (+) Start the TIM Output Compare and enable interrupt.
-    (+) Stop the TIM Output Compare and disable interrupt.
-    (+) Start the TIM Output Compare and enable DMA transfer.
-    (+) Stop the TIM Output Compare and disable DMA transfer.
-
-@endverbatim
-  * @{
-  */
-/**
-  * @brief  Initializes the TIM Output Compare according to the specified
-  *         parameters in the TIM_HandleTypeDef and initializes the associated handle.
-  * @note   Switching from Center Aligned counter mode to Edge counter mode (or reverse)
-  *         requires a timer reset to avoid unexpected direction
-  *         due to DIR bit readonly in center aligned mode.
-  *         Ex: call @ref HAL_TIM_OC_DeInit() before HAL_TIM_OC_Init()
-  * @param  htim TIM Output Compare handle
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_TIM_OC_Init(TIM_HandleTypeDef *htim)
-{
-  /* Check the TIM handle allocation */
-  if (htim == NULL)
-  {
-    return HAL_ERROR;
-  }
-
-  /* Check the parameters */
-  assert_param(IS_TIM_INSTANCE(htim->Instance));
-  assert_param(IS_TIM_COUNTER_MODE(htim->Init.CounterMode));
-  assert_param(IS_TIM_CLOCKDIVISION_DIV(htim->Init.ClockDivision));
-  assert_param(IS_TIM_PERIOD(htim, htim->Init.Period));
-  assert_param(IS_TIM_AUTORELOAD_PRELOAD(htim->Init.AutoReloadPreload));
-
-  if (htim->State == HAL_TIM_STATE_RESET)
-  {
-    /* Allocate lock resource and initialize it */
-    htim->Lock = HAL_UNLOCKED;
-
-#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
-    /* Reset interrupt callbacks to legacy weak callbacks */
-    TIM_ResetCallback(htim);
-
-    if (htim->OC_MspInitCallback == NULL)
-    {
-      htim->OC_MspInitCallback = HAL_TIM_OC_MspInit;
-    }
-    /* Init the low level hardware : GPIO, CLOCK, NVIC */
-    htim->OC_MspInitCallback(htim);
-#else
-    /* Init the low level hardware : GPIO, CLOCK, NVIC and DMA */
-    HAL_TIM_OC_MspInit(htim);
-#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
-  }
-
-  /* Set the TIM state */
-  htim->State = HAL_TIM_STATE_BUSY;
-
-  /* Init the base time for the Output Compare */
-  TIM_Base_SetConfig(htim->Instance,  &htim->Init);
-
-  /* Initialize the DMA burst operation state */
-  htim->DMABurstState = HAL_DMA_BURST_STATE_READY;
-
-  /* Initialize the TIM channels state */
-  TIM_CHANNEL_STATE_SET_ALL(htim, HAL_TIM_CHANNEL_STATE_READY);
-  TIM_CHANNEL_N_STATE_SET_ALL(htim, HAL_TIM_CHANNEL_STATE_READY);
-
-  /* Initialize the TIM state*/
-  htim->State = HAL_TIM_STATE_READY;
-
-  return HAL_OK;
-}
-
-/**
-  * @brief  DeInitializes the TIM peripheral
-  * @param  htim TIM Output Compare handle
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_TIM_OC_DeInit(TIM_HandleTypeDef *htim)
-{
-  /* Check the parameters */
-  assert_param(IS_TIM_INSTANCE(htim->Instance));
-
-  htim->State = HAL_TIM_STATE_BUSY;
-
-  /* Disable the TIM Peripheral Clock */
-  __HAL_TIM_DISABLE(htim);
-
-#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
-  if (htim->OC_MspDeInitCallback == NULL)
-  {
-    htim->OC_MspDeInitCallback = HAL_TIM_OC_MspDeInit;
-  }
-  /* DeInit the low level hardware */
-  htim->OC_MspDeInitCallback(htim);
-#else
-  /* DeInit the low level hardware: GPIO, CLOCK, NVIC and DMA */
-  HAL_TIM_OC_MspDeInit(htim);
-#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
-
-  /* Change the DMA burst operation state */
-  htim->DMABurstState = HAL_DMA_BURST_STATE_RESET;
-
-  /* Change the TIM channels state */
-  TIM_CHANNEL_STATE_SET_ALL(htim, HAL_TIM_CHANNEL_STATE_RESET);
-  TIM_CHANNEL_N_STATE_SET_ALL(htim, HAL_TIM_CHANNEL_STATE_RESET);
-
-  /* Change TIM state */
-  htim->State = HAL_TIM_STATE_RESET;
-
-  /* Release Lock */
-  __HAL_UNLOCK(htim);
-
-  return HAL_OK;
-}
-
-/**
-  * @brief  Initializes the TIM Output Compare MSP.
-  * @param  htim TIM Output Compare handle
-  * @retval None
-  */
-__weak void HAL_TIM_OC_MspInit(TIM_HandleTypeDef *htim)
-{
-  /* Prevent unused argument(s) compilation warning */
-  UNUSED(htim);
-
-  /* NOTE : This function should not be modified, when the callback is needed,
-            the HAL_TIM_OC_MspInit could be implemented in the user file
-   */
-}
-
-/**
-  * @brief  DeInitializes TIM Output Compare MSP.
-  * @param  htim TIM Output Compare handle
-  * @retval None
-  */
-__weak void HAL_TIM_OC_MspDeInit(TIM_HandleTypeDef *htim)
-{
-  /* Prevent unused argument(s) compilation warning */
-  UNUSED(htim);
-
-  /* NOTE : This function should not be modified, when the callback is needed,
-            the HAL_TIM_OC_MspDeInit could be implemented in the user file
-   */
-}
-
-/**
-  * @brief  Starts the TIM Output Compare signal generation.
-  * @param  htim TIM Output Compare handle
-  * @param  Channel TIM Channel to be enabled
-  *          This parameter can be one of the following values:
-  *            @arg TIM_CHANNEL_1: TIM Channel 1 selected
-  *            @arg TIM_CHANNEL_2: TIM Channel 2 selected
-  *            @arg TIM_CHANNEL_3: TIM Channel 3 selected
-  *            @arg TIM_CHANNEL_4: TIM Channel 4 selected
-  *            @arg TIM_CHANNEL_5: TIM Channel 5 selected
-  *            @arg TIM_CHANNEL_6: TIM Channel 6 selected
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_TIM_OC_Start(TIM_HandleTypeDef *htim, uint32_t Channel)
-{
-  uint32_t tmpsmcr;
-
-  /* Check the parameters */
-  assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel));
-
-  /* Check the TIM channel state */
-  if (TIM_CHANNEL_STATE_GET(htim, Channel) != HAL_TIM_CHANNEL_STATE_READY)
-  {
-    return HAL_ERROR;
-  }
-
-  /* Set the TIM channel state */
-  TIM_CHANNEL_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_BUSY);
-
-  /* Enable the Output compare channel */
-  TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_ENABLE);
-
-  if (IS_TIM_BREAK_INSTANCE(htim->Instance) != RESET)
-  {
-    /* Enable the main output */
-    __HAL_TIM_MOE_ENABLE(htim);
-  }
-
-  /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */
-  if (IS_TIM_SLAVE_INSTANCE(htim->Instance))
-  {
-    tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS;
-    if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr))
-    {
-      __HAL_TIM_ENABLE(htim);
-    }
-  }
-  else
-  {
-    __HAL_TIM_ENABLE(htim);
-  }
-
-  /* Return function status */
-  return HAL_OK;
-}
-
-/**
-  * @brief  Stops the TIM Output Compare signal generation.
-  * @param  htim TIM Output Compare handle
-  * @param  Channel TIM Channel to be disabled
-  *          This parameter can be one of the following values:
-  *            @arg TIM_CHANNEL_1: TIM Channel 1 selected
-  *            @arg TIM_CHANNEL_2: TIM Channel 2 selected
-  *            @arg TIM_CHANNEL_3: TIM Channel 3 selected
-  *            @arg TIM_CHANNEL_4: TIM Channel 4 selected
-  *            @arg TIM_CHANNEL_5: TIM Channel 5 selected
-  *            @arg TIM_CHANNEL_6: TIM Channel 6 selected
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_TIM_OC_Stop(TIM_HandleTypeDef *htim, uint32_t Channel)
-{
-  /* Check the parameters */
-  assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel));
-
-  /* Disable the Output compare channel */
-  TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_DISABLE);
-
-  if (IS_TIM_BREAK_INSTANCE(htim->Instance) != RESET)
-  {
-    /* Disable the Main Output */
-    __HAL_TIM_MOE_DISABLE(htim);
-  }
-
-  /* Disable the Peripheral */
-  __HAL_TIM_DISABLE(htim);
-
-  /* Set the TIM channel state */
-  TIM_CHANNEL_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_READY);
-
-  /* Return function status */
-  return HAL_OK;
-}
-
-/**
-  * @brief  Starts the TIM Output Compare signal generation in interrupt mode.
-  * @param  htim TIM Output Compare handle
-  * @param  Channel TIM Channel to be enabled
-  *          This parameter can be one of the following values:
-  *            @arg TIM_CHANNEL_1: TIM Channel 1 selected
-  *            @arg TIM_CHANNEL_2: TIM Channel 2 selected
-  *            @arg TIM_CHANNEL_3: TIM Channel 3 selected
-  *            @arg TIM_CHANNEL_4: TIM Channel 4 selected
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_TIM_OC_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel)
-{
-  HAL_StatusTypeDef status = HAL_OK;
-  uint32_t tmpsmcr;
-
-  /* Check the parameters */
-  assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel));
-
-  /* Check the TIM channel state */
-  if (TIM_CHANNEL_STATE_GET(htim, Channel) != HAL_TIM_CHANNEL_STATE_READY)
-  {
-    return HAL_ERROR;
-  }
-
-  /* Set the TIM channel state */
-  TIM_CHANNEL_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_BUSY);
-
-  switch (Channel)
-  {
-    case TIM_CHANNEL_1:
-    {
-      /* Enable the TIM Capture/Compare 1 interrupt */
-      __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC1);
-      break;
-    }
-
-    case TIM_CHANNEL_2:
-    {
-      /* Enable the TIM Capture/Compare 2 interrupt */
-      __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC2);
-      break;
-    }
-
-    case TIM_CHANNEL_3:
-    {
-      /* Enable the TIM Capture/Compare 3 interrupt */
-      __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC3);
-      break;
-    }
-
-    case TIM_CHANNEL_4:
-    {
-      /* Enable the TIM Capture/Compare 4 interrupt */
-      __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC4);
-      break;
-    }
-
-    default:
-      status = HAL_ERROR;
-      break;
-  }
-
-  if (status == HAL_OK)
-  {
-    /* Enable the Output compare channel */
-    TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_ENABLE);
-
-    if (IS_TIM_BREAK_INSTANCE(htim->Instance) != RESET)
-    {
-      /* Enable the main output */
-      __HAL_TIM_MOE_ENABLE(htim);
-    }
-
-    /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */
-    if (IS_TIM_SLAVE_INSTANCE(htim->Instance))
-    {
-      tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS;
-      if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr))
-      {
-        __HAL_TIM_ENABLE(htim);
-      }
-    }
-    else
-    {
-      __HAL_TIM_ENABLE(htim);
-    }
-  }
-
-  /* Return function status */
-  return status;
-}
-
-/**
-  * @brief  Stops the TIM Output Compare signal generation in interrupt mode.
-  * @param  htim TIM Output Compare handle
-  * @param  Channel TIM Channel to be disabled
-  *          This parameter can be one of the following values:
-  *            @arg TIM_CHANNEL_1: TIM Channel 1 selected
-  *            @arg TIM_CHANNEL_2: TIM Channel 2 selected
-  *            @arg TIM_CHANNEL_3: TIM Channel 3 selected
-  *            @arg TIM_CHANNEL_4: TIM Channel 4 selected
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_TIM_OC_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel)
-{
-  HAL_StatusTypeDef status = HAL_OK;
-
-  /* Check the parameters */
-  assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel));
-
-  switch (Channel)
-  {
-    case TIM_CHANNEL_1:
-    {
-      /* Disable the TIM Capture/Compare 1 interrupt */
-      __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC1);
-      break;
-    }
-
-    case TIM_CHANNEL_2:
-    {
-      /* Disable the TIM Capture/Compare 2 interrupt */
-      __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC2);
-      break;
-    }
-
-    case TIM_CHANNEL_3:
-    {
-      /* Disable the TIM Capture/Compare 3 interrupt */
-      __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC3);
-      break;
-    }
-
-    case TIM_CHANNEL_4:
-    {
-      /* Disable the TIM Capture/Compare 4 interrupt */
-      __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC4);
-      break;
-    }
-
-    default:
-      status = HAL_ERROR;
-      break;
-  }
-
-  if (status == HAL_OK)
-  {
-    /* Disable the Output compare channel */
-    TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_DISABLE);
-
-    if (IS_TIM_BREAK_INSTANCE(htim->Instance) != RESET)
-    {
-      /* Disable the Main Output */
-      __HAL_TIM_MOE_DISABLE(htim);
-    }
-
-    /* Disable the Peripheral */
-    __HAL_TIM_DISABLE(htim);
-
-    /* Set the TIM channel state */
-    TIM_CHANNEL_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_READY);
-  }
-
-  /* Return function status */
-  return status;
-}
-
-/**
-  * @brief  Starts the TIM Output Compare signal generation in DMA mode.
-  * @param  htim TIM Output Compare handle
-  * @param  Channel TIM Channel to be enabled
-  *          This parameter can be one of the following values:
-  *            @arg TIM_CHANNEL_1: TIM Channel 1 selected
-  *            @arg TIM_CHANNEL_2: TIM Channel 2 selected
-  *            @arg TIM_CHANNEL_3: TIM Channel 3 selected
-  *            @arg TIM_CHANNEL_4: TIM Channel 4 selected
-  * @param  pData The source Buffer address.
-  * @param  Length The length of data to be transferred from memory to TIM peripheral
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_TIM_OC_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, const uint32_t *pData,
-                                       uint16_t Length)
-{
-  HAL_StatusTypeDef status = HAL_OK;
-  uint32_t tmpsmcr;
-
-  /* Check the parameters */
-  assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel));
-
-  /* Set the TIM channel state */
-  if (TIM_CHANNEL_STATE_GET(htim, Channel) == HAL_TIM_CHANNEL_STATE_BUSY)
-  {
-    return HAL_BUSY;
-  }
-  else if (TIM_CHANNEL_STATE_GET(htim, Channel) == HAL_TIM_CHANNEL_STATE_READY)
-  {
-    if ((pData == NULL) || (Length == 0U))
-    {
-      return HAL_ERROR;
-    }
-    else
-    {
-      TIM_CHANNEL_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_BUSY);
-    }
-  }
-  else
-  {
-    return HAL_ERROR;
-  }
-
-  switch (Channel)
-  {
-    case TIM_CHANNEL_1:
-    {
-      /* Set the DMA compare callbacks */
-      htim->hdma[TIM_DMA_ID_CC1]->XferCpltCallback = TIM_DMADelayPulseCplt;
-      htim->hdma[TIM_DMA_ID_CC1]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt;
-
-      /* Set the DMA error callback */
-      htim->hdma[TIM_DMA_ID_CC1]->XferErrorCallback = TIM_DMAError ;
-
-      /* Enable the DMA channel */
-      if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC1], (uint32_t)pData, (uint32_t)&htim->Instance->CCR1,
-                           Length) != HAL_OK)
-      {
-        /* Return error status */
-        return HAL_ERROR;
-      }
-
-      /* Enable the TIM Capture/Compare 1 DMA request */
-      __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC1);
-      break;
-    }
-
-    case TIM_CHANNEL_2:
-    {
-      /* Set the DMA compare callbacks */
-      htim->hdma[TIM_DMA_ID_CC2]->XferCpltCallback = TIM_DMADelayPulseCplt;
-      htim->hdma[TIM_DMA_ID_CC2]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt;
-
-      /* Set the DMA error callback */
-      htim->hdma[TIM_DMA_ID_CC2]->XferErrorCallback = TIM_DMAError ;
-
-      /* Enable the DMA channel */
-      if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC2], (uint32_t)pData, (uint32_t)&htim->Instance->CCR2,
-                           Length) != HAL_OK)
-      {
-        /* Return error status */
-        return HAL_ERROR;
-      }
-
-      /* Enable the TIM Capture/Compare 2 DMA request */
-      __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC2);
-      break;
-    }
-
-    case TIM_CHANNEL_3:
-    {
-      /* Set the DMA compare callbacks */
-      htim->hdma[TIM_DMA_ID_CC3]->XferCpltCallback = TIM_DMADelayPulseCplt;
-      htim->hdma[TIM_DMA_ID_CC3]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt;
-
-      /* Set the DMA error callback */
-      htim->hdma[TIM_DMA_ID_CC3]->XferErrorCallback = TIM_DMAError ;
-
-      /* Enable the DMA channel */
-      if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC3], (uint32_t)pData, (uint32_t)&htim->Instance->CCR3,
-                           Length) != HAL_OK)
-      {
-        /* Return error status */
-        return HAL_ERROR;
-      }
-      /* Enable the TIM Capture/Compare 3 DMA request */
-      __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC3);
-      break;
-    }
-
-    case TIM_CHANNEL_4:
-    {
-      /* Set the DMA compare callbacks */
-      htim->hdma[TIM_DMA_ID_CC4]->XferCpltCallback = TIM_DMADelayPulseCplt;
-      htim->hdma[TIM_DMA_ID_CC4]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt;
-
-      /* Set the DMA error callback */
-      htim->hdma[TIM_DMA_ID_CC4]->XferErrorCallback = TIM_DMAError ;
-
-      /* Enable the DMA channel */
-      if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC4], (uint32_t)pData, (uint32_t)&htim->Instance->CCR4,
-                           Length) != HAL_OK)
-      {
-        /* Return error status */
-        return HAL_ERROR;
-      }
-      /* Enable the TIM Capture/Compare 4 DMA request */
-      __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC4);
-      break;
-    }
-
-    default:
-      status = HAL_ERROR;
-      break;
-  }
-
-  if (status == HAL_OK)
-  {
-    /* Enable the Output compare channel */
-    TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_ENABLE);
-
-    if (IS_TIM_BREAK_INSTANCE(htim->Instance) != RESET)
-    {
-      /* Enable the main output */
-      __HAL_TIM_MOE_ENABLE(htim);
-    }
-
-    /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */
-    if (IS_TIM_SLAVE_INSTANCE(htim->Instance))
-    {
-      tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS;
-      if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr))
-      {
-        __HAL_TIM_ENABLE(htim);
-      }
-    }
-    else
-    {
-      __HAL_TIM_ENABLE(htim);
-    }
-  }
-
-  /* Return function status */
-  return status;
-}
-
-/**
-  * @brief  Stops the TIM Output Compare signal generation in DMA mode.
-  * @param  htim TIM Output Compare handle
-  * @param  Channel TIM Channel to be disabled
-  *          This parameter can be one of the following values:
-  *            @arg TIM_CHANNEL_1: TIM Channel 1 selected
-  *            @arg TIM_CHANNEL_2: TIM Channel 2 selected
-  *            @arg TIM_CHANNEL_3: TIM Channel 3 selected
-  *            @arg TIM_CHANNEL_4: TIM Channel 4 selected
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_TIM_OC_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel)
-{
-  HAL_StatusTypeDef status = HAL_OK;
-
-  /* Check the parameters */
-  assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel));
-
-  switch (Channel)
-  {
-    case TIM_CHANNEL_1:
-    {
-      /* Disable the TIM Capture/Compare 1 DMA request */
-      __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC1);
-      (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC1]);
-      break;
-    }
-
-    case TIM_CHANNEL_2:
-    {
-      /* Disable the TIM Capture/Compare 2 DMA request */
-      __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC2);
-      (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC2]);
-      break;
-    }
-
-    case TIM_CHANNEL_3:
-    {
-      /* Disable the TIM Capture/Compare 3 DMA request */
-      __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC3);
-      (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC3]);
-      break;
-    }
-
-    case TIM_CHANNEL_4:
-    {
-      /* Disable the TIM Capture/Compare 4 interrupt */
-      __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC4);
-      (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC4]);
-      break;
-    }
-
-    default:
-      status = HAL_ERROR;
-      break;
-  }
-
-  if (status == HAL_OK)
-  {
-    /* Disable the Output compare channel */
-    TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_DISABLE);
-
-    if (IS_TIM_BREAK_INSTANCE(htim->Instance) != RESET)
-    {
-      /* Disable the Main Output */
-      __HAL_TIM_MOE_DISABLE(htim);
-    }
-
-    /* Disable the Peripheral */
-    __HAL_TIM_DISABLE(htim);
-
-    /* Set the TIM channel state */
-    TIM_CHANNEL_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_READY);
-  }
-
-  /* Return function status */
-  return status;
-}
-
-/**
-  * @}
-  */
-
-/** @defgroup TIM_Exported_Functions_Group3 TIM PWM functions
-  *  @brief    TIM PWM functions
-  *
-@verbatim
-  ==============================================================================
-                          ##### TIM PWM functions #####
-  ==============================================================================
-  [..]
-    This section provides functions allowing to:
-    (+) Initialize and configure the TIM PWM.
-    (+) De-initialize the TIM PWM.
-    (+) Start the TIM PWM.
-    (+) Stop the TIM PWM.
-    (+) Start the TIM PWM and enable interrupt.
-    (+) Stop the TIM PWM and disable interrupt.
-    (+) Start the TIM PWM and enable DMA transfer.
-    (+) Stop the TIM PWM and disable DMA transfer.
-
-@endverbatim
-  * @{
-  */
-/**
-  * @brief  Initializes the TIM PWM Time Base according to the specified
-  *         parameters in the TIM_HandleTypeDef and initializes the associated handle.
-  * @note   Switching from Center Aligned counter mode to Edge counter mode (or reverse)
-  *         requires a timer reset to avoid unexpected direction
-  *         due to DIR bit readonly in center aligned mode.
-  *         Ex: call @ref HAL_TIM_PWM_DeInit() before HAL_TIM_PWM_Init()
-  * @param  htim TIM PWM handle
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_TIM_PWM_Init(TIM_HandleTypeDef *htim)
-{
-  /* Check the TIM handle allocation */
-  if (htim == NULL)
-  {
-    return HAL_ERROR;
-  }
-
-  /* Check the parameters */
-  assert_param(IS_TIM_INSTANCE(htim->Instance));
-  assert_param(IS_TIM_COUNTER_MODE(htim->Init.CounterMode));
-  assert_param(IS_TIM_CLOCKDIVISION_DIV(htim->Init.ClockDivision));
-  assert_param(IS_TIM_PERIOD(htim, htim->Init.Period));
-  assert_param(IS_TIM_AUTORELOAD_PRELOAD(htim->Init.AutoReloadPreload));
-
-  if (htim->State == HAL_TIM_STATE_RESET)
-  {
-    /* Allocate lock resource and initialize it */
-    htim->Lock = HAL_UNLOCKED;
-
-#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
-    /* Reset interrupt callbacks to legacy weak callbacks */
-    TIM_ResetCallback(htim);
-
-    if (htim->PWM_MspInitCallback == NULL)
-    {
-      htim->PWM_MspInitCallback = HAL_TIM_PWM_MspInit;
-    }
-    /* Init the low level hardware : GPIO, CLOCK, NVIC */
-    htim->PWM_MspInitCallback(htim);
-#else
-    /* Init the low level hardware : GPIO, CLOCK, NVIC and DMA */
-    HAL_TIM_PWM_MspInit(htim);
-#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
-  }
-
-  /* Set the TIM state */
-  htim->State = HAL_TIM_STATE_BUSY;
-
-  /* Init the base time for the PWM */
-  TIM_Base_SetConfig(htim->Instance, &htim->Init);
-
-  /* Initialize the DMA burst operation state */
-  htim->DMABurstState = HAL_DMA_BURST_STATE_READY;
-
-  /* Initialize the TIM channels state */
-  TIM_CHANNEL_STATE_SET_ALL(htim, HAL_TIM_CHANNEL_STATE_READY);
-  TIM_CHANNEL_N_STATE_SET_ALL(htim, HAL_TIM_CHANNEL_STATE_READY);
-
-  /* Initialize the TIM state*/
-  htim->State = HAL_TIM_STATE_READY;
-
-  return HAL_OK;
-}
-
-/**
-  * @brief  DeInitializes the TIM peripheral
-  * @param  htim TIM PWM handle
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_TIM_PWM_DeInit(TIM_HandleTypeDef *htim)
-{
-  /* Check the parameters */
-  assert_param(IS_TIM_INSTANCE(htim->Instance));
-
-  htim->State = HAL_TIM_STATE_BUSY;
-
-  /* Disable the TIM Peripheral Clock */
-  __HAL_TIM_DISABLE(htim);
-
-#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
-  if (htim->PWM_MspDeInitCallback == NULL)
-  {
-    htim->PWM_MspDeInitCallback = HAL_TIM_PWM_MspDeInit;
-  }
-  /* DeInit the low level hardware */
-  htim->PWM_MspDeInitCallback(htim);
-#else
-  /* DeInit the low level hardware: GPIO, CLOCK, NVIC and DMA */
-  HAL_TIM_PWM_MspDeInit(htim);
-#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
-
-  /* Change the DMA burst operation state */
-  htim->DMABurstState = HAL_DMA_BURST_STATE_RESET;
-
-  /* Change the TIM channels state */
-  TIM_CHANNEL_STATE_SET_ALL(htim, HAL_TIM_CHANNEL_STATE_RESET);
-  TIM_CHANNEL_N_STATE_SET_ALL(htim, HAL_TIM_CHANNEL_STATE_RESET);
-
-  /* Change TIM state */
-  htim->State = HAL_TIM_STATE_RESET;
-
-  /* Release Lock */
-  __HAL_UNLOCK(htim);
-
-  return HAL_OK;
-}
-
-/**
-  * @brief  Initializes the TIM PWM MSP.
-  * @param  htim TIM PWM handle
-  * @retval None
-  */
-__weak void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef *htim)
-{
-  /* Prevent unused argument(s) compilation warning */
-  UNUSED(htim);
-
-  /* NOTE : This function should not be modified, when the callback is needed,
-            the HAL_TIM_PWM_MspInit could be implemented in the user file
-   */
-}
-
-/**
-  * @brief  DeInitializes TIM PWM MSP.
-  * @param  htim TIM PWM handle
-  * @retval None
-  */
-__weak void HAL_TIM_PWM_MspDeInit(TIM_HandleTypeDef *htim)
-{
-  /* Prevent unused argument(s) compilation warning */
-  UNUSED(htim);
-
-  /* NOTE : This function should not be modified, when the callback is needed,
-            the HAL_TIM_PWM_MspDeInit could be implemented in the user file
-   */
-}
-
-/**
-  * @brief  Starts the PWM signal generation.
-  * @param  htim TIM handle
-  * @param  Channel TIM Channels to be enabled
-  *          This parameter can be one of the following values:
-  *            @arg TIM_CHANNEL_1: TIM Channel 1 selected
-  *            @arg TIM_CHANNEL_2: TIM Channel 2 selected
-  *            @arg TIM_CHANNEL_3: TIM Channel 3 selected
-  *            @arg TIM_CHANNEL_4: TIM Channel 4 selected
-  *            @arg TIM_CHANNEL_5: TIM Channel 5 selected
-  *            @arg TIM_CHANNEL_6: TIM Channel 6 selected
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_TIM_PWM_Start(TIM_HandleTypeDef *htim, uint32_t Channel)
-{
-  uint32_t tmpsmcr;
-
-  /* Check the parameters */
-  assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel));
-
-  /* Check the TIM channel state */
-  if (TIM_CHANNEL_STATE_GET(htim, Channel) != HAL_TIM_CHANNEL_STATE_READY)
-  {
-    return HAL_ERROR;
-  }
-
-  /* Set the TIM channel state */
-  TIM_CHANNEL_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_BUSY);
-
-  /* Enable the Capture compare channel */
-  TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_ENABLE);
-
-  if (IS_TIM_BREAK_INSTANCE(htim->Instance) != RESET)
-  {
-    /* Enable the main output */
-    __HAL_TIM_MOE_ENABLE(htim);
-  }
-
-  /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */
-  if (IS_TIM_SLAVE_INSTANCE(htim->Instance))
-  {
-    tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS;
-    if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr))
-    {
-      __HAL_TIM_ENABLE(htim);
-    }
-  }
-  else
-  {
-    __HAL_TIM_ENABLE(htim);
-  }
-
-  /* Return function status */
-  return HAL_OK;
-}
-
-/**
-  * @brief  Stops the PWM signal generation.
-  * @param  htim TIM PWM handle
-  * @param  Channel TIM Channels to be disabled
-  *          This parameter can be one of the following values:
-  *            @arg TIM_CHANNEL_1: TIM Channel 1 selected
-  *            @arg TIM_CHANNEL_2: TIM Channel 2 selected
-  *            @arg TIM_CHANNEL_3: TIM Channel 3 selected
-  *            @arg TIM_CHANNEL_4: TIM Channel 4 selected
-  *            @arg TIM_CHANNEL_5: TIM Channel 5 selected
-  *            @arg TIM_CHANNEL_6: TIM Channel 6 selected
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_TIM_PWM_Stop(TIM_HandleTypeDef *htim, uint32_t Channel)
-{
-  /* Check the parameters */
-  assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel));
-
-  /* Disable the Capture compare channel */
-  TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_DISABLE);
-
-  if (IS_TIM_BREAK_INSTANCE(htim->Instance) != RESET)
-  {
-    /* Disable the Main Output */
-    __HAL_TIM_MOE_DISABLE(htim);
-  }
-
-  /* Disable the Peripheral */
-  __HAL_TIM_DISABLE(htim);
-
-  /* Set the TIM channel state */
-  TIM_CHANNEL_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_READY);
-
-  /* Return function status */
-  return HAL_OK;
-}
-
-/**
-  * @brief  Starts the PWM signal generation in interrupt mode.
-  * @param  htim TIM PWM handle
-  * @param  Channel TIM Channel to be enabled
-  *          This parameter can be one of the following values:
-  *            @arg TIM_CHANNEL_1: TIM Channel 1 selected
-  *            @arg TIM_CHANNEL_2: TIM Channel 2 selected
-  *            @arg TIM_CHANNEL_3: TIM Channel 3 selected
-  *            @arg TIM_CHANNEL_4: TIM Channel 4 selected
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_TIM_PWM_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel)
-{
-  HAL_StatusTypeDef status = HAL_OK;
-  uint32_t tmpsmcr;
-
-  /* Check the parameters */
-  assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel));
-
-  /* Check the TIM channel state */
-  if (TIM_CHANNEL_STATE_GET(htim, Channel) != HAL_TIM_CHANNEL_STATE_READY)
-  {
-    return HAL_ERROR;
-  }
-
-  /* Set the TIM channel state */
-  TIM_CHANNEL_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_BUSY);
-
-  switch (Channel)
-  {
-    case TIM_CHANNEL_1:
-    {
-      /* Enable the TIM Capture/Compare 1 interrupt */
-      __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC1);
-      break;
-    }
-
-    case TIM_CHANNEL_2:
-    {
-      /* Enable the TIM Capture/Compare 2 interrupt */
-      __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC2);
-      break;
-    }
-
-    case TIM_CHANNEL_3:
-    {
-      /* Enable the TIM Capture/Compare 3 interrupt */
-      __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC3);
-      break;
-    }
-
-    case TIM_CHANNEL_4:
-    {
-      /* Enable the TIM Capture/Compare 4 interrupt */
-      __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC4);
-      break;
-    }
-
-    default:
-      status = HAL_ERROR;
-      break;
-  }
-
-  if (status == HAL_OK)
-  {
-    /* Enable the Capture compare channel */
-    TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_ENABLE);
-
-    if (IS_TIM_BREAK_INSTANCE(htim->Instance) != RESET)
-    {
-      /* Enable the main output */
-      __HAL_TIM_MOE_ENABLE(htim);
-    }
-
-    /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */
-    if (IS_TIM_SLAVE_INSTANCE(htim->Instance))
-    {
-      tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS;
-      if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr))
-      {
-        __HAL_TIM_ENABLE(htim);
-      }
-    }
-    else
-    {
-      __HAL_TIM_ENABLE(htim);
-    }
-  }
-
-  /* Return function status */
-  return status;
-}
-
-/**
-  * @brief  Stops the PWM signal generation in interrupt mode.
-  * @param  htim TIM PWM handle
-  * @param  Channel TIM Channels to be disabled
-  *          This parameter can be one of the following values:
-  *            @arg TIM_CHANNEL_1: TIM Channel 1 selected
-  *            @arg TIM_CHANNEL_2: TIM Channel 2 selected
-  *            @arg TIM_CHANNEL_3: TIM Channel 3 selected
-  *            @arg TIM_CHANNEL_4: TIM Channel 4 selected
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_TIM_PWM_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel)
-{
-  HAL_StatusTypeDef status = HAL_OK;
-
-  /* Check the parameters */
-  assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel));
-
-  switch (Channel)
-  {
-    case TIM_CHANNEL_1:
-    {
-      /* Disable the TIM Capture/Compare 1 interrupt */
-      __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC1);
-      break;
-    }
-
-    case TIM_CHANNEL_2:
-    {
-      /* Disable the TIM Capture/Compare 2 interrupt */
-      __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC2);
-      break;
-    }
-
-    case TIM_CHANNEL_3:
-    {
-      /* Disable the TIM Capture/Compare 3 interrupt */
-      __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC3);
-      break;
-    }
-
-    case TIM_CHANNEL_4:
-    {
-      /* Disable the TIM Capture/Compare 4 interrupt */
-      __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC4);
-      break;
-    }
-
-    default:
-      status = HAL_ERROR;
-      break;
-  }
-
-  if (status == HAL_OK)
-  {
-    /* Disable the Capture compare channel */
-    TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_DISABLE);
-
-    if (IS_TIM_BREAK_INSTANCE(htim->Instance) != RESET)
-    {
-      /* Disable the Main Output */
-      __HAL_TIM_MOE_DISABLE(htim);
-    }
-
-    /* Disable the Peripheral */
-    __HAL_TIM_DISABLE(htim);
-
-    /* Set the TIM channel state */
-    TIM_CHANNEL_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_READY);
-  }
-
-  /* Return function status */
-  return status;
-}
-
-/**
-  * @brief  Starts the TIM PWM signal generation in DMA mode.
-  * @param  htim TIM PWM handle
-  * @param  Channel TIM Channels to be enabled
-  *          This parameter can be one of the following values:
-  *            @arg TIM_CHANNEL_1: TIM Channel 1 selected
-  *            @arg TIM_CHANNEL_2: TIM Channel 2 selected
-  *            @arg TIM_CHANNEL_3: TIM Channel 3 selected
-  *            @arg TIM_CHANNEL_4: TIM Channel 4 selected
-  * @param  pData The source Buffer address.
-  * @param  Length The length of data to be transferred from memory to TIM peripheral
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_TIM_PWM_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, const uint32_t *pData,
-                                        uint16_t Length)
-{
-  HAL_StatusTypeDef status = HAL_OK;
-  uint32_t tmpsmcr;
-
-  /* Check the parameters */
-  assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel));
-
-  /* Set the TIM channel state */
-  if (TIM_CHANNEL_STATE_GET(htim, Channel) == HAL_TIM_CHANNEL_STATE_BUSY)
-  {
-    return HAL_BUSY;
-  }
-  else if (TIM_CHANNEL_STATE_GET(htim, Channel) == HAL_TIM_CHANNEL_STATE_READY)
-  {
-    if ((pData == NULL) || (Length == 0U))
-    {
-      return HAL_ERROR;
-    }
-    else
-    {
-      TIM_CHANNEL_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_BUSY);
-    }
-  }
-  else
-  {
-    return HAL_ERROR;
-  }
-
-  switch (Channel)
-  {
-    case TIM_CHANNEL_1:
-    {
-      /* Set the DMA compare callbacks */
-      htim->hdma[TIM_DMA_ID_CC1]->XferCpltCallback = TIM_DMADelayPulseCplt;
-      htim->hdma[TIM_DMA_ID_CC1]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt;
-
-      /* Set the DMA error callback */
-      htim->hdma[TIM_DMA_ID_CC1]->XferErrorCallback = TIM_DMAError ;
-
-      /* Enable the DMA channel */
-      if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC1], (uint32_t)pData, (uint32_t)&htim->Instance->CCR1,
-                           Length) != HAL_OK)
-      {
-        /* Return error status */
-        return HAL_ERROR;
-      }
-
-      /* Enable the TIM Capture/Compare 1 DMA request */
-      __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC1);
-      break;
-    }
-
-    case TIM_CHANNEL_2:
-    {
-      /* Set the DMA compare callbacks */
-      htim->hdma[TIM_DMA_ID_CC2]->XferCpltCallback = TIM_DMADelayPulseCplt;
-      htim->hdma[TIM_DMA_ID_CC2]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt;
-
-      /* Set the DMA error callback */
-      htim->hdma[TIM_DMA_ID_CC2]->XferErrorCallback = TIM_DMAError ;
-
-      /* Enable the DMA channel */
-      if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC2], (uint32_t)pData, (uint32_t)&htim->Instance->CCR2,
-                           Length) != HAL_OK)
-      {
-        /* Return error status */
-        return HAL_ERROR;
-      }
-      /* Enable the TIM Capture/Compare 2 DMA request */
-      __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC2);
-      break;
-    }
-
-    case TIM_CHANNEL_3:
-    {
-      /* Set the DMA compare callbacks */
-      htim->hdma[TIM_DMA_ID_CC3]->XferCpltCallback = TIM_DMADelayPulseCplt;
-      htim->hdma[TIM_DMA_ID_CC3]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt;
-
-      /* Set the DMA error callback */
-      htim->hdma[TIM_DMA_ID_CC3]->XferErrorCallback = TIM_DMAError ;
-
-      /* Enable the DMA channel */
-      if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC3], (uint32_t)pData, (uint32_t)&htim->Instance->CCR3,
-                           Length) != HAL_OK)
-      {
-        /* Return error status */
-        return HAL_ERROR;
-      }
-      /* Enable the TIM Output Capture/Compare 3 request */
-      __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC3);
-      break;
-    }
-
-    case TIM_CHANNEL_4:
-    {
-      /* Set the DMA compare callbacks */
-      htim->hdma[TIM_DMA_ID_CC4]->XferCpltCallback = TIM_DMADelayPulseCplt;
-      htim->hdma[TIM_DMA_ID_CC4]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt;
-
-      /* Set the DMA error callback */
-      htim->hdma[TIM_DMA_ID_CC4]->XferErrorCallback = TIM_DMAError ;
-
-      /* Enable the DMA channel */
-      if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC4], (uint32_t)pData, (uint32_t)&htim->Instance->CCR4,
-                           Length) != HAL_OK)
-      {
-        /* Return error status */
-        return HAL_ERROR;
-      }
-      /* Enable the TIM Capture/Compare 4 DMA request */
-      __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC4);
-      break;
-    }
-
-    default:
-      status = HAL_ERROR;
-      break;
-  }
-
-  if (status == HAL_OK)
-  {
-    /* Enable the Capture compare channel */
-    TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_ENABLE);
-
-    if (IS_TIM_BREAK_INSTANCE(htim->Instance) != RESET)
-    {
-      /* Enable the main output */
-      __HAL_TIM_MOE_ENABLE(htim);
-    }
-
-    /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */
-    if (IS_TIM_SLAVE_INSTANCE(htim->Instance))
-    {
-      tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS;
-      if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr))
-      {
-        __HAL_TIM_ENABLE(htim);
-      }
-    }
-    else
-    {
-      __HAL_TIM_ENABLE(htim);
-    }
-  }
-
-  /* Return function status */
-  return status;
-}
-
-/**
-  * @brief  Stops the TIM PWM signal generation in DMA mode.
-  * @param  htim TIM PWM handle
-  * @param  Channel TIM Channels to be disabled
-  *          This parameter can be one of the following values:
-  *            @arg TIM_CHANNEL_1: TIM Channel 1 selected
-  *            @arg TIM_CHANNEL_2: TIM Channel 2 selected
-  *            @arg TIM_CHANNEL_3: TIM Channel 3 selected
-  *            @arg TIM_CHANNEL_4: TIM Channel 4 selected
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_TIM_PWM_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel)
-{
-  HAL_StatusTypeDef status = HAL_OK;
-
-  /* Check the parameters */
-  assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel));
-
-  switch (Channel)
-  {
-    case TIM_CHANNEL_1:
-    {
-      /* Disable the TIM Capture/Compare 1 DMA request */
-      __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC1);
-      (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC1]);
-      break;
-    }
-
-    case TIM_CHANNEL_2:
-    {
-      /* Disable the TIM Capture/Compare 2 DMA request */
-      __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC2);
-      (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC2]);
-      break;
-    }
-
-    case TIM_CHANNEL_3:
-    {
-      /* Disable the TIM Capture/Compare 3 DMA request */
-      __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC3);
-      (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC3]);
-      break;
-    }
-
-    case TIM_CHANNEL_4:
-    {
-      /* Disable the TIM Capture/Compare 4 interrupt */
-      __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC4);
-      (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC4]);
-      break;
-    }
-
-    default:
-      status = HAL_ERROR;
-      break;
-  }
-
-  if (status == HAL_OK)
-  {
-    /* Disable the Capture compare channel */
-    TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_DISABLE);
-
-    if (IS_TIM_BREAK_INSTANCE(htim->Instance) != RESET)
-    {
-      /* Disable the Main Output */
-      __HAL_TIM_MOE_DISABLE(htim);
-    }
-
-    /* Disable the Peripheral */
-    __HAL_TIM_DISABLE(htim);
-
-    /* Set the TIM channel state */
-    TIM_CHANNEL_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_READY);
-  }
-
-  /* Return function status */
-  return status;
-}
-
-/**
-  * @}
-  */
-
-/** @defgroup TIM_Exported_Functions_Group4 TIM Input Capture functions
-  *  @brief    TIM Input Capture functions
-  *
-@verbatim
-  ==============================================================================
-              ##### TIM Input Capture functions #####
-  ==============================================================================
- [..]
-   This section provides functions allowing to:
-   (+) Initialize and configure the TIM Input Capture.
-   (+) De-initialize the TIM Input Capture.
-   (+) Start the TIM Input Capture.
-   (+) Stop the TIM Input Capture.
-   (+) Start the TIM Input Capture and enable interrupt.
-   (+) Stop the TIM Input Capture and disable interrupt.
-   (+) Start the TIM Input Capture and enable DMA transfer.
-   (+) Stop the TIM Input Capture and disable DMA transfer.
-
-@endverbatim
-  * @{
-  */
-/**
-  * @brief  Initializes the TIM Input Capture Time base according to the specified
-  *         parameters in the TIM_HandleTypeDef and initializes the associated handle.
-  * @note   Switching from Center Aligned counter mode to Edge counter mode (or reverse)
-  *         requires a timer reset to avoid unexpected direction
-  *         due to DIR bit readonly in center aligned mode.
-  *         Ex: call @ref HAL_TIM_IC_DeInit() before HAL_TIM_IC_Init()
-  * @param  htim TIM Input Capture handle
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_TIM_IC_Init(TIM_HandleTypeDef *htim)
-{
-  /* Check the TIM handle allocation */
-  if (htim == NULL)
-  {
-    return HAL_ERROR;
-  }
-
-  /* Check the parameters */
-  assert_param(IS_TIM_INSTANCE(htim->Instance));
-  assert_param(IS_TIM_COUNTER_MODE(htim->Init.CounterMode));
-  assert_param(IS_TIM_CLOCKDIVISION_DIV(htim->Init.ClockDivision));
-  assert_param(IS_TIM_PERIOD(htim, htim->Init.Period));
-  assert_param(IS_TIM_AUTORELOAD_PRELOAD(htim->Init.AutoReloadPreload));
-
-  if (htim->State == HAL_TIM_STATE_RESET)
-  {
-    /* Allocate lock resource and initialize it */
-    htim->Lock = HAL_UNLOCKED;
-
-#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
-    /* Reset interrupt callbacks to legacy weak callbacks */
-    TIM_ResetCallback(htim);
-
-    if (htim->IC_MspInitCallback == NULL)
-    {
-      htim->IC_MspInitCallback = HAL_TIM_IC_MspInit;
-    }
-    /* Init the low level hardware : GPIO, CLOCK, NVIC */
-    htim->IC_MspInitCallback(htim);
-#else
-    /* Init the low level hardware : GPIO, CLOCK, NVIC and DMA */
-    HAL_TIM_IC_MspInit(htim);
-#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
-  }
-
-  /* Set the TIM state */
-  htim->State = HAL_TIM_STATE_BUSY;
-
-  /* Init the base time for the input capture */
-  TIM_Base_SetConfig(htim->Instance, &htim->Init);
-
-  /* Initialize the DMA burst operation state */
-  htim->DMABurstState = HAL_DMA_BURST_STATE_READY;
-
-  /* Initialize the TIM channels state */
-  TIM_CHANNEL_STATE_SET_ALL(htim, HAL_TIM_CHANNEL_STATE_READY);
-  TIM_CHANNEL_N_STATE_SET_ALL(htim, HAL_TIM_CHANNEL_STATE_READY);
-
-  /* Initialize the TIM state*/
-  htim->State = HAL_TIM_STATE_READY;
-
-  return HAL_OK;
-}
-
-/**
-  * @brief  DeInitializes the TIM peripheral
-  * @param  htim TIM Input Capture handle
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_TIM_IC_DeInit(TIM_HandleTypeDef *htim)
-{
-  /* Check the parameters */
-  assert_param(IS_TIM_INSTANCE(htim->Instance));
-
-  htim->State = HAL_TIM_STATE_BUSY;
-
-  /* Disable the TIM Peripheral Clock */
-  __HAL_TIM_DISABLE(htim);
-
-#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
-  if (htim->IC_MspDeInitCallback == NULL)
-  {
-    htim->IC_MspDeInitCallback = HAL_TIM_IC_MspDeInit;
-  }
-  /* DeInit the low level hardware */
-  htim->IC_MspDeInitCallback(htim);
-#else
-  /* DeInit the low level hardware: GPIO, CLOCK, NVIC and DMA */
-  HAL_TIM_IC_MspDeInit(htim);
-#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
-
-  /* Change the DMA burst operation state */
-  htim->DMABurstState = HAL_DMA_BURST_STATE_RESET;
-
-  /* Change the TIM channels state */
-  TIM_CHANNEL_STATE_SET_ALL(htim, HAL_TIM_CHANNEL_STATE_RESET);
-  TIM_CHANNEL_N_STATE_SET_ALL(htim, HAL_TIM_CHANNEL_STATE_RESET);
-
-  /* Change TIM state */
-  htim->State = HAL_TIM_STATE_RESET;
-
-  /* Release Lock */
-  __HAL_UNLOCK(htim);
-
-  return HAL_OK;
-}
-
-/**
-  * @brief  Initializes the TIM Input Capture MSP.
-  * @param  htim TIM Input Capture handle
-  * @retval None
-  */
-__weak void HAL_TIM_IC_MspInit(TIM_HandleTypeDef *htim)
-{
-  /* Prevent unused argument(s) compilation warning */
-  UNUSED(htim);
-
-  /* NOTE : This function should not be modified, when the callback is needed,
-            the HAL_TIM_IC_MspInit could be implemented in the user file
-   */
-}
-
-/**
-  * @brief  DeInitializes TIM Input Capture MSP.
-  * @param  htim TIM handle
-  * @retval None
-  */
-__weak void HAL_TIM_IC_MspDeInit(TIM_HandleTypeDef *htim)
-{
-  /* Prevent unused argument(s) compilation warning */
-  UNUSED(htim);
-
-  /* NOTE : This function should not be modified, when the callback is needed,
-            the HAL_TIM_IC_MspDeInit could be implemented in the user file
-   */
-}
-
-/**
-  * @brief  Starts the TIM Input Capture measurement.
-  * @param  htim TIM Input Capture handle
-  * @param  Channel TIM Channels to be enabled
-  *          This parameter can be one of the following values:
-  *            @arg TIM_CHANNEL_1: TIM Channel 1 selected
-  *            @arg TIM_CHANNEL_2: TIM Channel 2 selected
-  *            @arg TIM_CHANNEL_3: TIM Channel 3 selected
-  *            @arg TIM_CHANNEL_4: TIM Channel 4 selected
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_TIM_IC_Start(TIM_HandleTypeDef *htim, uint32_t Channel)
-{
-  uint32_t tmpsmcr;
-  HAL_TIM_ChannelStateTypeDef channel_state = TIM_CHANNEL_STATE_GET(htim, Channel);
-  HAL_TIM_ChannelStateTypeDef complementary_channel_state = TIM_CHANNEL_N_STATE_GET(htim, Channel);
-
-  /* Check the parameters */
-  assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel));
-
-  /* Check the TIM channel state */
-  if ((channel_state != HAL_TIM_CHANNEL_STATE_READY)
-      || (complementary_channel_state != HAL_TIM_CHANNEL_STATE_READY))
-  {
-    return HAL_ERROR;
-  }
-
-  /* Set the TIM channel state */
-  TIM_CHANNEL_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_BUSY);
-  TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_BUSY);
-
-  /* Enable the Input Capture channel */
-  TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_ENABLE);
-
-  /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */
-  if (IS_TIM_SLAVE_INSTANCE(htim->Instance))
-  {
-    tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS;
-    if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr))
-    {
-      __HAL_TIM_ENABLE(htim);
-    }
-  }
-  else
-  {
-    __HAL_TIM_ENABLE(htim);
-  }
-
-  /* Return function status */
-  return HAL_OK;
-}
-
-/**
-  * @brief  Stops the TIM Input Capture measurement.
-  * @param  htim TIM Input Capture handle
-  * @param  Channel TIM Channels to be disabled
-  *          This parameter can be one of the following values:
-  *            @arg TIM_CHANNEL_1: TIM Channel 1 selected
-  *            @arg TIM_CHANNEL_2: TIM Channel 2 selected
-  *            @arg TIM_CHANNEL_3: TIM Channel 3 selected
-  *            @arg TIM_CHANNEL_4: TIM Channel 4 selected
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_TIM_IC_Stop(TIM_HandleTypeDef *htim, uint32_t Channel)
-{
-  /* Check the parameters */
-  assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel));
-
-  /* Disable the Input Capture channel */
-  TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_DISABLE);
-
-  /* Disable the Peripheral */
-  __HAL_TIM_DISABLE(htim);
-
-  /* Set the TIM channel state */
-  TIM_CHANNEL_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_READY);
-  TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_READY);
-
-  /* Return function status */
-  return HAL_OK;
-}
-
-/**
-  * @brief  Starts the TIM Input Capture measurement in interrupt mode.
-  * @param  htim TIM Input Capture handle
-  * @param  Channel TIM Channels to be enabled
-  *          This parameter can be one of the following values:
-  *            @arg TIM_CHANNEL_1: TIM Channel 1 selected
-  *            @arg TIM_CHANNEL_2: TIM Channel 2 selected
-  *            @arg TIM_CHANNEL_3: TIM Channel 3 selected
-  *            @arg TIM_CHANNEL_4: TIM Channel 4 selected
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_TIM_IC_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel)
-{
-  HAL_StatusTypeDef status = HAL_OK;
-  uint32_t tmpsmcr;
-
-  HAL_TIM_ChannelStateTypeDef channel_state = TIM_CHANNEL_STATE_GET(htim, Channel);
-  HAL_TIM_ChannelStateTypeDef complementary_channel_state = TIM_CHANNEL_N_STATE_GET(htim, Channel);
-
-  /* Check the parameters */
-  assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel));
-
-  /* Check the TIM channel state */
-  if ((channel_state != HAL_TIM_CHANNEL_STATE_READY)
-      || (complementary_channel_state != HAL_TIM_CHANNEL_STATE_READY))
-  {
-    return HAL_ERROR;
-  }
-
-  /* Set the TIM channel state */
-  TIM_CHANNEL_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_BUSY);
-  TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_BUSY);
-
-  switch (Channel)
-  {
-    case TIM_CHANNEL_1:
-    {
-      /* Enable the TIM Capture/Compare 1 interrupt */
-      __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC1);
-      break;
-    }
-
-    case TIM_CHANNEL_2:
-    {
-      /* Enable the TIM Capture/Compare 2 interrupt */
-      __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC2);
-      break;
-    }
-
-    case TIM_CHANNEL_3:
-    {
-      /* Enable the TIM Capture/Compare 3 interrupt */
-      __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC3);
-      break;
-    }
-
-    case TIM_CHANNEL_4:
-    {
-      /* Enable the TIM Capture/Compare 4 interrupt */
-      __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC4);
-      break;
-    }
-
-    default:
-      status = HAL_ERROR;
-      break;
-  }
-
-  if (status == HAL_OK)
-  {
-    /* Enable the Input Capture channel */
-    TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_ENABLE);
-
-    /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */
-    if (IS_TIM_SLAVE_INSTANCE(htim->Instance))
-    {
-      tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS;
-      if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr))
-      {
-        __HAL_TIM_ENABLE(htim);
-      }
-    }
-    else
-    {
-      __HAL_TIM_ENABLE(htim);
-    }
-  }
-
-  /* Return function status */
-  return status;
-}
-
-/**
-  * @brief  Stops the TIM Input Capture measurement in interrupt mode.
-  * @param  htim TIM Input Capture handle
-  * @param  Channel TIM Channels to be disabled
-  *          This parameter can be one of the following values:
-  *            @arg TIM_CHANNEL_1: TIM Channel 1 selected
-  *            @arg TIM_CHANNEL_2: TIM Channel 2 selected
-  *            @arg TIM_CHANNEL_3: TIM Channel 3 selected
-  *            @arg TIM_CHANNEL_4: TIM Channel 4 selected
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_TIM_IC_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel)
-{
-  HAL_StatusTypeDef status = HAL_OK;
-
-  /* Check the parameters */
-  assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel));
-
-  switch (Channel)
-  {
-    case TIM_CHANNEL_1:
-    {
-      /* Disable the TIM Capture/Compare 1 interrupt */
-      __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC1);
-      break;
-    }
-
-    case TIM_CHANNEL_2:
-    {
-      /* Disable the TIM Capture/Compare 2 interrupt */
-      __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC2);
-      break;
-    }
-
-    case TIM_CHANNEL_3:
-    {
-      /* Disable the TIM Capture/Compare 3 interrupt */
-      __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC3);
-      break;
-    }
-
-    case TIM_CHANNEL_4:
-    {
-      /* Disable the TIM Capture/Compare 4 interrupt */
-      __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC4);
-      break;
-    }
-
-    default:
-      status = HAL_ERROR;
-      break;
-  }
-
-  if (status == HAL_OK)
-  {
-    /* Disable the Input Capture channel */
-    TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_DISABLE);
-
-    /* Disable the Peripheral */
-    __HAL_TIM_DISABLE(htim);
-
-    /* Set the TIM channel state */
-    TIM_CHANNEL_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_READY);
-    TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_READY);
-  }
-
-  /* Return function status */
-  return status;
-}
-
-/**
-  * @brief  Starts the TIM Input Capture measurement in DMA mode.
-  * @param  htim TIM Input Capture handle
-  * @param  Channel TIM Channels to be enabled
-  *          This parameter can be one of the following values:
-  *            @arg TIM_CHANNEL_1: TIM Channel 1 selected
-  *            @arg TIM_CHANNEL_2: TIM Channel 2 selected
-  *            @arg TIM_CHANNEL_3: TIM Channel 3 selected
-  *            @arg TIM_CHANNEL_4: TIM Channel 4 selected
-  * @param  pData The destination Buffer address.
-  * @param  Length The length of data to be transferred from TIM peripheral to memory.
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_TIM_IC_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, uint32_t *pData, uint16_t Length)
-{
-  HAL_StatusTypeDef status = HAL_OK;
-  uint32_t tmpsmcr;
-
-  HAL_TIM_ChannelStateTypeDef channel_state = TIM_CHANNEL_STATE_GET(htim, Channel);
-  HAL_TIM_ChannelStateTypeDef complementary_channel_state = TIM_CHANNEL_N_STATE_GET(htim, Channel);
-
-  /* Check the parameters */
-  assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel));
-  assert_param(IS_TIM_DMA_CC_INSTANCE(htim->Instance));
-
-  /* Set the TIM channel state */
-  if ((channel_state == HAL_TIM_CHANNEL_STATE_BUSY)
-      || (complementary_channel_state == HAL_TIM_CHANNEL_STATE_BUSY))
-  {
-    return HAL_BUSY;
-  }
-  else if ((channel_state == HAL_TIM_CHANNEL_STATE_READY)
-           && (complementary_channel_state == HAL_TIM_CHANNEL_STATE_READY))
-  {
-    if ((pData == NULL) || (Length == 0U))
-    {
-      return HAL_ERROR;
-    }
-    else
-    {
-      TIM_CHANNEL_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_BUSY);
-      TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_BUSY);
-    }
-  }
-  else
-  {
-    return HAL_ERROR;
-  }
-
-  /* Enable the Input Capture channel */
-  TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_ENABLE);
-
-  switch (Channel)
-  {
-    case TIM_CHANNEL_1:
-    {
-      /* Set the DMA capture callbacks */
-      htim->hdma[TIM_DMA_ID_CC1]->XferCpltCallback = TIM_DMACaptureCplt;
-      htim->hdma[TIM_DMA_ID_CC1]->XferHalfCpltCallback = TIM_DMACaptureHalfCplt;
-
-      /* Set the DMA error callback */
-      htim->hdma[TIM_DMA_ID_CC1]->XferErrorCallback = TIM_DMAError ;
-
-      /* Enable the DMA channel */
-      if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC1], (uint32_t)&htim->Instance->CCR1, (uint32_t)pData,
-                           Length) != HAL_OK)
-      {
-        /* Return error status */
-        return HAL_ERROR;
-      }
-      /* Enable the TIM Capture/Compare 1 DMA request */
-      __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC1);
-      break;
-    }
-
-    case TIM_CHANNEL_2:
-    {
-      /* Set the DMA capture callbacks */
-      htim->hdma[TIM_DMA_ID_CC2]->XferCpltCallback = TIM_DMACaptureCplt;
-      htim->hdma[TIM_DMA_ID_CC2]->XferHalfCpltCallback = TIM_DMACaptureHalfCplt;
-
-      /* Set the DMA error callback */
-      htim->hdma[TIM_DMA_ID_CC2]->XferErrorCallback = TIM_DMAError ;
-
-      /* Enable the DMA channel */
-      if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC2], (uint32_t)&htim->Instance->CCR2, (uint32_t)pData,
-                           Length) != HAL_OK)
-      {
-        /* Return error status */
-        return HAL_ERROR;
-      }
-      /* Enable the TIM Capture/Compare 2  DMA request */
-      __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC2);
-      break;
-    }
-
-    case TIM_CHANNEL_3:
-    {
-      /* Set the DMA capture callbacks */
-      htim->hdma[TIM_DMA_ID_CC3]->XferCpltCallback = TIM_DMACaptureCplt;
-      htim->hdma[TIM_DMA_ID_CC3]->XferHalfCpltCallback = TIM_DMACaptureHalfCplt;
-
-      /* Set the DMA error callback */
-      htim->hdma[TIM_DMA_ID_CC3]->XferErrorCallback = TIM_DMAError ;
-
-      /* Enable the DMA channel */
-      if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC3], (uint32_t)&htim->Instance->CCR3, (uint32_t)pData,
-                           Length) != HAL_OK)
-      {
-        /* Return error status */
-        return HAL_ERROR;
-      }
-      /* Enable the TIM Capture/Compare 3  DMA request */
-      __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC3);
-      break;
-    }
-
-    case TIM_CHANNEL_4:
-    {
-      /* Set the DMA capture callbacks */
-      htim->hdma[TIM_DMA_ID_CC4]->XferCpltCallback = TIM_DMACaptureCplt;
-      htim->hdma[TIM_DMA_ID_CC4]->XferHalfCpltCallback = TIM_DMACaptureHalfCplt;
-
-      /* Set the DMA error callback */
-      htim->hdma[TIM_DMA_ID_CC4]->XferErrorCallback = TIM_DMAError ;
-
-      /* Enable the DMA channel */
-      if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC4], (uint32_t)&htim->Instance->CCR4, (uint32_t)pData,
-                           Length) != HAL_OK)
-      {
-        /* Return error status */
-        return HAL_ERROR;
-      }
-      /* Enable the TIM Capture/Compare 4  DMA request */
-      __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC4);
-      break;
-    }
-
-    default:
-      status = HAL_ERROR;
-      break;
-  }
-
-  /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */
-  if (IS_TIM_SLAVE_INSTANCE(htim->Instance))
-  {
-    tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS;
-    if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr))
-    {
-      __HAL_TIM_ENABLE(htim);
-    }
-  }
-  else
-  {
-    __HAL_TIM_ENABLE(htim);
-  }
-
-  /* Return function status */
-  return status;
-}
-
-/**
-  * @brief  Stops the TIM Input Capture measurement in DMA mode.
-  * @param  htim TIM Input Capture handle
-  * @param  Channel TIM Channels to be disabled
-  *          This parameter can be one of the following values:
-  *            @arg TIM_CHANNEL_1: TIM Channel 1 selected
-  *            @arg TIM_CHANNEL_2: TIM Channel 2 selected
-  *            @arg TIM_CHANNEL_3: TIM Channel 3 selected
-  *            @arg TIM_CHANNEL_4: TIM Channel 4 selected
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_TIM_IC_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel)
-{
-  HAL_StatusTypeDef status = HAL_OK;
-
-  /* Check the parameters */
-  assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel));
-  assert_param(IS_TIM_DMA_CC_INSTANCE(htim->Instance));
-
-  /* Disable the Input Capture channel */
-  TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_DISABLE);
-
-  switch (Channel)
-  {
-    case TIM_CHANNEL_1:
-    {
-      /* Disable the TIM Capture/Compare 1 DMA request */
-      __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC1);
-      (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC1]);
-      break;
-    }
-
-    case TIM_CHANNEL_2:
-    {
-      /* Disable the TIM Capture/Compare 2 DMA request */
-      __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC2);
-      (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC2]);
-      break;
-    }
-
-    case TIM_CHANNEL_3:
-    {
-      /* Disable the TIM Capture/Compare 3  DMA request */
-      __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC3);
-      (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC3]);
-      break;
-    }
-
-    case TIM_CHANNEL_4:
-    {
-      /* Disable the TIM Capture/Compare 4  DMA request */
-      __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC4);
-      (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC4]);
-      break;
-    }
-
-    default:
-      status = HAL_ERROR;
-      break;
-  }
-
-  if (status == HAL_OK)
-  {
-    /* Disable the Peripheral */
-    __HAL_TIM_DISABLE(htim);
-
-    /* Set the TIM channel state */
-    TIM_CHANNEL_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_READY);
-    TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_READY);
-  }
-
-  /* Return function status */
-  return status;
-}
-/**
-  * @}
-  */
-
-/** @defgroup TIM_Exported_Functions_Group5 TIM One Pulse functions
-  *  @brief    TIM One Pulse functions
-  *
-@verbatim
-  ==============================================================================
-                        ##### TIM One Pulse functions #####
-  ==============================================================================
-  [..]
-    This section provides functions allowing to:
-    (+) Initialize and configure the TIM One Pulse.
-    (+) De-initialize the TIM One Pulse.
-    (+) Start the TIM One Pulse.
-    (+) Stop the TIM One Pulse.
-    (+) Start the TIM One Pulse and enable interrupt.
-    (+) Stop the TIM One Pulse and disable interrupt.
-    (+) Start the TIM One Pulse and enable DMA transfer.
-    (+) Stop the TIM One Pulse and disable DMA transfer.
-
-@endverbatim
-  * @{
-  */
-/**
-  * @brief  Initializes the TIM One Pulse Time Base according to the specified
-  *         parameters in the TIM_HandleTypeDef and initializes the associated handle.
-  * @note   Switching from Center Aligned counter mode to Edge counter mode (or reverse)
-  *         requires a timer reset to avoid unexpected direction
-  *         due to DIR bit readonly in center aligned mode.
-  *         Ex: call @ref HAL_TIM_OnePulse_DeInit() before HAL_TIM_OnePulse_Init()
-  * @note   When the timer instance is initialized in One Pulse mode, timer
-  *         channels 1 and channel 2 are reserved and cannot be used for other
-  *         purpose.
-  * @param  htim TIM One Pulse handle
-  * @param  OnePulseMode Select the One pulse mode.
-  *         This parameter can be one of the following values:
-  *            @arg TIM_OPMODE_SINGLE: Only one pulse will be generated.
-  *            @arg TIM_OPMODE_REPETITIVE: Repetitive pulses will be generated.
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_TIM_OnePulse_Init(TIM_HandleTypeDef *htim, uint32_t OnePulseMode)
-{
-  /* Check the TIM handle allocation */
-  if (htim == NULL)
-  {
-    return HAL_ERROR;
-  }
-
-  /* Check the parameters */
-  assert_param(IS_TIM_INSTANCE(htim->Instance));
-  assert_param(IS_TIM_COUNTER_MODE(htim->Init.CounterMode));
-  assert_param(IS_TIM_CLOCKDIVISION_DIV(htim->Init.ClockDivision));
-  assert_param(IS_TIM_OPM_MODE(OnePulseMode));
-  assert_param(IS_TIM_PERIOD(htim, htim->Init.Period));
-  assert_param(IS_TIM_AUTORELOAD_PRELOAD(htim->Init.AutoReloadPreload));
-
-  if (htim->State == HAL_TIM_STATE_RESET)
-  {
-    /* Allocate lock resource and initialize it */
-    htim->Lock = HAL_UNLOCKED;
-
-#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
-    /* Reset interrupt callbacks to legacy weak callbacks */
-    TIM_ResetCallback(htim);
-
-    if (htim->OnePulse_MspInitCallback == NULL)
-    {
-      htim->OnePulse_MspInitCallback = HAL_TIM_OnePulse_MspInit;
-    }
-    /* Init the low level hardware : GPIO, CLOCK, NVIC */
-    htim->OnePulse_MspInitCallback(htim);
-#else
-    /* Init the low level hardware : GPIO, CLOCK, NVIC and DMA */
-    HAL_TIM_OnePulse_MspInit(htim);
-#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
-  }
-
-  /* Set the TIM state */
-  htim->State = HAL_TIM_STATE_BUSY;
-
-  /* Configure the Time base in the One Pulse Mode */
-  TIM_Base_SetConfig(htim->Instance, &htim->Init);
-
-  /* Reset the OPM Bit */
-  htim->Instance->CR1 &= ~TIM_CR1_OPM;
-
-  /* Configure the OPM Mode */
-  htim->Instance->CR1 |= OnePulseMode;
-
-  /* Initialize the DMA burst operation state */
-  htim->DMABurstState = HAL_DMA_BURST_STATE_READY;
-
-  /* Initialize the TIM channels state */
-  TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY);
-  TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY);
-  TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY);
-  TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY);
-
-  /* Initialize the TIM state*/
-  htim->State = HAL_TIM_STATE_READY;
-
-  return HAL_OK;
-}
-
-/**
-  * @brief  DeInitializes the TIM One Pulse
-  * @param  htim TIM One Pulse handle
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_TIM_OnePulse_DeInit(TIM_HandleTypeDef *htim)
-{
-  /* Check the parameters */
-  assert_param(IS_TIM_INSTANCE(htim->Instance));
-
-  htim->State = HAL_TIM_STATE_BUSY;
-
-  /* Disable the TIM Peripheral Clock */
-  __HAL_TIM_DISABLE(htim);
-
-#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
-  if (htim->OnePulse_MspDeInitCallback == NULL)
-  {
-    htim->OnePulse_MspDeInitCallback = HAL_TIM_OnePulse_MspDeInit;
-  }
-  /* DeInit the low level hardware */
-  htim->OnePulse_MspDeInitCallback(htim);
-#else
-  /* DeInit the low level hardware: GPIO, CLOCK, NVIC */
-  HAL_TIM_OnePulse_MspDeInit(htim);
-#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
-
-  /* Change the DMA burst operation state */
-  htim->DMABurstState = HAL_DMA_BURST_STATE_RESET;
-
-  /* Set the TIM channel state */
-  TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_RESET);
-  TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_RESET);
-  TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_RESET);
-  TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_RESET);
-
-  /* Change TIM state */
-  htim->State = HAL_TIM_STATE_RESET;
-
-  /* Release Lock */
-  __HAL_UNLOCK(htim);
-
-  return HAL_OK;
-}
-
-/**
-  * @brief  Initializes the TIM One Pulse MSP.
-  * @param  htim TIM One Pulse handle
-  * @retval None
-  */
-__weak void HAL_TIM_OnePulse_MspInit(TIM_HandleTypeDef *htim)
-{
-  /* Prevent unused argument(s) compilation warning */
-  UNUSED(htim);
-
-  /* NOTE : This function should not be modified, when the callback is needed,
-            the HAL_TIM_OnePulse_MspInit could be implemented in the user file
-   */
-}
-
-/**
-  * @brief  DeInitializes TIM One Pulse MSP.
-  * @param  htim TIM One Pulse handle
-  * @retval None
-  */
-__weak void HAL_TIM_OnePulse_MspDeInit(TIM_HandleTypeDef *htim)
-{
-  /* Prevent unused argument(s) compilation warning */
-  UNUSED(htim);
-
-  /* NOTE : This function should not be modified, when the callback is needed,
-            the HAL_TIM_OnePulse_MspDeInit could be implemented in the user file
-   */
-}
-
-/**
-  * @brief  Starts the TIM One Pulse signal generation.
-  * @note Though OutputChannel parameter is deprecated and ignored by the function
-  *        it has been kept to avoid HAL_TIM API compatibility break.
-  * @note The pulse output channel is determined when calling
-  *       @ref HAL_TIM_OnePulse_ConfigChannel().
-  * @param  htim TIM One Pulse handle
-  * @param  OutputChannel See note above
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_TIM_OnePulse_Start(TIM_HandleTypeDef *htim, uint32_t OutputChannel)
-{
-  HAL_TIM_ChannelStateTypeDef channel_1_state = TIM_CHANNEL_STATE_GET(htim, TIM_CHANNEL_1);
-  HAL_TIM_ChannelStateTypeDef channel_2_state = TIM_CHANNEL_STATE_GET(htim, TIM_CHANNEL_2);
-  HAL_TIM_ChannelStateTypeDef complementary_channel_1_state = TIM_CHANNEL_N_STATE_GET(htim, TIM_CHANNEL_1);
-  HAL_TIM_ChannelStateTypeDef complementary_channel_2_state = TIM_CHANNEL_N_STATE_GET(htim, TIM_CHANNEL_2);
-
-  /* Prevent unused argument(s) compilation warning */
-  UNUSED(OutputChannel);
-
-  /* Check the TIM channels state */
-  if ((channel_1_state != HAL_TIM_CHANNEL_STATE_READY)
-      || (channel_2_state != HAL_TIM_CHANNEL_STATE_READY)
-      || (complementary_channel_1_state != HAL_TIM_CHANNEL_STATE_READY)
-      || (complementary_channel_2_state != HAL_TIM_CHANNEL_STATE_READY))
-  {
-    return HAL_ERROR;
-  }
-
-  /* Set the TIM channels state */
-  TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY);
-  TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY);
-  TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY);
-  TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY);
-
-  /* Enable the Capture compare and the Input Capture channels
-    (in the OPM Mode the two possible channels that can be used are TIM_CHANNEL_1 and TIM_CHANNEL_2)
-    if TIM_CHANNEL_1 is used as output, the TIM_CHANNEL_2 will be used as input and
-    if TIM_CHANNEL_1 is used as input, the TIM_CHANNEL_2 will be used as output
-    whatever the combination, the TIM_CHANNEL_1 and TIM_CHANNEL_2 should be enabled together
-
-    No need to enable the counter, it's enabled automatically by hardware
-    (the counter starts in response to a stimulus and generate a pulse */
-
-  TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_ENABLE);
-  TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_ENABLE);
-
-  if (IS_TIM_BREAK_INSTANCE(htim->Instance) != RESET)
-  {
-    /* Enable the main output */
-    __HAL_TIM_MOE_ENABLE(htim);
-  }
-
-  /* Return function status */
-  return HAL_OK;
-}
-
-/**
-  * @brief  Stops the TIM One Pulse signal generation.
-  * @note Though OutputChannel parameter is deprecated and ignored by the function
-  *        it has been kept to avoid HAL_TIM API compatibility break.
-  * @note The pulse output channel is determined when calling
-  *       @ref HAL_TIM_OnePulse_ConfigChannel().
-  * @param  htim TIM One Pulse handle
-  * @param  OutputChannel See note above
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_TIM_OnePulse_Stop(TIM_HandleTypeDef *htim, uint32_t OutputChannel)
-{
-  /* Prevent unused argument(s) compilation warning */
-  UNUSED(OutputChannel);
-
-  /* Disable the Capture compare and the Input Capture channels
-  (in the OPM Mode the two possible channels that can be used are TIM_CHANNEL_1 and TIM_CHANNEL_2)
-  if TIM_CHANNEL_1 is used as output, the TIM_CHANNEL_2 will be used as input and
-  if TIM_CHANNEL_1 is used as input, the TIM_CHANNEL_2 will be used as output
-  whatever the combination, the TIM_CHANNEL_1 and TIM_CHANNEL_2 should be disabled together */
-
-  TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_DISABLE);
-  TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_DISABLE);
-
-  if (IS_TIM_BREAK_INSTANCE(htim->Instance) != RESET)
-  {
-    /* Disable the Main Output */
-    __HAL_TIM_MOE_DISABLE(htim);
-  }
-
-  /* Disable the Peripheral */
-  __HAL_TIM_DISABLE(htim);
-
-  /* Set the TIM channels state */
-  TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY);
-  TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY);
-  TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY);
-  TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY);
-
-  /* Return function status */
-  return HAL_OK;
-}
-
-/**
-  * @brief  Starts the TIM One Pulse signal generation in interrupt mode.
-  * @note Though OutputChannel parameter is deprecated and ignored by the function
-  *        it has been kept to avoid HAL_TIM API compatibility break.
-  * @note The pulse output channel is determined when calling
-  *       @ref HAL_TIM_OnePulse_ConfigChannel().
-  * @param  htim TIM One Pulse handle
-  * @param  OutputChannel See note above
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_TIM_OnePulse_Start_IT(TIM_HandleTypeDef *htim, uint32_t OutputChannel)
-{
-  HAL_TIM_ChannelStateTypeDef channel_1_state = TIM_CHANNEL_STATE_GET(htim, TIM_CHANNEL_1);
-  HAL_TIM_ChannelStateTypeDef channel_2_state = TIM_CHANNEL_STATE_GET(htim, TIM_CHANNEL_2);
-  HAL_TIM_ChannelStateTypeDef complementary_channel_1_state = TIM_CHANNEL_N_STATE_GET(htim, TIM_CHANNEL_1);
-  HAL_TIM_ChannelStateTypeDef complementary_channel_2_state = TIM_CHANNEL_N_STATE_GET(htim, TIM_CHANNEL_2);
-
-  /* Prevent unused argument(s) compilation warning */
-  UNUSED(OutputChannel);
-
-  /* Check the TIM channels state */
-  if ((channel_1_state != HAL_TIM_CHANNEL_STATE_READY)
-      || (channel_2_state != HAL_TIM_CHANNEL_STATE_READY)
-      || (complementary_channel_1_state != HAL_TIM_CHANNEL_STATE_READY)
-      || (complementary_channel_2_state != HAL_TIM_CHANNEL_STATE_READY))
-  {
-    return HAL_ERROR;
-  }
-
-  /* Set the TIM channels state */
-  TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY);
-  TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY);
-  TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY);
-  TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY);
-
-  /* Enable the Capture compare and the Input Capture channels
-    (in the OPM Mode the two possible channels that can be used are TIM_CHANNEL_1 and TIM_CHANNEL_2)
-    if TIM_CHANNEL_1 is used as output, the TIM_CHANNEL_2 will be used as input and
-    if TIM_CHANNEL_1 is used as input, the TIM_CHANNEL_2 will be used as output
-    whatever the combination, the TIM_CHANNEL_1 and TIM_CHANNEL_2 should be enabled together
-
-    No need to enable the counter, it's enabled automatically by hardware
-    (the counter starts in response to a stimulus and generate a pulse */
-
-  /* Enable the TIM Capture/Compare 1 interrupt */
-  __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC1);
-
-  /* Enable the TIM Capture/Compare 2 interrupt */
-  __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC2);
-
-  TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_ENABLE);
-  TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_ENABLE);
-
-  if (IS_TIM_BREAK_INSTANCE(htim->Instance) != RESET)
-  {
-    /* Enable the main output */
-    __HAL_TIM_MOE_ENABLE(htim);
-  }
-
-  /* Return function status */
-  return HAL_OK;
-}
-
-/**
-  * @brief  Stops the TIM One Pulse signal generation in interrupt mode.
-  * @note Though OutputChannel parameter is deprecated and ignored by the function
-  *        it has been kept to avoid HAL_TIM API compatibility break.
-  * @note The pulse output channel is determined when calling
-  *       @ref HAL_TIM_OnePulse_ConfigChannel().
-  * @param  htim TIM One Pulse handle
-  * @param  OutputChannel See note above
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_TIM_OnePulse_Stop_IT(TIM_HandleTypeDef *htim, uint32_t OutputChannel)
-{
-  /* Prevent unused argument(s) compilation warning */
-  UNUSED(OutputChannel);
-
-  /* Disable the TIM Capture/Compare 1 interrupt */
-  __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC1);
-
-  /* Disable the TIM Capture/Compare 2 interrupt */
-  __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC2);
-
-  /* Disable the Capture compare and the Input Capture channels
-  (in the OPM Mode the two possible channels that can be used are TIM_CHANNEL_1 and TIM_CHANNEL_2)
-  if TIM_CHANNEL_1 is used as output, the TIM_CHANNEL_2 will be used as input and
-  if TIM_CHANNEL_1 is used as input, the TIM_CHANNEL_2 will be used as output
-  whatever the combination, the TIM_CHANNEL_1 and TIM_CHANNEL_2 should be disabled together */
-  TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_DISABLE);
-  TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_DISABLE);
-
-  if (IS_TIM_BREAK_INSTANCE(htim->Instance) != RESET)
-  {
-    /* Disable the Main Output */
-    __HAL_TIM_MOE_DISABLE(htim);
-  }
-
-  /* Disable the Peripheral */
-  __HAL_TIM_DISABLE(htim);
-
-  /* Set the TIM channels state */
-  TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY);
-  TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY);
-  TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY);
-  TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY);
-
-  /* Return function status */
-  return HAL_OK;
-}
-
-/**
-  * @}
-  */
-
-/** @defgroup TIM_Exported_Functions_Group6 TIM Encoder functions
-  *  @brief    TIM Encoder functions
-  *
-@verbatim
-  ==============================================================================
-                          ##### TIM Encoder functions #####
-  ==============================================================================
-  [..]
-    This section provides functions allowing to:
-    (+) Initialize and configure the TIM Encoder.
-    (+) De-initialize the TIM Encoder.
-    (+) Start the TIM Encoder.
-    (+) Stop the TIM Encoder.
-    (+) Start the TIM Encoder and enable interrupt.
-    (+) Stop the TIM Encoder and disable interrupt.
-    (+) Start the TIM Encoder and enable DMA transfer.
-    (+) Stop the TIM Encoder and disable DMA transfer.
-
-@endverbatim
-  * @{
-  */
-/**
-  * @brief  Initializes the TIM Encoder Interface and initialize the associated handle.
-  * @note   Switching from Center Aligned counter mode to Edge counter mode (or reverse)
-  *         requires a timer reset to avoid unexpected direction
-  *         due to DIR bit readonly in center aligned mode.
-  *         Ex: call @ref HAL_TIM_Encoder_DeInit() before HAL_TIM_Encoder_Init()
-  * @note   Encoder mode and External clock mode 2 are not compatible and must not be selected together
-  *         Ex: A call for @ref HAL_TIM_Encoder_Init will erase the settings of @ref HAL_TIM_ConfigClockSource
-  *         using TIM_CLOCKSOURCE_ETRMODE2 and vice versa
-  * @note   When the timer instance is initialized in Encoder mode, timer
-  *         channels 1 and channel 2 are reserved and cannot be used for other
-  *         purpose.
-  * @param  htim TIM Encoder Interface handle
-  * @param  sConfig TIM Encoder Interface configuration structure
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_TIM_Encoder_Init(TIM_HandleTypeDef *htim,  TIM_Encoder_InitTypeDef *sConfig)
-{
-  uint32_t tmpsmcr;
-  uint32_t tmpccmr1;
-  uint32_t tmpccer;
-
-  /* Check the TIM handle allocation */
-  if (htim == NULL)
-  {
-    return HAL_ERROR;
-  }
-
-  /* Check the parameters */
-  assert_param(IS_TIM_ENCODER_INTERFACE_INSTANCE(htim->Instance));
-  assert_param(IS_TIM_COUNTER_MODE(htim->Init.CounterMode));
-  assert_param(IS_TIM_CLOCKDIVISION_DIV(htim->Init.ClockDivision));
-  assert_param(IS_TIM_AUTORELOAD_PRELOAD(htim->Init.AutoReloadPreload));
-  assert_param(IS_TIM_ENCODER_MODE(sConfig->EncoderMode));
-  assert_param(IS_TIM_IC_SELECTION(sConfig->IC1Selection));
-  assert_param(IS_TIM_IC_SELECTION(sConfig->IC2Selection));
-  assert_param(IS_TIM_ENCODERINPUT_POLARITY(sConfig->IC1Polarity));
-  assert_param(IS_TIM_ENCODERINPUT_POLARITY(sConfig->IC2Polarity));
-  assert_param(IS_TIM_IC_PRESCALER(sConfig->IC1Prescaler));
-  assert_param(IS_TIM_IC_PRESCALER(sConfig->IC2Prescaler));
-  assert_param(IS_TIM_IC_FILTER(sConfig->IC1Filter));
-  assert_param(IS_TIM_IC_FILTER(sConfig->IC2Filter));
-  assert_param(IS_TIM_PERIOD(htim, htim->Init.Period));
-
-  if (htim->State == HAL_TIM_STATE_RESET)
-  {
-    /* Allocate lock resource and initialize it */
-    htim->Lock = HAL_UNLOCKED;
-
-#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
-    /* Reset interrupt callbacks to legacy weak callbacks */
-    TIM_ResetCallback(htim);
-
-    if (htim->Encoder_MspInitCallback == NULL)
-    {
-      htim->Encoder_MspInitCallback = HAL_TIM_Encoder_MspInit;
-    }
-    /* Init the low level hardware : GPIO, CLOCK, NVIC */
-    htim->Encoder_MspInitCallback(htim);
-#else
-    /* Init the low level hardware : GPIO, CLOCK, NVIC and DMA */
-    HAL_TIM_Encoder_MspInit(htim);
-#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
-  }
-
-  /* Set the TIM state */
-  htim->State = HAL_TIM_STATE_BUSY;
-
-  /* Reset the SMS and ECE bits */
-  htim->Instance->SMCR &= ~(TIM_SMCR_SMS | TIM_SMCR_ECE);
-
-  /* Configure the Time base in the Encoder Mode */
-  TIM_Base_SetConfig(htim->Instance, &htim->Init);
-
-  /* Get the TIMx SMCR register value */
-  tmpsmcr = htim->Instance->SMCR;
-
-  /* Get the TIMx CCMR1 register value */
-  tmpccmr1 = htim->Instance->CCMR1;
-
-  /* Get the TIMx CCER register value */
-  tmpccer = htim->Instance->CCER;
-
-  /* Set the encoder Mode */
-  tmpsmcr |= sConfig->EncoderMode;
-
-  /* Select the Capture Compare 1 and the Capture Compare 2 as input */
-  tmpccmr1 &= ~(TIM_CCMR1_CC1S | TIM_CCMR1_CC2S);
-  tmpccmr1 |= (sConfig->IC1Selection | (sConfig->IC2Selection << 8U));
-
-  /* Set the Capture Compare 1 and the Capture Compare 2 prescalers and filters */
-  tmpccmr1 &= ~(TIM_CCMR1_IC1PSC | TIM_CCMR1_IC2PSC);
-  tmpccmr1 &= ~(TIM_CCMR1_IC1F | TIM_CCMR1_IC2F);
-  tmpccmr1 |= sConfig->IC1Prescaler | (sConfig->IC2Prescaler << 8U);
-  tmpccmr1 |= (sConfig->IC1Filter << 4U) | (sConfig->IC2Filter << 12U);
-
-  /* Set the TI1 and the TI2 Polarities */
-  tmpccer &= ~(TIM_CCER_CC1P | TIM_CCER_CC2P);
-  tmpccer &= ~(TIM_CCER_CC1NP | TIM_CCER_CC2NP);
-  tmpccer |= sConfig->IC1Polarity | (sConfig->IC2Polarity << 4U);
-
-  /* Write to TIMx SMCR */
-  htim->Instance->SMCR = tmpsmcr;
-
-  /* Write to TIMx CCMR1 */
-  htim->Instance->CCMR1 = tmpccmr1;
-
-  /* Write to TIMx CCER */
-  htim->Instance->CCER = tmpccer;
-
-  /* Initialize the DMA burst operation state */
-  htim->DMABurstState = HAL_DMA_BURST_STATE_READY;
-
-  /* Set the TIM channels state */
-  TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY);
-  TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY);
-  TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY);
-  TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY);
-
-  /* Initialize the TIM state*/
-  htim->State = HAL_TIM_STATE_READY;
-
-  return HAL_OK;
-}
-
-
-/**
-  * @brief  DeInitializes the TIM Encoder interface
-  * @param  htim TIM Encoder Interface handle
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_TIM_Encoder_DeInit(TIM_HandleTypeDef *htim)
-{
-  /* Check the parameters */
-  assert_param(IS_TIM_INSTANCE(htim->Instance));
-
-  htim->State = HAL_TIM_STATE_BUSY;
-
-  /* Disable the TIM Peripheral Clock */
-  __HAL_TIM_DISABLE(htim);
-
-#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
-  if (htim->Encoder_MspDeInitCallback == NULL)
-  {
-    htim->Encoder_MspDeInitCallback = HAL_TIM_Encoder_MspDeInit;
-  }
-  /* DeInit the low level hardware */
-  htim->Encoder_MspDeInitCallback(htim);
-#else
-  /* DeInit the low level hardware: GPIO, CLOCK, NVIC */
-  HAL_TIM_Encoder_MspDeInit(htim);
-#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
-
-  /* Change the DMA burst operation state */
-  htim->DMABurstState = HAL_DMA_BURST_STATE_RESET;
-
-  /* Set the TIM channels state */
-  TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_RESET);
-  TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_RESET);
-  TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_RESET);
-  TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_RESET);
-
-  /* Change TIM state */
-  htim->State = HAL_TIM_STATE_RESET;
-
-  /* Release Lock */
-  __HAL_UNLOCK(htim);
-
-  return HAL_OK;
-}
-
-/**
-  * @brief  Initializes the TIM Encoder Interface MSP.
-  * @param  htim TIM Encoder Interface handle
-  * @retval None
-  */
-__weak void HAL_TIM_Encoder_MspInit(TIM_HandleTypeDef *htim)
-{
-  /* Prevent unused argument(s) compilation warning */
-  UNUSED(htim);
-
-  /* NOTE : This function should not be modified, when the callback is needed,
-            the HAL_TIM_Encoder_MspInit could be implemented in the user file
-   */
-}
-
-/**
-  * @brief  DeInitializes TIM Encoder Interface MSP.
-  * @param  htim TIM Encoder Interface handle
-  * @retval None
-  */
-__weak void HAL_TIM_Encoder_MspDeInit(TIM_HandleTypeDef *htim)
-{
-  /* Prevent unused argument(s) compilation warning */
-  UNUSED(htim);
-
-  /* NOTE : This function should not be modified, when the callback is needed,
-            the HAL_TIM_Encoder_MspDeInit could be implemented in the user file
-   */
-}
-
-/**
-  * @brief  Starts the TIM Encoder Interface.
-  * @param  htim TIM Encoder Interface handle
-  * @param  Channel TIM Channels to be enabled
-  *          This parameter can be one of the following values:
-  *            @arg TIM_CHANNEL_1: TIM Channel 1 selected
-  *            @arg TIM_CHANNEL_2: TIM Channel 2 selected
-  *            @arg TIM_CHANNEL_ALL: TIM Channel 1 and TIM Channel 2 are selected
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_TIM_Encoder_Start(TIM_HandleTypeDef *htim, uint32_t Channel)
-{
-  HAL_TIM_ChannelStateTypeDef channel_1_state = TIM_CHANNEL_STATE_GET(htim, TIM_CHANNEL_1);
-  HAL_TIM_ChannelStateTypeDef channel_2_state = TIM_CHANNEL_STATE_GET(htim, TIM_CHANNEL_2);
-  HAL_TIM_ChannelStateTypeDef complementary_channel_1_state = TIM_CHANNEL_N_STATE_GET(htim, TIM_CHANNEL_1);
-  HAL_TIM_ChannelStateTypeDef complementary_channel_2_state = TIM_CHANNEL_N_STATE_GET(htim, TIM_CHANNEL_2);
-
-  /* Check the parameters */
-  assert_param(IS_TIM_ENCODER_INTERFACE_INSTANCE(htim->Instance));
-
-  /* Set the TIM channel(s) state */
-  if (Channel == TIM_CHANNEL_1)
-  {
-    if ((channel_1_state != HAL_TIM_CHANNEL_STATE_READY)
-        || (complementary_channel_1_state != HAL_TIM_CHANNEL_STATE_READY))
-    {
-      return HAL_ERROR;
-    }
-    else
-    {
-      TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY);
-      TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY);
-    }
-  }
-  else if (Channel == TIM_CHANNEL_2)
-  {
-    if ((channel_2_state != HAL_TIM_CHANNEL_STATE_READY)
-        || (complementary_channel_2_state != HAL_TIM_CHANNEL_STATE_READY))
-    {
-      return HAL_ERROR;
-    }
-    else
-    {
-      TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY);
-      TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY);
-    }
-  }
-  else
-  {
-    if ((channel_1_state != HAL_TIM_CHANNEL_STATE_READY)
-        || (channel_2_state != HAL_TIM_CHANNEL_STATE_READY)
-        || (complementary_channel_1_state != HAL_TIM_CHANNEL_STATE_READY)
-        || (complementary_channel_2_state != HAL_TIM_CHANNEL_STATE_READY))
-    {
-      return HAL_ERROR;
-    }
-    else
-    {
-      TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY);
-      TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY);
-      TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY);
-      TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY);
-    }
-  }
-
-  /* Enable the encoder interface channels */
-  switch (Channel)
-  {
-    case TIM_CHANNEL_1:
-    {
-      TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_ENABLE);
-      break;
-    }
-
-    case TIM_CHANNEL_2:
-    {
-      TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_ENABLE);
-      break;
-    }
-
-    default :
-    {
-      TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_ENABLE);
-      TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_ENABLE);
-      break;
-    }
-  }
-  /* Enable the Peripheral */
-  __HAL_TIM_ENABLE(htim);
-
-  /* Return function status */
-  return HAL_OK;
-}
-
-/**
-  * @brief  Stops the TIM Encoder Interface.
-  * @param  htim TIM Encoder Interface handle
-  * @param  Channel TIM Channels to be disabled
-  *          This parameter can be one of the following values:
-  *            @arg TIM_CHANNEL_1: TIM Channel 1 selected
-  *            @arg TIM_CHANNEL_2: TIM Channel 2 selected
-  *            @arg TIM_CHANNEL_ALL: TIM Channel 1 and TIM Channel 2 are selected
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_TIM_Encoder_Stop(TIM_HandleTypeDef *htim, uint32_t Channel)
-{
-  /* Check the parameters */
-  assert_param(IS_TIM_ENCODER_INTERFACE_INSTANCE(htim->Instance));
-
-  /* Disable the Input Capture channels 1 and 2
-    (in the EncoderInterface the two possible channels that can be used are TIM_CHANNEL_1 and TIM_CHANNEL_2) */
-  switch (Channel)
-  {
-    case TIM_CHANNEL_1:
-    {
-      TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_DISABLE);
-      break;
-    }
-
-    case TIM_CHANNEL_2:
-    {
-      TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_DISABLE);
-      break;
-    }
-
-    default :
-    {
-      TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_DISABLE);
-      TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_DISABLE);
-      break;
-    }
-  }
-
-  /* Disable the Peripheral */
-  __HAL_TIM_DISABLE(htim);
-
-  /* Set the TIM channel(s) state */
-  if ((Channel == TIM_CHANNEL_1) || (Channel == TIM_CHANNEL_2))
-  {
-    TIM_CHANNEL_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_READY);
-    TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_READY);
-  }
-  else
-  {
-    TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY);
-    TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY);
-    TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY);
-    TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY);
-  }
-
-  /* Return function status */
-  return HAL_OK;
-}
-
-/**
-  * @brief  Starts the TIM Encoder Interface in interrupt mode.
-  * @param  htim TIM Encoder Interface handle
-  * @param  Channel TIM Channels to be enabled
-  *          This parameter can be one of the following values:
-  *            @arg TIM_CHANNEL_1: TIM Channel 1 selected
-  *            @arg TIM_CHANNEL_2: TIM Channel 2 selected
-  *            @arg TIM_CHANNEL_ALL: TIM Channel 1 and TIM Channel 2 are selected
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_TIM_Encoder_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel)
-{
-  HAL_TIM_ChannelStateTypeDef channel_1_state = TIM_CHANNEL_STATE_GET(htim, TIM_CHANNEL_1);
-  HAL_TIM_ChannelStateTypeDef channel_2_state = TIM_CHANNEL_STATE_GET(htim, TIM_CHANNEL_2);
-  HAL_TIM_ChannelStateTypeDef complementary_channel_1_state = TIM_CHANNEL_N_STATE_GET(htim, TIM_CHANNEL_1);
-  HAL_TIM_ChannelStateTypeDef complementary_channel_2_state = TIM_CHANNEL_N_STATE_GET(htim, TIM_CHANNEL_2);
-
-  /* Check the parameters */
-  assert_param(IS_TIM_ENCODER_INTERFACE_INSTANCE(htim->Instance));
-
-  /* Set the TIM channel(s) state */
-  if (Channel == TIM_CHANNEL_1)
-  {
-    if ((channel_1_state != HAL_TIM_CHANNEL_STATE_READY)
-        || (complementary_channel_1_state != HAL_TIM_CHANNEL_STATE_READY))
-    {
-      return HAL_ERROR;
-    }
-    else
-    {
-      TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY);
-      TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY);
-    }
-  }
-  else if (Channel == TIM_CHANNEL_2)
-  {
-    if ((channel_2_state != HAL_TIM_CHANNEL_STATE_READY)
-        || (complementary_channel_2_state != HAL_TIM_CHANNEL_STATE_READY))
-    {
-      return HAL_ERROR;
-    }
-    else
-    {
-      TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY);
-      TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY);
-    }
-  }
-  else
-  {
-    if ((channel_1_state != HAL_TIM_CHANNEL_STATE_READY)
-        || (channel_2_state != HAL_TIM_CHANNEL_STATE_READY)
-        || (complementary_channel_1_state != HAL_TIM_CHANNEL_STATE_READY)
-        || (complementary_channel_2_state != HAL_TIM_CHANNEL_STATE_READY))
-    {
-      return HAL_ERROR;
-    }
-    else
-    {
-      TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY);
-      TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY);
-      TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY);
-      TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY);
-    }
-  }
-
-  /* Enable the encoder interface channels */
-  /* Enable the capture compare Interrupts 1 and/or 2 */
-  switch (Channel)
-  {
-    case TIM_CHANNEL_1:
-    {
-      TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_ENABLE);
-      __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC1);
-      break;
-    }
-
-    case TIM_CHANNEL_2:
-    {
-      TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_ENABLE);
-      __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC2);
-      break;
-    }
-
-    default :
-    {
-      TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_ENABLE);
-      TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_ENABLE);
-      __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC1);
-      __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC2);
-      break;
-    }
-  }
-
-  /* Enable the Peripheral */
-  __HAL_TIM_ENABLE(htim);
-
-  /* Return function status */
-  return HAL_OK;
-}
-
-/**
-  * @brief  Stops the TIM Encoder Interface in interrupt mode.
-  * @param  htim TIM Encoder Interface handle
-  * @param  Channel TIM Channels to be disabled
-  *          This parameter can be one of the following values:
-  *            @arg TIM_CHANNEL_1: TIM Channel 1 selected
-  *            @arg TIM_CHANNEL_2: TIM Channel 2 selected
-  *            @arg TIM_CHANNEL_ALL: TIM Channel 1 and TIM Channel 2 are selected
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_TIM_Encoder_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel)
-{
-  /* Check the parameters */
-  assert_param(IS_TIM_ENCODER_INTERFACE_INSTANCE(htim->Instance));
-
-  /* Disable the Input Capture channels 1 and 2
-    (in the EncoderInterface the two possible channels that can be used are TIM_CHANNEL_1 and TIM_CHANNEL_2) */
-  if (Channel == TIM_CHANNEL_1)
-  {
-    TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_DISABLE);
-
-    /* Disable the capture compare Interrupts 1 */
-    __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC1);
-  }
-  else if (Channel == TIM_CHANNEL_2)
-  {
-    TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_DISABLE);
-
-    /* Disable the capture compare Interrupts 2 */
-    __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC2);
-  }
-  else
-  {
-    TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_DISABLE);
-    TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_DISABLE);
-
-    /* Disable the capture compare Interrupts 1 and 2 */
-    __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC1);
-    __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC2);
-  }
-
-  /* Disable the Peripheral */
-  __HAL_TIM_DISABLE(htim);
-
-  /* Set the TIM channel(s) state */
-  if ((Channel == TIM_CHANNEL_1) || (Channel == TIM_CHANNEL_2))
-  {
-    TIM_CHANNEL_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_READY);
-    TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_READY);
-  }
-  else
-  {
-    TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY);
-    TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY);
-    TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY);
-    TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY);
-  }
-
-  /* Return function status */
-  return HAL_OK;
-}
-
-/**
-  * @brief  Starts the TIM Encoder Interface in DMA mode.
-  * @param  htim TIM Encoder Interface handle
-  * @param  Channel TIM Channels to be enabled
-  *          This parameter can be one of the following values:
-  *            @arg TIM_CHANNEL_1: TIM Channel 1 selected
-  *            @arg TIM_CHANNEL_2: TIM Channel 2 selected
-  *            @arg TIM_CHANNEL_ALL: TIM Channel 1 and TIM Channel 2 are selected
-  * @param  pData1 The destination Buffer address for IC1.
-  * @param  pData2 The destination Buffer address for IC2.
-  * @param  Length The length of data to be transferred from TIM peripheral to memory.
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_TIM_Encoder_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, uint32_t *pData1,
-                                            uint32_t *pData2, uint16_t Length)
-{
-  HAL_TIM_ChannelStateTypeDef channel_1_state = TIM_CHANNEL_STATE_GET(htim, TIM_CHANNEL_1);
-  HAL_TIM_ChannelStateTypeDef channel_2_state = TIM_CHANNEL_STATE_GET(htim, TIM_CHANNEL_2);
-  HAL_TIM_ChannelStateTypeDef complementary_channel_1_state = TIM_CHANNEL_N_STATE_GET(htim, TIM_CHANNEL_1);
-  HAL_TIM_ChannelStateTypeDef complementary_channel_2_state = TIM_CHANNEL_N_STATE_GET(htim, TIM_CHANNEL_2);
-
-  /* Check the parameters */
-  assert_param(IS_TIM_ENCODER_INTERFACE_INSTANCE(htim->Instance));
-
-  /* Set the TIM channel(s) state */
-  if (Channel == TIM_CHANNEL_1)
-  {
-    if ((channel_1_state == HAL_TIM_CHANNEL_STATE_BUSY)
-        || (complementary_channel_1_state == HAL_TIM_CHANNEL_STATE_BUSY))
-    {
-      return HAL_BUSY;
-    }
-    else if ((channel_1_state == HAL_TIM_CHANNEL_STATE_READY)
-             && (complementary_channel_1_state == HAL_TIM_CHANNEL_STATE_READY))
-    {
-      if ((pData1 == NULL) || (Length == 0U))
-      {
-        return HAL_ERROR;
-      }
-      else
-      {
-        TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY);
-        TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY);
-      }
-    }
-    else
-    {
-      return HAL_ERROR;
-    }
-  }
-  else if (Channel == TIM_CHANNEL_2)
-  {
-    if ((channel_2_state == HAL_TIM_CHANNEL_STATE_BUSY)
-        || (complementary_channel_2_state == HAL_TIM_CHANNEL_STATE_BUSY))
-    {
-      return HAL_BUSY;
-    }
-    else if ((channel_2_state == HAL_TIM_CHANNEL_STATE_READY)
-             && (complementary_channel_2_state == HAL_TIM_CHANNEL_STATE_READY))
-    {
-      if ((pData2 == NULL) || (Length == 0U))
-      {
-        return HAL_ERROR;
-      }
-      else
-      {
-        TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY);
-        TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY);
-      }
-    }
-    else
-    {
-      return HAL_ERROR;
-    }
-  }
-  else
-  {
-    if ((channel_1_state == HAL_TIM_CHANNEL_STATE_BUSY)
-        || (channel_2_state == HAL_TIM_CHANNEL_STATE_BUSY)
-        || (complementary_channel_1_state == HAL_TIM_CHANNEL_STATE_BUSY)
-        || (complementary_channel_2_state == HAL_TIM_CHANNEL_STATE_BUSY))
-    {
-      return HAL_BUSY;
-    }
-    else if ((channel_1_state == HAL_TIM_CHANNEL_STATE_READY)
-             && (channel_2_state == HAL_TIM_CHANNEL_STATE_READY)
-             && (complementary_channel_1_state == HAL_TIM_CHANNEL_STATE_READY)
-             && (complementary_channel_2_state == HAL_TIM_CHANNEL_STATE_READY))
-    {
-      if ((((pData1 == NULL) || (pData2 == NULL))) || (Length == 0U))
-      {
-        return HAL_ERROR;
-      }
-      else
-      {
-        TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY);
-        TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY);
-        TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY);
-        TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY);
-      }
-    }
-    else
-    {
-      return HAL_ERROR;
-    }
-  }
-
-  switch (Channel)
-  {
-    case TIM_CHANNEL_1:
-    {
-      /* Set the DMA capture callbacks */
-      htim->hdma[TIM_DMA_ID_CC1]->XferCpltCallback = TIM_DMACaptureCplt;
-      htim->hdma[TIM_DMA_ID_CC1]->XferHalfCpltCallback = TIM_DMACaptureHalfCplt;
-
-      /* Set the DMA error callback */
-      htim->hdma[TIM_DMA_ID_CC1]->XferErrorCallback = TIM_DMAError ;
-
-      /* Enable the DMA channel */
-      if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC1], (uint32_t)&htim->Instance->CCR1, (uint32_t)pData1,
-                           Length) != HAL_OK)
-      {
-        /* Return error status */
-        return HAL_ERROR;
-      }
-      /* Enable the TIM Input Capture DMA request */
-      __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC1);
-
-      /* Enable the Capture compare channel */
-      TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_ENABLE);
-
-      /* Enable the Peripheral */
-      __HAL_TIM_ENABLE(htim);
-
-      break;
-    }
-
-    case TIM_CHANNEL_2:
-    {
-      /* Set the DMA capture callbacks */
-      htim->hdma[TIM_DMA_ID_CC2]->XferCpltCallback = TIM_DMACaptureCplt;
-      htim->hdma[TIM_DMA_ID_CC2]->XferHalfCpltCallback = TIM_DMACaptureHalfCplt;
-
-      /* Set the DMA error callback */
-      htim->hdma[TIM_DMA_ID_CC2]->XferErrorCallback = TIM_DMAError;
-      /* Enable the DMA channel */
-      if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC2], (uint32_t)&htim->Instance->CCR2, (uint32_t)pData2,
-                           Length) != HAL_OK)
-      {
-        /* Return error status */
-        return HAL_ERROR;
-      }
-      /* Enable the TIM Input Capture  DMA request */
-      __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC2);
-
-      /* Enable the Capture compare channel */
-      TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_ENABLE);
-
-      /* Enable the Peripheral */
-      __HAL_TIM_ENABLE(htim);
-
-      break;
-    }
-
-    default:
-    {
-      /* Set the DMA capture callbacks */
-      htim->hdma[TIM_DMA_ID_CC1]->XferCpltCallback = TIM_DMACaptureCplt;
-      htim->hdma[TIM_DMA_ID_CC1]->XferHalfCpltCallback = TIM_DMACaptureHalfCplt;
-
-      /* Set the DMA error callback */
-      htim->hdma[TIM_DMA_ID_CC1]->XferErrorCallback = TIM_DMAError ;
-
-      /* Enable the DMA channel */
-      if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC1], (uint32_t)&htim->Instance->CCR1, (uint32_t)pData1,
-                           Length) != HAL_OK)
-      {
-        /* Return error status */
-        return HAL_ERROR;
-      }
-
-      /* Set the DMA capture callbacks */
-      htim->hdma[TIM_DMA_ID_CC2]->XferCpltCallback = TIM_DMACaptureCplt;
-      htim->hdma[TIM_DMA_ID_CC2]->XferHalfCpltCallback = TIM_DMACaptureHalfCplt;
-
-      /* Set the DMA error callback */
-      htim->hdma[TIM_DMA_ID_CC2]->XferErrorCallback = TIM_DMAError ;
-
-      /* Enable the DMA channel */
-      if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC2], (uint32_t)&htim->Instance->CCR2, (uint32_t)pData2,
-                           Length) != HAL_OK)
-      {
-        /* Return error status */
-        return HAL_ERROR;
-      }
-
-      /* Enable the TIM Input Capture  DMA request */
-      __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC1);
-      /* Enable the TIM Input Capture  DMA request */
-      __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC2);
-
-      /* Enable the Capture compare channel */
-      TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_ENABLE);
-      TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_ENABLE);
-
-      /* Enable the Peripheral */
-      __HAL_TIM_ENABLE(htim);
-
-      break;
-    }
-  }
-
-  /* Return function status */
-  return HAL_OK;
-}
-
-/**
-  * @brief  Stops the TIM Encoder Interface in DMA mode.
-  * @param  htim TIM Encoder Interface handle
-  * @param  Channel TIM Channels to be enabled
-  *          This parameter can be one of the following values:
-  *            @arg TIM_CHANNEL_1: TIM Channel 1 selected
-  *            @arg TIM_CHANNEL_2: TIM Channel 2 selected
-  *            @arg TIM_CHANNEL_ALL: TIM Channel 1 and TIM Channel 2 are selected
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_TIM_Encoder_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel)
-{
-  /* Check the parameters */
-  assert_param(IS_TIM_ENCODER_INTERFACE_INSTANCE(htim->Instance));
-
-  /* Disable the Input Capture channels 1 and 2
-    (in the EncoderInterface the two possible channels that can be used are TIM_CHANNEL_1 and TIM_CHANNEL_2) */
-  if (Channel == TIM_CHANNEL_1)
-  {
-    TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_DISABLE);
-
-    /* Disable the capture compare DMA Request 1 */
-    __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC1);
-    (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC1]);
-  }
-  else if (Channel == TIM_CHANNEL_2)
-  {
-    TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_DISABLE);
-
-    /* Disable the capture compare DMA Request 2 */
-    __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC2);
-    (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC2]);
-  }
-  else
-  {
-    TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_DISABLE);
-    TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_DISABLE);
-
-    /* Disable the capture compare DMA Request 1 and 2 */
-    __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC1);
-    __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC2);
-    (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC1]);
-    (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC2]);
-  }
-
-  /* Disable the Peripheral */
-  __HAL_TIM_DISABLE(htim);
-
-  /* Set the TIM channel(s) state */
-  if ((Channel == TIM_CHANNEL_1) || (Channel == TIM_CHANNEL_2))
-  {
-    TIM_CHANNEL_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_READY);
-    TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_READY);
-  }
-  else
-  {
-    TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY);
-    TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY);
-    TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY);
-    TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY);
-  }
-
-  /* Return function status */
-  return HAL_OK;
-}
-
-/**
-  * @}
-  */
-/** @defgroup TIM_Exported_Functions_Group7 TIM IRQ handler management
-  *  @brief    TIM IRQ handler management
-  *
-@verbatim
-  ==============================================================================
-                        ##### IRQ handler management #####
-  ==============================================================================
-  [..]
-    This section provides Timer IRQ handler function.
-
-@endverbatim
-  * @{
-  */
-/**
-  * @brief  This function handles TIM interrupts requests.
-  * @param  htim TIM  handle
-  * @retval None
-  */
-void HAL_TIM_IRQHandler(TIM_HandleTypeDef *htim)
-{
-  /* Capture compare 1 event */
-  if (__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC1) != RESET)
-  {
-    if (__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_CC1) != RESET)
-    {
-      {
-        __HAL_TIM_CLEAR_IT(htim, TIM_IT_CC1);
-        htim->Channel = HAL_TIM_ACTIVE_CHANNEL_1;
-
-        /* Input capture event */
-        if ((htim->Instance->CCMR1 & TIM_CCMR1_CC1S) != 0x00U)
-        {
-#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
-          htim->IC_CaptureCallback(htim);
-#else
-          HAL_TIM_IC_CaptureCallback(htim);
-#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
-        }
-        /* Output compare event */
-        else
-        {
-#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
-          htim->OC_DelayElapsedCallback(htim);
-          htim->PWM_PulseFinishedCallback(htim);
-#else
-          HAL_TIM_OC_DelayElapsedCallback(htim);
-          HAL_TIM_PWM_PulseFinishedCallback(htim);
-#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
-        }
-        htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;
-      }
-    }
-  }
-  /* Capture compare 2 event */
-  if (__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC2) != RESET)
-  {
-    if (__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_CC2) != RESET)
-    {
-      __HAL_TIM_CLEAR_IT(htim, TIM_IT_CC2);
-      htim->Channel = HAL_TIM_ACTIVE_CHANNEL_2;
-      /* Input capture event */
-      if ((htim->Instance->CCMR1 & TIM_CCMR1_CC2S) != 0x00U)
-      {
-#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
-        htim->IC_CaptureCallback(htim);
-#else
-        HAL_TIM_IC_CaptureCallback(htim);
-#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
-      }
-      /* Output compare event */
-      else
-      {
-#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
-        htim->OC_DelayElapsedCallback(htim);
-        htim->PWM_PulseFinishedCallback(htim);
-#else
-        HAL_TIM_OC_DelayElapsedCallback(htim);
-        HAL_TIM_PWM_PulseFinishedCallback(htim);
-#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
-      }
-      htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;
-    }
-  }
-  /* Capture compare 3 event */
-  if (__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC3) != RESET)
-  {
-    if (__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_CC3) != RESET)
-    {
-      __HAL_TIM_CLEAR_IT(htim, TIM_IT_CC3);
-      htim->Channel = HAL_TIM_ACTIVE_CHANNEL_3;
-      /* Input capture event */
-      if ((htim->Instance->CCMR2 & TIM_CCMR2_CC3S) != 0x00U)
-      {
-#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
-        htim->IC_CaptureCallback(htim);
-#else
-        HAL_TIM_IC_CaptureCallback(htim);
-#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
-      }
-      /* Output compare event */
-      else
-      {
-#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
-        htim->OC_DelayElapsedCallback(htim);
-        htim->PWM_PulseFinishedCallback(htim);
-#else
-        HAL_TIM_OC_DelayElapsedCallback(htim);
-        HAL_TIM_PWM_PulseFinishedCallback(htim);
-#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
-      }
-      htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;
-    }
-  }
-  /* Capture compare 4 event */
-  if (__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC4) != RESET)
-  {
-    if (__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_CC4) != RESET)
-    {
-      __HAL_TIM_CLEAR_IT(htim, TIM_IT_CC4);
-      htim->Channel = HAL_TIM_ACTIVE_CHANNEL_4;
-      /* Input capture event */
-      if ((htim->Instance->CCMR2 & TIM_CCMR2_CC4S) != 0x00U)
-      {
-#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
-        htim->IC_CaptureCallback(htim);
-#else
-        HAL_TIM_IC_CaptureCallback(htim);
-#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
-      }
-      /* Output compare event */
-      else
-      {
-#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
-        htim->OC_DelayElapsedCallback(htim);
-        htim->PWM_PulseFinishedCallback(htim);
-#else
-        HAL_TIM_OC_DelayElapsedCallback(htim);
-        HAL_TIM_PWM_PulseFinishedCallback(htim);
-#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
-      }
-      htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;
-    }
-  }
-  /* TIM Update event */
-  if (__HAL_TIM_GET_FLAG(htim, TIM_FLAG_UPDATE) != RESET)
-  {
-    if (__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_UPDATE) != RESET)
-    {
-      __HAL_TIM_CLEAR_IT(htim, TIM_IT_UPDATE);
-#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
-      htim->PeriodElapsedCallback(htim);
-#else
-      HAL_TIM_PeriodElapsedCallback(htim);
-#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
-    }
-  }
-  /* TIM Break input event */
-  if (__HAL_TIM_GET_FLAG(htim, TIM_FLAG_BREAK) != RESET)
-  {
-    if (__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_BREAK) != RESET)
-    {
-      __HAL_TIM_CLEAR_IT(htim, TIM_IT_BREAK);
-#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
-      htim->BreakCallback(htim);
-#else
-      HAL_TIMEx_BreakCallback(htim);
-#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
-    }
-  }
-  /* TIM Break2 input event */
-  if (__HAL_TIM_GET_FLAG(htim, TIM_FLAG_BREAK2) != RESET)
-  {
-    if (__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_BREAK) != RESET)
-    {
-      __HAL_TIM_CLEAR_FLAG(htim, TIM_FLAG_BREAK2);
-#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
-      htim->Break2Callback(htim);
-#else
-      HAL_TIMEx_Break2Callback(htim);
-#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
-    }
-  }
-  /* TIM Trigger detection event */
-  if (__HAL_TIM_GET_FLAG(htim, TIM_FLAG_TRIGGER) != RESET)
-  {
-    if (__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_TRIGGER) != RESET)
-    {
-      __HAL_TIM_CLEAR_IT(htim, TIM_IT_TRIGGER);
-#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
-      htim->TriggerCallback(htim);
-#else
-      HAL_TIM_TriggerCallback(htim);
-#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
-    }
-  }
-  /* TIM commutation event */
-  if (__HAL_TIM_GET_FLAG(htim, TIM_FLAG_COM) != RESET)
-  {
-    if (__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_COM) != RESET)
-    {
-      __HAL_TIM_CLEAR_IT(htim, TIM_FLAG_COM);
-#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
-      htim->CommutationCallback(htim);
-#else
-      HAL_TIMEx_CommutCallback(htim);
-#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
-    }
-  }
-}
-
-/**
-  * @}
-  */
-
-/** @defgroup TIM_Exported_Functions_Group8 TIM Peripheral Control functions
-  *  @brief    TIM Peripheral Control functions
-  *
-@verbatim
-  ==============================================================================
-                   ##### Peripheral Control functions #####
-  ==============================================================================
- [..]
-   This section provides functions allowing to:
-      (+) Configure The Input Output channels for OC, PWM, IC or One Pulse mode.
-      (+) Configure External Clock source.
-      (+) Configure Complementary channels, break features and dead time.
-      (+) Configure Master and the Slave synchronization.
-      (+) Configure the DMA Burst Mode.
-
-@endverbatim
-  * @{
-  */
-
-/**
-  * @brief  Initializes the TIM Output Compare Channels according to the specified
-  *         parameters in the TIM_OC_InitTypeDef.
-  * @param  htim TIM Output Compare handle
-  * @param  sConfig TIM Output Compare configuration structure
-  * @param  Channel TIM Channels to configure
-  *          This parameter can be one of the following values:
-  *            @arg TIM_CHANNEL_1: TIM Channel 1 selected
-  *            @arg TIM_CHANNEL_2: TIM Channel 2 selected
-  *            @arg TIM_CHANNEL_3: TIM Channel 3 selected
-  *            @arg TIM_CHANNEL_4: TIM Channel 4 selected
-  *            @arg TIM_CHANNEL_5: TIM Channel 5 selected
-  *            @arg TIM_CHANNEL_6: TIM Channel 6 selected
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_TIM_OC_ConfigChannel(TIM_HandleTypeDef *htim,
-                                           const TIM_OC_InitTypeDef *sConfig,
-                                           uint32_t Channel)
-{
-  HAL_StatusTypeDef status = HAL_OK;
-
-  /* Check the parameters */
-  assert_param(IS_TIM_CHANNELS(Channel));
-  assert_param(IS_TIM_OC_MODE(sConfig->OCMode));
-  assert_param(IS_TIM_OC_POLARITY(sConfig->OCPolarity));
-
-  /* Process Locked */
-  __HAL_LOCK(htim);
-
-  switch (Channel)
-  {
-    case TIM_CHANNEL_1:
-    {
-      /* Check the parameters */
-      assert_param(IS_TIM_CC1_INSTANCE(htim->Instance));
-
-      /* Configure the TIM Channel 1 in Output Compare */
-      TIM_OC1_SetConfig(htim->Instance, sConfig);
-      break;
-    }
-
-    case TIM_CHANNEL_2:
-    {
-      /* Check the parameters */
-      assert_param(IS_TIM_CC2_INSTANCE(htim->Instance));
-
-      /* Configure the TIM Channel 2 in Output Compare */
-      TIM_OC2_SetConfig(htim->Instance, sConfig);
-      break;
-    }
-
-    case TIM_CHANNEL_3:
-    {
-      /* Check the parameters */
-      assert_param(IS_TIM_CC3_INSTANCE(htim->Instance));
-
-      /* Configure the TIM Channel 3 in Output Compare */
-      TIM_OC3_SetConfig(htim->Instance, sConfig);
-      break;
-    }
-
-    case TIM_CHANNEL_4:
-    {
-      /* Check the parameters */
-      assert_param(IS_TIM_CC4_INSTANCE(htim->Instance));
-
-      /* Configure the TIM Channel 4 in Output Compare */
-      TIM_OC4_SetConfig(htim->Instance, sConfig);
-      break;
-    }
-
-    case TIM_CHANNEL_5:
-    {
-      /* Check the parameters */
-      assert_param(IS_TIM_CC5_INSTANCE(htim->Instance));
-
-      /* Configure the TIM Channel 5 in Output Compare */
-      TIM_OC5_SetConfig(htim->Instance, sConfig);
-      break;
-    }
-
-    case TIM_CHANNEL_6:
-    {
-      /* Check the parameters */
-      assert_param(IS_TIM_CC6_INSTANCE(htim->Instance));
-
-      /* Configure the TIM Channel 6 in Output Compare */
-      TIM_OC6_SetConfig(htim->Instance, sConfig);
-      break;
-    }
-
-    default:
-      status = HAL_ERROR;
-      break;
-  }
-
-  __HAL_UNLOCK(htim);
-
-  return status;
-}
-
-/**
-  * @brief  Initializes the TIM Input Capture Channels according to the specified
-  *         parameters in the TIM_IC_InitTypeDef.
-  * @param  htim TIM IC handle
-  * @param  sConfig TIM Input Capture configuration structure
-  * @param  Channel TIM Channel to configure
-  *          This parameter can be one of the following values:
-  *            @arg TIM_CHANNEL_1: TIM Channel 1 selected
-  *            @arg TIM_CHANNEL_2: TIM Channel 2 selected
-  *            @arg TIM_CHANNEL_3: TIM Channel 3 selected
-  *            @arg TIM_CHANNEL_4: TIM Channel 4 selected
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_TIM_IC_ConfigChannel(TIM_HandleTypeDef *htim, const TIM_IC_InitTypeDef *sConfig, uint32_t Channel)
-{
-  HAL_StatusTypeDef status = HAL_OK;
-
-  /* Check the parameters */
-  assert_param(IS_TIM_CC1_INSTANCE(htim->Instance));
-  assert_param(IS_TIM_IC_POLARITY(sConfig->ICPolarity));
-  assert_param(IS_TIM_IC_SELECTION(sConfig->ICSelection));
-  assert_param(IS_TIM_IC_PRESCALER(sConfig->ICPrescaler));
-  assert_param(IS_TIM_IC_FILTER(sConfig->ICFilter));
-
-  /* Process Locked */
-  __HAL_LOCK(htim);
-
-  if (Channel == TIM_CHANNEL_1)
-  {
-    /* TI1 Configuration */
-    TIM_TI1_SetConfig(htim->Instance,
-                      sConfig->ICPolarity,
-                      sConfig->ICSelection,
-                      sConfig->ICFilter);
-
-    /* Reset the IC1PSC Bits */
-    htim->Instance->CCMR1 &= ~TIM_CCMR1_IC1PSC;
-
-    /* Set the IC1PSC value */
-    htim->Instance->CCMR1 |= sConfig->ICPrescaler;
-  }
-  else if (Channel == TIM_CHANNEL_2)
-  {
-    /* TI2 Configuration */
-    assert_param(IS_TIM_CC2_INSTANCE(htim->Instance));
-
-    TIM_TI2_SetConfig(htim->Instance,
-                      sConfig->ICPolarity,
-                      sConfig->ICSelection,
-                      sConfig->ICFilter);
-
-    /* Reset the IC2PSC Bits */
-    htim->Instance->CCMR1 &= ~TIM_CCMR1_IC2PSC;
-
-    /* Set the IC2PSC value */
-    htim->Instance->CCMR1 |= (sConfig->ICPrescaler << 8U);
-  }
-  else if (Channel == TIM_CHANNEL_3)
-  {
-    /* TI3 Configuration */
-    assert_param(IS_TIM_CC3_INSTANCE(htim->Instance));
-
-    TIM_TI3_SetConfig(htim->Instance,
-                      sConfig->ICPolarity,
-                      sConfig->ICSelection,
-                      sConfig->ICFilter);
-
-    /* Reset the IC3PSC Bits */
-    htim->Instance->CCMR2 &= ~TIM_CCMR2_IC3PSC;
-
-    /* Set the IC3PSC value */
-    htim->Instance->CCMR2 |= sConfig->ICPrescaler;
-  }
-  else if (Channel == TIM_CHANNEL_4)
-  {
-    /* TI4 Configuration */
-    assert_param(IS_TIM_CC4_INSTANCE(htim->Instance));
-
-    TIM_TI4_SetConfig(htim->Instance,
-                      sConfig->ICPolarity,
-                      sConfig->ICSelection,
-                      sConfig->ICFilter);
-
-    /* Reset the IC4PSC Bits */
-    htim->Instance->CCMR2 &= ~TIM_CCMR2_IC4PSC;
-
-    /* Set the IC4PSC value */
-    htim->Instance->CCMR2 |= (sConfig->ICPrescaler << 8U);
-  }
-  else
-  {
-    status = HAL_ERROR;
-  }
-
-  __HAL_UNLOCK(htim);
-
-  return status;
-}
-
-/**
-  * @brief  Initializes the TIM PWM  channels according to the specified
-  *         parameters in the TIM_OC_InitTypeDef.
-  * @param  htim TIM PWM handle
-  * @param  sConfig TIM PWM configuration structure
-  * @param  Channel TIM Channels to be configured
-  *          This parameter can be one of the following values:
-  *            @arg TIM_CHANNEL_1: TIM Channel 1 selected
-  *            @arg TIM_CHANNEL_2: TIM Channel 2 selected
-  *            @arg TIM_CHANNEL_3: TIM Channel 3 selected
-  *            @arg TIM_CHANNEL_4: TIM Channel 4 selected
-  *            @arg TIM_CHANNEL_5: TIM Channel 5 selected
-  *            @arg TIM_CHANNEL_6: TIM Channel 6 selected
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_TIM_PWM_ConfigChannel(TIM_HandleTypeDef *htim,
-                                            const TIM_OC_InitTypeDef *sConfig,
-                                            uint32_t Channel)
-{
-  HAL_StatusTypeDef status = HAL_OK;
-
-  /* Check the parameters */
-  assert_param(IS_TIM_CHANNELS(Channel));
-  assert_param(IS_TIM_PWM_MODE(sConfig->OCMode));
-  assert_param(IS_TIM_OC_POLARITY(sConfig->OCPolarity));
-  assert_param(IS_TIM_FAST_STATE(sConfig->OCFastMode));
-
-  /* Process Locked */
-  __HAL_LOCK(htim);
-
-  switch (Channel)
-  {
-    case TIM_CHANNEL_1:
-    {
-      /* Check the parameters */
-      assert_param(IS_TIM_CC1_INSTANCE(htim->Instance));
-
-      /* Configure the Channel 1 in PWM mode */
-      TIM_OC1_SetConfig(htim->Instance, sConfig);
-
-      /* Set the Preload enable bit for channel1 */
-      htim->Instance->CCMR1 |= TIM_CCMR1_OC1PE;
-
-      /* Configure the Output Fast mode */
-      htim->Instance->CCMR1 &= ~TIM_CCMR1_OC1FE;
-      htim->Instance->CCMR1 |= sConfig->OCFastMode;
-      break;
-    }
-
-    case TIM_CHANNEL_2:
-    {
-      /* Check the parameters */
-      assert_param(IS_TIM_CC2_INSTANCE(htim->Instance));
-
-      /* Configure the Channel 2 in PWM mode */
-      TIM_OC2_SetConfig(htim->Instance, sConfig);
-
-      /* Set the Preload enable bit for channel2 */
-      htim->Instance->CCMR1 |= TIM_CCMR1_OC2PE;
-
-      /* Configure the Output Fast mode */
-      htim->Instance->CCMR1 &= ~TIM_CCMR1_OC2FE;
-      htim->Instance->CCMR1 |= sConfig->OCFastMode << 8U;
-      break;
-    }
-
-    case TIM_CHANNEL_3:
-    {
-      /* Check the parameters */
-      assert_param(IS_TIM_CC3_INSTANCE(htim->Instance));
-
-      /* Configure the Channel 3 in PWM mode */
-      TIM_OC3_SetConfig(htim->Instance, sConfig);
-
-      /* Set the Preload enable bit for channel3 */
-      htim->Instance->CCMR2 |= TIM_CCMR2_OC3PE;
-
-      /* Configure the Output Fast mode */
-      htim->Instance->CCMR2 &= ~TIM_CCMR2_OC3FE;
-      htim->Instance->CCMR2 |= sConfig->OCFastMode;
-      break;
-    }
-
-    case TIM_CHANNEL_4:
-    {
-      /* Check the parameters */
-      assert_param(IS_TIM_CC4_INSTANCE(htim->Instance));
-
-      /* Configure the Channel 4 in PWM mode */
-      TIM_OC4_SetConfig(htim->Instance, sConfig);
-
-      /* Set the Preload enable bit for channel4 */
-      htim->Instance->CCMR2 |= TIM_CCMR2_OC4PE;
-
-      /* Configure the Output Fast mode */
-      htim->Instance->CCMR2 &= ~TIM_CCMR2_OC4FE;
-      htim->Instance->CCMR2 |= sConfig->OCFastMode << 8U;
-      break;
-    }
-
-    case TIM_CHANNEL_5:
-    {
-      /* Check the parameters */
-      assert_param(IS_TIM_CC5_INSTANCE(htim->Instance));
-
-      /* Configure the Channel 5 in PWM mode */
-      TIM_OC5_SetConfig(htim->Instance, sConfig);
-
-      /* Set the Preload enable bit for channel5*/
-      htim->Instance->CCMR3 |= TIM_CCMR3_OC5PE;
-
-      /* Configure the Output Fast mode */
-      htim->Instance->CCMR3 &= ~TIM_CCMR3_OC5FE;
-      htim->Instance->CCMR3 |= sConfig->OCFastMode;
-      break;
-    }
-
-    case TIM_CHANNEL_6:
-    {
-      /* Check the parameters */
-      assert_param(IS_TIM_CC6_INSTANCE(htim->Instance));
-
-      /* Configure the Channel 6 in PWM mode */
-      TIM_OC6_SetConfig(htim->Instance, sConfig);
-
-      /* Set the Preload enable bit for channel6 */
-      htim->Instance->CCMR3 |= TIM_CCMR3_OC6PE;
-
-      /* Configure the Output Fast mode */
-      htim->Instance->CCMR3 &= ~TIM_CCMR3_OC6FE;
-      htim->Instance->CCMR3 |= sConfig->OCFastMode << 8U;
-      break;
-    }
-
-    default:
-      status = HAL_ERROR;
-      break;
-  }
-
-  __HAL_UNLOCK(htim);
-
-  return status;
-}
-
-/**
-  * @brief  Initializes the TIM One Pulse Channels according to the specified
-  *         parameters in the TIM_OnePulse_InitTypeDef.
-  * @param  htim TIM One Pulse handle
-  * @param  sConfig TIM One Pulse configuration structure
-  * @param  OutputChannel TIM output channel to configure
-  *          This parameter can be one of the following values:
-  *            @arg TIM_CHANNEL_1: TIM Channel 1 selected
-  *            @arg TIM_CHANNEL_2: TIM Channel 2 selected
-  * @param  InputChannel TIM input Channel to configure
-  *          This parameter can be one of the following values:
-  *            @arg TIM_CHANNEL_1: TIM Channel 1 selected
-  *            @arg TIM_CHANNEL_2: TIM Channel 2 selected
-  * @note  To output a waveform with a minimum delay user can enable the fast
-  *        mode by calling the @ref __HAL_TIM_ENABLE_OCxFAST macro. Then CCx
-  *        output is forced in response to the edge detection on TIx input,
-  *        without taking in account the comparison.
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_TIM_OnePulse_ConfigChannel(TIM_HandleTypeDef *htim,  TIM_OnePulse_InitTypeDef *sConfig,
-                                                 uint32_t OutputChannel,  uint32_t InputChannel)
-{
-  HAL_StatusTypeDef status = HAL_OK;
-  TIM_OC_InitTypeDef temp1;
-
-  /* Check the parameters */
-  assert_param(IS_TIM_OPM_CHANNELS(OutputChannel));
-  assert_param(IS_TIM_OPM_CHANNELS(InputChannel));
-
-  if (OutputChannel != InputChannel)
-  {
-    /* Process Locked */
-    __HAL_LOCK(htim);
-
-    htim->State = HAL_TIM_STATE_BUSY;
-
-    /* Extract the Output compare configuration from sConfig structure */
-    temp1.OCMode = sConfig->OCMode;
-    temp1.Pulse = sConfig->Pulse;
-    temp1.OCPolarity = sConfig->OCPolarity;
-    temp1.OCNPolarity = sConfig->OCNPolarity;
-    temp1.OCIdleState = sConfig->OCIdleState;
-    temp1.OCNIdleState = sConfig->OCNIdleState;
-
-    switch (OutputChannel)
-    {
-      case TIM_CHANNEL_1:
-      {
-        assert_param(IS_TIM_CC1_INSTANCE(htim->Instance));
-
-        TIM_OC1_SetConfig(htim->Instance, &temp1);
-        break;
-      }
-
-      case TIM_CHANNEL_2:
-      {
-        assert_param(IS_TIM_CC2_INSTANCE(htim->Instance));
-
-        TIM_OC2_SetConfig(htim->Instance, &temp1);
-        break;
-      }
-
-      default:
-        status = HAL_ERROR;
-        break;
-    }
-
-    if (status == HAL_OK)
-    {
-      switch (InputChannel)
-      {
-        case TIM_CHANNEL_1:
-        {
-          assert_param(IS_TIM_CC1_INSTANCE(htim->Instance));
-
-          TIM_TI1_SetConfig(htim->Instance, sConfig->ICPolarity,
-                            sConfig->ICSelection, sConfig->ICFilter);
-
-          /* Reset the IC1PSC Bits */
-          htim->Instance->CCMR1 &= ~TIM_CCMR1_IC1PSC;
-
-          /* Select the Trigger source */
-          htim->Instance->SMCR &= ~TIM_SMCR_TS;
-          htim->Instance->SMCR |= TIM_TS_TI1FP1;
-
-          /* Select the Slave Mode */
-          htim->Instance->SMCR &= ~TIM_SMCR_SMS;
-          htim->Instance->SMCR |= TIM_SLAVEMODE_TRIGGER;
-          break;
-        }
-
-        case TIM_CHANNEL_2:
-        {
-          assert_param(IS_TIM_CC2_INSTANCE(htim->Instance));
-
-          TIM_TI2_SetConfig(htim->Instance, sConfig->ICPolarity,
-                            sConfig->ICSelection, sConfig->ICFilter);
-
-          /* Reset the IC2PSC Bits */
-          htim->Instance->CCMR1 &= ~TIM_CCMR1_IC2PSC;
-
-          /* Select the Trigger source */
-          htim->Instance->SMCR &= ~TIM_SMCR_TS;
-          htim->Instance->SMCR |= TIM_TS_TI2FP2;
-
-          /* Select the Slave Mode */
-          htim->Instance->SMCR &= ~TIM_SMCR_SMS;
-          htim->Instance->SMCR |= TIM_SLAVEMODE_TRIGGER;
-          break;
-        }
-
-        default:
-          status = HAL_ERROR;
-          break;
-      }
-    }
-
-    htim->State = HAL_TIM_STATE_READY;
-
-    __HAL_UNLOCK(htim);
-
-    return status;
-  }
-  else
-  {
-    return HAL_ERROR;
-  }
-}
-
-/**
-  * @brief  Configure the DMA Burst to transfer Data from the memory to the TIM peripheral
-  * @param  htim TIM handle
-  * @param  BurstBaseAddress TIM Base address from where the DMA  will start the Data write
-  *         This parameter can be one of the following values:
-  *            @arg TIM_DMABASE_CR1
-  *            @arg TIM_DMABASE_CR2
-  *            @arg TIM_DMABASE_SMCR
-  *            @arg TIM_DMABASE_DIER
-  *            @arg TIM_DMABASE_SR
-  *            @arg TIM_DMABASE_EGR
-  *            @arg TIM_DMABASE_CCMR1
-  *            @arg TIM_DMABASE_CCMR2
-  *            @arg TIM_DMABASE_CCER
-  *            @arg TIM_DMABASE_CNT
-  *            @arg TIM_DMABASE_PSC
-  *            @arg TIM_DMABASE_ARR
-  *            @arg TIM_DMABASE_RCR
-  *            @arg TIM_DMABASE_CCR1
-  *            @arg TIM_DMABASE_CCR2
-  *            @arg TIM_DMABASE_CCR3
-  *            @arg TIM_DMABASE_CCR4
-  *            @arg TIM_DMABASE_BDTR
-  *            @arg TIM_DMABASE_OR
-  *            @arg TIM_DMABASE_CCMR3
-  *            @arg TIM_DMABASE_CCR5
-  *            @arg TIM_DMABASE_CCR6
-  *            @arg TIM_DMABASE_AF1
-  *            @arg TIM_DMABASE_AF2
-  * @param  BurstRequestSrc TIM DMA Request sources
-  *         This parameter can be one of the following values:
-  *            @arg TIM_DMA_UPDATE: TIM update Interrupt source
-  *            @arg TIM_DMA_CC1: TIM Capture Compare 1 DMA source
-  *            @arg TIM_DMA_CC2: TIM Capture Compare 2 DMA source
-  *            @arg TIM_DMA_CC3: TIM Capture Compare 3 DMA source
-  *            @arg TIM_DMA_CC4: TIM Capture Compare 4 DMA source
-  *            @arg TIM_DMA_COM: TIM Commutation DMA source
-  *            @arg TIM_DMA_TRIGGER: TIM Trigger DMA source
-  * @param  BurstBuffer The Buffer address.
-  * @param  BurstLength DMA Burst length. This parameter can be one value
-  *         between: TIM_DMABURSTLENGTH_1TRANSFER and TIM_DMABURSTLENGTH_18TRANSFERS.
-  * @note   This function should be used only when BurstLength is equal to DMA data transfer length.
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_TIM_DMABurst_WriteStart(TIM_HandleTypeDef *htim, uint32_t BurstBaseAddress,
-                                              uint32_t BurstRequestSrc, const uint32_t *BurstBuffer, uint32_t  BurstLength)
-{
-  HAL_StatusTypeDef status;
-
-  status = HAL_TIM_DMABurst_MultiWriteStart(htim, BurstBaseAddress, BurstRequestSrc, BurstBuffer, BurstLength,
-                                            ((BurstLength) >> 8U) + 1U);
-
-
-
-  return status;
-}
-
-/**
-  * @brief  Configure the DMA Burst to transfer multiple Data from the memory to the TIM peripheral
-  * @param  htim TIM handle
-  * @param  BurstBaseAddress TIM Base address from where the DMA will start the Data write
-  *         This parameter can be one of the following values:
-  *            @arg TIM_DMABASE_CR1
-  *            @arg TIM_DMABASE_CR2
-  *            @arg TIM_DMABASE_SMCR
-  *            @arg TIM_DMABASE_DIER
-  *            @arg TIM_DMABASE_SR
-  *            @arg TIM_DMABASE_EGR
-  *            @arg TIM_DMABASE_CCMR1
-  *            @arg TIM_DMABASE_CCMR2
-  *            @arg TIM_DMABASE_CCER
-  *            @arg TIM_DMABASE_CNT
-  *            @arg TIM_DMABASE_PSC
-  *            @arg TIM_DMABASE_ARR
-  *            @arg TIM_DMABASE_RCR
-  *            @arg TIM_DMABASE_CCR1
-  *            @arg TIM_DMABASE_CCR2
-  *            @arg TIM_DMABASE_CCR3
-  *            @arg TIM_DMABASE_CCR4
-  *            @arg TIM_DMABASE_BDTR
-  *            @arg TIM_DMABASE_OR
-  *            @arg TIM_DMABASE_CCMR3
-  *            @arg TIM_DMABASE_CCR5
-  *            @arg TIM_DMABASE_CCR6
-  *            @arg TIM_DMABASE_AF1
-  *            @arg TIM_DMABASE_AF2
-  * @param  BurstRequestSrc TIM DMA Request sources
-  *         This parameter can be one of the following values:
-  *            @arg TIM_DMA_UPDATE: TIM update Interrupt source
-  *            @arg TIM_DMA_CC1: TIM Capture Compare 1 DMA source
-  *            @arg TIM_DMA_CC2: TIM Capture Compare 2 DMA source
-  *            @arg TIM_DMA_CC3: TIM Capture Compare 3 DMA source
-  *            @arg TIM_DMA_CC4: TIM Capture Compare 4 DMA source
-  *            @arg TIM_DMA_COM: TIM Commutation DMA source
-  *            @arg TIM_DMA_TRIGGER: TIM Trigger DMA source
-  * @param  BurstBuffer The Buffer address.
-  * @param  BurstLength DMA Burst length. This parameter can be one value
-  *         between: TIM_DMABURSTLENGTH_1TRANSFER and TIM_DMABURSTLENGTH_18TRANSFERS.
-  * @param  DataLength Data length. This parameter can be one value
-  *         between 1 and 0xFFFF.
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_TIM_DMABurst_MultiWriteStart(TIM_HandleTypeDef *htim, uint32_t BurstBaseAddress,
-                                                   uint32_t BurstRequestSrc, const uint32_t *BurstBuffer,
-                                                   uint32_t  BurstLength,  uint32_t  DataLength)
-{
-  HAL_StatusTypeDef status = HAL_OK;
-
-  /* Check the parameters */
-  assert_param(IS_TIM_DMABURST_INSTANCE(htim->Instance));
-  assert_param(IS_TIM_DMA_BASE(BurstBaseAddress));
-  assert_param(IS_TIM_DMA_SOURCE(BurstRequestSrc));
-  assert_param(IS_TIM_DMA_LENGTH(BurstLength));
-  assert_param(IS_TIM_DMA_DATA_LENGTH(DataLength));
-
-  if (htim->DMABurstState == HAL_DMA_BURST_STATE_BUSY)
-  {
-    return HAL_BUSY;
-  }
-  else if (htim->DMABurstState == HAL_DMA_BURST_STATE_READY)
-  {
-    if ((BurstBuffer == NULL) && (BurstLength > 0U))
-    {
-      return HAL_ERROR;
-    }
-    else
-    {
-      htim->DMABurstState = HAL_DMA_BURST_STATE_BUSY;
-    }
-  }
-  else
-  {
-    /* nothing to do */
-  }
-
-  switch (BurstRequestSrc)
-  {
-    case TIM_DMA_UPDATE:
-    {
-      /* Set the DMA Period elapsed callbacks */
-      htim->hdma[TIM_DMA_ID_UPDATE]->XferCpltCallback = TIM_DMAPeriodElapsedCplt;
-      htim->hdma[TIM_DMA_ID_UPDATE]->XferHalfCpltCallback = TIM_DMAPeriodElapsedHalfCplt;
-
-      /* Set the DMA error callback */
-      htim->hdma[TIM_DMA_ID_UPDATE]->XferErrorCallback = TIM_DMAError ;
-
-      /* Enable the DMA channel */
-      if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_UPDATE], (uint32_t)BurstBuffer,
-                           (uint32_t)&htim->Instance->DMAR, DataLength) != HAL_OK)
-      {
-        /* Return error status */
-        return HAL_ERROR;
-      }
-      break;
-    }
-    case TIM_DMA_CC1:
-    {
-      /* Set the DMA compare callbacks */
-      htim->hdma[TIM_DMA_ID_CC1]->XferCpltCallback = TIM_DMADelayPulseCplt;
-      htim->hdma[TIM_DMA_ID_CC1]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt;
-
-      /* Set the DMA error callback */
-      htim->hdma[TIM_DMA_ID_CC1]->XferErrorCallback = TIM_DMAError ;
-
-      /* Enable the DMA channel */
-      if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC1], (uint32_t)BurstBuffer,
-                           (uint32_t)&htim->Instance->DMAR, DataLength) != HAL_OK)
-      {
-        /* Return error status */
-        return HAL_ERROR;
-      }
-      break;
-    }
-    case TIM_DMA_CC2:
-    {
-      /* Set the DMA compare callbacks */
-      htim->hdma[TIM_DMA_ID_CC2]->XferCpltCallback = TIM_DMADelayPulseCplt;
-      htim->hdma[TIM_DMA_ID_CC2]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt;
-
-      /* Set the DMA error callback */
-      htim->hdma[TIM_DMA_ID_CC2]->XferErrorCallback = TIM_DMAError ;
-
-      /* Enable the DMA channel */
-      if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC2], (uint32_t)BurstBuffer,
-                           (uint32_t)&htim->Instance->DMAR, DataLength) != HAL_OK)
-      {
-        /* Return error status */
-        return HAL_ERROR;
-      }
-      break;
-    }
-    case TIM_DMA_CC3:
-    {
-      /* Set the DMA compare callbacks */
-      htim->hdma[TIM_DMA_ID_CC3]->XferCpltCallback = TIM_DMADelayPulseCplt;
-      htim->hdma[TIM_DMA_ID_CC3]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt;
-
-      /* Set the DMA error callback */
-      htim->hdma[TIM_DMA_ID_CC3]->XferErrorCallback = TIM_DMAError ;
-
-      /* Enable the DMA channel */
-      if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC3], (uint32_t)BurstBuffer,
-                           (uint32_t)&htim->Instance->DMAR, DataLength) != HAL_OK)
-      {
-        /* Return error status */
-        return HAL_ERROR;
-      }
-      break;
-    }
-    case TIM_DMA_CC4:
-    {
-      /* Set the DMA compare callbacks */
-      htim->hdma[TIM_DMA_ID_CC4]->XferCpltCallback = TIM_DMADelayPulseCplt;
-      htim->hdma[TIM_DMA_ID_CC4]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt;
-
-      /* Set the DMA error callback */
-      htim->hdma[TIM_DMA_ID_CC4]->XferErrorCallback = TIM_DMAError ;
-
-      /* Enable the DMA channel */
-      if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC4], (uint32_t)BurstBuffer,
-                           (uint32_t)&htim->Instance->DMAR, DataLength) != HAL_OK)
-      {
-        /* Return error status */
-        return HAL_ERROR;
-      }
-      break;
-    }
-    case TIM_DMA_COM:
-    {
-      /* Set the DMA commutation callbacks */
-      htim->hdma[TIM_DMA_ID_COMMUTATION]->XferCpltCallback =  TIMEx_DMACommutationCplt;
-      htim->hdma[TIM_DMA_ID_COMMUTATION]->XferHalfCpltCallback =  TIMEx_DMACommutationHalfCplt;
-
-      /* Set the DMA error callback */
-      htim->hdma[TIM_DMA_ID_COMMUTATION]->XferErrorCallback = TIM_DMAError ;
-
-      /* Enable the DMA channel */
-      if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_COMMUTATION], (uint32_t)BurstBuffer,
-                           (uint32_t)&htim->Instance->DMAR, DataLength) != HAL_OK)
-      {
-        /* Return error status */
-        return HAL_ERROR;
-      }
-      break;
-    }
-    case TIM_DMA_TRIGGER:
-    {
-      /* Set the DMA trigger callbacks */
-      htim->hdma[TIM_DMA_ID_TRIGGER]->XferCpltCallback = TIM_DMATriggerCplt;
-      htim->hdma[TIM_DMA_ID_TRIGGER]->XferHalfCpltCallback = TIM_DMATriggerHalfCplt;
-
-      /* Set the DMA error callback */
-      htim->hdma[TIM_DMA_ID_TRIGGER]->XferErrorCallback = TIM_DMAError ;
-
-      /* Enable the DMA channel */
-      if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_TRIGGER], (uint32_t)BurstBuffer,
-                           (uint32_t)&htim->Instance->DMAR, DataLength) != HAL_OK)
-      {
-        /* Return error status */
-        return HAL_ERROR;
-      }
-      break;
-    }
-    default:
-      status = HAL_ERROR;
-      break;
-  }
-
-  if (status == HAL_OK)
-  {
-    /* Configure the DMA Burst Mode */
-    htim->Instance->DCR = (BurstBaseAddress | BurstLength);
-    /* Enable the TIM DMA Request */
-    __HAL_TIM_ENABLE_DMA(htim, BurstRequestSrc);
-  }
-
-  /* Return function status */
-  return status;
-}
-
-/**
-  * @brief  Stops the TIM DMA Burst mode
-  * @param  htim TIM handle
-  * @param  BurstRequestSrc TIM DMA Request sources to disable
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_TIM_DMABurst_WriteStop(TIM_HandleTypeDef *htim, uint32_t BurstRequestSrc)
-{
-  HAL_StatusTypeDef status = HAL_OK;
-
-  /* Check the parameters */
-  assert_param(IS_TIM_DMA_SOURCE(BurstRequestSrc));
-
-  /* Abort the DMA transfer (at least disable the DMA channel) */
-  switch (BurstRequestSrc)
-  {
-    case TIM_DMA_UPDATE:
-    {
-      (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_UPDATE]);
-      break;
-    }
-    case TIM_DMA_CC1:
-    {
-      (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC1]);
-      break;
-    }
-    case TIM_DMA_CC2:
-    {
-      (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC2]);
-      break;
-    }
-    case TIM_DMA_CC3:
-    {
-      (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC3]);
-      break;
-    }
-    case TIM_DMA_CC4:
-    {
-      (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC4]);
-      break;
-    }
-    case TIM_DMA_COM:
-    {
-      (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_COMMUTATION]);
-      break;
-    }
-    case TIM_DMA_TRIGGER:
-    {
-      (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_TRIGGER]);
-      break;
-    }
-    default:
-      status = HAL_ERROR;
-      break;
-  }
-
-  if (status == HAL_OK)
-  {
-    /* Disable the TIM Update DMA request */
-    __HAL_TIM_DISABLE_DMA(htim, BurstRequestSrc);
-
-    /* Change the DMA burst operation state */
-    htim->DMABurstState = HAL_DMA_BURST_STATE_READY;
-  }
-
-  /* Return function status */
-  return status;
-}
-
-/**
-  * @brief  Configure the DMA Burst to transfer Data from the TIM peripheral to the memory
-  * @param  htim TIM handle
-  * @param  BurstBaseAddress TIM Base address from where the DMA  will start the Data read
-  *         This parameter can be one of the following values:
-  *            @arg TIM_DMABASE_CR1
-  *            @arg TIM_DMABASE_CR2
-  *            @arg TIM_DMABASE_SMCR
-  *            @arg TIM_DMABASE_DIER
-  *            @arg TIM_DMABASE_SR
-  *            @arg TIM_DMABASE_EGR
-  *            @arg TIM_DMABASE_CCMR1
-  *            @arg TIM_DMABASE_CCMR2
-  *            @arg TIM_DMABASE_CCER
-  *            @arg TIM_DMABASE_CNT
-  *            @arg TIM_DMABASE_PSC
-  *            @arg TIM_DMABASE_ARR
-  *            @arg TIM_DMABASE_RCR
-  *            @arg TIM_DMABASE_CCR1
-  *            @arg TIM_DMABASE_CCR2
-  *            @arg TIM_DMABASE_CCR3
-  *            @arg TIM_DMABASE_CCR4
-  *            @arg TIM_DMABASE_BDTR
-  *            @arg TIM_DMABASE_OR
-  *            @arg TIM_DMABASE_CCMR3
-  *            @arg TIM_DMABASE_CCR5
-  *            @arg TIM_DMABASE_CCR6
-  *            @arg TIM_DMABASE_AF1
-  *            @arg TIM_DMABASE_AF2
-  * @param  BurstRequestSrc TIM DMA Request sources
-  *         This parameter can be one of the following values:
-  *            @arg TIM_DMA_UPDATE: TIM update Interrupt source
-  *            @arg TIM_DMA_CC1: TIM Capture Compare 1 DMA source
-  *            @arg TIM_DMA_CC2: TIM Capture Compare 2 DMA source
-  *            @arg TIM_DMA_CC3: TIM Capture Compare 3 DMA source
-  *            @arg TIM_DMA_CC4: TIM Capture Compare 4 DMA source
-  *            @arg TIM_DMA_COM: TIM Commutation DMA source
-  *            @arg TIM_DMA_TRIGGER: TIM Trigger DMA source
-  * @param  BurstBuffer The Buffer address.
-  * @param  BurstLength DMA Burst length. This parameter can be one value
-  *         between: TIM_DMABURSTLENGTH_1TRANSFER and TIM_DMABURSTLENGTH_18TRANSFERS.
-  * @note   This function should be used only when BurstLength is equal to DMA data transfer length.
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_TIM_DMABurst_ReadStart(TIM_HandleTypeDef *htim, uint32_t BurstBaseAddress,
-                                             uint32_t BurstRequestSrc, uint32_t  *BurstBuffer, uint32_t  BurstLength)
-{
-  HAL_StatusTypeDef status;
-
-  status = HAL_TIM_DMABurst_MultiReadStart(htim, BurstBaseAddress, BurstRequestSrc, BurstBuffer, BurstLength,
-                                           ((BurstLength) >> 8U) + 1U);
-
-
-  return status;
-}
-
-/**
-  * @brief  Configure the DMA Burst to transfer Data from the TIM peripheral to the memory
-  * @param  htim TIM handle
-  * @param  BurstBaseAddress TIM Base address from where the DMA  will start the Data read
-  *         This parameter can be one of the following values:
-  *            @arg TIM_DMABASE_CR1
-  *            @arg TIM_DMABASE_CR2
-  *            @arg TIM_DMABASE_SMCR
-  *            @arg TIM_DMABASE_DIER
-  *            @arg TIM_DMABASE_SR
-  *            @arg TIM_DMABASE_EGR
-  *            @arg TIM_DMABASE_CCMR1
-  *            @arg TIM_DMABASE_CCMR2
-  *            @arg TIM_DMABASE_CCER
-  *            @arg TIM_DMABASE_CNT
-  *            @arg TIM_DMABASE_PSC
-  *            @arg TIM_DMABASE_ARR
-  *            @arg TIM_DMABASE_RCR
-  *            @arg TIM_DMABASE_CCR1
-  *            @arg TIM_DMABASE_CCR2
-  *            @arg TIM_DMABASE_CCR3
-  *            @arg TIM_DMABASE_CCR4
-  *            @arg TIM_DMABASE_BDTR
-  *            @arg TIM_DMABASE_OR
-  *            @arg TIM_DMABASE_CCMR3
-  *            @arg TIM_DMABASE_CCR5
-  *            @arg TIM_DMABASE_CCR6
-  *            @arg TIM_DMABASE_AF1
-  *            @arg TIM_DMABASE_AF2
-  * @param  BurstRequestSrc TIM DMA Request sources
-  *         This parameter can be one of the following values:
-  *            @arg TIM_DMA_UPDATE: TIM update Interrupt source
-  *            @arg TIM_DMA_CC1: TIM Capture Compare 1 DMA source
-  *            @arg TIM_DMA_CC2: TIM Capture Compare 2 DMA source
-  *            @arg TIM_DMA_CC3: TIM Capture Compare 3 DMA source
-  *            @arg TIM_DMA_CC4: TIM Capture Compare 4 DMA source
-  *            @arg TIM_DMA_COM: TIM Commutation DMA source
-  *            @arg TIM_DMA_TRIGGER: TIM Trigger DMA source
-  * @param  BurstBuffer The Buffer address.
-  * @param  BurstLength DMA Burst length. This parameter can be one value
-  *         between: TIM_DMABURSTLENGTH_1TRANSFER and TIM_DMABURSTLENGTH_18TRANSFERS.
-  * @param  DataLength Data length. This parameter can be one value
-  *         between 1 and 0xFFFF.
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_TIM_DMABurst_MultiReadStart(TIM_HandleTypeDef *htim, uint32_t BurstBaseAddress,
-                                                  uint32_t BurstRequestSrc, uint32_t  *BurstBuffer,
-                                                  uint32_t  BurstLength, uint32_t  DataLength)
-{
-  HAL_StatusTypeDef status = HAL_OK;
-
-  /* Check the parameters */
-  assert_param(IS_TIM_DMABURST_INSTANCE(htim->Instance));
-  assert_param(IS_TIM_DMA_BASE(BurstBaseAddress));
-  assert_param(IS_TIM_DMA_SOURCE(BurstRequestSrc));
-  assert_param(IS_TIM_DMA_LENGTH(BurstLength));
-  assert_param(IS_TIM_DMA_DATA_LENGTH(DataLength));
-
-  if (htim->DMABurstState == HAL_DMA_BURST_STATE_BUSY)
-  {
-    return HAL_BUSY;
-  }
-  else if (htim->DMABurstState == HAL_DMA_BURST_STATE_READY)
-  {
-    if ((BurstBuffer == NULL) && (BurstLength > 0U))
-    {
-      return HAL_ERROR;
-    }
-    else
-    {
-      htim->DMABurstState = HAL_DMA_BURST_STATE_BUSY;
-    }
-  }
-  else
-  {
-    /* nothing to do */
-  }
-  switch (BurstRequestSrc)
-  {
-    case TIM_DMA_UPDATE:
-    {
-      /* Set the DMA Period elapsed callbacks */
-      htim->hdma[TIM_DMA_ID_UPDATE]->XferCpltCallback = TIM_DMAPeriodElapsedCplt;
-      htim->hdma[TIM_DMA_ID_UPDATE]->XferHalfCpltCallback = TIM_DMAPeriodElapsedHalfCplt;
-
-      /* Set the DMA error callback */
-      htim->hdma[TIM_DMA_ID_UPDATE]->XferErrorCallback = TIM_DMAError ;
-
-      /* Enable the DMA channel */
-      if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_UPDATE], (uint32_t)&htim->Instance->DMAR, (uint32_t)BurstBuffer,
-                           DataLength) != HAL_OK)
-      {
-        /* Return error status */
-        return HAL_ERROR;
-      }
-      break;
-    }
-    case TIM_DMA_CC1:
-    {
-      /* Set the DMA capture callbacks */
-      htim->hdma[TIM_DMA_ID_CC1]->XferCpltCallback = TIM_DMACaptureCplt;
-      htim->hdma[TIM_DMA_ID_CC1]->XferHalfCpltCallback = TIM_DMACaptureHalfCplt;
-
-      /* Set the DMA error callback */
-      htim->hdma[TIM_DMA_ID_CC1]->XferErrorCallback = TIM_DMAError ;
-
-      /* Enable the DMA channel */
-      if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC1], (uint32_t)&htim->Instance->DMAR, (uint32_t)BurstBuffer,
-                           DataLength) != HAL_OK)
-      {
-        /* Return error status */
-        return HAL_ERROR;
-      }
-      break;
-    }
-    case TIM_DMA_CC2:
-    {
-      /* Set the DMA capture callbacks */
-      htim->hdma[TIM_DMA_ID_CC2]->XferCpltCallback = TIM_DMACaptureCplt;
-      htim->hdma[TIM_DMA_ID_CC2]->XferHalfCpltCallback = TIM_DMACaptureHalfCplt;
-
-      /* Set the DMA error callback */
-      htim->hdma[TIM_DMA_ID_CC2]->XferErrorCallback = TIM_DMAError ;
-
-      /* Enable the DMA channel */
-      if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC2], (uint32_t)&htim->Instance->DMAR, (uint32_t)BurstBuffer,
-                           DataLength) != HAL_OK)
-      {
-        /* Return error status */
-        return HAL_ERROR;
-      }
-      break;
-    }
-    case TIM_DMA_CC3:
-    {
-      /* Set the DMA capture callbacks */
-      htim->hdma[TIM_DMA_ID_CC3]->XferCpltCallback = TIM_DMACaptureCplt;
-      htim->hdma[TIM_DMA_ID_CC3]->XferHalfCpltCallback = TIM_DMACaptureHalfCplt;
-
-      /* Set the DMA error callback */
-      htim->hdma[TIM_DMA_ID_CC3]->XferErrorCallback = TIM_DMAError ;
-
-      /* Enable the DMA channel */
-      if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC3], (uint32_t)&htim->Instance->DMAR, (uint32_t)BurstBuffer,
-                           DataLength) != HAL_OK)
-      {
-        /* Return error status */
-        return HAL_ERROR;
-      }
-      break;
-    }
-    case TIM_DMA_CC4:
-    {
-      /* Set the DMA capture callbacks */
-      htim->hdma[TIM_DMA_ID_CC4]->XferCpltCallback = TIM_DMACaptureCplt;
-      htim->hdma[TIM_DMA_ID_CC4]->XferHalfCpltCallback = TIM_DMACaptureHalfCplt;
-
-      /* Set the DMA error callback */
-      htim->hdma[TIM_DMA_ID_CC4]->XferErrorCallback = TIM_DMAError ;
-
-      /* Enable the DMA channel */
-      if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC4], (uint32_t)&htim->Instance->DMAR, (uint32_t)BurstBuffer,
-                           DataLength) != HAL_OK)
-      {
-        /* Return error status */
-        return HAL_ERROR;
-      }
-      break;
-    }
-    case TIM_DMA_COM:
-    {
-      /* Set the DMA commutation callbacks */
-      htim->hdma[TIM_DMA_ID_COMMUTATION]->XferCpltCallback =  TIMEx_DMACommutationCplt;
-      htim->hdma[TIM_DMA_ID_COMMUTATION]->XferHalfCpltCallback =  TIMEx_DMACommutationHalfCplt;
-
-      /* Set the DMA error callback */
-      htim->hdma[TIM_DMA_ID_COMMUTATION]->XferErrorCallback = TIM_DMAError ;
-
-      /* Enable the DMA channel */
-      if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_COMMUTATION], (uint32_t)&htim->Instance->DMAR, (uint32_t)BurstBuffer,
-                           DataLength) != HAL_OK)
-      {
-        /* Return error status */
-        return HAL_ERROR;
-      }
-      break;
-    }
-    case TIM_DMA_TRIGGER:
-    {
-      /* Set the DMA trigger callbacks */
-      htim->hdma[TIM_DMA_ID_TRIGGER]->XferCpltCallback = TIM_DMATriggerCplt;
-      htim->hdma[TIM_DMA_ID_TRIGGER]->XferHalfCpltCallback = TIM_DMATriggerHalfCplt;
-
-      /* Set the DMA error callback */
-      htim->hdma[TIM_DMA_ID_TRIGGER]->XferErrorCallback = TIM_DMAError ;
-
-      /* Enable the DMA channel */
-      if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_TRIGGER], (uint32_t)&htim->Instance->DMAR, (uint32_t)BurstBuffer,
-                           DataLength) != HAL_OK)
-      {
-        /* Return error status */
-        return HAL_ERROR;
-      }
-      break;
-    }
-    default:
-      status = HAL_ERROR;
-      break;
-  }
-
-  if (status == HAL_OK)
-  {
-    /* Configure the DMA Burst Mode */
-    htim->Instance->DCR = (BurstBaseAddress | BurstLength);
-
-    /* Enable the TIM DMA Request */
-    __HAL_TIM_ENABLE_DMA(htim, BurstRequestSrc);
-  }
-
-  /* Return function status */
-  return status;
-}
-
-/**
-  * @brief  Stop the DMA burst reading
-  * @param  htim TIM handle
-  * @param  BurstRequestSrc TIM DMA Request sources to disable.
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_TIM_DMABurst_ReadStop(TIM_HandleTypeDef *htim, uint32_t BurstRequestSrc)
-{
-  HAL_StatusTypeDef status = HAL_OK;
-
-  /* Check the parameters */
-  assert_param(IS_TIM_DMA_SOURCE(BurstRequestSrc));
-
-  /* Abort the DMA transfer (at least disable the DMA channel) */
-  switch (BurstRequestSrc)
-  {
-    case TIM_DMA_UPDATE:
-    {
-      (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_UPDATE]);
-      break;
-    }
-    case TIM_DMA_CC1:
-    {
-      (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC1]);
-      break;
-    }
-    case TIM_DMA_CC2:
-    {
-      (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC2]);
-      break;
-    }
-    case TIM_DMA_CC3:
-    {
-      (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC3]);
-      break;
-    }
-    case TIM_DMA_CC4:
-    {
-      (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC4]);
-      break;
-    }
-    case TIM_DMA_COM:
-    {
-      (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_COMMUTATION]);
-      break;
-    }
-    case TIM_DMA_TRIGGER:
-    {
-      (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_TRIGGER]);
-      break;
-    }
-    default:
-      status = HAL_ERROR;
-      break;
-  }
-
-  if (status == HAL_OK)
-  {
-    /* Disable the TIM Update DMA request */
-    __HAL_TIM_DISABLE_DMA(htim, BurstRequestSrc);
-
-    /* Change the DMA burst operation state */
-    htim->DMABurstState = HAL_DMA_BURST_STATE_READY;
-  }
-
-  /* Return function status */
-  return status;
-}
-
-/**
-  * @brief  Generate a software event
-  * @param  htim TIM handle
-  * @param  EventSource specifies the event source.
-  *          This parameter can be one of the following values:
-  *            @arg TIM_EVENTSOURCE_UPDATE: Timer update Event source
-  *            @arg TIM_EVENTSOURCE_CC1: Timer Capture Compare 1 Event source
-  *            @arg TIM_EVENTSOURCE_CC2: Timer Capture Compare 2 Event source
-  *            @arg TIM_EVENTSOURCE_CC3: Timer Capture Compare 3 Event source
-  *            @arg TIM_EVENTSOURCE_CC4: Timer Capture Compare 4 Event source
-  *            @arg TIM_EVENTSOURCE_COM: Timer COM event source
-  *            @arg TIM_EVENTSOURCE_TRIGGER: Timer Trigger Event source
-  *            @arg TIM_EVENTSOURCE_BREAK: Timer Break event source
-  *            @arg TIM_EVENTSOURCE_BREAK2: Timer Break2 event source
-  * @note   Basic timers can only generate an update event.
-  * @note   TIM_EVENTSOURCE_COM is relevant only with advanced timer instances.
-  * @note   TIM_EVENTSOURCE_BREAK and TIM_EVENTSOURCE_BREAK2 are relevant
-  *         only for timer instances supporting break input(s).
-  * @retval HAL status
-  */
-
-HAL_StatusTypeDef HAL_TIM_GenerateEvent(TIM_HandleTypeDef *htim, uint32_t EventSource)
-{
-  /* Check the parameters */
-  assert_param(IS_TIM_INSTANCE(htim->Instance));
-  assert_param(IS_TIM_EVENT_SOURCE(EventSource));
-
-  /* Process Locked */
-  __HAL_LOCK(htim);
-
-  /* Change the TIM state */
-  htim->State = HAL_TIM_STATE_BUSY;
-
-  /* Set the event sources */
-  htim->Instance->EGR = EventSource;
-
-  /* Change the TIM state */
-  htim->State = HAL_TIM_STATE_READY;
-
-  __HAL_UNLOCK(htim);
-
-  /* Return function status */
-  return HAL_OK;
-}
-
-/**
-  * @brief  Configures the OCRef clear feature
-  * @param  htim TIM handle
-  * @param  sClearInputConfig pointer to a TIM_ClearInputConfigTypeDef structure that
-  *         contains the OCREF clear feature and parameters for the TIM peripheral.
-  * @param  Channel specifies the TIM Channel
-  *          This parameter can be one of the following values:
-  *            @arg TIM_CHANNEL_1: TIM Channel 1
-  *            @arg TIM_CHANNEL_2: TIM Channel 2
-  *            @arg TIM_CHANNEL_3: TIM Channel 3
-  *            @arg TIM_CHANNEL_4: TIM Channel 4
-  *            @arg TIM_CHANNEL_5: TIM Channel 5
-  *            @arg TIM_CHANNEL_6: TIM Channel 6
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_TIM_ConfigOCrefClear(TIM_HandleTypeDef *htim,
-                                           const TIM_ClearInputConfigTypeDef *sClearInputConfig,
-                                           uint32_t Channel)
-{
-  HAL_StatusTypeDef status = HAL_OK;
-
-  /* Check the parameters */
-  assert_param(IS_TIM_OCXREF_CLEAR_INSTANCE(htim->Instance));
-  assert_param(IS_TIM_CLEARINPUT_SOURCE(sClearInputConfig->ClearInputSource));
-
-  /* Process Locked */
-  __HAL_LOCK(htim);
-
-  htim->State = HAL_TIM_STATE_BUSY;
-
-  switch (sClearInputConfig->ClearInputSource)
-  {
-    case TIM_CLEARINPUTSOURCE_NONE:
-    {
-      /* Clear the OCREF clear selection bit and the the ETR Bits */
-      CLEAR_BIT(htim->Instance->SMCR, (TIM_SMCR_OCCS | TIM_SMCR_ETF | TIM_SMCR_ETPS | TIM_SMCR_ECE | TIM_SMCR_ETP));
-
-      /* Clear TIMx_AF1_OCREF_CLR (reset value) */
-      CLEAR_BIT(htim->Instance->AF1, TIM1_AF1_ETRSEL);
-      break;
-    }
-    case TIM_CLEARINPUTSOURCE_COMP1:
-    case TIM_CLEARINPUTSOURCE_COMP2:
-    {
-      /* Clear the OCREF clear selection bit */
-      CLEAR_BIT(htim->Instance->SMCR, TIM_SMCR_OCCS);
-
-      /* OCREF_CLR_INT is connected to COMPx output */
-      MODIFY_REG(htim->Instance->AF1, TIM1_AF1_ETRSEL, sClearInputConfig->ClearInputSource);
-      break;
-    }
-
-    case TIM_CLEARINPUTSOURCE_ETR:
-    {
-      /* Check the parameters */
-      assert_param(IS_TIM_CLEARINPUT_POLARITY(sClearInputConfig->ClearInputPolarity));
-      assert_param(IS_TIM_CLEARINPUT_PRESCALER(sClearInputConfig->ClearInputPrescaler));
-      assert_param(IS_TIM_CLEARINPUT_FILTER(sClearInputConfig->ClearInputFilter));
-
-      /* When OCRef clear feature is used with ETR source, ETR prescaler must be off */
-      if (sClearInputConfig->ClearInputPrescaler != TIM_CLEARINPUTPRESCALER_DIV1)
-      {
-        htim->State = HAL_TIM_STATE_READY;
-        __HAL_UNLOCK(htim);
-        return HAL_ERROR;
-      }
-
-      TIM_ETR_SetConfig(htim->Instance,
-                        sClearInputConfig->ClearInputPrescaler,
-                        sClearInputConfig->ClearInputPolarity,
-                        sClearInputConfig->ClearInputFilter);
-
-      /* Set the OCREF clear selection bit */
-      SET_BIT(htim->Instance->SMCR, TIM_SMCR_OCCS);
-
-      /* Clear TIMx_AF1_OCREF_CLR (reset value) */
-      CLEAR_BIT(htim->Instance->AF1, TIM1_AF1_ETRSEL);
-      break;
-    }
-
-    default:
-      status = HAL_ERROR;
-      break;
-  }
-
-  if (status == HAL_OK)
-  {
-    switch (Channel)
-    {
-      case TIM_CHANNEL_1:
-      {
-        if (sClearInputConfig->ClearInputState != (uint32_t)DISABLE)
-        {
-          /* Enable the OCREF clear feature for Channel 1 */
-          SET_BIT(htim->Instance->CCMR1, TIM_CCMR1_OC1CE);
-        }
-        else
-        {
-          /* Disable the OCREF clear feature for Channel 1 */
-          CLEAR_BIT(htim->Instance->CCMR1, TIM_CCMR1_OC1CE);
-        }
-        break;
-      }
-      case TIM_CHANNEL_2:
-      {
-        if (sClearInputConfig->ClearInputState != (uint32_t)DISABLE)
-        {
-          /* Enable the OCREF clear feature for Channel 2 */
-          SET_BIT(htim->Instance->CCMR1, TIM_CCMR1_OC2CE);
-        }
-        else
-        {
-          /* Disable the OCREF clear feature for Channel 2 */
-          CLEAR_BIT(htim->Instance->CCMR1, TIM_CCMR1_OC2CE);
-        }
-        break;
-      }
-      case TIM_CHANNEL_3:
-      {
-        if (sClearInputConfig->ClearInputState != (uint32_t)DISABLE)
-        {
-          /* Enable the OCREF clear feature for Channel 3 */
-          SET_BIT(htim->Instance->CCMR2, TIM_CCMR2_OC3CE);
-        }
-        else
-        {
-          /* Disable the OCREF clear feature for Channel 3 */
-          CLEAR_BIT(htim->Instance->CCMR2, TIM_CCMR2_OC3CE);
-        }
-        break;
-      }
-      case TIM_CHANNEL_4:
-      {
-        if (sClearInputConfig->ClearInputState != (uint32_t)DISABLE)
-        {
-          /* Enable the OCREF clear feature for Channel 4 */
-          SET_BIT(htim->Instance->CCMR2, TIM_CCMR2_OC4CE);
-        }
-        else
-        {
-          /* Disable the OCREF clear feature for Channel 4 */
-          CLEAR_BIT(htim->Instance->CCMR2, TIM_CCMR2_OC4CE);
-        }
-        break;
-      }
-      case TIM_CHANNEL_5:
-      {
-        if (sClearInputConfig->ClearInputState != (uint32_t)DISABLE)
-        {
-          /* Enable the OCREF clear feature for Channel 5 */
-          SET_BIT(htim->Instance->CCMR3, TIM_CCMR3_OC5CE);
-        }
-        else
-        {
-          /* Disable the OCREF clear feature for Channel 5 */
-          CLEAR_BIT(htim->Instance->CCMR3, TIM_CCMR3_OC5CE);
-        }
-        break;
-      }
-      case TIM_CHANNEL_6:
-      {
-        if (sClearInputConfig->ClearInputState != (uint32_t)DISABLE)
-        {
-          /* Enable the OCREF clear feature for Channel 6 */
-          SET_BIT(htim->Instance->CCMR3, TIM_CCMR3_OC6CE);
-        }
-        else
-        {
-          /* Disable the OCREF clear feature for Channel 6 */
-          CLEAR_BIT(htim->Instance->CCMR3, TIM_CCMR3_OC6CE);
-        }
-        break;
-      }
-      default:
-        break;
-    }
-  }
-
-  htim->State = HAL_TIM_STATE_READY;
-
-  __HAL_UNLOCK(htim);
-
-  return status;
-}
-
-/**
-  * @brief   Configures the clock source to be used
-  * @param  htim TIM handle
-  * @param  sClockSourceConfig pointer to a TIM_ClockConfigTypeDef structure that
-  *         contains the clock source information for the TIM peripheral.
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_TIM_ConfigClockSource(TIM_HandleTypeDef *htim, const TIM_ClockConfigTypeDef *sClockSourceConfig)
-{
-  HAL_StatusTypeDef status = HAL_OK;
-  uint32_t tmpsmcr;
-
-  /* Process Locked */
-  __HAL_LOCK(htim);
-
-  htim->State = HAL_TIM_STATE_BUSY;
-
-  /* Check the parameters */
-  assert_param(IS_TIM_CLOCKSOURCE(sClockSourceConfig->ClockSource));
-
-  /* Reset the SMS, TS, ECE, ETPS and ETRF bits */
-  tmpsmcr = htim->Instance->SMCR;
-  tmpsmcr &= ~(TIM_SMCR_SMS | TIM_SMCR_TS);
-  tmpsmcr &= ~(TIM_SMCR_ETF | TIM_SMCR_ETPS | TIM_SMCR_ECE | TIM_SMCR_ETP);
-  htim->Instance->SMCR = tmpsmcr;
-
-  switch (sClockSourceConfig->ClockSource)
-  {
-    case TIM_CLOCKSOURCE_INTERNAL:
-    {
-      assert_param(IS_TIM_INSTANCE(htim->Instance));
-      break;
-    }
-
-    case TIM_CLOCKSOURCE_ETRMODE1:
-    {
-      /* Check whether or not the timer instance supports external trigger input mode 1 (ETRF)*/
-      assert_param(IS_TIM_CLOCKSOURCE_ETRMODE1_INSTANCE(htim->Instance));
-
-      /* Check ETR input conditioning related parameters */
-      assert_param(IS_TIM_CLOCKPRESCALER(sClockSourceConfig->ClockPrescaler));
-      assert_param(IS_TIM_CLOCKPOLARITY(sClockSourceConfig->ClockPolarity));
-      assert_param(IS_TIM_CLOCKFILTER(sClockSourceConfig->ClockFilter));
-
-      /* Configure the ETR Clock source */
-      TIM_ETR_SetConfig(htim->Instance,
-                        sClockSourceConfig->ClockPrescaler,
-                        sClockSourceConfig->ClockPolarity,
-                        sClockSourceConfig->ClockFilter);
-
-      /* Select the External clock mode1 and the ETRF trigger */
-      tmpsmcr = htim->Instance->SMCR;
-      tmpsmcr |= (TIM_SLAVEMODE_EXTERNAL1 | TIM_CLOCKSOURCE_ETRMODE1);
-      /* Write to TIMx SMCR */
-      htim->Instance->SMCR = tmpsmcr;
-      break;
-    }
-
-    case TIM_CLOCKSOURCE_ETRMODE2:
-    {
-      /* Check whether or not the timer instance supports external trigger input mode 2 (ETRF)*/
-      assert_param(IS_TIM_CLOCKSOURCE_ETRMODE2_INSTANCE(htim->Instance));
-
-      /* Check ETR input conditioning related parameters */
-      assert_param(IS_TIM_CLOCKPRESCALER(sClockSourceConfig->ClockPrescaler));
-      assert_param(IS_TIM_CLOCKPOLARITY(sClockSourceConfig->ClockPolarity));
-      assert_param(IS_TIM_CLOCKFILTER(sClockSourceConfig->ClockFilter));
-
-      /* Configure the ETR Clock source */
-      TIM_ETR_SetConfig(htim->Instance,
-                        sClockSourceConfig->ClockPrescaler,
-                        sClockSourceConfig->ClockPolarity,
-                        sClockSourceConfig->ClockFilter);
-      /* Enable the External clock mode2 */
-      htim->Instance->SMCR |= TIM_SMCR_ECE;
-      break;
-    }
-
-    case TIM_CLOCKSOURCE_TI1:
-    {
-      /* Check whether or not the timer instance supports external clock mode 1 */
-      assert_param(IS_TIM_CLOCKSOURCE_TIX_INSTANCE(htim->Instance));
-
-      /* Check TI1 input conditioning related parameters */
-      assert_param(IS_TIM_CLOCKPOLARITY(sClockSourceConfig->ClockPolarity));
-      assert_param(IS_TIM_CLOCKFILTER(sClockSourceConfig->ClockFilter));
-
-      TIM_TI1_ConfigInputStage(htim->Instance,
-                               sClockSourceConfig->ClockPolarity,
-                               sClockSourceConfig->ClockFilter);
-      TIM_ITRx_SetConfig(htim->Instance, TIM_CLOCKSOURCE_TI1);
-      break;
-    }
-
-    case TIM_CLOCKSOURCE_TI2:
-    {
-      /* Check whether or not the timer instance supports external clock mode 1 (ETRF)*/
-      assert_param(IS_TIM_CLOCKSOURCE_TIX_INSTANCE(htim->Instance));
-
-      /* Check TI2 input conditioning related parameters */
-      assert_param(IS_TIM_CLOCKPOLARITY(sClockSourceConfig->ClockPolarity));
-      assert_param(IS_TIM_CLOCKFILTER(sClockSourceConfig->ClockFilter));
-
-      TIM_TI2_ConfigInputStage(htim->Instance,
-                               sClockSourceConfig->ClockPolarity,
-                               sClockSourceConfig->ClockFilter);
-      TIM_ITRx_SetConfig(htim->Instance, TIM_CLOCKSOURCE_TI2);
-      break;
-    }
-
-    case TIM_CLOCKSOURCE_TI1ED:
-    {
-      /* Check whether or not the timer instance supports external clock mode 1 */
-      assert_param(IS_TIM_CLOCKSOURCE_TIX_INSTANCE(htim->Instance));
-
-      /* Check TI1 input conditioning related parameters */
-      assert_param(IS_TIM_CLOCKPOLARITY(sClockSourceConfig->ClockPolarity));
-      assert_param(IS_TIM_CLOCKFILTER(sClockSourceConfig->ClockFilter));
-
-      TIM_TI1_ConfigInputStage(htim->Instance,
-                               sClockSourceConfig->ClockPolarity,
-                               sClockSourceConfig->ClockFilter);
-      TIM_ITRx_SetConfig(htim->Instance, TIM_CLOCKSOURCE_TI1ED);
-      break;
-    }
-
-    case TIM_CLOCKSOURCE_ITR0:
-    case TIM_CLOCKSOURCE_ITR1:
-    case TIM_CLOCKSOURCE_ITR2:
-    case TIM_CLOCKSOURCE_ITR3:
-    {
-      /* Check whether or not the timer instance supports internal trigger input */
-      assert_param(IS_TIM_CLOCKSOURCE_ITRX_INSTANCE(htim->Instance));
-
-      TIM_ITRx_SetConfig(htim->Instance, sClockSourceConfig->ClockSource);
-      break;
-    }
-
-    default:
-      status = HAL_ERROR;
-      break;
-  }
-  htim->State = HAL_TIM_STATE_READY;
-
-  __HAL_UNLOCK(htim);
-
-  return status;
-}
-
-/**
-  * @brief  Selects the signal connected to the TI1 input: direct from CH1_input
-  *         or a XOR combination between CH1_input, CH2_input & CH3_input
-  * @param  htim TIM handle.
-  * @param  TI1_Selection Indicate whether or not channel 1 is connected to the
-  *         output of a XOR gate.
-  *          This parameter can be one of the following values:
-  *            @arg TIM_TI1SELECTION_CH1: The TIMx_CH1 pin is connected to TI1 input
-  *            @arg TIM_TI1SELECTION_XORCOMBINATION: The TIMx_CH1, CH2 and CH3
-  *            pins are connected to the TI1 input (XOR combination)
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_TIM_ConfigTI1Input(TIM_HandleTypeDef *htim, uint32_t TI1_Selection)
-{
-  uint32_t tmpcr2;
-
-  /* Check the parameters */
-  assert_param(IS_TIM_XOR_INSTANCE(htim->Instance));
-  assert_param(IS_TIM_TI1SELECTION(TI1_Selection));
-
-  /* Get the TIMx CR2 register value */
-  tmpcr2 = htim->Instance->CR2;
-
-  /* Reset the TI1 selection */
-  tmpcr2 &= ~TIM_CR2_TI1S;
-
-  /* Set the TI1 selection */
-  tmpcr2 |= TI1_Selection;
-
-  /* Write to TIMxCR2 */
-  htim->Instance->CR2 = tmpcr2;
-
-  return HAL_OK;
-}
-
-/**
-  * @brief  Configures the TIM in Slave mode
-  * @param  htim TIM handle.
-  * @param  sSlaveConfig pointer to a TIM_SlaveConfigTypeDef structure that
-  *         contains the selected trigger (internal trigger input, filtered
-  *         timer input or external trigger input) and the Slave mode
-  *         (Disable, Reset, Gated, Trigger, External clock mode 1).
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_TIM_SlaveConfigSynchro(TIM_HandleTypeDef *htim, const TIM_SlaveConfigTypeDef *sSlaveConfig)
-{
-  /* Check the parameters */
-  assert_param(IS_TIM_SLAVE_INSTANCE(htim->Instance));
-  assert_param(IS_TIM_SLAVE_MODE(sSlaveConfig->SlaveMode));
-  assert_param(IS_TIM_TRIGGER_SELECTION(sSlaveConfig->InputTrigger));
-
-  __HAL_LOCK(htim);
-
-  htim->State = HAL_TIM_STATE_BUSY;
-
-  if (TIM_SlaveTimer_SetConfig(htim, sSlaveConfig) != HAL_OK)
-  {
-    htim->State = HAL_TIM_STATE_READY;
-    __HAL_UNLOCK(htim);
-    return HAL_ERROR;
-  }
-
-  /* Disable Trigger Interrupt */
-  __HAL_TIM_DISABLE_IT(htim, TIM_IT_TRIGGER);
-
-  /* Disable Trigger DMA request */
-  __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_TRIGGER);
-
-  htim->State = HAL_TIM_STATE_READY;
-
-  __HAL_UNLOCK(htim);
-
-  return HAL_OK;
-}
-
-/**
-  * @brief  Configures the TIM in Slave mode in interrupt mode
-  * @param  htim TIM handle.
-  * @param  sSlaveConfig pointer to a TIM_SlaveConfigTypeDef structure that
-  *         contains the selected trigger (internal trigger input, filtered
-  *         timer input or external trigger input) and the Slave mode
-  *         (Disable, Reset, Gated, Trigger, External clock mode 1).
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_TIM_SlaveConfigSynchro_IT(TIM_HandleTypeDef *htim,
-                                                const TIM_SlaveConfigTypeDef *sSlaveConfig)
-{
-  /* Check the parameters */
-  assert_param(IS_TIM_SLAVE_INSTANCE(htim->Instance));
-  assert_param(IS_TIM_SLAVE_MODE(sSlaveConfig->SlaveMode));
-  assert_param(IS_TIM_TRIGGER_SELECTION(sSlaveConfig->InputTrigger));
-
-  __HAL_LOCK(htim);
-
-  htim->State = HAL_TIM_STATE_BUSY;
-
-  if (TIM_SlaveTimer_SetConfig(htim, sSlaveConfig) != HAL_OK)
-  {
-    htim->State = HAL_TIM_STATE_READY;
-    __HAL_UNLOCK(htim);
-    return HAL_ERROR;
-  }
-
-  /* Enable Trigger Interrupt */
-  __HAL_TIM_ENABLE_IT(htim, TIM_IT_TRIGGER);
-
-  /* Disable Trigger DMA request */
-  __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_TRIGGER);
-
-  htim->State = HAL_TIM_STATE_READY;
-
-  __HAL_UNLOCK(htim);
-
-  return HAL_OK;
-}
-
-/**
-  * @brief  Read the captured value from Capture Compare unit
-  * @param  htim TIM handle.
-  * @param  Channel TIM Channels to be enabled
-  *          This parameter can be one of the following values:
-  *            @arg TIM_CHANNEL_1: TIM Channel 1 selected
-  *            @arg TIM_CHANNEL_2: TIM Channel 2 selected
-  *            @arg TIM_CHANNEL_3: TIM Channel 3 selected
-  *            @arg TIM_CHANNEL_4: TIM Channel 4 selected
-  * @retval Captured value
-  */
-uint32_t HAL_TIM_ReadCapturedValue(const TIM_HandleTypeDef *htim, uint32_t Channel)
-{
-  uint32_t tmpreg = 0U;
-
-  switch (Channel)
-  {
-    case TIM_CHANNEL_1:
-    {
-      /* Check the parameters */
-      assert_param(IS_TIM_CC1_INSTANCE(htim->Instance));
-
-      /* Return the capture 1 value */
-      tmpreg =  htim->Instance->CCR1;
-
-      break;
-    }
-    case TIM_CHANNEL_2:
-    {
-      /* Check the parameters */
-      assert_param(IS_TIM_CC2_INSTANCE(htim->Instance));
-
-      /* Return the capture 2 value */
-      tmpreg =   htim->Instance->CCR2;
-
-      break;
-    }
-
-    case TIM_CHANNEL_3:
-    {
-      /* Check the parameters */
-      assert_param(IS_TIM_CC3_INSTANCE(htim->Instance));
-
-      /* Return the capture 3 value */
-      tmpreg =   htim->Instance->CCR3;
-
-      break;
-    }
-
-    case TIM_CHANNEL_4:
-    {
-      /* Check the parameters */
-      assert_param(IS_TIM_CC4_INSTANCE(htim->Instance));
-
-      /* Return the capture 4 value */
-      tmpreg =   htim->Instance->CCR4;
-
-      break;
-    }
-
-    default:
-      break;
-  }
-
-  return tmpreg;
-}
-
-/**
-  * @}
-  */
-
-/** @defgroup TIM_Exported_Functions_Group9 TIM Callbacks functions
-  *  @brief    TIM Callbacks functions
-  *
-@verbatim
-  ==============================================================================
-                        ##### TIM Callbacks functions #####
-  ==============================================================================
- [..]
-   This section provides TIM callback functions:
-   (+) TIM Period elapsed callback
-   (+) TIM Output Compare callback
-   (+) TIM Input capture callback
-   (+) TIM Trigger callback
-   (+) TIM Error callback
-
-@endverbatim
-  * @{
-  */
-
-/**
-  * @brief  Period elapsed callback in non-blocking mode
-  * @param  htim TIM handle
-  * @retval None
-  */
-__weak void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
-{
-  /* Prevent unused argument(s) compilation warning */
-  UNUSED(htim);
-
-  /* NOTE : This function should not be modified, when the callback is needed,
-            the HAL_TIM_PeriodElapsedCallback could be implemented in the user file
-   */
-}
-
-/**
-  * @brief  Period elapsed half complete callback in non-blocking mode
-  * @param  htim TIM handle
-  * @retval None
-  */
-__weak void HAL_TIM_PeriodElapsedHalfCpltCallback(TIM_HandleTypeDef *htim)
-{
-  /* Prevent unused argument(s) compilation warning */
-  UNUSED(htim);
-
-  /* NOTE : This function should not be modified, when the callback is needed,
-            the HAL_TIM_PeriodElapsedHalfCpltCallback could be implemented in the user file
-   */
-}
-
-/**
-  * @brief  Output Compare callback in non-blocking mode
-  * @param  htim TIM OC handle
-  * @retval None
-  */
-__weak void HAL_TIM_OC_DelayElapsedCallback(TIM_HandleTypeDef *htim)
-{
-  /* Prevent unused argument(s) compilation warning */
-  UNUSED(htim);
-
-  /* NOTE : This function should not be modified, when the callback is needed,
-            the HAL_TIM_OC_DelayElapsedCallback could be implemented in the user file
-   */
-}
-
-/**
-  * @brief  Input Capture callback in non-blocking mode
-  * @param  htim TIM IC handle
-  * @retval None
-  */
-__weak void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
-{
-  /* Prevent unused argument(s) compilation warning */
-  UNUSED(htim);
-
-  /* NOTE : This function should not be modified, when the callback is needed,
-            the HAL_TIM_IC_CaptureCallback could be implemented in the user file
-   */
-}
-
-/**
-  * @brief  Input Capture half complete callback in non-blocking mode
-  * @param  htim TIM IC handle
-  * @retval None
-  */
-__weak void HAL_TIM_IC_CaptureHalfCpltCallback(TIM_HandleTypeDef *htim)
-{
-  /* Prevent unused argument(s) compilation warning */
-  UNUSED(htim);
-
-  /* NOTE : This function should not be modified, when the callback is needed,
-            the HAL_TIM_IC_CaptureHalfCpltCallback could be implemented in the user file
-   */
-}
-
-/**
-  * @brief  PWM Pulse finished callback in non-blocking mode
-  * @param  htim TIM handle
-  * @retval None
-  */
-__weak void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim)
-{
-  /* Prevent unused argument(s) compilation warning */
-  UNUSED(htim);
-
-  /* NOTE : This function should not be modified, when the callback is needed,
-            the HAL_TIM_PWM_PulseFinishedCallback could be implemented in the user file
-   */
-}
-
-/**
-  * @brief  PWM Pulse finished half complete callback in non-blocking mode
-  * @param  htim TIM handle
-  * @retval None
-  */
-__weak void HAL_TIM_PWM_PulseFinishedHalfCpltCallback(TIM_HandleTypeDef *htim)
-{
-  /* Prevent unused argument(s) compilation warning */
-  UNUSED(htim);
-
-  /* NOTE : This function should not be modified, when the callback is needed,
-            the HAL_TIM_PWM_PulseFinishedHalfCpltCallback could be implemented in the user file
-   */
-}
-
-/**
-  * @brief  Hall Trigger detection callback in non-blocking mode
-  * @param  htim TIM handle
-  * @retval None
-  */
-__weak void HAL_TIM_TriggerCallback(TIM_HandleTypeDef *htim)
-{
-  /* Prevent unused argument(s) compilation warning */
-  UNUSED(htim);
-
-  /* NOTE : This function should not be modified, when the callback is needed,
-            the HAL_TIM_TriggerCallback could be implemented in the user file
-   */
-}
-
-/**
-  * @brief  Hall Trigger detection half complete callback in non-blocking mode
-  * @param  htim TIM handle
-  * @retval None
-  */
-__weak void HAL_TIM_TriggerHalfCpltCallback(TIM_HandleTypeDef *htim)
-{
-  /* Prevent unused argument(s) compilation warning */
-  UNUSED(htim);
-
-  /* NOTE : This function should not be modified, when the callback is needed,
-            the HAL_TIM_TriggerHalfCpltCallback could be implemented in the user file
-   */
-}
-
-/**
-  * @brief  Timer error callback in non-blocking mode
-  * @param  htim TIM handle
-  * @retval None
-  */
-__weak void HAL_TIM_ErrorCallback(TIM_HandleTypeDef *htim)
-{
-  /* Prevent unused argument(s) compilation warning */
-  UNUSED(htim);
-
-  /* NOTE : This function should not be modified, when the callback is needed,
-            the HAL_TIM_ErrorCallback could be implemented in the user file
-   */
-}
-
-#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
-/**
-  * @brief  Register a User TIM callback to be used instead of the weak predefined callback
-  * @param htim tim handle
-  * @param CallbackID ID of the callback to be registered
-  *        This parameter can be one of the following values:
-  *          @arg @ref HAL_TIM_BASE_MSPINIT_CB_ID Base MspInit Callback ID
-  *          @arg @ref HAL_TIM_BASE_MSPDEINIT_CB_ID Base MspDeInit Callback ID
-  *          @arg @ref HAL_TIM_IC_MSPINIT_CB_ID IC MspInit Callback ID
-  *          @arg @ref HAL_TIM_IC_MSPDEINIT_CB_ID IC MspDeInit Callback ID
-  *          @arg @ref HAL_TIM_OC_MSPINIT_CB_ID OC MspInit Callback ID
-  *          @arg @ref HAL_TIM_OC_MSPDEINIT_CB_ID OC MspDeInit Callback ID
-  *          @arg @ref HAL_TIM_PWM_MSPINIT_CB_ID PWM MspInit Callback ID
-  *          @arg @ref HAL_TIM_PWM_MSPDEINIT_CB_ID PWM MspDeInit Callback ID
-  *          @arg @ref HAL_TIM_ONE_PULSE_MSPINIT_CB_ID One Pulse MspInit Callback ID
-  *          @arg @ref HAL_TIM_ONE_PULSE_MSPDEINIT_CB_ID One Pulse MspDeInit Callback ID
-  *          @arg @ref HAL_TIM_ENCODER_MSPINIT_CB_ID Encoder MspInit Callback ID
-  *          @arg @ref HAL_TIM_ENCODER_MSPDEINIT_CB_ID Encoder MspDeInit Callback ID
-  *          @arg @ref HAL_TIM_HALL_SENSOR_MSPINIT_CB_ID Hall Sensor MspInit Callback ID
-  *          @arg @ref HAL_TIM_HALL_SENSOR_MSPDEINIT_CB_ID Hall Sensor MspDeInit Callback ID
-  *          @arg @ref HAL_TIM_PERIOD_ELAPSED_CB_ID Period Elapsed Callback ID
-  *          @arg @ref HAL_TIM_PERIOD_ELAPSED_HALF_CB_ID Period Elapsed half complete Callback ID
-  *          @arg @ref HAL_TIM_TRIGGER_CB_ID Trigger Callback ID
-  *          @arg @ref HAL_TIM_TRIGGER_HALF_CB_ID Trigger half complete Callback ID
-  *          @arg @ref HAL_TIM_IC_CAPTURE_CB_ID Input Capture Callback ID
-  *          @arg @ref HAL_TIM_IC_CAPTURE_HALF_CB_ID Input Capture half complete Callback ID
-  *          @arg @ref HAL_TIM_OC_DELAY_ELAPSED_CB_ID Output Compare Delay Elapsed Callback ID
-  *          @arg @ref HAL_TIM_PWM_PULSE_FINISHED_CB_ID PWM Pulse Finished Callback ID
-  *          @arg @ref HAL_TIM_PWM_PULSE_FINISHED_HALF_CB_ID PWM Pulse Finished half complete Callback ID
-  *          @arg @ref HAL_TIM_ERROR_CB_ID Error Callback ID
-  *          @arg @ref HAL_TIM_COMMUTATION_CB_ID Commutation Callback ID
-  *          @arg @ref HAL_TIM_COMMUTATION_HALF_CB_ID Commutation half complete Callback ID
-  *          @arg @ref HAL_TIM_BREAK_CB_ID Break Callback ID
-  *          @arg @ref HAL_TIM_BREAK2_CB_ID Break2 Callback ID
-  *          @param pCallback pointer to the callback function
-  *          @retval status
-  */
-HAL_StatusTypeDef HAL_TIM_RegisterCallback(TIM_HandleTypeDef *htim, HAL_TIM_CallbackIDTypeDef CallbackID,
-                                           pTIM_CallbackTypeDef pCallback)
-{
-  HAL_StatusTypeDef status = HAL_OK;
-
-  if (pCallback == NULL)
-  {
-    return HAL_ERROR;
-  }
-
-  if (htim->State == HAL_TIM_STATE_READY)
-  {
-    switch (CallbackID)
-    {
-      case HAL_TIM_BASE_MSPINIT_CB_ID :
-        htim->Base_MspInitCallback                 = pCallback;
-        break;
-
-      case HAL_TIM_BASE_MSPDEINIT_CB_ID :
-        htim->Base_MspDeInitCallback               = pCallback;
-        break;
-
-      case HAL_TIM_IC_MSPINIT_CB_ID :
-        htim->IC_MspInitCallback                   = pCallback;
-        break;
-
-      case HAL_TIM_IC_MSPDEINIT_CB_ID :
-        htim->IC_MspDeInitCallback                 = pCallback;
-        break;
-
-      case HAL_TIM_OC_MSPINIT_CB_ID :
-        htim->OC_MspInitCallback                   = pCallback;
-        break;
-
-      case HAL_TIM_OC_MSPDEINIT_CB_ID :
-        htim->OC_MspDeInitCallback                 = pCallback;
-        break;
-
-      case HAL_TIM_PWM_MSPINIT_CB_ID :
-        htim->PWM_MspInitCallback                  = pCallback;
-        break;
-
-      case HAL_TIM_PWM_MSPDEINIT_CB_ID :
-        htim->PWM_MspDeInitCallback                = pCallback;
-        break;
-
-      case HAL_TIM_ONE_PULSE_MSPINIT_CB_ID :
-        htim->OnePulse_MspInitCallback             = pCallback;
-        break;
-
-      case HAL_TIM_ONE_PULSE_MSPDEINIT_CB_ID :
-        htim->OnePulse_MspDeInitCallback           = pCallback;
-        break;
-
-      case HAL_TIM_ENCODER_MSPINIT_CB_ID :
-        htim->Encoder_MspInitCallback              = pCallback;
-        break;
-
-      case HAL_TIM_ENCODER_MSPDEINIT_CB_ID :
-        htim->Encoder_MspDeInitCallback            = pCallback;
-        break;
-
-      case HAL_TIM_HALL_SENSOR_MSPINIT_CB_ID :
-        htim->HallSensor_MspInitCallback           = pCallback;
-        break;
-
-      case HAL_TIM_HALL_SENSOR_MSPDEINIT_CB_ID :
-        htim->HallSensor_MspDeInitCallback         = pCallback;
-        break;
-
-      case HAL_TIM_PERIOD_ELAPSED_CB_ID :
-        htim->PeriodElapsedCallback                = pCallback;
-        break;
-
-      case HAL_TIM_PERIOD_ELAPSED_HALF_CB_ID :
-        htim->PeriodElapsedHalfCpltCallback        = pCallback;
-        break;
-
-      case HAL_TIM_TRIGGER_CB_ID :
-        htim->TriggerCallback                      = pCallback;
-        break;
-
-      case HAL_TIM_TRIGGER_HALF_CB_ID :
-        htim->TriggerHalfCpltCallback              = pCallback;
-        break;
-
-      case HAL_TIM_IC_CAPTURE_CB_ID :
-        htim->IC_CaptureCallback                   = pCallback;
-        break;
-
-      case HAL_TIM_IC_CAPTURE_HALF_CB_ID :
-        htim->IC_CaptureHalfCpltCallback           = pCallback;
-        break;
-
-      case HAL_TIM_OC_DELAY_ELAPSED_CB_ID :
-        htim->OC_DelayElapsedCallback              = pCallback;
-        break;
-
-      case HAL_TIM_PWM_PULSE_FINISHED_CB_ID :
-        htim->PWM_PulseFinishedCallback            = pCallback;
-        break;
-
-      case HAL_TIM_PWM_PULSE_FINISHED_HALF_CB_ID :
-        htim->PWM_PulseFinishedHalfCpltCallback    = pCallback;
-        break;
-
-      case HAL_TIM_ERROR_CB_ID :
-        htim->ErrorCallback                        = pCallback;
-        break;
-
-      case HAL_TIM_COMMUTATION_CB_ID :
-        htim->CommutationCallback                  = pCallback;
-        break;
-
-      case HAL_TIM_COMMUTATION_HALF_CB_ID :
-        htim->CommutationHalfCpltCallback          = pCallback;
-        break;
-
-      case HAL_TIM_BREAK_CB_ID :
-        htim->BreakCallback                        = pCallback;
-        break;
-
-      case HAL_TIM_BREAK2_CB_ID :
-        htim->Break2Callback                       = pCallback;
-        break;
-
-      default :
-        /* Return error status */
-        status = HAL_ERROR;
-        break;
-    }
-  }
-  else if (htim->State == HAL_TIM_STATE_RESET)
-  {
-    switch (CallbackID)
-    {
-      case HAL_TIM_BASE_MSPINIT_CB_ID :
-        htim->Base_MspInitCallback         = pCallback;
-        break;
-
-      case HAL_TIM_BASE_MSPDEINIT_CB_ID :
-        htim->Base_MspDeInitCallback       = pCallback;
-        break;
-
-      case HAL_TIM_IC_MSPINIT_CB_ID :
-        htim->IC_MspInitCallback           = pCallback;
-        break;
-
-      case HAL_TIM_IC_MSPDEINIT_CB_ID :
-        htim->IC_MspDeInitCallback         = pCallback;
-        break;
-
-      case HAL_TIM_OC_MSPINIT_CB_ID :
-        htim->OC_MspInitCallback           = pCallback;
-        break;
-
-      case HAL_TIM_OC_MSPDEINIT_CB_ID :
-        htim->OC_MspDeInitCallback         = pCallback;
-        break;
-
-      case HAL_TIM_PWM_MSPINIT_CB_ID :
-        htim->PWM_MspInitCallback          = pCallback;
-        break;
-
-      case HAL_TIM_PWM_MSPDEINIT_CB_ID :
-        htim->PWM_MspDeInitCallback        = pCallback;
-        break;
-
-      case HAL_TIM_ONE_PULSE_MSPINIT_CB_ID :
-        htim->OnePulse_MspInitCallback     = pCallback;
-        break;
-
-      case HAL_TIM_ONE_PULSE_MSPDEINIT_CB_ID :
-        htim->OnePulse_MspDeInitCallback   = pCallback;
-        break;
-
-      case HAL_TIM_ENCODER_MSPINIT_CB_ID :
-        htim->Encoder_MspInitCallback      = pCallback;
-        break;
-
-      case HAL_TIM_ENCODER_MSPDEINIT_CB_ID :
-        htim->Encoder_MspDeInitCallback    = pCallback;
-        break;
-
-      case HAL_TIM_HALL_SENSOR_MSPINIT_CB_ID :
-        htim->HallSensor_MspInitCallback   = pCallback;
-        break;
-
-      case HAL_TIM_HALL_SENSOR_MSPDEINIT_CB_ID :
-        htim->HallSensor_MspDeInitCallback = pCallback;
-        break;
-
-      default :
-        /* Return error status */
-        status = HAL_ERROR;
-        break;
-    }
-  }
-  else
-  {
-    /* Return error status */
-    status = HAL_ERROR;
-  }
-
-  return status;
-}
-
-/**
-  * @brief  Unregister a TIM callback
-  *         TIM callback is redirected to the weak predefined callback
-  * @param htim tim handle
-  * @param CallbackID ID of the callback to be unregistered
-  *        This parameter can be one of the following values:
-  *          @arg @ref HAL_TIM_BASE_MSPINIT_CB_ID Base MspInit Callback ID
-  *          @arg @ref HAL_TIM_BASE_MSPDEINIT_CB_ID Base MspDeInit Callback ID
-  *          @arg @ref HAL_TIM_IC_MSPINIT_CB_ID IC MspInit Callback ID
-  *          @arg @ref HAL_TIM_IC_MSPDEINIT_CB_ID IC MspDeInit Callback ID
-  *          @arg @ref HAL_TIM_OC_MSPINIT_CB_ID OC MspInit Callback ID
-  *          @arg @ref HAL_TIM_OC_MSPDEINIT_CB_ID OC MspDeInit Callback ID
-  *          @arg @ref HAL_TIM_PWM_MSPINIT_CB_ID PWM MspInit Callback ID
-  *          @arg @ref HAL_TIM_PWM_MSPDEINIT_CB_ID PWM MspDeInit Callback ID
-  *          @arg @ref HAL_TIM_ONE_PULSE_MSPINIT_CB_ID One Pulse MspInit Callback ID
-  *          @arg @ref HAL_TIM_ONE_PULSE_MSPDEINIT_CB_ID One Pulse MspDeInit Callback ID
-  *          @arg @ref HAL_TIM_ENCODER_MSPINIT_CB_ID Encoder MspInit Callback ID
-  *          @arg @ref HAL_TIM_ENCODER_MSPDEINIT_CB_ID Encoder MspDeInit Callback ID
-  *          @arg @ref HAL_TIM_HALL_SENSOR_MSPINIT_CB_ID Hall Sensor MspInit Callback ID
-  *          @arg @ref HAL_TIM_HALL_SENSOR_MSPDEINIT_CB_ID Hall Sensor MspDeInit Callback ID
-  *          @arg @ref HAL_TIM_PERIOD_ELAPSED_CB_ID Period Elapsed Callback ID
-  *          @arg @ref HAL_TIM_PERIOD_ELAPSED_HALF_CB_ID Period Elapsed half complete Callback ID
-  *          @arg @ref HAL_TIM_TRIGGER_CB_ID Trigger Callback ID
-  *          @arg @ref HAL_TIM_TRIGGER_HALF_CB_ID Trigger half complete Callback ID
-  *          @arg @ref HAL_TIM_IC_CAPTURE_CB_ID Input Capture Callback ID
-  *          @arg @ref HAL_TIM_IC_CAPTURE_HALF_CB_ID Input Capture half complete Callback ID
-  *          @arg @ref HAL_TIM_OC_DELAY_ELAPSED_CB_ID Output Compare Delay Elapsed Callback ID
-  *          @arg @ref HAL_TIM_PWM_PULSE_FINISHED_CB_ID PWM Pulse Finished Callback ID
-  *          @arg @ref HAL_TIM_PWM_PULSE_FINISHED_HALF_CB_ID PWM Pulse Finished half complete Callback ID
-  *          @arg @ref HAL_TIM_ERROR_CB_ID Error Callback ID
-  *          @arg @ref HAL_TIM_COMMUTATION_CB_ID Commutation Callback ID
-  *          @arg @ref HAL_TIM_COMMUTATION_HALF_CB_ID Commutation half complete Callback ID
-  *          @arg @ref HAL_TIM_BREAK_CB_ID Break Callback ID
-  *          @arg @ref HAL_TIM_BREAK2_CB_ID Break2 Callback ID
-  *          @retval status
-  */
-HAL_StatusTypeDef HAL_TIM_UnRegisterCallback(TIM_HandleTypeDef *htim, HAL_TIM_CallbackIDTypeDef CallbackID)
-{
-  HAL_StatusTypeDef status = HAL_OK;
-
-  if (htim->State == HAL_TIM_STATE_READY)
-  {
-    switch (CallbackID)
-    {
-      case HAL_TIM_BASE_MSPINIT_CB_ID :
-        /* Legacy weak Base MspInit Callback */
-        htim->Base_MspInitCallback              = HAL_TIM_Base_MspInit;
-        break;
-
-      case HAL_TIM_BASE_MSPDEINIT_CB_ID :
-        /* Legacy weak Base Msp DeInit Callback */
-        htim->Base_MspDeInitCallback            = HAL_TIM_Base_MspDeInit;
-        break;
-
-      case HAL_TIM_IC_MSPINIT_CB_ID :
-        /* Legacy weak IC Msp Init Callback */
-        htim->IC_MspInitCallback                = HAL_TIM_IC_MspInit;
-        break;
-
-      case HAL_TIM_IC_MSPDEINIT_CB_ID :
-        /* Legacy weak IC Msp DeInit Callback */
-        htim->IC_MspDeInitCallback              = HAL_TIM_IC_MspDeInit;
-        break;
-
-      case HAL_TIM_OC_MSPINIT_CB_ID :
-        /* Legacy weak OC Msp Init Callback */
-        htim->OC_MspInitCallback                = HAL_TIM_OC_MspInit;
-        break;
-
-      case HAL_TIM_OC_MSPDEINIT_CB_ID :
-        /* Legacy weak OC Msp DeInit Callback */
-        htim->OC_MspDeInitCallback              = HAL_TIM_OC_MspDeInit;
-        break;
-
-      case HAL_TIM_PWM_MSPINIT_CB_ID :
-        /* Legacy weak PWM Msp Init Callback */
-        htim->PWM_MspInitCallback               = HAL_TIM_PWM_MspInit;
-        break;
-
-      case HAL_TIM_PWM_MSPDEINIT_CB_ID :
-        /* Legacy weak PWM Msp DeInit Callback */
-        htim->PWM_MspDeInitCallback             = HAL_TIM_PWM_MspDeInit;
-        break;
-
-      case HAL_TIM_ONE_PULSE_MSPINIT_CB_ID :
-        /* Legacy weak One Pulse Msp Init Callback */
-        htim->OnePulse_MspInitCallback          = HAL_TIM_OnePulse_MspInit;
-        break;
-
-      case HAL_TIM_ONE_PULSE_MSPDEINIT_CB_ID :
-        /* Legacy weak One Pulse Msp DeInit Callback */
-        htim->OnePulse_MspDeInitCallback        = HAL_TIM_OnePulse_MspDeInit;
-        break;
-
-      case HAL_TIM_ENCODER_MSPINIT_CB_ID :
-        /* Legacy weak Encoder Msp Init Callback */
-        htim->Encoder_MspInitCallback           = HAL_TIM_Encoder_MspInit;
-        break;
-
-      case HAL_TIM_ENCODER_MSPDEINIT_CB_ID :
-        /* Legacy weak Encoder Msp DeInit Callback */
-        htim->Encoder_MspDeInitCallback         = HAL_TIM_Encoder_MspDeInit;
-        break;
-
-      case HAL_TIM_HALL_SENSOR_MSPINIT_CB_ID :
-        /* Legacy weak Hall Sensor Msp Init Callback */
-        htim->HallSensor_MspInitCallback        = HAL_TIMEx_HallSensor_MspInit;
-        break;
-
-      case HAL_TIM_HALL_SENSOR_MSPDEINIT_CB_ID :
-        /* Legacy weak Hall Sensor Msp DeInit Callback */
-        htim->HallSensor_MspDeInitCallback      = HAL_TIMEx_HallSensor_MspDeInit;
-        break;
-
-      case HAL_TIM_PERIOD_ELAPSED_CB_ID :
-        /* Legacy weak Period Elapsed Callback */
-        htim->PeriodElapsedCallback             = HAL_TIM_PeriodElapsedCallback;
-        break;
-
-      case HAL_TIM_PERIOD_ELAPSED_HALF_CB_ID :
-        /* Legacy weak Period Elapsed half complete Callback */
-        htim->PeriodElapsedHalfCpltCallback     = HAL_TIM_PeriodElapsedHalfCpltCallback;
-        break;
-
-      case HAL_TIM_TRIGGER_CB_ID :
-        /* Legacy weak Trigger Callback */
-        htim->TriggerCallback                   = HAL_TIM_TriggerCallback;
-        break;
-
-      case HAL_TIM_TRIGGER_HALF_CB_ID :
-        /* Legacy weak Trigger half complete Callback */
-        htim->TriggerHalfCpltCallback           = HAL_TIM_TriggerHalfCpltCallback;
-        break;
-
-      case HAL_TIM_IC_CAPTURE_CB_ID :
-        /* Legacy weak IC Capture Callback */
-        htim->IC_CaptureCallback                = HAL_TIM_IC_CaptureCallback;
-        break;
-
-      case HAL_TIM_IC_CAPTURE_HALF_CB_ID :
-        /* Legacy weak IC Capture half complete Callback */
-        htim->IC_CaptureHalfCpltCallback        = HAL_TIM_IC_CaptureHalfCpltCallback;
-        break;
-
-      case HAL_TIM_OC_DELAY_ELAPSED_CB_ID :
-        /* Legacy weak OC Delay Elapsed Callback */
-        htim->OC_DelayElapsedCallback           = HAL_TIM_OC_DelayElapsedCallback;
-        break;
-
-      case HAL_TIM_PWM_PULSE_FINISHED_CB_ID :
-        /* Legacy weak PWM Pulse Finished Callback */
-        htim->PWM_PulseFinishedCallback         = HAL_TIM_PWM_PulseFinishedCallback;
-        break;
-
-      case HAL_TIM_PWM_PULSE_FINISHED_HALF_CB_ID :
-        /* Legacy weak PWM Pulse Finished half complete Callback */
-        htim->PWM_PulseFinishedHalfCpltCallback = HAL_TIM_PWM_PulseFinishedHalfCpltCallback;
-        break;
-
-      case HAL_TIM_ERROR_CB_ID :
-        /* Legacy weak Error Callback */
-        htim->ErrorCallback                     = HAL_TIM_ErrorCallback;
-        break;
-
-      case HAL_TIM_COMMUTATION_CB_ID :
-        /* Legacy weak Commutation Callback */
-        htim->CommutationCallback               = HAL_TIMEx_CommutCallback;
-        break;
-
-      case HAL_TIM_COMMUTATION_HALF_CB_ID :
-        /* Legacy weak Commutation half complete Callback */
-        htim->CommutationHalfCpltCallback       = HAL_TIMEx_CommutHalfCpltCallback;
-        break;
-
-      case HAL_TIM_BREAK_CB_ID :
-        /* Legacy weak Break Callback */
-        htim->BreakCallback                     = HAL_TIMEx_BreakCallback;
-        break;
-
-      case HAL_TIM_BREAK2_CB_ID :
-        /* Legacy weak Break2 Callback */
-        htim->Break2Callback                    = HAL_TIMEx_Break2Callback;
-        break;
-
-      default :
-        /* Return error status */
-        status = HAL_ERROR;
-        break;
-    }
-  }
-  else if (htim->State == HAL_TIM_STATE_RESET)
-  {
-    switch (CallbackID)
-    {
-      case HAL_TIM_BASE_MSPINIT_CB_ID :
-        /* Legacy weak Base MspInit Callback */
-        htim->Base_MspInitCallback         = HAL_TIM_Base_MspInit;
-        break;
-
-      case HAL_TIM_BASE_MSPDEINIT_CB_ID :
-        /* Legacy weak Base Msp DeInit Callback */
-        htim->Base_MspDeInitCallback       = HAL_TIM_Base_MspDeInit;
-        break;
-
-      case HAL_TIM_IC_MSPINIT_CB_ID :
-        /* Legacy weak IC Msp Init Callback */
-        htim->IC_MspInitCallback           = HAL_TIM_IC_MspInit;
-        break;
-
-      case HAL_TIM_IC_MSPDEINIT_CB_ID :
-        /* Legacy weak IC Msp DeInit Callback */
-        htim->IC_MspDeInitCallback         = HAL_TIM_IC_MspDeInit;
-        break;
-
-      case HAL_TIM_OC_MSPINIT_CB_ID :
-        /* Legacy weak OC Msp Init Callback */
-        htim->OC_MspInitCallback           = HAL_TIM_OC_MspInit;
-        break;
-
-      case HAL_TIM_OC_MSPDEINIT_CB_ID :
-        /* Legacy weak OC Msp DeInit Callback */
-        htim->OC_MspDeInitCallback         = HAL_TIM_OC_MspDeInit;
-        break;
-
-      case HAL_TIM_PWM_MSPINIT_CB_ID :
-        /* Legacy weak PWM Msp Init Callback */
-        htim->PWM_MspInitCallback          = HAL_TIM_PWM_MspInit;
-        break;
-
-      case HAL_TIM_PWM_MSPDEINIT_CB_ID :
-        /* Legacy weak PWM Msp DeInit Callback */
-        htim->PWM_MspDeInitCallback        = HAL_TIM_PWM_MspDeInit;
-        break;
-
-      case HAL_TIM_ONE_PULSE_MSPINIT_CB_ID :
-        /* Legacy weak One Pulse Msp Init Callback */
-        htim->OnePulse_MspInitCallback     = HAL_TIM_OnePulse_MspInit;
-        break;
-
-      case HAL_TIM_ONE_PULSE_MSPDEINIT_CB_ID :
-        /* Legacy weak One Pulse Msp DeInit Callback */
-        htim->OnePulse_MspDeInitCallback   = HAL_TIM_OnePulse_MspDeInit;
-        break;
-
-      case HAL_TIM_ENCODER_MSPINIT_CB_ID :
-        /* Legacy weak Encoder Msp Init Callback */
-        htim->Encoder_MspInitCallback      = HAL_TIM_Encoder_MspInit;
-        break;
-
-      case HAL_TIM_ENCODER_MSPDEINIT_CB_ID :
-        /* Legacy weak Encoder Msp DeInit Callback */
-        htim->Encoder_MspDeInitCallback    = HAL_TIM_Encoder_MspDeInit;
-        break;
-
-      case HAL_TIM_HALL_SENSOR_MSPINIT_CB_ID :
-        /* Legacy weak Hall Sensor Msp Init Callback */
-        htim->HallSensor_MspInitCallback   = HAL_TIMEx_HallSensor_MspInit;
-        break;
-
-      case HAL_TIM_HALL_SENSOR_MSPDEINIT_CB_ID :
-        /* Legacy weak Hall Sensor Msp DeInit Callback */
-        htim->HallSensor_MspDeInitCallback = HAL_TIMEx_HallSensor_MspDeInit;
-        break;
-
-      default :
-        /* Return error status */
-        status = HAL_ERROR;
-        break;
-    }
-  }
-  else
-  {
-    /* Return error status */
-    status = HAL_ERROR;
-  }
-
-  return status;
-}
-#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
-
-/**
-  * @}
-  */
-
-/** @defgroup TIM_Exported_Functions_Group10 TIM Peripheral State functions
-  *  @brief   TIM Peripheral State functions
-  *
-@verbatim
-  ==============================================================================
-                        ##### Peripheral State functions #####
-  ==============================================================================
-    [..]
-    This subsection permits to get in run-time the status of the peripheral
-    and the data flow.
-
-@endverbatim
-  * @{
-  */
-
-/**
-  * @brief  Return the TIM Base handle state.
-  * @param  htim TIM Base handle
-  * @retval HAL state
-  */
-HAL_TIM_StateTypeDef HAL_TIM_Base_GetState(const TIM_HandleTypeDef *htim)
-{
-  return htim->State;
-}
-
-/**
-  * @brief  Return the TIM OC handle state.
-  * @param  htim TIM Output Compare handle
-  * @retval HAL state
-  */
-HAL_TIM_StateTypeDef HAL_TIM_OC_GetState(const TIM_HandleTypeDef *htim)
-{
-  return htim->State;
-}
-
-/**
-  * @brief  Return the TIM PWM handle state.
-  * @param  htim TIM handle
-  * @retval HAL state
-  */
-HAL_TIM_StateTypeDef HAL_TIM_PWM_GetState(const TIM_HandleTypeDef *htim)
-{
-  return htim->State;
-}
-
-/**
-  * @brief  Return the TIM Input Capture handle state.
-  * @param  htim TIM IC handle
-  * @retval HAL state
-  */
-HAL_TIM_StateTypeDef HAL_TIM_IC_GetState(const TIM_HandleTypeDef *htim)
-{
-  return htim->State;
-}
-
-/**
-  * @brief  Return the TIM One Pulse Mode handle state.
-  * @param  htim TIM OPM handle
-  * @retval HAL state
-  */
-HAL_TIM_StateTypeDef HAL_TIM_OnePulse_GetState(const TIM_HandleTypeDef *htim)
-{
-  return htim->State;
-}
-
-/**
-  * @brief  Return the TIM Encoder Mode handle state.
-  * @param  htim TIM Encoder Interface handle
-  * @retval HAL state
-  */
-HAL_TIM_StateTypeDef HAL_TIM_Encoder_GetState(const TIM_HandleTypeDef *htim)
-{
-  return htim->State;
-}
-
-/**
-  * @brief  Return the TIM Encoder Mode handle state.
-  * @param  htim TIM handle
-  * @retval Active channel
-  */
-HAL_TIM_ActiveChannel HAL_TIM_GetActiveChannel(const TIM_HandleTypeDef *htim)
-{
-  return htim->Channel;
-}
-
-/**
-  * @brief  Return actual state of the TIM channel.
-  * @param  htim TIM handle
-  * @param  Channel TIM Channel
-  *          This parameter can be one of the following values:
-  *            @arg TIM_CHANNEL_1: TIM Channel 1
-  *            @arg TIM_CHANNEL_2: TIM Channel 2
-  *            @arg TIM_CHANNEL_3: TIM Channel 3
-  *            @arg TIM_CHANNEL_4: TIM Channel 4
-  *            @arg TIM_CHANNEL_5: TIM Channel 5
-  *            @arg TIM_CHANNEL_6: TIM Channel 6
-  * @retval TIM Channel state
-  */
-HAL_TIM_ChannelStateTypeDef HAL_TIM_GetChannelState(const TIM_HandleTypeDef *htim,  uint32_t Channel)
-{
-  HAL_TIM_ChannelStateTypeDef channel_state;
-
-  /* Check the parameters */
-  assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel));
-
-  channel_state = TIM_CHANNEL_STATE_GET(htim, Channel);
-
-  return channel_state;
-}
-
-/**
-  * @brief  Return actual state of a DMA burst operation.
-  * @param  htim TIM handle
-  * @retval DMA burst state
-  */
-HAL_TIM_DMABurstStateTypeDef HAL_TIM_DMABurstState(const TIM_HandleTypeDef *htim)
-{
-  /* Check the parameters */
-  assert_param(IS_TIM_DMABURST_INSTANCE(htim->Instance));
-
-  return htim->DMABurstState;
-}
-
-/**
-  * @}
-  */
-
-/**
-  * @}
-  */
-
-/** @defgroup TIM_Private_Functions TIM Private Functions
-  * @{
-  */
-
-/**
-  * @brief  TIM DMA error callback
-  * @param  hdma pointer to DMA handle.
-  * @retval None
-  */
-void TIM_DMAError(DMA_HandleTypeDef *hdma)
-{
-  TIM_HandleTypeDef *htim = (TIM_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
-
-  if (hdma == htim->hdma[TIM_DMA_ID_CC1])
-  {
-    htim->Channel = HAL_TIM_ACTIVE_CHANNEL_1;
-    TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY);
-  }
-  else if (hdma == htim->hdma[TIM_DMA_ID_CC2])
-  {
-    htim->Channel = HAL_TIM_ACTIVE_CHANNEL_2;
-    TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY);
-  }
-  else if (hdma == htim->hdma[TIM_DMA_ID_CC3])
-  {
-    htim->Channel = HAL_TIM_ACTIVE_CHANNEL_3;
-    TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_3, HAL_TIM_CHANNEL_STATE_READY);
-  }
-  else if (hdma == htim->hdma[TIM_DMA_ID_CC4])
-  {
-    htim->Channel = HAL_TIM_ACTIVE_CHANNEL_4;
-    TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_4, HAL_TIM_CHANNEL_STATE_READY);
-  }
-  else
-  {
-    htim->State = HAL_TIM_STATE_READY;
-  }
-
-#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
-  htim->ErrorCallback(htim);
-#else
-  HAL_TIM_ErrorCallback(htim);
-#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
-
-  htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;
-}
-
-/**
-  * @brief  TIM DMA Delay Pulse complete callback.
-  * @param  hdma pointer to DMA handle.
-  * @retval None
-  */
-static void TIM_DMADelayPulseCplt(DMA_HandleTypeDef *hdma)
-{
-  TIM_HandleTypeDef *htim = (TIM_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
-
-  if (hdma == htim->hdma[TIM_DMA_ID_CC1])
-  {
-    htim->Channel = HAL_TIM_ACTIVE_CHANNEL_1;
-
-    if (hdma->Init.Mode == DMA_NORMAL)
-    {
-      TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY);
-    }
-  }
-  else if (hdma == htim->hdma[TIM_DMA_ID_CC2])
-  {
-    htim->Channel = HAL_TIM_ACTIVE_CHANNEL_2;
-
-    if (hdma->Init.Mode == DMA_NORMAL)
-    {
-      TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY);
-    }
-  }
-  else if (hdma == htim->hdma[TIM_DMA_ID_CC3])
-  {
-    htim->Channel = HAL_TIM_ACTIVE_CHANNEL_3;
-
-    if (hdma->Init.Mode == DMA_NORMAL)
-    {
-      TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_3, HAL_TIM_CHANNEL_STATE_READY);
-    }
-  }
-  else if (hdma == htim->hdma[TIM_DMA_ID_CC4])
-  {
-    htim->Channel = HAL_TIM_ACTIVE_CHANNEL_4;
-
-    if (hdma->Init.Mode == DMA_NORMAL)
-    {
-      TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_4, HAL_TIM_CHANNEL_STATE_READY);
-    }
-  }
-  else
-  {
-    /* nothing to do */
-  }
-
-#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
-  htim->PWM_PulseFinishedCallback(htim);
-#else
-  HAL_TIM_PWM_PulseFinishedCallback(htim);
-#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
-
-  htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;
-}
-
-/**
-  * @brief  TIM DMA Delay Pulse half complete callback.
-  * @param  hdma pointer to DMA handle.
-  * @retval None
-  */
-void TIM_DMADelayPulseHalfCplt(DMA_HandleTypeDef *hdma)
-{
-  TIM_HandleTypeDef *htim = (TIM_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
-
-  if (hdma == htim->hdma[TIM_DMA_ID_CC1])
-  {
-    htim->Channel = HAL_TIM_ACTIVE_CHANNEL_1;
-  }
-  else if (hdma == htim->hdma[TIM_DMA_ID_CC2])
-  {
-    htim->Channel = HAL_TIM_ACTIVE_CHANNEL_2;
-  }
-  else if (hdma == htim->hdma[TIM_DMA_ID_CC3])
-  {
-    htim->Channel = HAL_TIM_ACTIVE_CHANNEL_3;
-  }
-  else if (hdma == htim->hdma[TIM_DMA_ID_CC4])
-  {
-    htim->Channel = HAL_TIM_ACTIVE_CHANNEL_4;
-  }
-  else
-  {
-    /* nothing to do */
-  }
-
-#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
-  htim->PWM_PulseFinishedHalfCpltCallback(htim);
-#else
-  HAL_TIM_PWM_PulseFinishedHalfCpltCallback(htim);
-#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
-
-  htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;
-}
-
-/**
-  * @brief  TIM DMA Capture complete callback.
-  * @param  hdma pointer to DMA handle.
-  * @retval None
-  */
-void TIM_DMACaptureCplt(DMA_HandleTypeDef *hdma)
-{
-  TIM_HandleTypeDef *htim = (TIM_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
-
-  if (hdma == htim->hdma[TIM_DMA_ID_CC1])
-  {
-    htim->Channel = HAL_TIM_ACTIVE_CHANNEL_1;
-
-    if (hdma->Init.Mode == DMA_NORMAL)
-    {
-      TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY);
-      TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY);
-    }
-  }
-  else if (hdma == htim->hdma[TIM_DMA_ID_CC2])
-  {
-    htim->Channel = HAL_TIM_ACTIVE_CHANNEL_2;
-
-    if (hdma->Init.Mode == DMA_NORMAL)
-    {
-      TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY);
-      TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY);
-    }
-  }
-  else if (hdma == htim->hdma[TIM_DMA_ID_CC3])
-  {
-    htim->Channel = HAL_TIM_ACTIVE_CHANNEL_3;
-
-    if (hdma->Init.Mode == DMA_NORMAL)
-    {
-      TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_3, HAL_TIM_CHANNEL_STATE_READY);
-      TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_3, HAL_TIM_CHANNEL_STATE_READY);
-    }
-  }
-  else if (hdma == htim->hdma[TIM_DMA_ID_CC4])
-  {
-    htim->Channel = HAL_TIM_ACTIVE_CHANNEL_4;
-
-    if (hdma->Init.Mode == DMA_NORMAL)
-    {
-      TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_4, HAL_TIM_CHANNEL_STATE_READY);
-      TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_4, HAL_TIM_CHANNEL_STATE_READY);
-    }
-  }
-  else
-  {
-    /* nothing to do */
-  }
-
-#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
-  htim->IC_CaptureCallback(htim);
-#else
-  HAL_TIM_IC_CaptureCallback(htim);
-#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
-
-  htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;
-}
-
-/**
-  * @brief  TIM DMA Capture half complete callback.
-  * @param  hdma pointer to DMA handle.
-  * @retval None
-  */
-void TIM_DMACaptureHalfCplt(DMA_HandleTypeDef *hdma)
-{
-  TIM_HandleTypeDef *htim = (TIM_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
-
-  if (hdma == htim->hdma[TIM_DMA_ID_CC1])
-  {
-    htim->Channel = HAL_TIM_ACTIVE_CHANNEL_1;
-  }
-  else if (hdma == htim->hdma[TIM_DMA_ID_CC2])
-  {
-    htim->Channel = HAL_TIM_ACTIVE_CHANNEL_2;
-  }
-  else if (hdma == htim->hdma[TIM_DMA_ID_CC3])
-  {
-    htim->Channel = HAL_TIM_ACTIVE_CHANNEL_3;
-  }
-  else if (hdma == htim->hdma[TIM_DMA_ID_CC4])
-  {
-    htim->Channel = HAL_TIM_ACTIVE_CHANNEL_4;
-  }
-  else
-  {
-    /* nothing to do */
-  }
-
-#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
-  htim->IC_CaptureHalfCpltCallback(htim);
-#else
-  HAL_TIM_IC_CaptureHalfCpltCallback(htim);
-#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
-
-  htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;
-}
-
-/**
-  * @brief  TIM DMA Period Elapse complete callback.
-  * @param  hdma pointer to DMA handle.
-  * @retval None
-  */
-static void TIM_DMAPeriodElapsedCplt(DMA_HandleTypeDef *hdma)
-{
-  TIM_HandleTypeDef *htim = (TIM_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
-
-  if (htim->hdma[TIM_DMA_ID_UPDATE]->Init.Mode == DMA_NORMAL)
-  {
-    htim->State = HAL_TIM_STATE_READY;
-  }
-
-#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
-  htim->PeriodElapsedCallback(htim);
-#else
-  HAL_TIM_PeriodElapsedCallback(htim);
-#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
-}
-
-/**
-  * @brief  TIM DMA Period Elapse half complete callback.
-  * @param  hdma pointer to DMA handle.
-  * @retval None
-  */
-static void TIM_DMAPeriodElapsedHalfCplt(DMA_HandleTypeDef *hdma)
-{
-  TIM_HandleTypeDef *htim = (TIM_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
-
-#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
-  htim->PeriodElapsedHalfCpltCallback(htim);
-#else
-  HAL_TIM_PeriodElapsedHalfCpltCallback(htim);
-#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
-}
-
-/**
-  * @brief  TIM DMA Trigger callback.
-  * @param  hdma pointer to DMA handle.
-  * @retval None
-  */
-static void TIM_DMATriggerCplt(DMA_HandleTypeDef *hdma)
-{
-  TIM_HandleTypeDef *htim = (TIM_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
-
-  if (htim->hdma[TIM_DMA_ID_TRIGGER]->Init.Mode == DMA_NORMAL)
-  {
-    htim->State = HAL_TIM_STATE_READY;
-  }
-
-#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
-  htim->TriggerCallback(htim);
-#else
-  HAL_TIM_TriggerCallback(htim);
-#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
-}
-
-/**
-  * @brief  TIM DMA Trigger half complete callback.
-  * @param  hdma pointer to DMA handle.
-  * @retval None
-  */
-static void TIM_DMATriggerHalfCplt(DMA_HandleTypeDef *hdma)
-{
-  TIM_HandleTypeDef *htim = (TIM_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
-
-#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
-  htim->TriggerHalfCpltCallback(htim);
-#else
-  HAL_TIM_TriggerHalfCpltCallback(htim);
-#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
-}
-
-/**
-  * @brief  Time Base configuration
-  * @param  TIMx TIM peripheral
-  * @param  Structure TIM Base configuration structure
-  * @retval None
-  */
-void TIM_Base_SetConfig(TIM_TypeDef *TIMx, const TIM_Base_InitTypeDef *Structure)
-{
-  uint32_t tmpcr1;
-  tmpcr1 = TIMx->CR1;
-
-  /* Set TIM Time Base Unit parameters ---------------------------------------*/
-  if (IS_TIM_COUNTER_MODE_SELECT_INSTANCE(TIMx))
-  {
-    /* Select the Counter Mode */
-    tmpcr1 &= ~(TIM_CR1_DIR | TIM_CR1_CMS);
-    tmpcr1 |= Structure->CounterMode;
-  }
-
-  if (IS_TIM_CLOCK_DIVISION_INSTANCE(TIMx))
-  {
-    /* Set the clock division */
-    tmpcr1 &= ~TIM_CR1_CKD;
-    tmpcr1 |= (uint32_t)Structure->ClockDivision;
-  }
-
-  /* Set the auto-reload preload */
-  MODIFY_REG(tmpcr1, TIM_CR1_ARPE, Structure->AutoReloadPreload);
-
-  TIMx->CR1 = tmpcr1;
-
-  /* Set the Autoreload value */
-  TIMx->ARR = (uint32_t)Structure->Period ;
-
-  /* Set the Prescaler value */
-  TIMx->PSC = Structure->Prescaler;
-
-  if (IS_TIM_REPETITION_COUNTER_INSTANCE(TIMx))
-  {
-    /* Set the Repetition Counter value */
-    TIMx->RCR = Structure->RepetitionCounter;
-  }
-
-  /* Generate an update event to reload the Prescaler
-     and the repetition counter (only for advanced timer) value immediately */
-  TIMx->EGR = TIM_EGR_UG;
-}
-
-/**
-  * @brief  Timer Output Compare 1 configuration
-  * @param  TIMx to select the TIM peripheral
-  * @param  OC_Config The output configuration structure
-  * @retval None
-  */
-static void TIM_OC1_SetConfig(TIM_TypeDef *TIMx, const TIM_OC_InitTypeDef *OC_Config)
-{
-  uint32_t tmpccmrx;
-  uint32_t tmpccer;
-  uint32_t tmpcr2;
-
-  /* Disable the Channel 1: Reset the CC1E Bit */
-  TIMx->CCER &= ~TIM_CCER_CC1E;
-
-  /* Get the TIMx CCER register value */
-  tmpccer = TIMx->CCER;
-  /* Get the TIMx CR2 register value */
-  tmpcr2 =  TIMx->CR2;
-
-  /* Get the TIMx CCMR1 register value */
-  tmpccmrx = TIMx->CCMR1;
-
-  /* Reset the Output Compare Mode Bits */
-  tmpccmrx &= ~TIM_CCMR1_OC1M;
-  tmpccmrx &= ~TIM_CCMR1_CC1S;
-  /* Select the Output Compare Mode */
-  tmpccmrx |= OC_Config->OCMode;
-
-  /* Reset the Output Polarity level */
-  tmpccer &= ~TIM_CCER_CC1P;
-  /* Set the Output Compare Polarity */
-  tmpccer |= OC_Config->OCPolarity;
-
-  if (IS_TIM_CCXN_INSTANCE(TIMx, TIM_CHANNEL_1))
-  {
-    /* Check parameters */
-    assert_param(IS_TIM_OCN_POLARITY(OC_Config->OCNPolarity));
-
-    /* Reset the Output N Polarity level */
-    tmpccer &= ~TIM_CCER_CC1NP;
-    /* Set the Output N Polarity */
-    tmpccer |= OC_Config->OCNPolarity;
-    /* Reset the Output N State */
-    tmpccer &= ~TIM_CCER_CC1NE;
-  }
-
-  if (IS_TIM_BREAK_INSTANCE(TIMx))
-  {
-    /* Check parameters */
-    assert_param(IS_TIM_OCNIDLE_STATE(OC_Config->OCNIdleState));
-    assert_param(IS_TIM_OCIDLE_STATE(OC_Config->OCIdleState));
-
-    /* Reset the Output Compare and Output Compare N IDLE State */
-    tmpcr2 &= ~TIM_CR2_OIS1;
-    tmpcr2 &= ~TIM_CR2_OIS1N;
-    /* Set the Output Idle state */
-    tmpcr2 |= OC_Config->OCIdleState;
-    /* Set the Output N Idle state */
-    tmpcr2 |= OC_Config->OCNIdleState;
-  }
-
-  /* Write to TIMx CR2 */
-  TIMx->CR2 = tmpcr2;
-
-  /* Write to TIMx CCMR1 */
-  TIMx->CCMR1 = tmpccmrx;
-
-  /* Set the Capture Compare Register value */
-  TIMx->CCR1 = OC_Config->Pulse;
-
-  /* Write to TIMx CCER */
-  TIMx->CCER = tmpccer;
-}
-
-/**
-  * @brief  Timer Output Compare 2 configuration
-  * @param  TIMx to select the TIM peripheral
-  * @param  OC_Config The output configuration structure
-  * @retval None
-  */
-void TIM_OC2_SetConfig(TIM_TypeDef *TIMx, const TIM_OC_InitTypeDef *OC_Config)
-{
-  uint32_t tmpccmrx;
-  uint32_t tmpccer;
-  uint32_t tmpcr2;
-
-  /* Disable the Channel 2: Reset the CC2E Bit */
-  TIMx->CCER &= ~TIM_CCER_CC2E;
-
-  /* Get the TIMx CCER register value */
-  tmpccer = TIMx->CCER;
-  /* Get the TIMx CR2 register value */
-  tmpcr2 =  TIMx->CR2;
-
-  /* Get the TIMx CCMR1 register value */
-  tmpccmrx = TIMx->CCMR1;
-
-  /* Reset the Output Compare mode and Capture/Compare selection Bits */
-  tmpccmrx &= ~TIM_CCMR1_OC2M;
-  tmpccmrx &= ~TIM_CCMR1_CC2S;
-
-  /* Select the Output Compare Mode */
-  tmpccmrx |= (OC_Config->OCMode << 8U);
-
-  /* Reset the Output Polarity level */
-  tmpccer &= ~TIM_CCER_CC2P;
-  /* Set the Output Compare Polarity */
-  tmpccer |= (OC_Config->OCPolarity << 4U);
-
-  if (IS_TIM_CCXN_INSTANCE(TIMx, TIM_CHANNEL_2))
-  {
-    assert_param(IS_TIM_OCN_POLARITY(OC_Config->OCNPolarity));
-
-    /* Reset the Output N Polarity level */
-    tmpccer &= ~TIM_CCER_CC2NP;
-    /* Set the Output N Polarity */
-    tmpccer |= (OC_Config->OCNPolarity << 4U);
-    /* Reset the Output N State */
-    tmpccer &= ~TIM_CCER_CC2NE;
-
-  }
-
-  if (IS_TIM_BREAK_INSTANCE(TIMx))
-  {
-    /* Check parameters */
-    assert_param(IS_TIM_OCNIDLE_STATE(OC_Config->OCNIdleState));
-    assert_param(IS_TIM_OCIDLE_STATE(OC_Config->OCIdleState));
-
-    /* Reset the Output Compare and Output Compare N IDLE State */
-    tmpcr2 &= ~TIM_CR2_OIS2;
-    tmpcr2 &= ~TIM_CR2_OIS2N;
-    /* Set the Output Idle state */
-    tmpcr2 |= (OC_Config->OCIdleState << 2U);
-    /* Set the Output N Idle state */
-    tmpcr2 |= (OC_Config->OCNIdleState << 2U);
-  }
-
-  /* Write to TIMx CR2 */
-  TIMx->CR2 = tmpcr2;
-
-  /* Write to TIMx CCMR1 */
-  TIMx->CCMR1 = tmpccmrx;
-
-  /* Set the Capture Compare Register value */
-  TIMx->CCR2 = OC_Config->Pulse;
-
-  /* Write to TIMx CCER */
-  TIMx->CCER = tmpccer;
-}
-
-/**
-  * @brief  Timer Output Compare 3 configuration
-  * @param  TIMx to select the TIM peripheral
-  * @param  OC_Config The output configuration structure
-  * @retval None
-  */
-static void TIM_OC3_SetConfig(TIM_TypeDef *TIMx, const TIM_OC_InitTypeDef *OC_Config)
-{
-  uint32_t tmpccmrx;
-  uint32_t tmpccer;
-  uint32_t tmpcr2;
-
-  /* Disable the Channel 3: Reset the CC2E Bit */
-  TIMx->CCER &= ~TIM_CCER_CC3E;
-
-  /* Get the TIMx CCER register value */
-  tmpccer = TIMx->CCER;
-  /* Get the TIMx CR2 register value */
-  tmpcr2 =  TIMx->CR2;
-
-  /* Get the TIMx CCMR2 register value */
-  tmpccmrx = TIMx->CCMR2;
-
-  /* Reset the Output Compare mode and Capture/Compare selection Bits */
-  tmpccmrx &= ~TIM_CCMR2_OC3M;
-  tmpccmrx &= ~TIM_CCMR2_CC3S;
-  /* Select the Output Compare Mode */
-  tmpccmrx |= OC_Config->OCMode;
-
-  /* Reset the Output Polarity level */
-  tmpccer &= ~TIM_CCER_CC3P;
-  /* Set the Output Compare Polarity */
-  tmpccer |= (OC_Config->OCPolarity << 8U);
-
-  if (IS_TIM_CCXN_INSTANCE(TIMx, TIM_CHANNEL_3))
-  {
-    assert_param(IS_TIM_OCN_POLARITY(OC_Config->OCNPolarity));
-
-    /* Reset the Output N Polarity level */
-    tmpccer &= ~TIM_CCER_CC3NP;
-    /* Set the Output N Polarity */
-    tmpccer |= (OC_Config->OCNPolarity << 8U);
-    /* Reset the Output N State */
-    tmpccer &= ~TIM_CCER_CC3NE;
-  }
-
-  if (IS_TIM_BREAK_INSTANCE(TIMx))
-  {
-    /* Check parameters */
-    assert_param(IS_TIM_OCNIDLE_STATE(OC_Config->OCNIdleState));
-    assert_param(IS_TIM_OCIDLE_STATE(OC_Config->OCIdleState));
-
-    /* Reset the Output Compare and Output Compare N IDLE State */
-    tmpcr2 &= ~TIM_CR2_OIS3;
-    tmpcr2 &= ~TIM_CR2_OIS3N;
-    /* Set the Output Idle state */
-    tmpcr2 |= (OC_Config->OCIdleState << 4U);
-    /* Set the Output N Idle state */
-    tmpcr2 |= (OC_Config->OCNIdleState << 4U);
-  }
-
-  /* Write to TIMx CR2 */
-  TIMx->CR2 = tmpcr2;
-
-  /* Write to TIMx CCMR2 */
-  TIMx->CCMR2 = tmpccmrx;
-
-  /* Set the Capture Compare Register value */
-  TIMx->CCR3 = OC_Config->Pulse;
-
-  /* Write to TIMx CCER */
-  TIMx->CCER = tmpccer;
-}
-
-/**
-  * @brief  Timer Output Compare 4 configuration
-  * @param  TIMx to select the TIM peripheral
-  * @param  OC_Config The output configuration structure
-  * @retval None
-  */
-static void TIM_OC4_SetConfig(TIM_TypeDef *TIMx, const TIM_OC_InitTypeDef *OC_Config)
-{
-  uint32_t tmpccmrx;
-  uint32_t tmpccer;
-  uint32_t tmpcr2;
-
-  /* Disable the Channel 4: Reset the CC4E Bit */
-  TIMx->CCER &= ~TIM_CCER_CC4E;
-
-  /* Get the TIMx CCER register value */
-  tmpccer = TIMx->CCER;
-  /* Get the TIMx CR2 register value */
-  tmpcr2 =  TIMx->CR2;
-
-  /* Get the TIMx CCMR2 register value */
-  tmpccmrx = TIMx->CCMR2;
-
-  /* Reset the Output Compare mode and Capture/Compare selection Bits */
-  tmpccmrx &= ~TIM_CCMR2_OC4M;
-  tmpccmrx &= ~TIM_CCMR2_CC4S;
-
-  /* Select the Output Compare Mode */
-  tmpccmrx |= (OC_Config->OCMode << 8U);
-
-  /* Reset the Output Polarity level */
-  tmpccer &= ~TIM_CCER_CC4P;
-  /* Set the Output Compare Polarity */
-  tmpccer |= (OC_Config->OCPolarity << 12U);
-
-  if (IS_TIM_BREAK_INSTANCE(TIMx))
-  {
-    /* Check parameters */
-    assert_param(IS_TIM_OCIDLE_STATE(OC_Config->OCIdleState));
-
-    /* Reset the Output Compare IDLE State */
-    tmpcr2 &= ~TIM_CR2_OIS4;
-
-    /* Set the Output Idle state */
-    tmpcr2 |= (OC_Config->OCIdleState << 6U);
-  }
-
-  /* Write to TIMx CR2 */
-  TIMx->CR2 = tmpcr2;
-
-  /* Write to TIMx CCMR2 */
-  TIMx->CCMR2 = tmpccmrx;
-
-  /* Set the Capture Compare Register value */
-  TIMx->CCR4 = OC_Config->Pulse;
-
-  /* Write to TIMx CCER */
-  TIMx->CCER = tmpccer;
-}
-
-/**
-  * @brief  Timer Output Compare 5 configuration
-  * @param  TIMx to select the TIM peripheral
-  * @param  OC_Config The output configuration structure
-  * @retval None
-  */
-static void TIM_OC5_SetConfig(TIM_TypeDef *TIMx,
-                              const TIM_OC_InitTypeDef *OC_Config)
-{
-  uint32_t tmpccmrx;
-  uint32_t tmpccer;
-  uint32_t tmpcr2;
-
-  /* Disable the output: Reset the CCxE Bit */
-  TIMx->CCER &= ~TIM_CCER_CC5E;
-
-  /* Get the TIMx CCER register value */
-  tmpccer = TIMx->CCER;
-  /* Get the TIMx CR2 register value */
-  tmpcr2 =  TIMx->CR2;
-  /* Get the TIMx CCMR1 register value */
-  tmpccmrx = TIMx->CCMR3;
-
-  /* Reset the Output Compare Mode Bits */
-  tmpccmrx &= ~(TIM_CCMR3_OC5M);
-  /* Select the Output Compare Mode */
-  tmpccmrx |= OC_Config->OCMode;
-
-  /* Reset the Output Polarity level */
-  tmpccer &= ~TIM_CCER_CC5P;
-  /* Set the Output Compare Polarity */
-  tmpccer |= (OC_Config->OCPolarity << 16U);
-
-  if (IS_TIM_BREAK_INSTANCE(TIMx))
-  {
-    /* Reset the Output Compare IDLE State */
-    tmpcr2 &= ~TIM_CR2_OIS5;
-    /* Set the Output Idle state */
-    tmpcr2 |= (OC_Config->OCIdleState << 8U);
-  }
-  /* Write to TIMx CR2 */
-  TIMx->CR2 = tmpcr2;
-
-  /* Write to TIMx CCMR3 */
-  TIMx->CCMR3 = tmpccmrx;
-
-  /* Set the Capture Compare Register value */
-  TIMx->CCR5 = OC_Config->Pulse;
-
-  /* Write to TIMx CCER */
-  TIMx->CCER = tmpccer;
-}
-
-/**
-  * @brief  Timer Output Compare 6 configuration
-  * @param  TIMx to select the TIM peripheral
-  * @param  OC_Config The output configuration structure
-  * @retval None
-  */
-static void TIM_OC6_SetConfig(TIM_TypeDef *TIMx,
-                              const TIM_OC_InitTypeDef *OC_Config)
-{
-  uint32_t tmpccmrx;
-  uint32_t tmpccer;
-  uint32_t tmpcr2;
-
-  /* Disable the output: Reset the CCxE Bit */
-  TIMx->CCER &= ~TIM_CCER_CC6E;
-
-  /* Get the TIMx CCER register value */
-  tmpccer = TIMx->CCER;
-  /* Get the TIMx CR2 register value */
-  tmpcr2 =  TIMx->CR2;
-  /* Get the TIMx CCMR1 register value */
-  tmpccmrx = TIMx->CCMR3;
-
-  /* Reset the Output Compare Mode Bits */
-  tmpccmrx &= ~(TIM_CCMR3_OC6M);
-  /* Select the Output Compare Mode */
-  tmpccmrx |= (OC_Config->OCMode << 8U);
-
-  /* Reset the Output Polarity level */
-  tmpccer &= (uint32_t)~TIM_CCER_CC6P;
-  /* Set the Output Compare Polarity */
-  tmpccer |= (OC_Config->OCPolarity << 20U);
-
-  if (IS_TIM_BREAK_INSTANCE(TIMx))
-  {
-    /* Reset the Output Compare IDLE State */
-    tmpcr2 &= ~TIM_CR2_OIS6;
-    /* Set the Output Idle state */
-    tmpcr2 |= (OC_Config->OCIdleState << 10U);
-  }
-
-  /* Write to TIMx CR2 */
-  TIMx->CR2 = tmpcr2;
-
-  /* Write to TIMx CCMR3 */
-  TIMx->CCMR3 = tmpccmrx;
-
-  /* Set the Capture Compare Register value */
-  TIMx->CCR6 = OC_Config->Pulse;
-
-  /* Write to TIMx CCER */
-  TIMx->CCER = tmpccer;
-}
-
-/**
-  * @brief  Slave Timer configuration function
-  * @param  htim TIM handle
-  * @param  sSlaveConfig Slave timer configuration
-  * @retval None
-  */
-static HAL_StatusTypeDef TIM_SlaveTimer_SetConfig(TIM_HandleTypeDef *htim,
-                                                  const TIM_SlaveConfigTypeDef *sSlaveConfig)
-{
-  HAL_StatusTypeDef status = HAL_OK;
-  uint32_t tmpsmcr;
-  uint32_t tmpccmr1;
-  uint32_t tmpccer;
-
-  /* Get the TIMx SMCR register value */
-  tmpsmcr = htim->Instance->SMCR;
-
-  /* Reset the Trigger Selection Bits */
-  tmpsmcr &= ~TIM_SMCR_TS;
-  /* Set the Input Trigger source */
-  tmpsmcr |= sSlaveConfig->InputTrigger;
-
-  /* Reset the slave mode Bits */
-  tmpsmcr &= ~TIM_SMCR_SMS;
-  /* Set the slave mode */
-  tmpsmcr |= sSlaveConfig->SlaveMode;
-
-  /* Write to TIMx SMCR */
-  htim->Instance->SMCR = tmpsmcr;
-
-  /* Configure the trigger prescaler, filter, and polarity */
-  switch (sSlaveConfig->InputTrigger)
-  {
-    case TIM_TS_ETRF:
-    {
-      /* Check the parameters */
-      assert_param(IS_TIM_CLOCKSOURCE_ETRMODE1_INSTANCE(htim->Instance));
-      assert_param(IS_TIM_TRIGGERPRESCALER(sSlaveConfig->TriggerPrescaler));
-      assert_param(IS_TIM_TRIGGERPOLARITY(sSlaveConfig->TriggerPolarity));
-      assert_param(IS_TIM_TRIGGERFILTER(sSlaveConfig->TriggerFilter));
-      /* Configure the ETR Trigger source */
-      TIM_ETR_SetConfig(htim->Instance,
-                        sSlaveConfig->TriggerPrescaler,
-                        sSlaveConfig->TriggerPolarity,
-                        sSlaveConfig->TriggerFilter);
-      break;
-    }
-
-    case TIM_TS_TI1F_ED:
-    {
-      /* Check the parameters */
-      assert_param(IS_TIM_CC1_INSTANCE(htim->Instance));
-      assert_param(IS_TIM_TRIGGERFILTER(sSlaveConfig->TriggerFilter));
-
-      if (sSlaveConfig->SlaveMode == TIM_SLAVEMODE_GATED)
-      {
-        return HAL_ERROR;
-      }
-
-      /* Disable the Channel 1: Reset the CC1E Bit */
-      tmpccer = htim->Instance->CCER;
-      htim->Instance->CCER &= ~TIM_CCER_CC1E;
-      tmpccmr1 = htim->Instance->CCMR1;
-
-      /* Set the filter */
-      tmpccmr1 &= ~TIM_CCMR1_IC1F;
-      tmpccmr1 |= ((sSlaveConfig->TriggerFilter) << 4U);
-
-      /* Write to TIMx CCMR1 and CCER registers */
-      htim->Instance->CCMR1 = tmpccmr1;
-      htim->Instance->CCER = tmpccer;
-      break;
-    }
-
-    case TIM_TS_TI1FP1:
-    {
-      /* Check the parameters */
-      assert_param(IS_TIM_CC1_INSTANCE(htim->Instance));
-      assert_param(IS_TIM_TRIGGERPOLARITY(sSlaveConfig->TriggerPolarity));
-      assert_param(IS_TIM_TRIGGERFILTER(sSlaveConfig->TriggerFilter));
-
-      /* Configure TI1 Filter and Polarity */
-      TIM_TI1_ConfigInputStage(htim->Instance,
-                               sSlaveConfig->TriggerPolarity,
-                               sSlaveConfig->TriggerFilter);
-      break;
-    }
-
-    case TIM_TS_TI2FP2:
-    {
-      /* Check the parameters */
-      assert_param(IS_TIM_CC2_INSTANCE(htim->Instance));
-      assert_param(IS_TIM_TRIGGERPOLARITY(sSlaveConfig->TriggerPolarity));
-      assert_param(IS_TIM_TRIGGERFILTER(sSlaveConfig->TriggerFilter));
-
-      /* Configure TI2 Filter and Polarity */
-      TIM_TI2_ConfigInputStage(htim->Instance,
-                               sSlaveConfig->TriggerPolarity,
-                               sSlaveConfig->TriggerFilter);
-      break;
-    }
-
-    case TIM_TS_ITR0:
-    case TIM_TS_ITR1:
-    case TIM_TS_ITR2:
-    case TIM_TS_ITR3:
-    {
-      /* Check the parameter */
-      assert_param(IS_TIM_CC2_INSTANCE(htim->Instance));
-      break;
-    }
-
-    default:
-      status = HAL_ERROR;
-      break;
-  }
-
-  return status;
-}
-
-/**
-  * @brief  Configure the TI1 as Input.
-  * @param  TIMx to select the TIM peripheral.
-  * @param  TIM_ICPolarity The Input Polarity.
-  *          This parameter can be one of the following values:
-  *            @arg TIM_ICPOLARITY_RISING
-  *            @arg TIM_ICPOLARITY_FALLING
-  *            @arg TIM_ICPOLARITY_BOTHEDGE
-  * @param  TIM_ICSelection specifies the input to be used.
-  *          This parameter can be one of the following values:
-  *            @arg TIM_ICSELECTION_DIRECTTI: TIM Input 1 is selected to be connected to IC1.
-  *            @arg TIM_ICSELECTION_INDIRECTTI: TIM Input 1 is selected to be connected to IC2.
-  *            @arg TIM_ICSELECTION_TRC: TIM Input 1 is selected to be connected to TRC.
-  * @param  TIM_ICFilter Specifies the Input Capture Filter.
-  *          This parameter must be a value between 0x00 and 0x0F.
-  * @retval None
-  * @note TIM_ICFilter and TIM_ICPolarity are not used in INDIRECT mode as TI2FP1
-  *       (on channel2 path) is used as the input signal. Therefore CCMR1 must be
-  *        protected against un-initialized filter and polarity values.
-  */
-void TIM_TI1_SetConfig(TIM_TypeDef *TIMx, uint32_t TIM_ICPolarity, uint32_t TIM_ICSelection,
-                       uint32_t TIM_ICFilter)
-{
-  uint32_t tmpccmr1;
-  uint32_t tmpccer;
-
-  /* Disable the Channel 1: Reset the CC1E Bit */
-  TIMx->CCER &= ~TIM_CCER_CC1E;
-  tmpccmr1 = TIMx->CCMR1;
-  tmpccer = TIMx->CCER;
-
-  /* Select the Input */
-  if (IS_TIM_CC2_INSTANCE(TIMx) != RESET)
-  {
-    tmpccmr1 &= ~TIM_CCMR1_CC1S;
-    tmpccmr1 |= TIM_ICSelection;
-  }
-  else
-  {
-    tmpccmr1 |= TIM_CCMR1_CC1S_0;
-  }
-
-  /* Set the filter */
-  tmpccmr1 &= ~TIM_CCMR1_IC1F;
-  tmpccmr1 |= ((TIM_ICFilter << 4U) & TIM_CCMR1_IC1F);
-
-  /* Select the Polarity and set the CC1E Bit */
-  tmpccer &= ~(TIM_CCER_CC1P | TIM_CCER_CC1NP);
-  tmpccer |= (TIM_ICPolarity & (TIM_CCER_CC1P | TIM_CCER_CC1NP));
-
-  /* Write to TIMx CCMR1 and CCER registers */
-  TIMx->CCMR1 = tmpccmr1;
-  TIMx->CCER = tmpccer;
-}
-
-/**
-  * @brief  Configure the Polarity and Filter for TI1.
-  * @param  TIMx to select the TIM peripheral.
-  * @param  TIM_ICPolarity The Input Polarity.
-  *          This parameter can be one of the following values:
-  *            @arg TIM_ICPOLARITY_RISING
-  *            @arg TIM_ICPOLARITY_FALLING
-  *            @arg TIM_ICPOLARITY_BOTHEDGE
-  * @param  TIM_ICFilter Specifies the Input Capture Filter.
-  *          This parameter must be a value between 0x00 and 0x0F.
-  * @retval None
-  */
-static void TIM_TI1_ConfigInputStage(TIM_TypeDef *TIMx, uint32_t TIM_ICPolarity, uint32_t TIM_ICFilter)
-{
-  uint32_t tmpccmr1;
-  uint32_t tmpccer;
-
-  /* Disable the Channel 1: Reset the CC1E Bit */
-  tmpccer = TIMx->CCER;
-  TIMx->CCER &= ~TIM_CCER_CC1E;
-  tmpccmr1 = TIMx->CCMR1;
-
-  /* Set the filter */
-  tmpccmr1 &= ~TIM_CCMR1_IC1F;
-  tmpccmr1 |= (TIM_ICFilter << 4U);
-
-  /* Select the Polarity and set the CC1E Bit */
-  tmpccer &= ~(TIM_CCER_CC1P | TIM_CCER_CC1NP);
-  tmpccer |= TIM_ICPolarity;
-
-  /* Write to TIMx CCMR1 and CCER registers */
-  TIMx->CCMR1 = tmpccmr1;
-  TIMx->CCER = tmpccer;
-}
-
-/**
-  * @brief  Configure the TI2 as Input.
-  * @param  TIMx to select the TIM peripheral
-  * @param  TIM_ICPolarity The Input Polarity.
-  *          This parameter can be one of the following values:
-  *            @arg TIM_ICPOLARITY_RISING
-  *            @arg TIM_ICPOLARITY_FALLING
-  *            @arg TIM_ICPOLARITY_BOTHEDGE
-  * @param  TIM_ICSelection specifies the input to be used.
-  *          This parameter can be one of the following values:
-  *            @arg TIM_ICSELECTION_DIRECTTI: TIM Input 2 is selected to be connected to IC2.
-  *            @arg TIM_ICSELECTION_INDIRECTTI: TIM Input 2 is selected to be connected to IC1.
-  *            @arg TIM_ICSELECTION_TRC: TIM Input 2 is selected to be connected to TRC.
-  * @param  TIM_ICFilter Specifies the Input Capture Filter.
-  *          This parameter must be a value between 0x00 and 0x0F.
-  * @retval None
-  * @note TIM_ICFilter and TIM_ICPolarity are not used in INDIRECT mode as TI1FP2
-  *       (on channel1 path) is used as the input signal. Therefore CCMR1 must be
-  *        protected against un-initialized filter and polarity values.
-  */
-static void TIM_TI2_SetConfig(TIM_TypeDef *TIMx, uint32_t TIM_ICPolarity, uint32_t TIM_ICSelection,
-                              uint32_t TIM_ICFilter)
-{
-  uint32_t tmpccmr1;
-  uint32_t tmpccer;
-
-  /* Disable the Channel 2: Reset the CC2E Bit */
-  TIMx->CCER &= ~TIM_CCER_CC2E;
-  tmpccmr1 = TIMx->CCMR1;
-  tmpccer = TIMx->CCER;
-
-  /* Select the Input */
-  tmpccmr1 &= ~TIM_CCMR1_CC2S;
-  tmpccmr1 |= (TIM_ICSelection << 8U);
-
-  /* Set the filter */
-  tmpccmr1 &= ~TIM_CCMR1_IC2F;
-  tmpccmr1 |= ((TIM_ICFilter << 12U) & TIM_CCMR1_IC2F);
-
-  /* Select the Polarity and set the CC2E Bit */
-  tmpccer &= ~(TIM_CCER_CC2P | TIM_CCER_CC2NP);
-  tmpccer |= ((TIM_ICPolarity << 4U) & (TIM_CCER_CC2P | TIM_CCER_CC2NP));
-
-  /* Write to TIMx CCMR1 and CCER registers */
-  TIMx->CCMR1 = tmpccmr1 ;
-  TIMx->CCER = tmpccer;
-}
-
-/**
-  * @brief  Configure the Polarity and Filter for TI2.
-  * @param  TIMx to select the TIM peripheral.
-  * @param  TIM_ICPolarity The Input Polarity.
-  *          This parameter can be one of the following values:
-  *            @arg TIM_ICPOLARITY_RISING
-  *            @arg TIM_ICPOLARITY_FALLING
-  *            @arg TIM_ICPOLARITY_BOTHEDGE
-  * @param  TIM_ICFilter Specifies the Input Capture Filter.
-  *          This parameter must be a value between 0x00 and 0x0F.
-  * @retval None
-  */
-static void TIM_TI2_ConfigInputStage(TIM_TypeDef *TIMx, uint32_t TIM_ICPolarity, uint32_t TIM_ICFilter)
-{
-  uint32_t tmpccmr1;
-  uint32_t tmpccer;
-
-  /* Disable the Channel 2: Reset the CC2E Bit */
-  TIMx->CCER &= ~TIM_CCER_CC2E;
-  tmpccmr1 = TIMx->CCMR1;
-  tmpccer = TIMx->CCER;
-
-  /* Set the filter */
-  tmpccmr1 &= ~TIM_CCMR1_IC2F;
-  tmpccmr1 |= (TIM_ICFilter << 12U);
-
-  /* Select the Polarity and set the CC2E Bit */
-  tmpccer &= ~(TIM_CCER_CC2P | TIM_CCER_CC2NP);
-  tmpccer |= (TIM_ICPolarity << 4U);
-
-  /* Write to TIMx CCMR1 and CCER registers */
-  TIMx->CCMR1 = tmpccmr1 ;
-  TIMx->CCER = tmpccer;
-}
-
-/**
-  * @brief  Configure the TI3 as Input.
-  * @param  TIMx to select the TIM peripheral
-  * @param  TIM_ICPolarity The Input Polarity.
-  *          This parameter can be one of the following values:
-  *            @arg TIM_ICPOLARITY_RISING
-  *            @arg TIM_ICPOLARITY_FALLING
-  *            @arg TIM_ICPOLARITY_BOTHEDGE
-  * @param  TIM_ICSelection specifies the input to be used.
-  *          This parameter can be one of the following values:
-  *            @arg TIM_ICSELECTION_DIRECTTI: TIM Input 3 is selected to be connected to IC3.
-  *            @arg TIM_ICSELECTION_INDIRECTTI: TIM Input 3 is selected to be connected to IC4.
-  *            @arg TIM_ICSELECTION_TRC: TIM Input 3 is selected to be connected to TRC.
-  * @param  TIM_ICFilter Specifies the Input Capture Filter.
-  *          This parameter must be a value between 0x00 and 0x0F.
-  * @retval None
-  * @note TIM_ICFilter and TIM_ICPolarity are not used in INDIRECT mode as TI3FP4
-  *       (on channel1 path) is used as the input signal. Therefore CCMR2 must be
-  *        protected against un-initialized filter and polarity values.
-  */
-static void TIM_TI3_SetConfig(TIM_TypeDef *TIMx, uint32_t TIM_ICPolarity, uint32_t TIM_ICSelection,
-                              uint32_t TIM_ICFilter)
-{
-  uint32_t tmpccmr2;
-  uint32_t tmpccer;
-
-  /* Disable the Channel 3: Reset the CC3E Bit */
-  TIMx->CCER &= ~TIM_CCER_CC3E;
-  tmpccmr2 = TIMx->CCMR2;
-  tmpccer = TIMx->CCER;
-
-  /* Select the Input */
-  tmpccmr2 &= ~TIM_CCMR2_CC3S;
-  tmpccmr2 |= TIM_ICSelection;
-
-  /* Set the filter */
-  tmpccmr2 &= ~TIM_CCMR2_IC3F;
-  tmpccmr2 |= ((TIM_ICFilter << 4U) & TIM_CCMR2_IC3F);
-
-  /* Select the Polarity and set the CC3E Bit */
-  tmpccer &= ~(TIM_CCER_CC3P | TIM_CCER_CC3NP);
-  tmpccer |= ((TIM_ICPolarity << 8U) & (TIM_CCER_CC3P | TIM_CCER_CC3NP));
-
-  /* Write to TIMx CCMR2 and CCER registers */
-  TIMx->CCMR2 = tmpccmr2;
-  TIMx->CCER = tmpccer;
-}
-
-/**
-  * @brief  Configure the TI4 as Input.
-  * @param  TIMx to select the TIM peripheral
-  * @param  TIM_ICPolarity The Input Polarity.
-  *          This parameter can be one of the following values:
-  *            @arg TIM_ICPOLARITY_RISING
-  *            @arg TIM_ICPOLARITY_FALLING
-  *            @arg TIM_ICPOLARITY_BOTHEDGE
-  * @param  TIM_ICSelection specifies the input to be used.
-  *          This parameter can be one of the following values:
-  *            @arg TIM_ICSELECTION_DIRECTTI: TIM Input 4 is selected to be connected to IC4.
-  *            @arg TIM_ICSELECTION_INDIRECTTI: TIM Input 4 is selected to be connected to IC3.
-  *            @arg TIM_ICSELECTION_TRC: TIM Input 4 is selected to be connected to TRC.
-  * @param  TIM_ICFilter Specifies the Input Capture Filter.
-  *          This parameter must be a value between 0x00 and 0x0F.
-  * @note TIM_ICFilter and TIM_ICPolarity are not used in INDIRECT mode as TI4FP3
-  *       (on channel1 path) is used as the input signal. Therefore CCMR2 must be
-  *        protected against un-initialized filter and polarity values.
-  * @retval None
-  */
-static void TIM_TI4_SetConfig(TIM_TypeDef *TIMx, uint32_t TIM_ICPolarity, uint32_t TIM_ICSelection,
-                              uint32_t TIM_ICFilter)
-{
-  uint32_t tmpccmr2;
-  uint32_t tmpccer;
-
-  /* Disable the Channel 4: Reset the CC4E Bit */
-  TIMx->CCER &= ~TIM_CCER_CC4E;
-  tmpccmr2 = TIMx->CCMR2;
-  tmpccer = TIMx->CCER;
-
-  /* Select the Input */
-  tmpccmr2 &= ~TIM_CCMR2_CC4S;
-  tmpccmr2 |= (TIM_ICSelection << 8U);
-
-  /* Set the filter */
-  tmpccmr2 &= ~TIM_CCMR2_IC4F;
-  tmpccmr2 |= ((TIM_ICFilter << 12U) & TIM_CCMR2_IC4F);
-
-  /* Select the Polarity and set the CC4E Bit */
-  tmpccer &= ~(TIM_CCER_CC4P | TIM_CCER_CC4NP);
-  tmpccer |= ((TIM_ICPolarity << 12U) & (TIM_CCER_CC4P | TIM_CCER_CC4NP));
-
-  /* Write to TIMx CCMR2 and CCER registers */
-  TIMx->CCMR2 = tmpccmr2;
-  TIMx->CCER = tmpccer ;
-}
-
-/**
-  * @brief  Selects the Input Trigger source
-  * @param  TIMx to select the TIM peripheral
-  * @param  InputTriggerSource The Input Trigger source.
-  *          This parameter can be one of the following values:
-  *            @arg TIM_TS_ITR0: Internal Trigger 0
-  *            @arg TIM_TS_ITR1: Internal Trigger 1
-  *            @arg TIM_TS_ITR2: Internal Trigger 2
-  *            @arg TIM_TS_ITR3: Internal Trigger 3
-  *            @arg TIM_TS_TI1F_ED: TI1 Edge Detector
-  *            @arg TIM_TS_TI1FP1: Filtered Timer Input 1
-  *            @arg TIM_TS_TI2FP2: Filtered Timer Input 2
-  *            @arg TIM_TS_ETRF: External Trigger input
-  * @retval None
-  */
-static void TIM_ITRx_SetConfig(TIM_TypeDef *TIMx, uint32_t InputTriggerSource)
-{
-  uint32_t tmpsmcr;
-
-  /* Get the TIMx SMCR register value */
-  tmpsmcr = TIMx->SMCR;
-  /* Reset the TS Bits */
-  tmpsmcr &= ~TIM_SMCR_TS;
-  /* Set the Input Trigger source and the slave mode*/
-  tmpsmcr |= (InputTriggerSource | TIM_SLAVEMODE_EXTERNAL1);
-  /* Write to TIMx SMCR */
-  TIMx->SMCR = tmpsmcr;
-}
-/**
-  * @brief  Configures the TIMx External Trigger (ETR).
-  * @param  TIMx to select the TIM peripheral
-  * @param  TIM_ExtTRGPrescaler The external Trigger Prescaler.
-  *          This parameter can be one of the following values:
-  *            @arg TIM_ETRPRESCALER_DIV1: ETRP Prescaler OFF.
-  *            @arg TIM_ETRPRESCALER_DIV2: ETRP frequency divided by 2.
-  *            @arg TIM_ETRPRESCALER_DIV4: ETRP frequency divided by 4.
-  *            @arg TIM_ETRPRESCALER_DIV8: ETRP frequency divided by 8.
-  * @param  TIM_ExtTRGPolarity The external Trigger Polarity.
-  *          This parameter can be one of the following values:
-  *            @arg TIM_ETRPOLARITY_INVERTED: active low or falling edge active.
-  *            @arg TIM_ETRPOLARITY_NONINVERTED: active high or rising edge active.
-  * @param  ExtTRGFilter External Trigger Filter.
-  *          This parameter must be a value between 0x00 and 0x0F
-  * @retval None
-  */
-void TIM_ETR_SetConfig(TIM_TypeDef *TIMx, uint32_t TIM_ExtTRGPrescaler,
-                       uint32_t TIM_ExtTRGPolarity, uint32_t ExtTRGFilter)
-{
-  uint32_t tmpsmcr;
-
-  tmpsmcr = TIMx->SMCR;
-
-  /* Reset the ETR Bits */
-  tmpsmcr &= ~(TIM_SMCR_ETF | TIM_SMCR_ETPS | TIM_SMCR_ECE | TIM_SMCR_ETP);
-
-  /* Set the Prescaler, the Filter value and the Polarity */
-  tmpsmcr |= (uint32_t)(TIM_ExtTRGPrescaler | (TIM_ExtTRGPolarity | (ExtTRGFilter << 8U)));
-
-  /* Write to TIMx SMCR */
-  TIMx->SMCR = tmpsmcr;
-}
-
-/**
-  * @brief  Enables or disables the TIM Capture Compare Channel x.
-  * @param  TIMx to select the TIM peripheral
-  * @param  Channel specifies the TIM Channel
-  *          This parameter can be one of the following values:
-  *            @arg TIM_CHANNEL_1: TIM Channel 1
-  *            @arg TIM_CHANNEL_2: TIM Channel 2
-  *            @arg TIM_CHANNEL_3: TIM Channel 3
-  *            @arg TIM_CHANNEL_4: TIM Channel 4
-  *            @arg TIM_CHANNEL_5: TIM Channel 5 selected
-  *            @arg TIM_CHANNEL_6: TIM Channel 6 selected
-  * @param  ChannelState specifies the TIM Channel CCxE bit new state.
-  *          This parameter can be: TIM_CCx_ENABLE or TIM_CCx_DISABLE.
-  * @retval None
-  */
-void TIM_CCxChannelCmd(TIM_TypeDef *TIMx, uint32_t Channel, uint32_t ChannelState)
-{
-  uint32_t tmp;
-
-  /* Check the parameters */
-  assert_param(IS_TIM_CC1_INSTANCE(TIMx));
-  assert_param(IS_TIM_CHANNELS(Channel));
-
-  tmp = TIM_CCER_CC1E << (Channel & 0x1FU); /* 0x1FU = 31 bits max shift */
-
-  /* Reset the CCxE Bit */
-  TIMx->CCER &= ~tmp;
-
-  /* Set or reset the CCxE Bit */
-  TIMx->CCER |= (uint32_t)(ChannelState << (Channel & 0x1FU)); /* 0x1FU = 31 bits max shift */
-}
-
-#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
-/**
-  * @brief  Reset interrupt callbacks to the legacy weak callbacks.
-  * @param  htim pointer to a TIM_HandleTypeDef structure that contains
-  *                the configuration information for TIM module.
-  * @retval None
-  */
-void TIM_ResetCallback(TIM_HandleTypeDef *htim)
-{
-  /* Reset the TIM callback to the legacy weak callbacks */
-  htim->PeriodElapsedCallback             = HAL_TIM_PeriodElapsedCallback;
-  htim->PeriodElapsedHalfCpltCallback     = HAL_TIM_PeriodElapsedHalfCpltCallback;
-  htim->TriggerCallback                   = HAL_TIM_TriggerCallback;
-  htim->TriggerHalfCpltCallback           = HAL_TIM_TriggerHalfCpltCallback;
-  htim->IC_CaptureCallback                = HAL_TIM_IC_CaptureCallback;
-  htim->IC_CaptureHalfCpltCallback        = HAL_TIM_IC_CaptureHalfCpltCallback;
-  htim->OC_DelayElapsedCallback           = HAL_TIM_OC_DelayElapsedCallback;
-  htim->PWM_PulseFinishedCallback         = HAL_TIM_PWM_PulseFinishedCallback;
-  htim->PWM_PulseFinishedHalfCpltCallback = HAL_TIM_PWM_PulseFinishedHalfCpltCallback;
-  htim->ErrorCallback                     = HAL_TIM_ErrorCallback;
-  htim->CommutationCallback               = HAL_TIMEx_CommutCallback;
-  htim->CommutationHalfCpltCallback       = HAL_TIMEx_CommutHalfCpltCallback;
-  htim->BreakCallback                     = HAL_TIMEx_BreakCallback;
-  htim->Break2Callback                    = HAL_TIMEx_Break2Callback;
-}
-#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
-
-/**
-  * @}
-  */
-
-#endif /* HAL_TIM_MODULE_ENABLED */
-/**
-  * @}
-  */
-
-/**
-  * @}
-  */

+ 0 - 2842
non_catalog_apps/flipperscope/lib/adc/stm32wbxx_hal_tim_ex.c

@@ -1,2842 +0,0 @@
-/**
-  ******************************************************************************
-  * @file    stm32wbxx_hal_tim_ex.c
-  * @author  MCD Application Team
-  * @brief   TIM HAL module driver.
-  *          This file provides firmware functions to manage the following
-  *          functionalities of the Timer Extended peripheral:
-  *           + Time Hall Sensor Interface Initialization
-  *           + Time Hall Sensor Interface Start
-  *           + Time Complementary signal break and dead time configuration
-  *           + Time Master and Slave synchronization configuration
-  *           + Time Output Compare/PWM Channel Configuration (for channels 5 and 6)
-  *           + Time OCRef clear configuration
-  *           + Timer remapping capabilities configuration
-  ******************************************************************************
-  * @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
-  ==============================================================================
-                      ##### TIMER Extended features #####
-  ==============================================================================
-  [..]
-    The Timer Extended features include:
-    (#) Complementary outputs with programmable dead-time for :
-        (++) Output Compare
-        (++) PWM generation (Edge and Center-aligned Mode)
-        (++) One-pulse mode output
-    (#) Synchronization circuit to control the timer with external signals and to
-        interconnect several timers together.
-    (#) Break input to put the timer output signals in reset state or in a known state.
-    (#) Supports incremental (quadrature) encoder and hall-sensor circuitry for
-        positioning purposes
-
-            ##### How to use this driver #####
-  ==============================================================================
-    [..]
-     (#) Initialize the TIM low level resources by implementing the following functions
-         depending on the selected feature:
-           (++) Hall Sensor output : HAL_TIMEx_HallSensor_MspInit()
-
-     (#) Initialize the TIM low level resources :
-        (##) Enable the TIM interface clock using __HAL_RCC_TIMx_CLK_ENABLE();
-        (##) TIM pins configuration
-            (+++) Enable the clock for the TIM GPIOs using the following function:
-              __HAL_RCC_GPIOx_CLK_ENABLE();
-            (+++) Configure these TIM pins in Alternate function mode using HAL_GPIO_Init();
-
-     (#) The external Clock can be configured, if needed (the default clock is the
-         internal clock from the APBx), using the following function:
-         HAL_TIM_ConfigClockSource, the clock configuration should be done before
-         any start function.
-
-     (#) Configure the TIM in the desired functioning mode using one of the
-         initialization function of this driver:
-          (++) HAL_TIMEx_HallSensor_Init() and HAL_TIMEx_ConfigCommutEvent(): to use the
-               Timer Hall Sensor Interface and the commutation event with the corresponding
-               Interrupt and DMA request if needed (Note that One Timer is used to interface
-               with the Hall sensor Interface and another Timer should be used to use
-               the commutation event).
-
-     (#) Activate the TIM peripheral using one of the start functions:
-           (++) Complementary Output Compare : HAL_TIMEx_OCN_Start(), HAL_TIMEx_OCN_Start_DMA(),
-                HAL_TIMEx_OCN_Start_IT()
-           (++) Complementary PWM generation : HAL_TIMEx_PWMN_Start(), HAL_TIMEx_PWMN_Start_DMA(),
-                HAL_TIMEx_PWMN_Start_IT()
-           (++) Complementary One-pulse mode output : HAL_TIMEx_OnePulseN_Start(), HAL_TIMEx_OnePulseN_Start_IT()
-           (++) Hall Sensor output : HAL_TIMEx_HallSensor_Start(), HAL_TIMEx_HallSensor_Start_DMA(),
-                HAL_TIMEx_HallSensor_Start_IT().
-
-  @endverbatim
-  ******************************************************************************
-  */
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32wbxx_hal.h"
-
-/** @addtogroup STM32WBxx_HAL_Driver
-  * @{
-  */
-
-/** @defgroup TIMEx TIMEx
-  * @brief TIM Extended HAL module driver
-  * @{
-  */
-
-#ifdef HAL_TIM_MODULE_ENABLED
-
-/* Private typedef -----------------------------------------------------------*/
-/* Private define ------------------------------------------------------------*/
-/* Private constants ---------------------------------------------------------*/
-/** @defgroup TIMEx_Private_Constants TIM Extended Private Constants
-  * @{
-  */
-/* Timeout for break input rearm */
-#define TIM_BREAKINPUT_REARM_TIMEOUT    5UL /* 5 milliseconds */
-/**
-  * @}
-  */
-/* End of private constants --------------------------------------------------*/
-
-/* Private macros ------------------------------------------------------------*/
-/** @addtogroup TIMEx_Private_Macros
-  * @{
-  */
-#if defined(STM32WB55xx) || defined(STM32WB5Mxx) || defined(STM32WB35xx)
-#define TIM_GET_OR_MASK(__INSTANCE__)                                                  \
-  (((__INSTANCE__) == TIM1) ? (TIM1_OR_ETR_ADC1_RMP | TIM1_OR_TI1_RMP) :               \
-   ((__INSTANCE__) == TIM2) ? (TIM2_OR_TI4_RMP | TIM2_OR_ETR_RMP | TIM2_OR_ITR1_RMP) : \
-   ((__INSTANCE__) == TIM16) ? TIM16_OR_TI1_RMP : TIM17_OR_TI1_RMP)
-#elif defined(STM32WB10xx)
-#define TIM_GET_OR_MASK(__INSTANCE__)                                    \
-  (((__INSTANCE__) == TIM1) ? (TIM1_OR_ETR_ADC1_RMP) : (TIM2_OR_ETR_RMP))
-#elif defined(STM32WB15xx) || defined(STM32WB1Mxx)
-#define TIM_GET_OR_MASK(__INSTANCE__)                                    \
-  (((__INSTANCE__) == TIM1) ? (TIM1_OR_ETR_ADC1_RMP | TIM1_OR_TI1_RMP) : \
-   (TIM2_OR_TI4_RMP | TIM2_OR_ETR_RMP))
-#else
-#define TIM_GET_OR_MASK(__INSTANCE__)                                    \
-  (((__INSTANCE__) == TIM1) ? (TIM1_OR_ETR_ADC1_RMP | TIM1_OR_TI1_RMP) : \
-   ((__INSTANCE__) == TIM2) ? TIM2_OR_ETR_RMP :                          \
-   ((__INSTANCE__) == TIM16) ? TIM16_OR_TI1_RMP : TIM17_OR_TI1_RMP)
-#endif
-/**
-  * @}
-  */
-
-/* Private variables ---------------------------------------------------------*/
-/* Private function prototypes -----------------------------------------------*/
-static void TIM_DMADelayPulseNCplt(DMA_HandleTypeDef *hdma);
-static void TIM_DMAErrorCCxN(DMA_HandleTypeDef *hdma);
-static void TIM_CCxNChannelCmd(TIM_TypeDef *TIMx, uint32_t Channel, uint32_t ChannelNState);
-
-/* Exported functions --------------------------------------------------------*/
-/** @defgroup TIMEx_Exported_Functions TIM Extended Exported Functions
-  * @{
-  */
-
-/** @defgroup TIMEx_Exported_Functions_Group1 Extended Timer Hall Sensor functions
-  * @brief    Timer Hall Sensor functions
-  *
-@verbatim
-  ==============================================================================
-                      ##### Timer Hall Sensor functions #####
-  ==============================================================================
-  [..]
-    This section provides functions allowing to:
-    (+) Initialize and configure TIM HAL Sensor.
-    (+) De-initialize TIM HAL Sensor.
-    (+) Start the Hall Sensor Interface.
-    (+) Stop the Hall Sensor Interface.
-    (+) Start the Hall Sensor Interface and enable interrupts.
-    (+) Stop the Hall Sensor Interface and disable interrupts.
-    (+) Start the Hall Sensor Interface and enable DMA transfers.
-    (+) Stop the Hall Sensor Interface and disable DMA transfers.
-
-@endverbatim
-  * @{
-  */
-/**
-  * @brief  Initializes the TIM Hall Sensor Interface and initialize the associated handle.
-  * @note   When the timer instance is initialized in Hall Sensor Interface mode,
-  *         timer channels 1 and channel 2 are reserved and cannot be used for
-  *         other purpose.
-  * @param  htim TIM Hall Sensor Interface handle
-  * @param  sConfig TIM Hall Sensor configuration structure
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_TIMEx_HallSensor_Init(TIM_HandleTypeDef *htim, const TIM_HallSensor_InitTypeDef *sConfig)
-{
-  TIM_OC_InitTypeDef OC_Config;
-
-  /* Check the TIM handle allocation */
-  if (htim == NULL)
-  {
-    return HAL_ERROR;
-  }
-
-  /* Check the parameters */
-  assert_param(IS_TIM_HALL_SENSOR_INTERFACE_INSTANCE(htim->Instance));
-  assert_param(IS_TIM_COUNTER_MODE(htim->Init.CounterMode));
-  assert_param(IS_TIM_CLOCKDIVISION_DIV(htim->Init.ClockDivision));
-  assert_param(IS_TIM_AUTORELOAD_PRELOAD(htim->Init.AutoReloadPreload));
-  assert_param(IS_TIM_IC_POLARITY(sConfig->IC1Polarity));
-  assert_param(IS_TIM_PERIOD(htim, htim->Init.Period));
-  assert_param(IS_TIM_IC_PRESCALER(sConfig->IC1Prescaler));
-  assert_param(IS_TIM_IC_FILTER(sConfig->IC1Filter));
-
-  if (htim->State == HAL_TIM_STATE_RESET)
-  {
-    /* Allocate lock resource and initialize it */
-    htim->Lock = HAL_UNLOCKED;
-
-#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
-    /* Reset interrupt callbacks to legacy week callbacks */
-    TIM_ResetCallback(htim);
-
-    if (htim->HallSensor_MspInitCallback == NULL)
-    {
-      htim->HallSensor_MspInitCallback = HAL_TIMEx_HallSensor_MspInit;
-    }
-    /* Init the low level hardware : GPIO, CLOCK, NVIC */
-    htim->HallSensor_MspInitCallback(htim);
-#else
-    /* Init the low level hardware : GPIO, CLOCK, NVIC and DMA */
-    HAL_TIMEx_HallSensor_MspInit(htim);
-#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
-  }
-
-  /* Set the TIM state */
-  htim->State = HAL_TIM_STATE_BUSY;
-
-  /* Configure the Time base in the Encoder Mode */
-  TIM_Base_SetConfig(htim->Instance, &htim->Init);
-
-  /* Configure the Channel 1 as Input Channel to interface with the three Outputs of the  Hall sensor */
-  TIM_TI1_SetConfig(htim->Instance, sConfig->IC1Polarity, TIM_ICSELECTION_TRC, sConfig->IC1Filter);
-
-  /* Reset the IC1PSC Bits */
-  htim->Instance->CCMR1 &= ~TIM_CCMR1_IC1PSC;
-  /* Set the IC1PSC value */
-  htim->Instance->CCMR1 |= sConfig->IC1Prescaler;
-
-  /* Enable the Hall sensor interface (XOR function of the three inputs) */
-  htim->Instance->CR2 |= TIM_CR2_TI1S;
-
-  /* Select the TIM_TS_TI1F_ED signal as Input trigger for the TIM */
-  htim->Instance->SMCR &= ~TIM_SMCR_TS;
-  htim->Instance->SMCR |= TIM_TS_TI1F_ED;
-
-  /* Use the TIM_TS_TI1F_ED signal to reset the TIM counter each edge detection */
-  htim->Instance->SMCR &= ~TIM_SMCR_SMS;
-  htim->Instance->SMCR |= TIM_SLAVEMODE_RESET;
-
-  /* Program channel 2 in PWM 2 mode with the desired Commutation_Delay*/
-  OC_Config.OCFastMode = TIM_OCFAST_DISABLE;
-  OC_Config.OCIdleState = TIM_OCIDLESTATE_RESET;
-  OC_Config.OCMode = TIM_OCMODE_PWM2;
-  OC_Config.OCNIdleState = TIM_OCNIDLESTATE_RESET;
-  OC_Config.OCNPolarity = TIM_OCNPOLARITY_HIGH;
-  OC_Config.OCPolarity = TIM_OCPOLARITY_HIGH;
-  OC_Config.Pulse = sConfig->Commutation_Delay;
-
-  TIM_OC2_SetConfig(htim->Instance, &OC_Config);
-
-  /* Select OC2REF as trigger output on TRGO: write the MMS bits in the TIMx_CR2
-    register to 101 */
-  htim->Instance->CR2 &= ~TIM_CR2_MMS;
-  htim->Instance->CR2 |= TIM_TRGO_OC2REF;
-
-  /* Initialize the DMA burst operation state */
-  htim->DMABurstState = HAL_DMA_BURST_STATE_READY;
-
-  /* Initialize the TIM channels state */
-  TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY);
-  TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY);
-  TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY);
-  TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY);
-
-  /* Initialize the TIM state*/
-  htim->State = HAL_TIM_STATE_READY;
-
-  return HAL_OK;
-}
-
-/**
-  * @brief  DeInitializes the TIM Hall Sensor interface
-  * @param  htim TIM Hall Sensor Interface handle
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_TIMEx_HallSensor_DeInit(TIM_HandleTypeDef *htim)
-{
-  /* Check the parameters */
-  assert_param(IS_TIM_INSTANCE(htim->Instance));
-
-  htim->State = HAL_TIM_STATE_BUSY;
-
-  /* Disable the TIM Peripheral Clock */
-  __HAL_TIM_DISABLE(htim);
-
-#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
-  if (htim->HallSensor_MspDeInitCallback == NULL)
-  {
-    htim->HallSensor_MspDeInitCallback = HAL_TIMEx_HallSensor_MspDeInit;
-  }
-  /* DeInit the low level hardware */
-  htim->HallSensor_MspDeInitCallback(htim);
-#else
-  /* DeInit the low level hardware: GPIO, CLOCK, NVIC */
-  HAL_TIMEx_HallSensor_MspDeInit(htim);
-#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
-
-  /* Change the DMA burst operation state */
-  htim->DMABurstState = HAL_DMA_BURST_STATE_RESET;
-
-  /* Change the TIM channels state */
-  TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_RESET);
-  TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_RESET);
-  TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_RESET);
-  TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_RESET);
-
-  /* Change TIM state */
-  htim->State = HAL_TIM_STATE_RESET;
-
-  /* Release Lock */
-  __HAL_UNLOCK(htim);
-
-  return HAL_OK;
-}
-
-/**
-  * @brief  Initializes the TIM Hall Sensor MSP.
-  * @param  htim TIM Hall Sensor Interface handle
-  * @retval None
-  */
-__weak void HAL_TIMEx_HallSensor_MspInit(TIM_HandleTypeDef *htim)
-{
-  /* Prevent unused argument(s) compilation warning */
-  UNUSED(htim);
-
-  /* NOTE : This function should not be modified, when the callback is needed,
-            the HAL_TIMEx_HallSensor_MspInit could be implemented in the user file
-   */
-}
-
-/**
-  * @brief  DeInitializes TIM Hall Sensor MSP.
-  * @param  htim TIM Hall Sensor Interface handle
-  * @retval None
-  */
-__weak void HAL_TIMEx_HallSensor_MspDeInit(TIM_HandleTypeDef *htim)
-{
-  /* Prevent unused argument(s) compilation warning */
-  UNUSED(htim);
-
-  /* NOTE : This function should not be modified, when the callback is needed,
-            the HAL_TIMEx_HallSensor_MspDeInit could be implemented in the user file
-   */
-}
-
-/**
-  * @brief  Starts the TIM Hall Sensor Interface.
-  * @param  htim TIM Hall Sensor Interface handle
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_TIMEx_HallSensor_Start(TIM_HandleTypeDef *htim)
-{
-  uint32_t tmpsmcr;
-  HAL_TIM_ChannelStateTypeDef channel_1_state = TIM_CHANNEL_STATE_GET(htim, TIM_CHANNEL_1);
-  HAL_TIM_ChannelStateTypeDef channel_2_state = TIM_CHANNEL_STATE_GET(htim, TIM_CHANNEL_2);
-  HAL_TIM_ChannelStateTypeDef complementary_channel_1_state = TIM_CHANNEL_N_STATE_GET(htim, TIM_CHANNEL_1);
-  HAL_TIM_ChannelStateTypeDef complementary_channel_2_state = TIM_CHANNEL_N_STATE_GET(htim, TIM_CHANNEL_2);
-
-  /* Check the parameters */
-  assert_param(IS_TIM_HALL_SENSOR_INTERFACE_INSTANCE(htim->Instance));
-
-  /* Check the TIM channels state */
-  if ((channel_1_state != HAL_TIM_CHANNEL_STATE_READY)
-      || (channel_2_state != HAL_TIM_CHANNEL_STATE_READY)
-      || (complementary_channel_1_state != HAL_TIM_CHANNEL_STATE_READY)
-      || (complementary_channel_2_state != HAL_TIM_CHANNEL_STATE_READY))
-  {
-    return HAL_ERROR;
-  }
-
-  /* Set the TIM channels state */
-  TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY);
-  TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY);
-  TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY);
-  TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY);
-
-  /* Enable the Input Capture channel 1
-  (in the Hall Sensor Interface the three possible channels that can be used are TIM_CHANNEL_1,
-  TIM_CHANNEL_2 and TIM_CHANNEL_3) */
-  TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_ENABLE);
-
-  /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */
-  if (IS_TIM_SLAVE_INSTANCE(htim->Instance))
-  {
-    tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS;
-    if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr))
-    {
-      __HAL_TIM_ENABLE(htim);
-    }
-  }
-  else
-  {
-    __HAL_TIM_ENABLE(htim);
-  }
-
-  /* Return function status */
-  return HAL_OK;
-}
-
-/**
-  * @brief  Stops the TIM Hall sensor Interface.
-  * @param  htim TIM Hall Sensor Interface handle
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_TIMEx_HallSensor_Stop(TIM_HandleTypeDef *htim)
-{
-  /* Check the parameters */
-  assert_param(IS_TIM_HALL_SENSOR_INTERFACE_INSTANCE(htim->Instance));
-
-  /* Disable the Input Capture channels 1, 2 and 3
-  (in the Hall Sensor Interface the three possible channels that can be used are TIM_CHANNEL_1,
-  TIM_CHANNEL_2 and TIM_CHANNEL_3) */
-  TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_DISABLE);
-
-  /* Disable the Peripheral */
-  __HAL_TIM_DISABLE(htim);
-
-  /* Set the TIM channels state */
-  TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY);
-  TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY);
-  TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY);
-  TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY);
-
-  /* Return function status */
-  return HAL_OK;
-}
-
-/**
-  * @brief  Starts the TIM Hall Sensor Interface in interrupt mode.
-  * @param  htim TIM Hall Sensor Interface handle
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_TIMEx_HallSensor_Start_IT(TIM_HandleTypeDef *htim)
-{
-  uint32_t tmpsmcr;
-  HAL_TIM_ChannelStateTypeDef channel_1_state = TIM_CHANNEL_STATE_GET(htim, TIM_CHANNEL_1);
-  HAL_TIM_ChannelStateTypeDef channel_2_state = TIM_CHANNEL_STATE_GET(htim, TIM_CHANNEL_2);
-  HAL_TIM_ChannelStateTypeDef complementary_channel_1_state = TIM_CHANNEL_N_STATE_GET(htim, TIM_CHANNEL_1);
-  HAL_TIM_ChannelStateTypeDef complementary_channel_2_state = TIM_CHANNEL_N_STATE_GET(htim, TIM_CHANNEL_2);
-
-  /* Check the parameters */
-  assert_param(IS_TIM_HALL_SENSOR_INTERFACE_INSTANCE(htim->Instance));
-
-  /* Check the TIM channels state */
-  if ((channel_1_state != HAL_TIM_CHANNEL_STATE_READY)
-      || (channel_2_state != HAL_TIM_CHANNEL_STATE_READY)
-      || (complementary_channel_1_state != HAL_TIM_CHANNEL_STATE_READY)
-      || (complementary_channel_2_state != HAL_TIM_CHANNEL_STATE_READY))
-  {
-    return HAL_ERROR;
-  }
-
-  /* Set the TIM channels state */
-  TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY);
-  TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY);
-  TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY);
-  TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY);
-
-  /* Enable the capture compare Interrupts 1 event */
-  __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC1);
-
-  /* Enable the Input Capture channel 1
-  (in the Hall Sensor Interface the three possible channels that can be used are TIM_CHANNEL_1,
-  TIM_CHANNEL_2 and TIM_CHANNEL_3) */
-  TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_ENABLE);
-
-  /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */
-  if (IS_TIM_SLAVE_INSTANCE(htim->Instance))
-  {
-    tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS;
-    if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr))
-    {
-      __HAL_TIM_ENABLE(htim);
-    }
-  }
-  else
-  {
-    __HAL_TIM_ENABLE(htim);
-  }
-
-  /* Return function status */
-  return HAL_OK;
-}
-
-/**
-  * @brief  Stops the TIM Hall Sensor Interface in interrupt mode.
-  * @param  htim TIM Hall Sensor Interface handle
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_TIMEx_HallSensor_Stop_IT(TIM_HandleTypeDef *htim)
-{
-  /* Check the parameters */
-  assert_param(IS_TIM_HALL_SENSOR_INTERFACE_INSTANCE(htim->Instance));
-
-  /* Disable the Input Capture channel 1
-  (in the Hall Sensor Interface the three possible channels that can be used are TIM_CHANNEL_1,
-  TIM_CHANNEL_2 and TIM_CHANNEL_3) */
-  TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_DISABLE);
-
-  /* Disable the capture compare Interrupts event */
-  __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC1);
-
-  /* Disable the Peripheral */
-  __HAL_TIM_DISABLE(htim);
-
-  /* Set the TIM channels state */
-  TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY);
-  TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY);
-  TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY);
-  TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY);
-
-  /* Return function status */
-  return HAL_OK;
-}
-
-/**
-  * @brief  Starts the TIM Hall Sensor Interface in DMA mode.
-  * @param  htim TIM Hall Sensor Interface handle
-  * @param  pData The destination Buffer address.
-  * @param  Length The length of data to be transferred from TIM peripheral to memory.
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_TIMEx_HallSensor_Start_DMA(TIM_HandleTypeDef *htim, uint32_t *pData, uint16_t Length)
-{
-  uint32_t tmpsmcr;
-  HAL_TIM_ChannelStateTypeDef channel_1_state = TIM_CHANNEL_STATE_GET(htim, TIM_CHANNEL_1);
-  HAL_TIM_ChannelStateTypeDef complementary_channel_1_state = TIM_CHANNEL_N_STATE_GET(htim, TIM_CHANNEL_1);
-
-  /* Check the parameters */
-  assert_param(IS_TIM_HALL_SENSOR_INTERFACE_INSTANCE(htim->Instance));
-
-  /* Set the TIM channel state */
-  if ((channel_1_state == HAL_TIM_CHANNEL_STATE_BUSY)
-      || (complementary_channel_1_state == HAL_TIM_CHANNEL_STATE_BUSY))
-  {
-    return HAL_BUSY;
-  }
-  else if ((channel_1_state == HAL_TIM_CHANNEL_STATE_READY)
-           && (complementary_channel_1_state == HAL_TIM_CHANNEL_STATE_READY))
-  {
-    if ((pData == NULL) || (Length == 0U))
-    {
-      return HAL_ERROR;
-    }
-    else
-    {
-      TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY);
-      TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY);
-    }
-  }
-  else
-  {
-    return HAL_ERROR;
-  }
-
-  /* Enable the Input Capture channel 1
-  (in the Hall Sensor Interface the three possible channels that can be used are TIM_CHANNEL_1,
-  TIM_CHANNEL_2 and TIM_CHANNEL_3) */
-  TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_ENABLE);
-
-  /* Set the DMA Input Capture 1 Callbacks */
-  htim->hdma[TIM_DMA_ID_CC1]->XferCpltCallback = TIM_DMACaptureCplt;
-  htim->hdma[TIM_DMA_ID_CC1]->XferHalfCpltCallback = TIM_DMACaptureHalfCplt;
-  /* Set the DMA error callback */
-  htim->hdma[TIM_DMA_ID_CC1]->XferErrorCallback = TIM_DMAError ;
-
-  /* Enable the DMA channel for Capture 1*/
-  if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC1], (uint32_t)&htim->Instance->CCR1, (uint32_t)pData, Length) != HAL_OK)
-  {
-    /* Return error status */
-    return HAL_ERROR;
-  }
-  /* Enable the capture compare 1 Interrupt */
-  __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC1);
-
-  /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */
-  if (IS_TIM_SLAVE_INSTANCE(htim->Instance))
-  {
-    tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS;
-    if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr))
-    {
-      __HAL_TIM_ENABLE(htim);
-    }
-  }
-  else
-  {
-    __HAL_TIM_ENABLE(htim);
-  }
-
-  /* Return function status */
-  return HAL_OK;
-}
-
-/**
-  * @brief  Stops the TIM Hall Sensor Interface in DMA mode.
-  * @param  htim TIM Hall Sensor Interface handle
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_TIMEx_HallSensor_Stop_DMA(TIM_HandleTypeDef *htim)
-{
-  /* Check the parameters */
-  assert_param(IS_TIM_HALL_SENSOR_INTERFACE_INSTANCE(htim->Instance));
-
-  /* Disable the Input Capture channel 1
-  (in the Hall Sensor Interface the three possible channels that can be used are TIM_CHANNEL_1,
-  TIM_CHANNEL_2 and TIM_CHANNEL_3) */
-  TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_DISABLE);
-
-
-  /* Disable the capture compare Interrupts 1 event */
-  __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC1);
-
-  (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC1]);
-
-  /* Disable the Peripheral */
-  __HAL_TIM_DISABLE(htim);
-
-  /* Set the TIM channel state */
-  TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY);
-  TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY);
-
-  /* Return function status */
-  return HAL_OK;
-}
-
-/**
-  * @}
-  */
-
-/** @defgroup TIMEx_Exported_Functions_Group2 Extended Timer Complementary Output Compare functions
-  *  @brief   Timer Complementary Output Compare functions
-  *
-@verbatim
-  ==============================================================================
-              ##### Timer Complementary Output Compare functions #####
-  ==============================================================================
-  [..]
-    This section provides functions allowing to:
-    (+) Start the Complementary Output Compare/PWM.
-    (+) Stop the Complementary Output Compare/PWM.
-    (+) Start the Complementary Output Compare/PWM and enable interrupts.
-    (+) Stop the Complementary Output Compare/PWM and disable interrupts.
-    (+) Start the Complementary Output Compare/PWM and enable DMA transfers.
-    (+) Stop the Complementary Output Compare/PWM and disable DMA transfers.
-
-@endverbatim
-  * @{
-  */
-
-/**
-  * @brief  Starts the TIM Output Compare signal generation on the complementary
-  *         output.
-  * @param  htim TIM Output Compare handle
-  * @param  Channel TIM Channel to be enabled
-  *          This parameter can be one of the following values:
-  *            @arg TIM_CHANNEL_1: TIM Channel 1 selected
-  *            @arg TIM_CHANNEL_2: TIM Channel 2 selected
-  *            @arg TIM_CHANNEL_3: TIM Channel 3 selected
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_TIMEx_OCN_Start(TIM_HandleTypeDef *htim, uint32_t Channel)
-{
-  uint32_t tmpsmcr;
-
-  /* Check the parameters */
-  assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel));
-
-  /* Check the TIM complementary channel state */
-  if (TIM_CHANNEL_N_STATE_GET(htim, Channel) != HAL_TIM_CHANNEL_STATE_READY)
-  {
-    return HAL_ERROR;
-  }
-
-  /* Set the TIM complementary channel state */
-  TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_BUSY);
-
-  /* Enable the Capture compare channel N */
-  TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_ENABLE);
-
-  /* Enable the Main Output */
-  __HAL_TIM_MOE_ENABLE(htim);
-
-  /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */
-  if (IS_TIM_SLAVE_INSTANCE(htim->Instance))
-  {
-    tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS;
-    if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr))
-    {
-      __HAL_TIM_ENABLE(htim);
-    }
-  }
-  else
-  {
-    __HAL_TIM_ENABLE(htim);
-  }
-
-  /* Return function status */
-  return HAL_OK;
-}
-
-/**
-  * @brief  Stops the TIM Output Compare signal generation on the complementary
-  *         output.
-  * @param  htim TIM handle
-  * @param  Channel TIM Channel to be disabled
-  *          This parameter can be one of the following values:
-  *            @arg TIM_CHANNEL_1: TIM Channel 1 selected
-  *            @arg TIM_CHANNEL_2: TIM Channel 2 selected
-  *            @arg TIM_CHANNEL_3: TIM Channel 3 selected
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_TIMEx_OCN_Stop(TIM_HandleTypeDef *htim, uint32_t Channel)
-{
-  /* Check the parameters */
-  assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel));
-
-  /* Disable the Capture compare channel N */
-  TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_DISABLE);
-
-  /* Disable the Main Output */
-  __HAL_TIM_MOE_DISABLE(htim);
-
-  /* Disable the Peripheral */
-  __HAL_TIM_DISABLE(htim);
-
-  /* Set the TIM complementary channel state */
-  TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_READY);
-
-  /* Return function status */
-  return HAL_OK;
-}
-
-/**
-  * @brief  Starts the TIM Output Compare signal generation in interrupt mode
-  *         on the complementary output.
-  * @param  htim TIM OC handle
-  * @param  Channel TIM Channel to be enabled
-  *          This parameter can be one of the following values:
-  *            @arg TIM_CHANNEL_1: TIM Channel 1 selected
-  *            @arg TIM_CHANNEL_2: TIM Channel 2 selected
-  *            @arg TIM_CHANNEL_3: TIM Channel 3 selected
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_TIMEx_OCN_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel)
-{
-  HAL_StatusTypeDef status = HAL_OK;
-  uint32_t tmpsmcr;
-
-  /* Check the parameters */
-  assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel));
-
-  /* Check the TIM complementary channel state */
-  if (TIM_CHANNEL_N_STATE_GET(htim, Channel) != HAL_TIM_CHANNEL_STATE_READY)
-  {
-    return HAL_ERROR;
-  }
-
-  /* Set the TIM complementary channel state */
-  TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_BUSY);
-
-  switch (Channel)
-  {
-    case TIM_CHANNEL_1:
-    {
-      /* Enable the TIM Output Compare interrupt */
-      __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC1);
-      break;
-    }
-
-    case TIM_CHANNEL_2:
-    {
-      /* Enable the TIM Output Compare interrupt */
-      __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC2);
-      break;
-    }
-
-    case TIM_CHANNEL_3:
-    {
-      /* Enable the TIM Output Compare interrupt */
-      __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC3);
-      break;
-    }
-
-
-    default:
-      status = HAL_ERROR;
-      break;
-  }
-
-  if (status == HAL_OK)
-  {
-    /* Enable the TIM Break interrupt */
-    __HAL_TIM_ENABLE_IT(htim, TIM_IT_BREAK);
-
-    /* Enable the Capture compare channel N */
-    TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_ENABLE);
-
-    /* Enable the Main Output */
-    __HAL_TIM_MOE_ENABLE(htim);
-
-    /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */
-    if (IS_TIM_SLAVE_INSTANCE(htim->Instance))
-    {
-      tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS;
-      if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr))
-      {
-        __HAL_TIM_ENABLE(htim);
-      }
-    }
-    else
-    {
-      __HAL_TIM_ENABLE(htim);
-    }
-  }
-
-  /* Return function status */
-  return status;
-}
-
-/**
-  * @brief  Stops the TIM Output Compare signal generation in interrupt mode
-  *         on the complementary output.
-  * @param  htim TIM Output Compare handle
-  * @param  Channel TIM Channel to be disabled
-  *          This parameter can be one of the following values:
-  *            @arg TIM_CHANNEL_1: TIM Channel 1 selected
-  *            @arg TIM_CHANNEL_2: TIM Channel 2 selected
-  *            @arg TIM_CHANNEL_3: TIM Channel 3 selected
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_TIMEx_OCN_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel)
-{
-  HAL_StatusTypeDef status = HAL_OK;
-  uint32_t tmpccer;
-
-  /* Check the parameters */
-  assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel));
-
-  switch (Channel)
-  {
-    case TIM_CHANNEL_1:
-    {
-      /* Disable the TIM Output Compare interrupt */
-      __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC1);
-      break;
-    }
-
-    case TIM_CHANNEL_2:
-    {
-      /* Disable the TIM Output Compare interrupt */
-      __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC2);
-      break;
-    }
-
-    case TIM_CHANNEL_3:
-    {
-      /* Disable the TIM Output Compare interrupt */
-      __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC3);
-      break;
-    }
-
-    default:
-      status = HAL_ERROR;
-      break;
-  }
-
-  if (status == HAL_OK)
-  {
-    /* Disable the Capture compare channel N */
-    TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_DISABLE);
-
-    /* Disable the TIM Break interrupt (only if no more channel is active) */
-    tmpccer = htim->Instance->CCER;
-    if ((tmpccer & (TIM_CCER_CC1NE | TIM_CCER_CC2NE | TIM_CCER_CC3NE)) == (uint32_t)RESET)
-    {
-      __HAL_TIM_DISABLE_IT(htim, TIM_IT_BREAK);
-    }
-
-    /* Disable the Main Output */
-    __HAL_TIM_MOE_DISABLE(htim);
-
-    /* Disable the Peripheral */
-    __HAL_TIM_DISABLE(htim);
-
-    /* Set the TIM complementary channel state */
-    TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_READY);
-  }
-
-  /* Return function status */
-  return status;
-}
-
-/**
-  * @brief  Starts the TIM Output Compare signal generation in DMA mode
-  *         on the complementary output.
-  * @param  htim TIM Output Compare handle
-  * @param  Channel TIM Channel to be enabled
-  *          This parameter can be one of the following values:
-  *            @arg TIM_CHANNEL_1: TIM Channel 1 selected
-  *            @arg TIM_CHANNEL_2: TIM Channel 2 selected
-  *            @arg TIM_CHANNEL_3: TIM Channel 3 selected
-  * @param  pData The source Buffer address.
-  * @param  Length The length of data to be transferred from memory to TIM peripheral
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_TIMEx_OCN_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, const uint32_t *pData,
-                                          uint16_t Length)
-{
-  HAL_StatusTypeDef status = HAL_OK;
-  uint32_t tmpsmcr;
-
-  /* Check the parameters */
-  assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel));
-
-  /* Set the TIM complementary channel state */
-  if (TIM_CHANNEL_N_STATE_GET(htim, Channel) == HAL_TIM_CHANNEL_STATE_BUSY)
-  {
-    return HAL_BUSY;
-  }
-  else if (TIM_CHANNEL_N_STATE_GET(htim, Channel) == HAL_TIM_CHANNEL_STATE_READY)
-  {
-    if ((pData == NULL) || (Length == 0U))
-    {
-      return HAL_ERROR;
-    }
-    else
-    {
-      TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_BUSY);
-    }
-  }
-  else
-  {
-    return HAL_ERROR;
-  }
-
-  switch (Channel)
-  {
-    case TIM_CHANNEL_1:
-    {
-      /* Set the DMA compare callbacks */
-      htim->hdma[TIM_DMA_ID_CC1]->XferCpltCallback = TIM_DMADelayPulseNCplt;
-      htim->hdma[TIM_DMA_ID_CC1]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt;
-
-      /* Set the DMA error callback */
-      htim->hdma[TIM_DMA_ID_CC1]->XferErrorCallback = TIM_DMAErrorCCxN ;
-
-      /* Enable the DMA channel */
-      if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC1], (uint32_t)pData, (uint32_t)&htim->Instance->CCR1,
-                           Length) != HAL_OK)
-      {
-        /* Return error status */
-        return HAL_ERROR;
-      }
-      /* Enable the TIM Output Compare DMA request */
-      __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC1);
-      break;
-    }
-
-    case TIM_CHANNEL_2:
-    {
-      /* Set the DMA compare callbacks */
-      htim->hdma[TIM_DMA_ID_CC2]->XferCpltCallback = TIM_DMADelayPulseNCplt;
-      htim->hdma[TIM_DMA_ID_CC2]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt;
-
-      /* Set the DMA error callback */
-      htim->hdma[TIM_DMA_ID_CC2]->XferErrorCallback = TIM_DMAErrorCCxN ;
-
-      /* Enable the DMA channel */
-      if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC2], (uint32_t)pData, (uint32_t)&htim->Instance->CCR2,
-                           Length) != HAL_OK)
-      {
-        /* Return error status */
-        return HAL_ERROR;
-      }
-      /* Enable the TIM Output Compare DMA request */
-      __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC2);
-      break;
-    }
-
-    case TIM_CHANNEL_3:
-    {
-      /* Set the DMA compare callbacks */
-      htim->hdma[TIM_DMA_ID_CC3]->XferCpltCallback = TIM_DMADelayPulseNCplt;
-      htim->hdma[TIM_DMA_ID_CC3]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt;
-
-      /* Set the DMA error callback */
-      htim->hdma[TIM_DMA_ID_CC3]->XferErrorCallback = TIM_DMAErrorCCxN ;
-
-      /* Enable the DMA channel */
-      if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC3], (uint32_t)pData, (uint32_t)&htim->Instance->CCR3,
-                           Length) != HAL_OK)
-      {
-        /* Return error status */
-        return HAL_ERROR;
-      }
-      /* Enable the TIM Output Compare DMA request */
-      __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC3);
-      break;
-    }
-
-    default:
-      status = HAL_ERROR;
-      break;
-  }
-
-  if (status == HAL_OK)
-  {
-    /* Enable the Capture compare channel N */
-    TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_ENABLE);
-
-    /* Enable the Main Output */
-    __HAL_TIM_MOE_ENABLE(htim);
-
-    /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */
-    if (IS_TIM_SLAVE_INSTANCE(htim->Instance))
-    {
-      tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS;
-      if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr))
-      {
-        __HAL_TIM_ENABLE(htim);
-      }
-    }
-    else
-    {
-      __HAL_TIM_ENABLE(htim);
-    }
-  }
-
-  /* Return function status */
-  return status;
-}
-
-/**
-  * @brief  Stops the TIM Output Compare signal generation in DMA mode
-  *         on the complementary output.
-  * @param  htim TIM Output Compare handle
-  * @param  Channel TIM Channel to be disabled
-  *          This parameter can be one of the following values:
-  *            @arg TIM_CHANNEL_1: TIM Channel 1 selected
-  *            @arg TIM_CHANNEL_2: TIM Channel 2 selected
-  *            @arg TIM_CHANNEL_3: TIM Channel 3 selected
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_TIMEx_OCN_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel)
-{
-  HAL_StatusTypeDef status = HAL_OK;
-
-  /* Check the parameters */
-  assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel));
-
-  switch (Channel)
-  {
-    case TIM_CHANNEL_1:
-    {
-      /* Disable the TIM Output Compare DMA request */
-      __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC1);
-      (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC1]);
-      break;
-    }
-
-    case TIM_CHANNEL_2:
-    {
-      /* Disable the TIM Output Compare DMA request */
-      __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC2);
-      (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC2]);
-      break;
-    }
-
-    case TIM_CHANNEL_3:
-    {
-      /* Disable the TIM Output Compare DMA request */
-      __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC3);
-      (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC3]);
-      break;
-    }
-
-    default:
-      status = HAL_ERROR;
-      break;
-  }
-
-  if (status == HAL_OK)
-  {
-    /* Disable the Capture compare channel N */
-    TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_DISABLE);
-
-    /* Disable the Main Output */
-    __HAL_TIM_MOE_DISABLE(htim);
-
-    /* Disable the Peripheral */
-    __HAL_TIM_DISABLE(htim);
-
-    /* Set the TIM complementary channel state */
-    TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_READY);
-  }
-
-  /* Return function status */
-  return status;
-}
-
-/**
-  * @}
-  */
-
-/** @defgroup TIMEx_Exported_Functions_Group3 Extended Timer Complementary PWM functions
-  * @brief    Timer Complementary PWM functions
-  *
-@verbatim
-  ==============================================================================
-                 ##### Timer Complementary PWM functions #####
-  ==============================================================================
-  [..]
-    This section provides functions allowing to:
-    (+) Start the Complementary PWM.
-    (+) Stop the Complementary PWM.
-    (+) Start the Complementary PWM and enable interrupts.
-    (+) Stop the Complementary PWM and disable interrupts.
-    (+) Start the Complementary PWM and enable DMA transfers.
-    (+) Stop the Complementary PWM and disable DMA transfers.
-    (+) Start the Complementary Input Capture measurement.
-    (+) Stop the Complementary Input Capture.
-    (+) Start the Complementary Input Capture and enable interrupts.
-    (+) Stop the Complementary Input Capture and disable interrupts.
-    (+) Start the Complementary Input Capture and enable DMA transfers.
-    (+) Stop the Complementary Input Capture and disable DMA transfers.
-    (+) Start the Complementary One Pulse generation.
-    (+) Stop the Complementary One Pulse.
-    (+) Start the Complementary One Pulse and enable interrupts.
-    (+) Stop the Complementary One Pulse and disable interrupts.
-
-@endverbatim
-  * @{
-  */
-
-/**
-  * @brief  Starts the PWM signal generation on the complementary output.
-  * @param  htim TIM handle
-  * @param  Channel TIM Channel to be enabled
-  *          This parameter can be one of the following values:
-  *            @arg TIM_CHANNEL_1: TIM Channel 1 selected
-  *            @arg TIM_CHANNEL_2: TIM Channel 2 selected
-  *            @arg TIM_CHANNEL_3: TIM Channel 3 selected
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_TIMEx_PWMN_Start(TIM_HandleTypeDef *htim, uint32_t Channel)
-{
-  uint32_t tmpsmcr;
-
-  /* Check the parameters */
-  assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel));
-
-  /* Check the TIM complementary channel state */
-  if (TIM_CHANNEL_N_STATE_GET(htim, Channel) != HAL_TIM_CHANNEL_STATE_READY)
-  {
-    return HAL_ERROR;
-  }
-
-  /* Set the TIM complementary channel state */
-  TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_BUSY);
-
-  /* Enable the complementary PWM output  */
-  TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_ENABLE);
-
-  /* Enable the Main Output */
-  __HAL_TIM_MOE_ENABLE(htim);
-
-  /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */
-  if (IS_TIM_SLAVE_INSTANCE(htim->Instance))
-  {
-    tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS;
-    if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr))
-    {
-      __HAL_TIM_ENABLE(htim);
-    }
-  }
-  else
-  {
-    __HAL_TIM_ENABLE(htim);
-  }
-
-  /* Return function status */
-  return HAL_OK;
-}
-
-/**
-  * @brief  Stops the PWM signal generation on the complementary output.
-  * @param  htim TIM handle
-  * @param  Channel TIM Channel to be disabled
-  *          This parameter can be one of the following values:
-  *            @arg TIM_CHANNEL_1: TIM Channel 1 selected
-  *            @arg TIM_CHANNEL_2: TIM Channel 2 selected
-  *            @arg TIM_CHANNEL_3: TIM Channel 3 selected
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_TIMEx_PWMN_Stop(TIM_HandleTypeDef *htim, uint32_t Channel)
-{
-  /* Check the parameters */
-  assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel));
-
-  /* Disable the complementary PWM output  */
-  TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_DISABLE);
-
-  /* Disable the Main Output */
-  __HAL_TIM_MOE_DISABLE(htim);
-
-  /* Disable the Peripheral */
-  __HAL_TIM_DISABLE(htim);
-
-  /* Set the TIM complementary channel state */
-  TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_READY);
-
-  /* Return function status */
-  return HAL_OK;
-}
-
-/**
-  * @brief  Starts the PWM signal generation in interrupt mode on the
-  *         complementary output.
-  * @param  htim TIM handle
-  * @param  Channel TIM Channel to be disabled
-  *          This parameter can be one of the following values:
-  *            @arg TIM_CHANNEL_1: TIM Channel 1 selected
-  *            @arg TIM_CHANNEL_2: TIM Channel 2 selected
-  *            @arg TIM_CHANNEL_3: TIM Channel 3 selected
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_TIMEx_PWMN_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel)
-{
-  HAL_StatusTypeDef status = HAL_OK;
-  uint32_t tmpsmcr;
-
-  /* Check the parameters */
-  assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel));
-
-  /* Check the TIM complementary channel state */
-  if (TIM_CHANNEL_N_STATE_GET(htim, Channel) != HAL_TIM_CHANNEL_STATE_READY)
-  {
-    return HAL_ERROR;
-  }
-
-  /* Set the TIM complementary channel state */
-  TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_BUSY);
-
-  switch (Channel)
-  {
-    case TIM_CHANNEL_1:
-    {
-      /* Enable the TIM Capture/Compare 1 interrupt */
-      __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC1);
-      break;
-    }
-
-    case TIM_CHANNEL_2:
-    {
-      /* Enable the TIM Capture/Compare 2 interrupt */
-      __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC2);
-      break;
-    }
-
-    case TIM_CHANNEL_3:
-    {
-      /* Enable the TIM Capture/Compare 3 interrupt */
-      __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC3);
-      break;
-    }
-
-    default:
-      status = HAL_ERROR;
-      break;
-  }
-
-  if (status == HAL_OK)
-  {
-    /* Enable the TIM Break interrupt */
-    __HAL_TIM_ENABLE_IT(htim, TIM_IT_BREAK);
-
-    /* Enable the complementary PWM output  */
-    TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_ENABLE);
-
-    /* Enable the Main Output */
-    __HAL_TIM_MOE_ENABLE(htim);
-
-    /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */
-    if (IS_TIM_SLAVE_INSTANCE(htim->Instance))
-    {
-      tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS;
-      if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr))
-      {
-        __HAL_TIM_ENABLE(htim);
-      }
-    }
-    else
-    {
-      __HAL_TIM_ENABLE(htim);
-    }
-  }
-
-  /* Return function status */
-  return status;
-}
-
-/**
-  * @brief  Stops the PWM signal generation in interrupt mode on the
-  *         complementary output.
-  * @param  htim TIM handle
-  * @param  Channel TIM Channel to be disabled
-  *          This parameter can be one of the following values:
-  *            @arg TIM_CHANNEL_1: TIM Channel 1 selected
-  *            @arg TIM_CHANNEL_2: TIM Channel 2 selected
-  *            @arg TIM_CHANNEL_3: TIM Channel 3 selected
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_TIMEx_PWMN_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel)
-{
-  HAL_StatusTypeDef status = HAL_OK;
-  uint32_t tmpccer;
-
-  /* Check the parameters */
-  assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel));
-
-  switch (Channel)
-  {
-    case TIM_CHANNEL_1:
-    {
-      /* Disable the TIM Capture/Compare 1 interrupt */
-      __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC1);
-      break;
-    }
-
-    case TIM_CHANNEL_2:
-    {
-      /* Disable the TIM Capture/Compare 2 interrupt */
-      __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC2);
-      break;
-    }
-
-    case TIM_CHANNEL_3:
-    {
-      /* Disable the TIM Capture/Compare 3 interrupt */
-      __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC3);
-      break;
-    }
-
-    default:
-      status = HAL_ERROR;
-      break;
-  }
-
-  if (status == HAL_OK)
-  {
-    /* Disable the complementary PWM output  */
-    TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_DISABLE);
-
-    /* Disable the TIM Break interrupt (only if no more channel is active) */
-    tmpccer = htim->Instance->CCER;
-    if ((tmpccer & (TIM_CCER_CC1NE | TIM_CCER_CC2NE | TIM_CCER_CC3NE)) == (uint32_t)RESET)
-    {
-      __HAL_TIM_DISABLE_IT(htim, TIM_IT_BREAK);
-    }
-
-    /* Disable the Main Output */
-    __HAL_TIM_MOE_DISABLE(htim);
-
-    /* Disable the Peripheral */
-    __HAL_TIM_DISABLE(htim);
-
-    /* Set the TIM complementary channel state */
-    TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_READY);
-  }
-
-  /* Return function status */
-  return status;
-}
-
-/**
-  * @brief  Starts the TIM PWM signal generation in DMA mode on the
-  *         complementary output
-  * @param  htim TIM handle
-  * @param  Channel TIM Channel to be enabled
-  *          This parameter can be one of the following values:
-  *            @arg TIM_CHANNEL_1: TIM Channel 1 selected
-  *            @arg TIM_CHANNEL_2: TIM Channel 2 selected
-  *            @arg TIM_CHANNEL_3: TIM Channel 3 selected
-  * @param  pData The source Buffer address.
-  * @param  Length The length of data to be transferred from memory to TIM peripheral
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_TIMEx_PWMN_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, const uint32_t *pData,
-                                           uint16_t Length)
-{
-  HAL_StatusTypeDef status = HAL_OK;
-  uint32_t tmpsmcr;
-
-  /* Check the parameters */
-  assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel));
-
-  /* Set the TIM complementary channel state */
-  if (TIM_CHANNEL_N_STATE_GET(htim, Channel) == HAL_TIM_CHANNEL_STATE_BUSY)
-  {
-    return HAL_BUSY;
-  }
-  else if (TIM_CHANNEL_N_STATE_GET(htim, Channel) == HAL_TIM_CHANNEL_STATE_READY)
-  {
-    if ((pData == NULL) || (Length == 0U))
-    {
-      return HAL_ERROR;
-    }
-    else
-    {
-      TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_BUSY);
-    }
-  }
-  else
-  {
-    return HAL_ERROR;
-  }
-
-  switch (Channel)
-  {
-    case TIM_CHANNEL_1:
-    {
-      /* Set the DMA compare callbacks */
-      htim->hdma[TIM_DMA_ID_CC1]->XferCpltCallback = TIM_DMADelayPulseNCplt;
-      htim->hdma[TIM_DMA_ID_CC1]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt;
-
-      /* Set the DMA error callback */
-      htim->hdma[TIM_DMA_ID_CC1]->XferErrorCallback = TIM_DMAErrorCCxN ;
-
-      /* Enable the DMA channel */
-      if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC1], (uint32_t)pData, (uint32_t)&htim->Instance->CCR1,
-                           Length) != HAL_OK)
-      {
-        /* Return error status */
-        return HAL_ERROR;
-      }
-      /* Enable the TIM Capture/Compare 1 DMA request */
-      __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC1);
-      break;
-    }
-
-    case TIM_CHANNEL_2:
-    {
-      /* Set the DMA compare callbacks */
-      htim->hdma[TIM_DMA_ID_CC2]->XferCpltCallback = TIM_DMADelayPulseNCplt;
-      htim->hdma[TIM_DMA_ID_CC2]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt;
-
-      /* Set the DMA error callback */
-      htim->hdma[TIM_DMA_ID_CC2]->XferErrorCallback = TIM_DMAErrorCCxN ;
-
-      /* Enable the DMA channel */
-      if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC2], (uint32_t)pData, (uint32_t)&htim->Instance->CCR2,
-                           Length) != HAL_OK)
-      {
-        /* Return error status */
-        return HAL_ERROR;
-      }
-      /* Enable the TIM Capture/Compare 2 DMA request */
-      __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC2);
-      break;
-    }
-
-    case TIM_CHANNEL_3:
-    {
-      /* Set the DMA compare callbacks */
-      htim->hdma[TIM_DMA_ID_CC3]->XferCpltCallback = TIM_DMADelayPulseNCplt;
-      htim->hdma[TIM_DMA_ID_CC3]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt;
-
-      /* Set the DMA error callback */
-      htim->hdma[TIM_DMA_ID_CC3]->XferErrorCallback = TIM_DMAErrorCCxN ;
-
-      /* Enable the DMA channel */
-      if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC3], (uint32_t)pData, (uint32_t)&htim->Instance->CCR3,
-                           Length) != HAL_OK)
-      {
-        /* Return error status */
-        return HAL_ERROR;
-      }
-      /* Enable the TIM Capture/Compare 3 DMA request */
-      __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC3);
-      break;
-    }
-
-    default:
-      status = HAL_ERROR;
-      break;
-  }
-
-  if (status == HAL_OK)
-  {
-    /* Enable the complementary PWM output  */
-    TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_ENABLE);
-
-    /* Enable the Main Output */
-    __HAL_TIM_MOE_ENABLE(htim);
-
-    /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */
-    if (IS_TIM_SLAVE_INSTANCE(htim->Instance))
-    {
-      tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS;
-      if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr))
-      {
-        __HAL_TIM_ENABLE(htim);
-      }
-    }
-    else
-    {
-      __HAL_TIM_ENABLE(htim);
-    }
-  }
-
-  /* Return function status */
-  return status;
-}
-
-/**
-  * @brief  Stops the TIM PWM signal generation in DMA mode on the complementary
-  *         output
-  * @param  htim TIM handle
-  * @param  Channel TIM Channel to be disabled
-  *          This parameter can be one of the following values:
-  *            @arg TIM_CHANNEL_1: TIM Channel 1 selected
-  *            @arg TIM_CHANNEL_2: TIM Channel 2 selected
-  *            @arg TIM_CHANNEL_3: TIM Channel 3 selected
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_TIMEx_PWMN_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel)
-{
-  HAL_StatusTypeDef status = HAL_OK;
-
-  /* Check the parameters */
-  assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel));
-
-  switch (Channel)
-  {
-    case TIM_CHANNEL_1:
-    {
-      /* Disable the TIM Capture/Compare 1 DMA request */
-      __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC1);
-      (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC1]);
-      break;
-    }
-
-    case TIM_CHANNEL_2:
-    {
-      /* Disable the TIM Capture/Compare 2 DMA request */
-      __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC2);
-      (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC2]);
-      break;
-    }
-
-    case TIM_CHANNEL_3:
-    {
-      /* Disable the TIM Capture/Compare 3 DMA request */
-      __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC3);
-      (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC3]);
-      break;
-    }
-
-    default:
-      status = HAL_ERROR;
-      break;
-  }
-
-  if (status == HAL_OK)
-  {
-    /* Disable the complementary PWM output */
-    TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_DISABLE);
-
-    /* Disable the Main Output */
-    __HAL_TIM_MOE_DISABLE(htim);
-
-    /* Disable the Peripheral */
-    __HAL_TIM_DISABLE(htim);
-
-    /* Set the TIM complementary channel state */
-    TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_READY);
-  }
-
-  /* Return function status */
-  return status;
-}
-
-/**
-  * @}
-  */
-
-/** @defgroup TIMEx_Exported_Functions_Group4 Extended Timer Complementary One Pulse functions
-  * @brief    Timer Complementary One Pulse functions
-  *
-@verbatim
-  ==============================================================================
-                ##### Timer Complementary One Pulse functions #####
-  ==============================================================================
-  [..]
-    This section provides functions allowing to:
-    (+) Start the Complementary One Pulse generation.
-    (+) Stop the Complementary One Pulse.
-    (+) Start the Complementary One Pulse and enable interrupts.
-    (+) Stop the Complementary One Pulse and disable interrupts.
-
-@endverbatim
-  * @{
-  */
-
-/**
-  * @brief  Starts the TIM One Pulse signal generation on the complementary
-  *         output.
-  * @note OutputChannel must match the pulse output channel chosen when calling
-  *       @ref HAL_TIM_OnePulse_ConfigChannel().
-  * @param  htim TIM One Pulse handle
-  * @param  OutputChannel pulse output channel to enable
-  *          This parameter can be one of the following values:
-  *            @arg TIM_CHANNEL_1: TIM Channel 1 selected
-  *            @arg TIM_CHANNEL_2: TIM Channel 2 selected
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_TIMEx_OnePulseN_Start(TIM_HandleTypeDef *htim, uint32_t OutputChannel)
-{
-  uint32_t input_channel = (OutputChannel == TIM_CHANNEL_1) ? TIM_CHANNEL_2 : TIM_CHANNEL_1;
-  HAL_TIM_ChannelStateTypeDef channel_1_state = TIM_CHANNEL_STATE_GET(htim, TIM_CHANNEL_1);
-  HAL_TIM_ChannelStateTypeDef channel_2_state = TIM_CHANNEL_STATE_GET(htim, TIM_CHANNEL_2);
-  HAL_TIM_ChannelStateTypeDef complementary_channel_1_state = TIM_CHANNEL_N_STATE_GET(htim, TIM_CHANNEL_1);
-  HAL_TIM_ChannelStateTypeDef complementary_channel_2_state = TIM_CHANNEL_N_STATE_GET(htim, TIM_CHANNEL_2);
-
-  /* Check the parameters */
-  assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, OutputChannel));
-
-  /* Check the TIM channels state */
-  if ((channel_1_state != HAL_TIM_CHANNEL_STATE_READY)
-      || (channel_2_state != HAL_TIM_CHANNEL_STATE_READY)
-      || (complementary_channel_1_state != HAL_TIM_CHANNEL_STATE_READY)
-      || (complementary_channel_2_state != HAL_TIM_CHANNEL_STATE_READY))
-  {
-    return HAL_ERROR;
-  }
-
-  /* Set the TIM channels state */
-  TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY);
-  TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY);
-  TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY);
-  TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY);
-
-  /* Enable the complementary One Pulse output channel and the Input Capture channel */
-  TIM_CCxNChannelCmd(htim->Instance, OutputChannel, TIM_CCxN_ENABLE);
-  TIM_CCxChannelCmd(htim->Instance, input_channel, TIM_CCx_ENABLE);
-
-  /* Enable the Main Output */
-  __HAL_TIM_MOE_ENABLE(htim);
-
-  /* Return function status */
-  return HAL_OK;
-}
-
-/**
-  * @brief  Stops the TIM One Pulse signal generation on the complementary
-  *         output.
-  * @note OutputChannel must match the pulse output channel chosen when calling
-  *       @ref HAL_TIM_OnePulse_ConfigChannel().
-  * @param  htim TIM One Pulse handle
-  * @param  OutputChannel pulse output channel to disable
-  *          This parameter can be one of the following values:
-  *            @arg TIM_CHANNEL_1: TIM Channel 1 selected
-  *            @arg TIM_CHANNEL_2: TIM Channel 2 selected
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_TIMEx_OnePulseN_Stop(TIM_HandleTypeDef *htim, uint32_t OutputChannel)
-{
-  uint32_t input_channel = (OutputChannel == TIM_CHANNEL_1) ? TIM_CHANNEL_2 : TIM_CHANNEL_1;
-
-  /* Check the parameters */
-  assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, OutputChannel));
-
-  /* Disable the complementary One Pulse output channel and the Input Capture channel */
-  TIM_CCxNChannelCmd(htim->Instance, OutputChannel, TIM_CCxN_DISABLE);
-  TIM_CCxChannelCmd(htim->Instance, input_channel, TIM_CCx_DISABLE);
-
-  /* Disable the Main Output */
-  __HAL_TIM_MOE_DISABLE(htim);
-
-  /* Disable the Peripheral */
-  __HAL_TIM_DISABLE(htim);
-
-  /* Set the TIM  channels state */
-  TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY);
-  TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY);
-  TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY);
-  TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY);
-
-  /* Return function status */
-  return HAL_OK;
-}
-
-/**
-  * @brief  Starts the TIM One Pulse signal generation in interrupt mode on the
-  *         complementary channel.
-  * @note OutputChannel must match the pulse output channel chosen when calling
-  *       @ref HAL_TIM_OnePulse_ConfigChannel().
-  * @param  htim TIM One Pulse handle
-  * @param  OutputChannel pulse output channel to enable
-  *          This parameter can be one of the following values:
-  *            @arg TIM_CHANNEL_1: TIM Channel 1 selected
-  *            @arg TIM_CHANNEL_2: TIM Channel 2 selected
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_TIMEx_OnePulseN_Start_IT(TIM_HandleTypeDef *htim, uint32_t OutputChannel)
-{
-  uint32_t input_channel = (OutputChannel == TIM_CHANNEL_1) ? TIM_CHANNEL_2 : TIM_CHANNEL_1;
-  HAL_TIM_ChannelStateTypeDef channel_1_state = TIM_CHANNEL_STATE_GET(htim, TIM_CHANNEL_1);
-  HAL_TIM_ChannelStateTypeDef channel_2_state = TIM_CHANNEL_STATE_GET(htim, TIM_CHANNEL_2);
-  HAL_TIM_ChannelStateTypeDef complementary_channel_1_state = TIM_CHANNEL_N_STATE_GET(htim, TIM_CHANNEL_1);
-  HAL_TIM_ChannelStateTypeDef complementary_channel_2_state = TIM_CHANNEL_N_STATE_GET(htim, TIM_CHANNEL_2);
-
-  /* Check the parameters */
-  assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, OutputChannel));
-
-  /* Check the TIM channels state */
-  if ((channel_1_state != HAL_TIM_CHANNEL_STATE_READY)
-      || (channel_2_state != HAL_TIM_CHANNEL_STATE_READY)
-      || (complementary_channel_1_state != HAL_TIM_CHANNEL_STATE_READY)
-      || (complementary_channel_2_state != HAL_TIM_CHANNEL_STATE_READY))
-  {
-    return HAL_ERROR;
-  }
-
-  /* Set the TIM channels state */
-  TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY);
-  TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY);
-  TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY);
-  TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY);
-
-  /* Enable the TIM Capture/Compare 1 interrupt */
-  __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC1);
-
-  /* Enable the TIM Capture/Compare 2 interrupt */
-  __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC2);
-
-  /* Enable the complementary One Pulse output channel and the Input Capture channel */
-  TIM_CCxNChannelCmd(htim->Instance, OutputChannel, TIM_CCxN_ENABLE);
-  TIM_CCxChannelCmd(htim->Instance, input_channel, TIM_CCx_ENABLE);
-
-  /* Enable the Main Output */
-  __HAL_TIM_MOE_ENABLE(htim);
-
-  /* Return function status */
-  return HAL_OK;
-}
-
-/**
-  * @brief  Stops the TIM One Pulse signal generation in interrupt mode on the
-  *         complementary channel.
-  * @note OutputChannel must match the pulse output channel chosen when calling
-  *       @ref HAL_TIM_OnePulse_ConfigChannel().
-  * @param  htim TIM One Pulse handle
-  * @param  OutputChannel pulse output channel to disable
-  *          This parameter can be one of the following values:
-  *            @arg TIM_CHANNEL_1: TIM Channel 1 selected
-  *            @arg TIM_CHANNEL_2: TIM Channel 2 selected
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_TIMEx_OnePulseN_Stop_IT(TIM_HandleTypeDef *htim, uint32_t OutputChannel)
-{
-  uint32_t input_channel = (OutputChannel == TIM_CHANNEL_1) ? TIM_CHANNEL_2 : TIM_CHANNEL_1;
-
-  /* Check the parameters */
-  assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, OutputChannel));
-
-  /* Disable the TIM Capture/Compare 1 interrupt */
-  __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC1);
-
-  /* Disable the TIM Capture/Compare 2 interrupt */
-  __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC2);
-
-  /* Disable the complementary One Pulse output channel and the Input Capture channel */
-  TIM_CCxNChannelCmd(htim->Instance, OutputChannel, TIM_CCxN_DISABLE);
-  TIM_CCxChannelCmd(htim->Instance, input_channel, TIM_CCx_DISABLE);
-
-  /* Disable the Main Output */
-  __HAL_TIM_MOE_DISABLE(htim);
-
-  /* Disable the Peripheral */
-  __HAL_TIM_DISABLE(htim);
-
-  /* Set the TIM  channels state */
-  TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY);
-  TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY);
-  TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY);
-  TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY);
-
-  /* Return function status */
-  return HAL_OK;
-}
-
-/**
-  * @}
-  */
-
-/** @defgroup TIMEx_Exported_Functions_Group5 Extended Peripheral Control functions
-  * @brief    Peripheral Control functions
-  *
-@verbatim
-  ==============================================================================
-                    ##### Peripheral Control functions #####
-  ==============================================================================
-  [..]
-    This section provides functions allowing to:
-      (+) Configure the commutation event in case of use of the Hall sensor interface.
-      (+) Configure Output channels for OC and PWM mode.
-
-      (+) Configure Complementary channels, break features and dead time.
-      (+) Configure Master synchronization.
-      (+) Configure timer remapping capabilities.
-      (+) Enable or disable channel grouping.
-
-@endverbatim
-  * @{
-  */
-
-/**
-  * @brief  Configure the TIM commutation event sequence.
-  * @note  This function is mandatory to use the commutation event in order to
-  *        update the configuration at each commutation detection on the TRGI input of the Timer,
-  *        the typical use of this feature is with the use of another Timer(interface Timer)
-  *        configured in Hall sensor interface, this interface Timer will generate the
-  *        commutation at its TRGO output (connected to Timer used in this function) each time
-  *        the TI1 of the Interface Timer detect a commutation at its input TI1.
-  * @param  htim TIM handle
-  * @param  InputTrigger the Internal trigger corresponding to the Timer Interfacing with the Hall sensor
-  *          This parameter can be one of the following values:
-  *            @arg TIM_TS_ITR0: Internal trigger 0 selected
-  *            @arg TIM_TS_ITR1: Internal trigger 1 selected
-  *            @arg TIM_TS_ITR2: Internal trigger 2 selected
-  *            @arg TIM_TS_ITR3: Internal trigger 3 selected
-  *            @arg TIM_TS_NONE: No trigger is needed
-  * @param  CommutationSource the Commutation Event source
-  *          This parameter can be one of the following values:
-  *            @arg TIM_COMMUTATION_TRGI: Commutation source is the TRGI of the Interface Timer
-  *            @arg TIM_COMMUTATION_SOFTWARE:  Commutation source is set by software using the COMG bit
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_TIMEx_ConfigCommutEvent(TIM_HandleTypeDef *htim, uint32_t  InputTrigger,
-                                              uint32_t  CommutationSource)
-{
-  /* Check the parameters */
-  assert_param(IS_TIM_COMMUTATION_EVENT_INSTANCE(htim->Instance));
-  assert_param(IS_TIM_INTERNAL_TRIGGEREVENT_SELECTION(InputTrigger));
-
-  __HAL_LOCK(htim);
-
-  if ((InputTrigger == TIM_TS_ITR0) || (InputTrigger == TIM_TS_ITR1) ||
-      (InputTrigger == TIM_TS_ITR2) || (InputTrigger == TIM_TS_ITR3))
-  {
-    /* Select the Input trigger */
-    htim->Instance->SMCR &= ~TIM_SMCR_TS;
-    htim->Instance->SMCR |= InputTrigger;
-  }
-
-  /* Select the Capture Compare preload feature */
-  htim->Instance->CR2 |= TIM_CR2_CCPC;
-  /* Select the Commutation event source */
-  htim->Instance->CR2 &= ~TIM_CR2_CCUS;
-  htim->Instance->CR2 |= CommutationSource;
-
-  /* Disable Commutation Interrupt */
-  __HAL_TIM_DISABLE_IT(htim, TIM_IT_COM);
-
-  /* Disable Commutation DMA request */
-  __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_COM);
-
-  __HAL_UNLOCK(htim);
-
-  return HAL_OK;
-}
-
-/**
-  * @brief  Configure the TIM commutation event sequence with interrupt.
-  * @note  This function is mandatory to use the commutation event in order to
-  *        update the configuration at each commutation detection on the TRGI input of the Timer,
-  *        the typical use of this feature is with the use of another Timer(interface Timer)
-  *        configured in Hall sensor interface, this interface Timer will generate the
-  *        commutation at its TRGO output (connected to Timer used in this function) each time
-  *        the TI1 of the Interface Timer detect a commutation at its input TI1.
-  * @param  htim TIM handle
-  * @param  InputTrigger the Internal trigger corresponding to the Timer Interfacing with the Hall sensor
-  *          This parameter can be one of the following values:
-  *            @arg TIM_TS_ITR0: Internal trigger 0 selected
-  *            @arg TIM_TS_ITR1: Internal trigger 1 selected
-  *            @arg TIM_TS_ITR2: Internal trigger 2 selected
-  *            @arg TIM_TS_ITR3: Internal trigger 3 selected
-  *            @arg TIM_TS_NONE: No trigger is needed
-  * @param  CommutationSource the Commutation Event source
-  *          This parameter can be one of the following values:
-  *            @arg TIM_COMMUTATION_TRGI: Commutation source is the TRGI of the Interface Timer
-  *            @arg TIM_COMMUTATION_SOFTWARE:  Commutation source is set by software using the COMG bit
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_TIMEx_ConfigCommutEvent_IT(TIM_HandleTypeDef *htim, uint32_t  InputTrigger,
-                                                 uint32_t  CommutationSource)
-{
-  /* Check the parameters */
-  assert_param(IS_TIM_COMMUTATION_EVENT_INSTANCE(htim->Instance));
-  assert_param(IS_TIM_INTERNAL_TRIGGEREVENT_SELECTION(InputTrigger));
-
-  __HAL_LOCK(htim);
-
-  if ((InputTrigger == TIM_TS_ITR0) || (InputTrigger == TIM_TS_ITR1) ||
-      (InputTrigger == TIM_TS_ITR2) || (InputTrigger == TIM_TS_ITR3))
-  {
-    /* Select the Input trigger */
-    htim->Instance->SMCR &= ~TIM_SMCR_TS;
-    htim->Instance->SMCR |= InputTrigger;
-  }
-
-  /* Select the Capture Compare preload feature */
-  htim->Instance->CR2 |= TIM_CR2_CCPC;
-  /* Select the Commutation event source */
-  htim->Instance->CR2 &= ~TIM_CR2_CCUS;
-  htim->Instance->CR2 |= CommutationSource;
-
-  /* Disable Commutation DMA request */
-  __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_COM);
-
-  /* Enable the Commutation Interrupt */
-  __HAL_TIM_ENABLE_IT(htim, TIM_IT_COM);
-
-  __HAL_UNLOCK(htim);
-
-  return HAL_OK;
-}
-
-/**
-  * @brief  Configure the TIM commutation event sequence with DMA.
-  * @note  This function is mandatory to use the commutation event in order to
-  *        update the configuration at each commutation detection on the TRGI input of the Timer,
-  *        the typical use of this feature is with the use of another Timer(interface Timer)
-  *        configured in Hall sensor interface, this interface Timer will generate the
-  *        commutation at its TRGO output (connected to Timer used in this function) each time
-  *        the TI1 of the Interface Timer detect a commutation at its input TI1.
-  * @note  The user should configure the DMA in his own software, in This function only the COMDE bit is set
-  * @param  htim TIM handle
-  * @param  InputTrigger the Internal trigger corresponding to the Timer Interfacing with the Hall sensor
-  *          This parameter can be one of the following values:
-  *            @arg TIM_TS_ITR0: Internal trigger 0 selected
-  *            @arg TIM_TS_ITR1: Internal trigger 1 selected
-  *            @arg TIM_TS_ITR2: Internal trigger 2 selected
-  *            @arg TIM_TS_ITR3: Internal trigger 3 selected
-  *            @arg TIM_TS_NONE: No trigger is needed
-  * @param  CommutationSource the Commutation Event source
-  *          This parameter can be one of the following values:
-  *            @arg TIM_COMMUTATION_TRGI: Commutation source is the TRGI of the Interface Timer
-  *            @arg TIM_COMMUTATION_SOFTWARE:  Commutation source is set by software using the COMG bit
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_TIMEx_ConfigCommutEvent_DMA(TIM_HandleTypeDef *htim, uint32_t  InputTrigger,
-                                                  uint32_t  CommutationSource)
-{
-  /* Check the parameters */
-  assert_param(IS_TIM_COMMUTATION_EVENT_INSTANCE(htim->Instance));
-  assert_param(IS_TIM_INTERNAL_TRIGGEREVENT_SELECTION(InputTrigger));
-
-  __HAL_LOCK(htim);
-
-  if ((InputTrigger == TIM_TS_ITR0) || (InputTrigger == TIM_TS_ITR1) ||
-      (InputTrigger == TIM_TS_ITR2) || (InputTrigger == TIM_TS_ITR3))
-  {
-    /* Select the Input trigger */
-    htim->Instance->SMCR &= ~TIM_SMCR_TS;
-    htim->Instance->SMCR |= InputTrigger;
-  }
-
-  /* Select the Capture Compare preload feature */
-  htim->Instance->CR2 |= TIM_CR2_CCPC;
-  /* Select the Commutation event source */
-  htim->Instance->CR2 &= ~TIM_CR2_CCUS;
-  htim->Instance->CR2 |= CommutationSource;
-
-  /* Enable the Commutation DMA Request */
-  /* Set the DMA Commutation Callback */
-  htim->hdma[TIM_DMA_ID_COMMUTATION]->XferCpltCallback = TIMEx_DMACommutationCplt;
-  htim->hdma[TIM_DMA_ID_COMMUTATION]->XferHalfCpltCallback = TIMEx_DMACommutationHalfCplt;
-  /* Set the DMA error callback */
-  htim->hdma[TIM_DMA_ID_COMMUTATION]->XferErrorCallback = TIM_DMAError;
-
-  /* Disable Commutation Interrupt */
-  __HAL_TIM_DISABLE_IT(htim, TIM_IT_COM);
-
-  /* Enable the Commutation DMA Request */
-  __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_COM);
-
-  __HAL_UNLOCK(htim);
-
-  return HAL_OK;
-}
-
-/**
-  * @brief  Configures the TIM in master mode.
-  * @param  htim TIM handle.
-  * @param  sMasterConfig pointer to a TIM_MasterConfigTypeDef structure that
-  *         contains the selected trigger output (TRGO) and the Master/Slave
-  *         mode.
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_TIMEx_MasterConfigSynchronization(TIM_HandleTypeDef *htim,
-                                                        const TIM_MasterConfigTypeDef *sMasterConfig)
-{
-  uint32_t tmpcr2;
-  uint32_t tmpsmcr;
-
-  /* Check the parameters */
-  assert_param(IS_TIM_MASTER_INSTANCE(htim->Instance));
-  assert_param(IS_TIM_TRGO_SOURCE(sMasterConfig->MasterOutputTrigger));
-  assert_param(IS_TIM_MSM_STATE(sMasterConfig->MasterSlaveMode));
-
-  /* Check input state */
-  __HAL_LOCK(htim);
-
-  /* Change the handler state */
-  htim->State = HAL_TIM_STATE_BUSY;
-
-  /* Get the TIMx CR2 register value */
-  tmpcr2 = htim->Instance->CR2;
-
-  /* Get the TIMx SMCR register value */
-  tmpsmcr = htim->Instance->SMCR;
-
-  /* If the timer supports ADC synchronization through TRGO2, set the master mode selection 2 */
-  if (IS_TIM_TRGO2_INSTANCE(htim->Instance))
-  {
-    /* Check the parameters */
-    assert_param(IS_TIM_TRGO2_SOURCE(sMasterConfig->MasterOutputTrigger2));
-
-    /* Clear the MMS2 bits */
-    tmpcr2 &= ~TIM_CR2_MMS2;
-    /* Select the TRGO2 source*/
-    tmpcr2 |= sMasterConfig->MasterOutputTrigger2;
-  }
-
-  /* Reset the MMS Bits */
-  tmpcr2 &= ~TIM_CR2_MMS;
-  /* Select the TRGO source */
-  tmpcr2 |=  sMasterConfig->MasterOutputTrigger;
-
-  /* Update TIMx CR2 */
-  htim->Instance->CR2 = tmpcr2;
-
-  if (IS_TIM_SLAVE_INSTANCE(htim->Instance))
-  {
-    /* Reset the MSM Bit */
-    tmpsmcr &= ~TIM_SMCR_MSM;
-    /* Set master mode */
-    tmpsmcr |= sMasterConfig->MasterSlaveMode;
-
-    /* Update TIMx SMCR */
-    htim->Instance->SMCR = tmpsmcr;
-  }
-
-  /* Change the htim state */
-  htim->State = HAL_TIM_STATE_READY;
-
-  __HAL_UNLOCK(htim);
-
-  return HAL_OK;
-}
-
-/**
-  * @brief  Configures the Break feature, dead time, Lock level, OSSI/OSSR State
-  *         and the AOE(automatic output enable).
-  * @param  htim TIM handle
-  * @param  sBreakDeadTimeConfig pointer to a TIM_ConfigBreakDeadConfigTypeDef structure that
-  *         contains the BDTR Register configuration  information for the TIM peripheral.
-  * @note   Interrupts can be generated when an active level is detected on the
-  *         break input, the break 2 input or the system break input. Break
-  *         interrupt can be enabled by calling the @ref __HAL_TIM_ENABLE_IT macro.
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_TIMEx_ConfigBreakDeadTime(TIM_HandleTypeDef *htim,
-                                                const TIM_BreakDeadTimeConfigTypeDef *sBreakDeadTimeConfig)
-{
-  /* Keep this variable initialized to 0 as it is used to configure BDTR register */
-  uint32_t tmpbdtr = 0U;
-
-  /* Check the parameters */
-  assert_param(IS_TIM_BREAK_INSTANCE(htim->Instance));
-  assert_param(IS_TIM_OSSR_STATE(sBreakDeadTimeConfig->OffStateRunMode));
-  assert_param(IS_TIM_OSSI_STATE(sBreakDeadTimeConfig->OffStateIDLEMode));
-  assert_param(IS_TIM_LOCK_LEVEL(sBreakDeadTimeConfig->LockLevel));
-  assert_param(IS_TIM_DEADTIME(sBreakDeadTimeConfig->DeadTime));
-  assert_param(IS_TIM_BREAK_STATE(sBreakDeadTimeConfig->BreakState));
-  assert_param(IS_TIM_BREAK_POLARITY(sBreakDeadTimeConfig->BreakPolarity));
-  assert_param(IS_TIM_BREAK_FILTER(sBreakDeadTimeConfig->BreakFilter));
-  assert_param(IS_TIM_AUTOMATIC_OUTPUT_STATE(sBreakDeadTimeConfig->AutomaticOutput));
-
-  /* Check input state */
-  __HAL_LOCK(htim);
-
-  /* Set the Lock level, the Break enable Bit and the Polarity, the OSSR State,
-     the OSSI State, the dead time value and the Automatic Output Enable Bit */
-
-  /* Set the BDTR bits */
-  MODIFY_REG(tmpbdtr, TIM_BDTR_DTG, sBreakDeadTimeConfig->DeadTime);
-  MODIFY_REG(tmpbdtr, TIM_BDTR_LOCK, sBreakDeadTimeConfig->LockLevel);
-  MODIFY_REG(tmpbdtr, TIM_BDTR_OSSI, sBreakDeadTimeConfig->OffStateIDLEMode);
-  MODIFY_REG(tmpbdtr, TIM_BDTR_OSSR, sBreakDeadTimeConfig->OffStateRunMode);
-  MODIFY_REG(tmpbdtr, TIM_BDTR_BKE, sBreakDeadTimeConfig->BreakState);
-  MODIFY_REG(tmpbdtr, TIM_BDTR_BKP, sBreakDeadTimeConfig->BreakPolarity);
-  MODIFY_REG(tmpbdtr, TIM_BDTR_AOE, sBreakDeadTimeConfig->AutomaticOutput);
-  MODIFY_REG(tmpbdtr, TIM_BDTR_BKF, (sBreakDeadTimeConfig->BreakFilter << TIM_BDTR_BKF_Pos));
-
-  if (IS_TIM_ADVANCED_INSTANCE(htim->Instance))
-  {
-    /* Check the parameters */
-    assert_param(IS_TIM_BREAK_AFMODE(sBreakDeadTimeConfig->BreakAFMode));
-
-    /* Set BREAK AF mode */
-    MODIFY_REG(tmpbdtr, TIM_BDTR_BKBID, sBreakDeadTimeConfig->BreakAFMode);
-  }
-
-  if (IS_TIM_BKIN2_INSTANCE(htim->Instance))
-  {
-    /* Check the parameters */
-    assert_param(IS_TIM_BREAK2_STATE(sBreakDeadTimeConfig->Break2State));
-    assert_param(IS_TIM_BREAK2_POLARITY(sBreakDeadTimeConfig->Break2Polarity));
-    assert_param(IS_TIM_BREAK_FILTER(sBreakDeadTimeConfig->Break2Filter));
-
-    /* Set the BREAK2 input related BDTR bits */
-    MODIFY_REG(tmpbdtr, TIM_BDTR_BK2F, (sBreakDeadTimeConfig->Break2Filter << TIM_BDTR_BK2F_Pos));
-    MODIFY_REG(tmpbdtr, TIM_BDTR_BK2E, sBreakDeadTimeConfig->Break2State);
-    MODIFY_REG(tmpbdtr, TIM_BDTR_BK2P, sBreakDeadTimeConfig->Break2Polarity);
-
-    if (IS_TIM_ADVANCED_INSTANCE(htim->Instance))
-    {
-      /* Check the parameters */
-      assert_param(IS_TIM_BREAK2_AFMODE(sBreakDeadTimeConfig->Break2AFMode));
-
-      /* Set BREAK2 AF mode */
-      MODIFY_REG(tmpbdtr, TIM_BDTR_BK2BID, sBreakDeadTimeConfig->Break2AFMode);
-    }
-  }
-
-  /* Set TIMx_BDTR */
-  htim->Instance->BDTR = tmpbdtr;
-
-  __HAL_UNLOCK(htim);
-
-  return HAL_OK;
-}
-
-/**
-  * @brief  Configures the break input source.
-  * @param  htim TIM handle.
-  * @param  BreakInput Break input to configure
-  *          This parameter can be one of the following values:
-  *            @arg TIM_BREAKINPUT_BRK: Timer break input
-  *            @arg TIM_BREAKINPUT_BRK2: Timer break 2 input
-  * @param  sBreakInputConfig Break input source configuration
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_TIMEx_ConfigBreakInput(TIM_HandleTypeDef *htim,
-                                             uint32_t BreakInput,
-                                             const TIMEx_BreakInputConfigTypeDef *sBreakInputConfig)
-
-{
-  HAL_StatusTypeDef status = HAL_OK;
-  uint32_t tmporx;
-  uint32_t bkin_enable_mask;
-  uint32_t bkin_polarity_mask;
-  uint32_t bkin_enable_bitpos;
-  uint32_t bkin_polarity_bitpos;
-
-  /* Check the parameters */
-  assert_param(IS_TIM_BREAK_INSTANCE(htim->Instance));
-  assert_param(IS_TIM_BREAKINPUT(BreakInput));
-  assert_param(IS_TIM_BREAKINPUTSOURCE(sBreakInputConfig->Source));
-  assert_param(IS_TIM_BREAKINPUTSOURCE_STATE(sBreakInputConfig->Enable));
-  assert_param(IS_TIM_BREAKINPUTSOURCE_POLARITY(sBreakInputConfig->Polarity));
-
-  /* Check input state */
-  __HAL_LOCK(htim);
-
-  switch (sBreakInputConfig->Source)
-  {
-    case TIM_BREAKINPUTSOURCE_BKIN:
-    {
-      bkin_enable_mask = TIM1_AF1_BKINE;
-      bkin_enable_bitpos = TIM1_AF1_BKINE_Pos;
-      bkin_polarity_mask = TIM1_AF1_BKINP;
-      bkin_polarity_bitpos = TIM1_AF1_BKINP_Pos;
-      break;
-    }
-#if defined(COMP1) && defined(COMP2)
-    case TIM_BREAKINPUTSOURCE_COMP1:
-    {
-      bkin_enable_mask = TIM1_AF1_BKCMP1E;
-      bkin_enable_bitpos = TIM1_AF1_BKCMP1E_Pos;
-      bkin_polarity_mask = TIM1_AF1_BKCMP1P;
-      bkin_polarity_bitpos = TIM1_AF1_BKCMP1P_Pos;
-      break;
-    }
-    case TIM_BREAKINPUTSOURCE_COMP2:
-    {
-      bkin_enable_mask = TIM1_AF1_BKCMP2E;
-      bkin_enable_bitpos = TIM1_AF1_BKCMP2E_Pos;
-      bkin_polarity_mask = TIM1_AF1_BKCMP2P;
-      bkin_polarity_bitpos = TIM1_AF1_BKCMP2P_Pos;
-      break;
-    }
-#endif /* COMP1 && COMP2 */
-
-    default:
-    {
-      bkin_enable_mask = 0U;
-      bkin_polarity_mask = 0U;
-      bkin_enable_bitpos = 0U;
-      bkin_polarity_bitpos = 0U;
-      break;
-    }
-  }
-
-  switch (BreakInput)
-  {
-    case TIM_BREAKINPUT_BRK:
-    {
-      /* Get the TIMx_AF1 register value */
-      tmporx = htim->Instance->AF1;
-
-      /* Enable the break input */
-      tmporx &= ~bkin_enable_mask;
-      tmporx |= (sBreakInputConfig->Enable << bkin_enable_bitpos) & bkin_enable_mask;
-
-      /* Set the break input polarity */
-      tmporx &= ~bkin_polarity_mask;
-      tmporx |= (sBreakInputConfig->Polarity << bkin_polarity_bitpos) & bkin_polarity_mask;
-
-      /* Set TIMx_AF1 */
-      htim->Instance->AF1 = tmporx;
-      break;
-    }
-    case TIM_BREAKINPUT_BRK2:
-    {
-      /* Get the TIMx_AF2 register value */
-      tmporx = htim->Instance->AF2;
-
-      /* Enable the break input */
-      tmporx &= ~bkin_enable_mask;
-      tmporx |= (sBreakInputConfig->Enable << bkin_enable_bitpos) & bkin_enable_mask;
-
-      /* Set the break input polarity */
-      tmporx &= ~bkin_polarity_mask;
-      tmporx |= (sBreakInputConfig->Polarity << bkin_polarity_bitpos) & bkin_polarity_mask;
-
-      /* Set TIMx_AF2 */
-      htim->Instance->AF2 = tmporx;
-      break;
-    }
-    default:
-      status = HAL_ERROR;
-      break;
-  }
-
-  __HAL_UNLOCK(htim);
-
-  return status;
-}
-
-/**
-  * @brief  Configures the TIMx Remapping input capabilities.
-  * @param  htim TIM handle.
-  * @param  Remap specifies the TIM remapping source.
-  *     For TIM1, the parameter is a combination of 2 fields (field1 | field2):
-  *
-  *       field1 can have the following values:
-  *            @arg TIM_TIM1_ETR_ADC1_GPIO:           TIM1_ETR is connected to I/O
-  *            @arg TIM_TIM1_ETR_ADC1_AWD1:           TIM1_ETR is connected to ADC1 AWD1
-  *            @arg TIM_TIM1_ETR_ADC1_AWD2:           TIM1_ETR is connected to ADC1 AWD2 (*)
-  *            @arg TIM_TIM1_ETR_ADC1_AWD3:           TIM1_ETR is connected to ADC1 AWD3 (*)
-  *            @arg TIM_TIM1_ETR_COMP1:               TIM1_ETR is connected to COMP1 output (*)
-  *            @arg TIM_TIM1_ETR_COMP2:               TIM1_ETR is connected to COMP2 output (*)
-  *       field2 can have the following values:
-  *            @arg TIM_TIM1_TI1_GPIO:                TIM1 TI1 is connected to I/O
-  *            @arg TIM_TIM1_TI1_COMP1:               TIM1 TI1 is connected to COMP1 output (*)
-  *
-  *        For TIM2, the parameter is a combination of 3 fields (field1 | field2 | field3):
-  *
-  *       field1 can have the following values:
-  *            @arg TIM_TIM2_ITR1_NONE:               No internal trigger on TIM2_ITR1
-  *            @arg TIM_TIM2_ITR1_USB:                TIM2_ITR1 is connected to USB SOF (*)
-  *
-  *       field2 can have the following values:
-  *            @arg TIM_TIM2_ETR_GPIO:                TIM2_ETR is connected to I/O
-  *            @arg TIM_TIM2_ETR_LSE:                 TIM2_ETR is connected to LSE
-  *            @arg TIM_TIM2_ETR_COMP1:               TIM2_ETR is connected to COMP1 output (*)
-  *            @arg TIM_TIM2_ETR_COMP2:               TIM2_ETR is connected to COMP2 output (*)
-  *
-  *       field3 can have the following values:
-  *            @arg TIM_TIM2_TI4_GPIO:                TIM2 TI4 is connected to I/O
-  *            @arg TIM_TIM2_TI4_COMP1:               TIM2 TI4 is connected to COMP1 output (*)
-  *            @arg TIM_TIM2_TI4_COMP2:               TIM2 TI4 is connected to COMP2 output (*)
-  *            @arg TIM_TIM2_TI4_COMP1_COMP2:         TIM2 TI4 is connected to logical OR between COMP1 and COMP2 output (*)
-  *
-  *     For TIM16, the parameter can have the following values:
-  *            @arg TIM_TIM16_TI1_GPIO:              TIM16 TI1 is connected to I/O
-  *            @arg TIM_TIM16_TI1_LSI:               TIM16 TI1 is connected to LSI
-  *            @arg TIM_TIM16_TI1_LSE:               TIM16 TI1 is connected to LSE
-  *            @arg TIM_TIM16_TI1_RTC:               TIM16 TI1 is connected to RTC wakeup interrupt
-  *
-  *     For TIM17, the parameter can have the following values:
-  *            @arg TIM_TIM17_TI1_GPIO:              TIM17 TI1 is connected to I/O
-  *            @arg TIM_TIM17_TI1_MSI:               TIM17 TI1 is connected to MSI  (constraint: MSI clock < 1/4 TIM APB clock)
-  *            @arg TIM_TIM17_TI1_HSE:               TIM17 TI1 is connected to HSE div 32
-  *            @arg TIM_TIM17_TI1_MCO:               TIM17 TI1 is connected to MCO
-  *
-  *         (*)  Value not defined in all devices.
-  *
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_TIMEx_RemapConfig(TIM_HandleTypeDef *htim, uint32_t Remap)
-{
-  uint32_t tmpor;
-  uint32_t tmpaf1;
-
-  /* Check parameters */
-  assert_param(IS_TIM_REMAP(htim->Instance, Remap));
-
-  __HAL_LOCK(htim);
-
-  /* Read TIMx_OR */
-  tmpor = READ_REG(htim->Instance->OR);
-
-  /* Read TIMx_AF1 */
-  tmpaf1 = READ_REG(htim->Instance->AF1);
-
-  /* Set ETR_SEL bit field (if required) */
-  if (IS_TIM_ETRSEL_INSTANCE(htim->Instance))
-  {
-    if ((Remap & TIM1_AF1_ETRSEL) != (uint32_t)RESET)
-    {
-      /* COMP1 output or COMP2 output connected to ETR input */
-      MODIFY_REG(tmpaf1, TIM1_AF1_ETRSEL, (Remap & TIM1_AF1_ETRSEL));
-    }
-    else
-    {
-      /* ETR legacy mode */
-      MODIFY_REG(tmpaf1, TIM1_AF1_ETRSEL, 0U);
-    }
-
-    /* Set TIMx_AF1 */
-    WRITE_REG(htim->Instance->AF1, tmpaf1);
-  }
-
-  /* Set other remapping capabilities */
-  MODIFY_REG(tmpor, TIM_GET_OR_MASK(htim->Instance), (Remap & (~TIM1_AF1_ETRSEL)));
-
-  /* Set TIMx_OR */
-  WRITE_REG(htim->Instance->OR, tmpor);
-
-  __HAL_UNLOCK(htim);
-
-  return HAL_OK;
-}
-
-/**
-  * @brief  Group channel 5 and channel 1, 2 or 3
-  * @param  htim TIM handle.
-  * @param  Channels specifies the reference signal(s) the OC5REF is combined with.
-  *         This parameter can be any combination of the following values:
-  *         TIM_GROUPCH5_NONE: No effect of OC5REF on OC1REFC, OC2REFC and OC3REFC
-  *         TIM_GROUPCH5_OC1REFC: OC1REFC is the logical AND of OC1REFC and OC5REF
-  *         TIM_GROUPCH5_OC2REFC: OC2REFC is the logical AND of OC2REFC and OC5REF
-  *         TIM_GROUPCH5_OC3REFC: OC3REFC is the logical AND of OC3REFC and OC5REF
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_TIMEx_GroupChannel5(TIM_HandleTypeDef *htim, uint32_t Channels)
-{
-  /* Check parameters */
-  assert_param(IS_TIM_COMBINED3PHASEPWM_INSTANCE(htim->Instance));
-  assert_param(IS_TIM_GROUPCH5(Channels));
-
-  /* Process Locked */
-  __HAL_LOCK(htim);
-
-  htim->State = HAL_TIM_STATE_BUSY;
-
-  /* Clear GC5Cx bit fields */
-  htim->Instance->CCR5 &= ~(TIM_CCR5_GC5C3 | TIM_CCR5_GC5C2 | TIM_CCR5_GC5C1);
-
-  /* Set GC5Cx bit fields */
-  htim->Instance->CCR5 |= Channels;
-
-  /* Change the htim state */
-  htim->State = HAL_TIM_STATE_READY;
-
-  __HAL_UNLOCK(htim);
-
-  return HAL_OK;
-}
-
-/**
-  * @brief  Disarm the designated break input (when it operates in bidirectional mode).
-  * @param  htim TIM handle.
-  * @param  BreakInput Break input to disarm
-  *          This parameter can be one of the following values:
-  *            @arg TIM_BREAKINPUT_BRK: Timer break input
-  *            @arg TIM_BREAKINPUT_BRK2: Timer break 2 input
-  * @note  The break input can be disarmed only when it is configured in
-  *        bidirectional mode and when when MOE is reset.
-  * @note  Purpose is to be able to have the input voltage back to high-state,
-  *        whatever the time constant on the output .
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_TIMEx_DisarmBreakInput(TIM_HandleTypeDef *htim, uint32_t BreakInput)
-{
-  HAL_StatusTypeDef status = HAL_OK;
-  uint32_t tmpbdtr;
-
-  /* Check the parameters */
-  assert_param(IS_TIM_ADVANCED_INSTANCE(htim->Instance));
-  assert_param(IS_TIM_BREAKINPUT(BreakInput));
-
-  switch (BreakInput)
-  {
-    case TIM_BREAKINPUT_BRK:
-    {
-      /* Check initial conditions */
-      tmpbdtr = READ_REG(htim->Instance->BDTR);
-      if ((READ_BIT(tmpbdtr, TIM_BDTR_BKBID) == TIM_BDTR_BKBID) &&
-          (READ_BIT(tmpbdtr, TIM_BDTR_MOE) == 0U))
-      {
-        /* Break input BRK is disarmed */
-        SET_BIT(htim->Instance->BDTR, TIM_BDTR_BKDSRM);
-      }
-      break;
-    }
-
-    case TIM_BREAKINPUT_BRK2:
-    {
-      /* Check initial conditions */
-      tmpbdtr = READ_REG(htim->Instance->BDTR);
-      if ((READ_BIT(tmpbdtr, TIM_BDTR_BK2BID) == TIM_BDTR_BK2BID) &&
-          (READ_BIT(tmpbdtr, TIM_BDTR_MOE) == 0U))
-      {
-        /* Break input BRK is disarmed */
-        SET_BIT(htim->Instance->BDTR, TIM_BDTR_BK2DSRM);
-      }
-      break;
-    }
-    default:
-      status = HAL_ERROR;
-      break;
-  }
-
-  return status;
-}
-
-/**
-  * @brief  Arm the designated break input (when it operates in bidirectional mode).
-  * @param  htim TIM handle.
-  * @param  BreakInput Break input to arm
-  *          This parameter can be one of the following values:
-  *            @arg TIM_BREAKINPUT_BRK: Timer break input
-  *            @arg TIM_BREAKINPUT_BRK2: Timer break 2 input
-  * @note  Arming is possible at anytime, even if fault is present.
-  * @note  Break input is automatically armed as soon as MOE bit is set.
-  * @retval HAL status
-  */
-HAL_StatusTypeDef HAL_TIMEx_ReArmBreakInput(TIM_HandleTypeDef *htim, uint32_t BreakInput)
-{
-  HAL_StatusTypeDef status = HAL_OK;
-  uint32_t tickstart;
-
-  /* Check the parameters */
-  assert_param(IS_TIM_ADVANCED_INSTANCE(htim->Instance));
-  assert_param(IS_TIM_BREAKINPUT(BreakInput));
-
-  switch (BreakInput)
-  {
-    case TIM_BREAKINPUT_BRK:
-    {
-      /* Check initial conditions */
-      if (READ_BIT(htim->Instance->BDTR, TIM_BDTR_BKBID) == TIM_BDTR_BKBID)
-      {
-        /* Break input BRK is re-armed automatically by hardware. Poll to check whether fault condition disappeared */
-        /* Init tickstart for timeout management */
-        tickstart = HAL_GetTick();
-        while (READ_BIT(htim->Instance->BDTR, TIM_BDTR_BKDSRM) != 0UL)
-        {
-          if ((HAL_GetTick() - tickstart) > TIM_BREAKINPUT_REARM_TIMEOUT)
-          {
-            /* New check to avoid false timeout detection in case of preemption */
-            if (READ_BIT(htim->Instance->BDTR, TIM_BDTR_BKDSRM) != 0UL)
-            {
-              return HAL_TIMEOUT;
-            }
-          }
-        }
-      }
-      break;
-    }
-
-    case TIM_BREAKINPUT_BRK2:
-    {
-      /* Check initial conditions */
-      if (READ_BIT(htim->Instance->BDTR, TIM_BDTR_BK2BID) == TIM_BDTR_BK2BID)
-      {
-        /* Break input BRK2 is re-armed automatically by hardware. Poll to check whether fault condition disappeared */
-        /* Init tickstart for timeout management */
-        tickstart = HAL_GetTick();
-        while (READ_BIT(htim->Instance->BDTR, TIM_BDTR_BK2DSRM) != 0UL)
-        {
-          if ((HAL_GetTick() - tickstart) > TIM_BREAKINPUT_REARM_TIMEOUT)
-          {
-            /* New check to avoid false timeout detection in case of preemption */
-            if (READ_BIT(htim->Instance->BDTR, TIM_BDTR_BK2DSRM) != 0UL)
-            {
-              return HAL_TIMEOUT;
-            }
-          }
-        }
-      }
-      break;
-    }
-    default:
-      status = HAL_ERROR;
-      break;
-  }
-
-  return status;
-}
-
-/**
-  * @}
-  */
-
-/** @defgroup TIMEx_Exported_Functions_Group6 Extended Callbacks functions
-  * @brief    Extended Callbacks functions
-  *
-@verbatim
-  ==============================================================================
-                    ##### Extended Callbacks functions #####
-  ==============================================================================
-  [..]
-    This section provides Extended TIM callback functions:
-    (+) Timer Commutation callback
-    (+) Timer Break callback
-
-@endverbatim
-  * @{
-  */
-
-/**
-  * @brief  Hall commutation changed callback in non-blocking mode
-  * @param  htim TIM handle
-  * @retval None
-  */
-__weak void HAL_TIMEx_CommutCallback(TIM_HandleTypeDef *htim)
-{
-  /* Prevent unused argument(s) compilation warning */
-  UNUSED(htim);
-
-  /* NOTE : This function should not be modified, when the callback is needed,
-            the HAL_TIMEx_CommutCallback could be implemented in the user file
-   */
-}
-/**
-  * @brief  Hall commutation changed half complete callback in non-blocking mode
-  * @param  htim TIM handle
-  * @retval None
-  */
-__weak void HAL_TIMEx_CommutHalfCpltCallback(TIM_HandleTypeDef *htim)
-{
-  /* Prevent unused argument(s) compilation warning */
-  UNUSED(htim);
-
-  /* NOTE : This function should not be modified, when the callback is needed,
-            the HAL_TIMEx_CommutHalfCpltCallback could be implemented in the user file
-   */
-}
-
-/**
-  * @brief  Hall Break detection callback in non-blocking mode
-  * @param  htim TIM handle
-  * @retval None
-  */
-__weak void HAL_TIMEx_BreakCallback(TIM_HandleTypeDef *htim)
-{
-  /* Prevent unused argument(s) compilation warning */
-  UNUSED(htim);
-
-  /* NOTE : This function should not be modified, when the callback is needed,
-            the HAL_TIMEx_BreakCallback could be implemented in the user file
-   */
-}
-
-/**
-  * @brief  Hall Break2 detection callback in non blocking mode
-  * @param  htim: TIM handle
-  * @retval None
-  */
-__weak void HAL_TIMEx_Break2Callback(TIM_HandleTypeDef *htim)
-{
-  /* Prevent unused argument(s) compilation warning */
-  UNUSED(htim);
-
-  /* NOTE : This function Should not be modified, when the callback is needed,
-            the HAL_TIMEx_Break2Callback could be implemented in the user file
-   */
-}
-/**
-  * @}
-  */
-
-/** @defgroup TIMEx_Exported_Functions_Group7 Extended Peripheral State functions
-  * @brief    Extended Peripheral State functions
-  *
-@verbatim
-  ==============================================================================
-                ##### Extended Peripheral State functions #####
-  ==============================================================================
-  [..]
-    This subsection permits to get in run-time the status of the peripheral
-    and the data flow.
-
-@endverbatim
-  * @{
-  */
-
-/**
-  * @brief  Return the TIM Hall Sensor interface handle state.
-  * @param  htim TIM Hall Sensor handle
-  * @retval HAL state
-  */
-HAL_TIM_StateTypeDef HAL_TIMEx_HallSensor_GetState(const TIM_HandleTypeDef *htim)
-{
-  return htim->State;
-}
-
-/**
-  * @brief  Return actual state of the TIM complementary channel.
-  * @param  htim TIM handle
-  * @param  ChannelN TIM Complementary channel
-  *          This parameter can be one of the following values:
-  *            @arg TIM_CHANNEL_1: TIM Channel 1
-  *            @arg TIM_CHANNEL_2: TIM Channel 2
-  *            @arg TIM_CHANNEL_3: TIM Channel 3
-  * @retval TIM Complementary channel state
-  */
-HAL_TIM_ChannelStateTypeDef HAL_TIMEx_GetChannelNState(const TIM_HandleTypeDef *htim,  uint32_t ChannelN)
-{
-  HAL_TIM_ChannelStateTypeDef channel_state;
-
-  /* Check the parameters */
-  assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, ChannelN));
-
-  channel_state = TIM_CHANNEL_N_STATE_GET(htim, ChannelN);
-
-  return channel_state;
-}
-/**
-  * @}
-  */
-
-/**
-  * @}
-  */
-
-/* Private functions ---------------------------------------------------------*/
-/** @defgroup TIMEx_Private_Functions TIM Extended Private Functions
-  * @{
-  */
-
-/**
-  * @brief  TIM DMA Commutation callback.
-  * @param  hdma pointer to DMA handle.
-  * @retval None
-  */
-void TIMEx_DMACommutationCplt(DMA_HandleTypeDef *hdma)
-{
-  TIM_HandleTypeDef *htim = (TIM_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
-
-  /* Change the htim state */
-  htim->State = HAL_TIM_STATE_READY;
-
-#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
-  htim->CommutationCallback(htim);
-#else
-  HAL_TIMEx_CommutCallback(htim);
-#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
-}
-
-/**
-  * @brief  TIM DMA Commutation half complete callback.
-  * @param  hdma pointer to DMA handle.
-  * @retval None
-  */
-void TIMEx_DMACommutationHalfCplt(DMA_HandleTypeDef *hdma)
-{
-  TIM_HandleTypeDef *htim = (TIM_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
-
-  /* Change the htim state */
-  htim->State = HAL_TIM_STATE_READY;
-
-#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
-  htim->CommutationHalfCpltCallback(htim);
-#else
-  HAL_TIMEx_CommutHalfCpltCallback(htim);
-#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
-}
-
-
-/**
-  * @brief  TIM DMA Delay Pulse complete callback (complementary channel).
-  * @param  hdma pointer to DMA handle.
-  * @retval None
-  */
-static void TIM_DMADelayPulseNCplt(DMA_HandleTypeDef *hdma)
-{
-  TIM_HandleTypeDef *htim = (TIM_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
-
-  if (hdma == htim->hdma[TIM_DMA_ID_CC1])
-  {
-    htim->Channel = HAL_TIM_ACTIVE_CHANNEL_1;
-
-    if (hdma->Init.Mode == DMA_NORMAL)
-    {
-      TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY);
-    }
-  }
-  else if (hdma == htim->hdma[TIM_DMA_ID_CC2])
-  {
-    htim->Channel = HAL_TIM_ACTIVE_CHANNEL_2;
-
-    if (hdma->Init.Mode == DMA_NORMAL)
-    {
-      TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY);
-    }
-  }
-  else if (hdma == htim->hdma[TIM_DMA_ID_CC3])
-  {
-    htim->Channel = HAL_TIM_ACTIVE_CHANNEL_3;
-
-    if (hdma->Init.Mode == DMA_NORMAL)
-    {
-      TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_3, HAL_TIM_CHANNEL_STATE_READY);
-    }
-  }
-  else if (hdma == htim->hdma[TIM_DMA_ID_CC4])
-  {
-    htim->Channel = HAL_TIM_ACTIVE_CHANNEL_4;
-
-    if (hdma->Init.Mode == DMA_NORMAL)
-    {
-      TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_4, HAL_TIM_CHANNEL_STATE_READY);
-    }
-  }
-  else
-  {
-    /* nothing to do */
-  }
-
-#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
-  htim->PWM_PulseFinishedCallback(htim);
-#else
-  HAL_TIM_PWM_PulseFinishedCallback(htim);
-#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
-
-  htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;
-}
-
-/**
-  * @brief  TIM DMA error callback (complementary channel)
-  * @param  hdma pointer to DMA handle.
-  * @retval None
-  */
-static void TIM_DMAErrorCCxN(DMA_HandleTypeDef *hdma)
-{
-  TIM_HandleTypeDef *htim = (TIM_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
-
-  if (hdma == htim->hdma[TIM_DMA_ID_CC1])
-  {
-    htim->Channel = HAL_TIM_ACTIVE_CHANNEL_1;
-    TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY);
-  }
-  else if (hdma == htim->hdma[TIM_DMA_ID_CC2])
-  {
-    htim->Channel = HAL_TIM_ACTIVE_CHANNEL_2;
-    TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY);
-  }
-  else if (hdma == htim->hdma[TIM_DMA_ID_CC3])
-  {
-    htim->Channel = HAL_TIM_ACTIVE_CHANNEL_3;
-    TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_3, HAL_TIM_CHANNEL_STATE_READY);
-  }
-  else
-  {
-    /* nothing to do */
-  }
-
-#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
-  htim->ErrorCallback(htim);
-#else
-  HAL_TIM_ErrorCallback(htim);
-#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
-
-  htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;
-}
-
-/**
-  * @brief  Enables or disables the TIM Capture Compare Channel xN.
-  * @param  TIMx to select the TIM peripheral
-  * @param  Channel specifies the TIM Channel
-  *          This parameter can be one of the following values:
-  *            @arg TIM_CHANNEL_1: TIM Channel 1
-  *            @arg TIM_CHANNEL_2: TIM Channel 2
-  *            @arg TIM_CHANNEL_3: TIM Channel 3
-  * @param  ChannelNState specifies the TIM Channel CCxNE bit new state.
-  *          This parameter can be: TIM_CCxN_ENABLE or TIM_CCxN_Disable.
-  * @retval None
-  */
-static void TIM_CCxNChannelCmd(TIM_TypeDef *TIMx, uint32_t Channel, uint32_t ChannelNState)
-{
-  uint32_t tmp;
-
-  tmp = TIM_CCER_CC1NE << (Channel & 0x1FU); /* 0x1FU = 31 bits max shift */
-
-  /* Reset the CCxNE Bit */
-  TIMx->CCER &=  ~tmp;
-
-  /* Set or reset the CCxNE Bit */
-  TIMx->CCER |= (uint32_t)(ChannelNState << (Channel & 0x1FU)); /* 0x1FU = 31 bits max shift */
-}
-/**
-  * @}
-  */
-
-#endif /* HAL_TIM_MODULE_ENABLED */
-/**
-  * @}
-  */
-
-/**
-  * @}
-  */

BIN
non_catalog_apps/flipperscope/photos/freq.jpg


BIN
non_catalog_apps/flipperscope/photos/rigol.jpg


BIN
non_catalog_apps/flipperscope/photos/sig.jpg


BIN
non_catalog_apps/flipperscope/photos/volt.jpg


+ 368 - 0
non_catalog_apps/flipperscope/scenes/adc.c

@@ -0,0 +1,368 @@
+#include "stm32wbxx_ll_adc.h"
+#include <furi.h>
+#define assert_param furi_assert
+
+/* Check of parameters for configuration of ADC hierarchical scope:           */
+/* common to several ADC instances.                                           */
+#if defined(ADC_SUPPORT_2_5_MSPS)
+#define IS_LL_ADC_COMMON_CLOCK(__CLOCK__)                                                      \
+    (((__CLOCK__) == LL_ADC_CLOCK_ASYNC_DIV1) || ((__CLOCK__) == LL_ADC_CLOCK_ASYNC_DIV2) ||   \
+     ((__CLOCK__) == LL_ADC_CLOCK_ASYNC_DIV4) || ((__CLOCK__) == LL_ADC_CLOCK_ASYNC_DIV6) ||   \
+     ((__CLOCK__) == LL_ADC_CLOCK_ASYNC_DIV8) || ((__CLOCK__) == LL_ADC_CLOCK_ASYNC_DIV10) ||  \
+     ((__CLOCK__) == LL_ADC_CLOCK_ASYNC_DIV12) || ((__CLOCK__) == LL_ADC_CLOCK_ASYNC_DIV16) || \
+     ((__CLOCK__) == LL_ADC_CLOCK_ASYNC_DIV32) || ((__CLOCK__) == LL_ADC_CLOCK_ASYNC_DIV64) || \
+     ((__CLOCK__) == LL_ADC_CLOCK_ASYNC_DIV128) || ((__CLOCK__) == LL_ADC_CLOCK_ASYNC_DIV256))
+#else
+#define IS_LL_ADC_COMMON_CLOCK(__CLOCK__)                                                        \
+    (((__CLOCK__) == LL_ADC_CLOCK_SYNC_PCLK_DIV1) ||                                             \
+     ((__CLOCK__) == LL_ADC_CLOCK_SYNC_PCLK_DIV2) ||                                             \
+     ((__CLOCK__) == LL_ADC_CLOCK_SYNC_PCLK_DIV4) || ((__CLOCK__) == LL_ADC_CLOCK_ASYNC_DIV1) || \
+     ((__CLOCK__) == LL_ADC_CLOCK_ASYNC_DIV2) || ((__CLOCK__) == LL_ADC_CLOCK_ASYNC_DIV4) ||     \
+     ((__CLOCK__) == LL_ADC_CLOCK_ASYNC_DIV6) || ((__CLOCK__) == LL_ADC_CLOCK_ASYNC_DIV8) ||     \
+     ((__CLOCK__) == LL_ADC_CLOCK_ASYNC_DIV10) || ((__CLOCK__) == LL_ADC_CLOCK_ASYNC_DIV12) ||   \
+     ((__CLOCK__) == LL_ADC_CLOCK_ASYNC_DIV16) || ((__CLOCK__) == LL_ADC_CLOCK_ASYNC_DIV32) ||   \
+     ((__CLOCK__) == LL_ADC_CLOCK_ASYNC_DIV64) || ((__CLOCK__) == LL_ADC_CLOCK_ASYNC_DIV128) ||  \
+     ((__CLOCK__) == LL_ADC_CLOCK_ASYNC_DIV256))
+#endif /* ADC_SUPPORT_2_5_MSPS */
+
+/* Check of parameters for configuration of ADC hierarchical scope:           */
+/* ADC instance.                                                              */
+#if defined(ADC_SUPPORT_2_5_MSPS)
+#define IS_LL_ADC_CLOCK(__CLOCK__)                   \
+    (((__CLOCK__) == LL_ADC_CLOCK_SYNC_PCLK_DIV4) || \
+     ((__CLOCK__) == LL_ADC_CLOCK_SYNC_PCLK_DIV2) || \
+     ((__CLOCK__) == LL_ADC_CLOCK_SYNC_PCLK_DIV1) || ((__CLOCK__) == LL_ADC_CLOCK_ASYNC))
+
+#endif /* ADC_SUPPORT_2_5_MSPS */
+#define IS_LL_ADC_RESOLUTION(__RESOLUTION__)                                                      \
+    (((__RESOLUTION__) == LL_ADC_RESOLUTION_12B) ||                                               \
+     ((__RESOLUTION__) == LL_ADC_RESOLUTION_10B) || ((__RESOLUTION__) == LL_ADC_RESOLUTION_8B) || \
+     ((__RESOLUTION__) == LL_ADC_RESOLUTION_6B))
+
+#define IS_LL_ADC_DATA_ALIGN(__DATA_ALIGN__) \
+    (((__DATA_ALIGN__) == LL_ADC_DATA_ALIGN_RIGHT) || ((__DATA_ALIGN__) == LL_ADC_DATA_ALIGN_LEFT))
+
+#if defined(ADC_SUPPORT_2_5_MSPS)
+#define IS_LL_ADC_LOW_POWER(__LOW_POWER__)                                                  \
+    (((__LOW_POWER__) == LL_ADC_LP_MODE_NONE) || ((__LOW_POWER__) == LL_ADC_LP_AUTOWAIT) || \
+     ((__LOW_POWER__) == LL_ADC_LP_AUTOPOWEROFF) ||                                         \
+     ((__LOW_POWER__) == LL_ADC_LP_AUTOWAIT_AUTOPOWEROFF))
+#else
+#define IS_LL_ADC_LOW_POWER(__LOW_POWER__) \
+    (((__LOW_POWER__) == LL_ADC_LP_MODE_NONE) || ((__LOW_POWER__) == LL_ADC_LP_AUTOWAIT))
+#endif /* ADC_SUPPORT_2_5_MSPS */
+/* Check of parameters for configuration of ADC hierarchical scope:           */
+/* ADC group regular                                                          */
+#if defined(ADC_SUPPORT_2_5_MSPS)
+#define IS_LL_ADC_REG_TRIG_SOURCE(__REG_TRIG_SOURCE__)            \
+    (((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_SOFTWARE) ||       \
+     ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM1_TRGO2) || \
+     ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM1_CH4) ||   \
+     ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM2_TRGO) ||  \
+     ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM2_CH4) ||   \
+     ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM2_CH3) ||   \
+     ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_EXTI_LINE11))
+#else
+#define IS_LL_ADC_REG_TRIG_SOURCE(__REG_TRIG_SOURCE__)            \
+    (((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_SOFTWARE) ||       \
+     ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM1_TRGO) ||  \
+     ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM1_TRGO2) || \
+     ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM1_CH1) ||   \
+     ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM1_CH2) ||   \
+     ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM1_CH3) ||   \
+     ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM2_TRGO) ||  \
+     ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM2_CH2) ||   \
+     ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_EXTI_LINE11))
+#endif /* ADC_SUPPORT_2_5_MSPS */
+
+#define IS_LL_ADC_REG_CONTINUOUS_MODE(__REG_CONTINUOUS_MODE__) \
+    (((__REG_CONTINUOUS_MODE__) == LL_ADC_REG_CONV_SINGLE) ||  \
+     ((__REG_CONTINUOUS_MODE__) == LL_ADC_REG_CONV_CONTINUOUS))
+
+#define IS_LL_ADC_REG_DMA_TRANSFER(__REG_DMA_TRANSFER__)            \
+    (((__REG_DMA_TRANSFER__) == LL_ADC_REG_DMA_TRANSFER_NONE) ||    \
+     ((__REG_DMA_TRANSFER__) == LL_ADC_REG_DMA_TRANSFER_LIMITED) || \
+     ((__REG_DMA_TRANSFER__) == LL_ADC_REG_DMA_TRANSFER_UNLIMITED))
+
+#define IS_LL_ADC_REG_OVR_DATA_BEHAVIOR(__REG_OVR_DATA_BEHAVIOR__)     \
+    (((__REG_OVR_DATA_BEHAVIOR__) == LL_ADC_REG_OVR_DATA_PRESERVED) || \
+     ((__REG_OVR_DATA_BEHAVIOR__) == LL_ADC_REG_OVR_DATA_OVERWRITTEN))
+
+#if defined(ADC_SUPPORT_2_5_MSPS)
+#define IS_LL_ADC_REG_SEQ_MODE(__REG_SEQ_MODE__)     \
+    (((__REG_SEQ_MODE__) == LL_ADC_REG_SEQ_FIXED) || \
+     ((__REG_SEQ_MODE__) == LL_ADC_REG_SEQ_CONFIGURABLE))
+#endif /* ADC_SUPPORT_2_5_MSPS */
+
+#if defined(ADC_SUPPORT_2_5_MSPS)
+#define IS_LL_ADC_REG_SEQ_SCAN_LENGTH(__REG_SEQ_SCAN_LENGTH__)           \
+    (((__REG_SEQ_SCAN_LENGTH__) == LL_ADC_REG_SEQ_SCAN_DISABLE) ||       \
+     ((__REG_SEQ_SCAN_LENGTH__) == LL_ADC_REG_SEQ_SCAN_ENABLE_2RANKS) || \
+     ((__REG_SEQ_SCAN_LENGTH__) == LL_ADC_REG_SEQ_SCAN_ENABLE_3RANKS) || \
+     ((__REG_SEQ_SCAN_LENGTH__) == LL_ADC_REG_SEQ_SCAN_ENABLE_4RANKS) || \
+     ((__REG_SEQ_SCAN_LENGTH__) == LL_ADC_REG_SEQ_SCAN_ENABLE_5RANKS) || \
+     ((__REG_SEQ_SCAN_LENGTH__) == LL_ADC_REG_SEQ_SCAN_ENABLE_6RANKS) || \
+     ((__REG_SEQ_SCAN_LENGTH__) == LL_ADC_REG_SEQ_SCAN_ENABLE_7RANKS) || \
+     ((__REG_SEQ_SCAN_LENGTH__) == LL_ADC_REG_SEQ_SCAN_ENABLE_8RANKS))
+#else
+#define IS_LL_ADC_REG_SEQ_SCAN_LENGTH(__REG_SEQ_SCAN_LENGTH__)            \
+    (((__REG_SEQ_SCAN_LENGTH__) == LL_ADC_REG_SEQ_SCAN_DISABLE) ||        \
+     ((__REG_SEQ_SCAN_LENGTH__) == LL_ADC_REG_SEQ_SCAN_ENABLE_2RANKS) ||  \
+     ((__REG_SEQ_SCAN_LENGTH__) == LL_ADC_REG_SEQ_SCAN_ENABLE_3RANKS) ||  \
+     ((__REG_SEQ_SCAN_LENGTH__) == LL_ADC_REG_SEQ_SCAN_ENABLE_4RANKS) ||  \
+     ((__REG_SEQ_SCAN_LENGTH__) == LL_ADC_REG_SEQ_SCAN_ENABLE_5RANKS) ||  \
+     ((__REG_SEQ_SCAN_LENGTH__) == LL_ADC_REG_SEQ_SCAN_ENABLE_6RANKS) ||  \
+     ((__REG_SEQ_SCAN_LENGTH__) == LL_ADC_REG_SEQ_SCAN_ENABLE_7RANKS) ||  \
+     ((__REG_SEQ_SCAN_LENGTH__) == LL_ADC_REG_SEQ_SCAN_ENABLE_8RANKS) ||  \
+     ((__REG_SEQ_SCAN_LENGTH__) == LL_ADC_REG_SEQ_SCAN_ENABLE_9RANKS) ||  \
+     ((__REG_SEQ_SCAN_LENGTH__) == LL_ADC_REG_SEQ_SCAN_ENABLE_10RANKS) || \
+     ((__REG_SEQ_SCAN_LENGTH__) == LL_ADC_REG_SEQ_SCAN_ENABLE_11RANKS) || \
+     ((__REG_SEQ_SCAN_LENGTH__) == LL_ADC_REG_SEQ_SCAN_ENABLE_12RANKS) || \
+     ((__REG_SEQ_SCAN_LENGTH__) == LL_ADC_REG_SEQ_SCAN_ENABLE_13RANKS) || \
+     ((__REG_SEQ_SCAN_LENGTH__) == LL_ADC_REG_SEQ_SCAN_ENABLE_14RANKS) || \
+     ((__REG_SEQ_SCAN_LENGTH__) == LL_ADC_REG_SEQ_SCAN_ENABLE_15RANKS) || \
+     ((__REG_SEQ_SCAN_LENGTH__) == LL_ADC_REG_SEQ_SCAN_ENABLE_16RANKS))
+#endif /* ADC_SUPPORT_2_5_MSPS */
+#if defined(ADC_SUPPORT_2_5_MSPS)
+#define IS_LL_ADC_REG_SEQ_SCAN_DISCONT_MODE(__REG_SEQ_DISCONT_MODE__)  \
+    (((__REG_SEQ_DISCONT_MODE__) == LL_ADC_REG_SEQ_DISCONT_DISABLE) || \
+     ((__REG_SEQ_DISCONT_MODE__) == LL_ADC_REG_SEQ_DISCONT_1RANK))
+#else
+#define IS_LL_ADC_REG_SEQ_SCAN_DISCONT_MODE(__REG_SEQ_DISCONT_MODE__)  \
+    (((__REG_SEQ_DISCONT_MODE__) == LL_ADC_REG_SEQ_DISCONT_DISABLE) || \
+     ((__REG_SEQ_DISCONT_MODE__) == LL_ADC_REG_SEQ_DISCONT_1RANK) ||   \
+     ((__REG_SEQ_DISCONT_MODE__) == LL_ADC_REG_SEQ_DISCONT_2RANKS) ||  \
+     ((__REG_SEQ_DISCONT_MODE__) == LL_ADC_REG_SEQ_DISCONT_3RANKS) ||  \
+     ((__REG_SEQ_DISCONT_MODE__) == LL_ADC_REG_SEQ_DISCONT_4RANKS) ||  \
+     ((__REG_SEQ_DISCONT_MODE__) == LL_ADC_REG_SEQ_DISCONT_5RANKS) ||  \
+     ((__REG_SEQ_DISCONT_MODE__) == LL_ADC_REG_SEQ_DISCONT_6RANKS) ||  \
+     ((__REG_SEQ_DISCONT_MODE__) == LL_ADC_REG_SEQ_DISCONT_7RANKS) ||  \
+     ((__REG_SEQ_DISCONT_MODE__) == LL_ADC_REG_SEQ_DISCONT_8RANKS))
+#endif /* ADC_SUPPORT_2_5_MSPS */
+/* Check of parameters for configuration of ADC hierarchical scope:           */
+/* ADC group injected                                                         */
+#define IS_LL_ADC_INJ_TRIG_SOURCE(__INJ_TRIG_SOURCE__)            \
+    (((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_SOFTWARE) ||       \
+     ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_TIM1_TRGO) ||  \
+     ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_TIM1_TRGO2) || \
+     ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_TIM1_CH4) ||   \
+     ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_TIM2_TRGO) ||  \
+     ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_TIM2_CH1) ||   \
+     ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_EXTI_LINE15))
+
+#define IS_LL_ADC_INJ_TRIG_EXT_EDGE(__INJ_TRIG_EXT_EDGE__)       \
+    (((__INJ_TRIG_EXT_EDGE__) == LL_ADC_INJ_TRIG_EXT_RISING) ||  \
+     ((__INJ_TRIG_EXT_EDGE__) == LL_ADC_INJ_TRIG_EXT_FALLING) || \
+     ((__INJ_TRIG_EXT_EDGE__) == LL_ADC_INJ_TRIG_EXT_RISINGFALLING))
+
+#define IS_LL_ADC_INJ_TRIG_AUTO(__INJ_TRIG_AUTO__)           \
+    (((__INJ_TRIG_AUTO__) == LL_ADC_INJ_TRIG_INDEPENDENT) || \
+     ((__INJ_TRIG_AUTO__) == LL_ADC_INJ_TRIG_FROM_GRP_REGULAR))
+
+#define IS_LL_ADC_INJ_SEQ_SCAN_LENGTH(__INJ_SEQ_SCAN_LENGTH__)           \
+    (((__INJ_SEQ_SCAN_LENGTH__) == LL_ADC_INJ_SEQ_SCAN_DISABLE) ||       \
+     ((__INJ_SEQ_SCAN_LENGTH__) == LL_ADC_INJ_SEQ_SCAN_ENABLE_2RANKS) || \
+     ((__INJ_SEQ_SCAN_LENGTH__) == LL_ADC_INJ_SEQ_SCAN_ENABLE_3RANKS) || \
+     ((__INJ_SEQ_SCAN_LENGTH__) == LL_ADC_INJ_SEQ_SCAN_ENABLE_4RANKS))
+
+#define IS_LL_ADC_INJ_SEQ_SCAN_DISCONT_MODE(__INJ_SEQ_DISCONT_MODE__)  \
+    (((__INJ_SEQ_DISCONT_MODE__) == LL_ADC_INJ_SEQ_DISCONT_DISABLE) || \
+     ((__INJ_SEQ_DISCONT_MODE__) == LL_ADC_INJ_SEQ_DISCONT_1RANK))
+
+ErrorStatus LL_ADC_Init(ADC_TypeDef* ADCx, const LL_ADC_InitTypeDef* ADC_InitStruct) {
+    ErrorStatus status = SUCCESS;
+
+    /* Check the parameters */
+    assert_param(IS_ADC_ALL_INSTANCE(ADCx));
+
+#if defined(ADC_SUPPORT_2_5_MSPS)
+    assert_param(IS_LL_ADC_CLOCK(ADC_InitStruct->Clock));
+#endif /* ADC_SUPPORT_2_5_MSPS */
+    assert_param(IS_LL_ADC_RESOLUTION(ADC_InitStruct->Resolution));
+    assert_param(IS_LL_ADC_DATA_ALIGN(ADC_InitStruct->DataAlignment));
+    assert_param(IS_LL_ADC_LOW_POWER(ADC_InitStruct->LowPowerMode));
+
+    /* Note: Hardware constraint (refer to description of this function):       */
+    /*       ADC instance must be disabled.                                     */
+    if(LL_ADC_IsEnabled(ADCx) == 0UL) {
+        /* Configuration of ADC hierarchical scope:                               */
+        /*  - ADC instance                                                        */
+        /*    - Set ADC data resolution                                           */
+        /*    - Set ADC conversion data alignment                                 */
+        /*    - Set ADC low power mode                                            */
+#if defined(ADC_SUPPORT_2_5_MSPS)
+        MODIFY_REG(
+            ADCx->CFGR1,
+            ADC_CFGR1_RES | ADC_CFGR1_ALIGN | ADC_CFGR1_WAIT | ADC_CFGR1_AUTOFF,
+            ADC_InitStruct->Resolution | ADC_InitStruct->DataAlignment |
+                ADC_InitStruct->LowPowerMode);
+
+        MODIFY_REG(ADCx->CFGR2, ADC_CFGR2_CKMODE, ADC_InitStruct->Clock);
+#else
+        MODIFY_REG(
+            ADCx->CFGR,
+            ADC_CFGR_RES | ADC_CFGR_ALIGN | ADC_CFGR_AUTDLY,
+            ADC_InitStruct->Resolution | ADC_InitStruct->DataAlignment |
+                ADC_InitStruct->LowPowerMode);
+#endif /* ADC_SUPPORT_2_5_MSPS */
+    } else {
+        /* Initialization error: ADC instance is not disabled. */
+        status = ERROR;
+    }
+    return status;
+}
+
+ErrorStatus LL_ADC_REG_Init(ADC_TypeDef* ADCx, const LL_ADC_REG_InitTypeDef* ADC_REG_InitStruct) {
+    ErrorStatus status = SUCCESS;
+
+    /* Check the parameters */
+    assert_param(IS_ADC_ALL_INSTANCE(ADCx));
+    assert_param(IS_LL_ADC_REG_TRIG_SOURCE(ADC_REG_InitStruct->TriggerSource));
+#if defined(ADC_SUPPORT_2_5_MSPS)
+    if(LL_ADC_REG_GetSequencerConfigurable(ADCx) != LL_ADC_REG_SEQ_FIXED) {
+        assert_param(IS_LL_ADC_REG_SEQ_SCAN_LENGTH(ADC_REG_InitStruct->SequencerLength));
+    }
+    if((LL_ADC_REG_GetSequencerConfigurable(ADCx) == LL_ADC_REG_SEQ_FIXED) ||
+       (ADC_REG_InitStruct->SequencerLength != LL_ADC_REG_SEQ_SCAN_DISABLE)) {
+        assert_param(IS_LL_ADC_REG_SEQ_SCAN_DISCONT_MODE(ADC_REG_InitStruct->SequencerDiscont));
+
+        /* ADC group regular continuous mode and discontinuous mode                 */
+        /* can not be enabled simultenaeously                                       */
+        assert_param(
+            (ADC_REG_InitStruct->ContinuousMode == LL_ADC_REG_CONV_SINGLE) ||
+            (ADC_REG_InitStruct->SequencerDiscont == LL_ADC_REG_SEQ_DISCONT_DISABLE));
+    }
+#else
+    assert_param(IS_LL_ADC_REG_SEQ_SCAN_LENGTH(ADC_REG_InitStruct->SequencerLength));
+    if(ADC_REG_InitStruct->SequencerLength != LL_ADC_REG_SEQ_SCAN_DISABLE) {
+        assert_param(IS_LL_ADC_REG_SEQ_SCAN_DISCONT_MODE(ADC_REG_InitStruct->SequencerDiscont));
+
+        /* ADC group regular continuous mode and discontinuous mode                 */
+        /* can not be enabled simultenaeously                                       */
+        assert_param(
+            (ADC_REG_InitStruct->ContinuousMode == LL_ADC_REG_CONV_SINGLE) ||
+            (ADC_REG_InitStruct->SequencerDiscont == LL_ADC_REG_SEQ_DISCONT_DISABLE));
+    }
+#endif /* ADC_SUPPORT_2_5_MSPS */
+    assert_param(IS_LL_ADC_REG_CONTINUOUS_MODE(ADC_REG_InitStruct->ContinuousMode));
+    assert_param(IS_LL_ADC_REG_DMA_TRANSFER(ADC_REG_InitStruct->DMATransfer));
+    assert_param(IS_LL_ADC_REG_OVR_DATA_BEHAVIOR(ADC_REG_InitStruct->Overrun));
+
+    /* Note: Hardware constraint (refer to description of this function):       */
+    /*       ADC instance must be disabled.                                     */
+    if(LL_ADC_IsEnabled(ADCx) == 0UL) {
+        /* Configuration of ADC hierarchical scope:                               */
+        /*  - ADC group regular                                                   */
+        /*    - Set ADC group regular trigger source                              */
+        /*    - Set ADC group regular sequencer length                            */
+        /*    - Set ADC group regular sequencer discontinuous mode                */
+        /*    - Set ADC group regular continuous mode                             */
+        /*    - Set ADC group regular conversion data transfer: no transfer or    */
+        /*      transfer by DMA, and DMA requests mode                            */
+        /*    - Set ADC group regular overrun behavior                            */
+        /* Note: On this STM32 series, ADC trigger edge is set to value 0x0 by     */
+        /*       setting of trigger source to SW start.                           */
+#if defined(ADC_SUPPORT_2_5_MSPS)
+        if((LL_ADC_REG_GetSequencerConfigurable(ADCx) == LL_ADC_REG_SEQ_FIXED) ||
+           (ADC_REG_InitStruct->SequencerLength != LL_ADC_REG_SEQ_SCAN_DISABLE)) {
+            /* Case of sequencer mode fixed
+               or sequencer length >= 2 ranks with sequencer mode fully configurable:
+               discontinuous mode configured */
+            MODIFY_REG(
+                ADCx->CFGR1,
+                ADC_CFGR1_EXTSEL | ADC_CFGR1_EXTEN | ADC_CFGR1_DISCEN | ADC_CFGR1_CONT |
+                    ADC_CFGR1_DMAEN | ADC_CFGR1_DMACFG | ADC_CFGR1_OVRMOD,
+                ADC_REG_InitStruct->TriggerSource | ADC_REG_InitStruct->SequencerDiscont |
+                    ADC_REG_InitStruct->ContinuousMode | ADC_REG_InitStruct->DMATransfer |
+                    ADC_REG_InitStruct->Overrun);
+        } else {
+            /* Case of sequencer mode fully configurable
+               and sequencer length 1 rank (sequencer disabled):
+               discontinuous mode discarded (fixed to disable) */
+            MODIFY_REG(
+                ADCx->CFGR1,
+                ADC_CFGR1_EXTSEL | ADC_CFGR1_EXTEN | ADC_CFGR1_DISCEN | ADC_CFGR1_CONT |
+                    ADC_CFGR1_DMAEN | ADC_CFGR1_DMACFG | ADC_CFGR1_OVRMOD,
+                ADC_REG_InitStruct->TriggerSource | LL_ADC_REG_SEQ_DISCONT_DISABLE |
+                    ADC_REG_InitStruct->ContinuousMode | ADC_REG_InitStruct->DMATransfer |
+                    ADC_REG_InitStruct->Overrun);
+        }
+#else
+        if(ADC_REG_InitStruct->SequencerLength != LL_ADC_REG_SEQ_SCAN_DISABLE) {
+            MODIFY_REG(
+                ADCx->CFGR,
+                ADC_CFGR_EXTSEL | ADC_CFGR_EXTEN | ADC_CFGR_DISCEN | ADC_CFGR_DISCNUM |
+                    ADC_CFGR_CONT | ADC_CFGR_DMAEN | ADC_CFGR_DMACFG | ADC_CFGR_OVRMOD,
+                ADC_REG_InitStruct->TriggerSource | ADC_REG_InitStruct->SequencerDiscont |
+                    ADC_REG_InitStruct->ContinuousMode | ADC_REG_InitStruct->DMATransfer |
+                    ADC_REG_InitStruct->Overrun);
+        } else {
+            MODIFY_REG(
+                ADCx->CFGR,
+                ADC_CFGR_EXTSEL | ADC_CFGR_EXTEN | ADC_CFGR_DISCEN | ADC_CFGR_DISCNUM |
+                    ADC_CFGR_CONT | ADC_CFGR_DMAEN | ADC_CFGR_DMACFG | ADC_CFGR_OVRMOD,
+                ADC_REG_InitStruct->TriggerSource | LL_ADC_REG_SEQ_DISCONT_DISABLE |
+                    ADC_REG_InitStruct->ContinuousMode | ADC_REG_InitStruct->DMATransfer |
+                    ADC_REG_InitStruct->Overrun);
+        }
+#endif /* ADC_SUPPORT_2_5_MSPS */
+
+        /* Set ADC group regular sequencer length and scan direction */
+#if defined(ADC_SUPPORT_2_5_MSPS)
+        if(LL_ADC_REG_GetSequencerConfigurable(ADCx) != LL_ADC_REG_SEQ_FIXED) {
+            LL_ADC_REG_SetSequencerLength(ADCx, ADC_REG_InitStruct->SequencerLength);
+        }
+#else
+        LL_ADC_REG_SetSequencerLength(ADCx, ADC_REG_InitStruct->SequencerLength);
+#endif /* ADC_SUPPORT_2_5_MSPS */
+    } else {
+        /* Initialization error: ADC instance is not disabled. */
+        status = ERROR;
+    }
+    return status;
+}
+
+ErrorStatus LL_ADC_CommonInit(
+    ADC_Common_TypeDef* ADCxy_COMMON,
+    const LL_ADC_CommonInitTypeDef* ADC_CommonInitStruct) {
+    ErrorStatus status = SUCCESS;
+
+    /* Check the parameters */
+    assert_param(IS_ADC_COMMON_INSTANCE(ADCxy_COMMON));
+    assert_param(IS_LL_ADC_COMMON_CLOCK(ADC_CommonInitStruct->CommonClock));
+
+    /* Note: Hardware constraint (refer to description of functions             */
+    /*       "LL_ADC_SetCommonXXX()":                                           */
+    /*       On this STM32 series, setting of these features is conditioned to   */
+    /*       ADC state:                                                         */
+    /*       All ADC instances of the ADC common group must be disabled.        */
+    if(__LL_ADC_IS_ENABLED_ALL_COMMON_INSTANCE(ADCxy_COMMON) == 0UL) {
+        /* Configuration of ADC hierarchical scope:                               */
+        /*  - common to several ADC                                               */
+        /*    (all ADC instances belonging to the same ADC common instance)       */
+        /*    - Set ADC clock (conversion clock)                                  */
+#if defined(ADC_MULTIMODE_SUPPORT)
+        if(ADC_CommonInitStruct->Multimode != LL_ADC_MULTI_INDEPENDENT) {
+            MODIFY_REG(
+                ADCxy_COMMON->CCR,
+                ADC_CCR_CKMODE | ADC_CCR_PRESC | ADC_CCR_DUAL | ADC_CCR_MDMA | ADC_CCR_DELAY,
+                ADC_CommonInitStruct->CommonClock | ADC_CommonInitStruct->Multimode |
+                    ADC_CommonInitStruct->MultiDMATransfer |
+                    ADC_CommonInitStruct->MultiTwoSamplingDelay);
+        } else {
+            MODIFY_REG(
+                ADCxy_COMMON->CCR,
+                ADC_CCR_CKMODE | ADC_CCR_PRESC | ADC_CCR_DUAL | ADC_CCR_MDMA | ADC_CCR_DELAY,
+                ADC_CommonInitStruct->CommonClock | LL_ADC_MULTI_INDEPENDENT);
+        }
+#else
+        LL_ADC_SetCommonClock(ADCxy_COMMON, ADC_CommonInitStruct->CommonClock);
+#endif
+    } else {
+        /* Initialization error: One or several ADC instances belonging to        */
+        /* the same ADC common instance are not disabled.                         */
+        status = ERROR;
+    }
+
+    return status;
+}

+ 1 - 2
non_catalog_apps/flipperscope/scenes/scope_scene_about.c

@@ -13,8 +13,7 @@ void scope_scene_about_on_enter(void* context) {
     FuriString* temp_str;
     temp_str = furi_string_alloc();
     furi_string_printf(temp_str, "\e#%s\n", "Information");
-
-    furi_string_cat_printf(temp_str, "Version: %s\n", S_VERSION_APP);
+    furi_string_cat_printf(temp_str, "Provide signal to pin 16/PC0, with a voltage ranging from 0V to 2.5V and ground to pin 18/GND.\n\n");
     furi_string_cat_printf(temp_str, "Developed by: %s\n", S_DEVELOPED);
     furi_string_cat_printf(temp_str, "Github: %s\n\n", S_GITHUB);
 

+ 223 - 159
non_catalog_apps/flipperscope/scenes/scope_scene_run.c

@@ -1,7 +1,6 @@
 #include <float.h>
 #include <furi.h>
 #include <furi_hal.h>
-#include <furi_hal_bus.h>
 #include <furi_hal_resources.h>
 #include <gui/gui.h>
 #include <gui/view_dispatcher.h>
@@ -11,10 +10,19 @@
 #include <gui/modules/widget.h>
 #include <notification/notification_messages.h>
 
-#include "stm32wbxx_hal.h"
-#include "stm32wbxx_hal_tim.h"
-#include "stm32wbxx_nucleo.h"
-#include "stm32wbxx_hal_adc.h"
+#include "stm32wbxx_ll_adc.h"
+#include "stm32wbxx_ll_dma.h"
+#include "stm32wbxx_ll_crs.h"
+#include "stm32wbxx_ll_rcc.h"
+#include "stm32wbxx_ll_bus.h"
+#include "stm32wbxx_ll_system.h"
+#include "stm32wbxx_ll_exti.h"
+#include "stm32wbxx_ll_cortex.h"
+#include "stm32wbxx_ll_utils.h"
+#include "stm32wbxx_ll_pwr.h"
+#include "stm32wbxx_ll_tim.h"
+#include "stm32wbxx_ll_gpio.h"
+
 #include "../scope_app_i.h"
 
 #define DIGITAL_SCALE_12BITS ((uint32_t)0xFFF)
@@ -24,6 +32,9 @@
 #define __ADC_CALC_DATA_VOLTAGE(__VREFANALOG_VOLTAGE__, __ADC_DATA__) \
     ((__ADC_DATA__) * (__VREFANALOG_VOLTAGE__) / DIGITAL_SCALE_12BITS)
 #define VDDA_APPLI ((uint32_t)2500)
+#define TIMER_FREQUENCY_RANGE_MIN (1UL)
+#define TIMER_PRESCALER_MAX_VALUE (0xFFFF - 1UL)
+#define ADC_DELAY_CALIB_ENABLE_CPU_CYCLES (LL_ADC_DELAY_CALIB_ENABLE_ADC_CYCLES * 32)
 
 // ramVector found from - https://community.nxp.com/t5/i-MX-Processors/Relocate-vector-table-to-ITCM/m-p/1302304
 // the aligned aspect is key!
@@ -62,10 +73,6 @@ void Error_Handler() {
     }
 }
 
-static ADC_HandleTypeDef hadc1;
-static DMA_HandleTypeDef hdma_adc1;
-static TIM_HandleTypeDef htim2;
-
 __IO uint16_t
     aADCxConvertedData[ADC_CONVERTED_DATA_BUFFER_SIZE]; // Array that ADC data is copied to, via DMA
 __IO uint16_t aADCxConvertedData_Voltage_mVoltA
@@ -79,145 +86,180 @@ __IO uint16_t* mvoltWrite =
 __IO uint16_t* mvoltDisplay =
     &aADCxConvertedData_Voltage_mVoltB[0]; // Pointer to area of memory we display
 
-void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc) {
-    GPIO_InitTypeDef GPIO_InitStruct = {0};
-    if(hadc->Instance == ADC1) {
-        __HAL_RCC_ADC_CLK_ENABLE();
-        __HAL_RCC_GPIOC_CLK_ENABLE();
-        GPIO_InitStruct.Pin = GPIO_PIN_0;
-        GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
-        GPIO_InitStruct.Pull = GPIO_NOPULL;
-        HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
-        hdma_adc1.Instance = DMA1_Channel1;
-        hdma_adc1.Init.Request = DMA_REQUEST_ADC1;
-        hdma_adc1.Init.Direction = DMA_PERIPH_TO_MEMORY;
-        hdma_adc1.Init.PeriphInc = DMA_PINC_DISABLE;
-        hdma_adc1.Init.MemInc = DMA_MINC_ENABLE;
-        hdma_adc1.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
-        hdma_adc1.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
-        hdma_adc1.Init.Mode = DMA_CIRCULAR;
-        hdma_adc1.Init.Priority = DMA_PRIORITY_LOW;
-        if(HAL_DMA_Init(&hdma_adc1) != HAL_OK) {
-            Error_Handler();
-        }
-        __HAL_LINKDMA(hadc, DMA_Handle, hdma_adc1);
-        HAL_NVIC_SetPriority(ADC1_IRQn, 15, 0);
-        HAL_NVIC_EnableIRQ(ADC1_IRQn);
-    }
+void AdcDmaTransferComplete_Callback();
+void AdcDmaTransferHalf_Callback();
+
+void AdcGrpRegularOverrunError_Callback(void) {
+    LL_ADC_DisableIT_OVR(ADC1);
 }
 
-void HAL_ADC_MspDeInit(ADC_HandleTypeDef* hadc) {
-    if(hadc->Instance == ADC1) {
-        __HAL_RCC_ADC_CLK_DISABLE();
-        HAL_GPIO_DeInit(GPIOC, GPIO_PIN_0);
-        HAL_DMA_DeInit(hadc->DMA_Handle);
-        HAL_NVIC_DisableIRQ(ADC1_IRQn);
-    }
+void AdcDmaTransferError_Callback() {
 }
 
-void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* htim_base) {
-    if(htim_base->Instance == TIM2) {
-        __HAL_RCC_TIM2_CLK_ENABLE();
-        HAL_NVIC_SetPriority(TIM2_IRQn, 15, 0);
-        HAL_NVIC_EnableIRQ(TIM2_IRQn);
+void DMA1_Channel1_IRQHandler(void) {
+    if(LL_DMA_IsActiveFlag_TC1(DMA1) == 1) {
+        LL_DMA_ClearFlag_TC1(DMA1);
+        AdcDmaTransferComplete_Callback();
     }
-}
 
-void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef* htim_base) {
-    if(htim_base->Instance == TIM2) {
-        __HAL_RCC_TIM2_CLK_DISABLE();
-        HAL_NVIC_DisableIRQ(TIM2_IRQn);
+    if(LL_DMA_IsActiveFlag_HT1(DMA1) == 1) {
+        LL_DMA_ClearFlag_HT1(DMA1);
+        AdcDmaTransferHalf_Callback();
     }
-}
 
-void DMA1_Channel1_IRQHandler(void) {
-    HAL_DMA_IRQHandler(&hdma_adc1);
+    if(LL_DMA_IsActiveFlag_TE1(DMA1) == 1) {
+        LL_DMA_ClearFlag_TE1(DMA1);
+        AdcDmaTransferError_Callback();
+    }
 }
 
 void ADC1_IRQHandler(void) {
-    HAL_ADC_IRQHandler(&hadc1);
+    if(LL_ADC_IsActiveFlag_OVR(ADC1) != 0) {
+        LL_ADC_ClearFlag_OVR(ADC1);
+        AdcGrpRegularOverrunError_Callback();
+    }
 }
 
 void TIM2_IRQHandler(void) {
-    HAL_TIM_IRQHandler(&htim2);
 }
 
-// Setup ADC1 to be triggered by timer2
 static void MX_ADC1_Init(void) {
-    ADC_ChannelConfTypeDef sConfig = {0};
-    hadc1.Instance = ADC1;
-    hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;
-    hadc1.Init.Resolution = ADC_RESOLUTION_12B;
-    hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
-    hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE;
-    hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
-    hadc1.Init.LowPowerAutoWait = DISABLE;
-    hadc1.Init.ContinuousConvMode = DISABLE;
-    hadc1.Init.NbrOfConversion = 1;
-    hadc1.Init.DiscontinuousConvMode = DISABLE;
-    hadc1.Init.ExternalTrigConv = ADC_EXTERNALTRIG_T2_TRGO;
-    hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_RISING;
-    hadc1.Init.DMAContinuousRequests = ENABLE;
-    hadc1.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN;
-    hadc1.Init.OversamplingMode = DISABLE;
-    if(HAL_ADC_Init(&hadc1) != HAL_OK) {
-        Error_Handler();
-    }
-    sConfig.Channel = ADC_CHANNEL_1;
-    sConfig.Rank = ADC_REGULAR_RANK_1;
-    sConfig.SamplingTime = ADC_SAMPLETIME_2CYCLES_5;
-    sConfig.SingleDiff = ADC_SINGLE_ENDED;
-    sConfig.OffsetNumber = ADC_OFFSET_NONE;
-    sConfig.Offset = 0;
-    if(HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) {
-        Error_Handler();
+    LL_ADC_CommonInitTypeDef ADC_CommonInitStruct = {0};
+    LL_ADC_InitTypeDef ADC_InitStruct = {0};
+    LL_ADC_REG_InitTypeDef ADC_REG_InitStruct = {0};
+    LL_GPIO_InitTypeDef GPIO_InitStruct = {0};
+
+    LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_ADC);
+    LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOC);
+    GPIO_InitStruct.Pin = LL_GPIO_PIN_0;
+    GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG;
+    GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
+    LL_GPIO_Init(GPIOC, &GPIO_InitStruct);
+
+    LL_DMA_SetPeriphRequest(DMA1, LL_DMA_CHANNEL_1, LL_DMAMUX_REQ_ADC1);
+    LL_DMA_SetDataTransferDirection(DMA1, LL_DMA_CHANNEL_1, LL_DMA_DIRECTION_PERIPH_TO_MEMORY);
+    LL_DMA_SetChannelPriorityLevel(DMA1, LL_DMA_CHANNEL_1, LL_DMA_PRIORITY_HIGH);
+    LL_DMA_SetMode(DMA1, LL_DMA_CHANNEL_1, LL_DMA_MODE_CIRCULAR);
+    LL_DMA_SetPeriphIncMode(DMA1, LL_DMA_CHANNEL_1, LL_DMA_PERIPH_NOINCREMENT);
+    LL_DMA_SetMemoryIncMode(DMA1, LL_DMA_CHANNEL_1, LL_DMA_MEMORY_INCREMENT);
+    LL_DMA_SetPeriphSize(DMA1, LL_DMA_CHANNEL_1, LL_DMA_PDATAALIGN_HALFWORD);
+    LL_DMA_SetMemorySize(DMA1, LL_DMA_CHANNEL_1, LL_DMA_MDATAALIGN_HALFWORD);
+
+    LL_DMAMUX_SetRequestID(DMAMUX1, LL_DMAMUX_CHANNEL_0, LL_DMAMUX_REQ_ADC1);
+
+    LL_DMA_ConfigAddresses(
+        DMA1,
+        LL_DMA_CHANNEL_1,
+        LL_ADC_DMA_GetRegAddr(ADC1, LL_ADC_DMA_REG_REGULAR_DATA),
+        (uint32_t)&aADCxConvertedData,
+        LL_DMA_DIRECTION_PERIPH_TO_MEMORY);
+
+    LL_DMA_SetDataLength(DMA1, LL_DMA_CHANNEL_1, ADC_CONVERTED_DATA_BUFFER_SIZE);
+
+    LL_DMA_EnableIT_TC(DMA1, LL_DMA_CHANNEL_1);
+    LL_DMA_EnableIT_HT(DMA1, LL_DMA_CHANNEL_1);
+    LL_DMA_EnableIT_TE(DMA1, LL_DMA_CHANNEL_1);
+
+    LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_1);
+    NVIC_SetPriority(ADC1_IRQn, 0);
+    NVIC_EnableIRQ(ADC1_IRQn);
+
+    ADC_CommonInitStruct.CommonClock = LL_ADC_CLOCK_SYNC_PCLK_DIV2;
+    LL_ADC_CommonInit(__LL_ADC_COMMON_INSTANCE(ADC1), &ADC_CommonInitStruct);
+    ADC_InitStruct.Resolution = LL_ADC_RESOLUTION_12B;
+    ADC_InitStruct.DataAlignment = LL_ADC_DATA_ALIGN_RIGHT;
+    ADC_InitStruct.LowPowerMode = LL_ADC_LP_MODE_NONE;
+    LL_ADC_Init(ADC1, &ADC_InitStruct);
+    ADC_REG_InitStruct.TriggerSource = LL_ADC_REG_TRIG_EXT_TIM2_TRGO;
+    ADC_REG_InitStruct.SequencerLength = LL_ADC_REG_SEQ_SCAN_DISABLE;
+    ADC_REG_InitStruct.SequencerDiscont = LL_ADC_REG_SEQ_DISCONT_DISABLE;
+    ADC_REG_InitStruct.ContinuousMode = LL_ADC_REG_CONV_SINGLE;
+    ADC_REG_InitStruct.DMATransfer = LL_ADC_REG_DMA_TRANSFER_UNLIMITED;
+    ADC_REG_InitStruct.Overrun = LL_ADC_REG_OVR_DATA_OVERWRITTEN;
+    LL_ADC_REG_Init(ADC1, &ADC_REG_InitStruct);
+    LL_ADC_SetOverSamplingScope(ADC1, LL_ADC_OVS_DISABLE);
+    LL_ADC_REG_SetTriggerEdge(ADC1, LL_ADC_REG_TRIG_EXT_FALLING);
+
+    LL_ADC_DisableDeepPowerDown(ADC1);
+    LL_ADC_EnableInternalRegulator(ADC1);
+    uint32_t wait_loop_index;
+    wait_loop_index =
+        ((LL_ADC_DELAY_INTERNAL_REGUL_STAB_US * (SystemCoreClock / (100000 * 2))) / 10);
+    while(wait_loop_index != 0) {
+        wait_loop_index--;
     }
+
+    LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_1, LL_ADC_CHANNEL_1);
+    LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_1, LL_ADC_SAMPLINGTIME_247CYCLES_5);
+    LL_ADC_SetChannelSingleDiff(ADC1, LL_ADC_CHANNEL_1, LL_ADC_SINGLE_ENDED);
+    LL_ADC_EnableIT_OVR(ADC1);
 }
 
-// Only used in testing, for toggling GPIO pin, to measure timer frequency
-void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef* htim) {
-    if(htim->Instance == TIM2) {
-        toggle ^= 1;
-        furi_hal_gpio_write(&gpio_ext_pa7, toggle);
-    }
+double abs_error(double num1, double num2) {
+    return fabs((num1 - num2) / num1);
 }
 
-// Init timer2
-static void MX_TIM2_Init(uint32_t period) {
-    if(!furi_hal_bus_is_enabled(FuriHalBusTIM2)) {
-        furi_hal_bus_enable(FuriHalBusTIM2);
-    }
-    TIM_ClockConfigTypeDef sClockSourceConfig = {0};
-    TIM_MasterConfigTypeDef sMasterConfig = {0};
-    htim2.Instance = TIM2;
-    htim2.Init.Prescaler = 1;
-    htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
-    htim2.Init.Period = period;
-    htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
-    htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
-    if(HAL_TIM_Base_Init(&htim2) != HAL_OK) {
-        Error_Handler();
+static void MX_TIM2_Init(int freq) {
+    uint32_t timer_clock_frequency = 0; /* Timer clock frequency */
+    uint32_t timer_prescaler =
+        0; /* Time base prescaler to have timebase aligned on minimum frequency possible */
+    uint32_t timer_reload =
+        0; /* Timer reload value in function of timer prescaler to achieve time base period */
+
+    LL_TIM_InitTypeDef TIM_InitStruct = {0};
+    LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM2);
+
+    if(LL_RCC_GetAPB1Prescaler() == LL_RCC_APB1_DIV_1) {
+        timer_clock_frequency =
+            __LL_RCC_CALC_PCLK1_FREQ(SystemCoreClock, LL_RCC_GetAPB1Prescaler());
+    } else {
+        timer_clock_frequency =
+            (__LL_RCC_CALC_PCLK1_FREQ(SystemCoreClock, LL_RCC_GetAPB1Prescaler()) * 2);
     }
-    sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
-    if(HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK) {
-        Error_Handler();
-    }
-    sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE;
-    sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
-    if(HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK) {
-        Error_Handler();
+
+    //(PSC+1) * (ARR+1)
+    double calc = timer_clock_frequency / (1 / (1 / (double)freq));
+    double PSC;
+    double ARR;
+    double minerr = 10000;
+    for(int i = 1; i < 65536; i++) {
+        PSC = i - 1;
+        ARR = calc / (PSC + 1);
+        double error = abs_error((int)(ARR), ARR);
+        if(error < (double)0.001 && error < minerr && ARR - 1 > 0) {
+            timer_prescaler = PSC;
+            timer_reload = ARR - 1;
+            minerr = error;
+            break;
+        }
     }
+
+    TIM_InitStruct.Prescaler = timer_prescaler;
+    TIM_InitStruct.CounterMode = LL_TIM_COUNTERMODE_UP;
+    TIM_InitStruct.Autoreload = timer_reload;
+    TIM_InitStruct.ClockDivision = LL_TIM_CLOCKDIVISION_DIV1;
+    LL_TIM_Init(TIM2, &TIM_InitStruct);
+    LL_TIM_SetTriggerInput(TIM2, LL_TIM_TS_ITR0);
+    LL_TIM_SetSlaveMode(TIM2, LL_TIM_SLAVEMODE_DISABLED);
+    LL_TIM_DisableIT_TRIG(TIM2);
+    LL_TIM_DisableDMAReq_TRIG(TIM2);
+    LL_TIM_SetTriggerOutput(TIM2, LL_TIM_TRGO_UPDATE);
+    LL_TIM_DisableMasterSlaveMode(TIM2);
+    LL_TIM_SetTriggerOutput(TIM2, LL_TIM_TRGO_UPDATE);
+    LL_TIM_EnableCounter(TIM2);
 }
 
 static void MX_DMA_Init(void) {
-    __HAL_RCC_DMAMUX1_CLK_ENABLE();
-    __HAL_RCC_DMA1_CLK_ENABLE();
-    HAL_NVIC_SetPriority(DMA1_Channel1_IRQn, 15, 0);
-    HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);
+    LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_DMAMUX1);
+    LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_DMA1);
+    NVIC_SetPriority(DMA1_Channel1_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 1, 0));
+    NVIC_EnableIRQ(DMA1_Channel1_IRQn);
 }
 
 static void MX_GPIO_Init(void) {
-    __HAL_RCC_GPIOC_CLK_ENABLE();
+    LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOA);
+    LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOB);
+    LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOC);
 }
 
 // Swap pointer addresses, used for double buffer
@@ -228,39 +270,79 @@ void swap(__IO uint16_t** a, __IO uint16_t** b) {
     *b = tmp;
 }
 
-// Write end half of DMA buffer to converted output
-void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc) {
-    UNUSED(hadc);
+void AdcDmaTransferComplete_Callback() {
     uint32_t tmp_index = 0;
     for(tmp_index = (ADC_CONVERTED_DATA_BUFFER_SIZE / 2);
         tmp_index < ADC_CONVERTED_DATA_BUFFER_SIZE;
         tmp_index++) {
-        mvoltWrite[tmp_index] = __ADC_CALC_DATA_VOLTAGE(VDDA_APPLI, aADCxConvertedData[tmp_index]);
+        mvoltWrite[tmp_index] = __LL_ADC_CALC_DATA_TO_VOLTAGE(
+            VDDA_APPLI, aADCxConvertedData[tmp_index], LL_ADC_RESOLUTION_12B);
     }
     ubDmaTransferStatus = 1;
-    // Swap double buffer, so new data can be displayed, provided we're not paused
     if(!pause) swap(&mvoltWrite, &mvoltDisplay);
 }
 
-// Write first half of DMA buffer to converted output
-void HAL_ADC_ConvHalfCpltCallback(ADC_HandleTypeDef* hadc) {
-    UNUSED(hadc);
+void AdcDmaTransferHalf_Callback() {
     uint32_t tmp_index = 0;
     for(tmp_index = 0; tmp_index < (ADC_CONVERTED_DATA_BUFFER_SIZE / 2); tmp_index++) {
-        mvoltWrite[tmp_index] = __ADC_CALC_DATA_VOLTAGE(VDDA_APPLI, aADCxConvertedData[tmp_index]);
+        mvoltWrite[tmp_index] = __LL_ADC_CALC_DATA_TO_VOLTAGE(
+            VDDA_APPLI, aADCxConvertedData[tmp_index], LL_ADC_RESOLUTION_12B);
     }
     ubDmaTransferStatus = 0;
 }
 
-void HAL_ADC_ErrorCallback(ADC_HandleTypeDef* hadc) {
-    UNUSED(hadc);
-    Error_Handler();
+void Activate_ADC(void) {
+    __IO uint32_t wait_loop_index = 0U;
+#if(USE_TIMEOUT == 1)
+    uint32_t Timeout = 0U; /* Variable used for timeout management */
+#endif /* USE_TIMEOUT */
+    if(LL_ADC_IsEnabled(ADC1) == 0) {
+        LL_ADC_DisableDeepPowerDown(ADC1);
+        LL_ADC_EnableInternalRegulator(ADC1);
+        wait_loop_index =
+            ((LL_ADC_DELAY_INTERNAL_REGUL_STAB_US * (SystemCoreClock / (100000 * 2))) / 10);
+        while(wait_loop_index != 0) {
+            wait_loop_index--;
+        }
+        LL_ADC_StartCalibration(ADC1, LL_ADC_SINGLE_ENDED);
+
+#if(USE_TIMEOUT == 1)
+        Timeout = ADC_CALIBRATION_TIMEOUT_MS;
+#endif /* USE_TIMEOUT */
+
+        while(LL_ADC_IsCalibrationOnGoing(ADC1) != 0) {
+#if(USE_TIMEOUT == 1)
+            if(LL_SYSTICK_IsActiveCounterFlag()) {
+                if(Timeout-- == 0) {
+                }
+            }
+#endif /* USE_TIMEOUT */
+        }
+        wait_loop_index = (ADC_DELAY_CALIB_ENABLE_CPU_CYCLES >> 1);
+        while(wait_loop_index != 0) {
+            wait_loop_index--;
+        }
+        LL_ADC_Enable(ADC1);
+#if(USE_TIMEOUT == 1)
+        Timeout = ADC_ENABLE_TIMEOUT_MS;
+#endif /* USE_TIMEOUT */
+        while(LL_ADC_IsActiveFlag_ADRDY(ADC1) == 0) {
+#if(USE_TIMEOUT == 1)
+            /* Check Systick counter flag to decrement the time-out value */
+            if(LL_SYSTICK_IsActiveCounterFlag()) {
+                if(Timeout-- == 0) {
+                    /* Time-out occurred. Set LED to blinking mode */
+                    LED_Blinking(LED_BLINK_ERROR);
+                }
+            }
+#endif /* USE_TIMEOUT */
+        }
+    }
 }
 
 // Used to draw to display
 static void app_draw_callback(Canvas* canvas, void* ctx) {
     UNUSED(ctx);
-
     static int16_t index[ADC_CONVERTED_DATA_BUFFER_SIZE];
     static float data[ADC_CONVERTED_DATA_BUFFER_SIZE];
     static float crossings[ADC_CONVERTED_DATA_BUFFER_SIZE];
@@ -372,10 +454,6 @@ void scope_scene_run_on_enter(void* context) {
     // What type of measurement are we performing
     type = app->measurement;
 
-    // Test purposes
-    //furi_hal_gpio_write(&gpio_ext_pa7, false);
-    //furi_hal_gpio_init( &gpio_ext_pa7, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh);
-
     // Copy vector table, modify to use our own IRQ handlers
     __disable_irq();
     memcpy(ramVector, (uint32_t*)(FLASH_BASE | SCB->VTOR), sizeof(uint32_t) * TABLE_SIZE);
@@ -385,9 +463,7 @@ void scope_scene_run_on_enter(void* context) {
     ramVector[44] = (uint32_t)TIM2_IRQHandler;
     __enable_irq();
 
-    // Found this recommended by https://www.freertos.org/RTOS-Cortex-M3-M4.html
-    // although we're using after RTOS started
-    HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);
+    furi_hal_bus_enable(FuriHalBusTIM2);
 
     FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(InputEvent));
 
@@ -395,11 +471,8 @@ void scope_scene_run_on_enter(void* context) {
     MX_GPIO_Init();
     MX_DMA_Init();
 
-    // Hack -- PCLK1 - seems to be twice what is reported? Not sure how?
-    uint32_t period = (uint32_t)((double)(HAL_RCC_GetPCLK1Freq() * 2) * app->time);
     freq = 1 / app->time;
-
-    MX_TIM2_Init(period);
+    MX_TIM2_Init((int)freq);
 
     // Set VREFBUF to 2.5V, as vref isn't connected to 3.3V itself in the flipper zero
     VREFBUF->CSR |= VREFBUF_CSR_ENVR;
@@ -419,20 +492,11 @@ void scope_scene_run_on_enter(void* context) {
         aADCxConvertedData_Voltage_mVoltB[tmp_index_adc_converted_data] = 0;
     }
 
-    if(HAL_ADCEx_Calibration_Start(&hadc1, ADC_SINGLE_ENDED) != HAL_OK) {
-        Error_Handler();
-    }
-
-    // Use to generate interrupt to toggle GPIO for testing
-    //if (HAL_TIM_Base_Start_IT(&htim2) != HAL_OK) {
-    if(HAL_TIM_Base_Start(&htim2) != HAL_OK) {
-        Error_Handler();
-    }
+    Activate_ADC();
 
-    // Start DMA transfer
-    if(HAL_ADC_Start_DMA(&hadc1, (uint32_t*)aADCxConvertedData, ADC_CONVERTED_DATA_BUFFER_SIZE) !=
-       HAL_OK) {
-        Error_Handler();
+    if((LL_ADC_IsEnabled(ADC1) == 1) && (LL_ADC_IsDisableOngoing(ADC1) == 0) &&
+       (LL_ADC_REG_IsConversionOngoing(ADC1) == 0)) {
+        LL_ADC_REG_StartConversion(ADC1);
     }
 
     ViewPort* view_port = view_port_alloc();
@@ -468,15 +532,15 @@ void scope_scene_run_on_enter(void* context) {
         view_port_update(view_port);
     }
 
+    furi_hal_bus_disable(FuriHalBusTIM2);
+
     // Stop DMA and switch back to original vector table
-    HAL_ADC_Stop_DMA(&hadc1);
+    LL_DMA_DisableChannel(DMA1, LL_DMA_CHANNEL_1);
+
     __disable_irq();
     SCB->VTOR = 0;
     __enable_irq();
 
-    if(furi_hal_bus_is_enabled(FuriHalBusTIM2)) {
-        furi_hal_bus_disable(FuriHalBusTIM2);
-    }
     view_port_enabled_set(view_port, false);
     gui_remove_view_port(gui, view_port);
     view_port_free(view_port);

+ 0 - 1
non_catalog_apps/flipperscope/scenes/scope_types.h

@@ -3,7 +3,6 @@
 #include <furi.h>
 #include <furi_hal.h>
 
-#define S_VERSION_APP "0.0.1"
 #define S_DEVELOPED "anfractuosity"
 #define S_GITHUB "https://github.com/anfractuosity/flipperscope"
 

+ 2 - 7
non_catalog_apps/flipperscope/scope_app_i.h

@@ -18,13 +18,8 @@ typedef struct {
     char* str;
 } timeperiod;
 
-static const timeperiod time_list[] = {
-    {1.0, "1s"},
-    {0.1, "0.1s"},
-    {1e-3, "1ms"},
-    {0.1e-3, "0.1ms"},
-    {1e-6, "1us"},
-    {0.5e-6, "0.5us"}};
+static const timeperiod time_list[] =
+    {{1.0, "1s"}, {0.1, "0.1s"}, {1e-3, "1ms"}, {0.1e-3, "0.1ms"}, {1e-6, "1us"}};
 
 enum measureenum { m_time, m_voltage };
 

+ 1 - 0
non_catalog_apps/flipperzero-esp-flasher/application.fam

@@ -1,6 +1,7 @@
 App(
     appid="esp_flasher",
     name="ESP Flasher",
+    fap_version=(1,1),
     apptype=FlipperAppType.EXTERNAL,
     entry_point="esp_flasher_app",
     requires=["gui"],

+ 5 - 0
non_catalog_apps/flipperzero-esp-flasher/docs/changelog.md

@@ -1,3 +1,8 @@
+## v1.1
+
+Auto-reset and notifications! For supported boards (RTS and DTR connected), flasher will now automatically enter the bootloader and reset the board. Also added notifications for user feedback (blue LED for duration of flash, vibrate when done).
+
+
 ## v1.0
 
 Initial ESP flasher release! Supports hardcoded addresses for bootloader, partition table, NVS, boot_app0, and firmware, with a toggle for ESP32-S3 (different bootloader address).

+ 5 - 0
non_catalog_apps/flipperzero-esp-flasher/esp_flasher_app.c

@@ -27,6 +27,7 @@ EspFlasherApp* esp_flasher_app_alloc() {
     app->gui = furi_record_open(RECORD_GUI);
     app->dialogs = furi_record_open(RECORD_DIALOGS);
     app->storage = furi_record_open(RECORD_STORAGE);
+    app->notification = furi_record_open(RECORD_NOTIFICATION);
 
     app->view_dispatcher = view_dispatcher_alloc();
     app->scene_manager = scene_manager_alloc(&esp_flasher_scene_handlers, app);
@@ -65,6 +66,9 @@ EspFlasherApp* esp_flasher_app_alloc() {
 
     app->flash_worker_busy = false;
 
+    app->reset = false;
+    app->boot = false;
+
     scene_manager_next_scene(app->scene_manager, EspFlasherSceneStart);
 
     return app;
@@ -103,6 +107,7 @@ void esp_flasher_app_free(EspFlasherApp* app) {
     furi_record_close(RECORD_GUI);
     furi_record_close(RECORD_STORAGE);
     furi_record_close(RECORD_DIALOGS);
+    furi_record_close(RECORD_NOTIFICATION);
 
     free(app);
 }

+ 1 - 1
non_catalog_apps/flipperzero-esp-flasher/esp_flasher_app.h

@@ -4,7 +4,7 @@
 extern "C" {
 #endif
 
-#define ESP_FLASHER_APP_VERSION "v1.0"
+#define ESP_FLASHER_APP_VERSION "v1.1"
 
 typedef struct EspFlasherApp EspFlasherApp;
 

+ 5 - 0
non_catalog_apps/flipperzero-esp-flasher/esp_flasher_app_i.h

@@ -20,6 +20,7 @@
 #include <storage/storage.h>
 #include <lib/toolbox/path.h>
 #include <dialogs/dialogs.h>
+#include <notification/notification_messages.h>
 
 #define ESP_FLASHER_TEXT_BOX_STORE_SIZE (4096)
 
@@ -47,6 +48,7 @@ struct EspFlasherApp {
     TextBox* text_box;
     Storage* storage;
     DialogsApp* dialogs;
+    NotificationApp* notification;
 
     VariableItemList* var_item_list;
     Widget* widget;
@@ -54,6 +56,9 @@ struct EspFlasherApp {
 
     EspFlasherUart* uart;
 
+    bool reset;
+    bool boot;
+
     bool selected_flash_options[NUM_FLASH_OPTIONS];
     int num_selected_flash_options;
     char bin_file_path_boot[100];

+ 74 - 3
non_catalog_apps/flipperzero-esp-flasher/esp_flasher_worker.c

@@ -131,6 +131,9 @@ static int32_t esp_flasher_flash_bin(void* context) {
     flash_rx_stream = furi_stream_buffer_alloc(RX_BUF_SIZE, 1);
     timer = furi_timer_alloc(_timer_callback, FuriTimerTypePeriodic, app);
 
+    // turn on flipper blue LED for duration of flash
+    notification_message(app->notification, &sequence_set_only_blue_255);
+
     loader_port_debug_print("Connecting\n");
     esp_loader_connect_args_t connect_config = ESP_LOADER_CONNECT_DEFAULT();
     err = esp_loader_connect(&connect_config);
@@ -169,9 +172,20 @@ static int32_t esp_flasher_flash_bin(void* context) {
         loader_port_debug_print("Restoring transmission rate\n");
         furi_hal_uart_set_br(FuriHalUartIdUSART1, 115200);
 #endif
-        loader_port_debug_print("Done flashing. Please reset the board manually.\n");
+        loader_port_debug_print("Done flashing. Please reset the board manually if it doesn't auto-reset.\n");
+
+        // auto-reset for supported boards
+        loader_port_reset_target();
+
+        // short buzz to alert user
+        notification_message(app->notification, &sequence_set_vibro_on);
+        loader_port_delay_ms(50);
+        notification_message(app->notification, &sequence_reset_vibro);
     }
 
+    // turn off flipper blue LED
+    notification_message(app->notification, &sequence_reset_blue);
+
     // done
     app->flash_worker_busy = false;
 
@@ -182,6 +196,48 @@ static int32_t esp_flasher_flash_bin(void* context) {
     return 0;
 }
 
+static void _initDTR(void) {
+    furi_hal_gpio_init(&gpio_ext_pc3, GpioModeOutputPushPull, GpioPullDown, GpioSpeedVeryHigh);
+}
+
+static void _initRTS(void) {
+    furi_hal_gpio_init(&gpio_ext_pb2, GpioModeOutputPushPull, GpioPullDown, GpioSpeedVeryHigh);
+}
+
+static void _setDTR(bool state) {
+    furi_hal_gpio_write(&gpio_ext_pc3, state);
+}
+
+static void _setRTS(bool state) {
+    furi_hal_gpio_write(&gpio_ext_pb2, state);
+}
+
+static int32_t esp_flasher_reset(void* context) {
+    EspFlasherApp* app = (void*)context;
+
+    app->flash_worker_busy = true;
+
+    _setDTR(false);
+    _initDTR();
+    _setRTS(false);
+    _initRTS();
+
+    if (app->reset) {
+        loader_port_debug_print("Resetting board\n");
+        loader_port_reset_target();
+    } else if (app->boot) {
+        loader_port_debug_print("Entering bootloader\n");
+        loader_port_enter_bootloader();
+    }
+
+    // done
+    app->flash_worker_busy = false;
+    app->reset = false;
+    app->boot = false;
+
+    return 0;
+}
+
 void esp_flasher_worker_start_thread(EspFlasherApp* app) {
     global_app = app;
 
@@ -189,7 +245,11 @@ void esp_flasher_worker_start_thread(EspFlasherApp* app) {
     furi_thread_set_name(app->flash_worker, "EspFlasherFlashWorker");
     furi_thread_set_stack_size(app->flash_worker, 2048);
     furi_thread_set_context(app->flash_worker, app);
-    furi_thread_set_callback(app->flash_worker, esp_flasher_flash_bin);
+    if (app->reset || app->boot) {
+        furi_thread_set_callback(app->flash_worker, esp_flasher_reset);
+    } else {
+        furi_thread_set_callback(app->flash_worker, esp_flasher_flash_bin);
+    }
     furi_thread_start(app->flash_worker);
 }
 
@@ -213,8 +273,19 @@ esp_loader_error_t loader_port_write(const uint8_t* data, uint16_t size, uint32_
     return ESP_LOADER_SUCCESS;
 }
 
+void loader_port_reset_target(void) {
+    _setDTR(true);
+    loader_port_delay_ms(SERIAL_FLASHER_RESET_HOLD_TIME_MS);
+    _setDTR(false);
+}
+
 void loader_port_enter_bootloader(void) {
-    // unimplemented
+    _setDTR(true);
+    loader_port_delay_ms(SERIAL_FLASHER_RESET_HOLD_TIME_MS);
+    _setRTS(true);
+    _setDTR(false);
+    loader_port_delay_ms(SERIAL_FLASHER_BOOT_HOLD_TIME_MS);
+    _setRTS(false);
 }
 
 void loader_port_delay_ms(uint32_t ms) {

+ 4 - 0
non_catalog_apps/flipperzero-esp-flasher/esp_flasher_worker.h

@@ -2,7 +2,11 @@
 
 #include "esp_flasher_app_i.h"
 #include "esp_flasher_uart.h"
+#ifndef SERIAL_FLASHER_INTERFACE_UART
 #define SERIAL_FLASHER_INTERFACE_UART /* TODO why is application.fam not passing this via cdefines */
+#endif
+#define SERIAL_FLASHER_RESET_HOLD_TIME_MS 100
+#define SERIAL_FLASHER_BOOT_HOLD_TIME_MS 50
 #include "esp_loader_io.h"
 
 #define ESP_ADDR_BOOT_S3 0x0

+ 22 - 0
non_catalog_apps/flipperzero-esp-flasher/scenes/esp_flasher_scene_start.c

@@ -3,6 +3,8 @@
 enum SubmenuIndex {
     SubmenuIndexEspFlasherFlash,
     SubmenuIndexEspFlasherAbout,
+    SubmenuIndexEspFlasherReset,
+    SubmenuIndexEspFlasherBootloader,
 };
 
 void esp_flasher_scene_start_submenu_callback(void* context, uint32_t index) {
@@ -23,6 +25,18 @@ void esp_flasher_scene_start_on_enter(void* context) {
         SubmenuIndexEspFlasherFlash,
         esp_flasher_scene_start_submenu_callback,
         app);
+    submenu_add_item(
+        submenu,
+        "Reset Board",
+        SubmenuIndexEspFlasherReset,
+        esp_flasher_scene_start_submenu_callback,
+        app);
+    submenu_add_item(
+        submenu,
+        "Enter Bootloader",
+        SubmenuIndexEspFlasherBootloader,
+        esp_flasher_scene_start_submenu_callback,
+        app);
     submenu_add_item(
         submenu,
         "About",
@@ -48,6 +62,14 @@ bool esp_flasher_scene_start_on_event(void* context, SceneManagerEvent event) {
         } else if(event.event == SubmenuIndexEspFlasherFlash) {
             scene_manager_next_scene(app->scene_manager, EspFlasherSceneBrowse);
             consumed = true;
+        } else if(event.event == SubmenuIndexEspFlasherReset) {
+            app->reset = true;
+            scene_manager_next_scene(app->scene_manager, EspFlasherSceneConsoleOutput);
+            consumed = true;
+        } else if(event.event == SubmenuIndexEspFlasherBootloader) {
+            app->boot = true;
+            scene_manager_next_scene(app->scene_manager, EspFlasherSceneConsoleOutput);
+            consumed = true;
         }
         scene_manager_set_scene_state(app->scene_manager, EspFlasherSceneStart, event.event);
     }

+ 20 - 20
non_catalog_apps/seader/ccid.c

@@ -18,7 +18,7 @@ uint8_t getSequence() {
     return sequence++;
 }
 
-size_t addLRC(uint8_t* data, size_t len) {
+size_t seader_ccid_add_lrc(uint8_t* data, size_t len) {
     uint8_t lrc = 0;
     for(size_t i = 0; i < len; i++) {
         lrc ^= data[i];
@@ -27,7 +27,7 @@ size_t addLRC(uint8_t* data, size_t len) {
     return len + 1;
 }
 
-void PC_to_RDR_IccPowerOn(SeaderUartBridge* seader_uart) {
+void seader_ccid_IccPowerOn(SeaderUartBridge* seader_uart) {
     if(powered) {
         return;
     }
@@ -42,18 +42,18 @@ void PC_to_RDR_IccPowerOn(SeaderUartBridge* seader_uart) {
     seader_uart->tx_buf[2 + 6] = getSequence();
     seader_uart->tx_buf[2 + 7] = 2; //power
 
-    seader_uart->tx_len = addLRC(seader_uart->tx_buf, 2 + 10);
+    seader_uart->tx_len = seader_ccid_add_lrc(seader_uart->tx_buf, 2 + 10);
     furi_thread_flags_set(furi_thread_get_id(seader_uart->tx_thread), WorkerEvtSamRx);
 }
 
-void check_for_sam(SeaderUartBridge* seader_uart) {
+void seader_ccid_check_for_sam(SeaderUartBridge* seader_uart) {
     hasSAM = false; // If someone is calling this, reset sam state
     powered = false;
-    PC_to_RDR_GetSlotStatus(seader_uart);
+    seader_ccid_GetSlotStatus(seader_uart);
 }
 
-void PC_to_RDR_GetSlotStatus(SeaderUartBridge* seader_uart) {
-    FURI_LOG_D(TAG, "PC_to_RDR_GetSlotStatus");
+void seader_ccid_GetSlotStatus(SeaderUartBridge* seader_uart) {
+    FURI_LOG_D(TAG, "seader_ccid_GetSlotStatus");
     memset(seader_uart->tx_buf, 0, SEADER_UART_RX_BUF_SIZE);
     seader_uart->tx_buf[0] = SYNC;
     seader_uart->tx_buf[1] = CTRL;
@@ -61,11 +61,11 @@ void PC_to_RDR_GetSlotStatus(SeaderUartBridge* seader_uart) {
     seader_uart->tx_buf[2 + 5] = slot;
     seader_uart->tx_buf[2 + 6] = getSequence();
 
-    seader_uart->tx_len = addLRC(seader_uart->tx_buf, 2 + 10);
+    seader_uart->tx_len = seader_ccid_add_lrc(seader_uart->tx_buf, 2 + 10);
     furi_thread_flags_set(furi_thread_get_id(seader_uart->tx_thread), WorkerEvtSamRx);
 }
 
-void PC_to_RDR_SetParameters(SeaderUartBridge* seader_uart) {
+void seader_ccid_SetParameters(SeaderUartBridge* seader_uart) {
     uint8_t T1 = 1;
     memset(seader_uart->tx_buf, 0, SEADER_UART_RX_BUF_SIZE);
     seader_uart->tx_buf[0] = SYNC;
@@ -78,12 +78,12 @@ void PC_to_RDR_SetParameters(SeaderUartBridge* seader_uart) {
     seader_uart->tx_buf[2 + 8] = 0;
     seader_uart->tx_buf[2 + 9] = 0;
 
-    seader_uart->tx_len = addLRC(seader_uart->tx_buf, 2 + 10);
+    seader_uart->tx_len = seader_ccid_add_lrc(seader_uart->tx_buf, 2 + 10);
 
     furi_thread_flags_set(furi_thread_get_id(seader_uart->tx_thread), WorkerEvtSamRx);
 }
 
-void PC_to_RDR_GetParameters(SeaderUartBridge* seader_uart) {
+void seader_ccid_GetParameters(SeaderUartBridge* seader_uart) {
     memset(seader_uart->tx_buf, 0, SEADER_UART_RX_BUF_SIZE);
     seader_uart->tx_buf[0] = SYNC;
     seader_uart->tx_buf[1] = CTRL;
@@ -95,12 +95,12 @@ void PC_to_RDR_GetParameters(SeaderUartBridge* seader_uart) {
     seader_uart->tx_buf[2 + 8] = 0;
     seader_uart->tx_buf[2 + 9] = 0;
 
-    seader_uart->tx_len = addLRC(seader_uart->tx_buf, 2 + 10);
+    seader_uart->tx_len = seader_ccid_add_lrc(seader_uart->tx_buf, 2 + 10);
 
     furi_thread_flags_set(furi_thread_get_id(seader_uart->tx_thread), WorkerEvtSamRx);
 }
 
-void PC_to_RDR_XfrBlock(SeaderUartBridge* seader_uart, uint8_t* data, size_t len) {
+void seader_ccid_XfrBlock(SeaderUartBridge* seader_uart, uint8_t* data, size_t len) {
     memset(seader_uart->tx_buf, 0, SEADER_UART_RX_BUF_SIZE);
     seader_uart->tx_buf[0] = SYNC;
     seader_uart->tx_buf[1] = CTRL;
@@ -113,13 +113,13 @@ void PC_to_RDR_XfrBlock(SeaderUartBridge* seader_uart, uint8_t* data, size_t len
     seader_uart->tx_buf[2 + 9] = 0;
 
     memcpy(seader_uart->tx_buf + 2 + 10, data, len);
-    seader_uart->tx_len = addLRC(seader_uart->tx_buf, 2 + 10 + len);
-    // FURI_LOG_I(TAG, "PC_to_RDR_XfrBlock %d bytes", seader_uart->tx_len);
+    seader_uart->tx_len = seader_ccid_add_lrc(seader_uart->tx_buf, 2 + 10 + len);
+    // FURI_LOG_I(TAG, "seader_ccid_XfrBlock %d bytes", seader_uart->tx_len);
 
     furi_thread_flags_set(furi_thread_get_id(seader_uart->tx_thread), WorkerEvtSamRx);
 }
 
-size_t processCCID(SeaderWorker* seader_worker, uint8_t* cmd, size_t cmd_len) {
+size_t seader_ccid_process(SeaderWorker* seader_worker, uint8_t* cmd, size_t cmd_len) {
     SeaderUartBridge* seader_uart = seader_worker->uart;
     CCID_Message message;
     message.consumed = 0;
@@ -144,14 +144,14 @@ size_t processCCID(SeaderWorker* seader_worker, uint8_t* cmd, size_t cmd_len) {
                 retries = 0;
                 slot = 0;
                 sequence = 0;
-                PC_to_RDR_IccPowerOn(seader_uart);
+                seader_ccid_IccPowerOn(seader_uart);
                 break;
             case CARD_IN_2:
                 FURI_LOG_D(TAG, "Card Inserted (2)");
                 retries = 0;
                 slot = 1;
                 sequence = 0;
-                PC_to_RDR_IccPowerOn(seader_uart);
+                seader_ccid_IccPowerOn(seader_uart);
                 break;
             case CARD_IN_BOTH:
                 FURI_LOG_W(TAG, "Loading 2 cards not supported");
@@ -194,13 +194,13 @@ size_t processCCID(SeaderWorker* seader_worker, uint8_t* cmd, size_t cmd_len) {
         if(message.bMessageType == CCID_MESSAGE_TYPE_RDR_to_PC_SlotStatus) {
             uint8_t status = (message.bStatus & BMICCSTATUS_MASK);
             if(status == 0 || status == 1) {
-                PC_to_RDR_IccPowerOn(seader_uart);
+                seader_ccid_IccPowerOn(seader_uart);
                 return message.consumed;
             } else if(status == 2) {
                 FURI_LOG_W(TAG, "No ICC is present [retries %d]", retries);
                 if(retries-- > 1 && hasSAM == false) {
                     furi_delay_ms(100);
-                    PC_to_RDR_GetSlotStatus(seader_uart);
+                    seader_ccid_GetSlotStatus(seader_uart);
                 } else {
                     if(seader_worker->callback) {
                         seader_worker->callback(

+ 7 - 7
non_catalog_apps/seader/ccid.h

@@ -82,10 +82,10 @@ struct CCID_Message {
     size_t consumed;
 };
 
-void check_for_sam(SeaderUartBridge* seader_uart);
-void PC_to_RDR_IccPowerOn(SeaderUartBridge* seader_uart);
-void PC_to_RDR_GetSlotStatus(SeaderUartBridge* seader_uart);
-void PC_to_RDR_SetParameters(SeaderUartBridge* seader_uart);
-void PC_to_RDR_GetParameters(SeaderUartBridge* seader_uart);
-void PC_to_RDR_XfrBlock(SeaderUartBridge* seader_uart, uint8_t* data, size_t len);
-size_t processCCID(SeaderWorker* seader_worker, uint8_t* cmd, size_t cmd_len);
+void seader_ccid_check_for_sam(SeaderUartBridge* seader_uart);
+void seader_ccid_IccPowerOn(SeaderUartBridge* seader_uart);
+void seader_ccid_GetSlotStatus(SeaderUartBridge* seader_uart);
+void seader_ccid_SetParameters(SeaderUartBridge* seader_uart);
+void seader_ccid_GetParameters(SeaderUartBridge* seader_uart);
+void seader_ccid_XfrBlock(SeaderUartBridge* seader_uart, uint8_t* data, size_t len);
+size_t seader_ccid_process(SeaderWorker* seader_worker, uint8_t* cmd, size_t cmd_len);

+ 13 - 0
non_catalog_apps/seader/scenes/seader_scene_card_menu.c

@@ -5,6 +5,7 @@ enum SubmenuIndex {
     SubmenuIndexSavePicopass,
     SubmenuIndexSaveRFID,
     SubmenuIndexSaveSR,
+    SubmenuIndexSaveMFC,
 };
 
 void seader_scene_card_menu_submenu_callback(void* context, uint32_t index) {
@@ -42,6 +43,12 @@ void seader_scene_card_menu_on_enter(void* context) {
                 seader_scene_card_menu_submenu_callback,
                 seader);
         }
+        submenu_add_item(
+            submenu,
+            "Save MFC",
+            SubmenuIndexSaveMFC,
+            seader_scene_card_menu_submenu_callback,
+            seader);
     }
 
     submenu_set_selected_item(
@@ -79,6 +86,12 @@ bool seader_scene_card_menu_on_event(void* context, SceneManagerEvent event) {
             seader->credential->save_format = SeaderCredentialSaveFormatSR;
             scene_manager_next_scene(seader->scene_manager, SeaderSceneSaveName);
             consumed = true;
+        } else if(event.event == SubmenuIndexSaveMFC) {
+            scene_manager_set_scene_state(
+                seader->scene_manager, SeaderSceneCardMenu, SubmenuIndexSaveMFC);
+            seader->credential->save_format = SeaderCredentialSaveFormatMFC;
+            scene_manager_next_scene(seader->scene_manager, SeaderSceneSaveName);
+            consumed = true;
         }
     } else if(event.type == SceneManagerEventTypeBack) {
         consumed = scene_manager_search_and_switch_to_previous_scene(

+ 251 - 3
non_catalog_apps/seader/seader_credential.c

@@ -103,6 +103,242 @@ static bool seader_credential_load(SeaderCredential* cred, FuriString* path, boo
     return parsed;
 }
 
+bool seader_credential_save_mfc(SeaderCredential* cred, const char* name) {
+    furi_assert(cred);
+
+    static const char* nfc_file_header = "Flipper NFC device";
+    static const uint32_t nfc_file_version = 3;
+    static const uint32_t nfc_mifare_classic_data_format_version = 2;
+
+    uint8_t uid[4] = {0xDF, 0xC6, 0x9C, 0x05};
+    uint8_t atqa[2] = {0x00, 0x04};
+    uint8_t sak = 0x08;
+    uint8_t manuf_block[16] = {
+        0xDF,
+        0xC6,
+        0x9C,
+        0x05,
+        0x80,
+        0x08,
+        0x04,
+        0x00,
+        0x00,
+        0x00,
+        0x73,
+        0x65,
+        0x61,
+        0x64,
+        0x65,
+        0x72};
+    uint8_t sector0_trailer[16] = {
+        0xa0,
+        0xa1,
+        0xa2,
+        0xa3,
+        0xa4,
+        0xa5,
+        0x78,
+        0x77,
+        0x88,
+        0xc1,
+        0x89,
+        0xec,
+        0xa9,
+        0x7f,
+        0x8c,
+        0x2a};
+    uint8_t sector1_trailer[16] = {
+        0x48,
+        0x49,
+        0x44,
+        0x20,
+        0x49,
+        0x53,
+        0x78,
+        0x77,
+        0x88,
+        0xaa,
+        0x20,
+        0x47,
+        0x52,
+        0x45,
+        0x41,
+        0x54};
+    uint8_t sectorn_trailer[16] = {
+        0xff,
+        0xff,
+        0xff,
+        0xff,
+        0xff,
+        0xff,
+        0xff,
+        0x07,
+        0x80,
+        0x69,
+        0xff,
+        0xff,
+        0xff,
+        0xff,
+        0xff,
+        0xff};
+    uint8_t mad_block[16] = {
+        0x1b,
+        0x01,
+        0x4d,
+        0x48,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00};
+    uint8_t empty_block[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+    uint8_t pacs_block[16] = {0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+
+    bool use_load_path = true;
+    bool saved = false;
+    FlipperFormat* file = flipper_format_file_alloc(cred->storage);
+    FuriString* temp_str;
+    temp_str = furi_string_alloc();
+
+    uint64_t sentinel = 1ULL << cred->bit_length;
+    uint64_t swapped = __builtin_bswap64(cred->credential | sentinel);
+    memcpy(pacs_block + 8, &swapped, sizeof(swapped));
+
+    do {
+        if(use_load_path && !furi_string_empty(cred->load_path)) {
+            // Get directory name
+            path_extract_dirname(furi_string_get_cstr(cred->load_path), temp_str);
+            // Make path to file to save
+            furi_string_cat_printf(temp_str, "/%s%s", name, SEADER_APP_MFC_EXTENSION);
+        } else {
+            furi_string_printf(
+                temp_str, "%s/%s%s", SEADER_APP_MFC_FOLDER, name, SEADER_APP_MFC_EXTENSION);
+        }
+
+        FURI_LOG_D(TAG, "Save as MFC [%s]", furi_string_get_cstr(temp_str));
+
+        // Open file
+        if(!flipper_format_file_open_always(file, furi_string_get_cstr(temp_str))) break;
+        if(!flipper_format_write_header_cstr(file, nfc_file_header, nfc_file_version)) break;
+        // Write nfc device type
+        if(!flipper_format_write_comment_cstr(
+               file, "Nfc device type can be UID, Mifare Ultralight, Mifare Classic or ISO15693"))
+            break;
+        furi_string_set(temp_str, "Mifare Classic");
+        if(!flipper_format_write_string(file, "Device type", temp_str)) break;
+        // Write UID
+        if(!flipper_format_write_comment_cstr(file, "UID is common for all formats")) break;
+        if(!flipper_format_write_hex(file, "UID", uid, 4)) break;
+        // Write ATQA, SAK
+        if(!flipper_format_write_comment_cstr(file, "ISO14443 specific fields")) break;
+        // Save ATQA in MSB order for correct companion apps display
+        if(!flipper_format_write_hex(file, "ATQA", atqa, 2)) break;
+        if(!flipper_format_write_hex(file, "SAK", &sak, 1)) break;
+        if(!flipper_format_write_comment_cstr(file, "Mifare Classic specific data")) break;
+        if(!flipper_format_write_comment_cstr(file, "Made with Seader")) break;
+        if(!flipper_format_write_string_cstr(file, "Mifare Classic type", "1K")) break;
+        uint8_t blocks = 64;
+
+        if(!flipper_format_write_uint32(
+               file, "Data format version", &nfc_mifare_classic_data_format_version, 1))
+            break;
+        if(!flipper_format_write_comment_cstr(
+               file, "Mifare Classic blocks, \'??\' means unknown data"))
+            break;
+        bool block_saved = true;
+        FuriString* block_str;
+        block_str = furi_string_alloc();
+        for(size_t i = 0; i < blocks; i++) {
+            furi_string_printf(temp_str, "Block %d", i);
+            switch(i) {
+            case 0:
+                if(!flipper_format_write_hex(
+                       file, furi_string_get_cstr(temp_str), manuf_block, sizeof(manuf_block))) {
+                    block_saved = false;
+                }
+                break;
+            case 1:
+                if(!flipper_format_write_hex(
+                       file, furi_string_get_cstr(temp_str), mad_block, sizeof(mad_block))) {
+                    block_saved = false;
+                }
+                break;
+            case 3:
+                if(!flipper_format_write_hex(
+                       file,
+                       furi_string_get_cstr(temp_str),
+                       sector0_trailer,
+                       sizeof(sector0_trailer))) {
+                    block_saved = false;
+                }
+                break;
+            case 5:
+                if(!flipper_format_write_hex(
+                       file, furi_string_get_cstr(temp_str), pacs_block, sizeof(pacs_block))) {
+                    block_saved = false;
+                }
+                break;
+            case 7:
+                if(!flipper_format_write_hex(
+                       file,
+                       furi_string_get_cstr(temp_str),
+                       sector1_trailer,
+                       sizeof(sector1_trailer))) {
+                    block_saved = false;
+                }
+                break;
+            // Trailers
+            case 11:
+            case 15:
+            case 19:
+            case 23:
+            case 27:
+            case 31:
+            case 35:
+            case 39:
+            case 43:
+            case 47:
+            case 51:
+            case 55:
+            case 59:
+            case 63:
+                if(!flipper_format_write_hex(
+                       file,
+                       furi_string_get_cstr(temp_str),
+                       sectorn_trailer,
+                       sizeof(sectorn_trailer))) {
+                    block_saved = false;
+                }
+                break;
+            default:
+                if(!flipper_format_write_hex(
+                       file, furi_string_get_cstr(temp_str), empty_block, sizeof(empty_block))) {
+                    block_saved = false;
+                }
+                break;
+            }
+        }
+        furi_string_free(block_str);
+        if(!block_saved) break;
+
+        saved = true;
+    } while(false);
+
+    if(!saved) {
+        dialog_message_show_storage_error(cred->dialogs, "Can not save\nfile");
+    }
+    furi_string_free(temp_str);
+    flipper_format_free(file);
+    return saved;
+}
+
 bool seader_credential_save_agnostic(SeaderCredential* cred, const char* name) {
     furi_assert(cred);
 
@@ -160,6 +396,8 @@ bool seader_credential_save(SeaderCredential* cred, const char* name) {
 
     if(cred->save_format == SeaderCredentialSaveFormatAgnostic) {
         return seader_credential_save_agnostic(cred, name);
+    } else if(cred->save_format == SeaderCredentialSaveFormatMFC) {
+        return seader_credential_save_mfc(cred, name);
     } else if(
         cred->save_format == SeaderCredentialSaveFormatPicopass ||
         cred->save_format == SeaderCredentialSaveFormatSR) {
@@ -195,9 +433,19 @@ bool seader_credential_save(SeaderCredential* cred, const char* name) {
                 furi_string_printf(temp_str, "Block %d", i);
                 switch(i) {
                 case CSN_INDEX:
-                    if(!flipper_format_write_hex(
-                           file, furi_string_get_cstr(temp_str), csn, sizeof(csn))) {
-                        block_saved = false;
+                    if(withSIO) {
+                        if(!flipper_format_write_hex(
+                               file,
+                               furi_string_get_cstr(temp_str),
+                               cred->diversifier,
+                               PICOPASS_BLOCK_LEN)) {
+                            block_saved = false;
+                        }
+                    } else {
+                        if(!flipper_format_write_hex(
+                               file, furi_string_get_cstr(temp_str), csn, sizeof(csn))) {
+                            block_saved = false;
+                        }
                     }
                     break;
                 case EPURSE_INDEX:

+ 3 - 0
non_catalog_apps/seader/seader_credential.h

@@ -7,6 +7,8 @@
 
 #define SEADER_CRED_NAME_MAX_LEN 22
 #define SEADER_APP_EXTENSION ".credential"
+#define SEADER_APP_MFC_EXTENSION ".nfc"
+#define SEADER_APP_MFC_FOLDER ANY_PATH("nfc")
 
 typedef void (*SeaderLoadingCallback)(void* context, bool state);
 
@@ -23,6 +25,7 @@ typedef enum {
     SeaderCredentialSaveFormatPicopass,
     SeaderCredentialSaveFormatRFID,
     SeaderCredentialSaveFormatSR,
+    SeaderCredentialSaveFormatMFC,
 } SeaderCredentialSaveFormat;
 
 typedef struct {

+ 139 - 79
non_catalog_apps/seader/seader_worker.c

@@ -21,7 +21,7 @@ char asn1_log[SEADER_UART_RX_BUF_SIZE] = {0};
 bool requestPacs = true;
 
 // Forward declaration
-void sendCardDetected(SeaderUartBridge* seader_uart, CardDetails_t* cardDetails);
+void seader_send_card_detected(SeaderUartBridge* seader_uart, CardDetails_t* cardDetails);
 
 static void seader_worker_enable_field() {
     furi_hal_nfc_ll_txrx_on();
@@ -35,6 +35,32 @@ static ReturnCode seader_worker_disable_field(ReturnCode rc) {
     return rc;
 }
 
+static uint16_t seader_worker_picopass_update_ccitt(uint16_t crcSeed, uint8_t dataByte) {
+    uint16_t crc = crcSeed;
+    uint8_t dat = dataByte;
+
+    dat ^= (uint8_t)(crc & 0xFFU);
+    dat ^= (dat << 4);
+
+    crc = (crc >> 8) ^ (((uint16_t)dat) << 8) ^ (((uint16_t)dat) << 3) ^ (((uint16_t)dat) >> 4);
+
+    return crc;
+}
+
+static uint16_t seader_worker_picopass_calculate_ccitt(
+    uint16_t preloadValue,
+    const uint8_t* buf,
+    uint16_t length) {
+    uint16_t crc = preloadValue;
+    uint16_t index;
+
+    for(index = 0; index < length; index++) {
+        crc = seader_worker_picopass_update_ccitt(crc, buf[index]);
+    }
+
+    return crc;
+}
+
 /***************************** Seader Worker API *******************************/
 
 SeaderWorker* seader_worker_alloc() {
@@ -109,17 +135,17 @@ void* calloc(size_t count, size_t size) {
     return malloc(count * size);
 }
 
-void nfc_scene_field_on_enter() {
+void seader_nfc_scene_field_on_enter() {
     furi_hal_nfc_field_on();
     furi_hal_nfc_exit_sleep();
 }
 
-void nfc_scene_field_on_exit() {
+void seader_nfc_scene_field_on_exit() {
     furi_hal_nfc_sleep();
     furi_hal_nfc_field_off();
 }
 
-bool sendAPDU(
+bool seader_send_apdu(
     SeaderUartBridge* seader_uart,
     uint8_t CLA,
     uint8_t INS,
@@ -140,12 +166,12 @@ bool sendAPDU(
     apdu[4] = length;
     memcpy(apdu + APDU_HEADER_LEN, payload, length);
 
-    PC_to_RDR_XfrBlock(seader_uart, apdu, APDU_HEADER_LEN + length);
+    seader_ccid_XfrBlock(seader_uart, apdu, APDU_HEADER_LEN + length);
     free(apdu);
     return true;
 }
 
-static int toString(const void* buffer, size_t size, void* app_key) {
+static int seader_asn_to_string(const void* buffer, size_t size, void* app_key) {
     if(app_key) {
         char* str = (char*)app_key;
         size_t next = strlen(str);
@@ -157,11 +183,11 @@ static int toString(const void* buffer, size_t size, void* app_key) {
     return 0;
 }
 
-bool mf_df_check_card_type(uint8_t ATQA0, uint8_t ATQA1, uint8_t SAK) {
+bool seader_mf_df_check_card_type(uint8_t ATQA0, uint8_t ATQA1, uint8_t SAK) {
     return ATQA0 == 0x44 && ATQA1 == 0x03 && SAK == 0x20;
 }
 
-bool mf_classic_check_card_type(uint8_t ATQA0, uint8_t ATQA1, uint8_t SAK) {
+bool seader_mf_classic_check_card_type(uint8_t ATQA0, uint8_t ATQA1, uint8_t SAK) {
     if((ATQA0 == 0x44 || ATQA0 == 0x04) && (SAK == 0x08 || SAK == 0x88 || SAK == 0x09)) {
         return true;
     } else if((ATQA0 == 0x01) && (ATQA1 == 0x0F) && (SAK == 0x01)) {
@@ -174,7 +200,7 @@ bool mf_classic_check_card_type(uint8_t ATQA0, uint8_t ATQA1, uint8_t SAK) {
     }
 }
 
-bool read_nfc(SeaderUartBridge* seader_uart) {
+bool seader_read_nfc(SeaderUartBridge* seader_uart) {
     FuriHalNfcDevData nfc_data = {};
     bool rtn = false;
     if(furi_hal_nfc_detect(&nfc_data, 300)) {
@@ -195,24 +221,24 @@ bool read_nfc(SeaderUartBridge* seader_uart) {
 
             uint8_t fake_seos_ats[] = {0x78, 0x77, 0x80, 0x02};
             uint8_t fake_desfire_ats[] = {0x75, 0x77, 0x81, 0x02, 0x80};
-            if(mf_df_check_card_type(nfc_data.atqa[0], nfc_data.atqa[1], nfc_data.sak)) {
+            if(seader_mf_df_check_card_type(nfc_data.atqa[0], nfc_data.atqa[1], nfc_data.sak)) {
                 FURI_LOG_D(TAG, "Desfire");
                 OCTET_STRING_t atqa = {.buf = fake_desfire_ats, .size = sizeof(fake_desfire_ats)};
                 cardDetails->atqa = &atqa;
-                sendCardDetected(seader_uart, cardDetails);
+                seader_send_card_detected(seader_uart, cardDetails);
                 rtn = true;
-            } else if(mf_classic_check_card_type(
+            } else if(seader_mf_classic_check_card_type(
                           nfc_data.atqa[0], nfc_data.atqa[1], nfc_data.sak)) {
                 FURI_LOG_D(TAG, "MFC");
                 OCTET_STRING_t atqa = {.buf = nfc_data.atqa, .size = sizeof(nfc_data.atqa)};
                 cardDetails->atqa = &atqa;
-                sendCardDetected(seader_uart, cardDetails);
+                seader_send_card_detected(seader_uart, cardDetails);
                 rtn = true;
             } else if(nfc_data.interface == FuriHalNfcInterfaceIsoDep) {
                 FURI_LOG_D(TAG, "ISO-DEP");
                 OCTET_STRING_t atqa = {.buf = fake_seos_ats, .size = sizeof(fake_seos_ats)};
                 cardDetails->atqa = &atqa;
-                sendCardDetected(seader_uart, cardDetails);
+                seader_send_card_detected(seader_uart, cardDetails);
                 rtn = true;
             }
             ASN_STRUCT_FREE(asn_DEF_CardDetails, cardDetails);
@@ -221,12 +247,12 @@ bool read_nfc(SeaderUartBridge* seader_uart) {
     return rtn;
 }
 
-bool detect_nfc(SeaderWorker* seader_worker) {
+bool seader_detect_nfc(SeaderWorker* seader_worker) {
     SeaderUartBridge* seader_uart = seader_worker->uart;
 
     while(seader_worker->state == SeaderWorkerStateRead14a) {
         // Card found
-        if(read_nfc(seader_uart)) {
+        if(seader_read_nfc(seader_uart)) {
             return true;
         }
 
@@ -235,7 +261,7 @@ bool detect_nfc(SeaderWorker* seader_worker) {
     return false;
 }
 
-void sendPayload(
+void seader_send_payload(
     SeaderUartBridge* seader_uart,
     Payload_t* payload,
     uint8_t to,
@@ -249,7 +275,8 @@ void sendPayload(
 #ifdef ASN1_DEBUG
     if(er.encoded > -1) {
         memset(payloadDebug, 0, sizeof(payloadDebug));
-        (&asn_DEF_Payload)->op->print_struct(&asn_DEF_Payload, payload, 1, toString, payloadDebug);
+        (&asn_DEF_Payload)
+            ->op->print_struct(&asn_DEF_Payload, payload, 1, seader_asn_to_string, payloadDebug);
         if(strlen(payloadDebug) > 0) {
             FURI_LOG_D(TAG, "Sending payload: %s", payloadDebug);
         }
@@ -261,10 +288,10 @@ void sendPayload(
     rBuffer[1] = from;
     rBuffer[2] = replyTo;
 
-    sendAPDU(seader_uart, 0xA0, 0xDA, 0x02, 0x63, rBuffer, 6 + er.encoded);
+    seader_send_apdu(seader_uart, 0xA0, 0xDA, 0x02, 0x63, rBuffer, 6 + er.encoded);
 }
 
-void sendResponse(
+void seader_send_response(
     SeaderUartBridge* seader_uart,
     Response_t* response,
     uint8_t to,
@@ -277,7 +304,7 @@ void sendResponse(
     payload->present = Payload_PR_response;
     payload->choice.response = *response;
 
-    sendPayload(seader_uart, payload, to, from, replyTo);
+    seader_send_payload(seader_uart, payload, to, from, replyTo);
 
     ASN_STRUCT_FREE(asn_DEF_Payload, payload);
 }
@@ -303,7 +330,7 @@ void sendRequestPacs(SeaderUartBridge* seader_uart) {
     payload->present = Payload_PR_samCommand;
     payload->choice.samCommand = *samCommand;
 
-    sendPayload(seader_uart, payload, 0x44, 0x0a, 0x44);
+    seader_send_payload(seader_uart, payload, 0x44, 0x0a, 0x44);
 
     ASN_STRUCT_FREE(asn_DEF_RequestPacs, requestPacs);
     ASN_STRUCT_FREE(asn_DEF_SamCommand, samCommand);
@@ -325,13 +352,13 @@ void seader_worker_send_version(SeaderWorker* seader_worker) {
     payload->present = Payload_PR_samCommand;
     payload->choice.samCommand = *samCommand;
 
-    sendPayload(seader_uart, payload, 0x44, 0x0a, 0x44);
+    seader_send_payload(seader_uart, payload, 0x44, 0x0a, 0x44);
 
     ASN_STRUCT_FREE(asn_DEF_SamCommand, samCommand);
     ASN_STRUCT_FREE(asn_DEF_Payload, payload);
 }
 
-void sendCardDetected(SeaderUartBridge* seader_uart, CardDetails_t* cardDetails) {
+void seader_send_card_detected(SeaderUartBridge* seader_uart, CardDetails_t* cardDetails) {
     CardDetected_t* cardDetected = 0;
     cardDetected = calloc(1, sizeof *cardDetected);
     assert(cardDetected);
@@ -352,14 +379,14 @@ void sendCardDetected(SeaderUartBridge* seader_uart, CardDetails_t* cardDetails)
     payload->present = Payload_PR_samCommand;
     payload->choice.samCommand = *samCommand;
 
-    sendPayload(seader_uart, payload, 0x44, 0x0a, 0x44);
+    seader_send_payload(seader_uart, payload, 0x44, 0x0a, 0x44);
 
     ASN_STRUCT_FREE(asn_DEF_CardDetected, cardDetected);
     ASN_STRUCT_FREE(asn_DEF_SamCommand, samCommand);
     ASN_STRUCT_FREE(asn_DEF_Payload, payload);
 }
 
-bool unpack_pacs(
+bool seader_unpack_pacs(
     SeaderWorker* seader_worker,
     SeaderCredential* seader_credential,
     uint8_t* buf,
@@ -373,7 +400,7 @@ bool unpack_pacs(
 
     if(rval.code == RC_OK) {
         char pacDebug[384] = {0};
-        (&asn_DEF_PAC)->op->print_struct(&asn_DEF_PAC, pac, 1, toString, pacDebug);
+        (&asn_DEF_PAC)->op->print_struct(&asn_DEF_PAC, pac, 1, seader_asn_to_string, pacDebug);
         if(strlen(pacDebug) > 0) {
             FURI_LOG_D(TAG, "Received pac: %s", pacDebug);
 
@@ -409,7 +436,7 @@ bool unpack_pacs(
 
 //    800201298106683d052026b6820101
 //300F800201298106683D052026B6820101
-bool parseVersion(SeaderWorker* seader_worker, uint8_t* buf, size_t size) {
+bool seader_parse_version(SeaderWorker* seader_worker, uint8_t* buf, size_t size) {
     SamVersion_t* version = 0;
     version = calloc(1, sizeof *version);
     assert(version);
@@ -431,7 +458,8 @@ bool parseVersion(SeaderWorker* seader_worker, uint8_t* buf, size_t size) {
     if(rval.code == RC_OK) {
         char versionDebug[128] = {0};
         (&asn_DEF_SamVersion)
-            ->op->print_struct(&asn_DEF_SamVersion, version, 1, toString, versionDebug);
+            ->op->print_struct(
+                &asn_DEF_SamVersion, version, 1, seader_asn_to_string, versionDebug);
         if(strlen(versionDebug) > 0) {
             FURI_LOG_D(TAG, "Received version: %s", versionDebug);
         }
@@ -446,7 +474,7 @@ bool parseVersion(SeaderWorker* seader_worker, uint8_t* buf, size_t size) {
     return rtn;
 }
 
-bool parseSamResponse(SeaderWorker* seader_worker, SamResponse_t* samResponse) {
+bool seader_parse_sam_response(SeaderWorker* seader_worker, SamResponse_t* samResponse) {
     SeaderUartBridge* seader_uart = seader_worker->uart;
     SeaderCredential* credential = seader_worker->credential;
 
@@ -461,9 +489,9 @@ bool parseSamResponse(SeaderWorker* seader_worker, SamResponse_t* samResponse) {
                 seader_worker->callback(SeaderWorkerEventFail, seader_worker->context);
             }
         }
-    } else if(parseVersion(seader_worker, samResponse->buf, samResponse->size)) {
+    } else if(seader_parse_version(seader_worker, samResponse->buf, samResponse->size)) {
         // no-op
-    } else if(unpack_pacs(seader_worker, credential, samResponse->buf, samResponse->size)) {
+    } else if(seader_unpack_pacs(seader_worker, credential, samResponse->buf, samResponse->size)) {
         if(seader_worker->callback) {
             seader_worker->callback(SeaderWorkerEventSuccess, seader_worker->context);
         }
@@ -478,10 +506,10 @@ bool parseSamResponse(SeaderWorker* seader_worker, SamResponse_t* samResponse) {
     return false;
 }
 
-bool parseResponse(SeaderWorker* seader_worker, Response_t* response) {
+bool seader_parse_response(SeaderWorker* seader_worker, Response_t* response) {
     switch(response->present) {
     case Response_PR_samResponse:
-        parseSamResponse(seader_worker, &response->choice.samResponse);
+        seader_parse_sam_response(seader_worker, &response->choice.samResponse);
         break;
     default:
         break;
@@ -489,7 +517,7 @@ bool parseResponse(SeaderWorker* seader_worker, Response_t* response) {
     return false;
 }
 
-void sendNFCRx(SeaderUartBridge* seader_uart, uint8_t* buffer, size_t len) {
+void seader_send_nfc_rx(SeaderUartBridge* seader_uart, uint8_t* buffer, size_t len) {
     OCTET_STRING_t rxData = {.buf = buffer, .size = len};
     uint8_t status[] = {0x00, 0x00};
     RfStatus_t rfStatus = {.buf = status, .size = 2};
@@ -515,14 +543,14 @@ void sendNFCRx(SeaderUartBridge* seader_uart, uint8_t* buffer, size_t len) {
     response->present = Response_PR_nfcResponse;
     response->choice.nfcResponse = *nfcResponse;
 
-    sendResponse(seader_uart, response, 0x14, 0x0a, 0x0);
+    seader_send_response(seader_uart, response, 0x14, 0x0a, 0x0);
 
     ASN_STRUCT_FREE(asn_DEF_NFCRx, nfcRx);
     ASN_STRUCT_FREE(asn_DEF_NFCResponse, nfcResponse);
     ASN_STRUCT_FREE(asn_DEF_Response, response);
 }
 
-bool iso14443aTransmit(SeaderWorker* seader_worker, uint8_t* buffer, size_t len) {
+bool seader_iso14443a_transmit(SeaderWorker* seader_worker, uint8_t* buffer, size_t len) {
     SeaderUartBridge* seader_uart = seader_worker->uart;
     FuriHalNfcTxRxContext tx_rx = {.tx_rx_type = FuriHalNfcTxRxTypeDefault};
     memcpy(&tx_rx.tx_data, buffer, len);
@@ -536,7 +564,7 @@ bool iso14443aTransmit(SeaderWorker* seader_worker, uint8_t* buffer, size_t len)
             snprintf(display + (i * 2), sizeof(display), "%02x", tx_rx.rx_data[i]);
         }
         // FURI_LOG_D(TAG, "NFC Response %d: %s", length, display);
-        sendNFCRx(seader_uart, tx_rx.rx_data, length);
+        seader_send_nfc_rx(seader_uart, tx_rx.rx_data, length);
     } else {
         FURI_LOG_W(TAG, "Bad exchange");
         if(seader_worker->callback) {
@@ -551,8 +579,13 @@ uint8_t read4Block6[] = {0x06, 0x06, 0x45, 0x56};
 uint8_t read4Block9[] = {0x06, 0x09, 0xB2, 0xAE};
 uint8_t read4Block10[] = {0x06, 0x0A, 0x29, 0x9C};
 uint8_t read4Block13[] = {0x06, 0x0D, 0x96, 0xE8};
+uint8_t updateBlock2[] = {0x87, 0x02};
 
-void handleSIO(uint8_t* buffer, size_t len, uint8_t* rxBuffer, SeaderCredential* credential) {
+void seader_capture_sio(
+    uint8_t* buffer,
+    size_t len,
+    uint8_t* rxBuffer,
+    SeaderCredential* credential) {
     if(memcmp(buffer, read4Block6, len) == 0 && rxBuffer[0] == 0x30) {
         memcpy(credential->sio, rxBuffer, 32);
     } else if(memcmp(buffer, read4Block10, len) == 0 && rxBuffer[0] == 0x30) {
@@ -564,7 +597,28 @@ void handleSIO(uint8_t* buffer, size_t len, uint8_t* rxBuffer, SeaderCredential*
     }
 }
 
-bool iso15693Transmit(SeaderWorker* seader_worker, uint8_t* buffer, size_t len) {
+FuriHalNfcReturn
+    seader_worker_fake_epurse_update(uint8_t* buffer, uint8_t* rxBuffer, uint16_t* recvLen) {
+    uint8_t fake_response[10];
+    memset(fake_response, 0, sizeof(fake_response));
+    memcpy(fake_response + 0, buffer + 6, 4);
+    memcpy(fake_response + 4, buffer + 2, 4);
+
+    uint16_t crc = seader_worker_picopass_calculate_ccitt(0xE012, fake_response, 8);
+    memcpy(fake_response + 8, &crc, sizeof(uint16_t));
+
+    memcpy(rxBuffer, fake_response, sizeof(fake_response));
+    *recvLen = sizeof(fake_response);
+
+    memset(display, 0, sizeof(display));
+    for(uint8_t i = 0; i < sizeof(fake_response); i++) {
+        snprintf(display + (i * 2), sizeof(display), "%02x", fake_response[i]);
+    }
+    FURI_LOG_I(TAG, "Fake update E-Purse response: %s", display);
+    return FuriHalNfcReturnOk;
+}
+
+bool seader_iso15693_transmit(SeaderWorker* seader_worker, uint8_t* buffer, size_t len) {
     SeaderUartBridge* seader_uart = seader_worker->uart;
     SeaderCredential* credential = seader_worker->credential;
     char display[SEADER_UART_RX_BUF_SIZE * 2 + 1] = {0};
@@ -574,7 +628,12 @@ bool iso15693Transmit(SeaderWorker* seader_worker, uint8_t* buffer, size_t len)
     uint32_t fwt = furi_hal_nfc_ll_ms2fc(20);
 
     uint8_t rxBuffer[64] = {0};
-    ret = furi_hal_nfc_ll_txrx(buffer, len, rxBuffer, sizeof(rxBuffer), &recvLen, flags, fwt);
+
+    if(memcmp(buffer, updateBlock2, sizeof(updateBlock2)) == 0) {
+        ret = seader_worker_fake_epurse_update(buffer, rxBuffer, &recvLen);
+    } else {
+        ret = furi_hal_nfc_ll_txrx(buffer, len, rxBuffer, sizeof(rxBuffer), &recvLen, flags, fwt);
+    }
 
     if(ret == FuriHalNfcReturnOk) {
         memset(display, 0, sizeof(display));
@@ -582,18 +641,16 @@ bool iso15693Transmit(SeaderWorker* seader_worker, uint8_t* buffer, size_t len)
             snprintf(display + (i * 2), sizeof(display), "%02x", rxBuffer[i]);
         }
         // FURI_LOG_D(TAG, "Result %d %s", recvLen, display);
-        handleSIO(buffer, len, rxBuffer, credential);
-
-        sendNFCRx(seader_uart, rxBuffer, recvLen);
+        seader_capture_sio(buffer, len, rxBuffer, credential);
+        seader_send_nfc_rx(seader_uart, rxBuffer, recvLen);
     } else if(ret == FuriHalNfcReturnCrc) {
         memset(display, 0, sizeof(display));
         for(uint8_t i = 0; i < recvLen; i++) {
             snprintf(display + (i * 2), sizeof(display), "%02x", rxBuffer[i]);
         }
         // FURI_LOG_D(TAG, "[CRC error] Result %d %s", recvLen, display);
-        handleSIO(buffer, len, rxBuffer, credential);
-
-        sendNFCRx(seader_uart, rxBuffer, recvLen);
+        seader_capture_sio(buffer, len, rxBuffer, credential);
+        seader_send_nfc_rx(seader_uart, rxBuffer, recvLen);
 
         // Act as if it was OK
         return true;
@@ -608,20 +665,22 @@ bool iso15693Transmit(SeaderWorker* seader_worker, uint8_t* buffer, size_t len)
     return ret == FuriHalNfcReturnOk;
 }
 
-bool parseNfcCommandTransmit(SeaderWorker* seader_worker, NFCSend_t* nfcSend) {
+bool seader_parse_nfc_command_transmit(SeaderWorker* seader_worker, NFCSend_t* nfcSend) {
     long timeOut = nfcSend->timeOut;
     Protocol_t protocol = nfcSend->protocol;
     FrameProtocol_t frameProtocol = protocol.buf[1];
 
 #ifdef ASN1_DEBUG
-    char display[SEADER_UART_RX_BUF_SIZE * 2 + 1] = {0};
+    memset(display, 0, sizeof(display));
     for(uint8_t i = 0; i < nfcSend->data.size; i++) {
         snprintf(display + (i * 2), sizeof(display), "%02x", nfcSend->data.buf[i]);
     }
 
     char protocolName[8] = {0};
+    memset(protocolName, 0, sizeof(protocolName));
     (&asn_DEF_FrameProtocol)
-        ->op->print_struct(&asn_DEF_FrameProtocol, &frameProtocol, 1, toString, protocolName);
+        ->op->print_struct(
+            &asn_DEF_FrameProtocol, &frameProtocol, 1, seader_asn_to_string, protocolName);
 
     FURI_LOG_D(
         TAG,
@@ -635,17 +694,17 @@ bool parseNfcCommandTransmit(SeaderWorker* seader_worker, NFCSend_t* nfcSend) {
 #endif
 
     if(frameProtocol == FrameProtocol_iclass) {
-        return iso15693Transmit(seader_worker, nfcSend->data.buf, nfcSend->data.size);
+        return seader_iso15693_transmit(seader_worker, nfcSend->data.buf, nfcSend->data.size);
     } else if(frameProtocol == FrameProtocol_nfc) {
-        return iso14443aTransmit(seader_worker, nfcSend->data.buf, nfcSend->data.size);
+        return seader_iso14443a_transmit(seader_worker, nfcSend->data.buf, nfcSend->data.size);
     }
     return false;
 }
 
-bool parseNfcOff(SeaderUartBridge* seader_uart) {
+bool seader_parse_nfc_off(SeaderUartBridge* seader_uart) {
     FURI_LOG_D(TAG, "Set Field Off");
     seader_worker_disable_field(ERR_NONE);
-    nfc_scene_field_on_exit();
+    seader_nfc_scene_field_on_exit();
 
     NFCResponse_t* nfcResponse = 0;
     nfcResponse = calloc(1, sizeof *nfcResponse);
@@ -660,7 +719,7 @@ bool parseNfcOff(SeaderUartBridge* seader_uart) {
     response->present = Response_PR_nfcResponse;
     response->choice.nfcResponse = *nfcResponse;
 
-    sendResponse(seader_uart, response, 0x44, 0x0a, 0);
+    seader_send_response(seader_uart, response, 0x44, 0x0a, 0);
 
     ASN_STRUCT_FREE(asn_DEF_Response, response);
     ASN_STRUCT_FREE(asn_DEF_NFCResponse, nfcResponse);
@@ -668,14 +727,14 @@ bool parseNfcOff(SeaderUartBridge* seader_uart) {
     return false;
 }
 
-bool parseNfcCommand(SeaderWorker* seader_worker, NFCCommand_t* nfcCommand) {
+bool seader_parse_nfc_command(SeaderWorker* seader_worker, NFCCommand_t* nfcCommand) {
     SeaderUartBridge* seader_uart = seader_worker->uart;
     switch(nfcCommand->present) {
     case NFCCommand_PR_nfcSend:
-        parseNfcCommandTransmit(seader_worker, &nfcCommand->choice.nfcSend);
+        seader_parse_nfc_command_transmit(seader_worker, &nfcCommand->choice.nfcSend);
         break;
     case NFCCommand_PR_nfcOff:
-        parseNfcOff(seader_uart);
+        seader_parse_nfc_off(seader_uart);
         break;
     default:
         FURI_LOG_W(TAG, "unparsed NFCCommand");
@@ -685,13 +744,13 @@ bool parseNfcCommand(SeaderWorker* seader_worker, NFCCommand_t* nfcCommand) {
     return false;
 }
 
-bool stateMachine(SeaderWorker* seader_worker, Payload_t* payload) {
+bool seader_worker_state_machine(SeaderWorker* seader_worker, Payload_t* payload) {
     switch(payload->present) {
     case Payload_PR_response:
-        parseResponse(seader_worker, &payload->choice.response);
+        seader_parse_response(seader_worker, &payload->choice.response);
         break;
     case Payload_PR_nfcCommand:
-        parseNfcCommand(seader_worker, &payload->choice.nfcCommand);
+        seader_parse_nfc_command(seader_worker, &payload->choice.nfcCommand);
         break;
     case Payload_PR_errorResponse:
         // TODO: screen saying this was a failure, or maybe start over?
@@ -707,7 +766,7 @@ bool stateMachine(SeaderWorker* seader_worker, Payload_t* payload) {
     return false;
 }
 
-bool processSuccessResponse(SeaderWorker* seader_worker, uint8_t* apdu, size_t len) {
+bool seader_process_success_response(SeaderWorker* seader_worker, uint8_t* apdu, size_t len) {
     Payload_t* payload = 0;
     payload = calloc(1, sizeof *payload);
     assert(payload);
@@ -717,19 +776,20 @@ bool processSuccessResponse(SeaderWorker* seader_worker, uint8_t* apdu, size_t l
     if(rval.code == RC_OK) {
 #ifdef ASN1_DEBUG
         memset(payloadDebug, 0, sizeof(payloadDebug));
-        (&asn_DEF_Payload)->op->print_struct(&asn_DEF_Payload, payload, 1, toString, payloadDebug);
+        (&asn_DEF_Payload)
+            ->op->print_struct(&asn_DEF_Payload, payload, 1, seader_asn_to_string, payloadDebug);
         if(strlen(payloadDebug) > 0) {
             FURI_LOG_D(TAG, "Received payload: %s", payloadDebug);
         }
 #endif
-        stateMachine(seader_worker, payload);
+        seader_worker_state_machine(seader_worker, payload);
     }
 
     ASN_STRUCT_FREE(asn_DEF_Payload, payload);
     return (rval.code == RC_OK);
 }
 
-bool processAPDU(SeaderWorker* seader_worker, uint8_t* apdu, size_t len) {
+bool seader_process_apdu(SeaderWorker* seader_worker, uint8_t* apdu, size_t len) {
     SeaderUartBridge* seader_uart = seader_worker->uart;
     if(len < 2) {
         return false;
@@ -749,14 +809,14 @@ bool processAPDU(SeaderWorker* seader_worker, uint8_t* apdu, size_t len) {
     case 0x61:
         // FURI_LOG_I(TAG, "Request %d bytes", SW2);
         GET_RESPONSE[4] = SW2;
-        PC_to_RDR_XfrBlock(seader_uart, GET_RESPONSE, sizeof(GET_RESPONSE));
+        seader_ccid_XfrBlock(seader_uart, GET_RESPONSE, sizeof(GET_RESPONSE));
         return true;
         break;
 
     case 0x90:
         if(SW2 == 0x00) {
             if(len > 2) {
-                return processSuccessResponse(seader_worker, apdu, len - 2);
+                return seader_process_success_response(seader_worker, apdu, len - 2);
             }
         }
         break;
@@ -765,7 +825,7 @@ bool processAPDU(SeaderWorker* seader_worker, uint8_t* apdu, size_t len) {
     return false;
 }
 
-ReturnCode picopass_card_init(SeaderWorker* seader_worker) {
+ReturnCode seader_picopass_card_init(SeaderWorker* seader_worker) {
     SeaderUartBridge* seader_uart = seader_worker->uart;
     SeaderCredential* credential = seader_worker->credential;
     rfalPicoPassIdentifyRes idRes;
@@ -803,13 +863,13 @@ ReturnCode picopass_card_init(SeaderWorker* seader_worker) {
 
     memcpy(credential->diversifier, selRes.CSN, RFAL_PICOPASS_MAX_BLOCK_LEN);
 
-    sendCardDetected(seader_uart, cardDetails);
+    seader_send_card_detected(seader_uart, cardDetails);
 
     ASN_STRUCT_FREE(asn_DEF_CardDetails, cardDetails);
     return ERR_NONE;
 }
 
-ReturnCode picopass_card_detect() {
+ReturnCode seader_picopass_card_detect() {
     ReturnCode err;
 
     err = rfalPicoPassPollerInitialize();
@@ -835,13 +895,13 @@ ReturnCode picopass_card_detect() {
     return ERR_NONE;
 }
 
-ReturnCode picopass_card_read(SeaderWorker* seader_worker) {
+ReturnCode seader_picopass_card_read(SeaderWorker* seader_worker) {
     ReturnCode err = ERR_TIMEOUT;
 
     while(seader_worker->state == SeaderWorkerStateReadPicopass) {
         // Card found
-        if(picopass_card_detect() == ERR_NONE) {
-            err = picopass_card_init(seader_worker);
+        if(seader_picopass_card_detect() == ERR_NONE) {
+            err = seader_picopass_card_init(seader_worker);
             if(err != ERR_NONE) {
                 FURI_LOG_E(TAG, "picopass_card_init error %d", err);
             }
@@ -855,7 +915,7 @@ ReturnCode picopass_card_read(SeaderWorker* seader_worker) {
 }
 
 void seader_worker_process_message(SeaderWorker* seader_worker, CCID_Message* message) {
-    if(processAPDU(seader_worker, message->payload, message->dwLength)) {
+    if(seader_process_apdu(seader_worker, message->payload, message->dwLength)) {
         // no-op
     } else {
         memset(display, 0, sizeof(display));
@@ -876,14 +936,14 @@ int32_t seader_worker_task(void* context) {
 
     if(seader_worker->state == SeaderWorkerStateCheckSam) {
         furi_delay_ms(1000);
-        check_for_sam(seader_uart);
+        seader_ccid_check_for_sam(seader_uart);
     } else if(seader_worker->state == SeaderWorkerStateReadPicopass) {
         FURI_LOG_D(TAG, "Read Picopass");
         requestPacs = true;
         seader_credential_clear(seader_worker->credential);
         seader_worker->credential->type = SeaderCredentialTypePicopass;
         seader_worker_enable_field();
-        if(picopass_card_read(seader_worker) != ERR_NONE) {
+        if(seader_picopass_card_read(seader_worker) != ERR_NONE) {
             // Turn off if cancelled / no card found
             seader_worker_disable_field(ERR_NONE);
         }
@@ -892,10 +952,10 @@ int32_t seader_worker_task(void* context) {
         requestPacs = true;
         seader_credential_clear(seader_worker->credential);
         seader_worker->credential->type = SeaderCredentialType14A;
-        nfc_scene_field_on_enter();
-        if(!detect_nfc(seader_worker)) {
+        seader_nfc_scene_field_on_enter();
+        if(!seader_detect_nfc(seader_worker)) {
             // Turn off if cancelled / no card found
-            nfc_scene_field_on_exit();
+            seader_nfc_scene_field_on_exit();
         }
     }
     FURI_LOG_D(TAG, "Worker Task Complete");

+ 1 - 1
non_catalog_apps/seader/uart.c

@@ -47,7 +47,7 @@ size_t seader_uart_process_buffer(Seader* seader, uint8_t* cmd, size_t cmd_len)
 
     size_t consumed = 0;
     do {
-        consumed = processCCID(seader_worker, cmd, cmd_len);
+        consumed = seader_ccid_process(seader_worker, cmd, cmd_len);
 
         if(consumed > 0) {
             memset(cmd, 0, consumed);

+ 15 - 0
non_catalog_apps/tpms_receiver/Readme.md

@@ -0,0 +1,15 @@
+# TPMS application for [Flipper Zero](https://flipperzero.one/)
+[![FlipC.org](https://flipc.org/wosk/flipperzero-tpms/badge)](https://flipc.org/wosk/flipperzero-tpms)
+
+## Features
+
+- Read [TPMS](https://en.wikipedia.org/wiki/Tire-pressure_monitoring_system) sensors
+- Relearn by 125kHz signal
+
+####  Supported sensors
+* Schrader GG4
+* Abarth 124 (soon)
+
+#### Feel free to contribute via PR or fill issue
+
+Code based on [weather station app](https://github.com/flipperdevices/flipperzero-firmware/tree/dev/applications/external/weather_station)

+ 13 - 0
non_catalog_apps/tpms_receiver/application.fam

@@ -0,0 +1,13 @@
+App(
+    appid="tpms",
+    name="TPMS Reader",
+    apptype=FlipperAppType.EXTERNAL,
+    targets=["f7"],
+    entry_point="tpms_app",
+    requires=["gui"],
+    stack_size=4 * 1024,
+    order=50,
+    fap_icon="tpms_10px.png",
+    fap_category="Sub-GHz",
+    fap_icon_assets="images",
+)

+ 69 - 0
non_catalog_apps/tpms_receiver/helpers/radio_device_loader.c

@@ -0,0 +1,69 @@
+#include "radio_device_loader.h"
+
+#include <applications/drivers/subghz/cc1101_ext/cc1101_ext_interconnect.h>
+#include <lib/subghz/devices/cc1101_int/cc1101_int_interconnect.h>
+
+static void radio_device_loader_power_on() {
+    uint8_t attempts = 0;
+    while(!furi_hal_power_is_otg_enabled() && attempts++ < 5) {
+        furi_hal_power_enable_otg();
+        //CC1101 power-up time
+        furi_delay_ms(10);
+    }
+}
+
+static void radio_device_loader_power_off() {
+    if(furi_hal_power_is_otg_enabled()) furi_hal_power_disable_otg();
+}
+
+bool radio_device_loader_is_connect_external(const char* name) {
+    bool is_connect = false;
+    bool is_otg_enabled = furi_hal_power_is_otg_enabled();
+
+    if(!is_otg_enabled) {
+        radio_device_loader_power_on();
+    }
+
+    const SubGhzDevice* device = subghz_devices_get_by_name(name);
+    if(device) {
+        is_connect = subghz_devices_is_connect(device);
+    }
+
+    if(!is_otg_enabled) {
+        radio_device_loader_power_off();
+    }
+    return is_connect;
+}
+
+const SubGhzDevice* radio_device_loader_set(
+    const SubGhzDevice* current_radio_device,
+    SubGhzRadioDeviceType radio_device_type) {
+    const SubGhzDevice* radio_device;
+
+    if(radio_device_type == SubGhzRadioDeviceTypeExternalCC1101 &&
+       radio_device_loader_is_connect_external(SUBGHZ_DEVICE_CC1101_EXT_NAME)) {
+        radio_device_loader_power_on();
+        radio_device = subghz_devices_get_by_name(SUBGHZ_DEVICE_CC1101_EXT_NAME);
+        subghz_devices_begin(radio_device);
+    } else if(current_radio_device == NULL) {
+        radio_device = subghz_devices_get_by_name(SUBGHZ_DEVICE_CC1101_INT_NAME);
+    } else {
+        radio_device_loader_end(current_radio_device);
+        radio_device = subghz_devices_get_by_name(SUBGHZ_DEVICE_CC1101_INT_NAME);
+    }
+
+    return radio_device;
+}
+
+bool radio_device_loader_is_external(const SubGhzDevice* radio_device) {
+    furi_assert(radio_device);
+    return (radio_device != subghz_devices_get_by_name(SUBGHZ_DEVICE_CC1101_INT_NAME));
+}
+
+void radio_device_loader_end(const SubGhzDevice* radio_device) {
+    furi_assert(radio_device);
+    radio_device_loader_power_off();
+    if(radio_device != subghz_devices_get_by_name(SUBGHZ_DEVICE_CC1101_INT_NAME)) {
+        subghz_devices_end(radio_device);
+    }
+}

+ 17 - 0
non_catalog_apps/tpms_receiver/helpers/radio_device_loader.h

@@ -0,0 +1,17 @@
+#pragma once
+
+#include <lib/subghz/devices/devices.h>
+
+/** SubGhzRadioDeviceType */
+typedef enum {
+    SubGhzRadioDeviceTypeInternal,
+    SubGhzRadioDeviceTypeExternalCC1101,
+} SubGhzRadioDeviceType;
+
+const SubGhzDevice* radio_device_loader_set(
+    const SubGhzDevice* current_radio_device,
+    SubGhzRadioDeviceType radio_device_type);
+
+bool radio_device_loader_is_external(const SubGhzDevice* radio_device);
+
+void radio_device_loader_end(const SubGhzDevice* radio_device);

+ 14 - 0
non_catalog_apps/tpms_receiver/helpers/tpms_event.h

@@ -0,0 +1,14 @@
+#pragma once
+
+typedef enum {
+    //TPMSCustomEvent
+    TPMSCustomEventStartId = 100,
+
+    TPMSCustomEventSceneSettingLock,
+
+    TPMSCustomEventViewReceiverOK,
+    TPMSCustomEventViewReceiverConfig,
+    TPMSCustomEventViewReceiverBack,
+    TPMSCustomEventViewReceiverOffDisplay,
+    TPMSCustomEventViewReceiverUnlock,
+} TPMSCustomEvent;

+ 58 - 0
non_catalog_apps/tpms_receiver/helpers/tpms_types.h

@@ -0,0 +1,58 @@
+#pragma once
+
+#include <furi.h>
+#include <furi_hal.h>
+
+#define TPMS_VERSION_APP "0.1"
+#define TPMS_DEVELOPED "wosk"
+#define TPMS_GITHUB "https://github.com/beewosk/flipperzero-tpms"
+
+#define TPMS_KEY_FILE_VERSION 1
+#define TPMS_KEY_FILE_TYPE "Flipper Tire Pressure Monitoring System Key File"
+
+/** TPMSRxKeyState state */
+typedef enum {
+    TPMSRxKeyStateIDLE,
+    TPMSRxKeyStateBack,
+    TPMSRxKeyStateStart,
+    TPMSRxKeyStateAddKey,
+} TPMSRxKeyState;
+
+/** TPMSHopperState state */
+typedef enum {
+    TPMSHopperStateOFF,
+    TPMSHopperStateRunnig,
+    TPMSHopperStatePause,
+    TPMSHopperStateRSSITimeOut,
+} TPMSHopperState;
+
+typedef enum {
+    TPMSLockOff,
+    TPMSLockOn,
+} TPMSLock;
+
+typedef enum {
+    TPMSViewVariableItemList,
+    TPMSViewSubmenu,
+    TPMSViewReceiver,
+    TPMSViewReceiverInfo,
+    TPMSViewWidget,
+} TPMSView;
+
+/** TPMSTxRx state */
+typedef enum {
+    TPMSTxRxStateIDLE,
+    TPMSTxRxStateRx,
+    TPMSTxRxStateTx,
+    TPMSTxRxStateSleep,
+} TPMSTxRxState;
+
+typedef enum {
+    TPMSRelearnOff,
+    TPMSRelearnOn,
+} TPMSRelearn;
+
+typedef enum {
+    TPMSRelearnTypeCommon,
+    //TPMSRelearnAnotherOEM,
+} TPMSRelearnType;

BIN
non_catalog_apps/tpms_receiver/images/Fishing_123x52.png


BIN
non_catalog_apps/tpms_receiver/images/Lock_7x8.png


BIN
non_catalog_apps/tpms_receiver/images/Pin_back_arrow_10x8.png


BIN
non_catalog_apps/tpms_receiver/images/Press_7x16.png


BIN
non_catalog_apps/tpms_receiver/images/Quest_7x8.png


BIN
non_catalog_apps/tpms_receiver/images/Scanning_123x52.png


BIN
non_catalog_apps/tpms_receiver/images/Therm_7x16.png


BIN
non_catalog_apps/tpms_receiver/images/Timer_11x11.png


BIN
non_catalog_apps/tpms_receiver/images/Unlock_7x8.png


BIN
non_catalog_apps/tpms_receiver/images/WarningDolphin_45x42.png


BIN
non_catalog_apps/tpms_receiver/images/station_icon.png


+ 9 - 0
non_catalog_apps/tpms_receiver/protocols/protocol_items.c

@@ -0,0 +1,9 @@
+#include "protocol_items.h"
+
+const SubGhzProtocol* tpms_protocol_registry_items[] = {
+    &tpms_protocol_schrader_gg4,
+};
+
+const SubGhzProtocolRegistry tpms_protocol_registry = {
+    .items = tpms_protocol_registry_items,
+    .size = COUNT_OF(tpms_protocol_registry_items)};

+ 6 - 0
non_catalog_apps/tpms_receiver/protocols/protocol_items.h

@@ -0,0 +1,6 @@
+#pragma once
+#include "../tpms_app_i.h"
+
+#include "schrader_gg4.h"
+
+extern const SubGhzProtocolRegistry tpms_protocol_registry;

+ 295 - 0
non_catalog_apps/tpms_receiver/protocols/schrader_gg4.c

@@ -0,0 +1,295 @@
+#include "schrader_gg4.h"
+#include <lib/toolbox/manchester_decoder.h>
+
+#define TAG "Schrader"
+
+// https://github.com/merbanan/rtl_433/blob/master/src/devices/schraeder.c
+// https://elib.dlr.de/81155/1/TPMS_for_Trafffic_Management_purposes.pdf
+// https://github.com/furrtek/portapack-havoc/issues/349
+// https://fccid.io/MRXGG4
+// https://fccid.io/MRXGG4T
+
+/**
+ * Schrader 3013/3015 MRX-GG4
+
+OEM:
+KIA Sportage CGA 11-SPT1504-RA
+Mercedes-Benz A0009054100
+
+* Frequency: 433.92MHz+-38KHz
+* Modulation: ASK
+* Working Temperature: -50°C to 125°C
+* Tire monitoring range value: 0kPa-350kPa+-7kPa
+
+Examples in normal environmental conditions:
+3000878456094cd0
+3000878456084ecb
+3000878456074d01
+
+Data layout:
+ * | Byte 0    | Byte 1    | Byte 2    | Byte 3    | Byte 4    | Byte 5    | Byte 6    | Byte 7    |
+ * | --------- | --------- | --------- | --------- | --------- | --------- | --------- | --------- |
+ * | SSSS SSSS | IIII IIII | IIII IIII | IIII IIII | IIII IIII | PPPP PPPP | TTTT TTTT | CCCC CCCC |
+ *
+
+- The preamble is 0b000
+- S: always 0x30 in relearn state
+- I: 32 bit ID
+- P: 8 bit Pressure (multiplyed by 2.5 = PSI)
+- T: 8 bit Temperature (deg. C offset by 50)
+- C: 8 bit Checksum (CRC8, Poly 0x7, Init 0x0)
+*/
+
+#define PREAMBLE 0b000
+#define PREAMBLE_BITS_LEN 3
+
+static const SubGhzBlockConst tpms_protocol_schrader_gg4_const = {
+    .te_short = 120,
+    .te_long = 240,
+    .te_delta = 55, // 50% of te_short due to poor sensitivity
+    .min_count_bit_for_found = 64,
+};
+
+struct TPMSProtocolDecoderSchraderGG4 {
+    SubGhzProtocolDecoderBase base;
+
+    SubGhzBlockDecoder decoder;
+    TPMSBlockGeneric generic;
+
+    ManchesterState manchester_saved_state;
+    uint16_t header_count;
+};
+
+struct TPMSProtocolEncoderSchraderGG4 {
+    SubGhzProtocolEncoderBase base;
+
+    SubGhzProtocolBlockEncoder encoder;
+    TPMSBlockGeneric generic;
+};
+
+typedef enum {
+    SchraderGG4DecoderStepReset = 0,
+    SchraderGG4DecoderStepCheckPreamble,
+    SchraderGG4DecoderStepDecoderData,
+    SchraderGG4DecoderStepSaveDuration,
+    SchraderGG4DecoderStepCheckDuration,
+} SchraderGG4DecoderStep;
+
+const SubGhzProtocolDecoder tpms_protocol_schrader_gg4_decoder = {
+    .alloc = tpms_protocol_decoder_schrader_gg4_alloc,
+    .free = tpms_protocol_decoder_schrader_gg4_free,
+
+    .feed = tpms_protocol_decoder_schrader_gg4_feed,
+    .reset = tpms_protocol_decoder_schrader_gg4_reset,
+
+    .get_hash_data = tpms_protocol_decoder_schrader_gg4_get_hash_data,
+    .serialize = tpms_protocol_decoder_schrader_gg4_serialize,
+    .deserialize = tpms_protocol_decoder_schrader_gg4_deserialize,
+    .get_string = tpms_protocol_decoder_schrader_gg4_get_string,
+};
+
+const SubGhzProtocolEncoder tpms_protocol_schrader_gg4_encoder = {
+    .alloc = NULL,
+    .free = NULL,
+
+    .deserialize = NULL,
+    .stop = NULL,
+    .yield = NULL,
+};
+
+const SubGhzProtocol tpms_protocol_schrader_gg4 = {
+    .name = TPMS_PROTOCOL_SCHRADER_GG4_NAME,
+    .type = SubGhzProtocolTypeStatic,
+    .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_315 | SubGhzProtocolFlag_868 |
+            SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable,
+
+    .decoder = &tpms_protocol_schrader_gg4_decoder,
+    .encoder = &tpms_protocol_schrader_gg4_encoder,
+};
+
+void* tpms_protocol_decoder_schrader_gg4_alloc(SubGhzEnvironment* environment) {
+    UNUSED(environment);
+    TPMSProtocolDecoderSchraderGG4* instance = malloc(sizeof(TPMSProtocolDecoderSchraderGG4));
+    instance->base.protocol = &tpms_protocol_schrader_gg4;
+    instance->generic.protocol_name = instance->base.protocol->name;
+    return instance;
+}
+
+void tpms_protocol_decoder_schrader_gg4_free(void* context) {
+    furi_assert(context);
+    TPMSProtocolDecoderSchraderGG4* instance = context;
+    free(instance);
+}
+
+void tpms_protocol_decoder_schrader_gg4_reset(void* context) {
+    furi_assert(context);
+    TPMSProtocolDecoderSchraderGG4* instance = context;
+    instance->decoder.parser_step = SchraderGG4DecoderStepReset;
+}
+
+static bool tpms_protocol_schrader_gg4_check_crc(TPMSProtocolDecoderSchraderGG4* instance) {
+    uint8_t msg[] = {
+        instance->decoder.decode_data >> 48,
+        instance->decoder.decode_data >> 40,
+        instance->decoder.decode_data >> 32,
+        instance->decoder.decode_data >> 24,
+        instance->decoder.decode_data >> 16,
+        instance->decoder.decode_data >> 8};
+
+    uint8_t crc = subghz_protocol_blocks_crc8(msg, 6, 0x7, 0);
+    return (crc == (instance->decoder.decode_data & 0xFF));
+}
+
+/**
+ * Analysis of received data
+ * @param instance Pointer to a TPMSBlockGeneric* instance
+ */
+static void tpms_protocol_schrader_gg4_analyze(TPMSBlockGeneric* instance) {
+    instance->id = instance->data >> 24;
+
+    // TODO locate and fix
+    instance->battery_low = TPMS_NO_BATT;
+
+    instance->temperature = ((instance->data >> 8) & 0xFF) - 50;
+    instance->pressure = ((instance->data >> 16) & 0xFF) * 2.5 * 0.069;
+}
+
+static ManchesterEvent level_and_duration_to_event(bool level, uint32_t duration) {
+    bool is_long = false;
+
+    if(DURATION_DIFF(duration, tpms_protocol_schrader_gg4_const.te_long) <
+       tpms_protocol_schrader_gg4_const.te_delta) {
+        is_long = true;
+    } else if(
+        DURATION_DIFF(duration, tpms_protocol_schrader_gg4_const.te_short) <
+        tpms_protocol_schrader_gg4_const.te_delta) {
+        is_long = false;
+    } else {
+        return ManchesterEventReset;
+    }
+
+    if(level)
+        return is_long ? ManchesterEventLongHigh : ManchesterEventShortHigh;
+    else
+        return is_long ? ManchesterEventLongLow : ManchesterEventShortLow;
+}
+
+void tpms_protocol_decoder_schrader_gg4_feed(void* context, bool level, uint32_t duration) {
+    furi_assert(context);
+    bool bit = false;
+    bool have_bit = false;
+    TPMSProtocolDecoderSchraderGG4* instance = context;
+
+    // low-level bit sequence decoding
+    if(instance->decoder.parser_step != SchraderGG4DecoderStepReset) {
+        ManchesterEvent event = level_and_duration_to_event(level, duration);
+
+        if(event == ManchesterEventReset) {
+            if((instance->decoder.parser_step == SchraderGG4DecoderStepDecoderData) &&
+               instance->decoder.decode_count_bit) {
+                // FURI_LOG_D(TAG, "%d-%ld", level, duration);
+                FURI_LOG_D(
+                    TAG,
+                    "reset accumulated %d bits: %llx",
+                    instance->decoder.decode_count_bit,
+                    instance->decoder.decode_data);
+            }
+
+            instance->decoder.parser_step = SchraderGG4DecoderStepReset;
+        } else {
+            have_bit = manchester_advance(
+                instance->manchester_saved_state, event, &instance->manchester_saved_state, &bit);
+            if(!have_bit) return;
+
+            // Invert value, due to signal is Manchester II and decoder is Manchester I
+            bit = !bit;
+        }
+    }
+
+    switch(instance->decoder.parser_step) {
+    case SchraderGG4DecoderStepReset:
+        // wait for start ~480us pulse
+        if((level) && (DURATION_DIFF(duration, tpms_protocol_schrader_gg4_const.te_long * 2) <
+                       tpms_protocol_schrader_gg4_const.te_delta)) {
+            instance->decoder.parser_step = SchraderGG4DecoderStepCheckPreamble;
+            instance->header_count = 0;
+            instance->decoder.decode_data = 0;
+            instance->decoder.decode_count_bit = 0;
+
+            // First will be short space, so set correct initial state for machine
+            // https://clearwater.com.au/images/rc5/rc5-state-machine.gif
+            instance->manchester_saved_state = ManchesterStateStart1;
+        }
+        break;
+    case SchraderGG4DecoderStepCheckPreamble:
+        if(bit != 0) {
+            instance->decoder.parser_step = SchraderGG4DecoderStepReset;
+            break;
+        }
+
+        instance->header_count++;
+        if(instance->header_count == PREAMBLE_BITS_LEN)
+            instance->decoder.parser_step = SchraderGG4DecoderStepDecoderData;
+        break;
+
+    case SchraderGG4DecoderStepDecoderData:
+        subghz_protocol_blocks_add_bit(&instance->decoder, bit);
+        if(instance->decoder.decode_count_bit ==
+           tpms_protocol_schrader_gg4_const.min_count_bit_for_found) {
+            FURI_LOG_D(TAG, "%016llx", instance->decoder.decode_data);
+            if(!tpms_protocol_schrader_gg4_check_crc(instance)) {
+                FURI_LOG_D(TAG, "CRC mismatch drop");
+            } else {
+                instance->generic.data = instance->decoder.decode_data;
+                instance->generic.data_count_bit = instance->decoder.decode_count_bit;
+                tpms_protocol_schrader_gg4_analyze(&instance->generic);
+                if(instance->base.callback)
+                    instance->base.callback(&instance->base, instance->base.context);
+            }
+            instance->decoder.parser_step = SchraderGG4DecoderStepReset;
+        }
+        break;
+    }
+}
+
+uint8_t tpms_protocol_decoder_schrader_gg4_get_hash_data(void* context) {
+    furi_assert(context);
+    TPMSProtocolDecoderSchraderGG4* instance = context;
+    return subghz_protocol_blocks_get_hash_data(
+        &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1);
+}
+
+SubGhzProtocolStatus tpms_protocol_decoder_schrader_gg4_serialize(
+    void* context,
+    FlipperFormat* flipper_format,
+    SubGhzRadioPreset* preset) {
+    furi_assert(context);
+    TPMSProtocolDecoderSchraderGG4* instance = context;
+    return tpms_block_generic_serialize(&instance->generic, flipper_format, preset);
+}
+
+SubGhzProtocolStatus
+    tpms_protocol_decoder_schrader_gg4_deserialize(void* context, FlipperFormat* flipper_format) {
+    furi_assert(context);
+    TPMSProtocolDecoderSchraderGG4* instance = context;
+    return tpms_block_generic_deserialize_check_count_bit(
+        &instance->generic,
+        flipper_format,
+        tpms_protocol_schrader_gg4_const.min_count_bit_for_found);
+}
+
+void tpms_protocol_decoder_schrader_gg4_get_string(void* context, FuriString* output) {
+    furi_assert(context);
+    TPMSProtocolDecoderSchraderGG4* instance = context;
+    furi_string_printf(
+        output,
+        "%s\r\n"
+        "Id:0x%08lX\r\n"
+        "Bat:%d\r\n"
+        "Temp:%2.0f C Bar:%2.1f",
+        instance->generic.protocol_name,
+        instance->generic.id,
+        instance->generic.battery_low,
+        (double)instance->generic.temperature,
+        (double)instance->generic.pressure);
+}

+ 80 - 0
non_catalog_apps/tpms_receiver/protocols/schrader_gg4.h

@@ -0,0 +1,80 @@
+#pragma once
+
+#include <lib/subghz/protocols/base.h>
+
+#include <lib/subghz/blocks/const.h>
+#include <lib/subghz/blocks/decoder.h>
+#include <lib/subghz/blocks/encoder.h>
+#include "tpms_generic.h"
+#include <lib/subghz/blocks/math.h>
+
+#define TPMS_PROTOCOL_SCHRADER_GG4_NAME "Schrader GG4"
+
+typedef struct TPMSProtocolDecoderSchraderGG4 TPMSProtocolDecoderSchraderGG4;
+typedef struct TPMSProtocolEncoderSchraderGG4 TPMSProtocolEncoderSchraderGG4;
+
+extern const SubGhzProtocolDecoder tpms_protocol_schrader_gg4_decoder;
+extern const SubGhzProtocolEncoder tpms_protocol_schrader_gg4_encoder;
+extern const SubGhzProtocol tpms_protocol_schrader_gg4;
+
+/**
+ * Allocate TPMSProtocolDecoderSchraderGG4.
+ * @param environment Pointer to a SubGhzEnvironment instance
+ * @return TPMSProtocolDecoderSchraderGG4* pointer to a TPMSProtocolDecoderSchraderGG4 instance
+ */
+void* tpms_protocol_decoder_schrader_gg4_alloc(SubGhzEnvironment* environment);
+
+/**
+ * Free TPMSProtocolDecoderSchraderGG4.
+ * @param context Pointer to a TPMSProtocolDecoderSchraderGG4 instance
+ */
+void tpms_protocol_decoder_schrader_gg4_free(void* context);
+
+/**
+ * Reset decoder TPMSProtocolDecoderSchraderGG4.
+ * @param context Pointer to a TPMSProtocolDecoderSchraderGG4 instance
+ */
+void tpms_protocol_decoder_schrader_gg4_reset(void* context);
+
+/**
+ * Parse a raw sequence of levels and durations received from the air.
+ * @param context Pointer to a TPMSProtocolDecoderSchraderGG4 instance
+ * @param level Signal level true-high false-low
+ * @param duration Duration of this level in, us
+ */
+void tpms_protocol_decoder_schrader_gg4_feed(void* context, bool level, uint32_t duration);
+
+/**
+ * Getting the hash sum of the last randomly received parcel.
+ * @param context Pointer to a TPMSProtocolDecoderSchraderGG4 instance
+ * @return hash Hash sum
+ */
+uint8_t tpms_protocol_decoder_schrader_gg4_get_hash_data(void* context);
+
+/**
+ * Serialize data TPMSProtocolDecoderSchraderGG4.
+ * @param context Pointer to a TPMSProtocolDecoderSchraderGG4 instance
+ * @param flipper_format Pointer to a FlipperFormat instance
+ * @param preset The modulation on which the signal was received, SubGhzRadioPreset
+ * @return status
+ */
+SubGhzProtocolStatus tpms_protocol_decoder_schrader_gg4_serialize(
+    void* context,
+    FlipperFormat* flipper_format,
+    SubGhzRadioPreset* preset);
+
+/**
+ * Deserialize data TPMSProtocolDecoderSchraderGG4.
+ * @param context Pointer to a TPMSProtocolDecoderSchraderGG4 instance
+ * @param flipper_format Pointer to a FlipperFormat instance
+ * @return status
+ */
+SubGhzProtocolStatus
+    tpms_protocol_decoder_schrader_gg4_deserialize(void* context, FlipperFormat* flipper_format);
+
+/**
+ * Getting a textual representation of the received data.
+ * @param context Pointer to a TPMSProtocolDecoderSchraderGG4 instance
+ * @param output Resulting text
+ */
+void tpms_protocol_decoder_schrader_gg4_get_string(void* context, FuriString* output);

+ 228 - 0
non_catalog_apps/tpms_receiver/protocols/tpms_generic.c

@@ -0,0 +1,228 @@
+#include "tpms_generic.h"
+#include <lib/toolbox/stream/stream.h>
+#include <lib/flipper_format/flipper_format_i.h>
+#include "../helpers/tpms_types.h"
+
+#define TAG "TPMSBlockGeneric"
+
+void tpms_block_generic_get_preset_name(const char* preset_name, FuriString* preset_str) {
+    const char* preset_name_temp;
+    if(!strcmp(preset_name, "AM270")) {
+        preset_name_temp = "FuriHalSubGhzPresetOok270Async";
+    } else if(!strcmp(preset_name, "AM650")) {
+        preset_name_temp = "FuriHalSubGhzPresetOok650Async";
+    } else if(!strcmp(preset_name, "FM238")) {
+        preset_name_temp = "FuriHalSubGhzPreset2FSKDev238Async";
+    } else if(!strcmp(preset_name, "FM476")) {
+        preset_name_temp = "FuriHalSubGhzPreset2FSKDev476Async";
+    } else {
+        preset_name_temp = "FuriHalSubGhzPresetCustom";
+    }
+    furi_string_set(preset_str, preset_name_temp);
+}
+
+SubGhzProtocolStatus tpms_block_generic_serialize(
+    TPMSBlockGeneric* instance,
+    FlipperFormat* flipper_format,
+    SubGhzRadioPreset* preset) {
+    furi_assert(instance);
+    SubGhzProtocolStatus res = SubGhzProtocolStatusError;
+    FuriString* temp_str;
+    temp_str = furi_string_alloc();
+    do {
+        stream_clean(flipper_format_get_raw_stream(flipper_format));
+        if(!flipper_format_write_header_cstr(
+               flipper_format, TPMS_KEY_FILE_TYPE, TPMS_KEY_FILE_VERSION)) {
+            FURI_LOG_E(TAG, "Unable to add header");
+            res = SubGhzProtocolStatusErrorParserHeader;
+            break;
+        }
+
+        if(!flipper_format_write_uint32(flipper_format, "Frequency", &preset->frequency, 1)) {
+            FURI_LOG_E(TAG, "Unable to add Frequency");
+            res = SubGhzProtocolStatusErrorParserFrequency;
+            break;
+        }
+
+        tpms_block_generic_get_preset_name(furi_string_get_cstr(preset->name), temp_str);
+        if(!flipper_format_write_string_cstr(
+               flipper_format, "Preset", furi_string_get_cstr(temp_str))) {
+            FURI_LOG_E(TAG, "Unable to add Preset");
+            res = SubGhzProtocolStatusErrorParserPreset;
+            break;
+        }
+        if(!strcmp(furi_string_get_cstr(temp_str), "FuriHalSubGhzPresetCustom")) {
+            if(!flipper_format_write_string_cstr(
+                   flipper_format, "Custom_preset_module", "CC1101")) {
+                FURI_LOG_E(TAG, "Unable to add Custom_preset_module");
+                res = SubGhzProtocolStatusErrorParserCustomPreset;
+                break;
+            }
+            if(!flipper_format_write_hex(
+                   flipper_format, "Custom_preset_data", preset->data, preset->data_size)) {
+                FURI_LOG_E(TAG, "Unable to add Custom_preset_data");
+                res = SubGhzProtocolStatusErrorParserCustomPreset;
+                break;
+            }
+        }
+        if(!flipper_format_write_string_cstr(flipper_format, "Protocol", instance->protocol_name)) {
+            FURI_LOG_E(TAG, "Unable to add Protocol");
+            res = SubGhzProtocolStatusErrorParserProtocolName;
+            break;
+        }
+
+        uint32_t temp_data = instance->id;
+        if(!flipper_format_write_uint32(flipper_format, "Id", &temp_data, 1)) {
+            FURI_LOG_E(TAG, "Unable to add Id");
+            res = SubGhzProtocolStatusErrorParserOthers;
+            break;
+        }
+
+        temp_data = instance->data_count_bit;
+        if(!flipper_format_write_uint32(flipper_format, "Bit", &temp_data, 1)) {
+            FURI_LOG_E(TAG, "Unable to add Bit");
+            res = SubGhzProtocolStatusErrorParserBitCount;
+            break;
+        }
+
+        uint8_t key_data[sizeof(uint64_t)] = {0};
+        for(size_t i = 0; i < sizeof(uint64_t); i++) {
+            key_data[sizeof(uint64_t) - i - 1] = (instance->data >> (i * 8)) & 0xFF;
+        }
+
+        if(!flipper_format_write_hex(flipper_format, "Data", key_data, sizeof(uint64_t))) {
+            FURI_LOG_E(TAG, "Unable to add Data");
+            res = SubGhzProtocolStatusErrorParserOthers;
+            break;
+        }
+
+        temp_data = instance->battery_low;
+        if(!flipper_format_write_uint32(flipper_format, "Batt", &temp_data, 1)) {
+            FURI_LOG_E(TAG, "Unable to add Battery_low");
+            res = SubGhzProtocolStatusErrorParserOthers;
+            break;
+        }
+
+        float temp = instance->pressure;
+        if(!flipper_format_write_float(flipper_format, "Pressure", &temp, 1)) {
+            FURI_LOG_E(TAG, "Unable to add Pressure");
+            res = SubGhzProtocolStatusErrorParserOthers;
+            break;
+        }
+
+        //DATE AGE set
+        FuriHalRtcDateTime curr_dt;
+        furi_hal_rtc_get_datetime(&curr_dt);
+        uint32_t curr_ts = furi_hal_rtc_datetime_to_timestamp(&curr_dt);
+
+        temp_data = curr_ts;
+        if(!flipper_format_write_uint32(flipper_format, "Ts", &temp_data, 1)) {
+            FURI_LOG_E(TAG, "Unable to add timestamp");
+            res = SubGhzProtocolStatusErrorParserOthers;
+            break;
+        }
+
+        temp = instance->temperature;
+        if(!flipper_format_write_float(flipper_format, "Temp", &temp, 1)) {
+            FURI_LOG_E(TAG, "Unable to add Temperature");
+            res = SubGhzProtocolStatusErrorParserOthers;
+            break;
+        }
+
+        res = SubGhzProtocolStatusOk;
+    } while(false);
+    furi_string_free(temp_str);
+    return res;
+}
+
+SubGhzProtocolStatus
+    tpms_block_generic_deserialize(TPMSBlockGeneric* instance, FlipperFormat* flipper_format) {
+    furi_assert(instance);
+    SubGhzProtocolStatus res = SubGhzProtocolStatusError;
+    uint32_t temp_data = 0;
+
+    do {
+        if(!flipper_format_rewind(flipper_format)) {
+            FURI_LOG_E(TAG, "Rewind error");
+            res = SubGhzProtocolStatusErrorParserOthers;
+            break;
+        }
+
+        if(!flipper_format_read_uint32(flipper_format, "Id", &temp_data, 1)) {
+            FURI_LOG_E(TAG, "Missing Id");
+            res = SubGhzProtocolStatusErrorParserOthers;
+            break;
+        }
+        instance->id = temp_data;
+
+        if(!flipper_format_read_uint32(flipper_format, "Bit", &temp_data, 1)) {
+            FURI_LOG_E(TAG, "Missing Bit");
+            res = SubGhzProtocolStatusErrorParserBitCount;
+            break;
+        }
+        instance->data_count_bit = (uint8_t)temp_data;
+
+        uint8_t key_data[sizeof(uint64_t)] = {0};
+        if(!flipper_format_read_hex(flipper_format, "Data", key_data, sizeof(uint64_t))) {
+            FURI_LOG_E(TAG, "Missing Data");
+            res = SubGhzProtocolStatusErrorParserOthers;
+            break;
+        }
+
+        for(uint8_t i = 0; i < sizeof(uint64_t); i++) {
+            instance->data = instance->data << 8 | key_data[i];
+        }
+
+        if(!flipper_format_read_uint32(flipper_format, "Batt", &temp_data, 1)) {
+            FURI_LOG_E(TAG, "Missing Battery_low");
+            res = SubGhzProtocolStatusErrorParserOthers;
+            break;
+        }
+        instance->battery_low = (uint8_t)temp_data;
+
+        float temp;
+        if(!flipper_format_read_float(flipper_format, "Pressure", &temp, 1)) {
+            FURI_LOG_E(TAG, "Missing Pressure");
+            res = SubGhzProtocolStatusErrorParserOthers;
+            break;
+        }
+        instance->pressure = temp;
+
+        if(!flipper_format_read_uint32(flipper_format, "Ts", &temp_data, 1)) {
+            FURI_LOG_E(TAG, "Missing timestamp");
+            res = SubGhzProtocolStatusErrorParserOthers;
+            break;
+        }
+        instance->timestamp = temp_data;
+
+        if(!flipper_format_read_float(flipper_format, "Temp", &temp, 1)) {
+            FURI_LOG_E(TAG, "Missing Temperature");
+            res = SubGhzProtocolStatusErrorParserOthers;
+            break;
+        }
+        instance->temperature = temp;
+
+        res = SubGhzProtocolStatusOk;
+    } while(0);
+
+    return res;
+}
+
+SubGhzProtocolStatus tpms_block_generic_deserialize_check_count_bit(
+    TPMSBlockGeneric* instance,
+    FlipperFormat* flipper_format,
+    uint16_t count_bit) {
+    SubGhzProtocolStatus ret = SubGhzProtocolStatusError;
+    do {
+        ret = tpms_block_generic_deserialize(instance, flipper_format);
+        if(ret != SubGhzProtocolStatusOk) {
+            break;
+        }
+        if(instance->data_count_bit != count_bit) {
+            FURI_LOG_E(TAG, "Wrong number of bits in key");
+            ret = SubGhzProtocolStatusErrorValueBitCount;
+            break;
+        }
+    } while(false);
+    return ret;
+}

+ 77 - 0
non_catalog_apps/tpms_receiver/protocols/tpms_generic.h

@@ -0,0 +1,77 @@
+#pragma once
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stddef.h>
+
+#include <lib/flipper_format/flipper_format.h>
+#include "furi.h"
+#include <furi_hal.h>
+#include <lib/subghz/types.h>
+#include <locale/locale.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define TPMS_NO_BATT 0xFF
+
+typedef struct TPMSBlockGeneric TPMSBlockGeneric;
+
+struct TPMSBlockGeneric {
+    const char* protocol_name;
+    uint64_t data;
+    uint8_t data_count_bit;
+
+    uint32_t timestamp;
+
+    uint32_t id;
+    uint8_t battery_low;
+    // bool storage;
+    float pressure; // bar
+    float temperature; // celsius
+};
+
+/**
+     * Get name preset.
+     * @param preset_name name preset
+     * @param preset_str Output name preset
+     */
+void tpms_block_generic_get_preset_name(const char* preset_name, FuriString* preset_str);
+
+/**
+     * Serialize data TPMSBlockGeneric.
+     * @param instance Pointer to a TPMSBlockGeneric instance
+     * @param flipper_format Pointer to a FlipperFormat instance
+     * @param preset The modulation on which the signal was received, SubGhzRadioPreset
+     * @return status
+     */
+SubGhzProtocolStatus tpms_block_generic_serialize(
+    TPMSBlockGeneric* instance,
+    FlipperFormat* flipper_format,
+    SubGhzRadioPreset* preset);
+
+/**
+     * Deserialize data TPMSBlockGeneric.
+     * @param instance Pointer to a TPMSBlockGeneric instance
+     * @param flipper_format Pointer to a FlipperFormat instance
+     * @return status
+     */
+SubGhzProtocolStatus
+    tpms_block_generic_deserialize(TPMSBlockGeneric* instance, FlipperFormat* flipper_format);
+
+/**
+     * Deserialize data TPMSBlockGeneric.
+     * @param instance Pointer to a TPMSBlockGeneric instance
+     * @param flipper_format Pointer to a FlipperFormat instance
+     * @param count_bit Count bit protocol
+     * @return status
+     */
+SubGhzProtocolStatus tpms_block_generic_deserialize_check_count_bit(
+    TPMSBlockGeneric* instance,
+    FlipperFormat* flipper_format,
+    uint16_t count_bit);
+
+#ifdef __cplusplus
+}
+#endif

+ 30 - 0
non_catalog_apps/tpms_receiver/scenes/tpms_scene.c

@@ -0,0 +1,30 @@
+#include "../tpms_app_i.h"
+
+// Generate scene on_enter handlers array
+#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_enter,
+void (*const tpms_scene_on_enter_handlers[])(void*) = {
+#include "tpms_scene_config.h"
+};
+#undef ADD_SCENE
+
+// Generate scene on_event handlers array
+#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_event,
+bool (*const tpms_scene_on_event_handlers[])(void* context, SceneManagerEvent event) = {
+#include "tpms_scene_config.h"
+};
+#undef ADD_SCENE
+
+// Generate scene on_exit handlers array
+#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_exit,
+void (*const tpms_scene_on_exit_handlers[])(void* context) = {
+#include "tpms_scene_config.h"
+};
+#undef ADD_SCENE
+
+// Initialize scene handlers configuration structure
+const SceneManagerHandlers tpms_scene_handlers = {
+    .on_enter_handlers = tpms_scene_on_enter_handlers,
+    .on_event_handlers = tpms_scene_on_event_handlers,
+    .on_exit_handlers = tpms_scene_on_exit_handlers,
+    .scene_num = TPMSSceneNum,
+};

+ 29 - 0
non_catalog_apps/tpms_receiver/scenes/tpms_scene.h

@@ -0,0 +1,29 @@
+#pragma once
+
+#include <gui/scene_manager.h>
+
+// Generate scene id and total number
+#define ADD_SCENE(prefix, name, id) TPMSScene##id,
+typedef enum {
+#include "tpms_scene_config.h"
+    TPMSSceneNum,
+} TPMSScene;
+#undef ADD_SCENE
+
+extern const SceneManagerHandlers tpms_scene_handlers;
+
+// Generate scene on_enter handlers declaration
+#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_enter(void*);
+#include "tpms_scene_config.h"
+#undef ADD_SCENE
+
+// Generate scene on_event handlers declaration
+#define ADD_SCENE(prefix, name, id) \
+    bool prefix##_scene_##name##_on_event(void* context, SceneManagerEvent event);
+#include "tpms_scene_config.h"
+#undef ADD_SCENE
+
+// Generate scene on_exit handlers declaration
+#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_exit(void* context);
+#include "tpms_scene_config.h"
+#undef ADD_SCENE

+ 57 - 0
non_catalog_apps/tpms_receiver/scenes/tpms_scene_about.c

@@ -0,0 +1,57 @@
+#include "../tpms_app_i.h"
+#include "../helpers/tpms_types.h"
+
+void tpms_scene_about_widget_callback(GuiButtonType result, InputType type, void* context) {
+    TPMSApp* app = context;
+    if(type == InputTypeShort) {
+        view_dispatcher_send_custom_event(app->view_dispatcher, result);
+    }
+}
+
+void tpms_scene_about_on_enter(void* context) {
+    TPMSApp* app = context;
+
+    FuriString* temp_str;
+    temp_str = furi_string_alloc();
+    furi_string_printf(temp_str, "\e#%s\n", "Information");
+
+    furi_string_cat_printf(temp_str, "Version: %s\n", TPMS_VERSION_APP);
+    furi_string_cat_printf(temp_str, "Developed by: %s\n", TPMS_DEVELOPED);
+    furi_string_cat_printf(temp_str, "Github: %s\n\n", TPMS_GITHUB);
+
+    furi_string_cat_printf(temp_str, "\e#%s\n", "Description");
+    furi_string_cat_printf(
+        temp_str, "Reading messages from\nTPMS sensors that work\nwith SubGhz sensors\n\n");
+
+    furi_string_cat_printf(temp_str, "Supported protocols:\n");
+    size_t i = 0;
+    const char* protocol_name =
+        subghz_environment_get_protocol_name_registry(app->txrx->environment, i++);
+    do {
+        furi_string_cat_printf(temp_str, "%s\n", protocol_name);
+        protocol_name = subghz_environment_get_protocol_name_registry(app->txrx->environment, i++);
+    } while(protocol_name != NULL);
+
+    widget_add_text_box_element(
+        app->widget, 0, 2, 128, 14, AlignCenter, AlignBottom, "TPMS Reader\n", false);
+    widget_add_text_scroll_element(app->widget, 0, 16, 128, 50, furi_string_get_cstr(temp_str));
+    furi_string_free(temp_str);
+
+    view_dispatcher_switch_to_view(app->view_dispatcher, TPMSViewWidget);
+}
+
+bool tpms_scene_about_on_event(void* context, SceneManagerEvent event) {
+    TPMSApp* app = context;
+    bool consumed = false;
+    UNUSED(app);
+    UNUSED(event);
+
+    return consumed;
+}
+
+void tpms_scene_about_on_exit(void* context) {
+    TPMSApp* app = context;
+
+    // Clear views
+    widget_reset(app->widget);
+}

+ 6 - 0
non_catalog_apps/tpms_receiver/scenes/tpms_scene_config.h

@@ -0,0 +1,6 @@
+ADD_SCENE(tpms, start, Start)
+ADD_SCENE(tpms, about, About)
+ADD_SCENE(tpms, receiver, Receiver)
+ADD_SCENE(tpms, relearn_config, Relearn)
+ADD_SCENE(tpms, receiver_config, ReceiverConfig)
+ADD_SCENE(tpms, receiver_info, ReceiverInfo)

+ 221 - 0
non_catalog_apps/tpms_receiver/scenes/tpms_scene_receiver.c

@@ -0,0 +1,221 @@
+#include "../tpms_app_i.h"
+#include "../views/tpms_receiver.h"
+
+static const NotificationSequence subghz_sequence_rx = {
+    &message_green_255,
+
+    &message_vibro_on,
+    &message_note_c6,
+    &message_delay_50,
+    &message_sound_off,
+    &message_vibro_off,
+
+    &message_delay_50,
+    NULL,
+};
+
+static const NotificationSequence subghz_sequence_rx_locked = {
+    &message_green_255,
+
+    &message_display_backlight_on,
+
+    &message_vibro_on,
+    &message_note_c6,
+    &message_delay_50,
+    &message_sound_off,
+    &message_vibro_off,
+
+    &message_delay_500,
+
+    &message_display_backlight_off,
+    NULL,
+};
+
+static void tpms_scene_receiver_update_statusbar(void* context) {
+    TPMSApp* app = context;
+    FuriString* history_stat_str;
+    history_stat_str = furi_string_alloc();
+    if(!tpms_history_get_text_space_left(app->txrx->history, history_stat_str)) {
+        FuriString* frequency_str;
+        FuriString* modulation_str;
+
+        frequency_str = furi_string_alloc();
+        modulation_str = furi_string_alloc();
+
+        tpms_get_frequency_modulation(app, frequency_str, modulation_str);
+
+        tpms_view_receiver_add_data_statusbar(
+            app->tpms_receiver,
+            furi_string_get_cstr(frequency_str),
+            furi_string_get_cstr(modulation_str),
+            furi_string_get_cstr(history_stat_str),
+            radio_device_loader_is_external(app->txrx->radio_device));
+
+        furi_string_free(frequency_str);
+        furi_string_free(modulation_str);
+    } else {
+        tpms_view_receiver_add_data_statusbar(
+            app->tpms_receiver,
+            furi_string_get_cstr(history_stat_str),
+            "",
+            "",
+            radio_device_loader_is_external(app->txrx->radio_device));
+    }
+    furi_string_free(history_stat_str);
+}
+
+void tpms_scene_receiver_callback(TPMSCustomEvent event, void* context) {
+    furi_assert(context);
+    TPMSApp* app = context;
+    view_dispatcher_send_custom_event(app->view_dispatcher, event);
+}
+
+static void tpms_scene_receiver_add_to_history_callback(
+    SubGhzReceiver* receiver,
+    SubGhzProtocolDecoderBase* decoder_base,
+    void* context) {
+    furi_assert(context);
+    TPMSApp* app = context;
+    FuriString* str_buff;
+    str_buff = furi_string_alloc();
+
+    if(tpms_history_add_to_history(app->txrx->history, decoder_base, app->txrx->preset) ==
+       TPMSHistoryStateAddKeyNewDada) {
+        furi_string_reset(str_buff);
+
+        tpms_history_get_text_item_menu(
+            app->txrx->history, str_buff, tpms_history_get_item(app->txrx->history) - 1);
+        tpms_view_receiver_add_item_to_menu(
+            app->tpms_receiver,
+            furi_string_get_cstr(str_buff),
+            tpms_history_get_type_protocol(
+                app->txrx->history, tpms_history_get_item(app->txrx->history) - 1));
+
+        tpms_scene_receiver_update_statusbar(app);
+        notification_message(app->notifications, &sequence_blink_green_10);
+        if(app->lock != TPMSLockOn) {
+            notification_message(app->notifications, &subghz_sequence_rx);
+        } else {
+            notification_message(app->notifications, &subghz_sequence_rx_locked);
+        }
+    }
+    subghz_receiver_reset(receiver);
+    furi_string_free(str_buff);
+    app->txrx->rx_key_state = TPMSRxKeyStateAddKey;
+}
+
+void tpms_scene_receiver_on_enter(void* context) {
+    TPMSApp* app = context;
+
+    FuriString* str_buff;
+    str_buff = furi_string_alloc();
+
+    if(app->txrx->rx_key_state == TPMSRxKeyStateIDLE) {
+        tpms_preset_init(
+            app, "AM650", subghz_setting_get_default_frequency(app->setting), NULL, 0);
+        tpms_history_reset(app->txrx->history);
+        app->txrx->rx_key_state = TPMSRxKeyStateStart;
+    }
+
+    tpms_view_receiver_set_lock(app->tpms_receiver, app->lock);
+
+    //Load history to receiver
+    tpms_view_receiver_exit(app->tpms_receiver);
+    for(uint8_t i = 0; i < tpms_history_get_item(app->txrx->history); i++) {
+        furi_string_reset(str_buff);
+        tpms_history_get_text_item_menu(app->txrx->history, str_buff, i);
+        tpms_view_receiver_add_item_to_menu(
+            app->tpms_receiver,
+            furi_string_get_cstr(str_buff),
+            tpms_history_get_type_protocol(app->txrx->history, i));
+        app->txrx->rx_key_state = TPMSRxKeyStateAddKey;
+    }
+    furi_string_free(str_buff);
+    tpms_scene_receiver_update_statusbar(app);
+
+    tpms_view_receiver_set_callback(app->tpms_receiver, tpms_scene_receiver_callback, app);
+    subghz_receiver_set_rx_callback(
+        app->txrx->receiver, tpms_scene_receiver_add_to_history_callback, app);
+
+    if(app->txrx->txrx_state == TPMSTxRxStateRx) {
+        tpms_rx_end(app);
+    };
+    if((app->txrx->txrx_state == TPMSTxRxStateIDLE) ||
+       (app->txrx->txrx_state == TPMSTxRxStateSleep)) {
+        tpms_begin(
+            app,
+            subghz_setting_get_preset_data_by_name(
+                app->setting, furi_string_get_cstr(app->txrx->preset->name)));
+
+        tpms_rx(app, app->txrx->preset->frequency);
+    }
+
+    tpms_view_receiver_set_idx_menu(app->tpms_receiver, app->txrx->idx_menu_chosen);
+    view_dispatcher_switch_to_view(app->view_dispatcher, TPMSViewReceiver);
+}
+
+bool tpms_scene_receiver_on_event(void* context, SceneManagerEvent event) {
+    TPMSApp* app = context;
+    bool consumed = false;
+    if(event.type == SceneManagerEventTypeCustom) {
+        switch(event.event) {
+        case TPMSCustomEventViewReceiverBack:
+            // Stop CC1101 Rx
+            if(app->txrx->txrx_state == TPMSTxRxStateRx) {
+                tpms_rx_end(app);
+                tpms_sleep(app);
+            };
+            app->txrx->hopper_state = TPMSHopperStateOFF;
+            app->txrx->idx_menu_chosen = 0;
+            subghz_receiver_set_rx_callback(app->txrx->receiver, NULL, app);
+
+            app->txrx->rx_key_state = TPMSRxKeyStateIDLE;
+            tpms_preset_init(
+                app, "AM650", subghz_setting_get_default_frequency(app->setting), NULL, 0);
+            if(scene_manager_has_previous_scene(app->scene_manager, TPMSSceneStart)) {
+                consumed = scene_manager_search_and_switch_to_previous_scene(
+                    app->scene_manager, TPMSSceneStart);
+            } else {
+                scene_manager_next_scene(app->scene_manager, TPMSSceneStart);
+            }
+            break;
+        case TPMSCustomEventViewReceiverOK:
+            app->txrx->idx_menu_chosen = tpms_view_receiver_get_idx_menu(app->tpms_receiver);
+            scene_manager_next_scene(app->scene_manager, TPMSSceneReceiverInfo);
+            consumed = true;
+            break;
+        case TPMSCustomEventViewReceiverConfig:
+            app->txrx->idx_menu_chosen = tpms_view_receiver_get_idx_menu(app->tpms_receiver);
+            scene_manager_next_scene(app->scene_manager, TPMSSceneReceiverConfig);
+            consumed = true;
+            break;
+        case TPMSCustomEventViewReceiverOffDisplay:
+            notification_message(app->notifications, &sequence_display_backlight_off);
+            consumed = true;
+            break;
+        case TPMSCustomEventViewReceiverUnlock:
+            app->lock = TPMSLockOff;
+            consumed = true;
+            break;
+        default:
+            break;
+        }
+    } else if(event.type == SceneManagerEventTypeTick) {
+        if(app->txrx->hopper_state != TPMSHopperStateOFF) {
+            tpms_hopper_update(app);
+            tpms_scene_receiver_update_statusbar(app);
+        }
+        // Get current RSSI
+        float rssi = furi_hal_subghz_get_rssi();
+        tpms_view_receiver_set_rssi(app->tpms_receiver, rssi);
+
+        if(app->txrx->txrx_state == TPMSTxRxStateRx) {
+            notification_message(app->notifications, &sequence_blink_cyan_10);
+        }
+    }
+    return consumed;
+}
+
+void tpms_scene_receiver_on_exit(void* context) {
+    UNUSED(context);
+}

+ 218 - 0
non_catalog_apps/tpms_receiver/scenes/tpms_scene_receiver_config.c

@@ -0,0 +1,218 @@
+#include "../tpms_app_i.h"
+
+enum TPMSSettingIndex {
+    TPMSSettingIndexFrequency,
+    TPMSSettingIndexHopping,
+    TPMSSettingIndexModulation,
+    TPMSSettingIndexLock,
+};
+
+#define HOPPING_COUNT 2
+const char* const hopping_text[HOPPING_COUNT] = {
+    "OFF",
+    "ON",
+};
+const uint32_t hopping_value[HOPPING_COUNT] = {
+    TPMSHopperStateOFF,
+    TPMSHopperStateRunnig,
+};
+
+uint8_t tpms_scene_receiver_config_next_frequency(const uint32_t value, void* context) {
+    furi_assert(context);
+    TPMSApp* app = context;
+    uint8_t index = 0;
+    for(uint8_t i = 0; i < subghz_setting_get_frequency_count(app->setting); i++) {
+        if(value == subghz_setting_get_frequency(app->setting, i)) {
+            index = i;
+            break;
+        } else {
+            index = subghz_setting_get_frequency_default_index(app->setting);
+        }
+    }
+    return index;
+}
+
+uint8_t tpms_scene_receiver_config_next_preset(const char* preset_name, void* context) {
+    furi_assert(context);
+    TPMSApp* app = context;
+    uint8_t index = 0;
+    for(uint8_t i = 0; i < subghz_setting_get_preset_count(app->setting); i++) {
+        if(!strcmp(subghz_setting_get_preset_name(app->setting, i), preset_name)) {
+            index = i;
+            break;
+        } else {
+            //  index = subghz_setting_get_frequency_default_index(app ->setting);
+        }
+    }
+    return index;
+}
+
+uint8_t tpms_scene_receiver_config_hopper_value_index(
+    const uint32_t value,
+    const uint32_t values[],
+    uint8_t values_count,
+    void* context) {
+    furi_assert(context);
+    UNUSED(values_count);
+    TPMSApp* app = context;
+
+    if(value == values[0]) {
+        return 0;
+    } else {
+        variable_item_set_current_value_text(
+            (VariableItem*)scene_manager_get_scene_state(
+                app->scene_manager, TPMSSceneReceiverConfig),
+            " -----");
+        return 1;
+    }
+}
+
+static void tpms_scene_receiver_config_set_frequency(VariableItem* item) {
+    TPMSApp* app = variable_item_get_context(item);
+    uint8_t index = variable_item_get_current_value_index(item);
+
+    if(app->txrx->hopper_state == TPMSHopperStateOFF) {
+        char text_buf[10] = {0};
+        snprintf(
+            text_buf,
+            sizeof(text_buf),
+            "%lu.%02lu",
+            subghz_setting_get_frequency(app->setting, index) / 1000000,
+            (subghz_setting_get_frequency(app->setting, index) % 1000000) / 10000);
+        variable_item_set_current_value_text(item, text_buf);
+        app->txrx->preset->frequency = subghz_setting_get_frequency(app->setting, index);
+    } else {
+        variable_item_set_current_value_index(
+            item, subghz_setting_get_frequency_default_index(app->setting));
+    }
+}
+
+static void tpms_scene_receiver_config_set_preset(VariableItem* item) {
+    TPMSApp* app = variable_item_get_context(item);
+    uint8_t index = variable_item_get_current_value_index(item);
+    variable_item_set_current_value_text(
+        item, subghz_setting_get_preset_name(app->setting, index));
+    tpms_preset_init(
+        app,
+        subghz_setting_get_preset_name(app->setting, index),
+        app->txrx->preset->frequency,
+        subghz_setting_get_preset_data(app->setting, index),
+        subghz_setting_get_preset_data_size(app->setting, index));
+}
+
+static void tpms_scene_receiver_config_set_hopping_running(VariableItem* item) {
+    TPMSApp* app = variable_item_get_context(item);
+    uint8_t index = variable_item_get_current_value_index(item);
+
+    variable_item_set_current_value_text(item, hopping_text[index]);
+    if(hopping_value[index] == TPMSHopperStateOFF) {
+        char text_buf[10] = {0};
+        snprintf(
+            text_buf,
+            sizeof(text_buf),
+            "%lu.%02lu",
+            subghz_setting_get_default_frequency(app->setting) / 1000000,
+            (subghz_setting_get_default_frequency(app->setting) % 1000000) / 10000);
+        variable_item_set_current_value_text(
+            (VariableItem*)scene_manager_get_scene_state(
+                app->scene_manager, TPMSSceneReceiverConfig),
+            text_buf);
+        app->txrx->preset->frequency = subghz_setting_get_default_frequency(app->setting);
+        variable_item_set_current_value_index(
+            (VariableItem*)scene_manager_get_scene_state(
+                app->scene_manager, TPMSSceneReceiverConfig),
+            subghz_setting_get_frequency_default_index(app->setting));
+    } else {
+        variable_item_set_current_value_text(
+            (VariableItem*)scene_manager_get_scene_state(
+                app->scene_manager, TPMSSceneReceiverConfig),
+            " -----");
+        variable_item_set_current_value_index(
+            (VariableItem*)scene_manager_get_scene_state(
+                app->scene_manager, TPMSSceneReceiverConfig),
+            subghz_setting_get_frequency_default_index(app->setting));
+    }
+
+    app->txrx->hopper_state = hopping_value[index];
+}
+
+static void tpms_scene_receiver_config_var_list_enter_callback(void* context, uint32_t index) {
+    furi_assert(context);
+    TPMSApp* app = context;
+    if(index == TPMSSettingIndexLock) {
+        view_dispatcher_send_custom_event(app->view_dispatcher, TPMSCustomEventSceneSettingLock);
+    }
+}
+
+void tpms_scene_receiver_config_on_enter(void* context) {
+    TPMSApp* app = context;
+    VariableItem* item;
+    uint8_t value_index;
+
+    item = variable_item_list_add(
+        app->variable_item_list,
+        "Frequency:",
+        subghz_setting_get_frequency_count(app->setting),
+        tpms_scene_receiver_config_set_frequency,
+        app);
+    value_index = tpms_scene_receiver_config_next_frequency(app->txrx->preset->frequency, app);
+    scene_manager_set_scene_state(app->scene_manager, TPMSSceneReceiverConfig, (uint32_t)item);
+    variable_item_set_current_value_index(item, value_index);
+    char text_buf[10] = {0};
+    snprintf(
+        text_buf,
+        sizeof(text_buf),
+        "%lu.%02lu",
+        subghz_setting_get_frequency(app->setting, value_index) / 1000000,
+        (subghz_setting_get_frequency(app->setting, value_index) % 1000000) / 10000);
+    variable_item_set_current_value_text(item, text_buf);
+
+    item = variable_item_list_add(
+        app->variable_item_list,
+        "Hopping:",
+        HOPPING_COUNT,
+        tpms_scene_receiver_config_set_hopping_running,
+        app);
+    value_index = tpms_scene_receiver_config_hopper_value_index(
+        app->txrx->hopper_state, hopping_value, HOPPING_COUNT, app);
+    variable_item_set_current_value_index(item, value_index);
+    variable_item_set_current_value_text(item, hopping_text[value_index]);
+
+    item = variable_item_list_add(
+        app->variable_item_list,
+        "Modulation:",
+        subghz_setting_get_preset_count(app->setting),
+        tpms_scene_receiver_config_set_preset,
+        app);
+    value_index =
+        tpms_scene_receiver_config_next_preset(furi_string_get_cstr(app->txrx->preset->name), app);
+    variable_item_set_current_value_index(item, value_index);
+    variable_item_set_current_value_text(
+        item, subghz_setting_get_preset_name(app->setting, value_index));
+
+    variable_item_list_add(app->variable_item_list, "Lock Keyboard", 1, NULL, NULL);
+    variable_item_list_set_enter_callback(
+        app->variable_item_list, tpms_scene_receiver_config_var_list_enter_callback, app);
+
+    view_dispatcher_switch_to_view(app->view_dispatcher, TPMSViewVariableItemList);
+}
+
+bool tpms_scene_receiver_config_on_event(void* context, SceneManagerEvent event) {
+    TPMSApp* app = context;
+    bool consumed = false;
+
+    if(event.type == SceneManagerEventTypeCustom) {
+        if(event.event == TPMSCustomEventSceneSettingLock) {
+            app->lock = TPMSLockOn;
+            scene_manager_previous_scene(app->scene_manager);
+            consumed = true;
+        }
+    }
+    return consumed;
+}
+
+void tpms_scene_receiver_config_on_exit(void* context) {
+    TPMSApp* app = context;
+    variable_item_list_set_selected_item(app->variable_item_list, 0);
+    variable_item_list_reset(app->variable_item_list);
+}

+ 50 - 0
non_catalog_apps/tpms_receiver/scenes/tpms_scene_receiver_info.c

@@ -0,0 +1,50 @@
+#include "../tpms_app_i.h"
+#include "../views/tpms_receiver.h"
+
+void tpms_scene_receiver_info_callback(TPMSCustomEvent event, void* context) {
+    furi_assert(context);
+    TPMSApp* app = context;
+    view_dispatcher_send_custom_event(app->view_dispatcher, event);
+}
+
+static void tpms_scene_receiver_info_add_to_history_callback(
+    SubGhzReceiver* receiver,
+    SubGhzProtocolDecoderBase* decoder_base,
+    void* context) {
+    furi_assert(context);
+    TPMSApp* app = context;
+
+    if(tpms_history_add_to_history(app->txrx->history, decoder_base, app->txrx->preset) ==
+       TPMSHistoryStateAddKeyUpdateData) {
+        tpms_view_receiver_info_update(
+            app->tpms_receiver_info,
+            tpms_history_get_raw_data(app->txrx->history, app->txrx->idx_menu_chosen));
+        subghz_receiver_reset(receiver);
+
+        notification_message(app->notifications, &sequence_blink_green_10);
+        app->txrx->rx_key_state = TPMSRxKeyStateAddKey;
+    }
+}
+
+void tpms_scene_receiver_info_on_enter(void* context) {
+    TPMSApp* app = context;
+
+    subghz_receiver_set_rx_callback(
+        app->txrx->receiver, tpms_scene_receiver_info_add_to_history_callback, app);
+    tpms_view_receiver_info_update(
+        app->tpms_receiver_info,
+        tpms_history_get_raw_data(app->txrx->history, app->txrx->idx_menu_chosen));
+    view_dispatcher_switch_to_view(app->view_dispatcher, TPMSViewReceiverInfo);
+}
+
+bool tpms_scene_receiver_info_on_event(void* context, SceneManagerEvent event) {
+    TPMSApp* app = context;
+    bool consumed = false;
+    UNUSED(app);
+    UNUSED(event);
+    return consumed;
+}
+
+void tpms_scene_receiver_info_on_exit(void* context) {
+    UNUSED(context);
+}

+ 91 - 0
non_catalog_apps/tpms_receiver/scenes/tpms_scene_relearn.c

@@ -0,0 +1,91 @@
+#include "../tpms_app_i.h"
+
+#define TAG "TPMSRelearn"
+
+enum TPMSRelearnSetting
+{
+    TPMSRelearnSettingOff,
+    TPMSRelearnSettingOn,
+    TPMSRelearnSettingNum,
+};
+
+const char *const relearn_setting_text[TPMSRelearnSettingNum] = {
+    "OFF",
+    "ON",
+};
+
+enum TPMSRelearnType
+{
+    TPMSRelearnCommon, // Just signal without data
+    // TPMSRelearnGM_FORD,
+    // TPMSRelearnAnotherOEM,
+    TPMSRelearnTypeNum,
+};
+
+const char *const relearn_type_text[TPMSRelearnTypeNum] = {
+    "Common",
+};
+
+static void tpms_scene_relearn_setting_callback(VariableItem* item) {
+    TPMSApp* app = variable_item_get_context(item);
+    uint8_t index = variable_item_get_current_value_index(item);
+    if(index == TPMSRelearnSettingOn) {
+        app->relearn = TPMSRelearnOn;
+    } else {
+        app->relearn = TPMSRelearnOff;
+    }
+    variable_item_set_current_value_text(item, relearn_setting_text[index]);
+}
+
+static void tpms_scene_relearn_type_callback(VariableItem* item) {
+    TPMSApp* app = variable_item_get_context(item);
+    uint8_t index = variable_item_get_current_value_index(item);
+    if(index == TPMSRelearnCommon) {
+        app->relearn_type = TPMSRelearnTypeCommon;
+    } else {
+        FURI_LOG_E(TAG, "Relearn type %d not implemented", index);
+        return;
+    }
+    variable_item_set_current_value_text(item, relearn_type_text[index]);
+}
+
+void tpms_scene_relearn_config_on_enter(void *context)
+{
+    TPMSApp *app = context;
+    VariableItemList *var_item_list = app->variable_item_list;
+    VariableItem *item;
+
+    item = variable_item_list_add(
+        var_item_list,
+        "Relearn 125kHz",
+        TPMSRelearnSettingNum,
+        tpms_scene_relearn_setting_callback,
+        app);
+    // scene_manager_set_scene_state(app->scene_manager, TPMSSceneReceiverConfig, (uint32_t)item);
+    variable_item_set_current_value_index(item, app->relearn);
+    variable_item_set_current_value_text(item, relearn_setting_text[app->relearn]);
+
+    item = variable_item_list_add(
+        var_item_list, "Type", TPMSRelearnTypeNum, tpms_scene_relearn_type_callback, app);
+    variable_item_set_current_value_index(item, app->relearn_type);
+    variable_item_set_current_value_text(item, relearn_type_text[app->relearn_type]);
+
+    view_dispatcher_switch_to_view(app->view_dispatcher, TPMSViewVariableItemList);
+}
+bool tpms_scene_relearn_config_on_event(void *context, SceneManagerEvent event)
+{
+    TPMSApp *app = context;
+    UNUSED(app);
+    bool consumed = false;
+
+    if (event.type == SceneManagerEventTypeCustom){
+    }
+    return consumed;
+}
+
+void tpms_scene_relearn_config_on_exit(void *context)
+{
+    TPMSApp *app = context;
+    variable_item_list_set_selected_item(app->variable_item_list, 0);
+    variable_item_list_reset(app->variable_item_list);
+}

+ 62 - 0
non_catalog_apps/tpms_receiver/scenes/tpms_scene_start.c

@@ -0,0 +1,62 @@
+#include "../tpms_app_i.h"
+
+typedef enum {
+    SubmenuIndexTPMSReceiver,
+    SubmenuIndexTPMSRelearn,
+    SubmenuIndexTPMSAbout,
+} SubmenuIndex;
+
+void tpms_scene_start_submenu_callback(void* context, uint32_t index) {
+    TPMSApp* app = context;
+    view_dispatcher_send_custom_event(app->view_dispatcher, index);
+}
+
+void tpms_scene_start_on_enter(void* context) {
+    UNUSED(context);
+    TPMSApp* app = context;
+    Submenu* submenu = app->submenu;
+
+    submenu_add_item(
+        submenu, "Read TPMS", SubmenuIndexTPMSReceiver, tpms_scene_start_submenu_callback, app);
+    submenu_add_item(
+        submenu, "Relearn", SubmenuIndexTPMSRelearn, tpms_scene_start_submenu_callback, app);
+    // Help
+    submenu_add_item(
+        submenu, "About", SubmenuIndexTPMSAbout, tpms_scene_start_submenu_callback, app);
+
+    submenu_set_selected_item(
+        submenu, scene_manager_get_scene_state(app->scene_manager, TPMSSceneStart));
+
+    view_dispatcher_switch_to_view(app->view_dispatcher, TPMSViewSubmenu);
+}
+
+bool tpms_scene_start_on_event(void* context, SceneManagerEvent event) {
+    TPMSApp* app = context;
+    bool consumed = false;
+
+    if(event.type == SceneManagerEventTypeBack) {
+        // Exit application.
+        scene_manager_stop(app->scene_manager);
+        view_dispatcher_stop(app->view_dispatcher);
+        consumed = true;
+    } else if(event.type == SceneManagerEventTypeCustom) {
+        if(event.event == SubmenuIndexTPMSAbout) {
+            scene_manager_next_scene(app->scene_manager, TPMSSceneAbout);
+            consumed = true;
+        } else if(event.event == SubmenuIndexTPMSReceiver) {
+            scene_manager_next_scene(app->scene_manager, TPMSSceneReceiver);
+            consumed = true;
+        } else if(event.event == SubmenuIndexTPMSRelearn) {
+            scene_manager_next_scene(app->scene_manager, TPMSSceneRelearn);
+            consumed = true;
+        }
+        scene_manager_set_scene_state(app->scene_manager, TPMSSceneStart, event.event);
+    }
+
+    return consumed;
+}
+
+void tpms_scene_start_on_exit(void* context) {
+    TPMSApp* app = context;
+    submenu_reset(app->submenu);
+}

BIN
non_catalog_apps/tpms_receiver/tpms_10px.png


+ 185 - 0
non_catalog_apps/tpms_receiver/tpms_app.c

@@ -0,0 +1,185 @@
+#include "tpms_app_i.h"
+
+#include <furi.h>
+#include <furi_hal.h>
+#include "protocols/protocol_items.h"
+
+static bool tpms_app_custom_event_callback(void* context, uint32_t event) {
+    furi_assert(context);
+    TPMSApp* app = context;
+    return scene_manager_handle_custom_event(app->scene_manager, event);
+}
+
+static bool tpms_app_back_event_callback(void* context) {
+    furi_assert(context);
+    TPMSApp* app = context;
+    return scene_manager_handle_back_event(app->scene_manager);
+}
+
+static void tpms_app_tick_event_callback(void* context) {
+    furi_assert(context);
+    TPMSApp* app = context;
+    scene_manager_handle_tick_event(app->scene_manager);
+}
+
+TPMSApp* tpms_app_alloc() {
+    TPMSApp* app = malloc(sizeof(TPMSApp));
+
+    // GUI
+    app->gui = furi_record_open(RECORD_GUI);
+
+    // View Dispatcher
+    app->view_dispatcher = view_dispatcher_alloc();
+    app->scene_manager = scene_manager_alloc(&tpms_scene_handlers, app);
+    view_dispatcher_enable_queue(app->view_dispatcher);
+
+    view_dispatcher_set_event_callback_context(app->view_dispatcher, app);
+    view_dispatcher_set_custom_event_callback(
+        app->view_dispatcher, tpms_app_custom_event_callback);
+    view_dispatcher_set_navigation_event_callback(
+        app->view_dispatcher, tpms_app_back_event_callback);
+    view_dispatcher_set_tick_event_callback(
+        app->view_dispatcher, tpms_app_tick_event_callback, 100);
+
+    view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen);
+
+    // Open Notification record
+    app->notifications = furi_record_open(RECORD_NOTIFICATION);
+
+    // Variable Item List
+    app->variable_item_list = variable_item_list_alloc();
+    view_dispatcher_add_view(
+        app->view_dispatcher,
+        TPMSViewVariableItemList,
+        variable_item_list_get_view(app->variable_item_list));
+
+    // SubMenu
+    app->submenu = submenu_alloc();
+    view_dispatcher_add_view(
+        app->view_dispatcher, TPMSViewSubmenu, submenu_get_view(app->submenu));
+
+    // Widget
+    app->widget = widget_alloc();
+    view_dispatcher_add_view(app->view_dispatcher, TPMSViewWidget, widget_get_view(app->widget));
+
+    // Receiver
+    app->tpms_receiver = tpms_view_receiver_alloc();
+    view_dispatcher_add_view(
+        app->view_dispatcher, TPMSViewReceiver, tpms_view_receiver_get_view(app->tpms_receiver));
+
+    // Receiver Info
+    app->tpms_receiver_info = tpms_view_receiver_info_alloc();
+    view_dispatcher_add_view(
+        app->view_dispatcher,
+        TPMSViewReceiverInfo,
+        tpms_view_receiver_info_get_view(app->tpms_receiver_info));
+
+    //init setting
+    app->setting = subghz_setting_alloc();
+
+    //ToDo FIX  file name setting
+    subghz_setting_load(app->setting, EXT_PATH("subghz/assets/setting_user"));
+
+    //init Worker & Protocol & History
+    app->lock = TPMSLockOff;
+    app->txrx = malloc(sizeof(TPMSTxRx));
+    app->txrx->preset = malloc(sizeof(SubGhzRadioPreset));
+    app->txrx->preset->name = furi_string_alloc();
+    tpms_preset_init(app, "AM650", subghz_setting_get_default_frequency(app->setting), NULL, 0);
+
+    app->txrx->hopper_state = TPMSHopperStateOFF;
+    app->txrx->history = tpms_history_alloc();
+    app->txrx->worker = subghz_worker_alloc();
+    app->txrx->environment = subghz_environment_alloc();
+    subghz_environment_set_protocol_registry(
+        app->txrx->environment, (void*)&tpms_protocol_registry);
+    app->txrx->receiver = subghz_receiver_alloc_init(app->txrx->environment);
+
+    subghz_devices_init();
+
+    app->txrx->radio_device =
+        radio_device_loader_set(app->txrx->radio_device, SubGhzRadioDeviceTypeExternalCC1101);
+
+    subghz_devices_reset(app->txrx->radio_device);
+    subghz_devices_idle(app->txrx->radio_device);
+
+    subghz_receiver_set_filter(app->txrx->receiver, SubGhzProtocolFlag_Decodable);
+    subghz_worker_set_overrun_callback(
+        app->txrx->worker, (SubGhzWorkerOverrunCallback)subghz_receiver_reset);
+    subghz_worker_set_pair_callback(
+        app->txrx->worker, (SubGhzWorkerPairCallback)subghz_receiver_decode);
+    subghz_worker_set_context(app->txrx->worker, app->txrx->receiver);
+
+    furi_hal_power_suppress_charge_enter();
+
+    scene_manager_next_scene(app->scene_manager, TPMSSceneReceiver);
+
+    return app;
+}
+
+void tpms_app_free(TPMSApp* app) {
+    furi_assert(app);
+
+    subghz_devices_sleep(app->txrx->radio_device);
+    radio_device_loader_end(app->txrx->radio_device);
+
+    subghz_devices_deinit();
+
+    // Submenu
+    view_dispatcher_remove_view(app->view_dispatcher, TPMSViewSubmenu);
+    submenu_free(app->submenu);
+
+    // Variable Item List
+    view_dispatcher_remove_view(app->view_dispatcher, TPMSViewVariableItemList);
+    variable_item_list_free(app->variable_item_list);
+
+    //  Widget
+    view_dispatcher_remove_view(app->view_dispatcher, TPMSViewWidget);
+    widget_free(app->widget);
+
+    // Receiver
+    view_dispatcher_remove_view(app->view_dispatcher, TPMSViewReceiver);
+    tpms_view_receiver_free(app->tpms_receiver);
+
+    // Receiver Info
+    view_dispatcher_remove_view(app->view_dispatcher, TPMSViewReceiverInfo);
+    tpms_view_receiver_info_free(app->tpms_receiver_info);
+
+    //setting
+    subghz_setting_free(app->setting);
+
+    //Worker & Protocol & History
+    subghz_receiver_free(app->txrx->receiver);
+    subghz_environment_free(app->txrx->environment);
+    tpms_history_free(app->txrx->history);
+    subghz_worker_free(app->txrx->worker);
+    furi_string_free(app->txrx->preset->name);
+    free(app->txrx->preset);
+    free(app->txrx);
+
+    // View dispatcher
+    view_dispatcher_free(app->view_dispatcher);
+    scene_manager_free(app->scene_manager);
+
+    // Notifications
+    furi_record_close(RECORD_NOTIFICATION);
+    app->notifications = NULL;
+
+    // Close records
+    furi_record_close(RECORD_GUI);
+
+    furi_hal_power_suppress_charge_exit();
+
+    free(app);
+}
+
+int32_t tpms_app(void* p) {
+    UNUSED(p);
+    TPMSApp* tpms_app = tpms_app_alloc();
+
+    view_dispatcher_run(tpms_app->view_dispatcher);
+
+    tpms_app_free(tpms_app);
+
+    return 0;
+}

+ 153 - 0
non_catalog_apps/tpms_receiver/tpms_app_i.c

@@ -0,0 +1,153 @@
+#include "tpms_app_i.h"
+
+#define TAG "TPMS"
+#include <flipper_format/flipper_format_i.h>
+
+void tpms_preset_init(
+    void* context,
+    const char* preset_name,
+    uint32_t frequency,
+    uint8_t* preset_data,
+    size_t preset_data_size) {
+    furi_assert(context);
+    TPMSApp* app = context;
+    furi_string_set(app->txrx->preset->name, preset_name);
+    app->txrx->preset->frequency = frequency;
+    app->txrx->preset->data = preset_data;
+    app->txrx->preset->data_size = preset_data_size;
+}
+
+bool tpms_set_preset(TPMSApp* app, const char* preset) {
+    if(!strcmp(preset, "FuriHalSubGhzPresetOok270Async")) {
+        furi_string_set(app->txrx->preset->name, "AM270");
+    } else if(!strcmp(preset, "FuriHalSubGhzPresetOok650Async")) {
+        furi_string_set(app->txrx->preset->name, "AM650");
+    } else if(!strcmp(preset, "FuriHalSubGhzPreset2FSKDev238Async")) {
+        furi_string_set(app->txrx->preset->name, "FM238");
+    } else if(!strcmp(preset, "FuriHalSubGhzPreset2FSKDev476Async")) {
+        furi_string_set(app->txrx->preset->name, "FM476");
+    } else if(!strcmp(preset, "FuriHalSubGhzPresetCustom")) {
+        furi_string_set(app->txrx->preset->name, "CUSTOM");
+    } else {
+        FURI_LOG_E(TAG, "Unknown preset");
+        return false;
+    }
+    return true;
+}
+
+void tpms_get_frequency_modulation(TPMSApp* app, FuriString* frequency, FuriString* modulation) {
+    furi_assert(app);
+    if(frequency != NULL) {
+        furi_string_printf(
+            frequency,
+            "%03ld.%02ld",
+            app->txrx->preset->frequency / 1000000 % 1000,
+            app->txrx->preset->frequency / 10000 % 100);
+    }
+    if(modulation != NULL) {
+        furi_string_printf(modulation, "%.2s", furi_string_get_cstr(app->txrx->preset->name));
+    }
+}
+
+void tpms_begin(TPMSApp* app, uint8_t* preset_data) {
+    furi_assert(app);
+    UNUSED(preset_data);
+    furi_hal_subghz_reset();
+    furi_hal_subghz_idle();
+    furi_hal_subghz_load_custom_preset(preset_data);
+    furi_hal_gpio_init(&gpio_cc1101_g0, GpioModeInput, GpioPullNo, GpioSpeedLow);
+    app->txrx->txrx_state = TPMSTxRxStateIDLE;
+}
+
+uint32_t tpms_rx(TPMSApp* app, uint32_t frequency) {
+    furi_assert(app);
+    if(!furi_hal_subghz_is_frequency_valid(frequency)) {
+        furi_crash("TPMS: Incorrect RX frequency.");
+    }
+    furi_assert(
+        app->txrx->txrx_state != TPMSTxRxStateRx && app->txrx->txrx_state != TPMSTxRxStateSleep);
+
+    furi_hal_subghz_idle();
+    uint32_t value = furi_hal_subghz_set_frequency_and_path(frequency);
+    furi_hal_gpio_init(&gpio_cc1101_g0, GpioModeInput, GpioPullNo, GpioSpeedLow);
+    furi_hal_subghz_flush_rx();
+    furi_hal_subghz_rx();
+
+    furi_hal_subghz_start_async_rx(subghz_worker_rx_callback, app->txrx->worker);
+    subghz_worker_start(app->txrx->worker);
+    app->txrx->txrx_state = TPMSTxRxStateRx;
+    return value;
+}
+
+void tpms_idle(TPMSApp* app) {
+    furi_assert(app);
+    furi_assert(app->txrx->txrx_state != TPMSTxRxStateSleep);
+    furi_hal_subghz_idle();
+    app->txrx->txrx_state = TPMSTxRxStateIDLE;
+}
+
+void tpms_rx_end(TPMSApp* app) {
+    furi_assert(app);
+    furi_assert(app->txrx->txrx_state == TPMSTxRxStateRx);
+    if(subghz_worker_is_running(app->txrx->worker)) {
+        subghz_worker_stop(app->txrx->worker);
+        furi_hal_subghz_stop_async_rx();
+    }
+    furi_hal_subghz_idle();
+    app->txrx->txrx_state = TPMSTxRxStateIDLE;
+}
+
+void tpms_sleep(TPMSApp* app) {
+    furi_assert(app);
+    furi_hal_subghz_sleep();
+    app->txrx->txrx_state = TPMSTxRxStateSleep;
+}
+
+void tpms_hopper_update(TPMSApp* app) {
+    furi_assert(app);
+
+    switch(app->txrx->hopper_state) {
+    case TPMSHopperStateOFF:
+    case TPMSHopperStatePause:
+        return;
+    case TPMSHopperStateRSSITimeOut:
+        if(app->txrx->hopper_timeout != 0) {
+            app->txrx->hopper_timeout--;
+            return;
+        }
+        break;
+    default:
+        break;
+    }
+    float rssi = -127.0f;
+    if(app->txrx->hopper_state != TPMSHopperStateRSSITimeOut) {
+        // See RSSI Calculation timings in CC1101 17.3 RSSI
+        rssi = furi_hal_subghz_get_rssi();
+
+        // Stay if RSSI is high enough
+        if(rssi > -90.0f) {
+            app->txrx->hopper_timeout = 10;
+            app->txrx->hopper_state = TPMSHopperStateRSSITimeOut;
+            return;
+        }
+    } else {
+        app->txrx->hopper_state = TPMSHopperStateRunnig;
+    }
+    // Select next frequency
+    if(app->txrx->hopper_idx_frequency <
+       subghz_setting_get_hopper_frequency_count(app->setting) - 1) {
+        app->txrx->hopper_idx_frequency++;
+    } else {
+        app->txrx->hopper_idx_frequency = 0;
+    }
+
+    if(app->txrx->txrx_state == TPMSTxRxStateRx) {
+        tpms_rx_end(app);
+    };
+    if(app->txrx->txrx_state == TPMSTxRxStateIDLE) {
+        subghz_receiver_reset(app->txrx->receiver);
+        app->txrx->preset->frequency =
+            subghz_setting_get_hopper_frequency(app->setting, app->txrx->hopper_idx_frequency);
+        tpms_rx(app, app->txrx->preset->frequency);
+    }
+}

+ 77 - 0
non_catalog_apps/tpms_receiver/tpms_app_i.h

@@ -0,0 +1,77 @@
+#pragma once
+
+#include "helpers/tpms_types.h"
+
+#include "scenes/tpms_scene.h"
+#include <gui/gui.h>
+#include <gui/view_dispatcher.h>
+#include <gui/scene_manager.h>
+#include <gui/modules/submenu.h>
+#include <gui/modules/variable_item_list.h>
+#include <gui/modules/widget.h>
+#include <notification/notification_messages.h>
+#include "views/tpms_receiver.h"
+#include "views/tpms_receiver_info.h"
+#include "tpms_history.h"
+
+#include <lib/subghz/subghz_setting.h>
+#include <lib/subghz/subghz_worker.h>
+#include <lib/subghz/receiver.h>
+#include <lib/subghz/transmitter.h>
+#include <lib/subghz/registry.h>
+
+#include "helpers/radio_device_loader.h"
+
+typedef struct TPMSApp TPMSApp;
+
+struct TPMSTxRx
+{
+    SubGhzWorker *worker;
+
+    const SubGhzDevice *radio_device;
+    SubGhzEnvironment *environment;
+    SubGhzReceiver *receiver;
+    SubGhzRadioPreset *preset;
+    TPMSHistory *history;
+    uint16_t idx_menu_chosen;
+    TPMSTxRxState txrx_state;
+    TPMSHopperState hopper_state;
+    uint8_t hopper_timeout;
+    uint8_t hopper_idx_frequency;
+    TPMSRxKeyState rx_key_state;
+};
+
+typedef struct TPMSTxRx TPMSTxRx;
+
+struct TPMSApp
+{
+    Gui *gui;
+    ViewDispatcher *view_dispatcher;
+    TPMSTxRx *txrx;
+    SceneManager *scene_manager;
+    NotificationApp *notifications;
+    VariableItemList *variable_item_list;
+    Submenu *submenu;
+    Widget *widget;
+    TPMSReceiver *tpms_receiver;
+    TPMSReceiverInfo *tpms_receiver_info;
+    TPMSLock lock;
+    SubGhzSetting *setting;
+    TPMSRelearn relearn;
+    TPMSRelearnType relearn_type;
+};
+
+void tpms_preset_init(
+    void *context,
+    const char *preset_name,
+    uint32_t frequency,
+    uint8_t *preset_data,
+    size_t preset_data_size);
+bool tpms_set_preset(TPMSApp *app, const char *preset);
+void tpms_get_frequency_modulation(TPMSApp *app, FuriString *frequency, FuriString *modulation);
+void tpms_begin(TPMSApp *app, uint8_t *preset_data);
+uint32_t tpms_rx(TPMSApp *app, uint32_t frequency);
+void tpms_idle(TPMSApp *app);
+void tpms_rx_end(TPMSApp *app);
+void tpms_sleep(TPMSApp *app);
+void tpms_hopper_update(TPMSApp *app);

+ 232 - 0
non_catalog_apps/tpms_receiver/tpms_history.c

@@ -0,0 +1,232 @@
+#include "tpms_history.h"
+#include <flipper_format/flipper_format_i.h>
+#include <lib/toolbox/stream/stream.h>
+#include <lib/subghz/receiver.h>
+#include "protocols/tpms_generic.h"
+
+#include <furi.h>
+
+#define TPMS_HISTORY_MAX 50
+#define TAG "TPMSHistory"
+
+typedef struct {
+    FuriString* item_str;
+    FlipperFormat* flipper_string;
+    uint8_t type;
+    uint32_t id;
+    SubGhzRadioPreset* preset;
+} TPMSHistoryItem;
+
+ARRAY_DEF(TPMSHistoryItemArray, TPMSHistoryItem, M_POD_OPLIST)
+
+#define M_OPL_TPMSHistoryItemArray_t() ARRAY_OPLIST(TPMSHistoryItemArray, M_POD_OPLIST)
+
+typedef struct {
+    TPMSHistoryItemArray_t data;
+} TPMSHistoryStruct;
+
+struct TPMSHistory {
+    uint32_t last_update_timestamp;
+    uint16_t last_index_write;
+    uint8_t code_last_hash_data;
+    FuriString* tmp_string;
+    TPMSHistoryStruct* history;
+};
+
+TPMSHistory* tpms_history_alloc(void) {
+    TPMSHistory* instance = malloc(sizeof(TPMSHistory));
+    instance->tmp_string = furi_string_alloc();
+    instance->history = malloc(sizeof(TPMSHistoryStruct));
+    TPMSHistoryItemArray_init(instance->history->data);
+    return instance;
+}
+
+void tpms_history_free(TPMSHistory* instance) {
+    furi_assert(instance);
+    furi_string_free(instance->tmp_string);
+    for
+        M_EACH(item, instance->history->data, TPMSHistoryItemArray_t) {
+            furi_string_free(item->item_str);
+            furi_string_free(item->preset->name);
+            free(item->preset);
+            flipper_format_free(item->flipper_string);
+            item->type = 0;
+        }
+    TPMSHistoryItemArray_clear(instance->history->data);
+    free(instance->history);
+    free(instance);
+}
+
+uint32_t tpms_history_get_frequency(TPMSHistory* instance, uint16_t idx) {
+    furi_assert(instance);
+    TPMSHistoryItem* item = TPMSHistoryItemArray_get(instance->history->data, idx);
+    return item->preset->frequency;
+}
+
+SubGhzRadioPreset* tpms_history_get_radio_preset(TPMSHistory* instance, uint16_t idx) {
+    furi_assert(instance);
+    TPMSHistoryItem* item = TPMSHistoryItemArray_get(instance->history->data, idx);
+    return item->preset;
+}
+
+const char* tpms_history_get_preset(TPMSHistory* instance, uint16_t idx) {
+    furi_assert(instance);
+    TPMSHistoryItem* item = TPMSHistoryItemArray_get(instance->history->data, idx);
+    return furi_string_get_cstr(item->preset->name);
+}
+
+void tpms_history_reset(TPMSHistory* instance) {
+    furi_assert(instance);
+    furi_string_reset(instance->tmp_string);
+    for
+        M_EACH(item, instance->history->data, TPMSHistoryItemArray_t) {
+            furi_string_free(item->item_str);
+            furi_string_free(item->preset->name);
+            free(item->preset);
+            flipper_format_free(item->flipper_string);
+            item->type = 0;
+        }
+    TPMSHistoryItemArray_reset(instance->history->data);
+    instance->last_index_write = 0;
+    instance->code_last_hash_data = 0;
+}
+
+uint16_t tpms_history_get_item(TPMSHistory* instance) {
+    furi_assert(instance);
+    return instance->last_index_write;
+}
+
+uint8_t tpms_history_get_type_protocol(TPMSHistory* instance, uint16_t idx) {
+    furi_assert(instance);
+    TPMSHistoryItem* item = TPMSHistoryItemArray_get(instance->history->data, idx);
+    return item->type;
+}
+
+const char* tpms_history_get_protocol_name(TPMSHistory* instance, uint16_t idx) {
+    furi_assert(instance);
+    TPMSHistoryItem* item = TPMSHistoryItemArray_get(instance->history->data, idx);
+    flipper_format_rewind(item->flipper_string);
+    if(!flipper_format_read_string(item->flipper_string, "Protocol", instance->tmp_string)) {
+        FURI_LOG_E(TAG, "Missing Protocol");
+        furi_string_reset(instance->tmp_string);
+    }
+    return furi_string_get_cstr(instance->tmp_string);
+}
+
+FlipperFormat* tpms_history_get_raw_data(TPMSHistory* instance, uint16_t idx) {
+    furi_assert(instance);
+    TPMSHistoryItem* item = TPMSHistoryItemArray_get(instance->history->data, idx);
+    if(item->flipper_string) {
+        return item->flipper_string;
+    } else {
+        return NULL;
+    }
+}
+bool tpms_history_get_text_space_left(TPMSHistory* instance, FuriString* output) {
+    furi_assert(instance);
+    if(instance->last_index_write == TPMS_HISTORY_MAX) {
+        if(output != NULL) furi_string_printf(output, "Memory is FULL");
+        return true;
+    }
+    if(output != NULL)
+        furi_string_printf(output, "%02u/%02u", instance->last_index_write, TPMS_HISTORY_MAX);
+    return false;
+}
+
+void tpms_history_get_text_item_menu(TPMSHistory* instance, FuriString* output, uint16_t idx) {
+    TPMSHistoryItem* item = TPMSHistoryItemArray_get(instance->history->data, idx);
+    furi_string_set(output, item->item_str);
+}
+
+TPMSHistoryStateAddKey
+    tpms_history_add_to_history(TPMSHistory* instance, void* context, SubGhzRadioPreset* preset) {
+    furi_assert(instance);
+    furi_assert(context);
+
+    if(instance->last_index_write >= TPMS_HISTORY_MAX) return TPMSHistoryStateAddKeyOverflow;
+
+    SubGhzProtocolDecoderBase* decoder_base = context;
+    if((instance->code_last_hash_data ==
+        subghz_protocol_decoder_base_get_hash_data(decoder_base)) &&
+       ((furi_get_tick() - instance->last_update_timestamp) < 500)) {
+        instance->last_update_timestamp = furi_get_tick();
+        return TPMSHistoryStateAddKeyTimeOut;
+    }
+
+    instance->code_last_hash_data = subghz_protocol_decoder_base_get_hash_data(decoder_base);
+    instance->last_update_timestamp = furi_get_tick();
+
+    FlipperFormat* fff = flipper_format_string_alloc();
+    uint32_t id = 0;
+    subghz_protocol_decoder_base_serialize(decoder_base, fff, preset);
+
+    do {
+        if(!flipper_format_rewind(fff)) {
+            FURI_LOG_E(TAG, "Rewind error");
+            break;
+        }
+        if(!flipper_format_read_uint32(fff, "Id", (uint32_t*)&id, 1)) {
+            FURI_LOG_E(TAG, "Missing Id");
+            break;
+        }
+    } while(false);
+    flipper_format_free(fff);
+
+    // Update record if found
+    bool sensor_found = false;
+    for(size_t i = 0; i < TPMSHistoryItemArray_size(instance->history->data); i++) {
+        TPMSHistoryItem* item = TPMSHistoryItemArray_get(instance->history->data, i);
+        if(item->id == id) {
+            sensor_found = true;
+            Stream* flipper_string_stream = flipper_format_get_raw_stream(item->flipper_string);
+            stream_clean(flipper_string_stream);
+            subghz_protocol_decoder_base_serialize(decoder_base, item->flipper_string, preset);
+            return TPMSHistoryStateAddKeyUpdateData;
+        }
+    }
+
+    // or add new record
+    if(!sensor_found) { //-V547
+        TPMSHistoryItem* item = TPMSHistoryItemArray_push_raw(instance->history->data);
+        item->preset = malloc(sizeof(SubGhzRadioPreset));
+        item->type = decoder_base->protocol->type;
+        item->preset->frequency = preset->frequency;
+        item->preset->name = furi_string_alloc();
+        furi_string_set(item->preset->name, preset->name);
+        item->preset->data = preset->data;
+        item->preset->data_size = preset->data_size;
+        item->id = id;
+
+        item->item_str = furi_string_alloc();
+        item->flipper_string = flipper_format_string_alloc();
+        subghz_protocol_decoder_base_serialize(decoder_base, item->flipper_string, preset);
+
+        do {
+            if(!flipper_format_rewind(item->flipper_string)) {
+                FURI_LOG_E(TAG, "Rewind error");
+                break;
+            }
+            if(!flipper_format_read_string(
+                   item->flipper_string, "Protocol", instance->tmp_string)) {
+                FURI_LOG_E(TAG, "Missing Protocol");
+                break;
+            }
+
+            if(!flipper_format_rewind(item->flipper_string)) {
+                FURI_LOG_E(TAG, "Rewind error");
+                break;
+            }
+            uint32_t id = 0;
+            if(!flipper_format_read_uint32(item->flipper_string, "Id", &id, 1)) {
+                FURI_LOG_E(TAG, "Missing Id");
+                break;
+            }
+            furi_string_cat_printf(instance->tmp_string, " %lX", id);
+
+            furi_string_set(item->item_str, instance->tmp_string);
+        } while(false);
+        instance->last_index_write++;
+        return TPMSHistoryStateAddKeyNewDada;
+    }
+    return TPMSHistoryStateAddKeyUnknown;
+}

+ 112 - 0
non_catalog_apps/tpms_receiver/tpms_history.h

@@ -0,0 +1,112 @@
+
+#pragma once
+
+#include <math.h>
+#include <furi.h>
+#include <furi_hal.h>
+#include <lib/flipper_format/flipper_format.h>
+#include <lib/subghz/types.h>
+
+typedef struct TPMSHistory TPMSHistory;
+
+/** History state add key */
+typedef enum {
+    TPMSHistoryStateAddKeyUnknown,
+    TPMSHistoryStateAddKeyTimeOut,
+    TPMSHistoryStateAddKeyNewDada,
+    TPMSHistoryStateAddKeyUpdateData,
+    TPMSHistoryStateAddKeyOverflow,
+} TPMSHistoryStateAddKey;
+
+/** Allocate TPMSHistory
+ * 
+ * @return TPMSHistory* 
+ */
+TPMSHistory* tpms_history_alloc(void);
+
+/** Free TPMSHistory
+ * 
+ * @param instance - TPMSHistory instance
+ */
+void tpms_history_free(TPMSHistory* instance);
+
+/** Clear history
+ * 
+ * @param instance - TPMSHistory instance
+ */
+void tpms_history_reset(TPMSHistory* instance);
+
+/** Get frequency to history[idx]
+ * 
+ * @param instance  - TPMSHistory instance
+ * @param idx       - record index  
+ * @return frequency - frequency Hz
+ */
+uint32_t tpms_history_get_frequency(TPMSHistory* instance, uint16_t idx);
+
+SubGhzRadioPreset* tpms_history_get_radio_preset(TPMSHistory* instance, uint16_t idx);
+
+/** Get preset to history[idx]
+ * 
+ * @param instance  - TPMSHistory instance
+ * @param idx       - record index  
+ * @return preset   - preset name
+ */
+const char* tpms_history_get_preset(TPMSHistory* instance, uint16_t idx);
+
+/** Get history index write 
+ * 
+ * @param instance  - TPMSHistory instance
+ * @return idx      - current record index  
+ */
+uint16_t tpms_history_get_item(TPMSHistory* instance);
+
+/** Get type protocol to history[idx]
+ * 
+ * @param instance  - TPMSHistory instance
+ * @param idx       - record index  
+ * @return type      - type protocol  
+ */
+uint8_t tpms_history_get_type_protocol(TPMSHistory* instance, uint16_t idx);
+
+/** Get name protocol to history[idx]
+ * 
+ * @param instance  - TPMSHistory instance
+ * @param idx       - record index  
+ * @return name      - const char* name protocol  
+ */
+const char* tpms_history_get_protocol_name(TPMSHistory* instance, uint16_t idx);
+
+/** Get string item menu to history[idx]
+ * 
+ * @param instance  - TPMSHistory instance
+ * @param output    - FuriString* output
+ * @param idx       - record index
+ */
+void tpms_history_get_text_item_menu(TPMSHistory* instance, FuriString* output, uint16_t idx);
+
+/** Get string the remaining number of records to history
+ * 
+ * @param instance  - TPMSHistory instance
+ * @param output    - FuriString* output
+ * @return bool - is FUUL
+ */
+bool tpms_history_get_text_space_left(TPMSHistory* instance, FuriString* output);
+
+/** Add protocol to history
+ * 
+ * @param instance  - TPMSHistory instance
+ * @param context    - SubGhzProtocolCommon context
+ * @param preset    - SubGhzRadioPreset preset
+ * @return TPMSHistoryStateAddKey;
+ */
+TPMSHistoryStateAddKey
+    tpms_history_add_to_history(TPMSHistory* instance, void* context, SubGhzRadioPreset* preset);
+
+/** Get SubGhzProtocolCommonLoad to load into the protocol decoder bin data
+ * 
+ * @param instance  - TPMSHistory instance
+ * @param idx       - record index
+ * @return SubGhzProtocolCommonLoad*
+ */
+FlipperFormat* tpms_history_get_raw_data(TPMSHistory* instance, uint16_t idx);

+ 509 - 0
non_catalog_apps/tpms_receiver/views/tpms_receiver.c

@@ -0,0 +1,509 @@
+#include "tpms_receiver.h"
+#include "../tpms_app_i.h"
+#include <tpms_icons.h>
+#include <math.h>
+
+#include <input/input.h>
+#include <gui/elements.h>
+#include <m-array.h>
+
+#define TAG "TPMSReceiver"
+
+#define FRAME_HEIGHT 12
+#define MAX_LEN_PX 112
+#define MENU_ITEMS 4u
+#define UNLOCK_CNT 3
+
+#define SUBGHZ_RAW_THRESHOLD_MIN -90.0f
+typedef struct {
+    FuriString* item_str;
+    uint8_t type;
+} TPMSReceiverMenuItem;
+
+ARRAY_DEF(TPMSReceiverMenuItemArray, TPMSReceiverMenuItem, M_POD_OPLIST)
+
+#define M_OPL_TPMSReceiverMenuItemArray_t() ARRAY_OPLIST(TPMSReceiverMenuItemArray, M_POD_OPLIST)
+
+struct TPMSReceiverHistory {
+    TPMSReceiverMenuItemArray_t data;
+};
+
+typedef struct TPMSReceiverHistory TPMSReceiverHistory;
+
+// static const Icon* ReceiverItemIcons[] = {
+//     [SubGhzProtocolTypeUnknown] = &I_Quest_7x8,
+//     [SubGhzProtocolTypeStatic] = &I_Unlock_7x8,
+//     [SubGhzProtocolTypeDynamic] = &I_Lock_7x8,
+//     //[SubGhzProtocolWeatherStation] = &I_station_icon,
+// };
+
+typedef enum {
+    TPMSReceiverBarShowDefault,
+    TPMSReceiverBarShowLock,
+    TPMSReceiverBarShowToUnlockPress,
+    TPMSReceiverBarShowUnlock,
+} TPMSReceiverBarShow;
+
+struct TPMSReceiver {
+    TPMSLock lock;
+    uint8_t lock_count;
+    FuriTimer* lock_timer;
+    FuriTimer* relearn_timer;
+    bool relearn_active;
+    View* view;
+    TPMSReceiverCallback callback;
+    void* context;
+};
+
+typedef struct {
+    FuriString* frequency_str;
+    FuriString* preset_str;
+    FuriString* history_stat_str;
+    TPMSReceiverHistory* history;
+    uint16_t idx;
+    uint16_t list_offset;
+    uint16_t history_item;
+    TPMSReceiverBarShow bar_show;
+    uint8_t u_rssi;
+    bool external_radio;
+} TPMSReceiverModel;
+
+void tpms_view_receiver_set_rssi(TPMSReceiver* instance, float rssi) {
+    furi_assert(instance);
+    with_view_model(
+        instance->view,
+        TPMSReceiverModel * model,
+        {
+            if(rssi < SUBGHZ_RAW_THRESHOLD_MIN) {
+                model->u_rssi = 0;
+            } else {
+                model->u_rssi = (uint8_t)(rssi - SUBGHZ_RAW_THRESHOLD_MIN);
+            }
+        },
+        true);
+}
+
+void tpms_view_receiver_set_lock(TPMSReceiver* tpms_receiver, TPMSLock lock) {
+    furi_assert(tpms_receiver);
+    tpms_receiver->lock_count = 0;
+    if(lock == TPMSLockOn) {
+        tpms_receiver->lock = lock;
+        with_view_model(
+            tpms_receiver->view,
+            TPMSReceiverModel * model,
+            { model->bar_show = TPMSReceiverBarShowLock; },
+            true);
+        furi_timer_start(tpms_receiver->lock_timer, pdMS_TO_TICKS(1000));
+    } else {
+        with_view_model(
+            tpms_receiver->view,
+            TPMSReceiverModel * model,
+            { model->bar_show = TPMSReceiverBarShowDefault; },
+            true);
+    }
+}
+
+void tpms_view_receiver_set_callback(
+    TPMSReceiver* tpms_receiver,
+    TPMSReceiverCallback callback,
+    void* context) {
+    furi_assert(tpms_receiver);
+    furi_assert(callback);
+    tpms_receiver->callback = callback;
+    tpms_receiver->context = context;
+}
+
+static void tpms_view_receiver_update_offset(TPMSReceiver* tpms_receiver) {
+    furi_assert(tpms_receiver);
+
+    with_view_model(
+        tpms_receiver->view,
+        TPMSReceiverModel * model,
+        {
+            size_t history_item = model->history_item;
+            uint16_t bounds = history_item > 3 ? 2 : history_item;
+
+            if(history_item > 3 && model->idx >= (int16_t)(history_item - 1)) {
+                model->list_offset = model->idx - 3;
+            } else if(model->list_offset < model->idx - bounds) {
+                model->list_offset =
+                    CLAMP(model->list_offset + 1, (int16_t)(history_item - bounds), 0);
+            } else if(model->list_offset > model->idx - bounds) {
+                model->list_offset = CLAMP(model->idx - 1, (int16_t)(history_item - bounds), 0);
+            }
+        },
+        true);
+}
+
+void tpms_view_receiver_add_item_to_menu(
+    TPMSReceiver* tpms_receiver,
+    const char* name,
+    uint8_t type) {
+    furi_assert(tpms_receiver);
+    with_view_model(
+        tpms_receiver->view,
+        TPMSReceiverModel * model,
+        {
+            TPMSReceiverMenuItem* item_menu =
+                TPMSReceiverMenuItemArray_push_raw(model->history->data);
+            item_menu->item_str = furi_string_alloc_set(name);
+            item_menu->type = type;
+            if((model->idx == model->history_item - 1)) {
+                model->history_item++;
+                model->idx++;
+            } else {
+                model->history_item++;
+            }
+        },
+        true);
+    tpms_view_receiver_update_offset(tpms_receiver);
+}
+
+void tpms_view_receiver_add_data_statusbar(
+    TPMSReceiver* tpms_receiver,
+    const char* frequency_str,
+    const char* preset_str,
+    const char* history_stat_str,
+    bool external) {
+    furi_assert(tpms_receiver);
+    with_view_model(
+        tpms_receiver->view,
+        TPMSReceiverModel * model,
+        {
+            furi_string_set_str(model->frequency_str, frequency_str);
+            furi_string_set_str(model->preset_str, preset_str);
+            furi_string_set_str(model->history_stat_str, history_stat_str);
+            model->external_radio = external;
+        },
+        true);
+}
+
+static void tpms_view_receiver_draw_frame(Canvas* canvas, uint16_t idx, bool scrollbar) {
+    canvas_set_color(canvas, ColorBlack);
+    canvas_draw_box(canvas, 0, 0 + idx * FRAME_HEIGHT, scrollbar ? 122 : 127, FRAME_HEIGHT);
+
+    canvas_set_color(canvas, ColorWhite);
+    canvas_draw_dot(canvas, 0, 0 + idx * FRAME_HEIGHT);
+    canvas_draw_dot(canvas, 1, 0 + idx * FRAME_HEIGHT);
+    canvas_draw_dot(canvas, 0, (0 + idx * FRAME_HEIGHT) + 1);
+
+    canvas_draw_dot(canvas, 0, (0 + idx * FRAME_HEIGHT) + 11);
+    canvas_draw_dot(canvas, scrollbar ? 121 : 126, 0 + idx * FRAME_HEIGHT);
+    canvas_draw_dot(canvas, scrollbar ? 121 : 126, (0 + idx * FRAME_HEIGHT) + 11);
+}
+
+static void tpms_view_rssi_draw(Canvas* canvas, TPMSReceiverModel* model) {
+    for(uint8_t i = 1; i < model->u_rssi; i++) {
+        if(i % 5) {
+            canvas_draw_dot(canvas, 46 + i, 50);
+            canvas_draw_dot(canvas, 47 + i, 51);
+            canvas_draw_dot(canvas, 46 + i, 52);
+        }
+    }
+}
+
+void tpms_view_receiver_draw(Canvas* canvas, TPMSReceiverModel* model) {
+    canvas_clear(canvas);
+    canvas_set_color(canvas, ColorBlack);
+    canvas_set_font(canvas, FontSecondary);
+
+    elements_button_left(canvas, "Config");
+
+    bool scrollbar = model->history_item > 4;
+    FuriString* str_buff;
+    str_buff = furi_string_alloc();
+
+    TPMSReceiverMenuItem* item_menu;
+
+    for(size_t i = 0; i < MIN(model->history_item, MENU_ITEMS); ++i) {
+        size_t idx = CLAMP((uint16_t)(i + model->list_offset), model->history_item, 0);
+        item_menu = TPMSReceiverMenuItemArray_get(model->history->data, idx);
+        furi_string_set(str_buff, item_menu->item_str);
+        elements_string_fit_width(canvas, str_buff, scrollbar ? MAX_LEN_PX - 6 : MAX_LEN_PX);
+        if(model->idx == idx) {
+            tpms_view_receiver_draw_frame(canvas, i, scrollbar);
+        } else {
+            canvas_set_color(canvas, ColorBlack);
+        }
+        // canvas_draw_icon(canvas, 4, 2 + i * FRAME_HEIGHT, ReceiverItemIcons[item_menu->type]);
+        canvas_draw_str(canvas, 4, 9 + i * FRAME_HEIGHT, furi_string_get_cstr(str_buff));
+        furi_string_reset(str_buff);
+    }
+    if(scrollbar) {
+        elements_scrollbar_pos(canvas, 128, 0, 49, model->idx, model->history_item);
+    }
+    furi_string_free(str_buff);
+
+    canvas_set_color(canvas, ColorBlack);
+
+    if(model->history_item == 0) {
+        canvas_draw_icon(
+            canvas, 0, 0, model->external_radio ? &I_Fishing_123x52 : &I_Scanning_123x52);
+        canvas_set_font(canvas, FontPrimary);
+        canvas_draw_str(canvas, 63, 46, "Scanning...");
+        canvas_set_font(canvas, FontSecondary);
+        canvas_draw_str(canvas, 44, 10, model->external_radio ? "Ext" : "Int");
+        canvas_draw_str(canvas, 70, 9, "-> to relearn");
+    }
+
+    // Draw RSSI
+    tpms_view_rssi_draw(canvas, model);
+
+    switch(model->bar_show) {
+    case TPMSReceiverBarShowLock:
+        canvas_draw_icon(canvas, 64, 55, &I_Lock_7x8);
+        canvas_draw_str(canvas, 74, 62, "Locked");
+        break;
+    case TPMSReceiverBarShowToUnlockPress:
+        canvas_draw_str(canvas, 44, 62, furi_string_get_cstr(model->frequency_str));
+        canvas_draw_str(canvas, 79, 62, furi_string_get_cstr(model->preset_str));
+        canvas_draw_str(canvas, 96, 62, furi_string_get_cstr(model->history_stat_str));
+        canvas_set_font(canvas, FontSecondary);
+        elements_bold_rounded_frame(canvas, 14, 8, 99, 48);
+        elements_multiline_text(canvas, 65, 26, "To unlock\npress:");
+        canvas_draw_icon(canvas, 65, 42, &I_Pin_back_arrow_10x8);
+        canvas_draw_icon(canvas, 80, 42, &I_Pin_back_arrow_10x8);
+        canvas_draw_icon(canvas, 95, 42, &I_Pin_back_arrow_10x8);
+        canvas_draw_icon(canvas, 16, 13, &I_WarningDolphin_45x42);
+        canvas_draw_dot(canvas, 17, 61);
+        break;
+    case TPMSReceiverBarShowUnlock:
+        canvas_draw_icon(canvas, 64, 55, &I_Unlock_7x8);
+        canvas_draw_str(canvas, 74, 62, "Unlocked");
+        break;
+    default:
+        canvas_draw_str(canvas, 44, 62, furi_string_get_cstr(model->frequency_str));
+        canvas_draw_str(canvas, 79, 62, furi_string_get_cstr(model->preset_str));
+        canvas_draw_str(canvas, 96, 62, furi_string_get_cstr(model->history_stat_str));
+        break;
+    }
+}
+
+static void tpms_view_receiver_lock_timer_callback(void* context) {
+    furi_assert(context);
+    TPMSReceiver* tpms_receiver = context;
+    with_view_model(
+        tpms_receiver->view,
+        TPMSReceiverModel * model,
+        { model->bar_show = TPMSReceiverBarShowDefault; },
+        true);
+    if(tpms_receiver->lock_count < UNLOCK_CNT) {
+        tpms_receiver->callback(TPMSCustomEventViewReceiverOffDisplay, tpms_receiver->context);
+    } else {
+        tpms_receiver->lock = TPMSLockOff;
+        tpms_receiver->callback(TPMSCustomEventViewReceiverUnlock, tpms_receiver->context);
+    }
+    tpms_receiver->lock_count = 0;
+}
+
+static void tpms_relearn_stop(void* context) {
+    furi_assert(context);
+    TPMSReceiver* tpms_receiver = context;
+    if(tpms_receiver->relearn_active) {
+        tpms_receiver->relearn_active = false;
+        furi_timer_stop(tpms_receiver->relearn_timer);
+        furi_hal_rfid_tim_read_stop();
+    }
+}
+
+static void tpms_relearn_start(void* context) {
+    furi_assert(context);
+    TPMSReceiver* tpms_receiver = context;
+    if(tpms_receiver->relearn_active) tpms_relearn_stop(context);
+    tpms_receiver->relearn_active = true;
+    furi_hal_rfid_tim_read_start(125000, 0.5);
+    furi_timer_start(tpms_receiver->relearn_timer, pdMS_TO_TICKS(3000));
+}
+
+static void tpms_view_receiver_relearn_timer_callback(void* context) {
+    furi_assert(context);
+    tpms_relearn_stop(context);
+}
+
+bool tpms_view_receiver_input(InputEvent* event, void* context) {
+    furi_assert(context);
+    TPMSReceiver* tpms_receiver = context;
+
+    if(tpms_receiver->lock == TPMSLockOn) {
+        with_view_model(
+            tpms_receiver->view,
+            TPMSReceiverModel * model,
+            { model->bar_show = TPMSReceiverBarShowToUnlockPress; },
+            true);
+        if(tpms_receiver->lock_count == 0) {
+            furi_timer_start(tpms_receiver->lock_timer, pdMS_TO_TICKS(1000));
+        }
+        if(event->key == InputKeyBack && event->type == InputTypeShort) {
+            tpms_receiver->lock_count++;
+        }
+        if(tpms_receiver->lock_count >= UNLOCK_CNT) {
+            tpms_receiver->callback(TPMSCustomEventViewReceiverUnlock, tpms_receiver->context);
+            with_view_model(
+                tpms_receiver->view,
+                TPMSReceiverModel * model,
+                { model->bar_show = TPMSReceiverBarShowUnlock; },
+                true);
+            tpms_receiver->lock = TPMSLockOff;
+            furi_timer_start(tpms_receiver->lock_timer, pdMS_TO_TICKS(650));
+        }
+
+        return true;
+    }
+
+    if(event->key == InputKeyBack && event->type == InputTypeShort) {
+        tpms_receiver->callback(TPMSCustomEventViewReceiverBack, tpms_receiver->context);
+    } else if(
+        event->key == InputKeyUp &&
+        (event->type == InputTypeShort || event->type == InputTypeRepeat)) {
+        with_view_model(
+            tpms_receiver->view,
+            TPMSReceiverModel * model,
+            {
+                if(model->idx != 0) model->idx--;
+            },
+            true);
+    } else if(
+        event->key == InputKeyDown &&
+        (event->type == InputTypeShort || event->type == InputTypeRepeat)) {
+        with_view_model(
+            tpms_receiver->view,
+            TPMSReceiverModel * model,
+            {
+                if(model->history_item && model->idx != model->history_item - 1) model->idx++;
+            },
+            true);
+    } else if(event->key == InputKeyLeft && event->type == InputTypeShort) {
+        tpms_receiver->callback(TPMSCustomEventViewReceiverConfig, tpms_receiver->context);
+    } else if(event->key == InputKeyRight && event->type == InputTypeShort) {
+        tpms_relearn_start(tpms_receiver);
+    } else if(event->key == InputKeyOk && event->type == InputTypeShort) {
+        with_view_model(
+            tpms_receiver->view,
+            TPMSReceiverModel * model,
+            {
+                if(model->history_item != 0) {
+                    tpms_receiver->callback(TPMSCustomEventViewReceiverOK, tpms_receiver->context);
+                }
+            },
+            false);
+    }
+
+    tpms_view_receiver_update_offset(tpms_receiver);
+
+    return true;
+}
+
+void tpms_view_receiver_enter(void* context) {
+    furi_assert(context);
+}
+
+void tpms_view_receiver_exit(void* context) {
+    furi_assert(context);
+    TPMSReceiver* tpms_receiver = context;
+    with_view_model(
+        tpms_receiver->view,
+        TPMSReceiverModel * model,
+        {
+            furi_string_reset(model->frequency_str);
+            furi_string_reset(model->preset_str);
+            furi_string_reset(model->history_stat_str);
+                for
+                    M_EACH(item_menu, model->history->data, TPMSReceiverMenuItemArray_t) {
+                        furi_string_free(item_menu->item_str);
+                        item_menu->type = 0;
+                    }
+                TPMSReceiverMenuItemArray_reset(model->history->data);
+                model->idx = 0;
+                model->list_offset = 0;
+                model->history_item = 0;
+        },
+        false);
+    furi_timer_stop(tpms_receiver->lock_timer);
+    tpms_relearn_stop(tpms_receiver);
+}
+
+TPMSReceiver* tpms_view_receiver_alloc() {
+    TPMSReceiver* tpms_receiver = malloc(sizeof(TPMSReceiver));
+
+    // View allocation and configuration
+    tpms_receiver->view = view_alloc();
+
+    tpms_receiver->lock = TPMSLockOff;
+    tpms_receiver->lock_count = 0;
+    view_allocate_model(tpms_receiver->view, ViewModelTypeLocking, sizeof(TPMSReceiverModel));
+    view_set_context(tpms_receiver->view, tpms_receiver);
+    view_set_draw_callback(tpms_receiver->view, (ViewDrawCallback)tpms_view_receiver_draw);
+    view_set_input_callback(tpms_receiver->view, tpms_view_receiver_input);
+    view_set_enter_callback(tpms_receiver->view, tpms_view_receiver_enter);
+    view_set_exit_callback(tpms_receiver->view, tpms_view_receiver_exit);
+
+    with_view_model(
+        tpms_receiver->view,
+        TPMSReceiverModel * model,
+        {
+            model->frequency_str = furi_string_alloc();
+            model->preset_str = furi_string_alloc();
+            model->history_stat_str = furi_string_alloc();
+            model->bar_show = TPMSReceiverBarShowDefault;
+            model->history = malloc(sizeof(TPMSReceiverHistory));
+            model->external_radio = false;
+            TPMSReceiverMenuItemArray_init(model->history->data);
+        },
+        true);
+    tpms_receiver->lock_timer =
+        furi_timer_alloc(tpms_view_receiver_lock_timer_callback, FuriTimerTypeOnce, tpms_receiver);
+    tpms_receiver->relearn_timer = furi_timer_alloc(
+        tpms_view_receiver_relearn_timer_callback, FuriTimerTypeOnce, tpms_receiver);
+    return tpms_receiver;
+}
+
+void tpms_view_receiver_free(TPMSReceiver* tpms_receiver) {
+    furi_assert(tpms_receiver);
+
+    with_view_model(
+        tpms_receiver->view,
+        TPMSReceiverModel * model,
+        {
+            furi_string_free(model->frequency_str);
+            furi_string_free(model->preset_str);
+            furi_string_free(model->history_stat_str);
+                for
+                    M_EACH(item_menu, model->history->data, TPMSReceiverMenuItemArray_t) {
+                        furi_string_free(item_menu->item_str);
+                        item_menu->type = 0;
+                    }
+                TPMSReceiverMenuItemArray_clear(model->history->data);
+                free(model->history);
+        },
+        false);
+    furi_timer_free(tpms_receiver->lock_timer);
+    furi_timer_free(tpms_receiver->relearn_timer);
+    view_free(tpms_receiver->view);
+    free(tpms_receiver);
+}
+
+View* tpms_view_receiver_get_view(TPMSReceiver* tpms_receiver) {
+    furi_assert(tpms_receiver);
+    return tpms_receiver->view;
+}
+
+uint16_t tpms_view_receiver_get_idx_menu(TPMSReceiver* tpms_receiver) {
+    furi_assert(tpms_receiver);
+    uint32_t idx = 0;
+    with_view_model(
+        tpms_receiver->view, TPMSReceiverModel * model, { idx = model->idx; }, false);
+    return idx;
+}
+
+void tpms_view_receiver_set_idx_menu(TPMSReceiver* tpms_receiver, uint16_t idx) {
+    furi_assert(tpms_receiver);
+    with_view_model(
+        tpms_receiver->view,
+        TPMSReceiverModel * model,
+        {
+            model->idx = idx;
+            if(model->idx > 2) model->list_offset = idx - 2;
+        },
+        true);
+    tpms_view_receiver_update_offset(tpms_receiver);
+}

+ 42 - 0
non_catalog_apps/tpms_receiver/views/tpms_receiver.h

@@ -0,0 +1,42 @@
+#pragma once
+
+#include <gui/view.h>
+#include "../helpers/tpms_types.h"
+#include "../helpers/tpms_event.h"
+
+typedef struct TPMSReceiver TPMSReceiver;
+
+typedef void (*TPMSReceiverCallback)(TPMSCustomEvent event, void* context);
+
+void tpms_view_receiver_set_rssi(TPMSReceiver* instance, float rssi);
+
+void tpms_view_receiver_set_lock(TPMSReceiver* tpms_receiver, TPMSLock keyboard);
+
+void tpms_view_receiver_set_callback(
+    TPMSReceiver* tpms_receiver,
+    TPMSReceiverCallback callback,
+    void* context);
+
+TPMSReceiver* tpms_view_receiver_alloc();
+
+void tpms_view_receiver_free(TPMSReceiver* tpms_receiver);
+
+View* tpms_view_receiver_get_view(TPMSReceiver* tpms_receiver);
+
+void tpms_view_receiver_add_data_statusbar(
+    TPMSReceiver* tpms_receiver,
+    const char* frequency_str,
+    const char* preset_str,
+    const char* history_stat_str,
+    bool external);
+
+void tpms_view_receiver_add_item_to_menu(
+    TPMSReceiver* tpms_receiver,
+    const char* name,
+    uint8_t type);
+
+uint16_t tpms_view_receiver_get_idx_menu(TPMSReceiver* tpms_receiver);
+
+void tpms_view_receiver_set_idx_menu(TPMSReceiver* tpms_receiver, uint16_t idx);
+
+void tpms_view_receiver_exit(void* context);

+ 233 - 0
non_catalog_apps/tpms_receiver/views/tpms_receiver_info.c

@@ -0,0 +1,233 @@
+#include "tpms_receiver.h"
+#include "../tpms_app_i.h"
+#include "tpms_icons.h"
+#include "../protocols/tpms_generic.h"
+#include <input/input.h>
+#include <gui/elements.h>
+#include <float_tools.h>
+
+struct TPMSReceiverInfo {
+    View* view;
+    FuriTimer* timer;
+};
+
+typedef struct {
+    uint32_t curr_ts;
+    FuriString* protocol_name;
+    TPMSBlockGeneric* generic;
+} TPMSReceiverInfoModel;
+
+void tpms_view_receiver_info_update(TPMSReceiverInfo* tpms_receiver_info, FlipperFormat* fff) {
+    furi_assert(tpms_receiver_info);
+    furi_assert(fff);
+
+    with_view_model(
+        tpms_receiver_info->view,
+        TPMSReceiverInfoModel * model,
+        {
+            flipper_format_rewind(fff);
+            flipper_format_read_string(fff, "Protocol", model->protocol_name);
+
+            tpms_block_generic_deserialize(model->generic, fff);
+
+            FuriHalRtcDateTime curr_dt;
+            furi_hal_rtc_get_datetime(&curr_dt);
+            model->curr_ts = furi_hal_rtc_datetime_to_timestamp(&curr_dt);
+        },
+        true);
+}
+
+void tpms_view_receiver_info_draw(Canvas* canvas, TPMSReceiverInfoModel* model) {
+    char buffer[64];
+    canvas_clear(canvas);
+    canvas_set_color(canvas, ColorBlack);
+    canvas_set_font(canvas, FontSecondary);
+
+    snprintf(
+        buffer,
+        sizeof(buffer),
+        "%s %db",
+        furi_string_get_cstr(model->protocol_name),
+        model->generic->data_count_bit);
+    canvas_draw_str(canvas, 0, 8, buffer);
+
+    snprintf(buffer, sizeof(buffer), "ID: 0x%lX", model->generic->id);
+    canvas_draw_str(canvas, 0, 20, buffer);
+
+    if(model->generic->battery_low != TPMS_NO_BATT) {
+        snprintf(
+            buffer, sizeof(buffer), "Batt: %s", (!model->generic->battery_low ? "ok" : "low"));
+        canvas_draw_str_aligned(canvas, 126, 17, AlignRight, AlignCenter, buffer);
+    }
+
+    // snprintf(buffer, sizeof(buffer), "Data: 0x%llX", model->generic->data);
+    // canvas_draw_str(canvas, 0, 32, buffer);
+
+    elements_bold_rounded_frame(canvas, 0, 38, 127, 25);
+    canvas_set_font(canvas, FontPrimary);
+
+    // Temperature
+    canvas_draw_icon(canvas, 6, 43, &I_Therm_7x16);
+
+    uint8_t temp_x1 = 0;
+    uint8_t temp_x2 = 0;
+    if(furi_hal_rtc_get_locale_units() == FuriHalRtcLocaleUnitsMetric) {
+        snprintf(buffer, sizeof(buffer), "%2.0f C", (double)model->generic->temperature);
+        if(model->generic->temperature < -9.0f) {
+            temp_x1 = 42;
+            temp_x2 = 33;
+        } else {
+            temp_x1 = 40;
+            temp_x2 = 30;
+        }
+    } else {
+        snprintf(
+            buffer,
+            sizeof(buffer),
+            "%3.0f F",
+            (double)locale_celsius_to_fahrenheit(model->generic->temperature));
+        if((model->generic->temperature < -27.77f) || (model->generic->temperature > 37.77f)) {
+            temp_x1 = 43;
+            temp_x2 = 35;
+        } else {
+            temp_x1 = 41;
+            temp_x2 = 33;
+        }
+    }
+
+    canvas_draw_str_aligned(canvas, temp_x1, 47, AlignRight, AlignTop, buffer);
+    canvas_draw_circle(canvas, temp_x2, 46, 1);
+
+    // Pressure
+    canvas_draw_icon(canvas, 46, 43, &I_Press_7x16);
+    snprintf(buffer, sizeof(buffer), "%2.1fbar", (double)model->generic->pressure);
+    canvas_draw_str(canvas, 56, 55, buffer);
+
+    if((int)model->generic->timestamp > 0 && model->curr_ts) {
+        int ts_diff = (int)model->curr_ts - (int)model->generic->timestamp;
+
+        canvas_draw_icon(canvas, 92, 46, &I_Timer_11x11);
+
+        if(ts_diff > 60) {
+            int tmp_sec = ts_diff;
+            int cnt_min = 1;
+            for(int i = 1; tmp_sec > 60; i++) {
+                tmp_sec = tmp_sec - 60;
+                cnt_min = i;
+            }
+
+            if(model->curr_ts % 2 == 0) {
+                canvas_draw_str_aligned(canvas, 106, 51, AlignLeft, AlignCenter, "Old");
+            } else {
+                if(cnt_min >= 59) {
+                    canvas_draw_str_aligned(canvas, 106, 51, AlignLeft, AlignCenter, "Old");
+                } else {
+                    snprintf(buffer, sizeof(buffer), "%dm", cnt_min);
+                    canvas_draw_str_aligned(canvas, 115, 51, AlignCenter, AlignCenter, buffer);
+                }
+            }
+
+        } else {
+            snprintf(buffer, sizeof(buffer), "%d", ts_diff);
+            canvas_draw_str_aligned(canvas, 112, 51, AlignCenter, AlignCenter, buffer);
+        }
+    }
+}
+
+bool tpms_view_receiver_info_input(InputEvent* event, void* context) {
+    furi_assert(context);
+    //TPMSReceiverInfo* tpms_receiver_info = context;
+
+    if(event->key == InputKeyBack) {
+        return false;
+    }
+
+    return true;
+}
+
+static void tpms_view_receiver_info_enter(void* context) {
+    furi_assert(context);
+    TPMSReceiverInfo* tpms_receiver_info = context;
+
+    furi_timer_start(tpms_receiver_info->timer, 1000);
+}
+
+static void tpms_view_receiver_info_exit(void* context) {
+    furi_assert(context);
+    TPMSReceiverInfo* tpms_receiver_info = context;
+
+    furi_timer_stop(tpms_receiver_info->timer);
+
+    with_view_model(
+        tpms_receiver_info->view,
+        TPMSReceiverInfoModel * model,
+        { furi_string_reset(model->protocol_name); },
+        false);
+}
+
+static void tpms_view_receiver_info_timer(void* context) {
+    TPMSReceiverInfo* tpms_receiver_info = context;
+    // Force redraw
+    with_view_model(
+        tpms_receiver_info->view,
+        TPMSReceiverInfoModel * model,
+        {
+            FuriHalRtcDateTime curr_dt;
+            furi_hal_rtc_get_datetime(&curr_dt);
+            model->curr_ts = furi_hal_rtc_datetime_to_timestamp(&curr_dt);
+        },
+        true);
+}
+
+TPMSReceiverInfo* tpms_view_receiver_info_alloc() {
+    TPMSReceiverInfo* tpms_receiver_info = malloc(sizeof(TPMSReceiverInfo));
+
+    // View allocation and configuration
+    tpms_receiver_info->view = view_alloc();
+
+    view_allocate_model(
+        tpms_receiver_info->view, ViewModelTypeLocking, sizeof(TPMSReceiverInfoModel));
+    view_set_context(tpms_receiver_info->view, tpms_receiver_info);
+    view_set_draw_callback(
+        tpms_receiver_info->view, (ViewDrawCallback)tpms_view_receiver_info_draw);
+    view_set_input_callback(tpms_receiver_info->view, tpms_view_receiver_info_input);
+    view_set_enter_callback(tpms_receiver_info->view, tpms_view_receiver_info_enter);
+    view_set_exit_callback(tpms_receiver_info->view, tpms_view_receiver_info_exit);
+
+    with_view_model(
+        tpms_receiver_info->view,
+        TPMSReceiverInfoModel * model,
+        {
+            model->generic = malloc(sizeof(TPMSBlockGeneric));
+            model->protocol_name = furi_string_alloc();
+        },
+        true);
+
+    tpms_receiver_info->timer =
+        furi_timer_alloc(tpms_view_receiver_info_timer, FuriTimerTypePeriodic, tpms_receiver_info);
+
+    return tpms_receiver_info;
+}
+
+void tpms_view_receiver_info_free(TPMSReceiverInfo* tpms_receiver_info) {
+    furi_assert(tpms_receiver_info);
+
+    furi_timer_free(tpms_receiver_info->timer);
+
+    with_view_model(
+        tpms_receiver_info->view,
+        TPMSReceiverInfoModel * model,
+        {
+            furi_string_free(model->protocol_name);
+            free(model->generic);
+        },
+        false);
+
+    view_free(tpms_receiver_info->view);
+    free(tpms_receiver_info);
+}
+
+View* tpms_view_receiver_info_get_view(TPMSReceiverInfo* tpms_receiver_info) {
+    furi_assert(tpms_receiver_info);
+    return tpms_receiver_info->view;
+}

+ 16 - 0
non_catalog_apps/tpms_receiver/views/tpms_receiver_info.h

@@ -0,0 +1,16 @@
+#pragma once
+
+#include <gui/view.h>
+#include "../helpers/tpms_types.h"
+#include "../helpers/tpms_event.h"
+#include <lib/flipper_format/flipper_format.h>
+
+typedef struct TPMSReceiverInfo TPMSReceiverInfo;
+
+void tpms_view_receiver_info_update(TPMSReceiverInfo* tpms_receiver_info, FlipperFormat* fff);
+
+TPMSReceiverInfo* tpms_view_receiver_info_alloc();
+
+void tpms_view_receiver_info_free(TPMSReceiverInfo* tpms_receiver_info);
+
+View* tpms_view_receiver_info_get_view(TPMSReceiverInfo* tpms_receiver_info);