STM32 based Ethernet I/O for LinuxCNC

Updated 27th Jul 2015

I've been a more or less active LinuxCNC user for maybe five years now. I've found it absolutely excellent for my purposes of controlling cheap, crappy DIY CNC machines I've built. The only annoying thing has been the hardware requirement of parallel port, so finding an alternative has been in my mind for a long time. I know that Mesa FPGA cards would be the de facto solution, but as a Do-It-Yourself guy, I've been dreaming of designing something myself. There seem to have been couple of trials in making realtime ethernet interfaces for LinuxCNC but documented, working solutions doesn't seem to exist. So after seeing the recent development in "uspace" realtime in LinuxCNC 2.7 and work being done with Mesa's ethernet cards, I finally got encouraged to try something on my own. I decided to do a quick webpage on the current status if someone happens to be interested.

The first version of my test board has an STM32F407 microcontroller with built-in ethernet MAC (10/100) attached to DP83848 PHY on an additional breakout board. Additionally the board has some levelshifters to obtain 5V IO (40 IO pins in total), some voltage requlators and basically that's all. The nice thing of this solution is that the full bill of materials for this kind of board, with the ethernet integrated to the main PCB, if produced in reasonable batches would propably cost less than 20 dollars. With zero experience on mass production of PCB's, that's just a guess though.

Partially assembled test board (click for full size)

On software side, I've written the embedded software for the uC based on a networking stack written by Andy Brown (see GitHub). The communication is done over UDP protocol with a custom message format. On the PC side, my HAL driver can be compiled either for realtime (2.7 uspace only) or for userspace (tested with both 2.7~pre6 and 2.6.8). On realtime, it exports write and read functions which can be added to the servo thread. On userspace, the read and write are done within the driver's main loop with predefined update rate. I wanted to have it working for both rt and non-rt tasks, because when using the board to provide only some low-priority IO such as human interface, pendants, coolants etc., the userspace is propably the best place to run the software. The configuration of the board happens during startup of LinuxCNC, when a configuration file is read and that determines the wanted configuration (HAL pin names and corresponding pin numbers in board basically). The configuration is sent to the board which then configures the pins as inputs and outputs correspondingly. The IO is divided into banks of 8 bits because of the levelshifter ICs. In a single bank, there can be either inputs or outputs but not both.

The IO types currently supported are

Currently the board and software are in the state where my projects usually end. That is, they work, but they are not pretty. :) Seriously, all the IO types seem to work, though I've tested the Encoder and Stepgen with only one instance of each and I don't know how the microcontroller would handle the interrupt rate with five step generators running at full speed.. My next plan is to design and mill an enclosure for the board, a jogwheel and couple of buttons and make a pendant to be used with my existing parallel port machine.

The biggest problem at the moment for really using the board for serious realtime operations is latency. When compiled for realtime and used with 2.7~pre6, the read operation which basically sends a 2-byte packet to the board and receives the current status (5-50 bytes depending on how much IO is configured) as a response, takes 500-600us. I consider that being too much for running the servo thread with 1kHz. By reading old LinuxCNC discussions and some theory, the operation should be able to complete in, say, 300us. I still need to investigate if the biggest bottleneck in the latency is my test PC, the STM32 hardware or the stack implementation inside. Despite that, running small stepper motor with crappy StepStick driver seemed to work quite well. But a lot more testing is required.

If you are interested, I'm happy to share any details. Of course, the software wont be very useful as such without exactly the same hardware, but if you are doing something similar, some parts could be helpful. I'm not at all a software engineer (I design analog electronics by profession), so the code isn't propably production ready as such. :) All the software will be under GPL if published because I've derived things from sources of LinuxCNC especially in the stepgen part. Big Thanks goes to the original authors.

I'm propably updating this page if something new gets done. You can contact me by email pekka (at) roivainen.eu

Cheers,
Pekka