Example #1
0
// return true is a command was read, false if a reset was requested
uint8_t receive_cmd(char *cmd)
{
    uint8_t num = 0, ch;

    dprintf(">");

    *cmd = 0;
    for(; !check_reset();)
    {
        for(;!check_reset() && !serial_rx_nb(&ch);)
            idle();

        if (check_reset())
            return 0;

        serial_tx(ch);
        if (ch == '\r')
        {
            serial_tx('\n');
            cmd[num] = 0;
            return 1;
        }
        cmd[num] = ch;
        num++;
    }
    return 0;
}
Example #2
0
void comm_test(void)
{
    uint8_t ch;

    // disable all interrupts and just echo every character received.
    cli();
    set_led_rgb(0, 255, 255);
    for(; !check_reset();)
        if (serial_rx_nb(&ch))
            for(; !serial_tx_nb(ch) && !check_reset();)
                ;
    sei();
}
Example #3
0
void id_conflict(void)
{
    // we failed to get an address. stop and wait for a reset
    set_led_rgb(255, 0, 0);
    for(; !check_reset();)
        ;
}
Example #4
0
uint8_t address_exchange(void)
{
    uint8_t  ch;
    uint8_t  id;

    set_led_rgb(0, 0, 255);
    id = eeprom_read_byte((uint8_t *)ee_pump_id_offset);
    if (id == 0 || id == 255)
    {
        // we failed to get a unique number for the pump. just stop.
        set_led_rgb(255, 0, 0);
        for(;;);
    }

    for(;;)
    {
        for(;;)
        {
            if (serial_rx_nb(&ch))
                break;

            if (check_reset())
                return 0xFF;
        }
        if (ch == 0xFF)
            break;
        if (ch == '?')
            serial_tx(id);
    }
    set_led_rgb(0, 255, 0);

    return id;
}
/* Process any pending interrupt(s) after a group of parallel insns.  */
void
frv_process_interrupts (SIM_CPU *current_cpu)
{
  SI NE_flags[2];
  /* Need to save the pc here because writeback may change it (due to a
     branch).  */
  IADDR pc = CPU_PC_GET (current_cpu);

  /* Check for a reset before anything else.  */
  if (check_reset (current_cpu, pc))
    return;

  /* First queue the writes for any accumulated NE flags.  */
  if (frv_interrupt_state.f_ne_flags[0] != 0
      || frv_interrupt_state.f_ne_flags[1] != 0)
    {
      GET_NE_FLAGS (NE_flags, H_SPR_FNER0);
      NE_flags[0] |= frv_interrupt_state.f_ne_flags[0];
      NE_flags[1] |= frv_interrupt_state.f_ne_flags[1];
      SET_NE_FLAGS (H_SPR_FNER0, NE_flags);
    }

  /* If there is no interrupt pending, then perform parallel writeback.  This
     may cause an interrupt.  */
  if (frv_interrupt_state.queue_index <= 0)
    frvbf_perform_writeback (current_cpu);

  /* If there is an interrupt pending, then process it.  */
  if (frv_interrupt_state.queue_index > 0)
    handle_interrupt (current_cpu, pc);
}
Example #6
0
void run_motor_timed(uint32_t duration)
{
    uint32_t t;

    if (duration == 0)
        return;

    set_motor_speed(255, 1);
    for(t = 0; t < duration && !check_reset(); t++)
        _delay_ms(1);
    stop_motor();
}
Example #7
0
/*
 *
 * Process the SCSI command
 *
 * Called with:
 *	cdev          -> Char dev file handle,
 *	cdb           -> SCSI Command buffer pointer,
 *	struct vtl_ds -> general purpose data structure... Need better name
 *
 * Return:
 *	SAM status returned in struct vtl_ds.sam_stat
 */
