Reformat code

This commit is contained in:
FliegendeWurst 2022-04-24 16:11:54 +02:00
parent d8b6ffec7e
commit 106e4050b0
3 changed files with 287 additions and 247 deletions

3
rustfmt.toml Normal file
View File

@ -0,0 +1,3 @@
hard_tabs = true
match_block_trailing_comma = true
max_width = 120

View File

@ -1,94 +1,100 @@
use std::{thread::sleep, time::{self, Duration}}; use std::{
thread::sleep,
time::{self, Duration},
};
use gpio_cdev::{EventType, Line, LineRequestFlags}; use gpio_cdev::{EventType, Line, LineRequestFlags};
fn read_events(line: &gpio_cdev::Line, timeout: std::time::Duration) -> Result<Vec<(u64, EventType)>, SensorError> { fn read_events(line: &gpio_cdev::Line, timeout: std::time::Duration) -> Result<Vec<(u64, EventType)>, SensorError> {
let input = line.request( let input = line.request(LineRequestFlags::INPUT, 0, "read-data")?;
LineRequestFlags::INPUT,
0,
"read-data")?;
let mut last_state = 1; let mut last_state = 1;
let start = time::Instant::now(); let start = time::Instant::now();
let mut events = Vec::with_capacity(81); let mut events = Vec::with_capacity(81);
while start.elapsed() < timeout && events.len() < 81 { while start.elapsed() < timeout && events.len() < 81 {
let new_state = input.get_value()?; let new_state = input.get_value()?;
if new_state != last_state { if new_state != last_state {
let timestamp = start.elapsed(); let timestamp = start.elapsed();
let event_type = if last_state < new_state { let event_type = if last_state < new_state {
EventType::RisingEdge EventType::RisingEdge
} else { } else {
EventType::FallingEdge EventType::FallingEdge
}; };
events.push((timestamp.as_micros() as u64, event_type)); events.push((timestamp.as_micros() as u64, event_type));
last_state = new_state; last_state = new_state;
} }
} }
if events.len() < 81 { if events.len() < 81 {
return Err(SensorError::Timeout); return Err(SensorError::Timeout);
} }
Ok(events) Ok(events)
} }
fn events_to_data(events: Vec<(u64, EventType)>) -> Vec<u8> { fn events_to_data(events: Vec<(u64, EventType)>) -> Vec<u8> {
events[1..] events[1..]
.windows(2) .windows(2)
.map(|pair| { .map(|pair| {
let prev = pair.get(0).unwrap(); let prev = pair.get(0).unwrap();
let next = pair.get(1).unwrap(); let next = pair.get(1).unwrap();
match next.1 { match next.1 {
EventType::FallingEdge => Some(next.0 - prev.0), EventType::FallingEdge => Some(next.0 - prev.0),
EventType::RisingEdge => None, EventType::RisingEdge => None,
} }
}) })
.filter(|&d| d.is_some()) .filter(|&d| d.is_some())
.map(|elapsed| { .map(|elapsed| if elapsed.unwrap() > 35 { 1 } else { 0 })
if elapsed.unwrap() > 35 { 1 } else { 0 } .collect()
}).collect()
} }
const MAX_HUMIDITY: u16 = 1000; const MAX_HUMIDITY: u16 = 1000;
fn process_data(mut bits: &[u8]) -> Result<(u16, u16), SensorError> { fn process_data(mut bits: &[u8]) -> Result<(u16, u16), SensorError> {
if bits[0] == 1 { if bits[0] == 1 {
// definitely incorrect first bit // definitely incorrect first bit
// (the humidity can't be this big..) // (the humidity can't be this big..)
bits = &bits[1..]; bits = &bits[1..];
} }
let bytes: Vec<u8> = bits let bytes: Vec<u8> = bits
.chunks(8) .chunks(8)
.map(|chunk| chunk.iter() .map(|chunk| {
.enumerate() chunk
// 8 bits, starting with the MSB .iter()
.map(|(bit_idx, &x)| x << (7 - bit_idx)) .enumerate()
.sum() // 8 bits, starting with the MSB
).collect(); .map(|(bit_idx, &x)| x << (7 - bit_idx))
let rh = (bytes[0] as u16) << 8 | bytes[1] as u16; .sum()
})
.collect();
let rh = (bytes[0] as u16) << 8 | bytes[1] as u16;
if rh > MAX_HUMIDITY { if rh > MAX_HUMIDITY {
return Err(SensorError::HumidityTooHigh); return Err(SensorError::HumidityTooHigh);
} }
let celsius = (bytes[2] as u16) << 8 | bytes[3] as u16; let celsius = (bytes[2] as u16) << 8 | bytes[3] as u16;
if bits.len() >= 40 { if bits.len() >= 40 {
let cksum: u8 = bits[32..40] let cksum: u8 = bits[32..40].iter().enumerate().map(|(idx, &x)| x << (7 - idx)).sum();
.iter() let actual_sum = (bytes[0]
.enumerate() .wrapping_add(bytes[1])
.map(|(idx, &x)| x << (7 - idx)) .wrapping_add(bytes[2])
.sum(); .wrapping_add(bytes[3]))
let actual_sum = (bytes[0].wrapping_add(bytes[1]).wrapping_add(bytes[2]).wrapping_add(bytes[3])) & 0xff; & 0xff;
if actual_sum != cksum { if actual_sum != cksum {
return Err(SensorError::ChecksumMismatch); return Err(SensorError::ChecksumMismatch);
} }
} }
Ok((rh, celsius)) Ok((rh, celsius))
} }
#[test] #[test]
fn test_process_data() { fn test_process_data() {
let x = process_data(&[1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1]).unwrap(); let x = process_data(&[
assert_eq!(471, x.0); 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0,
assert_eq!(268, x.1); 0, 1, 1,
])
.unwrap();
assert_eq!(471, x.0);
assert_eq!(268, x.1);
} }
#[derive(Debug)] #[derive(Debug)]
@ -96,45 +102,45 @@ pub enum SensorError {
Io(gpio_cdev::Error), Io(gpio_cdev::Error),
ChecksumMismatch, ChecksumMismatch,
HumidityTooHigh, HumidityTooHigh,
Timeout Timeout,
} }
impl From<gpio_cdev::Error> for SensorError { impl From<gpio_cdev::Error> for SensorError {
fn from(error: gpio_cdev::Error) -> Self { fn from(error: gpio_cdev::Error) -> Self {
SensorError::Io(error) SensorError::Io(error)
} }
} }
pub fn am2302_reading(line: &Line) -> Result<(u16, u16), SensorError> { pub fn am2302_reading(line: &Line) -> Result<(u16, u16), SensorError> {
line.request(LineRequestFlags::OUTPUT, 1, "rust-am2302").unwrap(); line.request(LineRequestFlags::OUTPUT, 1, "rust-am2302").unwrap();
sleep(Duration::from_millis(500)); sleep(Duration::from_millis(500));
set_max_priority(); set_max_priority();
// set low for 20 ms // set low for 20 ms
if let Err(e) = line.request(LineRequestFlags::OUTPUT, 0, "rust-am2302") { if let Err(e) = line.request(LineRequestFlags::OUTPUT, 0, "rust-am2302") {
set_normal_priority(); set_normal_priority();
return Err(SensorError::Io(e)); return Err(SensorError::Io(e));
} }
sleep(Duration::from_millis(3)); sleep(Duration::from_millis(3));
let events = read_events(&line, Duration::from_secs(1)); let events = read_events(&line, Duration::from_secs(1));
println!("{:?} {:?}", events, events.as_ref().map(|x| x.len())); println!("{:?} {:?}", events, events.as_ref().map(|x| x.len()));
set_normal_priority(); set_normal_priority();
let events = events?; let events = events?;
let data = events_to_data(events); let data = events_to_data(events);
process_data(&data) process_data(&data)
} }
fn set_max_priority() { fn set_max_priority() {
unsafe { unsafe {
let mut sched_para: libc::sched_param = std::mem::transmute([0u8; std::mem::size_of::<libc::sched_param>()]); let mut sched_para: libc::sched_param = std::mem::transmute([0u8; std::mem::size_of::<libc::sched_param>()]);
sched_para.sched_priority = libc::sched_get_priority_max(libc::SCHED_FIFO); sched_para.sched_priority = libc::sched_get_priority_max(libc::SCHED_FIFO);
libc::sched_setscheduler(0, libc::SCHED_FIFO, (&sched_para) as *const libc::sched_param); libc::sched_setscheduler(0, libc::SCHED_FIFO, (&sched_para) as *const libc::sched_param);
} }
} }
fn set_normal_priority() { fn set_normal_priority() {
unsafe { unsafe {
let sched_para: libc::sched_param = std::mem::transmute([0u8; std::mem::size_of::<libc::sched_param>()]); let sched_para: libc::sched_param = std::mem::transmute([0u8; std::mem::size_of::<libc::sched_param>()]);
libc::sched_setscheduler(0, libc::SCHED_OTHER, (&sched_para) as *const libc::sched_param); libc::sched_setscheduler(0, libc::SCHED_OTHER, (&sched_para) as *const libc::sched_param);
} }
} }

