I wanted to share an Mbed-based open-source project I’ve been working on for a while and plan to release in the coming months.
The driving force behind this project is, of course, a larger project…
I am restoring a 1973 GMC MotorHome (similar to what’s pictured below):
It’s been in my family since new and I’d love to get a few more decades of camping trips out of it while gasoline is still available
(You can skip the next few paragraphs if you’re not interested in the backstory)
I’m an automotive enthusiast and enjoy restoring classic cars in my free time. I wanted to update this MotorHome while keeping the retro style that defines it… So I’ve decided to completely redesign the electrical system for fun and professional practice!
When it comes to classic cars, I appreciate originality. So the mantra of this whole project is “modern but discreet”. I’m making custom-fit solutions as needed to retain as much of the original controls and instrumentation as possible, while adding modern features that rival those of brand new vehicles! I have a number of discreet updates planned.
Among them are a number of custom distributed sensors throughout the vehicle, like tire pressure monitoring, an auto-leveling system for the rear pneumatic suspension (air springs), a pressure-monitoring system for the same, outside ambient temperature… the list goes on.
I also plan to build a custom, Mbed-based engine computer to control the electronic fuel injection system I am replacing the carburetor with. This would allow me to add metrics like MPG, engine oil pressure, temperature, etc…
Below is a (somewhat outdated) overview of my planned vehicle system. There are a few new ideas I’ve had that I will mention in a future post
What good is all this information without something to display it all on? While I’m keeping most of the original analog gauges, I am going to add a digital gauge cluster (LCD) to be able to display all this new data.
This is the project I am describing in this post!
Much of the inspiration for this design has been from my Jeep Gladiator’s digital gauge cluster shown above
I call it: Marquesas. For reasons I will cover in a different post somewhere, I am naming all the boards for this project after islands (specifically the Florida Keys).
Marquesas is my custom Mbed target based on an STM32H745BI microcontroller
That would be this big boy ($15 in single quantities! Try not to fry it…)
Tech Specs Overview:
- Dual-Core 208-pin LQFP (for hand-solderability)
- Cortex M7 running at 480MHz (!!!)
- Cortex M4F co-processor running at 240MHz (also !!!)
- 2MB Flash, 1 MB internal RAM
- 5-inch 800px X 480px IPS TFT LCD screen with 24-bit RGB bus
- External 8MB SDRAM, primarily intended for the display buffer and image scratch space
- External 64MB QSPI Flash for asset storage (images, audio, etc)
- External SD Card slot using SDIO for a debug filesystem, more assets and images
- USB 2.0 High Speed (Device only)
- I2S Audio DAC for chimes and audible alerts
- CAN transceiver, compatible with CAN-FD (up to 8Mbps)
- 4 high current (3A-5A) low-side output drivers with integrated diagnostics (STM L9349-LF)
- 12-Channel protected low-side driver with integrated diagnostics and SPI control (NCV7751)
- 8-channel, protected high-side OR low-side driver with integrated diagnostics and SPI control (NCV7608)
- Fully digital 32-step backlight brightness control (TPS61165 with EasyScale protocol)
- Triple high-speed, self-protected low-side drivers (intended to drive old-style resistive analog gauges by PWM)
- Up to 12 fault-protected analog inputs allowing the board to read sensors like thermistors and photodiodes
- 13 fault-protected digital inputs to interface to switches, buttons, and existing OEM electronics.
- Ability to support a resistively-multiplexed joystick for UI navigation
As I said, I’m planning to release all this as open-source. I haven’t had the time to put together anything resembling project documentation yet though
Here’s a picture of the board in my preferred EDA CAD, DipTrace:
It’s a pretty extensive design, my most complex ever personally. I am mainly a software engineer but I like doing my fair share of hardware design. It’s much more rewarding to write code for hardware you’ve built from the copper up
I based a lot of it off the Discover H745/H747 boards. It’s only 4-layers but there are a lot of traces. I even got to play a bit with DipTrace’s high-speed routing features!
Last month I got prototypes in from JLCPCB:
I built one up with a stencil…
and hours of careful hand-placing…
I ordered the wrong size op-amps!
After fixing some solder blob shorts and probing the board a bit… I finally applied power (with a current limiter of course). No smoke! The MCU was unprogrammed so nothing interesting was going to happen at this point.
I pulled out my JLink and attempted to connect over SWD. It was a success! My JLink was able to see both the CM7 and CM4 cores of the H745!
The next step was to get Mbed OS up and running on the board. I started with the code in the H747 target folders and went through the CubeHAL files with a diff tool (Meld, in my case) to see what was different between the H745 and H747. The main difference I found between the H747 and H745 is that the H745 doesn’t have a MIPI-DSI interface like the H747. Having a reference target with the same HAL was nice in this case and was much easier than when I added support for the STM32G4-series to mbed-os (almost merged!)
The intent behind the dual-core MCU is that the M7 can run an application with all the UI code (way more surface area for potential bugs) while the M4 handles real-time functions like collecting data from other ECUs over the CAN bus, reading attached sensors, driving analog gauges, among other tasks. This makes it easier to harden the CM4 application handling all the critical functions of the gauge cluster.
After doing a couple STM32-based targets, I find it much easier to port new MCU product lines than other silicon vendors. This is largely thanks to STM’s nice HAL SDK and CubeIDE tools.
I wanted to share my port of mbed-os to the H745-series with other users of Mbed. My pull request to add the H745 series recently got merged !
After finally getting something to build properly, I uploaded the first test program: classic blinky. A bit of reconfiguring and debugging later, I got blinky to run on my board!
There are few things as satisfying as the first time an LED lights up on a new board design… let alone a new Mbed target!
I quickly got to work on the next stages of my porting process. I wanted to be able to use the external 8MB SDRAM in the linker script so I could reference symbols in that region at compile time. Using an H7Cube example, I determined how to configure the FMC peripheral to interface to the SDRAM. I added a hook early on in the code startup sequence so no illegal accesses of the external RAM would happen before the FMC was ready.
After that, I wrote a simple RAM write-read test program. It took a bit of fiddling with the delay settings but I finally got the SDRAM working reliably! With a 32-bit data bus @ 90+MHz, it is extremely fast (as far as MCUs go )
Next up was getting the display lit up. I have used TI’s nifty (and highly under-rated/utilized) EasyScale protocol before. It’s a simple 1-wire digital interface available on some of their backlight LED driver chips.
I pulled in my employer’s open source repository (ep-oc-mcu). This repository is a sort of catch-all for Mbed-OS-based drivers and embedded utilites of a non-proprietary nature that my coworkers and I create. Much of the code I use in personal projects I contribute back to this repo, including the EasyScale API I wrote and the drivers for this board.
Anyway, I already had the EasyScale driver written, so getting the backlight on was a piece of cake.
The last major hurdle in developing the board support package (BSP) for Marquesas was getting the LCD displaying something… ideally a UI of some sort.
I read some posts about the similar STM32F4 LTDC peripheral and configuring it for different LCDs. It was pretty similar to setting up the FMC, mostly just fiddling with delays and timing parameters. Point the LTDC to a (800 * 480 * 4-byte = ~1.5MB) buffer of RAM and let it rip! Of course, the LCD will show meaningless static pixels unless you write something to the display buffer… Eventually I got to this:
… Not quite what I was trying to display. It was supposed to be a solid cyan color! So I double-checked my LTDC settings and got this:
Much better! After getting the display working, it was very easy to add another project of mine to handle drawing the UI. I am a huge fan of the embedded graphics library LittlevGL. It’s a completely free and open source project that is entirely written in C, is highly portable, and has a bunch of built-in UI elements. It was developed from the ground up for embedded… and so you can configure it to be very compact in terms of ROM and RAM usage (80kB, 12kB RAM, maybe even less!)
My (admitedly scarce) framework for Mbed + LittlevGL can be found on my GitHub here. It makes the dead-simple process of adding LittlevGL to your project even dead-simplerer.
In my case, I’m using a memory-mapped frame buffer so I can just point LittlevGL there and it will draw the UI into RAM. The LTDC handles automatically transferring this frame buffer to the display. My framework also supports displays over a variety of interfaces like SPI using a related project, uDisplay.
I’ve been planning to write a tutorial post about using LittlevGL with Mbed for some time… so stay tuned for that if you’re interested.
Anyways, you pretty much just tell LittlevGL where your frame buffer is and give it a ticker to execute periodically on. Adding the UI library took all of 20 minutes. The result is shown below:
A hello world button. The most intuitive user interface.
I haven’t uploaded this example program just yet because it’s pretty much a scratch pad for me at this point. I do have the BSP and custom target uploaded to GitHub here so you can check out how I configure the custom H745 target and initialize the external SDRAM and display.
You’ll note the board says “Marquesas NFF” – this is what I call a “Non-Form Factor” board. The end design will probably have some sort of enclosure and automotive-grade connector instead of screw terminals. So the board is still in development.
My primary goal is to use this for my MotorHome project. However, there are a number of open-source ECU projects out there (Speeduino, RusEFI, MegaSquirt is kind open source) but I have not seen any open-source digital gauge clusters!
So I would also like to be able to offer this as a finished board (maybe a DIY kit for the adventurous, even) to the broader DIY automotive community.
Let me know if you’d be interested in getting a board and/or helping out with this project!
Thanks for reading if you made it this far!