• Adventures debugging STM8 with PlatformIO

    10/13/2021 at 10:02 0 comments

    I previously showed how to set up PlatformIO. Now I demonstrate putting PlatformIO to debugging firmware for the STM8. Debugging is where the IDE comes on its own as you can see multiple pieces of information on the screen, unlike a text debug session.

    Assuming you have all the build and debug tools installed for STM8 in PlatformIO, and you have the board connected to your host computer with a STlink dongle, then when you open the file explorer to the code you want to debug, and click on icon D, you should get a display like this. As you can see the relevant controls aren't exactly grouped well, they are scattered all over the screen, but you will get used to that. The left column shows the state of the program, including any breakpoints.

    To set a breakpoint, right click on the space before the line number and it will allow you set or delete breakpoints. As you can see there's one on line 25.

    Start the program with the arrow at R. It will first stop at the beginning of main(), then you can continue using the continue arrow control at C. Here you see we have paused at line 25. You can step into lines or over lines using the controls. These correspond to the gdb commands S and N and can be entered as text at the prompt under the debug console T. However if the program has gone into a loop without hitting any breakpoints, you will have to use the interrupt button at C. This cannot be done from the prompt. You can also restart the session.

    Other gdb commands like print [variable] also work, but it's more convenient to watch the variable display in the left column.

    One drawback to using debugging from the IDE is that the generated firmware will be larger and may not fit in flash memory if you are near the limits.

  • Addresses need to be doubled in SPL for STM8

    10/10/2021 at 22:47 0 comments

    While interfacing a DS3231 RTC to a STM8 development board using the Standard Peripherals Library and PlatformIO (BTW, you don't need to build SPL, it's provided by a PlatformIO package), I fell into a simple trap. I assumed that the address wanted by the I2C functions of the SPL was the one stated by the manufacturer. In the wire protocol this is the top 7 bits of the address byte (0x68 in the case of the DS3221) and the bottom bit indicates the direction of data transfer. However the SPL functions want the address shifted one bit left (or doubled if you prefer). This is obvious when looking at this SPL function.

    void I2C_Send7bitAddress(uint8_t Address, I2C_Direction_TypeDef Direction)
    {
      /* Check function parameters */
      assert_param(IS_I2C_ADDRESS_OK(Address));
      assert_param(IS_I2C_DIRECTION_OK(Direction));
    
      /* Clear bit0 (direction) just in case */
      Address &= (uint8_t)0xFE;
    
      /* Send the Address + Direction */
      I2C->DR = (uint8_t)(Address | (uint8_t)Direction);
    }

    I assume the SPL writer did this to avoid a runtime left shift of the address parameter, and wanted the SPL user to do this themselves, as the address is usually a constant in the code and the doubling folded by optimisation. Programmers who use the I2C registers directly without SPL will normally take care of this point when setting the address.

    Code examples of using I2C with STM8 SPL are a bit thin on the ground, but this is one that helped me.

    The embarrassing other problem that prevented my RTC reading routine from working was hardware. I had an unsoldered joint on the B5 (SDA) pin. Now I can see in the PlatformIO debug session (which uses openocd and stm8-gdb) that the correct time and date bytes are returned to the caller.

  • Fooled by idiosyncratic resistor network

    09/29/2021 at 12:34 0 comments

    One of my projects uses a 4 unit resistor network for switch pullups. I picked one out of my pile of spare parts, some stripped from old boards. However the buttons behaved strangely, one worked, but another caused strange symptoms. I checked the circuit board for breaks in the trace to the faulty button, but seeing as it did something, that couldn't be the reason.

    Finally it occurred to me to measure the resistor network. It turned out that contrary to nearly all resistor networks sold today where the common junction is at one end and indicated with a dot, or band, this one had the common junction in the middle. There was a filled circle in the middle of the text, thus: 10 ● kΩ. I thought it was just strange punctuation, but the circle was the position of the common pin. Once I replaced it with a regular unit, the circuit worked as I wanted. Lesson to me: check components when populating the board or face rework.

    I couldn't even find a picture of such a resistor network; it must be rare. I know that manufacturers sometimes used resistor networks with unusual topology for boards, like A-D converters.