<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>STM32 on BlocNotes</title>
    <link>https://notes.iopush.net/tags/stm32/</link>
    <description>Recent content in STM32 on BlocNotes</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en-us</language>
    <lastBuildDate>Thu, 06 Jan 2022 00:00:00 +0000</lastBuildDate><atom:link href="https://notes.iopush.net/tags/stm32/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>LoRaWAN on RAK3172 thanks to ST CubeMX, with VS Code</title>
      <link>https://notes.iopush.net/blog/2022/01-rak3172/</link>
      <pubDate>Thu, 06 Jan 2022 00:00:00 +0000</pubDate>
      
      <guid>https://notes.iopush.net/blog/2022/01-rak3172/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;https://twitter.com/Kongduino&#34;&gt;Kongduino&lt;/a&gt; kindly sent me a WisDuo &lt;a href=&#34;https://store.rakwireless.com/products/wisduo-breakout-board-rak3272s&#34;&gt;RAK3272s&lt;/a&gt; few weeks ago,
it is a a breakout board for RAK nice module (&lt;a href=&#34;https://www.rakwireless.com/en-us/products/lpwan-modules/rak3172-wisduo-lpwan-module&#34;&gt;RAK3172&lt;/a&gt;) around the
STM32WL5 system on chip from ST. Let&amp;rsquo;s see how to use STM32 CubeMX
to generate the initialization files and the LoRaWAN stack, then setup Visual
Studio code debugger.&lt;/p&gt;
&lt;h1 id=&#34;1-stm32-cubemx&#34;&gt;1. STM32 CubeMX&lt;/h1&gt;
&lt;p&gt;Download &lt;a href=&#34;https://www.st.com/en/development-tools/stm32cubemx.html&#34;&gt;STM32 CubeMX&lt;/a&gt; from ST website,
install it as instructed.&lt;br&gt;
Open it then create a new project thanks to &lt;code&gt;ACCESS TO MCU SELECTOR&lt;/code&gt;. In the &lt;code&gt;Part Number&lt;/code&gt; searchbox look for &lt;code&gt;STM32WLE5CC&lt;/code&gt; then select &lt;code&gt;STM32WLE5CCUx&lt;/code&gt; and &lt;code&gt;Start Project&lt;/code&gt;. CubeMX will now create empty project with only the RF and oscillator pins initialized plus some core peripherals, we have to select the features we want:&lt;/p&gt;
&lt;h2 id=&#34;11-pinout--configuration-tab&#34;&gt;1.1 Pinout &amp;amp; configuration tab&lt;/h2&gt;
&lt;h3 id=&#34;analog---adc&#34;&gt;Analog -&amp;gt; ADC&lt;/h3&gt;
&lt;p&gt;Check &lt;code&gt;Vrefint Channel&lt;/code&gt;, it will be used by the demo application.&lt;/p&gt;
&lt;h3 id=&#34;timers---rtc&#34;&gt;Timers -&amp;gt; RTC&lt;/h3&gt;
&lt;p&gt;Check &lt;code&gt;Activate Clock Source&lt;/code&gt; and &lt;code&gt;Activate calendar&lt;/code&gt;. Add the following values in configuration section, tab &lt;code&gt;User constants&lt;/code&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;RTC_PREDIV_A&lt;/code&gt;: &lt;code&gt;((1&amp;lt;&amp;lt;(15-RTC_N_PREDIV_S))-1)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;RTC_N_PREDIV_S&lt;/code&gt;: &lt;code&gt;10&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;RTC_PREDIV_S&lt;/code&gt;: &lt;code&gt;((1&amp;lt;&amp;lt;RTC_N_PREDIV_S)-1)&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In &lt;code&gt;Parameters Settings&lt;/code&gt; tab:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Bin mode&lt;/code&gt;: &lt;code&gt;Free running binary mode&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Asynchronous predivider value&lt;/code&gt;: &lt;code&gt;RTC_PREDIV_A&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;connectivity---subghz&#34;&gt;Connectivity -&amp;gt; SUBGHZ&lt;/h3&gt;
&lt;p&gt;Check &lt;code&gt;Activated&lt;/code&gt; to use the LoRa IP.&lt;/p&gt;
&lt;h3 id=&#34;connectivity---usart2&#34;&gt;Connectivity -&amp;gt; USART2&lt;/h3&gt;
&lt;p&gt;To send traces (printf) from the STM32 to the computer.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Select &lt;code&gt;Mode&lt;/code&gt; to &lt;code&gt;Asynchronous&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;In &lt;code&gt;Configuration&lt;/code&gt; section, tab &lt;code&gt;DMA Settings&lt;/code&gt;:
&lt;ol&gt;
&lt;li&gt;Click on &lt;code&gt;Add&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;In &lt;code&gt;DMA request&lt;/code&gt; select &lt;code&gt;USART2 TX&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;In &lt;code&gt;Channel&lt;/code&gt; select &lt;code&gt;DMA 1 channel 5&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;In &lt;code&gt;Direction&lt;/code&gt; select &lt;code&gt;Memory to peripheral&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;In &lt;code&gt;Priority&lt;/code&gt; select &lt;code&gt;Low&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;Tab &lt;code&gt;GPIO Settings&lt;/code&gt; should already have:
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;PA2&lt;/code&gt; as &lt;code&gt;USART2_TX&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;PA3&lt;/code&gt; as &lt;code&gt;USART2_RX&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;middleware---lorawan&#34;&gt;Middleware -&amp;gt; LoRaWAN&lt;/h3&gt;
&lt;p&gt;Check &lt;code&gt;enabled&lt;/code&gt; to add the LoRaWAN stack to the project then in the configuration section, tab &lt;code&gt;LoRaWAN Middleware&lt;/code&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;lorawan_conf&lt;/code&gt;: select your region&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Tx Rfo Config&lt;/code&gt;: &lt;code&gt;CONF RFO HP&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;In tab &lt;code&gt;LoraWAN Application&lt;/code&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;Application&lt;/code&gt;: &lt;code&gt;End Node skeleton&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;LoRa App&lt;/code&gt;-&amp;gt;&lt;code&gt;Active region&lt;/code&gt;: Select your region&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;In tab &lt;code&gt;Platform Settings&lt;/code&gt;:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Name&lt;/th&gt;
&lt;th&gt;IPs or Components&lt;/th&gt;
&lt;th&gt;Found Solutions&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;ADC&lt;/td&gt;
&lt;td&gt;ADC: Vrefint channel&lt;/td&gt;
&lt;td&gt;ADC&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;USART&lt;/td&gt;
&lt;td&gt;USART: Asynchronous&lt;/td&gt;
&lt;td&gt;USART2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RTC&lt;/td&gt;
&lt;td&gt;RTC: RTC Enabled&lt;/td&gt;
&lt;td&gt;RTC&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;em&gt;Note:&lt;/em&gt; If you do not know which EUI/Key to use follow the chapter &lt;code&gt;TTN OTAA Device Registration&lt;/code&gt; in &lt;a href=&#34;https://docs.rakwireless.com/Product-Categories/WisDuo/RAK3172-Module/Quickstart/#ttn-otaa-device-registration&#34;&gt;RAK&amp;rsquo;s quickstart&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;In tab &lt;code&gt;LoRaWAN commissioning&lt;/code&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Check &lt;code&gt;Static Device Eui&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Fill &lt;code&gt;LoRaWAN device eui&lt;/code&gt;, &lt;code&gt;App/JoinEUI&lt;/code&gt; and &lt;code&gt;Application key&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;system-core---nvic&#34;&gt;System core -&amp;gt; NVIC&lt;/h3&gt;
&lt;p&gt;Check &lt;code&gt;SUBGHZ&lt;/code&gt; Radio Interrupt.&lt;/p&gt;
&lt;h3 id=&#34;pin-configuration&#34;&gt;Pin configuration&lt;/h3&gt;
&lt;p&gt;On the STM32 picture click on:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Pin &lt;code&gt;PB0&lt;/code&gt;: select &lt;code&gt;VDDTCXO&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Pin &lt;code&gt;PC14&lt;/code&gt;: select &lt;code&gt;RCC_OSC32_IN&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Pin &lt;code&gt;PC15&lt;/code&gt;: select &lt;code&gt;RCC_OSC32_OUT&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;12-clock-configuration-tab&#34;&gt;1.2 Clock Configuration tab&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;In &lt;code&gt;RTC Clock Mux&lt;/code&gt; select &lt;code&gt;LSE&lt;/code&gt; input&lt;/li&gt;
&lt;li&gt;&lt;code&gt;MSI RC&lt;/code&gt; can be pushed to &lt;code&gt;48000&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;13-project-manager-tab&#34;&gt;1.3 Project Manager tab&lt;/h2&gt;
&lt;p&gt;Set &lt;code&gt;Project name&lt;/code&gt;, then in &lt;code&gt;Toolchain/IDE&lt;/code&gt; select &lt;code&gt;Makefile&lt;/code&gt;.&lt;br&gt;
The project is ready, click on &lt;code&gt;GENERATE CODE&lt;/code&gt; in top right corner.&lt;/p&gt;
&lt;p&gt;When generated you can open the folder in your favorite editor, I will use VS Code.&lt;/p&gt;
&lt;h1 id=&#34;2-configure-the-c-code&#34;&gt;2. Configure the C code&lt;/h1&gt;
&lt;p&gt;Now the program skeleton is generated but it can not be compiled yet, otherwise
the compiler with output warnings like:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#warning user to provide its board definitions pins
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;We have to provide some specifics about the radio pins. Download &lt;a href=&#34;https://notes.iopush.net/blog/2022/01-rak3172/radio_board_if_c.patch&#34;&gt;radio_board_if_c.patch&lt;/a&gt; and &lt;a href=&#34;https://notes.iopush.net/blog/2022/01-rak3172/radio_board_if_h.patch&#34;&gt;radio_board_if_h.patch&lt;/a&gt;, place them in the root directory of your project then:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;patch -u LoRaWAN/Target/radio_board_if.c -i radio_board_if_c.patch
patch -u LoRaWAN/Target/radio_board_if.h -i radio_board_if_h.patch
&lt;/code&gt;&lt;/pre&gt;&lt;h1 id=&#34;3-compile-the-binary&#34;&gt;3. Compile the binary&lt;/h1&gt;
&lt;p&gt;Download &lt;a href=&#34;https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm/downloads&#34;&gt;arm-none-eabi&lt;/a&gt; toolchain, add it to your path then it is as simple as &lt;code&gt;make -j&lt;/code&gt;.&lt;/p&gt;
&lt;h1 id=&#34;4-flash-the-microcontroller&#34;&gt;4. Flash the microcontroller&lt;/h1&gt;
&lt;p&gt;RAK &lt;a href=&#34;https://docs.rakwireless.com/Product-Categories/WisDuo/RAK3172-Module/Low-Level-Development/#uploading-the-fw-generated-using-stm32cubeprogrammer&#34;&gt;official documentation&lt;/a&gt; is using a serial&amp;lt;&amp;gt;USB converter and the integrated STM32 serial bootloader to flash the firmware, but I prefer an ST-Link as I will also be able to debug the code.&lt;/p&gt;
&lt;h2 id=&#34;41-st-link-pinout-and-wiring&#34;&gt;4.1 ST-Link pinout and wiring&lt;/h2&gt;
&lt;p&gt;You can use an ST-Link or any Nucleo header as long as it is broke from the target board or the jumpers &lt;code&gt;ST-LINK&lt;/code&gt; are removed. Then the connector &lt;code&gt;SWD/CN4&lt;/code&gt; must be wired to the RAK module, Nucleo&amp;rsquo;s serial&amp;lt;&amp;gt;USB converter can be used thanks to &lt;code&gt;CN3&lt;/code&gt;:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Signal name&lt;/th&gt;
&lt;th&gt;Nucleo header&lt;/th&gt;
&lt;th&gt;RAK3272s&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;VDD_ref (optional)&lt;/td&gt;
&lt;td&gt;CN4-&amp;gt;1&lt;/td&gt;
&lt;td&gt;3V3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SWCLK&lt;/td&gt;
&lt;td&gt;CN4-&amp;gt;2&lt;/td&gt;
&lt;td&gt;SWCLK-PA14&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GND&lt;/td&gt;
&lt;td&gt;CN4-&amp;gt;3&lt;/td&gt;
&lt;td&gt;GND&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SWDIO&lt;/td&gt;
&lt;td&gt;CN4-&amp;gt;4&lt;/td&gt;
&lt;td&gt;SWDIO-PA13&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;nRST&lt;/td&gt;
&lt;td&gt;CN4-&amp;gt;5&lt;/td&gt;
&lt;td&gt;RST&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;UART_TX&lt;/td&gt;
&lt;td&gt;CN3-&amp;gt;1&lt;/td&gt;
&lt;td&gt;UART2_TX&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;UART_RX&lt;/td&gt;
&lt;td&gt;CN3-&amp;gt;2&lt;/td&gt;
&lt;td&gt;UART2_RX&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Power Supply (3.3V)&lt;/td&gt;
&lt;td&gt;CN1-&amp;gt;1&lt;/td&gt;
&lt;td&gt;3V3&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&#34;42-use-st-link-usb-mass-storage&#34;&gt;4.2 Use ST-Link USB mass storage&lt;/h2&gt;
&lt;p&gt;You can flash the microcontroler by copy/pasting the &lt;code&gt;.bin&lt;/code&gt; file in the ST Link folder.&lt;/p&gt;
&lt;h2 id=&#34;43-openocd&#34;&gt;4.3 OpenOCD&lt;/h2&gt;
&lt;p&gt;Required only if you want to use the debugger. As of december 2021 most OpenOCD releases does not yet include STM32WL support, it has to be compiled from the sources. The steps are easy for Linux:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;git clone https://git.code.sf.net/p/openocd/code openocd-code&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;apt install make libtool pkg-config autoconf automake texinfo libusb-1.0-0 libusb-1.0-0-dev&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;./bootstrap&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;./configure --enable-stlink&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;make&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;make install&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;45-vs-code&#34;&gt;4.5 VS Code&lt;/h2&gt;
&lt;p&gt;Install the extension &lt;a href=&#34;https://marketplace.visualstudio.com/items?itemName=marus25.cortex-debug&#34;&gt;Cortex-Debug&lt;/a&gt; if you want to use the debugger, then edit the &lt;code&gt;launch.json&lt;/code&gt; file, or create it if required, to have&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
    &amp;quot;version&amp;quot;: &amp;quot;0.2.0&amp;quot;,
    &amp;quot;configurations&amp;quot;: [
        {
            &amp;quot;name&amp;quot;: &amp;quot;Cortex Debug&amp;quot;,
            &amp;quot;cwd&amp;quot;: &amp;quot;${workspaceRoot}&amp;quot;,
            &amp;quot;executable&amp;quot;: &amp;quot;./build/${workspaceFolderBasename}.elf&amp;quot;,
            &amp;quot;request&amp;quot;: &amp;quot;launch&amp;quot;,
            &amp;quot;type&amp;quot;: &amp;quot;cortex-debug&amp;quot;,
            &amp;quot;servertype&amp;quot;: &amp;quot;openocd&amp;quot;,
            &amp;quot;configFiles&amp;quot;: [
                &amp;quot;interface/stlink.cfg&amp;quot;,
                &amp;quot;target/stm32wlx.cfg&amp;quot;
            ],
        }
    ]
}
&lt;/code&gt;&lt;/pre&gt;&lt;h1 id=&#34;5-lorawan-uplinks&#34;&gt;5. LoRaWAN uplinks&lt;/h1&gt;
&lt;p&gt;Register your device in a network server like &lt;a href=&#34;https://console.thethingsnetwork.org&#34;&gt;The Things Network&lt;/a&gt;,
then you should see the JoinRequest/JoinAccept!&lt;/p&gt;



    
    
        
        
        
        
    

    
    
    

    
    







  


    

    
        &lt;p&gt;&lt;span class=&#34;image center&#34;&gt;
            &lt;img src=&#34;https://notes.iopush.net/blog/2022/01-rak3172/TTN-Uplink.png&#34; alt=&#34;TTN uplinks in the console&#34;&gt;
        &lt;/span&gt;&lt;/p&gt;
        &lt;p&gt;&lt;div class=&#34;align-center&#34; style=&#34;font-weight: bold;&#34;&gt;
            TTN uplinks in the console
        &lt;/div&gt;&lt;/p&gt;
    


