<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.3.3">Jekyll</generator><link href="https://etyp.dev/feed.xml" rel="self" type="application/atom+xml" /><link href="https://etyp.dev/" rel="alternate" type="text/html" /><updated>2026-03-18T13:40:33-04:00</updated><id>https://etyp.dev/feed.xml</id><title type="html">Evan Typanski</title><subtitle>Hi!</subtitle><author><name>Evan Typanski</name></author><entry><title type="html">Flipper your way into hardware - UI</title><link href="https://etyp.dev/posts/flipper-into-hardware-ui/" rel="alternate" type="text/html" title="Flipper your way into hardware - UI" /><published>2025-05-21T00:00:00-04:00</published><updated>2025-05-21T00:00:00-04:00</updated><id>https://etyp.dev/posts/flipper-into-hardware-3</id><content type="html" xml:base="https://etyp.dev/posts/flipper-into-hardware-ui/"><![CDATA[<div class="series">
  <h4> Read more in the "Flipper into hardware" series: </h4>
  <ol>
    
    
    <li>
      
      <a href="/posts/flipper-into-hardware-p1/">Flipper your way into hardware</a>
      
    </li>
    
    <li>
      
      <a href="/posts/flipper-into-hardware-step/">Flipper your way into hardware - Stepping</a>
      
    </li>
    
    <li>
      
      <strong>Flipper your way into hardware - UI</strong>
      
    </li>
    
  </ol>

  
</div>

<div class="track">
<audio title="Flipper your way into hardware p3" controls="">
  <source src="/assets/audio/posts/flipper-into-hardware-p3/flipper-into-hardware-p3.mp3" type="audio/mpeg" />
  Audio tag is not supported, sorry!
</audio>
<p><small> Let me read it for you! </small></p>
</div>

<p>At this point, we have a Flipper Zero application that steps a stepper motor. But, we want something that:</p>

<ol>
  <li>Looks pretty</li>
  <li>Is configurable</li>
</ol>

<p>So, we’ll (try to) make that here.</p>

<h1 id="requirements">Requirements</h1>

<p>Before, we were just exploring what it takes to write a Flipper Zero app that interacted with the pins - namely to step a stepper motor. Now we’ll take that groundwork and use it to make a somewhat functional app. What could we want to do with our app?</p>

<ol>
  <li>Change the pins used to step and set direction of the motor</li>
  <li>Start and stop the motor</li>
</ol>

<p>There may be some other stuff, but I’m honestly quite lazy when it comes to this “UI” thing. We just want to configure things and make the motor function.</p>

<p>But first, we need a different UI.</p>

<h1 id="the-goal-ui">The Goal UI</h1>

<p>The UI is a single view right now, but the Flipper Zero API gives a few more options. The first place that I looked at was <a href="https://developer.flipper.net/flipperzero/doxygen/submenu_8h.html">submenus</a>. These are just collections of options that you can press. Seems perfect, so we’ll have one for each option:</p>

<blockquote class="filename">
  <p>Goal UI</p>
</blockquote>
<div class="language-c highlighter-tree-sitter"><pre><code><span class='ts-operator'>+</span><span class='ts-operator'>--</span><span class='ts-operator'>--</span><span class='ts-operator'>--</span><span class='ts-operator'>--</span><span class='ts-operator'>--</span><span class='ts-operator'>--</span><span class='ts-operator'>--</span><span class='ts-operator'>-</span><span class='ts-operator'>+</span>
| <span class='ts-constant'>GO</span>!           |
| <span class='ts-variable'>Direction</span> <span class='ts-variable'>pin</span> |
| <span class='ts-variable'>Step</span> <span class='ts-variable'>pin</span>      |
<span class='ts-operator'>+</span><span class='ts-operator'>--</span><span class='ts-operator'>--</span><span class='ts-operator'>--</span><span class='ts-operator'>--</span><span class='ts-operator'>--</span><span class='ts-operator'>--</span><span class='ts-operator'>--</span><span class='ts-operator'>-</span><span class='ts-operator'>+</span>
</code></pre></div>

<p>It’s beautiful. Both of the pin options should be fairly easy since the official GPIO app has a <a href="https://github.com/flipperdevices/flipperzero-firmware/blob/dev/applications/main/gpio/views/gpio_test.c">view that selects pins</a> - similar logic can be used here. That will definitely work out.</p>

<p>Then “GO!” will step the motor until back is pressed.</p>

<p>We will start with making this menu, then get selecting pins working.</p>

<h2 id="the-submenu">The submenu</h2>

<p>We will have a submenu with multiple options to go to different “views.” This is easily made with a <a href="https://developer.flipper.net/flipperzero/doxygen/view__dispatcher_8h.html">view dispatcher</a> - this will hold all of the views and switch between them when needed. To set this up, I used the <a href="https://github.com/flipperdevices/flipperzero-firmware/tree/dev/applications/examples/example_view_dispatcher">view dispatcher example</a> as a reference.</p>

<p>I won’t go into every necessary part for code snippets, if you need completeness, simply <a href="https://github.com/evantypanski/flipper-stepper">look at the code on Github</a>.</p>

<p>First, we need to change the <code>StepperContext</code>. We removed the <code>ViewPort</code> and <code>FuriMessageQueue</code> and replaced them with the <code>ViewDispatcher</code>. Now the stepper context object (which is passed around a bunch of callbacks) is now this:</p>

<blockquote class="filename">
  <p>stepper.c</p>
</blockquote>
<div class="language-c highlighter-tree-sitter"><pre><code><span class='ts-keyword'>typedef</span> <span class='ts-keyword'>struct</span> {
  <span class='ts-type'>Gui</span> <span class='ts-operator'>*</span><span class='ts-property'>gui</span><span class='ts-delimiter'>;</span>
  <span class='ts-type'>ViewDispatcher</span> <span class='ts-operator'>*</span><span class='ts-property'>view_dispatcher</span><span class='ts-delimiter'>;</span>
  <span class='ts-type'>Submenu</span> <span class='ts-operator'>*</span><span class='ts-property'>submenu</span><span class='ts-delimiter'>;</span>
  <span class='ts-type'>Widget</span> <span class='ts-operator'>*</span><span class='ts-property'>stepping_widget</span><span class='ts-delimiter'>;</span>
  <span class='ts-keyword'>const</span> <span class='ts-type'>GpioPin</span> <span class='ts-operator'>*</span><span class='ts-property'>dir_pin</span><span class='ts-delimiter'>;</span>
  <span class='ts-keyword'>const</span> <span class='ts-type'>GpioPin</span> <span class='ts-operator'>*</span><span class='ts-property'>step_pin</span><span class='ts-delimiter'>;</span>
  <span class='ts-type'>bool</span> <span class='ts-property'>state</span><span class='ts-delimiter'>;</span>
} <span class='ts-type'>StepperContext</span><span class='ts-delimiter'>;</span>
</code></pre></div>

<p>The <code>stepping_widget</code> will be used for the “GO!” view - our first view.</p>

<p>We need to change the <code>stepper_context_alloc</code> function to set up the view dispatcher and its views. To do that, remove the references to removed members (namely the <code>ViewPort</code> and <code>FuriMessageQueue</code>). Then, we’ll start by creating the submenu:</p>

<blockquote class="filename">
  <p>stepper.c</p>
</blockquote>
<div class="language-c highlighter-tree-sitter"><pre><code>  <span class='ts-comment'>// Create and initialize the Submenu view.</span>
  <span class='ts-variable'>context</span><span class='ts-operator'>-&gt;</span><span class='ts-property'>submenu</span> <span class='ts-operator'>=</span> <span class='ts-function'>submenu_alloc</span>()<span class='ts-delimiter'>;</span>
  <span class='ts-function'>submenu_add_item</span>(<span class='ts-variable'>context</span><span class='ts-operator'>-&gt;</span><span class='ts-property'>submenu</span>, <span class='ts-string'>&quot;GO!&quot;</span>, <span class='ts-variable'>SubmenuIndexStep</span>,
                   <span class='ts-variable'>stepper_dispatcher_app_submenu_callback</span>, <span class='ts-variable'>context</span>)<span class='ts-delimiter'>;</span>
</code></pre></div>

<p>There’s a <code>SubmenuIndexStep</code> in there - that’s actually an enum value defined at the top:</p>

<blockquote class="filename">
  <p>stepper.c</p>
</blockquote>
<div class="language-c highlighter-tree-sitter"><pre><code><span class='ts-comment'>// Enumeration of submenu items.</span>
<span class='ts-keyword'>typedef</span> <span class='ts-keyword'>enum</span> {
  <span class='ts-variable'>SubmenuIndexStep</span>,
} <span class='ts-type'>SubmenuIndex</span><span class='ts-delimiter'>;</span>
</code></pre></div>

<p>Since we’re starting with just the step menu item, that enum only has one value, but we’ll add more when we build the submenu up.</p>

<p>Next we’ll create the “widget” that gets triggered when we switch to stepping mode:</p>

<blockquote class="filename">
  <p>stepper.c</p>
</blockquote>
<div class="language-c highlighter-tree-sitter"><pre><code>  <span class='ts-comment'>// Create the stepping widget.</span>
  <span class='ts-variable'>context</span><span class='ts-operator'>-&gt;</span><span class='ts-property'>stepping_widget</span> <span class='ts-operator'>=</span> <span class='ts-function'>widget_alloc</span>()<span class='ts-delimiter'>;</span>
  <span class='ts-function'>widget_add_string_multiline_element</span>(<span class='ts-variable'>context</span><span class='ts-operator'>-&gt;</span><span class='ts-property'>stepping_widget</span>, <span class='ts-number'>64</span>, <span class='ts-number'>32</span>,
                                      <span class='ts-variable'>AlignCenter</span>, <span class='ts-variable'>AlignCenter</span>, <span class='ts-variable'>FontSecondary</span>,
                                      <span class='ts-string'>&quot;Stepping!&quot;</span>)<span class='ts-delimiter'>;</span>
  <span class='ts-function'>widget_add_button_element</span>(<span class='ts-variable'>context</span><span class='ts-operator'>-&gt;</span><span class='ts-property'>stepping_widget</span>, <span class='ts-variable'>GuiButtonTypeCenter</span>,
                            <span class='ts-string'>&quot;Stop stepping&quot;</span>, <span class='ts-variable'>stepping_button_callback</span>, <span class='ts-variable'>context</span>)<span class='ts-delimiter'>;</span>
</code></pre></div>

<p>That’s just a string and a button. Pressing the button makes it stop stepping.</p>

<p>Now we’ll create the view dispatcher. This just manages the two views we just created:</p>

<blockquote class="filename">
  <p>stepper.c</p>
</blockquote>
<div class="language-c highlighter-tree-sitter"><pre><code>  <span class='ts-variable'>context</span><span class='ts-operator'>-&gt;</span><span class='ts-property'>view_dispatcher</span> <span class='ts-operator'>=</span> <span class='ts-function'>view_dispatcher_alloc</span>()<span class='ts-delimiter'>;</span>
  <span class='ts-function'>view_dispatcher_attach_to_gui</span>(<span class='ts-variable'>context</span><span class='ts-operator'>-&gt;</span><span class='ts-property'>view_dispatcher</span>, <span class='ts-variable'>context</span><span class='ts-operator'>-&gt;</span><span class='ts-property'>gui</span>,
                                <span class='ts-variable'>ViewDispatcherTypeFullscreen</span>)<span class='ts-delimiter'>;</span>
  <span class='ts-function'>view_dispatcher_add_view</span>(<span class='ts-variable'>context</span><span class='ts-operator'>-&gt;</span><span class='ts-property'>view_dispatcher</span>, <span class='ts-variable'>ViewIndexSubmenu</span>,
                           <span class='ts-function'>submenu_get_view</span>(<span class='ts-variable'>context</span><span class='ts-operator'>-&gt;</span><span class='ts-property'>submenu</span>))<span class='ts-delimiter'>;</span>
  <span class='ts-function'>view_dispatcher_add_view</span>(<span class='ts-variable'>context</span><span class='ts-operator'>-&gt;</span><span class='ts-property'>view_dispatcher</span>, <span class='ts-variable'>ViewIndexStepping</span>,
                           <span class='ts-function'>widget_get_view</span>(<span class='ts-variable'>context</span><span class='ts-operator'>-&gt;</span><span class='ts-property'>stepping_widget</span>))<span class='ts-delimiter'>;</span>
  <span class='ts-function'>view_dispatcher_set_custom_event_callback</span>(<span class='ts-variable'>context</span><span class='ts-operator'>-&gt;</span><span class='ts-property'>view_dispatcher</span>,
                                            <span class='ts-variable'>stepper_event_callback</span>)<span class='ts-delimiter'>;</span>

  <span class='ts-comment'>// Set the navigation, or back button callback. It will be called if the</span>
  <span class='ts-comment'>// user pressed the Back button and the event was not handled in the</span>
  <span class='ts-comment'>// currently displayed view.</span>
  <span class='ts-function'>view_dispatcher_set_navigation_event_callback</span>(<span class='ts-variable'>context</span><span class='ts-operator'>-&gt;</span><span class='ts-property'>view_dispatcher</span>,
                                                <span class='ts-variable'>navigation_callback</span>)<span class='ts-delimiter'>;</span>

  <span class='ts-comment'>// The context will be passed to the callbacks as a parameter, so we have</span>
  <span class='ts-comment'>// access to our application object.</span>
  <span class='ts-function'>view_dispatcher_set_event_callback_context</span>(<span class='ts-variable'>context</span><span class='ts-operator'>-&gt;</span><span class='ts-property'>view_dispatcher</span>, <span class='ts-variable'>context</span>)<span class='ts-delimiter'>;</span>
</code></pre></div>

<p>The <code>ViewIndexSubmenu</code> and <code>ViewIndexStepping</code> are just part of an enum defined above:</p>

<blockquote class="filename">
  <p>stepper.c</p>
</blockquote>
<div class="language-c highlighter-tree-sitter"><pre><code><span class='ts-keyword'>typedef</span> <span class='ts-keyword'>enum</span> {
  <span class='ts-variable'>ViewIndexSubmenu</span>,
  <span class='ts-variable'>ViewIndexStepping</span>,
} <span class='ts-type'>ViewIndex</span><span class='ts-delimiter'>;</span>
</code></pre></div>

<p>The remaining parts are just adding those views and adding callbacks. The first callback is <code>stepper_event_callback</code> - we’ll see this later. The <code>navigation_callback</code> is simpler - it’s basically straight from the example. If we press back, and the app screen doesn’t handle it, the navigation callback will exit. We’ll see both of those soon, but first we have a couple more setup points.</p>

<p>This needs to be called from the “main” application code. After setting up the GPIO pins, we can “enter” the app easily with these calls:</p>

<blockquote class="filename">
  <p>stepper.c</p>
</blockquote>
<div class="language-c highlighter-tree-sitter"><pre><code>  <span class='ts-function'>view_dispatcher_switch_to_view</span>(<span class='ts-variable'>context</span><span class='ts-operator'>-&gt;</span><span class='ts-property'>view_dispatcher</span>, <span class='ts-variable'>ViewIndexSubmenu</span>)<span class='ts-delimiter'>;</span>
  <span class='ts-function'>view_dispatcher_run</span>(<span class='ts-variable'>context</span><span class='ts-operator'>-&gt;</span><span class='ts-property'>view_dispatcher</span>)<span class='ts-delimiter'>;</span>
</code></pre></div>

<p>This will start at the submenu and run it. Then, we need to tear this down in <code>stepper_context_free</code>:</p>

<blockquote class="filename">
  <p>stepper.c</p>
</blockquote>
<div class="language-c highlighter-tree-sitter"><pre><code>  <span class='ts-function'>view_dispatcher_remove_view</span>(<span class='ts-variable'>context</span><span class='ts-operator'>-&gt;</span><span class='ts-property'>view_dispatcher</span>, <span class='ts-variable'>ViewIndexSubmenu</span>)<span class='ts-delimiter'>;</span>
  <span class='ts-function'>view_dispatcher_remove_view</span>(<span class='ts-variable'>context</span><span class='ts-operator'>-&gt;</span><span class='ts-property'>view_dispatcher</span>, <span class='ts-variable'>ViewIndexStepping</span>)<span class='ts-delimiter'>;</span>
  <span class='ts-function'>view_dispatcher_free</span>(<span class='ts-variable'>context</span><span class='ts-operator'>-&gt;</span><span class='ts-property'>view_dispatcher</span>)<span class='ts-delimiter'>;</span>
  <span class='ts-function'>submenu_free</span>(<span class='ts-variable'>context</span><span class='ts-operator'>-&gt;</span><span class='ts-property'>submenu</span>)<span class='ts-delimiter'>;</span>
</code></pre></div>

<p>Okay, enough just rahashing the example. Now for new stuff.</p>

<h3 id="the-callbacks">The Callbacks</h3>

<p>So we have four callbacks that we assigned:</p>

<ol>
  <li>
    <p><code>navigation_callback</code> - called when “back” is pressed</p>
  </li>
  <li>
    <p><code>stepper_dispatcher_app_submenu_callback</code> - called when a submenu button is pressed</p>
  </li>
  <li>
    <p><code>stepping_button_callback</code> - called when the “Stop stepping” button is pressed in the widget</p>
  </li>
  <li>
    <p><code>stepper_event_callback</code> - called by <code>stepper_dispatcher_app_submenu_callback</code> in order to start stepping</p>
  </li>
</ol>

<p>Now, it would be boring to show <em>all</em> of the code, so I’ll just show the interesting parts in each.</p>

<p>In <code>navigation_callback</code>, we exit with <code>view_dispatcher_stop(context-&gt;view_dispatcher);</code> - then it will return to where it was called from:</p>

<blockquote class="filename">
  <p>stepper.c</p>
</blockquote>
<div class="language-c highlighter-tree-sitter"><pre><code>  <span class='ts-comment'>// navigation_callback</span>

  <span class='ts-comment'>// Back means exit the application, which can be done by stopping the</span>
  <span class='ts-comment'>// ViewDispatcher.</span>
  <span class='ts-function'>view_dispatcher_stop</span>(<span class='ts-variable'>context</span><span class='ts-operator'>-&gt;</span><span class='ts-property'>view_dispatcher</span>)<span class='ts-delimiter'>;</span>
</code></pre></div>

<p><code>stepper_dispatcher_app_submenu_callback</code> actually triggers a different event conditionally, based on the submenu “index”:</p>

<blockquote class="filename">
  <p>stepper.c</p>
</blockquote>
<div class="language-c highlighter-tree-sitter"><pre><code>  <span class='ts-comment'>// stepper_dispatcher_app_submenu_callback</span>

  <span class='ts-keyword'>if</span> (<span class='ts-variable'>index</span> <span class='ts-operator'>==</span> <span class='ts-variable'>SubmenuIndexStep</span>) {
    <span class='ts-function'>view_dispatcher_send_custom_event</span>(<span class='ts-variable'>context</span><span class='ts-operator'>-&gt;</span><span class='ts-property'>view_dispatcher</span>,
                                      <span class='ts-variable'>ViewIndexStepping</span>)<span class='ts-delimiter'>;</span>
  }
</code></pre></div>

<p>Which triggers callback number 4 - we’ll get to that.</p>

<p><code>stepping_button_callback</code> has a couple of extra checks for a button getting pressed, provided by the example, in order to make sure it was a simple “press”:</p>

<blockquote class="filename">
  <p>stepper.c</p>
</blockquote>
<div class="language-c highlighter-tree-sitter"><pre><code>  <span class='ts-comment'>// stepping_button_callback</span>

  <span class='ts-comment'>// Only request the view switch if the user short-presses the Center button.</span>
  <span class='ts-keyword'>if</span> (<span class='ts-variable'>button_type</span> <span class='ts-operator'>==</span> <span class='ts-variable'>GuiButtonTypeCenter</span> <span class='ts-operator'>&amp;&amp;</span> <span class='ts-variable'>input_type</span> <span class='ts-operator'>==</span> <span class='ts-variable'>InputTypeShort</span>) {
    <span class='ts-comment'>// Request switch to the Submenu view via the custom event queue.</span>
    <span class='ts-function'>view_dispatcher_send_custom_event</span>(<span class='ts-variable'>context</span><span class='ts-operator'>-&gt;</span><span class='ts-property'>view_dispatcher</span>,
                                      <span class='ts-variable'>ViewIndexSubmenu</span>)<span class='ts-delimiter'>;</span>
  }
</code></pre></div>

<p>Finally, the big one. <code>stepper_event_callback</code> actually has a few points worth mentioning.</p>

<h3 id="back-to-stepping">Back to Stepping</h3>

<p>Here’s the issue: if we just block like before, we no longer have the same loop structure with the event queue to check what events are handled. Instead, the view dispatcher handles events for us. So, once we enter, how would we exit? If we just naively loop, we won’t leave.</p>

<p>We’re already being somewhat imprecise about timing (namely by putting a lot of logic in the loop), so we aren’t going to get the exact wait time that we want. Because of this, we have some freedom here to not reinvent anything. We’ll do this with another callback!</p>

<p>The best reference I found for this is in the <a href="https://developer.flipper.net/flipperzero/doxygen/js_event_loop.html#autotoc_md237">Javascript documentation</a>. In that example, the Javascript code creates an event that fires a second after creation:</p>

<blockquote class="filename">

</blockquote>
<div class="language-js highlighter-tree-sitter"><pre><code><span class='ts-comment'>// create an event source that will fire once 1 second after it has been created</span>
<span class='ts-keyword'>let</span> <span class='ts-variable'>timer</span> <span class='ts-operator'>=</span> <span class='ts-variable'>eventLoop</span><span class='ts-punctuation-delimiter'>.</span><span class='ts-function-method'>timer</span><span class='ts-punctuation-bracket'>(</span><span class='ts-string'>&quot;oneshot&quot;</span><span class='ts-punctuation-delimiter'>,</span> <span class='ts-number'>1000</span><span class='ts-punctuation-bracket'>)</span><span class='ts-punctuation-delimiter'>;</span>

<span class='ts-comment'>// subscribe a callback to the event source</span>
<span class='ts-variable'>eventLoop</span><span class='ts-punctuation-delimiter'>.</span><span class='ts-function-method'>subscribe</span><span class='ts-punctuation-bracket'>(</span><span class='ts-variable'>timer</span><span class='ts-punctuation-delimiter'>,</span> <span class='ts-keyword'>function</span><span class='ts-punctuation-bracket'>(</span><span class='ts-variable-parameter'>_subscription</span><span class='ts-punctuation-delimiter'>,</span> <span class='ts-variable-parameter'>_item</span><span class='ts-punctuation-delimiter'>,</span> <span class='ts-variable-parameter'>eventLoop</span><span class='ts-punctuation-bracket'>)</span> <span class='ts-punctuation-bracket'>{</span>
    <span class='ts-function'>print</span><span class='ts-punctuation-bracket'>(</span><span class='ts-string'>&quot;Hello, World!&quot;</span><span class='ts-punctuation-bracket'>)</span><span class='ts-punctuation-delimiter'>;</span>
    <span class='ts-variable-parameter'>eventLoop</span><span class='ts-punctuation-delimiter'>.</span><span class='ts-function-method'>stop</span><span class='ts-punctuation-bracket'>(</span><span class='ts-punctuation-bracket'>)</span><span class='ts-punctuation-delimiter'>;</span>
<span class='ts-punctuation-bracket'>}</span><span class='ts-punctuation-delimiter'>,</span> <span class='ts-variable'>eventLoop</span><span class='ts-punctuation-bracket'>)</span><span class='ts-punctuation-delimiter'>;</span> <span class='ts-comment'>// notice this extra argument. we&#39;ll come back to this later</span>
</code></pre></div>

<p>We’re doing something similar here, but in C. In our custom event, we want to set a timer that runs every <code>N</code> ticks. Since we don’t really care about absolute precision here, we’ll use <code>furi_event_loop_tick_set</code>. This can be done like so:</p>

<blockquote class="filename">
  <p>stepper.c</p>
</blockquote>
<div class="language-c highlighter-tree-sitter"><pre><code>    <span class='ts-function'>furi_event_loop_tick_set</span>(
        <span class='ts-function'>view_dispatcher_get_event_loop</span>(<span class='ts-variable'>context</span><span class='ts-operator'>-&gt;</span><span class='ts-property'>view_dispatcher</span>), <span class='ts-number'>3</span>,
        <span class='ts-variable'>stepper_tick_callback</span>, <span class='ts-variable'>context</span>)<span class='ts-delimiter'>;</span>
</code></pre></div>

<p>And you can stop the timer in the same function with:</p>

<blockquote class="filename">
  <p>stepper.c</p>
</blockquote>
<div class="language-c highlighter-tree-sitter"><pre><code>    <span class='ts-function'>furi_event_loop_tick_set</span>(
        <span class='ts-function'>view_dispatcher_get_event_loop</span>(<span class='ts-variable'>context</span><span class='ts-operator'>-&gt;</span><span class='ts-property'>view_dispatcher</span>), <span class='ts-number'>0</span>, <span class='ts-constant'>NULL</span>,
        <span class='ts-variable'>context</span>)<span class='ts-delimiter'>;</span>
</code></pre></div>

<p>Which one gets called depends on the <code>event</code> - if it’s <code>ViewIndexStepping</code>, then we want to start stepping. If not, we want to stop stepping.</p>

<p>The callback <code>stepper_tick_callback</code> just ticks the motor once:</p>

<blockquote class="filename">
  <p>stepper.c</p>
</blockquote>
<div class="language-c highlighter-tree-sitter"><pre><code><span class='ts-keyword'>static</span> <span class='ts-type'>void</span> <span class='ts-function'>stepper_tick_callback</span>(<span class='ts-type'>void</span> <span class='ts-operator'>*</span><span class='ts-variable'>ctx</span>) {
  <span class='ts-function'>furi_assert</span>(<span class='ts-variable'>ctx</span>)<span class='ts-delimiter'>;</span>
  <span class='ts-type'>StepperContext</span> <span class='ts-operator'>*</span><span class='ts-variable'>context</span> <span class='ts-operator'>=</span> <span class='ts-variable'>ctx</span><span class='ts-delimiter'>;</span>
  <span class='ts-function'>furi_hal_gpio_write</span>(<span class='ts-variable'>context</span><span class='ts-operator'>-&gt;</span><span class='ts-property'>step_pin</span>, true)<span class='ts-delimiter'>;</span>
  <span class='ts-function'>furi_delay_us</span>(<span class='ts-number'>10</span>)<span class='ts-delimiter'>;</span>
  <span class='ts-function'>furi_hal_gpio_write</span>(<span class='ts-variable'>context</span><span class='ts-operator'>-&gt;</span><span class='ts-property'>step_pin</span>, false)<span class='ts-delimiter'>;</span>
}
</code></pre></div>

<p>With all of this, we have… a button that says “GO!” - if you press it, it steps the motor, if not, it doesn’t. Incredible.</p>

<h3 id="choosing-the-pin">Choosing the Pin</h3>

<p>Now, we want two more submenus, one for each pin (step and dir). Those are pretty easy, I just made an enum like this which will change the pin in each case in a callback:</p>

<blockquote class="filename">
  <p>stepper.c</p>
</blockquote>
<div class="language-c highlighter-tree-sitter"><pre><code><span class='ts-comment'>// Each pin that can be used</span>
<span class='ts-keyword'>typedef</span> <span class='ts-keyword'>enum</span> {
  <span class='ts-variable'>PinA7</span>,
  <span class='ts-variable'>PinA6</span>,
  <span class='ts-variable'>PinA4</span>,
  <span class='ts-variable'>PinB3</span>,
  <span class='ts-variable'>PinB2</span>,
  <span class='ts-variable'>PinC3</span>,
  <span class='ts-variable'>PinC1</span>,
  <span class='ts-variable'>PinC0</span>,
} <span class='ts-type'>UsablePins</span><span class='ts-delimiter'>;</span>
</code></pre></div>

<p>Okay, I avoided using the GPIO examples. It’s simply annoying - if we started from the example, it would have been straightforward, but I like learning about this myself. Instead, we get more submenus, my favorite!</p>

<p>I won’t actually go through the submenu process again, but we did it twice more: once for the step pin, once for the direction pin. These pins don’t have extra validation - they may be the same. I don’t want to know what happens if they are.</p>

<p>Here’s what the app looked like after the two extra submenus:</p>

<p><img src="/assets/img/posts/flipper-hardware-p3/home.jpg" alt="Home" title="Home screen" height="500em" /></p>

<p><img src="/assets/img/posts/flipper-hardware-p3/pin-select.jpg" alt="Pin select" title="Pin select" height="500em" /></p>

<h1 id="ui-frustration">UI Frustration</h1>

<p>Developing for the Flipper Zero is enjoyable. I really liked using <a href="https://github.com/flipperdevices/flipperzero-ufbt">micro Flipper Build Tool</a>. GPIO worked as I would expect. But the UI development just stood in my way at every step. I wanted to do more - this was supposed to be a legitimate way for me to test stepper motors under various conditions! It’s just tiring. I’m tired.</p>

<p>If you want to make a real application, go for it! I’m just not great at making anything pretty, so I ended up getting pretty frustrated. Feel free to try <a href="https://developer.flipper.net/flipperzero/doxygen/js.html">Javascript</a> as well! It wasn’t an option when I started this, and I know C better.</p>

<p>All in all, the Flipper Zero was fun to mess with. Making an application was rewarding. But, the UI just kept getting in my way. I don’t think I’m cut out for screens.</p>

<p>Remember, the source code for all of this is <a href="https://github.com/evantypanski/flipper-stepper">on my Github</a>. Be warned, it should not be used as an example for how to do things right.</p>]]></content><author><name>Evan Typanski</name></author><summary type="html"><![CDATA[Read more in the "Flipper into hardware" series: Flipper your way into hardware Flipper your way into hardware - Stepping Flipper your way into hardware - UI]]></summary></entry><entry><title type="html">Flipper your way into hardware - Stepping</title><link href="https://etyp.dev/posts/flipper-into-hardware-step/" rel="alternate" type="text/html" title="Flipper your way into hardware - Stepping" /><published>2025-02-03T00:00:00-05:00</published><updated>2025-02-03T00:00:00-05:00</updated><id>https://etyp.dev/posts/flipper-into-hardware-2</id><content type="html" xml:base="https://etyp.dev/posts/flipper-into-hardware-step/"><![CDATA[<div class="series">
  <h4> Read more in the "Flipper into hardware" series: </h4>
  <ol>
    
    
    <li>
      
      <a href="/posts/flipper-into-hardware-p1/">Flipper your way into hardware</a>
      
    </li>
    
    <li>
      
      <strong>Flipper your way into hardware - Stepping</strong>
      
    </li>
    
    <li>
      
      <a href="/posts/flipper-into-hardware-ui/">Flipper your way into hardware - UI</a>
      
    </li>
    
  </ol>

  
</div>

<div class="track">
<audio title="Flipper your way into hardware p2" controls="">
  <source src="/assets/audio/posts/flipper-into-hardware-p2/flipper-into-hardware-p2.mp3" type="audio/mpeg" />
  Audio tag is not supported, sorry!
</audio>
<p><small> Let me read it for you! </small></p>
</div>

<p>Last time we left with a (crappy) app that would turn an LED on when you press the OK button and back off when you press it again. Now, we’ll take that and turn it into a stepper motor app - which is just the same thing but with a couple more moving parts (literally :) ).</p>

<h1 id="stepper-motors">Stepper motors</h1>

<p>So, first: How do stepper motors work? Well, stepper motors are a kind of brushless DC electric motor with discrete steps and don’t need a position sensor… well, that’s kind of secondary. I guess the best answer is: magnets!</p>

<p>For our purposes, we mainly care about how to make the stepper motor spin in circles (because that’s <em>definitely</em> useful). When you program a microcontroller to control a stepper motor, you’ll use a stepper motor driver (which itself is a microcontroller) - I will be using the <a href="https://www.pololu.com/product/1182">A4988</a>.</p>

<p>There are tons of tutorials on how to program these with an Arduino (I used <a href="https://www.makerguides.com/a4988-stepper-motor-driver-arduino-tutorial/">this one</a> a couple times). I’ll skip over wiring the motor and an external power supply and all of that, see some of those for specifics. What I care about is: how can I make a Flipper spin this?</p>

<p>For that, all we care about are two pins on the driver: <code>DIR</code> and <code>STEP</code> - one to change the direction we spin and one to step the motor. It’s really simple, we just send some pulse to <code>STEP</code> whenever we want to do a “step” on the motor - which may be smaller or bigger increments depending on if you wired with microstepping.</p>

<p>All of that to say: We need two pins. That’s it. One for direction, one for stepping. Let’s try it.</p>

<h1 id="adding-a-pin">Adding a pin</h1>

<p>This is really easy - first we just get separate pins for <code>dir</code> and <code>step</code> in the <code>StepperContext</code> object:</p>

