/**
 * List all programs stored on the terminal host over the serial line.
 * DIR
 */
void cmd_dir(char *) {
  unsigned char first = 1;

  acia_puts("*DIR\n");

  for(;;) {
    acia_puts("*NEXT\n");
    acia_gets(readline_buffer, 255);

    if (strncmp("*EOF", readline_buffer, 4) == 0) {
      break;
    } else {
      if (first) {
        first = 0;
      } else {
        do {
          if (is_interrupted()) {
            acia_puts("*BREAK\n");
            print_interrupted();
            return;
          }
          keys_update();
        } while (keys_get_code() == KEY_NONE);
      }

      lcd_puts(readline_buffer);
      lcd_put_newline();
    }
  }
  print_ready();
}
/**
 * List the program.
 * LiST [<from>]
 */
void cmd_list(char *args) {
  unsigned char range = 0;
  unsigned int from_number;
  unsigned int to_number;
  program_line *line;
  unsigned char first = 1;

  if (isdigit(args[0])) {
    sscanf(args, "%u", &from_number);
    to_number = from_number;
    range = 1;
  }

  line = program;
  while (line) {
    if (range == 0 || (line->number >= from_number && line->number <= to_number)) {
      if (first) {
        first = 0;
      } else {
        do {
          if (is_interrupted()) {
            print_interrupted();
            return;
          }
          keys_update();
        } while (keys_get_code() == KEY_NONE);
      }
      sprintf(print_buffer, "%u %s %s\n", line->number, keywords[line->command], line->args);
      lcd_puts(print_buffer);
    }
    line = line->next;
  }

  print_ready();
}
/**
 * Load a program by reading it from the terminal program over the serial line.
 * LOAD "<filename>"
 */
void cmd_load(char *args) {
  char *filename;
  if (parse_string_expression(args, &filename)) {
    cmd_new(0);
    lcd_puts("Loading...");
    acia_puts("*LOAD \"");
    acia_puts(filename);
    acia_puts("\"\n");
    for(;;) {
      acia_puts("*NEXT\n");
      acia_gets(readline_buffer, 255);
      if (strncmp("*EOF", readline_buffer, 4) == 0) {
        break;
      } else if (strncmp("!NOTFOUND", readline_buffer, 9) == 0) {
        lcd_put_newline();
        syntax_error_msg("File not found");
        break;
      } else {
        lcd_putc('.');
        interpret(readline_buffer);
      }
    }
    if (! error) {
      lcd_put_newline();
      print_ready();
    }
  } else {
    syntax_error_invalid_argument();
  }
}
/**
 * Run the program.
 * RUN
 */
void cmd_run(char *) {
  unsigned char command;
  error = 0;
  running = 1;
  current_line = program;
  current_line_changed = 0;
  while (current_line) {
    if (is_interrupted()) {
      print_interrupted();
      lcd_cursor_blink();
      break;
    }
    command = current_line->command;
    command_functions[command](current_line->args);
    if (error) {
      break;
    }
    if (current_line_changed) {
      current_line_changed = 0;
      if (! current_line) {
        break;
      }
    } else {
      current_line = current_line->next;
    }
  }
  print_ready();
}
/**
 * Terminate the program.
 * END
 */
void cmd_end(char *) {
  if (! current_line) {
    print_ready();
  }
  current_line = 0;
  current_line_changed = 1;
}
/**
 * Assign a value to a variable or delete the variable if no assignment is given.
 * List all variables if no arguments are given.
 */
void cmd_let(char *args) {
  unsigned char token;
  unsigned int var_name;
  unsigned char var_type;

  skip_whitespace(args);

  if (*args == '\0') {
    print_all_variables();
    print_ready();
    return;
  }

  if (args = parse_variable(args, &var_name, &var_type)) {
    if (next_token(args) == TOKEN_ASSIGN) {
      token = next_token(args);
      args = consume_token(args, token);
      switch (var_type) {
        case VAR_TYPE_INTEGER: {
          int value;
          if (parse_number_expression(args, &value)) {
            create_variable(var_name, var_type, &value);
          }
          break;
        }
        case VAR_TYPE_STRING: {
          char *value;
          if (parse_string_expression(args, &value)) {
            create_variable(var_name, var_type, value);
          }
          break;
        }
      }
    } else {
      if (*args == '\0') {
        delete_variable(var_name, var_type);
      }
    }
  } else {
    syntax_error();
  }
}
/**
 * Save a program by sending it to the terminal program over the serial line.
 * SAVE "<filename>"
 */
