<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <generator uri="http://jekyllrb.com" version="4.0.1">Jekyll</generator>
  
  
  <link href="http://iwasz.pl/feed.xml" rel="self" type="application/atom+xml" />
  <link href="http://iwasz.pl/" rel="alternate" type="text/html" />
  <updated>2022-03-26T12:23:29+01:00</updated>
  <id>http://iwasz.pl//</id>

  
    <title type="html">Iwasz</title>
  

  
    <subtitle>Personal blog of Łukasz Iwaszkiewicz known as Iwasz. Rants  about stuf I&apos;m working on mostly involving programming and electronics.</subtitle>
  

  

  
  
    <entry>
      
      <title type="html">UNI-T UT181A problems with charging and poor battery life. Proposed fix.</title>
      
      
      <link href="http://iwasz.pl/electronics/2022-03-25-ut181a-charging-fix.md/" rel="alternate" type="text/html" title="UNI-T UT181A problems with charging and poor battery life. Proposed fix." />
      
      <published>2022-03-25T00:00:00+01:00</published>
      <updated>2022-03-25T00:00:00+01:00</updated>
      <id>http://iwasz.pl/electronics/ut181a-charging-fix</id>
      <content type="html" xml:base="http://iwasz.pl/electronics/2022-03-25-ut181a-charging-fix.md/">&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt; : Device couldn’t be charged to full. I replaced the voltage divider responsible for battery sensing. However more investigation, and everyday use is needed to fully evaluate this fix.&lt;/p&gt;

&lt;h1 id=&quot;symptoms&quot;&gt;Symptoms&lt;/h1&gt;
&lt;ol&gt;
  &lt;li&gt;Near the end of the charging cycle, the power button flashes in red/green erratically. Screen shows 95% and 100% interchangeably.&lt;/li&gt;
  &lt;li&gt;After disconnecting the wall wart and switching to voltage measurement it shows only ~75%, even after 24h charging.&lt;/li&gt;
  &lt;li&gt;Single charge gives only about 10h of operation.&lt;/li&gt;
  &lt;li&gt;After a ~month on the shelf it does not turn back on (it somehow discharges even though turned off).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The lowest voltage my multimeter was able to work on was 7.55V which in my opinion is way to high. Below that it shuts down. I assumed that the critically low value should be around 3.3V * 2 = 6.6V (or even lower):
&lt;img src=&quot;/assets/ut181a-charging/discharged-7.60v.jpg&quot; alt=&quot;Discharged even though batt is 7.6V&quot; /&gt;&lt;/p&gt;

&lt;p&gt;At the other hand, after full charge the battery shows 8V. I’m not sure what to think about it. If I were designing this, I would charge to 8.4V, but I haven’t seen the battery’s specs, so maybe it’s desirable. Then I discharged the battery using an active load, and it seems to be in great condition. If not the charger nor the battery, then the voltage measurement done by the MCU has to be wrong. After poking the PCB I’ve found the divider:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/ut181a-charging/divider.jpg&quot; alt=&quot;The voltage divider&quot; /&gt;&lt;/p&gt;

&lt;p&gt;At 8V the original divider gave (measured) 2.16V (while it &lt;a href=&quot;https://ohmslawcalculator.com/voltage-divider-calculator&quot;&gt;should output 2.253&lt;/a&gt;). So I replaced the resistors as so:&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt; &lt;/th&gt;
      &lt;th&gt;R63&lt;/th&gt;
      &lt;th&gt;R64&lt;/th&gt;
      &lt;th&gt;out @ 8V in (theoretical)&lt;/th&gt;
      &lt;th&gt;out @ 8V in (measured)&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;original&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;392k&lt;/td&gt;
      &lt;td&gt;1M&lt;/td&gt;
      &lt;td&gt;2.253&lt;/td&gt;
      &lt;td&gt;2.16&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;replacement&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;35k7&lt;/td&gt;
      &lt;td&gt;82k5&lt;/td&gt;
      &lt;td&gt;2.362&lt;/td&gt;
      &lt;td&gt;?&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Values were chosen mostly because I had those on hand (1%). It fixed the problem, but more investigation, and everyday use is needed to fully evaluate this fix.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/ut181a-charging/fixed.jpg&quot; alt=&quot;Is id fixed?&quot; /&gt;&lt;/p&gt;

&lt;h1 id=&quot;thoughts&quot;&gt;Thoughts&lt;/h1&gt;
&lt;ul&gt;
  &lt;li&gt;Voltage sensing during charing and during normal operation is realized differently.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;links&quot;&gt;Links&lt;/h1&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.uni-trend.com/meters/html/product/General_Meters/DigitalMultimeters/UT181A/UT181A.html&quot;&gt;Multimeter itself&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://pdf1.alldatasheet.com/datasheet-pdf/view/329803/CYRUSTEK/ES636.html&quot;&gt;One of the chips, not relevant to the story&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.ti.com/lit/ds/symlink/max660.pdf&quot;&gt;Another chip, not relevant to the story&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://kiloohm.info/eia96-resistor/58D&quot;&gt;Very convenient 0603 resistor markings chart&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content>

      
      
      
      
      

      

      
        <category term="electronics" />
      

      

      
        <summary type="html">TL;DR : Device couldn’t be charged to full. I replaced the voltage divider responsible for battery sensing. However more investigation, and everyday use is needed to fully evaluate this fix.</summary>
      

      
      
    </entry>
  
  
  
    <entry>
      
      <title type="html">Samsung A70 not charging. Easy fix.</title>
      
      
      <link href="http://iwasz.pl/electronics/2021-11-11-samsung-a70-not-charging-easy-fix.md/" rel="alternate" type="text/html" title="Samsung A70 not charging. Easy fix." />
      
      <published>2021-11-11T00:00:00+01:00</published>
      <updated>2021-11-11T00:00:00+01:00</updated>
      <id>http://iwasz.pl/electronics/samsung-a70-not-charging-easy-fix%20copy</id>
      <content type="html" xml:base="http://iwasz.pl/electronics/2021-11-11-samsung-a70-not-charging-easy-fix.md/">&lt;p&gt;I’m a total newbie when comes to cellphone repair, but the fix presented here worked like a charm and is relatively easy if you know how to solder. I’ve came across the solution on the &lt;a href=&quot;https://www.youtube.com/watch?v=y5fMSp9zq3s&quot;&gt;iRepair channel on YT&lt;/a&gt; and below I post some photos from a microscope with a super brief explanation which the video lacks. First &lt;a href=&quot;https://www.ifixit.com/Device/samsung_galaxy_a70&quot;&gt;disassemble the phone&lt;/a&gt; and take a look at the “reference” image below.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/a70-charging/01-no-back-cover.jpg&quot; alt=&quot;No back cover reference image&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The part that has failed in my case was the wide flat cable connecting the main board (PCB on the left) with the connector board visible on the right. Probably replacing the cable itself would work, but only if the sockets the cable is attached to are OK and we do not know that. In particular the line that fails is the positive voltage one, which (if I’m not mistaken) is directly connected to the USB-C socket VBUS pins. The Vdd connection is realized through the wide pin on the side of the FFC socket. Depicted below is how it looks on the main board side:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/a70-charging/Picture%202021-11-11%2020-25-11.png&quot; alt=&quot;Power connection on the main board&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Scrape off the solder mask and solder a jumper wire:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/a70-charging/Picture%202021-11-11%2020-34-34.png&quot; alt=&quot;Soldered a jumper wire&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Then do the same on the “connector board” (the one with the USB-C on it). I didn’t make better photos, to try to find the spot basing on the shape of the PCB and its traces. “connector board” prepared for soldering:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/a70-charging/Picture%202021-11-11%2020-22-29.png&quot; alt=&quot;prepared for soldering&quot; /&gt;&lt;/p&gt;

&lt;p&gt;And here the same shot taken after soldering the wire:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/a70-charging/Picture%202021-11-11%2020-31-53.png&quot; alt=&quot;Soldered the wire&quot; /&gt;&lt;/p&gt;

&lt;p&gt;And that’s it! Reconnect the FFC:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/a70-charging/IMG_20211111_203927.jpg&quot; alt=&quot;FFC on its place&quot; /&gt;&lt;/p&gt;

&lt;p&gt;And voila! It works:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/a70-charging/IMG_20211111_204128.jpg&quot; alt=&quot;Works&quot; /&gt;&lt;/p&gt;

&lt;p&gt;I’m definitely buying a new phone soon as this one caused so much trouble, but fixing it was fun nonetheless :D&lt;/p&gt;</content>

      
      
      
      
      

      

      
        <category term="electronics" />
      

      

      
        <summary type="html">I’m a total newbie when comes to cellphone repair, but the fix presented here worked like a charm and is relatively easy if you know how to solder. I’ve came across the solution on the iRepair channel on YT and below I post some photos from a microscope with a super brief explanation which the video lacks. First disassemble the phone and take a look at the “reference” image below.</summary>
      

      
      
    </entry>
  
  
  
    <entry>
      
      <title type="html">Out Of Tree Zephyr RTOS module (driver)</title>
      
      
      <link href="http://iwasz.pl/electronics/2021-06-18-out-of-tree-zephyr-module.md/" rel="alternate" type="text/html" title="Out Of Tree Zephyr RTOS module (driver)" />
      
      <published>2021-06-18T00:00:00+02:00</published>
      <updated>2021-06-18T00:00:00+02:00</updated>
      <id>http://iwasz.pl/electronics/out-of-tree-zephyr-module</id>
      <content type="html" xml:base="http://iwasz.pl/electronics/2021-06-18-out-of-tree-zephyr-module.md/">&lt;p&gt;Sometimes it’s inconvenient to develop a driver for some peripheral or sensor &lt;em&gt;in-tree&lt;/em&gt;. As far as I was able to research (bare with me, I’m relatively new to Zephyr), the Zephyr RTOS modules are the way to go in such situations. First, a bunch of links that pointed me in the right direction:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://lists.zephyrproject.org/g/devel/topic/how_to_build_external_drivers/33154657?p=,,,20,0,0,0::recentpostdate%2Fsticky,,,20,2,0,33154657&quot;&gt;A thread&lt;/a&gt; stating that “it should not pose a problem, Nordic is doing just that”&lt;/li&gt;
  &lt;li&gt;The &lt;a href=&quot;https://github.com/nrfconnect/sdk-nrf&quot;&gt;nRF Connect SDK: sdk-nrf&lt;/a&gt; the above link is referring to.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://stackoverflow.com/questions/62358554/zephyros-how-to-add-driver-module-to-out-of-tree-project&quot;&gt;Stack overflow thread&lt;/a&gt; where a guy replied to himself. Even though this link covers the topic pretty much, I still stumbled upon some problems. See below.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/zephyrproject-rtos/zephyr/issues/27181&quot;&gt;Another out of tree approach&lt;/a&gt; but overall, this thread is inconclusive.&lt;/li&gt;
  &lt;li&gt;ZEPHYR_EXTRA_MODULES &lt;a href=&quot;https://community.platformio.org/t/zephyr-out-of-tree-driver-doesnt-get-compiled/14412&quot;&gt;is mentioned here&lt;/a&gt;.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/iwasz/example-zephyr-module&quot;&gt;My module&lt;/a&gt; this post is about.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/iwasz/example-zephyr-module-app&quot;&gt;Acompanying test application&lt;/a&gt; to try things out.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;My &lt;a href=&quot;https://github.com/iwasz/example-zephyr-module&quot;&gt;test module&lt;/a&gt; contains a driver for LSM6DS3 accelermoeter and gyroscope. This is an older version of LSM6DSL that is already supported by Zephyr, which makes my implementation as easy as changing one macro.&lt;/p&gt;

&lt;p&gt;The current version of Zephyr as of today is 2.6.&lt;/p&gt;

&lt;h1 id=&quot;the-module&quot;&gt;The module&lt;/h1&gt;
&lt;p&gt;Explains what has been copied and what modified. Create the directory structure:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;+drivers
  +sensor

+dts
  +bindings
    +sensor

+zephyr
CMakeLists.txt
Kconfig
README.md
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Copy &lt;code class=&quot;highlighter-rouge&quot;&gt;zephyr/drivers/sensor/lsm6dsl&lt;/code&gt; from the main Zephyr repo to  &lt;code class=&quot;highlighter-rouge&quot;&gt;drivers/sensor/lsm6ds3&lt;/code&gt; in our directory.&lt;/p&gt;

&lt;h2 id=&quot;names&quot;&gt;Names&lt;/h2&gt;

&lt;p&gt;Change all the function, macro and file names from &lt;strong&gt;lsm6dsl&lt;/strong&gt; to &lt;strong&gt;lsm6ds3&lt;/strong&gt;. Remember about &lt;code class=&quot;highlighter-rouge&quot;&gt;Kconfig&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;CMakeLists.txt&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Change the macro &lt;code class=&quot;highlighter-rouge&quot;&gt;LSM6DSL_VAL_WHO_AM_I&lt;/code&gt; from 0x6A to 0x69. This is the only “true” modification in the code.&lt;/p&gt;

&lt;h2 id=&quot;build-system&quot;&gt;Build system&lt;/h2&gt;

&lt;p&gt;Update / provide build system information. A module has to have a Kconfig and CMakeLists.txt in its root directory, so provide one. In my module, these files are as simple as:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;Kconfig&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-Kconfig&quot;&gt;menu &quot;My super zephyr module&quot;

rsource &quot;drivers/Kconfig&quot;

endmenu
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;CMakeLists.txt&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-cmake highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;add_subdirectory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;drivers&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;In the above files I point to the &lt;code class=&quot;highlighter-rouge&quot;&gt;drivers&lt;/code&gt; directory, so there have to be Kconfig and CMakeLists.txt there as well:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;drivers&lt;/code&gt; directory contains:&lt;/p&gt;

&lt;p&gt;CMakeLists.txt : &lt;code class=&quot;highlighter-rouge&quot;&gt;add_subdirectory_ifdef(CONFIG_SENSOR sensor)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Kconfig &lt;code class=&quot;highlighter-rouge&quot;&gt;rsource &quot;sensor/Kconfig&quot;&lt;/code&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;sensor&lt;/code&gt; directory contains:&lt;/p&gt;

&lt;p&gt;CMakeLists.txt : &lt;code class=&quot;highlighter-rouge&quot;&gt;add_subdirectory_ifdef(CONFIG_LSM6DS3 lsm6ds3)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Kconfig : &lt;code class=&quot;highlighter-rouge&quot;&gt;rsource &quot;lsm6ds3/Kconfig&quot;&lt;/code&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;You see the pattern.&lt;/p&gt;

&lt;h2 id=&quot;bindings&quot;&gt;Bindings&lt;/h2&gt;
&lt;p&gt;Copy &lt;code class=&quot;highlighter-rouge&quot;&gt;st,lsm6dsl-i2c.yaml&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;st,lsm6dsl-spi.yaml&lt;/code&gt; bindings from Zephyr repo to our &lt;code class=&quot;highlighter-rouge&quot;&gt;dts/bindings/sensor&lt;/code&gt;, and change the file names accordingly (don’t forget about the contents). Binding files are found automatically during the build.&lt;/p&gt;

&lt;h2 id=&quot;moduleyml&quot;&gt;module.yml&lt;/h2&gt;
&lt;p&gt;Lastly, provide the module description adding the &lt;code class=&quot;highlighter-rouge&quot;&gt;zephyr/module.yml&lt;/code&gt; :&lt;/p&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;na&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;cmake&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;.&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;kconfig&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Kconfig&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;settings&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;dts_root&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;problems-ive-had&quot;&gt;Problems I’ve had&lt;/h2&gt;
&lt;p&gt;Zephyr build system isn’t very verbose (nor precise) when problems occur, so if you ever encounter errors like this:&lt;/p&gt;

&lt;div class=&quot;language-cmake highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;cmake -B build -G Ninja -DBOARD=nucleo_h743zi -DBOARD_ROOT=. -DZEPHYR_EXTRA_MODULES=/home/iwasz/workspace/zephyr-modbus/my-zephyr-module .
Including &lt;span class=&quot;nf&quot;&gt;boilerplate&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;Zephyr base&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;: /home/iwasz/workspace/zephyr-modbus/zephyrproject/zephyr/cmake/app/boilerplate.cmake
-- Application: /home/iwasz/workspace/zephyr-modbus/zephyr-inclinometer
-- Zephyr version: 2.6.0-&lt;span class=&quot;nf&quot;&gt;rc3&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;/home/iwasz/workspace/zephyr-modbus/zephyrproject/zephyr&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;, build: v2.6.0-rc3
-- Found Python3: /usr/bin/python3.9 &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;found suitable exact version &lt;span class=&quot;s2&quot;&gt;&quot;3.9.4&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; found components: Interpreter 
-- Found &lt;span class=&quot;nf&quot;&gt;west&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;found suitable version &lt;span class=&quot;s2&quot;&gt;&quot;0.8.0&quot;&lt;/span&gt;, minimum required is &lt;span class=&quot;s2&quot;&gt;&quot;0.7.1&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
CMake Error at /home/iwasz/workspace/zephyr-modbus/zephyrproject/zephyr/cmake/zephyr_module.cmake:61 &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;message&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;:
  /home/iwasz/workspace/zephyr-modbus/my-zephyr-module, given in
  ZEPHYR_EXTRA_MODULES, is not a valid zephyr module

Call &lt;span class=&quot;nf&quot;&gt;Stack&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;most recent call first&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;:
  /home/iwasz/workspace/zephyr-modbus/zephyrproject/zephyr/cmake/app/boilerplate.cmake:183 &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;include&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  /home/iwasz/workspace/zephyr-modbus/zephyrproject/zephyr/share/zephyr-package/cmake/ZephyrConfig.cmake:24 &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;include&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  /home/iwasz/workspace/zephyr-modbus/zephyrproject/zephyr/share/zephyr-package/cmake/ZephyrConfig.cmake:35 &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;include_boilerplate&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  CMakeLists.txt:5 &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;find_package&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;


-- Configuring incomplete, errors occurred!
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;It could mean that the &lt;code class=&quot;highlighter-rouge&quot;&gt;module.yml&lt;/code&gt; is named incorrectly. In my case, I used &lt;code class=&quot;highlighter-rouge&quot;&gt;yaml&lt;/code&gt; extension instead of &lt;code class=&quot;highlighter-rouge&quot;&gt;yml&lt;/code&gt;.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;After correcting the problem with &lt;code class=&quot;highlighter-rouge&quot;&gt;module.yml&lt;/code&gt;, the app started and the analyzer showed that it does something on the I²C, but then it failed in &lt;code class=&quot;highlighter-rouge&quot;&gt;drivers/sensor/lsm6ds3/lsm6ds3_trigger.c&lt;/code&gt; in the &lt;code class=&quot;highlighter-rouge&quot;&gt;lsm6ds3_trigger_set&lt;/code&gt; function. The problematic code was:&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;drv_data&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;gpio&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;LOG_ERR&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;triggers not supported&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ENOTSUP&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Clearly, a problem with my overlay, but why? It seems the Zephyr build system did not see my binding files. &lt;a href=&quot;https://docs.zephyrproject.org/latest/guides/dts/bindings.html?highlight=bindings#where-bindings-are-located&quot;&gt;As stated here&lt;/a&gt; the &lt;code class=&quot;highlighter-rouge&quot;&gt;module.yml&lt;/code&gt; has to point at the binding files. The solution is to add:&lt;/p&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;na&quot;&gt;settings&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;dts_root&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;the-test-application&quot;&gt;The test application&lt;/h1&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/iwasz/example-zephyr-module-app&quot;&gt;Is here&lt;/a&gt;. The application is straightforward. I copied &lt;code class=&quot;highlighter-rouge&quot;&gt;zephyr/samples/sensor/lsm6dsl&lt;/code&gt;. I added my custom overlay in the &lt;code class=&quot;highlighter-rouge&quot;&gt;boards&lt;/code&gt; directory to configure what is connected and to which pins:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-dts&quot;&gt;&amp;amp;i2c2 {
        pinctrl-0 = &amp;lt;&amp;amp;i2c2_scl_pb10 &amp;amp;i2c2_sda_pb11&amp;gt;;
        status = &quot;okay&quot;;
        clock-frequency = &amp;lt;I2C_BITRATE_FAST&amp;gt;;

        lsm6ds3@6b {
                compatible = &quot;st,lsm6ds3&quot;;
                reg = &amp;lt;0x6b&amp;gt;;
                irq-gpios = &amp;lt;&amp;amp;gpiod 11 GPIO_ACTIVE_HIGH&amp;gt;;
                label = &quot;LSM6DS3&quot;;
        };
};
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I modified the &lt;code class=&quot;highlighter-rouge&quot;&gt;prj.conf&lt;/code&gt; to enable my implementation instead of theirs (again I changed from LSM6DSL to LSM6DS3).&lt;/p&gt;

&lt;p&gt;Finally I changed some (but not all) names in the C code from LSM6DSL to LSM6DS3:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;device_get_binding (DT_LABEL (DT_INST (0, st_lsm6ds3)))&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;CONFIG_LSM6DS3_TRIGGER&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;build&quot;&gt;Build&lt;/h1&gt;
&lt;p&gt;After these modification I was left with:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;The Zephyr itself (usual directory &lt;code class=&quot;highlighter-rouge&quot;&gt;zephyrproject&lt;/code&gt; + SDK)&lt;/li&gt;
  &lt;li&gt;My application in &lt;code class=&quot;highlighter-rouge&quot;&gt;my-zephyr-module-app&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;My module in &lt;code class=&quot;highlighter-rouge&quot;&gt;my-zephyr-module&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To build this i simply have to :&lt;/p&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;cd &lt;/span&gt;my-zephyr-module-app
cmake &lt;span class=&quot;nt&quot;&gt;-B&lt;/span&gt; build &lt;span class=&quot;nt&quot;&gt;-G&lt;/span&gt; Ninja &lt;span class=&quot;nt&quot;&gt;-DBOARD&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;nucleo_h743zi &lt;span class=&quot;nt&quot;&gt;-DBOARD_ROOT&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-DZEPHYR_EXTRA_MODULES&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/home/iwasz/workspace/zephyr-modbus/my-zephyr-module &lt;span class=&quot;nb&quot;&gt;.&lt;/span&gt;
ninja &lt;span class=&quot;nt&quot;&gt;-C&lt;/span&gt; build/
west flash
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h1 id=&quot;a-follow-up&quot;&gt;A follow-up&lt;/h1&gt;
&lt;p&gt;Sometimes it is convenient to have both the module and the application using it in one place. Thankfully there is an example in the Zephyr showing just that in &lt;code class=&quot;highlighter-rouge&quot;&gt;zephyr/samples/application_development/out_of_tree_driver&lt;/code&gt;. Interestingly enough, when I tried to incorporate this example into one of my projects, I got an error during build:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[...]
In declaration of void hello_world_print 
Traceback (most recent call last):
  File &quot;/home/iwasz/workspace/zephyrproject/zephyr/scripts/gen_syscalls.py&quot;, line 450, in &amp;lt;module&amp;gt;
    main()
  File &quot;/home/iwasz/workspace/zephyrproject/zephyr/scripts/gen_syscalls.py&quot;, line 379, in main
    handler, inv, mrsh, sys_id, entry = analyze_fn(match_group)
  File &quot;/home/iwasz/workspace/zephyrproject/zephyr/scripts/gen_syscalls.py&quot;, line 324, in analyze_fn
    func_type, func_name = typename_split(func)
  File &quot;/home/iwasz/workspace/zephyrproject/zephyr/scripts/gen_syscalls.py&quot;, line 143, in typename_split
    raise SyscallParseException(&quot;Malformed system call invocation&quot;)
__main__.SyscallParseException: Malformed system call invocation
[6/178] Generating include/generated/kobj-types-enum.h, include/generated/otype-to-str.h, include/generated/otype-to-size.h
ninja: build stopped: subcommand failed.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The cause was that I modified the &lt;code class=&quot;highlighter-rouge&quot;&gt;hello_world_driver.h&lt;/code&gt;, and saved it, which in turn fired the &lt;code class=&quot;highlighter-rouge&quot;&gt;clang-format&lt;/code&gt; tool (which uses my system-wide configuration). And this action alone broke the build completely (namely the lack of a space character after the function name and before the opening bracket is causing the problem). The solution is either to surround the problematic bit in &lt;code class=&quot;highlighter-rouge&quot;&gt;/* clang-format on/off */&lt;/code&gt; guards:&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cm&quot;&gt;/* clang-format off */&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;__syscall&lt;/span&gt;     &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt;        &lt;span class=&quot;nf&quot;&gt;hello_world_print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;device&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dev&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;inline&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;z_impl_hello_world_print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;device&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dev&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;cm&quot;&gt;/* clang-format on */&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Or to use the &lt;strong&gt;.clang-format&lt;/strong&gt; file provided by Zephyr. I went with the second option and copied the mentioned file to the directory where my modules are. This way I can use my system-wide (and preferred) formatting for the user-space C++ code, and make the Zephyr build system happy at the same time.&lt;/p&gt;

&lt;h1 id=&quot;todo&quot;&gt;TODO&lt;/h1&gt;
&lt;p&gt;Make vscode happy. The IDE is overwhelmed by the project split into 3 separate directories or I don’t know how to configure it. Let me know in the comments you whereabouts on this. Also I do not know (an I’ve tried) how to have the module included inside the application directory.&lt;/p&gt;</content>

      
      
      
      
      

      

      
        <category term="electronics" />
      

      

      
        <summary type="html">Sometimes it’s inconvenient to develop a driver for some peripheral or sensor in-tree. As far as I was able to research (bare with me, I’m relatively new to Zephyr), the Zephyr RTOS modules are the way to go in such situations. First, a bunch of links that pointed me in the right direction:</summary>
      

      
      
    </entry>
  
  
  
    <entry>
      
      <title type="html">STM32F042 option bytes under Linux</title>
      
      
      <link href="http://iwasz.pl/electronics/2020-07-29-stm32f042-option-bytes-linux/" rel="alternate" type="text/html" title="STM32F042 option bytes under Linux" />
      
      <published>2020-07-29T00:00:00+02:00</published>
      <updated>2020-07-29T00:00:00+02:00</updated>
      <id>http://iwasz.pl/electronics/stm32f042-option-bytes-linux</id>
      <content type="html" xml:base="http://iwasz.pl/electronics/2020-07-29-stm32f042-option-bytes-linux/">&lt;p&gt;These are instructions that worked for me when faced with a problem of modifying option bytes in stm32f042. The thing I was trying to do was to turn off BOOT0 pin support (PB8 in my chip) which then would eliminate the need to pull it. Then I could use this pin for something else, for example as a &lt;code class=&quot;highlighter-rouge&quot;&gt;CANbus&lt;/code&gt; &lt;code class=&quot;highlighter-rouge&quot;&gt;canRx&lt;/code&gt; input.&lt;/p&gt;

&lt;p&gt;A bunch of useful links:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://stackoverflow.com/questions/48927028/openocd-how-to-write-option-bytes-to-stm32f4&quot;&gt;Stack overflow question&lt;/a&gt; which put me on the right track.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://openocd.org/doc/html/General-Commands.html&quot;&gt;Openocd manual&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Reference manual of whatever chip you are using. The chapters of interest are entitled:
    &lt;ul&gt;
      &lt;li&gt;3.2.2 Flash program and erase operation
        &lt;ul&gt;
          &lt;li&gt;Unlocking the Flash memory&lt;/li&gt;
          &lt;li&gt;Option byte programming&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;4 Option byte&lt;/li&gt;
      &lt;li&gt;A.2.5 Option byte unlocking sequence code example&lt;/li&gt;
      &lt;li&gt;A.2.6 Option byte programming sequence code example&lt;/li&gt;
      &lt;li&gt;A.2.7 Option byte erasing sequence code example&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;tldr&quot;&gt;TL;DR&lt;/h1&gt;
