Example #1
0
static int lis3dh_start_dev(struct i2c_client *client, char rate)
{
	int liRet	= 0;
	int liRate	= 0;
	char lcTmp	= 0x0;
	struct lis3dh_data *lis3dh = (struct lis3dh_data *)i2c_get_clientdata(client);
	
	if((int)rate == 5)
	{
		liRate = 3;
	}
	else if((int)rate == 6)
	{
		liRate = 2;
	}
	else
	{
		liRate = 4;
	}

	lcTmp = liRate<<4 | LIS3DH_ACC_ENABLE_ALL_AXES;

	liRet =lis3dh_write_reg(lis3dh->client, CTRL_REG1, lcTmp);
	if (liRet < 0)
	{
		printk(KERN_ERR "lis3dh_start_dev err\n");
	}
	else
	{
		stprintkf("lis3dh_start_dev\n");
	}
	lis3dh_active(client,1);
	enable_irq(client->irq);
	return liRet;
}
Example #2
0
File: lis3dh.c Project: g-vidal/upm
upm_result_t
lis3dh_enable_interrupt_latching(const lis3dh_context dev, bool int1_latch, bool int2_latch)
{
    assert(dev != NULL);

    uint8_t reg = lis3dh_read_reg(dev, LIS3DH_REG_CTRL_REG5);

    if (int1_latch) {
        reg |= LIS3DH_CTRL_REG5_LIR_INT1;
    } else {
        reg &= ~LIS3DH_CTRL_REG5_LIR_INT1;
    }

    if (int2_latch) {
        reg |= LIS3DH_CTRL_REG5_LIR_INT2;
    } else {
        reg &= ~LIS3DH_CTRL_REG5_LIR_INT2;
    }

    if (lis3dh_write_reg(dev, LIS3DH_REG_CTRL_REG5, reg)) {
        printf("%s: failed to set interrupt latching mode\n", __FUNCTION__);
        return UPM_ERROR_OPERATION_FAILED;
    }

    return UPM_SUCCESS;
}
Example #3
0
int lis3dh_init(lis3dh_t *dev, spi_t spi, gpio_t cs_pin, gpio_t int1_pin, gpio_t int2_pin, lis3dh_scale_t scale)
{
    uint8_t in;

    dev->spi = spi;
    dev->cs = cs_pin;
    dev->int1 = int1_pin;
    dev->int2 = int2_pin;
    dev->scale = 0;

    /* CS */
    gpio_init(dev->cs, GPIO_DIR_OUT, GPIO_NOPULL);
    gpio_set(dev->cs);

    if (lis3dh_read_regs(dev, LIS3DH_REG_WHO_AM_I, 1, &in) < 0) {
        /* Communication error */
        return -1;
    }

    if (in != LIS3DH_WHO_AM_I_RESPONSE) {
        /* Chip is not responding correctly */
        return -1;
    }

    /* Set block data update and little endian mode. */
    lis3dh_write_reg(dev, LIS3DH_REG_CTRL_REG4,
                     (LIS3DH_CTRL_REG4_BDU_ENABLE |
                      LIS3DH_CTRL_REG4_BLE_LITTLE_ENDIAN));
    lis3dh_set_scale(dev, scale);
    return 0;
}
Example #4
0
File: lis3dh.c Project: g-vidal/upm
upm_result_t
lis3dh_enable_temperature(const lis3dh_context dev, bool temperature_enable)
{
    assert(dev != NULL);

    // ADC must be enabled for temperature readings to work
    if (temperature_enable && lis3dh_enable_adc(dev, true)) {
        printf("%s: failed to enable ADC - a prerequisite for enabling temperature sensor\n",
               __FUNCTION__);
        return UPM_ERROR_OPERATION_FAILED;
    }

    uint8_t reg = lis3dh_read_reg(dev, LIS3DH_REG_TEMP_CFG_REG);

    if (temperature_enable) {
        reg |= LIS3DH_TEMP_CFG_REG_TEMP_EN;
    } else {
        reg &= ~LIS3DH_TEMP_CFG_REG_TEMP_EN;
    }

    if (lis3dh_write_reg(dev, LIS3DH_REG_TEMP_CFG_REG, reg)) {
        printf("%s: failed to set temperature sensor mode\n", __FUNCTION__);
        return UPM_ERROR_OPERATION_FAILED;
    }

    return UPM_SUCCESS;
}
Example #5
0
File: lis3dh.c Project: g-vidal/upm
upm_result_t
lis3dh_set_odr(const lis3dh_context dev, LIS3DH_ODR_T odr)
{
    assert(dev != NULL);

    bool lp_mode = false;
    uint8_t reg = lis3dh_read_reg(dev, LIS3DH_REG_CTRL_REG1);

    // Zero out ODR bits
    reg &= ~_SHIFTMASK(CTRL_REG1_ODR);

    // We encoded an extra bit in LIS3DH_ODR_T indicating an LP mode. Check for it here.
    if ((int) odr > (int) _MASK(CTRL_REG1_ODR)) {
        lp_mode = true;
    }

    // Mask it off and set it
    odr &= _MASK(CTRL_REG1_ODR);
    reg |= (odr << _SHIFT(CTRL_REG1_ODR));

    // Set the LPEN bit appropriately
    lis3dh_enable_lp_mode(dev, lp_mode);

    // Commit our changes
    if (lis3dh_write_reg(dev, LIS3DH_REG_CTRL_REG1, reg)) {
        printf("%s: failed to set ODR configuration\n", __FUNCTION__);
        return UPM_ERROR_OPERATION_FAILED;
    }

    return UPM_SUCCESS;
}
Example #6
0
File: lis3dh.c Project: g-vidal/upm
upm_result_t
lis3dh_enable_hr_mode(const lis3dh_context dev, bool hr_enable)
{
    assert(dev != NULL);

    uint8_t reg = lis3dh_read_reg(dev, LIS3DH_REG_CTRL_REG4);

    if (hr_enable) {
        // Check whether low power mode is enabled - enabling both LP and HR is not allowed
        uint8_t tmp_reg = lis3dh_read_reg(dev, LIS3DH_REG_CTRL_REG1);
        if (tmp_reg & LIS3DH_CTRL_REG1_LPEN) {
            printf("%s: can't enable high resolution mode, low power mode is already enabled\n",
                   __FUNCTION__);
            return UPM_ERROR_INVALID_PARAMETER;
        } else {
            // We are good - enable high resolution mode
            reg |= LIS3DH_CTRL_REG4_HR;
        }
    } else {
        reg &= ~LIS3DH_CTRL_REG4_HR;
    }

    // Set the temperature sensor scaling factor appropriately.
    // Its max is 10 bit for both normal and HR modes.
    dev->temperatureFactor = 64;

    if (lis3dh_write_reg(dev, LIS3DH_REG_CTRL_REG4, reg)) {
        printf("%s: failed to set high resolution mode\n", __FUNCTION__);
        return UPM_ERROR_OPERATION_FAILED;
    }

    return UPM_SUCCESS;
}
Example #7
0
File: lis3dh.c Project: g-vidal/upm
upm_result_t
lis3dh_enable_adc(const lis3dh_context dev, bool adc_enable)
{
    assert(dev != NULL);

    // BDU mode is a prerequisite
    if (adc_enable && lis3dh_enable_bdu_mode(dev, true)) {
        printf("%s: failed to enable BDU mode - a prerequisite for enabling ADC\n", __FUNCTION__);
        return UPM_ERROR_OPERATION_FAILED;
    }

    uint8_t reg = lis3dh_read_reg(dev, LIS3DH_REG_TEMP_CFG_REG);

    if (adc_enable) {
        reg |= LIS3DH_TEMP_CFG_REG_ADC_EN;
    } else {
        reg &= ~LIS3DH_TEMP_CFG_REG_ADC_EN;
    }

    if (lis3dh_write_reg(dev, LIS3DH_REG_TEMP_CFG_REG, reg)) {
        printf("%s: failed to set ADC mode\n", __FUNCTION__);
        return UPM_ERROR_OPERATION_FAILED;
    }

    return UPM_SUCCESS;
}
Example #8
0
File: lis3dh.c Project: g-vidal/upm
upm_result_t
lis3dh_set_int2_config(const lis3dh_context dev, uint8_t cfg)
{
    assert(dev != NULL);

    if (lis3dh_write_reg(dev, LIS3DH_REG_CTRL_REG6, cfg)) {
        printf("%s: failed to set interrupt 2 configuration\n", __FUNCTION__);
        return UPM_ERROR_OPERATION_FAILED;
    }

    return UPM_SUCCESS;
}
Example #9
0
static int lis3dh_active(struct i2c_client *client,int enable)
{
	int liTmp = 0;
	int liRet = 0;

	liTmp =lis3dh_read_reg(client, CTRL_REG1);
	if(enable)
	{
		liTmp |= LIS3DH_ACC_ENABLE_ALL_AXES;
	}
	else
	{
		liTmp = 0x08;
	}
	
	liRet =lis3dh_write_reg(client, CTRL_REG1, liTmp);
	
	return liRet;
}
Example #10
0
File: lis3dh.c Project: g-vidal/upm
upm_result_t
lis3dh_set_interrupt_active_high(const lis3dh_context dev, bool high)
{
    assert(dev != NULL);

    uint8_t reg = lis3dh_read_reg(dev, LIS3DH_REG_CTRL_REG6);

    if (high) {
        reg &= ~LIS3DH_CTRL_REG6_INT_POLARITY;
    } else {
        reg |= LIS3DH_CTRL_REG6_INT_POLARITY;
    }

    if (lis3dh_write_reg(dev, LIS3DH_REG_CTRL_REG6, reg)) {
        printf("%s: failed to set interrupt polarity mode\n", __FUNCTION__);
        return UPM_ERROR_OPERATION_FAILED;
    }

    return UPM_SUCCESS;
}
Example #11
0
File: lis3dh.c Project: g-vidal/upm
upm_result_t
lis3dh_enable_hp_filtering(const lis3dh_context dev, bool filter)
{
    assert(dev != NULL);

    uint8_t reg = lis3dh_read_reg(dev, LIS3DH_REG_CTRL_REG2);

    if (filter) {
        reg |= LIS3DH_CTRL_REG2_FDS;
    } else {
        reg &= ~LIS3DH_CTRL_REG2_FDS;
    }

    if (lis3dh_write_reg(dev, LIS3DH_REG_CTRL_REG2, reg)) {
        printf("%s: failed to set HP filter mode\n", __FUNCTION__);
        return UPM_ERROR_OPERATION_FAILED;
    }

    return UPM_SUCCESS;
}
Example #12
0
File: lis3dh.c Project: g-vidal/upm
upm_result_t
lis3dh_enable_bdu_mode(const lis3dh_context dev, bool bdu_enable)
{
    assert(dev != NULL);

    uint8_t reg = lis3dh_read_reg(dev, LIS3DH_REG_CTRL_REG4);

    if (bdu_enable) {
        reg |= LIS3DH_CTRL_REG4_BDU;
    } else {
        reg &= ~LIS3DH_CTRL_REG4_BDU;
    }

    if (lis3dh_write_reg(dev, LIS3DH_REG_CTRL_REG4, reg)) {
        printf("%s: failed to set BDU mode\n", __FUNCTION__);
        return UPM_ERROR_OPERATION_FAILED;
    }

    return UPM_SUCCESS;
}
Example #13
0
File: lis3dh.c Project: g-vidal/upm
upm_result_t
lis3dh_set_full_scale(const lis3dh_context dev, LIS3DH_FS_T fs)
{
    assert(dev != NULL);

    uint8_t reg = lis3dh_read_reg(dev, LIS3DH_REG_CTRL_REG4);

    // Mask out FS bits, add our own
    reg &= ~_SHIFTMASK(CTRL_REG4_FS);
    reg |= (fs << _SHIFT(CTRL_REG4_FS));

    if (lis3dh_write_reg(dev, LIS3DH_REG_CTRL_REG4, reg)) {
        printf("%s: failed to set FS configuration\n", __FUNCTION__);
        return UPM_ERROR_OPERATION_FAILED;
    }

    // Basic sensitivity in g/LSB, calculated for a full 16b resolution.
    switch (fs) {
        case LIS3DH_FS_2G:
            // (2*2) / 2^16
            dev->accScale = 0.000061;
            break;

        case LIS3DH_FS_4G:
            // (4*2) / 2^16
            dev->accScale = 0.000122;
            break;

        case LIS3DH_FS_8G:
            // (8*2) / 2^16
            dev->accScale = 0.000244;
            break;

        case LIS3DH_FS_16G:
            // (16*2) / 2^16
            dev->accScale = 0.000488;
            break;
    }

    return UPM_SUCCESS;
}
Example #14
0
/**
 * @brief Write (both set and clear) bits of an 8-bit register on the LIS3DH.
 *
 * @param[in]  addr         Register address on the LIS3DH.
 * @param[in]  mask         Bitmask for the bits to modify.
 * @param[in]  values       The values to write to the masked bits.
 *
 * @return                  0 on success
 * @return                  -1 on error
 */
