More work on Marlin-compatibility (M104,M140,M109,M190 implemented)

This commit is contained in:
Rob Giseburt
2017-01-18 15:48:31 -06:00
parent b5d28c27f7
commit c1b2a91115
6 changed files with 190 additions and 34 deletions
+7 -1
View File
@@ -176,7 +176,13 @@ typedef enum { // these are in order to optimized CASE
NEXT_ACTION_SUSPEND_ORIGIN_OFFSETS, // G92.2
NEXT_ACTION_RESUME_ORIGIN_OFFSETS, // G92.3
NEXT_ACTION_JSON_COMMAND_SYNC, // M100
NEXT_ACTION_JSON_WAIT // M101
NEXT_ACTION_JSON_COMMAND_ASYNC, // M100.1
NEXT_ACTION_JSON_WAIT, // M101
#if MARLIN_COMPAT_ENABLED == true
NEXT_ACTION_MARLIN_SET_EXTRUDER_TEMP, // 104, 109
NEXT_ACTION_MARLIN_SET_BED_TEMP, // 140, 190
#endif
} cmNextAction;
typedef enum { // G Modal Group 1
+1 -1
View File
@@ -725,7 +725,7 @@ nvObj_t *nv_add_conditional_message(const char *string) // conditionally add
void nv_print_list(stat_t status, uint8_t text_flags, uint8_t json_flags)
{
if (js.json_mode == JSON_MODE) {
if ((js.json_mode == JSON_MODE) || (js.json_mode == MARLIN_COMM_MODE)) {
json_print_list(status, json_flags);
} else {
text_print_list(status, text_flags);
+4
View File
@@ -171,6 +171,10 @@ static void _controller_HSM()
DISPATCH(cm_jogging_cycle_callback()); // jog cycle operation
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!
#endif
//----- command readers and parsers --------------------------------------------------//
DISPATCH(_sync_to_planner()); // ensure there is at least one free buffer in planning queue
+42 -14
View File
@@ -76,6 +76,8 @@ typedef struct GCodeInputValue { // Gcode inputs - meaning depends on context
#if MARLIN_COMPAT_ENABLED == true
bool marlin_temp_requested; // M105 temperature report request (Marlin-only)
bool marlin_position_requested; // M114 position report request (Marlin-only)
bool marlin_wait_for_temp; // M140 or M190 - wait for temperature (Marlin-only)
#endif
} GCodeValue_t;
@@ -700,6 +702,12 @@ stat_t _parse_gcode_block(char *buf, char *active_comment)
#warning MARLIN_COMPAT_ENABLED
case 105: SET_NON_MODAL (marlin_temp_requested, true);
case 114: SET_NON_MODAL (marlin_position_requested, true);
case 140: gv.marlin_wait_for_temp = true; // NO break!
case 104: SET_NON_MODAL (next_action, NEXT_ACTION_MARLIN_SET_EXTRUDER_TEMP);
case 190: gv.marlin_wait_for_temp = true; // NO break!
case 109: SET_NON_MODAL (next_action, NEXT_ACTION_MARLIN_SET_BED_TEMP);
#endif // MARLIN_COMPAT_ENABLED
default: status = STAT_MCODE_COMMAND_UNSUPPORTED;
@@ -782,6 +790,40 @@ stat_t _execute_gcode_block(char *active_comment)
cm_set_model_linenum(gv.linenum);
EXEC_FUNC(cm_set_feed_rate_mode, feed_rate_mode); // G93, G94
EXEC_FUNC(cm_set_feed_rate, F_word); // F
#if MARLIN_COMPAT_ENABLED == true
// Handle Marlin specifics
// must be before we deal with S_word and P_word, since it MIGHT use those
if (gf.marlin_temp_requested) { // M105
js.json_mode = MARLIN_COMM_MODE; // we use M105 to know when to switch
ritorno(marlin_request_temperature_report());
}
if (gf.marlin_position_requested) { // M114
js.json_mode = MARLIN_COMM_MODE; // we use M105 to know when to switch
ritorno(marlin_request_position_report());
}
switch (gv.next_action) {
case NEXT_ACTION_MARLIN_SET_EXTRUDER_TEMP: { // M104 or M140
float temp = 0;
if (gf.S_word) { temp = gv.S_word; }
if (gf.P_word) { temp = gv.P_word; } // we treat them the same, for now
status = marlin_set_temperature(cm.gm.tool_select, temp, gv.marlin_wait_for_temp);
return status;
break;
}
case NEXT_ACTION_MARLIN_SET_BED_TEMP: { // M109 or M190
float temp = 0;
if (gf.S_word) { temp = gv.S_word; }
if (gf.P_word) { temp = gv.P_word; } // we treat them the same, for now
// Note: tool is zero-based, so to gt he3 (the bed) we pass tool as 2
status = marlin_set_temperature(2, temp, gv.marlin_wait_for_temp);
return status;
break;
}
}
#endif // MARLIN_COMPAT_ENABLED
EXEC_FUNC(cm_set_spindle_speed, S_word); // S
if (gf.sso_control) { // spindle speed override
ritorno(cm_sso_control(gv.P_word, gf.P_word));
@@ -883,20 +925,6 @@ stat_t _execute_gcode_block(char *active_comment)
}
}
#if MARLIN_COMPAT_ENABLED == true
// Handle Marlin specifics
if (gf.marlin_temp_requested) { // spindle speed override
js.json_mode = MARLIN_COMM_MODE; // we use M105 to know when to switch
ritorno(marlin_request_temperature_report());
}
if (gf.marlin_position_requested) { // spindle speed override
js.json_mode = MARLIN_COMM_MODE; // we use M105 to know when to switch
ritorno(marlin_request_position_report());
}
#endif // MARLIN_COMPAT_ENABLED
// do the program stops and ends : M0, M1, M2, M30, M60
if (gf.program_flow == true) {
if (gv.program_flow == PROGRAM_STOP) {
+133 -18
View File
@@ -29,6 +29,8 @@
#include "util.h"
#include "xio.h" // for char definitions
#include "json_parser.h"
#include "planner.h"
#include "MotateTimers.h" // for char definitions
// Structures used
enum STK500 {
@@ -51,6 +53,24 @@ enum STK500 {
bool temperature_requested = false;
bool position_requested = false;
// State machine to handle marlin temperature controls
enum class MarlinSetTempState {
Idle = 0,
SettingTemperature,
StartingUpdates,
StartingWait,
StoppingUpdates,
SettingTemperatureNoWait
};
MarlinSetTempState set_temp_state; // record the state for the temperature-control pseudo-cycle
// These next parameters for the next temperature-control pseudo-cycle are only needed until the calls are queued.
float next_temperature; // as it says
uint8_t next_temperature_tool; // this is a g2core (1-based) tool
// Information about if we are to be dumping periodic temperature updates
bool temperature_updates_requested = false;
Motate::Timeout temperature_update_timeout;
// local helper functions and macros
/*
@@ -263,27 +283,122 @@ void marlin_response(const stat_t status, char *buf)
xio_writeline(buffer);
}
//stat_t gc_get_gc(nvObj_t *nv)
//{
// ritorno(nv_copy_string(nv, cs.saved_buf));
// nv->valuetype = TYPE_STRING;
// return (STAT_OK);
//}
//
//stat_t gc_run_gc(nvObj_t *nv)
//{
// return(gcode_parser(*nv->stringp));
//}
/*
* _marlin_start_temperature_updates()/_marlin_end_temperature_updates() -
* calls from commands in the buffer to manage temperature_updates_requested
*/
void _marlin_start_temperature_updates(float* vect, bool* flag) {
temperature_updates_requested = true;
temperature_update_timeout.set(1); // immediately
}
/***********************************************************************************
* TEXT MODE SUPPORT
* Functions to print variables from the cfgArray table
***********************************************************************************/
void _marlin_end_temperature_updates(float* vect, bool* flag) {
temperature_updates_requested = false;
}
#ifdef __TEXT_MODE
/*
* _queue_next_temperature_comands() - returns true if it finished
*/
bool _queue_next_temperature_commands()
{
if (MarlinSetTempState::Idle != set_temp_state) {
if (mp_planner_is_full()) {
return false;
}
// no text mode functions here. Move along
char buffer[128];
char *str = buffer;
#endif // __TEXT_MODE
if ((MarlinSetTempState::SettingTemperature == set_temp_state) ||
(MarlinSetTempState::SettingTemperatureNoWait == set_temp_state))
{
str += sprintf(str, "{he%dst:%.2f}", next_temperature_tool, next_temperature);
cm_json_command(buffer);
if (MarlinSetTempState::SettingTemperatureNoWait == set_temp_state) {
set_temp_state = MarlinSetTempState::Idle;
return true;
}
set_temp_state = MarlinSetTempState::StartingUpdates;
if (mp_planner_is_full()) {
return false;
}
}
if (MarlinSetTempState::StartingUpdates == set_temp_state) {
mp_queue_command(_marlin_start_temperature_updates, nullptr, nullptr);
set_temp_state = MarlinSetTempState::StartingWait;
if (mp_planner_is_full()) {
return false;
}
}
if (MarlinSetTempState::StartingWait == set_temp_state) {
str = buffer;
str += sprintf(str, "{he%dat:t}", next_temperature_tool);
cm_json_wait(buffer);
set_temp_state = MarlinSetTempState::StoppingUpdates;
if (mp_planner_is_full()) {
return false;
}
}
if (MarlinSetTempState::StoppingUpdates == set_temp_state) {
mp_queue_command(_marlin_end_temperature_updates, nullptr, nullptr);
set_temp_state = MarlinSetTempState::Idle;
}
}
return true;
}
/*
* marlin_callback() - called by controller dispatcher - return STAT_EAGAIN if it failed
*/
stat_t marlin_callback()
{
if (temperature_updates_requested && (temperature_update_timeout.isPast())) {
char buffer[128];
char *str = buffer;
_report_temperatures(str);
*str++ = '\n';
*str++ = 0;
temperature_update_timeout.set(1000); // every second
xio_writeline(buffer);
} // temperature updates
if (!_queue_next_temperature_commands()) {
return STAT_EAGAIN;
}
return STAT_OK;
}
stat_t marlin_set_temperature(uint8_t tool, float temperature, bool wait) {
if (MarlinSetTempState::Idle != set_temp_state) {
return (STAT_BUFFER_FULL_FATAL); // this shouldn't happen
}
if ((tool < 0) || (tool > 3)) {
return STAT_INPUT_VALUE_RANGE_ERROR;
}
set_temp_state = wait ? MarlinSetTempState::SettingTemperature : MarlinSetTempState::SettingTemperatureNoWait;
next_temperature = temperature;
// Note the conversion from a "marlin" tool (zero-base) to a g2core tool (1-based)
next_temperature_tool = tool + 1;
_queue_next_temperature_commands(); // we can ignore the return
return (STAT_OK);
}
#endif // MARLIN_COMPAT_ENABLED == true
+3
View File
@@ -33,7 +33,10 @@ bool marlin_handle_fake_stk500(char *str);
stat_t marlin_request_temperature_report(); // M105
stat_t marlin_request_position_report(); // M114
stat_t marlin_set_temperature(uint8_t tool, float temperature, bool wait); // M104, M109, M140, M190
void marlin_response(const stat_t status, char *buf);
stat_t marlin_callback();
#endif // End of include guard: MARLIN_COMPAT_H_ONCE