ESPHome  2025.3.2
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Modules Pages
msa3xx.h
Go to the documentation of this file.
1 #pragma once
2 
6 
7 #ifdef USE_BINARY_SENSOR
9 #endif
10 #ifdef USE_SENSOR
12 #endif
13 #ifdef USE_TEXT_SENSOR
15 #endif
16 
17 namespace esphome {
18 namespace msa3xx {
19 
20 // Combined register map of MSA301 and MSA311
21 // Differences
22 // What | MSA301 | MSA11 |
23 // - Resolution | 14-bit | 12-bit |
24 //
25 
26 // I2c address
27 enum class Model : uint8_t {
28  MSA301 = 0x26,
29  MSA311 = 0x62,
30 };
31 
32 // Combined MSA301 and MSA311 register map
33 enum class RegisterMap : uint8_t {
34  SOFT_RESET = 0x00,
35  PART_ID = 0x01,
36  ACC_X_LSB = 0x02,
37  ACC_X_MSB = 0x03,
38  ACC_Y_LSB = 0x04,
39  ACC_Y_MSB = 0x05,
40  ACC_Z_LSB = 0x06,
41  ACC_Z_MSB = 0x07,
42  MOTION_INTERRUPT = 0x09,
43  DATA_INTERRUPT = 0x0A,
44  TAP_ACTIVE_STATUS = 0x0B,
45  ORIENTATION_STATUS = 0x0C,
47  RANGE_RESOLUTION = 0x0F,
48  ODR = 0x10,
49  POWER_MODE_BANDWIDTH = 0x11,
50  SWAP_POLARITY = 0x12,
51  INT_SET_0 = 0x16,
52  INT_SET_1 = 0x17,
53  INT_MAP_0 = 0x19,
54  INT_MAP_1 = 0x1A,
55  INT_CONFIG = 0x20,
56  INT_LATCH = 0x21,
57  FREEFALL_DURATION = 0x22,
58  FREEFALL_THRESHOLD = 0x23,
59  FREEFALL_HYSTERESIS = 0x24,
60  ACTIVE_DURATION = 0x27,
61  ACTIVE_THRESHOLD = 0x28,
62  TAP_DURATION = 0x2A,
63  TAP_THRESHOLD = 0x2B,
64  ORIENTATION_CONFIG = 0x2C,
65  Z_BLOCK = 0x2D,
66  OFFSET_COMP_X = 0x38,
67  OFFSET_COMP_Y = 0x39,
68  OFFSET_COMP_Z = 0x3A,
69 };
70 
71 enum class Range : uint8_t {
72  RANGE_2G = 0b00,
73  RANGE_4G = 0b01,
74  RANGE_8G = 0b10,
75  RANGE_16G = 0b11,
76 };
77 
78 enum class Resolution : uint8_t {
79  RES_14BIT = 0b00,
80  RES_12BIT = 0b01,
81  RES_10BIT = 0b10,
82  RES_8BIT = 0b11,
83 };
84 
85 enum class PowerMode : uint8_t {
86  NORMAL = 0b00,
87  LOW_POWER = 0b01,
88  SUSPEND = 0b11,
89 };
90 
91 enum class Bandwidth : uint8_t {
92  BW_1_95HZ = 0b0000,
93  BW_3_9HZ = 0b0011,
94  BW_7_81HZ = 0b0100,
95  BW_15_63HZ = 0b0101,
96  BW_31_25HZ = 0b0110,
97  BW_62_5HZ = 0b0111,
98  BW_125HZ = 0b1000,
99  BW_250HZ = 0b1001,
100  BW_500HZ = 0b1010,
101 };
102 
103 enum class DataRate : uint8_t {
104  ODR_1HZ = 0b0000, // not available in normal mode
105  ODR_1_95HZ = 0b0001, // not available in normal mode
106  ODR_3_9HZ = 0b0010,
107  ODR_7_81HZ = 0b0011,
108  ODR_15_63HZ = 0b0100,
109  ODR_31_25HZ = 0b0101,
110  ODR_62_5HZ = 0b0110,
111  ODR_125HZ = 0b0111,
112  ODR_250HZ = 0b1000,
113  ODR_500HZ = 0b1001, // not available in low power mode
114  ODR_1000HZ = 0b1010, // not available in low power mode
115 };
116 
117 enum class OrientationXY : uint8_t {
118  PORTRAIT_UPRIGHT = 0b00,
119  PORTRAIT_UPSIDE_DOWN = 0b01,
120  LANDSCAPE_LEFT = 0b10,
121  LANDSCAPE_RIGHT = 0b11,
122 };
123 
124 union Orientation {
125  struct {
127  bool z : 1;
128  uint8_t reserved : 5;
129  } __attribute__((packed));
130  uint8_t raw;
131 };
132 
133 // 0x09
135  struct {
137  bool reserved_1 : 1;
139  bool reserved_3 : 1;
143  bool reserved_7 : 1;
144  } __attribute__((packed));
145  uint8_t raw;
146 };
147 
148 // 0x0C
150  struct {
151  uint8_t reserved_0_3 : 4;
153  bool orient_z : 1;
154  uint8_t reserved_7 : 1;
155  } __attribute__((packed));
156  uint8_t raw{0x00};
157 };
158 
159 // 0x0f
161  struct {
164  uint8_t reserved_2 : 4;
165  } __attribute__((packed));
166  uint8_t raw{0x00};
167 };
168 
169 // 0x10
171  struct {
173  uint8_t reserved_4 : 1;
174  bool z_axis_disable : 1;
175  bool y_axis_disable : 1;
176  bool x_axis_disable : 1;
177  } __attribute__((packed));
178  uint8_t raw{0xde};
179 };
180 
181 // 0x11
183  struct {
184  uint8_t reserved_0 : 1;
186  uint8_t reserved_5 : 1;
188  } __attribute__((packed));
189  uint8_t raw{0xde};
190 };
191 
192 // 0x12
194  struct {
195  bool x_y_swap : 1;
196  bool z_polarity : 1;
197  bool y_polarity : 1;
198  bool x_polarity : 1;
199  uint8_t reserved : 4;
200  } __attribute__((packed));
201  uint8_t raw{0};
202 };
203 
204 // 0x2a
206  struct {
207  uint8_t duration : 3;
208  uint8_t reserved : 3;
209  bool tap_shock : 1;
210  bool tap_quiet : 1;
211  } __attribute__((packed));
212  uint8_t raw{0x04};
213 };
214 
216  public:
217  void setup() override;
218  void dump_config() override;
219 
220  void loop() override;
221  void update() override;
222 
223  float get_setup_priority() const override;
224 
225  void set_model(Model model) { this->model_ = model; }
226  void set_offset(float offset_x, float offset_y, float offset_z);
227  void set_range(Range range) { this->range_ = range; }
228  void set_bandwidth(Bandwidth bandwidth) { this->bandwidth_ = bandwidth; }
229  void set_resolution(Resolution resolution) { this->resolution_ = resolution; }
230  void set_transform(bool mirror_x, bool mirror_y, bool mirror_z, bool swap_xy);
231 
232 #ifdef USE_BINARY_SENSOR
234  SUB_BINARY_SENSOR(double_tap)
235  SUB_BINARY_SENSOR(active)
236 #endif
237 
238 #ifdef USE_SENSOR
239  SUB_SENSOR(acceleration_x)
240  SUB_SENSOR(acceleration_y)
241  SUB_SENSOR(acceleration_z)
242 #endif
243 
244 #ifdef USE_TEXT_SENSOR
245  SUB_TEXT_SENSOR(orientation_xy)
246  SUB_TEXT_SENSOR(orientation_z)
247 #endif
248 
249  Trigger<> *get_tap_trigger() { return &this->tap_trigger_; }
250  Trigger<> *get_double_tap_trigger() { return &this->double_tap_trigger_; }
251  Trigger<> *get_orientation_trigger() { return &this->orientation_trigger_; }
252  Trigger<> *get_freefall_trigger() { return &this->freefall_trigger_; }
253  Trigger<> *get_active_trigger() { return &this->active_trigger_; }
254 
255  protected:
257 
263  float offset_x_, offset_y_, offset_z_; // in m/s²
265 
266  struct {
269  } device_params_{};
270 
271  struct {
272  int16_t lsb_x, lsb_y, lsb_z;
273  float x, y, z;
274  } data_{};
275 
276  struct {
280 
281  uint32_t last_tap_ms{0};
282  uint32_t last_double_tap_ms{0};
283  uint32_t last_action_ms{0};
284 
285  bool never_published{true};
286  } status_{};
287 
288  void setup_odr_(DataRate rate);
289  void setup_power_mode_bandwidth_(PowerMode power_mode, Bandwidth bandwidth);
290  void setup_range_resolution_(Range range, Resolution resolution);
291  void setup_offset_(float offset_x, float offset_y, float offset_z);
292 
293  bool read_data_();
294  bool read_motion_status_();
295 
296  int64_t twos_complement_(uint64_t value, uint8_t bits);
297 
298  //
299  // Actons / Triggers
300  //
306 
307  void process_motions_(RegMotionInterrupt old);
308 };
309 
310 } // namespace msa3xx
311 } // namespace esphome
void setup()
void set_range(Range range)
Definition: msa3xx.h:227
void loop()
uint8_t raw[35]
Definition: bl0939.h:19
Trigger * get_orientation_trigger()
Definition: msa3xx.h:251
uint16_t x
Definition: tt21100.cpp:17
void set_bandwidth(Bandwidth bandwidth)
Definition: msa3xx.h:228
This class simplifies creating components that periodically check a state.
Definition: component.h:283
uint16_t y
Definition: tt21100.cpp:18
Trigger * get_freefall_trigger()
Definition: msa3xx.h:252
RegOrientationStatus orientation
Definition: msa3xx.h:278
Range range
Definition: msa3xx.h:413
Trigger * get_double_tap_trigger()
Definition: msa3xx.h:250
RegOrientationStatus orientation_old
Definition: msa3xx.h:279
PowerMode power_mode
Definition: msa3xx.h:424
RegMotionInterrupt motion_int
Definition: msa3xx.h:277
void set_model(Model model)
Definition: msa3xx.h:225
SUB_BINARY_SENSOR(tap) SUB_BINARY_SENSOR(double_tap) SUB_BINARY_SENSOR(active) SUB_SENSOR(acceleration_x) SUB_SENSOR(acceleration_y) SUB_SENSOR(acceleration_z) SUB_TEXT_SENSOR(orientation_xy) SUB_TEXT_SENSOR(orientation_z) Trigger<> *get_tap_trigger()
Definition: msa3xx.h:233
enum esphome::EntityCategory __attribute__
void set_resolution(Resolution resolution)
Definition: msa3xx.h:229
Resolution resolution
Definition: msa3xx.h:414
Implementation of SPI Controller mode.
Definition: a01nyub.cpp:7
This Class provides the methods to read/write bytes from/to an i2c device.
Definition: i2c.h:133