diff --git a/g2core/controller.cpp b/g2core/controller.cpp old mode 100755 new mode 100644 index 8b38f67d..b33f128c --- a/g2core/controller.cpp +++ b/g2core/controller.cpp @@ -172,7 +172,7 @@ static void _controller_HSM() DISPATCH(cm_deferred_write_callback()); // persist G10 changes when not in machining cycle #if MARLIN_COMPAT_ENABLED == true - DISPATCH(marlin_callback()); // handle marlin stuff - may return EAGAIN, must be after planner_callback! + DISPATCH(marlin_callback()); // handle Marlin stuff - may return EAGAIN, must be after planner_callback! #endif //----- command readers and parsers --------------------------------------------------// @@ -234,7 +234,6 @@ static void _dispatch_kernel(const devflags_t flags) // marlin_handle_fake_stk500 returns true if it responded to a stk500v2 message if (marlin_handle_fake_stk500(cs.bufp)) { js.json_mode = MARLIN_COMM_MODE; - sr.status_report_verbosity = SR_OFF; qr.queue_report_verbosity = QR_OFF; return; @@ -282,6 +281,7 @@ static void _dispatch_kernel(const devflags_t flags) text_response(gcode_parser(cs.bufp), cs.saved_buf); } #endif + #if MARLIN_COMPAT_ENABLED == true else if (js.json_mode == MARLIN_COMM_MODE) { // handle marlin-specific protocol gcode cs.comm_request_mode = MARLIN_COMM_MODE; // mode of this command @@ -297,16 +297,18 @@ static void _dispatch_kernel(const devflags_t flags) nv_copy_string(nv, cs.bufp); // copy the Gcode line nv->valuetype = TYPE_STRING; status = gcode_parser(cs.bufp); + #if MARLIN_COMPAT_ENABLED == true if (js.json_mode == MARLIN_COMM_MODE) { // in case a marlin-specific M-code was found cs.comm_request_mode = MARLIN_COMM_MODE; // mode of this command - // We ae switching to marlin_comm_mode, kill status reports and queue reports + // We are switching to marlin_comm_mode, kill status reports and queue reports sr.status_report_verbosity = SR_OFF; qr.queue_report_verbosity = QR_OFF; marlin_response(status, cs.saved_buf); return; } #endif + nv_print_list(status, TEXT_NO_PRINT, JSON_RESPONSE_FORMAT); sr_request_status_report(SR_REQUEST_TIMED); // generate incremental status report to show any changes } @@ -335,6 +337,7 @@ static stat_t _controller_state() { if (cs.controller_state == CONTROLLER_CONNECTED) { // first time through after reset cs.controller_state = CONTROLLER_STARTUP; + // This is here just to put a small delay in before the startup message. #if MARLIN_COMPAT_ENABLED == true // For Marlin compatibility, we need this to be long enough for the UI to say something and reveal diff --git a/g2core/gcode_parser.cpp b/g2core/gcode_parser.cpp index e3658e7f..91183f65 100644 --- a/g2core/gcode_parser.cpp +++ b/g2core/gcode_parser.cpp @@ -33,8 +33,12 @@ #include "json_parser.h" // so we can switch js.comm_mode on a marlin M-code #endif +// Helpers + static stat_t _execute_gcode_block_marlin(void); +// Locally used enums + typedef enum { // Used for detecting gcode errors. See NIST section 3.4 MODAL_GROUP_G0 = 0, // {G10,G28,G28.1,G92} non-modal axis commands (note 1) MODAL_GROUP_G1, // {G0,G1,G2,G3,G80} motion diff --git a/g2core/settings/settings_Printrbot_Play.h b/g2core/settings/settings_Printrbot_Play.h index 121c9520..3983a151 100644 --- a/g2core/settings/settings_Printrbot_Play.h +++ b/g2core/settings/settings_Printrbot_Play.h @@ -58,9 +58,9 @@ // Communications and reporting settings #define MARLIN_COMPAT_ENABLED true // enable marlin compatibility mode -#define COMM_MODE JSON_MODE // one of: TEXT_MODE, JSON_MODE -#define XIO_ENABLE_FLOW_CONTROL FLOW_CONTROL_RTS // FLOW_CONTROL_OFF, FLOW_CONTROL_RTS -#define XIO_UART_MUTES_WHEN_USB_CONNECTED 1 // Mute the UART when USB connects +#define COMM_MODE JSON_MODE // one of: TEXT_MODE, JSON_MODE +#define XIO_ENABLE_FLOW_CONTROL FLOW_CONTROL_RTS // FLOW_CONTROL_OFF, FLOW_CONTROL_RTS +#define XIO_UART_MUTES_WHEN_USB_CONNECTED 1 // Mute the UART when USB connects #define TEXT_VERBOSITY TV_VERBOSE // one of: TV_SILENT, TV_VERBOSE #define JSON_VERBOSITY JV_LINENUM // one of: JV_SILENT, JV_FOOTER, JV_CONFIGS, JV_MESSAGES, JV_LINENUM, JV_VERBOSE diff --git a/g2core/settings/settings_Printrbot_Simple_1403.h b/g2core/settings/settings_Printrbot_Simple_1403.h index 72a82f48..a79115d1 100644 --- a/g2core/settings/settings_Printrbot_Simple_1403.h +++ b/g2core/settings/settings_Printrbot_Simple_1403.h @@ -57,7 +57,7 @@ // Communications and reporting settings -#define MARLIN_COMPAT_ENABLED true // enable marlin compatibility mode +#define MARLIN_COMPAT_ENABLED true // enable marlin compatibility mode #define COMM_MODE JSON_MODE // one of: TEXT_MODE, JSON_MODE #define XIO_ENABLE_FLOW_CONTROL FLOW_CONTROL_RTS // FLOW_CONTROL_OFF, FLOW_CONTROL_RTS #define XIO_UART_MUTES_WHEN_USB_CONNECTED 1 // Mute the UART when USB connects diff --git a/g2core/xio.cpp b/g2core/xio.cpp old mode 100755 new mode 100644 index 6b1cab70..514f9ccb --- a/g2core/xio.cpp +++ b/g2core/xio.cpp @@ -355,18 +355,18 @@ struct xio_t { // Always check control-capable devices FIRST for (uint8_t dev=0; dev < _dev_count; dev++) { - if (!DeviceWrappers[dev]->isActive()) + if (!DeviceWrappers[dev]->isActive()) { continue; - + } + // If this channel is a DATA only, skip it this pass - if (!DeviceWrappers[dev]->isCtrl()) + if (!DeviceWrappers[dev]->isCtrl()) { continue; - + } ret_buffer = DeviceWrappers[dev]->readline(DEV_IS_CTRL, size); if (size > 0) { flags = DeviceWrappers[dev]->flags; - return ret_buffer; } } @@ -381,12 +381,10 @@ struct xio_t { if (size > 0) { flags = DeviceWrappers[dev]->flags; - return ret_buffer; } } } - size = 0; flags = 0; @@ -633,10 +631,8 @@ struct LineRXBuffer : RXBuffer<_size, owner_type, char> { while (_isMoreToScan()) { bool ends_line = false; bool is_control = false; - char c = _data[_scan_offset]; - #if MARLIN_COMPAT_ENABLED == true // it's possible something will try to talk stk500v2 to us. // See https://github.com/synthetos/g2/wiki/Marlin-Compatibility#stk500v2 @@ -647,8 +643,7 @@ struct LineRXBuffer : RXBuffer<_size, owner_type, char> { return false; } - if (_stk_parser_state >= STK500V2_State::Timeout) - { + if (_stk_parser_state >= STK500V2_State::Timeout) { if (_stk_parser_state == STK500V2_State::Timeout) { if (_stk_timeout.isPast()) { _stk_parser_state = STK500V2_State::Done; @@ -668,15 +663,12 @@ struct LineRXBuffer : RXBuffer<_size, owner_type, char> { _line_start_offset = _scan_offset; } else if ((c == '{') || (c == 'N') || (c == '\n') || (c == '\r') || (c == 'G') || (c == 'M')) { - // jump out of bootloader mode - _stk_parser_state = STK500V2_State::Done; + _stk_parser_state = STK500V2_State::Done; // jump out of bootloader mode _read_offset = _scan_offset; continue; } - } else if (_stk_parser_state == STK500V2_State::Sequence) { - // we ignore the sequence - _stk_parser_state = STK500V2_State::Length_0; + _stk_parser_state = STK500V2_State::Length_0; // we ignore the sequence } else if (_stk_parser_state == STK500V2_State::Length_0) { _stk_packet_data_length = c << 8; _stk_parser_state = STK500V2_State::Length_1; @@ -686,42 +678,34 @@ struct LineRXBuffer : RXBuffer<_size, owner_type, char> { } else if (_stk_parser_state == STK500V2_State::Header_End) { if (c == 0x0E) { _stk_parser_state = STK500V2_State::Data; - } else { - // end-of-header marker was corrupt, start over + } else { // end-of-header marker was corrupt, start over _stk_packet_data_length = 0; _read_offset = _scan_offset; _stk_parser_state = STK500V2_State::Start; } } else if (_stk_parser_state == STK500V2_State::Data) { - - // we don't read the data here, just return it - if (--_stk_packet_data_length == 0) { + if (--_stk_packet_data_length == 0) { // we don't read the data here, just return it _stk_parser_state = STK500V2_State::Checksum; } } else if (_stk_parser_state == STK500V2_State::Checksum) { - // we do NOT check the checksum, since if it's corrupt, we - // need to reply, and we can't reply here. - - // at this point, we at least have a complete packet - // we will use the "control" return machanism to handle this - // since controls don't have to be \r\n-terminated + // We do NOT check the checksum, since if it's corrupt, we'd need to reply, and we can't reply here. + // At this point, we at least have a complete packet we will use the "control" return mechanism to + // handle this since controls don't have to be \r\n-terminated is_control = true; ends_line = true; - - // this line is complete, reset the state engine - _stk_parser_state = STK500V2_State::Start; + _stk_parser_state = STK500V2_State::Start; // this line is complete, reset the state engine } } else -#else +#else // not MARLIN_COMPAT_ENABLED if (c == 0) { _debug_trap("scan ran into NULL"); flush(); // consider the connection and all data trashed return false; } +#endif // MARLIN_COMPAT_ENABLED -#endif // Look for line endings if (c == '\r' || c == '\n') { if (_ignore_until_next_line) { @@ -790,7 +774,6 @@ struct LineRXBuffer : RXBuffer<_size, owner_type, char> { if (_data[_line_start_offset] == '{') { is_control = true; } - // TODO --- } @@ -825,8 +808,6 @@ struct LineRXBuffer : RXBuffer<_size, owner_type, char> { // move the start of the next skip section to after this skip _line_start_offset = _scan_offset; } - - return false; // no control was found }; @@ -1119,9 +1100,7 @@ struct xioDeviceWrapper : xioDeviceWrapperBase { // describes a device for re setAsConnectedAndReady(); - - if (isAlwaysDataAndCtrl()) { - // Case 1 (ignoring others) + if (isAlwaysDataAndCtrl()) { // Case 1 (ignoring others) setActive(); controller_set_connected(true); @@ -1129,7 +1108,6 @@ struct xioDeviceWrapper : xioDeviceWrapperBase { // describes a device for re if (isMuteAsSecondary() && xio.othersConnected(this)) { controller_set_muted(true); // something was muted } - return; } @@ -1143,18 +1121,16 @@ struct xioDeviceWrapper : xioDeviceWrapperBase { // describes a device for re controller_set_muted(true); // something was muted } #if MARLIN_COMPAT_ENABLED == true - // start the "fake bootloader" + // start the "fake bootloader" to signal the Host that Marlin (mode) is operating _rx_buffer.startFakeBootloaderMode(); #endif } - else if (isMuteAsSecondary()) { - // Case 2b + else if (isMuteAsSecondary()) { // Case 2b setAsMuted(); controller_set_connected(true); // it DID just just get connected controller_set_muted(true); // but it muted it too } - else { - // Case 2a + else { // Case 2a xio.removeDataFromPrimary(); if (xio.checkMutedSecondaryChannels()) { controller_set_muted(true); // something was muted