aboutsummaryrefslogtreecommitdiffstats
path: root/src/utility
diff options
context:
space:
mode:
Diffstat (limited to 'src/utility')
-rw-r--r--src/utility/CircularBuffer.h51
-rw-r--r--src/utility/DirtyValue.h39
-rw-r--r--src/utility/LinearApproximation.h41
-rw-r--r--src/utility/Math.cpp49
-rw-r--r--src/utility/Math.h10
-rw-r--r--src/utility/StaticStack.h47
6 files changed, 237 insertions, 0 deletions
diff --git a/src/utility/CircularBuffer.h b/src/utility/CircularBuffer.h
new file mode 100644
index 00000000..c8abe92e
--- /dev/null
+++ b/src/utility/CircularBuffer.h
@@ -0,0 +1,51 @@
+#pragma once
+
+#include <array>
+#include <cstddef>
+
+namespace Pinetime {
+ namespace Utility {
+ template <class T, size_t S>
+ struct CircularBuffer {
+ constexpr size_t Size() const {
+ return S;
+ }
+
+ size_t Idx() const {
+ return idx;
+ }
+
+ T& operator[](size_t n) {
+ return data[(idx + n) % S];
+ }
+
+ const T& operator[](size_t n) const {
+ return data[(idx + n) % S];
+ }
+
+ void operator++() {
+ idx++;
+ idx %= S;
+ }
+
+ void operator++(int) {
+ operator++();
+ }
+
+ void operator--() {
+ if (idx > 0) {
+ idx--;
+ } else {
+ idx = S - 1;
+ }
+ }
+
+ void operator--(int) {
+ operator--();
+ }
+
+ std::array<T, S> data;
+ size_t idx = 0;
+ };
+ }
+}
diff --git a/src/utility/DirtyValue.h b/src/utility/DirtyValue.h
new file mode 100644
index 00000000..8d5147aa
--- /dev/null
+++ b/src/utility/DirtyValue.h
@@ -0,0 +1,39 @@
+#pragma once
+
+namespace Pinetime {
+ namespace Utility {
+ template <class T>
+ class DirtyValue {
+ public:
+ DirtyValue() = default; // Use NSDMI
+
+ explicit DirtyValue(T const& v) : value {v} {
+ } // Use MIL and const-lvalue-ref
+
+ bool IsUpdated() {
+ if (this->isUpdated) {
+ this->isUpdated = false;
+ return true;
+ }
+ return false;
+ }
+
+ T const& Get() {
+ this->isUpdated = false;
+ return value;
+ } // never expose a non-const lvalue-ref
+
+ DirtyValue& operator=(const T& other) {
+ if (this->value != other) {
+ this->value = other;
+ this->isUpdated = true;
+ }
+ return *this;
+ }
+
+ private:
+ T value {}; // NSDMI - default initialise type
+ bool isUpdated {true}; // NSDMI - use brace initialisation
+ };
+ }
+}
diff --git a/src/utility/LinearApproximation.h b/src/utility/LinearApproximation.h
new file mode 100644
index 00000000..34ceb7f2
--- /dev/null
+++ b/src/utility/LinearApproximation.h
@@ -0,0 +1,41 @@
+#pragma once
+
+#include <cstddef>
+#include <array>
+
+namespace Pinetime {
+ namespace Utility {
+ // based on: https://github.com/SHristov92/LinearApproximation/blob/main/Linear.h
+ template <typename Key, typename Value, std::size_t Size>
+ class LinearApproximation {
+ using Point = struct {
+ Key key;
+ Value value;
+ };
+
+ public:
+ LinearApproximation(const std::array<Point, Size>&& sorted_points) : points {sorted_points} {
+ }
+
+ Value GetValue(Key key) const {
+ if (key <= points[0].key) {
+ return points[0].value;
+ }
+
+ for (std::size_t i = 1; i < Size; i++) {
+ const auto& p = points[i];
+ const auto& p_prev = points[i - 1];
+
+ if (key < p.key) {
+ return p_prev.value + (key - p_prev.key) * (p.value - p_prev.value) / (p.key - p_prev.key);
+ }
+ }
+
+ return points[Size - 1].value;
+ }
+
+ private:
+ std::array<Point, Size> points;
+ };
+ }
+}
diff --git a/src/utility/Math.cpp b/src/utility/Math.cpp
new file mode 100644
index 00000000..fee4f64a
--- /dev/null
+++ b/src/utility/Math.cpp
@@ -0,0 +1,49 @@
+#include "utility/Math.h"
+
+#include <lvgl/src/lv_misc/lv_math.h>
+
+using namespace Pinetime::Utility;
+
+#ifndef PINETIME_IS_RECOVERY
+
+int16_t Pinetime::Utility::Asin(int16_t arg) {
+ int16_t a = arg < 0 ? -arg : arg;
+
+ int16_t angle = 45;
+ int16_t low = 0;
+ int16_t high = 90;
+ while (low <= high) {
+ int16_t sinAngle = _lv_trigo_sin(angle);
+ int16_t sinAngleSub = _lv_trigo_sin(angle - 1);
+ int16_t sinAngleAdd = _lv_trigo_sin(angle + 1);
+
+ if (a >= sinAngleSub && a <= sinAngleAdd) {
+ if (a <= (sinAngleSub + sinAngle) / 2) {
+ angle--;
+ } else if (a > (sinAngle + sinAngleAdd) / 2) {
+ angle++;
+ }
+ break;
+ }
+
+ if (a < sinAngle) {
+ high = angle - 1;
+ }
+
+ else {
+ low = angle + 1;
+ }
+
+ angle = (low + high) / 2;
+ }
+
+ return arg < 0 ? -angle : angle;
+}
+
+#else
+
+int16_t Pinetime::Utility::Asin(int16_t /*arg*/) {
+ return 0;
+}
+
+#endif
diff --git a/src/utility/Math.h b/src/utility/Math.h
new file mode 100644
index 00000000..e8d190c7
--- /dev/null
+++ b/src/utility/Math.h
@@ -0,0 +1,10 @@
+#pragma once
+
+#include <cstdint>
+
+namespace Pinetime {
+ namespace Utility {
+ // returns the arcsin of `arg`. asin(-32767) = -90, asin(32767) = 90
+ int16_t Asin(int16_t arg);
+ }
+}
diff --git a/src/utility/StaticStack.h b/src/utility/StaticStack.h
new file mode 100644
index 00000000..40df9354
--- /dev/null
+++ b/src/utility/StaticStack.h
@@ -0,0 +1,47 @@
+#include <array>
+#include <cstddef>
+
+namespace Pinetime {
+ namespace Utility {
+ template <typename T, size_t N>
+ class StaticStack {
+ public:
+ T Pop();
+ void Push(T element);
+ void Reset();
+ T Top();
+
+ private:
+ std::array<T, N> elementArray;
+ // Number of elements in stack, points to the next empty slot
+ size_t stackPointer = 0;
+ };
+
+ // Returns random data when popping from empty array.
+ template <typename T, size_t N>
+ T StaticStack<T, N>::Pop() {
+ if (stackPointer > 0) {
+ stackPointer--;
+ }
+ return elementArray[stackPointer];
+ }
+
+ template <typename T, size_t N>
+ void StaticStack<T, N>::Push(T element) {
+ if (stackPointer < elementArray.size()) {
+ elementArray[stackPointer] = element;
+ stackPointer++;
+ }
+ }
+
+ template <typename T, size_t N>
+ void StaticStack<T, N>::Reset() {
+ stackPointer = 0;
+ }
+
+ template <typename T, size_t N>
+ T StaticStack<T, N>::Top() {
+ return elementArray[stackPointer - 1];
+ }
+ }
+}