static inline int
lis3dh_write_bits(const lis3dh_t *dev, const lis3dh_reg_t reg, const uint8_t mask,
                  const uint8_t values)
{
    uint8_t tmp;

    if (lis3dh_read_regs(dev, reg, 1, &tmp) < 0) {
        /* Communication error */
        return -1;
    }

    tmp &= ~mask;
    tmp |= (values & mask);

    if (lis3dh_write_reg(dev, reg, tmp) < 0) {
        /* Communication error */
        return -1;
    }

    return 0;
}
Example #15
0
File: lis3dh.c Project: g-vidal/upm
upm_result_t
lis3dh_enable_axes(const lis3dh_context dev,
                   bool x_axis_enable,
                   bool y_axis_enable,
                   bool z_axis_enable)
{
    assert(dev != NULL);

    uint8_t reg = lis3dh_read_reg(dev, LIS3DH_REG_CTRL_REG1);

    // X axis
    if (x_axis_enable) {
        reg |= LIS3DH_CTRL_REG1_XEN;
    } else {
        reg &= ~LIS3DH_CTRL_REG1_XEN;
    }

    // Y axis
    if (y_axis_enable) {
        reg |= LIS3DH_CTRL_REG1_YEN;
    } else {
        reg &= ~LIS3DH_CTRL_REG1_YEN;
    }

    // Z axis
    if (z_axis_enable) {
        reg |= LIS3DH_CTRL_REG1_ZEN;
    } else {
        reg &= ~LIS3DH_CTRL_REG1_ZEN;
    }

    if (lis3dh_write_reg(dev, LIS3DH_REG_CTRL_REG1, reg)) {
        printf("%s: failed to enable axes\n", __FUNCTION__);
        return UPM_ERROR_OPERATION_FAILED;
    }

    return UPM_SUCCESS;
}
Example #16
0
File: lis3dh.c Project: g-vidal/upm
upm_result_t
lis3dh_enable_lp_mode(const lis3dh_context dev, bool lp_enable)
{
    assert(dev != NULL);

    uint8_t reg = lis3dh_read_reg(dev, LIS3DH_REG_CTRL_REG1);

    if (lp_enable) {
        // Check whether high resolution mode is enabled - enabling both LP and HR is not allowed
        uint8_t tmp_reg = lis3dh_read_reg(dev, LIS3DH_REG_CTRL_REG4);
        if (tmp_reg & LIS3DH_CTRL_REG4_HR) {
            printf("%s: can't enable low power mode, high resolution mode is already enabled\n",
                   __FUNCTION__);
            return UPM_ERROR_INVALID_PARAMETER;
        } else {
            // We are good - enable low power mode
            reg |= LIS3DH_CTRL_REG1_LPEN;
            // Set temperatureFactor according to LP mode bit width (8b).
            // This is needed to account for left alignment of the temperature data.
            // We have to shift the data right (== divide by a factor in case of float)
            // to eliminate "dead" bits.
            dev->temperatureFactor = 256;
        }
    } else {
        reg &= ~LIS3DH_CTRL_REG1_LPEN;
        // Set temperatureFactor according to Normal mode bit width (10b)
        dev->temperatureFactor = 64;
    }

    if (lis3dh_write_reg(dev, LIS3DH_REG_CTRL_REG1, reg)) {
        printf("%s: failed to set low power mode\n", __FUNCTION__);
        return UPM_ERROR_OPERATION_FAILED;
    }

    return UPM_SUCCESS;
}
Example #17
0
static int lis3dh_init_device(struct lis3dh_data *lis3dh)
{
	int liRet =-1;

	memset(lis3dh->resume_state, 0, ARRAY_SIZE(lis3dh->resume_state));
	lis3dh->resume_state[RES_CTRL_REG1]		= LIS3DH_ACC_ENABLE_ALL_AXES;
	lis3dh->resume_state[RES_CTRL_REG2]		= 0x00;
	lis3dh->resume_state[RES_CTRL_REG3]		= 0x40; 
	lis3dh->resume_state[RES_CTRL_REG4]		= 0x08;
	lis3dh->resume_state[RES_CTRL_REG5]		= 0x08;
	lis3dh->resume_state[RES_CTRL_REG6]		= 0x40; 
	lis3dh->resume_state[RES_TEMP_CFG_REG]	= 0x00;
	lis3dh->resume_state[RES_FIFO_CTRL_REG] = 0x00;
	lis3dh->resume_state[RES_INT_CFG1]		= 0xFF;
	lis3dh->resume_state[RES_INT_THS1]		= 0x7F; 
	lis3dh->resume_state[RES_INT_DUR1]		= 0x7F; //0x00->ox7f
	lis3dh->resume_state[RES_TT_CFG]		= 0x00;
	lis3dh->resume_state[RES_TT_THS] 		= 0x00;
	lis3dh->resume_state[RES_TT_LIM] 		= 0x00;
	lis3dh->resume_state[RES_TT_TLAT]		= 0x00;
	lis3dh->resume_state[RES_TT_TW]			= 0x00;
	
	liRet =lis3dh_write_reg(lis3dh->client, CTRL_REG1, lis3dh->resume_state[RES_CTRL_REG1]);
	if (liRet < 0)
	{
		printk("RES_CTRL_REG1 err\n");
		return 0;
	}
	else
	{
		//nothing
	}

	liRet =lis3dh_write_reg(lis3dh->client, TEMP_CFG_REG, lis3dh->resume_state[RES_TEMP_CFG_REG]);
	if (liRet < 0)
	{
		printk("TEMP_CFG_REG err\n");
		return 0;
	}
	else
	{
		//nothing
	}

	liRet =lis3dh_write_reg(lis3dh->client, FIFO_CTRL_REG, lis3dh->resume_state[RES_FIFO_CTRL_REG]);
	if(liRet < 0)
	{
		printk("FIFO_CTRL_REG err\n");
		return 0;
	}
	else
	{
		//nothing
	}
	
	liRet =lis3dh_write_reg(lis3dh->client, TT_THS, lis3dh->resume_state[RES_TT_THS]);
	liRet =lis3dh_write_reg(lis3dh->client, TT_LIM, lis3dh->resume_state[RES_TT_LIM]);
	liRet =lis3dh_write_reg(lis3dh->client, TT_TLAT, lis3dh->resume_state[RES_TT_TLAT]);
	liRet =lis3dh_write_reg(lis3dh->client, TT_TW, lis3dh->resume_state[RES_TT_TW]);
	if(liRet < 0)
	{
		printk("I2C_AUTO_INCREMENT err\n");
		return 0;
	}
	else
	{
		//nothing
	}

	liRet =lis3dh_write_reg(lis3dh->client, TT_CFG, lis3dh->resume_state[RES_TT_CFG]);
	if(liRet < 0)
	{
		printk("TT_CFG err\n");
		return 0;
	}
	else
	{
		//nothing
	}
	
	liRet =lis3dh_write_reg(lis3dh->client, INT_THS1, lis3dh->resume_state[RES_INT_THS1]);
	liRet =lis3dh_write_reg(lis3dh->client, INT_DUR1, lis3dh->resume_state[RES_INT_DUR1]);
	if(liRet < 0)
	{
		printk("I2C_AUTO_INCREMENT err\n");
		return 0;
	}
	else
	{
		//nothing
	}

	liRet =lis3dh_write_reg(lis3dh->client, INT_CFG1, lis3dh->resume_state[RES_INT_CFG1]);
	if(liRet < 0)
	{
		printk("INT_CFG1 err\n");
		return 0;
	}
	else
	{
		//nothing
	}
	
	liRet =lis3dh_write_reg(lis3dh->client, CTRL_REG2, lis3dh->resume_state[RES_CTRL_REG2]);
	liRet =lis3dh_write_reg(lis3dh->client, CTRL_REG3, lis3dh->resume_state[RES_CTRL_REG3]);
	liRet =lis3dh_write_reg(lis3dh->client, CTRL_REG4, lis3dh->resume_state[RES_CTRL_REG4]);
	liRet =lis3dh_write_reg(lis3dh->client, CTRL_REG5, lis3dh->resume_state[RES_CTRL_REG5]);
	liRet =lis3dh_write_reg(lis3dh->client, CTRL_REG6, lis3dh->resume_state[RES_CTRL_REG6]);
	if(liRet < 0)
	{
		printk("I2C_AUTO_INCREMENT err\n");
		return 0;
	}
	else
	{
		//nothing
	}

	return liRet;
}