ben-blinkenlights/ubb-patgen
Werner Almesberger 1d78c01bba ubb-patgen/Makefile (LDLIBS): add -lpthread -ldl
Strangly, using what's supposedly the same toolchain, I didn't seem to
need these items in the past. Or maybe I just never tried a non-static
build.
2013-03-29 20:33:41 -03:00
..
hw ubb-patgen/hw/: a simple resistor on CMD is sufficient - no need for a cap 2013-01-14 03:11:39 -03:00
table ubb-patgen/table/mktab: make the long vertical axes thinner 2013-01-15 16:45:08 -03:00
Makefile ubb-patgen/Makefile (LDLIBS): add -lpthread -ldl 2013-03-29 20:33:41 -03:00
README ubb-patgen/ubb-patgen.c: new option -I inter_s to select "unsafe" frequencies 2013-01-28 21:20:25 -03:00
timeline.fig ubb-patgen/timeline.fig: timeline of pattern generation (description in README) 2013-01-18 14:18:44 -03:00
ubb-patgen.c ubb-patgen/ubb-patgen.c: new option -I inter_s to select "unsafe" frequencies 2013-01-28 21:20:25 -03:00

README

UBB pattern generator
=====================

ubb-patgen uses the MMC controller in the Ben Nanonote to send a
digital pattern on the DATx lines of UBB. All four DATx lines can
be used. The maximum output rate is 56 MHz, the maximum pattern
size is 8128 nibbles.

ubb-patgen can also output a clock of arbitrary duration on the
CLK signal.

The frequencies available for the pattern and the clock signal
range from 41 kHz to 56 MHz. A map can be found here:
http://downloads.qi-hardware.com/people/werner/ubb/ben-mmc-clk.png


Frequency list
--------------

# ubb-patgen

shows the available frequencies in ascending order and the
corresponding MMC clock divider and bus clock tap settings.

# ubb-patgen -q

does the same but shows only the frequencies (in Hz) as
floating-point numbers.


Frequency selection
-------------------

# ubb-patgen -f 17000000
# ubb-patgen -f 17M
# ubb-patgen -f 17MHz

all look for the available frequency closest to 17 MHz and print
its value in Hz.

Appending a + limits the search to frequencies greater than or
equal to the specified value. Similarly, - searches for
frequencies that don't exceed the specified value. Examples:

# ubb-patgen -f 10MHz
9882352.941176
# ubb-patgen -f 10MHz+
10500000.000000

# ubb-patgen -f 15M
15272727.272727
# ubb-patgen -f 15M-
14000000.000000

Note that this form of invocation only searches the frequency
table but does not produce any output on UBB.

ubb-patgen warns if the selected frequency does not match the
requested frequency, e.g.,

# ubb-patgen -f 100kHz
bus clk = 100.962 kHz (+0.96%)

This warning can be suppressed with the option -q.

The frequency can also be specified as the cycle time with the
option -i:

# ubb-patgen -i 10us

The meaning of an appended + or - changes here, e.g., 10us+
selects a slower clock (producing an interval of at least 10 us).

The options -F and -I work like -f and -i but also allows
frequencies that may exceed the hardware's capabilities. As a
consequence, the MMC controller may hang.


Clock output
------------

# ubb-patgen -c

outputs a clock on CLK. The default is 1 MHz and can be changed
with the option -f.

ubb-patgen exits and leaves the clock running. To wait for a
while and clean up on exit, add the delay in seconds, e.g.:

# ubb-patgen -f 500kHz -c 10

The delay can be followed by "m", "u", or "n" for the respective
multiplier. Furthermore, it can end with an optional "s". Note
that the minimum time ubb-patgen actually spends generating a
clock will typically be in the order of several milliseconds.

To stop the MMC bus clock, run

# ubb-patgen -c 0


Pattern output
--------------

# ubb-patgen 0110

