diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0b6b2a3f7b..b46e819f41 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -443,9 +443,11 @@ list(APPEND SOURCE_FILES drivers/DebugPins.cpp drivers/InternalFlash.cpp drivers/Hrs3300.cpp + drivers/AccelerationSensor.cpp drivers/Bma421.cpp drivers/Bma421_C/bma4.c drivers/Bma421_C/bma423.c + drivers/SC7A20.cpp components/battery/BatteryController.cpp components/ble/BleController.cpp components/ble/NotificationManager.cpp @@ -510,9 +512,11 @@ list(APPEND RECOVERY_SOURCE_FILES drivers/DebugPins.cpp drivers/InternalFlash.cpp drivers/Hrs3300.cpp + drivers/AccelerationSensor.cpp drivers/Bma421.cpp drivers/Bma421_C/bma4.c drivers/Bma421_C/bma423.c + drivers/SC7A20.cpp components/battery/BatteryController.cpp components/ble/BleController.cpp components/ble/NotificationManager.cpp @@ -626,9 +630,12 @@ set(INCLUDE_FILES drivers/InternalFlash.h drivers/Hrs3300.h drivers/PinMap.h + drivers/AccelerationSensor.h drivers/Bma421.h drivers/Bma421_C/bma4.c drivers/Bma421_C/bma423.c + drivers/SC7A20.h + drivers/SC7A20_registers.h components/battery/BatteryController.h components/ble/BleController.h components/ble/NotificationManager.h @@ -799,20 +806,24 @@ add_definitions(-DTARGET_DEVICE_NAME="${TARGET_DEVICE}") if(TARGET_DEVICE STREQUAL "PINETIME") add_definitions(-DDRIVER_PINMAP_PINETIME) add_definitions(-DCLOCK_CONFIG_LF_SRC=1) # XTAL + add_definitions(-DDRIVER_ACC_BMA421) add_definitions(-DDRIVER_TOUCH_DYNAMIC) elseif(TARGET_DEVICE STREQUAL "MOY-TFK5") # P8a add_definitions(-DDRIVER_PINMAP_P8) add_definitions(-DCLOCK_CONFIG_LF_SRC=1) # XTAL + add_definitions(-DDRIVER_ACC_BMA421) add_definitions(-DDRIVER_TOUCH_GESTURE) elseif(TARGET_DEVICE STREQUAL "MOY-TIN5") # P8a variant 2 add_definitions(-DDRIVER_PINMAP_P8) add_definitions(-DCLOCK_CONFIG_LF_SRC=1) # XTAL + add_definitions(-DDRIVER_ACC_SC7A20) add_definitions(-DDRIVER_TOUCH_GESTURE) elseif(TARGET_DEVICE STREQUAL "MOY-TON5") # P8b add_definitions(-DDRIVER_PINMAP_P8) add_definitions(-DCLOCK_CONFIG_LF_SRC=0) # RC add_definitions(-DMYNEWT_VAL_BLE_LL_SCA=500) add_definitions(-DCLOCK_CONFIG_LF_CAL_ENABLED=1) + add_definitions(-DDRIVER_ACC_SC7A20) add_definitions(-DDRIVER_TOUCH_REPORT) elseif(TARGET_DEVICE STREQUAL "MOY-UNK") # P8b mirrored add_definitions(-DDRIVER_PINMAP_P8) @@ -820,6 +831,7 @@ elseif(TARGET_DEVICE STREQUAL "MOY-UNK") # P8b mirrored add_definitions(-DMYNEWT_VAL_BLE_LL_SCA=500) add_definitions(-DCLOCK_CONFIG_LF_CAL_ENABLED=1) add_definitions(-DDRIVER_DISPLAY_MIRROR) + add_definitions(-DDRIVER_ACC_SC7A20) add_definitions(-DDRIVER_TOUCH_REPORT) else() message(FATAL_ERROR "Invalid TARGET_DEVICE") diff --git a/src/components/ble/MotionService.cpp b/src/components/ble/MotionService.cpp index 121ad3b08a..8750f96672 100644 --- a/src/components/ble/MotionService.cpp +++ b/src/components/ble/MotionService.cpp @@ -90,20 +90,22 @@ void MotionService::OnNewStepCountValue(uint32_t stepCount) { ble_gattc_notify_custom(connectionHandle, stepCountHandle, om); } -void MotionService::OnNewMotionValues(int16_t x, int16_t y, int16_t z) { + +void MotionService::OnNewMotionValues(int16_t* samples, uint16_t samples_length) { if (!motionValuesNoficationEnabled) return; - int16_t buffer[3] = {motionController.X(), motionController.Y(), motionController.Z()}; - auto* om = ble_hs_mbuf_from_flat(buffer, 3 * sizeof(int16_t)); + if (samples_length > 0 && samples != nullptr) { + auto* om = ble_hs_mbuf_from_flat(samples, samples_length * 3 * sizeof(int16_t)); - uint16_t connectionHandle = system.nimble().connHandle(); + uint16_t connectionHandle = system.nimble().connHandle(); - if (connectionHandle == 0 || connectionHandle == BLE_HS_CONN_HANDLE_NONE) { - return; - } + if (connectionHandle == 0 || connectionHandle == BLE_HS_CONN_HANDLE_NONE) { + return; + } - ble_gattc_notify_custom(connectionHandle, motionValuesHandle, om); + ble_gattc_notify_custom(connectionHandle, motionValuesHandle, om); + } } void MotionService::SubscribeNotification(uint16_t connectionHandle, uint16_t attributeHandle) { diff --git a/src/components/ble/MotionService.h b/src/components/ble/MotionService.h index 1b4ac0a37e..172ed270fc 100644 --- a/src/components/ble/MotionService.h +++ b/src/components/ble/MotionService.h @@ -18,7 +18,7 @@ namespace Pinetime { void Init(); int OnStepCountRequested(uint16_t connectionHandle, uint16_t attributeHandle, ble_gatt_access_ctxt* context); void OnNewStepCountValue(uint32_t stepCount); - void OnNewMotionValues(int16_t x, int16_t y, int16_t z); + void OnNewMotionValues(int16_t* samples, uint16_t samples_length); void SubscribeNotification(uint16_t connectionHandle, uint16_t attributeHandle); void UnsubscribeNotification(uint16_t connectionHandle, uint16_t attributeHandle); diff --git a/src/components/motion/MotionController.cpp b/src/components/motion/MotionController.cpp index 7dd321271c..518ad08c55 100644 --- a/src/components/motion/MotionController.cpp +++ b/src/components/motion/MotionController.cpp @@ -2,13 +2,13 @@ #include "os/os_cputime.h" using namespace Pinetime::Controllers; -void MotionController::Update(int16_t x, int16_t y, int16_t z, uint32_t nbSteps) { +void MotionController::Update(uint32_t nbSteps, int16_t x, int16_t y, int16_t z, int16_t* samples, uint16_t samples_length) { if (this->nbSteps != nbSteps && service != nullptr) { service->OnNewStepCountValue(nbSteps); } if (service != nullptr && (this->x != x || this->y != y || this->z != z)) { - service->OnNewMotionValues(x, y, z); + service->OnNewMotionValues(samples, samples_length); } this->x = x; @@ -62,6 +62,7 @@ bool MotionController::Should_ShakeWake(uint16_t thresh) { lastZForShake = z; return wake; } + int32_t MotionController::currentShakeSpeed() { return accumulatedspeed; } @@ -69,19 +70,11 @@ int32_t MotionController::currentShakeSpeed() { void MotionController::IsSensorOk(bool isOk) { isSensorOk = isOk; } -void MotionController::Init(Pinetime::Drivers::Bma421::DeviceTypes types) { - switch (types) { - case Drivers::Bma421::DeviceTypes::BMA421: - this->deviceType = DeviceTypes::BMA421; - break; - case Drivers::Bma421::DeviceTypes::BMA425: - this->deviceType = DeviceTypes::BMA425; - break; - default: - this->deviceType = DeviceTypes::Unknown; - break; - } + +void MotionController::Init(Pinetime::Drivers::AccelerationDeviceTypes types) { + this->deviceType = types; } + void MotionController::SetService(Pinetime::Controllers::MotionService* service) { this->service = service; } diff --git a/src/components/motion/MotionController.h b/src/components/motion/MotionController.h index f80b11b994..da9dd16050 100644 --- a/src/components/motion/MotionController.h +++ b/src/components/motion/MotionController.h @@ -8,13 +8,7 @@ namespace Pinetime { namespace Controllers { class MotionController { public: - enum class DeviceTypes { - Unknown, - BMA421, - BMA425, - }; - - void Update(int16_t x, int16_t y, int16_t z, uint32_t nbSteps); + void Update(uint32_t nbSteps, int16_t x, int16_t y, int16_t z, int16_t* samples, uint16_t samples_length); int16_t X() const { return x; @@ -44,11 +38,11 @@ namespace Pinetime { return isSensorOk; } - DeviceTypes DeviceType() const { + Pinetime::Drivers::AccelerationDeviceTypes DeviceType() const { return deviceType; } - void Init(Pinetime::Drivers::Bma421::DeviceTypes types); + void Init(Pinetime::Drivers::AccelerationDeviceTypes types); void SetService(Pinetime::Controllers::MotionService* service); private: @@ -59,7 +53,7 @@ namespace Pinetime { int16_t z; int16_t lastYForWakeUp = 0; bool isSensorOk = false; - DeviceTypes deviceType = DeviceTypes::Unknown; + Pinetime::Drivers::AccelerationDeviceTypes deviceType = Pinetime::Drivers::AccelerationDeviceTypes::Unknown; Pinetime::Controllers::MotionService* service = nullptr; int16_t lastXForShake = 0; diff --git a/src/displayapp/screens/SystemInfo.cpp b/src/displayapp/screens/SystemInfo.cpp index 01c351955e..eaf33c688d 100644 --- a/src/displayapp/screens/SystemInfo.cpp +++ b/src/displayapp/screens/SystemInfo.cpp @@ -17,13 +17,15 @@ using namespace Pinetime::Applications::Screens; namespace { - const char* ToString(const Pinetime::Controllers::MotionController::DeviceTypes deviceType) { + const char* ToString(const Pinetime::Drivers::AccelerationDeviceTypes deviceType) { switch (deviceType) { - case Pinetime::Controllers::MotionController::DeviceTypes::BMA421: + case Pinetime::Drivers::AccelerationDeviceTypes::BMA421: return "BMA421"; - case Pinetime::Controllers::MotionController::DeviceTypes::BMA425: + case Pinetime::Drivers::AccelerationDeviceTypes::BMA425: return "BMA425"; - case Pinetime::Controllers::MotionController::DeviceTypes::Unknown: + case Pinetime::Drivers::AccelerationDeviceTypes::SC7A20: + return "SC7A20"; + case Pinetime::Drivers::AccelerationDeviceTypes::Unknown: return "???"; } return "???"; diff --git a/src/drivers/AccelerationSensor.cpp b/src/drivers/AccelerationSensor.cpp new file mode 100644 index 0000000000..c0d2bda168 --- /dev/null +++ b/src/drivers/AccelerationSensor.cpp @@ -0,0 +1,39 @@ +#include "AccelerationSensor.h" + +namespace Pinetime { + namespace Drivers { + + AccelerationSensor::AccelerationSensor(TwiMaster& twiMaster, uint8_t twiAddress) : twiMaster(twiMaster), deviceAddress(twiAddress) { + } + + void AccelerationSensor::SoftReset() { + } + + void AccelerationSensor::Init() { + } + + AccelerationValues AccelerationSensor::Process() { + return {0}; + } + + void AccelerationSensor::ResetStepCounter() { + } + + void AccelerationSensor::Read(uint8_t registerAddress, uint8_t* buffer, size_t size) { + twiMaster.Read(deviceAddress, registerAddress, buffer, size); + } + + void AccelerationSensor::Write(uint8_t registerAddress, const uint8_t* data, size_t size) { + twiMaster.Write(deviceAddress, registerAddress, data, size); + } + + AccelerationDeviceTypes AccelerationSensor::DeviceType() const { + return deviceType; + } + + bool AccelerationSensor::IsInitialized() const { + return isInitialized; + } + + } +} diff --git a/src/drivers/AccelerationSensor.h b/src/drivers/AccelerationSensor.h new file mode 100644 index 0000000000..428948c20f --- /dev/null +++ b/src/drivers/AccelerationSensor.h @@ -0,0 +1,47 @@ +#pragma once + +#include "drivers/TwiMaster.h" + +namespace Pinetime { + namespace Drivers { + + enum class AccelerationDeviceTypes : uint8_t { Unknown, BMA421, BMA425, SC7A20 }; + + struct AccelerationValues { + uint32_t steps; + int16_t x; + int16_t y; + int16_t z; + int16_t* samples = nullptr; + uint16_t samples_length = 0; + }; + + class AccelerationSensor { + public: + AccelerationSensor(TwiMaster& twiMaster, uint8_t twiAddress); + AccelerationSensor(const AccelerationSensor&) = delete; + AccelerationSensor& operator=(const AccelerationSensor&) = delete; + AccelerationSensor(AccelerationSensor&&) = delete; + AccelerationSensor& operator=(AccelerationSensor&&) = delete; + + virtual void SoftReset(); + virtual void Init(); + virtual AccelerationValues Process(); + virtual 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 IsInitialized() const; + AccelerationDeviceTypes DeviceType() const; + + protected: + TwiMaster& twiMaster; + uint8_t deviceAddress; + bool isInitialized = false; + AccelerationDeviceTypes deviceType = AccelerationDeviceTypes::Unknown; + int16_t fifo[32][3] = {0}; + }; + + } +} diff --git a/src/drivers/Bma421.cpp b/src/drivers/Bma421.cpp index 050a3a6fb1..313ba7c56f 100644 --- a/src/drivers/Bma421.cpp +++ b/src/drivers/Bma421.cpp @@ -1,11 +1,9 @@ #include "drivers/Bma421.h" -#include -#include #include "drivers/TwiMaster.h" #include +#include using namespace Pinetime::Drivers; - namespace { int8_t user_i2c_read(uint8_t reg_addr, uint8_t* reg_data, uint32_t length, void* intf_ptr) { auto bma421 = static_cast(intf_ptr); @@ -24,7 +22,7 @@ namespace { } } -Bma421::Bma421(TwiMaster& twiMaster, uint8_t twiAddress) : twiMaster {twiMaster}, deviceAddress {twiAddress} { +Bma421::Bma421(TwiMaster& twiMaster, uint8_t twiAddress) : AccelerationSensor(twiMaster, twiAddress) { bma.intf = BMA4_I2C_INTF; bma.bus_read = user_i2c_read; bma.bus_write = user_i2c_write; @@ -47,13 +45,13 @@ void Bma421::Init() { // Identify chip by ID. The driver code has been modified to handle BMA421 as BMA423 switch (bma.chip_id) { case BMA423_CHIP_ID: - deviceType = DeviceTypes::BMA421; + deviceType = AccelerationDeviceTypes::BMA421; break; case BMA425_CHIP_ID: - deviceType = DeviceTypes::BMA425; + deviceType = AccelerationDeviceTypes::BMA425; break; default: - deviceType = DeviceTypes::Unknown; + deviceType = AccelerationDeviceTypes::Unknown; break; } @@ -66,11 +64,9 @@ void Bma421::Init() { ret = bma423_feature_enable(BMA423_STEP_CNTR, 1, &bma); if (ret != BMA4_OK) return; - ret = bma423_step_detector_enable(0, &bma); if (ret != BMA4_OK) return; - ret = bma4_set_accel_enable(1, &bma); if (ret != BMA4_OK) return; @@ -94,24 +90,11 @@ void Bma421::Init() { if (ret != BMA4_OK) return; - isOk = true; -} - -void Bma421::Reset() { - uint8_t data = 0xb6; - twiMaster.Write(deviceAddress, 0x7E, &data, 1); + isInitialized = true; } -void Bma421::Read(uint8_t registerAddress, uint8_t* buffer, size_t size) { - twiMaster.Read(deviceAddress, registerAddress, buffer, size); -} - -void Bma421::Write(uint8_t registerAddress, const uint8_t* data, size_t size) { - twiMaster.Write(deviceAddress, registerAddress, data, size); -} - -Bma421::Values Bma421::Process() { - if (not isOk) +AccelerationValues Bma421::Process() { + if (!isInitialized) return {}; // Dump entire FIFO into buffer @@ -146,11 +129,7 @@ Bma421::Values Bma421::Process() { for (uint8_t j = 0; j < 3; j++) avgs[j] /= length; - return {steps, avgs[0], avgs[1], avgs[2]}; -} - -bool Bma421::IsOk() const { - return isOk; + return {steps, avgs[0], avgs[1], avgs[2], (int16_t*) fifo, length}; } void Bma421::ResetStepCounter() { @@ -164,6 +143,3 @@ void Bma421::SoftReset() { nrf_delay_ms(1); } } -Bma421::DeviceTypes Bma421::DeviceType() const { - return deviceType; -} diff --git a/src/drivers/Bma421.h b/src/drivers/Bma421.h index 9345227245..f2a6a1b9d6 100644 --- a/src/drivers/Bma421.h +++ b/src/drivers/Bma421.h @@ -1,18 +1,12 @@ #pragma once + +#include "drivers/AccelerationSensor.h" #include namespace Pinetime { namespace Drivers { - class TwiMaster; - class Bma421 { + class Bma421 : public AccelerationSensor { 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; @@ -23,26 +17,13 @@ namespace Pinetime { /// Init() method to allow the caller to uninit and then reinit the TWI device after the softreset. void SoftReset(); void Init(); - Values Process(); + AccelerationValues 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; + bool isResetOk = false; struct bma4_dev bma; struct bma4_fifo_frame fifo_frame; - int16_t fifo[32][3] = {0}; - bool isOk = false; - bool isResetOk = false; - DeviceTypes deviceType = DeviceTypes::Unknown; }; } -} \ No newline at end of file +} diff --git a/src/drivers/SC7A20.cpp b/src/drivers/SC7A20.cpp new file mode 100644 index 0000000000..4e75d24465 --- /dev/null +++ b/src/drivers/SC7A20.cpp @@ -0,0 +1,89 @@ +#include "drivers/SC7A20.h" +#include "drivers/SC7A20_registers.h" +#include +#include + +using namespace Pinetime::Drivers; + +SC7A20::SC7A20(TwiMaster& twiMaster, uint8_t twiAddress) : AccelerationSensor(twiMaster, twiAddress) { +} + +void SC7A20::Init() { + // Reset internal memory + uint8_t data = CTRL_REG5_BOOT; + Write(CTRL_REG5, &data, 1); + vTaskDelay(5); + data = 0; + Write(CTRL_REG5, &data, 1); + + // Read Chip ID + Read(WHO_AM_I, &data, 1); + if (data == 17) { + deviceType = AccelerationDeviceTypes::SC7A20; + } else { + deviceType = AccelerationDeviceTypes::Unknown; + return; + } + + // Configure resolution to be +-2g + data = CTRL_REG4_FS_2G; + Write(CTRL_REG4, &data, 1); + + // Enable block update, configure 12 bit resolution mode + data = CTRL_REG4_BDU | CTRL_REG4_HR; + Write(CTRL_REG4, &data, 1); + + // Use FIFO for batch data + data = CTRL_REG5_FIFO_EN; + Write(CTRL_REG5, &data, 1); + data = FIFO_CTRL_REG_FIFO; + Write(FIFO_CTRL_REG, &data, 1); + + // Set 200 Hz sample rate, enable all axes + data = CTRL_REG1_ODR_200HZ | CTRL_REG1_X_EN | CTRL_REG1_Y_EN | CTRL_REG1_Z_EN; + Write(CTRL_REG1, &data, 1); + + isInitialized = true; +} + +AccelerationValues SC7A20::Process() { + if (!isInitialized) + return {}; + + // Read FIFO size, should be about 20 (200 Hz ODR / 10 Hz main loop) + uint8_t length = 0; + Read(FIFO_SRC_REG, &length, 1); + length &= FIFO_SRC_REG_FSS_MASK; + + // Read FIFO samples one by one (full read does not work) + for (uint8_t i = 0; i < length; i++) { + // Set the most significant bit of the sub-address field for block read + Read(0x80 | OUT_X_L, (uint8_t*) &fifo[i], sizeof(int16_t) * 3); + // Shift because value is left-justified + for (uint8_t j = 0; j < 3; j++) + fifo[i][j] >>= (16 - 12); + // X and Y axis are swapped because of the way the sensor is mounted in the P8 + int16_t swap = fifo[i][0]; + fifo[i][0] = fifo[i][1]; + fifo[i][1] = swap; + } + + // Restart FIFO + uint8_t data = FIFO_CTRL_REG_BYPASS; + Write(FIFO_CTRL_REG, &data, 1); + data = FIFO_CTRL_REG_FIFO; + Write(FIFO_CTRL_REG, &data, 1); + + // Compute averages of FIFO + int16_t avgs[3] = {0}; + // 2g range in n bits + for (uint8_t i = 0; i < length; i++) + for (uint8_t j = 0; j < 3; j++) { + avgs[j] += ((fifo[i][j] * 2000) / (1 << (12 - 1))); + } + for (uint8_t j = 0; j < 3; j++) + avgs[j] /= length; + + // Step counting is not implemented + return {0, avgs[0], avgs[1], avgs[2], (int16_t*) fifo, length}; +} diff --git a/src/drivers/SC7A20.h b/src/drivers/SC7A20.h new file mode 100644 index 0000000000..9716a57098 --- /dev/null +++ b/src/drivers/SC7A20.h @@ -0,0 +1,19 @@ +#pragma once + +#include "drivers/AccelerationSensor.h" + +namespace Pinetime { + namespace Drivers { + class SC7A20 : public AccelerationSensor { + public: + SC7A20(TwiMaster& twiMaster, uint8_t twiAddress); + SC7A20(const SC7A20&) = delete; + SC7A20& operator=(const SC7A20&) = delete; + SC7A20(SC7A20&&) = delete; + SC7A20& operator=(SC7A20&&) = delete; + + void Init(); + AccelerationValues Process(); + }; + } +} diff --git a/src/drivers/SC7A20_registers.h b/src/drivers/SC7A20_registers.h new file mode 100644 index 0000000000..9b3464a1ef --- /dev/null +++ b/src/drivers/SC7A20_registers.h @@ -0,0 +1,423 @@ +#pragma once + +// SC7A20 ±2G/±4G/±8G/±16G Three-axis micromachined digital accelerometer +// Hangzhou Silan Microelectronics Co., Ltd. www.silan.com.cn + +// Manually assembled from an auto-translated incomplete datasheet +// This chips behaves nearly the same as a ST LIS2DH, the rest was added from the ST datasheet + +// Registers + +#define OUT_TEMP_L 0x0C // readonly +#define OUT_TEMP_H 0x0D // readonly +#define WHO_AM_I 0x0F // readonly +#define USER_CAL 0x13 // read-write +#define NVM_WR 0x1E // read-write +#define TEMP_CFG 0x1F // read-write +#define CTRL_REG1 0x20 // read-write. Control register 1. +#define CTRL_REG2 0x21 // read-write. Control register 2. +#define CTRL_REG3 0x22 // read-write. Control register 3. +#define CTRL_REG4 0x23 // read-write. Control register 4. +#define CTRL_REG5 0x24 // read-write. Control register 5. +#define CTRL_REG6 0x25 // read-write. Control register 6. +#define REFERENCE 0x26 // read-write +#define STATUS_REG 0x27 // read-write. Status register. +#define OUT_X_L 0x28 // readonly. X Axis accelerometer value. This value starts with 2 output in two's complement form. +#define OUT_X_H 0x29 // readonly +#define OUT_Y_L 0x2A // readonly. Y Axis accelerometer value. This value starts with 2 output in two's complement form. +#define OUT_Y_H 0x2B // readonly +#define OUT_Z_L 0x2C // readonly. Z Axis accelerometer value. This value starts with 2 output in two's complement form. +#define OUT_Z_H 0x2D // readonly +#define FIFO_CTRL_REG 0x2E // read-write +#define FIFO_SRC_REG 0x2F // readonly +#define INT1_CFG 0x30 // read-write. Interrupt 1 configuration. +#define INT1_SOURCE 0x31 // readonly. Interrupt 1 source / status. +#define INT1_THS 0x32 // read-write. Interrupt 1 treshold. +#define INT1_DURATION 0x33 // read-write. Interrupt 1 duration. +#define INT2_CFG 0x34 // read-write. Interrupt 2 configuration. +#define INT2_SOURCE 0x35 // readonly. Interrupt 2 source / status. +#define INT2_THS 0x36 // read-write. Interrupt 2 treshold. +#define INT2_DURATION 0x37 // read-write. Interrupt 1 duration. +#define CLICK_CFG 0x38 // read-write +#define CLICK_SRC 0x39 // readonly +#define CLICK_THS 0x3A // read-write +#define TIME_LIMIT 0x3B // read-write +#define TIME_LATENCY 0x3C // read-write +#define TIME_WINDOW 0x3D // read-write +#define ACT_THS 0x3E // read-write +#define ACT_DURATION 0x3F // read-write + +// Control register configurations + +// CTRL_REG1 + +#define CTRL_REG1_X_EN (1 << 0) // XAxis enable, default is 1. (0: Xaxis disabled, 1: Xaxis enabled) +#define CTRL_REG1_Y_EN (1 << 1) // YAxis enable, default is 1. (0: Yaxis disabled, 1: Yaxis enabled) +#define CTRL_REG1_Z_EN (1 << 2) // ZAxis enable, default is 1. (0: Zaxis disabled, 1: Zaxis enabled) +#define CTRL_REG1_LP_EN (1 << 3) // Low power enable, the default value is 0. (0: normal working mode, 1: low power mode) +#define CTRL_REG1_ODR0 (1 << 4) // Data rate selection, default: 0000 +#define CTRL_REG1_ODR1 (1 << 5) +#define CTRL_REG1_ODR2 (1 << 6) +#define CTRL_REG1_ODR3 (1 << 7) + +#define CTRL_REG1_ODR_POWERDOWN (0 << 4) // Power down mode +#define CTRL_REG1_ODR_1HZ (1 << 4) // Normal / Low power mode (1 Hz) +#define CTRL_REG1_ODR_10HZ (2 << 4) // Normal / Low power mode (10 Hz) +#define CTRL_REG1_ODR_25HZ (3 << 4) // Normal / Low power mode (25 Hz) +#define CTRL_REG1_ODR_50HZ (4 << 4) // Normal / Low power mode (50 Hz) +#define CTRL_REG1_ODR_100HZ (5 << 4) // Normal / Low power mode (100 Hz) +#define CTRL_REG1_ODR_200HZ (6 << 4) // Normal / Low power mode (200 Hz) +#define CTRL_REG1_ODR_400HZ (7 << 4) // Normal / Low power mode (400 Hz) +#define CTRL_REG1_ODR_1_6KHZ (8 << 4) // Low power mode (1.6 KHz) +#define CTRL_REG1_ODR_1_25KHZ (9 << 4) // normal working mode (1.25 kHz) / Low power mode (5KHz) + +// CTRL_REG2 + +#define CTRL_REG2_HPIS1 (1 << 0) // Interrupt 1 AOIFunction high pass filter enable. (0: Filter disabled; 1: filter enable) +#define CTRL_REG2_HPIS2 (1 << 1) // Interrupt 2 AOIFunction high pass filter enable. (0: Filter disabled; 1: filter enable) +#define CTRL_REG2_HPCLICK (1 << 2) // CLICK Function high pass filter enable. (0: Filter disabled; 1: filter enable) +// Data filtering options. Defaults: 0. (0: skip internal filtering; 1: The data after internal filtering is output to the data register or +// FIFO) +#define CTRL_REG2_FDS (1 << 3) +#define CTRL_REG2_HPCF1 (1 << 4) // High pass cutoff frequency selection +#define CTRL_REG2_HPCF2 (1 << 5) +#define CTRL_REG2_HPM0 (1 << 6) // High pass mode selection, Default 00 +#define CTRL_REG2_HPM1 (1 << 7) + +#define CTRL_REG2_HPM_NORMAL_HPFILTER_AUTORESET (0 << 6) // Normal mode (read high-pass filter resets automatically) +#define CTRL_REG2_HPM_FILTER_REF (1 << 6) // Filter reference signal +#define CTRL_REG2_HPM_NORMAL (2 << 6) // Normal mode +#define CTRL_REG2_HPM_INTERRUPT_AUTORESET (3 << 6) // Interrupt event auto reset + +// CTRL_REG3 + +#define CTRL_REG3_I1_OVERRUN (1 << 1) // FIFO overflow interrupt at INT1 superior. Defaults: 0 (0: prohibit; 1: Enable) +#define CTRL_REG3_I1_WTM (1 << 2) // FIFO watermark breaks at INT1 superior. Defaults:0 (0: prohibit; 1:Enable) +#define CTRL_REG3_I1_DRDY2 (1 << 3) // DRDY2 interrupted at INT1 superior. Defaults: 0 (0: prohibit; 1: Enable) +#define CTRL_REG3_I1_DRDY1 (1 << 4) // DRDY1 interrupted at INT1 superior. Defaults: 0 (0: prohibit; 1: Enable) +#define CTRL_REG3_I1_AOI2 (1 << 5) // Enable interrupt function 2 on interrupt pin 1. Defaults: 0 (0: prohibit; 1: Enable) +#define CTRL_REG3_I1_AOI1 (1 << 6) // Enable interrupt function 1 on interrupt pin 1. Defaults: 0 (0: prohibit; 1: Enable) +#define CTRL_REG3_I1_CLICK (1 << 7) // CLICK interrupted at INT1 superior. Defaults:0 (0: prohibit; 1: Enable) + +// CTRL_REG4 + +#define CTRL_REG4_SIM (1 << 0) // SPI Serial interface mode configuration. Defaults: 0 (0: 4line interface; 1: 3line interface) +#define CTRL_REG4_ST0 (1 << 1) // Self-test enabled. Defaults: 00. +#define CTRL_REG4_ST1 (1 << 2) +#define CTRL_REG4_HR (1 << 3) // High precision output mode selection. Defaults: (0: high precision prohibited; 1: high precision enable) +#define CTRL_REG4_FS0 (1 << 4) // Full range selection. Defaults: 00. +#define CTRL_REG4_FS1 (1 << 5) +// Big endian/little endian data selection. Defaults:0 (0: The low byte data is at the low address; 1: high byte data at low address) +#define CTRL_REG4_BLE (1 << 6) +// Block data update. Defaults: 0. (0: continuous update; 1: The output data register is not updated until MSB and LSB is read) +#define CTRL_REG4_BDU (1 << 7) + +#define CTRL_REG4_ST_NORMAL (0 << 1) +#define CTRL_REG4_ST_TEST0 (1 << 1) +#define CTRL_REG4_ST_TEST1 (2 << 1) + +#define CTRL_REG4_FS_2G (0 << 4) +#define CTRL_REG4_FS_4G (1 << 4) +#define CTRL_REG4_FS_8G (2 << 4) +#define CTRL_REG4_FS_16G (3 << 4) + +// CTRL_REG5 + +// 4D enable: in INT2 enable on pin 4D detection, while taking the interrupt2 in the configuration register 6D set 1. +#define CTRL_REG5_D4D_INT2 (1 << 0) +// Latch Interrupt2 The interrupt response specified on the configuration register. Interrupt by read 2 The configuration +// register can clear the corresponding interrupt latch signal. Defaults: 0 (0: Do not latch the interrupt signal; 1: Latch interrupt +// signal) +#define CTRL_REG5_LIR_INT2 (1 << 1) +// 4D enable: in INT1 enable on pin 4D detection, while taking the interrupt1 in the configuration register 6D set 1. +#define CTRL_REG5_D4D_INT1 (1 << 2) +// Latch Interrupt1 The interrupt response specified on the configuration register. Interrupt by read 1 The configuration +// register can clear the corresponding interrupt latch signal. Defaults: 0 (0: Do not latch the interrupt signal; 1: Latch interrupt +// signal) +#define CTRL_REG5_LIR_INT1 (1 << 3) +// FIFO Enable. Defaults: 0. (0: FIFO prohibit; 1: FIFO Enable) +#define CTRL_REG5_FIFO_EN (1 << 6) +// Override trim value. Defaults: 0. (0: normal mode; 1: Overload trim value) +#define CTRL_REG5_BOOT (1 << 7) + +// CTRL_REG6 + +#define CTRL_REG6_H_LACTIVE (1 << 1) // 0: High level trigger interrupt; 1: Low level trigger interrupt +#define CTRL_REG6_BOOT_I2 (1 << 4) // BOOT status is INT2 superior. Defaults: 0 (0: prohibit; 1: Enable) +#define CTRL_REG6_I2_AOI2 (1 << 5) // Enable interrupt function 2 on interrupt pin 2. Defaults: 0 (0: prohibit; 1: Enable) +#define CTRL_REG6_I2_AOI1 (1 << 6) // Enable interrupt function 1 on interrupt pin 2. Defaults: 0 (0: prohibit; 1: Enable) +#define CTRL_REG6_I2_CLICK (1 << 7) // CLICK interrupted at INT2 superior. Defaults: 0. (0: prohibit; 1: Enable) + +// Status register + +// STATUS_REG + +// X New data for the axis arrives. Defaults: 0 (0: X The new data of the axis has not been converted; 1: X Axis new data conversion +// completed) +#define STATUS_REG_XDA (1 << 0) +// Y New data for the axis arrives. Defaults: 0 (0: Y The new data of the axis has not been converted; 1: Y Axis new data conversion +// completed) +#define STATUS_REG_YDA (1 << 1) +// Z New data for the axis arrives. Defaults: 0 (0: Z The new data of the axis has not been converted; 1: Z Axis new data conversion +// completed) +#define STATUS_REG_ZDA (1 << 2) +// X, Y and Z The new data of the three axes are all converted. Defaults: 0 (0: The data of at least one of the three axes has +// not been converted; 1: The new data of the three axes are all converted) +#define STATUS_REG_ZYXDA (1 << 3) +// X The new data of the axis has overwritten the old data. Defaults: 0. (0: X The new data of the axis has not overwritten the +// old data; 1: X The new data of the axis overwrites the old data) +#define STATUS_REG_XOR (1 << 4) +// Y The new data of the axis has overwritten the old data. Defaults: 0. (0: Y The new data of the axis has not overwritten the +// old data; 1: Y The new data of the axis overwrites the old data) +#define STATUS_REG_YOR (1 << 5) +// Z The new data of the axis has overwritten the old data. Defaults: 0. (0: Z The new data of the axis has not overwritten the +// old data; 1: Z The new data of the axis overwrites the old data) +#define STATUS_REG_ZOR (1 << 6) +// X, Y and Z At least one of the new data on the three axes has overwritten the old data. Defaults: 0 .(0: The new data of none +// of the three axes overwrites the old data; 1: The new data of at least one of the three axes has overwritten the old data) +#define STATUS_REG_ZYXOR (1 << 7) + +// FIFO configuration + +// FIFO_CTRL_REG + +#define FIFO_CTRL_REG_BYPASS (0 << 6) // Bypass mode +#define FIFO_CTRL_REG_FIFO (1 << 6) // FIFO mode +#define FIFO_CTRL_REG_STREAM (2 << 6) // Stream mode +#define FIFO_CTRL_REG_STREAM_TO_FIFO (3 << 6) // Stream to FIFO mode + +// FIFO_SRC_REG + +#define FIFO_SRC_REG_FSS_MASK 0x1F + +#define FIFO_SRC_REG_FSS0 (1 << 0) // Contains the current number of unread samples stored in the FIFO buffer +#define FIFO_SRC_REG_FSS1 (1 << 1) +#define FIFO_SRC_REG_FSS2 (1 << 2) +#define FIFO_SRC_REG_FSS3 (1 << 3) +#define FIFO_SRC_REG_FSS4 (1 << 4) +// Set high when all FIFO samples have been read and the FIFO is empty +#define FIFO_SRC_REG_EMPTY (1 << 5) +// Set high when the FIFO buffer is full, which means that the FIFO buffer contains 32 unread samples +#define FIFO_SRC_REG_OVRN_FIFO (1 << 6) +#define FIFO_SRC_REG_WTM (1 << 7) // Set high when FIFO content exceeds watermark level + +// Interrupt configuration + +// INT1_CFG + +// X Axis low event interrupt or Z Axis Orientation Detection Interrupt Enable. Defaults: 0 (0: disable interrupt; 1: enable interrupt) +#define INT1_CFG_XLIE_XDOWNE (1 << 0) +// X Axis high event interrupt or Z Axis Orientation Detection Interrupt Enable. Defaults: 0 (0: disable interrupt; 1: enable interrupt) +#define INT1_CFG_XHIE_XUPE (1 << 1) +// Y Axis low event interrupt or Z Axis Orientation Detection Interrupt Enable. Defaults: 0 (0: disable interrupt; 1: enable interrupt) +#define INT1_CFG_YLIE_YDOWNE (1 << 2) +// Y Axis high event interrupt or Z Axis Orientation Detection Interrupt Enable. Defaults: 0 (0: disable interrupt; 1: enable interrupt) +#define INT1_CFG_YHIE_YUPE (1 << 3) +// Z Axis low event interrupt or Z Axis Orientation Detection Interrupt Enable. Defaults: 0 (0: disable interrupt; 1: enable interrupt) +#define INT1_CFG_ZLIE_XDOWNE (1 << 4) +// Z Axis high event interrupt or Z Axis Orientation Detection Interrupt Enable. Defaults: 0 (0: disable interrupt; 1: enable interrupt) +#define INT1_CFG_ZHIE_ZUPE (1 << 5) +// 6 The direction detection function is enabled. Defaults: 0. Refer to "Interrupt Mode" +#define INT1_CFG_6D (1 << 6) +// and/or interrupt events. Defaults: 0. Refer to "Interrupt Mode" +#define INT1_CFG_AOI (1 << 7) + +#define INT1_CFG_6D_AOI_OR_INT_EVENT (0 << 6) // or interrupt event +#define INT1_CFG_6D_AOI_6D_MOTION (1 << 6) // 6 direction motion recognition +#define INT1_CFG_6D_AOI_AND_INT_EVENT (2 << 6) // and interrupt event +#define INT1_CFG_6D_AOI_6D_POSITION (3 << 6) // 6 direction position detection + +// INT1_SOURCE + +#define INT1_SOURCE_XL (1 << 0) // X axis low. Defaults: 0. (0: no interruption, 1: X Axis low event has been generated) +#define INT1_SOURCE_XH (1 << 1) // X axis high. Defaults: 0. (0: no interruption, 1: X Axis high event has been generated) +#define INT1_SOURCE_YL (1 << 2) // Y axis low. Defaults: 0. (0: no interruption, 1: Y Axis low event has been generated) +#define INT1_SOURCE_YH (1 << 3) // Y axis high. Defaults: 0. (0: no interruption, 1: Y Axis high event has been generated) +#define INT1_SOURCE_ZL (1 << 4) // Z axis low. Defaults: 0. (0: no interruption, 1: Z Axis low event has been generated) +#define INT1_SOURCE_ZH (1 << 5) // Z axis high. Defaults: 0. (0: no interruption, 1: Z Axis high event has been generated) +// Interrupt activation. Defaults: 0. (0: Interrupt is not generated; 1: one or more interrupts have been generated) +#define INT1_SOURCE_IA (1 << 6) + +// INT1_THS + +#define INT1_THS_TH0 (1 << 0) // Interrupt 1 threshold. Defaults: 000 0000. Units: 16mg @ FS=2g, 32mg @ FS=4g, 64mg @ FS=8g, 128mg @ FS=16g +#define INT1_THS_TH1 (1 << 1) +#define INT1_THS_TH2 (1 << 2) +#define INT1_THS_TH3 (1 << 3) +#define INT1_THS_TH4 (1 << 4) +#define INT1_THS_TH5 (1 << 5) +#define INT1_THS_TH6 (1 << 6) + +// INT2_DURATION + +// Duration count value. Defaults: 000 0000. set recognized interrupt The minimum duration of the event. The maximum time and +// time step of the duration register is ODR for the clock. +#define INT1_DURATION_D0 (1 << 0) +#define INT1_DURATION_D1 (1 << 1) +#define INT1_DURATION_D2 (1 << 2) +#define INT1_DURATION_D3 (1 << 3) +#define INT1_DURATION_D4 (1 << 4) +#define INT1_DURATION_D5 (1 << 5) +#define INT1_DURATION_D6 (1 << 6) + +// INT2_CFG +// X Axis low event interrupt or Z Axis Orientation Detection Interrupt Enable. Defaults: 0 (0: disable interrupt; 1: enable interrupt) +#define INT2_CFG_XLIE_XDOWNE (1 << 0) +// X Axis high event interrupt or Z Axis Orientation Detection Interrupt Enable. Defaults: 0 (0: disable interrupt; 1: enable interrupt) +#define INT2_CFG_XHIE_XUPE (1 << 1) +// Y Axis low event interrupt or Z Axis Orientation Detection Interrupt Enable. Defaults: 0 (0: disable interrupt; 1: enable interrupt) +#define INT2_CFG_YLIE_YDOWNE (1 << 2) +// Y Axis high event interrupt or Z Axis Orientation Detection Interrupt Enable. Defaults: 0 (0: disable interrupt; 1: enable interrupt) +#define INT2_CFG_YHIE_YUPE (1 << 3) +// Z Axis low event interrupt or Z Axis Orientation Detection Interrupt Enable. Defaults: 0 (0: disable interrupt; 1: enable interrupt) +#define INT2_CFG_ZLIE_XDOWNE (1 << 4) +// Z Axis high event interrupt or Z Axis Orientation Detection Interrupt Enable. Defaults: 0 (0: disable interrupt; 1: enable interrupt) +#define INT2_CFG_ZHIE_ZUPE (1 << 5) +// 6 The direction detection function is enabled. Defaults: 0. Refer to "Interrupt Mode" +#define INT2_CFG_6D (1 << 6) +// and/or interrupt events. Defaults: 0. Refer to "Interrupt Mode" +#define INT2_CFG_AOI (1 << 7) + +#define INT2_CFG_6D_AOI_OR_INT_EVENT (0 << 6) // or interrupt event +#define INT2_CFG_6D_AOI_6D_MOTION (1 << 6) // 6 direction motion recognition +#define INT2_CFG_6D_AOI_AND_INT_EVENT (2 << 6) // and interrupt event +#define INT2_CFG_6D_AOI_6D_POSITION (3 << 6) // 6 direction position detection + +// INT2_SOURCE + +#define INT2_SOURCE_XL (1 << 0) // X axis low. Defaults: 0. (0: no interruption, 1: X Axis low event has been generated) +#define INT2_SOURCE_XH (1 << 1) // X axis high. Defaults: 0. (0: no interruption, 1: X Axis high event has been generated) +#define INT2_SOURCE_YL (1 << 2) // Y axis low. Defaults: 0. (0: no interruption, 1: Y Axis low event has been generated) +#define INT2_SOURCE_YH (1 << 3) // Y axis high. Defaults: 0. (0: no interruption, 1: Y Axis high event has been generated) +#define INT2_SOURCE_ZL (1 << 4) // Z axis low. Defaults: 0. (0: no interruption, 1: Z Axis low event has been generated) +#define INT2_SOURCE_ZH (1 << 5) // Z axis high. Defaults: 0. (0: no interruption, 1: Z Axis high event has been generated) +// Interrupt activation. Defaults: 0. (0: Interrupt is not generated; 1: one or more interrupts have been generated) +#define INT2_SOURCE_IA (1 << 6) + +// INT2_THS + +#define INT2_THS_TH0 (1 << 0) // Interrupt 1 threshold. Defaults: 000 0000. Units: 16mg @ FS=2g, 32mg @ FS=4g, 64mg @ FS=8g, 128mg @ FS=16g +#define INT2_THS_TH1 (1 << 1) +#define INT2_THS_TH2 (1 << 2) +#define INT2_THS_TH3 (1 << 3) +#define INT2_THS_TH4 (1 << 4) +#define INT2_THS_TH5 (1 << 5) +#define INT2_THS_TH6 (1 << 6) + +// INT2_DURATION + +// Duration count value. Defaults: 000 0000. set recognized interrupt The minimum duration of the event. The maximum time and +// time step of the duration register is ODR for the clock. +#define INT2_DURATION_D0 (1 << 0) +#define INT2_DURATION_D1 (1 << 1) +#define INT2_DURATION_D2 (1 << 2) +#define INT2_DURATION_D3 (1 << 3) +#define INT2_DURATION_D4 (1 << 4) +#define INT2_DURATION_D5 (1 << 5) +#define INT2_DURATION_D6 (1 << 6) + +// Click configuration + +// CLICK_CFG + +// Enable interrupt single tap on X axis. Default value: 0. (0: disable interrupt request; 1: enable interrupt request on +// measured accel. value higher than preset threshold) +#define CLICK_CFG_XS (1 << 0) +// Enable interrupt double tap on X axis. Default value: 0. (0: disable interrupt request; 1: enable interrupt request on +// measured accel. value higher than preset threshold) +#define CLICK_CFG_XD (1 << 1) +// Enable interrupt single tap on Y axis. Default value: 0. (0: disable interrupt request; 1: enable interrupt request on +// measured accel. value higher than preset threshold) +#define CLICK_CFG_YS (1 << 2) +// Enable interrupt double tap on Y axis. Default value: 0. (0: disable interrupt request; 1: enable interrupt request on +// measured accel. value higher than preset threshold) +#define CLICK_CFG_YD (1 << 3) +// Enable interrupt single tap on Z axis. Default value: 0. (0: disable interrupt request; 1: enable interrupt request on +// measured accel. value higher than preset threshold) +#define CLICK_CFG_ZS (1 << 4) +// Enable interrupt double tap on Z axis. Default value: 0. (0: disable interrupt request; 1: enable interrupt request on +// measured accel. value higher than preset threshold) +#define CLICK_CFG_ZD (1 << 5) + +// CLICK_SRC + +#define CLICK_SRC_X (1 << 0) // X Click-Click detection. Default value: 0. (0: no interrupt, 1: X High event has occurred) +#define CLICK_SRC_Y (1 << 1) // Y Click-Click detection. Default value: 0. (0: no interrupt, 1: Y High event has occurred) +#define CLICK_SRC_Z (1 << 2) // Z Click-Click detection. Default value: 0. (0: no interrupt, 1: Z High event has occurred) +#define CLICK_SRC_SIGN (1 << 3) // Click-Click Sign. 0: positive detection, 1: negative detection +// Single Click-Click enable. Default value: 0. (0:Single Click-Click detection disable, 1: single Click-Click detection enable) +#define CLICK_SRC_SCLICK (1 << 4) +// Single Click-Click enable. Default value: 0. (0:Single Click-Click detection disable, 1: single Click-Click detection enable) +#define CLICK_SRC_DCLICK (1 << 5) +// Interrupt active. Default value: 0. (0: no interrupt has been generated; 1: one or more interrupts have been generated) +#define CLICK_SRC_IA (1 << 6) + +// CLICK_THS + +#define CLICK_THS_TH0 (1 << 0) // Click-Click threshold. Default value: 000 0000 +#define CLICK_THS_TH1 (1 << 1) +#define CLICK_THS_TH2 (1 << 2) +#define CLICK_THS_TH3 (1 << 3) +#define CLICK_THS_TH4 (1 << 4) +#define CLICK_THS_TH5 (1 << 5) +#define CLICK_THS_TH6 (1 << 6) +// If the LIR_Click bit is not set, the interrupt is kept high for the duration of the latency window. If the LIR_Click bit is +// set, the interrupt is kept high until CLICK_SRC (39h) is read +#define CLICK_THS_LIR_CLICK (1 << 7) + +// TIME_LIMIT + +#define CLICK_TIME_LIMIT_TLI0 (1 << 0) // Click-Click Time Limit. Default value: 000 0000 +#define CLICK_TIME_LIMIT_TLI1 (1 << 1) +#define CLICK_TIME_LIMIT_TLI2 (1 << 2) +#define CLICK_TIME_LIMIT_TLI3 (1 << 3) +#define CLICK_TIME_LIMIT_TLI4 (1 << 4) +#define CLICK_TIME_LIMIT_TLI5 (1 << 5) +#define CLICK_TIME_LIMIT_TLI6 (1 << 6) + +// TIME_LATENCY + +#define CLICK_TIME_LATENCY_TLA0 (1 << 0) // Click-Click Time Latency. Default value: 000 0000 +#define CLICK_TIME_LATENCY_TLA1 (1 << 1) +#define CLICK_TIME_LATENCY_TLA2 (1 << 2) +#define CLICK_TIME_LATENCY_TLA3 (1 << 3) +#define CLICK_TIME_LATENCY_TLA4 (1 << 4) +#define CLICK_TIME_LATENCY_TLA5 (1 << 5) +#define CLICK_TIME_LATENCY_TLA6 (1 << 6) +#define CLICK_TIME_LATENCY_TLA7 (1 << 7) + +// TIME_WINDOW + +#define CLICK_TIME_WINDOW_TW0 (1 << 0) // Click-Click Time Window +#define CLICK_TIME_WINDOW_TW1 (1 << 1) +#define CLICK_TIME_WINDOW_TW2 (1 << 2) +#define CLICK_TIME_WINDOW_TW3 (1 << 3) +#define CLICK_TIME_WINDOW_TW4 (1 << 4) +#define CLICK_TIME_WINDOW_TW5 (1 << 5) +#define CLICK_TIME_WINDOW_TW6 (1 << 6) +#define CLICK_TIME_WINDOW_TW7 (1 << 7) + +// Active configuration + +// ACT_THS + +// Sleep to wake, return to Sleep activation threshold in Low power mode (1LSb = 16mg @FS=2g, 1LSb = 32 mg @FS=4g, 1LSb = 62 mg @FS=8g, 1LSb +// = 186 mg @FS=16g) +#define ACT_THS_ACTH0 (1 << 0) +#define ACT_THS_ACTH1 (1 << 1) +#define ACT_THS_ACTH2 (1 << 2) +#define ACT_THS_ACTH3 (1 << 3) +#define ACT_THS_ACTH4 (1 << 4) +#define ACT_THS_ACTH5 (1 << 5) +#define ACT_THS_ACTH6 (1 << 6) + +// ACT_DUR + +#define ACT_DUR_ACTD0 (1 << 0) // Sleep to Wake, Return to Sleep duration (1LSb = (8*1[LSb]+1)/ODR) +#define ACT_DUR_ACTD1 (1 << 1) +#define ACT_DUR_ACTD2 (1 << 2) +#define ACT_DUR_ACTD3 (1 << 3) +#define ACT_DUR_ACTD4 (1 << 4) +#define ACT_DUR_ACTD5 (1 << 5) +#define ACT_DUR_ACTD6 (1 << 6) +#define ACT_DUR_ACTD7 (1 << 7) diff --git a/src/main.cpp b/src/main.cpp index ad7a07dc98..cc26f4b4fc 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -26,7 +26,6 @@ #include #include #include -#include #include "BootloaderVersion.h" #include "components/battery/BatteryController.h" @@ -58,7 +57,6 @@ Pinetime::Logging::DummyLogger logger; #endif static constexpr uint8_t touchPanelTwiAddress = 0x15; -static constexpr uint8_t motionSensorTwiAddress = 0x18; static constexpr uint8_t heartRateSensorTwiAddress = 0x44; Pinetime::Drivers::SpiMaster spi {Pinetime::Drivers::SpiMaster::SpiModule::SPI0, @@ -90,7 +88,17 @@ Pinetime::Drivers::Cst816S touchPanel {twiMaster, touchPanelTwiAddress}; #endif Pinetime::Components::LittleVgl lvgl {lcd, touchPanel}; +#if (defined DRIVER_ACC_SC7A20) + #include +static constexpr uint8_t motionSensorTwiAddress = 0x18; +Pinetime::Drivers::SC7A20 motionSensor {twiMaster, motionSensorTwiAddress}; +#else +// Assume PineTime (DRIVER_ACC_BMA421) + #include +static constexpr uint8_t motionSensorTwiAddress = 0x18; Pinetime::Drivers::Bma421 motionSensor {twiMaster, motionSensorTwiAddress}; +#endif + Pinetime::Drivers::Hrs3300 heartRateSensor {twiMaster, heartRateSensorTwiAddress}; TimerHandle_t debounceTimer; diff --git a/src/systemtask/SystemTask.cpp b/src/systemtask/SystemTask.cpp index 4f58ea6d73..09e92abcc7 100644 --- a/src/systemtask/SystemTask.cpp +++ b/src/systemtask/SystemTask.cpp @@ -62,7 +62,7 @@ SystemTask::SystemTask(Drivers::SpiMaster& spi, Pinetime::Controllers::MotorController& motorController, Pinetime::Drivers::Hrs3300& heartRateSensor, Pinetime::Controllers::MotionController& motionController, - Pinetime::Drivers::Bma421& motionSensor, + Pinetime::Drivers::AccelerationSensor& motionSensor, Controllers::Settings& settingsController, Pinetime::Controllers::HeartRateController& heartRateController, Pinetime::Applications::DisplayApp& displayApp, @@ -477,11 +477,6 @@ void SystemTask::UpdateMotion() { return; } - if (state == SystemTaskState::Sleeping && !(settingsController.isWakeUpModeOn(Pinetime::Controllers::Settings::WakeUpMode::RaiseWrist) || - settingsController.isWakeUpModeOn(Pinetime::Controllers::Settings::WakeUpMode::Shake))) { - return; - } - if (stepCounterMustBeReset) { motionSensor.ResetStepCounter(); stepCounterMustBeReset = false; @@ -489,8 +484,9 @@ void SystemTask::UpdateMotion() { auto motionValues = motionSensor.Process(); - motionController.IsSensorOk(motionSensor.IsOk()); - motionController.Update(motionValues.x, motionValues.y, motionValues.z, motionValues.steps); + motionController.IsSensorOk(motionSensor.IsInitialized()); + motionController + .Update(motionValues.steps, motionValues.x, motionValues.y, motionValues.z, motionValues.samples, motionValues.samples_length); if (settingsController.GetNotificationStatus() != Controllers::Settings::Notification::Sleep) { if ((settingsController.isWakeUpModeOn(Pinetime::Controllers::Settings::WakeUpMode::RaiseWrist) && diff --git a/src/systemtask/SystemTask.h b/src/systemtask/SystemTask.h index d1e4a004f9..1439e3a80a 100644 --- a/src/systemtask/SystemTask.h +++ b/src/systemtask/SystemTask.h @@ -8,7 +8,7 @@ #include #include #include -#include +#include #include #include @@ -70,7 +70,7 @@ namespace Pinetime { Pinetime::Controllers::MotorController& motorController, Pinetime::Drivers::Hrs3300& heartRateSensor, Pinetime::Controllers::MotionController& motionController, - Pinetime::Drivers::Bma421& motionSensor, + Pinetime::Drivers::AccelerationSensor& motionSensor, Controllers::Settings& settingsController, Pinetime::Controllers::HeartRateController& heartRateController, Pinetime::Applications::DisplayApp& displayApp, @@ -115,7 +115,7 @@ namespace Pinetime { Pinetime::Controllers::NotificationManager& notificationManager; Pinetime::Controllers::MotorController& motorController; Pinetime::Drivers::Hrs3300& heartRateSensor; - Pinetime::Drivers::Bma421& motionSensor; + Pinetime::Drivers::AccelerationSensor& motionSensor; Pinetime::Controllers::Settings& settingsController; Pinetime::Controllers::HeartRateController& heartRateController; Pinetime::Controllers::MotionController& motionController;