First implementation of the HR sensor using 100% foss code (ported from waspos)

This commit is contained in:
Jean-François Milants
2021-01-10 17:57:26 +01:00
parent 50ae0ae5e0
commit 1a582815ba
23 changed files with 714 additions and 12 deletions

108
src/drivers/Hrs3300.cpp Normal file
View File

@@ -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;
}

47
src/drivers/Hrs3300.h Normal file
View File

@@ -0,0 +1,47 @@
#pragma once
#include "TwiMaster.h"
namespace Pinetime {
namespace Drivers {
class Hrs3300 {
public:
enum class Registers : uint8_t {
Id = 0x00,
Enable = 0x01,
EnableHen = 0x80,
C1dataM = 0x08,
C0DataM = 0x09,
C0DataH = 0x0a,
PDriver = 0x0c,
C1dataH = 0x0d,
C1dataL = 0x0e,
C0dataL = 0x0f,
Res = 0x16,
Hgain = 0x17
};
Hrs3300(TwiMaster& twiMaster, uint8_t twiAddress);
Hrs3300(const Hrs3300&) = delete;
Hrs3300& operator=(const Hrs3300&) = delete;
Hrs3300(Hrs3300&&) = delete;
Hrs3300& operator=(Hrs3300&&) = delete;
void Init();
void Enable();
void Disable();
uint16_t ReadHrs();
uint16_t ReadAls();
void SetGain(uint8_t gain);
void SetDrive(uint8_t drive);
private:
TwiMaster& twiMaster;
uint8_t twiAddress;
void WriteRegister(uint8_t reg, uint8_t data);
uint8_t ReadRegister(uint8_t reg);
};
}
}