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
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
//! This is a platform agnostic Rust driver for the KXCJ9 and KXCJB ultra-low-power
//! tri-axis accelerometers (up to +/-16g) using the [`embedded-hal`] traits.
//!
//! [`embedded-hal`]: https://github.com/rust-embedded/embedded-hal
//!
//! This driver allows you to:
//! - Enable/disable the device. See [`enable()`].
//! - Read the acceleration measurement. See [`read()`].
//! - Read the unscaled acceleration measurement. See [`read_unscaled()`].
//! - Set resolution. See [`set_resolution()`].
//! - Set output data rate. See [`set_output_data_rate()`].
//! - Set +/- G range. See [`set_scale()`].
//! - Read `WHO_AM_I` register. See [`who_am_i()`].
//! - Perform a software reset. See [`reset()`].
//! - Run a communication self-test. See [`communication_self_test()`].
//! - Enable/disable MEMS self-test function. See [`enable_mems_self_test()`].
//! - Interrupt support:
//! - Enable/disable new acceleration data ready interrupt. See [`enable_data_ready_interrupt()`].
//! - Enable/disable and configure wake-up motion detected interrupt. See [`enable_wake_up_interrupt()`].
//! - Enable/disable physical interrupt pin. See [`enable_interrupt_pin()`].
//! - Set physical interrupt pin polarity. See [`set_interrupt_pin_polarity()`].
//! - Set physical interrupt pin latching behavior. See [`set_interrupt_pin_latching()`].
//! - Check if any interrupt has happened. See [`has_interrupt_happened()`].
//! - Clear interrupts. See [`clear_interrupts()`].
//! - Read interrupt source information. See [`read_interrupt_info()`].
//!
//! [`enable()`]: struct.Kxcj9.html#method.enable
//! [`read()`]: struct.Kxcj9.html#method.read
//! [`read_unscaled()`]: struct.Kxcj9.html#method.read_unscaled
//! [`set_resolution()`]: struct.Kxcj9.html#method.set_resolution
//! [`set_output_data_rate()`]: struct.Kxcj9.html#method.set_output_data_rate
//! [`set_scale()`]: struct.Kxcj9.html#method.set_scale
//! [`who_am_i()`]: struct.Kxcj9.html#method.who_am_i
//! [`reset()`]: struct.Kxcj9.html#method.reset
//! [`communication_self_test()`]: struct.Kxcj9.html#method.communication_self_test
//! [`enable_mems_self_test()`]: struct.Kxcj9.html#method.enable_mems_self_test
//! [`enable_data_ready_interrupt()`]: struct.Kxcj9.html#method.enable_data_ready_interrupt
//! [`enable_wake_up_interrupt()`]: struct.Kxcj9.html#method.enable_wake_up_interrupt
//! [`enable_interrupt_pin()`]: struct.Kxcj9.html#method.enable_interrupt_pin
//! [`set_interrupt_pin_polarity()`]: struct.Kxcj9.html#method.set_interrupt_pin_polarity
//! [`set_interrupt_pin_latching()`]: struct.Kxcj9.html#method.set_interrupt_pin_latching
//! [`has_interrupt_happened()`]: struct.Kxcj9.html#method.has_interrupt_happened
//! [`clear_interrupts()`]: struct.Kxcj9.html#method.clear_interrupts
//! [`read_interrupt_info()`]: struct.Kxcj9.html#method.read_interrupt_info
//!
//! [Introductory blog post](https://blog.eldruin.com/kxcj9-kxcjb-tri-axis-mems-accelerator-driver-in-rust/)
//!
//! ## The devices
//!
//! The KXCJ9 is a high-performance, ultra-low-power, tri-axis accelerometer
//! designed for mobile applications. It offers our best power performance
//! along with an embedded wake-up feature, Fast-mode I²C and up to 14-bit
//! resolution. The KXCJ9 sensor offers improved shock, reflow, and temperature
//! performance, and the ASIC has internal voltage regulators that allow
//! operation from 1.8 V to 3.6 V within the specified product performance.
//!
//! The KXCJB is the thinnest tri-axis accelerometer available on the market
//! today. This ultra-thin 3x3x0.45mm low-power accelerometer is also one of
//! our most full-featured products. The KXCJB offers up to 14-bit resolution
//! for greater precision. User-selectable parameters include ± 2g, 4g or 8g
//! ranges and Output Data Rates (ODR) with programmable low-pass filter.
//! The KXCJB also features the Kionix XAC sense element, our most advanced
//! sense element, for outstanding stability over temperature, shock and
//! post-reflow performance.
//!
//! The communication is done through an I2C bidirectional bus.
//!
//! Datasheet:
//! - [KXCJ9-1008](http://kionixfs.kionix.com/en/datasheet/KXCJ9-1008%20Specifications%20Rev%205.pdf)
//! - [KXCJ9-1018](http://kionixfs.kionix.com/en/datasheet/KXCJ9-1018%20Specifications%20Rev%202.pdf)
//! - [KXCJB-1041](http://kionixfs.kionix.com/en/datasheet/KXCJB-1041%20Specifications%20Rev%201.0.pdf)
//!
//! Application Note:
//! - [Getting started with the KXCJ9 and KXCJB](http://kionixfs.kionix.com/en/document/AN028%20Getting%20Started%20with%20the%20KXCJ9%20and%20KXCJB.pdf)
//!
//! ## Usage examples (see also examples folder)
//!
//! To use this driver, import this crate and an `embedded_hal` implementation,
//! then instantiate the appropriate device.
//!
//! Please find additional examples using hardware in this repository: [driver-examples]
//!
//! [driver-examples]: https://github.com/eldruin/driver-examples
//!
//! ### Read acceleration in G
//!
//! ```no_run
//! extern crate kxcj9;
//! extern crate linux_embedded_hal as hal;
//! use kxcj9::{Kxcj9, SlaveAddr};
//!
//! # fn main() {
//! let dev = hal::I2cdev::new("/dev/i2c-1").unwrap();
//! let address = SlaveAddr::default();
//! let mut sensor = Kxcj9::new_kxcj9_1018(dev, address);
//! sensor.enable().unwrap();
//! loop {
//! let acc = sensor.read().unwrap();
//! println!("X: {:2}, Y: {:2}, Z: {:2}", acc.x, acc.y, acc.z);
//! }
//! # }
//! ```
//!
//! ### Select high resolution
//!
//! ```no_run
//! extern crate kxcj9;
//! extern crate linux_embedded_hal as hal;
//! use kxcj9::{Kxcj9, Resolution, SlaveAddr};
//!
//! # fn main() {
//! let dev = hal::I2cdev::new("/dev/i2c-1").unwrap();
//! let mut sensor = Kxcj9::new_kxcj9_1018(dev, SlaveAddr::default());
//! sensor.enable().unwrap();
//! sensor.set_resolution(Resolution::High).unwrap();
//! // with this settings measurements are taken with 12-bit resolution
//! # }
//! ```
//!
//! ### Select +/-16g scale
//!
//! ```no_run
//! extern crate kxcj9;
//! extern crate linux_embedded_hal as hal;
//! use kxcj9::{GScale16, Kxcj9, SlaveAddr};
//!
//! # fn main() {
//! let dev = hal::I2cdev::new("/dev/i2c-1").unwrap();
//! let mut sensor = Kxcj9::new_kxcj9_1018(dev, SlaveAddr::default());
//! sensor.enable().unwrap();
//! sensor.set_scale(GScale16::G16FP).unwrap();
//! // with this settings measurements are taken with 14-bit resolution
//! # }
//! ```
//!
//! ### Select 200Hz output data rate
//!
//! ```no_run
//! extern crate kxcj9;
//! extern crate linux_embedded_hal as hal;
//! use kxcj9::{Kxcj9, OutputDataRate, SlaveAddr};
//!
//! # fn main() {
//! let dev = hal::I2cdev::new("/dev/i2c-1").unwrap();
//! let mut sensor = Kxcj9::new_kxcj9_1018(dev, SlaveAddr::default());
//! sensor.enable().unwrap();
//! sensor.set_output_data_rate(OutputDataRate::Hz200).unwrap();
//! # }
//! ```
//!
//! ### Configure and enable wake-up interrupt
//!
//! ```no_run
//! extern crate kxcj9;
//! extern crate linux_embedded_hal as hal;
//! use kxcj9::{
//! Kxcj9, SlaveAddr, WakeUpInterruptConfig, WakeUpOutputDataRate,
//! WakeUpTriggerMotion,
//! };
//!
//! # fn main() {
//! let dev = hal::I2cdev::new("/dev/i2c-1").unwrap();
//! let mut sensor = Kxcj9::new_kxcj9_1008(dev, SlaveAddr::default());
//! let config = WakeUpInterruptConfig {
//! trigger_motion: WakeUpTriggerMotion::default(),
//! data_rate: WakeUpOutputDataRate::Hz3_125,
//! fault_count: 3,
//! threshold: 0.5, // G
//! };
//! // 0.5g acceleration must be present for 0.96s to trigger interrupt
//! sensor.enable_wake_up_interrupt(config).unwrap();
//! # }
//! ```
//!
//! ### Perform a software reset and wait for it to finish
//!
//! ```no_run
//! extern crate kxcj9;
//! extern crate linux_embedded_hal as hal;
//! #[macro_use(block)]
//! extern crate nb;
//! use kxcj9::{Kxcj9, OutputDataRate, SlaveAddr};
//!
//! # fn main() {
//! let dev = hal::I2cdev::new("/dev/i2c-1").unwrap();
//! let mut sensor = Kxcj9::new_kxcj9_1018(dev, SlaveAddr::default());
//! block!(sensor.reset());
//! # }
//! ```
extern crate embedded_hal as hal;
extern crate nb;
use PhantomData;
use i2c;
pub use ;
const DEVICE_BASE_ADDRESS: u8 = 0xE;
/// KXCJ9/KXCJB device driver
pub use ScaledDevice;
pub use ;