From 60053a20d10ba75c9797da5ac75d64c83ac5373e Mon Sep 17 00:00:00 2001
From: Graham Jones <grahamjones139@gmail.com>
Date: Fri, 5 Jan 2024 19:49:40 +0000
Subject: [PATCH 1/7] Update Bma421 acelerometer driver to return values in
 milli-g rather than raw counts.

---
 src/drivers/Bma421.cpp | 19 +++++++++++++++++--
 src/drivers/Bma421.h   |  5 +++++
 2 files changed, 22 insertions(+), 2 deletions(-)

diff --git a/src/drivers/Bma421.cpp b/src/drivers/Bma421.cpp
index 84d76ab3c0..3656dc50cf 100644
--- a/src/drivers/Bma421.cpp
+++ b/src/drivers/Bma421.cpp
@@ -24,6 +24,17 @@ namespace {
   }
 }
 
+// Scale factors to convert accelerometer counts to milli-g
+// from datasheet: https://files.pine64.org/doc/datasheet/pinetime/BST-BMA421-FL000.pdf
+// The array index to use is stored in accel_conf.range
+const short Bma421::accelScaleFactors[] = {
+  1024,  // LSB/g +/- 2g range
+  512,   // LSB/g +/- 4g range 
+  256,   // LSB/g +/- 8g range
+  128    // LSB/g +/- 16g range
+};
+
+
 Bma421::Bma421(TwiMaster& twiMaster, uint8_t twiAddress) : twiMaster {twiMaster}, deviceAddress {twiAddress} {
   bma.intf = BMA4_I2C_INTF;
   bma.bus_read = user_i2c_read;
@@ -74,7 +85,6 @@ void Bma421::Init() {
   if (ret != BMA4_OK)
     return;
 
-  struct bma4_accel_config accel_conf;
   accel_conf.odr = BMA4_OUTPUT_DATA_RATE_100HZ;
   accel_conf.range = BMA4_ACCEL_RANGE_2G;
   accel_conf.bandwidth = BMA4_ACCEL_NORMAL_AVG4;
@@ -102,8 +112,13 @@ void Bma421::Write(uint8_t registerAddress, const uint8_t* data, size_t size) {
 Bma421::Values Bma421::Process() {
   if (not isOk)
     return {};
+  struct bma4_accel rawData;
   struct bma4_accel data;
-  bma4_read_accel_xyz(&data, &bma);
+  bma4_read_accel_xyz(&rawData, &bma);
+
+  data.x = 1000 * rawData.x / accelScaleFactors[accel_conf.range];
+  data.y = 1000 * rawData.y / accelScaleFactors[accel_conf.range];
+  data.z = 1000 * rawData.z / accelScaleFactors[accel_conf.range];
 
   uint32_t steps = 0;
   bma423_step_counter_output(&steps, &bma);
diff --git a/src/drivers/Bma421.h b/src/drivers/Bma421.h
index fb83251449..339a557634 100644
--- a/src/drivers/Bma421.h
+++ b/src/drivers/Bma421.h
@@ -9,6 +9,10 @@ namespace Pinetime {
     public:
       enum class DeviceTypes : uint8_t { Unknown, BMA421, BMA425 };
 
+      // Scale factors to convert accelerometer counts to milli-g
+      // The array values are initialised in Bma421.cpp
+      static const short accelScaleFactors[];
+
       struct Values {
         uint32_t steps;
         int16_t x;
@@ -41,6 +45,7 @@ namespace Pinetime {
       TwiMaster& twiMaster;
       uint8_t deviceAddress = 0x18;
       struct bma4_dev bma;
+      struct bma4_accel_config accel_conf;   // Store the device configuration for later reference.
       bool isOk = false;
       bool isResetOk = false;
       DeviceTypes deviceType = DeviceTypes::Unknown;

From 2eee78264e43f15e63a056ba06fc11d0725acd4f Mon Sep 17 00:00:00 2001
From: Graham Jones <grahamjones139@gmail.com>
Date: Fri, 5 Jan 2024 19:50:46 +0000
Subject: [PATCH 2/7] Update Motion screen to display values in milli-g rather
 than scaled.

---
 src/displayapp/apps/CMakeLists.txt | 2 +-
 src/displayapp/screens/Motion.cpp  | 8 ++++----
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/src/displayapp/apps/CMakeLists.txt b/src/displayapp/apps/CMakeLists.txt
index ddf95171fb..6778001f5f 100644
--- a/src/displayapp/apps/CMakeLists.txt
+++ b/src/displayapp/apps/CMakeLists.txt
@@ -1,7 +1,7 @@
 if(DEFINED ENABLE_USERAPPS)
     set(USERAPP_TYPES ${ENABLE_USERAPPS} CACHE STRING "List of user apps to build into the firmware")
 else ()
-    set(USERAPP_TYPES "Apps::Navigation, Apps::StopWatch, Apps::Alarm, Apps::Timer, Apps::Steps, Apps::HeartRate, Apps::Music, Apps::Paint, Apps::Paddle, Apps::Twos, Apps::Metronome" CACHE STRING "List of user apps to build into the firmware")
+    set(USERAPP_TYPES "Apps::Navigation, Apps::StopWatch, Apps::Alarm, Apps::Timer, Apps::Steps, Apps::Motion, Apps::HeartRate, Apps::Music, Apps::Paint, Apps::Paddle, Apps::Twos, Apps::Metronome" CACHE STRING "List of user apps to build into the firmware")
 endif ()
 
 add_library(infinitime_apps INTERFACE)
diff --git a/src/displayapp/screens/Motion.cpp b/src/displayapp/screens/Motion.cpp
index 87c55eea9d..ecbed317c7 100644
--- a/src/displayapp/screens/Motion.cpp
+++ b/src/displayapp/screens/Motion.cpp
@@ -53,9 +53,9 @@ void Motion::Refresh() {
   lv_label_set_text_fmt(labelStep, "Steps %lu", motionController.NbSteps());
 
   lv_label_set_text_fmt(label,
-                        "X #FF0000 %d# Y #00B000 %d# Z #FFFF00 %d#",
-                        motionController.X() / 0x10,
-                        motionController.Y() / 0x10,
-                        motionController.Z() / 0x10);
+                        "X #FF0000 %d# Y #00B000 %d# Z #FFFF00 %d# mg",
+                        motionController.X(),
+                        motionController.Y(),
+                        motionController.Z());
   lv_obj_align(label, nullptr, LV_ALIGN_IN_TOP_MID, 0, 10);
 }

From c261579e954a6647daa89b079b350de3548b39ae Mon Sep 17 00:00:00 2001
From: Graham Jones <grahamjones139@gmail.com>
Date: Sun, 7 Jan 2024 16:13:37 +0000
Subject: [PATCH 3/7] Changed output from to 'binary milli-g' (scaled to 1024
 rather than 1000) - this means that the values for the default range of +/-2
 g are unchanged, and all ranges give something very close to milli-g - see
 discussion fof pull request #1950 for information.
 https://github.com/InfiniTimeOrg/InfiniTime/pull/1950

---
 src/drivers/Bma421.cpp | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/src/drivers/Bma421.cpp b/src/drivers/Bma421.cpp
index 3656dc50cf..89a8bac0c7 100644
--- a/src/drivers/Bma421.cpp
+++ b/src/drivers/Bma421.cpp
@@ -116,9 +116,13 @@ Bma421::Values Bma421::Process() {
   struct bma4_accel data;
   bma4_read_accel_xyz(&rawData, &bma);
 
-  data.x = 1000 * rawData.x / accelScaleFactors[accel_conf.range];
-  data.y = 1000 * rawData.y / accelScaleFactors[accel_conf.range];
-  data.z = 1000 * rawData.z / accelScaleFactors[accel_conf.range];
+  // Scale the measured ADC counts to units of 'binary milli-g'
+  // where 1g = 1024 'binary milli-g' units.
+  // See https://github.com/InfiniTimeOrg/InfiniTime/pull/1950 for
+  // discussion of why we opted for scaling to 1024 rather than 1000.
+  data.x = 1024 * rawData.x / accelScaleFactors[accel_conf.range];
+  data.y = 1024 * rawData.y / accelScaleFactors[accel_conf.range];
+  data.z = 1024 * rawData.z / accelScaleFactors[accel_conf.range];
 
   uint32_t steps = 0;
   bma423_step_counter_output(&steps, &bma);

From 99cdb8eced124775a12ebe75dcf15748be35c14c Mon Sep 17 00:00:00 2001
From: Graham Jones <grahamjones139@gmail.com>
Date: Sun, 7 Jan 2024 22:06:06 +0000
Subject: [PATCH 4/7] Update src/drivers/Bma421.cpp

Changes to array declaration as suggested during pull request review.

Co-authored-by: FintasticMan <finlay.neon.kid@gmail.com>
---
 src/drivers/Bma421.cpp | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/src/drivers/Bma421.cpp b/src/drivers/Bma421.cpp
index 89a8bac0c7..d640df74a0 100644
--- a/src/drivers/Bma421.cpp
+++ b/src/drivers/Bma421.cpp
@@ -27,11 +27,11 @@ namespace {
 // Scale factors to convert accelerometer counts to milli-g
 // from datasheet: https://files.pine64.org/doc/datasheet/pinetime/BST-BMA421-FL000.pdf
 // The array index to use is stored in accel_conf.range
-const short Bma421::accelScaleFactors[] = {
-  1024,  // LSB/g +/- 2g range
-  512,   // LSB/g +/- 4g range 
-  256,   // LSB/g +/- 8g range
-  128    // LSB/g +/- 16g range
+constexpr int16_t accelScaleFactors[] = {
+  [BMA4_ACCEL_RANGE_2G] = 1024,  // LSB/g +/- 2g range
+  [BMA4_ACCEL_RANGE_4G] = 512,   // LSB/g +/- 4g range 
+  [BMA4_ACCEL_RANGE_8G] = 256,   // LSB/g +/- 8g range
+  [BMA4_ACCEL_RANGE_16G] = 128   // LSB/g +/- 16g range
 };
 
 

From 7f6ea30556da8ecdf5d50ef8eae3865bd8e087df Mon Sep 17 00:00:00 2001
From: Graham Jones <grahamjones139@gmail.com>
Date: Mon, 8 Jan 2024 21:22:26 +0000
Subject: [PATCH 5/7] Moved scale factors out of class and into anonymous
 namespace

---
 src/drivers/Bma421.cpp | 21 ++++++++++-----------
 src/drivers/Bma421.h   |  4 ----
 2 files changed, 10 insertions(+), 15 deletions(-)

diff --git a/src/drivers/Bma421.cpp b/src/drivers/Bma421.cpp
index d640df74a0..eb8831e0b1 100644
--- a/src/drivers/Bma421.cpp
+++ b/src/drivers/Bma421.cpp
@@ -22,18 +22,17 @@ namespace {
   void user_delay(uint32_t period_us, void* /*intf_ptr*/) {
     nrf_delay_us(period_us);
   }
-}
-
-// Scale factors to convert accelerometer counts to milli-g
-// from datasheet: https://files.pine64.org/doc/datasheet/pinetime/BST-BMA421-FL000.pdf
-// The array index to use is stored in accel_conf.range
-constexpr int16_t accelScaleFactors[] = {
-  [BMA4_ACCEL_RANGE_2G] = 1024,  // LSB/g +/- 2g range
-  [BMA4_ACCEL_RANGE_4G] = 512,   // LSB/g +/- 4g range 
-  [BMA4_ACCEL_RANGE_8G] = 256,   // LSB/g +/- 8g range
-  [BMA4_ACCEL_RANGE_16G] = 128   // LSB/g +/- 16g range
-};
 
+  // Scale factors to convert accelerometer counts to milli-g
+  // from datasheet: https://files.pine64.org/doc/datasheet/pinetime/BST-BMA421-FL000.pdf
+  // The array index to use is stored in accel_conf.range
+  constexpr int16_t accelScaleFactors[] = {
+    [BMA4_ACCEL_RANGE_2G] = 1024,  // LSB/g +/- 2g range
+    [BMA4_ACCEL_RANGE_4G] = 512,   // LSB/g +/- 4g range 
+    [BMA4_ACCEL_RANGE_8G] = 256,   // LSB/g +/- 8g range
+    [BMA4_ACCEL_RANGE_16G] = 128   // LSB/g +/- 16g range
+  };
+}
 
 Bma421::Bma421(TwiMaster& twiMaster, uint8_t twiAddress) : twiMaster {twiMaster}, deviceAddress {twiAddress} {
   bma.intf = BMA4_I2C_INTF;
diff --git a/src/drivers/Bma421.h b/src/drivers/Bma421.h
index 339a557634..c36350b2af 100644
--- a/src/drivers/Bma421.h
+++ b/src/drivers/Bma421.h
@@ -9,10 +9,6 @@ namespace Pinetime {
     public:
       enum class DeviceTypes : uint8_t { Unknown, BMA421, BMA425 };
 
-      // Scale factors to convert accelerometer counts to milli-g
-      // The array values are initialised in Bma421.cpp
-      static const short accelScaleFactors[];
-
       struct Values {
         uint32_t steps;
         int16_t x;

From d3f667b1d2650522b74151c3dc91e7dc02cdf0bb Mon Sep 17 00:00:00 2001
From: Graham Jones <grahamjones139@gmail.com>
Date: Wed, 10 Jan 2024 11:06:55 +0000
Subject: [PATCH 6/7] Adjusted number of spaces between the end of the code and
 start of in-line comments to keep the formatter happy

---
 src/drivers/Bma421.cpp | 8 ++++----
 src/drivers/Bma421.h   | 2 +-
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/src/drivers/Bma421.cpp b/src/drivers/Bma421.cpp
index eb8831e0b1..aff62b8df0 100644
--- a/src/drivers/Bma421.cpp
+++ b/src/drivers/Bma421.cpp
@@ -27,10 +27,10 @@ namespace {
   // from datasheet: https://files.pine64.org/doc/datasheet/pinetime/BST-BMA421-FL000.pdf
   // The array index to use is stored in accel_conf.range
   constexpr int16_t accelScaleFactors[] = {
-    [BMA4_ACCEL_RANGE_2G] = 1024,  // LSB/g +/- 2g range
-    [BMA4_ACCEL_RANGE_4G] = 512,   // LSB/g +/- 4g range 
-    [BMA4_ACCEL_RANGE_8G] = 256,   // LSB/g +/- 8g range
-    [BMA4_ACCEL_RANGE_16G] = 128   // LSB/g +/- 16g range
+    [BMA4_ACCEL_RANGE_2G] = 1024, // LSB/g +/- 2g range
+    [BMA4_ACCEL_RANGE_4G] = 512,  // LSB/g +/- 4g range
+    [BMA4_ACCEL_RANGE_8G] = 256,  // LSB/g +/- 8g range
+    [BMA4_ACCEL_RANGE_16G] = 128  // LSB/g +/- 16g range
   };
 }
 
diff --git a/src/drivers/Bma421.h b/src/drivers/Bma421.h
index c36350b2af..5269f62b79 100644
--- a/src/drivers/Bma421.h
+++ b/src/drivers/Bma421.h
@@ -41,7 +41,7 @@ namespace Pinetime {
       TwiMaster& twiMaster;
       uint8_t deviceAddress = 0x18;
       struct bma4_dev bma;
-      struct bma4_accel_config accel_conf;   // Store the device configuration for later reference.
+      struct bma4_accel_config accel_conf; // Store the device configuration for later reference.
       bool isOk = false;
       bool isResetOk = false;
       DeviceTypes deviceType = DeviceTypes::Unknown;

From f5af62f263c7346985ac7d37b55627a8fd3be6cc Mon Sep 17 00:00:00 2001
From: Graham Jones <grahamjones139@gmail.com>
Date: Sun, 11 Feb 2024 19:42:31 +0000
Subject: [PATCH 7/7] Updated MotionService documentation to specify the units
 of the returned values.

---
 doc/MotionService.md | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/doc/MotionService.md b/doc/MotionService.md
index 429794acb3..58c7e83600 100644
--- a/doc/MotionService.md
+++ b/doc/MotionService.md
@@ -21,3 +21,5 @@ The current raw motion values. This is a 3 `int16_t` array:
 - [0] : X
 - [1] : Y
 - [2] : Z
+
+The three motion values are in units of "binary milli-g", where 1g is represented by a value of 1024.