LIS3DH through spi
Dependents: SimpleBLE-ObCP_ENSMM_V2019_Test_BLE SimpleBLE-ObCP_ENSMM_V2019_Test_BLE_S Roller_catcher_tests_fonctionnel SimpleBLE-ObCp_test-BLE_envoi ... more
LIS3DH.cpp@0:ce2396b1c9a1, 2017-03-15 (annotated)
- Committer:
- franzle
- Date:
- Wed Mar 15 17:41:22 2017 +0000
- Revision:
- 0:ce2396b1c9a1
Modified librbary for using LIS3DH through spi with enable pin by sw
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
franzle | 0:ce2396b1c9a1 | 1 | /* |
franzle | 0:ce2396b1c9a1 | 2 | * mbed library program |
franzle | 0:ce2396b1c9a1 | 3 | * LIS3DH MEMS motion sensor: 3-axis "nano" accelerometer, made by STMicroelectronics |
franzle | 0:ce2396b1c9a1 | 4 | * http://www.st-japan.co.jp/web/jp/catalog/sense_power/FM89/SC444/PF250725 |
franzle | 0:ce2396b1c9a1 | 5 | * |
franzle | 0:ce2396b1c9a1 | 6 | * Copyright (c) 2014,'15 Kenji Arai / JH1PJL |
franzle | 0:ce2396b1c9a1 | 7 | * http://www.page.sannet.ne.jp/kenjia/index.html |
franzle | 0:ce2396b1c9a1 | 8 | * http://mbed.org/users/kenjiArai/ |
franzle | 0:ce2396b1c9a1 | 9 | * Created: July 14th, 2014 |
franzle | 0:ce2396b1c9a1 | 10 | * Revised: December 12th, 2015 |
franzle | 0:ce2396b1c9a1 | 11 | * |
franzle | 0:ce2396b1c9a1 | 12 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, |
franzle | 0:ce2396b1c9a1 | 13 | * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE |
franzle | 0:ce2396b1c9a1 | 14 | * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, |
franzle | 0:ce2396b1c9a1 | 15 | * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
franzle | 0:ce2396b1c9a1 | 16 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
franzle | 0:ce2396b1c9a1 | 17 | */ |
franzle | 0:ce2396b1c9a1 | 18 | |
franzle | 0:ce2396b1c9a1 | 19 | #include "LIS3DH.h" |
franzle | 0:ce2396b1c9a1 | 20 | |
franzle | 0:ce2396b1c9a1 | 21 | LIS3DH::LIS3DH (PinName p_mosi, PinName p_miso, PinName p_sclk, PinName p_ssel, uint8_t data_rate, uint8_t fullscale) : _spi(p_mosi, p_miso, p_sclk), _cs(p_ssel) |
franzle | 0:ce2396b1c9a1 | 22 | { |
franzle | 0:ce2396b1c9a1 | 23 | _spi.frequency(4000000); |
franzle | 0:ce2396b1c9a1 | 24 | init (data_rate, fullscale); |
franzle | 0:ce2396b1c9a1 | 25 | } |
franzle | 0:ce2396b1c9a1 | 26 | |
franzle | 0:ce2396b1c9a1 | 27 | LIS3DH::LIS3DH (PinName p_mosi, PinName p_miso, PinName p_sclk, PinName p_ssel) : _spi(p_mosi, p_miso, p_sclk), _cs(p_ssel) |
franzle | 0:ce2396b1c9a1 | 28 | { |
franzle | 0:ce2396b1c9a1 | 29 | _spi.frequency(4000000); |
franzle | 0:ce2396b1c9a1 | 30 | init (LIS3DH_DR_NR_LP_50HZ, LIS3DH_FS_8G); |
franzle | 0:ce2396b1c9a1 | 31 | } |
franzle | 0:ce2396b1c9a1 | 32 | |
franzle | 0:ce2396b1c9a1 | 33 | void LIS3DH::readRegs(uint8_t addr, uint8_t * data, int len) { |
franzle | 0:ce2396b1c9a1 | 34 | _cs = 0 ; |
franzle | 0:ce2396b1c9a1 | 35 | for (int i = 0 ; i < len ; i++ ) { |
franzle | 0:ce2396b1c9a1 | 36 | _spi.write((addr+i)|0x80) ; // specify address to read |
franzle | 0:ce2396b1c9a1 | 37 | data[i] = _spi.write((addr+i)|0x80) ; |
franzle | 0:ce2396b1c9a1 | 38 | } |
franzle | 0:ce2396b1c9a1 | 39 | _spi.write(0x00) ; // to terminate read mode |
franzle | 0:ce2396b1c9a1 | 40 | _cs = 1 ; |
franzle | 0:ce2396b1c9a1 | 41 | } |
franzle | 0:ce2396b1c9a1 | 42 | |
franzle | 0:ce2396b1c9a1 | 43 | void LIS3DH::writeRegs(uint8_t * data, int len) { |
franzle | 0:ce2396b1c9a1 | 44 | _cs = 0 ; |
franzle | 0:ce2396b1c9a1 | 45 | for (int i = 0 ; i < len ; i++ ) { |
franzle | 0:ce2396b1c9a1 | 46 | _spi.write(data[i]) ; |
franzle | 0:ce2396b1c9a1 | 47 | } |
franzle | 0:ce2396b1c9a1 | 48 | _cs = 1 ; |
franzle | 0:ce2396b1c9a1 | 49 | } |
franzle | 0:ce2396b1c9a1 | 50 | |
franzle | 0:ce2396b1c9a1 | 51 | void LIS3DH::write_reg(uint8_t addr, uint8_t data8) |
franzle | 0:ce2396b1c9a1 | 52 | { |
franzle | 0:ce2396b1c9a1 | 53 | uint8_t data[2] ; |
franzle | 0:ce2396b1c9a1 | 54 | data[0] = addr ; |
franzle | 0:ce2396b1c9a1 | 55 | data[1] = data8 ; |
franzle | 0:ce2396b1c9a1 | 56 | writeRegs(data, 2) ; |
franzle | 0:ce2396b1c9a1 | 57 | } |
franzle | 0:ce2396b1c9a1 | 58 | |
franzle | 0:ce2396b1c9a1 | 59 | uint8_t LIS3DH::read_reg(uint8_t addr) |
franzle | 0:ce2396b1c9a1 | 60 | { |
franzle | 0:ce2396b1c9a1 | 61 | uint8_t data[1] ; |
franzle | 0:ce2396b1c9a1 | 62 | readRegs(addr, data, 1) ; |
franzle | 0:ce2396b1c9a1 | 63 | return( data[0] ) ; |
franzle | 0:ce2396b1c9a1 | 64 | } |
franzle | 0:ce2396b1c9a1 | 65 | |
franzle | 0:ce2396b1c9a1 | 66 | void LIS3DH::write16(uint8_t addr, uint16_t data16) |
franzle | 0:ce2396b1c9a1 | 67 | { |
franzle | 0:ce2396b1c9a1 | 68 | uint8_t data[3] ; |
franzle | 0:ce2396b1c9a1 | 69 | data[0] = addr ; |
franzle | 0:ce2396b1c9a1 | 70 | data[1] = (data16 >> 8) & 0xFF ; |
franzle | 0:ce2396b1c9a1 | 71 | data[2] = data16 & 0xFF ; |
franzle | 0:ce2396b1c9a1 | 72 | writeRegs(data, 3) ; |
franzle | 0:ce2396b1c9a1 | 73 | } |
franzle | 0:ce2396b1c9a1 | 74 | |
franzle | 0:ce2396b1c9a1 | 75 | uint16_t LIS3DH::read16(uint8_t addr) |
franzle | 0:ce2396b1c9a1 | 76 | { |
franzle | 0:ce2396b1c9a1 | 77 | uint8_t data[2] ; |
franzle | 0:ce2396b1c9a1 | 78 | uint16_t value = 0 ; |
franzle | 0:ce2396b1c9a1 | 79 | readRegs(addr, data, 2) ; |
franzle | 0:ce2396b1c9a1 | 80 | value = (data[0] << 8) | data[1] ; |
franzle | 0:ce2396b1c9a1 | 81 | return( value ) ; |
franzle | 0:ce2396b1c9a1 | 82 | } |
franzle | 0:ce2396b1c9a1 | 83 | |
franzle | 0:ce2396b1c9a1 | 84 | |
franzle | 0:ce2396b1c9a1 | 85 | void LIS3DH::init(uint8_t data_rate, uint8_t fullscale) |
franzle | 0:ce2396b1c9a1 | 86 | { |
franzle | 0:ce2396b1c9a1 | 87 | _spi.frequency(4000000); |
franzle | 0:ce2396b1c9a1 | 88 | dt[0] = read_reg(LIS3DH_WHO_AM_I); |
franzle | 0:ce2396b1c9a1 | 89 | if (dt[0] == I_AM_LIS3DH) { |
franzle | 0:ce2396b1c9a1 | 90 | acc_ready = 1; |
franzle | 0:ce2396b1c9a1 | 91 | } else { |
franzle | 0:ce2396b1c9a1 | 92 | acc_ready = 0; |
franzle | 0:ce2396b1c9a1 | 93 | return; // acc chip is NOT on I2C line then terminate |
franzle | 0:ce2396b1c9a1 | 94 | } |
franzle | 0:ce2396b1c9a1 | 95 | |
franzle | 0:ce2396b1c9a1 | 96 | write_reg(LIS3DH_CTRL_REG1, (0x07|(data_rate << 4))); // Reg.1 |
franzle | 0:ce2396b1c9a1 | 97 | write_reg(LIS3DH_CTRL_REG4, (0x08|(fullscale << 4))); // Reg.4 |
franzle | 0:ce2396b1c9a1 | 98 | |
franzle | 0:ce2396b1c9a1 | 99 | switch (fullscale) { |
franzle | 0:ce2396b1c9a1 | 100 | case LIS3DH_FS_2G: |
franzle | 0:ce2396b1c9a1 | 101 | fs_factor = LIS3DH_SENSITIVITY_2G; |
franzle | 0:ce2396b1c9a1 | 102 | break; |
franzle | 0:ce2396b1c9a1 | 103 | case LIS3DH_FS_4G: |
franzle | 0:ce2396b1c9a1 | 104 | fs_factor = LIS3DH_SENSITIVITY_4G; |
franzle | 0:ce2396b1c9a1 | 105 | break; |
franzle | 0:ce2396b1c9a1 | 106 | case LIS3DH_FS_8G: |
franzle | 0:ce2396b1c9a1 | 107 | fs_factor = LIS3DH_SENSITIVITY_8G; |
franzle | 0:ce2396b1c9a1 | 108 | break; |
franzle | 0:ce2396b1c9a1 | 109 | case LIS3DH_FS_16G: |
franzle | 0:ce2396b1c9a1 | 110 | fs_factor = LIS3DH_SENSITIVITY_16G; |
franzle | 0:ce2396b1c9a1 | 111 | break; |
franzle | 0:ce2396b1c9a1 | 112 | default: |
franzle | 0:ce2396b1c9a1 | 113 | ; |
franzle | 0:ce2396b1c9a1 | 114 | } |
franzle | 0:ce2396b1c9a1 | 115 | } |
franzle | 0:ce2396b1c9a1 | 116 | |
franzle | 0:ce2396b1c9a1 | 117 | void LIS3DH::read_mg_data(float *dt_usr) |
franzle | 0:ce2396b1c9a1 | 118 | { |
franzle | 0:ce2396b1c9a1 | 119 | uint8_t data[6]; |
franzle | 0:ce2396b1c9a1 | 120 | |
franzle | 0:ce2396b1c9a1 | 121 | if (acc_ready == 0) { |
franzle | 0:ce2396b1c9a1 | 122 | dt_usr[0] = 0; |
franzle | 0:ce2396b1c9a1 | 123 | dt_usr[1] = 0; |
franzle | 0:ce2396b1c9a1 | 124 | dt_usr[2] = 0; |
franzle | 0:ce2396b1c9a1 | 125 | return; |
franzle | 0:ce2396b1c9a1 | 126 | } |
franzle | 0:ce2396b1c9a1 | 127 | readRegs(LIS3DH_OUT_X_L, data, 6); |
franzle | 0:ce2396b1c9a1 | 128 | // change data type |
franzle | 0:ce2396b1c9a1 | 129 | #if OLD_REV // Fixed bugs -> (1) unit is not mg but g (2) shift right 4bit = /16 |
franzle | 0:ce2396b1c9a1 | 130 | dt_usr[0] = float(short((data[1] << 8) | data[0])) * fs_factor / 15; |
franzle | 0:ce2396b1c9a1 | 131 | dt_usr[1] = float(short((data[3] << 8) | data[2])) * fs_factor / 15; |
franzle | 0:ce2396b1c9a1 | 132 | dt_usr[2] = float(short((data[5] << 8) | data[4])) * fs_factor / 15; |
franzle | 0:ce2396b1c9a1 | 133 | #else |
franzle | 0:ce2396b1c9a1 | 134 | dt_usr[0] = float(short((data[1] << 8) | data[0]) >> 4) * fs_factor; |
franzle | 0:ce2396b1c9a1 | 135 | dt_usr[1] = float(short((data[3] << 8) | data[2]) >> 4) * fs_factor; |
franzle | 0:ce2396b1c9a1 | 136 | dt_usr[2] = float(short((data[5] << 8) | data[4]) >> 4) * fs_factor; |
franzle | 0:ce2396b1c9a1 | 137 | #endif |
franzle | 0:ce2396b1c9a1 | 138 | } |
franzle | 0:ce2396b1c9a1 | 139 | |
franzle | 0:ce2396b1c9a1 | 140 | void LIS3DH::read_data(float *dt_usr) |
franzle | 0:ce2396b1c9a1 | 141 | { |
franzle | 0:ce2396b1c9a1 | 142 | uint8_t data[6]; |
franzle | 0:ce2396b1c9a1 | 143 | |
franzle | 0:ce2396b1c9a1 | 144 | if (acc_ready == 0) { |
franzle | 0:ce2396b1c9a1 | 145 | dt_usr[0] = 0; |
franzle | 0:ce2396b1c9a1 | 146 | dt_usr[1] = 0; |
franzle | 0:ce2396b1c9a1 | 147 | dt_usr[2] = 0; |
franzle | 0:ce2396b1c9a1 | 148 | return; |
franzle | 0:ce2396b1c9a1 | 149 | } |
franzle | 0:ce2396b1c9a1 | 150 | readRegs(LIS3DH_OUT_X_L, data, 6); |
franzle | 0:ce2396b1c9a1 | 151 | // change data type |
franzle | 0:ce2396b1c9a1 | 152 | #if OLD_REV // Fixed bugs -> shift right 4bit = /16 (not /15) |
franzle | 0:ce2396b1c9a1 | 153 | dt_usr[0] = float(short((data[1] << 8) | data[0])) * fs_factor / 15 * GRAVITY; |
franzle | 0:ce2396b1c9a1 | 154 | dt_usr[1] = float(short((data[3] << 8) | data[2])) * fs_factor / 15 * GRAVITY; |
franzle | 0:ce2396b1c9a1 | 155 | dt_usr[2] = float(short((data[5] << 8) | data[4])) * fs_factor / 15 * GRAVITY; |
franzle | 0:ce2396b1c9a1 | 156 | #else |
franzle | 0:ce2396b1c9a1 | 157 | dt_usr[0] = float(short((data[1] << 8) | data[0]) >> 4) * fs_factor * GRAVITY; |
franzle | 0:ce2396b1c9a1 | 158 | dt_usr[1] = float(short((data[3] << 8) | data[2]) >> 4) * fs_factor * GRAVITY; |
franzle | 0:ce2396b1c9a1 | 159 | dt_usr[2] = float(short((data[5] << 8) | data[4]) >> 4) * fs_factor * GRAVITY; |
franzle | 0:ce2396b1c9a1 | 160 | #endif |
franzle | 0:ce2396b1c9a1 | 161 | } |
franzle | 0:ce2396b1c9a1 | 162 | |
franzle | 0:ce2396b1c9a1 | 163 | uint8_t LIS3DH::read_id() |
franzle | 0:ce2396b1c9a1 | 164 | { |
franzle | 0:ce2396b1c9a1 | 165 | dt[0] = read_reg(LIS3DH_WHO_AM_I); |
franzle | 0:ce2396b1c9a1 | 166 | return dt[0]; |
franzle | 0:ce2396b1c9a1 | 167 | } |
franzle | 0:ce2396b1c9a1 | 168 | |
franzle | 0:ce2396b1c9a1 | 169 | uint8_t LIS3DH::data_ready() |
franzle | 0:ce2396b1c9a1 | 170 | { |
franzle | 0:ce2396b1c9a1 | 171 | if (acc_ready == 1) { //device initialized correctly |
franzle | 0:ce2396b1c9a1 | 172 | dt[0] = read_reg(LIS3DH_STATUS_REG_AUX); |
franzle | 0:ce2396b1c9a1 | 173 | if (!(dt[0] & 0x01)) { |
franzle | 0:ce2396b1c9a1 | 174 | return 0; |
franzle | 0:ce2396b1c9a1 | 175 | } |
franzle | 0:ce2396b1c9a1 | 176 | } |
franzle | 0:ce2396b1c9a1 | 177 | return 1; |
franzle | 0:ce2396b1c9a1 | 178 | } |
franzle | 0:ce2396b1c9a1 | 179 | |
franzle | 0:ce2396b1c9a1 | 180 | void LIS3DH::set_frequency(int hz) |
franzle | 0:ce2396b1c9a1 | 181 | { |
franzle | 0:ce2396b1c9a1 | 182 | _spi.frequency(hz); |
franzle | 0:ce2396b1c9a1 | 183 | } |