Pinscape Controller version 1 fork. This is a fork to allow for ongoing bug fixes to the original controller version, from before the major changes for the expansion board project.

Dependencies:   FastIO FastPWM SimpleDMA mbed

Fork of Pinscape_Controller by Mike R

Committer:
mjr
Date:
Mon Feb 15 23:03:55 2016 +0000
Revision:
68:edfecf67a931
Parent:
5:a70c0bce770d
Finalize USB library updates to fix compatibility problems introduced in USBHAL_KL25Z overhaul.

Who changed what in which revision?

UserRevisionLine numberNew 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 3:3514575d4f86 60 #define CTRL_REG3_IPOL_MASK 0x02
mjr 3:3514575d4f86 61 #define CTRL_REG3_PPOD_MASK 0x01
mjr 3:3514575d4f86 62
mjr 3:3514575d4f86 63 #define INT_EN_DRDY 0x01
mjr 3:3514575d4f86 64 #define INT_CFG_DRDY 0x01
mjr 3:3514575d4f86 65
mjr 1:d913e0afb2ac 66
mjr 1:d913e0afb2ac 67 MMA8451Q::MMA8451Q(PinName sda, PinName scl, int addr) : m_i2c(sda, scl), m_addr(addr)
mjr 1:d913e0afb2ac 68 {
mjr 5:a70c0bce770d 69 // initialize parameters
mjr 5:a70c0bce770d 70 init();
mjr 5:a70c0bce770d 71 }
mjr 5:a70c0bce770d 72
mjr 5:a70c0bce770d 73 // reset the accelerometer and set our parameters
mjr 5:a70c0bce770d 74 void MMA8451Q::init()
mjr 5:a70c0bce770d 75 {
mjr 3:3514575d4f86 76 // reset all registers to power-on reset values
mjr 3:3514575d4f86 77 uint8_t d0[2] = { REG_CTRL_REG_2, 0x40 };
mjr 3:3514575d4f86 78 writeRegs(d0,2 );
mjr 3:3514575d4f86 79
mjr 3:3514575d4f86 80 // wait for the reset bit to clear
mjr 3:3514575d4f86 81 do {
mjr 3:3514575d4f86 82 readRegs(REG_CTRL_REG_2, d0, 1);
mjr 3:3514575d4f86 83 } while ((d0[0] & 0x40) != 0);
mjr 5:a70c0bce770d 84
mjr 5:a70c0bce770d 85 // go to standby mode
mjr 5:a70c0bce770d 86 standby();
mjr 3:3514575d4f86 87
mjr 1:d913e0afb2ac 88 // read the curent config register
mjr 1:d913e0afb2ac 89 uint8_t d1[1];
mjr 1:d913e0afb2ac 90 readRegs(XYZ_DATA_CFG_REG, d1, 1);
mjr 1:d913e0afb2ac 91
mjr 1:d913e0afb2ac 92 // set 2g mode
mjr 1:d913e0afb2ac 93 uint8_t d2[2] = { XYZ_DATA_CFG_REG, (d1[0] & ~FS_MASK) | FS_2G };
mjr 1:d913e0afb2ac 94 writeRegs(d2, 2);
mjr 1:d913e0afb2ac 95
mjr 1:d913e0afb2ac 96 // read the ctl2 register
mjr 1:d913e0afb2ac 97 uint8_t d3[1];
mjr 1:d913e0afb2ac 98 readRegs(REG_CTRL_REG_2, d3, 1);
mjr 1:d913e0afb2ac 99
mjr 1:d913e0afb2ac 100 // set the high resolution mode
mjr 1:d913e0afb2ac 101 uint8_t d4[2] = {REG_CTRL_REG_2, (d3[0] & ~MODS_MASK) | MODS1_MASK};
mjr 1:d913e0afb2ac 102 writeRegs(d4, 2);
mjr 1:d913e0afb2ac 103
mjr 3:3514575d4f86 104 // set 800 Hz mode
mjr 1:d913e0afb2ac 105 uint8_t d5[1];
mjr 1:d913e0afb2ac 106 readRegs(REG_CTRL_REG_1, d5, 1);
mjr 3:3514575d4f86 107 uint8_t d6[2] = {REG_CTRL_REG_1, (d5[0] & ~DR_MASK) | DR_800_HZ};
mjr 1:d913e0afb2ac 108 writeRegs(d6, 2);
mjr 1:d913e0afb2ac 109
mjr 1:d913e0afb2ac 110 // enter active mode
mjr 1:d913e0afb2ac 111 active();
mjr 1:d913e0afb2ac 112 }
mjr 1:d913e0afb2ac 113
mjr 1:d913e0afb2ac 114 MMA8451Q::~MMA8451Q() { }
mjr 1:d913e0afb2ac 115
mjr 3:3514575d4f86 116 void MMA8451Q::setInterruptMode(int pin)
mjr 3:3514575d4f86 117 {
mjr 3:3514575d4f86 118 // go to standby mode
mjr 3:3514575d4f86 119 standby();
mjr 3:3514575d4f86 120
mjr 3:3514575d4f86 121 // set IRQ push/pull and active high
mjr 3:3514575d4f86 122 uint8_t d1[1];
mjr 3:3514575d4f86 123 readRegs(REG_CTRL_REG_3, d1, 1);
mjr 3:3514575d4f86 124 uint8_t d2[2] = {
mjr 3:3514575d4f86 125 REG_CTRL_REG_3,
mjr 3:3514575d4f86 126 (d1[0] & ~CTRL_REG3_PPOD_MASK) | CTRL_REG3_IPOL_MASK
mjr 3:3514575d4f86 127 };
mjr 3:3514575d4f86 128 writeRegs(d2, 2);
mjr 3:3514575d4f86 129
mjr 3:3514575d4f86 130 // set pin 2 or pin 1
mjr 3:3514575d4f86 131 readRegs(REG_CTRL_REG_5, d1, 1);
mjr 3:3514575d4f86 132 uint8_t d3[2] = {
mjr 3:3514575d4f86 133 REG_CTRL_REG_5,
mjr 3:3514575d4f86 134 (d1[0] & ~INT_CFG_DRDY) | (pin == 1 ? INT_CFG_DRDY : 0)
mjr 3:3514575d4f86 135 };
mjr 3:3514575d4f86 136 writeRegs(d3, 2);
mjr 3:3514575d4f86 137
mjr 3:3514575d4f86 138 // enable data ready interrupt
mjr 3:3514575d4f86 139 readRegs(REG_CTRL_REG_4, d1, 1);
mjr 3:3514575d4f86 140 uint8_t d4[2] = { REG_CTRL_REG_4, d1[0] | INT_EN_DRDY };
mjr 3:3514575d4f86 141 writeRegs(d4, 2);
mjr 3:3514575d4f86 142
mjr 3:3514575d4f86 143 // enter active mode
mjr 3:3514575d4f86 144 active();
mjr 3:3514575d4f86 145 }
mjr 3:3514575d4f86 146
mjr 1:d913e0afb2ac 147 void MMA8451Q::standby()
mjr 1:d913e0afb2ac 148 {
mjr 1:d913e0afb2ac 149 // read the current control register
mjr 1:d913e0afb2ac 150 uint8_t d1[1];
mjr 1:d913e0afb2ac 151 readRegs(REG_CTRL_REG_1, d1, 1);
mjr 1:d913e0afb2ac 152
mjr 5:a70c0bce770d 153 // wait for standby mode
mjr 5:a70c0bce770d 154 do {
mjr 5:a70c0bce770d 155 // write it back with the Active bit cleared
mjr 5:a70c0bce770d 156 uint8_t d2[2] = { REG_CTRL_REG_1, d1[0] & ~CTL_ACTIVE };
mjr 5:a70c0bce770d 157 writeRegs(d2, 2);
mjr 5:a70c0bce770d 158
mjr 5:a70c0bce770d 159 readRegs(REG_CTRL_REG_1, d1, 1);
mjr 5:a70c0bce770d 160 } while (d1[0] & CTL_ACTIVE);
mjr 1:d913e0afb2ac 161 }
mjr 1:d913e0afb2ac 162
mjr 1:d913e0afb2ac 163 void MMA8451Q::active()
mjr 1:d913e0afb2ac 164 {
mjr 1:d913e0afb2ac 165 // read the current control register
mjr 1:d913e0afb2ac 166 uint8_t d1[1];
mjr 1:d913e0afb2ac 167 readRegs(REG_CTRL_REG_1, d1, 1);
mjr 1:d913e0afb2ac 168
mjr 1:d913e0afb2ac 169 // write it back out with the Active bit set
mjr 1:d913e0afb2ac 170 uint8_t d2[2] = { REG_CTRL_REG_1, d1[0] | CTL_ACTIVE };
mjr 1:d913e0afb2ac 171 writeRegs(d2, 2);
mjr 1:d913e0afb2ac 172 }
mjr 1:d913e0afb2ac 173
mjr 1:d913e0afb2ac 174 uint8_t MMA8451Q::getWhoAmI() {
mjr 1:d913e0afb2ac 175 uint8_t who_am_i = 0;
mjr 1:d913e0afb2ac 176 readRegs(REG_WHO_AM_I, &who_am_i, 1);
mjr 1:d913e0afb2ac 177 return who_am_i;
mjr 1:d913e0afb2ac 178 }
mjr 1:d913e0afb2ac 179
mjr 1:d913e0afb2ac 180 float MMA8451Q::getAccX() {
mjr 1:d913e0afb2ac 181 return (float(getAccAxis(REG_OUT_X_MSB))/4096.0);
mjr 1:d913e0afb2ac 182 }
mjr 1:d913e0afb2ac 183
mjr 1:d913e0afb2ac 184 void MMA8451Q::getAccXY(float &x, float &y)
mjr 1:d913e0afb2ac 185 {
mjr 1:d913e0afb2ac 186 // read the X and Y output registers
mjr 1:d913e0afb2ac 187 uint8_t res[4];
mjr 1:d913e0afb2ac 188 readRegs(REG_OUT_X_MSB, res, 4);
mjr 1:d913e0afb2ac 189
mjr 1:d913e0afb2ac 190 // translate the x value
mjr 1:d913e0afb2ac 191 uint16_t acc = (res[0] << 8) | (res[1]);
mjr 1:d913e0afb2ac 192 x = int16_t(acc)/(4*4096.0);
mjr 1:d913e0afb2ac 193
mjr 1:d913e0afb2ac 194 // translate the y value
mjr 1:d913e0afb2ac 195 acc = (res[2] << 9) | (res[3]);
mjr 1:d913e0afb2ac 196 y = int16_t(acc)/(4*4096.0);
mjr 1:d913e0afb2ac 197 }
mjr 1:d913e0afb2ac 198
mjr 3:3514575d4f86 199 void MMA8451Q::getAccXYZ(float &x, float &y, float &z)
mjr 3:3514575d4f86 200 {
mjr 3:3514575d4f86 201 // read the X, Y, and Z output registers
mjr 3:3514575d4f86 202 uint8_t res[6];
mjr 3:3514575d4f86 203 readRegs(REG_OUT_X_MSB, res, 6);
mjr 3:3514575d4f86 204
mjr 3:3514575d4f86 205 // translate the x value
mjr 3:3514575d4f86 206 uint16_t acc = (res[0] << 8) | (res[1]);
mjr 3:3514575d4f86 207 x = int16_t(acc)/(4*4096.0);
mjr 3:3514575d4f86 208
mjr 3:3514575d4f86 209 // translate the y value
mjr 3:3514575d4f86 210 acc = (res[2] << 8) | (res[3]);
mjr 3:3514575d4f86 211 y = int16_t(acc)/(4*4096.0);
mjr 3:3514575d4f86 212
mjr 3:3514575d4f86 213 // translate the z value
mjr 3:3514575d4f86 214 acc = (res[4] << 8) | (res[5]);
mjr 3:3514575d4f86 215 z = int16_t(acc)/(4*4096.0);
mjr 3:3514575d4f86 216 }
mjr 3:3514575d4f86 217
mjr 1:d913e0afb2ac 218 float MMA8451Q::getAccY() {
mjr 1:d913e0afb2ac 219 return (float(getAccAxis(REG_OUT_Y_MSB))/4096.0);
mjr 1:d913e0afb2ac 220 }
mjr 1:d913e0afb2ac 221
mjr 1:d913e0afb2ac 222 float MMA8451Q::getAccZ() {
mjr 1:d913e0afb2ac 223 return (float(getAccAxis(REG_OUT_Z_MSB))/4096.0);
mjr 1:d913e0afb2ac 224 }
mjr 1:d913e0afb2ac 225
mjr 1:d913e0afb2ac 226 void MMA8451Q::getAccAllAxis(float * res) {
mjr 1:d913e0afb2ac 227 res[0] = getAccX();
mjr 1:d913e0afb2ac 228 res[1] = getAccY();
mjr 1:d913e0afb2ac 229 res[2] = getAccZ();
mjr 1:d913e0afb2ac 230 }
mjr 1:d913e0afb2ac 231
mjr 1:d913e0afb2ac 232 int16_t MMA8451Q::getAccAxis(uint8_t addr) {
mjr 1:d913e0afb2ac 233 int16_t acc;
mjr 1:d913e0afb2ac 234 uint8_t res[2];
mjr 1:d913e0afb2ac 235 readRegs(addr, res, 2);
mjr 1:d913e0afb2ac 236
mjr 1:d913e0afb2ac 237 acc = (res[0] << 6) | (res[1] >> 2);
mjr 1:d913e0afb2ac 238 if (acc > UINT14_MAX/2)
mjr 1:d913e0afb2ac 239 acc -= UINT14_MAX;
mjr 1:d913e0afb2ac 240
mjr 1:d913e0afb2ac 241 return acc;
mjr 1:d913e0afb2ac 242 }
mjr 1:d913e0afb2ac 243
mjr 1:d913e0afb2ac 244 void MMA8451Q::readRegs(int addr, uint8_t * data, int len) {
mjr 1:d913e0afb2ac 245 char t[1] = {addr};
mjr 1:d913e0afb2ac 246 m_i2c.write(m_addr, t, 1, true);
mjr 1:d913e0afb2ac 247 m_i2c.read(m_addr, (char *)data, len);
mjr 1:d913e0afb2ac 248 }
mjr 1:d913e0afb2ac 249
mjr 1:d913e0afb2ac 250 void MMA8451Q::writeRegs(uint8_t * data, int len) {
mjr 1:d913e0afb2ac 251 m_i2c.write(m_addr, (char *)data, len);
mjr 1:d913e0afb2ac 252 }