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
- Committer:
- franzle
- Date:
- 2017-03-15
- Revision:
- 0:ce2396b1c9a1
File content as of revision 0:ce2396b1c9a1:
/* * mbed library program * LIS3DH MEMS motion sensor: 3-axis "nano" accelerometer, made by STMicroelectronics * http://www.st-japan.co.jp/web/jp/catalog/sense_power/FM89/SC444/PF250725 * * Copyright (c) 2014,'15 Kenji Arai / JH1PJL * http://www.page.sannet.ne.jp/kenjia/index.html * http://mbed.org/users/kenjiArai/ * Created: July 14th, 2014 * Revised: December 12th, 2015 * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "LIS3DH.h" 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) { _spi.frequency(4000000); init (data_rate, fullscale); } LIS3DH::LIS3DH (PinName p_mosi, PinName p_miso, PinName p_sclk, PinName p_ssel) : _spi(p_mosi, p_miso, p_sclk), _cs(p_ssel) { _spi.frequency(4000000); init (LIS3DH_DR_NR_LP_50HZ, LIS3DH_FS_8G); } void LIS3DH::readRegs(uint8_t addr, uint8_t * data, int len) { _cs = 0 ; for (int i = 0 ; i < len ; i++ ) { _spi.write((addr+i)|0x80) ; // specify address to read data[i] = _spi.write((addr+i)|0x80) ; } _spi.write(0x00) ; // to terminate read mode _cs = 1 ; } void LIS3DH::writeRegs(uint8_t * data, int len) { _cs = 0 ; for (int i = 0 ; i < len ; i++ ) { _spi.write(data[i]) ; } _cs = 1 ; } void LIS3DH::write_reg(uint8_t addr, uint8_t data8) { uint8_t data[2] ; data[0] = addr ; data[1] = data8 ; writeRegs(data, 2) ; } uint8_t LIS3DH::read_reg(uint8_t addr) { uint8_t data[1] ; readRegs(addr, data, 1) ; return( data[0] ) ; } void LIS3DH::write16(uint8_t addr, uint16_t data16) { uint8_t data[3] ; data[0] = addr ; data[1] = (data16 >> 8) & 0xFF ; data[2] = data16 & 0xFF ; writeRegs(data, 3) ; } uint16_t LIS3DH::read16(uint8_t addr) { uint8_t data[2] ; uint16_t value = 0 ; readRegs(addr, data, 2) ; value = (data[0] << 8) | data[1] ; return( value ) ; } void LIS3DH::init(uint8_t data_rate, uint8_t fullscale) { _spi.frequency(4000000); dt[0] = read_reg(LIS3DH_WHO_AM_I); if (dt[0] == I_AM_LIS3DH) { acc_ready = 1; } else { acc_ready = 0; return; // acc chip is NOT on I2C line then terminate } write_reg(LIS3DH_CTRL_REG1, (0x07|(data_rate << 4))); // Reg.1 write_reg(LIS3DH_CTRL_REG4, (0x08|(fullscale << 4))); // Reg.4 switch (fullscale) { case LIS3DH_FS_2G: fs_factor = LIS3DH_SENSITIVITY_2G; break; case LIS3DH_FS_4G: fs_factor = LIS3DH_SENSITIVITY_4G; break; case LIS3DH_FS_8G: fs_factor = LIS3DH_SENSITIVITY_8G; break; case LIS3DH_FS_16G: fs_factor = LIS3DH_SENSITIVITY_16G; break; default: ; } } void LIS3DH::read_mg_data(float *dt_usr) { uint8_t data[6]; if (acc_ready == 0) { dt_usr[0] = 0; dt_usr[1] = 0; dt_usr[2] = 0; return; } readRegs(LIS3DH_OUT_X_L, data, 6); // change data type #if OLD_REV // Fixed bugs -> (1) unit is not mg but g (2) shift right 4bit = /16 dt_usr[0] = float(short((data[1] << 8) | data[0])) * fs_factor / 15; dt_usr[1] = float(short((data[3] << 8) | data[2])) * fs_factor / 15; dt_usr[2] = float(short((data[5] << 8) | data[4])) * fs_factor / 15; #else dt_usr[0] = float(short((data[1] << 8) | data[0]) >> 4) * fs_factor; dt_usr[1] = float(short((data[3] << 8) | data[2]) >> 4) * fs_factor; dt_usr[2] = float(short((data[5] << 8) | data[4]) >> 4) * fs_factor; #endif } void LIS3DH::read_data(float *dt_usr) { uint8_t data[6]; if (acc_ready == 0) { dt_usr[0] = 0; dt_usr[1] = 0; dt_usr[2] = 0; return; } readRegs(LIS3DH_OUT_X_L, data, 6); // change data type #if OLD_REV // Fixed bugs -> shift right 4bit = /16 (not /15) dt_usr[0] = float(short((data[1] << 8) | data[0])) * fs_factor / 15 * GRAVITY; dt_usr[1] = float(short((data[3] << 8) | data[2])) * fs_factor / 15 * GRAVITY; dt_usr[2] = float(short((data[5] << 8) | data[4])) * fs_factor / 15 * GRAVITY; #else dt_usr[0] = float(short((data[1] << 8) | data[0]) >> 4) * fs_factor * GRAVITY; dt_usr[1] = float(short((data[3] << 8) | data[2]) >> 4) * fs_factor * GRAVITY; dt_usr[2] = float(short((data[5] << 8) | data[4]) >> 4) * fs_factor * GRAVITY; #endif } uint8_t LIS3DH::read_id() { dt[0] = read_reg(LIS3DH_WHO_AM_I); return dt[0]; } uint8_t LIS3DH::data_ready() { if (acc_ready == 1) { //device initialized correctly dt[0] = read_reg(LIS3DH_STATUS_REG_AUX); if (!(dt[0] & 0x01)) { return 0; } } return 1; } void LIS3DH::set_frequency(int hz) { _spi.frequency(hz); }