No changes
Dependencies: BLE_API mbed nRF51822
Fork of SDP_Version3_Abdul by
MMA8452Q.cpp@5:fd83a2ac378e, 2017-02-26 (annotated)
- Committer:
- galism
- Date:
- Sun Feb 26 03:24:30 2017 +0000
- Revision:
- 5:fd83a2ac378e
No changes
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
galism | 5:fd83a2ac378e | 1 | // Library for our MMA8452Q 3-axis accelerometer |
galism | 5:fd83a2ac378e | 2 | // Based on the MMA8452Q Arduino Library by Jim Lindblom (SparkFun Electronics) |
galism | 5:fd83a2ac378e | 3 | |
galism | 5:fd83a2ac378e | 4 | #include "mbed.h" |
galism | 5:fd83a2ac378e | 5 | #include "MMA8452Q.h" |
galism | 5:fd83a2ac378e | 6 | |
galism | 5:fd83a2ac378e | 7 | // Constructor |
galism | 5:fd83a2ac378e | 8 | MMA8452Q::MMA8452Q(PinName sda, PinName scl, int addr) : m_i2c(sda, scl), m_addr(addr) |
galism | 5:fd83a2ac378e | 9 | { |
galism | 5:fd83a2ac378e | 10 | // Initialize members |
galism | 5:fd83a2ac378e | 11 | scale = DEFAULT_FSR; |
galism | 5:fd83a2ac378e | 12 | } |
galism | 5:fd83a2ac378e | 13 | |
galism | 5:fd83a2ac378e | 14 | // Destructor |
galism | 5:fd83a2ac378e | 15 | MMA8452Q::~MMA8452Q() |
galism | 5:fd83a2ac378e | 16 | { |
galism | 5:fd83a2ac378e | 17 | |
galism | 5:fd83a2ac378e | 18 | } |
galism | 5:fd83a2ac378e | 19 | |
galism | 5:fd83a2ac378e | 20 | // Initialization |
galism | 5:fd83a2ac378e | 21 | bool MMA8452Q::init() |
galism | 5:fd83a2ac378e | 22 | { |
galism | 5:fd83a2ac378e | 23 | // Check to make sure the chip's ID matches the factory ID |
galism | 5:fd83a2ac378e | 24 | uint8_t c = readRegister(REG_WHO_AM_I); |
galism | 5:fd83a2ac378e | 25 | if( c != FACTORY_ID ) { |
galism | 5:fd83a2ac378e | 26 | return false; |
galism | 5:fd83a2ac378e | 27 | } |
galism | 5:fd83a2ac378e | 28 | |
galism | 5:fd83a2ac378e | 29 | // Set default scale and data rate |
galism | 5:fd83a2ac378e | 30 | standby(); |
galism | 5:fd83a2ac378e | 31 | setScale(DEFAULT_FSR); |
galism | 5:fd83a2ac378e | 32 | setODR(DEFAULT_ODR); |
galism | 5:fd83a2ac378e | 33 | active(); |
galism | 5:fd83a2ac378e | 34 | |
galism | 5:fd83a2ac378e | 35 | return true; |
galism | 5:fd83a2ac378e | 36 | } |
galism | 5:fd83a2ac378e | 37 | |
galism | 5:fd83a2ac378e | 38 | // Set the full-scale range for x, y, and z data |
galism | 5:fd83a2ac378e | 39 | void MMA8452Q::setScale(uint8_t fsr) |
galism | 5:fd83a2ac378e | 40 | { |
galism | 5:fd83a2ac378e | 41 | uint8_t config = readRegister(REG_XYZ_DATA_CFG); |
galism | 5:fd83a2ac378e | 42 | scale = fsr; |
galism | 5:fd83a2ac378e | 43 | config &= 0xFC; // Mask out FSR bits |
galism | 5:fd83a2ac378e | 44 | fsr = fsr >> 2; // Trick to translate scale to FSR bits |
galism | 5:fd83a2ac378e | 45 | fsr &= 0x03; // Mask out acceptable FSRs |
galism | 5:fd83a2ac378e | 46 | config |= fsr; // Write FSR bits to config byte |
galism | 5:fd83a2ac378e | 47 | writeRegister(REG_XYZ_DATA_CFG, config); // Write config back to register |
galism | 5:fd83a2ac378e | 48 | } |
galism | 5:fd83a2ac378e | 49 | |
galism | 5:fd83a2ac378e | 50 | // Set the Output Data Rate |
galism | 5:fd83a2ac378e | 51 | void MMA8452Q::setODR(uint8_t odr) |
galism | 5:fd83a2ac378e | 52 | { |
galism | 5:fd83a2ac378e | 53 | uint8_t ctrl = readRegister(REG_CTRL_REG1); |
galism | 5:fd83a2ac378e | 54 | ctrl &= 0xCF; // Mask out data rate bits |
galism | 5:fd83a2ac378e | 55 | odr &= 0x07; // Mask out acceptable ODRs |
galism | 5:fd83a2ac378e | 56 | ctrl |= (odr << 3); // Write ODR bits to control byte |
galism | 5:fd83a2ac378e | 57 | writeRegister(REG_CTRL_REG1, ctrl); // Write control back to register |
galism | 5:fd83a2ac378e | 58 | } |
galism | 5:fd83a2ac378e | 59 | |
galism | 5:fd83a2ac378e | 60 | // Set accelerometer into standby mode |
galism | 5:fd83a2ac378e | 61 | void MMA8452Q::standby() |
galism | 5:fd83a2ac378e | 62 | { |
galism | 5:fd83a2ac378e | 63 | uint8_t c = readRegister(REG_CTRL_REG1); |
galism | 5:fd83a2ac378e | 64 | c &= ~(0x01); // Clear bit 0 to go into standby |
galism | 5:fd83a2ac378e | 65 | writeRegister(REG_CTRL_REG1, c); // Write back to CONTROL register |
galism | 5:fd83a2ac378e | 66 | } |
galism | 5:fd83a2ac378e | 67 | |
galism | 5:fd83a2ac378e | 68 | // Set accelerometer into active mode |
galism | 5:fd83a2ac378e | 69 | void MMA8452Q::active() |
galism | 5:fd83a2ac378e | 70 | { |
galism | 5:fd83a2ac378e | 71 | uint8_t c = readRegister(REG_CTRL_REG1); |
galism | 5:fd83a2ac378e | 72 | c |= 0x01; // Set bit 0 to go into active mode |
galism | 5:fd83a2ac378e | 73 | writeRegister(REG_CTRL_REG1, c); // Write back to CONTROL register |
galism | 5:fd83a2ac378e | 74 | } |
galism | 5:fd83a2ac378e | 75 | |
galism | 5:fd83a2ac378e | 76 | // Read X registers |
galism | 5:fd83a2ac378e | 77 | float MMA8452Q::readX() |
galism | 5:fd83a2ac378e | 78 | { |
galism | 5:fd83a2ac378e | 79 | int16_t x = 0; |
galism | 5:fd83a2ac378e | 80 | float cx = 0; |
galism | 5:fd83a2ac378e | 81 | |
galism | 5:fd83a2ac378e | 82 | // Read MSB and LSB from X registers |
galism | 5:fd83a2ac378e | 83 | x = readRegister(OUT_X_MSB); |
galism | 5:fd83a2ac378e | 84 | x = x << 8; |
galism | 5:fd83a2ac378e | 85 | x |= readRegister(OUT_X_LSB); |
galism | 5:fd83a2ac378e | 86 | x = x >> 4; |
galism | 5:fd83a2ac378e | 87 | |
galism | 5:fd83a2ac378e | 88 | // Calculate human readable X |
galism | 5:fd83a2ac378e | 89 | cx = (float)x / (float)2048 * (float)(scale); |
galism | 5:fd83a2ac378e | 90 | |
galism | 5:fd83a2ac378e | 91 | return cx; |
galism | 5:fd83a2ac378e | 92 | } |
galism | 5:fd83a2ac378e | 93 | |
galism | 5:fd83a2ac378e | 94 | // Read Y registers |
galism | 5:fd83a2ac378e | 95 | float MMA8452Q::readY() |
galism | 5:fd83a2ac378e | 96 | { |
galism | 5:fd83a2ac378e | 97 | int16_t y = 0; |
galism | 5:fd83a2ac378e | 98 | float cy = 0; |
galism | 5:fd83a2ac378e | 99 | |
galism | 5:fd83a2ac378e | 100 | // Read MSB and LSB from Y registers |
galism | 5:fd83a2ac378e | 101 | y = readRegister(OUT_Y_MSB); |
galism | 5:fd83a2ac378e | 102 | y = y << 8; |
galism | 5:fd83a2ac378e | 103 | y |= readRegister(OUT_Y_LSB); |
galism | 5:fd83a2ac378e | 104 | y = y >> 4; |
galism | 5:fd83a2ac378e | 105 | |
galism | 5:fd83a2ac378e | 106 | // Calculate human readable Y |
galism | 5:fd83a2ac378e | 107 | cy = (float)y / (float)2048 * (float)(scale); |
galism | 5:fd83a2ac378e | 108 | |
galism | 5:fd83a2ac378e | 109 | return cy; |
galism | 5:fd83a2ac378e | 110 | } |
galism | 5:fd83a2ac378e | 111 | |
galism | 5:fd83a2ac378e | 112 | // Read Z registers |
galism | 5:fd83a2ac378e | 113 | float MMA8452Q::readZ() |
galism | 5:fd83a2ac378e | 114 | { |
galism | 5:fd83a2ac378e | 115 | int16_t z = 0; |
galism | 5:fd83a2ac378e | 116 | float cz = 0; |
galism | 5:fd83a2ac378e | 117 | |
galism | 5:fd83a2ac378e | 118 | // Read MSB and LSB from Z registers |
galism | 5:fd83a2ac378e | 119 | z = readRegister(OUT_Z_MSB); |
galism | 5:fd83a2ac378e | 120 | z = z << 8; |
galism | 5:fd83a2ac378e | 121 | z |= readRegister(OUT_Z_LSB); |
galism | 5:fd83a2ac378e | 122 | z = z >> 4; |
galism | 5:fd83a2ac378e | 123 | |
galism | 5:fd83a2ac378e | 124 | // Calculate human readable Z |
galism | 5:fd83a2ac378e | 125 | cz = (float)z / (float)2048 * (float)(scale); |
galism | 5:fd83a2ac378e | 126 | |
galism | 5:fd83a2ac378e | 127 | return cz; |
galism | 5:fd83a2ac378e | 128 | } |
galism | 5:fd83a2ac378e | 129 | |
galism | 5:fd83a2ac378e | 130 | // Raw read register over I2C |
galism | 5:fd83a2ac378e | 131 | uint8_t MMA8452Q::readRegister(uint8_t reg) |
galism | 5:fd83a2ac378e | 132 | { |
galism | 5:fd83a2ac378e | 133 | uint8_t dev_addr; |
galism | 5:fd83a2ac378e | 134 | uint8_t data; |
galism | 5:fd83a2ac378e | 135 | |
galism | 5:fd83a2ac378e | 136 | // I2C address are bits [6..1] in the transmitted byte, so we shift by 1 |
galism | 5:fd83a2ac378e | 137 | dev_addr = m_addr << 1; |
galism | 5:fd83a2ac378e | 138 | |
galism | 5:fd83a2ac378e | 139 | // Write device address with a trailing 'write' bit |
galism | 5:fd83a2ac378e | 140 | m_i2c.start(); |
galism | 5:fd83a2ac378e | 141 | m_i2c.write(dev_addr & 0xFE); |
galism | 5:fd83a2ac378e | 142 | |
galism | 5:fd83a2ac378e | 143 | // Write register address |
galism | 5:fd83a2ac378e | 144 | m_i2c.write(reg); |
galism | 5:fd83a2ac378e | 145 | |
galism | 5:fd83a2ac378e | 146 | // Write a start bit and device address with a trailing 'read' bit |
galism | 5:fd83a2ac378e | 147 | m_i2c.start(); |
galism | 5:fd83a2ac378e | 148 | m_i2c.write(dev_addr | 0x01); |
galism | 5:fd83a2ac378e | 149 | |
galism | 5:fd83a2ac378e | 150 | // Read single byte from I2C device |
galism | 5:fd83a2ac378e | 151 | data = m_i2c.read(0); |
galism | 5:fd83a2ac378e | 152 | m_i2c.stop(); |
galism | 5:fd83a2ac378e | 153 | |
galism | 5:fd83a2ac378e | 154 | return data; |
galism | 5:fd83a2ac378e | 155 | } |
galism | 5:fd83a2ac378e | 156 | |
galism | 5:fd83a2ac378e | 157 | char MMA8452Q::getMaskedRegister(int addr, char mask) { |
galism | 5:fd83a2ac378e | 158 | char rval = 0; |
galism | 5:fd83a2ac378e | 159 | if(readRegister(addr)) { |
galism | 5:fd83a2ac378e | 160 | return 0; |
galism | 5:fd83a2ac378e | 161 | } |
galism | 5:fd83a2ac378e | 162 | return (rval&mask); |
galism | 5:fd83a2ac378e | 163 | } |
galism | 5:fd83a2ac378e | 164 | |
galism | 5:fd83a2ac378e | 165 | int MMA8452Q::isXYZReady() { |
galism | 5:fd83a2ac378e | 166 | return getMaskedRegister(REG_STATUS ,MMA8452_STATUS_ZYXDR_MASK)>0; |
galism | 5:fd83a2ac378e | 167 | } |
galism | 5:fd83a2ac378e | 168 | |
galism | 5:fd83a2ac378e | 169 | bool MMA8452Q::available(){ |
galism | 5:fd83a2ac378e | 170 | return (readRegister(REG_STATUS) & 0x08) >> 3; |
galism | 5:fd83a2ac378e | 171 | } |
galism | 5:fd83a2ac378e | 172 | |
galism | 5:fd83a2ac378e | 173 | // Raw write data to a register over I2C |
galism | 5:fd83a2ac378e | 174 | void MMA8452Q::writeRegister(uint8_t reg, uint8_t data) |
galism | 5:fd83a2ac378e | 175 | { |
galism | 5:fd83a2ac378e | 176 | uint8_t dev_addr; |
galism | 5:fd83a2ac378e | 177 | |
galism | 5:fd83a2ac378e | 178 | // I2C address are bits [6..1] in the transmitted byte, so we shift by 1 |
galism | 5:fd83a2ac378e | 179 | dev_addr = m_addr << 1; |
galism | 5:fd83a2ac378e | 180 | |
galism | 5:fd83a2ac378e | 181 | // Write device address with a trailing 'write' bit |
galism | 5:fd83a2ac378e | 182 | m_i2c.start(); |
galism | 5:fd83a2ac378e | 183 | m_i2c.write(dev_addr & 0xFE); |
galism | 5:fd83a2ac378e | 184 | |
galism | 5:fd83a2ac378e | 185 | // Write register address |
galism | 5:fd83a2ac378e | 186 | m_i2c.write(reg); |
galism | 5:fd83a2ac378e | 187 | |
galism | 5:fd83a2ac378e | 188 | // Write the data to the register |
galism | 5:fd83a2ac378e | 189 | m_i2c.write(data); |
galism | 5:fd83a2ac378e | 190 | m_i2c.stop(); |
galism | 5:fd83a2ac378e | 191 | } |