summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorYilun Lin <yllin@google.com>2018-10-04 10:19:57 +0800
committerchrome-bot <chrome-bot@chromium.org>2018-10-04 12:55:53 -0700
commit315aaca9467f49bc432ef5f2de9c0e3bb56f0251 (patch)
tree3ea739aca1db340e93b9daee7958d5afc5c9f31f /test
parentece03ab4d09b157c5e6f3c4fe0446678c0d8684b (diff)
downloadchrome-ec-315aaca9467f49bc432ef5f2de9c0e3bb56f0251.tar.gz
mag_cal: Support fixed-point calculation.
Modified from floating point version. This includes changes to vec3, vec4, mat33, mat44, and mag_cal. Now fixed-point type (fp_*) functions is a function wrapper for both fixed-point and floating point version operations: * define CONFIG_FPU to use floating version mag_cal * undef CONFIG_FPU to use fixed-point version mag_cal Also, add tests for both float and fp types operations. TEST=define CONFIG_FPU; flash on reef; See ARC++ magnetmeter app moving. TEST=undef CONFIG_FPU; flash on reef; See ARC++ magnetmeter app moving. TEST=make runtests -j TEST=make buildalltests -j BUG=b:113364863 BRANCH=None Change-Id: Ie695945acb666912babb2a603e09c602a0624d44 Signed-off-by: Yilun Lin <yllin@google.com> Reviewed-on: https://chromium-review.googlesource.com/1260704 Commit-Ready: Yilun Lin <yllin@chromium.org> Tested-by: Yilun Lin <yllin@chromium.org> Reviewed-by: Nicolas Boichat <drinkcat@chromium.org>
Diffstat (limited to 'test')
-rw-r--r--test/build.mk4
-rw-r--r--test/float.tasklist17
-rw-r--r--test/fp.c319
-rw-r--r--test/fp.tasklist17
-rw-r--r--test/test_config.h10
5 files changed, 367 insertions, 0 deletions
diff --git a/test/build.mk b/test/build.mk
index b16b15e702..31cec03c9a 100644
--- a/test/build.mk
+++ b/test/build.mk
@@ -29,6 +29,8 @@ test-list-host += entropy
test-list-host += extpwr_gpio
test-list-host += fan
test-list-host += flash
+test-list-host += float
+test-list-host += fp
test-list-host += hooks
test-list-host += host_command
test-list-host += inductive_charging
@@ -124,4 +126,6 @@ usb_pd_rev30-y=usb_pd.o
utils-y=utils.o
utils_str-y=utils_str.o
vboot-y=vboot.o
+float-y=fp.o
+fp-y=fp.o
x25519-y=x25519.o
diff --git a/test/float.tasklist b/test/float.tasklist
new file mode 100644
index 0000000000..5e26d7102e
--- /dev/null
+++ b/test/float.tasklist
@@ -0,0 +1,17 @@
+/* Copyright 2018 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/**
+ * List of enabled tasks in the priority order
+ *
+ * The first one has the lowest priority.
+ *
+ * For each task, use the macro TASK_TEST(n, r, d, s) where :
+ * 'n' in the name of the task
+ * 'r' in the main routine of the task
+ * 'd' in an opaque parameter passed to the routine at startup
+ * 's' is the stack size in bytes; must be a multiple of 8
+ */
+#define CONFIG_TEST_TASK_LIST /* No test task */
diff --git a/test/fp.c b/test/fp.c
new file mode 100644
index 0000000000..296a78e4df
--- /dev/null
+++ b/test/fp.c
@@ -0,0 +1,319 @@
+/* Copyright 2018 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/*
+ * Explicitly include common.h to populate predefined macros in test_config.h
+ * early. e.g. CONFIG_FPU, which is needed in math_util.h
+ */
+#include "common.h"
+
+#include "mat33.h"
+#include "mat44.h"
+#include "math_util.h"
+#include "test_util.h"
+#include "vec3.h"
+
+#if defined(TEST_FP) && !defined(CONFIG_FPU)
+#define NORM_TOLERANCE FLOAT_TO_FP(0.01f)
+#define NORM_SQUARED_TOLERANCE FLOAT_TO_FP(0.0f)
+#define DOT_TOLERANCE FLOAT_TO_FP(0.001f)
+#define SCALAR_MUL_TOLERANCE FLOAT_TO_FP(0.005f)
+#define EIGENBASIS_TOLERANCE FLOAT_TO_FP(0.03f)
+#define LUP_TOLERANCE FLOAT_TO_FP(0.0005f)
+#define SOLVE_TOLERANCE FLOAT_TO_FP(0.0005f)
+#elif defined(TEST_FLOAT) && defined(CONFIG_FPU)
+#define NORM_TOLERANCE FLOAT_TO_FP(0.0f)
+#define NORM_SQUARED_TOLERANCE FLOAT_TO_FP(0.0f)
+#define DOT_TOLERANCE FLOAT_TO_FP(0.0f)
+#define SCALAR_MUL_TOLERANCE FLOAT_TO_FP(0.005f)
+#define EIGENBASIS_TOLERANCE FLOAT_TO_FP(0.02f)
+#define LUP_TOLERANCE FLOAT_TO_FP(0.0f)
+#define SOLVE_TOLERANCE FLOAT_TO_FP(0.0f)
+#else
+#error "No such test configuration."
+#endif
+
+#define IS_FPV3_VECTOR_EQUAL(a, b, diff) \
+ (IS_FP_EQUAL((a)[0], (b)[0], (diff)) && \
+ IS_FP_EQUAL((a)[1], (b)[1], (diff)) && \
+ IS_FP_EQUAL((a)[2], (b)[2], (diff)))
+#define IS_FP_EQUAL(a, b, diff) ((a) >= ((b)-diff) && (a) <= ((b) + diff))
+#define IS_FLOAT_EQUAL(a, b, diff) IS_FP_EQUAL(a, b, diff)
+
+static int test_fpv3_scalar_mul(void)
+{
+ const int N = 3;
+ const float s = 2.0f;
+ floatv3_t r = {1.0f, 2.0f, 4.0f};
+ /* Golden result g = s * r; */
+ const floatv3_t g = {2.0f, 4.0f, 8.0f};
+ int i;
+ fpv3_t a;
+
+ for (i = 0; i < N; ++i)
+ a[i] = FLOAT_TO_FP(r[i]);
+
+ fpv3_scalar_mul(a, FLOAT_TO_FP(s));
+
+ for (i = 0; i < N; ++i)
+ TEST_ASSERT(IS_FP_EQUAL(a[i], FLOAT_TO_FP(g[i]), 0));
+
+ return EC_SUCCESS;
+}
+
+static int test_fpv3_dot(void)
+{
+ const int N = 3;
+ int i;
+ floatv3_t a = {1.8f, 2.12f, 4.12f};
+ floatv3_t b = {3.1f, 4.3f, 5.8f};
+ /* Golden result g = dot(a, b) */
+ float g = 38.592f;
+ fpv3_t fpa, fpb;
+
+ for (i = 0; i < N; ++i) {
+ fpa[i] = FLOAT_TO_FP(a[i]);
+ fpb[i] = FLOAT_TO_FP(b[i]);
+ }
+
+ TEST_ASSERT(IS_FP_EQUAL(fpv3_dot(fpa, fpb), FLOAT_TO_FP(g),
+ DOT_TOLERANCE));
+
+ return EC_SUCCESS;
+}
+
+static int test_fpv3_norm_squared(void)
+{
+ const int N = 3;
+ int i;
+ floatv3_t a = {3.0f, 4.0f, 5.0f};
+ /* Golden result g = norm_squared(a) */
+ float g = 50.0f;
+ fpv3_t fpa;
+
+ for (i = 0; i < N; ++i)
+ fpa[i] = FLOAT_TO_FP(a[i]);
+
+ TEST_ASSERT(IS_FP_EQUAL(fpv3_norm_squared(fpa), FLOAT_TO_FP(g),
+ NORM_SQUARED_TOLERANCE));
+
+ return EC_SUCCESS;
+}
+
+static int test_fpv3_norm(void)
+{
+ const int N = 3;
+ floatv3_t a = {3.1f, 4.2f, 5.3f};
+ /* Golden result g = norm(a) */
+ float g = 7.439085483551025390625f;
+ int i;
+ fpv3_t fpa;
+
+ for (i = 0; i < N; ++i)
+ fpa[i] = FLOAT_TO_FP(a[i]);
+
+ TEST_ASSERT(
+ IS_FP_EQUAL(fpv3_norm(fpa), FLOAT_TO_FP(g), NORM_TOLERANCE));
+
+ return EC_SUCCESS;
+}
+
+static int test_mat33_fp_init_zero(void)
+{
+ const int N = 3;
+ int i, j;
+ mat33_fp_t a;
+
+ for (i = 0; i < N; ++i)
+ for (j = 0; j < N; ++j)
+ a[i][j] = FLOAT_TO_FP(55.66f);
+
+ mat33_fp_init_zero(a);
+
+ for (i = 0; i < N; ++i)
+ for (j = 0; j < N; ++j)
+ TEST_ASSERT(a[i][j] == FLOAT_TO_FP(0.0f));
+
+ return EC_SUCCESS;
+}
+
+static int test_mat33_fp_init_diagonal(void)
+{
+ const int N = 3;
+ int i, j;
+ mat33_fp_t a;
+ fp_t v = FLOAT_TO_FP(-3.45f);
+
+ for (i = 0; i < N; ++i)
+ for (j = 0; j < N; ++j)
+ a[i][j] = FLOAT_TO_FP(55.66f);
+
+ mat33_fp_init_diagonal(a, v);
+
+ for (i = 0; i < N; ++i)
+ for (j = 0; j < N; ++j) {
+ if (i == j)
+ TEST_ASSERT(a[i][j] == v);
+ else
+ TEST_ASSERT(a[i][j] == FLOAT_TO_FP(0.0f));
+ }
+
+ return EC_SUCCESS;
+}
+
+static int test_mat33_fp_scalar_mul(void)
+{
+ const int N = 3;
+ float scale = 3.11f;
+ mat33_float_t a = {
+ {1.0f, 2.0f, 3.0f},
+ {1.1f, 2.2f, 3.3f},
+ {0.38f, 13.2f, 88.3f}
+ };
+ /* Golden result g = scalar_mul(a, scale) */
+ mat33_float_t g = {{3.11f, 6.22f, 9.33f},
+ {3.421f, 6.842f, 10.263f},
+ {1.18179988861083984375f, 41.051998138427734375f,
+ 274.613006591796875f}
+ };
+ int i, j;
+ mat33_fp_t fpa;
+
+ for (i = 0; i < N; ++i)
+ for (j = 0; j < N; ++j)
+ fpa[i][j] = FLOAT_TO_FP(a[i][j]);
+
+ mat33_fp_scalar_mul(fpa, FLOAT_TO_FP(scale));
+
+ for (i = 0; i < N; ++i)
+ for (j = 0; j < N; ++j)
+ TEST_ASSERT(IS_FP_EQUAL(fpa[i][j], FLOAT_TO_FP(g[i][j]),
+ SCALAR_MUL_TOLERANCE));
+
+ return EC_SUCCESS;
+}
+
+static int test_mat33_fp_get_eigenbasis(void)
+{
+ mat33_fp_t s = {
+ {FLOAT_TO_FP(4.0f), FLOAT_TO_FP(2.0f), FLOAT_TO_FP(2.0f)},
+ {FLOAT_TO_FP(2.0f), FLOAT_TO_FP(4.0f), FLOAT_TO_FP(2.0f)},
+ {FLOAT_TO_FP(2.0f), FLOAT_TO_FP(2.0f), FLOAT_TO_FP(4.0f)}
+ };
+ fpv3_t e_vals;
+ mat33_fp_t e_vecs;
+ int i, j;
+
+ /* Golden result from float version. */
+ mat33_fp_t gold_vecs = {
+ {FLOAT_TO_FP(0.55735206f), FLOAT_TO_FP(0.55735206f),
+ FLOAT_TO_FP(0.55735206f)},
+ {FLOAT_TO_FP(0.70710677f), FLOAT_TO_FP(-0.70710677f),
+ FLOAT_TO_FP(0.0f)},
+ {FLOAT_TO_FP(-0.40824828f), FLOAT_TO_FP(-0.40824828f),
+ FLOAT_TO_FP(0.81649655f)}
+ };
+ fpv3_t gold_vals = {FLOAT_TO_FP(8.0f), FLOAT_TO_FP(2.0f),
+ FLOAT_TO_FP(2.0f)};
+
+ mat33_fp_get_eigenbasis(s, e_vals, e_vecs);
+
+ for (i = 0; i < 3; ++i) {
+ TEST_ASSERT(IS_FP_EQUAL(gold_vals[i], e_vals[i],
+ EIGENBASIS_TOLERANCE));
+ for (j = 0; j < 3; ++j) {
+ TEST_ASSERT(IS_FP_EQUAL(gold_vecs[i][j], e_vecs[i][j],
+ EIGENBASIS_TOLERANCE));
+ }
+ }
+
+ return EC_SUCCESS;
+}
+
+static int test_mat44_fp_decompose_lup(void)
+{
+ int i, j;
+ sizev4_t pivot;
+ mat44_fp_t fpa = {
+ {FLOAT_TO_FP(11.0f), FLOAT_TO_FP(9.0f),
+ FLOAT_TO_FP(24.0f), FLOAT_TO_FP(2.0f)},
+ {FLOAT_TO_FP(1.0f), FLOAT_TO_FP(5.0f),
+ FLOAT_TO_FP(2.0f), FLOAT_TO_FP(6.0f)},
+ {FLOAT_TO_FP(3.0f), FLOAT_TO_FP(17.0f),
+ FLOAT_TO_FP(18.0f), FLOAT_TO_FP(1.0f)},
+ {FLOAT_TO_FP(2.0f), FLOAT_TO_FP(5.0f),
+ FLOAT_TO_FP(7.0f), FLOAT_TO_FP(1.0f)}
+ };
+ /* Golden result from float version. */
+ mat44_fp_t gold_lu = {
+ {FLOAT_TO_FP(11.0f), FLOAT_TO_FP(0.8181818f),
+ FLOAT_TO_FP(2.1818182f), FLOAT_TO_FP(0.18181819f)},
+ {FLOAT_TO_FP(3.0f), FLOAT_TO_FP(14.545454),
+ FLOAT_TO_FP(0.7875f), FLOAT_TO_FP(0.03125f)},
+ {FLOAT_TO_FP(1.0f), FLOAT_TO_FP(4.181818f),
+ FLOAT_TO_FP(-3.4750001f), FLOAT_TO_FP(-1.6366906f)},
+ {FLOAT_TO_FP(2.0f), FLOAT_TO_FP(3.3636365f),
+ FLOAT_TO_FP(-0.012500286f), FLOAT_TO_FP(0.5107909f)}
+ };
+ sizev4_t gold_pivot = {0, 2, 2, 3};
+
+ mat44_fp_decompose_lup(fpa, pivot);
+
+ for (i = 0; i < 4; ++i) {
+ TEST_ASSERT(gold_pivot[i] == pivot[i]);
+ for (j = 0; j < 4; ++j)
+ TEST_ASSERT(IS_FP_EQUAL(gold_lu[i][j], fpa[i][j],
+ LUP_TOLERANCE));
+ }
+
+ return EC_SUCCESS;
+}
+
+static int test_mat44_fp_solve(void)
+{
+ int i;
+ fpv4_t x;
+ mat44_fp_t A = {
+ {FLOAT_TO_FP(11.0f), FLOAT_TO_FP(0.8181818f),
+ FLOAT_TO_FP(2.1818182f), FLOAT_TO_FP(0.18181819f)},
+ {FLOAT_TO_FP(3.0f), FLOAT_TO_FP(14.545454),
+ FLOAT_TO_FP(0.7875f), FLOAT_TO_FP(0.03125f)},
+ {FLOAT_TO_FP(1.0f), FLOAT_TO_FP(4.181818f),
+ FLOAT_TO_FP(-3.4750001f), FLOAT_TO_FP(-1.6366906f)},
+ {FLOAT_TO_FP(2.0f), FLOAT_TO_FP(3.3636365f),
+ FLOAT_TO_FP(-0.012500286f), FLOAT_TO_FP(0.5107909f)}
+ };
+ sizev4_t pivot = {0, 2, 2, 3};
+ fpv4_t b = {FLOAT_TO_FP(1.0f), FLOAT_TO_FP(3.3f), FLOAT_TO_FP(0.8f),
+ FLOAT_TO_FP(8.9f)};
+ /* Golden result from float version. */
+ fpv4_t gold_x = {FLOAT_TO_FP(-43.50743f), FLOAT_TO_FP(-21.459526f),
+ FLOAT_TO_FP(26.629248f), FLOAT_TO_FP(16.80776f)};
+
+ mat44_fp_solve(A, x, b, pivot);
+
+ for (i = 0; i < 4; ++i)
+ TEST_ASSERT(IS_FP_EQUAL(gold_x[i], x[i], SOLVE_TOLERANCE));
+
+ return EC_SUCCESS;
+}
+
+void run_test(void)
+{
+ test_reset();
+
+ RUN_TEST(test_fpv3_scalar_mul);
+ RUN_TEST(test_fpv3_dot);
+ RUN_TEST(test_fpv3_norm_squared);
+ RUN_TEST(test_fpv3_norm);
+ RUN_TEST(test_mat33_fp_init_zero);
+ RUN_TEST(test_mat33_fp_init_diagonal);
+ RUN_TEST(test_mat33_fp_scalar_mul);
+ RUN_TEST(test_mat33_fp_get_eigenbasis);
+ RUN_TEST(test_mat44_fp_decompose_lup);
+ RUN_TEST(test_mat44_fp_solve);
+
+ test_print_result();
+}
diff --git a/test/fp.tasklist b/test/fp.tasklist
new file mode 100644
index 0000000000..5e26d7102e
--- /dev/null
+++ b/test/fp.tasklist
@@ -0,0 +1,17 @@
+/* Copyright 2018 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/**
+ * List of enabled tasks in the priority order
+ *
+ * The first one has the lowest priority.
+ *
+ * For each task, use the macro TASK_TEST(n, r, d, s) where :
+ * 'n' in the name of the task
+ * 'r' in the main routine of the task
+ * 'd' in an opaque parameter passed to the routine at startup
+ * 's' is the stack size in bytes; must be a multiple of 8
+ */
+#define CONFIG_TEST_TASK_LIST /* No test task */
diff --git a/test/test_config.h b/test/test_config.h
index 8a972f10c3..a53ea87656 100644
--- a/test/test_config.h
+++ b/test/test_config.h
@@ -54,6 +54,16 @@
#define CONFIG_MATH_UTIL
#endif
+#ifdef TEST_FLOAT
+#define CONFIG_FPU
+#define CONFIG_MAG_CALIBRATE
+#endif
+
+#ifdef TEST_FP
+#undef CONFIG_FPU
+#define CONFIG_MAG_CALIBRATE
+#endif
+
#ifdef TEST_MOTION_LID
#define CONFIG_LID_ANGLE
#define CONFIG_LID_ANGLE_INVALID_CHECK