Compiling MMDVM Firmware for WA0EDA Modems


So there’s a new feature in MMDVM you say? Don’t want to wait for me to compile a new version for you? Never fear, I’m about to show you how to roll your own. To be clear, I’m talking about the firmware that goes onto the actual modem processor chip itself, the STM32F4xx microcontroller and not MMDVMHost that runs on the single board computer (NanoPi NEO or OrangePi Zero on older boards). This post is not about:

  1. Not a primer on using version control with Git
  2. Not about how to use stm32flash (that’s in the manual and another tutorial)

The first thing you’ll need to do is get yourself a fresh copy of the MMDVM firmware. Again, and I’ll probably say this at least one more time: This is the MMDVM modem firmware and not MMDVMHost. I’m going to recommend compiling it right on the WA0EDA Modem board itself, from the CLI. So get yourself logged in and ready to rock.

CLI on the STM32-DVM-MTR2K V1.0a after logging in.

My example system today is an MTR2000 loaded with an STM32-DVM-MTR2K V1.0a. Yep, the original modem that I only made 10 of (pretty sure all 10 are with KS-DMR and K1IMD). You only have to do this one time if you have more than one system. The resulting binary file can be copied to other modems. But that does bring up an issue: I’ve used both STM32F446RET6 and STM32F405RGT6 microcontrollers. While they’re extremely similar in specs and both work equally well for MMDVM, the compiled binary is different. you’ll need to know which one is on your board. You can read the part number on the chip, or look near the serial number of your board (written in black sharpie), it should have a “405” or “446” next to it… If you have an early enough board to not have a serial number it’s probably a 446, but take a look at that chip to be sure. The wrong version will successfully load onto the microcontroller chip, but won’t run correctly after reset.

The first thing we’re going to need to do is to install some prerequisite software packages for compiling the firmware. The Operating System images I’ve provided didn’t have all of these tools installed by default. Here’s a nice easy “copy and paste” version of what you need:

sudo apt-get install -y gcc-arm-none-eabi
sudo apt-get install -y libnewlib-arm-none-eabi
sudo apt-get install -y libstdc++-arm-none-eabi-newlib

Next we need to get a copy of the MMDVM source code. There will be more than one way to do this, but I’m going to clone the official GitHub repository with git, and work from there. I’ll do this from mmdvm’s home directory (and note, no sudo here).

git clone git://github.com/g4klx/mmdvm

You should see output similar to the following:

Cloning the MMDVM GitHub repository

Next we’ll change into the MMDVM directory, update the Config.h file for our needs. You’ll see me make a copy of the original so I can put it back if need be later. I prefer the nano text editor for most things, but you’re free to use whatever editor you prefer.

Customizing Config.h

Below are the contents of Config.h after I’m done editing. This isn’t the only possible configuration that will work – a few of the parameters are optional. I’d recommend sticking with what I’ve shown unless you really know what you’re doing; or download my Config.h here.

/*
Copyright (C) 2015,2016,2017,2018,2020 by Jonathan Naylor G4KLX
*
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
*
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
*
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
if !defined(CONFIG_H)
define CONFIG_H
// Allow for the use of high quality external clock oscillators
// The number is the frequency of the oscillator in Hertz.
//
// The frequency of the TCXO must be an integer multiple of 48000.
// Frequencies such as 12.0 Mhz (48000 * 250) and 14.4 Mhz (48000 * 300) are suitable.
// Frequencies such as 10.0 Mhz (48000 * 208.333) or 20 Mhz (48000 * 416.666) are not suitable.
//
// For 12 MHz
define EXTERNAL_OSC 12000000
// For 12.288 MHz
// #define EXTERNAL_OSC 12288000
// For 14.4 MHz
// #define EXTERNAL_OSC 14400000
// For 19.2 MHz
// #define EXTERNAL_OSC 19200000
// Use pins to output the current mode via LEDs
define MODE_LEDS
// For the original Arduino Due pin layout
// #define ARDUINO_DUE_PAPA
//#if defined(STM32F1)
// For the SQ6POG board
//#define STM32F1_POG
//#else
// For the ZUM V1.0 and V1.0.1 boards pin layout
//#define ARDUINO_DUE_ZUM_V10
//#endif
// For the SP8NTH board
// #define ARDUINO_DUE_NTH
// For ST Nucleo-64 STM32F446RE board
// #define STM32F4_NUCLEO_MORPHO_HEADER
// #define STM32F4_NUCLEO_ARDUINO_HEADER
// Use separate mode pins to switch external channel/filters/bandwidth for example
// #define MODE_PINS
// For the VK6MST Pi3 Shield communicating over i2c. i2c address & speed defined in i2cTeensy.cpp
// #define VK6MST_TEENSY_PI3_SHIELD_I2C
// Pass RSSI information to the host
define SEND_RSSI_DATA
// Use the modem as a serial repeater for Nextion displays
define SERIAL_REPEATER
// To reduce CPU load, you can remove the DC blocker by commenting out the next line
define USE_DCBLOCKER
// Constant Service LED once repeater is running
// Do not use if employing an external hardware watchdog
// #define CONSTANT_SRV_LED
// Use the YSF and P25 LEDs for NXDN
// #define USE_ALTERNATE_NXDN_LEDS
// Use the D-Star and DMR LEDs for POCSAG
// #define USE_ALTERNATE_POCSAG_LEDS
// Use the D-Star and YSF LEDs for FM
// #define USE_ALTERNATE_FM_LEDS
endif

There’s one more task before compiling the code. There are some submodules in the MMDVM GitHub repo that don’t download with the repository itself. We’ll need to get those with the following commands:

git submodule init
git submodule update

And the output in my terminal session looks like this:

Using git’s submodule system to get additional source code

That’s all of the prep work, we’re now ready to compile the MMDVM modem firmware with one of the two following commands – depending on whether you’re compiling for an STM32F446RET6 or STM32F405RGT6:

make eda446

or

make eda405

This will take a couple of minutes, and there will be gobs of text scrolling on your screen. There will be some that are warnings, but those can be ignored. The important part is that compilation completes without errors. You should have a screen that looks a lot like this if it works correctly:

Successful compilation of mmdvm_f4.hex

After this process completes, the file that you need is (full path):

/home/mmdvm/mmdvm/bin/mmdvm_f4.hex

I like to copy it out of the build directory and keep it in the mmdvm user’s home directory (/home/mmdvm), and if you use my update_modem.sh script, it’s easiest to do if you have the file there. If you’ve followed along with me, you’re still in /home/mmdvm/mmdvm, so from there you can simply do a:

cp bin/mmdvm_f4.hex ../
cd ..

and now you’re in the mmdvm user’s home directory and ready to program the modem. Remember, you must stop MMDVMHost before you can update the modem firmware:

killall MMDVMHost
./update_modem.sh mmdvm_f4.hex

The update process takes several minutes, and is documented both the the modem manual, and in another tutorial, so I won’t go too deeply into it here, but if it works correctly, you’ll something like this:

stm32flash successfully updating modem firmware

Remember, MMDVMHost has to be at least as new as the MMDVM modem firmware, or MMDVMHost will not be able to communicate properly with the modem – always check MMDVMHost’s log file to make sure it started up correctly (located in /var/log/mmdvm, and date-stamped). Keep in mind that when you update MMDVMHost, you don’t just need to update the binary, but any new stanzas changes in the MMDVM.ini file (located in /etc/MMDVM.ini on my image).

Have a question or comment?

Leave a Reply

Your email address will not be published. Required fields are marked *