Skip to content

Commit 18707fd

Browse files
committed
Add calibration support
1 parent b424f30 commit 18707fd

File tree

9 files changed

+390
-351
lines changed

9 files changed

+390
-351
lines changed

Cargo.lock

+60-114
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+8-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ doc = false
1616
[dependencies]
1717
chrono = "0.2"
1818
clap = "2.19"
19-
env_logger = "0.3"
19+
env_logger = "0.4"
2020
error-chain = "0.7"
2121
flate2 = "0.2"
2222
lazy_static = "0.2"
@@ -57,6 +57,13 @@ path = "../glutin"
5757

5858
[build-dependencies]
5959
regex = "0.2"
60+
serde = "0.8"
61+
serde_derive = "0.8"
62+
63+
[build-dependencies.toml]
64+
version = "0.2"
65+
default-features = false
66+
features = ["serde"]
6067

6168
[features]
6269
default = ["conrod", "lang_en-US"]

build.rs

+78-55
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,37 @@
11
extern crate regex;
2+
extern crate serde;
3+
#[macro_use] extern crate serde_derive;
4+
extern crate toml;
25

36
use regex::{Captures, Regex};
47

58
use std::collections::HashMap;
69
use std::env;
710
use std::fs::{self, File};
8-
use std::io::{self, BufWriter, Write};
11+
use std::io::{self, BufReader, BufWriter, Read, Write};
912
use std::path::{Path, PathBuf};
1013
use std::process::Command;
1114
use std::time::{self, SystemTime};
1215

