Wednesday, June 26, 2013

Using a BeBoPr with a BeagleBone Black

There are some problems using the BeBoPr with the BeagleBone Black.  The first issue is you cannot use the serial port header if you have a cape plugged in.  This is not specific to theBeBoPr board and affects all capes. I saw someone making a friction fit right-angle connector to solve this issue, but the easy solution is to just make the headers longer using stacking connectors.

Problem: Serial connector hits cape

Problem Solved!

I design electronics, so the nice folks at Samtec sent me a few stacking connectors as samples, but they are available for low-volume purchase as well.  Official connectors from the BeagleBone SRM are also available via the Major League BeagleBone store:
Samtec SSQ-123-03-T-D
Major League SSHQ-123-D-08-GT-LF

The next issue is BeBoPr specific.  Since the BeBoPr was designed for the initial BeagleBone white, it happens to overlap with the HDMI and eMMC pins.  Even worse, the two board enable signals are mapped to eMMC pins that are active during boot, meaning if you have a machine hooked up it could exhibit strange behavior while the BeagleBone Black is booting.  One solution is to *REALLY* make your BeagleBone Black behave like a White, but this requires changing boot resistors soldered onto the board and using a custom-built device tree.  The easier solution is to apply the ECO developed by the board designer that moves the enable pins away from the eMMC pins that wiggle during boot.  Note that my mod does not look exactly like Bas' because I tied pins P8.5 and P8.7 together on the stacking connectors instead of on the BeBoPr, but it's the same mod.  My LinuxCNC configuration is setup to drive both the old and the new enable pins, so it should work regardless of which 'Bone you're using and whether or not you've applied the ECO.

Finally, the BeBoPr does not have any provisions for connecting additional circuitry, such as a character LCD or an encoder as typically used in an Arduino based 3D printer as a stand-alone interface.  You could solder wires directly to the 'Bone, BeBoPr, or the stacking connectors.  However I recommend a breadboard cape, the very cool breakout cape (which also solves the problem of the serial port header interference), or since the 'Bone headers are on a 0.1" grid, just do what I plan on doing and use old-school perf-board from the 'Shack (get whatever size you want, there are several choices).  NOTE: For everything but the breakout cape, you will probably have to cut/trim/drill to provide clearance for the serial header and possibly the parts on the BeBoPr board.  Break out the Dremel!  :)

Stay tuned, I may be adding a section on getting HDMI working with the BeBoPr, but that will require moving a lot of pins.

Monday, June 24, 2013

BeBoPr Group Purchase

UPDATE: All the BeBoPr boards I purchased have been sold and shipped out.  If you are interested in obtaining a board, please contact Bas directly.

Since the BeBoPr boards are not readily available yet via the usual outlets (they've been back-ordered at Mouser for ages and CircuitCo doesn't seem to have a production run scheduled in the near future) I am coordinating a group purchase of some assembled boards remaining from the initial sample run directly from the board designer (Bas Laarhoven) to save on shipping costs and overall hassle.

Most of the boards are spoken for, but I am buying a few extras. If you are interested in obtaining one, please contact me directly.

List price is EUR 107 each FOB Europe, but I hope to be able to come in at or under that including shipping by doing a group buy. I should have final pricing in a couple of days, once shipping and currency conversion has been dealt with. I also have some technical details I can provide if you're interested.

The boards are on their way across the ocean.  If you want one, the cost is $135 including priority mail shipping.  Contact me directly via e-mail if you're interested:

Sunday, June 23, 2013

Force BeagleBone Black HDMI Resolution

UPDATE: You may find the modedb documentation helpful, in particular note you can add an 'M' to the settings below to force a non-standard resolution, and an 'e' to force the HDMI output to be enabled.  I also have another post on setting a custom resolution.

A lot of people seem to be having problems with the HDMI output on the BeagleBone Black (myself included, when I tried it...I usually live at the serial console).

