コード例 #1
0
ファイル: wdt_nrfx.c プロジェクト: milinddeore/zephyr
static int init_wdt(struct device *dev)
{
	nrfx_err_t err_code;
	/* Set default values. They will be overwritten by setup function. */
	const nrfx_wdt_config_t config = {
		.behaviour          = NRF_WDT_BEHAVIOUR_RUN_SLEEP_HALT,
		.reload_value       = 2000
	};

	ARG_UNUSED(dev);

	err_code = nrfx_wdt_init(&config, wdt_event_handler);
	if (err_code != NRFX_SUCCESS) {
		return -EBUSY;
	}

	IRQ_CONNECT(DT_NORDIC_NRF_WATCHDOG_WDT_0_IRQ,
		    DT_NORDIC_NRF_WATCHDOG_WDT_0_IRQ_PRIORITY,
		    nrfx_isr, nrfx_wdt_irq_handler, 0);
	irq_enable(DT_NORDIC_NRF_WATCHDOG_WDT_0_IRQ);

	return 0;
}

DEVICE_AND_API_INIT(wdt_nrf, DT_NORDIC_NRF_WATCHDOG_WDT_0_LABEL, init_wdt,
		    NULL, NULL, PRE_KERNEL_1,
		    CONFIG_KERNEL_INIT_PRIORITY_DEVICE, &wdt_nrf_api);
コード例 #2
0
ファイル: iwdg_stm32.c プロジェクト: milinddeore/zephyr
static int iwdg_stm32_init(struct device *dev)
{
#ifdef CONFIG_IWDG_STM32_START_AT_BOOT
	IWDG_TypeDef *iwdg = IWDG_STM32_STRUCT(dev);
	struct wdt_timeout_cfg config = {
		.window.max = CONFIG_IWDG_STM32_TIMEOUT * USEC_PER_MSEC,
	};

	LL_IWDG_Enable(iwdg);
	iwdg_stm32_install_timeout(dev, &config);
#endif

	/*
	 * The ST production value for the option bytes where WDG_SW bit is
	 * present is 0x00FF55AA, namely the Software watchdog mode is
	 * enabled by default.
	 * If the IWDG is started by either hardware option or software access,
	 * the LSI oscillator is forced ON and cannot be disabled.
	 *
	 * t_IWDG(ms) = t_LSI(ms) x 4 x 2^(IWDG_PR[2:0]) x (IWDG_RLR[11:0] + 1)
	 */

	return 0;
}

static struct iwdg_stm32_data iwdg_stm32_dev_data = {
	.Instance = (IWDG_TypeDef *)DT_ST_STM32_WATCHDOG_0_BASE_ADDRESS
};

DEVICE_AND_API_INIT(iwdg_stm32, DT_ST_STM32_WATCHDOG_0_LABEL,
		    iwdg_stm32_init, &iwdg_stm32_dev_data, NULL,
		    POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE,
		    &iwdg_stm32_api);
コード例 #3
0
ファイル: adt7420.c プロジェクト: nordic-krch/zephyr
static int adt7420_temp_reg_write(struct device *dev, u8_t reg, s16_t val)
{
	struct adt7420_data *drv_data = dev->driver_data;
	const struct adt7420_dev_config *cfg = dev->config->config_info;
	u8_t buf[3] = {reg, val >> 8, val & 0xFF};

	return i2c_write(drv_data->i2c, buf, sizeof(buf), cfg->i2c_addr);
}

