Jerry Bradshaw
/
mbed-os-test
ddd
Embed:
(wiki syntax)
Show/hide line numbers
LIS2DH.cpp
00001 /******************************************************************************* 00002 * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. 00003 * 00004 * Permission is hereby granted, free of charge, to any person obtaining a 00005 * copy of this software and associated documentation files (the "Software"), 00006 * to deal in the Software without restriction, including without limitation 00007 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 00008 * and/or sell copies of the Software, and to permit persons to whom the 00009 * Software is furnished to do so, subject to the following conditions: 00010 * 00011 * The above copyright notice and this permission notice shall be included 00012 * in all copies or substantial portions of the Software. 00013 * 00014 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 00015 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 00016 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 00017 * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES 00018 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 00019 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 00020 * OTHER DEALINGS IN THE SOFTWARE. 00021 * 00022 * Except as contained in this notice, the name of Maxim Integrated 00023 * Products, Inc. shall not be used except as stated in the Maxim Integrated 00024 * Products, Inc. Branding Policy. 00025 * 00026 * The mere transfer of this software does not imply any licenses 00027 * of trade secrets, proprietary technology, copyrights, patents, 00028 * trademarks, maskwork rights, or any other form of intellectual 00029 * property whatsoever. Maxim Integrated Products, Inc. retains all 00030 * ownership rights. 00031 ******************************************************************************* 00032 */ 00033 00034 #include "LIS2DH.h" 00035 #include "Streaming.h" 00036 #include "Peripherals.h" 00037 00038 void lis2dh_int_handler(void); 00039 /** buffer array to hold fifo contents for packetizing 00040 */ 00041 uint32_t lis2dh_buffer[LIS2DH_MAX_DATA_SIZE]; 00042 00043 static int debug_int_count = 0; 00044 int16_t motion_cached[3]; 00045 LIS2DH *LIS2DH::instance = NULL; 00046 00047 //****************************************************************************** 00048 LIS2DH::LIS2DH(PinName sda, PinName scl, int slaveAddress) : 00049 slaveAddress(slaveAddress) { 00050 i2c = new I2C(sda, scl); 00051 i2c->frequency(400000); 00052 isOwner = true; 00053 instance = this; 00054 } 00055 00056 //****************************************************************************** 00057 LIS2DH::LIS2DH(I2C *i2c, int slaveAddress) : 00058 slaveAddress(slaveAddress) { 00059 this->i2c = i2c; 00060 i2c->frequency(400000); 00061 isOwner = false; 00062 instance = this; 00063 } 00064 00065 //****************************************************************************** 00066 LIS2DH::~LIS2DH(void) { 00067 if (isOwner == true) { 00068 delete i2c; 00069 } 00070 } 00071 00072 //****************************************************************************** 00073 int LIS2DH::writeReg(char reg, char value) { 00074 int result; 00075 char cmdData[2] = {(char)reg, value}; 00076 result = i2c->write(slaveAddress, cmdData, 2); 00077 if (result != 0) 00078 return -1; 00079 return 0; 00080 } 00081 00082 //****************************************************************************** 00083 int LIS2DH::readReg(char reg, char *value) { 00084 int result; 00085 char cmdData[1] = {(char)reg}; 00086 00087 result = i2c->write(slaveAddress, cmdData, 1); 00088 if (result != 0) 00089 return -1; 00090 result = i2c->read(slaveAddress, value, 1); 00091 if (result != 0) 00092 return -1; 00093 return 0; 00094 } 00095 00096 //****************************************************************************** 00097 static void I2c_Reset(uint8_t index, int speed) { 00098 mxc_i2cm_regs_t *regs = MXC_I2CM_GET_I2CM(index); 00099 /* reset module */ 00100 regs->ctrl = MXC_F_I2CM_CTRL_MSTR_RESET_EN; 00101 regs->ctrl = 0; 00102 /* enable tx_fifo and rx_fifo */ 00103 regs->ctrl |= (MXC_F_I2CM_CTRL_TX_FIFO_EN | MXC_F_I2CM_CTRL_RX_FIFO_EN); 00104 } 00105 00106 //****************************************************************************** 00107 // Interrupt handler, this empties the hardware fifo and packetizes it for 00108 // streaming 00109 void LIS2DH::int_handler(void) { 00110 char fifo_src; 00111 int16_t valueX; 00112 int16_t valueY; 00113 int16_t valueZ; 00114 int num; 00115 int index; 00116 00117 I2c_Reset(2, 1); 00118 num = 0; 00119 index = 0; 00120 fifo_src = 0; 00121 while ((fifo_src & 0x20) != 0x20) { 00122 get_motion_fifo(&valueX, &valueY, &valueZ); 00123 lis2dh_buffer[index++] = valueX; 00124 lis2dh_buffer[index++] = valueY; 00125 lis2dh_buffer[index++] = valueZ; 00126 readReg(LIS2DH_FIFO_SRC_REG, &fifo_src); 00127 num++; 00128 if (num >= 32) 00129 break; 00130 } 00131 motion_cached[0] = valueX; 00132 motion_cached[1] = valueY; 00133 motion_cached[2] = valueZ; 00134 00135 StreamPacketUint32(PACKET_LIS2DH, lis2dh_buffer, index); 00136 } 00137 00138 //****************************************************************************** 00139 void LIS2DH::init(void) { 00140 stop(); 00141 configure_interrupt(); 00142 } 00143 00144 //****************************************************************************** 00145 void LIS2DH::configure_interrupt(void) { 00146 // interrupt enabled on INT1, interrupt active low 00147 lis2dh_ctrl_reg6.all = 0; 00148 lis2dh_ctrl_reg6.bit.I2_INT1 = 1; // interrupt 1 function enabled on int1 pin 00149 lis2dh_ctrl_reg6.bit.H_LACTIVE = 1; // interrupt active low 00150 writeReg(LIS2DH_CTRL_REG6, lis2dh_ctrl_reg6.all); 00151 } 00152 00153 //****************************************************************************** 00154 int LIS2DH::initStart(int dataRate, int fifoThreshold) { 00155 __disable_irq(); 00156 00157 configure_interrupt(); 00158 00159 // enable FIFO 00160 lis2dh_ctrl_reg5.all = 0x0; 00161 lis2dh_ctrl_reg5.bit.FIFO_EN = 0x1; 00162 if (writeReg(LIS2DH_CTRL_REG5, lis2dh_ctrl_reg5.all) == -1) { 00163 __enable_irq(); 00164 return -1; 00165 } 00166 00167 // set FIFO to stream mode, trigger select INT1 00168 lis2dh_fifo_ctrl_reg.all = 0x0; 00169 lis2dh_fifo_ctrl_reg.bit.FTH = fifoThreshold; 00170 lis2dh_fifo_ctrl_reg.bit.FM = LIS2DH_FIFOMODE_STREAM; 00171 lis2dh_fifo_ctrl_reg.bit.TR = 0x0; 00172 if (writeReg(LIS2DH_FIFO_CTRL_REG, lis2dh_fifo_ctrl_reg.all) == -1) { 00173 __enable_irq(); 00174 return -1; 00175 } 00176 00177 // set HR (high resolution) 00178 if (writeReg(LIS2DH_CTRL_REG4, 0x8) == -1) { 00179 __enable_irq(); 00180 return -1; 00181 } 00182 00183 // set the data rate, enable all axis 00184 dataRate = dataRate & 0xF; 00185 if (dataRate > 0x9) dataRate = 0x9; 00186 lis2dh_ctrl_reg1.bit.ODR = dataRate; // set the data rate 00187 lis2dh_ctrl_reg1.bit.LPen = 0x0; // disable low power mode 00188 lis2dh_ctrl_reg1.bit.Zen = 0x1; // enable z 00189 lis2dh_ctrl_reg1.bit.Yen = 0x1; // enable y 00190 lis2dh_ctrl_reg1.bit.Xen = 0x1; // enable x 00191 if (writeReg(LIS2DH_CTRL_REG1, lis2dh_ctrl_reg1.all) == -1) { 00192 __enable_irq(); 00193 return -1; 00194 } 00195 00196 // enable watermark interrupt 00197 lis2dh_ctrl_reg3.all = 0x00; 00198 lis2dh_ctrl_reg3.bit.I1_WTM = 0x1; 00199 if (writeReg(LIS2DH_CTRL_REG3, lis2dh_ctrl_reg3.all) == -1) { 00200 __enable_irq(); 00201 return -1; 00202 } 00203 __enable_irq(); 00204 00205 return 0; 00206 } 00207 00208 //****************************************************************************** 00209 int LIS2DH::detect(char *detected) { 00210 char val; 00211 *detected = 0; 00212 if (readReg(LIS2DH_WHO_AM_I, &val) == -1) 00213 return -1; 00214 if (val == LIS2DH_ID) *detected = 1; 00215 return 0; 00216 } 00217 00218 //****************************************************************************** 00219 int LIS2DH::get_motion_cached(int16_t *valueX, int16_t *valueY, 00220 int16_t *valueZ) { 00221 *valueX = motion_cached[0]; 00222 *valueY = motion_cached[1]; 00223 *valueZ = motion_cached[2]; 00224 return 0; 00225 } 00226 00227 //****************************************************************************** 00228 int LIS2DH::get_motion_fifo(int16_t *valueX, int16_t *valueY, int16_t *valueZ) { 00229 char reg = LIS2DH_OUT_X_L | 0x80; 00230 char values[6]; 00231 int i; 00232 00233 reg = LIS2DH_OUT_X_L; 00234 for (i = 0; i < 6; i++) { 00235 if (readReg(reg, &values[i]) != 0) { 00236 return -1; 00237 } 00238 reg++; 00239 } 00240 00241 *valueX = ((short)values[1] << 8) + values[0]; 00242 *valueY = ((short)values[3] << 8) + values[2]; 00243 *valueZ = ((short)values[5] << 8) + values[4]; 00244 motion_cached[0] = *valueX; 00245 motion_cached[1] = *valueY; 00246 motion_cached[2] = *valueZ; 00247 return 0; 00248 } 00249 00250 //****************************************************************************** 00251 // 0x33 = read ID 00252 char LIS2DH::readId(void) { 00253 char val; 00254 readReg(LIS2DH_WHO_AM_I, &val); 00255 return val; 00256 } 00257 00258 //****************************************************************************** 00259 void LIS2DH::stop(void) { 00260 __disable_irq(); 00261 writeReg(LIS2DH_CTRL_REG3, 0x00); // Disable watermark interrupt 00262 writeReg(LIS2DH_CTRL_REG1, 0x00); // Data rate = 0Hz 00263 writeReg(LIS2DH_FIFO_CTRL_REG, 00264 0x00); // set to bypass mode... clears FIFO_SRC_REG 00265 __enable_irq(); 00266 } 00267 00268 //****************************************************************************** 00269 void LIS2DHIntHandler(void) { 00270 char value; 00271 // read the data rate axis enable register, if this is zero then just return, 00272 // we are not ready for interrupts 00273 LIS2DH::instance->readReg(LIS2DH_CTRL_REG1, &value); 00274 if (value == 0x0) { 00275 return; 00276 } 00277 LIS2DH::instance->int_handler(); 00278 }
Generated on Tue Jul 12 2022 21:12:44 by 1.7.2