static void processCommand(int cdev, uint8_t *cdb, struct vtl_ds *dbuf_p,
			useconds_t pollInterval)
{
	int err = 0;
	struct scsi_cmd _cmd;
	struct scsi_cmd *cmd;
	cmd = &_cmd;

	cmd->scb = cdb;
	cmd->scb_len = 16;	/* fixme */
	cmd->dbuf_p = dbuf_p;
	cmd->lu = &lunit;
	cmd->pollInterval = pollInterval;
	cmd->cdev = cdev;

	MHVTL_DBG_PRT_CDB(1, cmd);

	switch (cdb[0]) {
	case REPORT_LUNS:
	case REQUEST_SENSE:
	case MODE_SELECT:
	case INQUIRY:
		dbuf_p->sam_stat = SAM_STAT_GOOD;
		break;
	default:
		if (cmd->lu->online == 0) {
			sam_not_ready(E_OFFLINE, &dbuf_p->sam_stat);
			return;
		}
		if (check_reset(&dbuf_p->sam_stat))
			return;
	}

	/* Skip main op code processing if pre-cmd returns non-zero */
	if (cmd->lu->scsi_ops->ops[cdb[0]].pre_cmd_perform)
		err = cmd->lu->scsi_ops->ops[cdb[0]].pre_cmd_perform(cmd, NULL);

	if (!err)
		dbuf_p->sam_stat = cmd->lu->scsi_ops->ops[cdb[0]].cmd_perform(cmd);

	/* Post op code processing regardless */
	if (cmd->lu->scsi_ops->ops[cdb[0]].post_cmd_perform)
		cmd->lu->scsi_ops->ops[cdb[0]].post_cmd_perform(cmd, NULL);

	return;
}
Example #8
0
/*
 *
 * Process the SCSI command
 *
 * Called with:
 *	cdev          -> Char dev file handle,
 *	cdb           -> SCSI Command buffer pointer,
 *	struct vtl_ds -> general purpose data structure... Need better name
 *
 * Return:
 *	SAM status returned in struct vtl_ds.sam_stat
 */