static int adt7420_attr_set(struct device *dev,
			   enum sensor_channel chan,
			   enum sensor_attribute attr,
			   const struct sensor_value *val)
{
	struct adt7420_data *drv_data = dev->driver_data;
	const struct adt7420_dev_config *cfg = dev->config->config_info;
	u8_t val8, reg = 0;
	u16_t rate;
	s64_t value;

	if (chan != SENSOR_CHAN_AMBIENT_TEMP) {
		return -ENOTSUP;
	}

	switch (attr) {
	case SENSOR_ATTR_SAMPLING_FREQUENCY:
		rate = val->val1 * 1000 + val->val2 / 1000; /* rate in mHz */

		switch (rate) {
		case 240:
			val8 = ADT7420_OP_MODE_CONT_CONV;
			break;
		case 1000:
			val8 = ADT7420_OP_MODE_1_SPS;
			break;
		default:
			return -EINVAL;
		}

		if (i2c_reg_update_byte(drv_data->i2c, cfg->i2c_addr,
					ADT7420_REG_CONFIG,
					ADT7420_CONFIG_OP_MODE(~0),
					ADT7420_CONFIG_OP_MODE(val8)) < 0) {
			LOG_DBG("Failed to set attribute!");
			return -EIO;
		}

		return 0;
	case SENSOR_ATTR_UPPER_THRESH:
		reg = ADT7420_REG_T_HIGH_MSB;
		/* Fallthrough */
	case SENSOR_ATTR_LOWER_THRESH:
		if (!reg) {
			reg = ADT7420_REG_T_LOW_MSB;
		}

		if ((val->val1 > 150) || (val->val1 < -40)) {
			return -EINVAL;
		}

		value = (s64_t)val->val1 * 1000000 + val->val2;
		value = (value / ADT7420_TEMP_SCALE) << 1;

		if (adt7420_temp_reg_write(dev, reg, value) < 0) {
			LOG_DBG("Failed to set attribute!");
			return -EIO;
		}

		return 0;
	default:
		return -ENOTSUP;
	}

	return 0;
}

static int adt7420_sample_fetch(struct device *dev, enum sensor_channel chan)
{
	struct adt7420_data *drv_data = dev->driver_data;
	s16_t value;

	__ASSERT_NO_MSG(chan == SENSOR_CHAN_ALL ||
			chan == SENSOR_CHAN_AMBIENT_TEMP);

	if (adt7420_temp_reg_read(dev, ADT7420_REG_TEMP_MSB, &value) < 0) {
		return -EIO;
	}

	drv_data->sample = value >> 1; /* use 15-bit only */

	return 0;
}

static int adt7420_channel_get(struct device *dev,
		enum sensor_channel chan,
		struct sensor_value *val)
{
	struct adt7420_data *drv_data = dev->driver_data;
	s32_t value;

	if (chan != SENSOR_CHAN_AMBIENT_TEMP) {
		return -ENOTSUP;
	}

	value = (s32_t)drv_data->sample * ADT7420_TEMP_SCALE;
	val->val1 = value / 1000000;
	val->val2 = value % 1000000;

	return 0;
}

static const struct sensor_driver_api adt7420_driver_api = {
	.attr_set = adt7420_attr_set,
	.sample_fetch = adt7420_sample_fetch,
	.channel_get = adt7420_channel_get,
#ifdef CONFIG_ADT7420_TRIGGER
	.trigger_set = adt7420_trigger_set,
#endif
};

static int adt7420_probe(struct device *dev)
{
	struct adt7420_data *drv_data = dev->driver_data;
	const struct adt7420_dev_config *cfg = dev->config->config_info;
	u8_t value;
	int ret;

	ret = i2c_reg_read_byte(drv_data->i2c, cfg->i2c_addr,
				ADT7420_REG_ID, &value);
	if (ret) {
		return ret;
	}

	if (value != ADT7420_DEFAULT_ID)
		return -ENODEV;

	ret = i2c_reg_write_byte(drv_data->i2c, cfg->i2c_addr,
			ADT7420_REG_CONFIG, ADT7420_CONFIG_RESOLUTION |
			ADT7420_CONFIG_OP_MODE(ADT7420_OP_MODE_CONT_CONV));
	if (ret) {
		return ret;
	}

	ret = i2c_reg_write_byte(drv_data->i2c, cfg->i2c_addr,
				 ADT7420_REG_HIST, CONFIG_ADT7420_TEMP_HYST);
	if (ret) {
		return ret;
	}
	ret = adt7420_temp_reg_write(dev, ADT7420_REG_T_CRIT_MSB,
				     (CONFIG_ADT7420_TEMP_CRIT * 1000000 /
				     ADT7420_TEMP_SCALE) << 1);
	if (ret) {
		return ret;
	}

#ifdef CONFIG_ADT7420_TRIGGER
	if (adt7420_init_interrupt(dev) < 0) {
		LOG_ERR("Failed to initialize interrupt!");
		return -EIO;
	}
#endif

	return 0;
}

static int adt7420_init(struct device *dev)
{
	struct adt7420_data *drv_data = dev->driver_data;
	const struct adt7420_dev_config *cfg = dev->config->config_info;

	drv_data->i2c = device_get_binding(cfg->i2c_port);
	if (drv_data->i2c == NULL) {
		LOG_DBG("Failed to get pointer to %s device!",
			    cfg->i2c_port);
		return -EINVAL;
	}

	return adt7420_probe(dev);
}

