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; }
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; }