From 7a9c41aa8d68703a4f67be1026fa05db0c87cdd2 Mon Sep 17 00:00:00 2001 From: Joseph Coffland Date: Mon, 27 Jun 2016 03:42:47 -0700 Subject: [PATCH] Improved usart_readline(), Improved help, Added feedhold, start cycle & flush queue character commands --- src/command.c | 34 ++++++++++++++++++++++++++++++++-- src/command.def | 1 + src/gcode_parser.c | 2 +- src/main.c | 4 ++-- src/messages.def | 5 ++++- src/status.c | 15 +++++++++++++++ src/status.h | 3 ++- src/usart.c | 45 +++++++++++++++++++++------------------------ 8 files changed, 78 insertions(+), 31 deletions(-) diff --git a/src/command.c b/src/command.c index 80818cc..64aba85 100644 --- a/src/command.c +++ b/src/command.c @@ -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; +} diff --git a/src/command.def b/src/command.def index 91d3240..03f5dca 100644 --- a/src/command.def +++ b/src/command.def @@ -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") diff --git a/src/gcode_parser.c b/src/gcode_parser.c index 8343c79..20e243f 100644 --- a/src/gcode_parser.c +++ b/src/gcode_parser.c @@ -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; diff --git a/src/main.c b/src/main.c index 2e176a6..6ea39ec 100644 --- a/src/main.c +++ b/src/main.c @@ -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 diff --git a/src/messages.def b/src/messages.def index 1aa07cb..1c18b54 100644 --- a/src/messages.def +++ b/src/messages.def @@ -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, "") diff --git a/src/status.c b/src/status.c index d3674f7..02bf2f5 100644 --- a/src/status.c +++ b/src/status.c @@ -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'); +} diff --git a/src/status.h b/src/status.h index 1047716..b320591 100644 --- a/src/status.h +++ b/src/status.h @@ -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 diff --git a/src/usart.c b/src/usart.c index 359b8fc..a99528c 100644 --- a/src/usart.c +++ b/src/usart.c @@ -43,10 +43,6 @@ #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; -- 2.27.0