BMD-200 Evaluation board using the on-board accelerometer (Freescale MMA8653FC). There a couple operating modes (streaming ADC data out the USB COM, moving board in a single axis causes an interrupt, others). Work in progress.

Dependencies:   PinDetect mbed-src-bmd-200

Committer:
dcnichols
Date:
Wed Jul 15 21:25:42 2015 +0000
Revision:
0:6f07db1b8cdc
initial check in

Who changed what in which revision?

UserRevisionLine numberNew contents of line
dcnichols 0:6f07db1b8cdc 1 /**
dcnichols 0:6f07db1b8cdc 2 * @file MMA845x.cpp
dcnichols 0:6f07db1b8cdc 3 * @brief Device driver - MMA845X 3-axis accelerometer IC
dcnichols 0:6f07db1b8cdc 4 * @author sam grove
dcnichols 0:6f07db1b8cdc 5 * @version 1.0
dcnichols 0:6f07db1b8cdc 6 * @see http://cache.freescale.com/files/sensors/doc/data_sheet/MMA8451Q.pdf
dcnichols 0:6f07db1b8cdc 7 * @see http://cache.freescale.com/files/sensors/doc/data_sheet/MMA8452Q.pdf
dcnichols 0:6f07db1b8cdc 8 * @see http://cache.freescale.com/files/sensors/doc/data_sheet/MMA8453Q.pdf
dcnichols 0:6f07db1b8cdc 9 *
dcnichols 0:6f07db1b8cdc 10 * Copyright (c) 2013
dcnichols 0:6f07db1b8cdc 11 *
dcnichols 0:6f07db1b8cdc 12 * Licensed under the Apache License, Version 2.0 (the "License");
dcnichols 0:6f07db1b8cdc 13 * you may not use this file except in compliance with the License.
dcnichols 0:6f07db1b8cdc 14 * You may obtain a copy of the License at
dcnichols 0:6f07db1b8cdc 15 *
dcnichols 0:6f07db1b8cdc 16 * http://www.apache.org/licenses/LICENSE-2.0
dcnichols 0:6f07db1b8cdc 17 *
dcnichols 0:6f07db1b8cdc 18 * Unless required by applicable law or agreed to in writing, software
dcnichols 0:6f07db1b8cdc 19 * distributed under the License is distributed on an "AS IS" BASIS,
dcnichols 0:6f07db1b8cdc 20 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
dcnichols 0:6f07db1b8cdc 21 * See the License for the specific language governing permissions and
dcnichols 0:6f07db1b8cdc 22 * limitations under the License.
dcnichols 0:6f07db1b8cdc 23 */
dcnichols 0:6f07db1b8cdc 24
dcnichols 0:6f07db1b8cdc 25 #include "MMA845x.h"
dcnichols 0:6f07db1b8cdc 26 #include "mbed.h"
dcnichols 0:6f07db1b8cdc 27
dcnichols 0:6f07db1b8cdc 28
dcnichols 0:6f07db1b8cdc 29 void MMA845x::disable(void)
dcnichols 0:6f07db1b8cdc 30 {
dcnichols 0:6f07db1b8cdc 31 uint8_t reg_val = 0;
dcnichols 0:6f07db1b8cdc 32 // Reset all registers to POR values
dcnichols 0:6f07db1b8cdc 33 MMA845x::writeRegister(CTRL_REG2, 0xF0); //REG 0x2B
dcnichols 0:6f07db1b8cdc 34 wait(0.05);
dcnichols 0:6f07db1b8cdc 35 do{
dcnichols 0:6f07db1b8cdc 36 // wait for the reset bit to clear
dcnichols 0:6f07db1b8cdc 37 reg_val = MMA845x::readRegister(CTRL_REG2) & 0x40;
dcnichols 0:6f07db1b8cdc 38 }while(reg_val);
dcnichols 0:6f07db1b8cdc 39 MMA845x::writeRegister(CTRL_REG1, 0x00); //REG 0x2A 0x98 = ASLP_RATE: 6.25hz Data Rate: 50hz
dcnichols 0:6f07db1b8cdc 40 }
dcnichols 0:6f07db1b8cdc 41
dcnichols 0:6f07db1b8cdc 42 void MMA845x::setIntMode(int intMode)
dcnichols 0:6f07db1b8cdc 43 {
dcnichols 0:6f07db1b8cdc 44 _intMode = intMode;
dcnichols 0:6f07db1b8cdc 45 }
dcnichols 0:6f07db1b8cdc 46
dcnichols 0:6f07db1b8cdc 47 void MMA845x::interrupt_1(void)
dcnichols 0:6f07db1b8cdc 48 {
dcnichols 0:6f07db1b8cdc 49 //_int1_waiting = true;
dcnichols 0:6f07db1b8cdc 50
dcnichols 0:6f07db1b8cdc 51 uint8_t reg_int_sts;
dcnichols 0:6f07db1b8cdc 52 uint8_t reg_sts;
dcnichols 0:6f07db1b8cdc 53 uint8_t reg_pulse_sts;
dcnichols 0:6f07db1b8cdc 54 uint8_t reg_motion_sts;
dcnichols 0:6f07db1b8cdc 55 char reg_data[3][2] = { 0 };
dcnichols 0:6f07db1b8cdc 56 int16_t values[3] = { 0 };
dcnichols 0:6f07db1b8cdc 57 float g_values[3] = { 0 };
dcnichols 0:6f07db1b8cdc 58 reg_int_sts = MMA845x::readRegister(INT_SOURCE); //REG 0x0C
dcnichols 0:6f07db1b8cdc 59 if((reg_int_sts & 0x01)) //Mask register read with SRC_DRDY bit
dcnichols 0:6f07db1b8cdc 60 {
dcnichols 0:6f07db1b8cdc 61 printf("Int1:");
dcnichols 0:6f07db1b8cdc 62 printf(" Data Ready");
dcnichols 0:6f07db1b8cdc 63 reg_sts = MMA845x::readRegister(STATUS); //REG 0x00
dcnichols 0:6f07db1b8cdc 64
dcnichols 0:6f07db1b8cdc 65 reg_pulse_sts = MMA845x::readRegister(PULSE_SRC); //REG 0x22
dcnichols 0:6f07db1b8cdc 66
dcnichols 0:6f07db1b8cdc 67 reg_data[0][0] = MMA845x::readRegister(OUT_X_MSB); //REG 0x01
dcnichols 0:6f07db1b8cdc 68 reg_data[0][1] = MMA845x::readRegister(OUT_X_LSB); //REG 0x02
dcnichols 0:6f07db1b8cdc 69 reg_data[1][0] = MMA845x::readRegister(OUT_Y_MSB); //REG 0x03
dcnichols 0:6f07db1b8cdc 70 reg_data[1][1] = MMA845x::readRegister(OUT_Y_LSB); //REG 0x04
dcnichols 0:6f07db1b8cdc 71 reg_data[2][0] = MMA845x::readRegister(OUT_Z_MSB); //REG 0x05
dcnichols 0:6f07db1b8cdc 72 reg_data[2][1] = MMA845x::readRegister(OUT_Z_LSB); //REG 0x06
dcnichols 0:6f07db1b8cdc 73 //printf(" STATUS: 0x%02X X: %d %d Y: %d %d Z: %d %d\n\r", reg_sts, reg_data[0][0], reg_data[0][1], reg_data[1][0], reg_data[1][1], reg_data[2][0], reg_data[2][1]);
dcnichols 0:6f07db1b8cdc 74
dcnichols 0:6f07db1b8cdc 75 values[0] = ((reg_data[0][0] * 256) + ((unsigned short) reg_data[0][1]));
dcnichols 0:6f07db1b8cdc 76 values[1] = ((reg_data[1][0] * 256) + ((unsigned short) reg_data[1][1]));
dcnichols 0:6f07db1b8cdc 77 values[2] = ((reg_data[2][0] * 256) + ((unsigned short) reg_data[2][1]));
dcnichols 0:6f07db1b8cdc 78
dcnichols 0:6f07db1b8cdc 79 g_values[0] = ((float) values[0]) / 16384.0;
dcnichols 0:6f07db1b8cdc 80 g_values[1] = ((float) values[1]) / 16384.0;
dcnichols 0:6f07db1b8cdc 81 g_values[2] = ((float) values[2]) / 16384.0;
dcnichols 0:6f07db1b8cdc 82
dcnichols 0:6f07db1b8cdc 83 //printf(" STATUS: 0x%02X X: %d Y: %d Z: %d\n\r", reg_sts, values[0], values[1], values[2]);
dcnichols 0:6f07db1b8cdc 84
dcnichols 0:6f07db1b8cdc 85 if (_intMode == 1)
dcnichols 0:6f07db1b8cdc 86 {
dcnichols 0:6f07db1b8cdc 87 printf(" STATUS: 0x%02X X: %.3f Y: %.3f Z: %.3f", reg_sts, g_values[0], g_values[1], g_values[2]);
dcnichols 0:6f07db1b8cdc 88 }
dcnichols 0:6f07db1b8cdc 89 else
dcnichols 0:6f07db1b8cdc 90 {
dcnichols 0:6f07db1b8cdc 91 int bars = abs( values[0] / 512 );
dcnichols 0:6f07db1b8cdc 92 printf(" X: ");
dcnichols 0:6f07db1b8cdc 93 for( int i = 0; i < bars; i++ )
dcnichols 0:6f07db1b8cdc 94 {
dcnichols 0:6f07db1b8cdc 95 printf(">");
dcnichols 0:6f07db1b8cdc 96 }
dcnichols 0:6f07db1b8cdc 97 }
dcnichols 0:6f07db1b8cdc 98
dcnichols 0:6f07db1b8cdc 99 if (reg_pulse_sts & 0x10)
dcnichols 0:6f07db1b8cdc 100 {
dcnichols 0:6f07db1b8cdc 101 printf(" ***********************************************");
dcnichols 0:6f07db1b8cdc 102 _callbackZAxisPulse.call();
dcnichols 0:6f07db1b8cdc 103 if (reg_pulse_sts & 0x01)
dcnichols 0:6f07db1b8cdc 104 {
dcnichols 0:6f07db1b8cdc 105 printf("--------------");
dcnichols 0:6f07db1b8cdc 106 }
dcnichols 0:6f07db1b8cdc 107 }
dcnichols 0:6f07db1b8cdc 108 printf("\n\r");
dcnichols 0:6f07db1b8cdc 109 }
dcnichols 0:6f07db1b8cdc 110 if (reg_int_sts & 0x08) //Pulse interrupt
dcnichols 0:6f07db1b8cdc 111 {
dcnichols 0:6f07db1b8cdc 112
dcnichols 0:6f07db1b8cdc 113 reg_pulse_sts = MMA845x::readRegister(PULSE_SRC); //REG 0x22
dcnichols 0:6f07db1b8cdc 114 if (reg_pulse_sts & 0x40) //Z-axis event
dcnichols 0:6f07db1b8cdc 115 {
dcnichols 0:6f07db1b8cdc 116
dcnichols 0:6f07db1b8cdc 117 if (reg_pulse_sts & 0x08) //Pulse event was double pulse
dcnichols 0:6f07db1b8cdc 118 {
dcnichols 0:6f07db1b8cdc 119
dcnichols 0:6f07db1b8cdc 120
dcnichols 0:6f07db1b8cdc 121 }
dcnichols 0:6f07db1b8cdc 122 if (reg_pulse_sts & 0x04)//Z-axis pulse direction
dcnichols 0:6f07db1b8cdc 123 {
dcnichols 0:6f07db1b8cdc 124
dcnichols 0:6f07db1b8cdc 125 }
dcnichols 0:6f07db1b8cdc 126 _callbackZAxisPulse.call();
dcnichols 0:6f07db1b8cdc 127
dcnichols 0:6f07db1b8cdc 128 }
dcnichols 0:6f07db1b8cdc 129 }
dcnichols 0:6f07db1b8cdc 130 if (reg_int_sts & 0x04) //Motion interrupt
dcnichols 0:6f07db1b8cdc 131 {
dcnichols 0:6f07db1b8cdc 132
dcnichols 0:6f07db1b8cdc 133 reg_motion_sts = MMA845x::readRegister(FF_MT_SRC); //REG 0x16
dcnichols 0:6f07db1b8cdc 134 if (reg_motion_sts & 0x02) //
dcnichols 0:6f07db1b8cdc 135 {
dcnichols 0:6f07db1b8cdc 136 /*
dcnichols 0:6f07db1b8cdc 137 if (reg_motion_sts & 0x08) //
dcnichols 0:6f07db1b8cdc 138 {
dcnichols 0:6f07db1b8cdc 139
dcnichols 0:6f07db1b8cdc 140
dcnichols 0:6f07db1b8cdc 141 }
dcnichols 0:6f07db1b8cdc 142 if (reg_motion_sts & 0x04)//
dcnichols 0:6f07db1b8cdc 143 {
dcnichols 0:6f07db1b8cdc 144
dcnichols 0:6f07db1b8cdc 145 }
dcnichols 0:6f07db1b8cdc 146 */
dcnichols 0:6f07db1b8cdc 147 _callbackZAxisPulse.call();
dcnichols 0:6f07db1b8cdc 148
dcnichols 0:6f07db1b8cdc 149 }
dcnichols 0:6f07db1b8cdc 150 }
dcnichols 0:6f07db1b8cdc 151 }
dcnichols 0:6f07db1b8cdc 152
dcnichols 0:6f07db1b8cdc 153 /* Call this function when a Z-axis pulse detected
dcnichols 0:6f07db1b8cdc 154 * @param function A C function pointer
dcnichols 0:6f07db1b8cdc 155 */
dcnichols 0:6f07db1b8cdc 156 void MMA845x::attachZAxisPulse( void (*function)(void) )
dcnichols 0:6f07db1b8cdc 157 {
dcnichols 0:6f07db1b8cdc 158 _callbackZAxisPulse.attach( function );
dcnichols 0:6f07db1b8cdc 159 }
dcnichols 0:6f07db1b8cdc 160
dcnichols 0:6f07db1b8cdc 161 void MMA845x::interrupt_handler(void)
dcnichols 0:6f07db1b8cdc 162 {
dcnichols 0:6f07db1b8cdc 163
dcnichols 0:6f07db1b8cdc 164 uint8_t reg_int_sts;
dcnichols 0:6f07db1b8cdc 165 uint8_t reg_sts;
dcnichols 0:6f07db1b8cdc 166 int reg_data[3] = { 0x00, 0x00, 0x00 };
dcnichols 0:6f07db1b8cdc 167 printf("Int1:");
dcnichols 0:6f07db1b8cdc 168 reg_int_sts = MMA845x::readRegister(INT_SOURCE); //REG 0x0C
dcnichols 0:6f07db1b8cdc 169 if((reg_int_sts & 0x01)) //Mask register read with SRC_DRDY bit
dcnichols 0:6f07db1b8cdc 170 {
dcnichols 0:6f07db1b8cdc 171 printf(" Data Ready");
dcnichols 0:6f07db1b8cdc 172 reg_sts = MMA845x::readRegister(STATUS); //REG 0x00
dcnichols 0:6f07db1b8cdc 173 reg_data[0] = MMA845x::readRegister(OUT_X_MSB); //REG 0x01
dcnichols 0:6f07db1b8cdc 174 reg_data[1] = MMA845x::readRegister(OUT_Y_MSB); //REG 0x03
dcnichols 0:6f07db1b8cdc 175 reg_data[2] = MMA845x::readRegister(OUT_Z_MSB); //REG 0x05
dcnichols 0:6f07db1b8cdc 176 printf(" STATUS: 0x%02X X: %d Y: %d Z: %d\n\r", reg_sts, reg_data[0], reg_data[1], reg_data[2]);
dcnichols 0:6f07db1b8cdc 177 }
dcnichols 0:6f07db1b8cdc 178 }
dcnichols 0:6f07db1b8cdc 179
dcnichols 0:6f07db1b8cdc 180 void MMA845x::init(void) const
dcnichols 0:6f07db1b8cdc 181 {
dcnichols 0:6f07db1b8cdc 182 uint8_t reg_val = 0;
dcnichols 0:6f07db1b8cdc 183
dcnichols 0:6f07db1b8cdc 184 _i2c->frequency(400000);
dcnichols 0:6f07db1b8cdc 185
dcnichols 0:6f07db1b8cdc 186 // Reset all registers to POR values
dcnichols 0:6f07db1b8cdc 187 MMA845x::writeRegister(CTRL_REG2, 0x40); //REG 0x2B
dcnichols 0:6f07db1b8cdc 188 do{
dcnichols 0:6f07db1b8cdc 189 // wait for the reset bit to clear
dcnichols 0:6f07db1b8cdc 190 reg_val = MMA845x::readRegister(CTRL_REG2) & 0x40;
dcnichols 0:6f07db1b8cdc 191 }while(reg_val);
dcnichols 0:6f07db1b8cdc 192
dcnichols 0:6f07db1b8cdc 193 // setup the registers that are common among modes
dcnichols 0:6f07db1b8cdc 194 MMA845x::writeRegister(CTRL_REG1, 0xA0); //REG 0x2A 0x98 = ASLP_RATE: 6.25hz Data Rate: 50hz
dcnichols 0:6f07db1b8cdc 195 MMA845x::writeRegister(CTRL_REG2, 0x18); //REG 0x2B Setup for low-power, no auto-sleep
dcnichols 0:6f07db1b8cdc 196 MMA845x::writeRegister(CTRL_REG3, 0x00); //REG 0x2C No interrupts wake device, active low int, push-pull
dcnichols 0:6f07db1b8cdc 197 MMA845x::writeRegister(CTRL_REG4, 0x00); //REG 0x2D
dcnichols 0:6f07db1b8cdc 198 MMA845x::writeRegister(CTRL_REG5, 0xFD); //REG 0x2E All interrupt sources to INT1
dcnichols 0:6f07db1b8cdc 199
dcnichols 0:6f07db1b8cdc 200 MMA845x::writeRegister(XYZ_DATA_CFG, 0x11); //REG 0x0E HPF / scale +/-2,4,8g
dcnichols 0:6f07db1b8cdc 201 MMA845x::writeRegister(HP_FILTER_CUTOFF, 0x00); //REG 0x0F HPF settings
dcnichols 0:6f07db1b8cdc 202
dcnichols 0:6f07db1b8cdc 203 return;
dcnichols 0:6f07db1b8cdc 204 }
dcnichols 0:6f07db1b8cdc 205
dcnichols 0:6f07db1b8cdc 206 void MMA845x::enableDataReadyMode(void) const
dcnichols 0:6f07db1b8cdc 207 {
dcnichols 0:6f07db1b8cdc 208 MMA845x::init();
dcnichols 0:6f07db1b8cdc 209 //MMA845x::writeRegister(SYSMOD, 0x01); //REG 0x0B This register is read only
dcnichols 0:6f07db1b8cdc 210 //MMA845x::writeRegister(INT_SOURCE, 0x01); //REG 0x0C This register is read only
dcnichols 0:6f07db1b8cdc 211 MMA845x::writeRegister(CTRL_REG4, 0x09); //REG 0x2D Enable data ready interrupt
dcnichols 0:6f07db1b8cdc 212
dcnichols 0:6f07db1b8cdc 213
dcnichols 0:6f07db1b8cdc 214
dcnichols 0:6f07db1b8cdc 215 //MMA845x::writeRegister(CTRL_REG1, 0xA3); //REG 0x2A 0xA3 = ASLP_RATE: 6.25hz Data Rate: 50hz, Fast Read, Active mode
dcnichols 0:6f07db1b8cdc 216
dcnichols 0:6f07db1b8cdc 217 MMA845x::writeRegister(XYZ_DATA_CFG, 0x11); //REG 0x0E HPF / scale +/-2,4,8g - Enable HPF
dcnichols 0:6f07db1b8cdc 218 MMA845x::writeRegister(HP_FILTER_CUTOFF, 0x10); //REG 0x0F HPF settings - HPF for pulse on, 0.25Hz cutoff for 12.5rate
dcnichols 0:6f07db1b8cdc 219
dcnichols 0:6f07db1b8cdc 220
dcnichols 0:6f07db1b8cdc 221 MMA845x::writeRegister(PULSE_CFG, 0x41); //REG 0x21 Setup single pulse in x axis
dcnichols 0:6f07db1b8cdc 222 MMA845x::writeRegister(PULSE_THSX, 0x09); //REG 0x21 Setup pulse threshold in x axis
dcnichols 0:6f07db1b8cdc 223 MMA845x::writeRegister(PULSE_TMLT, 0x14); //REG 0x21 Setup single pulse in x axis
dcnichols 0:6f07db1b8cdc 224 MMA845x::writeRegister(PULSE_LTCY, 0x04); //REG 0x21 Setup single latency in x axis
dcnichols 0:6f07db1b8cdc 225
dcnichols 0:6f07db1b8cdc 226
dcnichols 0:6f07db1b8cdc 227 MMA845x::writeRegister(CTRL_REG1, 0xA1); //REG 0x2A 0x98 = ASLP_RATE: 6.25hz Data Rate: 12.5hz, Normal Read, Active mode
dcnichols 0:6f07db1b8cdc 228
dcnichols 0:6f07db1b8cdc 229 }
dcnichols 0:6f07db1b8cdc 230
dcnichols 0:6f07db1b8cdc 231 void MMA845x::enableMotionMode(void) const
dcnichols 0:6f07db1b8cdc 232 {
dcnichols 0:6f07db1b8cdc 233 MMA845x::init();
dcnichols 0:6f07db1b8cdc 234
dcnichols 0:6f07db1b8cdc 235 MMA845x::writeRegister(CTRL_REG4, 0x04); //REG 0x2D Enable pulse interrupt
dcnichols 0:6f07db1b8cdc 236
dcnichols 0:6f07db1b8cdc 237 MMA845x::writeRegister(XYZ_DATA_CFG, 0xF1); //REG 0x0E HPF / scale +/-4g, Enable HPF for output data
dcnichols 0:6f07db1b8cdc 238 MMA845x::writeRegister(HP_FILTER_CUTOFF, 0x00); //REG 0x0F HPF settings - HPF for pulse on, 4Hz cutoff for 100Hz rate
dcnichols 0:6f07db1b8cdc 239
dcnichols 0:6f07db1b8cdc 240 MMA845x::writeRegister(FF_MT_CFG, 0xC8); //REG 0x21 Setup
dcnichols 0:6f07db1b8cdc 241 MMA845x::writeRegister(FF_MT_THS, 0x01); //REG 0x21 Setup
dcnichols 0:6f07db1b8cdc 242 MMA845x::writeRegister(FF_MT_COUNT, 0x5); //REG 0x21 Setup
dcnichols 0:6f07db1b8cdc 243
dcnichols 0:6f07db1b8cdc 244 MMA845x::writeRegister(CTRL_REG2, 0x03); //REG 0x2B Setup for low power mode, no auto-sleep
dcnichols 0:6f07db1b8cdc 245 MMA845x::writeRegister(CTRL_REG1, 0xA1); //REG 0x2A 0x98 = ASLP_RATE: 6.25hz Data Rate: 12.5Hz, Normal Read, Active mode
dcnichols 0:6f07db1b8cdc 246
dcnichols 0:6f07db1b8cdc 247 }
dcnichols 0:6f07db1b8cdc 248
dcnichols 0:6f07db1b8cdc 249 void MMA845x::enablePulseMode(void) const
dcnichols 0:6f07db1b8cdc 250 {
dcnichols 0:6f07db1b8cdc 251 MMA845x::init();
dcnichols 0:6f07db1b8cdc 252
dcnichols 0:6f07db1b8cdc 253 MMA845x::writeRegister(CTRL_REG4, 0x08); //REG 0x2D Enable pulse interrupt
dcnichols 0:6f07db1b8cdc 254
dcnichols 0:6f07db1b8cdc 255 MMA845x::writeRegister(XYZ_DATA_CFG, 0xF1); //REG 0x0E HPF / scale +/-2,4,8g - Enable HPF
dcnichols 0:6f07db1b8cdc 256 MMA845x::writeRegister(HP_FILTER_CUTOFF, 0x00); //REG 0x0F HPF settings - HPF for pulse on, 4Hz cutoff for 100Hz rate
dcnichols 0:6f07db1b8cdc 257
dcnichols 0:6f07db1b8cdc 258 MMA845x::writeRegister(PULSE_CFG, 0x50); //REG 0x21 Setup single pulse in z axis
dcnichols 0:6f07db1b8cdc 259 MMA845x::writeRegister(PULSE_THSX, 0x06); //REG 0x21 Setup pulse threshold in x axis
dcnichols 0:6f07db1b8cdc 260 MMA845x::writeRegister(PULSE_THSZ, 0x2F); //REG 0x21 Setup pulse threshold in z axis
dcnichols 0:6f07db1b8cdc 261 MMA845x::writeRegister(PULSE_TMLT, 0x28); //REG 0x21 Setup single pulse
dcnichols 0:6f07db1b8cdc 262 MMA845x::writeRegister(PULSE_LTCY, 0x0D); //REG 0x21 Setup single latency
dcnichols 0:6f07db1b8cdc 263 MMA845x::writeRegister(PULSE_WIND, 0x2D); //REG 0x21 Setup double pulse window
dcnichols 0:6f07db1b8cdc 264
dcnichols 0:6f07db1b8cdc 265 MMA845x::writeRegister(CTRL_REG2, 0x00); //REG 0x2B Setup for normal power mode, no auto-sleep
dcnichols 0:6f07db1b8cdc 266 MMA845x::writeRegister(CTRL_REG1, 0x99); //REG 0x2A 0x98 = ASLP_RATE: 6.25hz Data Rate: 100Hz, Normal Read, Active mode
dcnichols 0:6f07db1b8cdc 267
dcnichols 0:6f07db1b8cdc 268 }
dcnichols 0:6f07db1b8cdc 269
dcnichols 0:6f07db1b8cdc 270 void MMA845x::enableOrientationMode(void) const
dcnichols 0:6f07db1b8cdc 271 {
dcnichols 0:6f07db1b8cdc 272 uint16_t who_am_i = MMA845x::readRegister(WHO_AM_I);
dcnichols 0:6f07db1b8cdc 273 if(who_am_i != MMA8451)
dcnichols 0:6f07db1b8cdc 274 {
dcnichols 0:6f07db1b8cdc 275 error("%s %d: Feature not compatible with the connected device.\n", __FILE__, __LINE__);
dcnichols 0:6f07db1b8cdc 276 }
dcnichols 0:6f07db1b8cdc 277
dcnichols 0:6f07db1b8cdc 278 return;
dcnichols 0:6f07db1b8cdc 279 }
dcnichols 0:6f07db1b8cdc 280
dcnichols 0:6f07db1b8cdc 281 void MMA845x::enableTransitMode(void) const{}
dcnichols 0:6f07db1b8cdc 282 void MMA845x::enableAutoSleepMode(void) const{}
dcnichols 0:6f07db1b8cdc 283
dcnichols 0:6f07db1b8cdc 284 void MMA845x::enableFIFOMode(void) const
dcnichols 0:6f07db1b8cdc 285 {
dcnichols 0:6f07db1b8cdc 286 uint16_t who_am_i = MMA845x::readRegister(WHO_AM_I);
dcnichols 0:6f07db1b8cdc 287 if(who_am_i != MMA8451)
dcnichols 0:6f07db1b8cdc 288 {
dcnichols 0:6f07db1b8cdc 289 error("%s %d: Feature not compatible with the connected device.\n", __FILE__, __LINE__);
dcnichols 0:6f07db1b8cdc 290 }
dcnichols 0:6f07db1b8cdc 291
dcnichols 0:6f07db1b8cdc 292 //MMA845x::writeRegister(
dcnichols 0:6f07db1b8cdc 293
dcnichols 0:6f07db1b8cdc 294 return;
dcnichols 0:6f07db1b8cdc 295 }
dcnichols 0:6f07db1b8cdc 296
dcnichols 0:6f07db1b8cdc 297 uint16_t MMA845x::getX(void) const
dcnichols 0:6f07db1b8cdc 298 {
dcnichols 0:6f07db1b8cdc 299 return _data._x;
dcnichols 0:6f07db1b8cdc 300 }
dcnichols 0:6f07db1b8cdc 301
dcnichols 0:6f07db1b8cdc 302 uint16_t MMA845x::getY(void) const
dcnichols 0:6f07db1b8cdc 303 {
dcnichols 0:6f07db1b8cdc 304 return _data._y;
dcnichols 0:6f07db1b8cdc 305 }
dcnichols 0:6f07db1b8cdc 306
dcnichols 0:6f07db1b8cdc 307 uint16_t MMA845x::getZ(void) const
dcnichols 0:6f07db1b8cdc 308 {
dcnichols 0:6f07db1b8cdc 309 return _data._z;
dcnichols 0:6f07db1b8cdc 310 }
dcnichols 0:6f07db1b8cdc 311
dcnichols 0:6f07db1b8cdc 312 MMA845x_DATA MMA845x::getXYZ(void) const
dcnichols 0:6f07db1b8cdc 313 {
dcnichols 0:6f07db1b8cdc 314 return _data;
dcnichols 0:6f07db1b8cdc 315 }
dcnichols 0:6f07db1b8cdc 316
dcnichols 0:6f07db1b8cdc 317 void MMA845x::writeRegister(uint8_t const reg, uint8_t const data) const
dcnichols 0:6f07db1b8cdc 318 {
dcnichols 0:6f07db1b8cdc 319 char buf[2] = {reg, data};
dcnichols 0:6f07db1b8cdc 320 uint8_t result = 0;
dcnichols 0:6f07db1b8cdc 321
dcnichols 0:6f07db1b8cdc 322 /*
dcnichols 0:6f07db1b8cdc 323 __disable_irq(); // Tickers and other timebase events can jack up the I2C bus for some devices
dcnichols 0:6f07db1b8cdc 324 result = _i2c->write(_i2c_addr, buf, 2);
dcnichols 0:6f07db1b8cdc 325 __enable_irq(); // Just need to block during the transaction
dcnichols 0:6f07db1b8cdc 326 */
dcnichols 0:6f07db1b8cdc 327
dcnichols 0:6f07db1b8cdc 328 result = _i2c->write(_i2c_addr, (const char *)&buf, 2, false);
dcnichols 0:6f07db1b8cdc 329
dcnichols 0:6f07db1b8cdc 330 if(0 != result)
dcnichols 0:6f07db1b8cdc 331 {
dcnichols 0:6f07db1b8cdc 332 error("%s %d: I2c write failed\n", __FILE__, __LINE__);
dcnichols 0:6f07db1b8cdc 333 }
dcnichols 0:6f07db1b8cdc 334
dcnichols 0:6f07db1b8cdc 335 return;
dcnichols 0:6f07db1b8cdc 336 }
dcnichols 0:6f07db1b8cdc 337
dcnichols 0:6f07db1b8cdc 338 uint8_t MMA845x::readRegister(uint8_t const reg) const
dcnichols 0:6f07db1b8cdc 339 {
dcnichols 0:6f07db1b8cdc 340 uint8_t result = 1, data = 0;
dcnichols 0:6f07db1b8cdc 341 /*
dcnichols 0:6f07db1b8cdc 342 __disable_irq(); // Tickers and other timebase events can jack up the I2C bus
dcnichols 0:6f07db1b8cdc 343 _i2c->start();
dcnichols 0:6f07db1b8cdc 344 result &= _i2c->write(_i2c_addr);
dcnichols 0:6f07db1b8cdc 345 result &= _i2c->write(reg);
dcnichols 0:6f07db1b8cdc 346 // issue a repeated start...
dcnichols 0:6f07db1b8cdc 347 _i2c->start();
dcnichols 0:6f07db1b8cdc 348 result &= _i2c->write(_i2c_addr | 0x01);
dcnichols 0:6f07db1b8cdc 349 // read with nak
dcnichols 0:6f07db1b8cdc 350 data = _i2c->read(0);
dcnichols 0:6f07db1b8cdc 351 _i2c->stop();
dcnichols 0:6f07db1b8cdc 352 __enable_irq(); // Just need to block during the transaction
dcnichols 0:6f07db1b8cdc 353 */
dcnichols 0:6f07db1b8cdc 354
dcnichols 0:6f07db1b8cdc 355 result &= _i2c->write(_i2c_addr, (const char *)&reg, 1, true);
dcnichols 0:6f07db1b8cdc 356 result &= _i2c->read(_i2c_addr, (char *)&data, 1);
dcnichols 0:6f07db1b8cdc 357
dcnichols 0:6f07db1b8cdc 358 if(1 != result)
dcnichols 0:6f07db1b8cdc 359 {
dcnichols 0:6f07db1b8cdc 360 //error("%s %d: I2C read failed\n", __FILE__, __LINE__);
dcnichols 0:6f07db1b8cdc 361 }
dcnichols 0:6f07db1b8cdc 362
dcnichols 0:6f07db1b8cdc 363 return data;
dcnichols 0:6f07db1b8cdc 364 }
dcnichols 0:6f07db1b8cdc 365
dcnichols 0:6f07db1b8cdc 366 void MMA845x::registerDump(void) const
dcnichols 0:6f07db1b8cdc 367 {
dcnichols 0:6f07db1b8cdc 368 uint8_t reg_val = 0;
dcnichols 0:6f07db1b8cdc 369 printf("Starting register dump...\n\r");
dcnichols 0:6f07db1b8cdc 370
dcnichols 0:6f07db1b8cdc 371 for(int i=0; i<0x31; i++)
dcnichols 0:6f07db1b8cdc 372 {
dcnichols 0:6f07db1b8cdc 373 reg_val = MMA845x::readRegister(i);
dcnichols 0:6f07db1b8cdc 374 printf("Reg 0x%02x: 0x%02x \n\r", i, reg_val);
dcnichols 0:6f07db1b8cdc 375 }
dcnichols 0:6f07db1b8cdc 376
dcnichols 0:6f07db1b8cdc 377 return;
dcnichols 0:6f07db1b8cdc 378 }
dcnichols 0:6f07db1b8cdc 379