int ecs_sensor_init(struct ecs_sensor *snsr)
{
	int i, j, ret;

	if (unlikely(snsr == NULL))
		return -EINVAL;

	if (snsr->hw_ctx == NULL) {
		x_log(0, "hardware context not defined");
		return -EINVAL;
	}
	if (snsr->cfg_handler == NULL) {
		x_inf(0, "config handler not defined");
		return -EINVAL;
	}

	/* by this time, sensor driver should have line up all the settings and
	 * propertys. ECS driver will check if all of them are well organized */
	for (i = 0; i < snsr->prop_num; i++) {
		struct ecs_property *prop = ecs_find_property(snsr, i);
		if (unlikely(prop == NULL)) {
			x_inf(0, "error checking property %d", i);
			return -EINVAL;
		}

		/* copy handlers by the way. If no specific handler defined for
		 * this property, use global default handler */
		if (prop->cfg_handler == NULL)
			prop->cfg_handler = snsr->cfg_handler;

		for (j = 0; j < prop->stn_num; j++) {
			struct ecs_setting *stn = ecs_find_setting(prop, j);
			if (unlikely(stn == NULL)) {
				x_inf(0, "error checking '%s' setting %d", \
								prop->name, j);
				return -EINVAL;
			}
		}
		prop->speculate = prop->speculate && snsr->speculate;
	}

	for (i = 1; i < snsr->state_num; i++) {
		struct ecs_state *state = ecs_find_state(snsr, i);
		if (unlikely(state == NULL)) {
			x_inf(0, "error checking state %d", i);
			return -EINVAL;
		}
	}
ecs_sensor_dump(snsr);
	/* from this point on, ecs can directly access property/setting/state
	 * rather than calling ecs_find_property/setting/state */
	return ret;
}
Example #2
0
void derivs_one(const double* y, double* dydt, const double* p)
{
	double V=y[0], h=y[1], n=y[2], x=y[3], Ca=y[4];
	double V_tilde = C_1*V+C_2, V_Ca=p[0];

	dydt[0] = -g_Na*powf(m_inf(V_tilde), 3)*h*(V-V_Na) - g_Ca*x*(V-V_Ca) - (g_K*powf(n, 4)+g_K_Ca*Ca/(0.5+Ca))*(V-V_K) - g_L*(V-V_L);	// dV/dt
        dydt[1] = lambda*(h_inf(V_tilde)-h)/tau_h(V_tilde);	// dh/dt
        dydt[2] = lambda*(n_inf(V_tilde)-n)/tau_n(V_tilde);	// dn/dt
        dydt[3] = (x_inf(V)-x)/tau_x;				// dx/dt
        dydt[4] = rho * (K_c * x * (V_Ca - V) - Ca);		// d[Ca2+]/dt
}
/* set all */
inline int ecs_set_value(struct ecs_sensor *snsr, \
			const struct ecs_state_cfg *cfg)
{
	struct ecs_property *prop = NULL;
	struct ecs_setting *stn = NULL;
	int ret;

	prop = ecs_find_property(snsr, cfg->prop_id);
	if (prop == NULL)
		return -EINVAL;
	/* interpret property value according to its type */
	if (prop->value_type == 0) {
		stn = ecs_find_setting(prop, cfg->prop_val);
		if (stn == NULL)
			return -EINVAL;
		if (prop->speculate && (prop->value_now == cfg->prop_val)) {
			x_inf(2, "%10s == %s", prop->name, stn->name);
			return 0;
		}

		x_inf(2, "%10s := %s", prop->name, stn->name);
		ret = (*prop->cfg_handler)(snsr->hw_ctx, \
						stn->cfg_tab, stn->cfg_sz);
		if (ret != stn->cfg_sz) {
			x_inf(0, "%s: error applying setting %s = %s ", \
				snsr->name, prop->name, stn->name);
			return -EIO;
		}
	} else {
		/* the value is not integral, sensor driver knows what to do*/
		if ((prop->speculate) && (prop->value_equal) && \
			(*prop->value_equal)((void *)prop->value_now, \
						(void *)cfg->prop_val)) {
			x_inf(0, "%10s needs no change\n", prop->name);
			return 0;
		}
		/* Here ECS assumes as soon as sensor driver mark a property
		 * value as none-integral, there is no way to convert property
		 * value to integral, even if there is someway, ECS don't want
		 * to envolve into this complexity, but cfg_handler shall */
		x_inf(2, "%10s will be changed\n", prop->name);
		ret = (*prop->cfg_handler)(snsr->hw_ctx, \
				prop->stn_tab[0].cfg_tab, cfg->prop_val);
		if (ret < 0) {
			x_inf(0, "error changing property '%s'", prop->name);
			return -EIO;
		}
	}

	prop->value_now = cfg->prop_val;
	return ret;
}
static inline int _ecs_set_state(struct ecs_sensor *snsr, int state_id)
{
	struct ecs_state_cfg *cfg;
	struct ecs_state *state;
	int i, ret = 0;

	state = snsr->state_tab + state_id;
	for (i = 0; i < state->cfg_num; i++) {
		int cnt;
		cfg = &(state->cfg_tab[i]);
		cnt = ecs_set_value(snsr, cfg);
		if (cnt < 0) {
			x_inf(0, "change to state '%s' failed, when changing " \
				"property %d", state->name, cfg->prop_id);
			return -EIO;
		}
		ret += cnt;
	}

	snsr->state_now = state->id;
	return ret;
}
int ecs_sensor_merge(struct ecs_sensor *orig, const struct ecs_sensor *plat)
{
	char *name;
	int i, j;

	/* if no speciman defined */
	if (plat == NULL)
		return 0;

	x_log(0, "merge '%s' into '%s'", plat->name, orig->name);
	name = (plat->name == NULL) ? ECS_DEFAULT_SENSOR_NAME : plat->name;
	if (orig->name == NULL)
		orig->name = name;

	/* allow speculate only if both sensor physical nature and
	 * sensor implementation allows speculate */
	orig->speculate &= plat->speculate;

	if ((orig->hw_ctx == NULL) && (plat->hw_ctx != NULL))
		orig->hw_ctx = plat->hw_ctx;

	if ((orig->cfg_handler == NULL) && (plat->cfg_handler != NULL))
		orig->cfg_handler = plat->cfg_handler;

	/* deal with the platform specific setting and property */
	for (i = 0; i < plat->prop_num; i++) {
		struct ecs_property *prop = ecs_find_property(orig, \
			plat->prop_tab[i].id);

		if (prop == NULL) {
			x_inf(0, "can't find property id(%d) in %s", \
				plat->prop_tab[i].id, orig->name);
			return -EINVAL;
		}

		x_log(0, "set %s as %s", prop->name, plat->prop_tab[i].name);
		if (plat->prop_tab[i].name != NULL)
			prop->name = plat->prop_tab[i].name;

		if (prop->stn_tab == NULL) {
			/* If original template has no setting table at all,
			 * just simply use the platform specific table */
			prop->stn_tab = plat->prop_tab[i].stn_tab;
			prop->stn_num = plat->prop_tab[i].stn_num;
			goto next;
		}
		/* deal with settings */
		for (j = 0; j < plat->prop_tab[i].stn_num; j++) {
			struct ecs_setting *stn = ecs_find_setting(prop, \
				plat->prop_tab[i].stn_tab[j].id);
			if (stn == NULL) {
				x_inf(0, "can't find setting id(%d) in %s", \
					plat->prop_tab[i].stn_tab[j].id, \
					prop->name);
				return -EINVAL;
			}
			stn->cfg_tab = plat->prop_tab[i].stn_tab[j].cfg_tab;
			stn->cfg_sz = plat->prop_tab[i].stn_tab[j].cfg_sz;
		}
next:
		if (plat->prop_tab[i].cfg_handler != NULL)
			prop->cfg_handler = plat->prop_tab[i].cfg_handler;
	}

	/* finally...states */
	/* deal with the platform specific setting and property */
	for (i = 0; i < plat->state_num; i++) {
		struct ecs_state *state = ecs_find_state(orig, \
			plat->state_tab[i].id);
		if (state == NULL) {
			x_inf(0, "can't find state id(%d) in template", \
				plat->state_tab[i].id);
			return -EINVAL;
		}

		state->cfg_tab = plat->state_tab[i].cfg_tab;
		state->cfg_num = plat->state_tab[i].cfg_num;
	}

	return 0;
}