LSM9DS1 SPI

LSM9DS1.cpp

Committer:
771_8bit
Date:
2019-04-25
Revision:
0:cc9489570dd1

File content as of revision 0:cc9489570dd1:

#include "mbed.h"
#include "LSM9DS1.h"

//spi8,はmbedのSPIクラスのインスタンス
LSM9DS1::LSM9DS1(PinName _mosi, PinName _miso, PinName _sclk, PinName _cs_AG, PinName _cs_M) : spi8(_mosi, _miso, _sclk),cs_AG(_cs_AG),cs_M(_cs_M) {
    initSPI();
}

void LSM9DS1::initSPI(void){
    cs_AG = 1; //deselect
    cs_M =1;
    spi8.format(8,3);
    spi8.frequency(10000000);  
}

void LSM9DS1::initAccel(lsm9ds1AccelRange_t range){ 
    // Enable the accelerometer continous
    write8(LSM9DS1_cs_AG, LSM9DS1_REGISTER_CTRL_REG5_XL, 0x38); // enable X Y and Z axis    
    write8(LSM9DS1_cs_AG,LSM9DS1_REGISTER_CTRL_REG6_XL,0xC0 | range); // 1 KHz out data rate, BW set by ODR, 408Hz anti-aliasing 感度設定

    switch (range)
    {
        case LSM9DS1_ACCELRANGE_2G:
            _accel_mg_lsb = LSM9DS1_ACCEL_MG_LSB_2G;
            break;
        case LSM9DS1_ACCELRANGE_4G:
            _accel_mg_lsb = LSM9DS1_ACCEL_MG_LSB_4G;
            break;
        case LSM9DS1_ACCELRANGE_8G:
            _accel_mg_lsb = LSM9DS1_ACCEL_MG_LSB_8G;
            break;    
        case LSM9DS1_ACCELRANGE_16G:
            _accel_mg_lsb =LSM9DS1_ACCEL_MG_LSB_16G;
            break;
    }
}


void LSM9DS1::initGyro(lsm9ds1GyroScale_t scale){
    write8(LSM9DS1_cs_AG,LSM9DS1_REGISTER_CTRL_REG1_G,0xC0 | scale); //感度設定
    
    switch(scale)
    {
        case LSM9DS1_GYROSCALE_245DPS:
            _gyro_dps_digit = LSM9DS1_GYRO_DPS_DIGIT_245DPS;
            break;
        case LSM9DS1_GYROSCALE_500DPS:
            _gyro_dps_digit = LSM9DS1_GYRO_DPS_DIGIT_500DPS;
            break;
        case LSM9DS1_GYROSCALE_2000DPS:
            _gyro_dps_digit = LSM9DS1_GYRO_DPS_DIGIT_2000DPS;
            break;
    }
}

void LSM9DS1::initMag(lsm9ds1MagGain_t gain){
    write8(LSM9DS1_cs_M,LSM9DS1_REGISTER_CTRL_REG1_M,0xFC);
    write8(LSM9DS1_cs_M, LSM9DS1_REGISTER_CTRL_REG2_M, gain ); //感度設定
    write8(LSM9DS1_cs_M,LSM9DS1_REGISTER_CTRL_REG3_M,0x00);
    write8(LSM9DS1_cs_M,LSM9DS1_REGISTER_CTRL_REG4_M,0x0C);

    switch(gain)
    {
        case LSM9DS1_MAGGAIN_4GAUSS:
            _mag_mgauss_lsb = LSM9DS1_MAG_MGAUSS_4GAUSS;
            break;
        case LSM9DS1_MAGGAIN_8GAUSS:
            _mag_mgauss_lsb = LSM9DS1_MAG_MGAUSS_8GAUSS;
            break;
        case LSM9DS1_MAGGAIN_12GAUSS:
            _mag_mgauss_lsb = LSM9DS1_MAG_MGAUSS_12GAUSS;
            break;
        case LSM9DS1_MAGGAIN_16GAUSS:
            _mag_mgauss_lsb = LSM9DS1_MAG_MGAUSS_16GAUSS;
            break;
    }
}

