Home | History | Annotate | Download | only in mma7455
      1 /*
      2  * Author: Yevgeniy Kiveisha <yevgeniy.kiveisha (at) intel.com>
      3  * Copyright (c) 2014 Intel Corporation.
      4  *
      5  * Permission is hereby granted, free of charge, to any person obtaining
      6  * a copy of this software and associated documentation files (the
      7  * "Software"), to deal in the Software without restriction, including
      8  * without limitation the rights to use, copy, modify, merge, publish,
      9  * distribute, sublicense, and/or sell copies of the Software, and to
     10  * permit persons to whom the Software is furnished to do so, subject to
     11  * the following conditions:
     12  *
     13  * The above copyright notice and this permission notice shall be
     14  * included in all copies or substantial portions of the Software.
     15  *
     16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
     17  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
     19  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
     20  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
     21  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
     22  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     23  */
     24 
     25 #include <iostream>
     26 #include <string>
     27 #include <stdexcept>
     28 #include <unistd.h>
     29 #include <stdlib.h>
     30 #include <string.h>
     31 #include <pthread.h>
     32 #include <math.h>
     33 
     34 #include "mma7455.h"
     35 
     36 using namespace upm;
     37 
     38 MMA7455::MMA7455 (int bus, int devAddr) : m_i2ControlCtx(bus) {
     39     unsigned char data   = 0;
     40     int           nBytes = 0;
     41 
     42     m_name = "MMA7455";
     43 
     44     m_controlAddr = devAddr;
     45     m_bus = bus;
     46 
     47     mraa::Result error = m_i2ControlCtx.address(m_controlAddr);
     48     if (error != mraa::SUCCESS) {
     49         throw std::runtime_error(std::string(__FUNCTION__) +
     50                                  ": mraa_i2c_address() failed");
     51         return;
     52     }
     53 
     54     // setting GLVL 0x1 (64LSB/g) and MODE 0x1 (Measurement Mode)
     55     data = (BIT (MMA7455_GLVL0) | BIT (MMA7455_MODE0));
     56     error = i2cWriteReg (MMA7455_MCTL, &data, 0x1);
     57     if (error != mraa::SUCCESS) {
     58         throw std::runtime_error(std::string(__FUNCTION__) +
     59                                  ": writing mode register failed");
     60         return;
     61     }
     62 
     63     if (mraa::SUCCESS != calibrate ()) {
     64         throw std::runtime_error(std::string(__FUNCTION__) +
     65                                  ": calibrate() failed");
     66         return;
     67     }
     68 }
     69 
     70 mraa::Result
     71 MMA7455::calibrate () {
     72     mraa::Result error = mraa::SUCCESS;
     73     int i = 0;
     74 
     75     accelData xyz;
     76     xyz.value.x = xyz.value.y = xyz.value.z = 0;
     77 
     78     do {
     79         error = readData (&xyz.value.x, &xyz.value.y, &xyz.value.z);
     80         if (mraa::SUCCESS != error) {
     81             return error;
     82         }
     83 
     84         xyz.value.x += 2 * -xyz.value.x;
     85         xyz.value.y += 2 * -xyz.value.y;
     86         xyz.value.z += 2 * -(xyz.value.z - 64);
     87 
     88         error = i2cWriteReg (MMA7455_XOFFL,  (unsigned char *) &xyz, 0x6);
     89         if (error != mraa::SUCCESS) {
     90             return error;
     91         }
     92 
     93     } while ( ++i < 3 );
     94 
     95     return error;
     96 }
     97 
     98 mraa::Result
     99 MMA7455::readData (short * ptrX, short * ptrY, short * ptrZ) {
    100     accelData xyz;
    101     unsigned char data = 0;
    102     int nBytes = 0;
    103 
    104     /*do {
    105         nBytes = i2cReadReg (MMA7455_STATUS, &data, 0x1);
    106     } while ( !(data & MMA7455_DRDY) && nBytes == mraa::SUCCESS);
    107 
    108     if (nBytes == mraa::SUCCESS) {
    109         std::cout << "NO_GDB :: 1" << std::endl;
    110         return mraa::SUCCESS;
    111     }*/
    112 
    113     nBytes = i2cReadReg (MMA7455_XOUTL, (unsigned char *) &xyz, 0x6);
    114     if (nBytes == 0) {
    115         std::cout << "NO_GDB :: 2" << std::endl;
    116         return mraa::ERROR_UNSPECIFIED;
    117     }
    118 
    119     if (xyz.reg.x_msb & 0x02) {
    120         xyz.reg.x_msb |= 0xFC;
    121     }
    122 
    123     if (xyz.reg.y_msb & 0x02) {
    124         xyz.reg.y_msb |= 0xFC;
    125     }
    126 
    127     if (xyz.reg.z_msb & 0x02) {
    128         xyz.reg.z_msb |= 0xFC;
    129     }
    130 
    131     // The result is the g-force in units of 64 per 'g'.
    132     *ptrX = xyz.value.x;
    133     *ptrY = xyz.value.y;
    134     *ptrZ = xyz.value.z;
    135 
    136     return mraa::SUCCESS;
    137 }
    138 
    139 #ifdef SWIGJAVA
    140 short *MMA7455::readData() {
    141     short *v = new short[3];
    142     readData(&v[0], &v[1], &v[2]);
    143     return v;
    144 }
    145 #endif
    146 
    147 int
    148 MMA7455::i2cReadReg (unsigned char reg, uint8_t *buffer, int len) {
    149     if (mraa::SUCCESS != m_i2ControlCtx.address(m_controlAddr)) {
    150         throw std::runtime_error(std::string(__FUNCTION__) +
    151                                  ": mraa_i2c_address() failed");
    152         return 0;
    153     }
    154 
    155     if (mraa::SUCCESS != m_i2ControlCtx.writeByte(reg)) {
    156         throw std::runtime_error(std::string(__FUNCTION__) +
    157                                  ": mraa_i2c_write_byte() failed");
    158         return 0;
    159     }
    160 
    161     return (int) m_i2ControlCtx.read(buffer, len);
    162 }
    163 
    164 mraa::Result
    165 MMA7455::i2cWriteReg (unsigned char reg, uint8_t *buffer, int len) {
    166     mraa::Result error = mraa::SUCCESS;
    167 
    168     uint8_t data[len + 1];
    169     data[0] = reg;
    170     memcpy(&data[1], buffer, len);
    171 
    172     error = m_i2ControlCtx.address (m_controlAddr);
    173     if (error != mraa::SUCCESS) {
    174         throw std::runtime_error(std::string(__FUNCTION__) +
    175                                  ": mraa_i2c_address() failed");
    176         return error;
    177     }
    178     error = m_i2ControlCtx.write (data, len + 1);
    179     if (error != mraa::SUCCESS) {
    180         throw std::runtime_error(std::string(__FUNCTION__) +
    181                                  ": mraa_i2c_write() failed");
    182         return error;
    183     }
    184 
    185     return error;
    186 }
    187