Hard Fault Life
HFL
Tiny Telco, Part 3
Taking a Fork In The Road
This is the third entry in a series on my “Tiny Telco” project. I’m designing a compact, modular, hobbyist-friendly telephone exchange. The resulting device will allow me to connect my vintage computers together via their dial-up modems. I’ll probably also connect some phones to it, just for fun.
This post is a quickie. I will follow up with Part 4 in the next week or two. There’s a lot to talk about, and it didn’t make sense to combine everything into one post.
By the end of the last post, I had an adorable little circuit that made a phone ring with a pair of 555 timers. I also had an Arduino driving a PWM signal into a multiple-feedback band pass filter, which produced dial tone. Since then, I designed a simple breakout board for the KS0835F SLIC:
I’ve named this board SimpleSLIC. The KiCAD project is available here. It’s the same circuit as this perfboard prototype from the last post, but tidier and with a proper RJ11 connector. These boards will probably be a part of the final design! With the minimum order quantities and high per-area costs of PCBs, it’ll be more cost-effective for the final design to consist of several small, identical boards, instead of one big board.
With the SLICs out of the way, the next step was to detect the touch-tone dialing signals from the phone. My plan was to use a vintage MT8888 DTMF decoder chip for this task, since the Arduino can’t run FFTs fast enough to decode touch tones on its own.
But then, I went down a rabbit hole. I decided to experiment with a totally different approach to this project. Instead of using an Arduino and a flotilla of supporting chips, what if I just used a more powerful microcontroller that could do everything by itself? To nobody’s surprise, you can absolutely do that, and it’s not even difficult.
Nearly all of my work so far can be rendered pointless by the big fella above. That’s an ST Nucleo-F722ZE development board. It features a 216 MHz Cortex-M7 and 126 I/O pins. This board costs less than a name-brand Arduino Uno R3, but it’s an order of magnitude more capable.
In only two weeks with the Nucleo-F722ZE, I was able to go from zero to:
- Three tone generators working simultaneously. The Arduino can only do two.
- Two FFT-based DTMF decoders working simultaneously. The Arduino can’t calculate FFTs fast enough for even a single DTMF decoder.
- Enough ringer and hook-status signals to drive eight phone lines. I have the Arduino doing four, with a lot of help from discrete logic chips.
I must emphasize that the Nucleo is doing all of this with only the bare minimum supporting parts: some CD4066 switches, and a couple active filters for the tone generators and DTMF decoders. Here’s what I’ve had to do to get half the Nucleo’s abilities with the Arduino:
That picture should sum it up. Compared to the STM32, the Arduino-based approach is more expensive, more complex, and less capable. It is worse by every objective standard. The STM32 would be a no-brainer if I was designing a turnkey consumer product. But that’s the thing… I’m not designing a turnkey consumer product. This is a tough call, but I’m actually going to move the STM32 to the back burner and return to the Arduino.
When I decided to become an embedded systems engineer, I was agreeing to turn my hobby into my profession. It’s one of the best decisions I ever made. But, I have a bad habit of letting my profession leak back into my hobbies. I want this thing to be useful to other folks besides me, and that means making a design that’s accessible to other hobbyists. An STM32 running bare-metal firmware, built with Makefiles, and loaded via SEGGER J-Link isn’t a particularly accessible design. Meanwhile, Arduino is easily the most accessible platform for embedded development.
There are other benefits, too. The Arduino’s ATmega328P microcontroller is a through-hole part, meaning it can be hand-soldered by a novice. The beefiest STM32F7 is the LQFP144 package, as featured on the Nucleo board pictured above. It’s definitely possible to hand-solder LQFP parts; drag soldering is your best bet, but you’ll need the right tools and some experience. If you can drag solder a 144-pin LQFP without swearing, you’re better at soldering than I am.
I also like the aesthetic of all-through hole designs. Should this matter? Maybe not, but it’s my project.
The STM32 gave me an opportunity to work ahead of where I was with the Arduino. I was able to develop and validate the business logic of a telephone exchange, without stopping to fight with the Arduino’s limitations. I learned an important lesson along the way: The state machine of a telephone switch is much simpler when you consider it from the point of view of the interconnects between the SLICs, rather than from the point of view of the SLICs themselves. The Arduino code I had written out was very heavily “card-oriented.” After the STM32 adventure, I was able to return to the Arduino code and simplify it.
The STM32 code also serves as a convincing proof of concept for a modern, open-source, production-grade telephone interconnect. It’s not surprising that it works; it’s a 216MHz RISC processor with an FPU, of course it does FFTs really fast while also doing a dozen other things. What’s truly remarkable is that, in my rudimentary performance profiling tests, it doesn’t appear that I’m remotely close to the Cortex-M7’s limits. Remember, DTMF decoders and tone generators set the ceiling for the number of people who can be dialing at the same time. They don’t set the ceiling for the number of simultaneous connected calls. I’d wager that you could build an adorable little PBX around my code for the STM32F7. Perhaps I’ll do that in the future, but first things first. I’m going to start small, and that means starting with the Arduino.
The STM32 code is available here. It’s nowhere near finished, and I’ve made no effort to tidy things up. I’m not abandoning it, though. That code is doing some really cool stuff, like convolutions and DMA double-buffering. I plan on returning to the STM32 once I finish the Arduino version. The STM32 will allow me to take this project to heights that the Arduino simply can’t handle.
The Arduino presents a lot of challenges that the STM32 doesn’t. The tone generator hogs most of the Arduino’s limited processing power and memory. The MT8888 was designed to interface with the classic Intel multiplexed address/data bus. This restricts what I can do with the Arduino’s limited I/O. Other parts of the system will have to be built to interface with this bus. The resulting hardware design is more complex, but also more fun. If you were wondering what all of those breadboards were for, don’t worry. The next post will detail the Arduino-based hardware architecture.