first sets the DATx lines to 0, then outputs a 1 bit on DAT0 for
two clock cycles, and returns DAT0 to zero.

Each digit is a nibble representing the four DATx lines, with DAT0
having the value 1, DAT1 2, DAT2 4, and DAT3 8.

The repetition of a nibble can also be expressed by following it
with the number of repetitions in curly braces, e.g.,

# ubb-patgen 01{2}0

The options -f and -q work as usual.

The clock is normally not output but can be activated with the
option -C. Note that the clock output is not continuous in this
case.

The pattern can be read from a file. All whitespace is ignored
and so are comments beginning with #:

# cat <<EOF >pattern-file
1		# idle state is high
# send two characters in RS232 format
0 00010010 1	# "H"
0 10010110 1	# "i"
0 10000100 1	# "!"
0 10110000 1	# CR
1		# return to idle (high)
EOF
# ubb-patgen -f 115.2k pattern-file

If a file with the same name as a pattern exists, ubb-patgen will
try to load that file. This can be prevented with the option -p.

If only some of the DATx lines should be used for pattern output,
the option -m MASK can be used to leave the unused lines in their
previous state. MASK is a value in C syntax. Only lines whose bit
is set are used for pattern output.


External trigger
----------------

ubb-patgen normally sends the pattern immediately. This can be
delayed by waiting for an external trigger with the option -t.

# ubb-patgen -t 0 0f0

configures CLK as an input, waits for it to become zero, and then
outputs the 010 pattern. If CLK is already zero, ubb-patgen will
send the pattern immediately.

Likewise, -t 1 waits for CLK to become 1. -t cannot be used with
the -C option.

The trigger can also be a sequence, e.g., -t 01 would first wait
for CLK to become zero (if it isn't already), then wait for it to
become one.

ubb-patgen usually starts the pattern about 2-10 us after the
trigger, but this can be delayed by other system activity. An
extra delay can be added with the option -w, e.g.,

# ubb-patgen -t 0 -w 1s 010

The trigger signal can be debounced with the option -d, e.g.,

# ubb-patgen -t 0 -d 100us 0f0

This accepts the trigger only after it has been zero for at least
100 microseconds. If the trigger is a sequence, debouncing is
applied at each step.


Timeline details
----------------

timing.fig illustrates the various steps of pattern generation.
A PDF of the diagram can be found here:

http://downloads.qi-hardware.com/people/werner/ubb/patgen/timeline.pdf

CLK is the clock output if selected with -C. DATx are the data
lines, with the value of DAT0 shown. TRIG is the trigger input.
Note that in real life, the TRIG/CLK line can only act either as
trigger input or as clock output but not as both at the same time.

The pattern we send is 0110110. We trigger on TRIG being low, with
a debounce time of nominally about one pattern clock interval, and
some post-trigger delay.

After ubb-patgen starts, it first processes the command-line
options and arguments, then initializes the pins. DATx are set to
the value of the first pattern. Next, ubb-patgen sets up the MMC
controller, makes it send a command, receives a pseudo-response,
and begins sending copies of the first pattern on DATx. These
copies are necessary to get past the start bit and to make the MMC
controller drive DATx to known levels. Once this pattern has been
sent, we switch DATx to GPIO.

When this is done, ubb-patgen waits for the trigger. In this
example, we first ignore a glitch and then detect a correct
trigger value. Note that the effective debounce period is usually
longer than specified, since other system activity can delay the
sampling.

Once ubb-patgen has triggered, it starts the DMA controller and
thus begins sending the pattern. The first cycle (marked with a
question mark) is an uncommanded repetition of the first pattern
(apparently there is a buffer stage in the MMC controller)
followed by the entire sequence, first to last pattern.

At the end, several copies of the last pattern may be sent in
order to reach the transfer size of the DMA controller (32 bytes).
ubb-patgen then ensures that all data has left the MMC controller,
switches DATx back to GPIO, and exits.