added comments to functions
This commit is contained in:
130
src/lib.rs
130
src/lib.rs
@@ -88,6 +88,7 @@ pub enum Channel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Channel {
|
impl Channel {
|
||||||
|
/// Each channel is only read from one of three sensors
|
||||||
pub fn get_device_for_channel(&self) -> Device {
|
pub fn get_device_for_channel(&self) -> Device {
|
||||||
match self {
|
match self {
|
||||||
Channel::A | Channel::B | Channel::C | Channel::D | Channel::E | Channel::F => {
|
Channel::A | Channel::B | Channel::C | Channel::D | Channel::E | Channel::F => {
|
||||||
@@ -102,6 +103,7 @@ impl Channel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get the virtual register address for the raw value of the channel
|
||||||
fn get_raw_address(&self) -> u8 {
|
fn get_raw_address(&self) -> u8 {
|
||||||
match self {
|
match self {
|
||||||
Channel::A | Channel::G | Channel::R => 0x08,
|
Channel::A | Channel::G | Channel::R => 0x08,
|
||||||
@@ -113,12 +115,14 @@ impl Channel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get the virtual register address for the calibrated value of the channel
|
||||||
fn get_cal_address(&self) -> u8 {
|
fn get_cal_address(&self) -> u8 {
|
||||||
let raw = self.get_raw_address();
|
let raw = self.get_raw_address();
|
||||||
((raw - 0x08) / 2) * 4 + 0x14
|
((raw - 0x08) / 2) * 4 + 0x14
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The AS7265X has three sensor devices
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub enum Device {
|
pub enum Device {
|
||||||
Visable = 0x00,
|
Visable = 0x00,
|
||||||
@@ -126,6 +130,7 @@ pub enum Device {
|
|||||||
Uv = 0x02,
|
Uv = 0x02,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The three main LEDs on the device
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub enum Led {
|
pub enum Led {
|
||||||
White,
|
White,
|
||||||
@@ -134,6 +139,7 @@ pub enum Led {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Led {
|
impl Led {
|
||||||
|
/// Apparently the LEDs don't match the device the are for
|
||||||
fn get_device(&self) -> Device {
|
fn get_device(&self) -> Device {
|
||||||
match self {
|
match self {
|
||||||
Led::White => Device::Nir,
|
Led::White => Device::Nir,
|
||||||
@@ -159,7 +165,8 @@ pub enum GainConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl GainConfig {
|
impl GainConfig {
|
||||||
fn to_bits(self) -> u8 {
|
/// To byte that can be written to the virtual register
|
||||||
|
fn to_byte(self) -> u8 {
|
||||||
match self {
|
match self {
|
||||||
GainConfig::Gain1x => 0b00,
|
GainConfig::Gain1x => 0b00,
|
||||||
GainConfig::Gain3_7x => 0b01,
|
GainConfig::Gain3_7x => 0b01,
|
||||||
@@ -169,7 +176,6 @@ impl GainConfig {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Measurement mode options
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub enum MeasurementMode {
|
pub enum MeasurementMode {
|
||||||
/// 4 channels
|
/// 4 channels
|
||||||
@@ -186,7 +192,8 @@ pub enum MeasurementMode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl MeasurementMode {
|
impl MeasurementMode {
|
||||||
fn to_bits(self) -> u8 {
|
/// To byte that can be written to the virtual register
|
||||||
|
fn to_byte(self) -> u8 {
|
||||||
match self {
|
match self {
|
||||||
MeasurementMode::Mode0 => 0b00,
|
MeasurementMode::Mode0 => 0b00,
|
||||||
MeasurementMode::Mode1 => 0b01,
|
MeasurementMode::Mode1 => 0b01,
|
||||||
@@ -198,60 +205,60 @@ impl MeasurementMode {
|
|||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct AS7265XConfig {
|
pub struct AS7265XConfig {
|
||||||
|
/// Enable the onboard interrupt pin
|
||||||
pub enable_interrupt: bool,
|
pub enable_interrupt: bool,
|
||||||
pub gain: GainConfig,
|
pub gain: GainConfig,
|
||||||
pub measurement_mode: MeasurementMode,
|
pub measurement_mode: MeasurementMode,
|
||||||
|
/// Integration time: value * 2.8ms
|
||||||
pub integration_time: u8,
|
pub integration_time: u8,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for AS7265XConfig {
|
impl Default for AS7265XConfig {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
enable_interrupt: false,
|
enable_interrupt: true,
|
||||||
gain: GainConfig::Gain64x,
|
gain: GainConfig::Gain64x,
|
||||||
measurement_mode: MeasurementMode::Mode3OneShot,
|
measurement_mode: MeasurementMode::Mode3OneShot,
|
||||||
integration_time: 20,
|
integration_time: 49,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AS7265XConfig {
|
impl AS7265XConfig {
|
||||||
fn to_config_byte(&self) -> u8 {
|
/// Convert to byte to write to the config virtual register
|
||||||
|
fn to_byte(&self) -> u8 {
|
||||||
let mut byte = 0u8;
|
let mut byte = 0u8;
|
||||||
|
|
||||||
if self.enable_interrupt {
|
if self.enable_interrupt {
|
||||||
byte |= ENABLE_INTERRUPT;
|
byte |= ENABLE_INTERRUPT;
|
||||||
}
|
}
|
||||||
|
|
||||||
byte |= (self.gain.to_bits() << CONFIG_GAIN_SHIFT) & CONFIG_GAIN_MASK;
|
byte |= (self.gain.to_byte() << CONFIG_GAIN_SHIFT) & CONFIG_GAIN_MASK;
|
||||||
byte |= (self.measurement_mode.to_bits() << CONFIG_BANK_SHIFT) & CONFIG_BANK_MASK;
|
byte |= (self.measurement_mode.to_byte() << CONFIG_BANK_SHIFT) & CONFIG_BANK_MASK;
|
||||||
|
|
||||||
byte
|
byte
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub enum LedCurrent {
|
pub enum LedDriverCurrent {
|
||||||
/// 12.5 mA
|
/// 12.5 mA
|
||||||
Ma12_5,
|
Ma12_5,
|
||||||
|
|
||||||
/// 25 mA
|
/// 25 mA
|
||||||
Ma25,
|
Ma25,
|
||||||
|
|
||||||
/// 50 mA
|
/// 50 mA
|
||||||
Ma50,
|
Ma50,
|
||||||
|
|
||||||
/// 100 mA
|
/// 100 mA
|
||||||
Ma100,
|
Ma100,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LedCurrent {
|
impl LedDriverCurrent {
|
||||||
fn to_bits(self) -> u8 {
|
fn to_bits(self) -> u8 {
|
||||||
match self {
|
match self {
|
||||||
LedCurrent::Ma12_5 => 0b00,
|
LedDriverCurrent::Ma12_5 => 0b00,
|
||||||
LedCurrent::Ma25 => 0b01,
|
LedDriverCurrent::Ma25 => 0b01,
|
||||||
LedCurrent::Ma50 => 0b10,
|
LedDriverCurrent::Ma50 => 0b10,
|
||||||
LedCurrent::Ma100 => 0b11,
|
LedDriverCurrent::Ma100 => 0b11,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -282,13 +289,14 @@ impl LedIndicatorCurrent {
|
|||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub struct LedConfig {
|
pub struct LedConfig {
|
||||||
pub drv_enabled: bool,
|
pub drv_enabled: bool,
|
||||||
pub drv_current: LedCurrent,
|
pub drv_current: LedDriverCurrent,
|
||||||
pub ind_enabled: bool,
|
pub ind_enabled: bool,
|
||||||
pub ind_current: LedIndicatorCurrent,
|
pub ind_current: LedIndicatorCurrent,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LedConfig {
|
impl LedConfig {
|
||||||
fn config_byte(&self) -> u8 {
|
/// To byte that can be written to the virtual register
|
||||||
|
fn to_byte(self) -> u8 {
|
||||||
let mut byte = 0u8;
|
let mut byte = 0u8;
|
||||||
|
|
||||||
if self.drv_enabled {
|
if self.drv_enabled {
|
||||||
@@ -309,7 +317,7 @@ impl Default for LedConfig {
|
|||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
drv_enabled: false,
|
drv_enabled: false,
|
||||||
drv_current: LedCurrent::Ma12_5,
|
drv_current: LedDriverCurrent::Ma12_5,
|
||||||
ind_enabled: false,
|
ind_enabled: false,
|
||||||
ind_current: LedIndicatorCurrent::Ma8,
|
ind_current: LedIndicatorCurrent::Ma8,
|
||||||
}
|
}
|
||||||
@@ -328,6 +336,7 @@ impl<E> From<E> for Error<E> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The AS7265X device
|
||||||
pub struct AS7265X<I, D>
|
pub struct AS7265X<I, D>
|
||||||
where
|
where
|
||||||
I: i2c::I2c,
|
I: i2c::I2c,
|
||||||
@@ -344,6 +353,7 @@ where
|
|||||||
I: i2c::I2c,
|
I: i2c::I2c,
|
||||||
D: DelayNs,
|
D: DelayNs,
|
||||||
{
|
{
|
||||||
|
/// Create a new AS7265X device
|
||||||
pub fn new(device: I, config: AS7265XConfig, delay: D) -> Self {
|
pub fn new(device: I, config: AS7265XConfig, delay: D) -> Self {
|
||||||
Self {
|
Self {
|
||||||
device,
|
device,
|
||||||
@@ -352,6 +362,9 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Initialize the device.
|
||||||
|
/// Writes config, integration time and led config.
|
||||||
|
/// Ok to call multiple times & most likly not need but the cpp driver also does this.
|
||||||
#[maybe_async]
|
#[maybe_async]
|
||||||
pub async fn init(&mut self) -> Result<(), Error<I::Error>> {
|
pub async fn init(&mut self) -> Result<(), Error<I::Error>> {
|
||||||
self.write_config().await?;
|
self.write_config().await?;
|
||||||
@@ -386,6 +399,7 @@ where
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Perform a soft reset
|
||||||
#[maybe_async]
|
#[maybe_async]
|
||||||
pub async fn soft_reset(&mut self) -> Result<(), Error<I::Error>> {
|
pub async fn soft_reset(&mut self) -> Result<(), Error<I::Error>> {
|
||||||
self.write_virtual_register(CONFIG_ADDR, SOFT_RESET).await?;
|
self.write_virtual_register(CONFIG_ADDR, SOFT_RESET).await?;
|
||||||
@@ -393,59 +407,66 @@ where
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Write the config to the device
|
||||||
|
/// Also need to fire the oneshot mode again
|
||||||
#[maybe_async]
|
#[maybe_async]
|
||||||
async fn write_config(&mut self) -> Result<(), Error<I::Error>> {
|
async fn write_config(&mut self) -> Result<(), Error<I::Error>> {
|
||||||
let config_byte = self.config.to_config_byte();
|
let config_byte = self.config.to_byte();
|
||||||
self.write_virtual_register(CONFIG_ADDR, config_byte).await
|
self.write_virtual_register(CONFIG_ADDR, config_byte).await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Sets the integration time value
|
||||||
|
/// value * 2.8ms
|
||||||
#[maybe_async]
|
#[maybe_async]
|
||||||
pub async fn set_integration_time(&mut self, time: u8) -> Result<(), Error<I::Error>> {
|
pub async fn set_integration_time(&mut self, time: u8) -> Result<(), Error<I::Error>> {
|
||||||
|
self.config.integration_time = time;
|
||||||
self.write_virtual_register(INTEGRATION_ADDR, time).await
|
self.write_virtual_register(INTEGRATION_ADDR, time).await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Write the LED specific config
|
||||||
#[maybe_async]
|
#[maybe_async]
|
||||||
async fn set_led_config(&mut self, led: Led, config: LedConfig) -> Result<(), Error<I::Error>> {
|
async fn set_led_config(&mut self, led: Led, config: LedConfig) -> Result<(), Error<I::Error>> {
|
||||||
self.select_device(led.get_device()).await?;
|
self.select_device(led.get_device()).await?;
|
||||||
let config_byte = config.config_byte();
|
let config_byte = config.to_byte();
|
||||||
self.write_virtual_register(LED_ADDR, config_byte).await
|
self.write_virtual_register(LED_ADDR, config_byte).await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get the hardware info from the hw version register
|
||||||
#[maybe_async]
|
#[maybe_async]
|
||||||
pub async fn get_device_type(&mut self) -> Result<u8, Error<I::Error>> {
|
pub async fn get_device_type(&mut self) -> Result<u8, Error<I::Error>> {
|
||||||
self.read_virtual_register(HW_VERSION_HIGH_ADDR).await
|
self.read_virtual_register(HW_VERSION_HIGH_ADDR).await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get the hardware info from the hw version register
|
||||||
#[maybe_async]
|
#[maybe_async]
|
||||||
pub async fn get_hardware_version(&mut self) -> Result<u8, Error<I::Error>> {
|
pub async fn get_hardware_version(&mut self) -> Result<u8, Error<I::Error>> {
|
||||||
self.read_virtual_register(HW_VERSION_LOW_ADDR).await
|
self.read_virtual_register(HW_VERSION_LOW_ADDR).await
|
||||||
}
|
}
|
||||||
|
|
||||||
#[maybe_async]
|
/// Alot of function only work if you have the correct device selected
|
||||||
pub async fn get_firmware_version(&mut self) -> Result<(u8, u8), Error<I::Error>> {
|
|
||||||
let high = self.read_virtual_register(FW_VERSION_HIGH_ADDR).await?;
|
|
||||||
let low = self.read_virtual_register(FW_VERSION_LOW_ADDR).await?;
|
|
||||||
Ok((high, low))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[maybe_async]
|
#[maybe_async]
|
||||||
async fn select_device(&mut self, device: Device) -> Result<(), Error<I::Error>> {
|
async fn select_device(&mut self, device: Device) -> Result<(), Error<I::Error>> {
|
||||||
self.write_virtual_register(DEV_SELECT_ADDR, device as u8)
|
self.write_virtual_register(DEV_SELECT_ADDR, device as u8)
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Read the integrated temperature sensor in °C
|
||||||
#[maybe_async]
|
#[maybe_async]
|
||||||
pub async fn read_temperature(&mut self) -> Result<i8, Error<I::Error>> {
|
pub async fn read_temperature(&mut self) -> Result<i8, Error<I::Error>> {
|
||||||
let temp = self.read_virtual_register(TEMP_ADDR).await?;
|
let temp = self.read_virtual_register(TEMP_ADDR).await?;
|
||||||
Ok(temp as i8)
|
Ok(temp as i8)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Check if the internal register reports data ready
|
||||||
#[maybe_async]
|
#[maybe_async]
|
||||||
pub async fn is_data_ready(&mut self) -> Result<bool, Error<I::Error>> {
|
pub async fn is_data_ready(&mut self) -> Result<bool, Error<I::Error>> {
|
||||||
let config = self.read_virtual_register(CONFIG_ADDR).await?;
|
let config = self.read_virtual_register(CONFIG_ADDR).await?;
|
||||||
Ok((config & CONFIG_DATA_RDY) != 0)
|
Ok((config & CONFIG_DATA_RDY) != 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Run a messurement
|
||||||
|
/// Only needed if messurement mode is set to One-Shot
|
||||||
|
/// Basicly rewrites the config and waits the current integration time
|
||||||
#[maybe_async]
|
#[maybe_async]
|
||||||
pub async fn measure(&mut self) -> Result<(), Error<I::Error>> {
|
pub async fn measure(&mut self) -> Result<(), Error<I::Error>> {
|
||||||
self.write_config().await?;
|
self.write_config().await?;
|
||||||
@@ -454,6 +475,7 @@ where
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Same as measure but enable LED befor and disable after
|
||||||
#[maybe_async]
|
#[maybe_async]
|
||||||
pub async fn mesure_with_bulb(&mut self) -> Result<(), Error<I::Error>> {
|
pub async fn mesure_with_bulb(&mut self) -> Result<(), Error<I::Error>> {
|
||||||
self.set_led_config(
|
self.set_led_config(
|
||||||
@@ -512,6 +534,7 @@ where
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Read the raw value for a channel
|
||||||
#[maybe_async]
|
#[maybe_async]
|
||||||
pub async fn read_raw_measurement(&mut self, channel: Channel) -> Result<u16, Error<I::Error>> {
|
pub async fn read_raw_measurement(&mut self, channel: Channel) -> Result<u16, Error<I::Error>> {
|
||||||
let dev = channel.get_device_for_channel();
|
let dev = channel.get_device_for_channel();
|
||||||
@@ -519,6 +542,7 @@ where
|
|||||||
self.read_raw_channel(channel.get_raw_address()).await
|
self.read_raw_channel(channel.get_raw_address()).await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Read the calibrated value for a channel
|
||||||
#[maybe_async]
|
#[maybe_async]
|
||||||
pub async fn read_calibrated_messurement(
|
pub async fn read_calibrated_messurement(
|
||||||
&mut self,
|
&mut self,
|
||||||
@@ -531,6 +555,31 @@ where
|
|||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Read u16 value from address
|
||||||
|
#[maybe_async]
|
||||||
|
async fn read_raw_channel(&mut self, high_byte_addr: u8) -> Result<u16, Error<I::Error>> {
|
||||||
|
let high = self.read_virtual_register(high_byte_addr).await?;
|
||||||
|
let low = self.read_virtual_register(high_byte_addr + 1).await?;
|
||||||
|
|
||||||
|
Ok(((high as u16) << 8) | (low as u16))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Read f32 value from address
|
||||||
|
#[maybe_async]
|
||||||
|
async fn read_calibrated_channel(
|
||||||
|
&mut self,
|
||||||
|
high_byte_addr: u8,
|
||||||
|
) -> Result<f32, Error<I::Error>> {
|
||||||
|
let b0 = self.read_virtual_register(high_byte_addr).await?;
|
||||||
|
let b1 = self.read_virtual_register(high_byte_addr + 1).await?;
|
||||||
|
let b2 = self.read_virtual_register(high_byte_addr + 2).await?;
|
||||||
|
let b3 = self.read_virtual_register(high_byte_addr + 3).await?;
|
||||||
|
|
||||||
|
let bits = u32::from_be_bytes([b0, b1, b2, b3]);
|
||||||
|
Ok(f32::from_bits(bits))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Write to a virtual register
|
||||||
#[maybe_async]
|
#[maybe_async]
|
||||||
async fn write_virtual_register(
|
async fn write_virtual_register(
|
||||||
&mut self,
|
&mut self,
|
||||||
@@ -570,6 +619,7 @@ where
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Read from a virtual register
|
||||||
#[maybe_async]
|
#[maybe_async]
|
||||||
async fn read_virtual_register(&mut self, virtual_addr: u8) -> Result<u8, Error<I::Error>> {
|
async fn read_virtual_register(&mut self, virtual_addr: u8) -> Result<u8, Error<I::Error>> {
|
||||||
const MAX_RETRIES: u8 = 100;
|
const MAX_RETRIES: u8 = 100;
|
||||||
@@ -607,26 +657,4 @@ where
|
|||||||
|
|
||||||
Ok(data[0])
|
Ok(data[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
#[maybe_async]
|
|
||||||
async fn read_raw_channel(&mut self, high_byte_addr: u8) -> Result<u16, Error<I::Error>> {
|
|
||||||
let high = self.read_virtual_register(high_byte_addr).await?;
|
|
||||||
let low = self.read_virtual_register(high_byte_addr + 1).await?;
|
|
||||||
|
|
||||||
Ok(((high as u16) << 8) | (low as u16))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[maybe_async]
|
|
||||||
async fn read_calibrated_channel(
|
|
||||||
&mut self,
|
|
||||||
high_byte_addr: u8,
|
|
||||||
) -> Result<f32, Error<I::Error>> {
|
|
||||||
let b0 = self.read_virtual_register(high_byte_addr).await?;
|
|
||||||
let b1 = self.read_virtual_register(high_byte_addr + 1).await?;
|
|
||||||
let b2 = self.read_virtual_register(high_byte_addr + 2).await?;
|
|
||||||
let b3 = self.read_virtual_register(high_byte_addr + 3).await?;
|
|
||||||
|
|
||||||
let bits = u32::from_be_bytes([b0, b1, b2, b3]);
|
|
||||||
Ok(f32::from_bits(bits))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user