Sygaldry
Loading...
Searching...
No Matches
sygsp-icm20948_tests.hpp
1/*
2Copyright 2023 Travis J. West, https://traviswest.ca, Input Devices and Music
3Interaction Laboratory (IDMIL), Centre for Interdisciplinary Research in Music
4Media and Technology (CIRMMT), McGill University, Montréal, Canada, and Univ.
5Lille, Inria, CNRS, Centrale Lille, UMR 9189 CRIStAL, F-59000 Lille, France
6
7SPDX-License-Identifier: MIT
8*/
9#pragma once
10#include <cstdint>
11#include <cstdio>
12#include "sygsp-icm20948_registers.hpp"
13#include "sygsp-delay.hpp"
14
15namespace sygaldry { namespace sygsp {
16
19
20template<typename Serif, typename AK09916Serif>
22{
23 using Registers = ICM20948Registers<Serif>;
24 using AK09916Registers = ICM20948Registers<AK09916Serif>;
25 static bool test()
26 {
27 {
28 printf("icm20948-test: read test... ");
29 constexpr uint8_t who_am_i_address = 0;
30 constexpr uint8_t who_am_i_value = 0xea;
31 uint8_t ret = Serif::read(who_am_i_address);
32 if (ret == who_am_i_value) printf("passed!\n");
33 else
34 {
35 printf("unexpected who am I value %d?!\n", ret);
36 return false;
37 }
38 }
39 {
40 printf("icm20948-test: write test...");
41
42 constexpr uint8_t pwr_mgmt_1_address = 6;
43 constexpr uint8_t expected_value_after_reset = 0x41;
44 constexpr uint8_t wake_up_value = 0x01;
45 constexpr uint8_t reset_trigger_value = 0x81;
46
47 // Reset device
48 Serif::write(pwr_mgmt_1_address, reset_trigger_value);
49 delay(10);
50
51 // Read USER_CTRL register after reset
52 uint8_t value_after_reset = Serif::read(pwr_mgmt_1_address);
53 if (value_after_reset != expected_value_after_reset)
54 {
55 printf(" unexpected value after reset?!\n");
56 return false;
57 }
58
59 // Toggle a switch in USER_CTRL register
60 printf(".");
61 Serif::write(pwr_mgmt_1_address, wake_up_value);
62 delay(10);
63
64 // Confirm the change was recorded
65 uint8_t value_after_wake_up = Serif::read(pwr_mgmt_1_address);
66 if (value_after_wake_up != wake_up_value)
67 {
68 printf(" write operation unsuccessful?!\n");
69 return false;
70 }
71
72 // Reset device
73 printf(".");
74 Serif::write(pwr_mgmt_1_address, reset_trigger_value);
75 delay(10);
76
77 printf(" passed!\n");
78 }
79 {
80 printf("icm20948-test: register bases test...\n");
81
82 if (Registers::WHO_AM_I::read() != Registers::WHO_AM_I::after_reset)
83 {
84 printf(" unexpected who am I value?!\n");
85 return false;
86 }
87 printf(" WHO_AM_I good...\n");
88
89 Registers::PWR_MGMT_1::DEVICE_RESET::trigger();
90 delay(1);
91
92 auto v = Registers::PWR_MGMT_1::read();
93 if (v != Registers::PWR_MGMT_1::after_reset)
94 {
95 printf(" unexpected value %x after reset?!\n", v);
96 return false;
97 }
98 printf(" value after reset good...\n");
99
100 Registers::PWR_MGMT_1::SLEEP::disable();
101 delay(1);
102
103 // Confirm the change was recorded
104 uint8_t value_after_wake_up = Registers::PWR_MGMT_1::read();
105 uint8_t expected = Registers::PWR_MGMT_1::after_reset & ~Registers::PWR_MGMT_1::SLEEP::mask;
106 if (value_after_wake_up != expected)
107 {
108 printf(" write operation unsuccessful?!\n");
109 return false;
110 }
111 printf(" write operation good...\n");
112
113 Registers::PWR_MGMT_1::DEVICE_RESET::trigger();
114 delay(1);
115
116 printf(" passed!\n");
117 }
118 {
119 printf("icm20948-test: AK09916 test... \n");
120 Registers::PWR_MGMT_1::DEVICE_RESET::trigger(); delay(10);
121 Registers::PWR_MGMT_1::SLEEP::disable(); delay(10);
122 Registers::PWR_MGMT_1::LP_EN::disable(); delay(1);
123 Registers::INT_PIN_CFG::BYPASS_EN::enable(); delay(1);
124 Registers::USER_CTRL::I2C_MST_EN::disable(); delay(1);
125
126 if (AK09916Registers::WIA2::read() != AK09916Registers::WIA2::after_reset)
127 {
128 printf("unable to connect to AK09916\n");
129 return false;
130 }
131 else printf("AK09916 connected...\n");
132 AK09916Registers::CNTL3::SRST::trigger(); delay(1);
133 AK09916Registers::CNTL2::MODE::PowerDown::set(); delay(1);
134 AK09916Registers::CNTL2::MODE::SelfTest::set(); delay(1);
135 int i = 0;
136 while (i < 100 && !AK09916Registers::ST1::DRDY::read_field()) { delay(10); }
137 if (i >= 100)
138 {
139 printf("timeout while waiting for data ready?!\n");
140 return false;
141 }
142 constexpr uint8_t N_OUT = 8;
143 uint8_t measurement_data[N_OUT] = {0};
144 AK09916Serif::read(AK09916Registers::HXL::address, measurement_data, N_OUT);
145 int16_t x = measurement_data[1] << 8 | (measurement_data[0] & 0xFF);
146 int16_t y = measurement_data[3] << 8 | (measurement_data[2] & 0xFF);
147 int16_t z = measurement_data[5] << 8 | (measurement_data[4] & 0xFF);
148 if (!(-200 <= x && x <= 200))
149 {
150 printf("x data %d outside self-test range?! x: %d y: %d z: %d\n", x, x, y, z);
151 return false;
152 }
153 if (!(-200 <= y && y <= 200))
154 {
155 printf("y data %d outside self-test range?! x: %d y: %d z: %d\n", y, x, y, z);
156 return false;
157 }
158 if (!(-1000 <= z && z <= -200))
159 {
160 printf("z data %d outside self-test range?! x: %d y: %d z: %d\n", z, x, y, z);
161 return false;
162 }
163 printf("AK09916 self test pass! x: %d y: %d z: %d\n", x, y, z);
164 }
165 return true;
166 }
167};
168
170} }
void delay(unsigned long ms)
Definition sygsa-delay.cpp:14
Definition sygsp-icm20948_registers.hpp:27
Definition sygsp-icm20948_tests.hpp:22