MtM+ / BMA250E

Dependents:   MtConnect04S_Bike_Proximity Mt05_MtSense03

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers BMA250E.cpp Source File

BMA250E.cpp

00001 /* Copyright (c) 2016 MtM Technology Corporation, MIT License
00002  *
00003  * Permission is hereby granted, free of charge, to any person obtaining a copy of this software 
00004  * and associated documentation files (the "Software"), to deal in the Software without restriction, 
00005  * including without limitation the rights to use, copy, modify, merge, publish, distribute, 
00006  * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is 
00007  * furnished to do so, subject to the following conditions:
00008  *
00009  * The above copyright notice and this permission notice shall be included in all copies or 
00010  * substantial portions of the Software.
00011  *
00012  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 
00013  * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
00014  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 
00015  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
00016  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00017  */
00018 #include "BMA250E.h"
00019 
00020 /******************************* 
00021  * Public methods
00022  *******************************/
00023 BMA250E::BMA250E(PinName i2c_sda, PinName i2c_scl, PinName interrupt1_pinname, PinName interrupt2_pinname,uint8_t range, uint8_t bandwith)
00024     : i2c_(i2c_sda, i2c_scl), 
00025       interrupt1_pinname_(interrupt1_pinname),
00026       interrupt1_(interrupt1_pinname),
00027       interrupt2_pinname_(interrupt2_pinname),  
00028       interrupt2_(interrupt2_pinname),
00029       range_(range), bandwith_(bandwith) {
00030           
00031     /* Basic */
00032     RegWrite(0x14, 0xB6);        // softreset
00033     RegWrite(0x0F, range_);      // range
00034     RegWrite(0x10, bandwith_);   // bandwidth
00035     
00036     /* Interrupt */
00037     RegWrite(0x16, 0x00);   // Disable all interrupts
00038     RegWrite(0x17, 0x00);   // 
00039     RegWrite(0x20, 0x00);   // int1_od(PP), int1_lvl(Low active), int2_od(PP), int2a_lvl(Low active)
00040     RegWrite(0x21, 0x80);   // reset_int, latch_int(non_latched)
00041 }
00042 
00043 void BMA250E::ReadXYZ(int16_t *xyz) {
00044     char val[6];
00045 
00046     /* Read raw data */
00047     RegRead(0x02, val, sizeof(val));
00048     xyz[0] = ((int16_t)val[1] << 8) | (val[0] & 0xC0);
00049     xyz[1] = ((int16_t)val[3] << 8) | (val[2] & 0xC0);
00050     xyz[2] = ((int16_t)val[5] << 8) | (val[4] & 0xC0);
00051 
00052     /* Align right */
00053     xyz[0] >>= 6;
00054     xyz[1] >>= 6;
00055     xyz[2] >>= 6;
00056     
00057 }
00058 
00059 void BMA250E::NewData(void(*fptr)(void)) {
00060     // TODO
00061 }
00062 void BMA250E::AnyMotion(void(*fptr)(void)) {
00063     // TODO
00064 }
00065 void BMA250E::TapSening(void(*fptr)(void), bool double_tap) {
00066     RegWrite(0x2A, 0x04);   // tap_quiet(30ms), tap_shock(50ms), tap_dur(250ms)
00067     RegWrite(0x2B, 0x0A);   // tap_samp(2samples), tap_th(0x0A)
00068 
00069     if (interrupt1_pinname_ != NC) {
00070         /* Interrupt 1 */
00071         if (double_tap) {
00072             /* Double tap */
00073             RegReadModifyWrite(0x19, 0x30, 0x10);   // int1_d_tap
00074             RegReadModifyWrite(0x16, 0x30, 0x10);   // d_tap_en
00075         } else {
00076             /* Single tap */
00077             RegReadModifyWrite(0x19, 0x30, 0x20);   // int1_s_tap
00078             RegReadModifyWrite(0x16, 0x30, 0x20);   // s_tap_en
00079         }
00080         interrupt1_.mode(PullUp);
00081         interrupt1_.fall(fptr);
00082     }
00083     if (interrupt2_pinname_ != NC) {
00084         /* Interrupt 2 */
00085         if (double_tap) {
00086             /* Double tap */
00087             RegReadModifyWrite(0x1B, 0x30, 0x10);   // int2_d_tap
00088             RegReadModifyWrite(0x16, 0x30, 0x10);   // d_tap_en
00089         } else {
00090             /* Single tap */
00091             RegReadModifyWrite(0x1B, 0x30, 0x20);   // int2_s_tap
00092             RegReadModifyWrite(0x16, 0x30, 0x20);   // s_tap_en
00093         }
00094         interrupt2_.mode(PullUp);
00095         interrupt2_.fall(fptr);
00096     }
00097 }
00098 void BMA250E::OrientationRecognition(void(*fptr)(void)) {
00099     // TODO
00100 }
00101 void BMA250E::FlatDetection(void(*fptr)(void)) {
00102     // TODO
00103 }
00104 void BMA250E::LowHighGDetection(void(*fptr)(void), bool high_g) {
00105     // TODO
00106 }
00107 void BMA250E::ShakeDetection(void(*fptr)(void)) {
00108     RegWrite(0x28, 0x64);   // slope_th(100)
00109 
00110     if (interrupt1_pinname_ != NC) {
00111         /* Interrupt 1 */
00112         RegReadModifyWrite(0x19, 0x04, 0x04);   // int1_slope
00113         RegReadModifyWrite(0x16, 0x07, 0x07);   // slope_en_z/y/x
00114         interrupt1_.mode(PullUp);
00115         interrupt1_.fall(fptr);
00116     }
00117     if (interrupt2_pinname_ != NC) {
00118         /* Interrupt 2 */
00119         RegReadModifyWrite(0x1B, 0x04, 0x04);   // int2_slope
00120         RegReadModifyWrite(0x16, 0x07, 0x07);   // slope_en_z/y/x
00121         interrupt2_.mode(PullUp);
00122         interrupt2_.fall(fptr);
00123     }
00124 }
00125 
00126 void BMA250E::EnterStandbyMode(void)
00127 {
00128     RegReadModifyWrite(0x12, 0x40, 0x40);   // lowpower_mode(1)
00129     RegReadModifyWrite(0x11, 0x80, 0x80);   // suspend(1)
00130 }
00131 
00132 void BMA250E::LeaveStandbyMode(void)
00133 {
00134     RegReadModifyWrite(0x12, 0x40, 0x40);   // lowpower_mode(1)
00135     RegReadModifyWrite(0x11, 0x80, 0x00);   // suspend(0)
00136 }
00137 
00138 /******************************* 
00139  * Private methods
00140  *******************************/
00141 void BMA250E::RegWrite(char reg, char val) {
00142     char data[2];
00143     data[0] = reg;
00144     data[1] = val;
00145     i2c_.write(BMA250E_SLAVE_ADDR, data, 2, 0);
00146 }
00147 
00148 void BMA250E::RegRead(char reg, char *val, int len) {
00149     i2c_.write(BMA250E_SLAVE_ADDR, &reg, 1, 0);
00150     i2c_.read (BMA250E_SLAVE_ADDR, val, len);
00151 }
00152 
00153 void BMA250E::RegReadModifyWrite(char reg, char clr_mask, char set_mask) {
00154     char val;
00155     RegRead (reg, &val, 1);             // Read
00156     val = (val & ~clr_mask) | set_mask; // Modify
00157     RegWrite(reg, val);                 // Write
00158 }