Commit f8d6222b authored by Arist's avatar Arist

l0dable: add max86150 ecg and ppg sensor

parent 1b4e024d
Pipeline #4523 failed with stage
in 11 minutes and 24 seconds
......@@ -4,7 +4,7 @@
mod os;
pub use os::*;
mod display;
pub use display::{Color, Display, Font, FillStyle, LineStyle};
pub use display::{Color, Display, FillStyle, Font, LineStyle};
mod buttons;
pub mod framebuffer;
pub use buttons::Buttons;
......@@ -20,6 +20,8 @@ mod fmt_buffer;
pub use fmt_buffer::{str_to_cstr, FmtBuffer};
mod bme680;
pub use bme680::BME680;
mod max86150;
pub use max86150::MAX86150;
mod bhi160;
pub use bhi160::{
Accelerometer, Error as BHI160Error, Gyroscope, Orientation, Sensor as BHI160,
......
// ECG and PPG sensor
pub struct MAX86150 {
stream_id: i32,
}
use core::{mem::size_of, mem::MaybeUninit};
use card10_sys::*;
// TODO: redefine in common sensor
use crate::bhi160::Error;
const DATA_MAX: usize = 128;
impl MAX86150 {
pub fn start() -> Result<Self, Error> {
let mut cfg = max86150_sensor_config {
sample_buffer_len: DATA_MAX,
ppg_sample_rate: 200,
};
let stream_id =
unsafe { epic_max86150_enable_sensor(&mut cfg, size_of::<max86150_sensor_config>()) };
if stream_id < 0 {
let error = match -stream_id {
errno::EBUSY => Error::DriverBusy,
_ => Error::Unknown(stream_id),
};
return Err(error);
}
Ok(MAX86150 { stream_id })
}
pub fn read(&self) -> Result<MAX86150SensorData, Error> {
let mut buffer = MaybeUninit::<[max86150_sensor_data; DATA_MAX]>::zeroed();
let buffer_pointer = buffer.as_mut_ptr() as *mut _;
let packet_count = unsafe {
epic_stream_read(
self.stream_id,
buffer_pointer,
size_of::<max86150_sensor_data>() * DATA_MAX,
)
};
if packet_count < 0 {
let error = match -packet_count {
errno::ENODEV => Error::SensorUnavailable,
errno::EBADF => Error::SensorDescriptorUnknown,
errno::EINVAL => Error::InvalidSampleCount,
errno::EBUSY => Error::CouldNotAcquireLock,
_ => Error::Unknown(packet_count),
};
return Err(error);
}
Ok(MAX86150SensorData {
buf: unsafe { buffer.assume_init() },
n: packet_count as usize,
})
}
}
pub struct MAX86150SensorData {
buf: [max86150_sensor_data; DATA_MAX],
n: usize,
}
impl MAX86150SensorData {
pub const fn is_empty(&self) -> bool {
self.n == 0
}
pub const fn len(&self) -> usize {
self.n
}
}
impl<'a> IntoIterator for &'a MAX86150SensorData {
type Item = MAX86150SensorDataItem;
type IntoIter = MAX86150SensorDataIterator<'a>;
fn into_iter(self) -> Self::IntoIter {
MAX86150SensorDataIterator { data: self, pos: 0 }
}
}
pub struct MAX86150SensorDataIterator<'a> {
data: &'a MAX86150SensorData,
pos: usize,
}
#[derive(Debug, Clone)]
pub struct MAX86150SensorDataItem {
pub red_raw: u32,
pub ir_raw: u32,
pub ecg_raw: i32,
}
impl MAX86150SensorDataItem {
pub fn get_red(&self) -> u32 {
self.red_raw
}
}
impl<'a> Iterator for MAX86150SensorDataIterator<'a> {
type Item = MAX86150SensorDataItem;
fn next(&mut self) -> Option<Self::Item> {
while self.pos < self.data.n {
let vec = &self.data.buf[self.pos];
let item = MAX86150SensorDataItem {
red_raw: vec.red,
ir_raw: vec.ir,
ecg_raw: vec.ecg,
};
self.pos += 1;
return Some(item);
}
None
}
}
impl Drop for MAX86150 {
fn drop(&mut self) {
unsafe {
epic_max86150_disable_sensor();
}
}
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment