Ejemplo n.º 1
0
/**
 * @brief Set the ITG-3200 execution mode.
 *
 * This routine sets a specified ITG-3200 execution state to one of the
 * following:
 *
 * SENSOR_STATE_SLEEP or SENSOR_STATE_LOWEST_POWER
 *      Setting the sleep mode puts the device into very low power sleep
 *      mode.  In this mode, only the serial interface and internal registers
 *      remain active.
 *
 *  SENSOR_STATE_NORMAL or SENSOR_STATE_HIGHEST_POWER
 *      Sets the device to a normal operational state.
 *
 *  SENSOR_STATE_RESET
 *      Sets the device and internal registers to the power-up default
 *      settings.
 *
 * @param sensor    Address of an initialized sensor device descriptor.
 * @param state     A specified sensor operational state.
 * @return bool     true if the call succeeds, else false is returned.
 */
static bool itg3200_set_state(sensor_hal_t *hal, sensor_state_t state)
{
	switch (state) {
	default:
		return false;

	case SENSOR_STATE_SLEEP:
	case SENSOR_STATE_LOWEST_POWER:

		sensor_reg_bitset(hal, ITG3200_PWR_MGM, PWR_MGM_SLEEP);
		break;

	case SENSOR_STATE_NORMAL:
	case SENSOR_STATE_HIGHEST_POWER:

		sensor_reg_bitclear(hal, ITG3200_PWR_MGM, PWR_MGM_SLEEP);
		delay_ms(5);
		break;

	case SENSOR_STATE_RESET:

		/*
		 * \todo
		 *
		 * Update sensor device descriptor operational settings.
		 */
		return itg3200_default_init(hal);
	}

	return true;
}
Ejemplo n.º 2
0
/**
 * @brief Enable/disable ITG3200 sensor event
 *
 * @param  sensor    Address of an initialized sensor device descriptor
 * @param  callback  Application-defined event callback handler descriptor
 * @param  enable    Enable flag: true = enable event, false = disable event
 * @return bool      true if the call succeeds, else false is returned
 */
static bool itg3200_event(sensor_t *sensor, sensor_event_t sensor_event,
		sensor_event_callback_t *callback, bool enable)
{
	sensor_hal_t *const hal = sensor->hal;

	bool status = false;

	if (sensor_event & SENSOR_EVENT_NEW_DATA) {
		if (callback) {
			event_cb = *callback;
		}

		if (enable) {
			/* Enable new data int, latch until any reg is read,
			 * active high */
			sensor_bus_put(hal, ITG3200_INT_CFG,
					INT_CFG_RAW_RDY_EN |
					INT_CFG_ANYRD_2CLEAR);
		} else {
			/* Disable new data int */
			sensor_reg_bitclear(hal, ITG3200_INT_CFG,
					INT_CFG_LATCH_INT_EN);
		}

		status = true;
	}

	return status;
}
Ejemplo n.º 3
0
/**
 * @brief Enable or disable the BMA220 sleep mode.
 *
 * This routine enables or disables the BMA220 sleep mode depending upon
 * the value of the \sleep parameter; a \true value enables sleep mode and
 * a \false value disables sleep mode by setting or clearing the 'sleep_en'
 * bit, respectively.
 *
 * @param hal       Address of an initialized sensor hardware descriptor.
 * @param sleep     Set flag \true to enable sleep mode.
 * @return Nothing
 */
static inline void bma220_sleep_en(sensor_hal_t *hal, bool sleep)
{
	if (sleep) {
		sensor_reg_bitset(hal, BMA220_SLEEP_CONFIG, SLEEP_ENABLE);
	} else {
		sensor_reg_bitclear(hal, BMA220_SLEEP_CONFIG, SLEEP_ENABLE);
	}
}
Ejemplo n.º 4
0
/**
 * @brief Set the BMA150 execution mode.
 *
 * This routine sets a specified BMA150 execution state to one of the
 * following:
 *
 * SENSOR_STATE_SLEEP or SENSOR_STATE_LOWEST_POWER
 *      Setting the sleep mode puts the BMA150 into a very low power state in
 *      which no communication with the sensor IC is possible.  The current
 *      consumption in sleep mode is about 1 microamp.
 *
 *      In case of a soft-reset, it is recommended to do the reset after
 *      switching from sleep to operational mode.  In case a soft-reset is
 *      activated during sleep mode, it can take up to 30ms until normal
 *      operation has resumed.
 *
 *  SENSOR_STATE_LOW_POWER
 *      This option sets the BMA150 to a low power "wake-up" mode that triggers
 *      a system wake-up (interrupt output to master) when motion is detected.
 *      In this mode, the device periodically evaluates acceleration data with
 *      respect to interrupt criteria defined by the user.
 *
 *      Typical current consumption in wake-up mode is estimated as follows:
 * @code
 *                        i_DD * t_active + i_DDsm * wake_up_pause
 *      i_self_wake_up = ------------------------------------------
 *                                 t_active + wake_up_pause
 * @endcode
 *      with approximation:
 * @code
 *      t_active = 1ms + 0.333ms * [(4 * 750/bandwidth) + (1500/bandwidth) * n]
 * @endcode
 *      with parameters:
 * @code
 *      i_DD            Normal mode current (200 microamp)
 *      i_DDsm          Sleep mode current  (1 microamp)
 *      wake_up_pause   Wake-up pause setting
 *      n               Number of data points in any-motion logic (n=0 for
 *                      high-g and low-g threshold, n=3 for any-motion)
 *      bandwidth       bandwidth @ settings 1500 through 25 Hz.
 * @endcode
 *  SENSOR_STATE_NORMAL or SENSOR_STATE_HIGHEST_POWER
 *      In normal mode the sensor IC data and status registers can be accessed
 *      without restriction.  The device current consumption is 200 microamps
 *      in this state.
 *
 *  SENSOR_STATE_RESET
 *      This function resets the device and internal registers to the power-up
 *      default settings.
 *
 * In the wake-up mode, the BMA150 automatically switches from sleep mode to
 * normal mode after a delay defined by a programmable \c wake_up_pause value.
 * After transitioning from sleep to normal mode, acceleration data acquisition
 * and interrupt verification are performed.  The sensor automatically returns
 * to sleep mode again if no interrupt criteria are satisfied.
 *
 * @param hal       Address of an initialized sensor hardware descriptor.
 * @param state     A specified sensor operational state.
 * @return bool     true if the call succeeds, else false is returned.
 */
static bool bma150_set_state(sensor_hal_t *hal, sensor_state_t state)
{
	switch (state) {
	case SENSOR_STATE_SLEEP:
	case SENSOR_STATE_LOWEST_POWER:

		sensor_reg_bitclear(hal, BMA150_CTRL5, CTRL5_WAKE_UP);
		sensor_reg_bitset(hal, BMA150_CTRL1, CTRL1_SLEEP);
		break;

	case SENSOR_STATE_LOW_POWER:

		sensor_reg_bitclear(hal, BMA150_CTRL1, CTRL1_SLEEP);
		sensor_reg_bitset(hal, BMA150_CTRL5, CTRL5_WAKE_UP);
		break;

	case SENSOR_STATE_NORMAL:
	case SENSOR_STATE_HIGHEST_POWER:

		sensor_reg_bitclear(hal, BMA150_CTRL1, CTRL1_SLEEP);
		sensor_reg_bitclear(hal, BMA150_CTRL5, CTRL5_WAKE_UP);
		break;

	case SENSOR_STATE_RESET:

		/*
		 * \todo
		 *
		 * Update sensor device descriptor operational settings.
		 */
		sensor_reg_bitclear(hal, BMA150_CTRL1, CTRL1_SLEEP);
		sensor_bus_put(hal, BMA150_CTRL1, CTRL1_SOFT_RESET);
		break;

	default:
		return false;
	}

	return true;
}
Ejemplo n.º 5
0
/**
 * @brief Run BMA150 self-tests.
 *
 * @param sensor    Address of an initialized sensor device descriptor.
 * @param test_code Address of a device-specific numeric test code.
 * @param arg       Device-specific self-test argument options.
 * @return bool     true if the call succeeds, else false is returned.
 */
static bool bma150_selftest(sensor_t *sensor, int *test_code, void *arg)
{
	sensor_hal_t *const hal = sensor->hal;
	bool result = false;

	if (SENSOR_TEST_DEFLECTION == *test_code) {
		/* Execute BMA150 self-test 0; electrostatic deflection test. */
		sensor_reg_bitset(hal, BMA150_CTRL1, CTRL1_SELF_TEST_0);

		result = (STATUS1_ST_RESULT &
				sensor_bus_get(hal, BMA150_STATUS1))
				? true : false;

		sensor_reg_bitclear(hal, BMA150_CTRL1, CTRL1_SELF_TEST_0);
	} else if (SENSOR_TEST_INTERRUPT == *test_code) {
		/* Execute BMA150 self-test 1; interrupt to MCU test. */
		sensor_reg_bitset(hal, BMA150_CTRL1, CTRL1_SELF_TEST_1);
	}

	return result;
}
Ejemplo n.º 6
0
/**
 * @brief InvenSense IMU-3000 motion processor driver initialization.
 *
 * This is the main initialization function for the IMU-3000 device.
 *
 * @param sensor    Address of a sensor device descriptor.
 * @param resvd     Reserved value.
 * @return bool     true if the sensor is ready for use, else false.
 */