&lt;p&gt;If you have any issue the project is available on &lt;a href=&#34;https://gitlab.com/oliv4945/rak3172-st-stack-template&#34;&gt;Gitlab&lt;/a&gt;. The project also &lt;a href=&#34;https://gitlab.com/oliv4945/rak3172-st-stack-template/-/blob/2b9e75040c10cc6b40b8757184d7ca96343cf8d3/LoRaWAN/App/lora_app.c#L218&#34;&gt;contains a populated&lt;/a&gt; &lt;code&gt;SendTxData()&lt;/code&gt; function to actually send uplinks :)&lt;/p&gt;
&lt;h1 id=&#34;6-next-steps&#34;&gt;6. Next steps&lt;/h1&gt;
&lt;p&gt;Now that we are connected to the network the next post should be about optimizing power consumption and enter in stop mode to only consume µAmps when not sending data.&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>STM32 - Custom USB HID device step by step</title>
      <link>https://notes.iopush.net/blog/2016/stm32-custom-usb-hid-step-by-step-2/</link>
      <pubDate>Fri, 16 Dec 2016 20:49:40 +0000</pubDate>
      
      <guid>https://notes.iopush.net/blog/2016/stm32-custom-usb-hid-step-by-step-2/</guid>
      <description>&lt;p&gt;Step by step guide to do a custom USB HID device on STM32 using ST CubeMX. There
