M5Unit-IMU 0.0.2 git rev:e5b00aa
Loading...
Searching...
No Matches
unit_ak8963_data.hpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2026 M5Stack Technology CO LTD
3 *
4 * SPDX-License-Identifier: MIT
5 */
10#ifndef M5_UNIT_IMU_UNIT_UNIT_AK8963_DATA_HPP
11#define M5_UNIT_IMU_UNIT_UNIT_AK8963_DATA_HPP
12
13#include <array>
14#include <cstdint>
15#include <cmath>
16
17namespace m5 {
18namespace unit {
19namespace ak8963 {
20
25enum class Mode : uint8_t {
26 PowerDown = 0x00,
27 Single = 0x01,
28 Cont8Hz = 0x02,
29 Cont100Hz = 0x06,
30 SelfTest = 0x08,
31 FuseRom = 0x0F,
32};
33
42enum class MeasurementMode : uint8_t {
43 Cont8Hz = 0x02,
44 Cont100Hz = 0x06,
45};
46
53enum class OutputBit : uint8_t {
54 Bit14 = 0x00,
55 Bit16 = 0x10,
56};
57
59constexpr uint32_t interval_ms(const MeasurementMode mode)
60{
61 return (mode == MeasurementMode::Cont8Hz) ? 125U : 10U;
62}
63
65constexpr uint8_t cntl1_value(const MeasurementMode mode, const OutputBit bit)
66{
67 return static_cast<uint8_t>(static_cast<uint8_t>(bit) | static_cast<uint8_t>(mode));
68}
69
71constexpr float RAW_UT_PER_LSB{4912.0f / 32760.0f};
73constexpr float RAW_UT_PER_LSB_14BIT{4912.0f / 8190.0f};
75constexpr float OUTPUT_LSB_PER_UT{16.0f};
76
84struct Data {
85 std::array<uint8_t, 8> raw{};
86 std::array<uint8_t, 3> asa{};
87
89 inline bool drdy() const
90 {
91 return (raw[0] & 0x01) != 0;
92 }
94 inline bool dor() const
95 {
96 return (raw[0] & 0x02) != 0;
97 }
99 inline bool overflow() const
100 {
101 return (raw[7] & 0x08) != 0;
102 }
106 inline bool bit16() const
107 {
108 return (raw[7] & 0x10) != 0;
109 }
111 inline int16_t x_raw() const
112 {
113 return static_cast<int16_t>((raw[2] << 8) | raw[1]);
114 }
116 inline int16_t y_raw() const
117 {
118 return static_cast<int16_t>((raw[4] << 8) | raw[3]);
119 }
121 inline int16_t z_raw() const
122 {
123 return static_cast<int16_t>((raw[6] << 8) | raw[5]);
124 }
125
127 inline int32_t adj_x() const
128 {
129 return adjust(x_raw(), asa[0]);
130 }
132 inline int32_t adj_y() const
133 {
134 return adjust(y_raw(), asa[1]);
135 }
137 inline int32_t adj_z() const
138 {
139 return adjust(z_raw(), asa[2]);
140 }
141
142private:
143 inline int32_t adjust(const int16_t raw_axis, const uint8_t asa_axis) const
144 {
145 // Hadj = raw * (ASA + 128) / 256, then rescale to 16 LSB/µT. The sensitivity comes from the
146 // sample's own BITM bit, so a 14bit sample is scaled by 0.6µT/LSB even if the chip has been
147 // switched to 16bit since
148 const float ut = raw_axis * ((asa_axis + 128) / 256.0f) * (bit16() ? RAW_UT_PER_LSB : RAW_UT_PER_LSB_14BIT);
149 return static_cast<int32_t>(lroundf(ut * OUTPUT_LSB_PER_UT));
150 }
151};
152
153} // namespace ak8963
154} // namespace unit
155} // namespace m5
156#endif
Top level namespace of M5Stack.
Definition ahrs_controller.cpp:26
Unit-related namespace.
One AK8963 sample: an 8-byte burst from ST1 (0x02) plus the device ASA trim.
Definition unit_ak8963_data.hpp:84
bool bit16() const
16bit output? (ST2 bit4 BITM)
Definition unit_ak8963_data.hpp:106
int16_t z_raw() const
Raw Z.
Definition unit_ak8963_data.hpp:121
int32_t adj_z() const
ASA-adjusted Z.
Definition unit_ak8963_data.hpp:137
std::array< uint8_t, 3 > asa
Per-axis sensitivity adjustment (device constant)
Definition unit_ak8963_data.hpp:86
int32_t adj_y() const
ASA-adjusted Y.
Definition unit_ak8963_data.hpp:132
bool dor() const
Data overrun (ST1 bit1 DOR): a sample was read too late and one was skipped.
Definition unit_ak8963_data.hpp:94
int16_t y_raw() const
Raw Y.
Definition unit_ak8963_data.hpp:116
int16_t x_raw() const
Raw X (little-endian, signed 16bit)
Definition unit_ak8963_data.hpp:111
std::array< uint8_t, 8 > raw
ST1 + X/Y/Z (LE) + ST2.
Definition unit_ak8963_data.hpp:85
bool drdy() const
Data ready (ST1 bit0)
Definition unit_ak8963_data.hpp:89
int32_t adj_x() const
ASA-adjusted X in library-wide 16 LSB/µT.
Definition unit_ak8963_data.hpp:127
bool overflow() const
Magnetic overflow (ST2 bit3 HOFL); sample invalid if set.
Definition unit_ak8963_data.hpp:99
constexpr uint8_t cntl1_value(const MeasurementMode mode, const OutputBit bit)
REG_CNTL1 value entering a continuous measurement mode.
Definition unit_ak8963_data.hpp:65
MeasurementMode
Continuous measurement rate, the subset of Mode this driver measures in.
Definition unit_ak8963_data.hpp:42
constexpr float RAW_UT_PER_LSB
16bit-mode sensitivity (µT per raw LSB) = 4912/32760
Definition unit_ak8963_data.hpp:71
constexpr uint32_t interval_ms(const MeasurementMode mode)
Sampling interval (ms) for a continuous measurement rate.
Definition unit_ak8963_data.hpp:59
constexpr float RAW_UT_PER_LSB_14BIT
14bit-mode sensitivity (µT per raw LSB) = 4912/8190
Definition unit_ak8963_data.hpp:73
Mode
CNTL1 (0x0A) low-nibble operating mode.
Definition unit_ak8963_data.hpp:25
@ Cont100Hz
Continuous measurement, 100Hz.
@ Cont8Hz
Continuous measurement, 8Hz.
@ PowerDown
Power-down.
@ Single
Single measurement.
@ FuseRom
FUSE-ROM access (ASA readable only here)
constexpr float OUTPUT_LSB_PER_UT
Library-wide magnetometer output scale (raw LSB per µT); see imu_convert_param_t.
Definition unit_ak8963_data.hpp:75
OutputBit
Output bit width (CNTL1 bit4 BIT)
Definition unit_ak8963_data.hpp:53
@ Bit16
16bit (0.15µT/LSB)
@ Bit14
14bit (0.6µT/LSB)