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;
_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;
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()
}
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);
vars_clear();
return 0;
}
+
+
+uint8_t command_messages(int argc, char *argv[]) {
+ status_help();
+ return 0;
+}
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")
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;
#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
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")
// Probing
STAT_MSG(PROBE_CYCLE_FAILED, "Probe cycle failed")
+
+// End of stats marker
+STAT_MSG(MAX, "")
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');
+}
#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;
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
#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;
}
-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();
}
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)
}
}
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;