&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;openocd &lt;span class=&quot;nt&quot;&gt;-f&lt;/span&gt; /home/iwasz/local/share/openocd/scripts/interface/stlink.cfg &lt;span class=&quot;nt&quot;&gt;-f&lt;/span&gt; /home/iwasz/local/share/openocd/scripts/target/stm32f0x.cfg &lt;span class=&quot;nt&quot;&gt;-c&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;init; mww 0x40022004 0x45670123; mww 0x40022004 0xCDEF89AB; mww 0x40022008 0x45670123; mww 0x40022008 0xCDEF89AB; mww 0x40022010 0x00000220; mww 0x40022010 0x00000260; mww 0x40022010 0x00000210; mwh 0x1ffff800 0x55AA; mwh 0x1ffff802 0x807f; mdw 0x1ffff800&apos;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;preparation&quot;&gt;Preparation&lt;/h1&gt;
&lt;p&gt;Turn the power on. Run the &lt;code class=&quot;highlighter-rouge&quot;&gt;openocd&lt;/code&gt; (mind the paths):&lt;/p&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;openocd &lt;span class=&quot;nt&quot;&gt;-f&lt;/span&gt; /home/iwasz/local/share/openocd/scripts/interface/stlink.cfg &lt;span class=&quot;nt&quot;&gt;-f&lt;/span&gt; /home/iwasz/local/share/openocd/scripts/target/stm32f0x.cfg 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Connect to the running &lt;code class=&quot;highlighter-rouge&quot;&gt;openocd&lt;/code&gt; to get access to the interactive shell:&lt;/p&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;telnet localhost 4444
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Verify that the &lt;strong&gt;FLASH_CR.LOCK&lt;/strong&gt; is set, meaning that the entire flash is locked. Flash base address is : 0x40022000 which tells that &lt;strong&gt;FLASH_OPTKEYR&lt;/strong&gt; address is 0x40022008 and &lt;strong&gt;FLASH_CR&lt;/strong&gt; address is 0x40022010. Read FLASH_CR as so (00000080 means the &lt;strong&gt;LOCK&lt;/strong&gt; flag is set):&lt;/p&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;mdw 0x40022010
0x40022010: 00000080 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;unlock-the-flash-and-option-bytes&quot;&gt;Unlock the flash and option bytes&lt;/h1&gt;
&lt;p&gt;Unlock the flash directly performing the unlocking sequence on the &lt;strong&gt;FLASH_KEYR&lt;/strong&gt; (0x40022004) register. The procedure is described in the Reference Manual in the chapter &lt;em&gt;Flash program and erase operation&lt;/em&gt;, and also in the examples section as a source code snippet. You simply write two values to the same &lt;strong&gt;FLASH_KEYR&lt;/strong&gt; register:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;mww 0x40022004 0x45670123
mww 0x40022004 0xCDEF89AB
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Reassure that the flash is unlocked. Read the &lt;strong&gt;FLASH_CR&lt;/strong&gt;:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;mdw 0x40022010
0x40022010: 00000000 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This means that flash is unlocked, and &lt;strong&gt;LOCK&lt;/strong&gt; is 0 (and all other flags are 0 as well).&lt;/p&gt;

&lt;p&gt;Unlock option bytes for writing (which is described in the reference manual as &lt;em&gt;setting the OPTWRE bit in the FLASH_CR&lt;/em&gt;). The sequence is basically the same as in the previous step, with the only difference that this time we write the magic unlocking values to &lt;strong&gt;FLASH_OPTKEYR&lt;/strong&gt; (0x40022008):&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;mww 0x40022008 0x45670123
mww 0x40022008 0xCDEF89AB
mdw 0x40022010           
0x40022010: 00000200 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now instead &lt;code class=&quot;highlighter-rouge&quot;&gt;00000000&lt;/code&gt; we see &lt;code class=&quot;highlighter-rouge&quot;&gt;00000200&lt;/code&gt; which means that &lt;strong&gt;OPTWRE&lt;/strong&gt; flag is set.&lt;/p&gt;

&lt;h1 id=&quot;clear-the-option-bytes&quot;&gt;Clear the option bytes&lt;/h1&gt;
&lt;p&gt;Clear option bytes (they are stored in the FLASH after all). This is done by first setting &lt;strong&gt;FLASH_CR.OPTER&lt;/strong&gt; (erase), and then &lt;strong&gt;FLASH_CR.STRT&lt;/strong&gt; (start operation). Note that &lt;strong&gt;FLASH_CR.OPTWRE&lt;/strong&gt; must be still set:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;mww 0x40022010 0x00000220
mww 0x40022010 0x00000260
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;All (?) option bytes should now read 0xffffffff.&lt;/p&gt;

&lt;h1 id=&quot;modify-the-option-byte&quot;&gt;Modify the option byte&lt;/h1&gt;
&lt;p&gt;Enable programming by setting &lt;strong&gt;FLASH_CR.OPTPG&lt;/strong&gt;:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;mww 0x40022010 0x00000210
mdw 0x40022010
0x40022010: 00000210
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Store a value (only half-words). In this example, I am modifying the &lt;em&gt;User and read protection option byte&lt;/em&gt; (0x1FFFF800). In particular, I’m setting the &lt;strong&gt;BOOT_SEL&lt;/strong&gt; flag.&lt;/p&gt;

&lt;p&gt;What is described as a &lt;em&gt;User and read protection option byte&lt;/em&gt; is in fact a 32bit word containing the user option byte [23:16] (and its “complement”), and the RDP option byte [7:0] (and its “complement”).&lt;/p&gt;

&lt;p&gt;So wanting to change the &lt;strong&gt;BOOT_SEL&lt;/strong&gt; we calculate, that the proper value of the user option byte [23:16] is 0x7f, and thus its “complement” byte (a negation) should be 0x80.&lt;/p&gt;

&lt;p&gt;Also, I wanted to restore the RDP to its factory value, because it got lost for some reason.&lt;/p&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# Set read protection option byte to 0xaa which denotes level 0 (the default) &lt;/span&gt;
mwh 0x1ffff800 0x55AA
&lt;span class=&quot;c&quot;&gt;# Set BOOT_SEL to 1 to ignore BOOT0 pin. &lt;/span&gt;
mwh 0x1ffff802 0x807f
&lt;span class=&quot;c&quot;&gt;# Verify&lt;/span&gt;
mdw 0x1ffff800
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;</content>

      
      
      
      
      

      

      
        <category term="electronics" />
      

      

      
        <summary type="html">These are instructions that worked for me when faced with a problem of modifying option bytes in stm32f042. The thing I was trying to do was to turn off BOOT0 pin support (PB8 in my chip) which then would eliminate the need to pull it. Then I could use this pin for something else, for example as a CANbus canRx input.</summary>
      

      
      
    </entry>
  
  
  
    <entry>
      
      <title type="html">STM32 on Ubuntu Linux step by step</title>
      
      
      <link href="http://iwasz.pl/electronics/stm32-on-ubuntu-linux-step-by-step/" rel="alternate" type="text/html" title="STM32 on Ubuntu Linux step by step" />
      
      <published>2018-11-06T00:00:00+01:00</published>
      <updated>2018-11-06T00:00:00+01:00</updated>
      <id>http://iwasz.pl/electronics/stm32-on-ubuntu-linux-step-by-step</id>
      <content type="html" xml:base="http://iwasz.pl/electronics/stm32-on-ubuntu-linux-step-by-step/">&lt;p&gt;This is a step by step tutorial on using STM32 (&lt;strong&gt;stm32f407vg&lt;/strong&gt; to be precise) under Linux (Ubuntu 18.10) and other tools (&lt;strong&gt;QtCreator&lt;/strong&gt; and &lt;strong&gt;CMake&lt;/strong&gt;) that I use in my everyday work. In this article we will compile simple LED blinking program and run it on the 
&lt;a href=&quot;https://www.st.com/en/evaluation-tools/stm32f4discovery.html&quot;&gt;STM32F4-DISCOVERY&lt;/a&gt;. There may be easier ways of accomplishing this though. Paragraph titles ending with an asterisk are optional.&lt;/p&gt;

&lt;p&gt;First we will try to prepare a project which compiles simply in a terminal using make or ninja. This is very important for me because nowadays every µC vendor seems to provide its own shitty IDE, and their examples tend to compile only under those IDEs in nonstandard ways. This forces you to install and use stuff that you (or is it only me?) don’t like, not to mention that most of those tools run only under Windows. Then I’ll show you my favorite IDE which happens to be QtCreator, but any other IDE which can cope with CMake build system should do.&lt;/p&gt;

&lt;p&gt;Source code for this article is here : 
&lt;a href=&quot;https://github.com/iwasz/blinky01&quot;&gt;https://github.com/iwasz/blinky01&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt; : do not confuse [Stm32]CubeMX (a desktop configuration tool) and [Stm32]CubeF4 which is a SDK package.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note to myself&lt;/strong&gt; : &lt;em&gt;virtualBox&lt;/em&gt; creates way too small disk images by default. I went with 10GB which proved to be too small after only 1 hour of tweaking. Resizing the VB disk is done via &lt;em&gt;vboxmanage&lt;/em&gt;, reviving dead distro is done as usual by using LiveCD, and then you delete the partition using &lt;em&gt;fdisk&lt;/em&gt;, create new in the place of the old with all options set to defaults, and then you use &lt;em&gt;resize2fs&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note to myself 2&lt;/strong&gt; : install virtual box guest extensions in the guest system for seamless clipboard operation. Install virtualbox-ext-pack in the host system for USB 2.0 forwarding, add yourself to the &lt;em&gt;vboxusers&lt;/em&gt; group, 
&lt;a href=&quot;https://forums.virtualbox.org/viewtopic.php?f=35&amp;amp;t=82639&quot;&gt;read this&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;installing-the-tools&quot;&gt;Installing the tools&lt;/h2&gt;
&lt;h3 id=&quot;stm32cubemx&quot;&gt;Stm32CubeMX&lt;/h3&gt;
&lt;p&gt;Install &lt;a href=&quot;https://ubuntu.com/&quot;&gt;Ubuntu 18.10&lt;/a&gt;. I used VirtualBox running on Ubuntu 18.04 for this.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/VirtualBox_Ubuntu-18-300x194.png&quot; alt=&quot;Fresh install&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Make sure everything is up to date. Run apt update + upgrade, or use GUI Ubuntu provides.&lt;/p&gt;

&lt;p&gt;We are going to use an excellent program &lt;a href=&quot;https://www.st.com/en/development-tools/stm32cubemx.html&quot;&gt;ST provides called STM32CubeMX&lt;/a&gt; which lets us configure pins, clock sources and more. But above all it can generate some startup and config code which we’ll take as a base for our LED blinking application. So lets download it and remember to install Java first. I usually install Oracle’s Java JDK, but JRE of course will do as well (in this case it was &lt;strong&gt;jdk-11.0.1_linux-x64_bin.deb&lt;/strong&gt;). I have no experience with other Java implementations like OpenJDK but I suspect, that it also will work as expected.&lt;/p&gt;

&lt;p&gt;After jdk was installed I added java to the &lt;code class=&quot;highlighter-rouge&quot;&gt;PATH&lt;/code&gt; in ~/.profile : &lt;code class=&quot;highlighter-rouge&quot;&gt;PATH=&quot;/usr/lib/jvm/jdk-11.0.1/bin:$PATH&quot;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Download &lt;a href=&quot;https://www.st.com/en/development-tools/stm32cubemx.html&quot;&gt;Stm32CubeMX&lt;/a&gt; and unpack it (login required unfortunately). Run &lt;code class=&quot;highlighter-rouge&quot;&gt;./SetupSTM32CubeMX-4.27.0.linux&lt;/code&gt; . In my case (fresh Ubuntu) it said :&lt;/p&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;./SetupSTM32CubeMX-4.27.0.linux 
bash: ./SetupSTM32CubeMX-4.27.0.linux: No such file or directory
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;It is a very non-intuitive message, but it is because of 32 bit libraries missing. &lt;a href=&quot;https://blog.teststation.org/ubuntu/2016/05/12/installing-32-bit-software-on-ubuntu-16.04/&quot;&gt;This post tells us what&lt;/a&gt; to do, and to my surprise it discourages from installing ia32-libs which I would normally do:&lt;/p&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;file SetupSTM32CubeMX-4.27.0.linux
SetupSTM32CubeMX-4.27.0.linux: ELF 32-bit LSB executable, Intel 80386, ......
&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;dpkg &lt;span class=&quot;nt&quot;&gt;--add-architecture&lt;/span&gt; i386
&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;apt update
&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;apt-get &lt;span class=&quot;nb&quot;&gt;install &lt;/span&gt;libc6:i386 libstdc++6:i386
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Run the installer and verify, that CubeMX works.&lt;/p&gt;

&lt;h3 id=&quot;qtcreator&quot;&gt;QtCreator*&lt;/h3&gt;

&lt;p&gt;Everyone has his/her favorite IDE, but mine is QtCreator for various reasons which I’m not going to dive into, but Qt libraries are not one of them. I do not use Qt, I simply tried many IDE’s and QtCreator suits me the best. First let’s grab an installer.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://download.qt.io/official_releases/qtcreator/&quot;&gt;https://download.qt.io/official_releases/qtcreator/&lt;/a&gt; - those are the official releases.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://download.qt.io/snapshots/qtcreator/&quot;&gt;https://download.qt.io/snapshots/qtcreator/&lt;/a&gt; - and here are nightly builds.
For this article I picked &lt;a href=&quot;https://download.qt.io/official_releases/qtcreator/4.7/4.7.2/qt-creator-opensource-linux-x86_64-4.7.2.run&quot;&gt;qt-creator-opensource-linux-x86_64-4.7.2.run&lt;/a&gt; and run it in the terminal and that’s it (login required).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;toolchain&quot;&gt;Toolchain&lt;/h3&gt;

