Recore is Finally Printing!

The new 3D-printer control board (Recore) that was started in 2019 is now mature and ready to start shipping to customers. We are now at revision A5, but the A4 was also working fine, it was just a few minor tweaks related to testability mostly.

But this blog post and accompanying video will be centered around porting Klipper to be compatible with the new Recore. Here is the video, the rest of this post we give some details that did not make it into the video.

Here is that block diagram of Allwinner A64 again for reference.

Normally a Single Board Computer (SBC) that runs Linux is not suited for real time operations. That is why a microcontroller is needed which is why you end up with a combination of regular 3D-printer control board and a Rasberry Pi. There are exceptions, for instance the BeagleBone family has a separate (Programmable Realtime Unit) PRU which solves this elegantly.

In Recore I wanted to get rid of that separate microcontroller and find a solution similar to what the PRUs on the BeagleBone is doing. The solution is to use the AR100 which is a bit of a quirky “microprocessor” embedded on the Allwinner A64. But it’s fast! It can run at 300 MHz. Finding a similar microcontroller as a separate device would increase the final price quite a bit without really adding anything.

As mentioned in the video, in order to use the AR100 for real time operations, and to make it work with Klipper, there were three problems that needed to be solved.

Toggle Pins Fast

If you try to toggle pins from Linux, you will be disappointed. It is very slow and unpredictable since the pin toggling events are handled by the kernel and the program is running in user space. Also, the event be handled only when the kernel sees fit which can take a while. But even if you set aside a separate core out of those 4 cores in the A64, you would still be hunted by some amount of unpredictability since the toggling even has to be propagated on the same AHB as most other media on the SoC.

By offloading those events to the AR100, we can get very good speed and predictability. The more we can stay away from the AHB dedicated to the AR100, the less jitter we experience on the toggling of those pins. More jitter will cause steps on the stepper motors to appear uneven and can in turn cause wobbling on the finish of printed objects. I’ve not done extensive testing on this, but it would be a very interesting experiment.

The experiment shown in the video shows the difference between toggling pins that are in one of the GPIO banks and comparing to pins that are in the R_GPIO bank. If you look at the chart above, the “path” taken for the AR100 to toggle the pins in the GPIO bank is a bit more crooked and running through two shared buses, one of which potentially has a lot of traffic.

Spectrum of GPIO bank pin toggling
Spectrum of R_GPIO bank pin toggling

Communication Channel

In an effort to offload as much traffic as possible on the AHB, I chose a somewhat unconventional way to set up communication between the main Klipper program running on Linux and the real time bit running on the AR100. The conventional way might be to use a shared memory area to “send” commands, since both CPUs are on the same die. Instead, I chose a loopback between a UART controlled by the A53 cores and an R_UART controlled by the AR100. I’m not burning any bridges here, the shared mem solution is still available in case anyone wants to try it and look at possible benefits and downsides, but now we have to option to do both.

A Timer for the AR100

The third and final hurdle was getting a hold of a decent timer for the AR100. There is actually a timer peripheral (R_TIMER) in the A64 dedicated to the AR100, but unfortunately it is not timed by the AR100 CPU clock at 300 MHz. Instead, it is timed by the main oscillator at 24 MHz. This meas that the timer does not have enough resolution to cause stepping in the exact moment needed. But there is another solution, a tick timer facility in the OR1000 ISA . In Klipper, the implementation becomes very simple and even though the program will have to keep polling to check if time matches, the CPU is mostly idle regardless, so it should not make a difference.

The R_TIMER is clocked by the 24 MHz oscillator
The TTCR (Tick Timer Counter Register) is clocked by the same clock as the AR100 CPU

More Work is Needed

Even though Recore now runs, the work on this started about a year ago, so the branch of Klipper that is was based upon is very outdated. Once Recore A5 is available in the shop, work will shift back to upstreaming the AR100 patches in Klipper so the work will be maintained. But at lest there is a way to print with the Recore boards, and that is a good starting point.

Like I mentioned in the videos, it looks like the AR100 is doing very well in terms of print speed compared to other solutions measured by Klipper.

This is a screenshot of tests run on an early Recore A2 board. The tests are from the custom fork of Klipper hosted in the Intelligent-agent github repository.