While the newer image releases seem to be improving the operation of HDMI "out of the box", the auto-detection software always seems to pick some crazy resolution with my HDMI monitor and things just don't work properly.  If you don't see HDMI output or are still having problems with the latest images (like the display disappears once the 'Bone has booted), you can try forcing your resolution to something your monitor supports.

ALL HDMI monitors are REQUIRED to support 640x480@60 and one of 720x480@60 (NTSC) or 720x576@50 (PAL) depending on their native format.  If you force the 'Black output to one of these formats, you should get a working HDMI display.

To force the resolution, you need to add a kernel command line parameter in the uBoot file on the FAT partition of the SD Card (or in the eMMC boot partition if you're running out of the on-board memory).

The kernel command line parameter you need to pass is one of:
...and typically you would add this to the optargs= setting to get it passed to the kernel, ie:
Note that you can edit the uEnv.txt file on a Windows machine if you boot from an SD card, just be careful not to change the line endings.  If you're stuck with a 'Black that doesn't display an interface, upgrade to a recent Angstrom release and you'll at least have a serial console via USB you can use to edit the uEnv.txt file in the on-board eMMC.

If your HDMI is still not working, you can verify you got the setting actually passed to the kernel by looking at the kernel command line in /proc.  Here's mine (from a Debian based SD card boot):
$ cat /proc/cmdline
console=ttyO0,115200n8 video=HDMI-A-1:640x480@60 root=/dev/mmcblk0p2 ro rootfstype=ext4 rootwait fixrtc ip=
...if you see the "video=..." section and HDMI still isn't working, something lower level is wrong.

Once you get HDMI working at all, you can start to play around and see if you can get a higher resolution to work.  The 'Bone can't handle full 1080p60, but 720p should work on almost any modern HDMI display:
NTSC (North America, Japan):

PAL (Europe):
...configuring your HDMI display to disable overscan so you can see the entire image is left as an exercise for the reader!  :)

Note that my Samsung monitor/TV only disables overscan on one of the two HDMI inputs, and you have to set the source name to "DVI-PC" or it assumes you're feeding it from a video source and stretches the image a bit to get rid of any garbage at the edges.


All of the above only applies to what you see while the kernel is booting and simply verifies your monitor and BeagleBone will communicate properly.  Once the kernel boots, the BeagleBone launches a Gnome session which takes over full control of the display and picks it's own screen resolution.  My system typically defaults to 1080p24, which the BeagleBone can handle (vs. 1080p60, which requires a higher pixel clock frequency than the 'Bone can generate).

One issue I have had with the 'Black is if you do not have a keyboard or mouse plugged in, the system immediately goes into a power-saving mode and shuts down the HDMI output to turn off the monitor.  This apparently only happens if Ethernet is connected, which sets the system clock via NTP on boot (and makes your BeagleBone think it has been sitting idle 13+ years waiting for user input!).  You can disable the monitor power management for good via the graphical configuration settings in the GUI, or temporarily by giving the frame buffer a "wake up call" and telling it to come out of blanking:
echo 0 > /sys/class/graphics/fb0/blank
Obviously you have to do this from a serial console or an ssh session, and you'll need a mouse hooked to the BeagleBone temporarily to disable the display power management for good.  Once power management is disabled, you can remove the mouse and your display will stay alive on subsequent boots.

If you know a way to use the command line to disable Gnome monitor power management or force a particular display resolution, let me know in the comments.

Sunday, June 16, 2013

Creating SD Image Without a Linux Machine

If you have a BeagleBone and want to play with my MachineKit image but are stuck on Windows without a handy Linux system (other than the 'Bone itself), I've created a page with instructions on how to do it.

You will need a USB Hub, a 4G or larger USB Key, and a USB SD Card Reader in addition to the uSD card itself, your BeagleBone, and a Windows system.

I went through this process because someone reported problems extracting the tar.xz file using a USB key on the BeagleBone, since they didn't have a conventional Linux system handy.  As long as you untar the image file on a system with lots of disk space and memory (the xz compression uses a lot of run-time resources, and most BeagleBone systems aren't setup with swap), the BeagleBone can be easily used to run the extracted script and make a working image.