void LSM9DS1::readAccel() {
    // Read the accelerometer

    uint8_t xlo = read8(LSM9DS1_cs_AG,LSM9DS1_REGISTER_OUT_X_L_XL);
    int16_t xhi = read8(LSM9DS1_cs_AG,LSM9DS1_REGISTER_OUT_X_H_XL);
    uint8_t ylo = read8(LSM9DS1_cs_AG,LSM9DS1_REGISTER_OUT_Y_L_XL);
    int16_t yhi = read8(LSM9DS1_cs_AG,LSM9DS1_REGISTER_OUT_Y_H_XL);
    uint8_t zlo = read8(LSM9DS1_cs_AG,LSM9DS1_REGISTER_OUT_Z_L_XL);
    int16_t zhi = read8(LSM9DS1_cs_AG,LSM9DS1_REGISTER_OUT_Z_H_XL);

    // Shift values to create properly formed integer (low byte first)
    xhi <<= 8; xhi |= xlo;
    yhi <<= 8; yhi |= ylo;
    zhi <<= 8; zhi |= zlo;
    accel_x = (xhi * _accel_mg_lsb)/100;
    accel_y = (yhi * _accel_mg_lsb)/100;
    accel_z = (zhi * _accel_mg_lsb)/100;
}

void LSM9DS1::readGyro(){

    uint8_t xlo = read8(LSM9DS1_cs_AG,LSM9DS1_REGISTER_OUT_X_L_G);
    int16_t xhi = read8(LSM9DS1_cs_AG,LSM9DS1_REGISTER_OUT_X_H_G);
    uint8_t ylo = read8(LSM9DS1_cs_AG,LSM9DS1_REGISTER_OUT_Y_L_G);
    int16_t yhi = read8(LSM9DS1_cs_AG,LSM9DS1_REGISTER_OUT_Y_H_G);
    uint8_t zlo = read8(LSM9DS1_cs_AG,LSM9DS1_REGISTER_OUT_Z_L_G);
    int16_t zhi = read8(LSM9DS1_cs_AG,LSM9DS1_REGISTER_OUT_Z_H_G);

    // Shift values to create properly formed integer (low byte first)
    xhi <<= 8; xhi |= xlo;
    yhi <<= 8; yhi |= ylo;
    zhi <<= 8; zhi |= zlo;

    gyro_x = xhi * _gyro_dps_digit;
    gyro_y = yhi * _gyro_dps_digit;
    gyro_z = zhi * _gyro_dps_digit;
}

void LSM9DS1::readMag(){


    uint8_t xlo = read8(LSM9DS1_cs_M,LSM9DS1_REGISTER_OUT_X_L_M);
    int16_t xhi = read8(LSM9DS1_cs_M,LSM9DS1_REGISTER_OUT_X_H_M);
    uint8_t ylo = read8(LSM9DS1_cs_M,LSM9DS1_REGISTER_OUT_Y_L_M);
    int16_t yhi = read8(LSM9DS1_cs_M,LSM9DS1_REGISTER_OUT_Y_H_M);
    uint8_t zlo = read8(LSM9DS1_cs_M,LSM9DS1_REGISTER_OUT_Z_L_M);
    int16_t zhi = read8(LSM9DS1_cs_M,LSM9DS1_REGISTER_OUT_Z_H_M);

    // Shift values to create properly formed integer (low byte first)
    xhi <<= 8; xhi |= xlo;
    yhi <<= 8; yhi |= ylo;
    zhi <<= 8; zhi |= zlo;

    mag_x = xhi * _mag_mgauss_lsb;
    mag_y = yhi * _mag_mgauss_lsb;
    mag_z = zhi * _mag_mgauss_lsb;
}

uint8_t LSM9DS1::whoami(void){
    return read8(LSM9DS1_cs_AG,0x0F);
}

uint8_t LSM9DS1::read8(lsm9ds1ChipSelect_t cs,uint8_t address){
    if(cs == LSM9DS1_cs_AG) cs_AG = 0;
    else if(cs == LSM9DS1_cs_M)  cs_M  = 0;
    spi8.write(address | 0x80); //先頭ビットを1にするとreadモードになる
    uint8_t x = spi8.write(0x00);   //ダミーリードして読み込み
    if(cs == LSM9DS1_cs_AG) cs_AG = 1;
    else if(cs == LSM9DS1_cs_M)  cs_M  = 1;
    return x;
}

void LSM9DS1::write8(lsm9ds1ChipSelect_t cs,uint8_t address,uint8_t data){
    if(cs == LSM9DS1_cs_AG) cs_AG = 0;
    else if(cs == LSM9DS1_cs_M)  cs_M  = 0;
    spi8.write(address);
    spi8.write(data);
    if(cs == LSM9DS1_cs_AG) cs_AG = 1;
    else if(cs == LSM9DS1_cs_M)  cs_M  = 1;
}