<blockquote class="filename">
  <p>stepper.c</p>
</blockquote>
<div class="language-c highlighter-tree-sitter"><pre><code><span class='ts-keyword'>typedef</span> <span class='ts-keyword'>struct</span> {
    <span class='ts-comment'>// ...</span>
    <span class='ts-keyword'>const</span> <span class='ts-type'>GpioPin</span> <span class='ts-operator'>*</span><span class='ts-property'>dirPin</span><span class='ts-delimiter'>;</span>
    <span class='ts-keyword'>const</span> <span class='ts-type'>GpioPin</span> <span class='ts-operator'>*</span><span class='ts-property'>stepPin</span><span class='ts-delimiter'>;</span>
} <span class='ts-type'>StepperContext</span><span class='ts-delimiter'>;</span>
</code></pre></div>

<p>Then we’ll just go back and add a new parameter to our setup function:</p>

<blockquote class="filename">
  <p>stepper.c</p>
</blockquote>
<div class="language-c highlighter-tree-sitter"><pre><code><span class='ts-keyword'>static</span> <span class='ts-type'>StepperContext</span><span class='ts-operator'>*</span> <span class='ts-function'>stepper_context_alloc</span>(<span class='ts-type'>uint8_t</span> <span class='ts-variable'>dirPin</span>, <span class='ts-type'>uint8_t</span> <span class='ts-variable'>stepPin</span>) {
</code></pre></div>

<p>This sets them up in the same way as before, but with different names:</p>

<blockquote class="filename">
  <p>stepper.c</p>
</blockquote>
<div class="language-c highlighter-tree-sitter"><pre><code>  <span class='ts-variable'>context</span><span class='ts-operator'>-&gt;</span><span class='ts-property'>dirPin</span> <span class='ts-operator'>=</span> <span class='ts-function'>furi_hal_resources_pin_by_number</span>(<span class='ts-variable'>dirPin</span>)<span class='ts-operator'>-&gt;</span><span class='ts-property'>pin</span><span class='ts-delimiter'>;</span>
  <span class='ts-variable'>context</span><span class='ts-operator'>-&gt;</span><span class='ts-property'>stepPin</span> <span class='ts-operator'>=</span> <span class='ts-function'>furi_hal_resources_pin_by_number</span>(<span class='ts-variable'>stepPin</span>)<span class='ts-operator'>-&gt;</span><span class='ts-property'>pin</span><span class='ts-delimiter'>;</span>
</code></pre></div>

<p>Then we call this from the main <code>stepper_app</code> function along with setting up the pin:</p>

<blockquote class="filename">
  <p>stepper.c</p>
</blockquote>
<div class="language-c highlighter-tree-sitter"><pre><code>  <span class='ts-type'>StepperContext</span> <span class='ts-operator'>*</span><span class='ts-variable'>context</span> <span class='ts-operator'>=</span> <span class='ts-function'>stepper_context_alloc</span>(<span class='ts-number'>6</span>, <span class='ts-number'>7</span>)<span class='ts-delimiter'>;</span>
  <span class='ts-function'>furi_hal_gpio_write</span>(<span class='ts-variable'>context</span><span class='ts-operator'>-&gt;</span><span class='ts-property'>stepPin</span>, false)<span class='ts-delimiter'>;</span>
  <span class='ts-function'>furi_hal_gpio_init</span>(<span class='ts-variable'>context</span><span class='ts-operator'>-&gt;</span><span class='ts-property'>stepPin</span>,  <span class='ts-variable'>GpioModeOutputPushPull</span>, <span class='ts-variable'>GpioPullNo</span>, <span class='ts-variable'>GpioSpeedLow</span>)<span class='ts-delimiter'>;</span>
  <span class='ts-function'>furi_hal_gpio_write</span>(<span class='ts-variable'>context</span><span class='ts-operator'>-&gt;</span><span class='ts-property'>dirPin</span>, false)<span class='ts-delimiter'>;</span>
  <span class='ts-function'>furi_hal_gpio_init</span>(<span class='ts-variable'>context</span><span class='ts-operator'>-&gt;</span><span class='ts-property'>dirPin</span>,  <span class='ts-variable'>GpioModeOutputPushPull</span>, <span class='ts-variable'>GpioPullNo</span>, <span class='ts-variable'>GpioSpeedLow</span>)<span class='ts-delimiter'>;</span>
</code></pre></div>

<p>And finally reset the pins at the end:</p>

<blockquote class="filename">
  <p>stepper.c</p>
</blockquote>
<div class="language-c highlighter-tree-sitter"><pre><code>  <span class='ts-function'>furi_hal_gpio_init</span>(<span class='ts-variable'>context</span><span class='ts-operator'>-&gt;</span><span class='ts-property'>stepPin</span>, <span class='ts-variable'>GpioModeAnalog</span>, <span class='ts-variable'>GpioPullNo</span>, <span class='ts-variable'>GpioSpeedLow</span>)<span class='ts-delimiter'>;</span>
  <span class='ts-function'>furi_hal_gpio_init</span>(<span class='ts-variable'>context</span><span class='ts-operator'>-&gt;</span><span class='ts-property'>dirPin</span>, <span class='ts-variable'>GpioModeAnalog</span>, <span class='ts-variable'>GpioPullNo</span>, <span class='ts-variable'>GpioSpeedLow</span>)<span class='ts-delimiter'>;</span>
</code></pre></div>

<p>(obviously, changing <code>pin</code>-&gt;<code>stepPin</code> where it was used before).</p>

<p>Surprisingly, if you wired it right, this will do something! It will run one step every time you create a “rising edge” - that is, pressing the OK button to go from low to high. You can see this if you put tape or something on your stepper motor. You’ll also probably hear it.</p>

<p>Cool - now let’s make it a little more usable.</p>

<h2 id="toggling-continuous-steps">Toggling continuous steps</h2>

<p>First, it’d be nice to have this toggle continuous steps rather than just toggling a single step. To do this, we will repurpose the <code>state</code> variable in the context: now it’ll tell us if we’re stepping or not. That means we don’t need to change much to get this working - it’ll still trigger with OK and no more or fewer variables!</p>

<p>We do need to change the time out for <code>furi_message_queue_get</code> - we had it set to <code>FuriWaitForever</code> which would make it so we step once… then wait for input. Instead, we can wait forever if we’re not stepping, but when stepping we want to continue without waiting. We do this like so:</p>

<blockquote class="filename">
  <p>stepper.c</p>
</blockquote>
<div class="language-c highlighter-tree-sitter"><pre><code>    <span class='ts-comment'>// If we&#39;re stepping, don&#39;t wait</span>
    <span class='ts-type'>uint32_t</span> <span class='ts-variable'>timeout</span> <span class='ts-operator'>=</span> <span class='ts-variable'>context</span><span class='ts-operator'>-&gt;</span><span class='ts-property'>state</span> ? <span class='ts-number'>0</span> : <span class='ts-variable'>FuriWaitForever</span><span class='ts-delimiter'>;</span>
    <span class='ts-keyword'>const</span> <span class='ts-type'>FuriStatus</span> <span class='ts-variable'>status</span> <span class='ts-operator'>=</span> <span class='ts-function'>furi_message_queue_get</span>(<span class='ts-variable'>context</span><span class='ts-operator'>-&gt;</span><span class='ts-property'>event_queue</span>, <span class='ts-operator'>&amp;</span><span class='ts-variable'>event</span>, <span class='ts-variable'>timeout</span>)<span class='ts-delimiter'>;</span>
</code></pre></div>

<p>Surprisingly enough, there is exactly one more thing that needs done: stepping! That’s just turning the <code>STEP</code> pin high then low with a delay between, which I do at the top of the loop so that it’s always run:</p>

<blockquote class="filename">
  <p>stepper.c</p>
</blockquote>
<div class="language-c highlighter-tree-sitter"><pre><code>    <span class='ts-comment'>// Step before checking anything else</span>
    <span class='ts-keyword'>if</span> (<span class='ts-variable'>context</span><span class='ts-operator'>-&gt;</span><span class='ts-property'>state</span>) {
      <span class='ts-function'>furi_hal_gpio_write</span>(<span class='ts-variable'>context</span><span class='ts-operator'>-&gt;</span><span class='ts-property'>stepPin</span>, true)<span class='ts-delimiter'>;</span>
      <span class='ts-function'>furi_delay_us</span>(<span class='ts-number'>10</span>)<span class='ts-delimiter'>;</span>
      <span class='ts-function'>furi_hal_gpio_write</span>(<span class='ts-variable'>context</span><span class='ts-operator'>-&gt;</span><span class='ts-property'>stepPin</span>, false)<span class='ts-delimiter'>;</span>
      <span class='ts-function'>furi_delay_us</span>(<span class='ts-number'>3000</span>)<span class='ts-delimiter'>;</span>
    }
</code></pre></div>

<p>The time high (after writing <code>true</code>) is inconsequential here since we really only care about the rising edge. Calling the function itself has overhead. We’ll wait 10 microseconds for the heck of it.</p>

<p>Then we wait a bit of time after stepping. I was a bit generous and gave it 3 milliseconds, but you can figure it out for your motor and driver. I’m not making anything where that would matter.</p>

<p>Now, the keen eyed among you will remember that when setting up the pins, we passed in <code>GpioSpeedLow</code> - but now we’re waiting a very small amount of time!</p>

<blockquote class="filename">
  <p>stepper.c</p>
</blockquote>
<div class="language-c highlighter-tree-sitter"><pre><code>  <span class='ts-function'>furi_hal_gpio_init</span>(<span class='ts-variable'>context</span><span class='ts-operator'>-&gt;</span><span class='ts-property'>stepPin</span>, <span class='ts-variable'>GpioModeAnalog</span>, <span class='ts-variable'>GpioPullNo</span>, <span class='ts-variable'>GpioSpeedLow</span>)<span class='ts-delimiter'>;</span>
</code></pre></div>

<p>Is that okay?</p>

<p>Well, the short answer is, “I think so.” Basically, you want to choose the lowest speed that works for your context. I get a spinning motor with this, so obviously it works! But, if you want more information, that’s actually a product of some registers in the underlying microcontroller, the <a href="https://www.st.com/en/microcontrollers-microprocessors/stm32-32-bit-arm-cortex-mcus.html">STM32</a>. If you’re curious, there’s a whole <a href="https://www.st.com/en/microcontrollers-microprocessors/stm32wb55rg.html">194 page datasheet</a> you can rummage through.</p>

<h1 id="the-app-so-far">The app so far</h1>

<p>So now we have a real application which will toggle spinning a motor:</p>

<p><img src="/assets/img/posts/flipper-hardware-p2/stepping.gif" alt="Stepping" title="Stepping that motor" height="500em" /></p>

<p>It’s pretty cool that in 2 short posts we’re at a place where something physical is happening from the Flipper. There’s a lot more that can be done here to make the app useful and pretty.</p>

<p>For now, though, this was my intention when I set out to make this app: Interacting with hardware via the Flipper Zero. There’s pretty active development on the Github for ways to make the app-building experience easier (like <a href="https://www.reddit.com/r/flipperzero/comments/1h5lsuu/introducing_the_javascript_sdk_for_flipper_zero/">Javascript</a>).</p>

<p>Until then, enjoy… flipping? Stepping?</p>]]></content><author><name>Evan Typanski</name></author><summary type="html"><![CDATA[Read more in the "Flipper into hardware" series: Flipper your way into hardware Flipper your way into hardware - Stepping Flipper your way into hardware - UI]]></summary></entry><entry><title type="html">Flipper your way into hardware</title><link href="https://etyp.dev/posts/flipper-into-hardware-p1/" rel="alternate" type="text/html" title="Flipper your way into hardware" /><published>2024-12-03T00:00:00-05:00</published><updated>2024-12-03T00:00:00-05:00</updated><id>https://etyp.dev/posts/flipper-into-hardware</id><content type="html" xml:base="https://etyp.dev/posts/flipper-into-hardware-p1/"><![CDATA[<div class="series">
  <h4> Read more in the "Flipper into hardware" series: </h4>
  <ol>
    
    
    <li>
      
      <strong>Flipper your way into hardware</strong>
      
    </li>
    
    <li>
      
      <a href="/posts/flipper-into-hardware-step/">Flipper your way into hardware - Stepping</a>
      
    </li>
    
    <li>
      
      <a href="/posts/flipper-into-hardware-ui/">Flipper your way into hardware - UI</a>
      
    </li>
    
  </ol>

  
</div>

<div class="track">
<audio title="Flipper your way into hardware p1" controls="">
  <source src="/assets/audio/posts/flipper-into-hardware-p1/flipper-into-hardware-p1.mp3" type="audio/mpeg" />
  Audio tag is not supported, sorry!
</audio>
<p><small> Let me read it for you! </small></p>
</div>

<p>The <a href="https://flipperzero.one/">Flipper Zero</a> is a cool little multitool. You can clone RFID cards or… do lots of other things. From what I can tell, most people just clone a few cards then have a fancy paperweight. It’s cool, but the actual utility is kind of hard to spot.</p>

<p>I’m interested in the Flipper Zero, but for a different reason: it has GPIO pins! I really love messing with microcontrollers. This seems like a neat tool for that. You can do anything a microcontroller does, plus you have a lot of stuff built in (like a screen for GUI).</p>

<p>So, here I’ll explore what I did in order to make a small application to run a stepper motor. This isn’t for any practical purpose, so the app itself is pretty minimal. It’s just fun to see what it can do, then maybe later I’ll use that knowledge to create something actually useful.</p>

<p>If you do want to see the code, though, you can find it on <a href="https://github.com/evantypanski/flipper-stepper">my Github</a>.</p>

<p>This isn’t a tutorial. In fact, some of this code probably isn’t worth copying. It’s just an exploration. A lot of the Flipper Zero content that I’ve seen assumes a lot of knowledge or doesn’t explain it very well. This is my journey to sift through all of that.</p>

<p>But, it will be multiple parts.</p>

<h1 id="making-the-app">Making the app</h1>

<p>Throughout this process, we’ll use <a href="https://github.com/flipperdevices/flipperzero-ufbt">micro Flipper Build Tool</a>.</p>

<p>The first step is easy: make the project!</p>

<blockquote class="shell">

</blockquote>
<div class="language-bash highlighter-tree-sitter"><pre><code><span class='ts-function'>python3</span> <span class='ts-constant'>-m</span> ufbt create APPID=stepper
</code></pre></div>

<p>Now we have a stepper app with a few different files. We need to make sure this runs as is, so we’ll launch it:</p>

<blockquote class="shell">

</blockquote>
<div class="language-bash highlighter-tree-sitter"><pre><code><span class='ts-function'>python3</span> <span class='ts-constant'>-m</span> ufbt launch
</code></pre></div>

<p>This should load the app on the Flipper Zero. That app is in the apps menu, <code>Examples</code> directory.</p>

<p>… and it does nothing. Well, the source code provided <em>does</em> log some stuff:</p>

<blockquote class="filename">
  <p>stepper.c</p>
</blockquote>
<div class="language-c highlighter-tree-sitter"><pre><code><span class='ts-keyword'>#include</span> <span class='ts-string'>&lt;furi.h&gt;</span>

<span class='ts-comment'>/* generated by fbt from .png files in images folder */</span>
<span class='ts-keyword'>#include</span> <span class='ts-string'>&lt;stepper_icons.h&gt;</span>