View File

@ -6,26 +6,25 @@ use embedded_graphics::prelude::*;
use embedded_graphics::primitives::{Circle, Line, PrimitiveStyle, Rectangle}; use embedded_graphics::primitives::{Circle, Line, PrimitiveStyle, Rectangle};
use embedded_graphics::{ use embedded_graphics::{
mono_font::{ascii::FONT_6X10, MonoTextStyleBuilder}, mono_font::{ascii::FONT_6X10, MonoTextStyleBuilder},
text::Text, text::Text,
}; };
use embedded_hal::digital::v2::{InputPin, OutputPin}; use embedded_hal::digital::v2::{InputPin, OutputPin};
use embedded_hal::prelude::_embedded_hal_blocking_i2c_Write; use embedded_hal::prelude::_embedded_hal_blocking_i2c_Write;
use gpio_cdev::{Chip, EventRequestFlags, EventType, LineRequestFlags}; use gpio_cdev::{Chip, EventRequestFlags, EventType, LineRequestFlags};
use linux_embedded_hal::i2cdev::core::I2CDevice; use linux_embedded_hal::i2cdev::core::I2CDevice;
use linux_embedded_hal::i2cdev::linux::LinuxI2CError; use linux_embedded_hal::i2cdev::linux::LinuxI2CError;
use rusqlite::{Connection, params};
use ssd1306::{prelude::*, I2CDisplayInterface, Ssd1306};
use linux_embedded_hal::{Delay, I2cdev}; use linux_embedded_hal::{Delay, I2cdev};
use machine_ip; use machine_ip;
use rusqlite::{params, Connection};
use ssd1306::{prelude::*, I2CDisplayInterface, Ssd1306};
use std::intrinsics::transmute; use std::intrinsics::transmute;
use std::{env, mem, time};
use std::thread::sleep; use std::thread::sleep;
use std::time::{Duration, SystemTime}; use std::time::{Duration, SystemTime};
use std::{env, mem, time};
static IMG_DATA: &[u8; 512] = include_bytes!("../rust.raw"); static IMG_DATA: &[u8; 512] = include_bytes!("../rust.raw");
const CCS811_ADDR: u8 = 0x5A; // or 0x5B const CCS811_ADDR: u8 = 0x5A; // or 0x5B
const CCS811_STATUS: u8 = 0x00; const CCS811_STATUS: u8 = 0x00;
@ -45,209 +44,215 @@ const CCS811_APP_START: u8 = 0xF4;
const CCS811_SW_RESET: u8 = 0xFF; const CCS811_SW_RESET: u8 = 0xFF;
struct CCS811 { struct CCS811 {
i2c: I2cdev, i2c: I2cdev,
addr: u8 addr: u8,
} }
impl CCS811 { impl CCS811 {
fn new(mut i2c: I2cdev, addr: u8) -> Self { fn new(mut i2c: I2cdev, addr: u8) -> Self {
i2c.set_slave_address(addr as u16).unwrap(); i2c.set_slave_address(addr as u16).unwrap();
Self { Self { i2c, addr }
i2c, }
addr
}
}
fn check_for_error(&mut self) -> Option<u8> { fn check_for_error(&mut self) -> Option<u8> {
let x = self.i2c.smbus_read_byte_data(CCS811_STATUS).unwrap(); let x = self.i2c.smbus_read_byte_data(CCS811_STATUS).unwrap();
if (x & 1) != 0 { if (x & 1) != 0 {
let err_code = self.i2c.smbus_read_byte_data(CCS811_ERROR_ID).unwrap(); let err_code = self.i2c.smbus_read_byte_data(CCS811_ERROR_ID).unwrap();
Some(err_code) Some(err_code)
} else { } else {
None None
} }
} }
fn hardware_id(&mut self) -> u8 { fn hardware_id(&mut self) -> u8 {
self.i2c.smbus_read_byte_data(CCS811_HW_ID).unwrap() self.i2c.smbus_read_byte_data(CCS811_HW_ID).unwrap()
} }
fn app_valid(&mut self) -> bool { fn app_valid(&mut self) -> bool {
let x = self.i2c.smbus_read_byte_data(CCS811_STATUS).unwrap(); let x = self.i2c.smbus_read_byte_data(CCS811_STATUS).unwrap();
x & 1 << 4 != 0 x & 1 << 4 != 0
} }
fn set_drive_mode(&mut self, mode: CCS811DriveMode) -> Result<(), Option<LinuxI2CError>> { fn set_drive_mode(&mut self, mode: CCS811DriveMode) -> Result<(), Option<LinuxI2CError>> {
self.i2c.smbus_write_byte(CCS811_APP_START).map_err(Some)?; self.i2c.smbus_write_byte(CCS811_APP_START).map_err(Some)?;
if let Some(x) = self.check_for_error() { if let Some(x) = self.check_for_error() {
println!("error ignored {:b}", x); println!("error ignored {:b}", x);
} }
let mut setting = self.i2c.smbus_read_byte_data(CCS811_MEAS_MODE).map_err(Some)?; let mut setting = self.i2c.smbus_read_byte_data(CCS811_MEAS_MODE).map_err(Some)?;
setting &= !(0b00000111 << 4); setting &= !(0b00000111 << 4);
setting |= (mode as u8) << 4; setting |= (mode as u8) << 4;
self.i2c.smbus_write_byte_data(CCS811_MEAS_MODE, setting).map_err(Some)?; self.i2c
Ok(()) .smbus_write_byte_data(CCS811_MEAS_MODE, setting)
} .map_err(Some)?;
Ok(())
}
fn get_baseline(&mut self) -> u16 { fn get_baseline(&mut self) -> u16 {
let x = self.i2c.smbus_read_i2c_block_data(CCS811_BASELINE, 2).unwrap(); let x = self.i2c.smbus_read_i2c_block_data(CCS811_BASELINE, 2).unwrap();
((x[0] as u16) << 8) | (x[1] as u16) ((x[0] as u16) << 8) | (x[1] as u16)
} }
/// Returns (eCO2, tVOC) /// Returns (eCO2, tVOC)
fn get_reading(&mut self) -> (u16, u16) { fn get_reading(&mut self) -> (u16, u16) {
let x = self.i2c.smbus_read_i2c_block_data(CCS811_ALG_RESULT_DATA, 4).unwrap(); let x = self.i2c.smbus_read_i2c_block_data(CCS811_ALG_RESULT_DATA, 4).unwrap();
(((x[0] as u16) << 8) | (x[1] as u16), ((x[2] as u16) << 8) | (x[3] as u16)) (
} ((x[0] as u16) << 8) | (x[1] as u16),
((x[2] as u16) << 8) | (x[3] as u16),
)
}
} }
enum CCS811DriveMode { enum CCS811DriveMode {
Idle = 0, Idle = 0,
EverySecond = 1, EverySecond = 1,
Every10Seconds = 2, Every10Seconds = 2,
Every60Seconds = 3, Every60Seconds = 3,
/// Note the English manual states this is calculated every 10 ms! /// Note the English manual states this is calculated every 10 ms!
Every250Milliseconds = 4, Every250Milliseconds = 4,
} }
fn main() { fn main() {
let args = env::args().collect::<Vec<_>>(); let args = env::args().collect::<Vec<_>>();
if args.len() < 2 { if args.len() < 2 {
panic!("missing argument: database path"); panic!("missing argument: database path");
} }
let database = Connection::open(&args[1]).expect("failed to open database"); let database = Connection::open(&args[1]).expect("failed to open database");
database.execute(" database
.execute(
"
CREATE TABLE IF NOT EXISTS sensor_readings( CREATE TABLE IF NOT EXISTS sensor_readings(
time INTEGER PRIMARY KEY, time INTEGER PRIMARY KEY,
humidity INTEGER NOT NULL, humidity INTEGER NOT NULL,
celsius INTEGER NOT NULL celsius INTEGER NOT NULL
)", []).unwrap(); )",
[],
)
.unwrap();
/* /*
let mut ccs = CCS811::new(i2c, CCS811_ADDR); let mut ccs = CCS811::new(i2c, CCS811_ADDR);
println!("HW ID, should be 0x81 {:x}", ccs.hardware_id()); println!("HW ID, should be 0x81 {:x}", ccs.hardware_id());
println!("Error code, should be None: {:?}", ccs.check_for_error()); println!("Error code, should be None: {:?}", ccs.check_for_error());
println!("app valid = {:?}", ccs.app_valid()); println!("app valid = {:?}", ccs.app_valid());
println!("baseline = {:x}", ccs.get_baseline()); println!("baseline = {:x}", ccs.get_baseline());
println!("reading {:?}", ccs.get_reading()); println!("reading {:?}", ccs.get_reading());
println!("setting drive mode to 1: {:?}", ccs.set_drive_mode(CCS811DriveMode::EverySecond)); println!("setting drive mode to 1: {:?}", ccs.set_drive_mode(CCS811DriveMode::EverySecond));
*/ */
let mut chip = Chip::new("/dev/gpiochip0").unwrap(); let mut chip = Chip::new("/dev/gpiochip0").unwrap();
let line = chip.get_line(26).unwrap(); let line = chip.get_line(26).unwrap();
for _attempt in 0..5 { for _attempt in 0..5 {
let time = std::time::SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap(); let time = std::time::SystemTime::now()
if let Ok((rh, temp)) = raspi_oled::am2302_reading(&line) { .duration_since(SystemTime::UNIX_EPOCH)
if rh > 0 && temp < 500 { .unwrap();
database.execute("INSERT INTO sensor_readings (time, humidity, celsius) VALUES (?1, ?2, ?3)", params![time.as_secs(), rh, temp]).unwrap(); if let Ok((rh, temp)) = raspi_oled::am2302_reading(&line) {
display_on_ssd1306(rh, temp, time); if rh > 0 && temp < 500 {
break; database
} .execute(
} "INSERT INTO sensor_readings (time, humidity, celsius) VALUES (?1, ?2, ?3)",
} params![time.as_secs(), rh, temp],
)
.unwrap();
display_on_ssd1306(rh, temp, time);
break;
}
}
}
} }
fn display_on_ssd1306(rh: u16, temp: u16, time: Duration) { fn display_on_ssd1306(rh: u16, temp: u16, time: Duration) {
let i2c = I2cdev::new("/dev/i2c-1").unwrap(); let i2c = I2cdev::new("/dev/i2c-1").unwrap();
let interface = I2CDisplayInterface::new(i2c); let interface = I2CDisplayInterface::new(i2c);
let mut disp = Ssd1306::new( let mut disp = Ssd1306::new(interface, DisplaySize128x64, DisplayRotation::Rotate0).into_buffered_graphics_mode();
interface,
DisplaySize128x64,
DisplayRotation::Rotate0,
).into_buffered_graphics_mode();
disp.init().unwrap(); disp.init().unwrap();
let text_style = MonoTextStyleBuilder::new() let text_style = MonoTextStyleBuilder::new()
.font(&FONT_9X18) .font(&FONT_9X18)
.text_color(BinaryColor::On) .text_color(BinaryColor::On)
.build(); .build();
let text = format!("{}.{}% {}.{}°C", rh / 10, rh % 10, temp / 10, temp % 10); let text = format!("{}.{}% {}.{}°C", rh / 10, rh % 10, temp / 10, temp % 10);
Text::new(&text, Point::new(0, 10), text_style) Text::new(&text, Point::new(0, 10), text_style).draw(&mut disp).unwrap();
.draw(&mut disp) let secs = time.as_secs();
.unwrap(); let time = format!("{:02}:{:02} Uhr", (secs / 3600 + 2) % 24, secs / 60 % 60);
let secs = time.as_secs(); Text::new(&time, Point::new(0, 32), text_style).draw(&mut disp).unwrap();
let time = format!("{:02}:{:02} Uhr", (secs / 3600 + 2) % 24, secs / 60 % 60); disp.flush().unwrap();
Text::new(&time, Point::new(0, 32), text_style) /*
.draw(&mut disp) sleep(Duration::from_secs(2));
.unwrap(); disp.clear();
disp.flush().unwrap();
/*
sleep(Duration::from_secs(2));
disp.clear();
let base_y = 0.0; let base_y = 0.0;
let max_dy = 32.0; let max_dy = 32.0;
let mut tick = 0; let mut tick = 0;
loop { loop {
let y = if tick % 32 < 16 { let y = if tick % 32 < 16 {
base_y + (tick % 16) as f32 / 16.0 * max_dy base_y + (tick % 16) as f32 / 16.0 * max_dy
} else { } else {
base_y + max_dy - (tick % 16) as f32 / 16.0 * max_dy base_y + max_dy - (tick % 16) as f32 / 16.0 * max_dy
} as i32; } as i32;
tick += 1; tick += 1;
Line::new(Point::new(8, y + 16), Point::new(8 + 16, y + 16)) Line::new(Point::new(8, y + 16), Point::new(8 + 16, y + 16))
.into_styled(PrimitiveStyle::with_stroke(BinaryColor::On, 1)) .into_styled(PrimitiveStyle::with_stroke(BinaryColor::On, 1))
.draw(&mut disp).unwrap(); .draw(&mut disp).unwrap();
Line::new(Point::new(8, y + 16), Point::new(8 + 8, y)) Line::new(Point::new(8, y + 16), Point::new(8 + 8, y))
.into_styled(PrimitiveStyle::with_stroke(BinaryColor::On, 1)) .into_styled(PrimitiveStyle::with_stroke(BinaryColor::On, 1))
.draw(&mut disp).unwrap(); .draw(&mut disp).unwrap();
Line::new(Point::new(8 + 16, y + 16), Point::new(8 + 8, y))
.into_styled(PrimitiveStyle::with_stroke(BinaryColor::On, 1))
.draw(&mut disp).unwrap();
Rectangle::new(Point::new(48, y), Size::new(16, 16)) Line::new(Point::new(8 + 16, y + 16), Point::new(8 + 8, y))
.into_styled(PrimitiveStyle::with_stroke(BinaryColor::On, 1)) .into_styled(PrimitiveStyle::with_stroke(BinaryColor::On, 1))
.draw(&mut disp).unwrap(); .draw(&mut disp).unwrap();
Circle::new(Point::new(88, y), 16) Rectangle::new(Point::new(48, y), Size::new(16, 16))
.into_styled(PrimitiveStyle::with_stroke(BinaryColor::On, 1)) .into_styled(PrimitiveStyle::with_stroke(BinaryColor::On, 1))
.draw(&mut disp).unwrap(); .draw(&mut disp).unwrap();
/*
Text::new(&format!("Hello from frame {}", tick), Point::new(0, 56), text_style)
.draw(&mut disp)
.unwrap();
*/
disp.flush().unwrap();
sleep(Duration::from_millis(10)); Circle::new(Point::new(88, y), 16)
.into_styled(PrimitiveStyle::with_stroke(BinaryColor::On, 1))
.draw(&mut disp).unwrap();
disp.clear(); /*
Text::new(&format!("Hello from frame {}", tick), Point::new(0, 56), text_style)
.draw(&mut disp)
.unwrap();
*/
disp.flush().unwrap();
/* sleep(Duration::from_millis(10));
let im: ImageRaw<BinaryColor> = ImageRaw::new(IMG_DATA, 64);
let img = Image::new(&im, Point::new(32, 0));
img.draw(&mut disp).unwrap();
disp.flush().unwrap();
sleep(Duration::from_secs(2)); disp.clear();
disp.clear();
*/ /*
} let im: ImageRaw<BinaryColor> = ImageRaw::new(IMG_DATA, 64);
*/ let img = Image::new(&im, Point::new(32, 0));
img.draw(&mut disp).unwrap();
disp.flush().unwrap();
sleep(Duration::from_secs(2));
disp.clear();
*/
}
*/
} }
struct LineWrapper(gpio_cdev::Line); struct LineWrapper(gpio_cdev::Line);
impl InputPin for LineWrapper { impl InputPin for LineWrapper {
type Error = gpio_cdev::Error; type Error = gpio_cdev::Error;
fn is_high(&self) -> Result<bool, Self::Error> { fn is_high(&self) -> Result<bool, Self::Error> {
let handle = self.0.request(LineRequestFlags::INPUT, 0, "rust-line-wrapper")?; let handle = self.0.request(LineRequestFlags::INPUT, 0, "rust-line-wrapper")?;
Ok(handle.get_value()? == 1) Ok(handle.get_value()? == 1)
} }
fn is_low(&self) -> Result<bool, Self::Error> { fn is_low(&self) -> Result<bool, Self::Error> {
let handle = self.0.request(LineRequestFlags::INPUT, 0, "rust-line-wrapper")?; let handle = self.0.request(LineRequestFlags::INPUT, 0, "rust-line-wrapper")?;
Ok(handle.get_value()? == 0) Ok(handle.get_value()? == 0)
} }
} }
impl OutputPin for LineWrapper { impl OutputPin for LineWrapper {
<<<<<<< HEAD
type Error = gpio_cdev::Error; type Error = gpio_cdev::Error;
fn set_low(&mut self) -> Result<(), Self::Error> { fn set_low(&mut self) -> Result<(), Self::Error> {
@ -258,3 +263,29 @@ impl OutputPin for LineWrapper {
self.0.request(LineRequestFlags::OUTPUT, 1, "rust-line-wrapper")?.set_value(1) self.0.request(LineRequestFlags::OUTPUT, 1, "rust-line-wrapper")?.set_value(1)
} }
} }
||||||| parent of 683458d (Reformat code)
type Error = gpio_cdev::Error;
fn set_low(&mut self) -> Result<(), Self::Error> {
self.0.request(LineRequestFlags::OUTPUT, 1, "rust-line-wrapper")?.set_value(0)
}
fn set_high(&mut self) -> Result<(), Self::Error> {
self.0.request(LineRequestFlags::OUTPUT, 1, "rust-line-wrapper")?.set_value(1)
}
}
=======
type Error = gpio_cdev::Error;
fn set_low(&mut self) -> Result<(), Self::Error> {
self.0
.request(LineRequestFlags::OUTPUT, 1, "rust-line-wrapper")?
.set_value(0)
}
fn set_high(&mut self) -> Result<(), Self::Error> {
self.0
.request(LineRequestFlags::OUTPUT, 1, "rust-line-wrapper")?
.set_value(1)
}
}