blob: b6df53ce41d0106ba831248fb9bd2efad77678b6 [file] [log] [blame]
// Copyright 2024 The Pigweed Authors
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy of
// the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.
#pragma once
#include <chrono>
#include <utility>
#include "modules/light/sensor.h"
#include "modules/proximity/sensor.h"
#include "pw_chrono/system_clock.h"
#include "pw_i2c/address.h"
#include "pw_i2c/initiator.h"
#include "pw_i2c/register_device.h"
#include "pw_result/result.h"
#include "pw_status/status.h"
namespace sense {
/// Basic driver for the LTR559 ambient light and proximity sensor.
class Ltr559LightAndProxSensor {
public:
// Minimum delay after power on.
static constexpr pw::chrono::SystemClock::duration kPowerOnDelay =
pw::chrono::SystemClock::for_at_least(std::chrono::milliseconds(100));
// Max time after active mode for first sample.
static constexpr pw::chrono::SystemClock::duration kActiveModeDelay =
pw::chrono::SystemClock::for_at_least(std::chrono::milliseconds(10));
Ltr559LightAndProxSensor(pw::i2c::Initiator& i2c_initiator,
pw::chrono::SystemClock::duration timeout =
std::chrono::milliseconds(100));
/// Enables the ambient light sensor.
pw::Status EnableLight() {
return device_.WriteRegister(kAlsContrAddress, std::byte{0x01}, timeout_);
}
pw::Status DisableLight() {
return device_.WriteRegister(kAlsContrAddress, std::byte{0}, timeout_);
}
/// Enables the proximity sensor.
pw::Status EnableProximity() {
return device_.WriteRegister(kPsContrAddress, std::byte{0x03}, timeout_);
}
pw::Status DisableProximity() {
return device_.WriteRegister(kPsContrAddress, std::byte{0}, timeout_);
}
struct Info {
uint8_t part_id;
uint8_t manufacturer_id;
};
pw::Result<Info> ReadIds();
pw::Result<uint16_t> ReadProximitySample();
pw::Result<float> ReadLightSampleLux();
private:
static constexpr uint8_t kAlsContrAddress = 0x80;
static constexpr uint8_t kPsContrAddress = 0x81;
// 0x86: PART_ID
// 0x87: MANUFAC_ID
static constexpr uint8_t kPartIdAddress = 0x86;
// 0x88-89: ALS_DATA_CH1
// 0x8A-8B: ALS_DATA_CH0
static constexpr uint8_t kAlsDataCh1Address = 0x88;
static constexpr int kDefaultIntegrationTimeMillis = 100;
static constexpr int kDefaultGain = 1;
pw::i2c::Initiator& i2c_initiator_;
pw::i2c::RegisterDevice device_;
pw::chrono::SystemClock::duration timeout_;
};
// LTR559 that implements the generic ProximitySensor and AmbientLightSensor
// interfaces.
class Ltr559ProxAndLightSensorImpl final : public AmbientLightSensor,
public ProximitySensor {
public:
template <typename... Args>
explicit Ltr559ProxAndLightSensorImpl(Args&&... args)
: sensor_(std::forward<Args>(args)...) {}
private:
pw::Status DoEnableProximitySensor() override {
return sensor_.EnableProximity();
}
pw::Status DoDisableProximitySensor() override {
return sensor_.DisableProximity();
}
pw::Status DoEnableLightSensor() override { return sensor_.EnableLight(); }
pw::Status DoDisableLightSensor() override { return sensor_.DisableLight(); }
pw::Result<uint16_t> DoReadProxSample() override;
pw::Result<float> DoReadLightSampleLux() override {
return sensor_.ReadLightSampleLux();
}
Ltr559LightAndProxSensor sensor_;
};
} // namespace sense