<span class='ts-type'>int32_t</span> <span class='ts-function'>stepper_app</span>(<span class='ts-type'>void</span><span class='ts-operator'>*</span> <span class='ts-variable'>p</span>) {
    <span class='ts-function'>UNUSED</span>(<span class='ts-variable'>p</span>)<span class='ts-delimiter'>;</span>
    <span class='ts-function'>FURI_LOG_I</span>(<span class='ts-string'>&quot;TEST&quot;</span>, <span class='ts-string'>&quot;Hello world&quot;</span>)<span class='ts-delimiter'>;</span>
    <span class='ts-function'>FURI_LOG_I</span>(<span class='ts-string'>&quot;TEST&quot;</span>, <span class='ts-string'>&quot;I&#39;m stepper!&quot;</span>)<span class='ts-delimiter'>;</span>

    <span class='ts-keyword'>return</span> <span class='ts-number'>0</span><span class='ts-delimiter'>;</span>
}
</code></pre></div>

<p>So how do we see that? Through the CLI! Find the way that fits you best via the <a href="https://docs.flipper.net/development/cli">documentation’s CLI</a> section. For me, I do everything in the terminal, so I used <code>screen</code> with the device directly. To do that, I just found the device:</p>

<blockquote class="shell">

</blockquote>
<div class="language-bash highlighter-tree-sitter"><pre><code><span class='ts-function'><span class='ts-operator'>$</span> <span class='ts-property'>ls</span></span> /dev/serial/by-id/
<span class='ts-function'>usb-Flipper_Devices_Inc._Flipper_Idolisle_flip_Idolisle-if00</span>
</code></pre></div>

<p>Then I ran <code>screen</code> on that device:</p>

<blockquote class="shell">

</blockquote>
<div class="language-bash highlighter-tree-sitter"><pre><code><span class='ts-function'><span class='ts-operator'>$</span> <span class='ts-property'>screen</span></span> /dev/serial/by-id/usb-Flipper_Devices_Inc._Flipper_Idolisle_flip_Idolisle-if00
              <span class='ts-function'>_.-------.._</span>                    <span class='ts-constant'>-,</span>
          .-&quot;```&quot;--..,,_/ /`<span class='ts-function'>-,</span>               -,  \
       .:&quot;          /:/  /&#39;\  \     ,_...,  <span class='ts-embedded'>`<span class='ts-function'>.</span> <span class='ts-operator'>|</span>  <span class='ts-operator'>|</span></span>
<span class='ts-embedded'>      <span class='ts-function'>/</span>       ,----/:/  /`</span>\ _\~`_-&quot;`     <span class='ts-function'>_</span>;
     <span class='ts-function'><span class='ts-string'>&#39;      / /`&quot;&quot;&quot;&#39;</span></span>\ \ \.~`<span class='ts-function'>_-<span class='ts-string'>&#39;      ,-&quot;&#39;</span>/</span>
    <span class='ts-operator'>|</span>      <span class='ts-operator'>|</span> <span class='ts-operator'>|</span>  <span class='ts-function'>0</span>    <span class='ts-operator'>|</span> <span class='ts-operator'>|</span> <span class='ts-function'>.-<span class='ts-string'>&#39;      ,/`  /</span></span>
<span class='ts-function'><span class='ts-string'>   |    ,..\ \     ,.-&quot;`       ,/`    /</span></span>
<span class='ts-function'><span class='ts-string'>  ;    :    `/`&quot;&quot;\`           ,/--==,/-----,</span></span>
<span class='ts-function'><span class='ts-string'>  |    `-...|        -.___-Z:_______J...---;</span></span>
<span class='ts-function'><span class='ts-string'>  :         `                           _-&#39;</span></span>
 _L_  _     ___  ___  ___  ___  ____--&quot;`<span class='ts-function'>___</span>  _     ___
<span class='ts-operator'>|</span> <span class='ts-function'>__</span>|| <span class='ts-operator'>|</span>   <span class='ts-operator'>|</span><span class='ts-function'>_</span> _|| <span class='ts-function'>_</span> \| _ \| __|| <span class='ts-function'>_</span> \   / __|| <span class='ts-operator'>|</span>   <span class='ts-operator'>|</span><span class='ts-function'>_</span> _<span class='ts-operator'>|</span><span class='ts-function'></span>
<span class='ts-operator'>|</span> <span class='ts-function'>_</span><span class='ts-operator'>|</span> <span class='ts-operator'>|</span> <span class='ts-operator'>|</span><span class='ts-function'>__</span>  <span class='ts-operator'>|</span> <span class='ts-operator'>|</span> <span class='ts-operator'>|</span>  <span class='ts-function'>_/</span><span class='ts-operator'>|</span>  <span class='ts-function'>_/</span><span class='ts-operator'>|</span> <span class='ts-function'>_</span><span class='ts-operator'>|</span><span class='ts-function'></span> <span class='ts-operator'>|</span>   <span class='ts-function'>/</span>  <span class='ts-operator'>|</span> (<span class='ts-function'>__</span> <span class='ts-operator'>|</span> <span class='ts-operator'>|</span><span class='ts-function'>__</span>  <span class='ts-operator'>|</span> <span class='ts-operator'>|</span><span class='ts-function'></span>
<span class='ts-operator'>|</span><span class='ts-function'>_</span><span class='ts-operator'>|</span>  <span class='ts-operator'>|</span><span class='ts-function'>____</span>||<span class='ts-function'>___</span>||<span class='ts-function'>_</span><span class='ts-operator'>|</span>  <span class='ts-operator'>|</span><span class='ts-function'>_</span><span class='ts-operator'>|</span>  <span class='ts-operator'>|</span><span class='ts-function'>___</span>||<span class='ts-function'>_</span><span class='ts-operator'>|</span><span class='ts-function'>_\ </span>  \___||<span class='ts-function'>____</span>||<span class='ts-function'>___</span><span class='ts-operator'>|</span>

<span class='ts-function'>Welcome</span> to Flipper Zero Command Line Interface!
<span class='ts-function'>Read</span> the manual: https://docs.flipper.net/development/cli
<span class='ts-function'>Run</span> <span class='ts-embedded'>`<span class='ts-function'>help</span>`</span> or <span class='ts-embedded'>`<span class='ts-function'>?</span>`</span> to list available commands

<span class='ts-function'>Firmware</span> version: 1.0.1 1.0.1 (<span class='ts-function'>fe424061</span> built on 10-09-2024)

<span class='ts-operator'>&gt;</span>:
</code></pre></div>

<p>Great, we’re in. Now it’s pretty simple. I just ran <code>log</code> in the CLI prompt and I see:</p>

<blockquote class="shell">

</blockquote>
<div class="language-bash highlighter-tree-sitter"><pre><code><span class='ts-operator'>&gt;</span>: <span class='ts-function'>log</span>
<span class='ts-function'>Current</span> log level: info
<span class='ts-function'>Use</span> <span class='ts-operator'>&lt;</span>log ?<span class='ts-operator'>&gt;</span> to list available log levels
<span class='ts-function'>Press</span> CTRL+C to stop...
<span class='ts-function'>1431052</span> [I][AnimationManager] Unload animation <span class='ts-string'>&#39;L1_Sad_song_128x64&#39;</span>
<span class='ts-function'>1431060</span> [I][Loader] Loading /ext/apps/Examples/stepper.fap
<span class='ts-function'>1431091</span> [I][Elf] Total size of loaded sections: 74
<span class='ts-function'>1431094</span> [I][Loader] Loaded in 34ms
<span class='ts-function'>1431097</span> [I][TEST] Hello world
<span class='ts-function'>1431099</span> [I][TEST] I<span class='ts-string'>&#39;m stepper!</span>
<span class='ts-string'>1431123 [I][Loader] App returned: 0</span>
<span class='ts-string'>1431125 [I][Loader] Application stopped. Free heap: 124880</span>
<span class='ts-string'>1432254 [I][AnimationManager] Select &#39;</span>L1_Sad_song_128x64<span class='ts-string'>&#39; animation</span>
<span class='ts-string'>1432258 [I][AnimationManager] Load animation &#39;</span>L1_Sad_song_128x64&#39;
</code></pre></div>

<p>You can see our two log commands: “Hello world” and “I’m stepper!” Please ignore the fact that my flipper is playing the sad song animation, I promise it’s fine.</p>

<p>So, now back to the code. How did we even get those logging macros (<code>FURI_LOG_I</code>)? Well, the developer docs link to our included <code>furi.h</code> file <a href="https://developer.flipper.net/flipperzero/doxygen/furi_8h_source.html">here</a> - but that is just a header that includes a bunch of other headers. You can find the source code in that developer documentation or <a href="https://github.com/flipperdevices/flipperzero-firmware/tree/dev/furi">in the firmware repo</a>. For now I’ll look in the developer documentation. Just searching for the <code>FURI_LOG_I</code> in question finds a <a href="https://developer.flipper.net/flipperzero/doxygen/log_8h.html#a76227668659d8091501c81d659e2cc67">macro definition</a> with the following value:</p>

<blockquote class="filename">
  <p>log.h</p>
</blockquote>
<div class="language-c highlighter-tree-sitter"><pre><code><span class='ts-function'>furi_log_print_format</span>(<span class='ts-variable'>FuriLogLevelInfo</span>, <span class='ts-variable'>tag</span>, <span class='ts-variable'>format</span>, ##<span class='ts-variable'>__VA_ARGS__</span>)<span class='ts-delimiter'></span>
</code></pre></div>

<p>So, we now know where the development library is and how to search for what we need - great!</p>

<p>My goal here is to use one single pin from the Flipper to control a stepper motor. If we can get a pin working to, say, control an LED - then we can modify that until we control a stepper motor.</p>

<p>That means I need to find how to control a pin. As a first course of action, I searched for GPIO and… <a href="https://developer.flipper.net/flipperzero/doxygen/js_gpio.html#autotoc_md195">found exactly what I wanted</a>. But, that’s Javascript, so I searched a little more and found the <a href="https://developer.flipper.net/flipperzero/doxygen/furi__hal__gpio_8h_source.html">HAL (hardware abstraction layer) file</a> in C.</p>

<p>Unfortunately, for C, we don’t get a nice and easy example to copy-paste to do this for us, so we’ll have to figure it out ourselves. :(</p>

<p>GPIO is all handled in some <a href="https://developer.flipper.net/flipperzero/doxygen/furi__hal__gpio_8h_source.html"><code>furi_hal_gpio.h</code></a> header. We can find a couple functions that seem useful, like:</p>

<blockquote class="filename">
  <p>furi_hal_gpio.h</p>
</blockquote>
<div class="language-c highlighter-tree-sitter"><pre><code><span class='ts-type'>void</span> <span class='ts-function'>furi_hal_gpio_init_simple</span>(<span class='ts-keyword'>const</span> <span class='ts-type'>GpioPin</span><span class='ts-operator'>*</span> <span class='ts-variable'>gpio</span>, <span class='ts-keyword'>const</span> <span class='ts-type'>GpioMode</span> <span class='ts-variable'>mode</span>)<span class='ts-delimiter'>;</span>
</code></pre></div>

<p>and:</p>

<blockquote class="filename">
  <p>furi_hal_gpio.h</p>
</blockquote>
<div class="language-c highlighter-tree-sitter"><pre><code><span class='ts-keyword'>static</span> <span class='ts-keyword'>inline</span> <span class='ts-type'>void</span> <span class='ts-function'>furi_hal_gpio_write</span>(<span class='ts-keyword'>const</span> <span class='ts-type'>GpioPin</span><span class='ts-operator'>*</span> <span class='ts-variable'>gpio</span>, <span class='ts-keyword'>const</span> <span class='ts-type'>bool</span> <span class='ts-variable'>state</span>) {
</code></pre></div>

<p>We do need the <code>GpioPin</code> struct, which is:</p>

<blockquote class="filename">
  <p>furi_hal_gpio.h</p>
</blockquote>
<div class="language-c highlighter-tree-sitter"><pre><code><span class='ts-keyword'>typedef</span> <span class='ts-keyword'>struct</span> {
    <span class='ts-type'>GPIO_TypeDef</span><span class='ts-operator'>*</span> <span class='ts-property'>port</span><span class='ts-delimiter'>;</span>
    <span class='ts-type'>uint16_t</span> <span class='ts-property'>pin</span><span class='ts-delimiter'>;</span>
} <span class='ts-type'>GpioPin</span><span class='ts-delimiter'>;</span>
</code></pre></div>

<p>So there are a couple ways to do this. Manually doing this would mean taking 2 seconds to look at the data sheet and finding the port and pin used for the pin we want (something I explored a lot in my <a href="https://etyp.dev/posts/arduino-demystified/">Arduino Demystified</a> post). But, they also conveniently provide a <a href="https://developer.flipper.net/flipperzero/doxygen/f7_2furi__hal_2furi__hal__resources_8h_source.html"><code>furi_hal_resources.h</code></a> file with this promising function:</p>

<blockquote class="filename">
  <p>furi_hal_resources.h</p>
</blockquote>
<div class="language-c highlighter-tree-sitter"><pre><code><span class='ts-keyword'>const</span> <span class='ts-type'>GpioPinRecord</span><span class='ts-operator'>*</span> <span class='ts-function'>furi_hal_resources_pin_by_number</span>(<span class='ts-type'>uint8_t</span> <span class='ts-variable'>number</span>)<span class='ts-delimiter'>;</span>
</code></pre></div>

<p>Okay, so now we have a solid understanding of how to get what we need for GPIO. Let’s put that into action.</p>

<h1 id="making-my-app-blink">Making my app blink</h1>

<p>So first, let’s just make sure we know what these functions <em>do</em>. For this, I just want to grab a random pin number (say pin 7) then see if the name we grab matches what is printed on my Flipper. To do this, I needed to switch to the firmware <code>dev</code> branch, since those functions were just added (I’m on the cutting edge, you know). You can do this, too:</p>

<blockquote class="shell">

</blockquote>
<div class="language-bash highlighter-tree-sitter"><pre><code><span class='ts-function'><span class='ts-operator'>$</span> <span class='ts-property'>python3</span></span> <span class='ts-constant'>-m</span> ufbt update <span class='ts-constant'>--branch=dev</span>
<span class='ts-function'><span class='ts-operator'>$</span> <span class='ts-property'>python3</span></span> <span class='ts-constant'>-m</span> ufbt flash_usb
</code></pre></div>

<p>Then with that, I changed my <code>stepper.c</code> file:</p>

<blockquote class="filename">
  <p>stepper.c</p>
</blockquote>
<div class="language-c highlighter-tree-sitter"><pre><code><span class='ts-keyword'>#include</span> <span class='ts-string'>&lt;furi.h&gt;</span>
<span class='ts-keyword'>#include</span> <span class='ts-string'>&lt;furi_hal_resources.h&gt;</span>

<span class='ts-type'>int32_t</span> <span class='ts-function'>stepper_app</span>(<span class='ts-type'>void</span><span class='ts-operator'>*</span> <span class='ts-variable'>p</span>) {
    <span class='ts-function'>UNUSED</span>(<span class='ts-variable'>p</span>)<span class='ts-delimiter'>;</span>
    <span class='ts-function'>FURI_LOG_I</span>(<span class='ts-string'>&quot;PIN&quot;</span>, <span class='ts-function'>furi_hal_resources_pin_by_number</span>(<span class='ts-number'>7</span>)<span class='ts-operator'>-&gt;</span><span class='ts-property'>name</span>)<span class='ts-delimiter'>;</span>

    <span class='ts-keyword'>return</span> <span class='ts-number'>0</span><span class='ts-delimiter'>;</span>
}
</code></pre></div>

<p>Loaded it on my flipper, then checked the logs again:</p>

<blockquote class="shell">

</blockquote>
<div class="language-bash highlighter-tree-sitter"><pre><code><span class='ts-function'>38695</span> [I][PIN] PC3
</code></pre></div>

<p>That’s what pin 7 is labelled with! Awesome, so now we have access to a pin. It’s all through this <code>GpioPinRecord</code> struct:</p>

<blockquote class="filename">
  <p>furi_hal_resources.h</p>
</blockquote>
<div class="language-c highlighter-tree-sitter"><pre><code><span class='ts-keyword'>typedef</span> <span class='ts-keyword'>struct</span> {
    <span class='ts-keyword'>const</span> <span class='ts-type'>GpioPin</span><span class='ts-operator'>*</span> <span class='ts-property'>pin</span><span class='ts-delimiter'>;</span>
    <span class='ts-keyword'>const</span> <span class='ts-type'>char</span><span class='ts-operator'>*</span> <span class='ts-property'>name</span><span class='ts-delimiter'>;</span>
    <span class='ts-keyword'>const</span> <span class='ts-type'>FuriHalAdcChannel</span> <span class='ts-property'>channel</span><span class='ts-delimiter'>;</span>
    <span class='ts-keyword'>const</span> <span class='ts-type'>uint8_t</span> <span class='ts-property'>number</span><span class='ts-delimiter'>;</span>
    <span class='ts-keyword'>const</span> <span class='ts-type'>bool</span> <span class='ts-property'>debug</span><span class='ts-delimiter'>;</span>
} <span class='ts-type'>GpioPinRecord</span><span class='ts-delimiter'>;</span>
</code></pre></div>

<p>All we really care about is the <code>pin</code> member - that’s what the <code>furi_hal_gpio_write</code> function expects.</p>

<h2 id="the-gui-nonsense">The GUI nonsense</h2>

<p>At this point, we want an application that looks like <em>something</em>. Not only will that make everything else easier, but it’s actually necessary. The GUI’s <a href="https://developer.flipper.net/flipperzero/doxygen/view__port_8h.html">viewport</a> is what deals with inputs, we can even see <code>view_port_input_callback_set</code> which we provide a function that gets called on input. While we’re at it, we’ll just also add a nice draw callback, too. We could do this without the buttons, but I want to use the buttons.</p>

<p>The goal for a UI is simple right now: just show the current state of the pin (0 or 1). We can double check that aligns with what the LED shows. This is pretty explanatory with the code. It’s also not very useful right now. Here’s the callback I made:</p>

<blockquote class="filename">
  <p>stepper.c</p>
</blockquote>
<div class="language-c highlighter-tree-sitter"><pre><code><span class='ts-keyword'>#define</span> <span class='ts-constant'>TEXT_STORE_SIZE</span>  64U
<span class='ts-keyword'>static</span> <span class='ts-type'>void</span> <span class='ts-function'>stepper_draw_callback</span>(<span class='ts-type'>Canvas</span><span class='ts-operator'>*</span> <span class='ts-variable'>canvas</span>, <span class='ts-type'>void</span><span class='ts-operator'>*</span> <span class='ts-variable'>ctx</span>) {
    <span class='ts-type'>StepperContext</span><span class='ts-operator'>*</span> <span class='ts-variable'>context</span> <span class='ts-operator'>=</span> <span class='ts-variable'>ctx</span><span class='ts-delimiter'>;</span>

    <span class='ts-type'>char</span> <span class='ts-variable'>text_store</span>[<span class='ts-constant'>TEXT_STORE_SIZE</span>]<span class='ts-delimiter'>;</span>
    <span class='ts-function'>snprintf</span>(<span class='ts-variable'>text_store</span>, <span class='ts-constant'>TEXT_STORE_SIZE</span>, <span class='ts-string'>&quot;State: %d&quot;</span>, <span class='ts-variable'>context</span><span class='ts-operator'>-&gt;</span><span class='ts-property'>state</span>)<span class='ts-delimiter'>;</span>

    <span class='ts-keyword'>const</span> <span class='ts-type'>size_t</span> <span class='ts-variable'>middle_x</span> <span class='ts-operator'>=</span> <span class='ts-function'>canvas_width</span>(<span class='ts-variable'>canvas</span>) / <span class='ts-number'>2U</span><span class='ts-delimiter'>;</span>
    <span class='ts-function'>canvas_draw_str_aligned</span>(<span class='ts-variable'>canvas</span>, <span class='ts-variable'>middle_x</span>, <span class='ts-number'>58</span>, <span class='ts-variable'>AlignCenter</span>, <span class='ts-variable'>AlignBottom</span>, <span class='ts-variable'>text_store</span>)<span class='ts-delimiter'>;</span>
}
</code></pre></div>

<p>These callbacks use a <code>void*</code> parameter to pass in the “context” used - we’ll see how that’s set up in a second. The other callback is for inputs (say, button presses). That’s even easier:</p>

<blockquote class="filename">
  <p>stepper.c</p>
</blockquote>
<div class="language-c highlighter-tree-sitter"><pre><code><span class='ts-keyword'>static</span> <span class='ts-type'>void</span> <span class='ts-function'>stepper_input_callback</span>(<span class='ts-type'>InputEvent</span><span class='ts-operator'>*</span> <span class='ts-variable'>event</span>, <span class='ts-type'>void</span><span class='ts-operator'>*</span> <span class='ts-variable'>ctx</span>) {
    <span class='ts-type'>StepperContext</span><span class='ts-operator'>*</span> <span class='ts-variable'>context</span> <span class='ts-operator'>=</span> <span class='ts-variable'>ctx</span><span class='ts-delimiter'>;</span>
    <span class='ts-function'>furi_message_queue_put</span>(<span class='ts-variable'>context</span><span class='ts-operator'>-&gt;</span><span class='ts-property'>event_queue</span>, <span class='ts-variable'>event</span>, <span class='ts-variable'>FuriWaitForever</span>)<span class='ts-delimiter'>;</span>
}
</code></pre></div>

<p>We just shove the <code>event</code> we get into an <code>event_queue</code>. That’s in a <code>StepperContext</code> struct that we put at the top:</p>

<blockquote class="filename">
  <p>stepper.c</p>
</blockquote>
<div class="language-c highlighter-tree-sitter"><pre><code><span class='ts-keyword'>typedef</span> <span class='ts-keyword'>struct</span> {
    <span class='ts-type'>Gui</span><span class='ts-operator'>*</span> <span class='ts-property'>gui</span><span class='ts-delimiter'>;</span>
    <span class='ts-type'>ViewPort</span><span class='ts-operator'>*</span> <span class='ts-property'>view_port</span><span class='ts-delimiter'>;</span>
    <span class='ts-type'>FuriMessageQueue</span><span class='ts-operator'>*</span> <span class='ts-property'>event_queue</span><span class='ts-delimiter'>;</span>
    <span class='ts-keyword'>const</span> <span class='ts-type'>GpioPin</span> <span class='ts-operator'>*</span><span class='ts-property'>pin</span><span class='ts-delimiter'>;</span>
    <span class='ts-type'>bool</span> <span class='ts-property'>state</span><span class='ts-delimiter'>;</span>
} <span class='ts-type'>StepperContext</span><span class='ts-delimiter'>;</span>
</code></pre></div>

<p>Cool, but we have no idea how these are set up. This set up is in a function <code>stepper_context_alloc</code>:</p>

<blockquote class="filename">
  <p>stepper.c</p>
</blockquote>
<div class="language-c highlighter-tree-sitter"><pre><code><span class='ts-keyword'>static</span> <span class='ts-type'>StepperContext</span><span class='ts-operator'>*</span> <span class='ts-function'>stepper_context_alloc</span>(<span class='ts-type'>uint8_t</span> <span class='ts-variable'>pin</span>) {
  <span class='ts-type'>StepperContext</span><span class='ts-operator'>*</span> <span class='ts-variable'>context</span> <span class='ts-operator'>=</span> <span class='ts-function'>malloc</span>(<span class='ts-keyword'>sizeof</span>(<span class='ts-variable'>StepperContext</span>))<span class='ts-delimiter'>;</span>

  <span class='ts-variable'>context</span><span class='ts-operator'>-&gt;</span><span class='ts-property'>view_port</span> <span class='ts-operator'>=</span> <span class='ts-function'>view_port_alloc</span>()<span class='ts-delimiter'>;</span>
  <span class='ts-function'>view_port_draw_callback_set</span>(<span class='ts-variable'>context</span><span class='ts-operator'>-&gt;</span><span class='ts-property'>view_port</span>, <span class='ts-variable'>stepper_draw_callback</span>, <span class='ts-variable'>context</span>)<span class='ts-delimiter'>;</span>
  <span class='ts-function'>view_port_input_callback_set</span>(<span class='ts-variable'>context</span><span class='ts-operator'>-&gt;</span><span class='ts-property'>view_port</span>, <span class='ts-variable'>stepper_input_callback</span>, <span class='ts-variable'>context</span>)<span class='ts-delimiter'>;</span>
  <span class='ts-variable'>context</span><span class='ts-operator'>-&gt;</span><span class='ts-property'>event_queue</span> <span class='ts-operator'>=</span> <span class='ts-function'>furi_message_queue_alloc</span>(<span class='ts-number'>8</span>, <span class='ts-keyword'>sizeof</span>(<span class='ts-variable'>InputEvent</span>))<span class='ts-delimiter'>;</span>
  <span class='ts-variable'>context</span><span class='ts-operator'>-&gt;</span><span class='ts-property'>pin</span> <span class='ts-operator'>=</span> <span class='ts-function'>furi_hal_resources_pin_by_number</span>(<span class='ts-variable'>pin</span>)<span class='ts-operator'>-&gt;</span><span class='ts-property'>pin</span><span class='ts-delimiter'>;</span>

  <span class='ts-variable'>context</span><span class='ts-operator'>-&gt;</span><span class='ts-property'>gui</span> <span class='ts-operator'>=</span> <span class='ts-function'>furi_record_open</span>(<span class='ts-constant'>RECORD_GUI</span>)<span class='ts-delimiter'>;</span>
  <span class='ts-function'>gui_add_view_port</span>(<span class='ts-variable'>context</span><span class='ts-operator'>-&gt;</span><span class='ts-property'>gui</span>, <span class='ts-variable'>context</span><span class='ts-operator'>-&gt;</span><span class='ts-property'>view_port</span>, <span class='ts-variable'>GuiLayerFullscreen</span>)<span class='ts-delimiter'>;</span>
  <span class='ts-variable'>context</span><span class='ts-operator'>-&gt;</span><span class='ts-property'>state</span> <span class='ts-operator'>=</span> false<span class='ts-delimiter'>;</span>
  <span class='ts-keyword'>return</span> <span class='ts-variable'>context</span><span class='ts-delimiter'>;</span>
}
</code></pre></div>

<p>Okay that’s a lot. I’ll go line by line:</p>

<blockquote class="filename">
  <p>stepper.c</p>
</blockquote>
<div class="language-c highlighter-tree-sitter"><pre><code>  <span class='ts-type'>StepperContext</span><span class='ts-operator'>*</span> <span class='ts-variable'>context</span> <span class='ts-operator'>=</span> <span class='ts-function'>malloc</span>(<span class='ts-keyword'>sizeof</span>(<span class='ts-variable'>StepperContext</span>))<span class='ts-delimiter'>;</span>
</code></pre></div>

<p>Allocates the memory for <code>context</code> - easy enough, that’s just C.</p>

<blockquote class="filename">
  <p>stepper.c</p>
</blockquote>
<div class="language-c highlighter-tree-sitter"><pre><code>  <span class='ts-variable'>context</span><span class='ts-operator'>-&gt;</span><span class='ts-property'>view_port</span> <span class='ts-operator'>=</span> <span class='ts-function'>view_port_alloc</span>()<span class='ts-delimiter'>;</span>
</code></pre></div>

<p>Same as before (allocates memory for a <code>ViewPort</code>) but for some reason we have a helper function.</p>

<blockquote class="filename">
  <p>stepper.c</p>
</blockquote>
<div class="language-c highlighter-tree-sitter"><pre><code>  <span class='ts-function'>view_port_draw_callback_set</span>(<span class='ts-variable'>context</span><span class='ts-operator'>-&gt;</span><span class='ts-property'>view_port</span>, <span class='ts-variable'>stepper_draw_callback</span>, <span class='ts-variable'>context</span>)<span class='ts-delimiter'>;</span>
  <span class='ts-function'>view_port_input_callback_set</span>(<span class='ts-variable'>context</span><span class='ts-operator'>-&gt;</span><span class='ts-property'>view_port</span>, <span class='ts-variable'>stepper_input_callback</span>, <span class='ts-variable'>context</span>)<span class='ts-delimiter'>;</span>
</code></pre></div>

<p>This sets up the two callbacks we defined before. You can see this it where we pass in the <code>context</code> pointer that gets passed into the callback on call.</p>

<blockquote class="filename">
  <p>stepper.c</p>
</blockquote>
<div class="language-c highlighter-tree-sitter"><pre><code>  <span class='ts-variable'>context</span><span class='ts-operator'>-&gt;</span><span class='ts-property'>event_queue</span> <span class='ts-operator'>=</span> <span class='ts-function'>furi_message_queue_alloc</span>(<span class='ts-number'>8</span>, <span class='ts-keyword'>sizeof</span>(<span class='ts-variable'>InputEvent</span>))<span class='ts-delimiter'>;</span>
</code></pre></div>

<p>Allocates a message queue which can hold <code>8</code> messages, but it’s still basically just a <code>malloc</code> call.</p>

<blockquote class="filename">
  <p>stepper.c</p>
</blockquote>
<div class="language-c highlighter-tree-sitter"><pre><code>  <span class='ts-variable'>context</span><span class='ts-operator'>-&gt;</span><span class='ts-property'>pin</span> <span class='ts-operator'>=</span> <span class='ts-function'>furi_hal_resources_pin_by_number</span>(<span class='ts-variable'>pin</span>)<span class='ts-operator'>-&gt;</span><span class='ts-property'>pin</span><span class='ts-delimiter'>;</span>
</code></pre></div>

<p>Grabs the pin associated with the one passed into the function. This is where the stepper motor gets wired in.</p>

<blockquote class="filename">
  <p>stepper.c</p>
</blockquote>
<div class="language-c highlighter-tree-sitter"><pre><code>  <span class='ts-variable'>context</span><span class='ts-operator'>-&gt;</span><span class='ts-property'>gui</span> <span class='ts-operator'>=</span> <span class='ts-function'>furi_record_open</span>(<span class='ts-constant'>RECORD_GUI</span>)<span class='ts-delimiter'>;</span>
</code></pre></div>

<p>Sets up the GUI. This is just a “record” in the Flipper code, where <code>RECORD_GUI</code> is a string constant <a href="https://github.com/flipperdevices/flipperzero-firmware/blob/51aafd1b5ea1023616c88d2294ab411679ad8915/applications/services/gui/gui.h#L36"><code>"gui"</code></a></p>

<blockquote class="filename">
  <p>stepper.c</p>
</blockquote>
<div class="language-c highlighter-tree-sitter"><pre><code>  <span class='ts-function'>gui_add_view_port</span>(<span class='ts-variable'>context</span><span class='ts-operator'>-&gt;</span><span class='ts-property'>gui</span>, <span class='ts-variable'>context</span><span class='ts-operator'>-&gt;</span><span class='ts-property'>view_port</span>, <span class='ts-variable'>GuiLayerFullscreen</span>)<span class='ts-delimiter'>;</span>
</code></pre></div>

<p>Adds a viewport which we created earlier.</p>

<blockquote class="filename">
  <p>stepper.c</p>
</blockquote>
<div class="language-c highlighter-tree-sitter"><pre><code>  <span class='ts-variable'>context</span><span class='ts-operator'>-&gt;</span><span class='ts-property'>state</span> <span class='ts-operator'>=</span> false<span class='ts-delimiter'>;</span>
  <span class='ts-keyword'>return</span> <span class='ts-variable'>context</span><span class='ts-delimiter'>;</span>
</code></pre></div>

<p>Sets the state and returns the context. We’re done!</p>

<p>All of that is basic boilerplate for a lot of applications. We also free that all later, but I won’t go line by line. Here it is:</p>

<blockquote class="filename">
  <p>stepper.c</p>
</blockquote>
<div class="language-c highlighter-tree-sitter"><pre><code><span class='ts-keyword'>static</span> <span class='ts-type'>void</span> <span class='ts-function'>stepper_context_free</span>(<span class='ts-type'>StepperContext</span><span class='ts-operator'>*</span> <span class='ts-variable'>context</span>) {
    <span class='ts-function'>view_port_enabled_set</span>(<span class='ts-variable'>context</span><span class='ts-operator'>-&gt;</span><span class='ts-property'>view_port</span>, false)<span class='ts-delimiter'>;</span>
    <span class='ts-function'>gui_remove_view_port</span>(<span class='ts-variable'>context</span><span class='ts-operator'>-&gt;</span><span class='ts-property'>gui</span>, <span class='ts-variable'>context</span><span class='ts-operator'>-&gt;</span><span class='ts-property'>view_port</span>)<span class='ts-delimiter'>;</span>

    <span class='ts-function'>furi_message_queue_free</span>(<span class='ts-variable'>context</span><span class='ts-operator'>-&gt;</span><span class='ts-property'>event_queue</span>)<span class='ts-delimiter'>;</span>
    <span class='ts-function'>view_port_free</span>(<span class='ts-variable'>context</span><span class='ts-operator'>-&gt;</span><span class='ts-property'>view_port</span>)<span class='ts-delimiter'>;</span>

    <span class='ts-function'>furi_record_close</span>(<span class='ts-constant'>RECORD_GUI</span>)<span class='ts-delimiter'>;</span>
}
</code></pre></div>

<p>Since I got this from the onewire example, I’m… pretty sure that it’s the right order. :)</p>

<h2 id="back-to-gpio">Back to GPIO</h2>

<p>Okay, so now we have a setup and free function. Here we use that setup function and free before/after some main loop. So, first setup code:</p>

<blockquote class="filename">
  <p>stepper.c</p>
</blockquote>
<div class="language-c highlighter-tree-sitter"><pre><code><span class='ts-type'>int32_t</span> <span class='ts-function'>stepper_app</span>(<span class='ts-type'>void</span><span class='ts-operator'>*</span> <span class='ts-variable'>p</span>) {
  <span class='ts-function'>UNUSED</span>(<span class='ts-variable'>p</span>)<span class='ts-delimiter'>;</span>
  <span class='ts-type'>StepperContext</span> <span class='ts-operator'>*</span><span class='ts-variable'>context</span> <span class='ts-operator'>=</span> <span class='ts-function'>stepper_context_alloc</span>(<span class='ts-number'>7</span>)<span class='ts-delimiter'>;</span>
  <span class='ts-function'>furi_hal_gpio_write</span>(<span class='ts-variable'>context</span><span class='ts-operator'>-&gt;</span><span class='ts-property'>pin</span>, <span class='ts-variable'>context</span><span class='ts-operator'>-&gt;</span><span class='ts-property'>state</span>)<span class='ts-delimiter'>;</span>
  <span class='ts-function'>furi_hal_gpio_init</span>(<span class='ts-variable'>context</span><span class='ts-operator'>-&gt;</span><span class='ts-property'>pin</span>,  <span class='ts-variable'>GpioModeOutputPushPull</span>, <span class='ts-variable'>GpioPullNo</span>, <span class='ts-variable'>GpioSpeedLow</span>)<span class='ts-delimiter'>;</span>
</code></pre></div>

<p>That just calls the function we made with a hardcoded pin 7, then sets up the GPIO pin. The <code>furi_hal_gpio_init</code> function is like calling <a href="https://docs.arduino.cc/language-reference/en/functions/digital-io/pinMode/"><code>pinMode</code></a> for an Arduino - we’re just calling that pin an output pin.</p>

<p>Here’s that main loop:</p>

<blockquote class="filename">
  <p>stepper.c</p>
</blockquote>
<div class="language-c highlighter-tree-sitter"><pre><code>  <span class='ts-keyword'>for</span> (<span class='ts-type'>bool</span> <span class='ts-variable'>is_running</span> <span class='ts-operator'>=</span> true<span class='ts-delimiter'>;</span> <span class='ts-variable'>is_running</span><span class='ts-delimiter'>;</span> ) {
    <span class='ts-type'>InputEvent</span> <span class='ts-variable'>event</span><span class='ts-delimiter'>;</span>
    <span class='ts-keyword'>const</span> <span class='ts-type'>FuriStatus</span> <span class='ts-variable'>status</span> <span class='ts-operator'>=</span> <span class='ts-function'>furi_message_queue_get</span>(<span class='ts-variable'>context</span><span class='ts-operator'>-&gt;</span><span class='ts-property'>event_queue</span>, <span class='ts-operator'>&amp;</span><span class='ts-variable'>event</span>, <span class='ts-variable'>FuriWaitForever</span>)<span class='ts-delimiter'>;</span>
    <span class='ts-keyword'>if</span> ((<span class='ts-variable'>status</span> <span class='ts-operator'>!=</span> <span class='ts-variable'>FuriStatusOk</span>) <span class='ts-operator'>||</span> (<span class='ts-variable'>event</span><span class='ts-delimiter'>.</span><span class='ts-property'>type</span> <span class='ts-operator'>!=</span> <span class='ts-variable'>InputTypeShort</span>)) {
      <span class='ts-keyword'>continue</span><span class='ts-delimiter'>;</span>
    }

    <span class='ts-keyword'>switch</span> (<span class='ts-variable'>event</span><span class='ts-delimiter'>.</span><span class='ts-property'>key</span>) {
      <span class='ts-keyword'>case</span> <span class='ts-variable'>InputKeyBack</span>: <span class='ts-variable'>is_running</span> <span class='ts-operator'>=</span> false<span class='ts-delimiter'>;</span> <span class='ts-keyword'>break</span><span class='ts-delimiter'>;</span>
      <span class='ts-keyword'>case</span> <span class='ts-variable'>InputKeyOk</span>:
        <span class='ts-variable'>context</span><span class='ts-operator'>-&gt;</span><span class='ts-property'>state</span> <span class='ts-operator'>=</span> !<span class='ts-variable'>context</span><span class='ts-operator'>-&gt;</span><span class='ts-property'>state</span><span class='ts-delimiter'>;</span>
        <span class='ts-function'>view_port_update</span>(<span class='ts-variable'>context</span><span class='ts-operator'>-&gt;</span><span class='ts-property'>view_port</span>)<span class='ts-delimiter'>;</span>
        <span class='ts-keyword'>break</span><span class='ts-delimiter'>;</span>
      <span class='ts-keyword'>default</span>: <span class='ts-keyword'>break</span><span class='ts-delimiter'>;</span>
    }

    <span class='ts-function'>furi_hal_gpio_write</span>(<span class='ts-variable'>context</span><span class='ts-operator'>-&gt;</span><span class='ts-property'>pin</span>, <span class='ts-variable'>context</span><span class='ts-operator'>-&gt;</span><span class='ts-property'>state</span>)<span class='ts-delimiter'>;</span>
  }
</code></pre></div>

<p>While the app is running, we get events and loop if it’s an invalid event (like long button presses). Then we stop running if we hit back, or change the state if we hit Ok. We’ll update the viewport if we see Ok in order to get it to change the <code>status</code>. Then we write the state to the pin. Great.</p>

<p>Note, don’t remove the <code>InputKeyBack</code> case - while setting this up and minimizing this, I had to reset my Flipper many times to get it right with the GUI. Oops.</p>

<p>Then some teardown:</p>

<blockquote class="filename">
  <p>stepper.c</p>
</blockquote>
<div class="language-c highlighter-tree-sitter"><pre><code>  <span class='ts-function'>furi_hal_gpio_init</span>(<span class='ts-variable'>context</span><span class='ts-operator'>-&gt;</span><span class='ts-property'>pin</span>, <span class='ts-variable'>GpioModeAnalog</span>, <span class='ts-variable'>GpioPullNo</span>, <span class='ts-variable'>GpioSpeedLow</span>)<span class='ts-delimiter'>;</span>
  <span class='ts-function'>stepper_context_free</span>(<span class='ts-variable'>context</span>)<span class='ts-delimiter'>;</span>

  <span class='ts-keyword'>return</span> <span class='ts-number'>0</span><span class='ts-delimiter'>;</span>
</code></pre></div>

<p>The final <code>furi_hal_gpio_init</code> call is correct from what I can tell, it’s just trying to get it back into “floating” voltage rather than forcing it 0 or 1. I got that from a separate <a href="https://github.com/jamisonderek/flipper-zero-tutorials/wiki/GPIO-Signals">tutorial</a> on GPIO. At the very least, it seems to stop sending a high voltage if we exit, so I call that a success.</p>

<p>So now, finally, let’s run this and press Ok with an LED wired up on the correct pin (which I have hardcoded to pin <code>7</code>):</p>

<p><img src="/assets/img/posts/flipper-hardware-p1/led-light.jpg" alt="An LED" title="An LED and a flipper" />
<em>spooky</em></p>

<p>Okay, now we have fundamentals:</p>

<p>1) A GUI to see what’s going on</p>

<p>2) Interacting with the Flipper’s buttons</p>

<p>3) Interacting with some external GPIO stuff</p>

<p>That seems like all we need to do most of what we want! Sure, this is just a reskinned (and worse) version of apps that already come with the Flipper. But, it’s fun to learn about it. Now, we’ll make this interact with a stepper motor. In part 2.</p>]]></content><author><name>Evan Typanski</name></author><summary type="html"><![CDATA[Read more in the "Flipper into hardware" series: Flipper your way into hardware Flipper your way into hardware - Stepping Flipper your way into hardware - UI]]></summary></entry><entry><title type="html">Introducing minIR</title><link href="https://etyp.dev/posts/introducing-minir/" rel="alternate" type="text/html" title="Introducing minIR" /><published>2024-08-07T00:00:00-04:00</published><updated>2024-08-07T00:00:00-04:00</updated><id>https://etyp.dev/posts/introducing-minir</id><content type="html" xml:base="https://etyp.dev/posts/introducing-minir/"><![CDATA[<div class="track">
<audio title="Introducing minIR" controls="">
  <source src="/assets/audio/posts/introducing-minir/introducing-minir.mp3" type="audio/mpeg" />
  Audio tag is not supported, sorry!
</audio>
<p><small> Let me read it for you! </small></p>
</div>

<p>minIR is a compiler intermediate representation (IR) that’s meant to be tiny and easy to work with.</p>

<p>You can find the <a href="https://github.com/evantypanski/minir">source code</a> or an <a href="https://github.com/evantypanski/minirpass">example pass over it</a> on <a href="https://github.com/evantypanski">my Github</a>.</p>

<h2 id="the-language">The Language</h2>

<p>minIR has variables, branches, and labels, but no if statements and other higher level constructs. There’s the example in the README that counts from 42 to 59:</p>

<blockquote class="filename">
  <p>count_42_to_59.min</p>
</blockquote>
<div class="language-cpp highlighter-tree-sitter"><pre><code><span class='ts-type'>func</span> <span class='ts-function'>main</span>() <span class='ts-operator'>-&gt;</span> <span class='ts-type'>none</span> {
  <span class='ts-type'>let</span> <span class='ts-variable'>i</span>: <span class='ts-type'>int</span> <span class='ts-operator'>=</span> <span class='ts-number'>42</span>
@<span class='ts-variable'>loop</span>
  <span class='ts-function'>test</span>(<span class='ts-variable'>i</span>)
  <span class='ts-variable'>i</span> <span class='ts-operator'>=</span> <span class='ts-function'>addone</span>(<span class='ts-variable'>i</span>)<span class='ts-delimiter'></span>
  <span class='ts-type'>brc</span> <span class='ts-variable'>loop</span><span class='ts-delimiter'></span> !(<span class='ts-variable'>i</span> <span class='ts-operator'>==</span> <span class='ts-number'>60</span>)
  <span class='ts-variable'>ret</span>
}

<span class='ts-variable'>func</span> <span class='ts-function'>addone</span>(<span class='ts-variable'>i</span>: <span class='ts-type'>int</span>) <span class='ts-operator'>-&gt;</span> <span class='ts-property'>int</span><span class='ts-delimiter'></span> {
  <span class='ts-type'>ret</span> <span class='ts-variable'>i</span><span class='ts-delimiter'></span> <span class='ts-operator'>+</span> <span class='ts-number'>1</span><span class='ts-delimiter'></span>
}

<span class='ts-type'>func</span> <span class='ts-function'>test</span>(<span class='ts-variable'>k</span>: <span class='ts-type'>int</span>) <span class='ts-operator'>-&gt;</span> <span class='ts-type'>none</span> {
  <span class='ts-function'>debug</span>(<span class='ts-variable'>k</span>)
  <span class='ts-variable'>ret</span>
}
</code></pre></div>

<p>Then you can run it with the generated <code>minir</code> executable:</p>

<blockquote class="shell">

</blockquote>
<pre><code>etyp:minir/ $ zig-out/bin/minir interpret count_42_to_59.min
</code></pre>

<p>I could go through and introduce the language, but it may have pretty big changes. Instead, I’ll abstain and just try to go over the more important parts of its design.</p>

<h2 id="why-minir">Why minIR?</h2>

<p>minIR is my direct response to a problem: I want to learn more about a lot of things in compilers like static analysis, optimizations, and just-in-time compiling. But, most IRs that I could work with come in one of two varieties:</p>

<p>1) A teaching IR (like <a href="https://github.com/sampsyo/bril">bril</a>), which intentionally limits its scope in order to allow for students to implement certain details.</p>

<p>2) A giant IR (like <a href="https://github.com/llvm/llvm-project/tree/main/llvm">LLVM</a>), which gives a bunch of awesome tools, but has a lot of overhead and requirements to get your feet wet.</p>

<p>I want an in between. In particular, I want a million different ways to inject whatever hacky script I wrote to optimize an IR. I also want that IR to be small enough that I can be reasonably confident it won’t take a year to get a “production ready” analysis.</p>

<p>So, minIR is just an IR with a focus on developer experience, not on the actual language features. Many “hobbiest” languages explore one topic very thoroughly, but maybe they have bad error messages (or something else underdeveloped). That’s completely understandable - most of these are made in someone’s free time, the interesting part are the language features! But the developer experience <em>is</em> the interesting part of minIR.</p>

<h3 id="developer-experience--bad-language--">Developer experience + bad language = ?</h3>

<p>A language is intertwined with its developer experience. If the language is not implemented fully (say, like current minIR doesn’t have any structs or user-defined types), that necessarily hurts its developer experience. Then, we expect many things in modern languages: generics, user-defined types, casting… and those aren’t implemented in minIR yet.</p>

<p>So part of me worries about that. The point, however, is not that I’m planning on making this big awesome ecosystem out of the box. In order to get to Rust levels of developer experience, with beautiful error messages and a million tools, you need years upon years. This is the case even for a small language!</p>

<p>I’m <em>not</em> saying minIR is the best developer experience out of any programming language (or IR). Instead, at any particular point in the language’s life, it has a better-than-expected developer experience. I am prioritizing developer experience, that doesn’t mean that it is the best developer experience over established art.</p>

<h2 id="architecture">Architecture</h2>

<h3 id="interpreting">Interpreting</h3>

<p>minIR has two interpreters:</p>

<p>1) A tree-walking interpreter. This will walk down the tree after parsing (and whatever other passes are run) without another intermediate format.</p>

<p>2) A bytecode interpreter. This is a separate system which minIR gets lowered to then executed in.</p>

<p>This, hopefully, will help keep minIR more standard. Edge cases may get caught in one but not the other, so all implementations should be able to have a standard “output” for these edge cases more easily.</p>

<h3 id="parsing">Parsing</h3>

<p>The parser is a handwritten <a href="https://journal.stuffwithstuff.com/2011/03/19/pratt-parsers-expression-parsing-made-easy/">Pratt parser</a>. I got the idea for Pratt parsers (or “operator precedence” parsers) from <a href="https://craftinginterpreters.com/">Crafting Interpreters</a> - really a must read for anyone working on a compiler. If you want a bit more about why, well just read the article or the whole book I’ve linked :)</p>

<h3 id="ast">AST</h3>

<p>The abstract syntax tree (AST) is all implemented using Zig’s <a href="https://ziglang.org/documentation/0.13.0/#Tagged-union">tagged unions</a>. Let’s look at a <code>Value</code>, which is (basically?) an expression:</p>

<blockquote class="filename">
  <p>value.zig</p>
</blockquote>
<div class="language-source.zig highlighter-tree-sitter"><pre><code><span class='ts-keyword'>const</span> <span class='ts-variable'>ValueTag</span> <span class='ts-operator'>=</span> <span class='ts-keyword'>enum</span> <span class='ts-punctuation-bracket'>{</span>
    undef<span class='ts-operator'>,</span>
    access<span class='ts-operator'>,</span>
    int<span class='ts-operator'>,</span>
    float<span class='ts-operator'>,</span>
    <span class='ts-error'><span class='ts-type-builtin'>bool</span><span class='ts-operator'>,</span></span>
    unary<span class='ts-operator'>,</span>
    binary<span class='ts-operator'>,</span>
    call<span class='ts-operator'>,</span>
    type_<span class='ts-operator'>,</span>
    ptr<span class='ts-operator'>,</span>
<span class='ts-punctuation-bracket'>}</span><span class='ts-punctuation-delimiter'>;</span>

<span class='ts-comment'>// ...</span>

<span class='ts-keyword'>pub</span> <span class='ts-keyword'>const</span> <span class='ts-variable'>ValueKind</span> <span class='ts-operator'>=</span> <span class='ts-keyword'>union</span><span class='ts-punctuation-bracket'>(</span><span class='ts-type'>ValueTag</span><span class='ts-punctuation-bracket'>)</span> <span class='ts-punctuation-bracket'>{</span>
    undef<span class='ts-operator'>,</span>
    access<span class='ts-operator'>:</span> <span class='ts-type'>VarAccess</span><span class='ts-operator'>,</span>
    int<span class='ts-operator'>:</span> <span class='ts-type-builtin'>i32</span><span class='ts-operator'>,</span>
    float<span class='ts-operator'>:</span> <span class='ts-type-builtin'>f32</span><span class='ts-operator'>,</span>
    <span class='ts-error'><span class='ts-type-builtin'>bool</span><span class='ts-operator'>:</span> u1<span class='ts-operator'>,</span></span>
    unary<span class='ts-operator'>:</span> <span class='ts-type'>UnaryOp</span><span class='ts-operator'>,</span>
    binary<span class='ts-operator'>:</span> <span class='ts-type'>BinaryOp</span><span class='ts-operator'>,</span>
    call<span class='ts-operator'>:</span> <span class='ts-type'>FuncCall</span><span class='ts-operator'>,</span>
    type_<span class='ts-operator'>:</span> <span class='ts-type'>Type</span><span class='ts-operator'>,</span>
    ptr<span class='ts-operator'>:</span> <span class='ts-type'>Pointer</span><span class='ts-operator'>,</span>

    <span class='ts-comment'>// ...</span>
<span class='ts-punctuation-bracket'>}</span><span class='ts-punctuation-delimiter'>;</span>