is already
&lt;a href=&#34;http://damogranlabs.com/2016/03/stm32-custom-usb-hid-device-yes-please/&#34;&gt;one page&lt;/a&gt;
addressing it but without any details for beginners.&lt;br&gt;
I will use &lt;a href=&#34;https://notes.iopush.net/projects/stm32l052-development-board/&#34;&gt;my custom board&lt;/a&gt; based on STM32L0,
but any Nucleo can be used by wiring a USB cable to 5V, GND, USB_D+, USB_D-.&lt;/p&gt;
&lt;h1 id=&#34;step-1---cubemx-open-it-start-a-project-to-select-your-processor-or-board&#34;&gt;Step 1 - CubeMX Open it, start a project to select your processor or board.&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;In &lt;code&gt;Pinout&lt;/code&gt; tab &lt;code&gt;configuration&lt;/code&gt;-&amp;gt;&lt;code&gt;peripheral&lt;/code&gt;-&amp;gt;&lt;code&gt;usb&lt;/code&gt; and check &lt;code&gt;Device (FS)&lt;/code&gt;.
It will tell CubeMX that we want to use USB pins.&lt;/li&gt;
&lt;li&gt;You can check &lt;code&gt;Activate OE&lt;/code&gt; if you want to see a led blink when there is
traffic on USB lines. Then connect a resistor+led on the pin.&lt;/li&gt;
&lt;li&gt;Now, to speed up development, we want to use ST&amp;rsquo;s USB library, so in
&lt;code&gt;configuration&lt;/code&gt; -&amp;gt; &lt;code&gt;USB_Device&lt;/code&gt; select &lt;code&gt;Human interface device class (HID)&lt;/code&gt;.
Be sure to avoid custom class, we want ST working example to test our setup.
It will generate a mouse device.&lt;/li&gt;
&lt;li&gt;Then in the &lt;code&gt;Clock configuration&lt;/code&gt; tab select &lt;code&gt;USBCLK&lt;/code&gt; from &lt;code&gt;RC 48 MHZ&lt;/code&gt; if your
µC is compatible: ST implemented a nice feature allowing us to avoid adding an
external quartz by trimming internal 48 MHz RC against USB clock sent by the
host. If your uC is not crystal-less you must find a way to have accurate 48
MHz on &lt;code&gt;USBCLK&lt;/code&gt; (hint: use HSE)&lt;/li&gt;
&lt;li&gt;Then in &lt;code&gt;Configuration&lt;/code&gt; tab select &lt;code&gt;Middlewares&lt;/code&gt;-&amp;gt;&lt;code&gt;USB_Devices&lt;/code&gt;. Here you can
customize the &lt;code&gt;Device descriptor&lt;/code&gt; tab with PID/VID, manufacturer&amp;hellip;&lt;/li&gt;
&lt;li&gt;Now, generate the project for your IDE.&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&#34;step-2---test-the-mouse-example-first-before-modifying-anything-we-will-try&#34;&gt;Step 2 - Test the mouse example First, before modifying anything, we will try&lt;/h1&gt;
&lt;p&gt;ST&amp;rsquo;s mouse example. The USB stack is handled by ST&amp;rsquo;s library so we just need to
call it to move the mouse.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Modify &lt;code&gt;main.c&lt;/code&gt; to declare and initialise data to be send to the computer, in
&lt;code&gt;USER CODE BEGIN 1&lt;/code&gt;:&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-C&#34; data-lang=&#34;C&#34;&gt;  &lt;span style=&#34;color:#75715e&#34;&gt;// HID Mouse
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; mouseHID_t {
      uint8_t buttons;
      int8_t x;
      int8_t y;
      int8_t wheel;
  };
  &lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; mouseHID_t mouseHID;
  mouseHID.buttons &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;;
  mouseHID.x &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;10&lt;/span&gt;;
  mouseHID.y &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;;
  mouseHID.wheel &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;Then send them in &lt;code&gt;USER CODE BEGIN 3&lt;/code&gt;:&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-C&#34; data-lang=&#34;C&#34;&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;// Send HID report
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;    mouseHID.x &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;10&lt;/span&gt;;
    USBD_HID_SendReport(&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;hUsbDeviceFS, &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;mouseHID, &lt;span style=&#34;color:#66d9ef&#34;&gt;sizeof&lt;/span&gt;(&lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; mouseHID_t));
    HAL_Delay(&lt;span style=&#34;color:#ae81ff&#34;&gt;1000&lt;/span&gt;);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Compile, then test: the mouse is now slowly drifting to the right :-)&lt;/p&gt;
&lt;h1 id=&#34;step-3---modifications-for-custom-hid-now-we-want-to-change-the-mouse-example&#34;&gt;Step 3 - Modifications for custom HID Now we want to change the mouse example&lt;/h1&gt;
&lt;p&gt;to our custom descriptor. For this tutorial, we will use the keyboard+consumer
device (media) descriptor explained in my
&lt;a href=&#34;https://notes.iopush.net/custom-usb-hid-device-descriptor-media-keyboard/&#34;&gt;previous post&lt;/a&gt;.&lt;br&gt;
We can add it in &lt;code&gt;Middlewares&lt;/code&gt;-&amp;gt;&lt;code&gt;...&lt;/code&gt;-&amp;gt;&lt;code&gt;Src&lt;/code&gt;-&amp;gt;&lt;code&gt;usbd_hid.c&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Find &lt;code&gt;HID_MOUSE_ReportDesc&lt;/code&gt; array and comment or delete it, then add the custom
descriptor.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-C&#34; data-lang=&#34;C&#34;&gt;__ALIGN_BEGIN &lt;span style=&#34;color:#66d9ef&#34;&gt;static&lt;/span&gt; uint8_t HID_CUSTOM_ReportDesc[HID_CUSTOM_REPORT_DESC_SIZE]  __ALIGN_END &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; {
  &lt;span style=&#34;color:#75715e&#34;&gt;// 78 bytes
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#ae81ff&#34;&gt;0x05&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0x01&lt;/span&gt;,        &lt;span style=&#34;color:#75715e&#34;&gt;// Usage Page (Generic Desktop Ctrls)
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#ae81ff&#34;&gt;0x09&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0x06&lt;/span&gt;,        &lt;span style=&#34;color:#75715e&#34;&gt;// Usage (Keyboard)
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#ae81ff&#34;&gt;0xA1&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0x01&lt;/span&gt;,        &lt;span style=&#34;color:#75715e&#34;&gt;// Collection (Application)
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#ae81ff&#34;&gt;0x85&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0x01&lt;/span&gt;,        &lt;span style=&#34;color:#75715e&#34;&gt;//   Report ID (1)
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#ae81ff&#34;&gt;0x05&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0x07&lt;/span&gt;,        &lt;span style=&#34;color:#75715e&#34;&gt;//   Usage Page (Kbrd/Keypad)
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#ae81ff&#34;&gt;0x75&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0x01&lt;/span&gt;,        &lt;span style=&#34;color:#75715e&#34;&gt;//   Report Size (1)
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#ae81ff&#34;&gt;0x95&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0x08&lt;/span&gt;,        &lt;span style=&#34;color:#75715e&#34;&gt;//   Report Count (8)
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#ae81ff&#34;&gt;0x19&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0xE0&lt;/span&gt;,        &lt;span style=&#34;color:#75715e&#34;&gt;//   Usage Minimum (0xE0)
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#ae81ff&#34;&gt;0x29&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0xE7&lt;/span&gt;,        &lt;span style=&#34;color:#75715e&#34;&gt;//   Usage Maximum (0xE7)
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#ae81ff&#34;&gt;0x15&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0x00&lt;/span&gt;,        &lt;span style=&#34;color:#75715e&#34;&gt;//   Logical Minimum (0)
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#ae81ff&#34;&gt;0x25&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0x01&lt;/span&gt;,        &lt;span style=&#34;color:#75715e&#34;&gt;//   Logical Maximum (1)
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#ae81ff&#34;&gt;0x81&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0x02&lt;/span&gt;,        &lt;span style=&#34;color:#75715e&#34;&gt;//   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#ae81ff&#34;&gt;0x95&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0x03&lt;/span&gt;,        &lt;span style=&#34;color:#75715e&#34;&gt;//   Report Count (3)
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#ae81ff&#34;&gt;0x75&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0x08&lt;/span&gt;,        &lt;span style=&#34;color:#75715e&#34;&gt;//   Report Size (8)
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#ae81ff&#34;&gt;0x15&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0x00&lt;/span&gt;,        &lt;span style=&#34;color:#75715e&#34;&gt;//   Logical Minimum (0)
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#ae81ff&#34;&gt;0x25&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0x64&lt;/span&gt;,        &lt;span style=&#34;color:#75715e&#34;&gt;//   Logical Maximum (100)
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#ae81ff&#34;&gt;0x05&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0x07&lt;/span&gt;,        &lt;span style=&#34;color:#75715e&#34;&gt;//   Usage Page (Kbrd/Keypad)
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#ae81ff&#34;&gt;0x19&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0x00&lt;/span&gt;,        &lt;span style=&#34;color:#75715e&#34;&gt;//   Usage Minimum (0x00)
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#ae81ff&#34;&gt;0x29&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0x65&lt;/span&gt;,        &lt;span style=&#34;color:#75715e&#34;&gt;//   Usage Maximum (0x65)
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#ae81ff&#34;&gt;0x81&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0x00&lt;/span&gt;,        &lt;span style=&#34;color:#75715e&#34;&gt;//   Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#ae81ff&#34;&gt;0xC0&lt;/span&gt;,              &lt;span style=&#34;color:#75715e&#34;&gt;// End Collection
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#ae81ff&#34;&gt;0x05&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0x0C&lt;/span&gt;,        &lt;span style=&#34;color:#75715e&#34;&gt;// Usage Page (Consumer)
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#ae81ff&#34;&gt;0x09&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0x01&lt;/span&gt;,        &lt;span style=&#34;color:#75715e&#34;&gt;// Usage (Consumer Control)
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#ae81ff&#34;&gt;0xA1&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0x01&lt;/span&gt;,        &lt;span style=&#34;color:#75715e&#34;&gt;// Collection (Application)
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#ae81ff&#34;&gt;0x85&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0x02&lt;/span&gt;,        &lt;span style=&#34;color:#75715e&#34;&gt;//   Report ID (2)
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#ae81ff&#34;&gt;0x05&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0x0C&lt;/span&gt;,        &lt;span style=&#34;color:#75715e&#34;&gt;//   Usage Page (Consumer)
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#ae81ff&#34;&gt;0x15&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0x00&lt;/span&gt;,        &lt;span style=&#34;color:#75715e&#34;&gt;//   Logical Minimum (0)
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#ae81ff&#34;&gt;0x25&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0x01&lt;/span&gt;,        &lt;span style=&#34;color:#75715e&#34;&gt;//   Logical Maximum (1)
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#ae81ff&#34;&gt;0x75&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0x01&lt;/span&gt;,        &lt;span style=&#34;color:#75715e&#34;&gt;//   Report Size (1)
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#ae81ff&#34;&gt;0x95&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0x08&lt;/span&gt;,        &lt;span style=&#34;color:#75715e&#34;&gt;//   Report Count (8)
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#ae81ff&#34;&gt;0x09&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0xB5&lt;/span&gt;,        &lt;span style=&#34;color:#75715e&#34;&gt;//   Usage (Scan Next Track)
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#ae81ff&#34;&gt;0x09&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0xB6&lt;/span&gt;,        &lt;span style=&#34;color:#75715e&#34;&gt;//   Usage (Scan Previous Track)
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#ae81ff&#34;&gt;0x09&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0xB7&lt;/span&gt;,        &lt;span style=&#34;color:#75715e&#34;&gt;//   Usage (Stop)
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#ae81ff&#34;&gt;0x09&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0xB8&lt;/span&gt;,        &lt;span style=&#34;color:#75715e&#34;&gt;//   Usage (Eject)
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#ae81ff&#34;&gt;0x09&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0xCD&lt;/span&gt;,        &lt;span style=&#34;color:#75715e&#34;&gt;//   Usage (Play/Pause)
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#ae81ff&#34;&gt;0x09&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0xE2&lt;/span&gt;,        &lt;span style=&#34;color:#75715e&#34;&gt;//   Usage (Mute)
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#ae81ff&#34;&gt;0x09&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0xE9&lt;/span&gt;,        &lt;span style=&#34;color:#75715e&#34;&gt;//   Usage (Volume Increment)
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#ae81ff&#34;&gt;0x09&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0xEA&lt;/span&gt;,        &lt;span style=&#34;color:#75715e&#34;&gt;//   Usage (Volume Decrement)
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#ae81ff&#34;&gt;0x81&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0x02&lt;/span&gt;,        &lt;span style=&#34;color:#75715e&#34;&gt;//   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#ae81ff&#34;&gt;0xC0&lt;/span&gt;,              &lt;span style=&#34;color:#75715e&#34;&gt;// End Collection
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;};
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Then in &lt;code&gt;USBD_HID_CfgDesc&lt;/code&gt; change&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;bInterfaceSubClass&lt;/code&gt; to &lt;code&gt;0&lt;/code&gt;, the keyboard does not respect boot specifications&lt;/li&gt;
&lt;li&gt;&lt;code&gt;nInterfaceProtocol&lt;/code&gt; to &lt;code&gt;1&lt;/code&gt; (keyboard)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;All references to &lt;code&gt;mouse&lt;/code&gt; in the file should be changed to &lt;code&gt;custom&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;In &lt;code&gt;Middlewares&lt;/code&gt;-&amp;gt;&lt;code&gt;...&lt;/code&gt;-&amp;gt;&lt;code&gt;Src&lt;/code&gt;-&amp;gt;&lt;code&gt;usbd_hid.h&lt;/code&gt;, change:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;HID_EPIN_SIZE&lt;/code&gt; to &lt;code&gt;5&lt;/code&gt;, the max report size&lt;/li&gt;
&lt;li&gt;&lt;code&gt;HID_CUSTOM_REPORT_DESC_SIZE &lt;/code&gt; to &lt;code&gt;78&lt;/code&gt;, the length of our new descriptor.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Finally in &lt;code&gt;main.c&lt;/code&gt;:&lt;/strong&gt;&lt;br&gt;
Add reports initialization in &lt;code&gt;USER CODE BEGIN 1&lt;/code&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-C&#34; data-lang=&#34;C&#34;&gt;  &lt;span style=&#34;color:#75715e&#34;&gt;// HID Keyboard
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; keyboardHID_t {
      uint8_t id;
      uint8_t modifiers;
      uint8_t key1;
      uint8_t key2;
      uint8_t key3;
  };
  &lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; keyboardHID_t keyboardHID;
  keyboardHID.id &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;;
  keyboardHID.modifiers &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;;
  keyboardHID.key1 &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;;
  keyboardHID.key2 &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;;
  keyboardHID.key3 &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;;
  &lt;span style=&#34;color:#75715e&#34;&gt;// HID Media
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; mediaHID_t {
    uint8_t id;
    uint8_t keys;
  };
  &lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; mediaHID_t mediaHID;
  mediaHID.id &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt;;
  mediaHID.keys &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And send it in &lt;code&gt;USER CODE BEGIN 3&lt;/code&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-C&#34; data-lang=&#34;C&#34;&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;// Send HID report
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;    mediaHID.keys &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; USB_HID_VOL_DEC;
    USBD_HID_SendReport(&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;hUsbDeviceFS, &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;mediaHID, &lt;span style=&#34;color:#66d9ef&#34;&gt;sizeof&lt;/span&gt;(&lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; mediaHID_t));
    HAL_Delay(&lt;span style=&#34;color:#ae81ff&#34;&gt;30&lt;/span&gt;);
    mediaHID.keys &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;;
    USBD_HID_SendReport(&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;hUsbDeviceFS, &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;mediaHID, &lt;span style=&#34;color:#66d9ef&#34;&gt;sizeof&lt;/span&gt;(&lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; mediaHID_t));
    HAL_Delay(&lt;span style=&#34;color:#ae81ff&#34;&gt;30&lt;/span&gt;);

    keyboardHID.modifiers &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; USB_HID_MODIFIER_RIGHT_SHIFT;
    keyboardHID.key1 &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; USB_HID_KEY_L;
    USBD_HID_SendReport(&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;hUsbDeviceFS, &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;keyboardHID, &lt;span style=&#34;color:#66d9ef&#34;&gt;sizeof&lt;/span&gt;(&lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; keyboardHID_t));
    HAL_Delay(&lt;span style=&#34;color:#ae81ff&#34;&gt;30&lt;/span&gt;);
    keyboardHID.modifiers &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;;
    keyboardHID.key1 &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;;
    USBD_HID_SendReport(&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;hUsbDeviceFS, &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;keyboardHID, &lt;span style=&#34;color:#66d9ef&#34;&gt;sizeof&lt;/span&gt;(&lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; keyboardHID_t));
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Note: There is no need to use two structures if memory optimization is required,
but it simplifies the example.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Compile, send to uC and&amp;hellip;&lt;/strong&gt;&lt;br&gt;
The volume is decreasing while &amp;lsquo;L&amp;rsquo; characters appear on your screen :-)&lt;/p&gt;
&lt;p&gt;Full code can be found on
&lt;a href=&#34;https://github.com/Oliv4945/STM32L052_Breadboard/tree/USB_HID&#34;&gt;Github&lt;/a&gt;, and
commit diff from example is
&lt;a href=&#34;https://github.com/Oliv4945/STM32L052_Breadboard/commit/fc3e6c0f586749aad904f5ef558a8c3e6ce585d8&#34;&gt;there&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Edit 21/02/17: Correction of consumer control descriptor size&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Custom USB HID device descriptor: consumer device (media) &#43; keyboard</title>
      <link>https://notes.iopush.net/blog/2016/custom-usb-hid-device-descriptor-media-keyboard/</link>
      <pubDate>Tue, 13 Dec 2016 22:02:09 +0000</pubDate>
      
      <guid>https://notes.iopush.net/blog/2016/custom-usb-hid-device-descriptor-media-keyboard/</guid>
      <description>&lt;p&gt;For a project, I need media keys (play, volume, mute, &amp;hellip;) and a way to lock a
computer under Windows (Windows+L keys). There is a lot of HID keyboard
descriptors on the Internet, some are for keyboards + media but all contain at
least one unused byte&amp;hellip; Not a good thing for embedded systems with constraint
memory. Why? The descriptor can be found in
&lt;a href=&#34;http://www.usb.org/developers/hidpage/HID1_11.pdf&#34;&gt;USB-IF example&lt;/a&gt; (Appendix B)
and describe a boot compatible keyboard. So unless you need your keyboard in
boot menus, this byte can be dropped. Also, the example defines 6 simultaneous
keys, I decreased it to three as I don&amp;rsquo;t need more.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Consumer device&lt;/code&gt; profile allows a lot of actions, which can be found in
&lt;a href=&#34;http://www.usb.org/developers/hidpage/Hut1_12v2.pdf&#34;&gt;HID usage tables&lt;/a&gt;
document, in §15 &lt;code&gt;consumer page&lt;/code&gt;. I selected some relevant to my application
(media keys), but you can add more if required: just increase the &lt;code&gt;report count&lt;/code&gt;
and add the new key.&lt;br&gt;
Note that each started byte must be padded with constant bits, so if your
&lt;code&gt;report count&lt;/code&gt; is not a multiple of 8, add a constant section.&lt;/p&gt;
&lt;h1 id=&#34;how-to-use-it&#34;&gt;How to use it?&lt;/h1&gt;
&lt;p&gt;Prepare an &lt;code&gt;uint8_t&lt;/code&gt; table with a size matching the amount of data you have to
send plus one for the descriptor (first byte). For media keys, each bit of the
second byte will correspond to one key, LSB is the first in the descriptor. For
a keyboard, the second byte is for modifiers, and the third, fourth, fifth are
for keys.&lt;/p&gt;
&lt;p&gt;Those examples are related to the following descriptor.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-C&#34; data-lang=&#34;C&#34;&gt;uint8_t bufferHID[&lt;span style=&#34;color:#ae81ff&#34;&gt;5&lt;/span&gt;] &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; {&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;};
&lt;span style=&#34;color:#75715e&#34;&gt;// Send media mute
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;bufferHID[&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;] &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt;;      &lt;span style=&#34;color:#75715e&#34;&gt;// Start with the report ID
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;bufferHID[&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;] &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x20&lt;/span&gt;;   &lt;span style=&#34;color:#75715e&#34;&gt;// Set mute bit to 1
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;USB_HID_SendReport(bufferHID, &lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt;); &lt;span style=&#34;color:#75715e&#34;&gt;// Only 2 bytes required : report ID + media keys byte.
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// Send Windows+L
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;bufferHID[&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;] &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;;      &lt;span style=&#34;color:#75715e&#34;&gt;// Start with the report ID
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;bufferHID[&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;] &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x08&lt;/span&gt;;   &lt;span style=&#34;color:#75715e&#34;&gt;// Set left GUI bit to 1 - Windows or Apple/Cmd key
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;bufferHID[&lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt;] &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x0F&lt;/span&gt;;   &lt;span style=&#34;color:#75715e&#34;&gt;// &amp;#39;l&amp;#39; key
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;USB_HID_SendReport(bufferHID, &lt;span style=&#34;color:#ae81ff&#34;&gt;5&lt;/span&gt;); &lt;span style=&#34;color:#75715e&#34;&gt;// 5 bytes required : report ID + keyboard[4]
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;delay(&lt;span style=&#34;color:#ae81ff&#34;&gt;30&lt;/span&gt;);             &lt;span style=&#34;color:#75715e&#34;&gt;// Leave some time for the USB stack
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;bufferHID[&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;] &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;;      &lt;span style=&#34;color:#75715e&#34;&gt;// Release keys
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;bufferHID[&lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt;] &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;;
USB_HID_SendReport(bufferHID, &lt;span style=&#34;color:#ae81ff&#34;&gt;5&lt;/span&gt;); &lt;span style=&#34;color:#75715e&#34;&gt;// Send released keys
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id=&#34;descriptor&#34;&gt;Descriptor&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;Keyboard&lt;/li&gt;
&lt;li&gt;Modifiers (MSB-LSB) :
&lt;code&gt;RIGHT_GUI&lt;/code&gt;-&lt;code&gt;RIGHT_ALT&lt;/code&gt;-&lt;code&gt;RIGHT_SHIFT&lt;/code&gt;-&lt;code&gt;RIGHT_CTRL&lt;/code&gt;-&lt;code&gt;LEFT_GUI&lt;/code&gt;-&lt;code&gt;LEFT_ALT&lt;/code&gt;-&lt;code&gt;LEFT_SHIFT&lt;/code&gt;-&lt;code&gt;LEFT_CTRL&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Media keys&lt;/li&gt;
&lt;li&gt;Keys (MSB-LSB) :
&lt;code&gt;Next&lt;/code&gt;-&lt;code&gt;Previous&lt;/code&gt;-&lt;code&gt;Stop&lt;/code&gt;-&lt;code&gt;Eject&lt;/code&gt;-&lt;code&gt;Play/Pause&lt;/code&gt;-&lt;code&gt;Mute&lt;/code&gt;-&lt;code&gt;Vol inc&lt;/code&gt;-&lt;code&gt;Vol dec&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Descriptor&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-C&#34; data-lang=&#34;C&#34;&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// 78 bytes
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;0x05&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0x01&lt;/span&gt;,        &lt;span style=&#34;color:#75715e&#34;&gt;// Usage Page (Generic Desktop Ctrls)
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;0x09&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0x06&lt;/span&gt;,        &lt;span style=&#34;color:#75715e&#34;&gt;// Usage (Keyboard)
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;0xA1&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0x01&lt;/span&gt;,        &lt;span style=&#34;color:#75715e&#34;&gt;// Collection (Application)
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;0x85&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0x01&lt;/span&gt;,        &lt;span style=&#34;color:#75715e&#34;&gt;//   Report ID (1)
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;0x05&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0x07&lt;/span&gt;,        &lt;span style=&#34;color:#75715e&#34;&gt;//   Usage Page (Kbrd/Keypad)
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;0x75&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0x01&lt;/span&gt;,        &lt;span style=&#34;color:#75715e&#34;&gt;//   Report Size (1)
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;0x95&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0x08&lt;/span&gt;,        &lt;span style=&#34;color:#75715e&#34;&gt;//   Report Count (8)
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;0x19&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0xE0&lt;/span&gt;,        &lt;span style=&#34;color:#75715e&#34;&gt;//   Usage Minimum (0xE0)
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;0x29&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0xE7&lt;/span&gt;,        &lt;span style=&#34;color:#75715e&#34;&gt;//   Usage Maximum (0xE7)
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;0x15&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0x00&lt;/span&gt;,        &lt;span style=&#34;color:#75715e&#34;&gt;//   Logical Minimum (0)
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;0x25&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0x01&lt;/span&gt;,        &lt;span style=&#34;color:#75715e&#34;&gt;//   Logical Maximum (1)
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;0x81&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0x02&lt;/span&gt;,        &lt;span style=&#34;color:#75715e&#34;&gt;//   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;0x95&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0x03&lt;/span&gt;,        &lt;span style=&#34;color:#75715e&#34;&gt;//   Report Count (3)
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;0x75&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0x08&lt;/span&gt;,        &lt;span style=&#34;color:#75715e&#34;&gt;//   Report Size (8)
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;0x15&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0x00&lt;/span&gt;,        &lt;span style=&#34;color:#75715e&#34;&gt;//   Logical Minimum (0)
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;0x25&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0x64&lt;/span&gt;,        &lt;span style=&#34;color:#75715e&#34;&gt;//   Logical Maximum (100)
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;0x05&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0x07&lt;/span&gt;,        &lt;span style=&#34;color:#75715e&#34;&gt;//   Usage Page (Kbrd/Keypad)
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;0x19&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0x00&lt;/span&gt;,        &lt;span style=&#34;color:#75715e&#34;&gt;//   Usage Minimum (0x00)
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;0x29&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0x65&lt;/span&gt;,        &lt;span style=&#34;color:#75715e&#34;&gt;//   Usage Maximum (0x65)
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;0x81&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0x00&lt;/span&gt;,        &lt;span style=&#34;color:#75715e&#34;&gt;//   Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;0xC0&lt;/span&gt;,              &lt;span style=&#34;color:#75715e&#34;&gt;// End Collection
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;0x05&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0x0C&lt;/span&gt;,        &lt;span style=&#34;color:#75715e&#34;&gt;// Usage Page (Consumer)
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;0x09&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0x01&lt;/span&gt;,        &lt;span style=&#34;color:#75715e&#34;&gt;// Usage (Consumer Control)
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;0xA1&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0x01&lt;/span&gt;,        &lt;span style=&#34;color:#75715e&#34;&gt;// Collection (Application)
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;0x85&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0x02&lt;/span&gt;,        &lt;span style=&#34;color:#75715e&#34;&gt;//   Report ID (2)
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;0x05&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0x0C&lt;/span&gt;,        &lt;span style=&#34;color:#75715e&#34;&gt;//   Usage Page (Consumer)
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;0x15&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0x00&lt;/span&gt;,        &lt;span style=&#34;color:#75715e&#34;&gt;//   Logical Minimum (0)
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;0x25&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0x01&lt;/span&gt;,        &lt;span style=&#34;color:#75715e&#34;&gt;//   Logical Maximum (1)
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;0x75&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0x01&lt;/span&gt;,        &lt;span style=&#34;color:#75715e&#34;&gt;//   Report Size (1)
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;0x95&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0x07&lt;/span&gt;,        &lt;span style=&#34;color:#75715e&#34;&gt;//   Report Count (7)
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;0x09&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0xB5&lt;/span&gt;,        &lt;span style=&#34;color:#75715e&#34;&gt;//   Usage (Scan Next Track)
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;0x09&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0xB6&lt;/span&gt;,        &lt;span style=&#34;color:#75715e&#34;&gt;//   Usage (Scan Previous Track)
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;0x09&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0xB7&lt;/span&gt;,        &lt;span style=&#34;color:#75715e&#34;&gt;//   Usage (Stop)
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;0x09&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0xB8&lt;/span&gt;,        &lt;span style=&#34;color:#75715e&#34;&gt;//   Usage (Eject)
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;0x09&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0xCD&lt;/span&gt;,        &lt;span style=&#34;color:#75715e&#34;&gt;//   Usage (Play/Pause)
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;0x09&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0xE2&lt;/span&gt;,        &lt;span style=&#34;color:#75715e&#34;&gt;//   Usage (Mute)
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;0x09&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0xE9&lt;/span&gt;,        &lt;span style=&#34;color:#75715e&#34;&gt;//   Usage (Volume Increment)
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;0x09&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0xEA&lt;/span&gt;,        &lt;span style=&#34;color:#75715e&#34;&gt;//   Usage (Volume Decrement)
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;0x81&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0x02&lt;/span&gt;,        &lt;span style=&#34;color:#75715e&#34;&gt;//   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;0xC0&lt;/span&gt;,              &lt;span style=&#34;color:#75715e&#34;&gt;// End Collection
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Helpful defines&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-C&#34; data-lang=&#34;C&#34;&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// USB media codes
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#define USB_HID_SCAN_NEXT 0x01
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#define USB_HID_SCAN_PREV 0x02
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#define USB_HID_STOP      0x04
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#define USB_HID_EJECT     0x08
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#define USB_HID_PAUSE     0x10
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#define USB_HID_MUTE      0x20
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#define USB_HID_VOL_UP    0x40
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#define USB_HID_VOL_DEC   0x80
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;
&lt;span style=&#34;color:#75715e&#34;&gt;// USB keyboard codes
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#define USB_HID_MODIFIER_LEFT_CTRL   0x01
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#define USB_HID_MODIFIER_LEFT_SHIFT  0x02
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#define USB_HID_MODIFIER_LEFT_ALT    0x04
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#define USB_HID_MODIFIER_LEFT_GUI    0x08 &lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// (Win/Apple/Meta)
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#define USB_HID_MODIFIER_RIGHT_CTRL  0x10
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#define USB_HID_MODIFIER_RIGHT_SHIFT 0x20
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#define USB_HID_MODIFIER_RIGHT_ALT   0x40
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#define USB_HID_MODIFIER_RIGHT_GUI   0x80
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#define USB_HID_KEY_L     0x0F
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id=&#34;documentation&#34;&gt;Documentation&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;http://eleccelerator.com/tutorial-about-usb-hid-report-descriptors/&#34;&gt;Most useful page&lt;/a&gt;
I read about custom HID descriptors&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.usb.org/sites/default/files/hut1_21_0.pdf&#34;&gt;USB HID usage table&lt;/a&gt; to
find key codes.&lt;/li&gt;
&lt;li&gt;Next, how to implemnt it
&lt;a href=&#34;https://notes.iopush.net/blog/2016/stm32-custom-usb-hid-step-by-step-2/&#34;&gt;on STM32 targets&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;</description>
    </item>
    
    <item>
      <title>STM32 - Log and printf</title>
      <link>https://notes.iopush.net/blog/2016/stm32-log-and-printf/</link>
      <pubDate>Sun, 27 Nov 2016 09:41:28 +0000</pubDate>
      
      <guid>https://notes.iopush.net/blog/2016/stm32-log-and-printf/</guid>
      <description>&lt;p&gt;I am currently using a library which heavily uses &lt;code&gt;LOG()&lt;/code&gt; functions, which
requires to output text on &lt;code&gt;printf()&lt;/code&gt; or one of its derivative. As I am also
evaluating ST&amp;rsquo;s HAL, I tried to use it instead of the low level &lt;code&gt;putc()&lt;/code&gt;
function.&lt;/p&gt;
&lt;p&gt;First, we need to be able to use &lt;code&gt;printf()&lt;/code&gt; in combination with
&lt;code&gt;HAL_UART_Transmit()&lt;/code&gt;.&lt;br&gt;
For that, a small trick called
&lt;a href=&#34;https://en.wikipedia.org/wiki/Variadic_function&#34;&gt;variadic functions&lt;/a&gt; is
required, it allows passing multiple arguments to our function. The other trick
is &lt;code&gt;vprintf()&lt;/code&gt; which is a &lt;code&gt;printf()&lt;/code&gt; with variadic args input and char*
output.&lt;br&gt;
Two functions are implemented to be able to match the library Log prototype:
&lt;code&gt;void logE(const char* fmt, ...)&lt;/code&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-C&#34; data-lang=&#34;C&#34;&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#include&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#include&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;&amp;lt;stdarg.h&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#include&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;&amp;lt;string.h&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;
&lt;span style=&#34;color:#75715e&#34;&gt;#define PRINT_BUFFER_SIZE 100
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;
&lt;span style=&#34;color:#75715e&#34;&gt;/** Custom printf function in order to use HAL_UART_Transmit()
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt; * @param *fmt String to print
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt; * @param argp Parameters list
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt; */&lt;/span&gt;
&lt;span style=&#34;color:#66d9ef&#34;&gt;void&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;HAL_printf_valist&lt;/span&gt;(&lt;span style=&#34;color:#66d9ef&#34;&gt;const&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;char&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;fmt, va_list argp) {
  &lt;span style=&#34;color:#66d9ef&#34;&gt;char&lt;/span&gt; string[PRINT_BUFFER_SIZE];

  &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (vsprintf(string, fmt, argp) &lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;) {
    HAL_UART_Transmit(&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;HAL_PRINT_UART, (uint8_t&lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;)string, strlen(string), HAL_MAX_DELAY); &lt;span style=&#34;color:#75715e&#34;&gt;// send message via UART
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;  } &lt;span style=&#34;color:#66d9ef&#34;&gt;else&lt;/span&gt; {
	HAL_UART_Transmit(&lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;HAL_PRINT_UART, (uint8_t&lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;)&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;E - Print&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;14&lt;/span&gt;, HAL_MAX_DELAY);
  }
}

&lt;span style=&#34;color:#75715e&#34;&gt;/** Custom printf function, only translate to va_list arg HAL_UART.
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt; * @param *fmt String to print
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt; * @param ... Data
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt; */&lt;/span&gt;
&lt;span style=&#34;color:#66d9ef&#34;&gt;void&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;HAL_printf&lt;/span&gt;(&lt;span style=&#34;color:#66d9ef&#34;&gt;const&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;char&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;fmt, ...) {
  va_list argp;

  va_start(argp, fmt);
  HAL_printf_valist(fmt, argp);
  va_end(argp);
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now serial &lt;code&gt;printf()&lt;/code&gt; can be used with a simple &lt;code&gt;HAL_printf(&amp;quot;Test: %d&amp;quot;, value);&lt;/code&gt;
call.&lt;/p&gt;
&lt;p&gt;And now the implementation of &lt;code&gt;logI()&lt;/code&gt; and &lt;code&gt;logE()&lt;/code&gt; is obvious:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-C&#34; data-lang=&#34;C&#34;&gt;&lt;span style=&#34;color:#75715e&#34;&gt;/** Generic LOG procedure
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt; * @param Log level
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt; * @param *fmt String to print
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt; * @param argp Parameters list
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt; */&lt;/span&gt;
&lt;span style=&#34;color:#66d9ef&#34;&gt;static&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;void&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;log&lt;/span&gt;(uint8_t level, &lt;span style=&#34;color:#66d9ef&#34;&gt;const&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;char&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;fmt, va_list argp) {
	HAL_printf(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;%c - &amp;#34;&lt;/span&gt;, level);
	HAL_printf_valist(fmt, argp);
}

&lt;span style=&#34;color:#75715e&#34;&gt;/** LOG procedure - Info
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt; * @param *fmt String to print
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt; * @param ... Parameters list
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt; */&lt;/span&gt;
&lt;span style=&#34;color:#66d9ef&#34;&gt;void&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;logI&lt;/span&gt;(&lt;span style=&#34;color:#66d9ef&#34;&gt;const&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;char&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt; fmt, ...) {
  va_list argp;

	va_start(argp, fmt);
	log(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;I&amp;#39;&lt;/span&gt;, fmt, argp);
	va_end(argp);
}

&lt;span style=&#34;color:#75715e&#34;&gt;/** LOG procedure - Error
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt; * @param *fmt String to print
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt; * @param .. Parameters list
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt; */&lt;/span&gt;
&lt;span style=&#34;color:#66d9ef&#34;&gt;void&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;logE&lt;/span&gt;(&lt;span style=&#34;color:#66d9ef&#34;&gt;const&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;char&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt; fmt, ...) {
  va_list argp;

  va_start(argp, fmt);
  log(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;E&amp;#39;&lt;/span&gt;, fmt, argp);
  va_end(argp);
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Notes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If you want to display floats with &lt;code&gt;%f&lt;/code&gt; and you use
&lt;a href=&#34;https://launchpad.net/gcc-arm-embedded&#34;&gt;GNU ARM&lt;/a&gt; provided by
&lt;a href=&#34;http://www.openstm32.org/&#34;&gt;OpenSTM32&lt;/a&gt;, the flag &lt;code&gt;-u _printf_float&lt;/code&gt; must be
added to linker options otherwise the data will be only whitespaces.&lt;/li&gt;
&lt;li&gt;The main drawback of this method is the size of the char* buffer defined by
&lt;code&gt;PRINT_BUFFER_SIZE&lt;/code&gt;, you have to be sure that it is big enough for all your
strings.&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>STM32 - Designing an STM32L0xx board</title>
      <link>https://notes.iopush.net/blog/2016/designing-an-stm32l0xx-board/</link>
      <pubDate>Wed, 09 Nov 2016 15:13:15 +0000</pubDate>
      
      <guid>https://notes.iopush.net/blog/2016/designing-an-stm32l0xx-board/</guid>
      <description>&lt;p&gt;After the &lt;a href=&#34;http://notes.iopush.net/designing-an-stm32l151-board/&#34;&gt;STM32L151&lt;/a&gt;, I
am now designing a board for STM32L052. Following are some notes about ST
application notes I read to design an board.&lt;/p&gt;
&lt;p&gt;All documents can be found
&lt;a href=&#34;http://www.st.com/content/st_com/en/products/microcontrollers/stm32-32-bit-arm-cortex-mcus/stm32l0-series/stm32l0x2/stm32l052k8.html&#34;&gt;here&lt;/a&gt;.&lt;br&gt;
&lt;a href=&#34;http://www.st.com/content/ccc/resource/technical/document/datasheet/dc/d6/6d/24/86/2a/40/d3/DM00108217.pdf/files/DM00108217.pdf/jcr:content/translations/en.DM00108217.pdf&#34;&gt;Datasheet&lt;/a&gt;,
&lt;a href=&#34;http://www.st.com/content/ccc/resource/technical/document/reference_manual/63/3c/c0/51/1c/fb/44/d4/DM00108281.pdf/files/DM00108281.pdf/jcr:content/translations/en.DM00108281.pdf&#34;&gt;Reference manual&lt;/a&gt;,
&lt;a href=&#34;http://www.st.com/content/ccc/resource/technical/document/errata_sheet/91/9c/e9/86/a9/91/43/a6/DM00114896.pdf/files/DM00114896.pdf/jcr:content/translations/en.DM00114896.pdf&#34;&gt;Errata sheet&lt;/a&gt;.&lt;/p&gt;
&lt;h1 id=&#34;hardware-development&#34;&gt;Hardware development&lt;/h1&gt;
&lt;p&gt;&lt;a href=&#34;http://www.st.com/content/ccc/resource/technical/document/application_note/fd/f4/6b/40/9a/b5/41/a2/DM00112257.pdf/files/DM00112257.pdf/jcr:content/translations/en.DM00112257.pdf&#34;&gt;AN4467 - Getting started with STM32L0xx hardware development&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;hardware&#34;&gt;Hardware&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Voltage range, p6
&lt;ul&gt;
&lt;li&gt;Full speed (Range 1) : 2.0 to 3.6 VDC&lt;/li&gt;
&lt;li&gt;USB : 3.0 to 3.6 VDC&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Power supply capacitors, p11&lt;/li&gt;
&lt;li&gt;100 nF by VDD pin&lt;/li&gt;
&lt;li&gt;Min 4.7µf for the chip, 10µF recommended&lt;/li&gt;
&lt;li&gt;100 nF by VDDA pin&lt;/li&gt;
&lt;li&gt;1 µF for the chip, or 10 µF if high sampling rate ADC&lt;/li&gt;
&lt;li&gt;Reset circuit, p16&lt;/li&gt;
&lt;li&gt;No component mandatory&lt;/li&gt;
&lt;li&gt;10 nF to 100 nF pull-down can be added as EMS protection&lt;/li&gt;
&lt;li&gt;Clock, p17&lt;/li&gt;
&lt;li&gt;No external required&lt;/li&gt;
&lt;li&gt;Better to provide a 32.768 kHz quartz for RTC accuracy&lt;/li&gt;
&lt;li&gt;Recommended load capacitance for HSE is 2 to 7pF&lt;/li&gt;
&lt;li&gt;SWD port, p25&lt;/li&gt;
&lt;li&gt;Signals required are: NRST, SWDIO, SWCLK, GND&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;debug&#34;&gt;Debug&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;No JTAG port&lt;/li&gt;
&lt;li&gt;SWD: SerialWire Debug&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;boot&#34;&gt;Boot&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;See
&lt;a href=&#34;http://www.st.com/content/ccc/resource/technical/document/application_note/b9/9b/16/3a/12/1e/40/0c/CD00167594.pdf/files/CD00167594.pdf/jcr:content/translations/en.CD00167594.pdf&#34;&gt;AN2606&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Boot configuration
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;BOOT1&lt;/code&gt; bit in &lt;code&gt;user option byte&lt;/code&gt;, set to 0 by default&lt;/li&gt;
&lt;li&gt;&lt;code&gt;BOOT0&lt;/code&gt; pin, inline 10 kOhm resistor recommended&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Boot selection (&lt;code&gt;BOOT1&lt;/code&gt; - &lt;code&gt;BOOT0&lt;/code&gt;)
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;x-0&lt;/code&gt;: Flash memory&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0-1&lt;/code&gt;: System memory (ST bootloader)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;1-1&lt;/code&gt;: SRAM memory&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;ST bootloader on
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;USART1&lt;/code&gt;, &lt;code&gt;USART2&lt;/code&gt; (pulls-up required on &lt;code&gt;TX&lt;/code&gt; and &lt;code&gt;RX&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;SPI1&lt;/code&gt;, &lt;code&gt;SPI2&lt;/code&gt; (pull-down required on &lt;code&gt;CLK&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;No DFU&lt;/li&gt;
&lt;li&gt;All pins are in floating input state during reset =&amp;gt; Do not forget a weak pull
for components like MOSFET&amp;hellip;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;oscillator-design-guide&#34;&gt;Oscillator design guide&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;http://www.st.com/content/ccc/resource/technical/document/application_note/c6/eb/5e/11/e3/69/43/eb/CD00221665.pdf/files/CD00221665.pdf/jcr:content/translations/en.CD00221665.pdf&#34;&gt;AN2867 - Oscillator design guide&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;§4.2, p23 - Detailed steps to select an STM32-compatible crystal&lt;/li&gt;
&lt;li&gt;§5, p26 - Some recommended resonators for STM32 microcontrollers&lt;/li&gt;
&lt;li&gt;§7.1, p30 - PCB design guidelines&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;touch-sensing&#34;&gt;Touch sensing&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;http://www.st.com/content/ccc/resource/technical/document/application_note/f4/7c/88/47/75/08/42/a8/DM00035396.pdf/files/DM00035396.pdf/jcr:content/translations/en.DM00035396.pdf&#34;&gt;AN3960 - ESD considerations&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Most used method is to add an inline 50 Ohm&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://www.st.com/content/ccc/resource/technical/document/application_note/46/39/d6/92/4a/4d/40/9f/DM00087990.pdf/files/DM00087990.pdf/jcr:content/translations/en.DM00087990.pdf&#34;&gt;AN4312 - Guidelines for designing touch sensing applications&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;If a LED is placed closed to touch interface, use 10 nF bypass capacitor (p15)&lt;/li&gt;
&lt;li&gt;If possible use FT I/O instead of TT as they are clamped to VDD, or use
Shottky diode with capacitance &amp;lt;5 pf (p15)&lt;/li&gt;
&lt;li&gt;Recommended to use the same shape for all electrodes (p18)&lt;/li&gt;
&lt;li&gt;Recommended electrode size is 4 times panel thickness&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;usb&#34;&gt;USB&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;http://www.st.com/content/ccc/resource/technical/document/application_note/group0/0b/10/63/76/87/7a/47/4b/DM00296349/files/DM00296349.pdf/jcr:content/translations/en.DM00296349.pdf&#34;&gt;AN4879 - USB hardware and PCB guidelines&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Signal lines&lt;/li&gt;
&lt;li&gt;90 ohm +/-15% differential&lt;/li&gt;
&lt;li&gt;ESD protection circuits like ST USBLC6 are highly recommended&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;lets-put-it-into-practice&#34;&gt;Let&amp;rsquo;s put it into practice&lt;/h2&gt;
&lt;p&gt;An open-source dev. board I designed can be found
&lt;a href=&#34;https://notes.iopush.net/projects/stm32l052-development-board/&#34;&gt;here&lt;/a&gt;.&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>STM32 - Designing an STM32L15xx board</title>
      <link>https://notes.iopush.net/blog/2016/designing-an-stm32l151-board/</link>
      <pubDate>Tue, 15 Mar 2016 11:37:08 +0000</pubDate>
      
      <guid>https://notes.iopush.net/blog/2016/designing-an-stm32l151-board/</guid>
      <description>&lt;p&gt;Following are some notes about ST application notes I read to design an
STM32L151 board.&lt;/p&gt;
&lt;p&gt;All documents can be found
&lt;a href=&#34;http://www.st.com/web/catalog/mmc/FM141/SC1169/SS1295/LN1041/PF259973#&#34;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;an2606---microcontroller-system-memory-boot-mode&#34;&gt;AN2606 - Microcontroller system memory boot mode&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://my.st.com/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Attachments/18225/AN2606.pdf&#34;&gt;AN2606 - Microcontroller system memory boot mode&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Bootloader in &lt;code&gt;USART1&lt;/code&gt; or &lt;code&gt;USART2&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Unused &lt;code&gt;RX&lt;/code&gt; (&lt;code&gt;USART1&lt;/code&gt; or &lt;code&gt;2&lt;/code&gt;) pin must be pulled and not left floating&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;an3216---hardware-development&#34;&gt;AN3216 - Hardware development&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;http://www.st.com/web/en/resource/technical/document/application_note/CD00273528.pdf&#34;&gt;AN3216 - Getting started with STM32L1xxx hardware development&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&#34;hardware&#34;&gt;Hardware&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Voltage range&lt;/li&gt;
&lt;li&gt;Full speed (Range 1) : 2.0 to 3.6 VDC&lt;/li&gt;
&lt;li&gt;Capacitors:&lt;/li&gt;
&lt;li&gt;1x100 nF by VDD pin&lt;/li&gt;
&lt;li&gt;Min 4.7µf for the chip, 10µF recommended&lt;/li&gt;
&lt;li&gt;Reset and power supply supervisor&lt;/li&gt;
&lt;li&gt;Power on/down-reset signal - No consumption&lt;/li&gt;
&lt;li&gt;Programmable voltage detector - No consumption - between 1.85 and 3.02 V, 200
mV steps. Generates an interrupt.&lt;/li&gt;
&lt;li&gt;Brownout detector - Slight power consumption, can be disabled by &lt;code&gt;option byte&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Reset circuit&lt;/li&gt;
&lt;li&gt;A 100 nF grounded capacitor is recommended, can be reduced to 10 nF&lt;/li&gt;
&lt;li&gt;Clock&lt;/li&gt;
&lt;li&gt;Multi-Speed Internal : Activated on reset, can be trimmed with high speed
external clock.&lt;/li&gt;
&lt;li&gt;High Speed External clock : Optional, can be clock source (&amp;lt;32 MHz) or
oscillator (1 to 24 MHz)&lt;/li&gt;
&lt;li&gt;Low Speed External lock : Optional, can be clock source or oscillator (32.768
kHz). [-30%; +60%} tolerances&lt;/li&gt;
&lt;li&gt;PLL : Hook to generate various internal clocks&lt;/li&gt;
&lt;li&gt;Clock Security System : Disable HSE if failure detected&lt;/li&gt;
&lt;li&gt;Boot configuration : &lt;code&gt;boot0&lt;/code&gt; and &lt;code&gt;boot1&lt;/code&gt; inputs triggers 3 modes:&lt;/li&gt;
&lt;li&gt;&lt;code&gt;x0&lt;/code&gt; : Flash memory&lt;/li&gt;
&lt;li&gt;&lt;code&gt;01&lt;/code&gt; : System memory (ST bootloader)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;11&lt;/code&gt; : SRAM memory&lt;/li&gt;
&lt;li&gt;Inline 10 k resistor is recommended&lt;/li&gt;
&lt;li&gt;ST bootloader via &lt;code&gt;USART1&lt;/code&gt; or &lt;code&gt;USART2&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;RX&lt;/code&gt; pin from unused &lt;code&gt;USART&lt;/code&gt; must not be left floating&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;debug&#34;&gt;Debug&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Interface : ARM JTAG (5 pins) or SW ( SerialWire - 2 pins)&lt;/li&gt;
&lt;li&gt;See page 23&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;recommendations&#34;&gt;Recommendations&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Use 4 layers PCB with dedicated VSS and VDD layerS. If not, ensured good
ground&lt;/li&gt;
&lt;li&gt;Separate usages (High current, analog&amp;hellip;)&lt;/li&gt;
&lt;li&gt;Avoid floating pin I/O, disable unused features&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;an1709---emc-design-hardware&#34;&gt;AN1709 - EMC Design (hardware)&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;http://www.st.com/st-web-ui/static/active/en/resource/technical/document/application_note/CD00004479.pdf&#34;&gt;EMC design guide for ST microcontrollers&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;External oscillators must be as close as possible to the µC&lt;/li&gt;
&lt;li&gt;Avoid tracks surface and inductance
&lt;ul&gt;
&lt;li&gt;Multiple via reduce inductance&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Power supply must be decoupled&lt;/li&gt;
&lt;li&gt;Unused I/O pin must be set to low output&lt;/li&gt;
&lt;li&gt;Shielding might improve, but depends on the selected material&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;an1015---emc-design-software&#34;&gt;AN1015 - EMC Design (software)&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;http://www.st.com/web/en/resource/technical/document/application_note/CD00004037.pdf&#34;&gt;Software techniques for improving microcontrollers EMC performance&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    
  </channel>
</rss>
