Category Archives: micro

Sousaphone sound-reactive lights

Blinking lights is something that I guess I’ve been enamored with for a while – see 2001 dorm (with awesome work from Brad on visualizations), 2007 bike, and 2015 trumpet. When I got a last minute opportunity to play sousaphone at this year’s HONK fest with Brassterisk I figured I needed something to dress up my otherwise rather drab horn.

The “control board”
Light installation on bell

It is just a Teensy 4.0 I had lying around, together with an audio board, a basic lav mic, and a spare 74XX245 from my grab bag held together with hot glue and proto wire. It drives a cheapo 300 LED RGB strip that is VHB’d to the bell. I think the LEDs will only last a few more transport sessions, but with any luck I’ll make a slightly more polished revision with better longevity in the not too distant future.

Behold, lights:

More adventures in STM32G4 bringup

Last time I had an actually hard problem…, a mis-aligned stack which caused randomly misbehaving software.  This time, I had a more prosaic problem.  One that while not necessarily as interesting, was even more time consuming and frustrating.

The serial port wouldn’t work.  I had copied the module I used for DMA based receive and transmit from the STM32F4 and it just wasn’t working.  Nothing was written and nothing was received.  I carefully inspected the software many times.  I looked at the registers in the debugger and nothing seemed obviously amiss.  I read the datasheet to look for subtle differences in the theory of operation between the STM32F4 and STM32G4 but came up empty.

Eventually, I went completely out of the box and compiled one of the STM provided UART examples from STM32CubeMX.  That did work!  But how?  I once again carefully inspected its source and mine and saw no obvious differences.

Then, I took the ultimate slow path in debugging and binary searched, gradually transforming the STM provided example into my code half by half to figure out which transformation was the ultimate cause.  This did do the trick.  The final fix:

-  huart_.Init.WordLength = 8;
-  huart_.Init.StopBits = 1;
+  huart_.Init.WordLength = UART_WORDLENGTH_8B;
+  huart_.Init.StopBits = UART_STOPBITS_1;

That’s it.  In the old version, I passed in to the HAL the word size and number of stop bits as integers.  Somehow this actually worked, despite being documented as requiring the necessary #defines even in that version.

Notch another win up to: “it sure would be nice if there was less undefined behavior in C/C++”.

Adventures in bringing up the STM32G4

In my continued quest to bring up the STM32G4 for the moteus controller r4.1 and other efforts, I get to discover and learn about the million and one ways in which things don’t work on my path to find the one or two ways in which they can work.  I recently had an interesting enough problem that it is worth it to signal amplify google searches on the matter for the next unfortunate soul.

First, the symptom: snprintf of 32 bit floating point values gave seemingly random results.  The diagnostics and configuration functions of the moteus controller can in some modes render values into ASCII for human readable interactions.  In this particular instance, I was enumerating the full set of configurable values and saw that all of the floating point values read bogus values, like “0.00000”, “-0.00000”, “2.00001”, etc, no matter what actual value they were set to.  Integral types seemed to work fine, and the debugger showed that parsing floating values when setting the configurable values was working just fine.

I had a similar problem not too long ago, when a linker script mis-configuration resulted in an overlap between the RAM based interrupt vector table and the first few global variables resulted in state necessary for C library functions being corrupted during early boot.  Thus, I began investigating under that assumption.  However, the linker script definitely had enough room (I allocated 0x200, where the datasheet shows that the final entry is only 0x1c4).  Just to be sure it wasn’t some other global memory corruption issue, I stepped through the first 5,000 or so assembly instructions of an snprintf call, inspecting all RAM that was accessed and making sure that it wasn’t corrupted.  I did notice that my 32 bit floating point value had been promoted to a 64 bit value when passed to snprintf, but didn’t think any more of it at that point.

Despite all that debugging, I found nothing of interest and turned to my choice of last resort, googling for the original symptom.  Usually this doesn’t find much, because the set of root causes for any one particular failure is so vast and many problems are the result of simple misconfiguration.  However, in this case, I hit the jackpot after digging through an hour worth of junk results.

The problem ultimately was one of stack alignment.

When I ported mbed to the stm32g4, I created the initial linker script from the STM32F446 that I had been using, but made the interrupt table bigger so that I wouldn’t have to worry about it at all.  However, I managed to goof it up and ended up with the top of the stack aligned only to 4 bytes, not 8 bytes.  Since 32 bit floats are promoted to doubles when passed through a variadic function, this resulted in the double being not 8 byte aligned when passed on the stack.

Once the problem was identified, the fix was easy enough:

STM32G4 for mbed

While working on the next revision of the moteus controller, I started by bringing up a software toolchain on a NUCLEO-G474RE board.  Unfortunately, even the most recent mbed 5.14 doesn’t yet support that processor.  Thus, I have a half-baked solution which pulls in the ST CUBE sources for that controller into the mbed tree as a patch.

https://github.com/mjbots/rules_mbed/blob/master/tools/workspace/mbed/stm32g4.patch

The patch only implements wrappers for the things I care about, so it isn’t a complete solution. Since I am not really using any mbed libraries anymore in any project, that isn’t a whole lot.  Right now I’m just using it for the one function that sets up the board, a linker script, and the pin mappings.  I will probably eventually just make a rules_stm32 and ditch mbed entirely but for now that is more work than it is worth.

 

OpenOCD for STM32G4

While bringing up an STM32G4 for the new revision of the moteus controller, I wanted to be able to flash and debug the system, and thus needed a working OpenOCD installation.  The NUCLEO-G474RE board has an ST-LINK-V3 debug interface, which no released version of OpenOCD supports, although thankfully that is working just fine at HEAD in git.  However, to make the STM32G4 work I had to pull some patches from the sysprogs/openocd tree.