<span class='ts-keyword'>pub</span> <span class='ts-keyword'>const</span> <span class='ts-variable'>Value</span> <span class='ts-operator'>=</span> <span class='ts-keyword'>struct</span> <span class='ts-punctuation-bracket'>{</span>
    <span class='ts-property'>val_kind</span><span class='ts-operator'>:</span> <span class='ts-type'>ValueKind</span><span class='ts-operator'>,</span>

    <span class='ts-comment'>// ...</span>
<span class='ts-punctuation-bracket'>}</span><span class='ts-punctuation-delimiter'>;</span>
</code></pre></div>

<p>Some code above has been emitted for brevity</p>

<p>This is the same concept as enums in Rust, but maybe with fewer pattern matching capabilities. You may also know them by other names like variants or sum types. They’re often used when a language doesn’t have inheritance. Instead of a <code>BinaryOp</code> inheriting from <code>Value</code>, we make <code>Value</code> possibly contain a <code>BinaryOp</code> in its <code>val_kind</code> field.</p>

<p>This pattern is pretty intuitive for me, but it comes with some drawbacks. The most annoying part within minIR has been making a visitor to walk over the tree, which…</p>

<h3 id="visitors">Visitors</h3>

<p>Most operations will use a visitor in order to easily traverse the tree. This is provided in an <code>IrVisitor</code>:</p>

<blockquote class="filename">
  <p>visitor.zig</p>
</blockquote>
<div class="language-source.zig highlighter-tree-sitter"><pre><code><span class='ts-keyword'>pub</span> <span class='ts-keyword-function'>fn</span> <span class='ts-variable'>IrVisitor</span><span class='ts-punctuation-bracket'>(</span><span class='ts-keyword'>comptime</span> <span class='ts-variable'>ArgTy</span><span class='ts-operator'>:</span> <span class='ts-type-builtin'>type</span><span class='ts-operator'>,</span> <span class='ts-keyword'>comptime</span> <span class='ts-variable'>RetTy</span><span class='ts-operator'>:</span> <span class='ts-type-builtin'>type</span><span class='ts-punctuation-bracket'>)</span> <span class='ts-type-builtin'>type</span> <span class='ts-punctuation-bracket'>{</span>
    <span class='ts-keyword'>return</span> <span class='ts-keyword'>struct</span> <span class='ts-punctuation-bracket'>{</span>
        <span class='ts-comment'>// ...</span>
    <span class='ts-punctuation-bracket'>}</span><span class='ts-punctuation-delimiter'>;</span>
<span class='ts-punctuation-bracket'>}</span>
</code></pre></div>

<p>First, this syntax is a function which returns a type. It’s how <a href="https://ziglang.org/documentation/0.13.0/#struct">Zig implements generics</a>. <code>IrVisitor</code> can use <code>ArgTy</code> in order to refer to the argument type used throughout the returned struct. Then <code>RetTy</code> is used to refer to the return type used throughout. You’ll call the function with those two types, then use it like any other struct:</p>

<blockquote class="filename">
  <p>blockify.zig</p>
</blockquote>
<div class="language-source.zig highlighter-tree-sitter"><pre><code><span class='ts-keyword'>const</span> <span class='ts-variable'>VisitorTy</span> <span class='ts-operator'>=</span> <span class='ts-variable'>IrVisitor</span><span class='ts-punctuation-bracket'>(</span><span class='ts-operator'>*</span><span class='ts-variable'>Self</span><span class='ts-operator'>,</span> <span class='ts-type'>Error</span><span class='ts-operator'>!</span><span class='ts-type-builtin'>void</span><span class='ts-punctuation-bracket'>)</span><span class='ts-punctuation-delimiter'>;</span>
</code></pre></div>

<p>This pattern, where a function takes in types as parameters and returns a type, is one of the more important concepts in Zig. It’s a simple concept that produces powerful results. But, you lose the ability to refer to <code>IrVisitor</code> as a type without those two arguments, which can be frustrating.</p>

<p>When you have that visitor type, you can then initialize it and “overload” any functions you want to intercept:</p>

<blockquote class="filename">
  <p>blockify.zig</p>
</blockquote>
<div class="language-source.zig highlighter-tree-sitter"><pre><code><span class='ts-keyword'>pub</span> <span class='ts-keyword'>const</span> <span class='ts-variable'>BlockifyVisitor</span> <span class='ts-operator'>=</span> <span class='ts-type'>VisitorTy</span> <span class='ts-punctuation-bracket'>{</span>
    <span class='ts-operator'>.</span><span class='ts-property'>visitDecl</span> <span class='ts-operator'>=</span> <span class='ts-variable'>visitDecl</span><span class='ts-operator'>,</span>
<span class='ts-punctuation-bracket'>}</span><span class='ts-punctuation-delimiter'>;</span>
</code></pre></div>

<p>This will use the internal <code>visitDecl</code> rather than the default <code>visitDecl</code> within the visitor, just make sure it is compatible with the function type provided by the visitor:</p>

<blockquote class="filename">
  <p>visitor.zig</p>
</blockquote>
<div class="language-source.zig highlighter-tree-sitter"><pre><code><span class='ts-keyword'>const</span> <span class='ts-variable'>VisitDeclFn</span> <span class='ts-operator'>=</span> <span class='ts-operator'>*</span><span class='ts-keyword'>const</span> <span class='ts-variable'>fn</span><span class='ts-punctuation-bracket'>(</span><span class='ts-error'><span class='ts-label_identifier'>self</span><span class='ts-operator'>:</span></span> <span class='ts-variable'>Self</span><span class='ts-operator'>,</span> <span class='ts-error'><span class='ts-label_identifier'>arg</span><span class='ts-operator'>:</span></span> <span class='ts-variable'>ArgTy</span><span class='ts-operator'>,</span> <span class='ts-error'><span class='ts-label_identifier'>decl</span><span class='ts-operator'>:</span></span> <span class='ts-operator'>*</span><span class='ts-variable'>Decl</span><span class='ts-punctuation-bracket'>)</span> <span class='ts-error'>RetTy</span><span class='ts-punctuation-delimiter'>;</span>
</code></pre></div>

<p>Now that you can walk over the IR, how do you run a pass?</p>

<h3 id="passes">Passes</h3>

<p>A Pass is just a way to get your hands on the IR. You have three choices (at the time of writing), defined in <code>pass.zig</code>:</p>

<p>1) <code>Verifier</code>: These passes may only return an error or void. They <em>cannot</em> modify the AST</p>

<p>2) <code>Modifier</code>: These passes may only return an error or void. They <em>can</em> modify the AST</p>

<p>3) <code>Provider</code>: These passes may return an error or an arbitrary return value. They <em>cannot</em> modify the AST.</p>

<p>You also have another option, namely <code>SimplePass</code>, which is a wrapper around a <code>Verifier</code> but without the extra fluff that you may want for a verifier (like an initialization function).</p>

<p>When you use these passes, you need a <code>PassManager</code> (in <code>pass_manager.zig</code>). This object is created for you when using the standard <code>Driver</code> interface. If you’re directly interacting with it, then all you’ll need to do (once you have the manager) is that you must run <code>get</code>:</p>

<blockquote class="filename">
  <p>pass_manager.zig</p>
</blockquote>
<div class="language-source.zig highlighter-tree-sitter"><pre><code><span class='ts-keyword'>pub</span> <span class='ts-keyword-function'>fn</span> <span class='ts-variable'>get</span><span class='ts-punctuation-bracket'>(</span><span class='ts-variable'>self</span><span class='ts-operator'>:</span> <span class='ts-variable'>Self</span><span class='ts-operator'>,</span> <span class='ts-keyword'>comptime</span> <span class='ts-variable'>PassType</span><span class='ts-operator'>:</span> <span class='ts-type-builtin'>type</span><span class='ts-punctuation-bracket'>)</span> <span class='ts-variable'>PassType</span><span class='ts-operator'>.</span><span class='ts-property'>RetType</span> <span class='ts-punctuation-bracket'>{</span><span class='ts-punctuation-bracket'></span>
</code></pre></div>

<p>Then you’ll get your pass. So if you have a pass type (made from one of the four options above), you just call <code>pass_manager.get(MyPass)</code> and you’ll get its return value. Easy.</p>

<p>To me, this is the most crucial part of minIR. It should be easy to create a pass and run that pass on the IR in whichever way you see fit. That’s the goal here: flexibility plus simplicity.</p>

<h3 id="testing">Testing</h3>

<p>I’ve added a few easy cases for tests. The two notable ones are output tests, which make sure the output from running the program match the output provided (and the two interpreters match), and UI tests, which make sure things like error messages are output correctly.</p>

<p>Generally you’ll use output for end-to-end testing to make sure the interpreters work together well, or UI tests to make sure error messages look a certain way.</p>

<p>In order to add a test, you just make a file in the proper directory within <code>tests</code>. Then, you go in <code>src/test/output.zig</code> or <code>src/test/ui.zig</code> and add the new test to the list of tests (this is using the <a href="https://ziglang.org/documentation/0.13.0/#Test-Declarations">zig <code>test</code> declarations</a>). For UI tests, the necessary <code>.stderr</code> and <code>.stdout</code> will be created for you on the test’s first run. For output tests, you’ll only have a baseline if you explicitly provide a <code>.expected</code> file alongside the test. Otherwise, the test just ensures the two interpreters match.</p>

<p>There are a few different ways a test can fail.</p>

<p>First, there may be some memory error. Zig gives a testing allocator in <code>std.testing.allocator</code> that, when used in a test, will make it fail if a memory leak or other similar problems are detected.</p>

<p>Second, when you have a mismatch in program output, you also get a failure:</p>

<blockquote class="shell">

</blockquote>
<pre><code>error: 'test.output.test.output examples' failed: ====== expected this output: =========
3
7
4
2
42 oh no
␃

======== instead found this: =========
3
7
4
2
42
␃

======================================
First difference occurs on line 5:
expected:
42 oh no
  ^ ('\x20')
found:
42
  ^ ('\x0a')
</code></pre>

<p>I find that output pretty nice!</p>

<p>That’s mostly it. There are a few caveats, namely that modifying the <code>.min</code> test itself won’t trigger the cached test results to be invalidated, so you need to change a source file to get them to rerun. Also, the UI tests actually create a <code>minir</code> process call and use that, so you lose some benefits of the testing allocator for those. The reason for that is Zig-specific, I may just be unfamiliar with the language’s testing tools.</p>

<h2 id="where-is-minir-at">Where is minIR at?</h2>

<p>Right now, you can kind of use minIR for simple things. If you want a simple dead code elimination pass, you can do that today, and it’s pretty straightforward.</p>

<h3 id="language">Language</h3>

<p>Beyond that you might start to see some issues. There are a lot of small things in the language that aren’t quite up to the standard I want to be. As a small example, every function needs <code>ret</code> at the end of its body, even if it returns nothing - there are no implicit returns.</p>

<p>Another point is error messages. I have a somewhat decent interface using the <code>diag.err</code> method:</p>

<blockquote class="filename">
  <p>typecheck.zig</p>
</blockquote>
<div class="language-source.zig highlighter-tree-sitter"><pre><code><span class='ts-variable'>self</span><span class='ts-operator'>.</span><span class='ts-property'>diag</span><span class='ts-operator'>.</span><span class='ts-variable'>err</span><span class='ts-punctuation-bracket'>(</span><span class='ts-keyword'>error</span><span class='ts-operator'>.</span>InvalidType<span class='ts-operator'>,</span> <span class='ts-punctuation-bracket'>.{</span><span class='ts-variable'>@tagName</span><span class='ts-punctuation-bracket'>(</span><span class='ts-variable'>ty</span><span class='ts-punctuation-bracket'>)</span><span class='ts-operator'>,</span> <span class='ts-string'>&quot;!&quot;</span><span class='ts-punctuation-bracket'>}</span><span class='ts-operator'>,</span> <span class='ts-variable'>val</span><span class='ts-operator'>.*</span><span class='ts-operator'>.</span><span class='ts-property'>loc</span><span class='ts-punctuation-bracket'>)</span><span class='ts-punctuation-delimiter'>;</span>
</code></pre></div>

<p>Then we can find the format string used for <code>InvalidType</code> in the diagnostics engine:</p>

<blockquote class="filename">
  <p>diagnostics_engine.zig</p>
</blockquote>
<div class="language-source.zig highlighter-tree-sitter"><pre><code><span class='ts-error'><span class='ts-keyword'>error</span><span class='ts-operator'>.</span>InvalidType <span class='ts-operator'>=&gt;</span> <span class='ts-string'>&quot;{s} is an invalid type for &#39;{s}&#39;&quot;</span><span class='ts-operator'>,</span></span>
</code></pre></div>

<p>So the interface is decent, I just don’t use it everywhere. I want to go through and add errors and warnings where necessary.</p>

<p>The language itself should be a little less minimal than what I’ve made. Some core points I think are casting and user defined types. Also, there should be more sizes of certain types (like 8, 16, 32, 64 bit integers). Some sort of string would probably be useful, too.</p>

<h3 id="interface">Interface</h3>

<p>The directory structure makes sense within minIR right now, but when using a <code>.zig.zon</code> file… it uses this crappy <a href="https://github.com/evantypanski/minir/blob/main/src/lib.zig">lib.zig</a> file which just splattered what I needed in there, so that should be fixed up.</p>

<p>I also want easier ways to interact with minIR. One would be you should be able to use whatever language you want to write passes. I can use a JSON representation, but I really dislike JSON for serializing programming language ASTs. It may be best, though.</p>

<p>Then there are lots of simple things that can be better, like a better formatter.</p>

<h3 id="bytecode">Bytecode</h3>

<p>Right now the stack in the bytecode is just an array of <code>Value</code> - I want to make this variable sized, so each <code>Value</code> puts its tag first, then the size of the next bytes is determined from that tag. A value will then just be an access into a byte array, I think.</p>

<p>The bytecode should be printable. You should be able to run from just the bytecode and not interact with minIR.</p>

<p>Constants should be dealt with better - right now, all constants are just added to the bytecode, even if they already appear:</p>

<blockquote class="filename">
  <p>chunk.zig</p>
</blockquote>
<div class="language-source.zig highlighter-tree-sitter"><pre><code><span class='ts-keyword'>pub</span> <span class='ts-keyword-function'>fn</span> <span class='ts-variable'>addValue</span><span class='ts-punctuation-bracket'>(</span><span class='ts-variable'>self</span><span class='ts-operator'>:</span> <span class='ts-operator'>*</span><span class='ts-variable'>Self</span><span class='ts-operator'>,</span> <span class='ts-variable'>value</span><span class='ts-operator'>:</span> <span class='ts-variable'>Value</span><span class='ts-punctuation-bracket'>)</span> <span class='ts-operator'>!</span><span class='ts-type-builtin'>u8</span> <span class='ts-punctuation-bracket'>{</span>
    <span class='ts-keyword'>const</span> <span class='ts-variable'>idx</span> <span class='ts-operator'>=</span> <span class='ts-variable'>self</span><span class='ts-operator'>.</span><span class='ts-property'>values</span><span class='ts-operator'>.</span><span class='ts-property'>items</span><span class='ts-operator'>.</span><span class='ts-property'>len</span><span class='ts-punctuation-delimiter'>;</span>
    <span class='ts-keyword'>if</span> <span class='ts-punctuation-bracket'>(</span><span class='ts-variable'>idx</span> <span class='ts-keyword-operator'>&gt;</span> <span class='ts-variable'>std</span><span class='ts-operator'>.</span><span class='ts-property'>math</span><span class='ts-operator'>.</span><span class='ts-variable'>maxInt</span><span class='ts-punctuation-bracket'>(</span><span class='ts-type-builtin'>u8</span><span class='ts-punctuation-bracket'>)</span><span class='ts-punctuation-bracket'>)</span> <span class='ts-punctuation-bracket'>{</span>
        <span class='ts-keyword'>return</span> <span class='ts-keyword'>error</span><span class='ts-operator'>.</span>TooManyConstants<span class='ts-punctuation-delimiter'>;</span>
    <span class='ts-punctuation-bracket'>}</span>
    <span class='ts-keyword'>try</span> <span class='ts-variable'>self</span><span class='ts-operator'>.</span><span class='ts-property'>values</span><span class='ts-operator'>.</span><span class='ts-variable'>append</span><span class='ts-punctuation-bracket'>(</span><span class='ts-variable'>value</span><span class='ts-punctuation-bracket'>)</span><span class='ts-punctuation-delimiter'>;</span>
    <span class='ts-keyword'>return</span> <span class='ts-variable'>@intCast</span><span class='ts-punctuation-bracket'>(</span><span class='ts-variable'>idx</span><span class='ts-punctuation-bracket'>)</span><span class='ts-punctuation-delimiter'>;</span>
<span class='ts-punctuation-bracket'>}</span>
</code></pre></div>

<p>That should maybe <a href="https://en.wikipedia.org/wiki/Interning_(computer_science)">intern</a> the values, instead.</p>

<h3 id="misc">Misc</h3>

<p>Part of minIR is that it should be small enough to fit in a <a href="https://github.com/evantypanski/minir/tree/main/spec">spec</a> - that’s for two reasons. First, it keeps it small and formal, so parsing a certain way can be either a bug or intended. Second, it forces acknowledgment of edge cases: what happens with an integer overflow? That sort of thing.</p>

<h2 id="conclusions">Conclusions</h2>

<p>Overall, I think minIR is far from done, but just about far enough along that I’m comfortable talking about it. I think it solves a relatively unique problem and has some interesting ideas about to solve those problems.</p>

<p>I don’t really expect anyone to use it yet, but writing this is a good way to set my intentions straight and move forward making something interesting for others to use. Look for more minIR news in the coming while.</p>]]></content><author><name>Evan Typanski</name></author><summary type="html"><![CDATA[Audio tag is not supported, sorry! Let me read it for you!]]></summary></entry><entry><title type="html">Arduino Demystified</title><link href="https://etyp.dev/posts/arduino-demystified/" rel="alternate" type="text/html" title="Arduino Demystified" /><published>2024-03-26T00:00:00-04:00</published><updated>2024-03-26T00:00:00-04:00</updated><id>https://etyp.dev/posts/arduino-demystified</id><content type="html" xml:base="https://etyp.dev/posts/arduino-demystified/"><![CDATA[<p>Arduinos! Everyone’s favorite toy for random electronics projects. But honestly, it really doesn’t feel like you learn a lot about the hardware. Most of the time you grab a library and it does magical stuff for you, all you do is plug stuff together and use other libraries.</p>

<p>There are libraries for everything from <a href="https://www.arduino.cc/reference/en/libraries/servo/">servo motors</a> to <a href="https://www.arduino.cc/reference/en/libraries/ethernet/">ethernet</a> and <a href="https://www.arduino.cc/reference/en/libraries/sd/">SD cards</a>. You really don’t need to know much about the Arduino hardware or even the peripherals in order to make functional programs. That’s the beauty of an Arduino.</p>

<p>Now let’s strip away all of those niceties and learn how to suffer through the hardware details. I say suffer, but this is how you’ll use many other microcontrollers. Also, you may need to know this to write a library yourself. So here’s a bit of information that I wish I could find in one place more easily.</p>

<h2 id="what-programming-language">What programming language?</h2>

<p>You can write code for Arduino in any language. It’s just about targeting the AVR CPU and loading it on the chip. But, the <a href="https://www.arduino.cc/en/software">Arduino IDE</a> uses C++.. kind of.</p>

<p>When you first load up the IDE, you get a file like this:</p>

<blockquote class="filename">

</blockquote>
<div class="language-cpp highlighter-tree-sitter"><pre><code><span class='ts-type'>void</span> <span class='ts-function'>setup</span>() {
  <span class='ts-comment'>// put your setup code here, to run once:</span>

}

<span class='ts-type'>void</span> <span class='ts-function'>loop</span>() {
  <span class='ts-comment'>// put your main code here, to run repeatedly:</span>

}
</code></pre></div>

<p>Obviously, that’s not a “normal” C++ program - where’s <code>main</code>?</p>

<p>Turns out, you can find this and a lot more from the <a href="https://github.com/arduino/ArduinoCore-avr/">ArduinoCore-avr</a> project on Github. Just search <code>main</code> in that repo and you’ll find <a href="https://github.com/arduino/ArduinoCore-avr/blob/master/cores/arduino/main.cpp">main.cpp</a>. That has the following as its <code>main</code> function:</p>

<blockquote class="filename">
  <p>main.cpp</p>
</blockquote>
<div class="language-cpp highlighter-tree-sitter"><pre><code><span class='ts-type'>int</span> <span class='ts-function'>main</span>(<span class='ts-type'>void</span>)
{
	<span class='ts-function'>init</span>()<span class='ts-delimiter'>;</span>

	<span class='ts-function'>initVariant</span>()<span class='ts-delimiter'>;</span>

<span class='ts-keyword'>#if</span> defined(<span class='ts-constant'>USBCON</span>)
	<span class='ts-variable'>USBDevice</span><span class='ts-delimiter'>.</span><span class='ts-function'>attach</span>()<span class='ts-delimiter'>;</span>
<span class='ts-keyword'>#endif</span>

	<span class='ts-function'>setup</span>()<span class='ts-delimiter'>;</span>

	<span class='ts-keyword'>for</span> (<span class='ts-delimiter'>;</span><span class='ts-delimiter'>;</span>) {
		<span class='ts-function'>loop</span>()<span class='ts-delimiter'>;</span>
		<span class='ts-keyword'>if</span> (<span class='ts-variable'>serialEventRun</span>) <span class='ts-function'>serialEventRun</span>()<span class='ts-delimiter'>;</span>
	}

	<span class='ts-keyword'>return</span> <span class='ts-number'>0</span><span class='ts-delimiter'>;</span>
}
</code></pre></div>

<p>So, along with some extra stuff, it calls our <code>setup</code> and <code>loop</code> functions we saw before. So that’s how it all ties together - magic that we have no way of seeing how it’s called or what its context is! Well that’s fine for beginners I suppose, and at least it’s open source so people like me can look at what happens.</p>

<p>So yes, Arduino uses C++ (the file with <code>main</code> is a <code>.cpp</code> file!), but it’s simplified a bit for development on a tiny computer.</p>

<h2 id="blink">Blink!</h2>

<p>The first program you will write on basically any microcontroller is “blink” - just where you blink an LED on and off. Here’s what the Arduino IDE gives as an example:</p>

<blockquote class="filename">
  <p>Blink</p>
</blockquote>
<div class="language-cpp highlighter-tree-sitter"><pre><code><span class='ts-comment'>// the setup function runs once when you press reset or power the board</span>
<span class='ts-type'>void</span> <span class='ts-function'>setup</span>() {
  <span class='ts-comment'>// initialize digital pin LED_BUILTIN as an output.</span>
  <span class='ts-function'>pinMode</span>(<span class='ts-constant'>LED_BUILTIN</span>, <span class='ts-constant'>OUTPUT</span>)<span class='ts-delimiter'>;</span>
}

<span class='ts-comment'>// the loop function runs over and over again forever</span>
<span class='ts-type'>void</span> <span class='ts-function'>loop</span>() {
  <span class='ts-function'>digitalWrite</span>(<span class='ts-constant'>LED_BUILTIN</span>, <span class='ts-constant'>HIGH</span>)<span class='ts-delimiter'>;</span>  <span class='ts-comment'>// turn the LED on (HIGH is the voltage level)</span>
  <span class='ts-function'>delay</span>(<span class='ts-number'>1000</span>)<span class='ts-delimiter'>;</span>                      <span class='ts-comment'>// wait for a second</span>
  <span class='ts-function'>digitalWrite</span>(<span class='ts-constant'>LED_BUILTIN</span>, <span class='ts-constant'>LOW</span>)<span class='ts-delimiter'>;</span>   <span class='ts-comment'>// turn the LED off by making the voltage LOW</span>
  <span class='ts-function'>delay</span>(<span class='ts-number'>1000</span>)<span class='ts-delimiter'>;</span>                      <span class='ts-comment'>// wait for a second</span>
}
</code></pre></div>

<p>So, we have the <code>setup</code> and <code>loop</code> functions we saw before. In setup we run one time code: <code>pinMode(LED_BUILTIN, OUTPUT)</code> - sets the builtin LED to an output (as opposed to an input that we may read high/low, like a button). Then the <code>loop</code> function just sets that LED high, waits a second, then low, and waits another second. Easy!</p>

<p>Now, these sorts of functions aren’t included in a header file like normal in C++ - we don’t see a new include at the top. Where is it? Actually, we get it from an auto-included file <a href="https://github.com/arduino/ArduinoCore-avr/blob/master/cores/arduino/Arduino.h">Arduino.h</a>. We can see stubs for functions we used such as <code>pinMode</code>:</p>

<blockquote class="filename">
  <p>Arduino.h</p>
</blockquote>
<div class="language-cpp highlighter-tree-sitter"><pre><code><span class='ts-type'>void</span> <span class='ts-function'>pinMode</span>(<span class='ts-type'>uint8_t</span> <span class='ts-variable'>pin</span>, <span class='ts-type'>uint8_t</span> <span class='ts-variable'>mode</span>)<span class='ts-delimiter'>;</span>
</code></pre></div>

<p>Or <code>digitalWrite</code>:</p>

<blockquote class="filename">
  <p>Arduino.h</p>
</blockquote>
<div class="language-cpp highlighter-tree-sitter"><pre><code><span class='ts-type'>void</span> <span class='ts-function'>digitalWrite</span>(<span class='ts-type'>uint8_t</span> <span class='ts-variable'>pin</span>, <span class='ts-type'>uint8_t</span> <span class='ts-variable'>val</span>)<span class='ts-delimiter'>;</span>
</code></pre></div>

<p>And even <code>delay</code>:</p>

<blockquote class="filename">
  <p>Arduino.h</p>
</blockquote>
<div class="language-cpp highlighter-tree-sitter"><pre><code><span class='ts-type'>void</span> <span class='ts-function'>delay</span>(<span class='ts-type'>unsigned long</span> <span class='ts-variable'>ms</span>)<span class='ts-delimiter'>;</span>
</code></pre></div>

<p>Cool! If you’re less inclined to search through header files that are magically included without your say-so, these are also documented in the <a href="https://www.arduino.cc/reference/en/">Arduino library reference</a>.</p>

<p>It’d be pretty boring to just run through that file and explain how everything works. Instead, we’ll build it up ourselves and check out some Arduino code every so often. Sound good? Cool.</p>

<h2 id="registers">Registers</h2>

<p>For the remainder of this post, I’m going to refer to a few things. First, the <a href="https://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-7810-Automotive-Microcontrollers-ATmega328P_Datasheet.pdf">ATmega238P datasheet</a> (henceforth just “datasheet”). This is the actual core microcontroller that powers an Arduino Uno - note it’s more than the CPU! This is what does most of the control, from pins to memory. The Arduino just adds some nice to haves on top. Why? Well, look at this:</p>

<p><img src="/assets/img/posts/arduino-demystified/atmega328p.png" alt="ATmega328p" title="ATmega328p Microcontroller" />
<em><a href="https://en.wikipedia.org/wiki/ATmega328">source</a></em></p>

<p>If you’ve never worked with electronics or PCBs, you probably don’t even know where to start for this. Not exactly the best for quick education or prototyping, is it?</p>

<p>So we have a datasheet for the underlying microcontroller for an Arduino Uno. The main purpose for this is to give us register information. This includes registers like the stack pointer (split between SPH and SPL) and general purpose registers for arithmetic (R0 through R31). Each of these registers are 1 byte (8 bits). Some can get combined for certain operations, but we won’t deal with that.</p>

<p>We care more about the registers associated with I/O ports. In the datasheet, that’s section 13. I’ll try to translate it into simpler terms.</p>

<p>Each pin has three associated registers. These registers are split into different “ports” because there are more than 8 pins in each. The pin is associated with one bit from each of the three registers for a given port.</p>

<p>We’ll get to how to go from pin to its associated registers in a minute, but for now: pin 13 is associated with port B, bit 5. We then have three specific registers that we can manipulate bit 5 in order to achieve certain affects:</p>

<p>1) <code>PORTB</code> - section 13.4.2 in the datasheet. This controls what we send the pin - a high or low voltage.</p>

<p>2) <code>DDRB</code> - section 13.4.3 in the datasheet. This controls the direction of the pin - whether it’s input (0) or output (1).</p>

<p>3) <code>PINB</code> - section 13.4.4 in the datasheet. This gets set based on the value on the pin - it reads a high or low voltage.</p>

<p>For more information on each of those, feel free to read about what they mean in general in section 13.2.1 in the datasheet, since I’ll skip over some parts.</p>

<p>So now we have the three registers that will let us change that pin. How did we get those specific registers? Well, the easiest way is to find a pinout for the Arduino Uno and use that. There are <a href="https://forum.arduino.cc/t/arduino-uno-pinout-diagram/142856">very detailed</a> pinout diagrams, but here’s a <a href="https://docs.arduino.cc/retired/boards/arduino-uno-rev3-with-long-pins/">pretty simple</a> one that gives everything we need right now:</p>

<p><img src="/assets/img/posts/arduino-demystified/uno-pinout.png" alt="Pinout" title="Arduino Uno pinout" />
<em><a href="https://docs.arduino.cc/retired/boards/arduino-uno-rev3-with-long-pins/">source</a></em></p>

<p>Just look at pin D13 (D for digital) - next to it is PB5, which means port B pin 5. Easy enough.</p>

<p>With that background, we can go through each of the abstractions in our blink program and replace it with the harder to understand register manipulation!</p>

<h2 id="digitalwrite-and-pinmode"><code>digitalWrite</code> and <code>pinMode</code></h2>

<p>Alright, so let’s redo <code>digitalWrite</code>. We know we have port B pin 5. The register associated with that is the first of three we described earlier - <code>PORTB</code>. We’re writing an output bit, that’s it. For now let’s do something hacky and just get it working.</p>

<p>So how do we do that? Let’s just change <code>loop</code> to set bit 5 (where bit 0 is the least significant bit) and unset it and see if that blinks it:</p>

<blockquote class="filename">
  <p>Blink</p>
</blockquote>
<div class="language-cpp highlighter-tree-sitter"><pre><code><span class='ts-type'>void</span> <span class='ts-function'>loop</span>() {
  <span class='ts-constant'>PORTB</span> <span class='ts-operator'>=</span> <span class='ts-number'>0b100000</span><span class='ts-delimiter'>;</span>
  <span class='ts-function'>delay</span>(<span class='ts-number'>1000</span>)<span class='ts-delimiter'>;</span>
  <span class='ts-constant'>PORTB</span> <span class='ts-operator'>=</span> <span class='ts-number'>0</span><span class='ts-delimiter'>;</span>
  <span class='ts-function'>delay</span>(<span class='ts-number'>1000</span>)<span class='ts-delimiter'>;</span>
}
</code></pre></div>

<p>Turns out, that works! We set the 5th bit, delay, unset it, then delay. That blinks the LED. Wow!</p>

<p>It may be useful to note that <code>PORTB</code> is not defined in the Arduino standard library I pointed to earlier. It’s actually in the <a href="https://github.com/avrdudes/avr-libc">libc implementation for AVR</a>. This makes sense because <code>PORTB</code> is a register for the AVR microcontroller, not specific to Arduinos. Anything that uses the AVR microcontroller will need that. This will be the case for all of the registers I mention, so I won’t go through them again.</p>

<p>The <code>pinMode</code> function is also similarly easy. This sets the direction - if it’s input, the bit will be 0, if it’s output, the bit will be 1. That’s why when you make the inevitable mistake to not set a pin to output, nothing happens, but you’ll magically be able to use it as input - they default to zeroed out, which is input.</p>

<p>Turns out, the <code>setup</code> function with the new pin is pretty easy. We saw above that the register <code>DDRB</code> is associated with direction for pin 13. So.. let’s just set bit 5 the same way we did with <code>PORTB</code>:</p>

<blockquote class="filename">
  <p>Blink</p>
</blockquote>
<div class="language-cpp highlighter-tree-sitter"><pre><code><span class='ts-type'>void</span> <span class='ts-function'>setup</span>() {
  <span class='ts-constant'>DDRB</span> <span class='ts-operator'>=</span> <span class='ts-number'>0b100000</span><span class='ts-delimiter'>;</span>
}
</code></pre></div>

<p>And it’s that easy.</p>

<p>Now, let’s work towards getting this to work for all pins.</p>

<h3 id="generalizing-digitalwrite-for-all-pins">Generalizing <code>digitalWrite</code> for all pins</h3>