static struct adt7420_data adt7420_driver;

static const struct adt7420_dev_config adt7420_config = {
	.i2c_port = CONFIG_ADT7420_I2C_MASTER_DEV_NAME,
	.i2c_addr = CONFIG_ADT7420_I2C_ADDR,
#ifdef CONFIG_ADT7420_TRIGGER
	.gpio_port = CONFIG_ADT7420_GPIO_DEV_NAME,
	.int_gpio = CONFIG_ADT7420_GPIO_PIN_NUM,
#endif
};

DEVICE_AND_API_INIT(adt7420, CONFIG_ADT7420_NAME, adt7420_init, &adt7420_driver,
		    &adt7420_config, POST_KERNEL, CONFIG_SENSOR_INIT_PRIORITY,
		    &adt7420_driver_api);
コード例 #4
0
ファイル: fxos8700.c プロジェクト: nordic-krch/zephyr
static int fxos8700_init(struct device *dev)
{
	const struct fxos8700_config *config = dev->config->config_info;
	struct fxos8700_data *data = dev->driver_data;
	struct sensor_value odr = {.val1 = 6, .val2 = 250000};

	/* Get the I2C device */
	data->i2c = device_get_binding(config->i2c_name);
	if (data->i2c == NULL) {
		LOG_ERR("Could not find I2C device");
		return -EINVAL;
	}

	/*
	 * Read the WHOAMI register to make sure we are talking to FXOS8700 or
	 * compatible device and not some other type of device that happens to
	 * have the same I2C address.
	 */
	if (i2c_reg_read_byte(data->i2c, config->i2c_address,
			      FXOS8700_REG_WHOAMI, &data->whoami)) {
		LOG_ERR("Could not get WHOAMI value");
		return -EIO;
	}

	switch (data->whoami) {
	case WHOAMI_ID_MMA8451:
	case WHOAMI_ID_MMA8652:
	case WHOAMI_ID_MMA8653:
		if (config->mode != FXOS8700_MODE_ACCEL) {
			LOG_ERR("Device 0x%x supports only "
				    "accelerometer mode",
				    data->whoami);
			return -EIO;
		}
	case WHOAMI_ID_FXOS8700:
		LOG_DBG("Device ID 0x%x", data->whoami);
		break;
	default:
		LOG_ERR("Unknown Device ID 0x%x", data->whoami);
		return -EIO;
	}

	/* Reset the sensor. Upon issuing a software reset command over the I2C
	 * interface, the sensor immediately resets and does not send any
	 * acknowledgment (ACK) of the written byte to the master. Therefore,
	 * do not check the return code of the I2C transaction.
	 */
	i2c_reg_write_byte(data->i2c, config->i2c_address,
			   FXOS8700_REG_CTRLREG2, FXOS8700_CTRLREG2_RST_MASK);

	/* The sensor requires us to wait 1 ms after a software reset before
	 * attempting further communications.
	 */
	k_busy_wait(USEC_PER_MSEC);

	if (fxos8700_set_odr(dev, &odr)) {
		LOG_ERR("Could not set default data rate");
		return -EIO;
	}

	if (i2c_reg_update_byte(data->i2c, config->i2c_address,
				FXOS8700_REG_CTRLREG2,
				FXOS8700_CTRLREG2_MODS_MASK,
				config->power_mode)) {
		LOG_ERR("Could not set power scheme");
		return -EIO;
	}

	/* Set the mode (accel-only, mag-only, or hybrid) */
	if (i2c_reg_update_byte(data->i2c, config->i2c_address,
				FXOS8700_REG_M_CTRLREG1,
				FXOS8700_M_CTRLREG1_MODE_MASK,
				config->mode)) {
		LOG_ERR("Could not set mode");
		return -EIO;
	}

	/* Set hybrid autoincrement so we can read accel and mag channels in
	 * one I2C transaction.
	 */
	if (i2c_reg_update_byte(data->i2c, config->i2c_address,
				FXOS8700_REG_M_CTRLREG2,
				FXOS8700_M_CTRLREG2_AUTOINC_MASK,
				FXOS8700_M_CTRLREG2_AUTOINC_MASK)) {
		LOG_ERR("Could not set hybrid autoincrement");
		return -EIO;
	}

	/* Set the full-scale range */
	if (i2c_reg_update_byte(data->i2c, config->i2c_address,
				FXOS8700_REG_XYZ_DATA_CFG,
				FXOS8700_XYZ_DATA_CFG_FS_MASK,
				config->range)) {
		LOG_ERR("Could not set range");
		return -EIO;
	}

	k_sem_init(&data->sem, 0, UINT_MAX);

#if CONFIG_FXOS8700_TRIGGER
	if (fxos8700_trigger_init(dev)) {
		LOG_ERR("Could not initialize interrupts");
		return -EIO;
	}
#endif

	/* Set active */
	if (fxos8700_set_power(dev, FXOS8700_POWER_ACTIVE)) {
		LOG_ERR("Could not set active");
		return -EIO;
	}
	k_sem_give(&data->sem);

	LOG_DBG("Init complete");

	return 0;
}

