コード例 #1
0
ファイル: node.c プロジェクト: hydra/freewpc
/* Insert an unbound ball into a node. */
void node_insert (struct ball_node *node, struct ball *ball)
{
    unsigned int offset;

    if (ball->node)
    {
        simlog (SLC_DEBUG, "node_insert: %s already at %s",
                ball->name, ball->node->name);
        return;
    }

    if (node_full_p (node) || !node->type)
    {
        simlog (SLC_DEBUG, "node_insert: %s not allowed", node->name);
        return;
    }

    offset = (node->head + node->count) % node->size;
    node->ball_queue[offset] = ball;
    node->count++;
    ball->node = node;
    ball->pos = offset;
    if (node->type->insert)
        node->type->insert (node, ball);
#ifdef CONFIG_UI
    ui_update_ball_tracker (ball->index, node->name);
#endif
    simlog (SLC_DEBUG, "node_insert: added %s to %s, count=%d", ball->name, node->name, node->count);

    if (node->unlocked && !node_full_p (node->next))
        sim_time_register (100, FALSE, (time_handler_t)node_kick_delayed, node);
}
コード例 #2
0
ファイル: node.c プロジェクト: hydra/freewpc
/* Insert a ball at a node after some number of milliseconds has expired.
Until then the ball is not attached to any node. */
void node_insert_delay (struct ball_node *dst, struct ball *ball,
                        unsigned int delay)
{
    ball->node = dst;
    ball->timer = delay;
    sim_time_register (MIN_DELAY, FALSE,
                       (time_handler_t)node_insert_delay_update, ball);
}
コード例 #3
0
ファイル: coil.c プロジェクト: Dave2084/freewpc
/**
 * Update the state machine for a coil.
 *
 * The complexity here is that software can pulse the solenoid rapidly
 * between on and off; the goal is to detect when a single 'kick' operation
 * has occurred.  That requires ignoring brief off-periods and only
 * considering that it is been on a majority of the time in the recent past.
 *
 * Also, once a kick has occurred, it is not considered to kick again until
 * it has returned to the resting position (in reality, to allow another ball
 * to enter the kicking area).
 *
 * This function uses periodic callbacks to keep the solenoid state updated
 * even when no writes are emitted from the CPU; the power driver board
 * latches state.
 */
static void sim_coil_update (struct sim_coil_state *c)
{
	struct sim_coil_state *m = c->master;

	if (c->master == NULL)
		return;

	/* If the IO is on and the coil has not reached its maximum,
	move it forward. */
	if (c->on && m->pos < m->type->max_pos)
	{
		m->pos += c->type->on_step;
		if (m->pos >= m->type->max_pos && !m->at_max)
		{
			m->pos = m->type->max_pos;
			m->at_max = 1;
			simlog (SLC_DEBUG, "Coil %d on", m - coil_states);
			if (m->type->at_max)
				m->type->at_max (c);
		}
	}
	/* Else, if the IO is off and the coil has not reached its rest state,
	move it backward. */
	else if (!c->on && m->pos > 0)
	{
		m->pos += c->type->off_step;
		if (m->pos <= 0)
		{
			m->pos = 0;
			m->at_max = 0;
			simlog (SLC_DEBUG, "Coil %d off", m - coil_states);
			if (m->type->at_rest)
				m->type->at_rest (c);
		}
	}

	if (c->chain)
		sim_coil_update (c->chain);

#if 0
	simlog (SLC_DEBUG, "Coil %d on=%d pos=%d of %d", m - coil_states,
		c->on, m->pos, m->type->max_pos);
#endif
	/* If the coil requires monitoring, and it is not at rest, then reschedule.
	Else, we are done until the CPU modifies it again. */
	if (!c->type->unmonitored && m->pos != 0)
		sim_time_register (1, FALSE, (time_handler_t)sim_coil_update, c);
	else
	{
		c->scheduled = 0;
	}
}
コード例 #4
0
ファイル: node.c プロジェクト: hydra/freewpc
void node_insert_delay_update (struct ball *ball)
{
    ball->timer -= MIN_DELAY;
    if (ball->timer <= 0)
    {
        struct ball_node *dst = ball->node;
        ball->node = NULL;
        node_insert (dst, ball);
    }
    else
        sim_time_register (MIN_DELAY, FALSE,
                           (time_handler_t)node_insert_delay_update, ball);
}
コード例 #5
0
ファイル: coil.c プロジェクト: Dave2084/freewpc
/**
 * Called when the CPU board writes to a solenoid signal.
 * coil identifies the signal; on is nonzero for active voltage.
 */
void sim_coil_change (unsigned int coil, unsigned int on)
{
	struct sim_coil_state *c = coil_states + coil;

	if (c->disabled)
		return;

	if (c->on != on)
	{
		c->on = on;
		if (!c->scheduled)
		{
			sim_time_register (1, FALSE, (time_handler_t)sim_coil_update, c);
			c->scheduled = 1;
		}
	}
}
コード例 #6
0
ファイル: ui_remote.c プロジェクト: CardonaPinball/freewpc
void ui_init (void)
{
	sim_time_register (PS_FREQ, TRUE, remote_msg_update, NULL);
}