Adjusts the great pinscape controller to work with a cheap linear potentiometer instead of the expensive CCD array
Fork of Pinscape_Controller by
MMA8451Q/MMA8451Q.cpp@2:c174f9ee414a, 2014-07-22 (annotated)
- Committer:
- mjr
- Date:
- Tue Jul 22 04:33:47 2014 +0000
- Revision:
- 2:c174f9ee414a
- Parent:
- 1:d913e0afb2ac
- Child:
- 3:3514575d4f86
Before change to ISR for accelerometer
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
mjr | 1:d913e0afb2ac | 1 | /* Copyright (c) 2010-2011 mbed.org, MIT License |
mjr | 1:d913e0afb2ac | 2 | * |
mjr | 1:d913e0afb2ac | 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this software |
mjr | 1:d913e0afb2ac | 4 | * and associated documentation files (the "Software"), to deal in the Software without |
mjr | 1:d913e0afb2ac | 5 | * restriction, including without limitation the rights to use, copy, modify, merge, publish, |
mjr | 1:d913e0afb2ac | 6 | * distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the |
mjr | 1:d913e0afb2ac | 7 | * Software is furnished to do so, subject to the following conditions: |
mjr | 1:d913e0afb2ac | 8 | * |
mjr | 1:d913e0afb2ac | 9 | * The above copyright notice and this permission notice shall be included in all copies or |
mjr | 1:d913e0afb2ac | 10 | * substantial portions of the Software. |
mjr | 1:d913e0afb2ac | 11 | * |
mjr | 1:d913e0afb2ac | 12 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING |
mjr | 1:d913e0afb2ac | 13 | * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
mjr | 1:d913e0afb2ac | 14 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, |
mjr | 1:d913e0afb2ac | 15 | * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
mjr | 1:d913e0afb2ac | 16 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
mjr | 1:d913e0afb2ac | 17 | */ |
mjr | 1:d913e0afb2ac | 18 | |
mjr | 1:d913e0afb2ac | 19 | #include "MMA8451Q.h" |
mjr | 1:d913e0afb2ac | 20 | |
mjr | 1:d913e0afb2ac | 21 | #define REG_WHO_AM_I 0x0D |
mjr | 1:d913e0afb2ac | 22 | #define REG_CTRL_REG_1 0x2A |
mjr | 1:d913e0afb2ac | 23 | #define REG_CTRL_REG_2 0x2B |
mjr | 1:d913e0afb2ac | 24 | #define REG_CTRL_REG_3 0x2c |
mjr | 1:d913e0afb2ac | 25 | #define REG_CTRL_REG_4 0x2D |
mjr | 1:d913e0afb2ac | 26 | #define REG_CTRL_REG_5 0x2E |
mjr | 1:d913e0afb2ac | 27 | #define REG_OFF_X 0x2F |
mjr | 1:d913e0afb2ac | 28 | #define REG_OFF_Y 0x30 |
mjr | 1:d913e0afb2ac | 29 | #define REG_OFF_Z 0x31 |
mjr | 1:d913e0afb2ac | 30 | #define XYZ_DATA_CFG_REG 0x0E |
mjr | 1:d913e0afb2ac | 31 | #define REG_OUT_X_MSB 0x01 |
mjr | 1:d913e0afb2ac | 32 | #define REG_OUT_Y_MSB 0x03 |
mjr | 1:d913e0afb2ac | 33 | #define REG_OUT_Z_MSB 0x05 |
mjr | 1:d913e0afb2ac | 34 | |
mjr | 1:d913e0afb2ac | 35 | #define UINT14_MAX 16383 |
mjr | 1:d913e0afb2ac | 36 | |
mjr | 1:d913e0afb2ac | 37 | #define CTL_ACTIVE 0x01 |
mjr | 1:d913e0afb2ac | 38 | #define FS_MASK 0x03 |
mjr | 1:d913e0afb2ac | 39 | #define FS_2G 0x00 |
mjr | 1:d913e0afb2ac | 40 | #define FS_4G 0x01 |
mjr | 1:d913e0afb2ac | 41 | #define FS_8G 0x02 |
mjr | 1:d913e0afb2ac | 42 | |
mjr | 1:d913e0afb2ac | 43 | #define HPF_OUT_MASK 0x10 |
mjr | 1:d913e0afb2ac | 44 | |
mjr | 1:d913e0afb2ac | 45 | #define MODS1_MASK 0x02 |
mjr | 1:d913e0afb2ac | 46 | #define MODS0_MASK 0x01 |
mjr | 1:d913e0afb2ac | 47 | #define SMODS_MASK 0x18 |
mjr | 1:d913e0afb2ac | 48 | #define MODS_MASK 0x03 |
mjr | 1:d913e0afb2ac | 49 | |
mjr | 1:d913e0afb2ac | 50 | #define DR_MASK 0x38 |
mjr | 1:d913e0afb2ac | 51 | #define DR_800_HZ 0x00 |
mjr | 1:d913e0afb2ac | 52 | #define DR_400_HZ 0x08 |
mjr | 1:d913e0afb2ac | 53 | #define DR_200_HZ 0x10 |
mjr | 1:d913e0afb2ac | 54 | #define DR_100_HZ 0x18 |
mjr | 1:d913e0afb2ac | 55 | #define DR_50_HZ 0x20 |
mjr | 1:d913e0afb2ac | 56 | #define DR_12_HZ 0x28 |
mjr | 1:d913e0afb2ac | 57 | #define DR_6_HZ 0x30 |
mjr | 1:d913e0afb2ac | 58 | #define DR_1_HZ 0x38 |
mjr | 1:d913e0afb2ac | 59 | |
mjr | 1:d913e0afb2ac | 60 | |
mjr | 1:d913e0afb2ac | 61 | MMA8451Q::MMA8451Q(PinName sda, PinName scl, int addr) : m_i2c(sda, scl), m_addr(addr) |
mjr | 1:d913e0afb2ac | 62 | { |
mjr | 1:d913e0afb2ac | 63 | // go to standby mode |
mjr | 1:d913e0afb2ac | 64 | standby(); |
mjr | 1:d913e0afb2ac | 65 | |
mjr | 1:d913e0afb2ac | 66 | // read the curent config register |
mjr | 1:d913e0afb2ac | 67 | uint8_t d1[1]; |
mjr | 1:d913e0afb2ac | 68 | readRegs(XYZ_DATA_CFG_REG, d1, 1); |
mjr | 1:d913e0afb2ac | 69 | |
mjr | 1:d913e0afb2ac | 70 | // set 2g mode |
mjr | 1:d913e0afb2ac | 71 | uint8_t d2[2] = { XYZ_DATA_CFG_REG, (d1[0] & ~FS_MASK) | FS_2G }; |
mjr | 1:d913e0afb2ac | 72 | writeRegs(d2, 2); |
mjr | 1:d913e0afb2ac | 73 | |
mjr | 1:d913e0afb2ac | 74 | // read the ctl2 register |
mjr | 1:d913e0afb2ac | 75 | uint8_t d3[1]; |
mjr | 1:d913e0afb2ac | 76 | readRegs(REG_CTRL_REG_2, d3, 1); |
mjr | 1:d913e0afb2ac | 77 | |
mjr | 1:d913e0afb2ac | 78 | // set the high resolution mode |
mjr | 1:d913e0afb2ac | 79 | uint8_t d4[2] = {REG_CTRL_REG_2, (d3[0] & ~MODS_MASK) | MODS1_MASK}; |
mjr | 1:d913e0afb2ac | 80 | writeRegs(d4, 2); |
mjr | 1:d913e0afb2ac | 81 | |
mjr | 2:c174f9ee414a | 82 | // set 100 Hz mode |
mjr | 1:d913e0afb2ac | 83 | uint8_t d5[1]; |
mjr | 1:d913e0afb2ac | 84 | readRegs(REG_CTRL_REG_1, d5, 1); |
mjr | 1:d913e0afb2ac | 85 | uint8_t d6[2] = {REG_CTRL_REG_1, (d5[0] & ~DR_MASK) | DR_100_HZ}; |
mjr | 1:d913e0afb2ac | 86 | writeRegs(d6, 2); |
mjr | 1:d913e0afb2ac | 87 | |
mjr | 1:d913e0afb2ac | 88 | // enter active mode |
mjr | 1:d913e0afb2ac | 89 | active(); |
mjr | 1:d913e0afb2ac | 90 | } |
mjr | 1:d913e0afb2ac | 91 | |
mjr | 1:d913e0afb2ac | 92 | MMA8451Q::~MMA8451Q() { } |
mjr | 1:d913e0afb2ac | 93 | |
mjr | 1:d913e0afb2ac | 94 | void MMA8451Q::standby() |
mjr | 1:d913e0afb2ac | 95 | { |
mjr | 1:d913e0afb2ac | 96 | // read the current control register |
mjr | 1:d913e0afb2ac | 97 | uint8_t d1[1]; |
mjr | 1:d913e0afb2ac | 98 | readRegs(REG_CTRL_REG_1, d1, 1); |
mjr | 1:d913e0afb2ac | 99 | |
mjr | 1:d913e0afb2ac | 100 | // write it back witht he Active bit cleared |
mjr | 1:d913e0afb2ac | 101 | uint8_t d2[2] = { REG_CTRL_REG_1, d1[0] & ~CTL_ACTIVE }; |
mjr | 1:d913e0afb2ac | 102 | writeRegs(d2, 2); |
mjr | 1:d913e0afb2ac | 103 | } |
mjr | 1:d913e0afb2ac | 104 | |
mjr | 1:d913e0afb2ac | 105 | void MMA8451Q::active() |
mjr | 1:d913e0afb2ac | 106 | { |
mjr | 1:d913e0afb2ac | 107 | // read the current control register |
mjr | 1:d913e0afb2ac | 108 | uint8_t d1[1]; |
mjr | 1:d913e0afb2ac | 109 | readRegs(REG_CTRL_REG_1, d1, 1); |
mjr | 1:d913e0afb2ac | 110 | |
mjr | 1:d913e0afb2ac | 111 | // write it back out with the Active bit set |
mjr | 1:d913e0afb2ac | 112 | uint8_t d2[2] = { REG_CTRL_REG_1, d1[0] | CTL_ACTIVE }; |
mjr | 1:d913e0afb2ac | 113 | writeRegs(d2, 2); |
mjr | 1:d913e0afb2ac | 114 | } |
mjr | 1:d913e0afb2ac | 115 | |
mjr | 1:d913e0afb2ac | 116 | uint8_t MMA8451Q::getWhoAmI() { |
mjr | 1:d913e0afb2ac | 117 | uint8_t who_am_i = 0; |
mjr | 1:d913e0afb2ac | 118 | readRegs(REG_WHO_AM_I, &who_am_i, 1); |
mjr | 1:d913e0afb2ac | 119 | return who_am_i; |
mjr | 1:d913e0afb2ac | 120 | } |
mjr | 1:d913e0afb2ac | 121 | |
mjr | 1:d913e0afb2ac | 122 | float MMA8451Q::getAccX() { |
mjr | 1:d913e0afb2ac | 123 | return (float(getAccAxis(REG_OUT_X_MSB))/4096.0); |
mjr | 1:d913e0afb2ac | 124 | } |
mjr | 1:d913e0afb2ac | 125 | |
mjr | 1:d913e0afb2ac | 126 | void MMA8451Q::getAccXY(float &x, float &y) |
mjr | 1:d913e0afb2ac | 127 | { |
mjr | 1:d913e0afb2ac | 128 | // read the X and Y output registers |
mjr | 1:d913e0afb2ac | 129 | uint8_t res[4]; |
mjr | 1:d913e0afb2ac | 130 | readRegs(REG_OUT_X_MSB, res, 4); |
mjr | 1:d913e0afb2ac | 131 | |
mjr | 1:d913e0afb2ac | 132 | // translate the x value |
mjr | 1:d913e0afb2ac | 133 | uint16_t acc = (res[0] << 8) | (res[1]); |
mjr | 1:d913e0afb2ac | 134 | x = int16_t(acc)/(4*4096.0); |
mjr | 1:d913e0afb2ac | 135 | |
mjr | 1:d913e0afb2ac | 136 | // translate the y value |
mjr | 1:d913e0afb2ac | 137 | acc = (res[2] << 9) | (res[3]); |
mjr | 1:d913e0afb2ac | 138 | y = int16_t(acc)/(4*4096.0); |
mjr | 1:d913e0afb2ac | 139 | } |
mjr | 1:d913e0afb2ac | 140 | |
mjr | 1:d913e0afb2ac | 141 | float MMA8451Q::getAccY() { |
mjr | 1:d913e0afb2ac | 142 | return (float(getAccAxis(REG_OUT_Y_MSB))/4096.0); |
mjr | 1:d913e0afb2ac | 143 | } |
mjr | 1:d913e0afb2ac | 144 | |
mjr | 1:d913e0afb2ac | 145 | float MMA8451Q::getAccZ() { |
mjr | 1:d913e0afb2ac | 146 | return (float(getAccAxis(REG_OUT_Z_MSB))/4096.0); |
mjr | 1:d913e0afb2ac | 147 | } |
mjr | 1:d913e0afb2ac | 148 | |
mjr | 1:d913e0afb2ac | 149 | void MMA8451Q::getAccAllAxis(float * res) { |
mjr | 1:d913e0afb2ac | 150 | res[0] = getAccX(); |
mjr | 1:d913e0afb2ac | 151 | res[1] = getAccY(); |
mjr | 1:d913e0afb2ac | 152 | res[2] = getAccZ(); |
mjr | 1:d913e0afb2ac | 153 | } |
mjr | 1:d913e0afb2ac | 154 | |
mjr | 1:d913e0afb2ac | 155 | int16_t MMA8451Q::getAccAxis(uint8_t addr) { |
mjr | 1:d913e0afb2ac | 156 | int16_t acc; |
mjr | 1:d913e0afb2ac | 157 | uint8_t res[2]; |
mjr | 1:d913e0afb2ac | 158 | readRegs(addr, res, 2); |
mjr | 1:d913e0afb2ac | 159 | |
mjr | 1:d913e0afb2ac | 160 | acc = (res[0] << 6) | (res[1] >> 2); |
mjr | 1:d913e0afb2ac | 161 | if (acc > UINT14_MAX/2) |
mjr | 1:d913e0afb2ac | 162 | acc -= UINT14_MAX; |
mjr | 1:d913e0afb2ac | 163 | |
mjr | 1:d913e0afb2ac | 164 | return acc; |
mjr | 1:d913e0afb2ac | 165 | } |
mjr | 1:d913e0afb2ac | 166 | |
mjr | 1:d913e0afb2ac | 167 | void MMA8451Q::readRegs(int addr, uint8_t * data, int len) { |
mjr | 1:d913e0afb2ac | 168 | char t[1] = {addr}; |
mjr | 1:d913e0afb2ac | 169 | m_i2c.write(m_addr, t, 1, true); |
mjr | 1:d913e0afb2ac | 170 | m_i2c.read(m_addr, (char *)data, len); |
mjr | 1:d913e0afb2ac | 171 | } |
mjr | 1:d913e0afb2ac | 172 | |
mjr | 1:d913e0afb2ac | 173 | void MMA8451Q::writeRegs(uint8_t * data, int len) { |
mjr | 1:d913e0afb2ac | 174 | m_i2c.write(m_addr, (char *)data, len); |
mjr | 1:d913e0afb2ac | 175 | } |