示例#1
0
static int bmg160_read_gyro_xyz(struct bmg160_p *data, struct bmg160_v *gyro)
{
	int ret = 0, i;
	unsigned char temp[READ_DATA_LENTH];

	for (i = 0; i < READ_DATA_LENTH; i++) {
		ret += bmg160_i2c_read(data->client,
				BMG160_RATE_X_LSB_VALUEX__REG + i, &temp[i]);
	}

	temp[0] = BMG160_GET_BITSLICE(temp[0], BMG160_RATE_X_LSB_VALUEX);
	gyro->x = (short)((((short)((signed char)temp[1])) << 8) | (temp[0]));

	temp[2] = BMG160_GET_BITSLICE(temp[2], BMG160_RATE_Y_LSB_VALUEY);
	gyro->y = (short)((((short)((signed char)temp[3])) << 8) | (temp[2]));

	temp[4] = BMG160_GET_BITSLICE(temp[4], BMG160_RATE_Z_LSB_VALUEZ);
	gyro->z = (short)((((short)((signed char)temp[5])) << 8) | (temp[4]));

	remap_sensor_data(gyro->v, data->chip_pos);

	if (data->gyro_dps == BMG160_RANGE_250DPS) {
		gyro->x = gyro->x >> 1;
		gyro->y = gyro->y >> 1;
		gyro->z = gyro->z >> 1;
	} else if (data->gyro_dps == BMG160_RANGE_2000DPS) {
示例#2
0
static int bmg160_get_bw(struct bmg160_p *data, unsigned char *bandwidth)
{
	int ret;
	unsigned char temp;

	ret = bmg160_i2c_read(data->client, BMG160_BW_ADDR__REG, &temp);
	*bandwidth = BMG160_GET_BITSLICE(temp, BMG160_BW_ADDR);

	return ret;
}
示例#3
0
static int bmg160_get_autosleepdur(struct bmg160_p *data,
		unsigned char *duration)
{
	int ret = 0;
	unsigned char temp;

	ret = bmg160_i2c_read(data->client,
			BMG160_MODE_LPM2_ADDR_AUTOSLEEPDUR__REG, &temp);

	*duration = BMG160_GET_BITSLICE(temp,
			BMG160_MODE_LPM2_ADDR_AUTOSLEEPDUR);

	return ret;
}
/*=========================================================================*/
void sns_dd_bmg160_interrupt_handler(
		sns_ddf_handle_t        dd_handle,
		uint32_t                gpio_num,
		sns_ddf_time_t          timestamp)
{
	sns_ddf_status_e status;
	sns_dd_bmg160_state_t *state = (sns_dd_bmg160_state_t *)dd_handle;
	uint8_t int_stat1;
	int in_irq;
	uint8_t f_stat;
	uint8_t f_count;
	uint8_t f_overrun;
	uint8_t int_stat_fifo = 0;
#ifdef BMG160_DEBUG
	uint8_t int_stat_drdy = 0;
#endif // BMG160_DEBUG

	uint8_t dri_mockup_wmi = 0;
	uint8_t downsampling_factor = (state->odr_hw / state->odr_reported);

	uint8_t si_buf_wr;
	uint8_t tmp_r;

	bool    wmi_missing_possible = false;

	BMG160_MSG_3_F(HIGH, "sns_dd_bmg160_interrupt_handler %d %d %d",
			55555550, timestamp, gpio_num);
	if (gpio_num != ((sns_dd_bmg160_state_t*)dd_handle)->gpio_num) {
		return;
	}

	state->ts_irq = timestamp;

#if BMG160_CONFIG_DRI_MOCKUP_WMI
	if ((state->en_fifo_int) && (1 == state->f_wml)) {
		dri_mockup_wmi = 1;
	}
#endif
	if ((state->en_dri) || (dri_mockup_wmi)) {
		//this is to reduce false drdy interrupts rate
		int32_t lapse;
		uint32_t false_irq = false;

		lapse           = ((int32_t)timestamp - (int32_t)state->ts_last_drdy);

		BMG160_MSG_3(HIGH, "sns_dd_bmg160_interrupt_handler [anti_false_irq] <%d %d %d>",
				lapse, state->itvl_drdy - lapse, state->itvl_drdy_tolerance);

		if (lapse < state->itvl_drdy) {
			if ((state->itvl_drdy - lapse) > state->itvl_drdy_tolerance) {
				false_irq = true;
			}
		}

		if (!false_irq) {
			state->num_irq_drdy++;

			if (state->sample_cnt_to_skip_odrc > 0) {
				state->sample_cnt_to_skip_odrc--;
			}

			state->ts_last_drdy = timestamp;
		} else {
			BMG160_MSG_0(HIGH, "sns_dd_bmg160_interrupt_handler [anti_false_irq] false_irq detected");
		}

		if (0 == (state->num_irq_drdy % downsampling_factor)) {
			if (dri_mockup_wmi) {
				status = sns_ddf_smgr_notify_event(state->smgr_handle,
						SNS_DDF_SENSOR_GYRO,
						SNS_DDF_EVENT_FIFO_WM_INT);
			}

			sns_dd_bmg160_get_data_all(state);

			state->f_frames_cache.samples[SDD_GYRO_X].sample = state->data_cache[SDD_GYRO_X];
			state->f_frames_cache.samples[SDD_GYRO_Y].sample = state->data_cache[SDD_GYRO_Y];
			state->f_frames_cache.samples[SDD_GYRO_Z].sample = state->data_cache[SDD_GYRO_Z];

			if (0 >= state->sample_cnt_to_skip_odrc) {
				state->f_frames_cache.samples[SDD_GYRO_X].status = SNS_DDF_SUCCESS;
				state->f_frames_cache.samples[SDD_GYRO_Y].status = SNS_DDF_SUCCESS;
				state->f_frames_cache.samples[SDD_GYRO_Z].status = SNS_DDF_SUCCESS;

				state->f_frames_cache.status = SNS_DDF_SUCCESS;
			} else {
				state->f_frames_cache.samples[SDD_GYRO_X].status = SNS_DDF_EINVALID_DATA;
				state->f_frames_cache.samples[SDD_GYRO_Y].status = SNS_DDF_EINVALID_DATA;
				state->f_frames_cache.samples[SDD_GYRO_Z].status = SNS_DDF_EINVALID_DATA;

				state->f_frames_cache.status = SNS_DDF_EINVALID_DATA;

				BMG160_MSG_1(HIGH, "sns_dd_bmg160_interrupt_handler sample_cnt_to_skip_odrc: %d",
						state->sample_cnt_to_skip_odrc);
			}

			state->f_frames_cache.sensor = SNS_DDF_SENSOR_GYRO;

			/*! notice : the number samples value */
			state->f_frames_cache.num_samples = SDD_GYRO_NUM_AXES;
			sns_dd_bmg160_update_sample_ts(state, 1, 1 * downsampling_factor);

			status = sns_ddf_smgr_notify_data(state->smgr_handle,
					&state->f_frames_cache, 1);
			if(state->f_frames_cache.status == SNS_DDF_SUCCESS) {
			   sns_dd_gyro_log_fifo(&state->f_frames_cache);
			}
		}
	}

	if (state->en_fifo_int && (!dri_mockup_wmi) && (state->f_wml > 0)) {
		/* for FIFO, status1 does not need to be checked */
		int_stat1 = 0;
		if ((status = bmg160_get_interrupt_status_reg_1(&int_stat1)) != SNS_DDF_SUCCESS)
		{
			return;
		}
#ifdef BMG160_DEBUG
		int_stat_drdy = BMG160_GET_BITSLICE(int_stat1, BMG160_INT_STATUS1_DATA_INT);
#endif // BMG160_DEBUG
		int_stat_fifo = BMG160_GET_BITSLICE(int_stat1, BMG160_INT_STATUS1_FIFO_INT);

		f_stat = 0;
		if ((status = bmg160_get_fifostatus_reg(&f_stat))
				!= SNS_DDF_SUCCESS) {
			return;
		}

		f_count = BMG160_GET_BITSLICE(f_stat,BMG160_FIFO_STATUS_FRAME_COUNTER);
		f_overrun = BMG160_GET_BITSLICE(f_stat, BMG160_FIFO_STATUS_OVERRUN);

		if (f_overrun) {
			status = sns_ddf_smgr_notify_event(state->smgr_handle,
					SNS_DDF_SENSOR_GYRO,
					SNS_DDF_EVENT_FIFO_OVERFLOW);
			BMG160_MSG_3_F(ERROR, "sns_dd_bmg160_interrupt_handler SNS_DDF_EVENT_FIFO_OVERFLOW %d %d %d",
					55555551, 1, f_count);
			sns_dd_bmg160_reset_fifo(state);
			return;
		}

#ifdef BMG160_DEBUG
		BMG160_MSG_3_P(HIGH,
				"sns_dd_bmg160_interrupt_handler <---1---> int_stat_fifo=%d  int_stat_drdy=%d f_count=%d",
				int_stat_fifo, int_stat_drdy, f_count);
#endif

		in_irq = 1;
		while (int_stat_fifo
				|| (f_count >= state->f_wml)
		      ) {

			//this will solve the issue of potential timing inconsistancy that can happen during a boundary
			//condition when interrupt has fired but fifo count register is locked from being updated.
			if ((int_stat_fifo) && (f_count == (state->f_wml - 1))) {
				f_count = state->f_wml;
#ifdef BMG160_DEBUG
				BMG160_MSG_3_P(HIGH,
						"sns_dd_bmg160_interrupt_handler <-----> int_stat_fifo= %d  int_stat_drdy=%d f_count=%d",
						int_stat_fifo, int_stat_drdy, f_count);
#endif
			}

			if (int_stat_fifo
					|| (f_count >= state->f_wml)) {
				status = sns_ddf_smgr_notify_event(state->smgr_handle,
						SNS_DDF_SENSOR_GYRO,
						SNS_DDF_EVENT_FIFO_WM_INT);
			}

			tmp_r = f_count % state->f_wml;
			if (((tmp_r + 1) == state->f_wml) || (f_count >= (2 * state->f_wml))) {
				wmi_missing_possible = true;
				si_buf_wr = 0x00;
				bmg160_sbus_write(state->port_handle,
						BMG160_INT_MAP_1, &si_buf_wr, 1, NULL);

				BMG160_MSG_3(ERROR, "bmg160_interrupt_handler wmi_missing_possible 1"
						"timestamp: %d wml: %d f_count: %d",
						timestamp, state->f_wml, f_count | (in_irq << 8));
			}

			f_count = f_count / state->f_wml * state->f_wml;
#if 0
			if (f_count < 2 * state->f_wml) {
				f_count = state->f_wml;
			}
#endif
			bmg160_fifo_data_read_out_frames(state, f_count, in_irq);
			in_irq = 0;

			if (state->f_frames_cache.num_samples > 0) {
				status = sns_ddf_smgr_notify_data(state->smgr_handle,
						&state->f_frames_cache, 1);
				if(state->f_frames_cache.status == SNS_DDF_SUCCESS) {
				   sns_dd_gyro_log_fifo(&state->f_frames_cache);
				}

			}

			//poll the status and frame counter again
			int_stat1 = 0;
			if ((status = bmg160_get_interrupt_status_reg_1(&int_stat1)) != SNS_DDF_SUCCESS)
			{
				return;
			}
#ifdef BMG160_DEBUG
			int_stat_drdy = BMG160_GET_BITSLICE(int_stat1, BMG160_INT_STATUS1_DATA_INT);
#endif // BMG160_DEBUG
			int_stat_fifo = BMG160_GET_BITSLICE(int_stat1, BMG160_INT_STATUS1_FIFO_INT);

			f_stat = 0;
			if ((status = bmg160_get_fifostatus_reg(&f_stat))
					!= SNS_DDF_SUCCESS) {
				return;
			}

			f_count = BMG160_GET_BITSLICE(f_stat,BMG160_FIFO_STATUS_FRAME_COUNTER);
			f_overrun = BMG160_GET_BITSLICE(f_stat, BMG160_FIFO_STATUS_OVERRUN);

#ifdef BMG160_DEBUG
			BMG160_MSG_3_P(HIGH, "sns_dd_bmg160_interrupt_handler <---2---> int_stat_fifo= %d  int_stat_drdy= %d f_count =%d",
					int_stat_fifo, int_stat_drdy, f_count);
#endif //BMG160_DEBUG
		}
	}


	if (wmi_missing_possible) {
		bmg160_sbus_write(state->port_handle, BMG160_INT_MAP_1, &state->regv_int_map_1, 1, NULL);
	}

	return;
}