<p>At this point, we’ll look at the Arduino’s standard library. That’s because the pin to register mapping is not done by AVR, but by the Arduino library. We could do these mapping ourselves, but it turns out the Arduino standard library has a couple useful functions.</p>

<p>The first is in the standard <code>Arduino.h</code> file included in all Arduino sketches: a macro called <code>digitalPinToPort</code>. Well, it’s exactly what you think it is, it gives you the port from a pin. It’s defined as:</p>

<blockquote class="filename">
  <p>Arduino.h</p>
</blockquote>
<div class="language-cpp highlighter-tree-sitter"><pre><code><span class='ts-keyword'>#define</span> <span class='ts-function-special'>digitalPinToPort</span>(<span class='ts-constant'>P</span>) ( pgm_read_byte( digital_pin_to_port_PGM + (P) ) )
</code></pre></div>

<p>Then with that, you can use one of three macros to get a pointer to the register you need, whether it’s for output (like <code>PORTB</code>), direction (like <code>DDRB</code>), or input (like <code>PINB</code>):</p>

<blockquote class="filename">
  <p>Arduino.h</p>
</blockquote>
<div class="language-cpp highlighter-tree-sitter"><pre><code><span class='ts-keyword'>#define</span> <span class='ts-function-special'>portOutputRegister</span>(<span class='ts-constant'>P</span>) ( (volatile uint8_t *)( pgm_read_word( port_to_output_PGM + (P))) )
<span class='ts-keyword'>#define</span> <span class='ts-function-special'>portInputRegister</span>(<span class='ts-constant'>P</span>) ( (volatile uint8_t *)( pgm_read_word( port_to_input_PGM + (P))) )
<span class='ts-keyword'>#define</span> <span class='ts-function-special'>portModeRegister</span>(<span class='ts-constant'>P</span>) ( (volatile uint8_t *)( pgm_read_word( port_to_mode_PGM + (P))) )
</code></pre></div>

<p>Easy enough. Then, to get the specific bit.. well, it turns out we have that too:</p>

<blockquote class="filename">
  <p>Arduino.h</p>
</blockquote>
<div class="language-cpp highlighter-tree-sitter"><pre><code><span class='ts-keyword'>#define</span> <span class='ts-function-special'>digitalPinToBitMask</span>(<span class='ts-constant'>P</span>) ( pgm_read_byte( digital_pin_to_bit_mask_PGM + (P) ) )
</code></pre></div>

<p>Alright, with that, we now need to set or clear a specific bit. That’s just simply bit manipulation. If you want to set bit 5 without changing other bits, you may use a bitwise <code>|</code> (or). This will set that bit no matter what, then keep all of the others the same. So to do that for bit 5:</p>

<blockquote class="filename">

</blockquote>
<div class="language-cpp highlighter-tree-sitter"><pre><code><span class='ts-constant'>PORTB</span> |= <span class='ts-number'>0b100000</span><span class='ts-delimiter'>;</span>
</code></pre></div>

<p>Then to toggle it off, you can bitwise <code>&amp;</code> (and) the complement (all bits flipped). Like so:</p>

<blockquote class="filename">

</blockquote>
<div class="language-cpp highlighter-tree-sitter"><pre><code><span class='ts-constant'>PORTB</span> &amp;= ~<span class='ts-number'>0b100000</span><span class='ts-delimiter'>;</span>
</code></pre></div>

<p>So that ends up being <code>PORTB &amp;= 0b11011111</code> - this will always clear the bit with <code>0</code> (which is bit 5, as desired) and keep the other values for each other bit.</p>

<p>So to generalize <code>digitalWrite</code>, we’ll use the same signature:</p>

<blockquote class="filename">
  <p>Blink</p>
</blockquote>
<div class="language-cpp highlighter-tree-sitter"><pre><code><span class='ts-type'>void</span> <span class='ts-function'>myDigitalWrite</span>(<span class='ts-type'>uint8_t</span> <span class='ts-variable'>pin</span>, <span class='ts-type'>uint8_t</span> <span class='ts-variable'>val</span>) {
</code></pre></div>

<p>Then get the port, output pointer, and pin bit mask:</p>

<blockquote class="filename">
  <p>Blink</p>
</blockquote>
<div class="language-cpp highlighter-tree-sitter"><pre><code>  <span class='ts-type'>uint8_t</span> <span class='ts-variable'>port</span> <span class='ts-operator'>=</span> <span class='ts-function'>digitalPinToPort</span>(<span class='ts-variable'>pin</span>)<span class='ts-delimiter'>;</span>
  <span class='ts-type'>uint8_t</span> <span class='ts-operator'>*</span><span class='ts-variable'>ptr</span> <span class='ts-operator'>=</span> <span class='ts-function'>portOutputRegister</span>(<span class='ts-variable'>port</span>)<span class='ts-delimiter'>;</span>
  <span class='ts-type'>uint8_t</span> <span class='ts-variable'>bit</span> <span class='ts-operator'>=</span> <span class='ts-function'>digitalPinToBitMask</span>(<span class='ts-variable'>pin</span>)<span class='ts-delimiter'>;</span>
</code></pre></div>

<p>Now we can just set the pin like before. We’ll use Arduino’s defined <code>LOW</code> (0) and <code>HIGH</code> (1). We’ll just do nothing if they pass a value other than that:</p>

<blockquote class="filename">
  <p>Blink</p>
</blockquote>
<div class="language-cpp highlighter-tree-sitter"><pre><code>  <span class='ts-keyword'>if</span> (<span class='ts-variable'>val</span> <span class='ts-operator'>==</span> <span class='ts-constant'>HIGH</span>) {
    <span class='ts-operator'>*</span><span class='ts-variable'>ptr</span> |= <span class='ts-variable'>bit</span><span class='ts-delimiter'>;</span>
  } <span class='ts-keyword'>else</span> <span class='ts-keyword'>if</span> (<span class='ts-variable'>val</span> <span class='ts-operator'>==</span> <span class='ts-constant'>LOW</span>) {
    <span class='ts-operator'>*</span><span class='ts-variable'>ptr</span> &amp;= ~<span class='ts-variable'>bit</span><span class='ts-delimiter'>;</span>
  }
</code></pre></div>

<p>Then we’re done! Here’s the whole thing:</p>

<blockquote class="filename">
  <p>Blink</p>
</blockquote>
<div class="language-cpp highlighter-tree-sitter"><pre><code><span class='ts-type'>void</span> <span class='ts-function'>myDigitalWrite</span>(<span class='ts-type'>uint8_t</span> <span class='ts-variable'>pin</span>, <span class='ts-type'>uint8_t</span> <span class='ts-variable'>val</span>) {
  <span class='ts-type'>uint8_t</span> <span class='ts-variable'>port</span> <span class='ts-operator'>=</span> <span class='ts-function'>digitalPinToPort</span>(<span class='ts-variable'>pin</span>)<span class='ts-delimiter'>;</span>
  <span class='ts-type'>uint8_t</span> <span class='ts-operator'>*</span><span class='ts-variable'>ptr</span> <span class='ts-operator'>=</span> <span class='ts-function'>portOutputRegister</span>(<span class='ts-variable'>port</span>)<span class='ts-delimiter'>;</span>
  <span class='ts-type'>uint8_t</span> <span class='ts-variable'>bit</span> <span class='ts-operator'>=</span> <span class='ts-function'>digitalPinToBitMask</span>(<span class='ts-variable'>pin</span>)<span class='ts-delimiter'>;</span>

  <span class='ts-keyword'>if</span> (<span class='ts-variable'>val</span> <span class='ts-operator'>==</span> <span class='ts-constant'>HIGH</span>) {
    <span class='ts-operator'>*</span><span class='ts-variable'>ptr</span> |= <span class='ts-variable'>bit</span><span class='ts-delimiter'>;</span>
  } <span class='ts-keyword'>else</span> <span class='ts-keyword'>if</span> (<span class='ts-variable'>val</span> <span class='ts-operator'>==</span> <span class='ts-constant'>LOW</span>) {
    <span class='ts-operator'>*</span><span class='ts-variable'>ptr</span> &amp;= ~<span class='ts-variable'>bit</span><span class='ts-delimiter'>;</span>
  }
}
</code></pre></div>

<p>We can use it like:</p>

<blockquote class="filename">
  <p>Blink</p>
</blockquote>
<div class="language-cpp highlighter-tree-sitter"><pre><code><span class='ts-type'>void</span> <span class='ts-function'>loop</span>() {
  <span class='ts-function'>myDigitalWrite</span>(<span class='ts-constant'>LED_BUILTIN</span>, <span class='ts-constant'>HIGH</span>)<span class='ts-delimiter'>;</span>
  <span class='ts-function'>delay</span>(<span class='ts-number'>1000</span>)<span class='ts-delimiter'>;</span>
  <span class='ts-function'>myDigitalWrite</span>(<span class='ts-constant'>LED_BUILTIN</span>, <span class='ts-constant'>LOW</span>)<span class='ts-delimiter'>;</span>
  <span class='ts-function'>delay</span>(<span class='ts-number'>1000</span>)<span class='ts-delimiter'>;</span>
}
</code></pre></div>

<p>There we go, our own <code>digitalWrite</code>.</p>

<h4 id="aside-the-real-digitalwrite">Aside: The real <code>digitalWrite</code></h4>

<p>Alright, it turns out there are a couple complications with <code>digitalWrite</code> that may come up in other places, so I’ll mention them here. For this, I will go through the whole <code>digitalWrite</code> function in the Arduino standard library. I <em>promise</em> it’s the only time I’ll do this.</p>

<p>First, the setup is similar to the one we made:</p>

<blockquote class="filename">
  <p>wiring_digital.c</p>
</blockquote>
<div class="language-c highlighter-tree-sitter"><pre><code>	<span class='ts-type'>uint8_t</span> <span class='ts-variable'>timer</span> <span class='ts-operator'>=</span> <span class='ts-function'>digitalPinToTimer</span>(<span class='ts-variable'>pin</span>)<span class='ts-delimiter'>;</span>
	<span class='ts-type'>uint8_t</span> <span class='ts-variable'>bit</span> <span class='ts-operator'>=</span> <span class='ts-function'>digitalPinToBitMask</span>(<span class='ts-variable'>pin</span>)<span class='ts-delimiter'>;</span>
	<span class='ts-type'>uint8_t</span> <span class='ts-variable'>port</span> <span class='ts-operator'>=</span> <span class='ts-function'>digitalPinToPort</span>(<span class='ts-variable'>pin</span>)<span class='ts-delimiter'>;</span>
	<span class='ts-keyword'>volatile</span> <span class='ts-type'>uint8_t</span> <span class='ts-operator'>*</span><span class='ts-variable'>out</span><span class='ts-delimiter'>;</span>
</code></pre></div>

<p>The <code>out</code> variable here is equivalent to the <code>ptr</code> variable I used. Note that theirs is marked <code>volatile</code>. That’s because this is a memory address that may be changed by something outside of this function. So the compiler shouldn’t say it knows some crazy compiler optimization here: act as though this variable may change without your knowledge. That way it will do what it’s told.</p>

<p>We alse declare <code>timer</code> which is used after:</p>

<blockquote class="filename">
  <p>wiring_digital.c</p>
</blockquote>
<div class="language-c highlighter-tree-sitter"><pre><code>	<span class='ts-keyword'>if</span> (<span class='ts-variable'>port</span> <span class='ts-operator'>==</span> <span class='ts-constant'>NOT_A_PIN</span>) <span class='ts-keyword'>return</span><span class='ts-delimiter'>;</span>

	<span class='ts-comment'>// If the pin that support PWM output, we need to turn it off</span>
	<span class='ts-comment'>// before doing a digital write.</span>
	<span class='ts-keyword'>if</span> (<span class='ts-variable'>timer</span> <span class='ts-operator'>!=</span> <span class='ts-constant'>NOT_ON_TIMER</span>) <span class='ts-function'>turnOffPWM</span>(<span class='ts-variable'>timer</span>)<span class='ts-delimiter'>;</span>
</code></pre></div>

<p>Well, first we abort if they pass something that’s not an Arduino pin, like <code>42</code>.</p>

<p>Then, this condition is the only use of <code>timer</code> (set early). We’ll later get into what pulse width modulation (PWM) is and how it works. But, this is just a consequence of some pins being usable as pseudo-analog PWM pins. We should disable that functionality if we want a dumb on/off.</p>

<p>Next we set the <code>out</code> variable:</p>

<blockquote class="filename">
  <p>wiring_digital.c</p>
</blockquote>
<div class="language-c highlighter-tree-sitter"><pre><code>	<span class='ts-variable'>out</span> <span class='ts-operator'>=</span> <span class='ts-function'>portOutputRegister</span>(<span class='ts-variable'>port</span>)<span class='ts-delimiter'>;</span>
</code></pre></div>

<p>Just as we did with <code>ptr</code>. Easy.</p>

<p>Then we get some… stuff?</p>

<blockquote class="filename">
  <p>wiring_digital.c</p>
</blockquote>
<div class="language-c highlighter-tree-sitter"><pre><code>	<span class='ts-type'>uint8_t</span> <span class='ts-variable'>oldSREG</span> <span class='ts-operator'>=</span> <span class='ts-constant'>SREG</span><span class='ts-delimiter'>;</span>
	<span class='ts-function'>cli</span>()<span class='ts-delimiter'>;</span>
</code></pre></div>

<p>Alright so that came out of no where, but no fret, these are easy. If we search for <code>SREG</code> in the datasheet above, we find:</p>

<blockquote>
  <p>SREG - AVR status register</p>
</blockquote>

<p>So that’s <code>SREG</code> for S(tatus) Reg(ister). Simple. But why do we store the old value? Actually, the answer is in the bit 7 documentation:</p>

<blockquote>
  <p>The I-bit can also be set and cleared by the application with the SEI and CLI instructions, as described in the instruction set reference.</p>
</blockquote>

<p>So <code>cli</code> is just an instruction that clears the I-bit of the <code>SREG</code> register, which disables interrupts. Since an interrupt can come in at any time, we really really do not want that happening somewhere bad. It could happen after we read the register value, then we come back and do the operation with an old value!</p>

<p>Well, since <code>cli</code> is an instruction, it’s again in the AVR libc implementation:</p>

<blockquote class="filename">
  <p>interrupt.h</p>
</blockquote>
<div class="language-c highlighter-tree-sitter"><pre><code><span class='ts-keyword'># define</span> <span class='ts-function-special'>cli</span>()  __asm__ __volatile__ (&quot;cli&quot; ::: &quot;memory&quot;)
</code></pre></div>

<p>Yeah so it basically just adds the <code>cli</code> instruction into the assembly.</p>

<p>So, going back to <code>digitalWrite</code>, why do we have to keep the old <code>SREG</code> value? Well, it’s just because we don’t want that interrupt disable to be permanent. Say the user has interrupts enabled and we disable them in <code>digitalWrite</code> - that would be bad. Then, we can’t just reenable them after <code>digitalWrite</code> - what if the user disabled them? Then every time they call <code>digitalWrite</code> their interrupts are reenabled - not cool. So we keep the value that it was called with. We’ll see later that this is reapplied.</p>

<p>Okay, back to regularly scheduled programming, here’s something familiar in the next lines of <code>digitalWrite</code>:</p>

<blockquote class="filename">
  <p>wiring_digital.c</p>
</blockquote>
<div class="language-c highlighter-tree-sitter"><pre><code>	<span class='ts-keyword'>if</span> (<span class='ts-variable'>val</span> <span class='ts-operator'>==</span> <span class='ts-constant'>LOW</span>) {
		<span class='ts-operator'>*</span><span class='ts-variable'>out</span> &amp;= ~<span class='ts-variable'>bit</span><span class='ts-delimiter'>;</span>
	} <span class='ts-keyword'>else</span> {
		<span class='ts-operator'>*</span><span class='ts-variable'>out</span> |= <span class='ts-variable'>bit</span><span class='ts-delimiter'>;</span>
	}

</code></pre></div>

<p>Yup, pretty similar to the set/unset we did (except this will always set it if <code>val</code> is not <code>LOW</code> - slightly different!)</p>

<p>And finally:</p>

<blockquote class="filename">
  <p>wiring_digital.c</p>
</blockquote>
<div class="language-c highlighter-tree-sitter"><pre><code>	<span class='ts-constant'>SREG</span> <span class='ts-operator'>=</span> <span class='ts-variable'>oldSREG</span><span class='ts-delimiter'>;</span>
</code></pre></div>

<p>Yep so we restored the old <code>SREG</code> value.</p>

<p>It’s all pretty simple, even if there’s a bit of extra stuff we need to care about when dealing with the actual Arduino standard library. It’s important to do, but our dummy implementations don’t need to do all of that.</p>

<p>Speaking of dummy implementations of Arduino functions.. how about we read some inputs?</p>

<h2 id="inputs">Inputs</h2>

<p>Alright so that was a lot just for the most basic function that you can do with an Arduino. There’s absolutely no way that input is that much.</p>

<p>… Actually, yeah, it’s a bit simpler and we have all the tools for doing this now. But first, let’s take a detour to wire something up since we don’t have a builtin input method like we do with a builtin LED.</p>

<p>For this we’ll just grab Arduino’s Button example, which puts the button on pin 2. I won’t show any videos or anything of it working after each step, just believe me. But here’s a picture of my Arduino with a button on pin 2:</p>

<p><img src="/assets/img/posts/arduino-demystified/notpressingbutton.jpg" alt="Not pressing button" title="Me, not pressing a button" /></p>

<p>And here’s me pressing the button. If you hold your screen really close, you may see a small LED on the Arduino light up.</p>

<p><img src="/assets/img/posts/arduino-demystified/pressingbutton.jpg" alt="Pressing button" title="Me, pressing a button" /></p>

<p>Incredible! Here’s the code that comes with the Button example:</p>

<blockquote class="filename">
  <p>Button</p>
</blockquote>
<div class="language-cpp highlighter-tree-sitter"><pre><code><span class='ts-keyword'>const</span> <span class='ts-type'>int</span> <span class='ts-variable'>buttonPin</span> <span class='ts-operator'>=</span> <span class='ts-number'>2</span><span class='ts-delimiter'>;</span>  <span class='ts-comment'>// the number of the pushbutton pin</span>
<span class='ts-keyword'>const</span> <span class='ts-type'>int</span> <span class='ts-variable'>ledPin</span> <span class='ts-operator'>=</span> <span class='ts-number'>13</span><span class='ts-delimiter'>;</span>    <span class='ts-comment'>// the number of the LED pin</span>

<span class='ts-comment'>// variables will change:</span>
<span class='ts-type'>int</span> <span class='ts-variable'>buttonState</span> <span class='ts-operator'>=</span> <span class='ts-number'>0</span><span class='ts-delimiter'>;</span>  <span class='ts-comment'>// variable for reading the pushbutton status</span>

<span class='ts-type'>void</span> <span class='ts-function'>setup</span>() {
  <span class='ts-comment'>// initialize the LED pin as an output:</span>
  <span class='ts-function'>pinMode</span>(<span class='ts-variable'>ledPin</span>, <span class='ts-constant'>OUTPUT</span>)<span class='ts-delimiter'>;</span>
  <span class='ts-comment'>// initialize the pushbutton pin as an input:</span>
  <span class='ts-function'>pinMode</span>(<span class='ts-variable'>buttonPin</span>, <span class='ts-constant'>INPUT</span>)<span class='ts-delimiter'>;</span>
}

<span class='ts-type'>void</span> <span class='ts-function'>loop</span>() {
  <span class='ts-comment'>// read the state of the pushbutton value:</span>
  <span class='ts-variable'>buttonState</span> <span class='ts-operator'>=</span> <span class='ts-function'>digitalRead</span>(<span class='ts-variable'>buttonPin</span>)<span class='ts-delimiter'>;</span>

  <span class='ts-comment'>// check if the pushbutton is pressed. If it is, the buttonState is HIGH:</span>
  <span class='ts-keyword'>if</span> (<span class='ts-variable'>buttonState</span> <span class='ts-operator'>==</span> <span class='ts-constant'>HIGH</span>) {
    <span class='ts-comment'>// turn LED on:</span>
    <span class='ts-function'>digitalWrite</span>(<span class='ts-variable'>ledPin</span>, <span class='ts-constant'>HIGH</span>)<span class='ts-delimiter'>;</span>
  } <span class='ts-keyword'>else</span> {
    <span class='ts-comment'>// turn LED off:</span>
    <span class='ts-function'>digitalWrite</span>(<span class='ts-variable'>ledPin</span>, <span class='ts-constant'>LOW</span>)<span class='ts-delimiter'>;</span>
  }
}
</code></pre></div>

<p>So we care about one thing: the <code>digitalRead</code> function at the beginning of the <code>loop</code> function. Can we rewrite that line?</p>

<p>Well, we know from before that it will be in a register, just we’ll read from the register, not write. According to the handy pinout diagram I showed before, pin 2 is port D bit 2. The input register, then, is <code>PIND</code>. So <code>0b100</code> should be a proper bitmask on <code>PIND</code>.</p>

<p>Here’s a simplification: we could bitshift this right twice to get a 0 or 1 - or, we could just ask “is this above 0?” and if it is, that pin is high! If so, we’ll turn it into 1 (because I don’t want to touch the rest of the code that assumes it’s a 0 or 1), if not then we’ll just keep it 0. So we can change setting <code>buttonState</code> like so:</p>

<blockquote class="filename">
  <p>Button</p>
</blockquote>
<div class="language-cpp highlighter-tree-sitter"><pre><code>  <span class='ts-type'>int</span> <span class='ts-variable'>pinVal</span> <span class='ts-operator'>=</span> <span class='ts-constant'>PIND</span> <span class='ts-operator'>&amp;</span> <span class='ts-number'>0b100</span><span class='ts-delimiter'>;</span>
  <span class='ts-variable'>buttonState</span> <span class='ts-operator'>=</span> <span class='ts-variable'>pinVal</span> <span class='ts-operator'>&gt;</span> <span class='ts-number'>0</span><span class='ts-delimiter'>;</span>
</code></pre></div>

<p>Well.. that was easy. So look, not only can we write from registers, we can also read them! Memory!</p>

<p>Now we can make our own <code>digitalRead</code> like before, and it’s actually a bit easier in my opinion. Here’s the whole thing:</p>

<blockquote class="filename">
  <p>Button</p>
</blockquote>
<div class="language-cpp highlighter-tree-sitter"><pre><code><span class='ts-type'>int</span> <span class='ts-function'>myDigitalRead</span>(<span class='ts-type'>uint8_t</span> <span class='ts-variable'>pin</span>) {
  <span class='ts-type'>uint8_t</span> <span class='ts-variable'>port</span> <span class='ts-operator'>=</span> <span class='ts-function'>digitalPinToPort</span>(<span class='ts-variable'>pin</span>)<span class='ts-delimiter'>;</span>
  <span class='ts-type'>uint8_t</span> <span class='ts-operator'>*</span><span class='ts-variable'>ptr</span> <span class='ts-operator'>=</span> <span class='ts-function'>portInputRegister</span>(<span class='ts-variable'>port</span>)<span class='ts-delimiter'>;</span>
  <span class='ts-type'>uint8_t</span> <span class='ts-variable'>bit</span> <span class='ts-operator'>=</span> <span class='ts-function'>digitalPinToBitMask</span>(<span class='ts-variable'>pin</span>)<span class='ts-delimiter'>;</span>
  <span class='ts-keyword'>return</span> (<span class='ts-operator'>*</span><span class='ts-variable'>ptr</span> <span class='ts-operator'>&amp;</span> <span class='ts-variable'>bit</span>) <span class='ts-operator'>&gt;</span> <span class='ts-number'>0</span><span class='ts-delimiter'>;</span>
}
</code></pre></div>

<p>So we start with the same thing, just changing <code>ptr</code> to come from <code>portInputRegister</code> rather than <code>portOutputRegister</code>. Then, we just test if the bit value is greater than 0. Note that we’re kind of assuming that <code>HIGH</code> is 1 and <code>LOW</code> is 0, which may not always be true, but it works for now so who cares.</p>

<p>Now how about the real thing? Well it’s also a little easier:</p>

<blockquote class="filename">
  <p>wiring_digital.c</p>
</blockquote>
<div class="language-c highlighter-tree-sitter"><pre><code><span class='ts-type'>int</span> <span class='ts-function'>digitalRead</span>(<span class='ts-type'>uint8_t</span> <span class='ts-variable'>pin</span>)
{
	<span class='ts-type'>uint8_t</span> <span class='ts-variable'>timer</span> <span class='ts-operator'>=</span> <span class='ts-function'>digitalPinToTimer</span>(<span class='ts-variable'>pin</span>)<span class='ts-delimiter'>;</span>
	<span class='ts-type'>uint8_t</span> <span class='ts-variable'>bit</span> <span class='ts-operator'>=</span> <span class='ts-function'>digitalPinToBitMask</span>(<span class='ts-variable'>pin</span>)<span class='ts-delimiter'>;</span>
	<span class='ts-type'>uint8_t</span> <span class='ts-variable'>port</span> <span class='ts-operator'>=</span> <span class='ts-function'>digitalPinToPort</span>(<span class='ts-variable'>pin</span>)<span class='ts-delimiter'>;</span>

	<span class='ts-keyword'>if</span> (<span class='ts-variable'>port</span> <span class='ts-operator'>==</span> <span class='ts-constant'>NOT_A_PIN</span>) <span class='ts-keyword'>return</span> <span class='ts-constant'>LOW</span><span class='ts-delimiter'>;</span>

	<span class='ts-comment'>// If the pin that support PWM output, we need to turn it off</span>
	<span class='ts-comment'>// before getting a digital reading.</span>
	<span class='ts-keyword'>if</span> (<span class='ts-variable'>timer</span> <span class='ts-operator'>!=</span> <span class='ts-constant'>NOT_ON_TIMER</span>) <span class='ts-function'>turnOffPWM</span>(<span class='ts-variable'>timer</span>)<span class='ts-delimiter'>;</span>

	<span class='ts-keyword'>if</span> (<span class='ts-operator'>*</span><span class='ts-function'>portInputRegister</span>(<span class='ts-variable'>port</span>) <span class='ts-operator'>&amp;</span> <span class='ts-variable'>bit</span>) <span class='ts-keyword'>return</span> <span class='ts-constant'>HIGH</span><span class='ts-delimiter'>;</span>
	<span class='ts-keyword'>return</span> <span class='ts-constant'>LOW</span><span class='ts-delimiter'>;</span>
}
</code></pre></div>

<p>So we have the same stuff as <code>digitalWrite</code>: Return if the pin isn’t a real pin and turn off PWM if necessary. But we don’t do any nonsense around interrupts - we just read the pin, test it, and return <code>HIGH</code> or <code>LOW</code>.</p>

<p>Disabling interrupts is not necessary here - loading the value of that register is a single instruction. With <code>digitalWrite</code>, we read a value, used it, then set it again. If there was an interrupt between the read and write, we may get an issue. Here we just have one instruction and don’t write back to it, so no risk of that. It makes it nice and simple.</p>

<p>Now that we have the two fundamental operations, we need to get the way to go between them working.</p>

<h2 id="pinmode-revisited"><code>pinMode</code>, Revisited</h2>

<p>In the <code>digitalWrite</code> section, we had to put something hacky for <code>pinMode</code>, but it has some complications I wanted to address after showing how to make <code>digitalRead</code>. It’s time!</p>

<p>In theory, <code>pinMode</code> is also super easy. It’s just <code>digitalWrite</code> but with a different port:</p>

<blockquote class="filename">
  <p>Blink</p>
</blockquote>
<div class="language-cpp highlighter-tree-sitter"><pre><code><span class='ts-type'>void</span> <span class='ts-function'>myPinMode</span>(<span class='ts-type'>uint8_t</span> <span class='ts-variable'>pin</span>, <span class='ts-type'>uint8_t</span> <span class='ts-variable'>mode</span>) {
  <span class='ts-type'>uint8_t</span> <span class='ts-variable'>port</span> <span class='ts-operator'>=</span> <span class='ts-function'>digitalPinToPort</span>(<span class='ts-variable'>pin</span>)<span class='ts-delimiter'>;</span>
  <span class='ts-type'>uint8_t</span> <span class='ts-operator'>*</span><span class='ts-variable'>ptr</span> <span class='ts-operator'>=</span> <span class='ts-function'>portModeRegister</span>(<span class='ts-variable'>port</span>)<span class='ts-delimiter'>;</span>
  <span class='ts-type'>uint8_t</span> <span class='ts-variable'>bit</span> <span class='ts-operator'>=</span> <span class='ts-function'>digitalPinToBitMask</span>(<span class='ts-variable'>pin</span>)<span class='ts-delimiter'>;</span>

  <span class='ts-keyword'>if</span> (<span class='ts-variable'>mode</span> <span class='ts-operator'>==</span> <span class='ts-constant'>OUTPUT</span>) {
    <span class='ts-operator'>*</span><span class='ts-variable'>ptr</span> |= <span class='ts-variable'>bit</span><span class='ts-delimiter'>;</span>
  } <span class='ts-keyword'>else</span> <span class='ts-keyword'>if</span> (<span class='ts-variable'>mode</span> <span class='ts-operator'>==</span> <span class='ts-constant'>INPUT</span>) {
    <span class='ts-operator'>*</span><span class='ts-variable'>ptr</span> &amp;= ~<span class='ts-variable'>bit</span><span class='ts-delimiter'>;</span>
  }
}
</code></pre></div>

<p>Then, as with <code>HIGH</code> and <code>LOW</code> values for <code>digitalWrite</code>, we can find <code>OUTPUT</code> and <code>INPUT</code> in <code>Arduino.h</code>:</p>

<blockquote class="filename">
  <p>Blink</p>
</blockquote>
<div class="language-cpp highlighter-tree-sitter"><pre><code><span class='ts-keyword'>#define</span> <span class='ts-constant'>INPUT</span> 0x0
<span class='ts-keyword'>#define</span> <span class='ts-constant'>OUTPUT</span> 0x1
<span class='ts-keyword'>#define</span> <span class='ts-constant'>INPUT_PULLUP</span> 0x2
</code></pre></div>

<p>Wait, there’s also <code>INPUT_PULLUP</code>, what’s that?</p>

<h3 id="pull-up-resistors">Pull-up resistors</h3>

<p>Well, here’s Arduino’s <a href="https://docs.arduino.cc/tutorials/generic/digital-input-pullup/">documentation</a> on the pull up mode. It’s just an internal <a href="https://en.wikipedia.org/wiki/Pull-up_resistor">pull-up resistor</a>. These are used to prevent a “floating” value, where the input value may be anywhere between ground or high because it’s not connected to either!</p>

<p>The button is wired slightly differently, where pin 2 will read a floating value if the button is not pressed, or 0 if it is. This means it’s inverted logic compared to what we had before. Here’s Arduino’s “DigitalInputPullup” example for a reference:</p>

<blockquote class="filename">
  <p>DigitalInputPullup</p>
</blockquote>
<div class="language-cpp highlighter-tree-sitter"><pre><code><span class='ts-type'>void</span> <span class='ts-function'>setup</span>() {
  <span class='ts-comment'>//start serial connection</span>
  <span class='ts-variable'>Serial</span><span class='ts-delimiter'>.</span><span class='ts-function'>begin</span>(<span class='ts-number'>9600</span>)<span class='ts-delimiter'>;</span>
  <span class='ts-comment'>//configure pin 2 as an input and enable the internal pull-up resistor</span>
  <span class='ts-function'>pinMode</span>(<span class='ts-number'>2</span>, <span class='ts-constant'>INPUT_PULLUP</span>)<span class='ts-delimiter'>;</span>
  <span class='ts-function'>pinMode</span>(<span class='ts-number'>13</span>, <span class='ts-constant'>OUTPUT</span>)<span class='ts-delimiter'>;</span>
}

<span class='ts-type'>void</span> <span class='ts-function'>loop</span>() {
  <span class='ts-comment'>//read the pushbutton value into a variable</span>
  <span class='ts-type'>int</span> <span class='ts-variable'>sensorVal</span> <span class='ts-operator'>=</span> <span class='ts-function'>digitalRead</span>(<span class='ts-number'>2</span>)<span class='ts-delimiter'>;</span>
  <span class='ts-comment'>//print out the value of the pushbutton</span>
  <span class='ts-variable'>Serial</span><span class='ts-delimiter'>.</span><span class='ts-function'>println</span>(<span class='ts-variable'>sensorVal</span>)<span class='ts-delimiter'>;</span>

  <span class='ts-comment'>// Keep in mind the pull-up means the pushbutton&#39;s logic is inverted. It goes</span>
  <span class='ts-comment'>// HIGH when it&#39;s open, and LOW when it&#39;s pressed. Turn on pin 13 when the</span>
  <span class='ts-comment'>// button&#39;s pressed, and off when it&#39;s not:</span>
  <span class='ts-keyword'>if</span> (<span class='ts-variable'>sensorVal</span> <span class='ts-operator'>==</span> <span class='ts-constant'>HIGH</span>) {
    <span class='ts-function'>digitalWrite</span>(<span class='ts-number'>13</span>, <span class='ts-constant'>LOW</span>)<span class='ts-delimiter'>;</span>
  } <span class='ts-keyword'>else</span> {
    <span class='ts-function'>digitalWrite</span>(<span class='ts-number'>13</span>, <span class='ts-constant'>HIGH</span>)<span class='ts-delimiter'>;</span>
  }
}
</code></pre></div>

<p>So the goal here is to get <code>INPUT_PULLUP</code> working.</p>

<h3 id="how-to-pull-up">How to pull-up?</h3>

<p>The datasheet section 13.2.3 has a nice table (table 13-1), recreated here for your convenience:</p>

<table>
  <thead>
    <tr>
      <th>DDxn</th>
      <th>PORTxn</th>
      <th>PUD (in MCUCR)</th>
      <th>I/O</th>
      <th>Pull-up</th>
      <th>Comment</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>0</td>
      <td>0</td>
      <td>X</td>
      <td>Input</td>
      <td>No</td>
      <td>Tri-state (Hi-Z)</td>
    </tr>
    <tr>
      <td>0</td>
      <td>1</td>
      <td>0</td>
      <td>Input</td>
      <td>Yes</td>
      <td>Pxn will source current if ext. pulled low.</td>
    </tr>
    <tr>
      <td>0</td>
      <td>1</td>
      <td>1</td>
      <td>Input</td>
      <td>No</td>
      <td>Tri-state (Hi-Z)</td>
    </tr>
    <tr>
      <td>1</td>
      <td>0</td>
      <td>X</td>
      <td>Output</td>
      <td>No</td>
      <td>Output low (sink)</td>
    </tr>
    <tr>
      <td>1</td>
      <td>1</td>
      <td>X</td>
      <td>Output</td>
      <td>No</td>
      <td>Output high (source)</td>
    </tr>
  </tbody>
</table>

<p>Okay, most of this doesn’t matter for what we’re going towards, but compare the one row marked “Input” and “Pull-up” and the two marked “Input” without “Pull-up” - ignoring the PUD column so the two in common are basically the same. The difference is PORTxn - that’s the output register!</p>

<p>So the <code>myPinMode</code> function written above doesn’t address the output values for simplicity, but really it matters. So let’s make that change.</p>

<h3 id="the-final-custom-mypinmode">The final custom <code>myPinMode</code></h3>

<p>I’ll go by step by step again.</p>

<p>The first part is pretty predictable, with some different variable names for clarity:</p>

<blockquote class="filename">
  <p>DigitalInputPullup</p>
</blockquote>
<div class="language-cpp highlighter-tree-sitter"><pre><code><span class='ts-type'>void</span> <span class='ts-function'>myPinMode</span>(<span class='ts-type'>uint8_t</span> <span class='ts-variable'>pin</span>, <span class='ts-type'>uint8_t</span> <span class='ts-variable'>mode</span>) {
  <span class='ts-type'>uint8_t</span> <span class='ts-variable'>port</span> <span class='ts-operator'>=</span> <span class='ts-function'>digitalPinToPort</span>(<span class='ts-variable'>pin</span>)<span class='ts-delimiter'>;</span>
  <span class='ts-type'>uint8_t</span> <span class='ts-operator'>*</span><span class='ts-variable'>modeReg</span> <span class='ts-operator'>=</span> <span class='ts-function'>portModeRegister</span>(<span class='ts-variable'>port</span>)<span class='ts-delimiter'>;</span>
  <span class='ts-type'>uint8_t</span> <span class='ts-operator'>*</span><span class='ts-variable'>outReg</span> <span class='ts-operator'>=</span> <span class='ts-function'>portOutputRegister</span>(<span class='ts-variable'>port</span>)<span class='ts-delimiter'>;</span>
  <span class='ts-type'>uint8_t</span> <span class='ts-variable'>bit</span> <span class='ts-operator'>=</span> <span class='ts-function'>digitalPinToBitMask</span>(<span class='ts-variable'>pin</span>)<span class='ts-delimiter'>;</span>
</code></pre></div>

<p>Then we have output:</p>

<blockquote class="filename">
  <p>DigitalInputPullup</p>
</blockquote>
<div class="language-cpp highlighter-tree-sitter"><pre><code>  <span class='ts-keyword'>if</span> (<span class='ts-variable'>mode</span> <span class='ts-operator'>==</span> <span class='ts-constant'>OUTPUT</span>) {
    <span class='ts-operator'>*</span><span class='ts-variable'>modeReg</span> |= <span class='ts-variable'>bit</span><span class='ts-delimiter'>;</span>
</code></pre></div>

<p>Cool, it’s the same since the output value can just stay the same. Input is the same, but we clear the output register bit too:</p>

<blockquote class="filename">
  <p>DigitalInputPullup</p>
</blockquote>
<div class="language-cpp highlighter-tree-sitter"><pre><code>  } <span class='ts-keyword'>else</span> <span class='ts-keyword'>if</span> (<span class='ts-variable'>mode</span> <span class='ts-operator'>==</span> <span class='ts-constant'>INPUT</span>) {
    <span class='ts-operator'>*</span><span class='ts-variable'>modeReg</span> &amp;= ~<span class='ts-variable'>bit</span><span class='ts-delimiter'>;</span>
    <span class='ts-operator'>*</span><span class='ts-variable'>outReg</span> &amp;= ~<span class='ts-variable'>bit</span><span class='ts-delimiter'>;</span>
</code></pre></div>

<p>And, predictably, pull-up input just sets <code>outReg</code> too:</p>

<blockquote class="filename">
  <p>DigitalInputPullup</p>
</blockquote>
<div class="language-cpp highlighter-tree-sitter"><pre><code>  } <span class='ts-keyword'>else</span> <span class='ts-keyword'>if</span> (<span class='ts-variable'>mode</span> <span class='ts-operator'>==</span> <span class='ts-constant'>INPUT_PULLUP</span>) {
    <span class='ts-operator'>*</span><span class='ts-variable'>modeReg</span> &amp;= ~<span class='ts-variable'>bit</span><span class='ts-delimiter'>;</span>
    <span class='ts-operator'>*</span><span class='ts-variable'>outReg</span> |= <span class='ts-variable'>bit</span><span class='ts-delimiter'>;</span>
  }
}
</code></pre></div>

<p>And that’s the end of the function! Incredible.</p>

<h4 id="the-real-pinmode">The real <code>pinMode</code>?</h4>

<p>Okay, I’ll just go through differences with the real <code>pinMode</code> and not step through the whole thing.</p>

<p>First, before calling <code>portModeRegister</code> and <code>portOutputRegister</code>, there’s a check to make sure it’s a pin:</p>

<blockquote class="filename">
  <p>wiring_digital.c</p>
</blockquote>
<div class="language-cpp highlighter-tree-sitter"><pre><code><span class='ts-keyword'>if</span> (<span class='ts-variable'>port</span> <span class='ts-operator'>==</span> <span class='ts-constant'>NOT_A_PIN</span>) <span class='ts-keyword'>return</span><span class='ts-delimiter'>;</span>
</code></pre></div>

<p>Then, each case has a caching of the SREG register and stopping interrupts, then restoring, like <code>digitalWrite</code>. Here’s the <code>INPUT</code> logic as an example:</p>

<blockquote class="filename">
  <p>wiring_digital.c</p>
</blockquote>
<div class="language-cpp highlighter-tree-sitter"><pre><code><span class='ts-type'>uint8_t</span> <span class='ts-variable'>oldSREG</span> <span class='ts-operator'>=</span> <span class='ts-constant'>SREG</span><span class='ts-delimiter'>;</span>
<span class='ts-function'>cli</span>()<span class='ts-delimiter'>;</span>
<span class='ts-operator'>*</span><span class='ts-variable'>reg</span> &amp;= ~<span class='ts-variable'>bit</span><span class='ts-delimiter'>;</span>
<span class='ts-operator'>*</span><span class='ts-variable'>out</span> &amp;= ~<span class='ts-variable'>bit</span><span class='ts-delimiter'>;</span>
<span class='ts-constant'>SREG</span> <span class='ts-operator'>=</span> <span class='ts-variable'>oldSREG</span><span class='ts-delimiter'>;</span>
</code></pre></div>

<p>Leading whitespace for these snippets was fixed for your viewing pleasure.</p>

<p>And that’s about all of the differences we have. All in all, it wasn’t that bad. But now we’re going to go into something more complicated than just turning something off and on - turning something off and on in rapid succession!</p>

<h2 id="pwm">PWM</h2>

<p>Pulse width modulation (<a href="https://en.wikipedia.org/wiki/Pulse-width_modulation">PWM</a>) is a way to “fake” analog output from a digital source. If you can only output 5 volts, but you want 3 volts output, how can you do that? Well if you’re at 5 volts 3/5 of the time, then there you go. That’s (roughly) PWM.</p>

<p>The two variables you need to know are the duty cycle and the period (or its reciprocal, frequency). The duty cycle is what percentage of time you’re “on” - so our example above would be 3/5 = 60% duty cycle. The period is how long a duty cycle takes to complete - this would generally be too small for us to see.</p>

<p>Here’s a nice handy picture ripped straight from the Wikipedia article I linked above:</p>

<p><img src="/assets/img/posts/arduino-demystified/duty_cycle.png" alt="Duty cycle" title="Duty cycle diagram" />
<em><a href="https://en.wikipedia.org/wiki/Pulse-width_modulation">source</a></em></p>

<h3 id="pwm-in-action">PWM in action</h3>

<p>Normally I’d use Arduino’s example, but the example for <code>analogWrite</code> is a bit more complex than I really care for. I just want to show you a dim LED. Here’s the code to make a dim LED:</p>

<blockquote class="filename">
  <p>SimpleAnalogWrite</p>
</blockquote>
<div class="language-cpp highlighter-tree-sitter"><pre><code><span class='ts-type'>void</span> <span class='ts-function'>setup</span>() {
  <span class='ts-comment'>// Pin 3 is the first PWM pin on Uno</span>
  <span class='ts-function'>pinMode</span>(<span class='ts-number'>3</span>, <span class='ts-constant'>OUTPUT</span>)<span class='ts-delimiter'>;</span>
}

<span class='ts-type'>void</span> <span class='ts-function'>loop</span>() {
  <span class='ts-function'>analogWrite</span>(<span class='ts-number'>3</span>, <span class='ts-number'>50</span>)<span class='ts-delimiter'>;</span>
}
</code></pre></div>

<p>It’s pretty simple! The <code>analogWrite</code> function takes the pin (3) and the duty cycle, expressed as a number from 0-255. So 50 would be a 50/255 = 19.6% duty cycle.</p>

<p>Here’s a comparison between using 50 (left) and 200 (right) for the value:</p>

<p><img src="/assets/img/posts/arduino-demystified/compare-leds.png" alt="Duty cycle comparison" title="Left: 50/255 Right: 200/255" /></p>

<p>Well it’s not a super drastic difference, but that’s expected considering we see increases in brightness logarithmically. Doubling the brightness will seem like a constant increase. Obviously, I’m not an eye scientist, though.</p>

<p>If you want a clearer example of the difference, here’s a 5/255 = 1.9% duty cycle:</p>

<p><img src="/assets/img/posts/arduino-demystified/duty-cycle-5.jpg" alt="A dim LED" title="Well that's dim" /></p>

<p>Obviously, a fair bit dimmer.</p>

<p>As a side note, I got this LED for free, but apparently it was something like $20 USD. That’s really strange to me.</p>

<p>Okay, now we’ve seen PWM in action! Now let’s get into the low-level stuff, as is my want.</p>

<h3 id="our-pwm-interface-more-registers">Our PWM interface: more registers!</h3>

<p>Now, Arduino <a href="https://www.arduino.cc/reference/en/language/functions/analog-io/analogwrite/">defines the PWM frequency</a> for you. Each pin may be different. For example, pin 3 will be 490 Hz while pin 5 will be 980 Hz. That means 490 or 980 cycles of the (puny) 16 MHz frequency.</p>

<p>It gets a little funky here. There’s a really good reference in the <a href="https://docs.arduino.cc/tutorials/generic/secrets-of-arduino-pwm/">Arduino docs</a> for timers and how that affects PWM on the Arduino. I, however, won’t go into all of it. I’ll try to keep it as simple as possible - feel free to check that out if you want a detailed explanation.</p>

<p>PWM on Arduino is attached to various timers in the CPU. There are three such timers. For the following register names, replace ‘x’ with a timer number (0, 1, 2):</p>

<p>1) <em>TCCRxA</em> - The control register, where you set/clear bits in order to enable/disable certain modes and whatnot</p>

