Support for Debug Codes - Dnnn (#19225)

Co-authored-by: Scott Lahteine <thinkyhead@users.noreply.github.com>
This commit is contained in:
Victor Oliveira
2020-10-09 08:25:23 -03:00
committed by Scott Lahteine
parent 0b13608bad
commit 2553a18f40
20 changed files with 269 additions and 38 deletions

View File

@ -46,7 +46,7 @@
* Tx Same as T?, but nozzle doesn't have to be preheated. Tc requires a preheated nozzle to finish filament load.
* Tc Load to nozzle after filament was prepared by Tc and nozzle is already heated.
*/
void GcodeSuite::T(const uint8_t tool_index) {
void GcodeSuite::T(const int8_t tool_index) {
DEBUG_SECTION(log_T, "T", DEBUGGING(LEVELING));
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPAIR("...(", tool_index, ")");

View File

@ -923,6 +923,10 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) {
case 'T': T(parser.codenum); break; // Tn: Tool Change
#if ENABLED(MARLIN_DEV_MODE)
case 'D': D(parser.codenum); break; // Dn: Debug codes
#endif
default:
#if ENABLED(WIFI_CUSTOM_COMMAND)
if (wifi_custom_command(parser.command_ptr)) break;

View File

@ -285,6 +285,7 @@
* M995 - Touch screen calibration for TFT display
* M997 - Perform in-application firmware update
* M999 - Restart after being stopped by error
* D... - Custom Development G-code. Add hooks to 'gcode_D.cpp' for developers to test features. (Requires MARLIN_DEV_MODE)
*
* "T" Codes
*
@ -408,6 +409,8 @@ public:
private:
TERN_(MARLIN_DEV_MODE, static void D(const int16_t dcode));
static void G0_G1(TERN_(HAS_FAST_MOVES, const bool fast_move=false));
TERN_(ARC_SUPPORT, static void G2_G3(const bool clockwise));
@ -882,7 +885,7 @@ private:
TERN_(CONTROLLER_FAN_EDITABLE, static void M710());
static void T(const uint8_t tool_index);
static void T(const int8_t tool_index);
};

View File

@ -0,0 +1,173 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#include "../inc/MarlinConfigPre.h"
#if ENABLED(MARLIN_DEV_MODE)
#include "gcode.h"
#include "../module/settings.h"
#include "../libs/hex_print.h"
#include "../HAL/shared/eeprom_if.h"
/**
* Dn: G-code for development and testing
*
* See https://reprap.org/wiki/G-code#D:_Debug_codes
*
* Put whatever else you need here to test ongoing development.
*/
void GcodeSuite::D(const int16_t dcode) {
switch (dcode) {
case -1:
for (;;); // forever
case 0:
HAL_reboot();
break;
case 1: {
// Zero or pattern-fill the EEPROM data
#if ENABLED(EEPROM_SETTINGS)
persistentStore.access_start();
size_t total = persistentStore.capacity();
int pos = 0;
const uint8_t value = 0x0;
while(total--) {
persistentStore.write_data(pos, &value, 1);
}
persistentStore.access_finish();
#else
settings.reset();
settings.save();
#endif
HAL_reboot();
} break;
case 2: { // D2 Read / Write SRAM
#define SRAM_SIZE 8192
uint8_t *pointer = parser.hex_adr_val('A');
uint16_t len = parser.ushortval('C', 1);
uintptr_t addr = (uintptr_t)pointer;
NOMORE(addr, (size_t)(SRAM_SIZE - 1));
NOMORE(len, SRAM_SIZE - addr);
if (parser.seenval('X')) {
// Write the hex bytes after the X
uint16_t val = parser.hex_val('X');
while (len--) {
*pointer = val;
pointer++;
}
}
else {
while (len--) print_hex_byte(*(pointer++));
SERIAL_EOL();
}
} break;
case 3: { // D3 Read / Write EEPROM
uint8_t *pointer = parser.hex_adr_val('A');
uint16_t len = parser.ushortval('C', 1);
uintptr_t addr = (uintptr_t)pointer;
#ifndef MARLIN_EEPROM_SIZE
#define MARLIN_EEPROM_SIZE size_t(E2END + 1)
#endif
NOMORE(addr, (size_t)(MARLIN_EEPROM_SIZE - 1));
NOMORE(len, MARLIN_EEPROM_SIZE - addr);
if (parser.seenval('X')) {
uint16_t val = parser.hex_val('X');
#if ENABLED(EEPROM_SETTINGS)
persistentStore.access_start();
while(len--) {
int pos = 0;
persistentStore.write_data(pos, (uint8_t *)&val, sizeof(val));
}
SERIAL_EOL();
persistentStore.access_finish();
#else
SERIAL_ECHOLN("NO EEPROM");
#endif
}
else {
while (len--) {
// Read bytes from EEPROM
#if ENABLED(EEPROM_SETTINGS)
persistentStore.access_start();
uint8_t val;
while(len--) {
int pos = 0;
if (!persistentStore.read_data(pos, (uint8_t *)&val, sizeof(val))) {
print_hex_byte(val);
}
}
SERIAL_EOL();
persistentStore.access_finish();
#else
SERIAL_ECHOLN("NO EEPROM");
#endif
}
SERIAL_EOL();
}
} break;
case 4: { // D4 Read / Write PIN
// const uint8_t pin = parser.byteval('P');
// const bool is_out = parser.boolval('F'),
// val = parser.byteval('V', LOW);
if (parser.seenval('X')) {
// TODO: Write the hex bytes after the X
//while (len--) {
//}
}
else {
// while (len--) {
// TODO: Read bytes from EEPROM
// print_hex_byte(eeprom_read_byte(*(adr++));
// }
SERIAL_EOL();
}
} break;
case 5: { // D4 Read / Write onboard Flash
#define FLASH_SIZE 1024
uint8_t *pointer = parser.hex_adr_val('A');
uint16_t len = parser.ushortval('C', 1);
uintptr_t addr = (uintptr_t)pointer;
NOMORE(addr, (size_t)(FLASH_SIZE - 1));
NOMORE(len, FLASH_SIZE - addr);
if (parser.seenval('X')) {
// TODO: Write the hex bytes after the X
//while (len--) {
//}
}
else {
// while (len--) {
// TODO: Read bytes from EEPROM
// print_hex_byte(eeprom_read_byte(adr++));
// }
SERIAL_EOL();
}
} break;
}
}
#endif

View File

@ -147,22 +147,15 @@ void GCodeParser::parse(char *p) {
starpos[1] = '\0';
}
#if ENABLED(GCODE_MOTION_MODES)
#if ENABLED(ARC_SUPPORT)
#define GTOP 3
#else
#define GTOP 1
#endif
#if ANY(MARLIN_DEV_MODE, SWITCHING_TOOLHEAD, MAGNETIC_SWITCHING_TOOLHEAD, ELECTROMAGNETIC_SWITCHING_TOOLHEAD)
#define SIGNED_CODENUM 1
#endif
// Bail if the letter is not G, M, or T
// (or a valid parameter for the current motion mode)
switch (letter) {
case 'G': case 'M': case 'T':
#if ENABLED(CANCEL_OBJECTS)
case 'O':
#endif
case 'G': case 'M': case 'T': TERN_(MARLIN_DEV_MODE, case 'D':)
// Skip spaces to get the numeric part
while (*p == ' ') p++;
@ -178,22 +171,33 @@ void GCodeParser::parse(char *p) {
#endif
// Bail if there's no command code number
if (!NUMERIC(*p)) return;
if (!TERN(SIGNED_CODENUM, NUMERIC_SIGNED(*p), NUMERIC(*p))) return;
// Save the command letter at this point
// A '?' signifies an unknown command
command_letter = letter;
// Get the code number - integer digits only
codenum = 0;
do { codenum *= 10, codenum += *p++ - '0'; } while (NUMERIC(*p));
{
#if ENABLED(SIGNED_CODENUM)
int sign = 1; // Allow for a negative code like D-1 or T-1
if (*p == '-') { sign = -1; ++p; }
#endif
// Get the code number - integer digits only
codenum = 0;
do { codenum = codenum * 10 + *p++ - '0'; } while (NUMERIC(*p));
// Apply the sign, if any
TERN_(SIGNED_CODENUM, codenum *= sign);
}
// Allow for decimal point in command
#if ENABLED(USE_GCODE_SUBCODES)
if (*p == '.') {
p++;
while (NUMERIC(*p))
subcode *= 10, subcode += *p++ - '0';
subcode = subcode * 10 + *p++ - '0';
}
#endif
@ -201,11 +205,8 @@ void GCodeParser::parse(char *p) {
while (*p == ' ') p++;
#if ENABLED(GCODE_MOTION_MODES)
if (letter == 'G' && (codenum <= GTOP || codenum == 5
#if ENABLED(G38_PROBE_TARGET)
|| codenum == 38
#endif
)
if (letter == 'G'
&& (codenum <= TERN(ARC_SUPPORT, 3, 1) || codenum == 5 || TERN0(G38_PROBE_TARGET, codenum == 38))
) {
motion_mode_codenum = codenum;
TERN_(USE_GCODE_SUBCODES, motion_mode_subcode = subcode);
@ -216,12 +217,12 @@ void GCodeParser::parse(char *p) {
#if ENABLED(GCODE_MOTION_MODES)
#if ENABLED(ARC_SUPPORT)
case 'I': case 'J': case 'R':
case 'I' ... 'J': case 'R':
if (motion_mode_codenum != 2 && motion_mode_codenum != 3) return;
#endif
case 'P': case 'Q':
case 'P' ... 'Q':
if (motion_mode_codenum != 5) return;
case 'X': case 'Y': case 'Z': case 'E': case 'F':
case 'X' ... 'Z': case 'E' ... 'F':
if (motion_mode_codenum < 0) return;
command_letter = 'G';
codenum = motion_mode_codenum;
@ -247,7 +248,7 @@ void GCodeParser::parse(char *p) {
#if ENABLED(EXPECTED_PRINTER_CHECK)
case 16:
#endif
case 23: case 28: case 30: case 33: case 117: case 118: case 928:
case 23: case 28: case 30: case 117 ... 118: case 928:
string_arg = unescape_string(p);
return;
default: break;

View File

@ -114,6 +114,11 @@ public:
return valid_signless(p) || ((p[0] == '-' || p[0] == '+') && valid_signless(&p[1])); // [-+]?.?[0-9]
}
FORCE_INLINE static bool valid_number(const char * const p) {
// TODO: With MARLIN_DEV_MODE allow HEX values starting with "x"
return valid_float(p);
}
#if ENABLED(FASTER_GCODE_PARSER)
FORCE_INLINE static bool valid_int(const char * const p) {
@ -142,8 +147,12 @@ public:
if (ind >= COUNT(param)) return false; // Only A-Z
const bool b = TEST32(codebits, ind);
if (b) {
char * const ptr = command_ptr + param[ind];
value_ptr = param[ind] && valid_float(ptr) ? ptr : nullptr;
if (param[ind]) {
char * const ptr = command_ptr + param[ind];
value_ptr = valid_number(ptr) ? ptr : nullptr;
}
else
value_ptr = nullptr;
}
return b;
}
@ -198,7 +207,7 @@ public:
static inline bool seen(const char c) {
char *p = strgchr(command_args, c);
const bool b = !!p;
if (b) value_ptr = valid_float(&p[1]) ? &p[1] : nullptr;
if (b) value_ptr = valid_number(&p[1]) ? &p[1] : nullptr;
return b;
}
@ -401,6 +410,25 @@ public:
static inline float linearval(const char c, const float dval=0) { return seenval(c) ? value_linear_units() : dval; }
static inline float celsiusval(const char c, const float dval=0) { return seenval(c) ? value_celsius() : dval; }
#if ENABLED(MARLIN_DEV_MODE)
static inline uint8_t* hex_adr_val(const char c, uint8_t * const dval=nullptr) {
if (!seen(c) || *value_ptr != 'x') return dval;
uint8_t *out = nullptr;
for (char *vp = value_ptr + 1; HEXCHR(*vp) >= 0; vp++)
out = (uint8_t*)((uintptr_t(out) << 8) | HEXCHR(*vp));
return out;
}
static inline uint16_t hex_val(const char c, uint16_t const dval=0) {
if (!seen(c) || *value_ptr != 'x') return dval;
uint16_t out = 0;
for (char *vp = value_ptr + 1; HEXCHR(*vp) >= 0; vp++)
out = ((out) << 8) | HEXCHR(*vp);
return out;
}
#endif
};
extern GCodeParser parser;