Refactor BMA421 as a generic class that implements the concept IsMotionSensor.

This commit is contained in:
Jean-François Milants 2022-12-28 15:29:32 +01:00
parent 7d42c99e4d
commit 7d2ca5c63f
9 changed files with 153 additions and 52 deletions

View File

@ -69,12 +69,12 @@ int32_t MotionController::currentShakeSpeed() {
void MotionController::IsSensorOk(bool isOk) {
isSensorOk = isOk;
}
void MotionController::Init(Pinetime::Drivers::Bma421::DeviceTypes types) {
void MotionController::Init(Pinetime::Drivers::MotionSensors::DeviceTypes types) {
switch (types) {
case Drivers::Bma421::DeviceTypes::BMA421:
case Drivers::MotionSensors::DeviceTypes::BMA421:
this->deviceType = DeviceTypes::BMA421;
break;
case Drivers::Bma421::DeviceTypes::BMA425:
case Drivers::MotionSensors::DeviceTypes::BMA425:
this->deviceType = DeviceTypes::BMA425;
break;
default:

View File

@ -1,7 +1,8 @@
#pragma once
#include <cstdint>
#include <drivers/Bma421.h>
#include <drivers/MotionSensor.h>
#include <port/MotionSensor.h>
#include <components/ble/MotionService.h>
namespace Pinetime {
@ -48,7 +49,7 @@ namespace Pinetime {
return deviceType;
}
void Init(Pinetime::Drivers::Bma421::DeviceTypes types);
void Init(Pinetime::Drivers::MotionSensors::DeviceTypes types);
void SetService(Pinetime::Controllers::MotionService* service);
private:

View File

@ -4,7 +4,7 @@
#include "drivers/TwiMaster.h"
#include <drivers/Bma421_C/bma423.h>
using namespace Pinetime::Drivers;
using namespace Pinetime::Drivers::MotionSensors;
namespace {
int8_t user_i2c_read(uint8_t reg_addr, uint8_t* reg_data, uint32_t length, void* intf_ptr) {
@ -44,13 +44,13 @@ void Bma421::Init() {
switch (bma.chip_id) {
case BMA423_CHIP_ID:
deviceType = DeviceTypes::BMA421;
deviceType = MotionSensors::DeviceTypes::BMA421;
break;
case BMA425_CHIP_ID:
deviceType = DeviceTypes::BMA425;
deviceType = MotionSensors::DeviceTypes::BMA425;
break;
default:
deviceType = DeviceTypes::Unknown;
deviceType = MotionSensors::DeviceTypes::Unknown;
break;
}
@ -99,7 +99,7 @@ void Bma421::Write(uint8_t registerAddress, const uint8_t* data, size_t size) {
twiMaster.Write(deviceAddress, registerAddress, data, size);
}
Bma421::Values Bma421::Process() {
Pinetime::Drivers::MotionSensors::Values Bma421::Process() {
if (not isOk)
return {};
struct bma4_accel data;
@ -133,6 +133,6 @@ void Bma421::SoftReset() {
nrf_delay_ms(1);
}
}
Bma421::DeviceTypes Bma421::DeviceType() const {
Pinetime::Drivers::MotionSensors::DeviceTypes Bma421::DeviceType() const {
return deviceType;
}

View File

@ -1,47 +1,50 @@
#pragma once
#include "drivers/TwiMaster.h"
#include "port/TwiMaster.h"
#include "drivers/MotionSensor.h"
#include <drivers/Bma421_C/bma4_defs.h>
namespace Pinetime {
namespace Drivers {
class Bma421 {
public:
enum class DeviceTypes : uint8_t { Unknown, BMA421, BMA425 };
struct Values {
uint32_t steps;
int16_t x;
int16_t y;
int16_t z;
namespace MotionSensors {
class Bma421 {
public:
enum class DeviceTypes : uint8_t { Unknown, BMA421, BMA425 };
struct Values {
uint32_t steps;
int16_t x;
int16_t y;
int16_t z;
};
Bma421(TwiMaster& twiMaster, uint8_t twiAddress);
Bma421(const Bma421&) = delete;
Bma421& operator=(const Bma421&) = delete;
Bma421(Bma421&&) = delete;
Bma421& operator=(Bma421&&) = delete;
/// The chip freezes the TWI bus after the softreset operation. Softreset is separated from the
/// Init() method to allow the caller to uninit and then reinit the TWI device after the softreset.
void SoftReset();
void Init();
MotionSensors::Values Process();
void ResetStepCounter();
void Read(uint8_t registerAddress, uint8_t* buffer, size_t size);
void Write(uint8_t registerAddress, const uint8_t* data, size_t size);
bool IsOk() const;
MotionSensors::DeviceTypes DeviceType() const;
private:
void Reset();
TwiMaster& twiMaster;
uint8_t deviceAddress = 0x18;
struct bma4_dev bma;
bool isOk = false;
bool isResetOk = false;
MotionSensors::DeviceTypes deviceType = MotionSensors::DeviceTypes::Unknown;
};
Bma421(TwiMaster& twiMaster, uint8_t twiAddress);
Bma421(const Bma421&) = delete;
Bma421& operator=(const Bma421&) = delete;
Bma421(Bma421&&) = delete;
Bma421& operator=(Bma421&&) = delete;
/// The chip freezes the TWI bus after the softreset operation. Softreset is separated from the
/// Init() method to allow the caller to uninit and then reinit the TWI device after the softreset.
void SoftReset();
void Init();
Values Process();
void ResetStepCounter();
void Read(uint8_t registerAddress, uint8_t* buffer, size_t size);
void Write(uint8_t registerAddress, const uint8_t* data, size_t size);
bool IsOk() const;
DeviceTypes DeviceType() const;
private:
void Reset();
TwiMaster& twiMaster;
uint8_t deviceAddress = 0x18;
struct bma4_dev bma;
bool isOk = false;
bool isResetOk = false;
DeviceTypes deviceType = DeviceTypes::Unknown;
};
}
}
}

View File

@ -0,0 +1,78 @@
#pragma once
#include <concepts>
#include <cstddef>
#include <cstdint>
namespace Pinetime {
namespace Drivers {
namespace MotionSensors {
enum class DeviceTypes : uint8_t { Unknown, BMA421, BMA425 };
struct Values {
uint32_t steps;
int16_t x;
int16_t y;
int16_t z;
};
}
template <typename motionSensorImpl>
concept IsMotionSensor = requires(motionSensorImpl sensor, uint8_t registerAddress, uint8_t* data, uint8_t* constData, size_t size) {
{ sensor.SoftReset() };
{ sensor.Init() };
{ sensor.Process() };
{ sensor.ResetStepCounter() };
{ sensor.IsOk() };
{ sensor.DeviceType() };
{ sensor.Read(registerAddress, data, size) };
{ sensor.Write(registerAddress, constData, size) };
};
namespace Interface {
template <class T>
requires IsMotionSensor<T>
class MotionSensor {
public:
explicit MotionSensor(T& impl) : impl {impl} {}
MotionSensor(const MotionSensor&) = delete;
MotionSensor& operator=(const MotionSensor&) = delete;
MotionSensor(MotionSensor&&) = delete;
MotionSensor& operator=(MotionSensor&&) = delete;
void SoftReset() {
return impl.SoftReset();
}
void Init() {
impl.Init();
}
MotionSensors::Values Process() {
return impl.Process();
}
void ResetStepCounter() {
return impl.ResetStepCounter();
}
void Read(uint8_t registerAddress, uint8_t* buffer, size_t size) {
impl.Read(registerAddress, buffer, size);
}
void Write(uint8_t registerAddress, const uint8_t* data, size_t size) {
impl.Write(registerAddress, data, size);
}
bool IsOk() const {
return impl.IsOk();
}
MotionSensors::DeviceTypes DeviceType() const {
return impl.DeviceType();
}
private:
T& impl;
};
}
}
}

View File

@ -59,6 +59,7 @@ Pinetime::Logging::DummyLogger logger;
#endif
#include "port/TouchPanel.h"
#include "port/MotionSensor.h"
static constexpr uint8_t touchPanelTwiAddress = 0x15;
static constexpr uint8_t motionSensorTwiAddress = 0x18;
@ -101,7 +102,8 @@ Pinetime::Drivers::TouchPanel touchPanel {touchPanelImpl};
#endif
Pinetime::Components::LittleVgl lvgl {lcd, touchPanel};
Pinetime::Drivers::Bma421 motionSensor {twiMaster, motionSensorTwiAddress};
Pinetime::Drivers::MotionSensors::Bma421 motionSensorImpl {twiMaster, motionSensorTwiAddress};
Pinetime::Drivers::MotionSensor motionSensor {motionSensorImpl};
Pinetime::Drivers::Hrs3300 heartRateSensor {twiMaster, heartRateSensorTwiAddress};
TimerHandle_t debounceTimer;

16
src/port/MotionSensor.h Normal file
View File

@ -0,0 +1,16 @@
#pragma once
#include "drivers/MotionSensor.h"
#ifdef TARGET_DEVICE_PINETIME
#include <drivers/Bma421.h>
#endif
namespace Pinetime {
namespace Drivers {
#ifdef TARGET_DEVICE_PINETIME
using MotionSensor = Interface::MotionSensor<Pinetime::Drivers::MotionSensors::Bma421>;
#else
#error "No target device specified!"
#endif
}
}

View File

@ -55,7 +55,7 @@ SystemTask::SystemTask(Drivers::SpiMaster& spi,
Pinetime::Controllers::MotorController& motorController,
Pinetime::Drivers::Hrs3300& heartRateSensor,
Pinetime::Controllers::MotionController& motionController,
Pinetime::Drivers::Bma421& motionSensor,
Pinetime::Drivers::MotionSensor& motionSensor,
Controllers::Settings& settingsController,
Pinetime::Controllers::HeartRateController& heartRateController,
Pinetime::Applications::DisplayApp& displayApp,

View File

@ -36,6 +36,7 @@
#include "drivers/Watchdog.h"
#include "systemtask/Messages.h"
#include "port/SpiMaster.h"
#include "port/MotionSensor.h"
extern std::chrono::time_point<std::chrono::system_clock, std::chrono::nanoseconds> NoInit_BackUpTime;
namespace Pinetime {
@ -68,7 +69,7 @@ namespace Pinetime {
Pinetime::Controllers::MotorController& motorController,
Pinetime::Drivers::Hrs3300& heartRateSensor,
Pinetime::Controllers::MotionController& motionController,
Pinetime::Drivers::Bma421& motionSensor,
Pinetime::Drivers::MotionSensor& motionSensor,
Controllers::Settings& settingsController,
Pinetime::Controllers::HeartRateController& heartRateController,
Pinetime::Applications::DisplayApp& displayApp,
@ -113,7 +114,7 @@ namespace Pinetime {
Pinetime::Controllers::NotificationManager& notificationManager;
Pinetime::Controllers::MotorController& motorController;
Pinetime::Drivers::Hrs3300& heartRateSensor;
Pinetime::Drivers::Bma421& motionSensor;
Pinetime::Drivers::MotionSensor& motionSensor;
Pinetime::Controllers::Settings& settingsController;
Pinetime::Controllers::HeartRateController& heartRateController;
Pinetime::Controllers::MotionController& motionController;