void cmd_save(char *args) {
  char *filename;
  if (parse_string_expression(args, &filename)) {
    program_line *line = program;
    lcd_puts("Saving...");
    acia_puts("*SAVE \"");
    acia_puts(filename);
    acia_puts("\"\n");
    while (line) {
      sprintf(print_buffer, "%u %s %s\n", line->number, keywords[line->command], line->args);
      acia_puts(print_buffer);
      line = line->next;
      lcd_putc('.');
    }
    acia_puts("*EOF\n");
    lcd_put_newline();
    print_ready();
  } else {
    syntax_error_invalid_argument();
  }
}
/**
 * Delete all variables.
 */
void cmd_clear(char *) {
  clear_variables();
  print_ready();
}
Example #9
0
/**
 * @brief: c UART0 IRQ Handler
 */
void uart_iprocess(void)
{
	uint8_t IIR_IntId;	    // Interrupt ID from IIR 		 
	LPC_UART_TypeDef *pUart = (LPC_UART_TypeDef *)LPC_UART0;
	__disable_irq();
#ifdef DEBUG_0
	//uart1_put_string("Entering c_UART0_IRQHandler\n\r");
#endif // DEBUG_0

	/* Reading IIR automatically acknowledges the interrupt */
	IIR_IntId = (pUart->IIR) >> 1 ; // skip pending bit in IIR 
	if (IIR_IntId & IIR_RDA) { // Receive Data Avaialbe
		/* read UART. Read RBR will clear the interrupt */

		// Perform a 'context switch'
		PCB *old_proc = gp_current_process;
		gp_current_process = k_get_process(PID_UART_IPROC);
		g_char_in = pUart->RBR;

#ifdef DEBUG_0
		uart1_put_string("Reading a char = ");
		uart1_put_char(g_char_in);
		uart1_put_string("\n\r");
#endif // DEBUG_0

		// process the character. If it is a hotkey, call the corresponding function
		// If we are reading, fall through to default and add to the command buffer
		switch (g_char_in) {
			case '\r':
			case '\n':
				if (g_is_reading) {
					// We've finished reading a command, send it to the KCD process
					MSG_BUF *message;
					g_is_reading = 0;
					strcpy("\n\r", (char *)(g_in_buffer + g_in_index));
					if (is_memory_available()) {
						message = k_request_memory_block();
						message->mtype = DEFAULT;
						strcpy((char *)g_in_buffer, message->mtext);
						k_send_message(PID_KCD, message);
					}
					g_in_index = 0;
				}
				break;
			case '%':
				if (!g_is_reading) {
					// Start reading a command
					g_is_reading = 1;
					g_in_index = 1;
					g_in_buffer[0] = '%';
					break;
				}
#if defined(DEBUG_0) && defined(_DEBUG_HOTKEYS)
			case READY_Q_COMMAND:
				if (!g_is_reading) {
					print_ready();
					break;
				}
			case MEMORY_Q_COMMAND:
				if (!g_is_reading) {
					print_mem_blocked();
					break;
				}
			case RECEIVE_Q_COMMAND:
				if (!g_is_reading) {
					print_receive_blocked();
					break;
				}
			case MESSAGE_COMMAND:
				if (!g_is_reading) {
					print_messages();
					break;
				}
#endif /* DEBUG HOTKEYS */
			default:
				if (g_is_reading) {
					// TODO: check bounds
					g_in_buffer[g_in_index++] = g_char_in;
				}
		}

		gp_current_process = old_proc;
	} else if (IIR_IntId & IIR_THRE) {
	/* THRE Interrupt, transmit holding register becomes empty */
		// Check for messages and load the buffer

		// Perform a 'context switch' to the i-process
		MSG_BUF *message;
		PCB *old_proc = gp_current_process;
		gp_current_process = k_get_process(PID_UART_IPROC);

		// Don't block waiting for a message
		while (is_message(PID_UART_IPROC)) {
			int sender = PID_CRT;
			char *c;

			// Receive message and copy it to the buffer
			message = k_receive_message(&sender);
			c = message->mtext;

			//dprintf("Copying message to buffer: %s\n\r", message->mtext);

			if (*c != '\0') {
				do {
					g_out_buffer[g_out_end] = *c;
					g_out_end = (g_out_end + 1) % OUTPUT_BUFF_SIZE;
					c++;
				} while (g_out_end != g_out_start && *c != '\0');
			}
			k_release_memory_block(message);
		}

		// Check if there is something in the circular buffer
		if (g_out_start != g_out_end) {
			g_char_out = g_out_buffer[g_out_start];
			pUart->THR = g_char_out;
			g_out_start = (g_out_start + 1) % OUTPUT_BUFF_SIZE;
		} else {
			// nothing to print, disable the THRE interrupt
			pUart->IER ^= IER_THRE; // toggle (disable) the IER_THRE bit
		}

		gp_current_process = old_proc;
	      
	} else {  /* not implemented yet */
#ifdef DEBUG_0
			//uart1_put_string("Should not get here!\n\r");
#endif // DEBUG_0
		__enable_irq();
		return;
	}	
	__enable_irq();
}
Example #10
0
static void
update_state(void){
    static utime_t fault_song     = 0;
    static utime_t diag_last      = 0;
    static int8_t  diag_counter   = 0;

    int sw = get_switch();
    int bn = get_button();
    blinky_override = 0;

    switch( inv_state ){
    case INV_STATE_OFF:
        set_led_green(0);

        if( sw ){
            // switch was turned on
            ondelay_until = get_time() + ONDELAY;
            inv_state = INV_STATE_ONDELAY;
            blinky_override = 1;
            set_led_white(255);
            play(ivolume, "c+3"); 	// debounce delay
            printbig("STARTING...\n");
            syslog("switch on");
        }
        break;

    case INV_STATE_ONDELAY:

        if( !sw ){
            // switch was turned off
            inv_state = INV_STATE_OFF;
            play(ivolume, "a-3");
            diag_counter ++;
            diag_last = get_time();
            printbig("OFF\n");
            usleep(500000);
            print_ready();
            syslog("canceled");
        }else if( get_time() >= ondelay_until ){
            // countdown finished
            set_led_green( 255 );
            inv_state = INV_STATE_ONDELAY2;
            diag_counter = 0;
            play(ivolume, "b");
            printbig("ACTIVE\n");
            syslog("ac active");
        }else{
            // flash + chirp; 2Hz
            blinky_override = 1;
            set_led_green(127);
            set_led_white(0);
            play(ivolume, "b+5>>");
            set_led_green(0);
            set_led_white(64);
            usleep(437500);

            // reset the clock if Vi drops below 300 (per the spec)
            if( s_vi._curr < MIN_VI_SOFT ){
                ondelay_until = get_time() + ONDELAY;
            }
        }
        break;

    case INV_STATE_ONDELAY2:
        // will move to running at next zero-xing
        break;

    case INV_STATE_RUNNING:
        set_led_green( 127 );

        if( !sw ){
            // switch was turned off
            // quickly bring VH down, and stop at zero-xing
            shutdown_until = get_time() + OFFDELAY;
            inv_state = INV_STATE_SHUTTINGDOWN;
            play(ivolume, "a-3");	// debounce
            syslog("switch off");
        }
        break;

    case INV_STATE_SHUTTINGDOWN:
        set_led_green(255);

        if( get_time() >= shutdown_until ){
            if( sw ){
                // wild switch flipping
                inv_state    = INV_STATE_FAULTEDOFF;
                fault_song   = 0;
                fault_reason = "SWITCH ERR";
                syslog("switch fault");
            }else{
                // done ramping down
                inv_state = INV_STATE_OFF;
                play(ivolume, "f-3");
                printbig("AC OFF\n");
                syslog("ac disabled");
                usleep(500000);
                print_ready();
            }
        }
        break;

    case INV_STATE_FAULTED:
        set_led_green(255);
        set_led_red(255);
        // we ramp down same as a shutdown, but end in faultedoff
        shutdown_until = get_time() + OFFDELAY;
        inv_state = INV_STATE_FAULTINGDOWN;
        printadj(fault_reason);
        break;

    case INV_STATE_FAULTINGDOWN:
        set_led_green(255);
        set_led_red(255);
        if( get_time() >= shutdown_until ){
            inv_state    = INV_STATE_FAULTEDOFF;
            fault_song   = 0;
            syslog("ac disabled (fault)");
        }
        break;

    case INV_STATE_FAULTEDOFF:
        set_led_green(0);
        set_led_red(255);

        if( !sw ){
            // switch turned off, resume normal operation
            inv_state = INV_STATE_OFF;
            play(ivolume, "f-3");
            set_led_red(0);
            print_ready();
        }else if( get_time() >= fault_song ){
            // periodically, sing
            printadj(fault_reason);
            play(128, "t150[4 d+3d-3]");
            fault_song = get_time() + FAULTSONGT;
        }

        break;

    case INV_STATE_DIAG:
        menu(&guitop);
        inv_state = INV_STATE_OFF;
        print_ready();
        break;

    case INV_STATE_TEST:
        break;
    }

    if( diag_last && diag_last + 5000000 < get_time() ){
        diag_counter = 0;
        diag_last    = 0;
    }
    // toggle switch rapidly, or toggle switch once + press button
    if( (diag_mode != 2) && ((diag_counter >= 5) || (bn && diag_counter)) ){
        inv_state = INV_STATE_DIAG;
        diag_counter = 0;
        printbig("DIAG MODE\n");
        syslog("diag mode");
        play(ivolume, "g4e4f4f-3");
        // ...
    }

}