The excellent 7-Zip archiver utility can be used on Windows to extract the tar.xz file onto a USB key, which can then be hooked to the BeagleBone, where you can run the script and actually create the image.

Saturday, June 15, 2013

Temperature Conversion Working

Thanks to python and the flexibility of LinuxCNC, last night I was able to throw together a routine to convert ADC readings to temperature, add a PID loop to control the extruder heater, got the M104 temperature set command working, and add the current and set temperature values in a custom panel on the GUI interface:

I still need to tune my PID settings (it's working pretty much just like the bang-bang controller I was using, as I have no I or D terms, and not enough P gain), but that's for another day. If you want to check out the new code, just grab it from the repository. The linuxcnc directory on the image is a full git clone so all you have to do to update is:
cd ~/linuxcnc/src
git pull origin
sudo make setuid
The compile step is optional for this update, as all that really changed is some configuration files, but the above is generally how you would track updates on the development branch.

I have also several of the GUI interfaces that come with LinuxCNC.  The default axis interface is currently a CPU hog, and will need to be switched to something with better performance (or perhaps whatever is chewing up cycles can be identified and fixed).  The gscreen interface currently suffers from the same problem, while the tkemc interface is light on CPU cycles, but somewhat harder on the eyes.  A customized interface for 3D printing is on the list of features to work on, but I'm more of a low-level guy.  Holler if you'd like to help out!

Friday, June 14, 2013

Machinekit Image Available

See the MachineKit page for the latest version and updates!

After spending some time struggling with the new Linux 3.8 kernel and device tree overlays, I now have a Linux 3.8 build working as well as the 3.2 build.  Even better, I spent quite a bit of time setting up automated builds, and can now generate a customized Debian install that runs LinuxCNC "out of the box".

The images are named "machinekit", and they are built from scratch using a modified version of Robert C Nelson's omap-image-builder scripts.  If you don't want to pull the build scripts and make your own image (warning: it takes quite a while), you can just download the pre-built image.  Since my images are just tweaked versions of the rcn Debian release, the instructions on apply.  For the impatient or link challenged:

tar xJf debian-7.0.0-machinekit-armhf-2013-06-14.tar.xz
cd debian-7.0.0-machinekit-armhf-2013-06-14
sudo ./ --mmc /dev/sdX --uboot bone_dtb

Username: linuxcnc
Password: linuxcnc

md5sum debian-7.0.0-machinekit-armhf-2013-06-14.tar.xz
305aeda1edd4637ea4b284f9e982fdb9  debian-7.0.0-machinekit-armhf-2013-06-14.tar.xz

When you first boot the image, be patient.  It regenerates ssh host keys on the first boot and it will take a moment to become visible via ssh.  Ideally, you should monitor for progress and errors via the serial port.

Once the image has booted, login via ssh with X11 forwarding enabled, or set an appropriate DISPLAY environment variable (pointing to an open remote X server) and run linuxcnc.  Select the BeagleBone -> BeBoPr configuration, and follow along with the video if you are unfamiliar with the LinuxCNC Axis interface.  If you don't have a BeBoPr board, you can still watch the step/dir lines toggle on an oscilloscope.

WARNING: While I have an analog input working and reading the thermistor, the temperature control logic is extremely crude.  I do NOT recommend connecting your hot-end heater and trying to print unless you REALLY know what you are doing and are prepared to manually disconnect your hot-end if something goes wrong.  Currently, the temperature logic is just trying to slave to an ADC value that is set in the BeBoPr.HAL file (but can be changed on the command line using halcmd or via a python HAL script if you know what you're doing).  I expect to get the conversion to actual temperature and the various temperature M1xx codes working before long...stay tuned.

Close up of the BeagleBone Black / Linux 3.8 print from the video:

Monday, June 10, 2013

Black is White is Grey

Got a BeagleBone Black and a cape for the white that uses the eMMC signals?

Bas Laarhoven has verified a fix for turning your BBB into a BBW (or perhaps that's BeagleBone Grey?).  Details are in the Google groups thread (scroll to the bottom for the fix), and summarized here:
  • Find the mmc2 section in the BeagleBone Black device tree and change
    status = "okay"
    status = "disabled" 
  • Add "gpio set 52" to your uboot configuration to put the eMMC chip in reset at boot time
  • Enable the eMMC hardware reset pin.  This is a one-time configuration (it survives power cycles and cannot be changed once enabled) you can perform with either uboot or the mmc-utils program.
This gets the run-time behavior of your BeagleBone black matching the original BeagleBone  White, but there is still a boot-time difference.  As shipped, the Black will attempt to access the eMMC card as the first boot device, so if you cannot tolerate ANY transitions on the eMMC lines, you need to modify the boot configuration.  By moving one resistor (R68 to R93), you can pull SYS_BOOT2 low (same as pressing the uSD boot button) and the 'Black will not try to communicate with the on-board eMMC card.  It WILL, however, attempt to boot via SPI and twiddle pins on P9.

If you want to completely mimic the original BeagleBone boot behavior, you need to swap four resistors on the 'Black, or otherwise set the proper boot mode via the LCD_DATA pins on P8.  Details of what needs to be setup:
  • SYS_BOOT0 = 1: Move R95 to R70 or pull down LCD_DATA0 during reset
  • SYS_BOOT1 = 1: Move R94 to R69 or pull down LCD_DATA1 during reset
  • SYS_BOOT2 = 1: No change needed, leave R68 alone
  • SYS_BOOT3 = 0: Move R67 to R92 or pull up LCD_DATA3 during reset
So now you can turn your BeagleBone Black into a BeagleBone Grey and make it fully hardware compatible with the White (well, except for the more memory and faster CPU bits!).  All you need to do is find appropriate drivers or software to deal with the new 3.8 kernel changes.

Oh, and if you're worried about wasting money on the on-board eMMC card, don't be.  Even if you disable the  eMMC card at boot time via the resistor mods it's not gone.  You can still load a device tree overlay and start talking to it (assuming you don't have a conflicting cape plugged in).  If you are leaving 'Black booting from the on-chip eMMC, just tweak uEnv.txt and pop out your SD card and you're back to full Black, booting from the on-board flash.

Wednesday, June 5, 2013

BeagleBone Black, Linux 3.8, and Device Tree

I have been working to get the hardware side of things running under the Linux 3.8 kernel with device tree, which is pretty much required for the BeagleBone Black.  Since LinuxCNC requires the Xenomai patches, and there is a known bug with these patches on the Linux 3.2 kernel, even the BeagleBone White will need Device Tree support in the near future.

Anyway, I have successfully gotten the PRU and GPIO ports functioning as required under Linux 3.8, using a device tree overlay.  The pins that conflict with the on-board MMC on the Black have been commented out, as I am not yet sure the MMC is held in reset if you don't load it's driver.  If you would like to try out the device tree overlay, you can do so without the full LinuxCNC install.  The general procedure is:
  • Add "capemgr.disable_partno=BB-BONELT-HDMI" to your Linux kernel command line in uEnv.txt.  If you're using an SD card, this should be reasonably straight-forward.  If you're booting the Black from it's on-board MMC, it seems to have a default compiled-in configuration you need to over-ride somehow.  I don't currently know how to do this...if you have any details, let me know!
  • Reboot your system, and verify the HDMI cape is not loaded.  It will still show up in the slots file, but there won't be an "L":
    $ cat /sys/devices/bone_capemgr.*/slots
     0: 54:PF---
     1: 55:PF---
     2: 56:PF---
     3: 57:PF---
     4: ff:P-O-L Bone-LT-eMMC-2G,00A0,Texas Instrument,BB-BONE-EMMC-2G
     5: ff:P-O-- Bone-Black-HDMI,00A0,Texas Instrument,BB-BONELT-HDMI 
  • As root, execute the script to export the GPIO pins.  This makes sure they are initialized properly (ie: their clock has been enabled and the GPIO registers were taken out of reset).  Without this step, you will get cryptic errors like:
    Unhandled fault: external abort on non-linefetch (0x1018) at 0xb6d1e134
    When you try to talk to the memory-mapped GPIO control registers.
At this point, you are ready to run code that directly talks to the PRU and GPIO pins (see the dts file for which pins are muxed to the PRU and which pins are GPIO).  If you're running LinuxCNC, just run linuxcnc and select the BeBoPr configuration.  If you are writing your own code, now is the time to make it do it's thing!

I hope to get the analog inputs sorted fairly soon.  I have them working with the stock cape-bone-iio overlay, but this throws away a bunch of ADC resolution (0-1800 instead of 0-4095).  I'm working on fixing that without having to write a kernel driver, and I'll try and hook it into LinuxCNC HAL via python like I did under the 3.2 kernel.

Stay tuned!!!

Monday, June 3, 2013

Beagle Bone PRU Links

I'm dumping a bunch of links for the Beagle Bone and BeagleBone Black related to PRU support, the 3.8 kernel, device tree, and the tricky bits of getting my PRU code working under the new kernel.  This is so I can find these later, and with hopes that others might find something useful.  If you know of others good links for intermediate to advanced hardware support on the 'Bone, please let me and I'll add them.

PRU tools

  • pasm: New and Improved!  This is a "New and Improved" version of the open-source TI PRU assembler pasm.  Bas Laarhoven (designer of the BeBoPr cape) added support for some of the "semi-documented" instructions.  These instructions can be found in Revision C of the AM3358 technical reference manual (along with details on the hardware multiplier and other goodies), but are absent from the latest official TI documentation.  This repository also includes the pruss Linux-side C code required to talk to the PRU, and some example apps to help you get started.
  • The LinuxCNC PRU debugger: specific to the LinuxCNC HAL environment; supports symbolic debugging with source information.  This is the primary debugging tool I use when writing my code, and it works quite well.  Some instructions for use can be found in the LinuxCNC configs/pru-examples/README file.
  • Element 14 PRU Tutorial A nice write up if you haven't done anything with the PRU, and need to start at the beginning.
  • prudebug: - known to work with a minor change for the BB, see here: the UI is a tad rough, but the basics are in place. No symbolic debugging.
  • pView - A TI tool which isn't publicly available (inferred by the pasm docs).  pasm generates the debugging information for pView which is used by the Michael Haberler's symbolic debugger in LinuxCNC.
  • prude: , an abandoned debugger project, not useful without finishing
Want to help?  The LinuxCNC PRU debugger is an awesome tool, but currently needs the rest of LinuxCNC to run, making it hard to play with. It should not take much work (1-2 days worst case) to get this debugger running outside of the LinuxCNC HAL framework.

Device Tree

  • Beaglebone and the 3.8 Kernel An excellent introduction to Device Tree and how to use it with the BeagleBone
  • Device Tree Usage Another Device Tree overview, straight from the "horse's mouth" as it were.
  • Device Tree Pinmux Test A validation test script for capemgr that  serves as a great basic introduction to device tree fragments and using them to control the I/O pins

General BeagleBone Information

BeagleBone Pin Mux Tables
Pin mux and usage data extracted from the multiple tables in various TI manuals.  Official TI data can be found in the AM335x Technical Reference Manual, AM335x Datasheet, and AM335x PRU-ICSS Reference Guide

Sunday, June 2, 2013

Replicating the Results

I've had some folks want to replicate my results.  Short answer: you can't.  You see, I got this box from John Scalzi after he finished writing "Red Shirts", and if you don't have the box...

Just kidding!  :)

...but seriously, this is not quite ready for the unwashed masses, so you need to be pretty familiar with Linux, LinuxCNC, and the BeagleBone if you want to try this out.  If all you're interested in is the PRU code, just grab the source from the git repo, checkout the arm335x-hal-pru-tasks, and browse to the src/hal/drivers/hal_pru_generic directory.  The *.p files are the PRU source, and the *.c files are the Linux side code to talk to it.  The Linux code is written as a HAL driver for LinuxCNC, but it should be fairly apparent what is going on, and PRU communication is handled with the standard prussdrv driver, slightly modified to run under LinuxCNC.  Important: You have to use the supplied pasm assembler, which can be found in src/hal/support/pasm, as it includes modifications by Bas Laarhoven (designer of the BeBoPr board) to support some semi-documented PRU instructions.  Or you can just use Bas' version from github, but the "stock" TI pasm won't work.

If you really want to try running the code yourself and can't possibly wait until I get it working on a 3.8 kernel, here's what you need to do:
  • I started with a Debian wheezy image from eLinux, I think the one from Feb: debian-wheezy-console-armhf-2013-02-16.tar.xz, but any of them should work. 
  • You have to add Michael Haberler's Xenomai kernel, and all the packages necessary to build LinuxCNC. I have some details on-line
  • MAKE SURE YOU USE THE XENOMAI 3.2 KERNEL!  This won't run under the 3.8 xenomai kernel (yet) or the 3.2 BeagleBone kernel.
  • ...if this sounds like a hassle, you can bypass this by using a raw SDcard image provided by Michael Haberler  (see the README files for details).  This option also includes some things in rc.local that might trip up the casual user starting from scratch with a stock Debian install from eLinux (like setting the Xenomai gid at run-time, modifying permissions on /dev/mem, and getting all the LinuxCNC build dependencies pulled in from the package repositories).
  • From this point, checkout the arm335x-hal-pru-tasks branch from the git repository
  • ...and build LinuxCNC as normal (for a BeagleBone, using: "./configure --with-threads=xenomai-user --with-platform=beaglebone").
  • Now run the configs/pru-examples/ script as root to setup the pin multiplexing. This will hopefully be automatic once I get things working on the 3.8 kernel with device tree overlays.
  • If you're lucky, launch LinuxCNC, load the setup from configs/pru-examples/BeBoPr.ini and see pulses! 
 Holler if you get stuck anywhere, and feel free to edit the LinuxCNC wiki page with notes as you go if anything is unclear.

BeagleBone + BeBoPr + LinuxCNC + MendelMax Printing

Video of my very first print using LinuxCNC running on a BeagleBone with the BeBoPr cape to control my MendeMax RepRap 3D printer.  The BeagleBone is running a Xenomai real-time kernel, but using the PRU (Programmable Realtime Unit, a 200 MHz deterministic microcontroller for off-loading time-critical tasks) to do step/dir and pwm generation.  The PRU code is fairly advanced, and supports a configurable task list with full control over the number and types of tasks (ie: make as few/many step/dir and/or pwm outputs as you want).  The PRU is currently running a 10 uS task loop, but can run faster or slower depending on how many tasks you want to run.  The 10 uS is easily handling 4 step/dir tasks plus a pwm task with 3 outputs and is only busy about 1.5 uS (so 85% idle).

The source for the PRU code and the LinuxCNC HAL driver to talk to it can be found here:;a=shortlog;h=refs/heads/arm335x-hal-pru-tasks

Look in the src/hal/drivers/hal_pru_generic directory.  The *.p files are for the PRU, and the *.c files are the Linux/LinuxCNC side driver for it.

PRU Step Timings

I have had several folks ask me about the step timings.  The PRU code I've written is easily capable of rates up to about 50 KHz (with good timings), and could be pushed maybe 2-4x higher if necessary

The video shows the PRU generating 40 KHz step timings (500 mm/s with a standard MendelMax 80 steps/mm).  If you want a closer look at the waveforms, here are a couple of stills:

Changes from the code in git include reducing the PRU task period from 10 uS to 4 uS, and dialing up max velocity to 500 mm/S and acceleration to 5000 m/s/s

BeagleBone + BeBoPr + LinuxCNC

Video of LinuxCNC running on a BeagleBone driving the X and Y axis of a 3D printer using a BeBoPr cape.  Step/Dir generation is done by custom PRU code on the BeagleBone.  The LinuxCNC gui is running on a remote X display on a conventional x86 PC, but LinuxCNC and all real-time control are running on the BeagleBone.


Lately I have been working hard to try and get LinuxCNC running on the BeagleBone to control a 3D printer.  I needed a central location to collect details for this project, so I created this blog.  Follow along, and help out if you can!