My resulting work can be found at: https://github.com/mjbots/openocd

Hopefully the dependent OpenOCD gerrit review will eventually land: http://openocd.zylin.com/#/c/4932/ which will clear the way for getting G4 support into master there.

For now, I’ll just live with a custom compiled OpenOCD.

 

More VNC2 Toolchain Updates

FTDI once again updated their firmware, this time to 1.4.2. The release notes are promising. My goal for today is to try and validate as many of the fixes as I can. If enough of the regressions are fixed, the intended fix to USB host polling rates would actually make my device playable!

Update:

The 1.4.2 release did manage to fix the most glaring of bugs, most of the crashers and obvious incorrect behavior is now resolved: Issues Page. Even some of the bigger ones appeared to have progress made, specifically, the USB host polling rate problem. It did now appear that the host driver polled at 8ms for my device which requested a 10ms poll rate.

That was the upside. The downside was that for some reason the device only responded to every 3 out of 4 poll requests for data. (On my linux host, which also polls at 8ms, it responds to every single one). Additionally, something got broken about enumeration for devices which are connected at powerup that made enumeration moderately unreliable. That is a little bit ironic, given that I never had any problems with this before, and the release notes indicate that problems related to this were fixed in 1.4.2.

At this point, I’ve decided against freshening up my scope USB decoding skills again to see what the VNC2 library is doing wrong during enumeration or during the 1/4 interrupt IN polls that nothing comes in. Besides, rock band isn’t as popular as it was 8 months ago anyways. On to other projects, and maybe in a couple more years the VNC2 firmware will be usable enough to revisit.

VNC2 Firmware Update 1.4.0sp1

Two items of note: First, FTDI released a service patch to version 1.4.0 which looks to contain many bugfixes. Second, they’ve finally gotten back to me about the specific issues I have been having trying to use the firmware in my project.

This release looks like it did fix one of the issues I had (#11), although it was only a regression from 1.2, so it wasn’t one of my original showstoppers.

FTDI also indicated that a number of the other problems are scheduled to be fixed in a 1.4.2 point release due out in mid-July. Fingers crossed.

VNC2 v1.4.0 Redux

I worked through all the issues I had uncovered, testing each with the 1.4.0 version of FTDI’s toolchain and firmware. I can’t say a single one was actually fixed. The results by the numbers:

  • Fixed: 0
  • Still Broken: 6
  • Feature Partially Removed: 1
  • New: 4

Hopefully the next firmware update will actually fix enough that I can make progress again.

VNC Toolchain 1.4.0 Update

I was hopeful today when I discovered that FTDI had released a new version of their toolchain and firmware for the VNC2. As mentioned previously, I have been having a large number of problems with my rhythm controller adapter application, due largely to bugs and lack of features in the 1.2.2-SP1 version that had been current until today.

My hope lasted only a very short time.

The immediate problem I had been working on was with link-time optimizations producing bogus output. In 1.4.0, the GUI option to select link time optimization was removed, but the command line tool still supported it and produced corrupted output. Half points.

Then, as soon as I tried to reproduce the most critical of my issues I started having real fun. First, the compiler just segfaulted trying to compile my source. Then, once I had narrowed down the code which caused it to crash I fired up a new project so as to create the minimal reproduction recipe. However, the fresh project didn’t compile due to a trivial symbol mismatch in some FTDI generated code. Finally, after fixing that, I went to rename my reproduction recipe for transmission, and discovered that 1.4.0 started encoding absolute file paths into the .vproj files so that you can’t easily move or rename projects any more.

Ick!

Eventually, I will get around to testing all of my existing issues with the new toolchain, although it may take a bit as many of the FTDI provided examples have been re-worked to rely on the more advanced evaluation boards like the Vinculo, not my V2DIP2. At least that is my current theory, we’ll see as I dig in more.

FTDI VNC2 Binary Only Firmware

The rhythm game adapter work has basically been stalled for the last two weeks waiting on the microprocessor vendor, FTDI, to try and come up with any type of resolution for the problems I’ve found in their firmware. While they have been gracious to respond at all, until now the responses have been less than useful. If I had an alternate platform with the same properties that had open firmware, or at least a source license, I would switch to it in a heartbeat at this point.

First things first, I am using the VNC2 from FTDI for this project largely because it is the only part I have found that has both a USB slave and an independent USB host controller on the same chip. Plenty of microcontrollers have a USB OTG controller, but that only lets you use one modality at a time. For the USB HID proxying to work, you need to have both simultaneously. One alternative would be to use a micro with a built in USB controller, then an external serial interface controller to handle the other end. Or you could just use two USB enabled microcontrollers, like an AVR, back to back. My goal on this project was to keep the part cost below $10, so that it could be produced in large quantities. Unfortunately AVRs with enough memory to hold a reasonable USB host stack are much more expensive even in quantity than the VNC2, much less the fact that you would need two of them. As far as external USB controllers, you can’t seem to find any low/full speed external controllers that are any cheaper than an entire microcontroller

In the hope that someone has had similar problems and knows how to work around them, I am going to start cataloging all the problems I’ve had with the FTDI toolchain and firmware here on my website. If nothing else, that will give me a clear record of what they may have fixed in subsequent versions.

One thing I am considering, although hesitantly, is reverse engineering enough of the register level interface to the peripherals on the chip to fix the problems myself. As part of debugging some of these other issues, I’ve been hand assembling bits of code to patch interrupt vectors and their code. However, looking through binutils, it isn’t hard to guess that bringing up a brand new architecture with 0 documentation is likely to take several man months of effort, which is a rather large yak to shave for such a small project.