Coming Soon: STM32-DVM-MTR2K V2.0

Rendering of the STM32-DVM-MTR2K PCB

After publishing the article MTR2000 and STM32-DVM-MTR2K: Analog + Digital, Playing Nice Together, the question almost immediately came up about availability and cost of MTR2000 Auxiliary I/O boards (CLN1206). Apparently, they’re not very easy to find, and can be prohibitively expensive. I said to myself, “How hard can it be to replicate the I/O functions of the Aux I/O board?”.

There isn’t a detailed service manual for the MTR2000, but the “Field Service Manual” sections on the Station Control Module (SCM, CLN1465) and Auxiliary I/O Board do provide an amazing amount of information on how these modules communicate. As it turns out, it’s a not entirely straightforward implementation (mode 3) of SPI (Serial Peripheral Interface). SPI isn’t the same as the typical serial port you find on a PC. I won’t go into details, but will note that it’s a synchronous serial bus with a single master device and one or more slaves. The master is almost always a microcontroller and slaves are typically hardware modules such as I/O expanders, sensors, memory devices, etc.

The driving force behind V2.0 of the STM32-DVM-MTR2K was to replicate the physical GPIO capability of the Aux I/O board, but there were a few other improvements too. The complete list is as follows:

  • Add an additional display connector from the SBC
  • Re-factor the analog circuit design (remove unnecessary components)
  • Add functions of the original MTR2000 Aux. I/O card
  • Create a virtual gateway between the SBC (NanoPi) and the SCM via the Aux I/O board GPIOs.
  • Provide expansion bus access for the SBC on the J5 System Connector.
Fully functioning “breadboard version” of the STM32-DVM-MTR2K.

Thanks to the detailed theory of operation description in the MTR2000 Field Service Manual, figuring out how the SCM and I/O board communicate was easy. Unfortunately, what they were “saying” to each other was not included in the manual. As luck would have it – rarely the case with Motorola – the pattern turned out to be quite straightforward and reverse-engineered without much trouble. The MTR2000 SPI bus uses 16 bit datagrams, separated into two 8-bit bursts (in the same transaction). The GPIs (General Purpose Inputs) and GPOs (General Purpose Outputs) are treated as two separate SPI slaves on the bus. Each “slave” consisted of a pair of serially connected 8-bit shift registers on the Aux I/O board. The MTR2000 manual, RSS, etc. lists GPIs and GPOs by number. In fact, these are sequential and simply duplicated in the bit positions of the shift registers. That is to say, GPO_2 (they start numbering at 0), for example, is the 3rd least significant bit of the 16 bit datagram. This is depicted in the image below.

Using SPI decode features of the Rigol DS1054z to “sniff” the MTR2000 SPI bus. Note the least significant byte is 00000100, or 0x04 in hex. This is the third least significant bit and indicates GPO_2 (GPO numbering starts at 0, making 2 the 3rd output).

The Motorola MTR200 Aux I/O card is all logic hardware. No microprocessor. To put in four shift registers and re-gain the hardware I/O would have been easy. But in addition to the physical I/O, I wanted to build a “virtual bridge” between the MTR2000 SCM and the NanoPi NEO which would allow the Pi to both read and set the GPIO lines, virtually. The NanoPi NEO is not able to directly do this via the MTR2000 SPI Bus, and it lacks the GPIO pin count necessary to interface with discrete digital connections for each GPIO from the MTR2000. It became clear I would need to add a dedicated I/O processor.

The NanoPi NEO is running a general purpose operating system. While the NanoPi NEO’s CPU (AllWinner H3) has a hardware SPI interface, the use case for this interface is as a master. As a slave there are some very critical timing events that are better served in dedicated processing. Adding a separate, dedicated processor has an added benefit of ensuring any real physical GPIO functions continue to work if the NanoPi is offline (during a reboot, on power-up, etc.)

I chose the Atmel ATMEGA 328P for the job: It’s under $2, I know it well, has great C/C++ support, and I can use the Arduino IDE for programming (and so can you!) What’s not to like? The ATMEGA 328P is typical of devices in it’s class and only has a single 8-bit hardware SPI interface. The challenge became getting a single 8-bit SPI interface to act like the 2 separate 16-bit SPI interfaces that the MTR2000 was looking for. Since microcontrollers are generally not used as SPI slaves there’s little information about using them that way beyond the manufacturer’s data sheet. There was none at all about making them work with 16-bit data and reconfiguring on the fly to act as two separate slaves. I was on my own to find a solution.

Segment of code in the ATMEGA 328P used as the I/O processor on the STM32-DVM-MTR2K, conveniently programmed in the Arduino IDE… though you won’t see any “digtalWrite” here.

I was triumphant! had I failed, you wouldn’t be reading this. As I type, the PCBs for V2.0a are in production at JLCPCB. I will be sharing all files for the PCB files, schematics, I/O processor software, etc. (look for my work on GitHub) I’m waiting to see the production PCBs work before I upload, but it should all be available within the next couple of weeks.

My goal with the V2.0 board was to both add new features, but also to create something of a blank canvas for others to expand on. Folks may wish to run their own custom code in the ATMEGA 328P to expand its capabilities or even the NanoPi’s. To that end, I’ve connected the I2C buses for both the Pi and the ATMEGA to the J5 System Connector on the back of the station (pads for I2C pull-up resistors are supplied). The NanoPI NEO and ATMEGA 328P communicate with each other over a standard asynchronous serial interface – I’m including the Arduino bootloader on the ATMEGA 328P as well, making it a snap to upload new code remotely. The only catch is that you can’t use the async port on the NanoPi for an MMDVM display AND have the NanoPi and ATMEGA 328P connected to each other. The ATMEGA can still be used, it just cannot communicate with the NanoPi in this situation. Not enough serial ports to go around – but the serial repeater through the MODEM is still available, and I can’t image too many folks wanting to run two displays on an MMDVM repeater.

Once again, I will be pointing folks to Scott Zimmerman over at Repeater Builder who want to buy this board with Scott’s full commercial production and support. I will be building and selling them directly as well, but I’m not set up to provide the full commercial support that Scott does.

Finally, I need to thank Keith Neufeld for the use of his Saleae logic analyzer. When I reached the point that my oscilloscope’s protocol analysis feature wasn’t enough, Keith’s logic analyzer made the job a whole lot easier.

Have a question or comment?

Leave a Reply

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