Explorar el Código

Case-insensitive g-code option (#16932)

Scott Lahteine hace 5 años
padre
commit
832951ec44
No account linked to committer's email address
Se han modificado 3 ficheros con 34 adiciones y 13 borrados
  1. 2
    0
      Marlin/Configuration_adv.h
  2. 14
    7
      Marlin/src/gcode/parser.cpp
  3. 18
    6
      Marlin/src/gcode/parser.h

+ 2
- 0
Marlin/Configuration_adv.h Ver fichero

2790
   //#define GCODE_QUOTED_STRINGS  // Support for quoted string parameters
2790
   //#define GCODE_QUOTED_STRINGS  // Support for quoted string parameters
2791
 #endif
2791
 #endif
2792
 
2792
 
2793
+//#define GCODE_CASE_INSENSITIVE  // Accept G-code sent to the firmware in lowercase
2794
+
2793
 /**
2795
 /**
2794
  * CNC G-code options
2796
  * CNC G-code options
2795
  * Support CNC-style G-code dialects used by laser cutters, drawing machine cams, etc.
2797
  * Support CNC-style G-code dialects used by laser cutters, drawing machine cams, etc.

+ 14
- 7
Marlin/src/gcode/parser.cpp Ver fichero

118
 
118
 
119
   reset(); // No codes to report
119
   reset(); // No codes to report
120
 
120
 
121
+  auto uppercase = [](char c) {
122
+    #if ENABLED(GCODE_CASE_INSENSITIVE)
123
+      if (WITHIN(c, 'a', 'z')) c += 'A' - 'a';
124
+    #endif
125
+    return c;
126
+  };
127
+
121
   // Skip spaces
128
   // Skip spaces
122
   while (*p == ' ') ++p;
129
   while (*p == ' ') ++p;
123
 
130
 
124
   // Skip N[-0-9] if included in the command line
131
   // Skip N[-0-9] if included in the command line
125
-  if (*p == 'N' && NUMERIC_SIGNED(p[1])) {
132
+  if (uppercase(*p) == 'N' && NUMERIC_SIGNED(p[1])) {
126
     #if ENABLED(FASTER_GCODE_PARSER)
133
     #if ENABLED(FASTER_GCODE_PARSER)
127
       //set('N', p + 1);     // (optional) Set the 'N' parameter value
134
       //set('N', p + 1);     // (optional) Set the 'N' parameter value
128
     #endif
135
     #endif
135
   command_ptr = p;
142
   command_ptr = p;
136
 
143
 
137
   // Get the command letter, which must be G, M, or T
144
   // Get the command letter, which must be G, M, or T
138
-  const char letter = *p++;
145
+  const char letter = uppercase(*p++);
139
 
146
 
140
   // Nullify asterisk and trailing whitespace
147
   // Nullify asterisk and trailing whitespace
141
   char *starpos = strchr(p, '*');
148
   char *starpos = strchr(p, '*');
271
     bool quoted_string_arg = false;
278
     bool quoted_string_arg = false;
272
   #endif
279
   #endif
273
   string_arg = nullptr;
280
   string_arg = nullptr;
274
-  while (const char param = *p++) {              // Get the next parameter. A NUL ends the loop
281
+  while (const char param = uppercase(*p++)) {  // Get the next parameter. A NUL ends the loop
275
 
282
 
276
     // Special handling for M32 [P] !/path/to/file.g#
283
     // Special handling for M32 [P] !/path/to/file.g#
277
     // The path must be the last parameter
284
     // The path must be the last parameter
289
       }
296
       }
290
     #endif
297
     #endif
291
 
298
 
292
-    // Arguments MUST be uppercase for fast GCode parsing
293
     #if ENABLED(FASTER_GCODE_PARSER)
299
     #if ENABLED(FASTER_GCODE_PARSER)
294
-      #define PARAM_TEST WITHIN(param, 'A', 'Z')
300
+      // Arguments MUST be uppercase for fast GCode parsing
301
+      #define PARAM_OK(P) WITHIN((P), 'A', 'Z')
295
     #else
302
     #else
296
-      #define PARAM_TEST true
303
+      #define PARAM_OK(P) true
297
     #endif
304
     #endif
298
 
305
 
299
-    if (PARAM_TEST) {
306
+    if (PARAM_OK(param)) {
300
 
307
 
301
       while (*p == ' ') p++;                    // Skip spaces between parameters & values
308
       while (*p == ' ') p++;                    // Skip spaces between parameters & values
302
 
309
 

+ 18
- 6
Marlin/src/gcode/parser.h Ver fichero

166
     #ifdef CPU_32_BIT
166
     #ifdef CPU_32_BIT
167
       FORCE_INLINE static bool seen(const char * const str) { return !!(codebits & letter_bits(str)); }
167
       FORCE_INLINE static bool seen(const char * const str) { return !!(codebits & letter_bits(str)); }
168
     #else
168
     #else
169
-      // At least one of a list of code letters was seen
170
       FORCE_INLINE static bool seen(const char * const str) {
169
       FORCE_INLINE static bool seen(const char * const str) {
171
         const uint32_t letrbits = letter_bits(str);
170
         const uint32_t letrbits = letter_bits(str);
172
         const uint8_t * const cb = (uint8_t*)&codebits;
171
         const uint8_t * const cb = (uint8_t*)&codebits;
177
 
176
 
178
     static inline bool seen_any() { return !!codebits; }
177
     static inline bool seen_any() { return !!codebits; }
179
 
178
 
180
-    #define SEEN_TEST(L) TEST32(codebits, LETTER_BIT(L))
179
+    FORCE_INLINE static bool seen_test(const char c) { return TEST32(codebits, LETTER_BIT(c)); }
181
 
180
 
182
   #else // !FASTER_GCODE_PARSER
181
   #else // !FASTER_GCODE_PARSER
183
 
182
 
183
+    #if ENABLED(GCODE_CASE_INSENSITIVE)
184
+      FORCE_INLINE static char* strgchr(char *p, char g) {
185
+        auto uppercase = [](char c) {
186
+          return c + (WITHIN(c, 'a', 'z') ? 'A' - 'a' : 0);
187
+        };
188
+        const char d = uppercase(g);
189
+        for (char cc; (cc = uppercase(*p)); p++) if (cc == d) return p;
190
+        return nullptr;
191
+      }
192
+    #else
193
+      #define strgchr strchr
194
+    #endif
195
+
184
     // Code is found in the string. If not found, value_ptr is unchanged.
196
     // Code is found in the string. If not found, value_ptr is unchanged.
185
     // This allows "if (seen('A')||seen('B'))" to use the last-found value.
197
     // This allows "if (seen('A')||seen('B'))" to use the last-found value.
186
     static inline bool seen(const char c) {
198
     static inline bool seen(const char c) {
187
-      char *p = strchr(command_args, c);
199
+      char *p = strgchr(command_args, c);
188
       const bool b = !!p;
200
       const bool b = !!p;
189
       if (b) value_ptr = valid_float(&p[1]) ? &p[1] : nullptr;
201
       if (b) value_ptr = valid_float(&p[1]) ? &p[1] : nullptr;
190
       return b;
202
       return b;
192
 
204
 
193
     static inline bool seen_any() { return *command_args == '\0'; }
205
     static inline bool seen_any() { return *command_args == '\0'; }
194
 
206
 
195
-    #define SEEN_TEST(L) !!strchr(command_args, L)
207
+    FORCE_INLINE static bool seen_test(const char c) { return (bool)strgchr(command_args, c); }
196
 
208
 
197
     // At least one of a list of code letters was seen
209
     // At least one of a list of code letters was seen
198
     static inline bool seen(const char * const str) {
210
     static inline bool seen(const char * const str) {
199
       for (uint8_t i = 0; const char c = str[i]; i++)
211
       for (uint8_t i = 0; const char c = str[i]; i++)
200
-        if (SEEN_TEST(c)) return true;
212
+        if (seen_test(c)) return true;
201
       return false;
213
       return false;
202
     }
214
     }
203
 
215
 
205
 
217
 
206
   // Seen any axis parameter
218
   // Seen any axis parameter
207
   static inline bool seen_axis() {
219
   static inline bool seen_axis() {
208
-    return SEEN_TEST('X') || SEEN_TEST('Y') || SEEN_TEST('Z') || SEEN_TEST('E');
220
+    return seen_test('X') || seen_test('Y') || seen_test('Z') || seen_test('E');
209
   }
221
   }
210
 
222
 
211
   #if ENABLED(GCODE_QUOTED_STRINGS)
223
   #if ENABLED(GCODE_QUOTED_STRINGS)

Loading…
Cancelar
Guardar