16+
#[derive(Deserialize)]
17+
struct Config {
18+
board: String,
19+
calibration_pin: Option<u8>,
20+
sensor_pins: Vec<u8>,
21+
paths: Paths
22+
}
23+
24+
#[derive(Deserialize)]
25+
struct Paths {
26+
home: Option<PathBuf>,
27+
#[serde(default)]
28+
hardware: Vec<PathBuf>,
29+
#[serde(default)]
30+
tools: Vec<PathBuf>,
31+
#[serde(default)]
32+
libraries: Vec<PathBuf>,
33+
}
34+
1335
fn load_prefs_from_str(pref_str: &str) -> HashMap<&str, String> {
1436
let mut prefs = HashMap::new();
1537
for line in pref_str.lines() {
@@ -53,16 +75,16 @@ fn write_board_file(path: &Path, prefs: &HashMap<&str, String>, name: &str, time
5375
if *tool != "avrdude" {
5476
panic!("Only AVR boards are supported.");
5577
}
56-
let protocol: String = prefs.get("upload.protocol").map(Clone::clone).unwrap_or_default();
78+
let protocol: String = prefs.get("upload.protocol").cloned().unwrap_or_default();
5779
let speed: usize = prefs.get("upload.speed").and_then(|s| s.parse().ok()).unwrap_or_default();
5880
let use_1200bps_touch: bool = prefs.get("upload.use_1200bps_touch")
5981
.and_then(|s| s.parse().ok()).unwrap_or_default();
6082
let wait_for_upload_port: bool = prefs.get("upload.wait_for_upload_port")
6183
.and_then(|s| s.parse().ok()).unwrap_or_default();
62-
let mcu: String = prefs.get("build.mcu").map(Clone::clone).unwrap_or_default();
84+
let mcu: String = prefs.get("build.mcu").cloned().unwrap_or_default();
6385
let config_path: PathBuf = prefs.get("config.path").map_or(PathBuf::new(), PathBuf::from);
6486
let build_path: PathBuf = prefs.get("build.path").map_or(PathBuf::new(), PathBuf::from);
65-
let project_name: String = prefs.get("build.project_name").map(Clone::clone).unwrap_or_default();
87+
let project_name: String = prefs.get("build.project_name").cloned().unwrap_or_default();
6688

6789
let mut writer = BufWriter::new(File::create(path).unwrap());
6890
writeln!(writer, r##"pub const PROTOCOL: &'static str = r#"{}"#;"##, protocol).unwrap();
@@ -77,51 +99,54 @@ fn write_board_file(path: &Path, prefs: &HashMap<&str, String>, name: &str, time
7799
name, env!("CARGO_PKG_VERSION"), timestamp).unwrap();
78100
}
79101

80-
fn builder_command(compile: bool, src_path: &Path, out_path: &Path, prefs: Option<HashMap<&str, String>>) -> Command {
102+
fn builder_command(compile: bool, src_path: &Path, out_path: &Path, mut extra_flags: String, mut defines: Option<HashMap<&str, String>>) -> Command {
81103
let mut command = Command::new("arduino-builder");
82104
command.arg("-libraries").arg("libraries")
83105
.arg("-build-path").arg(out_path)
84106
.arg("-warnings").arg("all")
85107
.arg("-verbose")
86108
.arg(if compile { "-compile" } else { "-dump-prefs" });
87109

88-
if Path::new("build.options.json").exists() {
89-
command.arg("-build-options-file").arg("build.options.json");
90-
} else {
91-
if let Some(home) = env::var_os("ARDUINO_HOME").map(PathBuf::from) {
92-
command.arg("-built-in-libraries").arg(home.join("libraries"))
93-
.arg("-hardware").arg(home.join("hardware"))
94-
.arg("-tools").arg(home.join("hardware/tools/avr"))
95-
.arg("-tools").arg(home.join("tools-builder"));
96-
}
97-
98-
if let Some(board) = env::var_os("ARDUINO_BOARD") {
99-
command.arg("-fqbn").arg(board);
100-
}
101-
102-
if let Some(hardware) = env::var_os("ARDUINO_HARDWARE") {
103-
for path in env::split_paths(&hardware) {
104-
command.arg("-hardware").arg(path);
105-
}
106-
}
107-
108-
if let Some(tools) = env::var_os("ARDUINO_TOOLS") {
109-
for path in env::split_paths(&tools) {
110-
command.arg("-tools").arg(path);
111-
}
110+
let mut reader = BufReader::new(File::open("build.toml").unwrap());
111+
let mut toml = String::new();
112+
reader.read_to_string(&mut toml).unwrap();
113+
let config = toml::decode_str::<Config>(&toml).unwrap();
114+
115+
command.arg("-fqbn").arg(&config.board);
116+
if let Some(home) = config.paths.home.or_else(|| env::var_os("ARDUINO_HOME").map(PathBuf::from)) {
117+
command.arg("-built-in-libraries").arg(home.join("libraries"))
118+
.arg("-hardware").arg(home.join("hardware"))
119+
.arg("-tools").arg(home.join("hardware/tools/avr"))
120+
.arg("-tools").arg(home.join("tools-builder"));
121+
}
122+
for path in &config.paths.hardware {
123+
command.arg("-hardware").arg(path);
124+
}
125+
for path in &config.paths.tools {
126+
command.arg("-tools").arg(path);
127+
}
128+
for path in &config.paths.libraries {
129+
command.arg("-libraries").arg(path);
130+
}
131+
if let Some(ref mut defines) = defines.as_mut() {
132+
if let Some(calibration_pin) = config.calibration_pin {
133+
defines.insert("CALIBRATION_PIN", calibration_pin.to_string());
112134
}
135+
let sensor_pins = config.sensor_pins.iter()
136+
.map(|pin| format!("{{{:#04x}, A{}}}", pin, pin))
137+
.collect::<Vec<_>>()
138+
.join(", ");
139+
defines.insert("SENSOR_PINS", format!("{{{}}}", sensor_pins));
140+
}
113141

114-
if let Some(libraries) = env::var_os("ARDUINO_LIBRARIES") {
115-
for path in env::split_paths(&libraries) {
116-
command.arg("-libraries").arg(path);
117-
}
142+
if let Some(defines) = defines {
143+
for (key, value) in defines {
144+
extra_flags.push_str(&format!(" '-D{}={}'", key, value));
118145
}
119146
}
120147

121-
if let Some(prefs) = prefs {
122-
for (key, value) in prefs {
123-
command.arg("-prefs").arg(format!("{}={}", key, value));
124-
}
148+
if !extra_flags.is_empty() {
149+
command.arg("-prefs").arg(format!("build.extra_flags={}", extra_flags));
125150
}
126151

127152
command.arg(src_path);
@@ -131,13 +156,13 @@ fn builder_command(compile: bool, src_path: &Path, out_path: &Path, prefs: Optio
131156

132157
pub fn main() {
133158
let timestamp = SystemTime::now().duration_since(time::UNIX_EPOCH).unwrap().as_secs();
134-
let out = PathBuf::from(env::var_os("OUT_DIR").unwrap());
135-
let src = Path::new("src/arduino/program.ino");
136-
let arduino_out = out.join("arduino");
137-
fs::create_dir_all(&arduino_out).unwrap();
159+
let out_path = PathBuf::from(env::var_os("OUT_DIR").unwrap());
160+
let src_path = Path::new("src/arduino/program.ino");
161+
let build_path = out_path.join("arduino");
162+
fs::create_dir_all(&build_path).unwrap();
138163

139164
// Dump preferences
140-
let output = builder_command(false, src, &arduino_out, None).output().unwrap();
165+
let output = builder_command(false, src_path, &build_path, String::new(), None).output().unwrap();
141166
let _ = io::stdout().write_all(&output.stdout);
142167
let _ = io::stderr().write_all(&output.stderr);
143168
if !output.status.success() {
@@ -148,21 +173,19 @@ pub fn main() {
148173
let prefs_str = String::from_utf8_lossy(&output.stdout);
149174
let prefs = load_prefs_from_str(&prefs_str);
150175
let expanded_prefs = expand_prefs(&prefs);
151-
let name = expanded_prefs.get("name").map(Clone::clone).unwrap_or_default();
152-
write_board_file(&out.join("board.rs"), &expanded_prefs, &name, timestamp);
176+
let name = expanded_prefs.get("name").cloned().unwrap_or_default();
177+
write_board_file(&out_path.join("board.rs"), &expanded_prefs, &name, timestamp);
153178

154179

155180

156181
// Compile sketch
157-
let mut extra_prefs = HashMap::new();
158-
let extra_flags = format!(r#"{}'-DDEVICEINFO_NAME="{}"' '-DDEVICEINFO_VERSION="{}"' -DDEVICEINFO_TIMESTAMP={:#x}"#,
159-
prefs.get("build.extra_flags").map_or_else(String::new, |flags| format!("{} ", flags)),
160-
name,
161-
env!("CARGO_PKG_VERSION"),
162-
timestamp);
163-
extra_prefs.insert("build.extra_flags", extra_flags);
164-
165-
let output = builder_command(true, src, &arduino_out, Some(extra_prefs)).output().unwrap();
182+
let extra_flags = prefs.get("build.extra_flags").cloned().unwrap_or_default();
183+
let mut defines = HashMap::new();
184+
defines.insert("DEVICEINFO_NAME", format!(r#""{}""#, name));
185+
defines.insert("DEVICEINFO_VERSION", format!(r#""{}""#, env!("CARGO_PKG_VERSION")));
186+
defines.insert("DEVICEINFO_TIMESTAMP", format!("{:#x}", timestamp));
187+
188+
let output = builder_command(true, src_path, &build_path, extra_flags, Some(defines)).output().unwrap();
166189
let _ = io::stdout().write_all(&output.stdout);
167190
let _ = io::stderr().write_all(&output.stderr);
168191
if !output.status.success() {
@@ -176,6 +199,6 @@ pub fn main() {
176199
}
177200
}
178201

179-
println!("cargo:rerun-if-changed=src/arduino/program.ino");
180-
println!("cargo:rerun-if-changed=build.options.json");
202+
println!("cargo:rerun-if-changed={}", src_path.display());
203+
println!("cargo:rerun-if-changed=build.toml");
181204
}

src/arduino/mod.rs

+7-50
Original file line numberDiff line numberDiff line change
@@ -165,37 +165,6 @@ impl DeviceInfo {
165165
}
166166
}
167167

168-
#[derive(Clone, Copy, Debug)]
169-
pub struct SensorConfig {
170-
range: (u16, u16),
171-
thresholds: (u8, u8)
172-
}
173-
174-
impl SensorConfig {
175-
pub fn new(min: u16, max: u16) -> SensorConfig {
176-
debug_assert!(max < 1024);
177-
debug_assert!(min < 1024);
178-
SensorConfig {
179-
range: (min, max),
180-
thresholds: (u8::MIN, u8::MAX)
181-
}
182-
}
183-
184-
pub fn range(&self) -> (u16, u16) {
185-
self.range
186-
}
187-
188-
pub fn thresholds(&self) -> (u8, u8) {
189-
self.thresholds
190-
}
191-
192-
pub fn set_thresholds(&mut self, low: u8, high: u8) {
193-
debug_assert!(low < high);
194-
self.thresholds = (low, high);
195-
}
196-
}
197-
198-
199168

200169
pub struct Arduino(SystemPort);
201170

@@ -253,8 +222,7 @@ impl Arduino {
253222
#[cfg(windows)]
254223
::std::os::windows::process::CommandExt::creation_flags(&mut command, ::winapi::CREATE_NO_WINDOW);
255224

256-
let mut process = command.arg("-v").arg("-v")
257-
.arg("-C").arg(avrdude_conf_path)
225+
let mut process = command.arg("-C").arg(avrdude_conf_path)
258226
.arg("-p").arg(board::MCU)
259227
.arg("-c").arg(board::PROTOCOL)
260228
.arg("-P").arg(port.name())
@@ -428,26 +396,15 @@ impl Arduino {
428396
self.send_request("poll_event", &[])
429397
}
430398

431-
pub fn sensor_values(&mut self, raw: bool) -> Result<Vec<Option<u16>>> {
432-
self.send_request("sensor_values", &[("raw", serde_json::to_value(raw))])
399+
pub fn read_values(&mut self, raw: bool) -> Result<Vec<Option<u16>>> {
400+
self.send_request("read_values", &[("raw", serde_json::to_value(raw))])
433401
}
434402

435-
pub fn set_sensor(&mut self, id: u8, config: &SensorConfig) -> Result<()> {
436-
let (min, max) = config.range();
437-
let (low, high) = config.thresholds();
438-
439-
self.send_request("set_sensor", &[
403+
pub fn set_thresholds(&mut self, id: u8, trigger: u8, release: u8) -> Result<()> {
404+
self.send_request("set_thresholds", &[
440405
("id", serde_json::to_value(id)),
441-
("min", serde_json::to_value(min)),
442-
("max", serde_json::to_value(max)),
443-
("low", serde_json::to_value(low)),
444-
("high", serde_json::to_value(high))
445-
])
446-
}
447-
448-
pub fn unset_sensor(&mut self, id: u8) -> Result<()> {
449-
self.send_request("unset_sensor", &[
450-
("id", serde_json::to_value(id))
406+
("trigger", serde_json::to_value(trigger)),
407+
("release", serde_json::to_value(release))
451408
])
452409
}
453410
}

0 commit comments

Comments
 (0)