static const struct sensor_driver_api fxos8700_driver_api = {
	.sample_fetch = fxos8700_sample_fetch,
	.channel_get = fxos8700_channel_get,
	.attr_set = fxos8700_attr_set,
#if CONFIG_FXOS8700_TRIGGER
	.trigger_set = fxos8700_trigger_set,
#endif
};

static const struct fxos8700_config fxos8700_config = {
	.i2c_name = CONFIG_FXOS8700_I2C_NAME,
	.i2c_address = CONFIG_FXOS8700_I2C_ADDRESS,
#ifdef CONFIG_FXOS8700_MODE_ACCEL
	.mode = FXOS8700_MODE_ACCEL,
	.start_addr = FXOS8700_REG_OUTXMSB,
	.start_channel = FXOS8700_CHANNEL_ACCEL_X,
	.num_channels = FXOS8700_NUM_ACCEL_CHANNELS,
#elif CONFIG_FXOS8700_MODE_MAGN
	.mode = FXOS8700_MODE_MAGN,
	.start_addr = FXOS8700_REG_M_OUTXMSB,
	.start_channel = FXOS8700_CHANNEL_MAGN_X,
	.num_channels = FXOS8700_NUM_MAG_CHANNELS,
#else
	.mode = FXOS8700_MODE_HYBRID,
	.start_addr = FXOS8700_REG_OUTXMSB,
	.start_channel = FXOS8700_CHANNEL_ACCEL_X,
	.num_channels = FXOS8700_NUM_HYBRID_CHANNELS,
#endif
#if CONFIG_FXOS8700_PM_NORMAL
	.power_mode = FXOS8700_PM_NORMAL,
#elif CONFIG_FXOS8700_PM_LOW_NOISE_LOW_POWER
	.power_mode = FXOS8700_PM_LOW_NOISE_LOW_POWER,
#elif CONFIG_FXOS8700_PM_HIGH_RESOLUTION
	.power_mode = FXOS8700_PM_HIGH_RESOLUTION,
#else
	.power_mode = FXOS8700_PM_LOW_POWER,
#endif
#if CONFIG_FXOS8700_RANGE_8G
	.range = FXOS8700_RANGE_8G,
#elif CONFIG_FXOS8700_RANGE_4G
	.range = FXOS8700_RANGE_4G,
#else
	.range = FXOS8700_RANGE_2G,
#endif
#ifdef CONFIG_FXOS8700_TRIGGER
	.gpio_name = CONFIG_FXOS8700_GPIO_NAME,
	.gpio_pin = CONFIG_FXOS8700_GPIO_PIN,
#endif
#ifdef CONFIG_FXOS8700_PULSE
	.pulse_cfg = CONFIG_FXOS8700_PULSE_CFG,
	.pulse_ths[0] = CONFIG_FXOS8700_PULSE_THSX,
	.pulse_ths[1] = CONFIG_FXOS8700_PULSE_THSY,
	.pulse_ths[2] = CONFIG_FXOS8700_PULSE_THSZ,
	.pulse_tmlt = CONFIG_FXOS8700_PULSE_TMLT,
	.pulse_ltcy = CONFIG_FXOS8700_PULSE_LTCY,
	.pulse_wind = CONFIG_FXOS8700_PULSE_WIND,
#endif
};

static struct fxos8700_data fxos8700_data;

DEVICE_AND_API_INIT(fxos8700, CONFIG_FXOS8700_NAME, fxos8700_init,
		    &fxos8700_data, &fxos8700_config,
		    POST_KERNEL, CONFIG_SENSOR_INIT_PRIORITY,
		    &fxos8700_driver_api);