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

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?

UserRevisionLine numberNew 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 }