<p>2) <em>TCCRxB</em> - Basically the same thing as above but with more options</p>

<p>3) <em>TCNTx</em> - The actual timer value of timer X</p>

<p>4) <em>OCRxA/OCRxB</em> - Output compare register. This gets continuously compared with TCNTx in order to trigger events like interrupts</p>

<p>5) <em>TIMSKx</em> - Interrupt mask register, primarily used to enable interrupts for PWM</p>

<p>6) <em>TIFR0</em> - More data on the timer! Like overflows and matches</p>

<p>We care about TCCRxA and TCCRxB when enabling/disabling PWM. OCRxA and OCRxB will be used to set the duty cycle. The rest just have one time setup or other uses that we won’t look into.</p>

<p>Okay, with all of that background, we can understand the <code>analogWrite</code> function!</p>

<h3 id="arduinos-analogwrite">Arduino’s <code>analogWrite</code></h3>

<p>I won’t go into every line in detail since there’s a lot of repetition for other chips and whatnot. The beginning of the function is pretty easy to understand from the rest of what we’ve looked at:</p>

<blockquote class="filename">
  <p>wiring_analog.c</p>
</blockquote>
<div class="language-c highlighter-tree-sitter"><pre><code><span class='ts-comment'>// Right now, PWM output only works on the pins with</span>
<span class='ts-comment'>// hardware support.  These are defined in the appropriate</span>
<span class='ts-comment'>// pins_*.c file.  For the rest of the pins, we default</span>
<span class='ts-comment'>// to digital output.</span>
<span class='ts-type'>void</span> <span class='ts-function'>analogWrite</span>(<span class='ts-type'>uint8_t</span> <span class='ts-variable'>pin</span>, <span class='ts-type'>int</span> <span class='ts-variable'>val</span>)
{
	<span class='ts-comment'>// We need to make sure the PWM output is enabled for those pins</span>
	<span class='ts-comment'>// that support it, as we turn it off when digitally reading or</span>
	<span class='ts-comment'>// writing with them.  Also, make sure the pin is in output mode</span>
	<span class='ts-comment'>// for consistenty with Wiring, which doesn&#39;t require a pinMode</span>
	<span class='ts-comment'>// call for the analog output pins.</span>
	<span class='ts-function'>pinMode</span>(<span class='ts-variable'>pin</span>, <span class='ts-constant'>OUTPUT</span>)<span class='ts-delimiter'>;</span>
	<span class='ts-keyword'>if</span> (<span class='ts-variable'>val</span> <span class='ts-operator'>==</span> <span class='ts-number'>0</span>)
	{
		<span class='ts-function'>digitalWrite</span>(<span class='ts-variable'>pin</span>, <span class='ts-constant'>LOW</span>)<span class='ts-delimiter'>;</span>
	}
	<span class='ts-keyword'>else</span> <span class='ts-keyword'>if</span> (<span class='ts-variable'>val</span> <span class='ts-operator'>==</span> <span class='ts-number'>255</span>)
	{
		<span class='ts-function'>digitalWrite</span>(<span class='ts-variable'>pin</span>, <span class='ts-constant'>HIGH</span>)<span class='ts-delimiter'>;</span>
	}
	<span class='ts-keyword'>else</span>
	{
</code></pre></div>

<p>Basically, values of 0 and 255 are just aliased to <code>digitalWrite</code> calls, but you don’t need to call <code>pinMode</code> first.</p>

<p>The rest of this function is a big switch statement. For this, I’ll just omit a lot - that will be marked with <code>// ...</code> to signify it is skipped.</p>

<blockquote class="filename">
  <p>wiring_analog.c</p>
</blockquote>
<div class="language-c highlighter-tree-sitter"><pre><code><span class='ts-keyword'>switch</span>(<span class='ts-function'>digitalPinToTimer</span>(<span class='ts-variable'>pin</span>))
{
    <span class='ts-comment'>// ...</span>

	<span class='ts-keyword'>#if</span> defined(<span class='ts-constant'>TCCR0A</span>) <span class='ts-operator'>&amp;&amp;</span> defined(<span class='ts-constant'>COM0A1</span>)
	<span class='ts-keyword'>case</span> <span class='ts-constant'>TIMER0A</span>:
		<span class='ts-comment'>// connect pwm to pin on timer 0, channel A</span>
		<span class='ts-function'>sbi</span>(<span class='ts-constant'>TCCR0A</span>, <span class='ts-constant'>COM0A1</span>)<span class='ts-delimiter'>;</span>
		<span class='ts-constant'>OCR0A</span> <span class='ts-operator'>=</span> <span class='ts-variable'>val</span><span class='ts-delimiter'>;</span> <span class='ts-comment'>// set pwm duty</span>
		<span class='ts-keyword'>break</span><span class='ts-delimiter'>;</span>
	<span class='ts-keyword'>#endif</span>

    <span class='ts-comment'>// ...</span>

	<span class='ts-keyword'>case</span> <span class='ts-constant'>NOT_ON_TIMER</span>:
	<span class='ts-keyword'>default</span>:
		<span class='ts-keyword'>if</span> (<span class='ts-variable'>val</span> <span class='ts-operator'>&lt;</span> <span class='ts-number'>128</span>) {
			<span class='ts-function'>digitalWrite</span>(<span class='ts-variable'>pin</span>, <span class='ts-constant'>LOW</span>)<span class='ts-delimiter'>;</span>
		} <span class='ts-keyword'>else</span> {
			<span class='ts-function'>digitalWrite</span>(<span class='ts-variable'>pin</span>, <span class='ts-constant'>HIGH</span>)<span class='ts-delimiter'>;</span>
		}
}
</code></pre></div>

<p>So we have a big switch on the timer (from <code>digitalPinToTimer(pin)</code>) where we set some <code>COM</code> bit in the <code>TCCRx</code> register. All that does is enable the <code>OCRx</code> comparison at the hardware level. Then, we set the <code>OCRxA</code> register to the duty cycle provided (which is just a value from 1 to 254, since we filtered out the extremes before).</p>

<p>A small note is the default in the switch just sets it to low if below 128 and high otherwise. This may happen if we try calling this on a pin without PWM. Kind of weird in my opinion, but what else would you do?</p>

<h4 id="aside-where-is-digitalpintotimer">Aside: Where is <code>digitalPinToTimer</code>?</h4>

<p>We’ve seen a couple of “functions” like this from <code>Arduino.h</code>, like <code>digitalPinToPort</code>, for example. But I haven’t explained where those come from. So here we go.</p>

<p>We can find the function-like macro <code>digitalPinToTimer</code> in <code>Arduino.h</code>:</p>

<blockquote class="filename">
  <p>Arduino.h</p>
</blockquote>
<div class="language-c highlighter-tree-sitter"><pre><code><span class='ts-keyword'>#define</span> <span class='ts-function-special'>digitalPinToTimer</span>(<span class='ts-constant'>P</span>) ( pgm_read_byte( digital_pin_to_timer_PGM + (P) ) )
</code></pre></div>

<p>It gets the value from <code>digital_pin_to_timer_PGM</code>, whose declaration is just above that:</p>

<blockquote class="filename">
  <p>Arduino.h</p>
</blockquote>
<div class="language-c highlighter-tree-sitter"><pre><code><span class='ts-keyword'>extern</span> <span class='ts-keyword'>const</span> <span class='ts-type'>uint8_t</span> <span class='ts-constant'>PROGMEM</span> <span class='ts-variable'>digital_pin_to_timer_PGM</span>[]<span class='ts-delimiter'>;</span>
</code></pre></div>

<p>Well, it’s extern, so we don’t have it here. Where does that live? It’s actually in the same repo - just in the <code>variants</code> directory. Each variant has a <code>pins_arduino.h</code> file. In the <code>standard</code> variant, we can find this:</p>

<blockquote class="filename">
  <p>variants/standard/pins_arduino.h</p>
</blockquote>
<div class="language-c highlighter-tree-sitter"><pre><code><span class='ts-keyword'>const</span> <span class='ts-type'>uint8_t</span> <span class='ts-constant'>PROGMEM</span> <span class='ts-variable'>digital_pin_to_timer_PGM</span>[] <span class='ts-operator'>=</span> {
	<span class='ts-constant'>NOT_ON_TIMER</span>, <span class='ts-comment'>/* 0 - port D */</span>
	<span class='ts-constant'>NOT_ON_TIMER</span>,
	<span class='ts-constant'>NOT_ON_TIMER</span>,
	<span class='ts-comment'>// on the ATmega168, digital pin 3 has hardware pwm</span>
<span class='ts-keyword'>#if</span> defined(<span class='ts-variable'>__AVR_ATmega8__</span>)
	<span class='ts-constant'>NOT_ON_TIMER</span>,
<span class='ts-keyword'>#else</span>
	<span class='ts-constant'>TIMER2B</span>,
<span class='ts-keyword'>#endif</span>
	<span class='ts-constant'>NOT_ON_TIMER</span>,
	<span class='ts-comment'>// on the ATmega168, digital pins 5 and 6 have hardware pwm</span>
<span class='ts-keyword'>#if</span> defined(<span class='ts-variable'>__AVR_ATmega8__</span>)
	<span class='ts-constant'>NOT_ON_TIMER</span>,
	<span class='ts-constant'>NOT_ON_TIMER</span>,
<span class='ts-keyword'>#else</span>
	<span class='ts-constant'>TIMER0B</span>,
	<span class='ts-constant'>TIMER0A</span>,
<span class='ts-keyword'>#endif</span>
	<span class='ts-constant'>NOT_ON_TIMER</span>,
	<span class='ts-constant'>NOT_ON_TIMER</span>, <span class='ts-comment'>/* 8 - port B */</span>
	<span class='ts-constant'>TIMER1A</span>,
	<span class='ts-constant'>TIMER1B</span>,
<span class='ts-keyword'>#if</span> defined(<span class='ts-variable'>__AVR_ATmega8__</span>)
	<span class='ts-constant'>TIMER2</span>,
<span class='ts-keyword'>#else</span>
	<span class='ts-constant'>TIMER2A</span>,
<span class='ts-keyword'>#endif</span>
	<span class='ts-constant'>NOT_ON_TIMER</span>,
	<span class='ts-constant'>NOT_ON_TIMER</span>,
	<span class='ts-constant'>NOT_ON_TIMER</span>,
	<span class='ts-constant'>NOT_ON_TIMER</span>, <span class='ts-comment'>/* 14 - port C */</span>
	<span class='ts-constant'>NOT_ON_TIMER</span>,
	<span class='ts-constant'>NOT_ON_TIMER</span>,
	<span class='ts-constant'>NOT_ON_TIMER</span>,
	<span class='ts-constant'>NOT_ON_TIMER</span>,
}<span class='ts-delimiter'>;</span>
</code></pre></div>

<p>Just as a sanity check, let’s make sure pin 3 makes sense. It has a tilde next to it on my Arduino, so it should have a timer associated with it. We can look at the 4th element of the array (pins start from 0) to see that it is associated with the timer <code>TIMER2B</code> (if it’s not <code>__AVR_ATmega8__</code>). Then, we can go in the <code>analogWrite</code> function and look for <code>TIMER2B</code>:</p>

<blockquote class="filename">
  <p>wiring_analog.c</p>
</blockquote>
<div class="language-c highlighter-tree-sitter"><pre><code><span class='ts-keyword'>case</span> <span class='ts-constant'>TIMER2B</span>:
	<span class='ts-comment'>// connect pwm to pin on timer 2, channel B</span>
	<span class='ts-function'>sbi</span>(<span class='ts-constant'>TCCR2A</span>, <span class='ts-constant'>COM2B1</span>)<span class='ts-delimiter'>;</span>
	<span class='ts-constant'>OCR2B</span> <span class='ts-operator'>=</span> <span class='ts-variable'>val</span><span class='ts-delimiter'>;</span> <span class='ts-comment'>// set pwm duty</span>
	<span class='ts-keyword'>break</span><span class='ts-delimiter'>;</span>
</code></pre></div>

<p>So we use <code>OCR2B</code> for that. According to the <a href="https://docs.arduino.cc/tutorials/generic/secrets-of-arduino-pwm/">PWM reference</a> I linked before, in a table near the bottom, it shows pin 3 is associated with <code>OC2B</code>. Not sure why the <code>R</code> was omitted in the register names for this table, but it lines up with what is set in <code>analogWrite</code>. ¯\_(ツ)_/¯</p>

<h3 id="different-pin-frequencies">Different pin frequencies</h3>

<p>I mentioned before that different pins have different pin frequencies. Why?</p>

<p>Well, the first hint is in the <code>digital_pin_to_timer_PGM</code> array I copied in before. Pins 5 and 6 are the ones with different frequencies, and it turns out, they’re both on timer <code>TIMER0</code>. What’s the significance?</p>

<p>Well, you can prescale them! Here’s what that means, from the datasheet:</p>

<blockquote>
  <p>The Atmel ATmega328P has a system clock prescaler, and the system clock can be divided by setting the Section 8.12.2 “CLKPR – Clock Prescale Register” on page 33. This feature can be used to decrease the system clock frequency and the power consumption when the requirement for processing power is low.</p>
</blockquote>

<p>So you can change the prescaler and decrease clock frequency. Turns out, we’ve already seen the register associated with the prescaler for a given timer - <code>TCCRxB</code>. This contains three bits for the prescaler, dubbed <code>CS00</code>, <code>CS01</code>, and <code>CS02</code>. These will set the prescaler value according to this table (table 14-9 in the datasheet):</p>

<table>
  <thead>
    <tr>
      <th>CS02</th>
      <th>CS01</th>
      <th>CS00</th>
      <th>Description</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>0</td>
      <td>0</td>
      <td>0</td>
      <td>No clock source (Timer/Counter stopped)</td>
    </tr>
    <tr>
      <td>0</td>
      <td>0</td>
      <td>1</td>
      <td>clk_I/O / (no prescaling)</td>
    </tr>
    <tr>
      <td>0</td>
      <td>1</td>
      <td>0</td>
      <td>clk_I/O / 8 (from prescaler)</td>
    </tr>
    <tr>
      <td>0</td>
      <td>1</td>
      <td>1</td>
      <td>clk_I/O / 64 (from prescaler)</td>
    </tr>
    <tr>
      <td>1</td>
      <td>0</td>
      <td>0</td>
      <td>clk_I/O / 256 (from prescaler)</td>
    </tr>
    <tr>
      <td>1</td>
      <td>0</td>
      <td>1</td>
      <td>clk_I/O / 1024 (from prescaler)</td>
    </tr>
    <tr>
      <td>1</td>
      <td>1</td>
      <td>0</td>
      <td>External clock source on T0 pin. Clock on falling edge</td>
    </tr>
    <tr>
      <td>1</td>
      <td>1</td>
      <td>1</td>
      <td>External clock source on T0 pin. Clock on falling edge</td>
    </tr>
  </tbody>
</table>

<p>Okay, so we now have a table of different bits to set in order to get different prescaler values. Why did we do this again?</p>

<p>So then we can go into the Arduino main setup code (aka the function <code>init</code>) and see if they set any of these bits, and…</p>

<blockquote class="filename">
  <p>wiring.c</p>
</blockquote>
<div class="language-c highlighter-tree-sitter"><pre><code><span class='ts-type'>void</span> <span class='ts-function'>init</span>()
{ <span class='ts-comment'>// ...</span>
<span class='ts-keyword'>#elif</span> defined(TCCR0B) &amp;&amp; defined(CS01) &amp;&amp; defined(CS00)
	<span class='ts-comment'>// this combination is for the standard 168/328/1280/2560</span>
	<span class='ts-function'>sbi</span>(<span class='ts-constant'>TCCR0B</span>, <span class='ts-constant'>CS01</span>)<span class='ts-delimiter'>;</span>
	<span class='ts-function'>sbi</span>(<span class='ts-constant'>TCCR0B</span>, <span class='ts-constant'>CS00</span>)<span class='ts-delimiter'>;</span>
</code></pre></div>

<p>We set <code>CS01</code> and <code>CS00</code> for timer 0 - that’s associated with the prescaler that divides by 64, so we tick up the timer once for every 64 cycles of the clock. Given what we know, we can now get the values for the PWM frequency on pins 5 and 6: we have a 16 MHz (16,000,000 cycles per second) clock, then divide by 64 for the prescaler to get 250,000. Then, we have 256 values within the duty cycle, so divide 250,000 by that to get… 976.5625 Hz! Eh it’s close enough to 980 (seen before), pretty sure I’m right. We love math.</p>

<p>So that means the other timers would need a prescaler of half of 64, so 32, in order to get to 480 Hz for those. And… well, that’s impossible, as we see from the table above. There’s nothing between 8 and 64. Huh?</p>

<h3 id="the-other-timers-special-trick-phase-correct-pwm">The other timers’ special trick (phase correct PWM)</h3>

<p>Well the other timers also set their prescaler to clk/64, like:</p>

<blockquote class="filename">
  <p>wiring.c</p>
</blockquote>
<div class="language-c highlighter-tree-sitter"><pre><code><span class='ts-type'>void</span> <span class='ts-function'>init</span>()
{ <span class='ts-comment'>// ...</span>
	<span class='ts-comment'>// set timer 1 prescale factor to 64</span>
	<span class='ts-function'>sbi</span>(<span class='ts-constant'>TCCR1B</span>, <span class='ts-constant'>CS11</span>)<span class='ts-delimiter'>;</span>
<span class='ts-keyword'>#if</span> <span class='ts-constant'>F_CPU</span> &gt;= <span class='ts-number'>8000000L</span>
	<span class='ts-function'>sbi</span>(<span class='ts-constant'>TCCR1B</span>, <span class='ts-constant'>CS10</span>)<span class='ts-delimiter'>;</span>
<span class='ts-keyword'>#endif</span>
</code></pre></div>

<p>Well, there is one other hint in some comments…</p>

<blockquote class="filename">
  <p>wiring.c</p>
</blockquote>
<div class="language-c highlighter-tree-sitter"><pre><code><span class='ts-comment'>// timers 1 and 2 are used for phase-correct hardware pwm</span>
<span class='ts-comment'>// this is better for motors as it ensures an even waveform</span>
<span class='ts-comment'>// note, however, that fast pwm mode can achieve a frequency of up</span>
<span class='ts-comment'>// 8 MHz (with a 16 MHz clock) at 50% duty cycle</span>
</code></pre></div>

<p>From the datasheet, phase correct hardware PWM is set with “WGM02:0 = 1 or 5” (which just means those bits are 1 or 5, so <code>0b001</code> or <code>0b101</code>). Sure enough, in the same code, we see a bit get set:</p>

<blockquote class="filename">
  <p>wiring.c</p>
</blockquote>
<div class="language-c highlighter-tree-sitter"><pre><code><span class='ts-function'>sbi</span>(<span class='ts-constant'>TCCR1A</span>, <span class='ts-constant'>WGM10</span>)<span class='ts-delimiter'>;</span>
</code></pre></div>

<p>Which is the <code>WGM</code> bit associated with <code>0b001</code> on timer 1, which means it’s set to phase correct PWM. Awesome, but what does that mean?</p>

<blockquote>
  <p>The phase correct PWM mode is based on a dual-slope operation. The counter counts repeatedly from BOTTOM to TOP and then from TOP to BOTTOM. TOP is defined as 0xFF when WGM2:0 = 1, and OCR0A when WGM2:0 = 5. In non-inverting compare output mode, the output compare (OC0x) is cleared on the compare match between TCNT0 and OCR0x while upcounting, and set on the compare match while downcounting.</p>
</blockquote>

<p>So it just goes up and down the counter, rather than going up and resetting. That means it actually goes through 255 * 2 cycles before we trigger the interrupt, which gets us an extra divided by 2 to the 980 Hz. Finally, we get our 490 Hz (or 490.196… I guess). We have successfully calculated things!</p>

<p>Wait, there’s a 255 in there, and it was 256 earlier! Well since we’re counting up and down, we’re skipping at least one when we hit the top value - we don’t “tick” on it twice. Then same for the bottom, once we hit 0, we go right back up to 1. So, that takes out 2 cycles for each timer cycle, hence 255/2 instead of 256/2. Depending on your application, that may REALLY matter. I think if it really matters, though, you wouldn’t be using an Arduino.</p>

<p>I could go on and on about PWM. There’s so much more. But, I’ll hold off. Hopefully I gave you enough to learn more if you’re so inclined.</p>

<h2 id="so-what">So what?</h2>

<p>With all of this information, we have a pretty good understanding of Arduino, its registers, and how all of it fits together. Really, with any microcontroller, it almost all boils down to blink, but with extra steps. You may need to dive into hardware stuff, but that’s almost never necessary, especially if you’re using an Arduino. At least for us hobbyist folks.</p>

<p>I wanted to get into a <em>lot</em> more here - the <code>delay</code> function, the bootloader… there’s a lot that is hidden behind the magic of the Arduino that I find fascinating. But, that will (maybe) be another time. Writing this took way too long. The post is probably so long no one will actually get this far. Oh well.</p>

<p>This was all inspired from working on <a href="https://github.com/evantypanski/arduzig">arduzig</a> a while ago, which is an attempt to bring Arduino code to Zig. It turned out to be a frustrating project the second I got an update from the two dependencies used: one being Zig itself, because it’s changing so fast, and the other being a great project called <a href="https://github.com/ZigEmbeddedGroup/microzig">MicroZig</a>. Maybe one day I’ll return, when Zig and MicroZig are both more stable.</p>

<p>For what it’s worth, if MicroZig seems interesting, I very much recommend trying it: Zig seems like a great language for embedded development once it’s more stable.</p>

<p>Now go do silly stuff with your Arduino with your new found knowledge, it’s fun.</p>]]></content><author><name>Evan Typanski</name></author><summary type="html"><![CDATA[Arduinos! Everyone’s favorite toy for random electronics projects. But honestly, it really doesn’t feel like you learn a lot about the hardware. Most of the time you grab a library and it does magical stuff for you, all you do is plug stuff together and use other libraries.]]></summary></entry><entry><title type="html">The Anatomy of an Error Message</title><link href="https://etyp.dev/posts/errors-pls/" rel="alternate" type="text/html" title="The Anatomy of an Error Message" /><published>2024-02-06T00:00:00-05:00</published><updated>2024-02-06T00:00:00-05:00</updated><id>https://etyp.dev/posts/error-messages-pls</id><content type="html" xml:base="https://etyp.dev/posts/errors-pls/"><![CDATA[<p>Programming languages are fun to design and think about. The error messages aren’t as much. But let’s look at some anyway. Don’t worry, we’ll look at compiler source code too :)</p>

<h2 id="clang">Clang</h2>

<p>First, let’s say we just programmed a lot of Rust and forgot that C++ requires parentheses around the <code>if</code> condition:</p>

<blockquote class="filename">
  <p>test.cpp</p>
</blockquote>
<div class="language-cpp highlighter-tree-sitter"><pre><code><span class='ts-type'>int</span> <span class='ts-function'>main</span>() {
  <span class='ts-keyword'>if</span> <span class='ts-variable'>true</span> {
    <span class='ts-type'>int</span> <span class='ts-variable'>i</span> <span class='ts-operator'>=</span> <span class='ts-number'>0</span><span class='ts-delimiter'>;</span>
  }
}
</code></pre></div>

<p>Clang reacts:</p>

<blockquote class="shell">

</blockquote>
<div class="language-bash highlighter-tree-sitter"><pre><code><span class='ts-property'>etyp</span><span class='ts-function'>:errors-pl/</span> <span class='ts-operator'>$</span> clang++ test.cpp
<span class='ts-function'>test.cpp:2:6:</span> error: expected <span class='ts-string'>&#39;(&#39;</span> after <span class='ts-string'>&#39;if&#39;</span>
  <span class='ts-keyword'>if</span> <span class='ts-function'>true</span> {
     <span class='ts-function'>^</span>
<span class='ts-function'>1</span> error generated.
</code></pre></div>

<p>This is the quintessential compiler error. It doesn’t necessarily tell you how to fix it unless you’ve been programming for a bit and understand this jargon. Why did you expect a <code>(</code>? What happens after that? What goes in there?</p>

<p>A lot of compilers do this just because it’s how compilers work. Let’s look at Clang’s code to see why.</p>

<p>This error is from parsing. That means it’s still checking the structure of the source code before figuring out what it means.</p>

<p>In C++, there are a few ways to write the first part of an <code>if</code> statement. We’ll ignore the C++23 <code>consteval</code> if statements. That means the initial part can be written like:</p>

<blockquote class="filename">

</blockquote>
<div class="language-cpp highlighter-tree-sitter"><pre><code><span class='ts-keyword'>if</span> (<span class='ts-variable'>condition</span>)<span class='ts-delimiter'></span>
</code></pre></div>

<p>Or:</p>

<blockquote class="filename">

</blockquote>
<div class="language-cpp highlighter-tree-sitter"><pre><code><span class='ts-keyword'>if</span> <span class='ts-keyword'>constexpr</span> (<span class='ts-variable'>condition</span>)<span class='ts-delimiter'></span>
</code></pre></div>

<p>Now, we won’t go into what <code>constexpr</code> means here, but the important part is we have two choices: either we see a <code>constexpr</code> or not. In Clang’s source, we can find the check for <code>constexpr</code> in the function that parses <code>if</code> statements (suitably named <code>ParseIfStatement</code>):</p>

<blockquote class="filename">
  <p>ParseStmt.cpp</p>
</blockquote>
<div class="language-cpp highlighter-tree-sitter"><pre><code><span class='ts-keyword'>if</span> (<span class='ts-variable'>Tok</span><span class='ts-delimiter'>.</span><span class='ts-function'>is</span>(tok::<span class='ts-variable'>kw_constexpr</span>)) {
  <span class='ts-function'>Diag</span>(<span class='ts-variable'>Tok</span>, <span class='ts-function'>getLangOpts</span>()<span class='ts-delimiter'>.</span><span class='ts-property'>CPlusPlus17</span> ? diag::<span class='ts-variable'>warn_cxx14_compat_constexpr_if</span>
                                      : diag::<span class='ts-variable'>ext_constexpr_if</span>)<span class='ts-delimiter'>;</span>
  <span class='ts-variable'>IsConstexpr</span> <span class='ts-operator'>=</span> true<span class='ts-delimiter'>;</span>
  <span class='ts-function'>ConsumeToken</span>()<span class='ts-delimiter'>;</span>
}
</code></pre></div>

<p>At this point, we should always see a <code>(</code> (also known as left parentheses or lparen). So we check for that. Here’s that check:</p>

<blockquote class="filename">
  <p>ParseStmt.cpp</p>
</blockquote>
<div class="language-cpp highlighter-tree-sitter"><pre><code><span class='ts-keyword'>if</span> (!<span class='ts-variable'>IsConsteval</span> <span class='ts-operator'>&amp;&amp;</span> (<span class='ts-variable'>NotLocation</span><span class='ts-delimiter'>.</span><span class='ts-function'>isValid</span>() <span class='ts-operator'>||</span> <span class='ts-variable'>Tok</span><span class='ts-delimiter'>.</span><span class='ts-function'>isNot</span>(tok::<span class='ts-variable'>l_paren</span>))) {
  <span class='ts-function'>Diag</span>(<span class='ts-variable'>Tok</span>, diag::<span class='ts-variable'>err_expected_lparen_after</span>) &lt;&lt; <span class='ts-string'>&quot;if&quot;</span><span class='ts-delimiter'>;</span>
  <span class='ts-function'>SkipUntil</span>(tok::<span class='ts-variable'>semi</span>)<span class='ts-delimiter'>;</span>
  <span class='ts-keyword'>return</span> <span class='ts-function'>StmtError</span>()<span class='ts-delimiter'>;</span>
}
</code></pre></div>

<p>Ok we ignored the <code>consteval</code> stuff so the only important part of that condition is <code>Tok.isNot(tok::l_paren)</code>. If our next token is not an lparen, then we throw an error. All of these errors are in a file called <code>DiagnosticParseKinds.td</code>, which generates C++ code for these. If we search for that error we find:</p>

<blockquote class="filename">
  <p>DiagnosticParseKinds.td</p>
</blockquote>
<pre><code>def err_expected_lparen_after : Error&lt;"expected '(' after '%0'"&gt;;
</code></pre>

<p>Easy enough. That’s the error we saw.</p>

<h3 id="source-snippets">Source snippets</h3>

<p>The error message we saw contains a snippet of the code. How did we get that? Well, in Clang we can look back at the <code>Diag</code> call and see some arguments:</p>

<blockquote class="filename">
  <p>ParseStmt.cpp</p>
</blockquote>
<div class="language-cpp highlighter-tree-sitter"><pre><code><span class='ts-function'>Diag</span>(<span class='ts-variable'>Tok</span>, diag::<span class='ts-variable'>err_expected_lparen_after</span>) &lt;&lt; <span class='ts-string'>&quot;if&quot;</span><span class='ts-delimiter'>;</span>
</code></pre></div>

<p>The <code>Tok</code> argument gets passed in! In the parser we have a function:</p>

<blockquote class="filename">
  <p>Parser.cpp</p>
</blockquote>
<div class="language-cpp highlighter-tree-sitter"><pre><code><span class='ts-type'>DiagnosticBuilder</span> <span class='ts-type'>Parser</span>::<span class='ts-function'>Diag</span>(<span class='ts-keyword'>const</span> <span class='ts-type'>Token</span> <span class='ts-operator'>&amp;</span><span class='ts-variable'>Tok</span>, <span class='ts-type'>unsigned</span> <span class='ts-variable'>DiagID</span>) {
  <span class='ts-keyword'>return</span> <span class='ts-function'>Diag</span>(<span class='ts-variable'>Tok</span><span class='ts-delimiter'>.</span><span class='ts-function'>getLocation</span>(), <span class='ts-variable'>DiagID</span>)<span class='ts-delimiter'>;</span>
}
</code></pre></div>

<p>… which takes in a token. Exactly what we wanted. That ends up calling an overloaded variant where it just takes the <code>getLocation</code>, which returns a <a href="https://clang.llvm.org/doxygen/classclang_1_1SourceLocation.html"><code>SourceLocation</code></a>:</p>

<blockquote class="filename">
  <p>Parser.cpp</p>
</blockquote>
<div class="language-cpp highlighter-tree-sitter"><pre><code><span class='ts-type'>DiagnosticBuilder</span> <span class='ts-type'>Parser</span>::<span class='ts-function'>Diag</span>(<span class='ts-type'>SourceLocation</span> <span class='ts-variable'>Loc</span>, <span class='ts-type'>unsigned</span> <span class='ts-variable'>DiagID</span>) {
  <span class='ts-keyword'>return</span> <span class='ts-variable'>Diags</span><span class='ts-delimiter'>.</span><span class='ts-function'>Report</span>(<span class='ts-variable'>Loc</span>, <span class='ts-variable'>DiagID</span>)<span class='ts-delimiter'>;</span>
}
</code></pre></div>

<p>I don’t really want to get into that <code>Report</code> function since it’s pretty straightforward: We find the location and we print a format string that points to that location. But those source locations are a bit interesting.</p>

<p>Here’s Clang’s description of a source location:</p>

<blockquote>
  <p>The SourceManager can decode this to get at the full include stack, line and column information.
Technically, a source location is simply an offset into the manager’s view of the input source, which is all input buffers (including macro expansions) concatenated in an effectively arbitrary order. The manager actually maintains two blocks of input buffers. One, starting at offset 0 and growing upwards, contains all buffers from this module. The other, starting at the highest possible offset and growing downwards, contains buffers of loaded modules.</p>
</blockquote>

<p>Ok, so it’s just an offset? It turns out, we can look at the class and see one singular field:</p>

<blockquote class="filename">
  <p>Parser.h</p>
</blockquote>
<div class="language-cpp highlighter-tree-sitter"><pre><code><span class='ts-type'>UIntTy</span> <span class='ts-constant'>ID</span> <span class='ts-operator'>=</span> <span class='ts-number'>0</span><span class='ts-delimiter'>;</span>
</code></pre></div>

<p>Yep, so we can get all of that info from one 32 bit field. This includes macro expansion shenanigans!</p>

<p>We won’t get into macro shenanigans; don’t worry. If you’re not convinced it’s hard, what if our snippet was this:</p>

<blockquote class="filename">
  <p>test.cpp</p>
</blockquote>
<div class="language-cpp highlighter-tree-sitter"><pre><code><span class='ts-keyword'># define</span> <span class='ts-constant'>MY_IF</span> if true

<span class='ts-type'>int</span> <span class='ts-function'>main</span>() {
  <span class='ts-type'>MY_IF</span> {
    <span class='ts-type'>int</span> <span class='ts-variable'>i</span> <span class='ts-operator'>=</span> <span class='ts-number'>0</span><span class='ts-delimiter'>;</span>
  }
}<span class='ts-delimiter'></span>
</code></pre></div>

<p>Where do we show the error, where the macro is in source, or in the macro? This isn’t obvious since the error is actually inside the replacement from the macro. Well, it’s both:</p>

<blockquote class="shell">

</blockquote>
<div class="language-bash highlighter-tree-sitter"><pre><code><span class='ts-property'>etyp</span><span class='ts-function'>:errors-pl/</span> <span class='ts-operator'>$</span> ~/src/llvm-project/build-debug/bin/clang++ test.cpp
<span class='ts-function'>test.cpp:4:3:</span> error: expected <span class='ts-string'>&#39;(&#39;</span> after <span class='ts-string'>&#39;if&#39;</span>
    <span class='ts-function'>4</span> <span class='ts-operator'>|</span>   <span class='ts-function'>MY_IF</span> {
<span class='ts-function'></span>      <span class='ts-operator'>|</span>   <span class='ts-function'>^</span>
<span class='ts-function'>test.cpp:1:19:</span> note: expanded from macro <span class='ts-string'>&#39;MY_IF&#39;</span>
    <span class='ts-function'>1</span> <span class='ts-operator'>|</span> <span class='ts-comment'># define MY_IF if true</span>
      <span class='ts-operator'>|</span>                   <span class='ts-function'>^</span>
<span class='ts-function'>1</span> error generated.
</code></pre></div>

<p>So… we need a way to unwrap this macro in order to actually give the user useful information. We’ll just take a quick glance at code without dealing with the macro parts. This becomes a LOT when we have large nested macros.</p>

<p>Given a source location, then, what actually turns that offset into a snippet of source code to display? Well that’s the <a href="https://clang.llvm.org/doxygen/classclang_1_1SourceManager.html"><code>SourceManager</code></a>, of course!</p>

<p>So, there’s actually a lot that goes into this. C++ is unlike a lot of programming languages, where it has these <code>#include</code> directives which just put another file into your file in its entirety (minus some preprocessor stuff or language extensions). We need to keep track of files and macros and it’s all a pain. Because there’s all that extra complexity, I’ll just describe the implementation with pretty few source snippets.</p>

<p>First, we need the line number. That’s important for telling you where the error is, right? Well, say we have a 100 character file and it’s in an array, like <code>char MyFile[100]</code>. We want to find the line number for offset <code>42</code>. How can we do this?</p>

<p>The brute force method would be just go through <code>0</code> to <code>42</code> and count the number of newline characters. Easy enough, but that’s not really efficient. Clang doesn’t do this.</p>

<p>Instead Clang has a cache! We have a cache for the content in the file called <a href="https://clang.llvm.org/doxygen/classclang_1_1SrcMgr_1_1ContentCache.html"><code>ContentCache</code></a>. That has its own cache, suitably named <code>SourceLineCache</code>. The description in the documentation is:</p>

<blockquote>
  <p>A bump pointer allocated array of offsets for each source line.</p>
</blockquote>

<p>Okay let’s not get into all of that, but we store what positions hold newlines and we search for where our position falls in that. Then we get the line number.</p>

<p>Column number is actually pretty easy if we have the line number! Minus a bunch of caching stuff, here’s the calculation:</p>

<blockquote class="filename">
  <p>SourceManager.cpp</p>
</blockquote>
<div class="language-cpp highlighter-tree-sitter"><pre><code><span class='ts-keyword'>return</span> <span class='ts-variable'>FilePos</span> <span class='ts-operator'>-</span> <span class='ts-variable'>LineStart</span> <span class='ts-operator'>+</span> <span class='ts-number'>1</span><span class='ts-delimiter'>;</span>
</code></pre></div>

<p>So if the source location is at offset <code>50</code>, the line starts at offset <code>20</code>, then we’re at <code>50 - 20 + 1 = 31</code> (note <code>+1</code> to un-zero index it). So now we know where in the file it is!</p>

<p>Now with that info, it’s pretty straightforward to display a snippet (again… ignoring macros and other complications). We have a cache telling us where line numbers are. So we need this line, which we have its start in that cache. Go to the previous element of that cache and we can get the previous line too, to give some context. Then just print that out to the console.</p>

<p>I know some of this was rushed over and there’s less code examples here, but let’s just say the extra complications from macros and different files actually makes it hard to show without polluting the simplified example. Sorry :(</p>

<h3 id="fix-it">Fix it!</h3>

<p>Okay, so at this point we have a whole system of reporting errors at the correct location. There’s one thing that seems missing here: fixing it! In Clang’s <a href="https://clang.llvm.org/diagnostics.html">diagnostics documentation</a>, they mention a couple cases where the user gets hints to fix the issue. Here’s an example:</p>

<blockquote class="filename">
  <p>test.cpp</p>
</blockquote>
<div class="language-cpp highlighter-tree-sitter"><pre><code><span class='ts-keyword'>template</span><span class='ts-operator'>&lt;</span><span class='ts-keyword'>typename</span> <span class='ts-type'>T</span><span class='ts-operator'>&gt;</span> <span class='ts-keyword'>struct</span> <span class='ts-type'>S</span> {}<span class='ts-delimiter'>;</span>

<span class='ts-keyword'>struct</span> <span class='ts-type'>S</span><span class='ts-operator'>&lt;</span><span class='ts-type'>int</span><span class='ts-operator'>&gt;</span> {}<span class='ts-delimiter'>;</span>
</code></pre></div>

<blockquote class="shell">

</blockquote>
<div class="language-bash highlighter-tree-sitter"><pre><code><span class='ts-property'>etyp</span><span class='ts-function'>:errors-pl/</span> <span class='ts-operator'>$</span> clang++ test.cpp
<span class='ts-function'>test.cpp:3:8:</span> error: template specialization requires <span class='ts-string'>&#39;template&lt;&gt;&#39;</span>
    <span class='ts-function'>3</span> <span class='ts-operator'>|</span> <span class='ts-function'>struct</span> S<span class='ts-operator'>&lt;</span>int<span class='ts-operator'>&gt;</span> {
      <span class='ts-operator'>|</span>        <span class='ts-function'>^~~~~~</span>
      <span class='ts-operator'>|</span> <span class='ts-function'>template</span><span class='ts-operator'>&lt;</span><span class='ts-operator'>&gt;</span>
1 error generated.
</code></pre></div>

<p>Okay it’s a little weird that it points to <code>S</code> even though you need to put the fixit hint before the <code>struct</code> keyword. According to the page I linked, here’s the diagnostic:</p>

<blockquote class="shell">

</blockquote>
<div class="language-bash highlighter-tree-sitter"><pre><code><span class='ts-function'><span class='ts-operator'>$</span> <span class='ts-property'>clang</span></span> t.cpp
<span class='ts-function'>t.cpp:9:3:</span> error: template specialization requires <span class='ts-string'>&#39;template&lt;&gt;&#39;</span>
  <span class='ts-function'>struct</span> iterator_traits<span class='ts-operator'>&lt;</span>file_iterator<span class='ts-operator'>&gt;</span> {
  <span class='ts-function'>^</span>
  <span class='ts-function'>template</span><span class='ts-operator'>&lt;</span><span class='ts-operator'>&gt;</span>
</code></pre></div>

<p>… which puts <code>template&lt;&gt;</code> at the correct location. I won’t harp on this too much, but one of the more frustrating experiences you can have is to do exactly what the compiler suggests and have that be wrong. This is most likely a result of making the columns more accurate for other parts and this particular case just never got caught.</p>

<p>Okay, so how does this fixit work? The error is:</p>

<blockquote class="filename">
  <p>DiagnosticSemaKinds.td</p>
</blockquote>
<div class="language-cpp highlighter-tree-sitter"><pre><code><span class='ts-type'>def</span> <span class='ts-variable'>err_template_spec_needs_header</span> : <span class='ts-function'>Error</span><span class='ts-operator'>&lt;</span>
  <span class='ts-string'>&quot;template specialization requires &#39;template&lt;&gt;&#39;&quot;</span><span class='ts-operator'>&gt;</span><span class='ts-delimiter'>;</span>
</code></pre></div>

<p>So it doesn’t have any extra arguments for fixit, so it must be when it’s used:</p>

<blockquote class="filename">
  <p>SemaTemplate.cpp</p>
</blockquote>
<div class="language-cpp highlighter-tree-sitter"><pre><code><span class='ts-function'>Diag</span>(<span class='ts-variable'>DeclLoc</span>, diag::<span class='ts-variable'>err_template_spec_needs_header</span>)
  &lt;&lt; <span class='ts-variable'>Range</span>
  &lt;&lt; <span class='ts-type'>FixItHint</span>::<span class='ts-function'>CreateInsertion</span>(<span class='ts-variable'>ExpectedTemplateLoc</span>, <span class='ts-string'>&quot;template&lt;&gt; &quot;</span>)<span class='ts-delimiter'>;</span>
</code></pre></div>

<p>There we go, we have a class <code>FixItHint</code> that we can create a hint for the user. Let’s try to use this for our simple case of missing parentheses.</p>

<p>Here’s the line that diagnoses the parentheses error we saw before:</p>

<blockquote class="filename">
  <p>ParseStmt.cpp</p>
</blockquote>
<div class="language-cpp highlighter-tree-sitter"><pre><code><span class='ts-function'>Diag</span>(<span class='ts-variable'>Tok</span>, diag::<span class='ts-variable'>err_expected_lparen_after</span>) &lt;&lt; <span class='ts-string'>&quot;if&quot;</span><span class='ts-delimiter'>;</span>
</code></pre></div>

<p>As an experiment, here’s a first draft of adding the lparen:</p>

<blockquote class="filename">
  <p>ParseStmt.cpp</p>
</blockquote>
<div class="language-cpp highlighter-tree-sitter"><pre><code><span class='ts-function'>Diag</span>(<span class='ts-variable'>Tok</span>, diag::<span class='ts-variable'>err_expected_lparen_after</span>)
  &lt;&lt; <span class='ts-string'>&quot;if&quot;</span>
  &lt;&lt; <span class='ts-type'>FixItHint</span>::<span class='ts-function'>CreateInsertion</span>(<span class='ts-variable'>Tok</span><span class='ts-delimiter'>.</span><span class='ts-function'>getLocation</span>(), <span class='ts-string'>&quot;(&quot;</span>)<span class='ts-delimiter'>;</span>
</code></pre></div>

<p>Here’s the new error I get:</p>

<blockquote class="shell">

</blockquote>
<div class="language-bash highlighter-tree-sitter"><pre><code><span class='ts-property'>etyp</span><span class='ts-function'>:errors-pl/</span> <span class='ts-operator'>$</span> ~/src/llvm-project/build-debug/bin/clang++ test.cpp
<span class='ts-function'>test.cpp:2:6:</span> error: expected <span class='ts-string'>&#39;(&#39;</span> after <span class='ts-string'>&#39;if&#39;</span>
    <span class='ts-function'>2</span> <span class='ts-operator'>|</span>   <span class='ts-keyword'>if</span> <span class='ts-function'>true</span> {
<span class='ts-function'></span>      <span class='ts-operator'>|</span>      <span class='ts-function'>^</span>
      <span class='ts-operator'>|</span>      (
<span class='ts-function'>1</span> error generated.
</code></pre></div>

<p>That’s actually relatively informative, I think! It shows what would be expected and it makes it slightly clearer what it means.</p>

<p>Now, I think one weird part here is that adding in the fix it hint would not create a compileable program. If you just blindly follow it and only add the lparen, you get:</p>

<blockquote class="shell">

</blockquote>
<div class="language-bash highlighter-tree-sitter"><pre><code><span class='ts-property'>etyp</span><span class='ts-function'>:errors-pl/</span> <span class='ts-operator'>$</span> ~/src/llvm-project/build-debug/bin/clang++ test.cpp
<span class='ts-function'>test.cpp:2:12:</span> error: expected <span class='ts-string'>&#39;)&#39;</span>
    <span class='ts-function'>2</span> <span class='ts-operator'>|</span>   <span class='ts-keyword'>if</span> (<span class='ts-function'>true</span> {
      <span class='ts-operator'>|</span>            <span class='ts-function'>^</span>
<span class='ts-function'>test.cpp:2:6:</span> note: to match this <span class='ts-string'>&#39;(&#39;</span>
    <span class='ts-function'>2</span> <span class='ts-operator'>|</span>   <span class='ts-keyword'>if</span> (<span class='ts-function'>true</span> {
      <span class='ts-operator'>|</span>      <span class='ts-function'>^</span>
<span class='ts-function'>test.cpp:5:1:</span> error: expected statement
    <span class='ts-function'>5</span> <span class='ts-operator'>|</span> <span class='ts-function'>}</span>
<span class='ts-function'></span>      <span class='ts-operator'>|</span> <span class='ts-function'>^</span>
<span class='ts-function'>2</span> errors generated.
</code></pre></div>

<p>We could go in and add another fixit, but it does have a note to help. I think the problem here is a bit deeper: the fixit hint doesn’t completely fix the problem, it just provides a solution that needs an extra step. That’s not much clearer in my opinion.</p>

<p>So what if we try to fix that? Well, it’s a fair bit more complicated. We don’t know what mistakes the user made beyond this point. Trying to give a good fixit here would require some assumptions. If we assume that the user did provide a <code>{</code> (lbrace) where it would be necessary, then we can just skip until we see the lbrace and suggest a fixit surrounding the stuff before in parentheses.</p>

<p>When you write a parser, you (should) try to make it recover really really well from errors like this so that the user doesn’t have to continue to recompile just to get syntax right. But sometimes it’s just hard to have something that covers every case. So instead, you get somewhat vague error messages. This case isn’t exactly vague, but it is a specific type of jargon that is just another step to learning how to program.</p>

<h2 id="other-languages">Other languages</h2>

<p>My favorite language for error messages is Rust, and rightfully so. It’s a very complicated language, so in order to get people to use it, diagnostics have to be precise and tell the user what to do.</p>

<p>Let’s look at an analogous example with the <code>if</code> statement. Rust doesn’t require parentheses around the condition, but requires what follows to be a block surrounded by <code>{</code> and <code>}</code>:</p>

<blockquote class="filename">
  <p>test.rs</p>
</blockquote>
<div class="language-rust highlighter-tree-sitter"><pre><code><span class='ts-keyword'>fn</span> <span class='ts-function'>main</span><span class='ts-punctuation-bracket'>(</span><span class='ts-punctuation-bracket'>)</span> <span class='ts-punctuation-bracket'>{</span>
  <span class='ts-keyword'>if</span> <span class='ts-constant-builtin'>true</span>
    <span class='ts-keyword'>let</span> i = <span class='ts-constant-builtin'>0</span><span class='ts-punctuation-delimiter'>;</span>
<span class='ts-punctuation-bracket'>}</span>
</code></pre></div>

<p>We get this error:</p>

<blockquote class="shell">

</blockquote>
<div class="language-bash highlighter-tree-sitter"><pre><code><span class='ts-property'>etyp</span>:errors-pl/ $ rustc test.rs
error: expected `{`, found keyword `let`
 --&gt; test.rs:3:5
  |
3 |     let i = 0;
  |     ^^^ expected `{`
  |
note: the `if` expression is missing a block after this condition
 --&gt; test.rs:2:6
  |
2 |   if true
  |      ^^^^
help: try placing this code inside a block
  |
3 |     { let i = 0; }
  <span class='ts-operator'>|</span>     +            +

error: <span class='ts-function'>aborting</span> due to previous error
</code></pre></div>

<p>I think that’s awesome. We get the “compiler jargon” error, then a note saying WHY we got that. Then, because it’s a common mistake, we also have a special case that gives an easy fix for our issue. A super simple case where almost any other language simply gives the first one, but the standard Rust compiler goes above and beyond.</p>

<p>Then just to add another language with a bad error message, here’s what I get with my system installed golang:</p>

<blockquote class="filename">
  <p>test.go</p>
</blockquote>
<div class="language-go highlighter-tree-sitter"><pre><code><span class='ts-keyword'>package</span> main

<span class='ts-keyword'>func</span> <span class='ts-function'>main</span>() {
  <span class='ts-keyword'>if</span> <span class='ts-constant-builtin'>true</span>
    <span class='ts-variable'>var</span> _ <span class='ts-operator'>=</span> <span class='ts-number'>0</span>
}
</code></pre></div>

<blockquote class="shell">

</blockquote>
<div class="language-bash highlighter-tree-sitter"><pre><code><span class='ts-property'>etyp</span><span class='ts-function'>:errors-pl/</span> <span class='ts-operator'>$</span> go run test.go
<span class='ts-comment'># command-line-arguments</span>
<span class='ts-function'>./test.go:5:3:</span> syntax error: unexpected var, expected expression
</code></pre></div>

<p>At least it gives the column number?</p>

<h2 id="conclusions">Conclusions</h2>

<p>Maybe I’m weird, but I find that the quality of error messages is proportional to how much I enjoy a language. It should tell me what I did wrong and why.</p>

<p>Clang’s error messages are pretty good in the C/C++ world. For the opposite end of the spectrum, just take what <code>cl</code> (Microsoft’s C/C++ compiler) does with the example we looked at:</p>

<blockquote class="shell">

</blockquote>
<div class="language-bash highlighter-tree-sitter"><pre><code><span class='ts-function'>example.cpp</span>
<span class='ts-operator'>&lt;</span>source<span class='ts-function'><span class='ts-embedded'>&gt;(<span class='ts-function'>2</span>)</span>:</span> error C2059: syntax error: <span class='ts-string'>&#39;constant&#39;</span>
<span class='ts-operator'>&lt;</span>source<span class='ts-function'><span class='ts-embedded'>&gt;(<span class='ts-function'>2</span>)</span>:</span> error C2143: syntax error: missing <span class='ts-string'>&#39;;&#39;</span> before <span class='ts-string'>&#39;{&#39;</span>
<span class='ts-function'>Compiler</span> returned: 2
</code></pre></div>

<p>I know how to program with C++, I know a fair bit about programming languages, and I’ve seen a lot of them. But I have no idea what those errors mean. Basically the only piece of information I get is that it’s on line 2, and then some… less than helpful information.</p>

<p>So do better than MSVC. Your users deserve better. Oh yeah, this applies to websites too by the way… I just like compilers.</p>]]></content><author><name>Evan Typanski</name></author><summary type="html"><![CDATA[Programming languages are fun to design and think about. The error messages aren’t as much. But let’s look at some anyway. Don’t worry, we’ll look at compiler source code too :)]]></summary></entry><entry><title type="html">This C++ code doesn’t look ambiguous to me</title><link href="https://etyp.dev/posts/this-cpp-is-ambiguous/" rel="alternate" type="text/html" title="This C++ code doesn’t look ambiguous to me" /><published>2023-10-23T00:00:00-04:00</published><updated>2023-10-23T00:00:00-04:00</updated><id>https://etyp.dev/posts/this-cpp-not-ambiguous</id><content type="html" xml:base="https://etyp.dev/posts/this-cpp-is-ambiguous/"><![CDATA[<p>Look at this C++ code:</p>

<blockquote class="filename">
  <p>test.cpp</p>
</blockquote>
<div class="language-cpp highlighter-tree-sitter"><pre><code><span class='ts-keyword'>class</span> <span class='ts-type'>B</span><span class='ts-delimiter'>;</span>
<span class='ts-keyword'>class</span> <span class='ts-type'>A</span> { <span class='ts-keyword'>public</span>: <span class='ts-function'>A</span> (<span class='ts-type'>B</span><span class='ts-operator'>&amp;</span>)<span class='ts-delimiter'>;</span>}<span class='ts-delimiter'>;</span>
<span class='ts-keyword'>class</span> <span class='ts-type'>B</span> { <span class='ts-keyword'>public</span>: operator <span class='ts-type'>A</span>()<span class='ts-delimiter'>;</span> }<span class='ts-delimiter'>;</span>
<span class='ts-keyword'>class</span> <span class='ts-type'>C</span> { <span class='ts-keyword'>public</span>: <span class='ts-function'>C</span> (<span class='ts-type'>B</span><span class='ts-operator'>&amp;</span>)<span class='ts-delimiter'>;</span> }<span class='ts-delimiter'>;</span>
<span class='ts-type'>void</span> <span class='ts-function'>f</span>(<span class='ts-type'>A</span>) { }
<span class='ts-type'>void</span> <span class='ts-function'>f</span>(<span class='ts-type'>C</span>) { }

<span class='ts-type'>int</span> <span class='ts-function'>main</span>() {
  <span class='ts-type'>B</span> <span class='ts-variable'>b</span><span class='ts-delimiter'>;</span>
  <span class='ts-function'>f</span>(<span class='ts-variable'>b</span>)<span class='ts-delimiter'>;</span>
}
</code></pre></div>

<p>Do you think this compiles? Well, probably not because I’m asking. So here’s the error message from Clang 13:</p>

<blockquote class="shell">

</blockquote>
<div class="language-bash highlighter-tree-sitter"><pre><code><span class='ts-property'>etyp</span><span class='ts-function'>:fun/</span> <span class='ts-operator'>$</span> clang++ test.cpp
<span class='ts-function'>test.cpp:10:3:</span> error: call to <span class='ts-string'>&#39;f&#39;</span> is ambiguous
  <span class='ts-function'>f</span>(<span class='ts-function'>b</span>);
  <span class='ts-function'>^</span>
<span class='ts-function'>test.cpp:5:6:</span> note: candidate function
<span class='ts-function'>void</span> f(A) { }
     ^
<span class='ts-function'>test.cpp:6:6:</span> note: candidate function
<span class='ts-function'>void</span> f(C) { }
     ^
<span class='ts-function'>1</span> error generated.
</code></pre></div>

<p>Okay so it’s ambiguous which conversion gets done for the object <code>b</code> (of type <code>B</code>). So what options are there?</p>

<p>1) Call <code>f(A)</code>. We can call <code>A</code>’s constructor which takes a reference to a <code>B</code></p>

<p>2) Call <code>f(C)</code>. We can call <code>C</code>’s constructor which takes a reference to a <code>B</code></p>

<p>3) Call <code>f(A)</code>. We can call <code>operator A()</code> in the class <code>B</code></p>

<p>But, 1 and 3 are ambiguous because we can’t find a better one to call <code>f(A)</code>. But <code>f(C)</code> is still not ambiguous - we know how to call it without any ambiguity. Trying to call <code>f(A)</code> is ambiguous so <em>obviously</em> it shouldn’t be chosen.</p>

<p>It turns out in this case, the ambiguity between 1 and 3 is ranked equal priority as the user defined conversion in 2. From the C++20 standard section 12.4.2.10:</p>

<blockquote>
  <p>For the purpose of ranking implicit conversion sequences as described in 12.4.3.2, the ambiguous conversion sequence is treated as a user-defined conversion sequence that is indistinguishable from any other user-defined conversion sequence.</p>
</blockquote>

<p>I find this surprising because I could easily determine that option 2 is the unambiguous way to make this compile.</p>

<h2 id="not-all-compilers">Not all compilers…</h2>

<p>It turns out, MSVC actually <a href="https://godbolt.org/#g:!((g:!((g:!((h:codeEditor,i:(filename:'1',fontScale:14,fontUsePx:'0',j:1,lang:c%2B%2B,selection:(endColumn:1,endLineNumber:12,positionColumn:1,positionLineNumber:12,selectionStartColumn:1,selectionStartLineNumber:1,startColumn:1,startLineNumber:1),source:'class+B%3B%0Aclass+A+%7B+public:+A+(B%26)%3B%7D%3B%0Aclass+B+%7B+public:+operator+A()%3B+%7D%3B%0Aclass+C+%7B+public:+C+(B%26)%3B+%7D%3B%0Avoid+f(A)+%7B+%7D%0Avoid+f(C)+%7B+%7D%0A%0Aint+main()+%7B%0A++B+b%3B%0A++f(b)%3B%0A%7D%0A'),l:'5',n:'0',o:'C%2B%2B+source+%231',t:'0')),k:33.333333333333336,l:'4',n:'0',o:'',s:0,t:'0'),(g:!((h:compiler,i:(compiler:vcpp_v19_37_x64,deviceViewOpen:'1',filters:(b:'0',binary:'1',binaryObject:'1',commentOnly:'0',debugCalls:'1',demangle:'0',directives:'0',execute:'1',intel:'0',libraryCode:'0',trim:'1'),flagsViewOpen:'1',fontScale:14,fontUsePx:'0',j:1,lang:c%2B%2B,libs:!(),options:'',overrides:!(),selection:(endColumn:1,endLineNumber:1,positionColumn:1,positionLineNumber:1,selectionStartColumn:1,selectionStartLineNumber:1,startColumn:1,startLineNumber:1),source:1),l:'5',n:'0',o:'+x64+msvc+v19.37+(Editor+%231)',t:'0')),k:33.333333333333336,l:'4',n:'0',o:'',s:0,t:'0'),(g:!((h:output,i:(compilerName:'x86-64+gcc+13.1',editorid:1,fontScale:14,fontUsePx:'0',j:1,wrap:'1'),l:'5',n:'0',o:'Output+of+x64+msvc+v19.37+(Compiler+%231)',t:'0')),k:33.33333333333333,l:'4',n:'0',o:'',s:0,t:'0')),l:'2',n:'0',o:'',t:'0')),version:4">accepts the code</a>. You can even see in the assembly it calls <code>f(C)</code>.</p>

<p>I believe no matter how silly the standard is with its rules (which this particular point may have a very good reason), C++ compilers should aim to conform to the standard. This case was pulled exactly from the standard as a case that should not compile. MSVC should not compile this.</p>

<p>But that’s a whole other rant.</p>

<p>Thanks for looking at that C++ code.</p>]]></content><author><name>Evan Typanski</name></author><summary type="html"><![CDATA[Look at this C++ code:]]></summary></entry><entry><title type="html">Zig is for me - is it for you?</title><link href="https://etyp.dev/posts/is-zig-right/" rel="alternate" type="text/html" title="Zig is for me - is it for you?" /><published>2023-04-04T00:00:00-04:00</published><updated>2023-04-04T00:00:00-04:00</updated><id>https://etyp.dev/posts/is-zig-right</id><content type="html" xml:base="https://etyp.dev/posts/is-zig-right/"><![CDATA[<p>There has been <a href="https://matklad.github.io/2023/03/26/zig-and-rust.html">a</a> <a href="https://www.openmymind.net/Zig-Quirks/">ton</a> <a href="https://www.infoworld.com/article/3689648/meet-the-zig-programming-language.html">of</a> <a href="https://zackoverflow.dev/writing/unsafe-rust-vs-zig/">Zig</a> <a href="https://kristoff.it/blog/zig-multi-sequence-for-loops/">content</a> lately. So I’ll add to the swarm beating this dead horse, but only because I want to introduce some stuff that I’m working on :)</p>

<p>Also, I wanted to write more off-the-cuff style posts.</p>

<h2 id="zig">Zig?</h2>

<p><a href="https://ziglang.org/">Zig</a> is a modern programming language meant to “replace C.” There are a ton of those. There does seem to be a worrying trend where every programmer under the sun believes that they will be the one to destroy C. Despite that, I see legacy C code every day that is run in safety-critical contexts. That code is <em>untouchable</em>. We all know that the second you touch something, it all will crumble. So why would you look at Zig?</p>

<p>There are a lot of reasons. One of the posts I linked above probably does a better job than I will at explaining this. Let’s go through some requirements in a C successor:</p>

<ol>
  <li>A successor must have simple, easy control over memory. I believe this one of the main reasons C is so prominent - few other languages let you do what C does with memory with such simplicity. Most C applications work so closely with buffers and hardware that this is essential.</li>
  <li>A successor must do number 1) more safely than C. If you’ve ever touched a C codebase, you’ve seen crazy segfaults where one corner of the application doesn’t properly set memory where the other side assumes it’s set. To make a language more appealing than C, you must make it easier to be safe.</li>
  <li>A successor must be able to interact easily with C. If you are looking for a language to take over C, you probably have a lot of C sitting around. You don’t want to rewrite all of that.</li>
  <li>A successor must be able to compile to a lot of hardware, including proprietary hardware. Many devices you see use C for firmware. Many of these have no other choice. The ability to whip up a C compiler for your specific hardware is very important.</li>
  <li>A successor must not be ugly. Ugly code isn’t fun to write.</li>
</ol>

<p>How does Zig deal with each of these?</p>

<ol>
  <li>Zig gives you control over <a href="https://ziglang.org/documentation/master/std/#A;std:mem.Allocator">allocators</a> to chose how and where memory gets allocated. You also have access to suspiciously C like control over pointers…</li>
  <li>Zig still requires manual memory management. If you allocate something, you free it. Or, if another function returns allocated memory, you will free it. Zig’s allocators help you do this. First, the allocator pattern is generally implemented by you passing an allocator into a function, so you know it may allocate memory. Programmers should also make it clear that their function allocates memory. Second, you can have special allocators, like <a href="https://ziglang.org/documentation/master/std/#A;std:testing.allocator"><code>std.testing.allocator</code></a>, which will tell you if you have memory leaks in a unit test. Neat!</li>
  <li>Zig has my favorite thing: a transpiler from C (I <a href="https://etyp.dev/posts/art-of-transpilers/">really like</a> those). Just run <code>zig translate-c</code> and you get Zig code where you had C code. You can use this to include C libraries or upgrade your code base to Zig!</li>
  <li>Zig is based on LLVM, so you get a lot of hardware for free. I’d worry a bit about this point, since it seems a lot harder to make a good Zig compiler than a good C compiler. It’s not super common to make a brand new C compiler for each piece of hardware (that’s what a compiler backend is for), but there certainly are specialized C compilers. Stay tuned for this one.</li>
  <li>Zig is mostly pretty. You have to get over stuff like <code>.{}</code> for anonymous structs (I find the anonymous structs syntax satisfying). But some things are great. Say your program returns some enum that can be <code>RED</code>, <code>BLUE</code>, or <code>GREEN</code>. You can return just by saying <code>return .BLUE;</code> - I think that’s really cute. No need to even specify the enum name! (which is really convenient considering the enum could be anonymous…)</li>
</ol>

<h2 id="zig-is-special">Zig is special</h2>

<p>I admit, not everyone has my sensibilities. Zig isn’t the next Python, and many people conflate high level web development with programming in general. So you may hate it. That’s okay. Any worthy art has those who don’t like it.</p>

<p>What contexts would you use Zig? Obviously wherever C would be used. That could be operating systems, microcontrollers, or even game development. Zig also seems to be adding good support for WebAssembly targets - great for efficient web code. If you’re like me, it may also be a good language for compilers, as it gives you a no nonsense, quick language for a compiler or interpreter. Certainly better than Python for that, in my opinion.</p>

<p>Zig is beautiful. It has cool ideas, almost none of which I covered. Just take a look at it, I think it has room to make a splash in certain spaces.</p>

<h2 id="whats-next">What’s next?</h2>

<p>I’ve done a few things in Zig so far, but not as much as I want.</p>

<p>My current pet project takes Zig and puts it on the Arduino. I’ve gotten LEDs blinking, LCD panels with easy to use libraries, reading from sensors, pulse width modulation… all of that. Under the hood it uses <a href="https://github.com/ZigEmbeddedGroup/microzig">microzig</a> to provide the heavy lifting, I’m just providing an abstraction on top of that abstraction.</p>

<p>Right now, Zig is in a pretty unstable place (it is pre-1.0 after all). Libraries you use won’t always work with a new release. But, I think this time is crucial to build libraries and tools. Even if the project isn’t a brand new library, just using Zig is extremely helpful for the community. If you have a new project, consider using Zig, to give exposure to the language. Maybe not for your fancy new website, though, unless you’re <a href="https://dhh.dk/">DHH</a> (for all of you Rails lovers).</p>

<p>I plan on making <a href="https://github.com/evantypanski/arduzig">arduzig</a> just as easy to use as the Arduino IDE for whatever Arduino projects you have. I will probably (?) write examples and more posts to make it as understandable as possible. Probably don’t try it yet. But once Zig 0.11 is out and I’ve brought it up to date? Please.</p>

<p>By the way, take a look at the posts I linked in the first sentence if you haven’t. They’re better than this one.</p>]]></content><author><name>Evan Typanski</name></author><summary type="html"><![CDATA[There has been a ton of Zig content lately. So I’ll add to the swarm beating this dead horse, but only because I want to introduce some stuff that I’m working on :)]]></summary></entry><entry><title type="html">Rust will `never` do that!</title><link href="https://etyp.dev/posts/rust-will-never/" rel="alternate" type="text/html" title="Rust will `never` do that!" /><published>2022-09-02T00:00:00-04:00</published><updated>2022-09-02T00:00:00-04:00</updated><id>https://etyp.dev/posts/rust-will-never</id><content type="html" xml:base="https://etyp.dev/posts/rust-will-never/"><![CDATA[<p>That is, the Rust <a href="https://doc.rust-lang.org/reference/types/never.html"><code>never</code> type</a> (<code>!</code>).</p>

<h2 id="everything-is-an-expression">Everything is an expression</h2>

<p>Rust is kind of an “everything is an expression” type of language. An expression is something that produces a value. Not everything is an expression, but basically everything that is in a Rust body (executable code) is an expression. Actually, one thing that isn’t are locals, like:</p>

<blockquote class="filename">

</blockquote>
<div class="language-rust highlighter-tree-sitter"><pre><code><span class='ts-keyword'>let</span> x = <span class='ts-constant-builtin'>5</span><span class='ts-punctuation-delimiter'>;</span>
</code></pre></div>

<p>That is its own statement! But you can have an expression with a <code>let</code> statement, just take:</p>

<blockquote class="filename">

</blockquote>
<div class="language-rust highlighter-tree-sitter"><pre><code>
<span class='ts-keyword'>if</span> <span class='ts-keyword'>let</span> <span class='ts-constructor'>Some</span><span class='ts-punctuation-bracket'>(</span>num<span class='ts-punctuation-bracket'>)</span> = <span class='ts-function'>func_that_returns_option</span><span class='ts-punctuation-bracket'>(</span><span class='ts-punctuation-bracket'>)</span> <span class='ts-punctuation-bracket'>{</span><span class='ts-punctuation-bracket'>}</span>
</code></pre></div>

<p>The <code>let</code> statement in there isn’t a local, it’s a <a href="https://doc.rust-lang.org/stable/nightly-rustc/rustc_hir/hir/struct.Let.html"><code>let</code> expression</a>.</p>

<p>Let’s go over a few other things that are also expressions:</p>

<blockquote class="filename">

</blockquote>
<div class="language-rust highlighter-tree-sitter"><pre><code><span class='ts-punctuation-bracket'>{</span> <span class='ts-constant-builtin'>1</span> <span class='ts-punctuation-bracket'>}</span>
</code></pre></div>

<blockquote class="filename">

</blockquote>
<div class="language-rust highlighter-tree-sitter"><pre><code><span class='ts-keyword'>loop</span> <span class='ts-punctuation-bracket'>{</span> <span class='ts-keyword'>break</span> <span class='ts-constant-builtin'>1</span><span class='ts-punctuation-delimiter'>;</span> <span class='ts-punctuation-bracket'>}</span>
</code></pre></div>

<blockquote class="filename">

</blockquote>
<div class="language-rust highlighter-tree-sitter"><pre><code><span class='ts-keyword'>if</span> <span class='ts-constant-builtin'>true</span> <span class='ts-punctuation-bracket'>{</span> <span class='ts-constant-builtin'>1</span> <span class='ts-punctuation-bracket'>}</span> <span class='ts-keyword'>else</span> <span class='ts-punctuation-bracket'>{</span> <span class='ts-keyword'>return</span><span class='ts-punctuation-delimiter'>;</span> <span class='ts-punctuation-bracket'>}</span>
</code></pre></div>

<p>This last one is what we’ll be interested in.</p>

<h2 id="the-never-type">The <code>never</code> type</h2>

<p>So if we look into the last example I gave, you know the <code>if</code> block evaluates to <code>1</code>. But what about the <code>else</code> block? <code>return;</code> doesn’t produce a value, it actually leaves the function. So what is its type?</p>

<p>That’s right, the <code>never</code> type!</p>

<p>The point of the <code>never</code> type is to say “this computation will not complete.” That way, if you assign something to that value:</p>

<blockquote class="filename">

</blockquote>
<div class="language-rust highlighter-tree-sitter"><pre><code><span class='ts-keyword'>let</span> x = <span class='ts-keyword'>if</span> <span class='ts-constant-builtin'>true</span> <span class='ts-punctuation-bracket'>{</span> <span class='ts-constant-builtin'>1</span> <span class='ts-punctuation-bracket'>}</span> <span class='ts-keyword'>else</span> <span class='ts-punctuation-bracket'>{</span> <span class='ts-keyword'>return</span><span class='ts-punctuation-delimiter'>;</span> <span class='ts-punctuation-bracket'>}</span><span class='ts-punctuation-delimiter'></span>
</code></pre></div>

<p>The type of <code>x</code> is based on the <code>if</code> block. But, that doesn’t mean the <code>never</code> type is ignored. How the compiler figures that out is <code>never</code> can be coerced into any type. That means, when trying to infer the type for <code>x</code>, the compiler sees the <code>if</code> block has type <code>i32</code>. Then the <code>else</code> block has type <code>never</code>, so to make it consistent, it says “<code>never</code> can convert to <code>i32</code>” and it’s all okay!</p>

<h2 id="what-does-this-mean-for-the-user">What does this mean for the user?</h2>

<p>Well, not much. It’s mostly a fun compiler intricacy. But, if you want to see it mentioned in your diagnostics, try the new <code>let else</code> syntax (currently only available with nightly). This syntax lets you use a pattern for a <code>let</code> binding that may not always be true, like:</p>

<blockquote class="filename">

</blockquote>
<div class="language-rust highlighter-tree-sitter"><pre><code><span class='ts-keyword'>let</span> <span class='ts-constructor'>Ok</span><span class='ts-punctuation-bracket'>(</span>x<span class='ts-punctuation-bracket'>)</span> = <span class='ts-function'>returns_result</span><span class='ts-punctuation-bracket'>(</span><span class='ts-punctuation-bracket'>)</span> <span class='ts-keyword'>else</span> <span class='ts-punctuation-bracket'>{</span> <span class='ts-function-macro'>warn</span><span class='ts-function-macro'>!</span><span class='ts-punctuation-bracket'>(</span><span class='ts-string'>&quot;This is bad!&quot;</span><span class='ts-punctuation-bracket'>)</span><span class='ts-punctuation-delimiter'></span><span class='ts-punctuation-delimiter'>;</span> <span class='ts-keyword'>return</span><span class='ts-punctuation-delimiter'>;</span> <span class='ts-punctuation-bracket'>}</span><span class='ts-punctuation-delimiter'>;</span>
</code></pre></div>

<p>So, if <code>returns_result</code> returns <code>Ok</code>, then we assign <code>x</code> to the value in <code>Ok</code>. But, if it’s not, we warn and return. Pretty easy!</p>

<p>The type of that <code>else</code> block has to be <code>never</code>, though.</p>

<p>So try making it not, with this minimal example:</p>

<blockquote class="filename">
  <p>letelse.rs</p>
</blockquote>
<div class="language-rust highlighter-tree-sitter"><pre><code><span class='ts-attribute'>#!<span class='ts-punctuation-bracket'>[</span>feature<span class='ts-punctuation-bracket'>(</span>let_else<span class='ts-punctuation-bracket'>)</span><span class='ts-punctuation-bracket'>]</span></span>

<span class='ts-keyword'>fn</span> <span class='ts-function'>opt</span><span class='ts-punctuation-bracket'>(</span><span class='ts-punctuation-bracket'>)</span> -&gt; <span class='ts-type'>Option</span><span class='ts-punctuation-bracket'>&lt;</span><span class='ts-type-builtin'>i32</span><span class='ts-punctuation-bracket'>&gt;</span> <span class='ts-punctuation-bracket'>{</span>
    <span class='ts-constructor'>Some</span><span class='ts-punctuation-bracket'>(</span><span class='ts-constant-builtin'>1</span><span class='ts-punctuation-bracket'>)</span>
<span class='ts-punctuation-bracket'>}</span>

<span class='ts-keyword'>fn</span> <span class='ts-function'>main</span><span class='ts-punctuation-bracket'>(</span><span class='ts-punctuation-bracket'>)</span> <span class='ts-punctuation-bracket'>{</span>
    <span class='ts-keyword'>let</span> <span class='ts-constructor'>Some</span><span class='ts-punctuation-bracket'>(</span>x<span class='ts-punctuation-bracket'>)</span> = <span class='ts-function'>opt</span><span class='ts-punctuation-bracket'>(</span><span class='ts-punctuation-bracket'>)</span> <span class='ts-keyword'>else</span> <span class='ts-punctuation-bracket'>{</span> <span class='ts-constant-builtin'>1</span> <span class='ts-punctuation-bracket'>}</span><span class='ts-punctuation-delimiter'>;</span>
<span class='ts-punctuation-bracket'>}</span>
</code></pre></div>

<p>This will error:</p>

<blockquote class="shell">

</blockquote>
<div class="language-rust highlighter-tree-sitter"><pre><code>error<span class='ts-punctuation-bracket'>[</span><span class='ts-constructor'>E0308</span><span class='ts-punctuation-bracket'>]</span><span class='ts-punctuation-delimiter'>:</span> `<span class='ts-keyword'>else</span>` clause of `<span class='ts-keyword'>let</span>..<span class='ts-punctuation-delimiter'>.</span><span class='ts-keyword'>else</span>` does not diverge
 --&gt; letelse<span class='ts-punctuation-delimiter'>.</span>rs<span class='ts-punctuation-delimiter'>:</span><span class='ts-constant-builtin'>7</span><span class='ts-punctuation-delimiter'>:</span><span class='ts-constant-builtin'>30</span>
  |
<span class='ts-constant-builtin'>7</span> |     let <span class='ts-constructor'>Some</span><span class='ts-punctuation-bracket'>(</span>x<span class='ts-punctuation-bracket'>)</span> = <span class='ts-function'>opt</span><span class='ts-punctuation-bracket'>(</span><span class='ts-punctuation-bracket'>)</span> <span class='ts-keyword'>else</span> <span class='ts-punctuation-bracket'>{</span> <span class='ts-constant-builtin'>1</span> <span class='ts-punctuation-bracket'>}</span><span class='ts-punctuation-delimiter'>;</span>
  |                              ^^^^^ expected `!`<span class='ts-punctuation-delimiter'>,</span> found integer
  |
  = note<span class='ts-punctuation-delimiter'>:</span> expected type `!`
             <span class='ts-type'>found</span> type `<span class='ts-punctuation-bracket'>{</span>integer<span class='ts-punctuation-bracket'>}</span>`
  = help<span class='ts-punctuation-delimiter'>:</span> try adding a diverging expression<span class='ts-punctuation-delimiter'>,</span> such <span class='ts-keyword'>as</span> `<span class='ts-keyword'>return</span>` or `<span class='ts-function-macro'>panic</span><span class='ts-function-macro'>!</span><span class='ts-punctuation-bracket'>(</span><span class='ts-punctuation-delimiter'>.</span><span class='ts-punctuation-delimiter'>.</span><span class='ts-punctuation-bracket'>)</span>`
  = help<span class='ts-punctuation-delimiter'>:</span> ...or use `<span class='ts-keyword'>match</span>` instead of `<span class='ts-keyword'>let</span>...else`

error<span class='ts-punctuation-delimiter'>:</span> aborting due to previous error

<span class='ts-constructor'>For</span> more information about this error<span class='ts-punctuation-delimiter'>,</span> try `rustc --explain <span class='ts-constructor'>E0308</span>`<span class='ts-punctuation-delimiter'>.</span>
</code></pre></div>

<p>We expect that <code>else</code> block to diverge, so it has to be the <code>never</code> type!</p>

<p>Cool.</p>

<p>Rust will <code>never</code> return from that.</p>]]></content><author><name>Evan Typanski</name></author><summary type="html"><![CDATA[That is, the Rust never type (!).]]></summary></entry><entry><title type="html">The Art of Transpilers - From One Programming Language to Another</title><link href="https://etyp.dev/posts/art-of-transpilers/" rel="alternate" type="text/html" title="The Art of Transpilers - From One Programming Language to Another" /><published>2022-06-30T00:00:00-04:00</published><updated>2022-06-30T00:00:00-04:00</updated><id>https://etyp.dev/posts/art-of-transpilers</id><content type="html" xml:base="https://etyp.dev/posts/art-of-transpilers/"><![CDATA[<p>Compilers are cool, they take code you write and make code the machine can understand. Transpilers are cooler, they take code you write and make code in another programming language that machines can’t understand (yet). But why?</p>

<p>Let’s take a quick tour around the world of transpilers!</p>

<h2 id="javascript-clones">JavaScript Clones</h2>
<p>JavaScript is one of the top use cases for transpilers. JavaScript can run natively in any major browser. So, instead of making a new language and asking browsers to support that natively in the browser, many want to reuse what’s already there.</p>

<p>The problem is, <a href="https://blog.andrasbacsai.com/javascript-is-going-crazy-1">JavaScript is crazy</a>. There are many more examples of that. Even with perfect knowledge of JavaScript internals, bugs will happen because of just how dynamic the language is. So, to get around that, we have…</p>

<h3 id="typescript">TypeScript</h3>
<p><a href="https://www.typescriptlang.org/">TypeScript</a> is a superset of JavaScript that allows explicit type information. TypeScript solves many of JavaScript’s biggest woes with dynamic typing. I will not provide examples so I don’t go insane.</p>

<p>So, how does TypeScript do it? It’s a transpiler! You can just transpile your TypeScript to JavaScript then run <em>that</em> in the web browser.</p>

<p>So take this example in TypeScript, ruthlessly stolen from the <a href="https://www.typescriptlang.org/docs/handbook/2/everyday-types.html">handbook</a> on everyday types:</p>

<blockquote class="filename">
  <p>test.js</p>
</blockquote>
<div class="language-ts highlighter-tree-sitter"><pre><code><span class='ts-comment'>// Parameter type annotation</span>
<span class='ts-keyword'>function</span> <span class='ts-function'>greet</span><span class='ts-punctuation-bracket'>(</span><span class='ts-variable-parameter'>name</span>: <span class='ts-type-builtin'>string</span><span class='ts-punctuation-bracket'>)</span> <span class='ts-punctuation-bracket'>{</span>
  <span class='ts-variable-builtin'>console</span><span class='ts-punctuation-delimiter'>.</span><span class='ts-function-method'>log</span><span class='ts-punctuation-bracket'>(</span><span class='ts-string'>&quot;Hello, &quot;</span> <span class='ts-operator'>+</span> <span class='ts-variable-parameter'>name</span><span class='ts-punctuation-delimiter'>.</span><span class='ts-function-method'>toUpperCase</span><span class='ts-punctuation-bracket'>(</span><span class='ts-punctuation-bracket'>)</span> <span class='ts-operator'>+</span> <span class='ts-string'>&quot;!!&quot;</span><span class='ts-punctuation-bracket'>)</span><span class='ts-punctuation-delimiter'>;</span>
<span class='ts-punctuation-bracket'>}</span>
</code></pre></div>

<p>So we can see our <code>name</code> parameter has the type <code>string</code>. We can then compile this with <code>tsc test.ts</code> to get…</p>

<blockquote class="filename">
  <p>test.js</p>
</blockquote>
<div class="language-js highlighter-tree-sitter"><pre><code><span class='ts-comment'>// Parameter type annotation</span>
<span class='ts-keyword'>function</span> <span class='ts-function'>greet</span><span class='ts-punctuation-bracket'>(</span><span class='ts-variable-parameter'>name</span><span class='ts-punctuation-bracket'>)</span> <span class='ts-punctuation-bracket'>{</span>
  <span class='ts-variable-builtin'>console</span><span class='ts-punctuation-delimiter'>.</span><span class='ts-function-method'>log</span><span class='ts-punctuation-bracket'>(</span><span class='ts-string'>&quot;Hello, &quot;</span> <span class='ts-operator'>+</span> <span class='ts-variable-parameter'>name</span><span class='ts-punctuation-delimiter'>.</span><span class='ts-function-method'>toUpperCase</span><span class='ts-punctuation-bracket'>(</span><span class='ts-punctuation-bracket'>)</span> <span class='ts-operator'>+</span> <span class='ts-string'>&quot;!!&quot;</span><span class='ts-punctuation-bracket'>)</span><span class='ts-punctuation-delimiter'>;</span>
<span class='ts-punctuation-bracket'>}</span>
</code></pre></div>

<p>… The same thing without the type in <code>name</code>! Okay that’s not interesting, but try adding a call like <code>greet(1);</code> and you’ll see an error:</p>

<blockquote class="shell">

</blockquote>
<div class="language-bash highlighter-tree-sitter"><pre><code><span class='ts-function'>test.ts:6:7</span> <span class='ts-constant'>-</span> error TS2345: Argument of type <span class='ts-string'>&#39;1&#39;</span> is not assignable to parameter of type <span class='ts-string'>&#39;string&#39;</span>.

<span class='ts-function'>6</span> greet(<span class='ts-function'>1</span>);
        <span class='ts-function'>~</span>


<span class='ts-function'>Found</span> 1 error.
</code></pre></div>

<p>The type guarantee lets you call <code>toUpperCase()</code> and declines anything that’s not a <code>string</code> type. You may be able to see the bugs that could be caught from this. That’s why TypeScript has made such a splash.</p>

<h3 id="coffeescript">CoffeeScript</h3>

<p><a href="https://coffeescript.org/">CoffeeScript</a> tries to solve a slightly different problem. Instead of providing a superset that makes your code less prone to bugs, CoffeeScript makes JavaScript prettier.</p>

<p>However, I’ve always considered CoffeeScript its own language. Once learned, it’s a pleasure to write, which is a nice break from JavaScript, in my opinion. But, it seems to be in some middle ground between JavaScript and a standalone language.</p>

<p>In fact, as stated on the CoffeeScript site, NodeJS can natively run CoffeeScript. It doesn’t need to transpile down to JavaScript; it is its own language. What if we went more pure, with no intent to replace the syntax of some other language?</p>

<h2 id="nim">Nim</h2>

<p><a href="https://nim-lang.org/">Nim</a> can transpile to C, C++, or JavaScript. That would make Nim our lone example of a language whose purpose is to transpile to multiple other languages. For systems programming, use its C support with dependency-free executables. For frontend development, target JavaScript.</p>

<p>Let’s try an example:</p>

<blockquote class="filename">
  <p>test.nim</p>
</blockquote>
<pre><code>echo "Hello World!"
</code></pre>

<p>If we compile this to C with <code>nim cc --nimcache:nimcache test.nim</code>, we get.. an executable. So did it compile? Or transpile?</p>

<p>Well, if we check the nimcache directory I specifically included, we’ll find a fair few C files. These C files are what get compiled to create the executable we see. I won’t include these, since they’re a fair bit of code.
But, we see a pretty major difference from the JavaScript-like transpilers we looked at: Nim only uses the transpilation as a means to an end.</p>

<h2 id="c2rust">C2Rust</h2>

<p>But what if you want to permanently change your codebase? That’s the idea behind <a href="https://c2rust.com/">C2Rust</a>. There’s value in updating legacy codebases to safer, more secure languages like Rust. So, if you want to do it, try a transpiler!</p>

<p>The value in transpilers stretches far beyond just writing simpler code, or code that targets some other language for backend work. Transpilers can change your codebase and make modernizing the code far easier. In the process, your code becomes safer.</p>

<h2 id="many-frontends-one-backend">Many frontends, one backend</h2>

<p>Imagine you have a tool that you want to support many languages, like for static analysis. But, you don’t want to write different analyses for every language’s internal representation. What can you do? Introduce a new language, then transpile to that!</p>

<p>That’s what I currently work on every day. I make translators that go from many source languages and produce one proprietary language as its output. Then, we run checks based on that internal language.</p>

<p>This can have a pretty high barrier to entry because you have to design a new language <em>and</em> your transpiler. But, depending on the use case, it may be an interesting solution.</p>

<p>Those familiar with LLVM may wonder why this is different from compilation? Many compilers, from Rust to Clang, generate LLVM from your source code. Then, the LLVM generates the machine code. But, that’s a compiler, not a transpiler. Don’t be silly.</p>

<h1 id="why">Why?</h1>
<p>I don’t really have profound conclusions about transpilers. I just think they’re cool and underappreciated. And, when you work with them, you get to see the internals of two languages at once, rather than just one!</p>

<p>Two is better than one!</p>

<p>So write more transpilers… And compilers.</p>]]></content><author><name>Evan Typanski</name></author><summary type="html"><![CDATA[Compilers are cool, they take code you write and make code the machine can understand. Transpilers are cooler, they take code you write and make code in another programming language that machines can’t understand (yet). But why?]]></summary></entry></feed>