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

Files at this revision

API Documentation at this revision

Comitter:
franzle
Date:
Wed Mar 15 17:41:22 2017 +0000
Commit message:
Modified librbary for using LIS3DH through spi with enable pin by sw

Changed in this revision

LIS3DH.cpp Show annotated file Show diff for this revision Revisions of this file
LIS3DH.h Show annotated file Show diff for this revision Revisions of this file
--- /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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/LIS3DH.h	Wed Mar 15 17:41:22 2017 +0000
@@ -0,0 +1,212 @@
+/*
+ * 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.
+ */
+
+#ifndef LIS3DH_H
+#define LIS3DH_H
+
+#include "mbed.h"
+
+//  revision 6 have two bugs, (1) read_mg_data, (2) divided by 15 (16 is coorect value)
+#define OLD_REV             0       // KEEP 0!! (If you set 1, work as old revision)
+
+//   LIS3DH ID
+#define I_AM_LIS3DH            0x33
+
+//  Register's definition
+#define LIS3DH_STATUS_REG_AUX  0x07
+#define LIS3DH_OUT_ADC1_L      0x08
+#define LIS3DH_OUT_ADC1_H      0x09
+#define LIS3DH_OUT_ADC2_L      0x0a
+#define LIS3DH_OUT_ADC2_H      0x0b
+#define LIS3DH_OUT_ADC3_L      0x0c
+#define LIS3DH_OUT_ADC3_H      0x0d
+#define LIS3DH_INT_COUNTER_REG 0x0e
+#define LIS3DH_WHO_AM_I        0x0f
+#define LIS3DH_TEMP_CFG_REG    0x1f
+#define LIS3DH_CTRL_REG1       0x20
+#define LIS3DH_CTRL_REG2       0x21
+#define LIS3DH_CTRL_REG3       0x22
+#define LIS3DH_CTRL_REG4       0x23
+#define LIS3DH_CTRL_REG5       0x24
+#define LIS3DH_CTRL_REG6       0x25
+#define LIS3DH_REFERENCE       0x26
+#define LIS3DH_STATUS_REG      0x27
+#define LIS3DH_OUT_X_L         0x28
+#define LIS3DH_OUT_X_H         0x29
+#define LIS3DH_OUT_Y_L         0x2a
+#define LIS3DH_OUT_Y_H         0x2b
+#define LIS3DH_OUT_Z_L         0x2c
+#define LIS3DH_OUT_Z_H         0x2d
+#define LIS3DH_FIFO_CTRL_REG   0x2e
+#define LIS3DH_FIFO_SRC_REG    0x2f
+#define LIS3DH_INT1_CFG        0x30
+#define LIS3DH_INT1_SOURCE     0x31
+#define LIS3DH_INT1_THS        0x32
+#define LIS3DH_INT1_DURATION   0x33
+#define LIS3DH_CLICK_CFG       0x38
+#define LIS3DH_CLICK_SRC       0x39
+#define LIS3DH_CLICK_THS       0x3a
+#define LIS3DH_TIME_LIMIT      0x3b
+#define LIS3DH_TIME_LATENCY    0x3c
+#define LIS3DH_TIME_WINDOW     0x3d
+
+// Output Data Rate (ODR)
+#define LIS3DH_DR_PWRDWN       0
+#define LIS3DH_DR_NR_LP_1HZ    1
+#define LIS3DH_DR_NR_LP_10HZ   2
+#define LIS3DH_DR_NR_LP_25HZ   3
+#define LIS3DH_DR_NR_LP_50HZ   4
+#define LIS3DH_DR_NR_LP_100HZ  5
+#define LIS3DH_DR_NR_LP_200HZ  6
+#define LIS3DH_DR_NR_LP_400HZ  7
+#define LIS3DH_DR_LP_1R6KHZ    8
+#define LIS3DH_DR_NR_1R25KHZ   9
+
+// Bandwidth (Low pass)
+#define LIS3DH_BW_LOW          0
+#define LIS3DH_BW_M_LOW        1
+#define LIS3DH_BW_M_HI         2
+#define LIS3DH_BW_HI           3
+
+// Low power mode enable/disable
+#define LIS3DH_LP_EN           0
+#define LIS3DH_LP_DIS          1
+
+// Axis control
+#define LIS3DH_X_EN            1
+#define LIS3DH_X_DIS           0
+#define LIS3DH_Y_EN            1
+#define LIS3DH_Y_DIS           0
+#define LIS3DH_Z_EN            1
+#define LIS3DH_Z_DIS           0
+
+// Full Scale
+#define LIS3DH_FS_2G           0
+#define LIS3DH_FS_4G           1
+#define LIS3DH_FS_8G           2
+#define LIS3DH_FS_16G          3
+
+// definition for Nomalization
+#if OLD_REV
+#define LIS3DH_SENSITIVITY_2G  (0.001F)
+#define LIS3DH_SENSITIVITY_4G  (0.002F)
+#define LIS3DH_SENSITIVITY_8G  (0.004F)
+#define LIS3DH_SENSITIVITY_16G (0.012F)
+#else
+#define LIS3DH_SENSITIVITY_2G  1
+#define LIS3DH_SENSITIVITY_4G  2
+#define LIS3DH_SENSITIVITY_8G  4
+#define LIS3DH_SENSITIVITY_16G 12
+#endif
+
+//Gravity at Earth's surface in m/s/s
+#if OLD_REV
+#define GRAVITY                (9.80665F)
+#else
+#define GRAVITY                (9.80665F / 1000)
+#endif
+
+class LIS3DH
+{
+public:
+    /** Configure data pin
+      * @param data MISO MOSI SCLK and CS pins
+      * @param output data rate selection, power down mode, 1Hz to 5KHz
+      * @param full scale selection, +/-2g to +/-16g
+      */
+    LIS3DH(PinName p_mosi, PinName p_miso, PinName p_sclk, PinName p_ssel, uint8_t data_rate, uint8_t fullscale);
+
+    /** Configure data pin
+      * @param data MISO MOSI SCLK and CS pins
+      * @default output data rate selection = 50Hz
+      * @default full scale selection = +/-8g
+      */
+    LIS3DH (PinName p_mosi, PinName p_miso, PinName p_sclk, PinName p_ssel);
+    
+    /** Read a float type data from acc
+      * @param float type of three arry's address, e.g. float dt_usr[3];
+      * @return acc motion data unit: m/s/s(m/s2)
+      * @return dt_usr[0]->x, dt_usr[1]->y, dt_usr[2]->z
+      */
+    void read_data(float *dt_usr);
+
+    /** Read a float type data from acc
+      * @param float type of three arry's address, e.g. float dt_usr[3];
+      * @return acc motion data unit: mg
+      * @return dt_usr[0]->x, dt_usr[1]->y, dt_usr[2]->z
+      */
+    void read_mg_data(float *dt_usr);
+
+    /** Read a acc ID number
+      * @param none
+      * @return if STM MEMS acc, it should be I_AM_ LIS3DH(0x33)
+      */
+    uint8_t read_id();
+
+    /** Read Data Ready flag
+      * @param none
+      * @return 1 = Ready
+      */
+    uint8_t data_ready();
+
+    /** Set I2C clock frequency
+      * @param freq.
+      * @return none
+      */
+    void set_frequency(int hz);
+
+    /** Read register (general purpose)
+      * @param register's address
+      * @return register data
+      */
+    uint8_t read_reg(uint8_t addr);
+
+    /** Write register (general purpose)
+      * @param register's address
+      * @param data
+      * @return none
+      */
+    void write_reg(uint8_t addr, uint8_t data);
+    
+protected:
+    void readRegs(uint8_t addr, uint8_t * data, int len);
+    void writeRegs(uint8_t * data, int len);
+    void write16(uint8_t addr, uint16_t data16);
+    uint16_t read16(uint8_t addr);
+    void init(uint8_t data_rate, uint8_t fullscale);
+
+    void read_reg_data(char *data);
+    SPI _spi;
+    DigitalOut _cs ;
+
+private:
+#if OLD_REV
+    float   fs_factor;  // full scale factor
+#else
+    uint8_t fs_factor;  // full scale factor
+#endif
+    char    dt[2];      // working buffer
+    uint8_t acc_id;     // acc ID
+    uint8_t acc_ready;  // acc is on I2C line = 1, not = 0
+};
+
+#endif      // LIS3DH_H
+
+
+
+