diff options
Diffstat (limited to 'src/drivers/Hrs3300.cpp')
-rw-r--r-- | src/drivers/Hrs3300.cpp | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/src/drivers/Hrs3300.cpp b/src/drivers/Hrs3300.cpp new file mode 100644 index 00000000..31956575 --- /dev/null +++ b/src/drivers/Hrs3300.cpp @@ -0,0 +1,108 @@ +#include <algorithm> +#include <nrf_gpio.h> +#include "Hrs3300.h" + +#include <FreeRTOS.h> +#include <task.h> +#include <nrf_log.h> + +using namespace Pinetime::Drivers; + +Hrs3300::Hrs3300(TwiMaster &twiMaster, uint8_t twiAddress) : twiMaster{twiMaster}, twiAddress{twiAddress} { + +} + +void Hrs3300::Init() { + nrf_gpio_cfg_input(30, NRF_GPIO_PIN_NOPULL); + + Disable(); + vTaskDelay(100); + + // HRS disabled, 12.5 ms wait time between cycles, (partly) 20mA drive + WriteRegister(static_cast<uint8_t>(Registers::Enable), 0x60); + + // (partly) 20mA drive, power on, "magic" (datasheet says both + // "reserved" and "set low nibble to 8" but 0xe gives better results + // and is used by at least two other HRS3300 drivers + WriteRegister(static_cast<uint8_t>(Registers::PDriver), 0x6E); + + // HRS and ALS both in 16-bit mode + WriteRegister(static_cast<uint8_t>(Registers::Res), 0x88); + + // 64x gain + WriteRegister(static_cast<uint8_t>(Registers::Hgain), 0x10); +} + +void Hrs3300::Enable() { + NRF_LOG_INFO("ENABLE"); + auto value = ReadRegister(static_cast<uint8_t>(Registers::Enable)); + value |= 0x80; + WriteRegister(static_cast<uint8_t>(Registers::Enable), value); +} + +void Hrs3300::Disable() { + NRF_LOG_INFO("DISABLE"); + auto value = ReadRegister(static_cast<uint8_t>(Registers::Enable)); + value &= ~0x80; + WriteRegister(static_cast<uint8_t>(Registers::Enable), value); +} + +uint16_t Hrs3300::ReadHrs() { + auto m = ReadRegister(static_cast<uint8_t>(Registers::C0DataM)); + auto h = ReadRegister(static_cast<uint8_t>(Registers::C0DataH)); + auto l = ReadRegister(static_cast<uint8_t>(Registers::C0dataL)); + return (m << 8) | ((h & 0x0f) << 4) | (l & 0x0f) | ((l & 0x30) << 12); +} + +uint16_t Hrs3300::ReadAls() { + auto m = ReadRegister(static_cast<uint8_t>(Registers::C1dataM)); + auto h = ReadRegister(static_cast<uint8_t>(Registers::C1dataH)); + auto l = ReadRegister(static_cast<uint8_t>(Registers::C1dataL)); + return (m << 3) | ((h & 0x3f) << 11) | (l & 0x07); +} + +void Hrs3300::SetGain(uint8_t gain) { + static constexpr uint8_t maxGain = 64; + gain = std::min(gain, maxGain); + uint8_t hgain = 0; + while((1 << hgain) < gain) + hgain++; + + WriteRegister(static_cast<uint8_t>(Registers::Hgain), hgain << 2); +} + +void Hrs3300::SetDrive(uint8_t drive) { + auto en = ReadRegister(static_cast<uint8_t>(Registers::Enable)); + auto pd = ReadRegister(static_cast<uint8_t>(Registers::PDriver)); + + en = (en & 0xf7) | ((drive & 2) << 2); + pd = (pd & 0xbf) | ((drive & 1) << 6); + + WriteRegister(static_cast<uint8_t>(Registers::Enable), en); + WriteRegister(static_cast<uint8_t>(Registers::PDriver), pd); +} + +void Hrs3300::WriteRegister(uint8_t reg, uint8_t data) { + auto ret = twiMaster.Write(twiAddress, reg, &data, 1); + if(ret != TwiMaster::ErrorCodes::NoError) + NRF_LOG_INFO("WRITE ERROR"); +} + +uint8_t Hrs3300::ReadRegister(uint8_t reg) { + uint8_t value; + auto ret = twiMaster.Read(twiAddress, reg, &value, 1); + if(ret != TwiMaster::ErrorCodes::NoError) + NRF_LOG_INFO("READ ERROR"); + return value; +} + + + + + + + + + + + |