missing www

This commit is contained in:
Sam 2023-06-03 14:43:53 +02:00
parent 5f7c61f616
commit cfc7c70d16
131 changed files with 11126 additions and 661 deletions

55
doc/etherdream/dmx.html Normal file
View file

@ -0,0 +1,55 @@
<!DOCTYPE html>
<html>
<head>
<title>Ether Dream - DMX Interface</title>
<link rel="stylesheet" type="text/css" href="main.css" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
</head>
<body>
<img src="etherdream.png" width="298" height="75" alt="ether dream">
<div id="header"><a href="protocol.html">Ether Dream</a></div>
<div id="content">
<h1>Ether Dream - DMX Interface</h1>
<h2 style="color:red"><em>NOTE</em> - This page is for the previous Ether Dream 1. Check the <a href="/">current website</a>.</h2>
<p>
The Ether Dream DMX interface is an add-on board for the Ether Dream
that allows it to control external DMX devices and receive DMX input. New firmware
allows the Ether Dream to work as a DMX-to-OSC and OSC-to-DMX bridge, for compatibility
with a wide variety of other software.
</p>
<img src="/dmx-dream.jpg" alt="photo of Ether Dream with DMX interface"/>
<h2>Features</h2>
<ul>
<li>3-pin and 5-pin XLR connectors available</li>
<li>DMX in, thru (electrically connected to in), and out</li>
<li>Optional full electrical isolation for noise and damage resistance</li>
<li>Driver support in Ether Dream DLLM</li>
<li>Standard OSC interface</li>
<li><i>Future</i>: control of laser output via DMX commands</li>
<li>Works with any production Ether Dream with firmware v0.5.0 or later, available from the <a href="downloads.html">Downloads</a> page
</ul>
<h2>Connection Diagram</h2>
<p>
Use the included 6-pin jumper cable to connect the DMX board to one of the serial expansion headers on the Ether Dream.
Match pin 1 on the Ether Dream to pin 1 on the DMX board. Serial expansion header #1 correponds to DMX universe 1, and
likewise for 2 and 3. Only header 1 can currently be used for input.
</p>
<img src="/2dmx.png"/>
<img src="/etherdreamboard.png"/>
</div>
<div id="footer">
&copy; 2010-2021 Jacob Potter.
</div>
<div id="menu">
<ul>
<li><a href="../index.html">LJ doc</a></li>
<li><a href="protocol.html">Protocol</a></li>
<li><a href="userguide.html">V1 User Guide</a></li>
<li><a href="manual.html">V1 Developer Manual</a></li>
<li><a href="dmx.html">V1 DMX Board</a></li>
</ul>
</div>
</body>
</html>

115
doc/etherdream/main.css Normal file
View file

