• The Curious Case of xpcc's Error Model

    In hindsight it is quite apparent that xpcc and therefore also the @RCA_eV robot code was missing a good error model. Until now xpcc’s way of dealing with failures included using static_assert at compile time and returning error codes at runtime whenever it was deemed necessary. We never considered runtime assertions, nor catching hardware errors like the ARM Cortex-M Fault exceptions. We crashed and burned, a few times literally.

    So what can we do that is simple to use and efficient on AVR and Cortex-M devices, but still powerful enough to be useful? It’s time we thought about our error model.

    Read on →

  • State of the Blog

    Over the last years I worked a lot on xpcc and other @RCA_eV related projects and their documentation has served well enough for capturing my written output.

    But now my interests have diversified a little and I’m working on things are that don’t fit into one coherent project anymore. So I’ve decided to move my content from blog.xpcc.io over here and talk about embedded development more in general. Let’s see how this goes.

  • Computing and Asserting Baudrate Settings at Compile Time

    Prescaler and baudrate calculations are a tricky topic. I have had many situations where the baudrate turned out to be off by a couple of percent, which was enough to render my serial output streams unreadable. Sure, calculating the baudrate error beforehand would have saved me some hours of useless debugging, however, that would require understanding the often complicated mathematical formula hidden somewhere in the depths of the datasheet describing the prescaler vs. baudrate relationship.

    And that seemed to be more work than just using a logic analyzer to measure the resulting error. Of course, this felt like using a sledgehammer to crack a nut and it was neither a fast nor practical solution.

    I think there exists a better solution and I think it can be done using pure C++. This solution needs to be able to:

    1. compute the best possible prescaler settings for the desired baudrate, and
    2. notify me when the desired baudrate cannot be achieved without unresonable error.

    Read on →

  • Typesafe Register Access in C++

    When you are writing software for microcontrollers, reading and writing hardware registers becomes second nature. Registers and bit mappings are typically “modeled” using C preprocessor defines, and usually provided to you by your cross compiler toolchain in device specific header files.

    Setting up and toggling PG13 on the STM32F4 this way looks rather… unreadable:

    // set push-pull, output
    GPIOG->OSPEEDR = (GPIOG->OSPEEDR & ~(3 << 26)) | (3 << 26);
    GPIOG->MODER   = (GPIOG->MODER & ~(3 << 26)) | (1 << 26);
    GPIOG->OTYPER &= ~(1 << 13);
    GPIOG->PUPDR  &= ~(1 << 13);
    
    while(true)
    {
        GPIOG->ODR ^= (1 << 13);  // toggle
        // delay
    }
    

    It did not really dawn on me how primitive this concept was until I was forced to model a memory map myself for one of our many device drivers. Since I have never been a friend of using the C preprocessor in C++ unless absolutely necessary, it seemed like a good opportunity to research how best to implement this in pure C++.

    Read on →