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

Revision:
0:ce2396b1c9a1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/LIS3DH.cpp	Wed Mar 15 17:41:22 2017 +0000
@@ -0,0 +1,183 @@
+/*
+ * 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);
+}
\ No newline at end of file