The Spincore PulseBlaster is a Programmable TTL Pulse Generator / Digital Word Generator and Timing Engine. We have written a Linux driver for it, some utilities, and a parser/compiler/simulator. Everything is Free Software, under GNU GPL.
Linux kernel driver: this works under 3.8, and we are currently working to get it accepted upstream. It creates entries in /sys, under /sys/class/PulseBlaster/, and has a very simple interface: to program the device, just cat the binary into the the program interface, and to start/stop/arm, just echo a 1 into the start/stop/arm interface.
Utilities: pb_utils contains a set of C-programs which can control the PulseBlaster, assemble "Very long instruction word" (VLIW) files, and are useful for diagnostics, testing and debugging.
Parser: pb_parse is a high-level parser for the PulseBlaster. It reads a high-level PBSRC format, and outputs VLIW for pb_asm. It can also simulate the PulseBlaster, writing a virtual "piano-roll", or to a wavefile analyser (e.g. GTKWave. It can prove program correctness, because the PulseBlaster is not Turing-Complete. [This also facilitates a "hack" of combining 1-3 ordinary parallel-ports into a "Poor-man's PulseBlaster", albeit rather slow and jittery.]
Overview: Source-file (.pbsrc) -> parser (pb_parse) -> assembly file (.vliw) -> assembler (pb_asm) -> binary file (.bin) -> programmer (pb_prog) -> pulseblaster hardware (/sys/class/pulseblaster) -> trigger (pb_start).
Example 1: This is an example of the type of program one can write, which is actually useful: pixel_characterise.pbsrc, hawaii.h, macros.pbsrc, clock_calc.php, README.txt
Example 2: This is a demonstration of the simulation output (piano-roll mode). The source is a simple 2-of-5 walking LEDs program (walking_5leds_5Hz.pbsrc).
This supports the PulseBlaster SP1 PB24-100-32k board, with PCI vendor/device ID of 0x10e8:0x5920.
The newer SP2 boards have the same vendor id (0x10e8) and device IDs (0x8879 or 0x8852; both being functionally identical).
[Although we haven't an SP2 board to test with, if the protocol is the same, it will suffice to add the IDs into the pb_pci_tbl struct in PulseBlaster.c.]
The kernel module, pulseblaster.ko, creates entries in /sys/class/pulseblaster/pulseblaster0/ as follows:
These are the features of pb_parse. It is basically a complicated pre-processor, that fakes as many desired features as possible (eg bit-at-a-time instructions and macros).
Because the PB isn't Turing-Complete, the advanced hacks must be evaluated at compile-time, not run-time. For more details, see the man-page and some of the examples.
As an example of the fun to be had with preprocessor abuse, this contrived line is legal syntax, in which, #define, #ifnot, and bit_flip() are all effected at compile-time.
#define JULY #ifnot(HERRING) bit_flip(PENGUIN) goto ANTARCTICA ALL_SUMMER
The basic human-readable "assembly" format is vliw. This is converted (by pb_asm) to a raw (binary) file, which can be loaded with pb_prog. The vliw format consists of 4 columns (delimited by whitespace and with an optional //comment), in the order: Output, Opcode, Arg, Length. Output and Length are numbers (dec/hex). Opcode is a string eg "cont" or "goto". Arg is either a number, or a "-" where it is not required. Vliw programs are not especially easy to write: for example, time-units must be in ticks, addresses must be literal, and there is no support for macros.
These are the details of the PulseBlaster opcodes. Some specific details are for loops, long-delay, wait, and latencies.
Triggering (hardware and software) behaviour is described here.
Here is a simple example.vliw file; there are many more in the vliw_examples directory.
The pbsrc language and associated compiler abstracts away some of the quirks of the device, and adds (or fakes) extra features such as bit-at-a-time instructions. [It will emit an error or a warning in cases where these are used inappropriately.]
For example, loop (n) may have n=1 and n=0, and cont<-->longdelay are implicitly promoted/demoted. It's also possible to have executable-includes, a hack which allows much greater flexibility of dynamically-generated code.
The parser can also simulate the PulseBlaster, which allows for program validation (will it halt or run forever? does it ever exceed the maximum stack depths?) and full or partial simulation. The output data can be in pbsim format (useful for hawaiisim), or in vcd (value change dump) format for GTKWave. It can also write directly to a parallel port (for the "poor-man's PulseBlaster").
Here is an example.pbsrc file; there are many more in the pbsrc_examples directory.
The implementation of the PulseBlaster is unusual: it runs pulse programs on an internal FPGA. This means that it will keep running even during a reboot of the host!
Also, the language is not Turing-complete: this makes it very predictable, but adds certain limitations. pb_parse gets around a few of them.
We also created some custom additions: external clock input and triggering via an RS-232 port: details.
Bugs: pb_parse is a very long PHP program, containing some 5368 lines and 130 Regular Expressions, and needing significant RAM for larger programs. It hasn't yet fulfilled Zawinski's law, though the -M option is reserved. Also, as the PBSRC language is based on VLIW, it uses whitespace as the delimiter, which, with hindsight, isn't ideal
This was originally written as part of my PhD Infrared Camera system. It should be applicable for wider usage.
A real-world example of the system is in hawaii_characterise.sh distributed in the hawaii_sensor section: PulseBlaster code is dynamically generated to run a series of experiments on a detector.
pulseblaster.tgz
GIT repository
Some selected files, from the tarball:
README.txt
vliw.5
pbsrc.5
pbsim.5
pb_utils.1
pb_parse.1
pb_freq_gen.1
pb_manual.1
pb_parport-output.1
Return to all programs, site home.