&lt;p&gt;The toolchain can be easily installed from Launchpad PPA, or can be compiled using &lt;a href=&quot;https://crosstool-ng.github.io/&quot;&gt;excellent tool called crosstool-ng&lt;/a&gt;. Detailed instructions are in 
&lt;a href=&quot;http://www.iwasz.pl/electronics/toolchain-for-cortex-m4/&quot;&gt;one of my previous posts&lt;/a&gt;. But for now lets use the easier way:&lt;/p&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;add-apt-repository ppa:team-
gcc-arm-
embedded/
ppa
&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;apt-get update
&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;apt &lt;span class=&quot;nb&quot;&gt;install &lt;/span&gt;gcc-arm-none-eabi binutils-arm-none-eabi libnewlib-arm-none-eabi libstdc++-arm-none-eabi-newlib
&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;apt &lt;span class=&quot;nb&quot;&gt;install &lt;/span&gt;cmake ninja
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;other-tools&quot;&gt;Other tools&lt;/h3&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;apt &lt;span class=&quot;nb&quot;&gt;install &lt;/span&gt;mc openocd dos2unix gdb-multiarch
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;the-project&quot;&gt;The project&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;/assets/Screenshot-from-2018-11-02-12-42-39-300x206.png&quot; alt=&quot;CubeMX window&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Run Stm32CubeMX and start a new project. In the “Part Number Search” in the top left corner insert “stm32f407vg”. This is the model of a µC we will be using and which is mounted in the STM32F4-DISCOVERY, a popular evaluation board (you can get it from all major distributors, though 
&lt;a href=&quot;https://www.findchips.com/search/stm32f4-discovery&quot;&gt;findchips.com shows&lt;/a&gt;, that availability is not at its best right now).&lt;/p&gt;

&lt;p&gt;Click on the blue link-like label in the search result table and start the project. The next thing you’ll see is a view of your microcontroller with all the peripherals and GPIOs initialized according to the board’s specs. This is because the board itself contains some neat stuff like accelerometer, digital to analog audio chip with amplifier, and so on. We are focused on PD12 - PD15 which are connected directly to LEDs.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/Screenshot-from-2018-11-05-13-32-46-300x139.png&quot; alt=&quot;CubeMX setup&quot; /&gt;Turn off USB support. It uses some additional files which makes compilation a little bit harder. Make sure that USB_OTG_FS Mode is set to “Disable” in the left pane. Also on the “Configuration” tab make sure, that USB middleware is not used.&lt;/p&gt;

&lt;p&gt;Turn off other unnecessary peripherals like SPI, I2C, USARTs. The more the peripherals, the more source files from SDK we will have to compile, so in my project only SYS, RCC and of course GPIOs are configured. Please check my &lt;a href=&quot;https://github.com/iwasz/blinky01/blob/master/blinky.ioc&quot;&gt;blinky.ioc&lt;/a&gt; in case of trouble or simply experiment with CubeMx’s output.&lt;/p&gt;

&lt;p&gt;Then use “project -&amp;gt; Generate Code” in the main menu to generate the code. When asked about downloading the SDK called StmCubeF4 click YES, and appropriate SDK will be placed in the ~/STM32Cube/Repository. This is important as our code will depend on it (although the SDK can be separately &lt;a href=&quot;https://www.st.com/en/embedded-software/stm32cubef4.html&quot;&gt;downloaded from here&lt;/a&gt;). Here’s what the generated directory structure looks like on my computer:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;./EWARM : 
some stuff for some proprietary IDE i guess.
./blinky.ioc : 
CubeMX project file.
./Middlewares
./Middlewares/ST : 
USB library which won&apos;t be of interest for us since we only want to blink LEDs.

./Drivers : 
Parts of the CubeF4 gets copied here. 
./Drivers/STM32F4xx_HAL_Driver : 
Peripheral library.
./Drivers/CMSIS : 
CMSIS Library is a low level code for interfacing with the CPU.

./Inc 
./Inc/stm32f4xx_it.h : IRQ handlers declarations used by our app. Not particularly useful.
./Inc/stm32f4xx_hal_conf.h : 
low level peripheral configuration based on CubeMX options.
./Inc/main.h : 
another unnecessary file.
./Src
./Src/system_stm32f4xx.c : 
Low level init routines run from the startup code before main.
./Src/stm32f4xx_it.c : 
IRQ handler definitions.
./Src/stm32f4xx_hal_msp.c : 
hi level peripheral configuration based on CubeMX options (GPIOs etc).
./Src/main.c
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;So as you can see pretty verbose output gets produced from CubeMX, but we are interested only in the *.h and *.c files. My favorite directory structure at the other hand looks like this one below (for completeness sake, the directory resides in ~/workspace/blinky but of course dir names are up to you). Create it, and copy generated sources into src directory as so:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;./build : 
Compiled files goes here. Never commit this dir as it&apos;s contents are generated.
./stm32f407xx.cmake : 
The toolchain file, more on it later.
./src : 
Sources generated by the CubeMX. *.h and *.c together, but it&apos;s up to you.
./src/stm32f4xx_it.h
./src/system_stm32f4xx.c
./src/stm32f4xx_hal_conf.h
./src/stm32f4xx_it.c
./src/stm32f4xx_hal_msp.c
./src/main.h
./src/main.c
./CMakeLists.txt : 
The CMake file.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;One can argue whether STM32F4xx_HAL_Driver and CMSIS should be inside our project tree or not. I prefer having all parts of SDK in some external directories simply because copying them into dozens of projects would be a waste and a pollution of the source tree. At the other hand though packaging all the necessary code into our project makes it self contained and easier to compile (no external deps. your choice). For this article I assume that SDK resides in the ~/STM32Cube/Repository/STM32Cube_FW_F4_V1.21.0 (the default for CubeMX). So now you have two files missing : &lt;strong&gt;stm32f407xx.cmake&lt;/strong&gt; and &lt;strong&gt;CMakeLists.txt&lt;/strong&gt;. The latter looks like this:&lt;/p&gt;

&lt;div class=&quot;language-cmake highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;# This variable is used later to set a C/C++ macro which tells CubeF4 which µC to use. ST&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# drivers, and other code is bloated with all sorts of macros, #defines and #ifdefs.&lt;/span&gt;
&lt;span class=&quot;nf&quot;&gt;SET&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;DEVICE &lt;span class=&quot;s2&quot;&gt;&quot;STM32F407xx&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# This is a variable which is later used here and in the CMakeLists.txt. It simply tells&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# where to find the SDK (CubeF4). Please change it accordingly if you have other &lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# version of CubeF4 installed.&lt;/span&gt;
&lt;span class=&quot;nf&quot;&gt;SET&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;CUBE_ROOT &lt;span class=&quot;s2&quot;&gt;&quot;$ENV{HOME}/STM32Cube/Repository/STM32Cube_FW_F4_V1.21.0&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Startup code and linker script - more on it later.&lt;/span&gt;
&lt;span class=&quot;nf&quot;&gt;SET&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;STARTUP_CODE &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CUBE_ROOT&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/Projects/STM32F4-Discovery/Templates/SW4STM32/startup_stm32f407xx.s&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nf&quot;&gt;SET&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;LINKER_SCRIPT &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CUBE_ROOT&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/Projects/STM32F4-Discovery/Templates/SW4STM32/STM32F4-Discovery/STM32F407VGTx_FLASH.ld&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Magic settings. Without it CMake tries to run test programs on the host platform, which&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# fails of course.&lt;/span&gt;
&lt;span class=&quot;nf&quot;&gt;SET&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;CMAKE_SYSTEM_NAME Generic&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nf&quot;&gt;SET&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;CMAKE_SYSTEM_PROCESSOR arm&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# -mcpu tells which CPU to target obviously. -fdata-sections -ffunction-sections Tells GCC to.&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# get rid of unused code in the output binary. -Wall produces verbose warnings.&lt;/span&gt;
&lt;span class=&quot;nf&quot;&gt;SET&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;CMAKE_C_FLAGS &lt;span class=&quot;s2&quot;&gt;&quot;-mcpu=cortex-m4 -std=gnu99 -fdata-sections -ffunction-sections -Wall&quot;&lt;/span&gt; CACHE INTERNAL &lt;span class=&quot;s2&quot;&gt;&quot;c compiler flags&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Flags for g++ are used only when compliing C++ sources (*.cc, *.cpp etc). -std=c++17 Turns&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# on all the C++17 goodies, -fno-rtti -fno-exceptions turns off rtti and exceptions.&lt;/span&gt;
&lt;span class=&quot;nf&quot;&gt;SET&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;CMAKE_CXX_FLAGS &lt;span class=&quot;s2&quot;&gt;&quot;-mcpu=cortex-m4 -std=c++17 -fno-rtti -fno-exceptions -Wall -fdata-sections -ffunction-sections -MD -Wall&quot;&lt;/span&gt; CACHE INTERNAL &lt;span class=&quot;s2&quot;&gt;&quot;cxx compiler flags&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Those flags gets passed into the linker which is run by the GCC at he end of the process..&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# -T tells the linker which LD script to use, -specs=nosys.specs sets the specs which most &lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# notably tells the compiler to use libnosys.a which contains all the syscalls like _sbrk,&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# _exit and much more. They are more like an interface between our program and operating system /&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# bare metal system we are running it on. You can use rdimon.specs instead or write syscalls &lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# yourself which for bare-metal isn&apos;t difficult. --gc-sections strips out unused code from &lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;#binaries I think.&lt;/span&gt;
&lt;span class=&quot;nf&quot;&gt;SET&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;CMAKE_EXE_LINKER_FLAGS &lt;span class=&quot;s2&quot;&gt;&quot;-T &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;LINKER_SCRIPT&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; -specs=nosys.specs -Wl,--gc-sections&quot;&lt;/span&gt; CACHE INTERNAL &lt;span class=&quot;s2&quot;&gt;&quot;exe link flags&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Some directories in the GCC tree.&lt;/span&gt;
&lt;span class=&quot;nf&quot;&gt;INCLUDE_DIRECTORIES&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;SUPPORT_FILES&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nf&quot;&gt;LINK_DIRECTORIES&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;SUPPORT_FILES&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Macro I wrote about in the first line.&lt;/span&gt;
&lt;span class=&quot;nf&quot;&gt;ADD_DEFINITIONS&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;-D&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;DEVICE&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Random include paths for CubeF4 peripheral drivers and CMSIS.&lt;/span&gt;
&lt;span class=&quot;nf&quot;&gt;INCLUDE_DIRECTORIES&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CUBE_ROOT&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/Drivers/STM32F4xx_HAL_Driver/Inc/&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nf&quot;&gt;INCLUDE_DIRECTORIES&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CUBE_ROOT&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/Drivers/CMSIS/Device/ST/STM32F4xx/Include/&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nf&quot;&gt;INCLUDE_DIRECTORIES&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CUBE_ROOT&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/Drivers/CMSIS/Include/&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Few more words on the linker script (LD script) and the startup code. I won’t dive into detail to much, but LD script tells the linker how to assemble the final executable from all the object files that were compiled by a compiler. Basically for every &lt;em&gt;.c or *cc file one object (&lt;/em&gt;.o or *.obj) file gets created (you can find them later inside build/CMakeFiles dir), and every of them is full of symbols stored in the “input” sections. LD script tells the linker what input symbols from which input sections should be copied into the “output” sections in the final executable (and much more; LD scripts are powerful).&lt;/p&gt;

&lt;p&gt;Cortex-M4 CPU after powering up looks at memory address 0 which tells it where the stack starts. Then at the address 0x0000’0004 it checks where the reset IRQ routine is and runs it. Reset IRQ is the first of the many IRQ handlers which addresses reside in the IRQ vector defined in the startup (assembly file). Reset IRQ is called Reset_Handler in ST’s assembly startup code and does a few simple things:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Copies the &lt;strong&gt;.data&lt;/strong&gt; section from flash to RAM. .data section contains global initialized variables.&lt;/li&gt;
  &lt;li&gt;Clears the &lt;strong&gt;.bss&lt;/strong&gt; RAM section which contains uninitialized static variables.&lt;/li&gt;
  &lt;li&gt;Calls &lt;strong&gt;SystemInit&lt;/strong&gt; which I mentioned previously (basic stuff like external memory controller maybe?)&lt;/li&gt;
  &lt;li&gt;Calls &lt;strong&gt;__libc_init_array&lt;/strong&gt; which among other things that I’m unaware of calls C++ constructors.&lt;/li&gt;
  &lt;li&gt;Calls the &lt;strong&gt;main&lt;/strong&gt; function.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Writing startup code and LD script is not trivial (although startup code can be written in C), so thankfully ST provided us with their own implementations which we can use. &lt;a href=&quot;https://jacobmossberg.se/posts/2018/08/11/run-c-program-bare-metal-on-arm-cortex-m3.html&quot;&gt;There is an excellent article on the subject for those who are interested&lt;/a&gt;. Go to the &lt;code class=&quot;highlighter-rouge&quot;&gt;~/STM32Cube/Repository/STM32Cube_FW_F4_V1.21.0&lt;/code&gt; and issue a find :&lt;/p&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;find ~/STM32Cube/Repository/STM32Cube_FW_F4_V1.21.0/ &lt;span class=&quot;nt&quot;&gt;-name&lt;/span&gt; startup_stm32f407xx.s /home/iwasz/STM32Cube/Repository/STM32Cube_FW_F4_V1.21.0/Projects/STM32F4-Discovery/Templates/SW4STM32/startup_stm32f407xx.s
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;There’s a lots of hits because the CubeF4 SDK is made so it can be used with all of STM evaluation boards which there are tons of. This file which we found though, seems to be prepared for our board (Stm32F4-DISCOVERY or sometimes Stm32F4-DISCO for short). Secondly, they provide projects for 3 or 4 major (in their opinion) IDEs. Files prepared for TrueStudio and SW4STM32 are the way to go as those are GCC based apparently (never used them).&lt;/p&gt;

&lt;p&gt;For finding the LD script issue:&lt;/p&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;find ~/STM32Cube/Repository/STM32Cube_FW_F4_V1.21.0/ &lt;span class=&quot;nt&quot;&gt;-name&lt;/span&gt; STM32F407&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;.ld /home/iwasz/STM32Cube/Repository/STM32Cube_FW_F4_V1.21.0/Projects/STM32F4-Discovery/Templates/SW4STM32/STM32F4-Discovery/STM32F407VGTx_FLASH.ld
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Modify  &lt;strong&gt;stm32f407xx.cmake&lt;/strong&gt; according to your findings (STARTUP_CODE and LINKER_SCRIPT variables) though if you followed my instructions directly, you should be fine without modifications.&lt;/p&gt;

&lt;p&gt;Next the CMakeLists.txt file. This is like Makefile but on the higher level of abstraction. Mine looks like this:&lt;/p&gt;

&lt;div class=&quot;language-cmake highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nf&quot;&gt;CMAKE_MINIMUM_REQUIRED&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;VERSION 2.8&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;nf&quot;&gt;PROJECT&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;blinky&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Startup code is written by ST in assembly, so without this statement there are errors.&lt;/span&gt;
&lt;span class=&quot;nf&quot;&gt;ENABLE_LANGUAGE&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;ASM-ATT&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;nf&quot;&gt;INCLUDE_DIRECTORIES&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;src/&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Resonator used in this project. Stm32F4-DISCO uses 8MHz crystal. I left this definition here&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# in the CMakeLists.txt rather than the toolchain file, because it&apos;s project dependent, not&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# &quot;platform&quot; dependent, where by platform I mean STM32F4.&lt;/span&gt;
&lt;span class=&quot;nf&quot;&gt;ADD_DEFINITIONS&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;-DHSE_VALUE=8000000&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# All the sources goes here. Adding headers isn&apos;t obligatory, but since QtCreator treats CMakeLists.txt as&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# its &quot;project configuration&quot; it simply makes header files appear in the source tree pane.&lt;/span&gt;
&lt;span class=&quot;nf&quot;&gt;ADD_EXECUTABLE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CMAKE_PROJECT_NAME&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;.elf
 &lt;span class=&quot;s2&quot;&gt;&quot;src/main.c&quot;&lt;/span&gt;
 &lt;span class=&quot;s2&quot;&gt;&quot;src/main.h&quot;&lt;/span&gt;
 &lt;span class=&quot;s2&quot;&gt;&quot;src/stm32f4xx_hal_conf.h&quot;&lt;/span&gt;
 &lt;span class=&quot;s2&quot;&gt;&quot;src/stm32f4xx_hal_msp.c&quot;&lt;/span&gt;
 &lt;span class=&quot;s2&quot;&gt;&quot;src/stm32f4xx_it.c&quot;&lt;/span&gt;
 &lt;span class=&quot;s2&quot;&gt;&quot;src/stm32f4xx_it.h&quot;&lt;/span&gt;
 &lt;span class=&quot;s2&quot;&gt;&quot;src/system_stm32f4xx&quot;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Workaround : splitting C and C++ code helps QtCreator parse header files correctly. Without it, QtCreator&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# sometimes treats C++ as C and vice versa. EDIT : this comment was written when in the ADD_EXECUTABLE C++&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# files were present.&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;add_library&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;stm&quot;&lt;/span&gt; STATIC
 &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CUBE_ROOT&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal.c&quot;&lt;/span&gt;
 &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CUBE_ROOT&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_cortex.c&quot;&lt;/span&gt;
 &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CUBE_ROOT&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_gpio.c&quot;&lt;/span&gt;
 &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CUBE_ROOT&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc.c&quot;&lt;/span&gt;
 &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CUBE_ROOT&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_gpio.c&quot;&lt;/span&gt;
 &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CUBE_ROOT&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_rcc.c&quot;&lt;/span&gt;
 &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CUBE_ROOT&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_utils.c&quot;&lt;/span&gt;
 &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CUBE_ROOT&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_cortex.h&quot;&lt;/span&gt;
 &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CUBE_ROOT&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_gpio_ex.h&quot;&lt;/span&gt;
 &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CUBE_ROOT&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_gpio.h&quot;&lt;/span&gt;
 &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CUBE_ROOT&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal.h&quot;&lt;/span&gt;
 &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CUBE_ROOT&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_rcc_ex.h&quot;&lt;/span&gt;
 &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CUBE_ROOT&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_rcc.h&quot;&lt;/span&gt;
 &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CUBE_ROOT&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_cortex.h&quot;&lt;/span&gt;
 &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CUBE_ROOT&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_gpio.h&quot;&lt;/span&gt;
 &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CUBE_ROOT&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_rcc.h&quot;&lt;/span&gt;
 &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CUBE_ROOT&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_system.h&quot;&lt;/span&gt;
 &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;STARTUP_CODE&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# This links both pieces together.&lt;/span&gt;
&lt;span class=&quot;nf&quot;&gt;TARGET_LINK_LIBRARIES&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CMAKE_PROJECT_NAME&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;.elf -Wl,--whole-archive stm -Wl,--no-whole-archive&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;nf&quot;&gt;FIND_PROGRAM&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;OPENOCD openocd&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nf&quot;&gt;ADD_CUSTOM_TARGET&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;upload&quot;&lt;/span&gt; DEPENDS &lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CMAKE_PROJECT_NAME&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;.elf COMMAND &lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;OPENOCD&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt; -f /usr/share/openocd/scripts/interface/stlink-v2.cfg -f /usr/share/openocd/scripts/target/stm32f4x.cfg -c &apos;program &lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CMAKE_PROJECT_NAME&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;.elf verify reset exit&apos;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;OK now that we are set, let`s create a build directory if it doesn’t exist yet, and build our project:&lt;/p&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;pwd&lt;/span&gt;
/home/iwasz/workspace/blinky
&lt;span class=&quot;nb&quot;&gt;mkdir &lt;/span&gt;build
&lt;span class=&quot;nb&quot;&gt;cd &lt;/span&gt;build
cmake &lt;span class=&quot;nt&quot;&gt;-DCMAKE_CXX_COMPILER&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;arm-none-eabi-g++ &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;-DCMAKE_C_COMPILER&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;arm-none-eabi-gcc &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;-DCMAKE_TOOLCHAIN_FILE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;../stm32f407xx.cmake &lt;span class=&quot;nt&quot;&gt;-GNinja&lt;/span&gt; ..
ninja
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;If all went well, blinky.elf should appear in the build directory. Ninja isn’t mandatory (but its faster, more modern and jazzy), so if you omit &lt;strong&gt;-GNinja&lt;/strong&gt; part, you will be left with classic Makefile and you would issue make instead of ninja at the end.&lt;/p&gt;

&lt;p&gt;Feel free to post a comment in case of any trouble, we will sort it out.&lt;/p&gt;

&lt;h2 id=&quot;uploading&quot;&gt;Uploading&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;/assets/blinky.gif&quot; alt=&quot;Stm32-disco blinking&quot; /&gt;&lt;/p&gt;

&lt;p&gt;I don’t know why but, most of the Internet and books says “downloading” to describe the process of transmitting a binary firmware from host (PC) to the target (µC). I find it very confusing, because when a file is moved from a PC to some remote server, everybody calls it “uploading” not “downloading”.&lt;/p&gt;

&lt;p&gt;Let’s modify our generated code, so it actually blinks. Locate the main loop in the main.c file (it will be empty), and place this inside, and recompile (simply issue ninja or make inside the build dir):&lt;/p&gt;

&lt;div class=&quot;language-cpp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;HAL_GPIO_WritePin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GPIOD&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;LD4_Pin&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;LD3_Pin&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;LD5_Pin&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;LD6_Pin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;GPIO_PIN_RESET&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;HAL_Delay&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;500&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;HAL_GPIO_WritePin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GPIOD&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;LD4_Pin&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;LD3_Pin&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;LD5_Pin&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;LD6_Pin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;GPIO_PIN_SET&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;HAL_Delay&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;500&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;In the “other tools” section we installed &lt;code class=&quot;highlighter-rouge&quot;&gt;openocd&lt;/code&gt;, so lets use it now. Connect the STM32F4-DISCO, make sure that ST-LINK and JP1 jumpers are closed (the default), and :&lt;/p&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;cd &lt;/span&gt;build
ninja
openocd &lt;span class=&quot;nt&quot;&gt;-f&lt;/span&gt; /usr/share/openocd/scripts/interface/stlink-v2.cfg &lt;span class=&quot;nt&quot;&gt;-f&lt;/span&gt; /usr/share/openocd/scripts/target/stm32f4x.cfg &lt;span class=&quot;nt&quot;&gt;-c&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;program blinky.elf verify reset exit&apos;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;If everything went OK, you should see like a two dozens of messages like :&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;adapter speed: 8000 kHz
** Programming Started **
auto erase enabled
Info : device id = 0x10016413
Info : flash size = 1024kbytes
[...]
** Programming Finished **
** Verify Started **
[...]
verified 7992 bytes in 0.104675s (74.561 KiB/s)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Let me know in case of any problems, we can work it out probably. Remember that I managed to flash the thing under Ubuntu 18.10 running inside Ubuntu 18.04, so it cannot be that difficult :D. Another way of flashing STM32s under Linux is by using 
&lt;a href=&quot;https://github.com/texane/stlink&quot;&gt;Texane’s st-link&lt;/a&gt;, but I found openocd to be more reliable and universal.&lt;/p&gt;

&lt;p&gt;Oh, and I added an “upload” target in the CMakeLists.txt, so you can simply do “ninja upload” instead of running openocd manually.&lt;/p&gt;

&lt;h2 id=&quot;the-qtcreator-ide&quot;&gt;The QtCreator IDE*&lt;/h2&gt;

&lt;p&gt;Now that our project compiles and runs in a console we can integrate it with QtCreator (or other IDE). Run it, and open &lt;strong&gt;Help -&amp;gt; About plugins&lt;/strong&gt;. Make sure, that BareMetal (experimental) plugin is active and restart the IDE when asked.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/plugins-qtcreator-300x202.png&quot; alt=&quot;Installed plugins in QtCreator&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Now open &lt;strong&gt;Tools -&amp;gt; Options&lt;/strong&gt; from the main menu.&lt;/p&gt;

&lt;p&gt;In the &lt;strong&gt;Devices&lt;/strong&gt; section go to &lt;strong&gt;Bare Metal&lt;/strong&gt; tab and &lt;strong&gt;Add&lt;/strong&gt; OpenOCD GDB server provider. Defaults are OK, don’t change anything.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/bare-metal-gdb-provider-300x187.png&quot; alt=&quot;Openocd config&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Apply changes and move to the &lt;strong&gt;Devices&lt;/strong&gt; tab. Add new &lt;strong&gt;Bare Metal Device&lt;/strong&gt;, name it accordingly (I named it Stm32F4) and pick OpenOCD GDB Server provider we created in the previous step.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/Screenshot-from-2018-11-05-23-38-54-300x187.png&quot; alt=&quot;Devices popup&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Go to &lt;strong&gt;Kits&lt;/strong&gt; section, &lt;strong&gt;Compilers&lt;/strong&gt; tab, and make sure GCC for ARM 32 got auto-detected. If it weren’t (because you installed some other GCC based toolchain in some non-standard place) add it there using the &lt;strong&gt;Add&lt;/strong&gt; button.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/Screenshot-from-2018-11-05-23-41-52-300x206.png&quot; alt=&quot;Kits popup&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Go to the &lt;strong&gt;Debuggers&lt;/strong&gt; tab and add &lt;code class=&quot;highlighter-rouge&quot;&gt;gdb-multiarch&lt;/code&gt; which we installed previously like so (remember to Apply after each modification):&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/Screenshot-from-2018-11-05-23-55-55-300x206.png&quot; alt=&quot;Kits popup again&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Finally go to the &lt;strong&gt;Kits&lt;/strong&gt; tab and add new. Pick a name (you can even add an icon), change &lt;strong&gt;Device type&lt;/strong&gt; to Bare Metal Device, and pick proper one in the combo below it. In the &lt;strong&gt;Compiler&lt;/strong&gt; combos pick the ones we created / found in the Compilers tab, and do the same with the &lt;strong&gt;Debugger&lt;/strong&gt; combo.&lt;/p&gt;

&lt;p&gt;Change &lt;strong&gt;CMake Configuration&lt;/strong&gt; (last row) so it looks like this (those are the options we passed to the CMake using -D flag):&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/Screenshot-from-2018-11-06-00-12-57-300x106.png&quot; alt=&quot;CMake config window&quot; /&gt;&lt;/p&gt;

&lt;p&gt;After all this effort you should be left with a new kit looking like that:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/Screenshot-from-2018-11-06-00-02-25-300x229.png&quot; alt=&quot;Finished kit setup&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Now we can open our project. Delete old build directory to be sure old config doesn’t break anything and open the project by selecting CMakeLists.txt. If you don’t delete our old build directory created by hand in previous paragraphs, new “temporary” kit gets created and it can be used after some modifications, but we already have better one.&lt;/p&gt;

&lt;p&gt;You will be presented with &lt;strong&gt;Configure Project&lt;/strong&gt; window where you can pick a kit to be used. Uncheck the &lt;strong&gt;Desktop&lt;/strong&gt; kit, and check our &lt;strong&gt;Stm32F4&lt;/strong&gt; one:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/Screenshot-from-2018-11-06-00-56-24-300x175.png&quot; alt=&quot;Configure project tab&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Click &lt;strong&gt;Configure&lt;/strong&gt; project and hit Ctrl-B to verify that everything compiles.&lt;/p&gt;

&lt;h2 id=&quot;debugging-in-qtcreator&quot;&gt;Debugging in QtCreator*&lt;/h2&gt;

&lt;p&gt;It’s simple. Open a terminal, and run openocd like so:&lt;/p&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;openocd &lt;span class=&quot;nt&quot;&gt;-f&lt;/span&gt; /usr/share/openocd/scripts/interface/stlink-v2.cfg &lt;span class=&quot;nt&quot;&gt;-f&lt;/span&gt; /usr/share/openocd/scripts/target/stm32f4x.cfg
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This way GDB remote protocol server is started (not sure about the name), and “normal” GDB can communicate with it. Switch to QtCreator, hit &lt;strong&gt;F5&lt;/strong&gt; and that’s it! Hit &lt;strong&gt;Shift-F5&lt;/strong&gt; to pause program, and you will be presented with a call stack, variables, and so On. &lt;strong&gt;F10&lt;/strong&gt; is for stepping over, &lt;strong&gt;F11&lt;/strong&gt; for stepping into, and &lt;strong&gt;Shift-F11&lt;/strong&gt; for stepping out. Happy debugging.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/Screenshot-from-2018-11-06-01-26-00-300x179.png&quot; alt=&quot;Debugging in QtCreator&quot; /&gt;&lt;/p&gt;</content>

      
      
      
      
      

      

      
        <category term="electronics" />
      

      

      
        <summary type="html">This is a step by step tutorial on using STM32 (stm32f407vg to be precise) under Linux (Ubuntu 18.10) and other tools (QtCreator and CMake) that I use in my everyday work. In this article we will compile simple LED blinking program and run it on the STM32F4-DISCOVERY. There may be easier ways of accomplishing this though. Paragraph titles ending with an asterisk are optional.</summary>
      

      
      
    </entry>
  
  
  
    <entry>
      
      <title type="html">BlueNRG-2-Android. Source code troubleshooting, bonding, and privacy</title>
      
      
      <link href="http://iwasz.pl/electronics/bluenrg-2-android-source-code-troubleshooting-bonding-and-privacy/" rel="alternate" type="text/html" title="BlueNRG-2-Android. Source code troubleshooting, bonding, and privacy" />
      
      <published>2018-08-01T00:00:00+02:00</published>
      <updated>2018-08-01T00:00:00+02:00</updated>
      <id>http://iwasz.pl/electronics/bluenrg-android</id>
      <content type="html" xml:base="http://iwasz.pl/electronics/bluenrg-2-android-source-code-troubleshooting-bonding-and-privacy/">&lt;p&gt;The objective of the firmware presented in this article is to provide an example which would implement the following functionality:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;After resetting the BlueNRG-2 (called the “device” or simply BlueNRG later on) it would make itself general discoverable and accept a connection from whatever connects first.&lt;/li&gt;
  &lt;li&gt;It would bond with this first connecting thing (called the “cellphone” later on) and allow it to connect and modify GATT characteristics exclusively.&lt;/li&gt;
  &lt;li&gt;No other central device (cellphone) would be allowed to modify device’s characteristics (or even connect).&lt;/li&gt;
  &lt;li&gt;This BlueNRG device would work with modern iOS and Android phones (it’s 2018 when I’m writing this).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;My starting point was an example from 
&lt;a href=&quot;https://www.st.com/content/st_com/en/products/embedded-software/evaluation-tool-software/stsw-bluenrg1-dk.html&quot;&gt;STSW-BLUENRG1-DK&lt;/a&gt; version 3.0.0 named &lt;code class=&quot;highlighter-rouge&quot;&gt;BLE_Security&lt;/code&gt; which resides in 
&lt;code class=&quot;highlighter-rouge&quot;&gt;BlueNRG-1_2-DK-3.0.0/Project/BLE_Examples/BLE_Security/src/peripheral&lt;/code&gt; directory. This package comes as an executable if I remember correctly, but most of the ST’s execs run under wine (wine-3.6 (Ubuntu 3.6-1), Ubuntu version 18.04). So just after incorporating the example source code into my project, I was able to pair, bond, connect and read characteristics on the BlueNRG-2 using 
&lt;a href=&quot;https://play.google.com/store/apps/details?id=no.nordicsemi.android.mcp&quot;&gt;nRF connect app&lt;/a&gt; running on Android 8 on Huawei Honor 9. The problem arisen though, when I tried to disconnect, and then connect again. In such case, I would always get “GATT ERROR 0x85” in the nRF connect logs, and the only way to connect to the BlueNRG again was to reset it (it clears its security database, removing all bond information) and to remove bond information from the cellphone. After some time 
&lt;a href=&quot;https://community.st.com/s/question/0D50X00009ZE6BiSAL/bluenrg-1-security-example-not-working&quot;&gt;I posted a question on my ST forum&lt;/a&gt;, but not getting the answer I slowly figured out, that  there is a problem with whitelist because when I turned “undirected connectable” without whitelist, everything worked OK. Let me explain. In the file 
&lt;code class=&quot;highlighter-rouge&quot;&gt;BlueNRG-1_2-DK-3.0.0/Project/BLE_Examples/BLE_Security/src/peripheral/BLE_Security_Peripheral.c&lt;/code&gt; there is &lt;code class=&quot;highlighter-rouge&quot;&gt;Make_Connection&lt;/code&gt; function which at first turn general discoverable :&lt;/p&gt;

&lt;div class=&quot;language-cpp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;ret&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;aci_gap_set_discoverable&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ADV_IND&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x200&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PUBLIC_ADDR&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;filter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;sizeof&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;local_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;local_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;with filter ==NO_WHITE_LIST_USE and after bonding it turns undirected connectable like this :&lt;/p&gt;

&lt;div class=&quot;language-cpp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;ret&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;aci_gap_set_undirected_connectable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x200&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PUBLIC_ADDR&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;filter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;with &lt;code class=&quot;highlighter-rouge&quot;&gt;filter == WHITE_LIST_FOR_ALL&lt;/code&gt;. The way I see this problem is, that modern 
&lt;a href=&quot;http://www.summitdata.com/blog/overview-addressing-privacy-lairds-ble-modules/&quot;&gt;cellphones use random private resolvable addresses&lt;/a&gt; which can change anytime, so it may happen that the address BlueNRG has on its whitelist is out of date. The solution is to turn on the controller privacy (introduced in so-called link-layer privacy 1.2 in BLE 4.2) which would resolve addresses in the link-layer tier thus allowing whitelisting. There are more reliable sources on the topic, but the way I understand it is that [I may be wrong here] on the 3rd stage of bonding peripheral and central exchange IRKs between each other (along with other information) and thus the peer device identity is stored in the BlueNRG. This peer device identity consists of peer’s device identity address (the “real” address which can be public or static random), the local IRK and peer’s IRK. This information is then passed to the controller letting it to resolve random private resolvable addresses from the peer (cellphone) or to “randomize / hide” its own address. [/I may be wrong here]&lt;/p&gt;

&lt;p&gt;To turn the controller privacy on I modified 
&lt;code class=&quot;highlighter-rouge&quot;&gt;aci_gap_init&lt;/code&gt; as so:&lt;/p&gt;

&lt;div class=&quot;language-cpp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;ret&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;aci_gap_init&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GAP_PERIPHERAL_ROLE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x02&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;sizeof&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;deviceName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;service_handle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dev_name_char_handle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;appearance_char_handle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;but it retured error BLE_STATUS_INVALID_PARAMS. The same goes if I wanted to turn “LE secure connections” instead of “legacy pairing” where I got BLE_ERROR_UNSUPPORTED_FEATURE.It turned out that I needed to modify &lt;code class=&quot;highlighter-rouge&quot;&gt;stack_user_cfg.h&lt;/code&gt; and turn appropriate options on :&lt;/p&gt;

&lt;div class=&quot;language-cpp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cp&quot;&gt;#define CONTROLLER_PRIVACY_ENABLED (1U)
#define SECURE_CONNECTIONS_ENABLED (1U)
#define CONTROLLER_MASTER_ENABLED (0U)
#define CONTROLLER_DATA_LENGTH_EXTENSION_ENABLED (0U)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;In addition I added &lt;code class=&quot;highlighter-rouge&quot;&gt;stack_user_cfg.c&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;libcrypto.a&lt;/code&gt; to the source base, and was able to go past the aci_gap_init call. Next I wanted to turn on the 
&lt;a href=&quot;http://blog.bluetooth.com/bluetooth-pairing-part-4&quot;&gt;“LE secure connections” which where introduced in BLE 4.2&lt;/a&gt;. This is some fancy option which modifies the way the bonding process goes and introduces even more security, yay. I did:&lt;/p&gt;

&lt;div class=&quot;language-cpp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;ret&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;aci_gap_set_authentication_requirement&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;BONDING&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MITM_PROTECTION_NOT_REQUIRED&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SC_IS_SUPPORTED&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;KEYPRESS_IS_NOT_SUPPORTED&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;USE_FIXED_PIN_FOR_PAIRING&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;123456&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;STATIC_RANDOM_ADDR&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;and got &lt;code class=&quot;highlighter-rouge&quot;&gt;BLE_STATUS_OUT_OF_MEMORY&lt;/code&gt; (0x48) when adding first (and only) custom GATT service. Turns out, that when SC is supported, there is another characteristic added to the Genaral Access service called 
&lt;a href=&quot;https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.characteristic.gap.central_address_resolution.xml&quot;&gt;Central Address Resolution characteristic&lt;/a&gt;. So I needed to fire the &lt;code class=&quot;highlighter-rouge&quot;&gt;BLUENRG1_Wizard.exe&lt;/code&gt; and generate new header file with “privacy - controller” option turned on. This way ATT attributes number was increased by 1 and the out of memory error went away.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/bluenrg-wizard-privacy-300x253.png&quot; alt=&quot;BlueNRG radio parameters wizard&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Next problem was that &lt;code class=&quot;highlighter-rouge&quot;&gt;aci_gap_set_discoverable&lt;/code&gt; started to return 
&lt;code class=&quot;highlighter-rouge&quot;&gt;BLE_STATUS_INVALID_PARAMS&lt;/code&gt; (0x42). It turns out, that when host or controller privacy is turned on, 
&lt;code class=&quot;highlighter-rouge&quot;&gt;Own_Address_Type&lt;/code&gt; parameter can be only 
&lt;code class=&quot;highlighter-rouge&quot;&gt;RESOLVABLE_PRIVATE_ADDR&lt;/code&gt; or 
&lt;code class=&quot;highlighter-rouge&quot;&gt;NON_RESOLVABLE_PRIVATE_ADDR&lt;/code&gt;, and conversely when privacy is off, 
&lt;code class=&quot;highlighter-rouge&quot;&gt;Own_Address_Type&lt;/code&gt; can be only 
&lt;code class=&quot;highlighter-rouge&quot;&gt;PUBLIC_ADDR&lt;/code&gt; or 
&lt;code class=&quot;highlighter-rouge&quot;&gt;STATIC_RANDOM_ADDR&lt;/code&gt;. So this way if you want the BlueNRG to resolve private resolvable addresses from the peer, you are also forced to use them on the NRG as well.&lt;/p&gt;

&lt;p&gt;This way I was able to run the firmware without any errors, but my cellphone was unable to detect the device 99% of the time. It would occasionally detect it, but on very rare occasions. The problem was solved after… replacing 16MHz High-speed oscillator crystal with 32MHz one. I really do not know where this bug/feature is documented, because I was able to found it only in the 
&lt;code class=&quot;highlighter-rouge&quot;&gt;Privacy_1_2_Slave_WhiteList.py&lt;/code&gt; script of 
&lt;a href=&quot;https://www.st.com/en/embedded-software/stsw-bnrgui.html&quot;&gt;the BlueNRG GUI application&lt;/a&gt;. After replacing the crystal, I made a change so 
&lt;code class=&quot;highlighter-rouge&quot;&gt;HS_SPEED_XTAL&lt;/code&gt; macro would preprocess to 1 and 
&lt;code class=&quot;highlighter-rouge&quot;&gt;SYSCLK_FREQ&lt;/code&gt; to 32000000.&lt;/p&gt;

&lt;p&gt;And the last problem I had, which took me almost 2 days to fix was caused by (I think) improper capabilities setup:&lt;/p&gt;

&lt;div class=&quot;language-cpp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;ret&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;aci_gap_set_io_capability&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IO_CAP_NO_INPUT_NO_OUTPUT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;ret&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;aci_gap_set_authentication_requirement&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;BONDING&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MITM_PROTECTION_NOT_REQUIRED&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SC_IS_SUPPORTED&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;KEYPRESS_IS_NOT_SUPPORTED&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;USE_FIXED_PIN_FOR_PAIRING&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;123456&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
&lt;span class=&quot;n&quot;&gt;STATIC_RANDOM_ADDR&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;I wanted to bond using the “Just-Works” scheme, but this particular set of calls above made pairing process behave very oddly. I was able to scan for my device (still using nRF connect), and to bond (… -&amp;gt; bond), but it would not appear on the “bonded” list as it usually happened:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/nrf-connect-bonding-peculiar-300x267.jpg&quot; alt=&quot;Nrf connect and bonding peculiarity&quot; /&gt;&lt;/p&gt;

&lt;p&gt;And although I could connect to such oddly bonded device and even reconnect to id multiple times, what I could not achieve was to reconnect after devices disconnected by themselves due to signal loss (i.e. when a cellphone was carried away). In such case, when I brought my cellphone back and turned scanning on, my BlueNRG device would reappear in the “Scanned” list but with different address! Trying to connect to it would return GAT ERROR 0x3d in the nRF logs which means &lt;code class=&quot;highlighter-rouge&quot;&gt;BLE_ERROR_CONNECTION_END_WITH_MIC_FAILURE&lt;/code&gt; (MIC is some little chunk of bytes added to the payload when privacy is turned on if I remember correctly). To fix this I had to do two things:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;replace &lt;code class=&quot;highlighter-rouge&quot;&gt;IO_CAP_NO_INPUT_NO_OUTPUT&lt;/code&gt; with &lt;code class=&quot;highlighter-rouge&quot;&gt;IO_CAP_DISPLAY_ONLY&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;reset the phone and find out, that “Bonding” list in the nRF connect was all of a sudden populated with ten or so instances of my BlueNRG device made that day during some of the tests.
And then during pairing, I had to enter a PIN (123456), and after that I was able to do whatever I wanted, disconnect, go out of range, reconnect turn Bluetooth off and on, reset the phone and so on. All worked pretty fine.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Remarks / TODOs:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;My peripheral’s (BlueNRG) name isn’t shown int the “Scanned” list in nRF connect, and I don’t know how to fix this.&lt;/li&gt;
  &lt;li&gt;I don’t know how to enable “Just Works” scheme.&lt;/li&gt;
  &lt;li&gt;Linux (Ubuntu 18.04) uses static random addresses, so the whole address resolving and privacy thing is not a problem.&lt;/li&gt;
&lt;/ul&gt;</content>

      
      
      
      
      

      

      
        <category term="electronics" />
      

      

      
        <summary type="html">The objective of the firmware presented in this article is to provide an example which would implement the following functionality:</summary>
      

      
      
    </entry>
  
  
  
    <entry>
      
      <title type="html">Self balancing robot improvements</title>
      
      
      <link href="http://iwasz.pl/uncategorized/self-balancing-robot-improvements/" rel="alternate" type="text/html" title="Self balancing robot improvements" />
      
      <published>2018-01-16T00:00:00+01:00</published>
      <updated>2018-01-16T00:00:00+01:00</updated>
      <id>http://iwasz.pl/uncategorized/self-balancing-robot-improvements</id>
      <content type="html" xml:base="http://iwasz.pl/uncategorized/self-balancing-robot-improvements/">&lt;p&gt;I was dissatisfied with robot’s performance, so I experimented a lot with various aspects to improve it. But along the way, the robot, however simple in concept, proved to be a pretty complex system which depends on many factors that I didn’t anticipate. This variety of factors which altogether influence its movements make it very difficult to troubleshoot problems. So, now I’ll try to recall my adventures with it in order. Oh, and my objective (best case scenario) is to make it stable to the point it stands completely still. This is what I found the most difficult.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://www.youtube.com/watch?v=M3uyGxLnFOw&quot;&gt;&lt;img src=&quot;https://img.youtube.com/vi/M3uyGxLnFOw/0.jpg&quot; alt=&quot;Ballancing robot ballances&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3 id=&quot;better-motors&quot;&gt;Better motors&lt;/h3&gt;

&lt;p&gt;&lt;img src=&quot;/assets/IMG_20180107_163408-e1516133185673-169x300.jpg&quot; alt=&quot;Better motors picture&quot; /&gt;&lt;/p&gt;

&lt;p&gt;I decided, my first set of motors (Dagu DG02S 48:1) have too low torque on low RPM (driven from DRV8835 H-Bridge again with PWM). The robot was able to stand, but wiggled (video in the previous post). So I changed them to JK28HS32 stepper motors, which proved to be even weaker. They simply have too low torque in all RPM range for the weight of my robot. More disadvantages:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Draws tons of current even when robot is stationary. This is because un-geared steppers (at least small ones) spin freely when unpowered and thus need current which hold them in position.&lt;/li&gt;
  &lt;li&gt;More complex electronics (1 H-bridge per motor instead of 1/2 per brushed one), and much more complex programming.&lt;/li&gt;
  &lt;li&gt;Intense vibration even in half stepping mode. And I used 200step ones. The solution for that would be to use smaller wheels with soft tires or implement micro stepping which would in turn reduce its 
&lt;a href=&quot;https://www.micromo.com/technical-library/stepper-motor-tutorials/microstepping-myths-and-realities&quot;&gt;incremental torque&lt;/a&gt;. Every time I use one of these steppers, and I dig into the subject I realize how difficult a stupid motor might get.
So, not without disappointment I moved to another set of motors which happened to be 
&lt;a href=&quot;https://www.dfrobot.com/index.php?route=product/product&amp;amp;product_id=1364&amp;amp;search=FIT0441&amp;amp;description=true#.VnlABPnhBUR&quot;&gt;Brushless DC Motor with Encoder 12V 159RPM&lt;/a&gt; from DFrobot (I found them on Aliexpress BTW). To my consternation it didn’t help much. Advantages of the newly mounted motors are its high torque, ease of interfacing (they have controller stuffed inside), but cons are:&lt;/li&gt;
  &lt;li&gt;They have quite some backlash.&lt;/li&gt;
  &lt;li&gt;They run on 12V, so I had to rework some of the electronics.&lt;/li&gt;
  &lt;li&gt;They might be a little bit faster, though at the end I was able to stabilize the thing pretty satisfactory.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;/assets/IMG_20180107_173324-300x205.jpg&quot; alt=&quot;Motors ina a chassis&quot; /&gt;&lt;/p&gt;

&lt;p&gt;To sum up : high-quality motors eliminate one point of failure and let you focus on different aspects if something is failing. My ideal motors, that I would like to have are:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Precise in terms of control. Wide range of RPMs i.e. able to spin super slow or quite fast with decent torque in all situations. What is a decant torque? Dunno. 2,4 kg*cm?&lt;/li&gt;
  &lt;li&gt;Fast. I would love to have 300RPM.&lt;/li&gt;
  &lt;li&gt;Minimal backlash.&lt;/li&gt;
  &lt;li&gt;Encoders built-in.&lt;/li&gt;
  &lt;li&gt;Not to mention power efficiency and ease of programming, but this is not the most important thing.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;surface&quot;&gt;Surface&lt;/h3&gt;
&lt;p&gt;So then I finally decided, that I stop there with changing motors, and won’t replace them for the 4th time, but try to tune the PID and fiddle with the software. I replaced my fusion algorithm from simple complementary one to Madgwick, which open-source implementation is 
&lt;a href=&quot;http://x-io.co.uk/open-source-imu-and-ahrs-algorithms/&quot;&gt;available online&lt;/a&gt;, and it is a part of a PhD thesis of some clever guy (Sebastian Madgwick). I cannot stress how far superior this algorithm is over my humble thing. But no luck with that neither. If I increased Kp and Ki it would oscillate vigorously (Kd was of not  much help there), and when I decreased Kp and especially Ki, the robot would always drift away gaining speed and tipping over. Playing with the dreaded thing which would not stand at all, and wiggle as some drunk I recalled, that on many YT videos (
&lt;a href=&quot;https://www.youtube.com/watch?v=-bQdrvSLqpg&quot;&gt;user upgrdman among my favorites on the subject&lt;/a&gt;) people was driving their robots on soft surfaces like carpets and that made me wonder. So I put my robot on a blanket and it helped a little. It reduced both oscillations and the drifting. I have a theory, that firm surface (and/or soft tires) first damps vibrations, but also when a tyre flattens under the weight, it somewhat blocks further movements. Hard tires do not have this effect and on hard surfaces, they spin every time the robot is only slightly out of its balance, where as on soft ones this slight error can be counteracted by a deformed wheel to some very small extent. Think of dry sand on the beach and big soft wheels, I think even when unpowered, the robot could have a chance to stand still in such an environment. So it thought about changing the wheels (and tires) because at that time I used pretty hard wheels from a hardware store (some furniture ones) and I ordered 70mm and 110mm squishy wheels for model aircraft. And then, while waiting for the wheels I made hasty decision to shorten the thing.&lt;/p&gt;

&lt;h3 id=&quot;length&quot;&gt;Length&lt;/h3&gt;
&lt;p&gt;Bear in mind, that I can be completely wrong here! As far as I understand, when you have a normal pendulum, the longer the string is, the faster will be the linear velocity of the pendulum bob. I assumed The same thing will be with inverted pendulum, thus the taller the robot, the bigger velocity of it top-end when tipping over. Thus, I concluded, the faster lower-end movements will be necessary to counteract the moving top. At that time I thought my motors are to slow, so It seemed to be a good idea to shorten the body. So I did that. And the improvement was negligible if at all. Also, from the pendulum frequency equation I knew, that shortening the length increases the pendulum frequency, so I understood that my algorithm must react faster from now on.&lt;/p&gt;

&lt;h3 id=&quot;mechanical-issues&quot;&gt;Mechanical issues&lt;/h3&gt;
&lt;p&gt;Then I realized, that the wheels got loose. I ordered a bunch of adapters and fixed them in place. Still no luck.&lt;/p&gt;

&lt;h3 id=&quot;scratching-head-and-tuning-pid&quot;&gt;Scratching head and tuning PID&lt;/h3&gt;
&lt;p&gt;I couldn’t sleep but visualized my dangling robot. I tried to tune the PID controller a lot. And still, every time I increased Ki it oscillated, and when decreased it drifted away. Too much Ki and it oscillated left and right, and too much Kd and it oscillated but in like one direction. Like hiccup. Derivative term damps output when error decreases, so in theory, the robot should decelerate near sweet point and make a full stop but instead, it would stop for a moment (like millisecond moment), and start in the same direction, then stop and then again, all in sudden sequence.&lt;/p&gt;

&lt;h3 id=&quot;nrf24l01-distraction&quot;&gt;nRF24L01+ distraction&lt;/h3&gt;
&lt;p&gt;I was frustrated and sick and tired, so decided to do something different, as a break from the main subject. I got into nRF24 code and telemetry. I wanted to make full telemetry for the project as YT user &lt;code class=&quot;highlighter-rouge&quot;&gt;upgrdman&lt;/code&gt; did. I thought that it would help me to debug. Then I run into more problems, procrastinated a little bit more with refactoring my SPI library and so on. I had curious adventures with nRF though, but this is completely different story. I use an excellent application 
&lt;a href=&quot;https://kst-plot.kde.org/&quot;&gt;called KST2&lt;/a&gt; for plotting the data. From the plots, I observed that the robot is drifting due to sudden integral peaks. It’s like the robot was balancing for a moment, and then the pitch plot would show a slight shift towards one direction, and just after that the integral part grew, robot started to move and tried to catch up, the &lt;em&gt;i&lt;/em&gt; increased and increased, robot speed up, and then output saturated leading to a crash. The only thing which helped a little was to increase &lt;em&gt;Ki&lt;/em&gt; (it amplified the reaction for integral, so robot drove faster, so was able to catch up and straighten), but it also increased oscillations.&lt;/p&gt;

&lt;h3 id=&quot;main-loop-frequency&quot;&gt;Main loop frequency&lt;/h3&gt;
&lt;p&gt;In the act of desperation, not hoping for a change for better, I increased the main loop frequency from 100Hz to 1kHz. I could do that because I use very fast STM32F4 (compared to Arduinos and Atmegas that everybody seems to love so much) with a fpu. And that was it. It calmed the robot so much, that I could increase Ki to the values not possible before. Then I mounted the 110mm squishy wheels and it helped even more for the reasons described above, and because bigger wheels give more speed. That’s all for now, I’m a little bit tired of this project, but in the future I plan to:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Program encoders.&lt;/li&gt;
  &lt;li&gt;Program remote control (I bought myself a nice Devo 7E transmitter).&lt;/li&gt;
  &lt;li&gt;Experiment with all (or most) of the parameters I talked about. Height vs. loop frequency, various wheels and so on.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;/assets/IMG_20180111_215004-1024x342.jpg&quot; alt=&quot;Wheels galore&quot; /&gt;&lt;/p&gt;</content>

      
      
      
      
      

      

      
        <category term="Uncategorized" />
      

      

      
        <summary type="html">I was dissatisfied with robot’s performance, so I experimented a lot with various aspects to improve it. But along the way, the robot, however simple in concept, proved to be a pretty complex system which depends on many factors that I didn’t anticipate. This variety of factors which altogether influence its movements make it very difficult to troubleshoot problems. So, now I’ll try to recall my adventures with it in order. Oh, and my objective (best case scenario) is to make it stable to the point it stands completely still. This is what I found the most difficult.</summary>
      

      
      
    </entry>
  
  
  
    <entry>
      
      <title type="html">Self balancing robot first tests</title>
      
      
      <link href="http://iwasz.pl/uncategorized/self-balancing-robot-first-tests/" rel="alternate" type="text/html" title="Self balancing robot first tests" />
      
      <published>2017-12-28T00:00:00+01:00</published>
      <updated>2017-12-28T00:00:00+01:00</updated>
      <id>http://iwasz.pl/uncategorized/self-balancing-robot-first-tests</id>
      <content type="html" xml:base="http://iwasz.pl/uncategorized/self-balancing-robot-first-tests/">&lt;p&gt;I have built a self-balancing robot, and here I want to post some notes regarding problems that I encountered. It was (as usual) more difficult than I anticipated, but I guess every hacker know this feeling.&lt;/p&gt;

&lt;h3 id=&quot;frame&quot;&gt;Frame&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;http://www.youtube.com/watch?v=VrV6Haa0kxQ&quot;&gt;&lt;img src=&quot;https://img.youtube.com/vi/VrV6Haa0kxQ/0.jpg&quot; alt=&quot;Ballancing robot ballances&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The frame is made of 8mm aluminium pipes, 2 sheets of 2mm solid transparent polycarbonate, and aluminium angle bars. The pieces are screwed together with threaded rods and self-locking nuts. Making the frame was the easiest part, so I won’t write much about it.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/22424639_1863508117010274_5025855902577973208_o-169x300.jpg&quot; alt=&quot;View from a side&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;motors&quot;&gt;Motors&lt;/h3&gt;

&lt;p&gt;&lt;img src=&quot;/assets/86_P_1388386610626-300x219.jpg&quot; alt=&quot;Motors dagu&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Motors are labeled “Dagu DG02S 48:1”, and I am disappointed, because they have very low torque at low RPM, and are of a low quality I think (their low price also suggests that). The consequences are, that they are unable to move my robot gently and precisely, but instead, they start all of a sudden with a couple of RPMs. At very low PWM duty cycle they are unable to move wheels at all, even with no load. The lowest RPM I can get out of them is probably a couple of RPMs, which sounds OK, but I think, that many of my problems arise from them being unable to gently move the wheels a few millimeters forth and back. 
&lt;strong&gt;Such a gentle movement is in my opinion crucial&lt;/strong&gt;
 for steady (nearly stationary) operation, that you have on certain YouTube videos. So next tests (if there will be any) will be performed with steppers or geared brushless motors. Oh, and there are no encoders either.&lt;/p&gt;

&lt;h3 id=&quot;electronics&quot;&gt;Electronics&lt;/h3&gt;

&lt;p&gt;If motors are the muscles, electronics are the brain. The mainboard is a
&lt;a href=&quot;http://www.st.com/en/evaluation-tools/stm32f4discovery.html&quot;&gt;STM32F4-DISCO&lt;/a&gt; and is connected to the battery via custom per-boards with connectors. On top of the robot, there is a single 
&lt;a href=&quot;https://www.ebay.com/sch/i.html?_from=R40&amp;amp;_trksid=p2322090.m570.l1313.TR0.TRC0.H0.TRS0&amp;amp;_nkw=samsung+icr18650-26f&amp;amp;_sacat=0&quot;&gt;16850 Samsung&lt;/a&gt; cell paired with cheap LiPo charger, and a switch. I chose it because it is a lot cheaper per mAh than those silverish ones. The battery sits inside a holder ordered on AliExpress. As of accelerometer and gyroscope, the super popular MPU 6050 does the job (also AliExpress). Motors are driven by 
&lt;a href=&quot;https://www.pololu.com/product/2135&quot;&gt;Pololu DRV8835&lt;/a&gt;, and last but not least nRF24L01+ is used for connectivity with the robot, which is crucial to tune PID controller without dangling cables which would degrade stability, and make the center of mass unstable. Like shooting to a moving target.&lt;/p&gt;

&lt;p&gt;Oh, and I wanted to control the robot using cheap CX-10 remote, but It failed. I based my code on deviation and other’s work, but after many hours I gave up. Then I’ve got Syma X5HW for Christmas, and with it’s remote I finally had success (after the first try, like 10 minutes of coding, not everyday something like this happens. But of course I only had to modify parameters for my CX-10 code). At first, I confused the binding channel number (I set 0 instead of 8), and I was still able to receive data, but only from approx 5 cm apart. Then after setting it correctly to channel 8 range increased dramatically.&lt;/p&gt;

&lt;h3 id=&quot;programming&quot;&gt;Programming&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/iwasz/self-balancer&quot;&gt;https://github.com/iwasz/self-balancer&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/iwasz/libmicro&quot;&gt;https://github.com/iwasz/libmicro&lt;/a&gt;
With electronics and motors on its place, there comes programming, the most difficult part. First I made peripherals of the robot to work (Arduino library called i2cdevlib was very helpful), so I was able to read raw data from MPU 6050, send basic commands via nRF, and spin the motors. Then, the most challenging part was to implement:&lt;/li&gt;
  &lt;li&gt;pitch angle calculation (
&lt;a href=&quot;http://www.starlino.com/imu_guide.html&quot;&gt;http://www.starlino.com/imu_guide.html&lt;/a&gt;),&lt;/li&gt;
  &lt;li&gt;fusion of gyroscope and accelerometer data (this was helpful : 
&lt;a href=&quot;http://www.pieter-jan.com/node/11&quot;&gt;http://www.pieter-jan.com/node/11&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;PID tuning (though implementing a PID is dead simple, tuning it is completely another story). Most helpful for me in this regard was probably the Wikipedia article on the PID controller. In my case, the most (positive) impact came from the integral part, where the &lt;strong&gt;D&lt;/strong&gt; part seems to have minimal influence.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I’ll try to force myself to get into detail on the topics above, as I only scratched the surface.&lt;/p&gt;</content>

      
      
      
      
      

      

      
        <category term="Uncategorized" />
      

      

      
        <summary type="html">I have built a self-balancing robot, and here I want to post some notes regarding problems that I encountered. It was (as usual) more difficult than I anticipated, but I guess every hacker know this feeling.</summary>
      

      
      
    </entry>
  
  
  
    <entry>
      
      <title type="html">Implementing zoom with moving pivot point using libclutter</title>
      
      
      <link href="http://iwasz.pl/uncategorized/implementing-zoom-with-moving-pivot-point-using-libclutter/" rel="alternate" type="text/html" title="Implementing zoom with moving pivot point using libclutter" />
      
      <published>2017-04-28T00:00:00+02:00</published>
      <updated>2017-04-28T00:00:00+02:00</updated>
      <id>http://iwasz.pl/uncategorized/implementing-zoom-with-moving-pivot-point-using-libclutter</id>
      <content type="html" xml:base="http://iwasz.pl/uncategorized/implementing-zoom-with-moving-pivot-point-using-libclutter/">&lt;p&gt;I’m making this post because I struggled with this functionality a lot! I was implementing it (to the extent I was happy with) in the course of 4 or even 5 days! Ok, first goes an animated gif which shows my desired zoom behavior (check out Inkscape, or other graphics programs, they all work the same in this regard):&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://iwasz.pl/files/zoomok.gif&quot; alt=&quot;Desired zoom functionality&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Basically the idea is that, the center of the scale transformation is where the mouse pointer is on the screen, so the object under the cursor does not move while scaling, whereas other objects around it do. My first, and most obvious implementation (which didn’t work as expected) was as such:&lt;/p&gt;

&lt;div class=&quot;language-cpp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cm&quot;&gt;/*
 * Point center is in screen coordinates. This is a where mouse pointer is on the screen.
 * The layout is : GtkWindow has ClutterStage which contains ClutterActor scaleLayer
 * (in this function named self), which contains those blue
 * circles you see on animated gif.
 *
 * ScaleLayer is simply a huge invisible plane which contains all the objects an user
 * interacts with. User can pan and zoom it as he whishes.
 */&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ScaleLayer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;zoomOut&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Point&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;center&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;double&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;scaleX&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;scaleY&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// This gets our actual zoom factor.&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;clutter_actor_get_scale&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;scaleX&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;scaleY&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// We decrease the zoom factor since this is a zoomOut method.&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;float&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;newScale&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;scaleX&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;1.1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;kt&quot;&gt;float&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cx1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cy1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// Like I said &apos;center&apos; is in screen coords, so we convert it to scaleLayer coords&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;clutter_actor_transform_stage_point&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;center&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;center&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cx1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cy1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;kt&quot;&gt;float&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;scaleLayerNW&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;scaleLayerNH&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;clutter_actor_get_size&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;scaleLayerNW&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;scaleLayerNH&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// We set pivot_point&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;clutter_actor_set_pivot_point&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;double&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cx1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;scaleLayerNW&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;double&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cy1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;scaleLayerNH&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// And finalyy perform the scalling. Fair enough, isn&apos;t it?&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;clutter_actor_set_scale&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;newScale&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;newScale&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Here is the outcome (wrong) of the above :&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://iwasz.pl/files/zoomfail.gif&quot; alt=&quot;Zoom fail&quot; /&gt;&lt;/p&gt;

&lt;p&gt;It is fine until you move the mouse cursor which changes the pivot point (center of the scale transformation) while scale is not == 1.0. I dunno why this happens. Apparently I do not understand affine transformations as well as I thought, or there is a bug in libclutter (I doubt it). The solution is to convert the pivot point from screen to scaleLayer coordinates before scaling (as I did), and again after scaling. The difference is in scaleLayer coordinates, so it must be converted back to screen coordinates, and the result can be used to cancel this offset you see on the second gif. Here is my current implementation:&lt;/p&gt;

&lt;div class=&quot;language-cpp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ScaleLayer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;zoomIn&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Point&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;center&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;double&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;clutter_actor_get_scale&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;kt&quot;&gt;double&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;newScale&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;1.1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;newScale&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;newScale&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;scale&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;center&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;newScale&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;cm&quot;&gt;/*****************************************************************************/&lt;/span&gt;

&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ScaleLayer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;zoomOut&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Point&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;center&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;ClutterActor&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stage&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;clutter_actor_get_parent&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;kt&quot;&gt;float&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;stageW&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;stageH&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;clutter_actor_get_size&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stageW&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stageH&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;kt&quot;&gt;float&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dim&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;max&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stageW&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;stageH&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;double&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;minScale&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dim&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SCALE_SURFACE_SIZE&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.05&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;kt&quot;&gt;double&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;scaleX&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;scaleY&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;clutter_actor_get_scale&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;scaleX&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;scaleY&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;scaleX&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;minScale&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;scale&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;center&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;scaleX&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;1.1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; 
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; 

&lt;span class=&quot;cm&quot;&gt;/*****************************************************************************/&lt;/span&gt; 

&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ScaleLayer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;scale&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Point&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;float&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;newScale&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; 
   &lt;span class=&quot;n&quot;&gt;Point&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;center&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;float&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cx1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cy1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;center&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Point&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;())&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;impl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lastCenter&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Point&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;())&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                        &lt;span class=&quot;kt&quot;&gt;float&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;stageW&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;stageH&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
                        &lt;span class=&quot;n&quot;&gt;ClutterActor&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stage&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;clutter_actor_get_parent&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
                        &lt;span class=&quot;n&quot;&gt;clutter_actor_get_size&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stageW&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stageH&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
                        &lt;span class=&quot;n&quot;&gt;impl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lastCenter&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Point&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stageW&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;2.0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;stageH&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;2.0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

                &lt;span class=&quot;n&quot;&gt;center&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;impl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lastCenter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;impl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lastCenter&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;center&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;clutter_actor_transform_stage_point&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;center&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;center&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cx1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cy1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;float&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;scaleLayerNW&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;scaleLayerNH&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;clutter_actor_get_size&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;scaleLayerNW&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;scaleLayerNH&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;clutter_actor_set_pivot_point&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;double&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cx1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;scaleLayerNW&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;double&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cy1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;scaleLayerNH&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;clutter_actor_set_scale&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;newScale&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;newScale&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;c1&quot;&gt;// Idea taken from here : https://community.oracle.com/thread/1263955&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;float&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cx2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cy2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;clutter_actor_transform_stage_point&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;center&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;center&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cx2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cy2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;ClutterVertex&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;vi1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;ClutterVertex&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;vo1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;clutter_actor_apply_transform_to_point&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vi1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vo1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;ClutterVertex&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;vi2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cx2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cx1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cy2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cy1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;ClutterVertex&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;vo2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;clutter_actor_apply_transform_to_point&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vi2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vo2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;kt&quot;&gt;float&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mx&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;vo2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;vo1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;float&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;my&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;vo2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;vo1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;clutter_actor_move_by&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;my&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The whole project is here : 
&lt;a href=&quot;https://github.com/iwasz/data-flow-gui&quot;&gt;https://github.com/iwasz/data-flow-gui&lt;/a&gt;
Here’s the thread which pointed me in right direction : 
&lt;a href=&quot;https://community.oracle.com/thread/1263955&quot;&gt;https://community.oracle.com/thread/1263955&lt;/a&gt;&lt;/p&gt;</content>

      
      
      
      
      

      

      
        <category term="Uncategorized" />
      

      

      
        <summary type="html">I’m making this post because I struggled with this functionality a lot! I was implementing it (to the extent I was happy with) in the course of 4 or even 5 days! Ok, first goes an animated gif which shows my desired zoom behavior (check out Inkscape, or other graphics programs, they all work the same in this regard):</summary>
      

      
      
    </entry>
  
  
  
    <entry>
      
      <title type="html">Cross compilation with GCC &amp;amp; QtCreator for ARM Cortex M</title>
      
      
      <link href="http://iwasz.pl/uncategorized/cross-compilation-with-gcc-qtcreator-for-arm-cortex-m/" rel="alternate" type="text/html" title="Cross compilation with GCC &amp; QtCreator for ARM Cortex M" />
      
      <published>2016-06-21T00:00:00+02:00</published>
      <updated>2016-06-21T00:00:00+02:00</updated>
      <id>http://iwasz.pl/uncategorized/cross-compilation-with-gcc-qtcreator-for-arm-cortex-m</id>
      <content type="html" xml:base="http://iwasz.pl/uncategorized/cross-compilation-with-gcc-qtcreator-for-arm-cortex-m/">&lt;p&gt;&lt;strong&gt;This post is outdated!!&lt;/strong&gt;
. Please see http://www.iwasz.pl/electronics/stm32-on-ubuntu-linux-step-by-step/ for more up to date instructions.&lt;/p&gt;

&lt;p&gt;I used Eclipse CDT for years for C/C++ and was disappointed by its bulkiness, slowness, and memory usage. I did mostly embedded, and sometimes GTK+ desktop apps (even OpenGL once or twice). I looked for a replacement, tried dozen or more IDEs and editors, and finally found out the QtCreator (my main concerns were : great code navigation - eclipse often get confused wit serious, templated C++ code), great code completion, and CMake integration. I am satisfied for now (It’s been a year now), and I use it for all but Qt. But all of a sudden, wen a new version appeared, I came across a minor flaw in CMake builder, which reported an error like “Can’t link a test program”. Obviously it cannot because he used a host compiler instead of ARM one.&lt;/p&gt;

&lt;p&gt;So in versions prior to 4.0.0 I used to configure my project with cmake like:&lt;/p&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;cd &lt;/span&gt;build
cmake ..
make
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Then, from QtCreator, I simply compiled the project, and it worked flawlessly. But since QtCreator 4.0.0 it started to invoke cmake in every possible situation. Be it an IDE startup, or saving a CMakeLists.txt file. And it did it with 
&lt;code class=&quot;highlighter-rouge&quot;&gt;-DCMAKE_CXX_COMPILER=xyz&lt;/code&gt; where “xyz” was a path configured in 
Tools -&amp;gt; Options -&amp;gt; Build &amp;amp; Run -&amp;gt; Compilers. If I run cmake manually, without this &lt;code class=&quot;highlighter-rouge&quot;&gt;CMAKE_CXX_COMPILER&lt;/code&gt; variable set, everything was OK. I saw on the Internet, that many people had the same problem, and used QtCreator for embedded like I do (
&lt;a href=&quot;https://blog.qt.io/blog/2016/05/11/qt-creator-4-0-0-released/&quot;&gt;see comments here&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;So I decided, that instead of forcing QtCreator to stop invoking cmake, or invoking it with different parameters, I should fix my CMakeLists.txt so it would run as QtCreator want it. A solution I found was 
&lt;a href=&quot;https://cmake.org/Wiki/CMake_Cross_Compiling#The_toolchain_file&quot;&gt;CMAKE_FORCE_C_COMPILER and CMAKE_FORCE_CXX_COMPILER documented here&lt;/a&gt;. My CMakeLists.txt looks like this:&lt;/p&gt;

&lt;div class=&quot;language-cmake highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nf&quot;&gt;CMAKE_MINIMUM_REQUIRED&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;VERSION 2.8&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;nf&quot;&gt;SET&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;CMAKE_VERBOSE_MAKEFILE OFF&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;stm32.cmake&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;nf&quot;&gt;PROJECT&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;robot1&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;nf&quot;&gt;SET&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;USB_LIB &lt;span class=&quot;s2&quot;&gt;&quot;&quot;&lt;/span&gt; CACHE STRING &lt;span class=&quot;s2&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;nf&quot;&gt;INCLUDE_DIRECTORIES&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;src/&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nf&quot;&gt;LIST&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;APPEND APP_SOURCES &lt;span class=&quot;s2&quot;&gt;&quot;src/main.c&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nf&quot;&gt;LIST&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;APPEND APP_SOURCES &lt;span class=&quot;s2&quot;&gt;&quot;src/stm32f4xx_it.c&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nf&quot;&gt;LIST&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;APPEND APP_SOURCES &lt;span class=&quot;s2&quot;&gt;&quot;src/syscalls.c&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nf&quot;&gt;LIST&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;APPEND APP_SOURCES &lt;span class=&quot;s2&quot;&gt;&quot;src/system_stm32f0xx.c&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nf&quot;&gt;LIST&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;APPEND APP_SOURCES &lt;span class=&quot;s2&quot;&gt;&quot;src/config.h&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nf&quot;&gt;LIST&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;APPEND APP_SOURCES &lt;span class=&quot;s2&quot;&gt;&quot;src/stm32f0xx_hal_conf.h&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;nf&quot;&gt;AUX_SOURCE_DIRECTORY&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CUBE_ROOT&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/Drivers/STM32F0xx_HAL_Driver/Src/&quot;&lt;/span&gt; APP_SOURCES&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nf&quot;&gt;LIST&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;APPEND APP_SOURCES &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;STARTUP_CODE&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;nf&quot;&gt;ADD_EXECUTABLE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CMAKE_PROJECT_NAME&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;.elf &lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;APP_SOURCES&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nf&quot;&gt;ADD_CUSTOM_TARGET&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CMAKE_PROJECT_NAME&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;.bin ALL DEPENDS &lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CMAKE_PROJECT_NAME&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;.elf COMMAND &lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CMAKE_OBJCOPY&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt; -Obinary &lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CMAKE_PROJECT_NAME&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;.elf &lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CMAKE_PROJECT_NAME&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;.bin&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;nf&quot;&gt;FIND_PROGRAM&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;ST_FLASH st-flash&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nf&quot;&gt;ADD_CUSTOM_TARGET&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;upload&quot;&lt;/span&gt; DEPENDS &lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CMAKE_PROJECT_NAME&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;.elf COMMAND &lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;ST_FLASH&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt; --reset write &lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CMAKE_PROJECT_NAME&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;.bin 0x8000000&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;And the “toolchain file” is like this:&lt;/p&gt;

&lt;div class=&quot;language-cmake highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nf&quot;&gt;SET&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;TOOLCHAIN_PREFIX &lt;span class=&quot;s2&quot;&gt;&quot;/home/iwasz/local/share/armcortexm0-unknown-eabi&quot;&lt;/span&gt; CACHE STRING &lt;span class=&quot;s2&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nf&quot;&gt;SET&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;TARGET_TRIPLET &lt;span class=&quot;s2&quot;&gt;&quot;armcortexm0-unknown-eabi&quot;&lt;/span&gt; CACHE STRING &lt;span class=&quot;s2&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nf&quot;&gt;SET&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;DEVICE &lt;span class=&quot;s2&quot;&gt;&quot;STM32F072xB&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nf&quot;&gt;SET&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;CUBE_ROOT &lt;span class=&quot;s2&quot;&gt;&quot;/home/iwasz/workspace/stm32cubef0&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nf&quot;&gt;SET&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;CRYSTAL_HZ 16000000&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nf&quot;&gt;SET&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;STARTUP_CODE &lt;span class=&quot;s2&quot;&gt;&quot;src/startup_stm32f072xb.s&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nf&quot;&gt;SET&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;LINKER_SCRIPT &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CMAKE_SOURCE_DIR&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/src/STM32F072RB_FLASH.ld&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nf&quot;&gt;SET&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;TOOLCHAIN_BIN_DIR &lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;TOOLCHAIN_PREFIX&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;/bin&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nf&quot;&gt;SET&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;TOOLCHAIN_INC_DIR &lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;TOOLCHAIN_PREFIX&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;/&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;TARGET_TRIPLET&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;/include&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nf&quot;&gt;SET&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;TOOLCHAIN_LIB_DIR &lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;TOOLCHAIN_PREFIX&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;/&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;TARGET_TRIPLET&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;/lib&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;nf&quot;&gt;INCLUDE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;CMakeForceCompiler&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nf&quot;&gt;SET&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;CMAKE_SYSTEM_NAME Generic&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nf&quot;&gt;SET&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;CMAKE_SYSTEM_PROCESSOR arm&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;nf&quot;&gt;CMAKE_FORCE_C_COMPILER&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;TOOLCHAIN_BIN_DIR&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;TARGET_TRIPLET&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;-gcc&quot;&lt;/span&gt; GNU&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nf&quot;&gt;CMAKE_FORCE_CXX_COMPILER&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;TOOLCHAIN_BIN_DIR&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;TARGET_TRIPLET&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;-gcc&quot;&lt;/span&gt; GNU&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nf&quot;&gt;SET&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;CMAKE_ASM_COMPILER &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;TOOLCHAIN_BIN_DIR&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;TARGET_TRIPLET&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;-as&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nf&quot;&gt;SET&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;CMAKE_ASM-ATT_COMPILER &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;TOOLCHAIN_BIN_DIR&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;TARGET_TRIPLET&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;-as&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nf&quot;&gt;SET&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;CMAKE_OBJCOPY &lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;TOOLCHAIN_BIN_DIR&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;/&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;TARGET_TRIPLET&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;-objcopy&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nf&quot;&gt;SET&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;CMAKE_OBJDUMP &lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;TOOLCHAIN_BIN_DIR&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;/&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;TARGET_TRIPLET&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;-objdump&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nf&quot;&gt;SET&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;CMAKE_C_FLAGS &lt;span class=&quot;s2&quot;&gt;&quot;-std=gnu99 -fdata-sections -ffunction-sections -Wall&quot;&lt;/span&gt; CACHE INTERNAL &lt;span class=&quot;s2&quot;&gt;&quot;c compiler flags&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nf&quot;&gt;SET&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;CMAKE_CXX_FLAGS &lt;span class=&quot;s2&quot;&gt;&quot;-std=c++11 -Wall -fdata-sections -ffunction-sections -MD -Wall&quot;&lt;/span&gt; CACHE INTERNAL &lt;span class=&quot;s2&quot;&gt;&quot;cxx compiler flags&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nf&quot;&gt;SET&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;CMAKE_EXE_LINKER_FLAGS &lt;span class=&quot;s2&quot;&gt;&quot;-T &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;LINKER_SCRIPT&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; -Wl,--gc-sections&quot;&lt;/span&gt; CACHE INTERNAL &lt;span class=&quot;s2&quot;&gt;&quot;exe link flags&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nf&quot;&gt;SET&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;CMAKE_SHARED_LIBRARY_LINK_C_FLAGS &lt;span class=&quot;s2&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nf&quot;&gt;SET&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS &lt;span class=&quot;s2&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;nf&quot;&gt;INCLUDE_DIRECTORIES&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;SUPPORT_FILES&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nf&quot;&gt;LINK_DIRECTORIES&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;SUPPORT_FILES&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nf&quot;&gt;ADD_DEFINITIONS&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;-D&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;DEVICE&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nf&quot;&gt;INCLUDE_DIRECTORIES&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CUBE_ROOT&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/Drivers/STM32F0xx_HAL_Driver/Inc/&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nf&quot;&gt;INCLUDE_DIRECTORIES&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CUBE_ROOT&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/Drivers/CMSIS/Device/ST/STM32F0xx/Include/&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nf&quot;&gt;INCLUDE_DIRECTORIES&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CUBE_ROOT&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/Drivers/CMSIS/Include/&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;nf&quot;&gt;ENABLE_LANGUAGE&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;ASM-ATT&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Two most important changes were:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Using &lt;code class=&quot;highlighter-rouge&quot;&gt;CMAKE_FORCE_CXX_COMPILER&lt;/code&gt; macro instead of simply setting &lt;code class=&quot;highlighter-rouge&quot;&gt;CMAKE_CXX_COMPILER&lt;/code&gt; var.&lt;/li&gt;
  &lt;li&gt;Including the toolchain file (and thus setting / forcing the compiler) before PROJECT macro.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;My configuration as of writing this:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Qt Creator 4.0.2, Based on Qt 5.7.0 (GCC 4.9.1 20140922 (Red Hat 4.9.1-10), 64 bit), Built on Jun 13 2016 01:05:36, From revision 47b4f2c738&lt;/li&gt;
  &lt;li&gt;Host system : Ubuntu 15.10, Linux ingram 4.2.0-38-generic #45-Ubuntu SMP Wed Jun 8 21:21:49 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux&lt;/li&gt;
  &lt;li&gt;Host GCC : gcc (Ubuntu 5.2.1-22ubuntu2) 5.2.1 20151010&lt;/li&gt;
  &lt;li&gt;Target GCC : armcortexm0-unknown-eabi-gcc (crosstool-NG crosstool-ng-1.21.0-74-g6ac93ed - iwasz) 5.2.0&lt;/li&gt;
&lt;/ul&gt;</content>

      
      
      
      
      

      

      
        <category term="Uncategorized" />
      

      

      
        <summary type="html">This post is outdated!! . Please see http://www.iwasz.pl/electronics/stm32-on-ubuntu-linux-step-by-step/ for more up to date instructions.</summary>
      

      
      
    </entry>
  
  
  
    <entry>
      
      <title type="html">BlueNRG + STM32F7-DISCO tests</title>
      
      
      <link href="http://iwasz.pl/uncategorized/bluenrg-stm32f7-disco-tests/" rel="alternate" type="text/html" title="BlueNRG + STM32F7-DISCO tests" />
      
      <published>2016-03-21T00:00:00+01:00</published>
      <updated>2016-03-21T00:00:00+01:00</updated>
      <id>http://iwasz.pl/uncategorized/bluenrg-stm32f7-disco-tests</id>
      <content type="html" xml:base="http://iwasz.pl/uncategorized/bluenrg-stm32f7-disco-tests/">&lt;ul&gt;
  &lt;li&gt;Tested 32bit cross-compiler from Launchpad, it worked OK, but binaries were much bigger, and debugger lacked Python support which is required by QtCreator which is an IDE of my choice (for all C/C++ development including embedded).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;/assets/IMG_20160321_020856-300x225.jpg&quot; alt=&quot;Discovery board&quot; /&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Made my own compiler with crosstool-NG (master from GIT). Used my own tutorial, which can be found 
&lt;a href=&quot;http://www.iwasz.pl/electronics/toolchain-for-cortex-m4/&quot;&gt;somewhere over this blog&lt;/a&gt;.&lt;/li&gt;
  &lt;li&gt;Verified that a “hello world” / “blinky” program works. It did not, because I copied code for STM32F4, and I messed the clock configuration. Examples from STM32F7-cube helped.&lt;/li&gt;
  &lt;li&gt;I &lt;a href=&quot;https://github.com/iwasz/blue-nrg-test&quot;&gt;ported my project&lt;/a&gt; which aimed to bring 
&lt;a href=&quot;http://www.st.com/web/catalog/tools/FM116/SC1075/PF260517&quot;&gt;my BlueNRG dev board&lt;/a&gt; to life. The project consists of a USB vendor-specific class for debugging (somewhat more advanced, and tuned for the purpose than simple CDC class), slightly adapted BlueNRG 
&lt;a href=&quot;http://www.st.com/web/en/catalog/tools/PF261442&quot;&gt;example code from ST (for Nucleo)&lt;/a&gt;, and some glue code.&lt;/li&gt;
  &lt;li&gt;I switched to STM32F7-disco because I couldn’t get BlueNRG to work with STM32F4-disco. F7 has Arduino connector on the back, so I thought it’d be better than bunch of loosely connected wires which was required for F4. At that time I thought that there is something wrong with my wiring.&lt;/li&gt;
  &lt;li&gt;On STM32F7-disco BLE still would not work. I hooked up a logic analyzer, and noticed that MISO and CLK is silent. It turned up that I have to use an alternative CLK configuration on BlueNRG board which required to move 0R resistor from R10 to R11. Although it was small (0402), at first I had a problem desoldering it, probably because of the unleaded solder used. See image.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;/assets/IMG_20160320_175826-300x182.jpg&quot; alt=&quot;Jumper configuration changed&quot; /&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Next problem I had, was with SPI_CS pin. According to the BlueNRG-dev board docs, I wanted to use D8 pin (this is PI2 pin on STM32F7-disco), but it didn’t work. Glimpse on the schematics revealed that the SPI_CS is connected to A1, which is marked as “alternative” in the docs. So IMHO this is an error in the docs.&lt;/li&gt;
  &lt;li&gt;Final pin configuration that worked was:&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-cpp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// SPI Reset Pin&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;#define BNRG_SPI_RESET_PIN GPIO_PIN_3
#define BNRG_SPI_RESET_PORT GPIOI
&lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;// SCLK&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;#define BNRG_SPI_SCLK_PIN GPIO_PIN_1
#define BNRG_SPI_SCLK_PORT GPIOI
&lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;// MISO (Master Input Slave Output)&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;#define BNRG_SPI_MISO_PIN GPIO_PIN_14
#define BNRG_SPI_MISO_PORT GPIOB
&lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;// MOSI (Master Output Slave Input)&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;#define BNRG_SPI_MOSI_PIN GPIO_PIN_15
&lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;// NSS/CSN/CS&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;#define BNRG_SPI_CS_PIN GPIO_PIN_10
#define BNRG_SPI_CS_PORT GPIOF
&lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;// IRQ&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;#define BNRG_SPI_IRQ_PIN GPIO_PIN_0
&lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;// !!!&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;#define BNRG_SPI_IRQ_PULL GPIO_PULLDOWN
#define BNRG_SPI_IRQ_PORT GPIOA
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;Next thing that got me puzzled for quite a time was that after initial version query command, which seemed to work OK (I got some reasonably looking responses) the communication hanged. IRQ pin went high, and wouldn’t go low. So µC thought that there is data to read and was continuously reading and reading.&lt;/li&gt;
  &lt;li&gt;Only after I read in 
&lt;a href=&quot;http://www.st.com/st-web-ui/static/active/en/resource/technical/document/user_manual/DM00114498.pdf&quot;&gt;UM1755 User manual&lt;/a&gt; that IRQ goes HI when there is data from NRG to µC, and it goes HI-Z when there is no data, I double checked the schematics, and found that BlueNRG-dev board has no pull-down resistor in it. The ST example code I had also hadn’t have IRQ pin configured in pull-down state, so I wonder how this could work. Maybe Nucleo boards have pull-down resistor soldered there.&lt;/li&gt;
  &lt;li&gt;For now (after 3 or 4 nights, and I consider myself as quite experienced) I got this (see photo):&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;/assets/Screenshot-from-2016-03-21-02-09-30-300x217.png&quot; alt=&quot;Linux is seeing the BlueNRG&quot; /&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Quick update made the next day morning. My Linux computer is able to connect to the test project, and query it (right now it simply counts up):&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;/assets/Screenshot-from-2016-03-21-13-05-25-300x179.png&quot; alt=&quot;Some console output&quot; /&gt;&lt;/p&gt;</content>

      
      
      
      
      

      

      
        <category term="Uncategorized" />
      

      

      
        <summary type="html">Tested 32bit cross-compiler from Launchpad, it worked OK, but binaries were much bigger, and debugger lacked Python support which is required by QtCreator which is an IDE of my choice (for all C/C++ development including embedded).</summary>
      

      
      
    </entry>
  
  
  
    <entry>
      
      <title type="html">Internet thermal printer part 2</title>
      
      
      <link href="http://iwasz.pl/electronics/internet-thermal-printer-part-2/" rel="alternate" type="text/html" title="Internet thermal printer part 2" />
      
      <published>2014-07-21T00:00:00+02:00</published>
      <updated>2014-07-21T00:00:00+02:00</updated>
      <id>http://iwasz.pl/electronics/internet-thermal-printer-part-2</id>
      <content type="html" xml:base="http://iwasz.pl/electronics/internet-thermal-printer-part-2/">&lt;p&gt;The printer I bought and 
&lt;a href=&quot;http://www.iwasz.pl/electronics/internet-thermal-printer/&quot;&gt;described in the previous&lt;/a&gt; post really disappointed me. I didn’t spend some huge amount of time on that (say 3-4 evenings), but I dig into the subject so deep so I couldn’t help myself but do some more hacking. First of all I wanted to know if my cool looking, but quite useless printer can be used in some other way (i.e. the printing head) and whether that is the main board which is broken or the head itself. If the former was true, and the head was OK, I would try to communicate with the head and thus make something which would pretty much implement the whole printer main board that was broken. But if the head was broken, I couldn’t do anything but to abandon the project or find another printer. And it’s funny, because, as you may have seen at the end of my previous post, this is exactly I’ve written not to do. But I just love it. When the work you do all day every day is stupid and pointless, when you are constantly bothered with more and more irrelevant things, and after all day you are tired and discouraged, what would you do after arriving home (excluding household duties :D)? Grab a beer, sit and watch TV? Hell no! Grab a beer and tinker some more! It calms me down you know (unless I’m stuck for to long). The printer head used in my 
&lt;strong&gt;Intermec PW40&lt;/strong&gt;
 is a Seiko (
&lt;a href=&quot;http://www.sii.co.jp&quot;&gt;www.sii.co.jp&lt;/a&gt;) 
&lt;a href=&quot;http://zival.ru/sites/default/files/download/ltp3445.pdf&quot;&gt;&lt;strong&gt;SII 
LTP3445&lt;/strong&gt;
(datasheet here)&lt;/a&gt; and it is obsolete. New designs are encouraged to use LTPV445.&lt;/p&gt;

&lt;p&gt;So what I did is that I soldered a bunch of wires to the main board to be able to speak directly to the printing head. The resulting wiring looks like that:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/IMG_20140708_010418-225x300.jpg&quot; alt=&quot;Bunch of wires soldered&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Then I grabbed signals with a logic analyzer and an oscilloscope to figure out what is malfunctioning (i.e. when the printer was operating). In my opinion, the main board is broken, because printing short strings like ‘A\r\n’ works OK, and all signals seems to be correct (i.e. 832 bits per row are transferred and quite a few rows are present). But when longer strings are submitted, the whole transmission appears to be corrupted at some point. Serial data burst is clearly shorter, like interrupted. Unfortunately I have made a screenshot of correct transmission (A\r\n), and don’t have the corrupted one now (and the board is not operational since I removed the FFC socket). Here’s the screen:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/screenshot-300x183.png&quot; alt=&quot;Transmission dump&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Above : a correct transmission to the thermal head issued by the original Intermec PW40 main board. Letter ‘A’ is being transmitted.&lt;/p&gt;

&lt;p&gt;The next step was to wire up some circuitry to actually drive the head while it was still soldered to the original main board. I didn’t want to break it then, but later it ceased to be a priority :D My setup consists of:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.ti.com/tool/ek-tm4c123gxl&quot;&gt;Texas Instruments EK-TM4C123GXL&lt;/a&gt; as the main logic unit.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.pololu.com/product/2135&quot;&gt;DRV8835 Dual Motor Driver Carrier&lt;/a&gt; from Pololu. It uses a 
&lt;a href=&quot;http://www.ti.com/product/drv8835&quot;&gt;DRV8835&lt;/a&gt; chip from Texas Instruments.&lt;/li&gt;
  &lt;li&gt;Two 
&lt;a href=&quot;http://www.ti.com/product/cd40109b&quot;&gt;CD40109B&lt;/a&gt; level shifters from Texas Instruments. Breadboard looks like this:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;/assets/IMG_20140708_000707-225x300.jpg&quot; alt=&quot;Bread board&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Above : the circuit. You can see that the printer is more or less intact i.e. the head is mounted on the main board and the plastic frame. Later on I decided to disconnect the head from the original main board.&lt;/p&gt;

&lt;p&gt;Shifters are controlled with 3.3V and output 5V for the head’s logic. The whole contraption is powered from a laboratory power supply which was set to 5V with low current limit to prevent smoke and fire in case of errors in wiring on my side. The setup drawn about 0.1A when idle and 2.5A when feeding the paper. Driving the motor was pretty easy, I did stepper motor before, so I rather quickly caught up with this one. But the head took more time and at some (thankfully short) time I was stuck. First, the DST signal (DST is for power and thus temperature) circuitry on the main board is secured with some (I believe) TTL logic. The idea is that if the thermistor says to the µC that he head is overheating, the µC shuts the head down. This is the first protection mechanism programmed in software (BTW manual says that if overheat, the head may cause skin burns, smoke and even fire. It is a thermal one after all). But there is another protection mechanism done in hardware which shuts down the head if the software one malfunctions. I believe, that the two mechanisms are AND-ed by some TTLs. The protection mechanisms are pulling down the DST in case of trouble. In my case, when actually two logic circuits were connected to the head, this situation caused problems, because the original main board, which was not powered, pulled the DST down all time. The solution to this was to cut the trace and that was it (if not cut, the DST would stay low no mater what level I was trying to drive it. Oscilloscope shown only 100mV level changes, obviously to small to be useful).&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/screenshot1-300x183.png&quot; alt=&quot;Logic analyzer window&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Above : a transmission. A 12*8 pixel wide bar strip. 12 x 0xaa.&lt;/p&gt;

&lt;p&gt;But still no luck after the DST problem was resolved, so I decided that something else on the original main board is interfering and I need to disconnect the head from it in sake of connecting to it directly. Didn’t have spare FFC socket though (Molex 25 pin 1.25 mm pitch rare and obsolete), so after obtaining a wrong one from Farnell (bought 1 mm pitch instead od 1.25 duh!) I soldered the wires directly to the FFC cable. Looks awful, but is rigid:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/IMG_20140711_233318-300x225.jpg&quot; alt=&quot;Wires soldered to the FFC cable&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Still no luck! What the hell! Logic analyzer still happily shows correct bursts of data, so for the third time rewired the breadboard and checked levels with an oscilloscope. And curious thing revealed : all levels (shifted up) were 0-4V instead od 0-5V. I have completely no idea why? My power supply is a cheap one, but can 1 or 2 amps of load cause 1V drop? Must investigate further. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;EDIT&lt;/strong&gt;
 my cheap counterfeit Saleae logic analyzer must have somewhat low input impedance and it was it that caused significant voltage drop on logic signals. Disappointing. On the picture below you can see (far left) that only after increasing the voltage repeatedly, the printer started to print:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/ltp3445-first-success-1024x215.jpg&quot; alt=&quot;A printout&quot; /&gt;&lt;/p&gt;

&lt;p&gt;I’m excited!&lt;/p&gt;</content>

      
      
      
      
      

      

      
        <category term="electronics" />
      

      

      
        <summary type="html">The printer I bought and described in the previous post really disappointed me. I didn’t spend some huge amount of time on that (say 3-4 evenings), but I dig into the subject so deep so I couldn’t help myself but do some more hacking. First of all I wanted to know if my cool looking, but quite useless printer can be used in some other way (i.e. the printing head) and whether that is the main board which is broken or the head itself. If the former was true, and the head was OK, I would try to communicate with the head and thus make something which would pretty much implement the whole printer main board that was broken. But if the head was broken, I couldn’t do anything but to abandon the project or find another printer. And it’s funny, because, as you may have seen at the end of my previous post, this is exactly I’ve written not to do. But I just love it. When the work you do all day every day is stupid and pointless, when you are constantly bothered with more and more irrelevant things, and after all day you are tired and discouraged, what would you do after arriving home (excluding household duties :D)? Grab a beer, sit and watch TV? Hell no! Grab a beer and tinker some more! It calms me down you know (unless I’m stuck for to long). The printer head used in my Intermec PW40 is a Seiko ( www.sii.co.jp) SII LTP3445 (datasheet here) and it is obsolete. New designs are encouraged to use LTPV445.</summary>
      

      
      
    </entry>
  
  
  
    <entry>
      
      <title type="html">Internet thermal printer</title>
      
      
      <link href="http://iwasz.pl/electronics/internet-thermal-printer/" rel="alternate" type="text/html" title="Internet thermal printer" />
      
      <published>2014-07-11T00:00:00+02:00</published>
      <updated>2014-07-11T00:00:00+02:00</updated>
      <id>http://iwasz.pl/electronics/internet-thermal-printer</id>
      <content type="html" xml:base="http://iwasz.pl/electronics/internet-thermal-printer/">&lt;p&gt;What this project is intended to be:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;A toy printer (for my son) with some light and sound signal connected to the Internet and accessible by some web interface. Anyone with password (basic auth configured in .htaccess) could send a graphic and/or text message to the printer which would immediately flash the light, beep the buzzer as well as print the message. Protocol to the printer (on the network level) : whatever a.k.a my own &amp;amp; super-simple.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;del&gt;What this project shall not become&lt;/del&gt;. &lt;strong&gt;EDIT&lt;/strong&gt;:  It evolved.. (note to myself because I tend to complicate things):&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;An over-engineered wireless CUPS compatible Postscript full featured printer which also makes coffee.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After deciding that I would try to make such a thing which took approx. 1 second after seeing Jim’s site I went to 
&lt;a href=&quot;http://allegro.pl&quot;&gt;allegro.pl&lt;/a&gt; (local EBay. BTW we have ebay.com.pl here in Poland, but allegro seems to be winning the battle) and found something printer-ish alike and seemingly broken, with some parts missing. It is a 
&lt;strong&gt;Intermec PW40&lt;/strong&gt;
 mobile printer. Useful links I found on this printer:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.intermec.com/support/manuals/search.aspx?categoryid=7&amp;amp;familyid=11&amp;amp;productnodeid=PRTRPW50A&quot;&gt;Manuals - Intermec site&lt;/a&gt; (those are for PW50, but I assume they are compatible in some way).&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://community.intermec.com/&quot;&gt;Intermec&lt;/a&gt; community - they even have forum, and some community around the site.
Photos after dismantling the thing:&lt;/li&gt;
&lt;/ul&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt; &lt;/th&gt;
      &lt;th&gt; &lt;/th&gt;
      &lt;th&gt; &lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;img src=&quot;/assets/IMG_20140617_185647-150x150.jpg&quot; alt=&quot;Printer&quot; /&gt;&lt;/td&gt;
      &lt;td&gt;&lt;img src=&quot;/assets/IMG_20140617_185416-150x150.jpg&quot; alt=&quot;Printer&quot; /&gt;&lt;/td&gt;
      &lt;td&gt;&lt;img src=&quot;/assets/IMG_20140617_185551-150x150.jpg&quot; alt=&quot;Printer&quot; /&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Main Board&lt;/td&gt;
      &lt;td&gt;Main board mounted on the plastic frame.&lt;/td&gt;
      &lt;td&gt;Main board&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;img src=&quot;/assets/IMG_20140617_185630-150x150.jpg&quot; alt=&quot;Printer&quot; /&gt;&lt;/td&gt;
      &lt;td&gt;&lt;img src=&quot;/assets/IMG_20140617_190016-150x150.jpg&quot; alt=&quot;Printer&quot; /&gt;&lt;/td&gt;
      &lt;td&gt;&lt;img src=&quot;/assets/IMG_20140617_190024-150x150.jpg&quot; alt=&quot;Printer&quot; /&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Main board&lt;/td&gt;
      &lt;td&gt;Bottom view. Without the casing.&lt;/td&gt;
      &lt;td&gt;Printer from above without the casing.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;img src=&quot;/assets/IMG_20140617_190244-150x150.jpg&quot; alt=&quot;Printer&quot; /&gt;&lt;/td&gt;
      &lt;td&gt;&lt;img src=&quot;/assets/IMG_20140617_190255-150x150.jpg&quot; alt=&quot;Printer&quot; /&gt;&lt;/td&gt;
      &lt;td&gt;&lt;img src=&quot;/assets/IMG_20140617_190332-150x150.jpg&quot; alt=&quot;Printer&quot; /&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;The head. It is 2005 made I believe.&lt;/td&gt;
      &lt;td&gt;Thermal head sticker.&lt;/td&gt;
      &lt;td&gt;Thermal head closeup&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;img src=&quot;/assets/IMG_20140617_190444-150x150.jpg&quot; alt=&quot;Printer&quot; /&gt;&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;7.2V Batteries, pretty dead.&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;The sticker is important because it has markings which informs you about certain resistance levels in the head. My head is a “C” type.&lt;/p&gt;

&lt;p&gt;Looks like it 
&lt;a href=&quot;http://en.wikipedia.org/wiki/ESC/P&quot;&gt;uses ESC/P&lt;/a&gt; like Jim’s printer and 7.2V battery pack also. Looks promising (at least some standard language). Elements found on the main board of PW-40:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://pl.mouser.com/ProductDetail/Toshiba/TMP95C061BFZ/?qs=f0GatGUIxV3RUG14ubT6RQ==&quot;&gt;Toshiba TMP95C061BF&lt;/a&gt; : some 16 bit microcontroller. 
&lt;a href=&quot;http://en.wikipedia.org/wiki/Toshiba_TLCS&quot;&gt;TLCS-900&lt;/a&gt; family. No free C compiler available according to Wikipedia.&lt;/li&gt;
  &lt;li&gt;NEC 
&lt;a href=&quot;http://search.datasheetcatalog.net/key/D431000&quot;&gt;D431000AGW&lt;/a&gt; : SRAM 1Mb&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://pdf.datasheetcatalog.com/datasheet/SGSThomsonMicroelectronics/mXyxzsz.pdf&quot;&gt;ST M29F040B&lt;/a&gt; : Flash 4Mb.&lt;/li&gt;
  &lt;li&gt;LinearTechnology 
&lt;a href=&quot;http://www.51samples.com/upfiles/Manual/1384fa%5B1%5D.pdf&quot;&gt;LTC1384CG&lt;/a&gt; : this is what I was looking for : a RS232 transceiver.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.cirrus.com/en/pubs/proDatasheet/CS8130_F1.pdf&quot;&gt;CS8130&lt;/a&gt; : IR transceiver.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I’ve written the LTC chip looks promising, because it connects the printer to the outside world, and gives a hint where to start hacking. It translates RS232 high voltage levels to TTL, but since I wanted to drive the printer directly from some µC I needed to bypass the LTC. After some research I determined what follows : RS 232 port (this with RJ socket) is connected to pins 14 (232 input) and 15 (232 output). Corresponding TTL pins are : pin 13 (logic output), and 12 (logic input). So as far as I am reasoning correctly :&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Pin 13 is connected to the Toshiba’s RX pin.&lt;/li&gt;
  &lt;li&gt;Pin 12 is connected to the Toshiba’s TX pin.&lt;/li&gt;
  &lt;li&gt;The whole device can be powered from 12V supply (I read that somewhere).&lt;/li&gt;
  &lt;li&gt;Let’s try it! It seems to work. At least a PC and the printer are communicating. Wiring looks like this:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;/assets/IMG_20140618_001437-150x150.jpg&quot; alt=&quot;Printer&quot; /&gt; &lt;img src=&quot;/assets/IMG_20140618_000309-150x150.jpg&quot; alt=&quot;Printer&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Costs so far:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Printer : 25PLN ($8).&lt;/li&gt;
  &lt;li&gt;10 rolls of thermal paper 20PLN ($7)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href=&quot;http://www.intermec.com/public-files/technology-briefs/en/CUPS-Printing-In-Linux-UNIX-For-Intermec-Printers-Tech-Brief.pdf&quot;&gt;Intermec provides a CUPS driver&lt;/a&gt; for Linux which enables you to use their printer as regular printer in the OS. Apparently PW40 isn’t supported. I successfully compiled and installed the software, but printing a random text file gave me some gibberish. After that I tried to communicate with te printer in ESC/P language directly, but with no luck. I 
&lt;a href=&quot;http://community.intermec.com/t5/General-Intermec-Device/PW40-is-it-broken-or-not/m-p/27118&quot;&gt;described my problems on the Intermec&lt;/a&gt; forums and still waiting for some reply. In short the problem is, that I don’t really know for sure if this is me doing something wrong, or the printer is broken (it was sold on auction as broken, but the seller couldn’t tell for sure if it is really broken or not). So after two evenings the situation looks that I am able to print only one character in a row. If I’m sending more than 1 character to print, it hangs. To make matters worse, my printer won’t print a self test page as it is described in the manual. It feeds paper a little and that’s all. At the other hand I 
&lt;a href=&quot;http://zival.ru/sites/default/files/download/ltp3445.pdf&quot;&gt;found a datasheet&lt;/a&gt; of the printer head used in my printer, but using it directly would be a triumph of form over the content I’m afraid, and I don’t have enough time for that (i.e. making my own printer from scratch). But I’m overambitious you know, so who knows…&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/IMG_20140620_123905-300x225.jpg&quot; alt=&quot;The printer is broken&quot; /&gt;&lt;/p&gt;</content>

      
      
      
      
      

      

      
        <category term="electronics" />
      

      

      
        <summary type="html">What this project is intended to be:</summary>
      

      
      
    </entry>
  
  
  
    <entry>
      
      <title type="html">The any key</title>
      
      
      <link href="http://iwasz.pl/electronics/the-any-key/" rel="alternate" type="text/html" title="The any key" />
      
      <published>2014-06-09T00:00:00+02:00</published>
      <updated>2014-06-09T00:00:00+02:00</updated>
      <id>http://iwasz.pl/electronics/the-any-key</id>
      <content type="html" xml:base="http://iwasz.pl/electronics/the-any-key/">&lt;p&gt;…which in fact is an one button HID keyboard which you can reprogram to be any key or combination of keys you wish (open-source hardware and software). For starters here’s a bunch of links:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://code.google.com/p/iwasz-sandbox/source/browse#svn%2Ftrunk%2Ftm4c123-drama-button-v2&quot;&gt;Device firmware &lt;strong&gt;source code&lt;/strong&gt; + eagle files&lt;/a&gt;.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://code.google.com/p/iwasz-sandbox/source/browse/#svn%2Ftrunk%2Fany-key-host-app&quot;&gt;Host software&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.iwasz.pl/electronics/a-chaotic-post-on-hid-keyboard-stm32f407-success-stm32f105-fail/&quot;&gt;Previous attempt.&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And a quick video (one blurry shoot):&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://www.youtube.com/watch?v=CeLo8d0pDmI&quot;&gt;&lt;img src=&quot;https://img.youtube.com/vi/CeLo8d0pDmI/0.jpg&quot; alt=&quot;The any key video&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At some point, after a few battles I bravely fought with STM32 I wanted to learn something new. I’ve been a few times on Texas Instrument’s site because I wanted to learn more about BeagleBone black and the Sitara CPU that sits on it and spotted the TIVA microcontrolers somewhere on the page. After quick research they looked very promising. It had all I needed that is : can be easily programmed with GCC stack under Linux, has affordable starting platform (they call them launchpads, and they cost $13 and $20 for TM4C123 and TM4C129 respectively) and, what is most important for me, they have well written peripheral libraries and documentation (i.e. at that time I could only rely on opinions from the Web, but after my first project I definitely can confirm that).&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/IMG_20140603_012851-225x300.jpg&quot; alt=&quot;My button assembled&quot; /&gt;&lt;/p&gt;

&lt;p&gt;So I started a new simple project, which I previously tried to make with STMs and had countless problems with (&lt;a href=&quot;http://www.iwasz.pl/electronics/a-chaotic-post-on-hid-keyboard-stm32f407-success-stm32f105-fail/&quot;&gt;here is the link&lt;/a&gt;). I’ve got 
&lt;a href=&quot;http://www.ti.com/tool/ek-tm4c123gxl&quot;&gt;EK-TM4C123GXL&lt;/a&gt; launchpad and it’s great. Somewhere in near future I’ll try to write another post which would explain how to start development on Linux with GCC toolchain with this board, but for now I can only assure you that getting started was as easy and quick as one evening (I used my own cross-compiler which is 
&lt;a href=&quot;http://www.iwasz.pl/electronics/toolchain-for-cortex-m4/&quot;&gt;described in previous post here&lt;/a&gt;). The project aims to construct one button USB-HID keyboard which could be reprogrammed in such a way that pressing the button would send any key code user wishes or even combination of keys if necessary. I imagined, that it would be super cool to have something like that on my desk at work, and if someone comes by and interrupt me with my work, I would ostentatiously hit the big red button which stops the music in my headphones and ask : “what? once again?”. TI provides excellent peripheral library with many examples for many evaluation boards. Furthermore they have great USB library which is neatly divided in four tiers dependent on each other. On the very top is the highest level tier called the “Device Class API” which enables one to implement typical devices in just few lines of code (I mean simple HID, DFU, CDC etc.) ST does not have that! Device class API is great, but in fact quite inflexible. For example HID keyboard can have only one interface which is not enough if one wants to implement something more sophisticated. 
&lt;a href=&quot;https://www.microsoft.com/china/whdc/archive/w2kbd.mspx&quot;&gt;Here are instructions for designing HID&lt;/a&gt; a keyboard design with additional multimedia capabilities (which I wanted so bad). Microsoft recommends that there should be at least two USB interfaces in such a device. One should implement a ordinary keyboard compatible with BOOT interface, so such keyboard would be operational during system start up, when there is no OS support yet, and another one would implement the rest of desired keys such as play/pause, volume up, down and so on. I saw quite a few USB interface layouts conforming to this recommendations over the net, including my own keyboard connected to my computer as I write this, so I assume this is the right way to do this. 
&lt;a href=&quot;http://www.usblyzer.com/reports/usb-properties/usb-keyboard.html&quot;&gt;And here is an example of&lt;/a&gt; USB interface layout as mentioned earlier. HID reports are also provided. So I moved to lower level tiers and it was not so simple. 
&lt;a href=&quot;https://code.google.com/p/iwasz-sandbox/source/browse/#svn%2Ftrunk%2Ftm4c123-drama-button-v2&quot;&gt;Here you can find all the code that is inside the button&lt;/a&gt;. All the magic is done in main.c which could be split in several smaller files, but who cares. Firstly there are USB descriptors. Standard and HID ones:&lt;/p&gt;

&lt;div class=&quot;language-cpp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tConfigSection&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;allConfigSections&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;configSection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;interfaceSection1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hidKeyboardSection1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endpointSection1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;interfaceSection2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hideKeyboardSection2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endpointSection2&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Next you have callbacks. My code is heavily based on TI examples, but in some places it is simplified where no advanced functionality is needed. Custom requests are handled in 
&lt;code class=&quot;highlighter-rouge&quot;&gt;onRequest&lt;/code&gt;
where you can find bits responsible for sending and receiving configuration from the host (using another program running on a PC which is linked below). Configuration (i.e. what key combination should be sent to the host when “any-key” is pressed) is stored in eeprom (functions 
&lt;code class=&quot;highlighter-rouge&quot;&gt;readEeprom&lt;/code&gt;
 and 
&lt;code class=&quot;highlighter-rouge&quot;&gt;saveEeprom&lt;/code&gt;
). And of course in 
&lt;code class=&quot;highlighter-rouge&quot;&gt;main&lt;/code&gt;
 function you can find the main loop with buttons polling and report sending. After connecting the device to a Linux PC it introduces itself as two interface HID device which is silently recognized by Linux (and not so silently by Windows which searches for some drivers for it). What distinguishes this HID keyboard from others is that it recognizes two additional control requests from the host PC which enables user to store and receive combination of keys this device sends when pressed. This requests are prepared in PC application which looks like this:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/904881400189746306-300x109.png&quot; alt=&quot;Any key host app&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Every button on the main screen can be toggled (on the picture above the “play/pause” one is turned on) which immediately sends the configuration data which is stored in eeprom. After closing the host application (which then releases the USB device to the OS) button works as programmed, in situation depicted above behaving as a play/pause keyboard button. Play/pause was my initial intention and I am using it with this function right now, but friend of mine used in on presentation (as arrow down), and also I tested ctrl-alt-del, ctrl-shift-t (eclipse CDT open element), and power among others. Maximum simultaneously pressed keys which can be simulated is 8 for control ones (like ctrl, shift, alt etc) and 6 for regular ones.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/IMG_20140609_234756-300x225.jpg&quot; alt=&quot;Any key internals&quot; /&gt;&lt;/p&gt;

&lt;p&gt;So there you have it. Feel free to post questions etc. I am also wondering about a “mass production experiment” which would aim to make, say, 10 of those things (with cheaper micro of course!) and sell them on 
&lt;a href=&quot;https://www.tindie.com/&quot;&gt;tindie&lt;/a&gt; (I have never sold anything made by myself yet). What do you think? Would you buy one of these? What would be reasonable price for this (it is only one button after all… + PC app). I made some very rough calculations and the total cost of one device (assuming production of 100 pcs) would be somewhere around $10, when using MSP430 as a µC and importing casings from China. Not to mention boxes to pack the stuff, soldering (probably in some kind of reflow oven) and sending it all together. So for now it seems overwhelming for me, but who knows.&lt;/p&gt;

&lt;p&gt;And for something completely different : what happens when you connect a USB device with VBUS and GND shorted:&lt;/p&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Jun  4 08:58:52 diora kernel: &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;  998.928731] hub 2-1:1.0: over-current condition on port 1
Jun  4 08:58:52 diora kernel: &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;  999.136827] hub 2-1:1.0: over-current condition on port 2
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;… and you can hear humming in headphones connected to the PC.&lt;/p&gt;

&lt;dl&gt;
  &lt;dt&gt;&lt;strong&gt;EDIT&lt;/strong&gt;&lt;/dt&gt;
  &lt;dd&gt;User jancumps on the EEVBlog forums pointed out, that there is an 
&lt;a href=&quot;https://www.indiegogo.com/projects/very-serious-button&quot;&gt;ongoing indiegogo campaign for a similar idea&lt;/a&gt;. Looks quite the same as mine :D&lt;/dd&gt;
  &lt;dt&gt;&lt;strong&gt;EDIT2&lt;/strong&gt;&lt;/dt&gt;
  &lt;dd&gt;Dave did a review of the “serious button” 
&lt;strong&gt;this design is not mine, it only looks the same&lt;/strong&gt;
:&lt;/dd&gt;
&lt;/dl&gt;

&lt;p&gt;http://www.youtube.com/watch?v=f2Tr8r2j8wQ&amp;amp;t=12m44s&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;EDIT3&lt;/strong&gt;
 (09/2014) : 
&lt;a href=&quot;https://www.indiegogo.com/projects/bttn/x/7931932&quot;&gt;Another one on indiegogo with goal of $100k!&lt;/a&gt;&lt;/p&gt;</content>

      
      
      
      
      

      

      
        <category term="electronics" />
      

      

      
        <summary type="html">…which in fact is an one button HID keyboard which you can reprogram to be any key or combination of keys you wish (open-source hardware and software). For starters here’s a bunch of links:</summary>
      

      
      
    </entry>
  
  
  
    <entry>
      
      <title type="html">Toolchain for Cortex-M4/M0/M7</title>
      
      
      <link href="http://iwasz.pl/electronics/toolchain-for-cortex-m4/" rel="alternate" type="text/html" title="Toolchain for Cortex-M4/M0/M7" />
      
      <published>2014-05-27T00:00:00+02:00</published>
      <updated>2014-05-27T00:00:00+02:00</updated>
      <id>http://iwasz.pl/electronics/toolchain-for-cortex-m4</id>
      <content type="html" xml:base="http://iwasz.pl/electronics/toolchain-for-cortex-m4/">&lt;h1 id=&quot;installation&quot;&gt;Installation&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;EDIT&lt;/strong&gt; : do not accidentally press ctrl-c. It exists menu-config immediately.&lt;/p&gt;

&lt;p&gt;Important links:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://gcc.gnu.org/onlinedocs/gcc/ARM-Options.html&quot;&gt;http://gcc.gnu.org/onlinedocs/gcc/ARM-Options.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are brief instructions for creating your own GCC based tool-chain for a Cortex-M4 microcontroller, heavily based on 
&lt;a href=&quot;http://www.kitware.com/blog/home/post/426&quot;&gt;this post&lt;/a&gt;. I tried a few precompiled ones which I found on the Internet, but always wondered how to make one which would be configured specifically for my micro, not for “ARM” in general. Tool-chains generated by the following method was tested by me on ST STM32F407 and Texas Instruments TIVA-C TM4C123 (i.e. one tool-chain for these two µC since they both include the same CPU). My setup as I write this:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Host operating system : Ubuntu 14.04 - 16.10&lt;/li&gt;
  &lt;li&gt;Kernel : 3.13.0-24-generic - 4.8.0-30-generic&lt;/li&gt;
  &lt;li&gt;Few GB of free space on HD.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Making a toolchain is hard, therefore wise people over the net developed tools to simplify the process. Few years ago, when I attempted to build a GCC tool-chain I struggled with lack of information, complexity of the process, and variety of recipes, which all seemed were extremely complex, and in some point in the process I was struck with problem I couldn’t solve. Then I found crosstool-NG - it may seem funny, but all this stuff was new to me, and I was looking for the best way possible to finish the task, some “canonical” way of building a cross-compiler, and for me, crosstool-NG is exactly this. 
&lt;a href=&quot;https://crosstool-ng.github.io/docs/install/&quot;&gt;Lets grab the newest version from its website&lt;/a&gt; and follow the installation instructions (this step will build only the crosstool-NG itself, 
read the &lt;strong&gt;EDIT note below before doing this&lt;/strong&gt;):&lt;/p&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;mkdir &lt;/span&gt;my-toolchain
&lt;span class=&quot;nb&quot;&gt;cd &lt;/span&gt;my-toolchain

&lt;span class=&quot;c&quot;&gt;# Pay attention which version is the newest. As of writing this, the newest was&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# 1.19.0, but at http://crosstool-ng.org/download/crosstool-ng/ the &quot;header-file&quot; &lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# incorrectly indicated the 1.18.0 version&lt;/span&gt;
wget http://crosstool-ng.org/download/crosstool-ng/crosstool-ng-1.19.0.tar.bz2

&lt;span class=&quot;nb&quot;&gt;tar &lt;/span&gt;jxvf crosstool-ng-1.19.0.tar.bz2 
&lt;span class=&quot;nb&quot;&gt;cd &lt;/span&gt;crosstool-ng-1.19.0/

&lt;span class=&quot;c&quot;&gt;# Resolve some dependencies. EDIT Ubuntu 15.04 wants libtool-bin as well.&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;apt-get &lt;span class=&quot;nb&quot;&gt;install &lt;/span&gt;bison flex gperf texinfo gawk libtool libtool-bin automake libncurses5-dev libexpat-dev help2man

&lt;span class=&quot;c&quot;&gt;# Provide a prefix to some destination which PATH points to.&lt;/span&gt;
./configure &lt;span class=&quot;nt&quot;&gt;--prefix&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/home/iwasz/local/
make
make &lt;span class=&quot;nb&quot;&gt;install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;EDIT (2016-12)&lt;/strong&gt; It seems, that the newest official release available today is 1.22, which is more than year old. The older ct-ng is, the older GCC, and libraries it provides, which may cause a problems on newer systems. For example making a cross-gcc version 5.3 using ct-ng version 1.22 on Ubuntu 16.10 (which uses GCC 6.2) resulted in compilation error during GCC stage. Thus I think, that the best option is to start with development ct-ng from github repo. Instructions are 
&lt;a href=&quot;https://github.com/crosstool-ng/crosstool-ng&quot;&gt;here&lt;/a&gt; but basically you only need to:&lt;/p&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;git clone git@github.com:crosstool-ng/crosstool-ng.git
&lt;span class=&quot;nb&quot;&gt;cd &lt;/span&gt;crosstool-ng
./bootstrap
./configure &lt;span class=&quot;nt&quot;&gt;--prefix&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/home/iwasz/local/
make
make &lt;span class=&quot;nb&quot;&gt;install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now we perform some setup. All features of our future tool-chain will be set during this step:&lt;/p&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# cd back, so we are in &quot;my-toolchain&quot; directory again.&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt; ..
&lt;span class=&quot;nb&quot;&gt;mkdir &lt;/span&gt;staging
&lt;span class=&quot;nb&quot;&gt;cd &lt;/span&gt;staging
ct-ng  menuconfig
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The last command brings the following menu-config tool:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/01-start-screen-300x222.png&quot; alt=&quot;01-start-screen&quot; /&gt;&lt;/p&gt;

&lt;h1 id=&quot;paths-and-misc-options&quot;&gt;Paths and misc options&lt;/h1&gt;

&lt;ul&gt;
  &lt;li&gt;Try features marked as EXPERIMENTAL : &lt;strong&gt;Y&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;del&gt;Prefix : ${HOME}/local/share/${CT_TARGET} . Provide a destination folder that suits your needs, give descriptive name if you plan to host more than one crosscompilers.&lt;/del&gt;&lt;/li&gt;
  &lt;li&gt;Number of parallel jobs : 8 (depends on host capabilities of course).&lt;/li&gt;
  &lt;li&gt;Uncheck “Render the toolchain read-only” (I find it annoying to have read only directory in my stuff, it’s problematic to delete it later, you have to chmod etc).&lt;/li&gt;
  &lt;li&gt;Check “Debug Crosstool-NG”, “Save intermediate steps”, and “gzip saved states” as 
&lt;a href=&quot;http://stackoverflow.com/questions/9900005/is-it-possible-to-speed-up-crosstool-ng-builds-once-errors-have-occured&quot;&gt;described here&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;/assets/02-paths-and-misc-285x300.png&quot; alt=&quot;02-paths-and-misc-285x300&quot; /&gt;&lt;/p&gt;

&lt;h1 id=&quot;target-options&quot;&gt;Target options&lt;/h1&gt;

&lt;ul&gt;
  &lt;li&gt;Target Architecture : &lt;strong&gt;arm&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;del&gt;(cortexm4) Suffix to the arch-part (breaks the build!)&lt;/del&gt;. EDIT : tried with this turned on in 1.21.0, and works.&lt;/li&gt;
  &lt;li&gt;&lt;del&gt;Use the MMU : N&lt;/del&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The following 3 options can be somewhat tricky because when you set “
Emit assembly for CPU”, the two other (being “Architecture level” and “
Tune for CPU”) will disappear. So either you set the first mentioned one or two other.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Architecture level (correspods to -march flag). For Cortex-M4 use 
&lt;strong&gt;armv7e-m+fp&lt;/strong&gt;
 (armv7-m for older compilers, probably before GCC-4.9). Pay attention that every architecture type has its own additional parameters which can be obtained from the man page. In this case I used “+fp” which stands for “the single-precision VFPv4 floating-point instructions”, just to be sure that hard-fp assembly instructions are emmited. 
&lt;strong&gt;EDIT :&lt;/strong&gt; armv6-m for Cortex-M0. You can always check it in the “programming manual” of every STM32 part in chapter entitled like “About the STM32 Cortex-M0 processor and core peripherals”&lt;/li&gt;
  &lt;li&gt;Tune for CPU (-mtune) : use &lt;strong&gt;cortex-m4&lt;/strong&gt; or wathever you are using. Check the man page.&lt;/li&gt;
  &lt;li&gt;Emit assembly for CPU (-mcpu). Use this &lt;strong&gt;instead&lt;/strong&gt;
 of the two above if you preffer, but remember, that GCC will then try to automatically figure out what architecture and tune flags to use. The values are the same as for -mtune, so we can use 
&lt;strong&gt;cortex-m4&lt;/strong&gt;
 for Cortex-M4 (full list of available options can be found in GCC manual somewhere near -mcpu phrase). 
&lt;strong&gt;&lt;a href=&quot;https://gcc.gnu.org/onlinedocs/gcc/ARM-Options.html&quot;&gt;Or here.&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;Use specific FPU : fpv4-sp-d16. Cortex-M4 can have FPU, but not necessarily (with FPU it is called Cortex-M4F, and Cortex-M4 without). But the fact is I found this option somewhere over the net, and I am a little bit confused on the topic of FPU. For STM32H7 you would use fpv5-d16 for double precision and fpv5-sp-d16 for single precision.&lt;/li&gt;
  &lt;li&gt;Floating point : &lt;strong&gt;hardware&lt;/strong&gt; (FPU). &lt;strong&gt;EDIT&lt;/strong&gt; : M0 have no FPU.&lt;/li&gt;
  &lt;li&gt;Default instruction set mode (&lt;strong&gt;thumb&lt;/strong&gt;).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;/assets/03-target-options-300x240.png&quot; alt=&quot;03-target-options&quot; /&gt;&lt;/p&gt;

&lt;h1 id=&quot;toolchain-options&quot;&gt;Toolchain options.&lt;/h1&gt;
&lt;ul&gt;
  &lt;li&gt;Add some cool Toolchain ID string.&lt;/li&gt;
  &lt;li&gt;Set “Tuple’s vendor string” to none.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;/assets/04-toolchain-options-300x260.png&quot; alt=&quot;04-toolchain-options&quot; /&gt;&lt;/p&gt;

&lt;h1 id=&quot;operating-system&quot;&gt;Operating System.&lt;/h1&gt;

&lt;ul&gt;
  &lt;li&gt;Set Target OS to bare-metal:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;/assets/05-operating-system-300x67.png&quot; alt=&quot;05-operating-system&quot; /&gt;&lt;/p&gt;

&lt;h1 id=&quot;binary-utilities&quot;&gt;Binary utilities&lt;/h1&gt;
&lt;ul&gt;
  &lt;li&gt;Binary format: ELF&lt;/li&gt;
  &lt;li&gt;binutils version (&lt;strong&gt;2.22&lt;/strong&gt;) - latest which is not marked as EXPERIMENTAL. &lt;strong&gt;EDIT&lt;/strong&gt; just recently I went with 2.24 (EXPERIMENTAL), and everything seems to be OK.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;/assets/06-binary-utilities-300x141.png&quot; alt=&quot;binary utilities&quot; /&gt;&lt;/p&gt;

&lt;h1 id=&quot;c-compiler&quot;&gt;C compiler&lt;/h1&gt;
&lt;ul&gt;
  &lt;li&gt;Show Linaro versions : &lt;strong&gt;Y&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;gcc version (&lt;strong&gt;linaro-4.8-2013.06-1&lt;/strong&gt;)&lt;/li&gt;
  &lt;li&gt;C++ : &lt;strong&gt;Y&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;/assets/07-c-compiler-300x262.png&quot; alt=&quot;C compiler&quot; /&gt;&lt;/p&gt;

&lt;h1 id=&quot;c-library&quot;&gt;C-library&lt;/h1&gt;
&lt;ul&gt;
  &lt;li&gt;C library (&lt;strong&gt;newlib&lt;/strong&gt;)&lt;/li&gt;
  &lt;li&gt;newlib version (&lt;strong&gt;2.0.0&lt;/strong&gt; (EXPERIMENTAL)) - the newest, and works OK.&lt;/li&gt;
  &lt;li&gt;Disable the syscalls supplied with newlib : &lt;strong&gt;Y&lt;/strong&gt;
 - I provide my own syscalls in every program. BTW I had some problems when his option was checked (crt0 missing?)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;/assets/08-c-library-300x154.png&quot; alt=&quot;C library config&quot; /&gt;&lt;/p&gt;

&lt;h1 id=&quot;debuging&quot;&gt;Debuging&lt;/h1&gt;
&lt;ul&gt;
  &lt;li&gt;gdb : &lt;strong&gt;Y&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;/assets/09-debug.png&quot; alt=&quot;Debugging options&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Then descend into “GDB” menu and check and choose the newest from linaro, and set Enable python scripting to &lt;strong&gt;N&lt;/strong&gt; (caused build problems for me) &lt;strong&gt;EDIT&lt;/strong&gt; : qtcreator requires python support in GDB:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/10-gdb-cfg-300x145.png&quot; alt=&quot;Gdb config&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Exit menu-config (few times ESC, and save when prompted) and finally build the toolchain:&lt;/p&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;unset &lt;/span&gt;LD_LIBRARY_PATH 
ct-ng build
&lt;span class=&quot;nb&quot;&gt;tail&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-f&lt;/span&gt; build.log &lt;span class=&quot;c&quot;&gt;# in another console (not necessary if debug options were set)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The build process takes some time (30-60 minutes), and if in some point for some reason the build fail, first place you check is the build.log file in staging directory (therefore I pasted this tail -f command earlier, but of course it does not matter how you display the file). For example, in my case, the crosstool-NG decided to fail with this:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;... kilobytes, megabytes of logs ....
[ALL  ]    checking whether to use python... yes
[ALL  ]    checking for python... /usr/bin/python
[ALL  ]    checking for python2.7... no
[ERROR]    configure: error: python is missing or unusable
[ERROR]    make[2]: *** [configure-gdb] Error 1
[ALL  ]    make[2]: Leaving directory `/home/iwasz/Documents/my-toolchain/staging/.build/arm-unknown-eabi/build/build-gdb-cross&apos;
[ERROR]    make[1]: *** [all] Error 2
[ALL  ]    make[1]: Leaving directory `/home/iwasz/Documents/my-toolchain/staging/.build/arm-unknown-eabi/build/build-gdb-cross&apos;
[ERROR]  
[ERROR]  &amp;gt;&amp;gt;
[ERROR]  &amp;gt;&amp;gt;  Build failed in step &apos;Installing cross-gdb&apos;
[ERROR]  &amp;gt;&amp;gt;        called in step &apos;(top-level)&apos;
[ERROR]  &amp;gt;&amp;gt;
[ERROR]  &amp;gt;&amp;gt;  Error happened in: CT_DoExecLog[scripts/functions@257]
[ERROR]  &amp;gt;&amp;gt;        called from: do_debug_gdb_build[scripts/build/debug/300-gdb.sh@170]
[ERROR]  &amp;gt;&amp;gt;        called from: do_debug[scripts/build/debug.sh@35]
[ERROR]  &amp;gt;&amp;gt;        called from: main[scripts/crosstool-NG.sh@632]
[ERROR]  &amp;gt;&amp;gt;
[ERROR]  &amp;gt;&amp;gt;  For more info on this error, look at the file: &apos;build.log&apos;
[ERROR]  &amp;gt;&amp;gt;  There is a list of known issues, some with workarounds, in:
[ERROR]  &amp;gt;&amp;gt;      &apos;/home/iwasz/local/share/doc/crosstool-ng/ct-ng.1.19.0/B - Known issues.txt&apos;
[ERROR]  
[ERROR]  (elapsed: 58:52.70)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;I didn’t thought long on this one (apt-get install libpython2.7-dev maybe???), but disabled the python support for GDB (I modified the instructions accordingly, so hopefully you haven’t had the same error). But in case you had, you should resolve the error (maybe change the configuration using menuconfig, or resolve the problem in other ways, depending on the cause) and rerun ct-ng, or 
&lt;a href=&quot;http://stackoverflow.com/questions/9900005/is-it-possible-to-speed-up-crosstool-ng-builds-once-errors-have-occured&quot;&gt;refer to this stack-overflow thread for more info on speeding up the process&lt;/a&gt; after build has failed.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;&lt;strong&gt;Edit&lt;/strong&gt; Feb 2015 : I recently made cross-compiler x86_64 -&amp;gt; i686 to be able to make 32bit binaries on 64bit box. Statically linked binaries made with it crashed with message:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;FATAL: kernel too old
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Following suggestions found 
&lt;a href=&quot;http://stackoverflow.com/questions/6941332/anticipate-kernel-too-old-errors-between-2-6-16-and-2-6-26-kernel-versions&quot;&gt;here&lt;/a&gt;, I found that indeed, my binaries were (output of file command):&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;ELF 32-bit LSB  executable, Intel 80386, version 1 (GNU/Linux), statically linked, for GNU/Linux 3.15.4, not stripped
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;But my uname -a is:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Linux xxx 3.13.0-44-generic #73-Ubuntu SMP Tue Dec 16 00:22:43 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The solution is to instruct crosstool-ng so it compile glibc/eglibc with older kernel support. Invoke ct-ng menuconfig and:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Go into “C-library”&lt;/li&gt;
  &lt;li&gt;Go into “Minimum supported kernel version (Specific kernel version) —&amp;gt;”&lt;/li&gt;
  &lt;li&gt;Check “(X) Specific kernel version”&lt;/li&gt;
  &lt;li&gt;“ESC ESC” and make sure that : “(2.6.9) Minimum kernel version to support”&lt;/li&gt;
&lt;/ol&gt;

&lt;hr /&gt;

&lt;p&gt;&lt;strong&gt;EDIT&lt;/strong&gt; (mar 2016). For the second time I encountered an error like this:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[ALL  ]    /usr/bin/install: cannot stat &apos;.../.build/src/newlib-linaro-2.2.0-2015.01/libgloss/arm/linux.specs&apos;: No such file or directory
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;According to 
&lt;a href=&quot;https://sourceware.org/ml/crossgcc/2015-02/msg00026.html&quot;&gt;this&lt;/a&gt;, and especially 
&lt;a href=&quot;https://github.com/crosstool-ng/crosstool-ng/issues/206&quot;&gt;this&lt;/a&gt; , the error is caused by some bug in newlib itself. User ‘
&lt;a href=&quot;https://github.com/bhundven&quot;&gt;bhundven&lt;/a&gt;&lt;strong&gt;‘&lt;/strong&gt;
sugested that suffix ‘hf’ to ‘eabi’ (making it ‘eabihf’) is causing problems, so I turned off ‘Target options —&amp;gt; append ‘hf’ to the tuple (EXPERIMENTAL)’, and it helped.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;EDIT (Jul 2018). Toolchain for Cortex-M0 was successfully tested on BlueNRG-1 and BlueNRG-2 IC’s, and works just fine.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;Special remarks for LPC812 (March 2020)&lt;/p&gt;

&lt;p&gt;This µC has so tiny amount of RAM and flash, that normal version of newlib is to heavy for it and compiler made using above instructions would not be able to produce a simple hello-world program that would fit in 16k of flash.&lt;/p&gt;

&lt;p&gt;A glimpse into one of CMakeLists.txt provided by NXP as an example, shows that they use nano.specs, which instruct GCC to use libc_nano.a and libg_nano.a (when -g) instead of their full counterparts. I have been unsuccessful assembling a toolchain which would include libraries with those exact names (I mean with nano suffixes) but I finally found a way to compile the lighter libraries that would fit on the LPC812 instead of the usual ones. So even if they have usual names like libc.a, they are smaller and lighter, just like libc_nano.a would be. Here are the options:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/newlib-nano-250x300.png&quot; alt=&quot;New lib nano configuration options&quot; /&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Here is the 
&lt;a href=&quot;http://iwasz.pl/files/ct-ng-config-nano&quot;&gt;config file itself&lt;/a&gt;.&lt;/li&gt;
  &lt;li&gt;Here is a 
&lt;a href=&quot;https://stackoverflow.com/questions/50154137/how-to-rebuild-newlib-and-newlib-nano-of-gnu-arm-embedded-toolchain&quot;&gt;stack overflow quiestion that helped me&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;</content>

      
      
      
      
      

      

      
        <category term="electronics" />
      

      

      
        <summary type="html">Installation</summary>
      

      
      
    </entry>
  
  
  
    <entry>
      
      <title type="html">STM32F407 DMA early tests</title>
      
      
      <link href="http://iwasz.pl/electronics/stm32f407-dma-early-tests/" rel="alternate" type="text/html" title="STM32F407 DMA early tests" />
      
      <published>2014-01-13T00:00:00+01:00</published>
      <updated>2014-01-13T00:00:00+01:00</updated>
      <id>http://iwasz.pl/electronics/stm32f407-dma-early-tests</id>
      <content type="html" xml:base="http://iwasz.pl/electronics/stm32f407-dma-early-tests/">&lt;p&gt;Research notes. Useful links:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Frank’s site (very valuable stuff) : 
&lt;a href=&quot;http://blog.frankvh.com/2011/08/18/stm32f2xx-dma-controllers/&quot;&gt;part 1&lt;/a&gt;, &lt;a href=&quot;http://blog.frankvh.com/2011/11/21/stm32f2xx-dma-controllers-part-2/&quot;&gt;part 2&lt;/a&gt;, and 
&lt;a href=&quot;http://blog.frankvh.com/2012/01/13/stm32f2xx-stm32f4xx-dma-maximum-transactions/&quot;&gt;part 3&lt;/a&gt; (part 3 covers then undocumented bug in µCs which Frank found).&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Direct_memory_access&quot;&gt;Wikipedia article&lt;/a&gt; for complete beginners like me.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.st.com/web/en/resource/technical/document/reference_manual/DM00031020.pdf&quot;&gt;Reference manual&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://code.google.com/p/iwasz-sandbox/source/browse/#svn%2Ftags%2Fstm32-dma-tests-simple-DMA-read-usart&quot;&gt;Code for this article&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Direct_memory_access&quot;&gt;DMA&lt;/a&gt; is a peripheral that can copy data between other peripherals and memory or between memory and memory. It used to be implemented in form of 
&lt;a href=&quot;http://en.wikipedia.org/wiki/Intel_8237&quot;&gt;separate IC&lt;/a&gt; in early days, but in modern µCs it is of course integrated inside the single chip.&lt;/p&gt;

&lt;p&gt;STM32 DMA peripherals are able to copy data from memory to peripheral, from peripheral to memory and from memory to the other place in memory (for example from RAM to FLASH as StdPeriph example shows). There are two DMA controllers : DMA1 and DMA2 and both have 8 streams. I see a stream as a some kind of physical, bi-directional connection between the DMA controller and some other peripheral. Those 16 streams cover all (most?) peripherals meaning that one stream is connected to more than one peripheral. For example if one is about to send data using USART1 he has to use exactly DMA2_Stream7, or if he wants to receive data from SPI3_RX he has to use DMA1_Stream0 or DMA1_Stream2, because apparently SPI3_RX is connected to both of those streams (see table 43 and 44 in reference manual of STM32F407).&lt;/p&gt;

&lt;p&gt;DMA works automatically meaning that if there is some new data it will be copied without user code (and CPU) involved. It is possible thanks to channels, which I imagine as signals (like GUI signals if you know what I mean) connected between DMA controller and the peripheral (there is also something called “arbiter” between them). Peripheral can send a request (signal) to the DMA if it has new data, and DMA can then process it. At the same time DMA acknowledges it has got this new portion of data, and peripheral releases the request. Each stream can “listen” to its 8 channels, so there are 2 controllers * 8 streams * 8 channels = 128 configuration combinations, and that way every peripheral can have its own communication path with the DMA.&lt;/p&gt;

&lt;p&gt;Streams have configurable priorities in case two or more streams request DMA controller attention. If two or more streams have the same priority, then stream with lower number wins. The bit of hardware called “arbiter” manages those priorities and decides which stream goes first.&lt;/p&gt;

&lt;p&gt;So here comes the first DMA test I wrote (tested on STM32F407-DISCOVERY). It writes to USART1:&lt;/p&gt;

&lt;div class=&quot;language-cpp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cp&quot;&gt;#include &amp;lt;stm32f4xx.h&amp;gt;
#include &quot;logf.h&quot;
&lt;/span&gt;
&lt;span class=&quot;cm&quot;&gt;/**
 * For printf, and USART1 in general.
 */&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;initUsart&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;RCC_APB2PeriphClockCmd&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;RCC_APB2Periph_USART1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ENABLE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;GPIO_InitTypeDef&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;gpioInitStruct&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;RCC_AHB1PeriphClockCmd&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;RCC_AHB1Periph_GPIOB&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ENABLE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;gpioInitStruct&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GPIO_Pin&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;GPIO_Pin_6&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;GPIO_Pin_7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;gpioInitStruct&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GPIO_Mode&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;GPIO_Mode_AF&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;gpioInitStruct&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GPIO_Speed&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;GPIO_High_Speed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;gpioInitStruct&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GPIO_OType&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;GPIO_OType_PP&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;gpioInitStruct&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GPIO_PuPd&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;GPIO_PuPd_UP&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;GPIO_Init&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GPIOB&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;gpioInitStruct&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;GPIO_PinAFConfig&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GPIOB&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;GPIO_PinSource6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;GPIO_AF_USART1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// TX&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;GPIO_PinAFConfig&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GPIOB&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;GPIO_PinSource7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;GPIO_AF_USART1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// RX&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;USART_InitTypeDef&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;usartInitStruct&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;usartInitStruct&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;USART_BaudRate&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;9600&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;usartInitStruct&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;USART_WordLength&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;USART_WordLength_8b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;usartInitStruct&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;USART_StopBits&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;USART_StopBits_1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;usartInitStruct&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;USART_Parity&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;USART_Parity_No&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;usartInitStruct&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;USART_Mode&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;USART_Mode_Rx&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;USART_Mode_Tx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;usartInitStruct&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;USART_HardwareFlowControl&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;USART_HardwareFlowControl_None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;USART_Init&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;USART1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;usartInitStruct&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;USART_Cmd&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;USART1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ENABLE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;kt&quot;&gt;uint8_t&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;myStrlen&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;uint8_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;len&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;o&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;cm&quot;&gt;/**
 * Test1
 */&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;initDma&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;outputBuffer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;cm&quot;&gt;/*
         * Reset DMA Stream registers (for debug purpose). For DMA2_Stream7 exmplanation read on.
         * It also disables the stream. Stream must be disabled prior configure it. Otherwise it can
         * misbehave.
         */&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;DMA_DeInit&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DMA2_Stream7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;cm&quot;&gt;/*
         * Check if the DMA Stream is disabled before enabling it.
         * Note that this step is useful when the same Stream is used multiple times:
         * enabled, then disabled then re-enabled... In this case, the DMA Stream disable
         * will be effective only at the end of the ongoing data transfer and it will
         * not be possible to re-configure it before making sure that the Enable bit
         * has been cleared by hardware. If the Stream is used only once, this step might
         * be bypassed.
         */&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DMA_GetCmdStatus&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DMA2_Stream7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DISABLE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;cm&quot;&gt;/* Configure the DMA stream. */&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;DMA_InitTypeDef&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;dmaInitStructure&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;cm&quot;&gt;/*
         * Possible values for DMA_Channel are DMA_Channel_[0..7]. Refer to table 44 in reference manual
         * mentioned earlier. USART1_RX is communicate with DMA via streams 2 and 5 (both on channel 4).
         * USART1_TX uses stream7 / channel 4.
         */&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;dmaInitStructure&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DMA_Channel&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DMA_Channel_4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;cm&quot;&gt;/*
         * Possible values : DMA_DIR_PeripheralToMemory, DMA_DIR_MemoryToPeripheral,
         * DMA_DIR_MemoryToMemory.
         */&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;dmaInitStructure&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DMA_DIR&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DMA_DIR_MemoryToPeripheral&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;cm&quot;&gt;/* Why DMA_PeripheralBaseAddr is of type uint32_t? Shouldn&apos;t it be void *? */&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;dmaInitStructure&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DMA_PeripheralBaseAddr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;uint32_t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;USART1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DR&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;dmaInitStructure&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DMA_Memory0BaseAddr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;uint32_t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;outputBuffer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;cm&quot;&gt;/*
         * Only valid values here are : DMA_PeripheralDataSize_Byte, DMA_PeripheralDataSize_HalfWord,
         * DMA_PeripheralDataSize_Word
         */&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;dmaInitStructure&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DMA_PeripheralDataSize&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DMA_PeripheralDataSize_Byte&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;cm&quot;&gt;/*
         * I guess, that for memory is is always good to use DMA_MemoryDataSize_Word (32bits), since this is
         * a 32 bit micro. But haven&apos;t checked that. But here I use Byte instead for easier  DMA_BufferSize
         * calculations.
         */&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;dmaInitStructure&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DMA_MemoryDataSize&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DMA_MemoryDataSize_Byte&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;cm&quot;&gt;/*
         * Length of the data to be transferred by the DMA. Unit of this length is DMA_MemoryDataSize when
         * direction is from memory to peripheral or DMA_PeripheralDataSize otherwise. Since I set both
         * sizes to one byte, I simply put strlen here.
         */&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;dmaInitStructure&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DMA_BufferSize&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;myStrlen&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;outputBuffer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;cm&quot;&gt;/*
         * DMA_PeripheralInc_Disable means to read or to write to the same location everytime.
         * DMA_MemoryInc_Enable would increase memory or peripheral location after each read/write.
         */&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;dmaInitStructure&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DMA_PeripheralInc&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DMA_PeripheralInc_Disable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;dmaInitStructure&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DMA_MemoryInc&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DMA_MemoryInc_Enable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;cm&quot;&gt;/* DMA_Mode_Normal or DMA_Mode_Circular here. */&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;dmaInitStructure&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DMA_Mode&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DMA_Mode_Normal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;cm&quot;&gt;/* DMA_Priority_Low, DMA_Priority_Medium, DMA_Priority_High or DMA_Priority_VeryHigh */&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;dmaInitStructure&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DMA_Priority&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DMA_Priority_VeryHigh&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;cm&quot;&gt;/* DMA_FIFOMode_Disable means direst mode, DMA_FIFOMode_Enable means FIFO mode. FIFO is good. */&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;dmaInitStructure&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DMA_FIFOMode&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DMA_FIFOMode_Disable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;cm&quot;&gt;/*
         * DMA_FIFOThreshold_1QuarterFull, DMA_FIFOThreshold_HalfFull, DMA_FIFOThreshold_3QuartersFull or
         * DMA_FIFOThreshold_Full.
         */&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;dmaInitStructure&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DMA_FIFOThreshold&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DMA_FIFOThreshold_Full&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;cm&quot;&gt;/*
         * Specifies whether to use single or busrt mode. If burst, then it specifies how much &quot;beats&quot;
         * to use. DMA_MemoryBurst_Single, DMA_MemoryBurst_INC4, DMA_MemoryBurst_INC8 or
         * DMA_MemoryBurst_INC16.
         */&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;dmaInitStructure&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DMA_MemoryBurst&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DMA_MemoryBurst_Single&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;dmaInitStructure&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DMA_PeripheralBurst&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DMA_PeripheralBurst_Single&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;cm&quot;&gt;/* Configure DMA, but still leave it turned off. */&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;DMA_Init&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DMA2_Stream7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dmaInitStructure&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;cm&quot;&gt;/* DMA_FlowCtrl_Memory, DMA_FlowCtrl_Peripheral */&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;DMA_FlowControllerConfig&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DMA2_Stream7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DMA_FlowCtrl_Memory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;cm&quot;&gt;/* Enable DMA interrupts. */&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;DMA_ITConfig&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DMA2_Stream7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DMA_IT_TC&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DMA_IT_HT&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DMA_IT_TE&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DMA_IT_DME&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DMA_IT_FE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ENABLE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;cm&quot;&gt;/*--------------------------------------------------------------------------*/&lt;/span&gt;

        &lt;span class=&quot;cm&quot;&gt;/* Enable the DMA Stream. */&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;DMA_Cmd&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DMA2_Stream7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ENABLE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;cm&quot;&gt;/*
         * And check if the DMA Stream has been effectively enabled.
         * The DMA Stream Enable bit is cleared immediately by hardware if there is an
         * error in the configuration parameters and the transfer is no started (ie. when
         * wrong FIFO threshold is configured ...)
         */&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;uint16_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;timeout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DMA_GetCmdStatus&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DMA2_Stream7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ENABLE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;timeout&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;--&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;cm&quot;&gt;/* Check if a timeout condition occurred */&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;timeout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;cm&quot;&gt;/* Manage the error: to simplify the code enter an infinite loop */&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;cm&quot;&gt;/* This would be a function parameter or something like that. */&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;outputBufferA&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Ala ma kota, a kot ma ale, to jest taki wierszyk z czytanki dla dzieci, ktora jest tylko w Polsce.&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\r\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;outputBufferB&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Wlazl kotek na plotek i mruga. Ladna to piosenka nie dluga. Nie dluga, nie krotka lecz w sam raz.&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\r\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;cm&quot;&gt;/*
         * Enable the peripheral clock for DMA2. I want to use DMA with USART1, so according to
         * table 44 in reference manual for STM32F407 (RM0090) this would be DMA2 peripheral.
         * Description in stm32f4xx_dma.c advises to do this as the first operarion.
         */&lt;/span&gt;

        &lt;span class=&quot;cm&quot;&gt;/*
         * Spend two fu.king nights on this. Docs says to use RCC_AHB1PeriphResetCmd, but use
         * RCC_AHB1PeriphClockCmd instead!!!
         */&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;//        RCC_AHB1PeriphResetCmd (RCC_AHB1Periph_DMA2, ENABLE);&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;RCC_AHB1PeriphClockCmd&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;RCC_AHB1Periph_DMA2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ENABLE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;cm&quot;&gt;/*--------------------------------------------------------------------------*/&lt;/span&gt;

        &lt;span class=&quot;cm&quot;&gt;/*
         * Enable the USART1 device as usual.
         */&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;initUsart&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;logf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Init&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\r\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;cm&quot;&gt;/*--------------------------------------------------------------------------*/&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;initDma&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;outputBufferA&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;cm&quot;&gt;/*
         * The DMA stream is turned on now and waits for DMA requests. As far as I know, if this
         * were to be memory-to-memory transfer, it would start immedialtely without enabling any
         * channels. But for peripherals one has to enable the channel for requests. After following
         * statement, you should see data on serial console.
         *
         * This statement enables the DMA internals in USART (this stuff which communicates with the DMA
         * controller).
         */&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;USART_DMACmd&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;USART1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;USART_DMAReq_Tx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ENABLE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;cm&quot;&gt;/* Waiting the end of Data transfer */&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;USART_GetFlagStatus&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;USART1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;USART_FLAG_TC&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;RESET&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DMA_GetFlagStatus&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DMA2_Stream7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DMA_FLAG_TCIF7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;RESET&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;logf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;It worked, and didn&apos;t hanged&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\r\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;cm&quot;&gt;/* Clear DMA Transfer Complete Flags */&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;DMA_ClearFlag&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DMA2_Stream7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DMA_FLAG_TCIF7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;cm&quot;&gt;/* Th has to be initialized once again AFAIK to send another portion of data. */&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;initDma&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;outputBufferB&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;cm&quot;&gt;/* Try to start it again */&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;USART_DMACmd&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;USART1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;USART_DMAReq_Tx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ENABLE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;cm&quot;&gt;/* Waiting the end of Data transfer */&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;USART_GetFlagStatus&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;USART1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;USART_FLAG_TC&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;RESET&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;logf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;It workedagain&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\r\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;cm&quot;&gt;/* Infinite loop */&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;</content>

      
      
      
      
      

      

      
        <category term="electronics" />
      

      

      
        <summary type="html">Research notes. Useful links: Frank’s site (very valuable stuff) :  part 1, part 2, and  part 3 (part 3 covers then undocumented bug in µCs which Frank found). Wikipedia article for complete beginners like me. Reference manual Code for this article</summary>
      

      
      
    </entry>
  
  
  
    <entry>
      
      <title type="html">STM32F407-DISCOVERY SDIO tests.</title>
      
      
      <link href="http://iwasz.pl/electronics/stm32f407-sdio-tests/" rel="alternate" type="text/html" title="STM32F407-DISCOVERY SDIO tests." />
      
      <published>2014-01-10T00:00:00+01:00</published>
      <updated>2014-01-10T00:00:00+01:00</updated>
      <id>http://iwasz.pl/electronics/stm32f407-sdio-tests</id>
      <content type="html" xml:base="http://iwasz.pl/electronics/stm32f407-sdio-tests/">&lt;ul&gt;
  &lt;li&gt;Started a new project (includes StdPeriph 1.3.0). Repository can be found 
&lt;a href=&quot;https://code.google.com/p/iwasz-sandbox/source/browse/#svn%2Ftrunk%2Fstm32-sdio-tests&quot;&gt;here&lt;/a&gt;.&lt;/li&gt;
  &lt;li&gt;First commit makes it simply output a “Init” text on the debug console (i.e. on USART1).&lt;/li&gt;
  &lt;li&gt;Browsing StdPeriph. Seems that stm32f4xx_sdio.[ch] are very low level (I’ve read SD card spec version 2.0).&lt;/li&gt;
  &lt;li&gt;Higher level stuff seems to be in StdPeriph here:&lt;/li&gt;
  &lt;li&gt;Utilities/STM32_EVAL/STM324x7I_EVAL&lt;/li&gt;
  &lt;li&gt;Utilities/STM32_EVAL/STM3240_41_G_EVAL&lt;/li&gt;
  &lt;li&gt;Utilities/STM32_EVAL/STM324x9I_EVAL&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But I don’t know why there is one version per dev-board. Looks like bad design to me at a first glance. Differences between those 3 files:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Lines 517/519 : Card presence is detected by different means (different pins are used on these boards). As far as I remember card presence detection is an optional feature, so maybe even it is not part of the standard. That would explain why different pins are used on the boards (I expect, that standard pins are laid out the same on …?).&lt;/li&gt;
  &lt;li&gt;Lines 1570/1572 different parameter passed to 
&lt;code class=&quot;highlighter-rouge&quot;&gt;SDIO_ITConfig&lt;/code&gt; in function 
&lt;code class=&quot;highlighter-rouge&quot;&gt;SD_WriteMultiBlocks&lt;/code&gt;. One dev-board uses 
&lt;code class=&quot;highlighter-rouge&quot;&gt;SDIO_IT_RXOVERR&lt;/code&gt; and the other two use
&lt;code class=&quot;highlighter-rouge&quot;&gt;SDIO_IT_TXUNDERR&lt;/code&gt; (among others, this is a bitmask).&lt;/li&gt;
  &lt;li&gt;Copied STM324x9I_EVAL sdio routines to my source tree.&lt;/li&gt;
  &lt;li&gt;Included code from the SDIO example : 
&lt;code class=&quot;highlighter-rouge&quot;&gt;Project/STM32F4xx_StdPeriph_Examples/SDIO/SDIO_uSDCard&lt;/code&gt;. Serial console went crazy and shows some gibberish, so I can’t see my debug messages, but card previously filled with random data now shows :&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;root@diora:~# hexdump &lt;span class=&quot;nt&quot;&gt;-n&lt;/span&gt; 128 /dev/sdc 
0000000 0100 0302 0504 0706 0908 0b0a 0d0c 0f0e
0000010 1110 1312 1514 1716 1918 1b1a 1d1c 1f1e
0000020 2120 2322 2524 2726 2928 2b2a 2d2c 2f2e
0000030 3130 3332 3534 3736 3938 3b3a 3d3c 3f3e
0000040 4140 4342 4544 4746 4948 4b4a 4d4c 4f4e
0000050 5150 5352 5554 5756 5958 5b5a 5d5c 5f5e
0000060 6160 6362 6564 6766 6968 6b6a 6d6c 6f6e
0000070 7170 7372 7574 7776 7978 7b7a 7d7c 7f7e
0000080
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Looks less random to me.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;I had problems with serial console attached to USART1 after upgrading StdPeriph from 1.1.0 to 1.3.0. Console would speak Chinese from now on, and logic analyzer shows “framing errors” when attached to the TX pin. There were two problems: in 1.1.0 in file 
&lt;code class=&quot;highlighter-rouge&quot;&gt;stm32f4xx.h&lt;/code&gt; default 
&lt;code class=&quot;highlighter-rouge&quot;&gt;HSE_VALUE&lt;/code&gt; definition was 8MHz. In 1.3.0 ST increased this to 25MHz. In addition in 
&lt;code class=&quot;highlighter-rouge&quot;&gt;stm32f4xx_conf.h&lt;/code&gt; I had &lt;code class=&quot;highlighter-rouge&quot;&gt;HSE_VALUE&lt;/code&gt; redefined, but later on I upgraded this file (got it from some example projest from StdPeriph from 1.3.0 version), and it lacked this re-definition. Thus µC thought it is running on 25MHz which in turn disrupted the transmission. This re-definition looks as follows:&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-cpp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cp&quot;&gt;#if defined  (HSE_VALUE)
&lt;/span&gt;&lt;span class=&quot;cm&quot;&gt;/* Redefine the HSE value; it&apos;s equal to 8 MHz on the STM32F4-DISCOVERY Kit */&lt;/span&gt;
 &lt;span class=&quot;cp&quot;&gt;#undef HSE_VALUE
&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;#define HSE_VALUE    ((uint32_t)8000000) 
#endif &lt;/span&gt;&lt;span class=&quot;cm&quot;&gt;/* HSE_VALUE */&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;I am facing a 
&lt;a href=&quot;https://my.st.com/public/STe2ecommunities/mcu/Lists/STM32Discovery/Flat.aspx?RootFolder=%2Fpublic%2FSTe2ecommunities%2Fmcu%2FLists%2FSTM32Discovery%2FSTM32F4%20Serial%20Interrupts%20Crash&amp;amp;FolderCTID=0x01200200770978C69A1141439FE559EB459D75800084C20D8867EAD444A5987D47BE638E0F&amp;amp;currentviews=560&quot;&gt;similar problem&lt;/a&gt; to this. Program hangs after returning from interrupt routine(?) In fact I don’t really know what is happening… Program hangs in
&lt;code class=&quot;highlighter-rouge&quot;&gt;SD_WaitReadOperation&lt;/code&gt; after successfully returning from 
&lt;code class=&quot;highlighter-rouge&quot;&gt;SD_ReadMultiBlocks&lt;/code&gt;. It idles in loop (or at first glance it looks like it is iterating the loop forever) which looks like this:&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-cpp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DMAEndOfTransfer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x00&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TransferEnd&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TransferError&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SD_OK&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;timeout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;timeout&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;--&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Normally after successful transfer either &lt;code class=&quot;highlighter-rouge&quot;&gt;DMAEndOfTransfer&lt;/code&gt; or 
&lt;code class=&quot;highlighter-rouge&quot;&gt;TransferEnd&lt;/code&gt; would turn 1, but seemingly none of this happened. The only place the &lt;code class=&quot;highlighter-rouge&quot;&gt;TransferEnd&lt;/code&gt; is set is &lt;code class=&quot;highlighter-rouge&quot;&gt;SDIO_IRQHandler&lt;/code&gt;, so I added logs to check if µC hits this routine. It does, and it even set  &lt;code class=&quot;highlighter-rouge&quot;&gt;TransferEnd&lt;/code&gt; to 1, but it never returns from it. Debugger says, that program hangs in some strange places like &lt;code class=&quot;highlighter-rouge&quot;&gt;WWDG_IRQHandler&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The problem was caused by missing DMA handler routine, namely the 
&lt;code class=&quot;highlighter-rouge&quot;&gt;DMA2_Stream3_IRQHandler&lt;/code&gt;. I made two mistakes. First, I assumed, that since I run the demo with &lt;code class=&quot;highlighter-rouge&quot;&gt;SD_DMA_MODE&lt;/code&gt; turned off (undefined), and &lt;code class=&quot;highlighter-rouge&quot;&gt;SD_POLLING_MODE&lt;/code&gt; turned on (#defined), the DMA routines are unnecessary. This is not the case, those handlers are required in either cases (that’s the way SDIO example is made). So I copied &lt;code class=&quot;highlighter-rouge&quot;&gt;DMA_IRQ&lt;/code&gt; handler from the example, where its name was hidden behind the &lt;code class=&quot;highlighter-rouge&quot;&gt;SD_SDIO_DMA_IRQHANDLER&lt;/code&gt; macro (but at that point I didn’t know this is a macro, and thought that this is a regular function name). So secondly, &lt;code class=&quot;highlighter-rouge&quot;&gt;SD_SDIO_DMA_IRQHANDLER&lt;/code&gt; was undefined in my &lt;code class=&quot;highlighter-rouge&quot;&gt;stm32fxxx_it.c&lt;/code&gt;, It simply was not visible in this translation unit, and I ended up with function named &lt;code class=&quot;highlighter-rouge&quot;&gt;SD_SDIO_DMA_IRQHANDLER&lt;/code&gt;, but without proper DMA IRQ handler. So µC jumped to the default handler which had infinite loop in it, but for some reason GDB showed the other handler.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://code.google.com/p/iwasz-sandbox/source/browse/#svn%2Ftags%2Fstm32-sdio-tests-first-working-version&quot;&gt;Here I made a tag of the code&lt;/a&gt; with first version that actually worked.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://code.google.com/p/iwasz-sandbox/source/browse/#svn%2Ftrunk%2Fstm32-sdio-tests&quot;&gt;And here is regular repository&lt;/a&gt; of the project, I will be improving this for some time now.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://blog.frankvh.com/2011/09/04/stm32f2xx-sdio-sd-card-interface/&quot;&gt;http://blog.frankvh.com/2011/09/04/stm32f2xx-sdio-sd-card-interface/&lt;/a&gt; - great post on the topic.&lt;/li&gt;
&lt;/ul&gt;</content>

      
      
      
      
      

      

      
        <category term="electronics" />
      

      

      
        <summary type="html">Started a new project (includes StdPeriph 1.3.0). Repository can be found  here. First commit makes it simply output a “Init” text on the debug console (i.e. on USART1). Browsing StdPeriph. Seems that stm32f4xx_sdio.[ch] are very low level (I’ve read SD card spec version 2.0). Higher level stuff seems to be in StdPeriph here: Utilities/STM32_EVAL/STM324x7I_EVAL Utilities/STM32_EVAL/STM3240_41_G_EVAL Utilities/STM32_EVAL/STM324x9I_EVAL</summary>
      

      
      
    </entry>
  
  
  
    <entry>
      
      <title type="html">A chaotic post on HID keyboard. STM32F407 success, STM32F105 fail</title>
      
      
      <link href="http://iwasz.pl/electronics/a-chaotic-post-on-hid-keyboard-stm32f407-success-stm32f105-fail/" rel="alternate" type="text/html" title="A chaotic post on HID keyboard. STM32F407 success, STM32F105 fail" />
      
      <published>2014-01-05T00:00:00+01:00</published>
      <updated>2014-01-05T00:00:00+01:00</updated>
      <id>http://iwasz.pl/electronics/a-chaotic-post-on-hid-keyboard-stm32f407-success-stm32f105-fail</id>
      <content type="html" xml:base="http://iwasz.pl/electronics/a-chaotic-post-on-hid-keyboard-stm32f407-success-stm32f105-fail/">&lt;p&gt;This is a quick dev-log post on my latest design, which was only partially successful. I have STM32F407-DISCOVERY board on which I successfully implemented a HID keyboard with only one keyboard. At first it reported that ‘a’ key was pressed every time user pressed the blue button, then, according to my plan I changed this to play/pause button, which can turn music on and of. It works under Linux and Windows (only ‘a’ version tested under win though). Then I decided to make a board for this and, since F407 is quite expensive, in fact too expensive for simple one-key keyboard, I decided to use something simpler. The slowest and cheapest µcros that support STM32_USB-Host-Device_Lib are those labeled as “connectivity line” i.e. STM32F105 and STM32F107. I’ve got myself two STM32F105R8T6 and made a board, which fits into a case I also bought. The case is labeled as “XB2-ES542”  :&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/board-300x129.png&quot; alt=&quot;The any key PCB&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/3729255047-300x168.jpg&quot; alt=&quot;The USB button&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Eagle schematic and board are &lt;a href=&quot;https://code.google.com/p/iwasz-sandbox/source/browse/#svn%2Ftrunk%2Fstm32f105-drama-button%2Fboard&quot;&gt;here&lt;/a&gt;, OSH Park shared projest is &lt;a href=&quot;http://oshpark.com/orders/new/ZLB4alej&quot;&gt;here&lt;/a&gt;. I assumed (incorrectly) that porting my program from F407 dev board to my custom board featuring different micro will be easy since they are quite similar. I was wrong. And I don’t have a dev board for F105 nor 107. Ok, but first things first. As I mentioned, program works on F407, so let me write down some random thoughts which emerged during the process of making this work:&lt;/p&gt;

&lt;h2 id=&quot;few-facts-about-hid-devices-that-i-learned&quot;&gt;Few facts about HID devices (that I learned)&lt;/h2&gt;

&lt;p&gt;All data exchanged resides in structures called reports. The host sends and receives data by sending and requesting reports in control or interrupt transfers. The report format is flexible and can handle just about any type of data, but each defined report has a fixed size. The device’s descriptors must include an interface descriptor that specifies the HID class, a HID descriptor, and an interrupt IN endpoint descriptor. The firmware must also contain a report descriptor that contains information about the contents of a HID’s reports.&lt;/p&gt;

&lt;p&gt;So there are two additional descriptors when comparing to the ‘vendor specific’ device I made recently (there may be third, optional descriptor as well). First is HID class device descriptor and it specifies which other class descriptors are present (for example report descriptors or physical descriptors).&lt;/p&gt;

&lt;p&gt;A HID can support one or more reports. The report descriptor specifies the size and contents of the data which this device generates. Physical descriptors at the other hand are optional pieces of data which describe the part(s) of human body used to operate the HID device. The HID class does not use subclasses to define most protocols. Instead, a HID class device identifies its data protocol and the type of data provided within its Report descriptor.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://www.usb.org/developers/devclass_docs/Hut1_11.pdf&quot;&gt;Here&lt;/a&gt; on page 53 you can find all key codes defined by the HID spec. Document “Device Class Definition for Human Interface Devices (HID) Version 1.11” on page 62 has very useful information regarding keyboard implementation. Especially crucial are those bits about when to send a data report: “The keyboard must send data reports at the Idle rate or when receiving a Get_Report request, even when there are no new key events.” I mixed up the rates and my HID keyboard acted unpredictable. Only after adjusting wait period for 4ms * idle rate things went OK.&lt;/p&gt;

&lt;p&gt;Then I started to getting familiar with the report descriptors, but nah, the more I read HID specification the more I realized this is too much complexity, and too much effort than I wanted to put into this project. At first I was like, “OK let’s read the whole spec, it has 97 pages, I’ve read longer specs before, not a problem”. But hey, this was meant to be a simple, few evenings project, and this HID spec turned out to be surprisingly complex (I mean report descriptors in particular. When I came to Push and Pop items I refused to read further). The better and simpler way of accomplishing this project was to grab some descriptors from the net, and so I did:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.obdev.at/products/vusb/hidkeys.html&quot;&gt;Here I found useful&lt;/a&gt;report descriptor for regular keyboards (like qwerty ones). Other, special buttons are implemented by other means (other items in reports) as I noticed before.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.tretec.it/public/webroot/media/PSE/090224_USB_HID.pdf&quot;&gt;Here are some interesting&lt;/a&gt;report descriptors which looks like something I want to do (multimedia control). Seems to me, that all those volume, play/pause and other knobs are implenmented in some other means that regular keyboards are. There are different type of “usage” used i.e. regular keyboard has 0x09 0x06 (USAGE (Keyboard)), but in above document there is 0x09 0x01 (Usage (Consumer Control)) used.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There is also a tool on USB-IF page, which helps to assembly HID report descriptors, and I can confirm that it runs on Wine, but that is all I can say about it. I suppose you still have to know the specs, and know what you are doing while using this thing. Last but not least the source code which runs flawlessly on STM32F407-DISCO:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://code.google.com/p/iwasz-sandbox/source/browse/#svn%2Ftrunk%2Fstm32f407-drama-button&quot;&gt;The source code for this project (works OK on STM32F407).&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;failed-attempt-to-port-it-to-stm32f105&quot;&gt;Failed attempt to port it to STM32F105&lt;/h2&gt;

&lt;p&gt;Then I started to move to my custom board depicted above, which I didn’t managed to accomplish. Actual status of the whole device (source code linked below, Eagle files above) is that, after connecting the USB, device initializes itself (i.e. USB stack gets initialized) then it gets quite a few reset requests (like 10) and then it hangs. Wireshark + usbmon shows “Malformed packet” when device tries to send the Device descriptor to host. Random notes from development:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Note : STM32F105 and 107 are called “connectivity line microprocessors”. It is useful to know that since there are many resources for STM32F1x out there which are tagged like “value line”, “connectivity line” etc.&lt;/li&gt;
  &lt;li&gt;I copied my previous project &lt;a href=&quot;https://code.google.com/p/iwasz-sandbox/source/browse/#svn%2Ftrunk%2Fstm32f407-drama-button&quot;&gt;stm32f407-drama-button&lt;/a&gt; into new place in my SVN repository : &lt;a href=&quot;https://code.google.com/p/iwasz-sandbox/source/browse/#svn%2Ftrunk%2Fstm32f105-drama-button&quot;&gt;stm32f105-drama-button&lt;/a&gt;.&lt;/li&gt;
  &lt;li&gt;I downloaded and unpacked STM32F10x_StdPeriph_Lib_V3.5.0 library from 
&lt;a href=&quot;http://www.st.com/web/catalog/tools/FM147/CL1794/SC961/SS1743/PF257890&quot;&gt;here&lt;/a&gt;. Main page for this micro is 
&lt;a href=&quot;http://www.st.com/web/catalog/mmc/FM141/SC1169/SS1031/LN1564&quot;&gt;here&lt;/a&gt;. Current version of standard peripheral library for STM32F10x as of writing this is 3.5.0.&lt;/li&gt;
  &lt;li&gt;I replaced &lt;code class=&quot;highlighter-rouge&quot;&gt;/STM32F4xx_StdPeriph_Driver&lt;/code&gt; with &lt;code class=&quot;highlighter-rouge&quot;&gt;/STM32F10x_StdPeriph_Driver&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;Replaced &lt;code class=&quot;highlighter-rouge&quot;&gt;CMSIS&lt;/code&gt; folder. Removed &lt;code class=&quot;highlighter-rouge&quot;&gt;Docs&lt;/code&gt; folder.&lt;/li&gt;
  &lt;li&gt;Made new toolchain with crosstool-ng fine tuned for Cortex-M3 µC.&lt;/li&gt;
  &lt;li&gt;Copied and modified stm32f105-crosstool.cmake.&lt;/li&gt;
  &lt;li&gt;StdPeriph comes with ld-scripts for various dev-boards. I figuret out that :
    &lt;ul&gt;
      &lt;li&gt;STM3210B-EVAL has STM32F103VBT6 µC.&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;http://www.st.com/st-web-ui/static/active/en/resource/technical/document/user_manual/CD00212441.pdf&quot;&gt;STM3210C-EVAL&lt;/a&gt; has STM32F107VCT µC.&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;http://www.st.com/st-web-ui/static/active/en/resource/technical/document/user_manual/CD00178166.pdf&quot;&gt;STM3210E-EVAL&lt;/a&gt; has STM32F103ZGT6 µC.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;So linker script for STM3210C-EVAL is best suited for me and will check it first. Have it copied and modified. In “drama button” project I use STM32F105R8T6 which has:
    &lt;ul&gt;
      &lt;li&gt;64kB of flash,&lt;/li&gt;
      &lt;li&gt;64kB of RAM&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;I copied &lt;code class=&quot;highlighter-rouge&quot;&gt;stm32f10x_conf.h&lt;/code&gt; from examples into src. CMSIS uses it somehow and I think this is bad design. Lower level library depends on higher level header file?&lt;/li&gt;
  &lt;li&gt;Had trouble when used GCC-4.8.0 (linaro version made with ct-ng 1.19). Works fine with GCC-4.7.0 (linaro version prepared with ct-ng 1.18). Some strange assembler errors when compiling &lt;code class=&quot;highlighter-rouge&quot;&gt;core_cm3.c&lt;/code&gt; file poped out.  &lt;a href=&quot;http://www.embedds.com/st32mvldiscovery-project-template-for-gcc/#comment-54664&quot;&gt;Here&lt;/a&gt; a guy in comments had similar issue, and someone told him to download fresh CMSIS library, because this provided with StdPeriph is old. I can believe that, because for example ST USB OTG library comes with StdPeriph bundled inside and it is also some old version. So my rule of thumb now is to collect newest versions of all the individual libraries, even when they are distributed together (i.e. OTG library virtually has everything required to compile the examples it provides, but now I throw it away and get fresh ones).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;EDIT&lt;/strong&gt; : when compiling with gcc-4.7.0 with heavy optimizations (-O3) the same assembler error emerges. Message is&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/tmp/ccOfylWN.s: Assembler messages:
/tmp/ccOfylWN.s:646: Error: registers may not be the same -- `strexb r0,r0,[r1]&apos;
/tmp/ccOfylWN.s:675: Error: registers may not be the same -- `strexh r0,r0,[r1]&apos;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;I downloaded and upgraded CMSIS from here : &lt;a href=&quot;https://silver.arm.com/browse/CMSIS#&quot;&gt;https://silver.arm.com/browse/CMSIS#&lt;/a&gt; (registration required). Upgraded from version 1.3.0 to 3.2.0. No *.c file this time, only header files.&lt;/p&gt;

&lt;p&gt;When ported from STM32F407-DISCO to my custom STM32F105 board, program refused to operate. Kernel log says that:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Jan  3 00:08:09 diora kernel: [ 4993.895502] usb 7-2: new full-speed USB device number 4 using uhci_hcd
Jan  3 00:08:09 diora kernel: [ 4993.959542] hub 7-0:1.0: unable to enumerate USB device on port 2
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;And oscilloscope says, that… well… seems OK to me (compared for example to Wikipedia article on USB) :)&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/map001-300x180.png&quot; alt=&quot;Oscilloscoe1&quot; /&gt;
&lt;img src=&quot;/assets/map002-300x180.png&quot; alt=&quot;Oscilloscoe1&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Debugger shows that program is running, It correctly invoke Reset_Handler, and then hits the main function.&lt;/p&gt;

&lt;p&gt;Mistakes that I know I made:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;I made a circuit with µC that I don’t have development board for (Assumed, that porting tested program from STMF407 to STMF105 will be easy. Wrong).&lt;/li&gt;
  &lt;li&gt;I screwed up a SWD port. Issues with signal integrity (probably due to lack of termination resistors?). This made debugging with GDB harder. It would hang, or disconnect at random points.&lt;/li&gt;
  &lt;li&gt;I forgot to add serial console output for STDOUT. Terrible mistake. I’ve wired that up, but board looks messy now.&lt;/li&gt;
  &lt;li&gt;Simple delay functions was dependent on optimization switches.
And then, after about 10 evenings / nights I gave up and put this project on the shelf for some time.&lt;/li&gt;
&lt;/ul&gt;</content>

      
      
      
      
      

      

      
        <category term="electronics" />
      

      

      
        <summary type="html">This is a quick dev-log post on my latest design, which was only partially successful. I have STM32F407-DISCOVERY board on which I successfully implemented a HID keyboard with only one keyboard. At first it reported that ‘a’ key was pressed every time user pressed the blue button, then, according to my plan I changed this to play/pause button, which can turn music on and of. It works under Linux and Windows (only ‘a’ version tested under win though). Then I decided to make a board for this and, since F407 is quite expensive, in fact too expensive for simple one-key keyboard, I decided to use something simpler. The slowest and cheapest µcros that support STM32_USB-Host-Device_Lib are those labeled as “connectivity line” i.e. STM32F105 and STM32F107. I’ve got myself two STM32F105R8T6 and made a board, which fits into a case I also bought. The case is labeled as “XB2-ES542”  :</summary>
      

      
      
    </entry>
  
  
  
    <entry>
      
      <title type="html">Motorcycle black box. A quick update.</title>
      
      
      <link href="http://iwasz.pl/electronics/motorcycle-black-box-a-quick-update/" rel="alternate" type="text/html" title="Motorcycle black box. A quick update." />
      
      <published>2013-06-30T00:00:00+02:00</published>
      <updated>2013-06-30T00:00:00+02:00</updated>
      <id>http://iwasz.pl/electronics/motorcycle-black-box-a-quick-update</id>
      <content type="html" xml:base="http://iwasz.pl/electronics/motorcycle-black-box-a-quick-update/">&lt;p&gt;Just a quick update for those who are interested if this project is still alive. It is. Above you can find an early test video from the application which runs on a PC and does post processing of the data collected by raspberry pi. More details to come in next post. All source code for this project is &lt;a href=&quot;https://code.google.com/p/motoblackbox/&quot;&gt;here&lt;/a&gt; (work in progress). First post &lt;a href=&quot;http://www.iwasz.pl/electronics/motorcycle-black-box-part-1-data-acquisition-with-arduino-mega/&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://www.youtube.com/watch?v=jydEZ-RwJKM&quot;&gt;&lt;img src=&quot;https://img.youtube.com/vi/jydEZ-RwJKM/0.jpg&quot; alt=&quot;Alt text&quot; /&gt;&lt;/a&gt;&lt;/p&gt;</content>

      
      
      
      
      

      

      
        <category term="electronics" />
      

      

      
        <summary type="html">Just a quick update for those who are interested if this project is still alive. It is. Above you can find an early test video from the application which runs on a PC and does post processing of the data collected by raspberry pi. More details to come in next post. All source code for this project is here (work in progress). First post here.</summary>
      

      
      
    </entry>
  
  
  
    <entry>
      
      <title type="html">Motorcycle black box part 1. Data acquisition with Arduino Mega.</title>
      
      
      <link href="http://iwasz.pl/electronics/motorcycle-black-box-part-1-data-acquisition-with-arduino-mega/" rel="alternate" type="text/html" title="Motorcycle black box part 1. Data acquisition with Arduino Mega." />
      
      <published>2013-06-02T00:00:00+02:00</published>
      <updated>2013-06-02T00:00:00+02:00</updated>
      <id>http://iwasz.pl/electronics/motorcycle-black-box-part-1-data-acquisition-with-arduino-mega</id>
      <content type="html" xml:base="http://iwasz.pl/electronics/motorcycle-black-box-part-1-data-acquisition-with-arduino-mega/">&lt;h1 id=&quot;the-objective&quot;&gt;The objective&lt;/h1&gt;
&lt;p&gt;Make a black box, a device which would record short clips from camera in loop overwriting oldest clips. That would produce constant stream of short movies which put together would make one long recording containing last 30minutes (or more - depending on storage capacity) of my riding. Among with the recording, telemetric data would be collected such as velocity, RPM, temperature, front and rear brake pressed, depressed, and turn signals, and maybe more. Then this data could be put on the video in overlay.&lt;/p&gt;

&lt;h1 id=&quot;the-motorcycle&quot;&gt;The motorcycle&lt;/h1&gt;
&lt;p&gt;Yamaha XJ6SA 2010.&lt;/p&gt;

&lt;h2 id=&quot;identify-by-what-means-communication-between-the-ecu-and-the-dashboard-is-performed&quot;&gt;Identify by what means communication between the ECU and the dashboard is performed.&lt;/h2&gt;
&lt;p&gt;Which cables are used and what is the protocol used? After inspecting the service manual for my bike I was able to eliminate wires which are used for other things (see picture), and I left with only one, which is connecting the dash, the ECU and the immobilizer. Other ones was for flashing some warning LEDs, gathering information from fuel pump, oil switch and so on. So the yellow-blue wire was my first guess and it was correct. On the &lt;a href=&quot;http://ecuhacking.activeboard.com/t38959479/yamaha-fi-diagnostics-tool/&quot;&gt;ecuhacking forum&lt;/a&gt;, which was source of very helpful information, guys was talking about something called K-line. I believe it is something widely common in the automotive industry, and for certain it has bunch of ISO standards describing it, but hey, if this is only one wire, and data flowing inside is some kind of serial communication, I bet I could sniff it, and figure out without any standards, which are hard to find and get (there is so much of them, I’ve got confused after few minutes of googling).&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/wiring2-245x300.png&quot; alt=&quot;Dashboard connections&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;figure-out-how-to-interface-this-make-some-circuit-if-needed&quot;&gt;Figure out how to interface this, make some circuit if needed.&lt;/h2&gt;
&lt;p&gt;Again on the ecuhacing forum I’ve found information that K-line has logic levels relative to 12V, where 0V is logic 0, and 12V logic 1. There has to be some voltage level converter if I want to connect some TTL stuff to it. On the forum some guys were using a L9637 chip which is described as “ISO 9141 INTERFACE” by its datasheet. So I bought a few of these and connected it as follows :&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/L9637-300x156.png&quot; alt=&quot;L9637&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Later on I  &lt;strong&gt;removed the 510 ohm pull up resistor&lt;/strong&gt;, because after turning engine on there was error showing of on the dash. I guessed that could be this resistor, and it helped. Dunno what was wrong.&lt;/p&gt;

&lt;p&gt;Most difficult part for me was to find a place in motorcycle’s wiring to connect to. After some time I managed to insert piece of rigid wire to the back side of ECU connector as depicted below:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/IMG_20130529_234215-300x225.jpg&quot; alt=&quot;ECU connector&quot; /&gt;&lt;/p&gt;

&lt;p&gt;5V supply voltage I was drawing from step down voltage converter which I bought on the Internets. It is a PCB with a few discrete parts and quite huge radiator with some coils inside. There is [EDIT] label on it. To the output of L9637 I connected a Saleae logic analyzer, which I also bought. It is quite cheap and has good software for Windows, Linux and MAC OS. I can definitely recommend it, especially if you want to use it with Linux (I use Ubuntu).&lt;/p&gt;

&lt;h2 id=&quot;sniff-the-data-and-collect-it-for-further-investigation&quot;&gt;Sniff the data, and collect it for further investigation.&lt;/h2&gt;
&lt;p&gt;My circuit worked the first time. After turning ignition to the ON state this is what I got:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/screenshot-300x164.png&quot; alt=&quot;Sealae logic analyzer window&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Sealae app, among others, has a “Async serial” analyzer which I used with default configuration, and “use autobaud” checkbox checked. This useful option corrected initial 9600 baud to whatever it thought to be appropriate, and showed 16064 baud. Pretty odd value isn’t it? None the less it is very useful information if I want to read the data with some AVR, or something like that. It turns out, that data comes in packets which are 6B long. First byte is some kind of command, and the rest is the reply i.e the dashboard issues command 0x01 ant then ECU replies with 5 bytes of data. From the ecuhacking I knew that forst byte of the reply would be the RPM, second probably velocity, third an error code, fourth would be engine temperature (that is coolant or oil temperature?) and the very last is the checksum.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/Screenshot-from-2013-05-30-023913-300x256.png&quot; alt=&quot;Sealae async serial analyzer setup&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;collect-the-data-in-some-more-useful-format&quot;&gt;Collect the data in some more useful format.&lt;/h2&gt;
&lt;p&gt;Although Sealae has an option to store the analyzer’s data in CSV, sooner or later I would have to make some custom electronics anyway. Yet I want to make self contained logger hidden in neat case somewhere in the bike. I want to use a Raspberry PI i own as the main component of the gizmo, but after reading about serial communication with the Pi, I gave up for that time, and connected Arduino Mega. The main problem with PI is that I don’t know how to set it up for so unusual baud rate as 16064 baud (or 15625 as someone suggested). I had limited time, so for now I chose the Arduino. Below the code I uploaded :&lt;/p&gt;

&lt;div class=&quot;language-cpp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cp&quot;&gt;#include &amp;lt;SoftwareSerial.h&amp;gt;
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SoftwareSerial&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;mySerial&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;11&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// RX, TX&lt;/span&gt;

&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;setup&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// initialize both serial ports:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;Serial&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;begin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;115200&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// set the data rate for the SoftwareSerial port&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;mySerial&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;begin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;16064&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;loop&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;count&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// read from port 1, send to port 0:&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mySerial&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;available&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;inByte&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mySerial&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inByte&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x01&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;count&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;Serial&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sc&quot;&gt;&apos; &apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;count&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;Serial&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inByte&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;HEX&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;Serial&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sc&quot;&gt;&apos; &apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;count&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;As you can see, RX is set up for pin 10, so the only thing I did was to disconnect the logic analyzer, and connect Arduino pin 10 instead. But nothing happened. This was because the SoftSerial library have a few baud rates predefined, namely the most usual ones. The solution was to modify arduino-1.0.5/libraries/SoftwareSerial/SoftwareSerial.cpp so it looks like that:&lt;/p&gt;

&lt;div class=&quot;language-cpp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// .... line 59&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DELAY_TABLE&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PROGMEM&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;table&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// baud rxcenter rxintra rxstop tx&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;115200&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;17&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;17&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;12&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;57600&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;37&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;37&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;33&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;38400&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;25&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;57&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;57&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;54&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;31250&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;31&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;70&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;70&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;68&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;28800&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;34&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;77&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;77&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;74&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;19200&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;54&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;117&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;117&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;114&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;16064&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;66&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;140&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;140&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;137&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// added baud rate&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;15625&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;68&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;144&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;144&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;141&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// added baud rate 2&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;14400&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;74&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;156&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;156&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;153&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;9600&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;114&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;236&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;236&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;233&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4800&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;233&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;474&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;474&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;471&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2400&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;471&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;950&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;950&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;947&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1200&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;947&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1902&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1902&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1899&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;600&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1902&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3804&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3804&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3800&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;300&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3804&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;7617&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;7617&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;7614&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// ....&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href=&quot;http://www.tocpcs.com/newsoftserial-adding-a-baud-rate/&quot;&gt;Here is the link&lt;/a&gt; you should follow for more info. I haven’t figured it out by myself. After this modification Arduino happily sent me my precious data, which I observed in serial monitor.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/serial-data-300x168.png&quot; alt=&quot;Serial data as seen on arduino serial monitor&quot; /&gt;&lt;/p&gt;

&lt;p&gt;This is the data I collected so far (motorcycle standing on central stand, back wheel revolving, velocity comes from the back wheel, ABS LED blinking).&lt;/p&gt;

&lt;p&gt;Ignition ON, engine stopped.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;1 0 0 0 30 30
1 0 0 0 30 30
1 0 0 0 30 30
1 0 0 0 30 30
...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Ignition ON, engine started, no throttle (~1200 RPM), no gear (N) i.e. wheel not revolving, cold engine:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;1 24 0 0 30 54
1 24 0 0 30 54
1 24 0 0 30 54
1 24 0 0 30 54
...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Ignition ON, engine started, little throttle (more RPM), no gear (N) i.e. wheel not revolving, cold engine:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;1 34 0 0 53 87
1 34 0 0 53 87
1 34 0 0 53 87
1 34 0 0 53 87
...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;1st gear, no throttle (engine warmed up thus less RPM). About 10 km/h&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;1 17 0 0 5C 73
1 17 1 0 5C 74
1 17 1 0 5C 74
1 17 0 0 5C 73
1 17 1 0 5C 74
1 18 1 0 60 79
1 18 1 0 60 79
1 18 0 0 60 78
1 18 1 0 60 79
1 17 1 0 60 78
1 17 0 0 60 77
1 17 1 0 60 78
1 17 1 0 60 78
1 17 0 0 60 77
1 17 1 0 60 78
1 17 1 0 60 78
1 17 0 0 60 77
1 18 1 0 60 79
1 18 1 0 60 79
1 18 1 0 60 79
1 18 0 0 60 78
1 18 1 0 60 79
1 18 1 0 60 79
1 18 0 0 60 78
1 18 1 0 60 79
1 18 1 0 60 79
1 17 0 0 60 77
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;23 km/h (6th gear)&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;1 17 2 0 68 81
1 17 2 0 69 82
1 17 2 0 69 82
1 17 2 0 69 82
1 17 1 0 69 81
1 17 2 0 68 81
1 17 2 0 68 81
1 17 2 0 68 81
1 17 2 0 68 81
1 17 1 0 68 80
1 17 2 0 69 82
1 17 2 0 68 81
1 17 2 0 68 81
1 17 1 0 68 80
1 17 2 0 68 81
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;40 km/h&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;1 2B 4 0 70 9F
1 2B 3 0 70 9E
1 2B 3 0 72 A0
1 2B 3 0 72 A0
1 2B 4 0 72 A1
1 2B 3 0 72 A0
1 2C 3 0 72 A1
1 2C 4 0 72 A2
1 2C 3 0 72 A1
1 2C 3 0 72 A1
1 2C 4 0 72 A2
1 2C 3 0 72 A1
1 2C 3 0 72 A1
1 2C 4 0 72 A2
1 2C 3 0 72 A1
1 2C 4 0 72 A2
1 2C 3 0 72 A1
1 2C 3 0 72 A1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;60 km/h&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;1 40 5 0 74 B9
1 40 5 0 74 B9
1 40 5 0 74 B9
1 40 5 0 74 B9
1 40 5 0 74 B9
1 40 5 0 74 B9
1 40 5 0 74 B9
1 40 5 0 74 B9
1 41 4 0 74 B9
1 41 6 0 74 BB
1 41 4 0 74 B9
1 40 5 0 74 B9
1 40 5 0 74 B9
1 41 5 0 74 BA
1 40 5 0 74 B9
1 40 5 0 74 B9
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;80 km/h&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;1 56 7 0 77 D4
1 55 6 0 77 D2
1 56 7 0 77 D4
1 55 6 0 77 D2
1 56 7 0 77 D4
1 56 6 0 77 D3
1 56 7 0 77 D4
1 56 6 0 77 D3
1 56 7 0 77 D4
1 56 6 0 77 D3
1 56 7 0 77 D4
1 56 7 0 77 D4
1 56 6 0 77 D3
1 56 7 0 77 D4
1 56 7 0 77 D4
1 56 6 0 77 D3
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;future&quot;&gt;Future&lt;/h1&gt;
&lt;p&gt;Due to uncertainty about Raspberry PI serial communication I plan to make custom PCB with AVR in form of shield to Raspberry Pi. It will have two purposes. First it will acquire the data in some similar manner as depicted above, and will pass it to Pi by I2C or SPI (probably with velocity in some more usable form), among with some other data such as brakes and turn-lights, an maybe even outdoor temperature (I always wanted to have this information, especially in spring and autumn). And secondly it will drive some relay to cut the power to Pi which draws 2W of power even when shut down. Of course it also should send some signal first to Raspberry to shut it down correctly. If someone know something more about Pi’s UART and custom baud rates in particular, please let me know. Maybe there is a way to read K-line directly without AVR.&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;</content>

      
      
      
      
      

      

      
        <category term="electronics" />
      

      

      
        <summary type="html">The objective Make a black box, a device which would record short clips from camera in loop overwriting oldest clips. That would produce constant stream of short movies which put together would make one long recording containing last 30minutes (or more - depending on storage capacity) of my riding. Among with the recording, telemetric data would be collected such as velocity, RPM, temperature, front and rear brake pressed, depressed, and turn signals, and maybe more. Then this data could be put on the video in overlay.</summary>
      

      
      
    </entry>
  
  
</feed>
