From a4fcd0e32fe774217c8381e0cdb862ddfc001bcc Mon Sep 17 00:00:00 2001 From: Markus Hitter Date: Sun, 12 Jun 2016 19:22:01 +0200 Subject: [PATCH] Attic: tar up 'input-float'. --- attic/input-float.tar.gz | Bin 0 -> 7556 bytes ...fca06ae6c21b3103b9a721bf19ca4cf33a25.patch | 672 ------------------ attic/input-float/gcode_parse.c | 274 ------- attic/input-float/gcode_parse.h | 73 -- 4 files changed, 1019 deletions(-) create mode 100644 attic/input-float.tar.gz delete mode 100644 attic/input-float/apply-to-fc4bfca06ae6c21b3103b9a721bf19ca4cf33a25.patch delete mode 100644 attic/input-float/gcode_parse.c delete mode 100644 attic/input-float/gcode_parse.h diff --git a/attic/input-float.tar.gz b/attic/input-float.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..a2a3b1b94beb3d8dc0efa61855424427b54dbc3e GIT binary patch literal 7556 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 -Date: Sat, 5 Feb 2011 18:39:35 +1100 -Subject: big gcode_parse update- wait for whole line to ease processing, use - floats to receive numerical data, plugs into existing gcode_process.c. TODO: - revamp gcode_process to use new gcode_parse data structures - ---- - func.sh | 32 ++++ - gcode_parse.c | 563 +++++++++++++++++++++++----------------------------------- - gcode_parse.h | 4 +- - 3 files changed, 256 insertions(+), 343 deletions(-) - -diff --git a/func.sh b/func.sh -index e59b7a5..18827e0 100755 ---- a/func.sh -+++ b/func.sh -@@ -322,6 +322,38 @@ ENDPERL - } - - # Read status of PID routines. -+mendel_readsym_nexttarget() { -+ local val=$(mendel_readsym next_target) -+ perl - <<'ENDPERL' -- $val -+ $i = -1; -+ @a = qw/flags 2 G 1 M 1 X 4 Y 4 Z 4 E 4 F 4 S 2 P 2 T 1 N 4 eN 4 cr 1 cc 1/; -+ $c = 1234567; -+ while (length $ARGV[1]) { -+ if ($c > ($#a / 2)) { -+ $i++; -+ $c = 0; -+ } -+ if ($a[$c * 2 + 1] & 8) { -+ printf "\n"; -+ } -+ if (($a[$c * 2 + 1] & 7) == 4) { -+ $ARGV[1] =~ s#^(..)(..)(..)(..)##; -+ printf "%s: %d\t", $a[$c * 2], eval "0x$4$3$2$1"; -+ } -+ if (($a[$c * 2 + 1] & 7) == 2) { -+ $ARGV[1] =~ s#^(..)(..)##; -+ printf "%s: %d\t", $a[$c * 2], eval "0x$2$1"; -+ } -+ elsif (($a[$c * 2 + 1] & 7) == 1) { -+ $ARGV[1] =~ s#^(..)##; -+ printf "%s: %d\t", $a[$c * 2], eval "0x$1"; -+ } -+ $c++; -+ } -+ printf "\n"; -+ENDPERL -+} -+ - mendel_heater_pid() { - local P=$(mendel_readsym_int16 heater_p) - local I=$(mendel_readsym_int16 heater_i) -diff --git a/gcode_parse.c b/gcode_parse.c -index 1eb4eb0..626b694 100644 ---- a/gcode_parse.c -+++ b/gcode_parse.c -@@ -4,15 +4,12 @@ - \brief Parse received G-Codes - */ - --#include -+#include - -+#include "config.h" -+#include "sersendf.h" - #include "serial.h" - #include "sermsg.h" --#include "dda_queue.h" --#include "debug.h" --#include "heater.h" --#include "sersendf.h" -- - #include "gcode_process.h" - - /// current or previous gcode word -@@ -22,64 +19,232 @@ uint8_t last_field = 0; - /// crude crc macro - #define crc(a, b) (a ^ b) - --/// crude floating point data storage --decfloat read_digit __attribute__ ((__section__ (".bss"))); -- --/// this is where we store all the data for the current command before we work out what to do with it --GCODE_COMMAND next_target __attribute__ ((__section__ (".bss"))); -- --/* -- decfloat_to_int() is the weakest subject to variable overflow. For evaluation, we assume a build room of +-1000 mm and STEPS_PER_MM_x between 1.000 and 4096. Accordingly for metric units: -- -- df->mantissa: +-0..1048075 (20 bit - 500 for rounding) -- df->exponent: 0, 2, 3, 4 or 5 (10 bit) -- multiplicand: 1000 (10 bit) -- -- imperial units: -- -- df->mantissa: +-0..32267 (15 bit - 500 for rounding) -- df->exponent: 0, 2, 3, 4 or 5 (10 bit) -- multiplicand: 25400 (15 bit) --*/ --// decfloat_to_int() can handle a bit more: --#define DECFLOAT_EXP_MAX 3 // more is pointless, as 1 um is our presision --// (2^^32 - 1) / multiplicand - powers[DECFLOAT_EXP_MAX] / 2 = --// 4294967295 / 1000 - 5000 = --#define DECFLOAT_MANT_MM_MAX 4289967 // = 4290 mm --// 4294967295 / 25400 - 5000 = --#define DECFLOAT_MANT_IN_MAX 164093 // = 164 inches = 4160 mm -+#define GCODE_LINE_BUFFER_LEN 64 -+ -+#define iA 0 -+#define iB 1 -+#define iC 2 -+#define iD 3 -+#define iE 4 -+#define iF 5 -+#define iG 6 -+#define iH 7 -+#define iI 8 -+#define iJ 9 -+#define iK 10 -+#define iL 11 -+#define iM 12 -+#define iN 13 -+#define iO 14 -+#define iP 15 -+#define iQ 16 -+#define iR 17 -+#define iS 18 -+#define iT 19 -+#define iU 20 -+#define iV 21 -+#define iW 22 -+#define iX 23 -+#define iY 24 -+#define iZ 25 -+#define iAsterisk 26 -+ -+GCODE_COMMAND next_target; -+ -+uint8_t gcode_line[GCODE_LINE_BUFFER_LEN]; -+uint8_t gcode_line_pointer = 0; -+ -+float words[32]; -+uint32_t seen_mask = 0; -+ -+#define SEEN(c) (seen_mask & (1L << (c))) -+ -+uint32_t line_number = 0; -+ -+const uint8_t char2index(uint8_t c) __attribute__ ((pure)); -+const uint8_t char2index(uint8_t c) { -+ if (c >= 'a' && c <= 'z') -+ return c - 'a'; -+ if (c >= 'A' && c <= 'Z') -+ return c - 'A'; -+ if (c == '*') -+ return 26; -+ return 255; -+} - --/* -- utility functions --*/ --extern const uint32_t powers[]; // defined in sermsg.c -+void gcode_parse_char(uint8_t c) { -+ if (gcode_line_pointer < (GCODE_LINE_BUFFER_LEN - 1)) -+ gcode_line[gcode_line_pointer++] = c; -+ if ((c == 13) || (c == 10)) { -+ uint8_t i; -+ for (i = gcode_line_pointer; i < GCODE_LINE_BUFFER_LEN; i++) -+ gcode_line[i] = 0; -+ if (gcode_line_pointer > 2) -+ gcode_parse_line(gcode_line); -+ gcode_line_pointer = 0; -+ } -+} - --/// convert a floating point input value into an integer with appropriate scaling. --/// \param *df pointer to floating point structure that holds fp value to convert --/// \param multiplicand multiply by this amount during conversion to integer --/// --/// Tested for up to 42'000 mm (accurate), 420'000 mm (precision 10 um) and --/// 4'200'000 mm (precision 100 um). --static int32_t decfloat_to_int(decfloat *df, uint16_t multiplicand) { -- uint32_t r = df->mantissa; -- uint8_t e = df->exponent; -+void gcode_parse_line(uint8_t *c) { -+ enum { -+ STATE_FIND_WORD, -+ STATE_FIND_VALUE, -+ STATE_SEMICOLON_COMMENT, -+ STATE_BRACKET_COMMENT, -+ } state = STATE_FIND_WORD; -+ -+ uint8_t i; // string index -+ uint8_t w = 0; // current gcode word -+ uint8_t checksum = 0; -+ -+ seen_mask = 0; -+ -+ // calculate checksum -+ for(i = 0; c[i] != '*' && c[i] != 0; i++) -+ checksum = checksum ^ c[i]; -+ -+ // extract gcode words from line -+ for (i = 0; c[i] != 0 && c[i] != 13 && c[i] != 10; i++) { -+ switch (state) { -+ case STATE_FIND_WORD: -+ // start of word -+ if (char2index(c[i]) < 255) { -+ w = char2index(c[i]); -+ state = STATE_FIND_VALUE; -+ } -+ // comment until end of line -+ if (c[i] == ';') -+ state = STATE_SEMICOLON_COMMENT; -+ // comment until close bracket -+ if (c[i] == '(') -+ state = STATE_BRACKET_COMMENT; -+ break; -+ case STATE_FIND_VALUE: -+ if ((c[i] >= '0' && c[i] <= '9') || c[i] == '-') { -+ uint8_t *ep; -+ float v = strtod((const char *) &c[i], (char **) &ep); -+ state = STATE_FIND_WORD; -+ if (ep > &c[i]) { -+// sersendf_P(PSTR("[seen %c: %lx->"), w + 'A', seen_mask); -+ seen_mask |= (1L << w); -+// sersendf_P(PSTR("%lx]"), seen_mask); -+ words[w] = v; -+ i = ep - c - 1; -+ } -+ } -+ break; -+ case STATE_BRACKET_COMMENT: -+ if (c[i] == ')') -+ state = STATE_FIND_WORD; -+ break; -+ case STATE_SEMICOLON_COMMENT: -+ // dummy entry to suppress compiler warning -+ break; -+ } // switch (state) -+ } // for i=0 .. newline -+ -+ // TODO: process line just read -+ -+ if (SEEN(iAsterisk)) { -+ if (checksum != words[iAsterisk]) { -+ if (seen_mask & iAsterisk) -+ sersendf_P(PSTR("rs %d "), ((uint8_t) words[iAsterisk])); -+ sersendf_P(PSTR("Bad checksum, received %d, expected %d\n"), ((uint8_t) words[iAsterisk]), checksum); -+ seen_mask = 0; -+ return; -+ } -+ } -+ -+ if (SEEN(iN)) { -+ if (((uint32_t) words[iN]) != line_number) { -+ sersendf_P(PSTR("Bad line number, received %ld, expected %ld\n"), ((uint32_t) words[iN]), line_number); -+ seen_mask = 0; -+ return; -+ } -+ line_number++; -+ } -+ -+ serial_writestr_P(PSTR("ok ")); - -- // e=1 means we've seen a decimal point but no digits after it, and e=2 means we've seen a decimal point with one digit so it's too high by one if not zero -- if (e) -- e--; -+ // patch words into next_target struct -+ // TODO: eliminate next_target, update gcode_process to use words[] directly - -- // This raises range for mm by factor 1000 and for inches by factor 100. -- // It's a bit expensive, but we should have the time while parsing. -- while (e && multiplicand % 10 == 0) { -- multiplicand /= 10; -- e--; -+ next_target.flags = 0; -+ if (SEEN(iG)) { -+ next_target.seen_G = 1; -+ next_target.G = words[iG]; -+// sersendf_P(PSTR("G:%d/"), next_target.G); -+ } -+ if (SEEN(iM)) { -+ next_target.seen_M = 1; -+ next_target.M = words[iM]; -+// sersendf_P(PSTR("M:%d/"), next_target.M); -+ } -+ if (SEEN(iX)) { -+ next_target.seen_X = 1; -+ next_target.target.X = words[iX] * STEPS_PER_MM_X; -+// sersendf_P(PSTR("X:%ld/"), next_target.target.X); -+ } -+ if (SEEN(iY)) { -+ next_target.seen_Y = 1; -+ next_target.target.Y = words[iY] * STEPS_PER_MM_Y; -+// sersendf_P(PSTR("Y:%ld/"), next_target.target.Y); -+ } -+ if (SEEN(iZ)) { -+ next_target.seen_Z = 1; -+ next_target.target.Z = words[iZ] * STEPS_PER_MM_Z; -+// sersendf_P(PSTR("Z:%ld/"), next_target.target.Z); -+ } -+ if (SEEN(iE)) { -+ next_target.seen_E = 1; -+ next_target.target.E = words[iE] * STEPS_PER_MM_E; -+// sersendf_P(PSTR("E:%ld/"), next_target.target.E); -+ } -+ if (SEEN(iF)) { -+ next_target.seen_F = 1; -+ next_target.target.F = words[iF]; -+// sersendf_P(PSTR("F:%ld/"), next_target.target.F); -+ } -+ if (SEEN(iS)) { -+ next_target.seen_S = 1; -+ // if this is temperature, multiply by 4 to convert to quarter-degree units -+ // cosmetically this should be done in the temperature section, -+ // but it takes less code, less memory and loses no precision if we do it here instead -+ if ((next_target.M == 104) || (next_target.M == 109)) -+ next_target.S = words[iS] * 4.0; -+ // if this is heater PID stuff, multiply by PID_SCALE because we divide by PID_SCALE later on -+ else if ((next_target.M >= 130) && (next_target.M <= 132)) -+ next_target.S = words[iS] * PID_SCALE; -+ else -+ next_target.S = words[iS]; -+// sersendf_P(PSTR("S:%d/"), next_target.S); -+ } -+ if (SEEN(iP)) { -+ next_target.seen_P = 1; -+ next_target.P = words[iP]; -+// sersendf_P(PSTR("P:%u/"), next_target.P); -+ } -+ if (SEEN(iT)) { -+ next_target.seen_T = 1; -+ next_target.T = words[iT]; -+// sersendf_P(PSTR("T:%d/"), next_target.T); -+ } -+ if (SEEN(iN)) { -+ next_target.seen_N = 1; -+ next_target.N = words[iN]; -+// sersendf_P(PSTR("N:%lu/"), next_target.N); - } -+ next_target.N_expected = line_number; -+ if (SEEN(iAsterisk)) { -+ next_target.seen_checksum = 1; -+ next_target.checksum_read = words[iAsterisk]; -+ } -+ next_target.checksum_calculated = checksum; - -- r *= multiplicand; -- if (e) -- r = (r + powers[e] / 2) / powers[e]; -+ process_gcode_command(); -+ serial_writechar('\n'); - -- return df->sign ? -(int32_t)r : (int32_t)r; -+ seen_mask = 0; - } - - void gcode_init(void) { -@@ -94,290 +259,6 @@ void gcode_init(void) { - #endif - } - --/// Character Received - add it to our command --/// \param c the next character to process --void gcode_parse_char(uint8_t c) { -- uint8_t checksum_char = c; -- -- // uppercase -- if (c >= 'a' && c <= 'z') -- c &= ~32; -- -- // process previous field -- if (last_field) { -- // check if we're seeing a new field or end of line -- // any character will start a new field, even invalid/unknown ones -- if ((c >= 'A' && c <= 'Z') || c == '*' || (c == 10) || (c == 13)) { -- switch (last_field) { -- case 'G': -- next_target.G = read_digit.mantissa; -- if (DEBUG_ECHO && (debug_flags & DEBUG_ECHO)) -- serwrite_uint8(next_target.G); -- break; -- case 'M': -- next_target.M = read_digit.mantissa; -- if (DEBUG_ECHO && (debug_flags & DEBUG_ECHO)) -- serwrite_uint8(next_target.M); -- break; -- case 'X': -- if (next_target.option_inches) -- next_target.target.X = decfloat_to_int(&read_digit, 25400); -- else -- next_target.target.X = decfloat_to_int(&read_digit, 1000); -- if (DEBUG_ECHO && (debug_flags & DEBUG_ECHO)) -- serwrite_int32(next_target.target.X); -- break; -- case 'Y': -- if (next_target.option_inches) -- next_target.target.Y = decfloat_to_int(&read_digit, 25400); -- else -- next_target.target.Y = decfloat_to_int(&read_digit, 1000); -- if (DEBUG_ECHO && (debug_flags & DEBUG_ECHO)) -- serwrite_int32(next_target.target.Y); -- break; -- case 'Z': -- if (next_target.option_inches) -- next_target.target.Z = decfloat_to_int(&read_digit, 25400); -- else -- next_target.target.Z = decfloat_to_int(&read_digit, 1000); -- if (DEBUG_ECHO && (debug_flags & DEBUG_ECHO)) -- serwrite_int32(next_target.target.Z); -- break; -- case 'E': -- if (next_target.option_inches) -- next_target.target.E = decfloat_to_int(&read_digit, 25400); -- else -- next_target.target.E = decfloat_to_int(&read_digit, 1000); -- if (DEBUG_ECHO && (debug_flags & DEBUG_ECHO)) -- serwrite_uint32(next_target.target.E); -- break; -- case 'F': -- // just use raw integer, we need move distance and n_steps to convert it to a useful value, so wait until we have those to convert it -- if (next_target.option_inches) -- next_target.target.F = decfloat_to_int(&read_digit, 25400); -- else -- next_target.target.F = decfloat_to_int(&read_digit, 1); -- if (DEBUG_ECHO && (debug_flags & DEBUG_ECHO)) -- serwrite_uint32(next_target.target.F); -- break; -- case 'S': -- // if this is temperature, multiply by 4 to convert to quarter-degree units -- // cosmetically this should be done in the temperature section, -- // but it takes less code, less memory and loses no precision if we do it here instead -- if ((next_target.M == 104) || (next_target.M == 109) || (next_target.M == 140)) -- next_target.S = decfloat_to_int(&read_digit, 4); -- // if this is heater PID stuff, multiply by PID_SCALE because we divide by PID_SCALE later on -- else if ((next_target.M >= 130) && (next_target.M <= 132)) -- next_target.S = decfloat_to_int(&read_digit, PID_SCALE); -- else -- next_target.S = decfloat_to_int(&read_digit, 1); -- if (DEBUG_ECHO && (debug_flags & DEBUG_ECHO)) -- serwrite_uint16(next_target.S); -- break; -- case 'P': -- next_target.P = decfloat_to_int(&read_digit, 1); -- if (DEBUG_ECHO && (debug_flags & DEBUG_ECHO)) -- serwrite_uint16(next_target.P); -- break; -- case 'T': -- next_target.T = read_digit.mantissa; -- if (DEBUG_ECHO && (debug_flags & DEBUG_ECHO)) -- serwrite_uint8(next_target.T); -- break; -- case 'N': -- next_target.N = decfloat_to_int(&read_digit, 1); -- if (DEBUG_ECHO && (debug_flags & DEBUG_ECHO)) -- serwrite_uint32(next_target.N); -- break; -- case '*': -- next_target.checksum_read = decfloat_to_int(&read_digit, 1); -- if (DEBUG_ECHO && (debug_flags & DEBUG_ECHO)) -- serwrite_uint8(next_target.checksum_read); -- break; -- } -- // reset for next field -- last_field = 0; -- read_digit.sign = read_digit.mantissa = read_digit.exponent = 0; -- } -- } -- -- // skip comments -- if (next_target.seen_semi_comment == 0 && next_target.seen_parens_comment == 0) { -- // new field? -- if ((c >= 'A' && c <= 'Z') || c == '*') { -- last_field = c; -- if (DEBUG_ECHO && (debug_flags & DEBUG_ECHO)) -- serial_writechar(c); -- } -- -- // process character -- // Can't do ranges in switch..case, so process actual digits here. -- // Do it early, as there are many more digits than characters expected. -- if (c >= '0' && c <= '9') { -- if (read_digit.exponent < DECFLOAT_EXP_MAX + 1 && -- ((next_target.option_inches == 0 && -- read_digit.mantissa < DECFLOAT_MANT_MM_MAX) || -- (next_target.option_inches && -- read_digit.mantissa < DECFLOAT_MANT_IN_MAX))) { -- // this is simply mantissa = (mantissa * 10) + atoi(c) in different clothes -- read_digit.mantissa = (read_digit.mantissa << 3) + -- (read_digit.mantissa << 1) + (c - '0'); -- if (read_digit.exponent) -- read_digit.exponent++; -- } -- } -- else { -- switch (c) { -- // Each currently known command is either G or M, so preserve -- // previous G/M unless a new one has appeared. -- // FIXME: same for T command -- case 'G': -- next_target.seen_G = 1; -- next_target.seen_M = 0; -- next_target.M = 0; -- break; -- case 'M': -- next_target.seen_M = 1; -- next_target.seen_G = 0; -- next_target.G = 0; -- break; -- case 'X': -- next_target.seen_X = 1; -- break; -- case 'Y': -- next_target.seen_Y = 1; -- break; -- case 'Z': -- next_target.seen_Z = 1; -- break; -- case 'E': -- next_target.seen_E = 1; -- break; -- case 'F': -- next_target.seen_F = 1; -- break; -- case 'S': -- next_target.seen_S = 1; -- break; -- case 'P': -- next_target.seen_P = 1; -- break; -- case 'T': -- next_target.seen_T = 1; -- break; -- case 'N': -- next_target.seen_N = 1; -- break; -- case '*': -- next_target.seen_checksum = 1; -- break; -- -- // comments -- case ';': -- next_target.seen_semi_comment = 1; -- break; -- case '(': -- next_target.seen_parens_comment = 1; -- break; -- -- // now for some numeracy -- case '-': -- read_digit.sign = 1; -- // force sign to be at start of number, so 1-2 = -2 instead of -12 -- read_digit.exponent = 0; -- read_digit.mantissa = 0; -- break; -- case '.': -- if (read_digit.exponent == 0) -- read_digit.exponent = 1; -- break; -- #ifdef DEBUG -- case ' ': -- case '\t': -- case 10: -- case 13: -- // ignore -- break; -- #endif -- -- default: -- #ifdef DEBUG -- // invalid -- serial_writechar('?'); -- serial_writechar(c); -- serial_writechar('?'); -- #endif -- break; -- } -- } -- } else if ( next_target.seen_parens_comment == 1 && c == ')') -- next_target.seen_parens_comment = 0; // recognize stuff after a (comment) -- -- if (next_target.seen_checksum == 0) -- next_target.checksum_calculated = -- crc(next_target.checksum_calculated, checksum_char); -- -- // end of line -- if ((c == 10) || (c == 13)) { -- if (DEBUG_ECHO && (debug_flags & DEBUG_ECHO)) -- serial_writechar(c); -- -- if ( -- #ifdef REQUIRE_LINENUMBER -- ((next_target.N >= next_target.N_expected) && (next_target.seen_N == 1)) || -- (next_target.seen_M && (next_target.M == 110)) -- #else -- 1 -- #endif -- ) { -- if ( -- #ifdef REQUIRE_CHECKSUM -- ((next_target.checksum_calculated == next_target.checksum_read) && (next_target.seen_checksum == 1)) -- #else -- ((next_target.checksum_calculated == next_target.checksum_read) || (next_target.seen_checksum == 0)) -- #endif -- ) { -- // process -- serial_writestr_P(PSTR("ok ")); -- process_gcode_command(); -- serial_writechar('\n'); -- -- // expect next line number -- if (next_target.seen_N == 1) -- next_target.N_expected = next_target.N + 1; -- } -- else { -- sersendf_P(PSTR("rs N%ld Expected checksum %d\n"), next_target.N_expected, next_target.checksum_calculated); --// request_resend(); -- } -- } -- else { -- sersendf_P(PSTR("rs N%ld Expected line number %ld\n"), next_target.N_expected, next_target.N_expected); --// request_resend(); -- } -- -- // reset variables -- next_target.seen_X = next_target.seen_Y = next_target.seen_Z = \ -- next_target.seen_E = next_target.seen_F = next_target.seen_S = \ -- next_target.seen_P = next_target.seen_T = next_target.seen_N = \ -- next_target.seen_M = next_target.seen_checksum = next_target.seen_semi_comment = \ -- next_target.seen_parens_comment = next_target.checksum_read = \ -- next_target.checksum_calculated = 0; -- // last_field and read_digit are reset above already -- -- // assume a G1 by default -- next_target.seen_G = 1; -- next_target.G = 1; -- -- if (next_target.option_all_relative) { -- next_target.target.X = next_target.target.Y = next_target.target.Z = 0; -- } -- if (next_target.option_all_relative || next_target.option_e_relative) { -- next_target.target.E = 0; -- } -- } --} -- - /***************************************************************************\ - * * - * Request a resend of the current line - used from various places. * -diff --git a/gcode_parse.h b/gcode_parse.h -index 825bbbc..73e44c1 100644 ---- a/gcode_parse.h -+++ b/gcode_parse.h -@@ -64,8 +64,8 @@ extern GCODE_COMMAND next_target; - - void gcode_init(void); - --/// accept the next character and process it --void gcode_parse_char(uint8_t c); -+// once we have a whole line, process it -+void gcode_parse_line(uint8_t *c); - - // uses the global variable next_target.N - void request_resend(void); --- -1.8.1.2 - diff --git a/attic/input-float/gcode_parse.c b/attic/input-float/gcode_parse.c deleted file mode 100644 index 626b694..0000000 --- a/attic/input-float/gcode_parse.c +++ /dev/null @@ -1,274 +0,0 @@ -#include "gcode_parse.h" - -/** \file - \brief Parse received G-Codes -*/ - -#include - -#include "config.h" -#include "sersendf.h" -#include "serial.h" -#include "sermsg.h" -#include "gcode_process.h" - -/// current or previous gcode word -/// for working out what to do with data just received -uint8_t last_field = 0; - -/// crude crc macro -#define crc(a, b) (a ^ b) - -#define GCODE_LINE_BUFFER_LEN 64 - -#define iA 0 -#define iB 1 -#define iC 2 -#define iD 3 -#define iE 4 -#define iF 5 -#define iG 6 -#define iH 7 -#define iI 8 -#define iJ 9 -#define iK 10 -#define iL 11 -#define iM 12 -#define iN 13 -#define iO 14 -#define iP 15 -#define iQ 16 -#define iR 17 -#define iS 18 -#define iT 19 -#define iU 20 -#define iV 21 -#define iW 22 -#define iX 23 -#define iY 24 -#define iZ 25 -#define iAsterisk 26 - -GCODE_COMMAND next_target; - -uint8_t gcode_line[GCODE_LINE_BUFFER_LEN]; -uint8_t gcode_line_pointer = 0; - -float words[32]; -uint32_t seen_mask = 0; - -#define SEEN(c) (seen_mask & (1L << (c))) - -uint32_t line_number = 0; - -const uint8_t char2index(uint8_t c) __attribute__ ((pure)); -const uint8_t char2index(uint8_t c) { - if (c >= 'a' && c <= 'z') - return c - 'a'; - if (c >= 'A' && c <= 'Z') - return c - 'A'; - if (c == '*') - return 26; - return 255; -} - -void gcode_parse_char(uint8_t c) { - if (gcode_line_pointer < (GCODE_LINE_BUFFER_LEN - 1)) - gcode_line[gcode_line_pointer++] = c; - if ((c == 13) || (c == 10)) { - uint8_t i; - for (i = gcode_line_pointer; i < GCODE_LINE_BUFFER_LEN; i++) - gcode_line[i] = 0; - if (gcode_line_pointer > 2) - gcode_parse_line(gcode_line); - gcode_line_pointer = 0; - } -} - -void gcode_parse_line(uint8_t *c) { - enum { - STATE_FIND_WORD, - STATE_FIND_VALUE, - STATE_SEMICOLON_COMMENT, - STATE_BRACKET_COMMENT, - } state = STATE_FIND_WORD; - - uint8_t i; // string index - uint8_t w = 0; // current gcode word - uint8_t checksum = 0; - - seen_mask = 0; - - // calculate checksum - for(i = 0; c[i] != '*' && c[i] != 0; i++) - checksum = checksum ^ c[i]; - - // extract gcode words from line - for (i = 0; c[i] != 0 && c[i] != 13 && c[i] != 10; i++) { - switch (state) { - case STATE_FIND_WORD: - // start of word - if (char2index(c[i]) < 255) { - w = char2index(c[i]); - state = STATE_FIND_VALUE; - } - // comment until end of line - if (c[i] == ';') - state = STATE_SEMICOLON_COMMENT; - // comment until close bracket - if (c[i] == '(') - state = STATE_BRACKET_COMMENT; - break; - case STATE_FIND_VALUE: - if ((c[i] >= '0' && c[i] <= '9') || c[i] == '-') { - uint8_t *ep; - float v = strtod((const char *) &c[i], (char **) &ep); - state = STATE_FIND_WORD; - if (ep > &c[i]) { -// sersendf_P(PSTR("[seen %c: %lx->"), w + 'A', seen_mask); - seen_mask |= (1L << w); -// sersendf_P(PSTR("%lx]"), seen_mask); - words[w] = v; - i = ep - c - 1; - } - } - break; - case STATE_BRACKET_COMMENT: - if (c[i] == ')') - state = STATE_FIND_WORD; - break; - case STATE_SEMICOLON_COMMENT: - // dummy entry to suppress compiler warning - break; - } // switch (state) - } // for i=0 .. newline - - // TODO: process line just read - - if (SEEN(iAsterisk)) { - if (checksum != words[iAsterisk]) { - if (seen_mask & iAsterisk) - sersendf_P(PSTR("rs %d "), ((uint8_t) words[iAsterisk])); - sersendf_P(PSTR("Bad checksum, received %d, expected %d\n"), ((uint8_t) words[iAsterisk]), checksum); - seen_mask = 0; - return; - } - } - - if (SEEN(iN)) { - if (((uint32_t) words[iN]) != line_number) { - sersendf_P(PSTR("Bad line number, received %ld, expected %ld\n"), ((uint32_t) words[iN]), line_number); - seen_mask = 0; - return; - } - line_number++; - } - - serial_writestr_P(PSTR("ok ")); - - // patch words into next_target struct - // TODO: eliminate next_target, update gcode_process to use words[] directly - - next_target.flags = 0; - if (SEEN(iG)) { - next_target.seen_G = 1; - next_target.G = words[iG]; -// sersendf_P(PSTR("G:%d/"), next_target.G); - } - if (SEEN(iM)) { - next_target.seen_M = 1; - next_target.M = words[iM]; -// sersendf_P(PSTR("M:%d/"), next_target.M); - } - if (SEEN(iX)) { - next_target.seen_X = 1; - next_target.target.X = words[iX] * STEPS_PER_MM_X; -// sersendf_P(PSTR("X:%ld/"), next_target.target.X); - } - if (SEEN(iY)) { - next_target.seen_Y = 1; - next_target.target.Y = words[iY] * STEPS_PER_MM_Y; -// sersendf_P(PSTR("Y:%ld/"), next_target.target.Y); - } - if (SEEN(iZ)) { - next_target.seen_Z = 1; - next_target.target.Z = words[iZ] * STEPS_PER_MM_Z; -// sersendf_P(PSTR("Z:%ld/"), next_target.target.Z); - } - if (SEEN(iE)) { - next_target.seen_E = 1; - next_target.target.E = words[iE] * STEPS_PER_MM_E; -// sersendf_P(PSTR("E:%ld/"), next_target.target.E); - } - if (SEEN(iF)) { - next_target.seen_F = 1; - next_target.target.F = words[iF]; -// sersendf_P(PSTR("F:%ld/"), next_target.target.F); - } - if (SEEN(iS)) { - next_target.seen_S = 1; - // if this is temperature, multiply by 4 to convert to quarter-degree units - // cosmetically this should be done in the temperature section, - // but it takes less code, less memory and loses no precision if we do it here instead - if ((next_target.M == 104) || (next_target.M == 109)) - next_target.S = words[iS] * 4.0; - // if this is heater PID stuff, multiply by PID_SCALE because we divide by PID_SCALE later on - else if ((next_target.M >= 130) && (next_target.M <= 132)) - next_target.S = words[iS] * PID_SCALE; - else - next_target.S = words[iS]; -// sersendf_P(PSTR("S:%d/"), next_target.S); - } - if (SEEN(iP)) { - next_target.seen_P = 1; - next_target.P = words[iP]; -// sersendf_P(PSTR("P:%u/"), next_target.P); - } - if (SEEN(iT)) { - next_target.seen_T = 1; - next_target.T = words[iT]; -// sersendf_P(PSTR("T:%d/"), next_target.T); - } - if (SEEN(iN)) { - next_target.seen_N = 1; - next_target.N = words[iN]; -// sersendf_P(PSTR("N:%lu/"), next_target.N); - } - next_target.N_expected = line_number; - if (SEEN(iAsterisk)) { - next_target.seen_checksum = 1; - next_target.checksum_read = words[iAsterisk]; - } - next_target.checksum_calculated = checksum; - - process_gcode_command(); - serial_writechar('\n'); - - seen_mask = 0; -} - -void gcode_init(void) { - // gcc guarantees us all variables are initialised to 0. - - // assume a G1 by default - next_target.seen_G = 1; - next_target.G = 1; - - #ifndef E_ABSOLUTE - next_target.option_e_relative = 1; - #endif -} - -/***************************************************************************\ -* * -* Request a resend of the current line - used from various places. * -* * -* Relies on the global variable next_target.N being valid. * -* * -\***************************************************************************/ - -void request_resend(void) { - serial_writestr_P(PSTR("rs ")); - serwrite_uint8(next_target.N); - serial_writechar('\n'); -} diff --git a/attic/input-float/gcode_parse.h b/attic/input-float/gcode_parse.h deleted file mode 100644 index 73e44c1..0000000 --- a/attic/input-float/gcode_parse.h +++ /dev/null @@ -1,73 +0,0 @@ -#ifndef _GCODE_PARSE_H -#define _GCODE_PARSE_H - -#include - -#include "dda.h" - -// wether to insist on N line numbers -// if not defined, N's are completely ignored -//#define REQUIRE_LINENUMBER - -// wether to insist on a checksum -//#define REQUIRE_CHECKSUM - -/// this is a very crude decimal-based floating point structure. -/// a real floating point would at least have signed exponent.\n -/// resulting value is \f$ mantissa * 10^{-(exponent - 1)} * ((sign * 2) - 1)\f$ -typedef struct { - uint32_t mantissa; ///< the actual digits of our floating point number - uint8_t exponent :7; ///< scale mantissa by \f$10^{-exponent}\f$ - uint8_t sign :1; ///< positive or negative? -} decfloat; - -/// this holds all the possible data from a received command -typedef struct { - struct { - uint8_t seen_G :1; - uint8_t seen_M :1; - uint8_t seen_X :1; - uint8_t seen_Y :1; - uint8_t seen_Z :1; - uint8_t seen_E :1; - uint8_t seen_F :1; - uint8_t seen_S :1; - uint8_t seen_P :1; - uint8_t seen_T :1; - uint8_t seen_N :1; - uint8_t seen_checksum :1; ///< seen a checksum? - uint8_t seen_semi_comment :1; ///< seen a semicolon? - uint8_t seen_parens_comment :1; ///< seen an open parenthesis - uint8_t option_all_relative :1; ///< relative or absolute coordinates? - uint8_t option_e_relative :1; ///< same for e axis (M82/M83) - uint8_t option_inches :1; ///< inches or millimeters? - }; - - uint8_t G; ///< G command number - uint8_t M; ///< M command number - TARGET target; ///< target position: X, Y, Z, E and F - - int16_t S; ///< S word (various uses) - uint16_t P; ///< P word (various uses) - - uint8_t T; ///< T word (tool index) - - uint32_t N; ///< line number - uint32_t N_expected; ///< expected line number - - uint8_t checksum_read; ///< checksum in gcode command - uint8_t checksum_calculated; ///< checksum we calculated -} GCODE_COMMAND; - -/// the command being processed -extern GCODE_COMMAND next_target; - -void gcode_init(void); - -// once we have a whole line, process it -void gcode_parse_line(uint8_t *c); - -// uses the global variable next_target.N -void request_resend(void); - -#endif /* _GCODE_PARSE_H */