1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
//! DMX512
//!
//! The "Digital Multiplex" (DMX) protocol is used to control stage lighting
//! and effects in large and small setups. It is electrically based on [RS485]
//! (https://en.wikipedia.org/wiki/RS-485) and can (almost) easily be
//! implemented on microcontrollers as well as soft real-time capable operating
//! systems.
//!
//! ## The protocol
//!
//! The protocol itself assumes a single-master/multiple-slave system. The
//! master periodically sends updates for up to 512 *channels*. Each one of
//! these updates is called a DMX *packet*, which consists of a *start code*
//! and any number of channels, in-order starting from channel 1. Packets can
//! contain less than 512 channels, but must always start at 1 and progress
//! in order.
//!
//! Channels are byte values ranging from 0 to 255. For most channels these
//! are intensity values, with 0 being "off" and 255 "full brightness". However
//! other functions may be connected to a channel, such as selecting a blink
//! sequence or setting a servo position.
//!
//! ## Technical details
//!
//! DMX is transmitted using serial protocol at the unusual bitrate of
//! 250,000 baud, with no parity and two stop bits.
//!
//! To begin a transmission, a sender must first pull the line low to send a
//! so called *break*, followed by pulling it high to send a *mark*. The
//! duration of this break is fairly long, as is the mark, both being far
//! longer than the time it usually takes to submit a single byte.
//!
//! After the break/mark-after-break sequence, regular transmission begins at
//! 250,000 baud by sending a single-byte start code. This start code is almost
//! always `0xFF`, unless special functions are used, which are
//! vendor-specific.
//!
//! Right after the start code, any number of channels may be transmitted.
//!
//! ## Refresh rate
//!
//! The refresh rate depends on the number of channels transmitted. For the
//! full 512 channels, the maximum achievable standard-compliant refresh rate
//! is about 44 frames per second. If less than 512 channels are sent inside
//! a packet, higher refresh rate are possible.
//!
//! It should be noted that there is a minimum time between breaks (and
//! therefore DMX packets) of 1204 microseconds, theoretically capping the
//! refresh rate at about 830 updates per second.
//!
//! DMX is usually meant to be sent continuously, with at least one update
//! per second. A lot of devices will switch off if intervals become too large.
//!
//! ## More information
//!
//! The [DMX512-A standard]
//! (http://tsp.esta.org/tsp/documents/docs/E1-11_2008R2013.pdf) contains the
//! detailed specification.
//!
//! # Implementations
//!
//! Currently, only an implementation using Linux serial devices is available.
//! Connecting a UART to an RS485 transceiver is enough to get this working.
//! The implementation is not 100% optimal for DMX: As most Linux kernels
//! are not real-time capable, perfectly stable frame rates are not always
//! achievable. However, the DMX protocol is fairly tolerant of loose timing.
//!
//! The UARTs must support non-standard baudrates and reasonably fast baud-rate
//! switching. Sending a break is done by switch to a slow baud-rate, sending
//! a single `0x00` byte, then waiting a bit and switching back to 250,000
//! baud.
//!
//! ## Example
//!
//! The interface is fairly simple to use:
//!
//! ```no_run
//! use dmx::{self, DmxTransmitter};
//! use std::{thread, time};
//!
//! let mut dmx_port = dmx::open_serial("/dev/ttyS1").unwrap();
//!
//! // a typical 4-channel device, expecting RGBV values. this will set a
//! // fairly bright yellow.
//! let data = &[0xe4, 0xe4, 0x00, 0xca];
//!
//! loop {
//! dmx_port.send_dmx_packet(data).unwrap();
//!
//! // repeat about every 51 ms. for more accurate frame timings,
//! // consider using the ticktock crate.
//! thread::sleep(time::Duration::new(0, 50_000_000));
//! }
//! ```
use OsStr;
extern crate dmx_serial as serial;
extern crate lazy_static;
use ;
// The ideal baudrate for sending a break is 45,455 baud.
// At this rate, sendin an 8-bit 0x00 will take the recommended 176 us
// The following stop bit would take a reasonable 22 us.
//
// However, this non-standard baud rate is not supported. The closest common
// baud rates are 57,600 bit/s and 38,400 bit/s. The former is chose here,
// resulting in the following timings:
//
// BREAK: 138 us (spec minimum is 92 uS)
// actual BREAK
// MARK-AFTER-BREAK: 17 us (spec minimum is 8 uS)
const BREAK_SETTINGS: PortSettings = PortSettings ;
const DMX_SETTINGS: PortSettings = PortSettings ;
lazy_static!
/// A DMX transmitter.
///
/// Usually there is one transmitter on a bus, the master. Transmitters send
/// DMX data.
/// Opens a serial device with DMX support.
Sized>