@ -0,0 +1,115 @@
body {
margin:0px;
padding:0px;
font: 12px/20px verdana, arial, helvetica, sans-serif;
color: #333;
background-color: white;
}
h1 {
margin:0px 0px 15px 0px;
padding:0px;
font-size:28px;
line-height:28px;
font-weight:900;
color:#666;
}
h2 {
margin:0px 0px 10px 0px;
padding:0px;
font-size:22px;
line-height:22px;
font-weight:900;
color:#888;
}
h3 {
color: #888;
font-weight: bold;
}
p {
margin:0px 0px 16px 0px;
padding:0px;
}
a {
color: #09c;
text-decoration: none;
font-weight: 600;
}
a:link {
color:#09c;
}
a:visited {
color:#07a;
}
a:hover {
background-color:#eee;
}
#header {
font-size: 18px;
margin:0px 0px 10px 0px;
padding:17px 0px 0px 20px;
height:14px;
border: 1px 0px solid black;
border-style: solid;
border-color: black;
border-width: 1px 0px; /* top and bottom borders: 1px; left and right borders: 0px */
line-height:11px;
background-color:#eee;
}
#content {
margin:0px 50px 20px 200px;
padding:10px;
}
#footer {
margin: 0px 0px 10px 200px;
font-size: 11px;
line-height: 11px;
}
#menu {
position: absolute;
top: 150px;
left: 20px;
width: 130px;
padding: 10px 20px;
background-color: #eee;
border: 1px dashed #999;
line-height: 17px;
}
#menu ul {
margin: 0;
padding: 0;
}
#menu li {
list-style: none;
margin: 10px 0;
padding: 0;
}
table.grid {
border-collapse: collapse;
}
table.grid td {
border: 1px solid black;
margin: 0px none;
padding: 2px;
}
blockquote {
background: #ddd;
border: 1px dashed #888;
padding: 6px;
}
pre {
margin: 0;
padding: 0;

195
doc/etherdream/manual.html Normal file
View file

@ -0,0 +1,195 @@
<!DOCTYPE html>
<html>
<head>
<title>Ether Dream - Developer Manual</title>
<link rel="stylesheet" type="text/css" href="main.css" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
</head>
<body>
<img src="etherdream.png" width="298" height="75" alt="ether dream">
<div id="header"><a href="protocol.html">Ether Dream</a></div>
<div id="content">
<h1>Ether Dream - Developer Manual</h1>
<h2 style="color:red"><em>NOTE</em> - This page is for the previous Ether Dream 1. Check the <a href="/">current website</a>.</h2>
<h2>Contents</h2>
<ul>
<li><a href="#intro">Introduction</a></li>
<li><a href="#hw">Hardware</a></li>
<li><a href="#config">Configuration</a></li>
<li><a href="#protocol">Protocol</a></li>
<li><a href="#dev">Development</a></li>
<li><a href="#fw">Firmware Updates</a></li>
</ul>
<h2 id="intro">Introduction</h2>
<p>
This is a work-in-progress developer-oriented guide to the hardware features and software architecture
of the Ether Dream DAC. For setup and usage tips, see the <a href="/userguide.html">User
Guide</a>.
</p>
<h2 id="hw">Hardware</h2>
<img src="etherdreamboard.png" alt="Ether Dream board diagram" width="700" height="357">
<p>
Starting at the Ethernet connector on the board and moving counterclockwise, the
hardware features and connectors on the board are:
</p>
<ul>
<li>Ethernet connector - includes link and activity LEDs</li>
<li>USB connector. This is currently used only for firmware upgrades.</li>
<li>Status LED. This LED blinks when the board is in bootloader mode, and
is on normally.</li>
<li>MicroSD slot. This will be used, in future software updates, for settings
and playback of stored shows.</li>
<li>External power jack. This is a 2.1mm/5.5mm barrel connector, center-positive,
accepting 8V-25V DC.</li>
<li>Power supply screw terminals. Ground is on the left (towards the outside of
the board), positive is on the right (towards the inside of the board).
The two power inputs are isolated from one another with diodes; if both
are connected, power will be drawn only from the one with the higher voltage.</li>
<li>GPIO header. This connects extra pins from the microcontroller. Pin 1 is closest
to the power jack. The pinout is:
<table class="grid">
<tr><td>1 - P1[8] / PWM1[1] / CAP1[0]</td><td>2 - +5.5v supply</td></tr>
<tr><td>3 - P1[19] / MCOA0 / CAP1[1]</td><td>4 - P1[22] / MCOB0 / MAT1[0]</td></tr>
<tr><td>5 - P1[26] / MCOB1 / PWM1[6] / CAP0[0]</td><td>6 - P1[29] / MCOB[2] / PCAP1[1] / MAT0[1]</td></tr>
<tr><td>7 - +3.3v supply</td><td>8 - P0[15] / TXD1 / SCK0 / SCK</td></tr>
<tr><td>9 - ground</td><td>10 - P0[17] / CTS1 / MISO0 / MISO</td></tr>
<tr><td>11 - P0[18] / DCD1 / MOSI0 / MOSI</td><td>12 - P0[16] / RXD1 / SSEL0 / SSEL</td></tr>
</table>
</li>
<li>Serial header #2. Pinout:
<table class="grid">
<tr><td>1 - P0[10] / TXD2 / SDA2 / MAT3[0]</td><td>2 - +5.5v supply</td></tr>
<tr><td>3 - P0[11] / RXD2 / SCL2 / MAT3[1]</td><td>4 - +3.3v supply</td></tr>
<tr><td>5 - P1[28] / MCOA2 / PCAP1[0] / MAT0[0]</td><td>6 - ground</td></tr>
</table>
</li>
<li>Interlock LED (yellow). This LED is on whenever the interlock relay is closed.</li>
<li>ILDA DB-25 connector.</li>
<li>Behind the DB-25 connector: 2x13 pin header wired identically to the DB-25.</li>
<li>Emission LED (green). Whenever the DAC is producing output, this LED is on.</li>
<li>20-pin ARM JTAG header. Pin 1 is towards the power connectors.</li>
<li>1x6 pin serial debug header. This is intended to be used for debug purposes with a
TTL serial adapter, such as <a href="http://www.sparkfun.com/products/9717">this unit</a>
available from sparkfun. Pin 1 is closest to the Ethernet connector. The pinout is:
<table class="grid">
<tr><td>1 - P2[10]/EINT0/NMI</td></tr>
<tr><td>2 - P0[2] / TXD0 / AD0[7]</td></tr>
<tr><td>3 - P0[3] / RXD0 / AD0[6]</td></tr>
<tr><td>4 - unconnected</td></tr>
<tr><td>5 - unconnected</td></tr>
<tr><td>6 - ground</td></tr>
</table>
</li>
<li>Serial header #1. Pinout:
<table class="grid">
<tr><td>1 - P2[0] / PWM1[1] / TXD1</td><td>2 - +5.5v supply</td></tr>
<tr><td>3 - P2[1] / PWM1[2] / RXD1</td><td>4 - +3.3v supply</td></tr>
<tr><td>5 - P2[2] / PWM1[3] / CTS1</td><td>6 - ground</td></tr>
</table>
</li>
<li>Serial header #3. Pinout:
<table class="grid">
<tr><td>1 - P0[25] / AD0[2] / I2SRX_SDA / TXD3</td><td>2 - +5.5v supply</td></tr>
<tr><td>3 - P0[26] / AD0[3] / AOUT / RXD3</td><td>4 - +3.3v supply</td></tr>
<tr><td>5 - P2[3] / PWM1[4] / DCD1</td><td>6 - ground</td></tr>
</table>
</li>
</ul>
<h2 id="config">Configuration</h2>
<p>
The Ether Dream requires no network configuration. By default, it will attempt to acquire
an IP address with DHCP; if no DHCP server is found, it will instead choose a link-local
169.254.x.x address. Once it has an address, it will begin advertising its presence with
UDP broadcast packets on port 7654. The playback DLL looks for these broadcasts to find
DACs on the network.
</p>
<h2 id="protocol">Protocol</h2>
<p>
Protocol documentation is <a href="protocol.html">here</a>.
</p>
<p>
Drivers are available for <a href="https://github.com/j4cbo/j4cDAC/tree/master/driver/">Windows</a>
and <a href="https://github.com/j4cbo/j4cDAC/tree/master/driver/libetherdream/">Mac/Linux</a>.
</p>
<h2 id="dev">Development</h2>
The Ether Dream firmware, available <a href="https://github.com/j4cbo/j4cDAC">on github</a>,
builds on a standard Linux system with the free CodeSourcery ARM toolchain. The README in the
repository describes the needed tools.
<h2 id="fw">Firmware Updates</h2>
There are three ways of updating the Ether Dream's firmware:
<ol>
<li><b>USB</b>
<p>
The Ether Dream board comes with a USB bootloader in the first 16kB of Flash. (Source
for the bootloader is in the boot/ directory of the source tree.) This bootloader
implements the standard DFU protocol; the <a href="http://wiki.openmoko.org/wiki/Dfu-util"
>dfu-util</a> project provides a PC-side tool.
</p>
<p>
The bootloader runs on every power-up, but normally immediately jumps to the main firmware.
If the firmware is corrupt or the DAC has been forced into bootloader mode, it will
instead run and appear as a USB DFU device. This mode is indicated by the LED
next to the USB connector flashing rapidly. There are
two ways to force the DAC to run in bootloader mode:
</p>
<ul><li>Hold P0[18] low during power-on.</li>
<li>Send a special USB control request while the normal firmware is running.
There is <a href="https://github.com/j4cbo/j4cDAC/tree/master/tools/f0ad">a tool to
do this</a> in the source repository.</li></ul>
<p>The pin to force bootloader mode, P0[18], is located next to a ground pin on the 2x6
expansion header. Connect a jumper across these pins and then apply power to run
the bootloader.
</p><p>
<img src="bootloader-jumper.jpg" width="366" height="186" alt="bootloader jumper">
</p><p>
On the host PC, if dfu-util is installed, running "make bl" in the firmware directory
will automatically update the firmware of an attached DAC. Either force the DAC into
bootloader mode and run "make bl", or "make bl" while the DAC is running its usual
firmware; in the latter case, the DAC will be rebooted into bootloader mode and then
updated.
</p>
</li>
<li><b>Serial</b>
<p>There is a built-in ROM bootloader on the LPC1758 which runs over UART0,
connected to the 1x6 header on the board. It enters if P2[10] is held low when
power is applied. When the ROM bootloader is running, both LEDs on the board will
be very dimly lit. The <a href="http://sourceforge.net/projects/lpc21isp/">lpc21isp</a>
tool talks to the DAC in this mode.
</p>
<p>
P2[10] on the LPC1758 is connected to RTS on the 6-pin serial header. Running "make
flash" in the firmware directory and then applying power to the DAC will
update the firmware and USB bootloader over serial.
</p>
<p>This method is somewhat slower than the USB bootloader and so is not generally
recommended - it is useful primarily for installing the firmware into a
previously-unprogrammed DAC. Also, note that the 6-pin serial header is <i>logic-level</i>;
it is 5-volt-tolerant but must not be connected directly to an RS-232 port.
</p>
</li>
<li><b>JTAG</b>
<p>The LPC1758 Flash can be reprogrammed over JTAG with openocd. See the
user's manual for the microcontroller and the openocd documentation for details.</p>
</li>
</ol>
</div>
<div id="footer">
&copy; 2010-2021 Jacob Potter.
</div>
<div id="menu">
<ul>
<li><a href="../index.html">LJ doc</a></li>
<li><a href="protocol.html">Protocol</a></li>
<li><a href="userguide.html">V1 User Guide</a></li>
<li><a href="manual.html">V1 Developer Manual</a></li>
<li><a href="dmx.html">V1 DMX Board</a></li>
</ul>
</div>
</body>
</html>

View file

@ -0,0 +1,274 @@
<!DOCTYPE html>
<html>
<head>
<title>Ether Dream - Protocol</title>
<link rel="stylesheet" type="text/css" href="main.css" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
</head>
<body>
<img src="etherdream.png" width="298" height="75" alt="ether dream">
<div id="header"><a href="protocol.html">Ether Dream</a></div>
<div id="content">
<h1>Ether Dream - Protocol</h1>
<h2>Contents</h2>
<ul>
<li><a href="#intro">Introduction</a></li>
<li><a href="#stm">State Machines</a></li>
<li><a href="#status">Status Responses</a></li>
<li><a href="#broadcast">Broadcast</a></li>
<li><a href="#commands">Commands</a></li>
<li><a href="#responses">Responses</a></li>
</ul>
<h2 id="intro">Introduction</h2>
<p>
Communication with the DAC happens over TCP on port 7765. The DAC will only
communicate with one host at a time; another device that connects while the DAC
has an established control connection will have its connection attempt rejected.
If the host does not send anything to the device for one second, the device will close
the TCP connection. <em>TODO: The 1-second timeout is not implemented, but will be
in the future.</em>
</p>
<p>
The DAC has a USB interface as well. This is used for firmware updates. <em>TODO:
In the future, the USB interface may also emulate a standard USB CDC-ECM network
device. This would allow the same communication protocol to be spoken over USB. In
this mode, the DAC would choose a link-local IP address.</em>
</p>
<p>
In this document, protocol messages are described as structs. Fields are packed
together with no padding (<code>__attribute__((packed))</code> or <code>#pragma pack(1)</code>);
standard C typedefs such as uint8_t, uint32_t, int32_t, etc. have
their usual meanings, and multi-byte values are transmitted little-endian
("host" byte order on x86 and ARM): the most significant byte appears first.
</p>
<h2 id="stm">State Machines</h2>
<p>
There are three distinct state machines within the DAC: light engine, playback, and source. The light
engine states are:
</p>
<ul>
<li>0: Ready.</li>
<li>1: Warmup. In the case where the DAC is also used for thermal control of laser apparatus,
this is the state that is entered after power-up.</li>
<li>2: Cooldown. Lasers are off but thermal control is still active.</li>
<li>3: Emergency stop. An emergency stop has been triggered, either by an E-stop input on the DAC,
an E-stop command over the network, or a fault such as over-temperature.</li>
</ul>
<p>
<em class="todo">TODO: Since thermal control is not implemented yet, it is not defined how
transitions to and from the "Warmup" and "Cooldown" states occur.</em>
</p>
<p>
The DAC has one playback system, which buffers data and sends it to the analog output
hardware at its current point rate. At any given time, the playback system is connected
to a source. Usually, the source is the network streamer, which uses the protocol described
in this document; however, other sources exist, such as a built-in abstract generator and
file playback from SD card. The playback system is in one of the following states:
</p>
<ul>
<li>0: Idle. This is the default state. No points may be added to the buffer. No output is
generated; all analog outputs are at 0v, and the shutter is controlled by the data source.</li>
<li>1: Prepared. The buffer will accept points. The output is the same as in the Idle state.</li>
<li>2: Playing. Points are being sent to the output.</li>
</ul>
<h2 id="status">Status Responses</h2>
<p>Periodically, and as part of ACK packets, the DAC sends to the host information on its
current playback status. The status struct is:</p>
<blockquote><pre>struct dac_status {
uint8_t protocol;
uint8_t light_engine_state;
uint8_t playback_state;
uint8_t source;
uint16_t light_engine_flags;
uint16_t playback_flags;
uint16_t source_flags;
uint16_t buffer_fullness;
uint32_t point_rate;
uint32_t point_count;
};</pre></blockquote>
<p>
The light_engine_state field gives the current state of the light engine. If the light engine
is Ready, light_engine_flags will be 0. Otherwise, bits in light_engine_flags will be set as follows:
</p>
<ul>
<li>[0]: Emergency stop occurred due to E-Stop packet or invalid command.
<li>[1]: Emergency stop occurred due to E-Stop input to projector.
<li>[2]: Emergency stop input to projector is currently active.
<li>[3]: Emergency stop occurred due to overtemperature condition.
<li>[4]: Overtemperature condition is currently active.
<li>[5]: Emergency stop occurred due to loss of Ethernet link.
<li>[15:5]: Future use.
</ul>
<p>
<p>Similarly, playback_state gives the state of the playback system. The playback_flags field may
be nonzero during normal operation. Its bits are defined as follows:</p>
<ul>
<li>[0]: Shutter state: 0 = closed, 1 = open.
<li>[1]: Underflow. 1 if the last stream ended with underflow, rather than a
Stop command. Reset to zero by the Prepare command.
<li>[2]: E-Stop. 1 if the last stream ended because the E-Stop state was entered.
Reset to zero by the Prepare command.
</ul>
<p>
The buffer_fullness field contains the number of points currently buffered.
point_rate is the number of points per second for which the DAC is configured (if Prepared or
Playing), or zero if the DAC is idle. point_count is the number of points that the DAC has
actually emitted since it started playing (if Playing), or zero (if Prepared or Idle).
</p>
<p>
The currently-selected data source is specified in the source field:
</p>
<ul>
<li>0: Network streaming (the protocol defined in the rest of this document).
<li>1: ILDA playback from SD card.
<li>2: Internal abstract generator.
</ul>
<h2 id="broadcast">Broadcast</h2>
<p>
Regardless of the data source being used, each DAC broadcasts a status/ID datagram over UDP to
its local network's broadcast address once per second. This datagram is formed as follows:
</p>
<blockquote><pre>struct j4cDAC_broadcast {
uint8_t mac_address[6];
uint16_t hw_revision;
uint16_t sw_revision;
uint16_t buffer_capacity;
uint32_t max_point_rate;
struct dac_status status;
};</pre></blockquote>
<h2 id="commands">Commands</h2>
<p>
When a host first connects to the device, the device immediately sends it a status reply,
as if the host had sent a ping packet (described later). The host sends to the device a
series of commands. All commands receive a response from the DAC; responses are described
after the list of commands. The commands are as follows:
</p>
<h3>Prepare Stream</h3>
<p>Single byte: 'p' (0x70)</p>
<p>This command causes the playback system to enter the Prepared state. The DAC resets its buffer to
be empty and sets "point_count" to 0. This command may only be sent if the light engine is Ready
and the playback system is Idle. If so, the DAC replies with ACK; otherwise, it replies with NAK - Invalid.</p>
<h3>Begin Playback</h3>
<blockquote><pre>struct begin_command {
uint8_t command; /* 'b' (0x62) */
uint16_t low_water_mark;
uint32_t point_rate;
};</pre></blockquote>
<p>This causes the DAC to begin producing output. point_rate is the number of points per second to be
read from the buffer. If the playback system was Prepared and there was data in the buffer, then the
DAC will reply with ACK; otherwise, it replies with NAK - Invalid.</p>
<p><span class="todo">TODO: The low_water_mark parameter is currently unused.</span></p>
<h3>Queue Rate Change</h3>
<blockquote><pre>struct queue_change_command {
uint8_t command; /* 'q' (0x74) */
uint32_t point_rate;
};</pre></blockquote>
<p>This adds a new point rate to the point rate buffer. Point rate changes are read out of the buffer when
a point with an appropriate flag is played; see the Write Data command. If the DAC is not Prepared or
Playing, it replies with NAK - Invalid. If the point rate buffer is full, it replies with NAK - Full.
Otherwise, it replies with ACK.</p>
<h3>Write Data</h3>
<blockquote><pre>struct data_command {
uint8_t command; /* d (0x64) */
uint16_t npoints;
struct dac_point data[];
};
struct dac_point {
uint16_t control;
int16_t x;
int16_t y;
uint16_t r;
uint16_t g;
uint16_t b;
uint16_t i;
uint16_t u1;
uint16_t u2;
};</pre></blockquote>
<p>This provides data for the DAC to add to its buffer. The data values are full-scale (for instance,
for color channels, 65535 is full output); the least-significant bits of each word will be ignored
if the DACs resolution is less than 16 bits. The DAC will reply with ACK if the incoming packet
can fully fit in its buffer, or NAK - Full if it cannot. It is valid for npoints to be zero; in
this case, no point will be added to the buffer, but the packet will still be ACKed (as long as
the DAC is Prepared or Playing.)</p>
<p>The "control" field has the following fields defined:</p>
<ul>
<li>[15]: Change point rate. If this bit is set, and there are any values in the point rate change
buffer, then a new rate is read out of the buffer and set as the current playback rate. If the
buffer is empty, the point rate is not changed.
<li>Other bits: reserved for future expansion to support extra TTL outputs, etc.
</ul>
<h3>Stop</h3>
<p>Single byte: 's' (0x73)</p>
<p>The stop command causes the DAC to immediately stop playing and return to the Idle state. It is
ACKed if the DAC was Playing or Prepared; otherwise it is replied to with NAK - Invalid.</p>
<h3>Emergency Stop</h3>
<p>Single byte: 0x00 or 0xFF. (The DAC will recognize either one.)</p>
<p>The e-stop command causes the light engine to enter the E-Stop state, regardless
of its previous state. It is always ACKed.</p>
<p>Any unrecognized command will also be trested as E-stop; however, software should not send
undefined commands deliberately, since they may be defined in the future.</p>
<h3>Clear E-Stop</h3>
<p>Single byte: 'c' (0x63)</p>
<p>If the light engine was in E-Stop state due to an emergency stop command (either from a local
stop condition or over the network), then this command resets it to be Ready. It is ACKed if the
DAC was previously in E-Stop; otherwise it is replied to with a NAK - Invalid. If the condition
that caused the emergency stop is still active (E-Stop input still asserted, temperature still
out of bounds, etc.), then a NAK - Stop Condition is sent.</p>
<h3>Ping</h3>
<p>Single byte: '?' (0x3F)</p>
<p>The DAC will reply to this with an ACK packet. This serves as a keep-alive for the connection when
the DAC is not actively streaming.</p>
<h2 id="responses">Responses</h2>
<p>Responses have one form:</p>
<blockquote><pre>struct dac_response {
uint8_t response;
uint8_t command;
struct status dac_status;
};</pre></blockquote>
<p>In the case of ACK/NAK responses, "command" echoes back the command to which the response is sent.
(Commands are always sent in order, so this field exists for sanity-checking on the host side.)
The response field can be one of the following:</p>
<ul>
<li>ACK - 'a' (0x61) - The previous command was accepted.
<li>NAK - Full - 'F' (0x46) - The write command could not be performed because there was not
enough buffer space when it was received.
<li>NAK - Invalid - 'I' (0x49) - The command contained an invalid command byte or parameters.
<li>NAK - Stop Condition - '!' (0x21) - An emergency-stop condition still exists.
</ul>
</div>
<div id="footer">
&copy; 2010-2021 Jacob Potter.
</div>
<div id="menu">
<ul>
<li><a href="../index.html">LJ doc</a></li>
<li><a href="protocol.html">Protocol</a></li>
<li><a href="userguide.html">V1 User Guide</a></li>
<li><a href="manual.html">V1 Developer Manual</a></li>
<li><a href="dmx.html">V1 DMX Board</a></li>
</ul>
</div>
</body>
</html>

View file

@ -0,0 +1,310 @@
<!DOCTYPE html>
<html>
<head>
<title>Ether Dream - User Guide</title>
<link rel="stylesheet" type="text/css" href="main.css" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
</head>
<body>
<img src="etherdream.png" width="298" height="75" alt="ether dream">
<div id="header"><a href="protocol.html">Ether Dream</a></div>
<div id="content">
<h1>Ether Dream - User Guide</h1>
<h2 style="color:red"><em>NOTE</em> - This page is for the original Ether Dream 1. Check the <a href="/">current website</a>.</h2>
<h2>Contents</h2>
<ul>
<li><a href="#intro">Introduction</a></li>
<li><a href="#quick">Quick Start</a></li>
<li><a href="#hw">Hardware</a></li>
<li><a href="#setup">Setup</a></li>
<li><a href="#live">Live Playback</a></li>
<li><a href="#dmx">DMX</a></li>
<li><a href="#parameters">Parameters</a></li>
<li><a href="#dev">Development</a></li>
</ul>
<h2 id="intro">Introduction</h2>
<p>
Congratulations! Ether Dream is the most flexible, powerful, and open DAC available
today. It is designed to enable easy live playback from PC software and to serve
as a platform for experimentation and development.
</p>
<h2 id="quick">Quick Start</h2>
<p>
To get started with your Ether Dream, just connect its output to your
projector, its Ethernet connection to your network or computer, and then
the power supply to a source of 9-25v DC or to the included adapter.
The green LED next to the USB connector will light to
indicate that power is on, and the yellow LED next to the ILDA connector
will light to indicate that the interlock is now closed.
</p>
<p>
If you're connecting to a home network with a router or DHCP server, no
other configuration will be needed - any computer on the network will
be able to reach the Ether Dream. If you connect the Ether Dream directly
to your computer, make sure that it is set to obtain its IP address
automatically.
</p>
<p>
To make sure that your computer can communicate properly with your Ether
Dream, a <a href="downloads.html">diagnostic tool</a> is available on the
Downloads page.
</p>
<p>Note: you may need to disable or adjust the settings on your firewall
software to be able to communicate with the Ether Dream. The driver DLL
uses TCP port 7765 and UDP port 7654.
</p>
<p>
LSX, ILD S&Ocirc;S, and other software using the
<a href="http://www.photonlexicon.com/forums/showthread.php/15653-Happy-programmer-s-day!-Does-your-DAC-have-an-SDK-DAC-interface-library-released.">universal DAC interface library</a> written by drlava have native
Ether Dream support. However, a software update may be needed - support was only added to the library
in late October 2011. Contact drlava for an updated build of LSX or ILD S&Ocirc;S. Other software that works with ezauddac.dll can be set up to use an Ether Dream by making a backup of
its ezauddac.dll and renaming EtherDream.dll (from <a href="/downloads.html">the Downloads page</a>) to ezauddac.dll.
</p>
<p>Once the driver DLL is installed, just start up the software and the Ether Dream will
automatically be detected.
</p>
<h2 id="hw">Hardware</h2>
<img src="etherdreamboard.png" alt="Ether Dream board diagram" width="700" height="357">
<p>
Starting at the Ethernet connector on the board and moving counterclockwise, the
indicators and connectors on the board are:
</p>
<ul>
<li>Ethernet connector - includes link and activity LEDs.</li>
<li>USB connector. This is currently used only for firmware upgrades.</li>
<li>Status LED. This LED blinks when the board is in bootloader mode, and
is on normally.</li>
<li>MicroSD slot. This is used for configuration and for playback of stored
content.</li>
<li>External power jack. This is a 2.1mm/5.5mm barrel connector, center-positive,
accepting 8V-25V DC at 300mA.</li>
<li>Power supply screw terminals. Ground is on the left (towards the outside of
the board), positive is on the right (towards the inside of the board).
The two power inputs are isolated from one another with diodes; if both
are connected, power will be drawn only from the one with the higher voltage.</li>
<li>GPIO header. This connects extra pins from the microcontroller.</li>
<li>Serial header for future expansion (#2).</li>
<li>Interlock LED (yellow). This LED is on whenever the interlock relay is closed.</li>
<li>ILDA DB-25 connector.</li>
<li>Behind the DB-25 connector: 2x13 pin header wired identically to the DB-25. This
can be used when the Ether Dream is built into a projector.</li>
<li>Emission LED (green). Whenever the DAC is producing output, this LED is on.</li>
<li>2x10-pin programming/debug header (JTAG).</li>
<li>1x6 pin programming/debug header (serial).</li>
<li>Serial header for future expansion (#1).</li>
<li>Serial header for future expansion (#3).</li>
</ul>
<h2 id="live">Live Playback</h2>
<p>
Ether Dream supports a standard frame-based API and should work "out of the box" with existing
playback software, once drivers are installed.
</p>
<p>
In the event of a momentary glitch in its data stream, the Ether Dream driver will automatically
restart playback. If an Ether Dream unit detects that its network link is physically
disconnected, it will go into an 'emergency-stop' mode and stop output until the network is
restored.
</p>
<h2 id="dmx">DMX</h2>
<p>
With an extra adapter board, the expansion connectors on the Ether Dream can transmit and receive
DMX signals to interface with lighting equipment. The Ether Dream can simultaneously drive three
DMX universes, relaying commands from Ethernet to DMX, and also receive on one universe, sending
information from DMX to Ethernet.
</p>
<p>
Each of the serial expansion headers on the diagram above can connect to a DMX adapter board. The
firmware supports both transmitting and receiving DMX from connector #1, and transmitting only
from conectors #2 and #3.
</p>
<p>
DMX output is enabled and controlled with OSC messages. When the Ether Dream receives a message
for a given DMX universe, it will enable output for that universe and start continuously sending
DMX data to an attached interface board. The DMX output can be controlled in any of several ways:
</p>
<ul>
<li><code>/dmx</code><i>n</i><code>/</code><i>channel</i><code> </code><i>value...</i>
<p>
Update one or more channels. For example, to set DMX channel 42 on universe 1 to 200, send an
OSC message to <code>/dmx1/42</code> containing the number 200. If multiple values are sent, they
will be assigned to sequential DMX channels: for instance, sending 200, 250 to <code>/dmx1/10</code>
will set channel 10 to 200 and channel 11 to 250. One OSC message can change up to 50 channels. The
rest of the channels in the universe will not be changed.
</p></li>
<li><code>/dmx</code><i>n</i> <i>channel</i><code> </code><i>value...</i>
<p>
Alternately, the first channel to update can be sent as a numerical parameter, instead of in the
target path of the OSC message. Send 7, 100, 100 to <code>/dmx2</code> to set channels 7 and 8
of universe 2 both to 100. As above, up to 50 channels can be specified, and only the specified
channels will be changed.
</p></li>
<li><code>/dmx</code><i>n</i><code> </code><i>blob</i>
<p>
To change all 512 channels in a universe with a single OSC command, the Ether Dream will accept an OSC
<i>blob</i> (data) parameter. The first byte (index 0) in the blob sets DMX channel 0, the next sets
channel 1, and so on. The blob must be the only parameter and must be exactly 512 bytes long.
</p></li>
</ul>
<p>
DMX input is enabled by sending a message with a string and a number to <code>/dmx1/input</code>. The
string specifies the IP address (must be a numeric IP address, not a hostname) to relay DMX updates to,
and the number is a port number. DMX updates will be sent as OSC messages to <code>/dmx1</code> containing
a single blob - the same format as described above for DMX output.
</p>
<p>
If the address given is "<code>me</code>" and the port is 0, then messages will be sent back to the same
host and port that the <code>/dmx1/input</code> command was received one. If the address is blank and
the port is 0, then DMX input will be disabled.
</p>
<p>
This code will set the first four channels of an Ether Dream's DMX universe 1 to 255:
<blockquote><pre>import liblo
liblo.send(liblo.Address("192.168.1.11", 60000), "/dmx1/1", 255, 255, 255, 255)</pre></blockquote>
</p>
<p>
To receive input over DMX, raw sockets can be used easily:
<blockquote><pre>sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.sendto("/dmx1/input\x00,si\x00me\x00\x00\x00\x00\x00\x00", ("192.168.1.11", 60000))
while True:
data, addr = sock.recvfrom(1024)
print "DMX channels: %d %d %d %d" % map(ord, data[16:20]))</pre></blockquote>
</p>
<p>
Or liblo's server functionality can be used instead:
<blockquote><pre>import liblo
class DMXServer(liblo.Server):
@liblo.make_method('/dmx1', 'b')
def dmx1_callback(self, channel_blob):
chanenls = map(ord, channel_blob)
print "DMX channels: %d %d %d %d" % channels[:4]
server = DMXServer(32123)
liblo.send(liblo.Address("192.168.1.11", 60000), "/dmx1/input", "me", 32123)
while True:
server.recv(100)</pre></blockquote>
</p>
<h2 id="parameters">Parameters</h2>
<p>
The other capabilites of the Ether Dream are accessed via its <i>parameters</i>. Parameters can be
set and actions invoked in two ways:
<ol>
<li>The DAC listens for <a href="http://opensoundcontrol.org/">OSC</a> packets on a UDP port.</li>
<li>On startup, commands are loaded from the <code>autoplay.txt</code> on the SD card, if present.</li>
</ol>
</p>
<p><a href="http://opensoundcontrol.org/">OSC</a> is a simple UDP-based protocol for
sending control messages; it is usually used for audio, to control synthesizers, mixers,
etc., but is flexible enough to support laser applications as well. Bridges exist
between OSC and MIDI or DMX. An OSC message is sent to an <i>address</i>, like
<code>/channel/1/volume</code> or <code>/ilda/pps</code>, and contains some <i>data</i>:
zero or more numbers, strings, True/False values, etc.
</p>
<p>
The Ether Dream listens for OSC messages on UDP port 60000. When it sends a response to
a message, it will send that response to port 60001 on the originating host. There
are many OSC-handling programs and OSC plugins, as well as libraries for most programming
languages, available on the Internet.
</p>
<p>
Most of the OSC parameter endpoints implemented on the Ether Dream take some
sort of data. Those labeled as "integer" or "float" expect a value in the given range.
OSC endpoints specified as "message" can be sent a message with either no data or with an
integer value, but will ignore the message if the value is zero. This allows them to
be controlled by a pushbutton on a control surface that sends OSC messages - a pushbutton
will send a nonzero value when it is pressed, and then send 0 when it is released.
</p>
<ul>
<li><code>/ilda/play</code> <i>filename</i> - string
<p>Writing a string to this address causes the DAC to switch to file playback mode and
begin playing <i>filename</i> from the SD card.</p>
<p><b>NOTE:</b> Playing a file by name can currently only be done via autoplay.txt, not
via OSC.</p>
</li>
<li><code>/ilda/</code><i>n</i><code>/play</code> - message
<p>As <code>/ilda/play</code> <i>filename</i>, but plays the <i>n</i>th file found on the SD card.
Works over OSC.</p>
</li>
<li><code>/ilda/fps</code> <i>fps</i> - integer
<p>Switch to file playback mode and set the frame rate limit to <i>fps</i>.
</li>
<li><code>/ilda/pps</code> <i>pps</i> - integer
<p>Switch to file playback mode and set the point rate to <i>pps</i>.
</li>
<li><code>/ilda/repeat</code> <i>value</i> - integer
<p>Switch to file playback mode. If <i>value</i> is nonzero, then files played will be repeated
until a stop command is received; if zero, playback stops at the end of a file.</p>
</li>
<li><code>/stop</code> - message
<p>Stop playing the current file.</p>
</li>
<li><code>/geom/tl</code>, <code>/geom/tr</code>, <code>/geom/bl</code>, <code>/geom/br</code> <i>x</i> <i>y</i> - float, range [-1, 1]
<p>Set the position of a corner of the image within the overall projection field. Values range from -1 to 1. This
can apply any arbitrary perspective transform to the input image.</p>
<p>The output bottom left is (-1, -1); the output top right is (1, 1). For example, to leave the image
unchanged, set the values as:
<ul><li><code>/geom/tl</code> -1 1</li>
<li><code>/geom/tr</code> 1 1</li>
<li><code>/geom/bl</code> -1 -1</li>
<li><code>/geom/br</code> 1 -1</li></ul></p>
</li>
<li><code>/geom/size</code> <i>size</i>, <code>/geom/offset</code> <i>offset-x</i> <i>offset-y</i>
<p>These parameters provide a shortcut to setting per-corner positions when only size
and position adjustments are needed. To set the image at 50% size and in the top right
corner of the projection field, set:
<ul><li><code>/geom/size</code> 0.5</li>
<li><code>/geom/offset</code> 0.5 0.5</li></ul></p>
</li>
<li><code>/geom/rdelay</code>, <code>/geom/gdelay</code>, <code>/geom/bdelay</code> <i>points</i> - integer, 0 to 15
<p>Set the delay on the red, green, or blue color channel to <i>points</i> points.
</li>
</ul>
<p>
As an example, the following <code>autoplay.txt</code> file might be used to play a prerecorded show
automatically when the DAC is powered up:
<blockquote><pre>/ilda/pps 30000
/ilda/fps 30
/geom/size 0.3
/geom/offset 0.4 -0.2
/ilda/play show.ild</pre></blockquote>
</p>
<p>
The following Python code, using <a href="http://das.nasophon.de/pyliblo/">liblo</a>, will play the first ILDA
file on the SD card:
<blockquote><pre>import liblo
dac = liblo.Address("192.168.1.107", 60000)
liblo.send(dac, "/ilda/1/play")</blockquote>
</p>
<p>Control layout files for TouchOSC, a third-party iPhone/iPad app, are available
in the Ether Dream source repository under the <a href="https://github.com/j4cbo/j4cDAC/tree/master/tools">tools/</a> directory - <code>j4cDAC.touchosc</code> is for iPad, and
<code>j4cDAC-phone.touchosc</code> is for iPhone.</p>
<h2 id="dev">Development</h2>
The Ether Dream firmware, available <a href="https://github.com/j4cbo/j4cDAC">on github</a>,
builds on a standard Linux system with the free CodeSourcery ARM toolchain. The README in the
repository describes the needed tools.
</div>
<div id="footer">
&copy; 2010-2021 Jacob Potter.
</div>
<div id="menu">
<ul>
<li><a href="../index.html">LJ doc</a></li>
<li><a href="protocol.html">Protocol</a></li>
<li><a href="userguide.html">V1 User Guide</a></li>
<li><a href="manual.html">V1 Developer Manual</a></li>
<li><a href="dmx.html">V1 DMX Board</a></li>
</ul>
</div>
</body>
</html>