-
Notifications
You must be signed in to change notification settings - Fork 12
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Adds I2C implementation and basic accelerometer crate. #30
Merged
Changes from all commits
Commits
Show all changes
10 commits
Select commit
Hold shift + click to select a range
7ce3726
Adds I2C hardware interface
johnnyman727 16f67d3
Changes pins to be Mutex'd objects.
tcr bded061
Refactors protocol modules, socket communication.
tcr 0dcc6e6
Moves port socket to protocol crate.
tcr b17d2d9
Temp
tcr ee50a61
Implements working accelerometer code.
tcr 24951f2
Adds acceleration reading code.
tcr 32af6ec
Refactors into two sub-modules.
tcr 62858b1
Fixes tests.
tcr fa649e4
Removes extra println lines.
tcr File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,4 @@ | ||
paths = ["./tessel"] | ||
|
||
[target.mipsel-unknown-linux-gnu] | ||
linker = "mipsel-openwrt-linux-gcc" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,8 @@ | ||
language: rust | ||
rust: | ||
- 1.10.0 | ||
- nightly | ||
script: | ||
- cd tessel | ||
- cargo build | ||
- cargo test | ||
- cargo doc |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
[package] | ||
name = "accel-mma84" | ||
version = "0.1.0" | ||
authors = ["Tim Ryan <[email protected]>"] | ||
|
||
[dependencies] | ||
tessel = "0.2.0" | ||
|
||
[[bin]] | ||
name = "tessel-accel" | ||
doc = false |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,173 @@ | ||
#![feature(alloc_system)] | ||
|
||
extern crate alloc_system; | ||
extern crate tessel; | ||
|
||
use tessel::Tessel; | ||
use std::thread::sleep; | ||
use std::time::Duration; | ||
use std::io::prelude::*; | ||
|
||
pub mod mma84 { | ||
use tessel; | ||
use std::io; | ||
|
||
#[repr(u8)] | ||
pub enum ScaleRange { | ||
Scale2G = 0x00, | ||
Scale4G = 0x01, | ||
Scale8G = 0x10, | ||
} | ||
|
||
#[repr(u8)] | ||
#[allow(dead_code)] | ||
enum Command { | ||
OutXMsb = 0x01, | ||
XyzDataCfg = 0x0E, | ||
WhoAmI = 0x0D, | ||
CtrlReg1 = 0x2A, | ||
CtrlReg4 = 0x2D, | ||
} | ||
|
||
pub struct Accelerometer<'a> { | ||
i2c: tessel::I2C<'a>, | ||
} | ||
|
||
#[repr(u8)] | ||
#[allow(non_camel_case_types)] | ||
pub enum OutputRate { | ||
Rate800 = 0, | ||
Rate400 = 1, | ||
Rate200 = 2, | ||
Rate100 = 3, | ||
Rate50 = 4, | ||
Rate12_5 = 5, | ||
Rate6_25 = 6, | ||
Rate1_56 = 7, | ||
} | ||
|
||
const I2C_ID: u8 = 0x1d; | ||
|
||
impl<'a> Accelerometer<'a> { | ||
pub fn new<'b>(i2c: tessel::I2C<'b>) -> Accelerometer<'b> { | ||
Accelerometer { | ||
i2c: i2c, | ||
} | ||
} | ||
|
||
fn read_register(&mut self, cmd: Command) -> io::Result<u8> { | ||
let mut xr: [u8; 1] = [0; 1]; | ||
try!(self.read_registers(cmd, &mut xr)); | ||
Ok(xr[0]) | ||
} | ||
|
||
/// Reads sequential buffers. | ||
fn read_registers(&mut self, cmd: Command, buf: &mut [u8]) -> io::Result<()> { | ||
try!(self.i2c.transfer(I2C_ID, &[cmd as u8], buf)); | ||
Ok(()) | ||
} | ||
|
||
fn write_register(&mut self, cmd: Command, value: u8) -> io::Result<()> { | ||
self.i2c.send(I2C_ID, &[cmd as u8, value]); | ||
Ok(()) | ||
} | ||
|
||
pub fn connect(&mut self) -> io::Result<()> { | ||
if try!(self.read_register(Command::WhoAmI)) != 0x2A { | ||
return Err(io::Error::new(io::ErrorKind::InvalidData, "Invalid connection code.")) | ||
} | ||
|
||
try!(self.set_scale_range(ScaleRange::Scale2G)); | ||
try!(self.set_output_rate(OutputRate::Rate1_56)); | ||
|
||
Ok(()) | ||
} | ||
|
||
fn standby_enable(&mut self) -> io::Result<()> { | ||
// Sets the MMA8452 to standby mode. | ||
let value = try!(self.read_register(Command::CtrlReg1)); | ||
self.write_register(Command::CtrlReg1, value & !(0x01u8)) | ||
} | ||
|
||
fn standby_disable(&mut self) -> io::Result<()> { | ||
// Sets the MMA8452 to active mode. | ||
let value = try!(self.read_register(Command::CtrlReg1)); | ||
self.write_register(Command::CtrlReg1, value | (0x01u8)) | ||
} | ||
|
||
pub fn set_scale_range(&mut self, range: ScaleRange) -> io::Result<()> { | ||
try!(self.standby_enable()); | ||
try!(self.write_register(Command::XyzDataCfg, range as u8)); | ||
try!(self.standby_disable()); | ||
|
||
Ok(()) | ||
} | ||
|
||
pub fn set_output_rate(&mut self, rate: OutputRate) -> io::Result<()> { | ||
try!(self.standby_enable()); | ||
|
||
// Clear the three bits of output rate control (0b11000111 = 199) | ||
let mut value = try!(self.read_register(Command::CtrlReg1)); | ||
value &= 0b11000111; | ||
try!(self.write_register(Command::CtrlReg1, value | ((rate as u8) << 3))); | ||
|
||
try!(self.standby_disable()); | ||
|
||
Ok(()) | ||
} | ||
|
||
pub fn read_acceleration(&mut self) -> io::Result<(f64, f64, f64)> { | ||
let mut buf = [0; 6]; | ||
try!(self.read_registers(Command::OutXMsb, &mut buf)); | ||
|
||
let mut out = vec![0.0, 0.0, 0.0]; | ||
|
||
// Loop to calculate 12-bit ADC and g value for each axis | ||
for (i, win) in buf.chunks(2).enumerate() { | ||
// Combine the two 8 bit registers into one 12-bit number. | ||
// The registers are left aligned, so right align the 12-bit integer. | ||
let g = (((win[0] as u16) << 8) | (win[1] as u16)) >> 4; | ||
|
||
// If the number is negative, we have to make it so manually. | ||
// Transform into negative 2's complement. | ||
let dim = if win[0] > 0x7F { | ||
-(1 + 0xFFF - (g as i16)) | ||
} else { | ||
g as i16 | ||
}; | ||
|
||
let scale_range = 2.0; | ||
out[i] = (dim as f64) / ((1 << 11) as f64) * scale_range; | ||
} | ||
|
||
Ok((out[0], out[1], out[2])) | ||
} | ||
} | ||
} | ||
|
||
fn main() { | ||
// Create a new Tessel | ||
let mut tessel = Tessel::new(); | ||
|
||
let mut acc = mma84::Accelerometer::new(tessel.port.a.i2c(100000).unwrap()); | ||
acc.connect().expect("Could not connect to accelerometer."); | ||
println!("Connected!"); | ||
|
||
// Turn on one of the LEDs | ||
tessel.led[2].on().unwrap(); | ||
|
||
println!("I'm blinking! (Press CTRL + C to stop)"); | ||
|
||
// Loop forever | ||
loop { | ||
// Toggle each LED | ||
tessel.led[2].toggle().unwrap(); | ||
tessel.led[3].toggle().unwrap(); | ||
// Re-execute the loop after sleeping for 100ms | ||
sleep(Duration::from_millis(100)); | ||
|
||
println!("acceleration: {:?}", acc.read_acceleration()); | ||
|
||
let _ = std::io::stdout().flush(); | ||
} | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did you add this just for clarity? I don't think I needed this but maybe my setup was just different.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, mine required it. Guess it doesn't hurt to be specific when cross-compiling.