Improved usart_readline(), Improved help, Added feedhold, start cycle & flush queue...
authorJoseph Coffland <joseph@cauldrondevelopment.com>
Mon, 27 Jun 2016 10:42:47 +0000 (03:42 -0700)
committerJoseph Coffland <joseph@cauldrondevelopment.com>
Mon, 27 Jun 2016 10:42:47 +0000 (03:42 -0700)
src/command.c
src/command.def
src/gcode_parser.c
src/main.c
src/messages.def
src/status.c
src/status.h
src/usart.c

index 80818cc3911b7f06a46b6008c75ff110b55be415..64aba8540bd3a5ef844424442f71f701101613e5 100644 (file)
@@ -127,6 +127,11 @@ int command_parser(char *cmd) {
   int argc = 0;
   char *argv[MAX_ARGS] = {};
 
+  if (cmd[1] == '$' && !cmd[2]) {
+    report_request_full(); // Full report
+    return STAT_OK;
+  }
+
   while (argc < MAX_ARGS && *p) {
     // Skip space
     while (*p && isspace(*p)) *p++ = 0;
@@ -152,8 +157,12 @@ stat_t command_hi() {
     _cmd = usart_readline();
     if (!_cmd) return STAT_OK;
 
-    // Skip leading whitespace
+    // Remove leading whitespace
     while (*_cmd && isspace(*_cmd)) _cmd++;
+
+    // Remove trailing whitespace
+    for (size_t len = strlen(_cmd); len && isspace(_cmd[len - 1]); len--)
+      _cmd[len - 1] = 0;
   }
 
   if (usart_tx_full()) return STAT_OK;
@@ -161,9 +170,12 @@ stat_t command_hi() {
   stat_t status = STAT_OK;
 
   switch (*_cmd) {
-  case 0: report_request_full(); break; // Full report
+  case 0: break; // Empty line
   case '{': status = vars_parser(_cmd); break;
   case '$': status = command_parser(_cmd); break;
+  case '!': if (!_cmd[1]) cm_request_feedhold(); break;
+  case '~': if (!_cmd[1]) cm_request_cycle_start(); break;
+  case '%': if (!_cmd[1]) cm_request_queue_flush(); break;
   default: return STAT_OK; // Continue processing in command_lo()
   }
 
@@ -207,6 +219,18 @@ uint8_t command_help(int argc, char *argv[]) {
     return STAT_OK;
   }
 
+  puts_P(PSTR("\nSpecial Character Commands:\n"
+              "  !         Feedhold (pause).\n"
+              "  ~         Start cycle (unpause).\n"
+              "  %         Flush queue\n"
+              "\n"
+              "Character commands must be entered alone on a single line."));
+
+  puts_P(PSTR("\nLine editing:\n"
+              "  ENTER     Submit current command line.\n"
+              "  BS        Backspace, delete last character.\n"
+              "  CTRL-X    Cancel current line entry."));
+
   puts_P(PSTR("\nCommands:"));
   for (int i = 0; ; i++) {
     const char *name = pgm_read_word(&commands[i].name);
@@ -255,3 +279,9 @@ uint8_t command_clear(int argc, char *argv[]) {
   vars_clear();
   return 0;
 }
+
+
+uint8_t command_messages(int argc, char *argv[]) {
+  status_help();
+  return 0;
+}
index 91d3240327d525d5713cc02e4bffab80c4f19cd8..03f5dcadefb5c857fa2080b3e5cf0faf3fa3a139 100644 (file)
@@ -36,3 +36,4 @@ CMD(clear,        0, 0, "Clear saved settings")
 CMD(jog,          1, 4, "Jog")
 CMD(mreset,       0, 1, "Reset motor")
 CMD(calibrate,    0, 0, "Calibrate motors")
+CMD(messages,     0, 0, "Dump all possible status messages")
index 8343c7916ce5c6c625d4af91147fe263786349da..20e243fb4752cfe05cd0bb5b6f9456903c133093 100644 (file)
@@ -156,7 +156,7 @@ static stat_t _get_next_gcode_word(char **pstr, char *letter, float *value) {
   char *end;
   *value = strtod(*pstr, &end);
   // more robust test then checking for value == 0
-  if (end == *pstr) return STAT_BAD_NUMBER_FORMAT;
+  if (end == *pstr) return STAT_GCODE_COMMAND_UNSUPPORTED;
   *pstr = end; // pointer points to next character after the word
 
   return STAT_OK;
index 2e176a6a1cd6f8ace5150996cf3a481e2adcaace..6ea39ece0f8c36c4d59c14c4b593e164e298129f 100644 (file)
@@ -81,11 +81,11 @@ static void _run() {
 #define DISPATCH(func) if (_dispatch(func)) return;
 
   DISPATCH(hw_reset_handler);                // handle hard reset requests
-  DISPATCH(tmc2660_sync);                    // synchronize driver config
-  DISPATCH(motor_power_callback);            // stepper motor power sequencing
 
   DISPATCH(command_hi);
 
+  DISPATCH(tmc2660_sync);                    // synchronize driver config
+  DISPATCH(motor_power_callback);            // stepper motor power sequencing
   DISPATCH(cm_feedhold_sequencing_callback); // feedhold state machine
   DISPATCH(mp_plan_hold_callback);           // plan a feedhold
   DISPATCH(cm_arc_callback);                 // arc generation runs
index 1aa07cbb372babca1392d488ea77ec6b23418bf8..1c18b54f86cb7ea7c35bc345e25398de69018086 100644 (file)
@@ -56,7 +56,7 @@ STAT_MSG(INPUT_EXCEEDS_MAX_VALUE, "Input exceeds maximum value")
 STAT_MSG(INPUT_VALUE_RANGE_ERROR, "Input value range error")
 
 // Gcode errors & warnings (Most originate from NIST)
-STAT_MSG(GCODE_COMMAND_UNSUPPORTED, "Gcode command unsupported")
+STAT_MSG(GCODE_COMMAND_UNSUPPORTED, "Invalid or unsupported G-Code command")
 STAT_MSG(MCODE_COMMAND_UNSUPPORTED, "M code unsupported")
 STAT_MSG(GCODE_AXIS_IS_MISSING, "Axis word missing")
 STAT_MSG(GCODE_FEEDRATE_NOT_SPECIFIED, "Feedrate not specified")
@@ -88,3 +88,6 @@ STAT_MSG(HOMING_ERROR_SWITCH_MISCONFIGURATION,
 
 // Probing
 STAT_MSG(PROBE_CYCLE_FAILED, "Probe cycle failed")
+
+// End of stats marker
+STAT_MSG(MAX, "")
index d3674f7675cb8b091d672a6795ff2a7754a592a8..02bf2f5e68e5d291e8f2502c8b2e741ac52e7de4 100644 (file)
@@ -64,3 +64,18 @@ stat_t status_error_P(const char *location, const char *msg, stat_t status) {
 
   return status;
 }
+
+
+void status_help() {
+  putchar('{');
+
+  for (int i = 0; i < STAT_MAX; i++) {
+    if (i) putchar(',');
+    putchar('\n');
+    printf_P(PSTR("  \"%d\": \"%S\""), i, status_to_pgmstr(i));
+  }
+
+  putchar('\n');
+  putchar('}');
+  putchar('\n');
+}
index 10477169b2c245c1973f5c3294db37a9df748486..b320591ae38a1db5787df6d235f4235df993fa03 100644 (file)
@@ -39,7 +39,7 @@ typedef enum {
 #include "messages.def"
 #undef STAT_MSG
 
-  STAT_MAX_VALUE = 255 // Do not exceed 255
+  STAT_DO_NOT_EXCEED = 255 // Do not exceed 255
 } stat_t;
 
 
@@ -48,6 +48,7 @@ extern stat_t status_code;
 const char *status_to_pgmstr(stat_t status);
 stat_t status_error(stat_t status);
 stat_t status_error_P(const char *location, const char *msg, stat_t status);
+void status_help();
 
 #define TO_STRING(x) _TO_STRING(x)
 #define _TO_STRING(x) #x
index 359b8fc5eab78e360b7192faea1a997e2dfb6cf0..a99528cec94a11c007971b8b4e1899b08cda876a 100644 (file)
 #define RING_BUF_SIZE USART_RX_RING_BUF_SIZE
 #include "ringbuf.def"
 
-#define RING_BUF_NAME echo_buf
-#define RING_BUF_SIZE USART_ECHO_RING_BUF_SIZE
-#include "ringbuf.def"
-
 static int usart_flags = USART_CRLF | USART_ECHO;
 
 
@@ -65,26 +61,11 @@ static void _set_rxc_interrupt(bool enable) {
 }
 
 
-static void _echo_char(char c) {
-  if (echo_buf_full()) return;
-
-  echo_buf_push(c);
-  _set_dre_interrupt(true); // Enable interrupt
-
-  if ((usart_flags & USART_CRLF) && c == '\n') _echo_char('\r');
-}
-
-
 // Data register empty interrupt vector
 ISR(USARTC0_DRE_vect) {
-  if (tx_buf_empty() && echo_buf_empty())
-    _set_dre_interrupt(false); // Disable interrupt
+  if (tx_buf_empty()) _set_dre_interrupt(false); // Disable interrupt
 
-  else if (!echo_buf_empty()) {
-    USARTC0.DATA = echo_buf_peek();
-    echo_buf_pop();
-
-  } else {
+  else {
     USARTC0.DATA = tx_buf_peek();
     tx_buf_pop();
   }
@@ -98,7 +79,6 @@ ISR(USARTC0_RXC_vect) {
   else {
     uint8_t data = USARTC0.DATA;
     rx_buf_push(data);
-    if (usart_flags & USART_ECHO) _echo_char(data);
     if (rx_buf_space() < 4) PORTC.OUTSET = 1 << 4; // CTS Hi (disable)
   }
 }
@@ -221,14 +201,31 @@ char *usart_readline() {
     char data = rx_buf_peek();
     rx_buf_pop();
 
+    if (usart_flags & USART_ECHO) usart_putc(data);
+
     switch (data) {
     case '\r': case '\n': eol = true; break;
 
-    case '\b':
-      printf(" \b");
+    case '\b': // BS - backspace
+      if (usart_flags & USART_ECHO) {
+        usart_putc(' ');
+        usart_putc('\b');
+      }
       if (i) i--;
       break;
 
+    case 0x18: // CAN - Cancel or CTRL-X
+      if (usart_flags & USART_ECHO)
+        while (i) {
+          usart_putc('\b');
+          usart_putc(' ');
+          usart_putc('\b');
+          i--;
+        }
+
+      i = 0;
+      break;
+
     default:
       line[i++] = data;
       if (i == INPUT_BUFFER_LEN - 1) eol = true;