bool imu3000_init(sensor_t *sensor, int resvd)
{
	sensor_hal_t *const hal = sensor->hal;
	sensor_hal_t *const aux = (sensor_hal_t *)sensor->aux;
	bool status = false;

	/* Set the driver function table and capabilities pointer. */
	static const sensor_device_t imu3000_device = {
		.func.read            = imu3000_read,
		.func.ioctl           = imu3000_ioctl,
		.func.event           = imu3000_event,

		.caps.feature         = SENSOR_CAPS_3_AXIS   |
				SENSOR_CAPS_AUX_TEMP |
				SENSOR_CAPS_AUX_ACCEL,
		.caps.vendor          = SENSOR_VENDOR_INVENSENSE,
		.caps.range_table     = range_table,
		.caps.band_table      = band_table,
		.caps.range_count     = ARRAYSIZE(range_table),
		.caps.band_count      = ARRAYSIZE(band_table),
		.caps.units           = SENSOR_UNITS_deg_per_sec,
		.caps.name = "InvenSense IMU-3000 Motion Processing Unit"
	};

	sensor->drv = &imu3000_device;

	/* Set the driver default, range, bandwidth, resolution, etc. */
	hal->range      = range_table [sensor_fs_sel].range_units;
	hal->bandwidth  = band_table [sensor_dlpf_cfg].bandwidth_Hz;
	hal->sample_rate = 100;
	hal->resolution = IMU3000_RESOLUTION;

	/* Apply default device settings */
	if (imu3000_default_init(hal, aux) != true) {
		return status; /* return error */
	}

	/* Set start addr for burst read (used during interrupt). */
	hal->burst_addr = IMU3000_INT_STATUS;

	/* Connect interrupt event handler. */
	if (sensor_irq_connect(hal->mcu_sigint, imu3000_isr, hal)) {
		status = true;
	}

	return status;
}

/**
 * @brief Invensense IMU3000 driver interrupt service routine.
 *
 * This is the interrupt service routine for enabled IMU3000 interrupt events.
 * Only the new data ("raw data ready") interrupt is supported.
 *
 * @param arg       The address of the driver sensor_hal_t descriptor.
 * @return Nothing.
 */
static void imu3000_isr(volatile void *arg)
{
	sensor_hal_t *const hal = (sensor_hal_t *)arg;
	int16_t input[3];

	hal->bus.no_wait = true;

	imu3000_event_t regs;
	sensor_bus_read(hal, hal->burst_addr, &regs, sizeof(regs));

	hal->bus.no_wait = false;

	if (STATUS_OK == hal->bus.status) {
		/* Assume new data to avoid an apparent race condition. The
		 * interupt status register sometimes has the new data flag
		 * cleared before it is read above.  If this happens, the sensor will
		 * not generate any further new data interrupts until the device is
		 * independently accessed.
		 */
		static sensor_event_data_t event_data = {.data.scaled = true};

		event_data.data.timestamp = sensor_timestamp();
		event_data.event = SENSOR_EVENT_NEW_DATA;

		input[0] = (regs.x_hi << 8) | regs.x_lo;
		input[1] = (regs.y_hi << 8) | regs.y_lo;
		input[2] = (regs.z_hi << 8) | regs.z_lo;

		event_data.data.axis.x
			= hal->orientation.x.sign *
				input[hal->orientation.x.axis];
		event_data.data.axis.y
			= hal->orientation.y.sign *
				input[hal->orientation.y.axis];
		event_data.data.axis.z
			= hal->orientation.z.sign *
				input[hal->orientation.z.axis];

		const int32_t scaling
			= (int32_t)scale_lsb_per_dps[sensor_fs_sel];
		event_data.data.axis.x /= scaling;
		event_data.data.axis.y /= scaling;
		event_data.data.axis.z /= scaling;

		/* Call application-supplied handler routine */
		(event_cb.handler)(&event_data, event_cb.arg);
	}
}

/**
 * @brief Enable/disable IMU3000 sensor event
 *
 * @param  sensor    Address of an initialized sensor device descriptor
 * @param  callback  Application-defined event callback handler descriptor
 * @param  enable    Enable flag: true = enable event, false = disable event
 * @return bool      true if the call succeeds, else false is returned
 */
static bool imu3000_event(sensor_t *sensor, sensor_event_t sensor_event,
		sensor_event_callback_t *callback, bool enable)
{
	sensor_hal_t *const hal = sensor->hal;

	bool status = false;

	if (sensor_event & SENSOR_EVENT_NEW_DATA) {
		if (callback) {
			event_cb = *callback;
		}

		if (enable) {
			/* Enable new data int, latch until any reg is read,
			 * active high */
			sensor_bus_put(hal, IMU3000_INT_CFG,
					INT_CFG_RAW_RDY_EN |
					INT_CFG_ANYRD_2CLEAR);
		} else {
			/* Disable new data int */
			sensor_reg_bitclear(hal, IMU3000_INT_CFG,
					INT_CFG_LATCH_INT_EN);
		}

		status = true;
	}

	return status;
}