static void processCommand(int cdev, uint8_t *cdb, struct vtl_ds *dbuf_p,
			useconds_t pollInterval)
{
	struct scsi_cmd _cmd;
	struct scsi_cmd *cmd;
	cmd = &_cmd;

	cmd->scb = cdb;
	cmd->scb_len = 16;	/* fixme */
	cmd->dbuf_p = dbuf_p;
	cmd->lu = &lunit;
	cmd->pollInterval = pollInterval;

	MHVTL_DBG_PRT_CDB(1, cmd);

	switch (cdb[0]) {
	case REPORT_LUNS:
	case REQUEST_SENSE:
	case MODE_SELECT:
	case INQUIRY:
		dbuf_p->sam_stat = SAM_STAT_GOOD;
		break;
	default:
		if (cmd->lu->online == 0) {
			mkSenseBuf(NOT_READY, E_OFFLINE, &dbuf_p->sam_stat);
			return;
		}
		if (check_reset(&dbuf_p->sam_stat))
			return;
	}

	if (cmd->lu->scsi_ops->ops[cdb[0]].pre_cmd_perform)
		cmd->lu->scsi_ops->ops[cdb[0]].pre_cmd_perform(cmd, NULL);

	dbuf_p->sam_stat = cmd->lu->scsi_ops->ops[cdb[0]].cmd_perform(cmd);
	return;
}
Example #9
0
int main(void)
{
    uint8_t  id, rec, i, cs;
    color_t  c;
    packet_t p;

    setup();
    stop_motor();
    sei();
    for(i = 0; i < 5; i++)
    {
        set_led_rgb(255, 0, 255);
        _delay_ms(50);
        set_led_rgb(255, 255, 0);
        _delay_ms(50);
    }

    // get the current liquid level 
    update_liquid_level();

    for(;;)
    {
        cli();
        g_reset = 0;
        g_current_sense_detected = 0;
        g_current_sense_num_cycles = 0;
        setup();
        serial_init();
        stop_motor();
        set_led_rgb(0, 0, 255);

        sei();
        id = address_exchange();

        for(; !check_reset();)
        {
            rec = receive_packet(&p);
            if (rec == COMM_CRC_FAIL)
                continue;

            if (rec == COMM_RESET)
                break;

            if (rec == COMM_OK && (p.dest == DEST_BROADCAST || p.dest == id))
            {
                // If we've detected a over current sitatuion, ignore all comamnds until reset
                cli();
                cs = g_current_sense_detected;
                sei();

                switch(p.type)
                {
                    case PACKET_PING:
                        break;

                    case PACKET_SET_MOTOR_SPEED:
                        if (!cs)
                            set_motor_speed(p.p.uint8[0], p.p.uint8[1]);

                        if (p.p.uint8[0] == 0)
                            flush_saved_tick_count(0);
                        break;

                    case PACKET_TICK_DISPENSE:
                        if (!cs)
                        {
                            dispense_ticks((uint16_t)p.p.uint32, 255);
                            flush_saved_tick_count(0);
                        }
                        break;

                    case PACKET_TIME_DISPENSE:
                        if (!cs)
                        {
                            run_motor_timed(p.p.uint32);
                            flush_saved_tick_count(0);
                        }
                        break;

                    case PACKET_IS_DISPENSING:
                        is_dispensing();
                        break;

                    case PACKET_LIQUID_LEVEL:
                        get_liquid_level();
                        break;

                    case PACKET_UPDATE_LIQUID_LEVEL:
                        update_liquid_level();
                        break;

                    case PACKET_LED_OFF:
                        set_led_pattern(LED_PATTERN_OFF);
                        break;

                    case PACKET_LED_IDLE:
                        if (!cs)
                            set_led_pattern(LED_PATTERN_IDLE);
                        break;

                    case PACKET_LED_DISPENSE:
                        if (!cs)
                            set_led_pattern(LED_PATTERN_DISPENSE);
                        break;

                    case PACKET_LED_DRINK_DONE:
                        if (!cs)
                            set_led_pattern(LED_PATTERN_DRINK_DONE);
                        break;

                    case PACKET_LED_CLEAN:
                        if (!cs)
                            set_led_pattern(LED_PATTERN_CLEAN);
                        break;

                    case PACKET_COMM_TEST:
                        comm_test();
                        break;

                    case PACKET_ID_CONFLICT:
                        id_conflict();
                        break;

                    case PACKET_SET_CS_THRESHOLD:
                        g_current_sense_threshold = p.p.uint16[0];
                        break;

                    case PACKET_SAVED_TICK_COUNT:
                        get_saved_tick_count();
                        break;

                    case PACKET_RESET_SAVED_TICK_COUNT:
                        reset_saved_tick_count();
                        break;

                    case PACKET_FLUSH_SAVED_TICK_COUNT:
                        flush_saved_tick_count(1);
                        break;

                    case PACKET_GET_LIQUID_THRESHOLDS:
                        get_liquid_thresholds();
                        break;

                    case PACKET_SET_LIQUID_THRESHOLDS:
                        set_liquid_thresholds(p.p.uint16[0], p.p.uint16[1]);
                        break;

                    case PACKET_TICK_SPEED_DISPENSE:
                        if (!cs)
                        {
                            dispense_ticks(p.p.uint16[0], (uint8_t)p.p.uint16[1]);
                            flush_saved_tick_count(0);
                        }
                        break;
                    case PACKET_PATTERN_DEFINE:
                        pattern_define(p.p.uint8[0]);
                        break;

                    case PACKET_PATTERN_ADD_SEGMENT:
                        c.red = p.p.uint8[0];
                        c.green = p.p.uint8[1];
                        c.blue = p.p.uint8[2];
                        pattern_add_segment(&c, p.p.uint8[3]);
                        break;

                    case PACKET_PATTERN_FINISH:
                        pattern_finish();
                        break;
                }
            }
        }
    }
    return 0;
}
Example #10
0
int mark(int argc, char *argv[], int retc, char *retv[] )
{
	int	 firstarg, cmd_is_ds, mark_ret_val, num_num_args, reset_flag,
		 trace_flag;
	double	 mark_args[ 4 ];

/************************************************************************/
/*  Check for `reset' as a keyword.  Need to verify syntax.  Three	*/
/*  situations:  "reset" used improperly; "reset" used correctly;	*/
/*  no "reset" keyword.							*/
/************************************************************************/

	reset_flag = check_reset( argc, argv );
	if (reset_flag < 0)
	  ABORT;
	else if (reset_flag > 0) {
		if (do_mark_reset() == 0)
		  RETURN;
		else
		  ABORT;
	}

/************************************************************************/
/*  Check for `trace' as a keyword.  Situation is similar to `reset',	*/
/*  except there is no file name and the returned value distinguishes   */
/*  `trace' as first from `trace' as last argument (the only 2 choices) */
/************************************************************************/

	firstarg = 1;			/* Skip command name */
	trace_flag = check_trace( argc, argv );
	if (trace_flag < 0)
	  ABORT;
	if (trace_flag != 0) {
		if (retc > 2) {
			Werrprintf(
    "%s:  cannot return more than 2 values when using `trace' keyword", argv[ 0 ]
			);
			ABORT;
		}
		if (trace_flag == 1)	/* Skip over 1st argument */
		  firstarg = 2;		/* if it was `trace'	  */
		else			/* Otherwise it was the last */
		  argc--;		/* argument, so reduce total */
	}				/* number of arguments by 1  */

/************************************************************************/
/*  Extract numeric values, number of numeric values.  The `mark'	*/
/*  command accepts 0, 1, 2 or 4 such arguments.  If `num_vals_args'	*/
/*  returns -1, the subroutine has already posted an error message.	*/
/************************************************************************/

	num_num_args = num_vals_args( firstarg, argc, argv, &mark_args[ 0 ], 4 );
	if (num_num_args < 0)
	  ABORT;
	else if (num_num_args == 3 || num_num_args > 4) {
		Werrprintf( "%s:  incorrect number of numeric arguments", argv[ 0 ] );
		ABORT;
	}

/************************************************************************/
/*  Get the current graphics command to establish if DS was the last 	*/
/*  such command executed.  In that case, we perform a 1D operation	*/
/*  unless MARK was called with 4 numeric arguments.			*/
/*									*/
/*  Abort if current graphics command is not DS or DCONI.  Add checks	*/
/*  for other display commands (DCON, DPCON, etc.) here if required.	*/
/************************************************************************/

	cmd_is_ds = WgraphicsdisplayValid( "ds" );
	if ( !cmd_is_ds &&
	     !WgraphicsdisplayValid( "dconi" ) &&
	     num_num_args == 0 )
	{
		Werrprintf(
	    "%s:  requires arguments when no data displayed", argv[ 0 ]
		);
		ABORT;
	}

/************************************************************************/
/*  `init2d' subroutine defines `d2flag' and many other important	*/
/*  variables.  First argument instructs `init2d' to set "reverse"	*/
/*  flag if trace = "f1".  Second argument instructs `init2d' to	*/
/*  prepare chart variables for displaying data.			*/
/************************************************************************/

	if (init2d( 1, 1 ))
	  ABORT;

/************************************************************************/
/*  Now that `d2flag' is defined, check on 4 more error conditions:	*/
/*  A.  2D data is present, last command not `ds', 1 numeric argument	*/
/*      and no `trace' keyword.						*/
/*  B.  No 2D data present and 4 numeric arguments entered.		*/
/*  C.  No 2D data present and the `trace' keyword was used.		*/
/*  D.  No 2D data present and command returns more than 2 values.	*/
/************************************************************************/

	if (d2flag) {
		if (trace_flag == 0 && cmd_is_ds == 0 && num_num_args == 1) {
			Werrprintf(
    "%s:  'trace' keyword required with 2D data and 1 numeric argument", argv[ 0 ]
			);
			ABORT;
		}
	}
	else {					/* No 2D data */
		if (num_num_args == 4) {
			Werrprintf(
	    "%s:  Cannot have 4 numeric arguments with 1D data", argv[ 0 ]
			);
			ABORT;
		}
		if (trace_flag) {
			Werrprintf(
	    "%s:  Cannot use 'trace' keyword with 1D data", argv[ 0 ]
			);
			ABORT;
		}
		if (retc > 2) {
			Werrprintf(
	    "%s:  Cannot return more than 2 values with 1D data", argv[ 0 ]
			);
			ABORT;
		}
	}

/*  2D operations.  If 2D data is present and the `trace' keyword was
    NOT selected, then there were either 2 or 4 numeric arguments.	*/

	if (num_num_args == 4 || (d2flag && trace_flag == 0 && cmd_is_ds == 0)) {
		mark_ret_val = do_2d_mark(
			 retc, retv,
			 num_num_args,
			&mark_args[ 0 ]
		);
	}

/*  1D operations.  Come here if
    A.  num_num_args != 4 AND
    B.  d2flag is clear OR trace_flag is set OR cmd_is_ds is set.	*/

	else {
		mark_ret_val = do_1d_mark(
			 cmd_is_ds,
			 retc, retv,
			 num_num_args,
			&mark_args[ 0 ]
		);
	}

	if (mark_ret_val == 0)
	  RETURN;
	else
	  ABORT;
}