-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathMMA8452.h
178 lines (141 loc) · 4.92 KB
/
MMA8452.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
#ifndef MMA8452_H_
#define MMA8452_H_
#ifdef ARDUINO
#include <Arduino.h>
#include <Wire.h>
#else
#include <stdlib.h>
#include <avr/io.h>
#include "i2cmaster.h"
#include <util/delay.h>
#endif
#include "MMA8452Reg.h"
// I2C address set in hardware (tied high or low)
#define SA0 0
#if SA0
#define MMA8452_ADDRESS 0x1D
#else
#define MMA8452_ADDRESS 0x1C
#endif
typedef enum {
MMA_RANGE_2G = 0,
MMA_RANGE_4G,
MMA_RANGE_8G
} mma8452_range_t;
typedef enum {
MMA_STANDBY = 0,
MMA_WAKE,
MMA_SLEEP
} mma8452_mode_t;
// See table on page 23 in datasheet (http://www.freescale.com/files/sensors/doc/data_sheet/MMA8452Q.pdf)
typedef enum {
MMA_HP1 = 0,
MMA_HP2,
MMA_HP3,
MMA_HP4
} mma8452_highpass_mode_t;
typedef enum {
MMA_PORTRAIT_UP = 0,
MMA_PORTRAIT_DOWN,
MMA_LANDSCAPE_RIGHT,
MMA_LANDSCAPE_LEFT
} mma8452_orientation_t;
typedef enum {
MMA_FREEFALL = 0,
MMA_MOTION
} mma8452_motion_type_t;
// sleep sampling mode
typedef enum {
MMA_SLEEP_50hz = 0,
MMA_SLEEP_12_5hz,
MMA_SLEEP_6_25hz,
MMA_SLEEP_1_56hz
} mma8452_sleep_frequency_t;
// normal running mode
typedef enum {
MMA_800hz = 0,
MMA_400hz,
MMA_200hz,
MMA_100hz,
MMA_50hz,
MMA_12_5hz,
MMA_6_25hz,
MMA_1_56hz
} mma_datarate_t;
// power mode
typedef enum {
MMA_NORMAL = 0,
MMA_LOW_NOISE_LOW_POWER,
MMA_HIGH_RESOLUTION,
MMA_LOW_POWER
} mma_power_mode_t;
typedef enum {
MMA_AUTO_SLEEP = 0x80,
MMA_TRANSIENT = 0x20,
MMA_ORIENTATION_CHANGE = 0x10,
MMA_TAP = 0x08,
MMA_FREEFALL_MOTION = 0x04,
MMA_DATA_READY = 0x01
} mma_interrupt_types_t;
typedef enum {
MMA_X = 0x01,
MMA_Y = 0x02,
MMA_Z = 0x04,
MMA_ALL_AXIS = 0x07
} mma_axis_t;
class MMA8452
{
public:
bool init();
void setRange(mma8452_range_t range);
mma8452_range_t getRange();
void getRawData(uint16_t *x, uint16_t *y, uint16_t *z);
void getAcceleration(float *x, float *y, float *z);
mma8452_mode_t getMode();
void getInterruptEvent(bool *wakeStateChanged = NULL, bool *transient = NULL, bool *landscapePortrait = NULL, bool *pulseEvent = NULL, bool *freefallMotion = NULL, bool *dataReady = NULL);
// todo: implement Pulse_LPF_EN
void setHighPassFilter(bool enabled, mma8452_highpass_mode_t mode = MMA_HP1);
void enableOrientationChange(bool enabled, bool clearCounterWhenInvalid = true);
void getPortaitLandscapeStatus(bool *orientationChanged, bool *zTiltLockoutDetected, mma8452_orientation_t *orientation, bool *back);
bool isFlat();
void configureLandscapePortraitDetection(bool enableDetection, uint8_t debounceCount = 0, bool debounceTimeout = true);
void setMotionDetectionMode(mma8452_motion_type_t motion, uint8_t axis, bool latchMotion = false);
bool motionDetected(bool *x = NULL, bool *y = NULL, bool *z = NULL, bool *negativeX = NULL, bool *negativeY = NULL, bool *negativeZ = NULL);
// threshold: 8G/127
void setMotionTreshold(uint8_t threshold, uint8_t debounceCount = 0, bool resetDebounceOnNoMotion = true);
void setTransientDetection(uint8_t axis, bool latchMotion = false, bool bypassHighPass = false);
bool transientDetected(bool *x, bool *y, bool *z, bool *negativeX = NULL, bool *negativeY = NULL, bool *negativeZ = NULL);
// threshold: 8G/127
void setTransientTreshold(uint8_t threshold, uint8_t debounceCount = 0, bool resetDebounceOnNoMotion = 0);
void enableSingleTapDetector(uint8_t axis, bool latch = true);
void enableDoubleTapDetector(uint8_t axis, uint8_t minDuration, uint8_t maxDuration, bool latch = true, bool abortOnQuickDoubleTap = false);
bool getTapDetails(bool *singleTap, bool *doubleTap, bool *x, bool *y, bool *z, bool *negativeX = NULL, bool *negativeY = NULL, bool *negativeZ = NULL);
void setTapThreshold(uint8_t x, uint8_t y, uint8_t z);
void setMaxTapDuration(uint8_t maxDuration);
void setAutoSleep(bool enabled, uint8_t time, mma8452_sleep_frequency_t sleepFrequencySampling = MMA_SLEEP_1_56hz, mma_power_mode_t sleepPowerMode = MMA_LOW_POWER);
void setWakeOnInterrupt(bool transient = true, bool landscapePortraitChange = true, bool tap = true, bool freefall_motion = true);
void setDataRate(mma_datarate_t dataRate);
void setLowNoiseMode(bool enabled);
void set8BitMode(bool enabled);
void reset(); // todo: might not be working
void setPowerMode(mma_power_mode_t powerMode);
void setInterruptsEnabled(uint8_t interruptMask);
void configureInterrupts(bool activeHigh, bool openDrain);
// true: pin1, false: pin2
void setInterruptPins(bool autoSleepWake, bool transient, bool landscapePortraitChange, bool tap, bool freefall_motion, bool dataReady);
// 2mG/LSB
void setOffsets(int8_t x, int8_t y, int8_t z);
void setActive(bool active = true);
private:
bool active;
mma8452_range_t range;
void standby(bool standby);
uint8_t read(uint8_t reg);
void readMultiple(uint8_t reg, uint8_t *buffer, uint8_t numuint8_ts);
void write(uint8_t reg, uint8_t value);
bool singleTapEnabled;
bool doubleTapEnabled;
float convertGCounts(uint16_t data);
int8_t convertTo2sComplement(int8_t value);
};
#endif // MMA8452_H_