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
use std::ffi::OsStr;
extern crate dmx_serial as serial;
#[macro_use]
extern crate lazy_static;
use std::{cmp, thread, time};
const BREAK_SETTINGS: serial::PortSettings = serial::PortSettings {
baud_rate: serial::Baud57600,
char_size: serial::Bits7,
parity: serial::ParityNone,
stop_bits: serial::Stop1,
flow_control: serial::FlowNone,
};
const DMX_SETTINGS: serial::PortSettings = serial::PortSettings {
baud_rate: serial::BaudOther(250_000),
char_size: serial::Bits8,
parity: serial::ParityNone,
stop_bits: serial::Stop2,
flow_control: serial::FlowNone,
};
lazy_static! {
static ref SERIAL_TOTAL_BREAK: time::Duration = time::Duration::new(0, 136_000);
}
pub trait DmxPort {
fn send_break(&mut self) -> serial::Result<()>;
fn send_raw_data(&mut self, data: &[u8]) -> serial::Result<()>;
#[inline(always)]
fn send_dmx_packet(&mut self, data: &[u8]) -> serial::Result<()> {
self.send_dmx_alt_packet(data, 0x00)
}
#[inline]
fn send_dmx_alt_packet(&mut self, data: &[u8], start: u8) -> serial::Result<()> {
let mut prefixed = [0; 513];
let dlen = cmp::min(data.len(), 512);
prefixed[0] = start;
prefixed[1..(dlen + 1)].clone_from_slice(data);
self.send_raw_dmx_packet(&prefixed)
}
fn send_raw_dmx_packet(&mut self, data: &[u8]) -> serial::Result<()>;
}
impl<T: serial::SerialPort> DmxPort for T {
#[inline(always)]
fn send_break(&mut self) -> serial::Result<()> {
self.configure(&BREAK_SETTINGS)?;
self.write(&[0x00])?;
Ok(())
}
#[inline(always)]
fn send_raw_data(&mut self, data: &[u8]) -> serial::Result<()> {
self.configure(&DMX_SETTINGS)?;
self.write(data)?;
Ok(())
}
#[inline]
fn send_raw_dmx_packet(&mut self, data: &[u8]) -> serial::Result<()> {
let min_brk = *SERIAL_TOTAL_BREAK;
self.send_break()?;
thread::sleep(min_brk);
self.send_raw_data(data)?;
Ok(())
}
}
pub fn open_serial<T: AsRef<OsStr> + ?Sized>(port: &T) -> serial::Result<serial::SystemPort> {
serial::open(port)
}