Merge pull request #7165 from thinkyhead/bf_parser_shorthand

Use parser.seenval, add shorthand functions
This commit is contained in:
Scott Lahteine 2017-06-27 18:57:48 -05:00 committed by GitHub
commit f4246dc8ff
9 changed files with 293 additions and 275 deletions

View file

@ -638,11 +638,11 @@
g26_hotend_temp = HOTEND_TEMP; g26_hotend_temp = HOTEND_TEMP;
g26_prime_flag = 0; g26_prime_flag = 0;
g26_ooze_amount = parser.seen('O') && parser.has_value() ? parser.value_linear_units() : OOZE_AMOUNT; g26_ooze_amount = parser.linearval('O', OOZE_AMOUNT);
g26_keep_heaters_on = parser.seen('K') && parser.value_bool(); g26_keep_heaters_on = parser.boolval('K');
g26_continue_with_closest = parser.seen('C') && parser.value_bool(); g26_continue_with_closest = parser.boolval('C');
if (parser.seen('B')) { if (parser.seenval('B')) {
g26_bed_temp = parser.value_celsius(); g26_bed_temp = parser.value_celsius();
if (!WITHIN(g26_bed_temp, 15, 140)) { if (!WITHIN(g26_bed_temp, 15, 140)) {
SERIAL_PROTOCOLLNPGM("?Specified bed temperature not plausible."); SERIAL_PROTOCOLLNPGM("?Specified bed temperature not plausible.");
@ -650,7 +650,7 @@
} }
} }
if (parser.seen('L')) { if (parser.seenval('L')) {
g26_layer_height = parser.value_linear_units(); g26_layer_height = parser.value_linear_units();
if (!WITHIN(g26_layer_height, 0.0, 2.0)) { if (!WITHIN(g26_layer_height, 0.0, 2.0)) {
SERIAL_PROTOCOLLNPGM("?Specified layer height not plausible."); SERIAL_PROTOCOLLNPGM("?Specified layer height not plausible.");
@ -672,7 +672,7 @@
} }
} }
if (parser.seen('S')) { if (parser.seenval('S')) {
g26_nozzle = parser.value_float(); g26_nozzle = parser.value_float();
if (!WITHIN(g26_nozzle, 0.1, 1.0)) { if (!WITHIN(g26_nozzle, 0.1, 1.0)) {
SERIAL_PROTOCOLLNPGM("?Specified nozzle size not plausible."); SERIAL_PROTOCOLLNPGM("?Specified nozzle size not plausible.");
@ -699,7 +699,7 @@
} }
} }
if (parser.seen('F')) { if (parser.seenval('F')) {
g26_filament_diameter = parser.value_linear_units(); g26_filament_diameter = parser.value_linear_units();
if (!WITHIN(g26_filament_diameter, 1.0, 4.0)) { if (!WITHIN(g26_filament_diameter, 1.0, 4.0)) {
SERIAL_PROTOCOLLNPGM("?Specified filament size not plausible."); SERIAL_PROTOCOLLNPGM("?Specified filament size not plausible.");
@ -712,7 +712,7 @@
g26_extrusion_multiplier *= g26_filament_diameter * sq(g26_nozzle) / sq(0.3); // Scale up by nozzle size g26_extrusion_multiplier *= g26_filament_diameter * sq(g26_nozzle) / sq(0.3); // Scale up by nozzle size
if (parser.seen('H')) { if (parser.seenval('H')) {
g26_hotend_temp = parser.value_celsius(); g26_hotend_temp = parser.value_celsius();
if (!WITHIN(g26_hotend_temp, 165, 280)) { if (!WITHIN(g26_hotend_temp, 165, 280)) {
SERIAL_PROTOCOLLNPGM("?Specified nozzle temperature not plausible."); SERIAL_PROTOCOLLNPGM("?Specified nozzle temperature not plausible.");
@ -727,7 +727,7 @@
} }
#if ENABLED(NEWPANEL) #if ENABLED(NEWPANEL)
g26_repeats = parser.seen('R') && parser.has_value() ? parser.value_int() : GRID_MAX_POINTS + 1; g26_repeats = parser.intval('R', GRID_MAX_POINTS + 1);
#else #else
if (!parser.seen('R')) { if (!parser.seen('R')) {
SERIAL_PROTOCOLLNPGM("?(R)epeat must be specified when not using an LCD."); SERIAL_PROTOCOLLNPGM("?(R)epeat must be specified when not using an LCD.");
@ -741,8 +741,8 @@
return UBL_ERR; return UBL_ERR;
} }
g26_x_pos = parser.seen('X') ? parser.value_linear_units() : current_position[X_AXIS]; g26_x_pos = parser.linearval('X', current_position[X_AXIS]);
g26_y_pos = parser.seen('Y') ? parser.value_linear_units() : current_position[Y_AXIS]; g26_y_pos = parser.linearval('Y', current_position[Y_AXIS]);
if (!position_is_reachable_xy(g26_x_pos, g26_y_pos)) { if (!position_is_reachable_xy(g26_x_pos, g26_y_pos)) {
SERIAL_PROTOCOLLNPGM("?Specified X,Y coordinate out of bounds."); SERIAL_PROTOCOLLNPGM("?Specified X,Y coordinate out of bounds.");
return UBL_ERR; return UBL_ERR;

View file

@ -189,19 +189,17 @@ void free_memory_pool_report(char * const ptr, const int16_t size) {
* This is useful to check the correctness of the M100 D and the M100 F commands. * This is useful to check the correctness of the M100 D and the M100 F commands.
*/ */
void corrupt_free_memory(char *ptr, const uint16_t size) { void corrupt_free_memory(char *ptr, const uint16_t size) {
if (parser.seen('C')) { ptr += 8;
ptr += 8; const uint16_t near_top = top_of_stack() - ptr - 250, // -250 to avoid interrupt activity that's altered the stack.
const uint16_t near_top = top_of_stack() - ptr - 250, // -250 to avoid interrupt activity that's altered the stack. j = near_top / (size + 1);
j = near_top / (size + 1);
SERIAL_ECHOLNPGM("Corrupting free memory block.\n"); SERIAL_ECHOLNPGM("Corrupting free memory block.\n");
for (uint16_t i = 1; i <= size; i++) { for (uint16_t i = 1; i <= size; i++) {
char * const addr = ptr + i * j; char * const addr = ptr + i * j;
*addr = i; *addr = i;
SERIAL_ECHOPAIR("\nCorrupting address: ", hex_address(addr)); SERIAL_ECHOPAIR("\nCorrupting address: ", hex_address(addr));
}
SERIAL_EOL();
} }
SERIAL_EOL();
} }
#endif // M100_FREE_MEMORY_CORRUPTOR #endif // M100_FREE_MEMORY_CORRUPTOR

File diff suppressed because it is too large Load diff

View file

@ -523,7 +523,7 @@ struct directoryEntry {
uint8_t reservedNT; uint8_t reservedNT;
/** /**
* The granularity of the seconds part of creationTime is 2 seconds * The granularity of the seconds part of creationTime is 2 seconds
* so this field is a count of tenths of a second and its valid * so this field is a count of tenths of a second and it's valid
* value range is 0-199 inclusive. (WHG note - seems to be hundredths) * value range is 0-199 inclusive. (WHG note - seems to be hundredths)
*/ */
uint8_t creationTimeTenths; uint8_t creationTimeTenths;

View file

@ -2,7 +2,7 @@
http://www.k8400.eu/ http://www.k8400.eu/
Configuration files for the K8400, ported upstream from the official Velleman firmware. Configuration files for the K8400, ported upstream from the official Velleman firmware.
Like it's predecessor, (K8200), the K8400 is a 3Drag clone. There are some minor differences, documented in pins_K8400.h. Like its predecessor, (K8200), the K8400 is a 3Drag clone. There are some minor differences, documented in pins_K8400.h.
Single and dual head configurations provided. Copy the correct Configuration.h and Configuration_adv.h to the /Marlin/ directory. Single and dual head configurations provided. Copy the correct Configuration.h and Configuration_adv.h to the /Marlin/ directory.

View file

@ -97,6 +97,13 @@ public:
// Reset is done before parsing // Reset is done before parsing
static void reset(); static void reset();
// Index so that 'X' falls on index 24
#define PARAM_IND(N) ((N) >> 3)
#define PARAM_BIT(N) ((N) & 0x7)
#define LETTER_OFF(N) ((N) - 'A' + 1)
#define LETTER_IND(N) PARAM_IND(LETTER_OFF(N))
#define LETTER_BIT(N) PARAM_BIT(LETTER_OFF(N))
#if ENABLED(FASTER_GCODE_PARSER) #if ENABLED(FASTER_GCODE_PARSER)
// Set the flag and pointer for a parameter // Set the flag and pointer for a parameter
@ -105,14 +112,14 @@ public:
, const bool debug=false , const bool debug=false
#endif #endif
) { ) {
const uint8_t ind = c - 'A'; const uint8_t ind = LETTER_OFF(c);
if (ind >= COUNT(param)) return; // Only A-Z if (ind >= COUNT(param)) return; // Only A-Z
SBI(codebits[ind >> 3], ind & 0x7); // parameter exists SBI(codebits[PARAM_IND(ind)], PARAM_BIT(ind)); // parameter exists
param[ind] = ptr ? ptr - command_ptr : 0; // parameter offset or 0 param[ind] = ptr ? ptr - command_ptr : 0; // parameter offset or 0
#if ENABLED(DEBUG_GCODE_PARSER) #if ENABLED(DEBUG_GCODE_PARSER)
if (debug) { if (debug) {
SERIAL_ECHOPAIR("Set bit ", (int)(ind & 0x7)); SERIAL_ECHOPAIR("Set bit ", (int)PARAM_BIT(ind));
SERIAL_ECHOPAIR(" of index ", (int)(ind >> 3)); SERIAL_ECHOPAIR(" of index ", (int)PARAM_IND(ind));
SERIAL_ECHOLNPAIR(" | param = ", hex_address((void*)param[ind])); SERIAL_ECHOLNPAIR(" | param = ", hex_address((void*)param[ind]));
} }
#endif #endif
@ -120,22 +127,28 @@ public:
// Code seen bit was set. If not found, value_ptr is unchanged. // Code seen bit was set. If not found, value_ptr is unchanged.
// This allows "if (seen('A')||seen('B'))" to use the last-found value. // This allows "if (seen('A')||seen('B'))" to use the last-found value.
// This is volatile because its side-effects are important
static volatile bool seen(const char c) { static volatile bool seen(const char c) {
const uint8_t ind = c - 'A'; const uint8_t ind = LETTER_OFF(c);
if (ind >= COUNT(param)) return false; // Only A-Z if (ind >= COUNT(param)) return false; // Only A-Z
const bool b = TEST(codebits[ind >> 3], ind & 0x7); const bool b = TEST(codebits[PARAM_IND(ind)], PARAM_BIT(ind));
if (b) value_ptr = command_ptr + param[ind]; if (b) value_ptr = command_ptr + param[ind];
return b; return b;
} }
static volatile bool seen_any() { return codebits[3] || codebits[2] || codebits[1] || codebits[0]; } static bool seen_any() { return codebits[3] || codebits[2] || codebits[1] || codebits[0]; }
#define SEEN_TEST(L) TEST(codebits[(L - 'A') >> 3], (L - 'A') & 0x7) #define SEEN_TEST(L) TEST(codebits[LETTER_IND(L)], LETTER_BIT(L))
#else // Seen any axis parameter
// Optimized by moving 'X' up to index 24
FORCE_INLINE bool seen_axis() { return codebits[3] || SEEN_TEST('E'); }
#else // !FASTER_GCODE_PARSER
// Code is found in the string. If not found, value_ptr is unchanged. // Code is found in the string. If not found, value_ptr is unchanged.
// This allows "if (seen('A')||seen('B'))" to use the last-found value. // This allows "if (seen('A')||seen('B'))" to use the last-found value.
// This is volatile because its side-effects are important
static volatile bool seen(const char c) { static volatile bool seen(const char c) {
const char *p = strchr(command_args, c); const char *p = strchr(command_args, c);
const bool b = !!p; const bool b = !!p;
@ -143,25 +156,26 @@ public:
return b; return b;
} }
static volatile bool seen_any() { return *command_args == '\0'; } static bool seen_any() { return *command_args == '\0'; }
#define SEEN_TEST(L) !!strchr(command_args, L) #define SEEN_TEST(L) !!strchr(command_args, L)
#endif // FASTER_GCODE_PARSER // Seen any axis parameter
static bool seen_axis() {
return SEEN_TEST('X') || SEEN_TEST('Y') || SEEN_TEST('Z') || SEEN_TEST('E');
}
#endif // !FASTER_GCODE_PARSER
// Populate all fields by parsing a single line of GCode // Populate all fields by parsing a single line of GCode
// This uses 54 bytes of SRAM to speed up seen/value // This uses 54 bytes of SRAM to speed up seen/value
static void parse(char * p); static void parse(char * p);
// Code value pointer was set // The code value pointer was set
FORCE_INLINE static bool has_value() { return value_ptr != NULL; } FORCE_INLINE static bool has_value() { return value_ptr != NULL; }
// Seen and has value // Seen a parameter with a value
FORCE_INLINE static bool seenval(const char c) { return seen(c) && has_value(); } inline static bool seenval(const char c) { return seen(c) && has_value(); }
static volatile bool seen_axis() {
return SEEN_TEST('X') || SEEN_TEST('Y') || SEEN_TEST('Z') || SEEN_TEST('E');
}
// Float removes 'E' to prevent scientific notation interpretation // Float removes 'E' to prevent scientific notation interpretation
inline static float value_float() { inline static float value_float() {
@ -184,20 +198,20 @@ public:
} }
// Code value as a long or ulong // Code value as a long or ulong
inline static long value_long() { return value_ptr ? strtol(value_ptr, NULL, 10) : 0L; } inline static int32_t value_long() { return value_ptr ? strtol(value_ptr, NULL, 10) : 0L; }
inline unsigned static long value_ulong() { return value_ptr ? strtoul(value_ptr, NULL, 10) : 0UL; } inline static uint32_t value_ulong() { return value_ptr ? strtoul(value_ptr, NULL, 10) : 0UL; }
// Code value for use as time // Code value for use as time
FORCE_INLINE static millis_t value_millis() { return value_ulong(); } FORCE_INLINE static millis_t value_millis() { return value_ulong(); }
FORCE_INLINE static millis_t value_millis_from_seconds() { return value_float() * 1000UL; } FORCE_INLINE static millis_t value_millis_from_seconds() { return value_float() * 1000UL; }
// Reduce to fewer bits // Reduce to fewer bits
FORCE_INLINE static int value_int() { return (int)value_long(); } FORCE_INLINE static int16_t value_int() { return (int16_t)value_long(); }
FORCE_INLINE uint16_t value_ushort() { return (uint16_t)value_long(); } FORCE_INLINE static uint16_t value_ushort() { return (uint16_t)value_long(); }
inline static uint8_t value_byte() { return (uint8_t)(constrain(value_long(), 0, 255)); } inline static uint8_t value_byte() { return (uint8_t)constrain(value_long(), 0, 255); }
// Bool is true with no value or non-zero // Bool is true with no value or non-zero
inline static bool value_bool() { return !has_value() || value_byte(); } inline static bool value_bool() { return !has_value() || value_byte(); }
// Units modes: Inches, Fahrenheit, Kelvin // Units modes: Inches, Fahrenheit, Kelvin
@ -282,17 +296,28 @@ public:
} }
} }
#else #else // !TEMPERATURE_UNITS_SUPPORT
FORCE_INLINE static float value_celsius() { return value_float(); } FORCE_INLINE static float value_celsius() { return value_float(); }
FORCE_INLINE static float value_celsius_diff() { return value_float(); } FORCE_INLINE static float value_celsius_diff() { return value_float(); }
#endif #endif // !TEMPERATURE_UNITS_SUPPORT
FORCE_INLINE static float value_feedrate() { return value_linear_units(); } FORCE_INLINE static float value_feedrate() { return value_linear_units(); }
void unknown_command_error(); void unknown_command_error();
// Provide simple value accessors with default option
FORCE_INLINE static float floatval(const char c, const float dval=0.0) { return seenval(c) ? value_float() : dval; }
FORCE_INLINE static bool boolval(const char c, const bool dval=false) { return seen(c) ? value_bool() : dval; }
FORCE_INLINE static uint8_t byteval(const char c, const uint8_t dval=0) { return seenval(c) ? value_byte() : dval; }
FORCE_INLINE static int16_t intval(const char c, const int16_t dval=0) { return seenval(c) ? value_int() : dval; }
FORCE_INLINE static uint16_t ushortval(const char c, const uint16_t dval=0) { return seenval(c) ? value_ushort() : dval; }
FORCE_INLINE static int32_t longval(const char c, const int32_t dval=0) { return seenval(c) ? value_long() : dval; }
FORCE_INLINE static uint32_t ulongval(const char c, const uint32_t dval=0) { return seenval(c) ? value_ulong() : dval; }
FORCE_INLINE static float linearval(const char c, const float dval=0.0) { return seenval(c) ? value_linear_units() : dval; }
FORCE_INLINE static float celsiusval(const char c, const float dval=0.0) { return seenval(c) ? value_celsius() : dval; }
}; };
extern GCodeParser parser; extern GCodeParser parser;

View file

@ -95,7 +95,7 @@ static inline void handle_interrupts(timer16_Sequence_t timer, volatile uint16_t
if (SERVO_INDEX(timer, Channel[timer]) < ServoCount && Channel[timer] < SERVOS_PER_TIMER) { if (SERVO_INDEX(timer, Channel[timer]) < ServoCount && Channel[timer] < SERVOS_PER_TIMER) {
*OCRnA = *TCNTn + SERVO(timer, Channel[timer]).ticks; *OCRnA = *TCNTn + SERVO(timer, Channel[timer]).ticks;
if (SERVO(timer, Channel[timer]).Pin.isActive) // check if activated if (SERVO(timer, Channel[timer]).Pin.isActive) // check if activated
digitalWrite(SERVO(timer, Channel[timer]).Pin.nbr, HIGH); // its an active channel so pulse it high digitalWrite(SERVO(timer, Channel[timer]).Pin.nbr, HIGH); // it's an active channel so pulse it high
} }
else { else {
// finished all channels so wait for the refresh period to expire before starting over // finished all channels so wait for the refresh period to expire before starting over

View file

@ -38,18 +38,18 @@ typedef void (*twiRequestFunc_t)();
/** /**
* TWIBUS class * TWIBUS class
* *
* This class implements a wrapper around the two wire (I2C) bus, it allows * This class implements a wrapper around the two wire (I2C) bus, allowing
* Marlin to send and request data from any slave device on the bus. This is * Marlin to send and request data from any slave device on the bus.
* an experimental feature and it's inner workings as well as public facing
* interface are prune to change in the future.
* *
* The two main consumers of this class are M260 and M261, where M260 allows * The two main consumers of this class are M260 and M261. M260 provides a way
* Marlin to send a I2C packet to a device (please be aware that no repeated * to send an I2C packet to a device (no repeated starts) by caching up to 32
* starts are possible), this can be done in caching method by calling multiple * bytes in a buffer and then sending the buffer.
* times M260 B<byte-1 value in base 10> or a one liner M260, have a look at * M261 requests data from a device. The received data is relayed to serial out
* the gcode_M260() function for more information. M261 allows Marlin to * for the host to interpret.
* request data from a device, the received data is then relayed into the serial *
* line for host interpretation. * For more information see
* - http://marlinfw.org/docs/gcode/M260.html
* - http://marlinfw.org/docs/gcode/M261.html
* *
*/ */
class TWIBus { class TWIBus {

View file

@ -314,7 +314,7 @@
// Check for commands that require the printer to be homed // Check for commands that require the printer to be homed
if (axis_unhomed_error()) { if (axis_unhomed_error()) {
const int8_t p_val = parser.seen('P') && parser.has_value() ? parser.value_int() : -1; const int8_t p_val = parser.intval('P', -1);
if (p_val == 1 || p_val == 2 || p_val == 4 || parser.seen('J')) if (p_val == 1 || p_val == 2 || p_val == 4 || parser.seen('J'))
home_all_axes(); home_all_axes();
} }
@ -492,7 +492,7 @@
return; return;
} }
const float height = parser.seen('H') && parser.has_value() ? parser.value_float() : Z_CLEARANCE_BETWEEN_PROBES; const float height = parser.floatval('H', Z_CLEARANCE_BETWEEN_PROBES);
manually_probe_remaining_mesh(g29_x_pos, g29_y_pos, height, g29_card_thickness, parser.seen('T')); manually_probe_remaining_mesh(g29_x_pos, g29_y_pos, height, g29_card_thickness, parser.seen('T'));
SERIAL_PROTOCOLLNPGM("G29 P2 finished."); SERIAL_PROTOCOLLNPGM("G29 P2 finished.");
@ -1094,9 +1094,9 @@
g29_constant = 0.0; g29_constant = 0.0;
g29_repetition_cnt = 0; g29_repetition_cnt = 0;
g29_x_flag = parser.seen('X') && parser.has_value(); g29_x_flag = parser.seenval('X');
g29_x_pos = g29_x_flag ? parser.value_float() : current_position[X_AXIS]; g29_x_pos = g29_x_flag ? parser.value_float() : current_position[X_AXIS];
g29_y_flag = parser.seen('Y') && parser.has_value(); g29_y_flag = parser.seenval('Y');
g29_y_pos = g29_y_flag ? parser.value_float() : current_position[Y_AXIS]; g29_y_pos = g29_y_flag ? parser.value_float() : current_position[Y_AXIS];
if (parser.seen('R')) { if (parser.seen('R')) {
@ -1170,7 +1170,7 @@
g29_constant = parser.value_float(); g29_constant = parser.value_float();
#if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT)
if (parser.seen('F') && parser.has_value()) { if (parser.seenval('F')) {
const float fh = parser.value_float(); const float fh = parser.value_float();
if (!WITHIN(fh, 0.0, 100.0)) { if (!WITHIN(fh, 0.0, 100.0)) {
SERIAL_PROTOCOLLNPGM("?(F)ade height for Bed Level Correction not plausible.\n"); SERIAL_PROTOCOLLNPGM("?(F)ade height for Bed Level Correction not plausible.\n");
@ -1180,7 +1180,7 @@
} }
#endif #endif
g29_map_type = parser.seen('T') && parser.has_value() ? parser.value_int() : 0; g29_map_type = parser.intval('T');
if (!WITHIN(g29_map_type, 0, 2)) { if (!WITHIN(g29_map_type, 0, 2)) {
SERIAL_PROTOCOLLNPGM("Invalid map type.\n"); SERIAL_PROTOCOLLNPGM("Invalid map type.\n");
return UBL_ERR; return UBL_ERR;