From ea20c05260569bdfc0520fd88d368b779011e0d0 Mon Sep 17 00:00:00 2001 From: Rob Giseburt Date: Tue, 27 Sep 2016 16:46:54 -0500 Subject: [PATCH 01/98] Initial pass of changes to work on the gQuadratic (includes Motate update) --- Motate | 2 +- Resources/debug/mb_analyze.py | 11 +- g2core.atsln | 4 + g2core/board/gquadratic.mk | 6 +- ...ratic-a-pinout.h => gquadratic-b-pinout.h} | 156 +++++++++--------- g2core/board/gquadratic/hardware.h | 4 +- .../board/gquadratic/motate_pin_assignments.h | 16 +- g2core/board/printrboardg2/board_xio.cpp | 4 +- g2core/boards.mk | 2 +- g2core/canonical_machine.h | 25 +++ g2core/g2core.cppproj | 78 ++++++++- g2core/g2core.xcodeproj/project.pbxproj | 40 +++++ g2core/planner.cpp | 19 ++- g2core/planner.h | 47 +++++- 14 files changed, 303 insertions(+), 111 deletions(-) rename g2core/board/gquadratic/{gquadratic-a-pinout.h => gquadratic-b-pinout.h} (50%) diff --git a/Motate b/Motate index 73dbb3ce..84f1a21c 160000 --- a/Motate +++ b/Motate @@ -1 +1 @@ -Subproject commit 73dbb3ce43f28cb3ac3c9175b3569dd3d6c93d5b +Subproject commit 84f1a21c14a0e1d1b780c746afc6d19a850f867f diff --git a/Resources/debug/mb_analyze.py b/Resources/debug/mb_analyze.py index 13ab4deb..3e3368cb 100644 --- a/Resources/debug/mb_analyze.py +++ b/Resources/debug/mb_analyze.py @@ -25,13 +25,13 @@ def load_pool(filename): if buf: current_buffer = int(buf.groups()[0], 16) pool[TUMBLER[tumbler_pos]] = current_buffer - # print "TUMBLER[tumbler_pos]: %s=%i" % (TUMBLER[tumbler_pos], current_buffer) + print "TUMBLER[tumbler_pos]: %s=%i" % (TUMBLER[tumbler_pos], current_buffer) tumbler_pos += 1 else: buf = re.search('\(mpBuf_t\s\*\)\s(0x[0-9a-fA-F]+)', line) if buf: current_buffer = int(buf.groups()[0], 16) - # print "setup current_buffer: %s" % current_buffer + print "setup current_buffer: %s" % current_buffer pool[current_buffer] = {'move_time': 0} if current_buffer == pool['r']: pool[current_buffer]['is_r'] = True @@ -49,9 +49,11 @@ def load_pool(filename): if key == 'pv': pv = int(val, 16) pool[current_buffer]['pv'] = pv + print "pv: %s" % pv elif key == 'nx': - nv = int(val, 16) - pool[current_buffer]['nx'] = nv + nx = int(val, 16) + pool[current_buffer]['nx'] = nx + print "nx: %s" % nx elif key == 'buffer_state': pool[current_buffer]['buffer_state'] = val elif key == 'jerk': @@ -60,6 +62,7 @@ def load_pool(filename): pool[current_buffer]['linenum'] = val elif key == 'buffer_number': pool[current_buffer]['buffer_number'] = val + print "#: %s" % val elif key == 'junction_vmax': pool[current_buffer]['junction_vmax'] = float(val) elif key == 'cruise_velocity': diff --git a/g2core.atsln b/g2core.atsln index ca5ee57b..73d8f923 100755 --- a/g2core.atsln +++ b/g2core.atsln @@ -22,6 +22,7 @@ Global Shapeoko2|ARM = Shapeoko2|ARM shopbotShield|ARM = shopbotShield|ARM Stub|ARM = Stub|ARM + TestQuadratic|ARM = TestQuadratic|ARM TestQuintic|ARM = TestQuintic|ARM TestV9|ARM = TestV9|ARM Ultimakerv9k|ARM = Ultimakerv9k|ARM @@ -49,6 +50,8 @@ Global {44EA8FEC-55D7-4149-8A78-A574FC26BF51}.shopbotShield|ARM.ActiveCfg = shopbotShield|ARM {44EA8FEC-55D7-4149-8A78-A574FC26BF51}.shopbotShield|ARM.Build.0 = shopbotShield|ARM {44EA8FEC-55D7-4149-8A78-A574FC26BF51}.Stub|ARM.ActiveCfg = Shapeoko2|ARM + {44EA8FEC-55D7-4149-8A78-A574FC26BF51}.TestQuadratic|ARM.ActiveCfg = TestQuadratic|ARM + {44EA8FEC-55D7-4149-8A78-A574FC26BF51}.TestQuadratic|ARM.Build.0 = TestQuadratic|ARM {44EA8FEC-55D7-4149-8A78-A574FC26BF51}.TestQuintic|ARM.ActiveCfg = TestQuintic|ARM {44EA8FEC-55D7-4149-8A78-A574FC26BF51}.TestQuintic|ARM.Build.0 = TestQuintic|ARM {44EA8FEC-55D7-4149-8A78-A574FC26BF51}.TestV9|ARM.ActiveCfg = TestV9|ARM @@ -68,6 +71,7 @@ Global {D7779B24-5CD6-4A1B-893C-2CAE8CF7A3A0}.Shapeoko2|ARM.ActiveCfg = Stub|ARM {D7779B24-5CD6-4A1B-893C-2CAE8CF7A3A0}.shopbotShield|ARM.ActiveCfg = Stub|ARM {D7779B24-5CD6-4A1B-893C-2CAE8CF7A3A0}.Stub|ARM.ActiveCfg = Stub|ARM + {D7779B24-5CD6-4A1B-893C-2CAE8CF7A3A0}.TestQuadratic|ARM.ActiveCfg = Stub|ARM {D7779B24-5CD6-4A1B-893C-2CAE8CF7A3A0}.TestQuintic|ARM.ActiveCfg = Stub|ARM {D7779B24-5CD6-4A1B-893C-2CAE8CF7A3A0}.TestV9|ARM.ActiveCfg = Stub|ARM {D7779B24-5CD6-4A1B-893C-2CAE8CF7A3A0}.Ultimakerv9k|ARM.ActiveCfg = Stub|ARM diff --git a/g2core/board/gquadratic.mk b/g2core/board/gquadratic.mk index 14bae333..91010b7c 100755 --- a/g2core/board/gquadratic.mk +++ b/g2core/board/gquadratic.mk @@ -12,15 +12,15 @@ ########## # BOARDs for use directly from the make command line (with default settings) or by CONFIGs. -ifeq ("$(BOARD)","gquadratic-a") +ifeq ("$(BOARD)","gquadratic-b") BASE_BOARD=gquadratic - DEVICE_DEFINES += MOTATE_BOARD="gquadratic-a" + DEVICE_DEFINES += MOTATE_BOARD="gquadratic-b" DEVICE_DEFINES += SETTINGS_FILE=${SETTINGS_FILE} endif ########## -# The general pboard-a BASE_BOARD. +# The general gquadratic BASE_BOARD. ifeq ("$(BASE_BOARD)","gquadratic") _BOARD_FOUND = 1 diff --git a/g2core/board/gquadratic/gquadratic-a-pinout.h b/g2core/board/gquadratic/gquadratic-b-pinout.h similarity index 50% rename from g2core/board/gquadratic/gquadratic-a-pinout.h rename to g2core/board/gquadratic/gquadratic-b-pinout.h index 600accfe..c4650921 100755 --- a/g2core/board/gquadratic/gquadratic-a-pinout.h +++ b/g2core/board/gquadratic/gquadratic-b-pinout.h @@ -1,5 +1,5 @@ /* - * gquadratic-a-pinout.h - board pinout specification + * gquadratic-b-pinout.h - board pinout specification * This file is part of the g2core project * * Copyright (c) 2016 Robert Giseburt @@ -29,8 +29,8 @@ * */ -#ifndef GQUADRATIC_A_PINOUT_H -#define GQUADRATIC_A_PINOUT_H +#ifndef GQUADRATIC_B_PINOUT_H +#define GQUADRATIC_B_PINOUT_H /* * USAGE NOTES @@ -100,9 +100,9 @@ // So we have to explicitly enable them as PWM pins. // Generated with: // perl -e 'for($i=1;$i<14;$i++) { print "#define OUTPUT${i}_PWM 0\n";}' -#define OUTPUT1_PWM 1 // Timer0ch0 +#define OUTPUT1_PWM 1 // TC0.0 #define OUTPUT2_PWM 1 // PWM0.0 -#define OUTPUT3_PWM 1 // Timer0ch1 +#define OUTPUT3_PWM 1 // TC0.1 #define OUTPUT4_PWM 1 // PWM1.3 #define OUTPUT5_PWM 0 // unused #define OUTPUT6_PWM 0 // unused @@ -117,86 +117,86 @@ namespace Motate { // Arduino pin name & function -_MAKE_MOTATE_PIN(kOutput1_PinNumber, 'A', 0); // -_MAKE_MOTATE_PIN(kOutput3_PinNumber, 'A', 1); // -_MAKE_MOTATE_PIN(kSocket2_VrefPinNumber, 'A', 2); // -_MAKE_MOTATE_PIN(kI2C1_SDAPinNumber, 'A', 3); // -_MAKE_MOTATE_PIN(kI2C1_SCLPinNumber, 'A', 4); // -_MAKE_MOTATE_PIN(kOutput4_PinNumber, 'A', 5); // -_MAKE_MOTATE_PIN(kUnassigned1, 'A', 6); // Missing in 100-pin package -_MAKE_MOTATE_PIN(kUnassigned2, 'A', 7); // -_MAKE_MOTATE_PIN(kUnassigned3, 'A', 8); // -_MAKE_MOTATE_PIN(kSerial_RX, 'A', 9); // -_MAKE_MOTATE_PIN(kSerial_TX, 'A', 10); // +_MAKE_MOTATE_PIN(kOutput2_PinNumber, 'A', 0); // TC0.0 or PWM0 +_MAKE_MOTATE_PIN(kOutput3_PinNumber, 'A', 1); // TC0.1 or PWM1 +_MAKE_MOTATE_PIN(kSocket2_VrefPinNumber, 'A', 2); // PWM1 +_MAKE_MOTATE_PIN(kI2C1_SDAPinNumber, 'A', 3); // +_MAKE_MOTATE_PIN(kI2C1_SCLPinNumber, 'A', 4); // +_MAKE_MOTATE_PIN(kUnassigned1, 'A', 5); // +_MAKE_MOTATE_PIN(kUnassigned2, 'A', 6); // Missing in 100-pin package +_MAKE_MOTATE_PIN(kUnassigned3, 'A', 7); // +_MAKE_MOTATE_PIN(kUnassigned4, 'A', 8); // +_MAKE_MOTATE_PIN(kSerial_RX, 'A', 9); // +_MAKE_MOTATE_PIN(kSerial_TX, 'A', 10); // _MAKE_MOTATE_PIN(kSocket1_Microstep_1PinNumber, 'A', 11); // -_MAKE_MOTATE_PIN(kSocket1_EnablePinNumber, 'A', 12); // -_MAKE_MOTATE_PIN(kUnassigned4, 'A', 13); // -_MAKE_MOTATE_PIN(kUnassigned6, 'A', 14); // -_MAKE_MOTATE_PIN(kUnassigned5, 'A', 15); // -_MAKE_MOTATE_PIN(kUnassigned7, 'A', 16); // -_MAKE_MOTATE_PIN(kUnassigned8, 'A', 17); // -_MAKE_MOTATE_PIN(kUnassigned9, 'A', 18); // -_MAKE_MOTATE_PIN(kUnassigned10, 'A', 19); // -_MAKE_MOTATE_PIN(kUnassigned11, 'A', 20); // -_MAKE_MOTATE_PIN(kUnassigned13, 'A', 21); // -_MAKE_MOTATE_PIN(kUnassigned12, 'A', 22); // -_MAKE_MOTATE_PIN(kUnassigned14, 'A', 23); // -_MAKE_MOTATE_PIN(kUnassigned15, 'A', 24); // -_MAKE_MOTATE_PIN(kUnassigned16, 'A', 25); // -_MAKE_MOTATE_PIN(kUnassigned17, 'A', 26); // -_MAKE_MOTATE_PIN(kSocket1_VrefPinNumber, 'A', 27); // -_MAKE_MOTATE_PIN(kSerial_CTS, 'A', 28); // -_MAKE_MOTATE_PIN(kUnassigned18, 'A', 29); // Missing in 100-pin package -_MAKE_MOTATE_PIN(kSerial_RTS, 'A', 30); // -_MAKE_MOTATE_PIN(kOutputSAFE_PinNumber, 'A', 31); // +_MAKE_MOTATE_PIN(kSocket1_EnablePinNumber, 'A', 12); // +_MAKE_MOTATE_PIN(kUnassigned5, 'A', 13); // +_MAKE_MOTATE_PIN(kUnassigned6, 'A', 14); // +_MAKE_MOTATE_PIN(kUnassigned7, 'A', 15); // +_MAKE_MOTATE_PIN(kUnassigned8, 'A', 16); // +_MAKE_MOTATE_PIN(kUnassigned9, 'A', 17); // +_MAKE_MOTATE_PIN(kUnassigned10, 'A', 18); // +_MAKE_MOTATE_PIN(kUnassigned11, 'A', 19); // +_MAKE_MOTATE_PIN(kUnassigned12, 'A', 20); // +_MAKE_MOTATE_PIN(kUnassigned13, 'A', 21); // +_MAKE_MOTATE_PIN(kUnassigned14, 'A', 22); // +_MAKE_MOTATE_PIN(kUnassigned15, 'A', 23); // +_MAKE_MOTATE_PIN(kUnassigned16, 'A', 24); // +_MAKE_MOTATE_PIN(kUnassigned17, 'A', 25); // +_MAKE_MOTATE_PIN(kUnassigned18, 'A', 26); // +_MAKE_MOTATE_PIN(kSocket1_VrefPinNumber, 'A', 27); // TC2.1 +_MAKE_MOTATE_PIN(kSerial_CTS, 'A', 28); // +_MAKE_MOTATE_PIN(kUnassigned19, 'A', 29); // Missing in 100-pin package +_MAKE_MOTATE_PIN(kOutput1_PinNumber, 'A', 30); // PWM2 +_MAKE_MOTATE_PIN(kInput4_PinNumber, 'A', 31); // -_MAKE_MOTATE_PIN(kUnassigned20, 'B', 0); // -_MAKE_MOTATE_PIN(kUnassigned22, 'B', 1); // -_MAKE_MOTATE_PIN(kUnassigned21, 'B', 2); // -_MAKE_MOTATE_PIN(kUnassigned23, 'B', 3); // -//_MAKE_MOTATE_PIN( , 'B', 4); // TDI -//_MAKE_MOTATE_PIN( , 'B', 5); // TRACESDO -//_MAKE_MOTATE_PIN( , 'B', 6); // SWDIO -//_MAKE_MOTATE_PIN( , 'B', 7); // SWDCLK -//_MAKE_MOTATE_PIN( , 'B', 8); // XOUT -//_MAKE_MOTATE_PIN( , 'B', 9); // XIN -//_MAKE_MOTATE_PIN( , 'B', 10); // USB_D- -//_MAKE_MOTATE_PIN( , 'B', 11); // USB_D+ -//_MAKE_MOTATE_PIN( , 'B', 12); // ERASE -_MAKE_MOTATE_PIN(kUnassigned38, 'B', 13); // LED_1 (Heartbeat) - PWM2 +_MAKE_MOTATE_PIN(kUnassigned20, 'B', 0); // +_MAKE_MOTATE_PIN(kUnassigned21, 'B', 1); // +_MAKE_MOTATE_PIN(kUnassigned22, 'B', 2); // +_MAKE_MOTATE_PIN(kUnassigned23, 'B', 3); // +//_MAKE_MOTATE_PIN( , 'B', 4); // TDI +//_MAKE_MOTATE_PIN( , 'B', 5); // TRACESDO +//_MAKE_MOTATE_PIN( , 'B', 6); // SWDIO +//_MAKE_MOTATE_PIN( , 'B', 7); // SWDCLK +//_MAKE_MOTATE_PIN( , 'B', 8); // XOUT +//_MAKE_MOTATE_PIN( , 'B', 9); // XIN +//_MAKE_MOTATE_PIN( , 'B', 10); // USB_D- +//_MAKE_MOTATE_PIN( , 'B', 11); // USB_D+ +//_MAKE_MOTATE_PIN( , 'B', 12); // ERASE +_MAKE_MOTATE_PIN(kUnassigned24, 'B', 13); // LED_1 (Heartbeat) - PWM2 -//_MAKE_MOTATE_PIN( , 'D', 0); // USB_VBUS -_MAKE_MOTATE_PIN(kInput1_PinNumber, 'D', 1); // -_MAKE_MOTATE_PIN(kInput2_PinNumber, 'D', 2); // -_MAKE_MOTATE_PIN(kUnassigned24, 'D', 3); // -_MAKE_MOTATE_PIN(kUnassigned25, 'D', 4); // -_MAKE_MOTATE_PIN(kUnassigned26, 'D', 5); // -_MAKE_MOTATE_PIN(kInput3_PinNumber, 'D', 6); // -_MAKE_MOTATE_PIN(kInput4_PinNumber, 'D', 7); // -_MAKE_MOTATE_PIN(kUnassigned19, 'D', 8); // INTERRUPT_OUT -_MAKE_MOTATE_PIN(kUnassigned27, 'D', 9); // -_MAKE_MOTATE_PIN(kOutput2_PinNumber, 'D', 10); // -_MAKE_MOTATE_PIN(kUnassigned28, 'D', 11); // -_MAKE_MOTATE_PIN(kSocket2_DirPinNumber, 'D', 12); // -_MAKE_MOTATE_PIN(kSocket2_EnablePinNumber, 'D', 13); // -_MAKE_MOTATE_PIN(kSocket2_StepPinNumber, 'D', 14); // -_MAKE_MOTATE_PIN(kUnassigned29, 'D', 15); // +//_MAKE_MOTATE_PIN( , 'D', 0); // USB_VBUS +_MAKE_MOTATE_PIN(kInput1_PinNumber, 'D', 1); // +_MAKE_MOTATE_PIN(kInput2_PinNumber, 'D', 2); // +_MAKE_MOTATE_PIN(kUnassigned25, 'D', 3); // +_MAKE_MOTATE_PIN(kUnassigned26, 'D', 4); // +_MAKE_MOTATE_PIN(kUnassigned27, 'D', 5); // +_MAKE_MOTATE_PIN(kInput3_PinNumber, 'D', 6); // +_MAKE_MOTATE_PIN(kSerial_RTS, 'D', 7); // +_MAKE_MOTATE_PIN(kUnassigned28, 'D', 8); // INTERRUPT_OUT +_MAKE_MOTATE_PIN(kUnassigned29, 'D', 9); // +_MAKE_MOTATE_PIN(kUnassigned30, 'D', 10); // +_MAKE_MOTATE_PIN(kLED_RGBWPixelPinNumber, 'D', 11); // PWM0 +_MAKE_MOTATE_PIN(kSocket2_DirPinNumber, 'D', 12); // +_MAKE_MOTATE_PIN(kSocket2_EnablePinNumber, 'D', 13); // +_MAKE_MOTATE_PIN(kSocket2_StepPinNumber, 'D', 14); // +_MAKE_MOTATE_PIN(kOutputSAFE_PinNumber, 'D', 15); // _MAKE_MOTATE_PIN(kSocket2_Microstep_0PinNumber, 'D', 16); // _MAKE_MOTATE_PIN(kSocket2_Microstep_1PinNumber, 'D', 17); // -_MAKE_MOTATE_PIN(kSocket1_DirPinNumber, 'D', 18); // -_MAKE_MOTATE_PIN(kSocket1_StepPinNumber, 'D', 19); // +_MAKE_MOTATE_PIN(kSocket1_DirPinNumber, 'D', 18); // +_MAKE_MOTATE_PIN(kSocket1_StepPinNumber, 'D', 19); // _MAKE_MOTATE_PIN(kSocket1_Microstep_0PinNumber, 'D', 20); // _MAKE_MOTATE_PIN(kSocket1_Microstep_2PinNumber, 'D', 21); // -_MAKE_MOTATE_PIN(kUnassigned30, 'D', 22); // -_MAKE_MOTATE_PIN(kUnassigned31, 'D', 23); // Missing in 100-pin package -_MAKE_MOTATE_PIN(kUnassigned32, 'D', 24); // -_MAKE_MOTATE_PIN(kUnassigned33, 'D', 25); // -_MAKE_MOTATE_PIN(kUnassigned34, 'D', 26); // -_MAKE_MOTATE_PIN(kUnassigned35, 'D', 27); // +_MAKE_MOTATE_PIN(kUnassigned31, 'D', 22); // +_MAKE_MOTATE_PIN(kUnassigned32, 'D', 23); // Missing in 100-pin package +_MAKE_MOTATE_PIN(kUnassigned33, 'D', 24); // +_MAKE_MOTATE_PIN(kUnassigned34, 'D', 25); // +_MAKE_MOTATE_PIN(kUnassigned35, 'D', 26); // +_MAKE_MOTATE_PIN(kUnassigned36, 'D', 27); // _MAKE_MOTATE_PIN(kSocket2_Microstep_2PinNumber, 'D', 28); // -_MAKE_MOTATE_PIN(kUnassigned36, 'D', 29); // Missing in 100-pin package -_MAKE_MOTATE_PIN(kLEDPWM_PinNumber, 'D', 30); // -_MAKE_MOTATE_PIN(kUnassigned37, 'D', 31); // +_MAKE_MOTATE_PIN(kUnassigned37, 'D', 29); // Missing in 100-pin package +_MAKE_MOTATE_PIN(kLEDPWM_PinNumber, 'D', 30); // +_MAKE_MOTATE_PIN(kUnassigned38, 'D', 31); // } // namespace Motate @@ -206,4 +206,4 @@ _MAKE_MOTATE_PIN(kUnassigned37, 'D', 31); // #endif -// GQUADRATIC_A_PINOUT_H +// GQUADRATIC_B_PINOUT_H diff --git a/g2core/board/gquadratic/hardware.h b/g2core/board/gquadratic/hardware.h index fa05771c..1c467915 100755 --- a/g2core/board/gquadratic/hardware.h +++ b/g2core/board/gquadratic/hardware.h @@ -130,8 +130,8 @@ using Motate::OutputPin; /**** Motate Definitions ****/ // Timer definitions. See stepper.h and other headers for setup -typedef TimerChannel<0, 0> dda_timer_type; // stepper pulse generation in stepper.cpp -typedef TimerChannel<1, 0> dwell_timer_type; // dwell timing in stepper.cpp +typedef TimerChannel<9, 0> dda_timer_type; // stepper pulse generation in stepper.cpp +typedef TimerChannel<10, 0> dwell_timer_type; // dwell timing in stepper.cpp typedef ServiceCall<0> load_timer_type; // request load timer in stepper.cpp typedef ServiceCall<1> exec_timer_type; // request exec timer in stepper.cpp typedef ServiceCall<2> fwd_plan_timer_type; // request exec timer in stepper.cpp diff --git a/g2core/board/gquadratic/motate_pin_assignments.h b/g2core/board/gquadratic/motate_pin_assignments.h index 77609574..78050357 100755 --- a/g2core/board/gquadratic/motate_pin_assignments.h +++ b/g2core/board/gquadratic/motate_pin_assignments.h @@ -159,13 +159,15 @@ pin_number kDebug3_PinNumber = -1; // 116; //e Not the out-of-order numbering & pin_number kDebug4_PinNumber = -1; // 114; // END DEBUG PINS -pin_number kLED_USBRXPinNumber = 117; -pin_number kLED_USBTXPinNumber = 118; -pin_number kSD_CardDetectPinNumber = 119; -pin_number kSD_ChipSelectPinNumber = 120; -pin_number kInterlock_InPinNumber = 121; -pin_number kOutputSAFE_PinNumber = 122; // SAFE signal -pin_number kLEDPWM_PinNumber = 123; +pin_number kLED_USBRXPinNumber = 117; +pin_number kLED_USBTXPinNumber = 118; +pin_number kSD_CardDetectPinNumber = 119; +pin_number kSD_ChipSelectPinNumber = 120; +pin_number kInterlock_InPinNumber = 121; +pin_number kOutputSAFE_PinNumber = 122; // SAFE signal +pin_number kLEDPWM_PinNumber = 123; +pin_number kOutputInterrupt_PinNumber = 124; // to-host interrupt signal +pin_number kLED_RGBWPixelPinNumber = 125; // 117; // GRBL / gShield compatibility pins -- Due board ONLY diff --git a/g2core/board/printrboardg2/board_xio.cpp b/g2core/board/printrboardg2/board_xio.cpp index 8122e268..f46df5e9 100755 --- a/g2core/board/printrboardg2/board_xio.cpp +++ b/g2core/board/printrboardg2/board_xio.cpp @@ -50,8 +50,8 @@ decltype(usb.mixin<1>::Serial) &SerialUSB1 = usb.mixin<1>::Serial; // 115200 is the default, as well. //UART Serial {115200, UARTMode::RTSCTSFlowControl}; -MOTATE_SET_USB_VENDOR_STRING( {'S' ,'y', 'n', 't', 'h', 'e', 't', 'o', 's'} ) -MOTATE_SET_USB_PRODUCT_STRING( {'T', 'i', 'n', 'y', 'G', ' ', 'v', '2'} ) +MOTATE_SET_USB_VENDOR_STRING( u"Synthetos" ) +MOTATE_SET_USB_PRODUCT_STRING( u"TinyG v2" ) MOTATE_SET_USB_SERIAL_NUMBER_STRING_FROM_CHIPID() diff --git a/g2core/boards.mk b/g2core/boards.mk index 81443f81..f906dc06 100644 --- a/g2core/boards.mk +++ b/g2core/boards.mk @@ -80,7 +80,7 @@ endif ifeq ("$(CONFIG)","TestQuadratic") ifeq ("$(BOARD)","NONE") - BOARD=gquadratic-a + BOARD=gquadratic-b endif SETTINGS_FILE="settings_test.h" endif diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index 7804d79d..1a7c1991 100755 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -339,6 +339,31 @@ typedef struct GCodeState { // Gcode model state - used by model, pl cmCoordSystem coord_system; // G54-G59 - select coordinate system 1-9 uint8_t tool; // G // M6 tool change - moves "tool_select" to "tool" uint8_t tool_select; // G // T value - T sets this value + + void reset() { + linenum = 0; + motion_mode = 0; + + for (uint8_t i = 0; i< AXES; i++) { + target[i] = 0.0; + work_offset[i] = 0.0; + } + + feed_rate = 0.0; + parameter = 0.0; + + feed_rate_mode = INVERSE_TIME_MODE; + select_plane = CANON_PLANE_XY; + units_mode = INCHES; + path_control = PATH_EXACT_PATH; + distance_mode = ABSOLUTE_MODE; + arc_distance_mode = ABSOLUTE_MODE; + absolute_override = ABSOLUTE_OVERRIDE_OFF; + coord_system = ABSOLUTE_COORDS; + tool = 0; + tool_select = 0; + + }; } GCodeState_t; typedef struct GCodeStateExtended { // Gcode dynamic state extensions - used by model and arcs diff --git a/g2core/g2core.cppproj b/g2core/g2core.cppproj index e25a188c..e6d6348a 100644 --- a/g2core/g2core.cppproj +++ b/g2core/g2core.cppproj @@ -5,7 +5,7 @@ 7.0 com.Atmel.ARMGCC.CPP {44ea8fec-55d7-4149-8a78-a574fc26bf51} - ATSAM3X8C + ATSAMS70N19 none Executable CPP @@ -68,12 +68,12 @@ - 2000000 + 10000000 SWD com.atmel.avrdbg.tool.atmelice - J41800004259 + J41800006366 Atmel-ICE True @@ -100,9 +100,9 @@ True true - J41800004259 - 0x284E0A60 - 2000000 + J41800006366 + 0xA11D0A00 + 10000000 @@ -1454,6 +1454,72 @@ Makefile bin\PrintrbotSimple1608-printrboardG2v3\ + + + + True + True + True + True + True + + + C:\Program Files\Atmel\Atmel Studio 6.0\extensions\Atmel\ARMGCC\3.3.1.128\ARMSupportFiles + C:\Program Files\Atmel\Atmel Studio 6.0\extensions\Atmel\ARMGCC\3.3.1.128\ARMSupportFiles\CMSIS\Include + C:\Program Files\Atmel\Atmel Studio 6.0\extensions\Atmel\ARMGCC\3.3.1.128\ARMSupportFiles\Device\ATMEL + C:\Program Files\Atmel\Atmel Studio 6.0\extensions\Atmel\ARMGCC\3.3.1.128\ARMSupportFiles\Device\ATMEL\sam3xa\include + C:\Program Files\Atmel\Atmel Toolchain\ARM GCC\Native\4.7.2.87\arm-gnu-toolchain\bin\..\..\CMSIS_Atmel + C:\Program Files\Atmel\Atmel Toolchain\ARM GCC\Native\4.7.2.87\arm-gnu-toolchain\bin\..\..\CMSIS_Atmel\CMSIS\Include + C:\Program Files\Atmel\Atmel Toolchain\ARM GCC\Native\4.7.2.87\arm-gnu-toolchain\bin\..\..\CMSIS_Atmel\Device\ATMEL + C:\Program Files\Atmel\Atmel Toolchain\ARM GCC\Native\4.7.2.87\arm-gnu-toolchain\bin\..\..\CMSIS_Atmel\Device\ATMEL\sam3xa\include + + + Optimize (-O1) + True + Maximum (-g3) + True + + + C:\Program Files\Atmel\Atmel Studio 6.0\extensions\Atmel\ARMGCC\3.3.1.128\ARMSupportFiles + C:\Program Files\Atmel\Atmel Studio 6.0\extensions\Atmel\ARMGCC\3.3.1.128\ARMSupportFiles\CMSIS\Include + C:\Program Files\Atmel\Atmel Studio 6.0\extensions\Atmel\ARMGCC\3.3.1.128\ARMSupportFiles\Device\ATMEL + C:\Program Files\Atmel\Atmel Studio 6.0\extensions\Atmel\ARMGCC\3.3.1.128\ARMSupportFiles\Device\ATMEL\sam3xa\include + C:\Program Files\Atmel\Atmel Toolchain\ARM GCC\Native\4.7.2.87\arm-gnu-toolchain\bin\..\..\CMSIS_Atmel + C:\Program Files\Atmel\Atmel Toolchain\ARM GCC\Native\4.7.2.87\arm-gnu-toolchain\bin\..\..\CMSIS_Atmel\CMSIS\Include + C:\Program Files\Atmel\Atmel Toolchain\ARM GCC\Native\4.7.2.87\arm-gnu-toolchain\bin\..\..\CMSIS_Atmel\Device\ATMEL + C:\Program Files\Atmel\Atmel Toolchain\ARM GCC\Native\4.7.2.87\arm-gnu-toolchain\bin\..\..\CMSIS_Atmel\Device\ATMEL\sam3xa\include + + + Optimize (-O1) + True + Maximum (-g3) + True + + + libm + + + True + -Tsam3x8c_flash.ld + Default (-g) + + + C:\Program Files\Atmel\Atmel Toolchain\ARM GCC\Native\4.7.2.87\arm-gnu-toolchain\bin\..\..\CMSIS_Atmel + C:\Program Files\Atmel\Atmel Toolchain\ARM GCC\Native\4.7.2.87\arm-gnu-toolchain\bin\..\..\CMSIS_Atmel\CMSIS\Include + C:\Program Files\Atmel\Atmel Toolchain\ARM GCC\Native\4.7.2.87\arm-gnu-toolchain\bin\..\..\CMSIS_Atmel\Device\ATMEL + C:\Program Files\Atmel\Atmel Toolchain\ARM GCC\Native\4.7.2.87\arm-gnu-toolchain\bin\..\..\CMSIS_Atmel\Device\ATMEL\sam3xa\include + + + Default (-Wa,-g) + + + True + + CONFIG=TestQuadratic COLOR=0 VERBOSE=1 DEBUG=1 + clean CONFIG=TestQuintic + Makefile + bin\TestQuadratic\ + compile diff --git a/g2core/g2core.xcodeproj/project.pbxproj b/g2core/g2core.xcodeproj/project.pbxproj index d6ac4fe3..7751ec2a 100644 --- a/g2core/g2core.xcodeproj/project.pbxproj +++ b/g2core/g2core.xcodeproj/project.pbxproj @@ -291,6 +291,20 @@ passBuildSettingsInEnvironment = 1; productName = g3_due; }; + D4782AAE1D9B16BE00B32136 /* G2 Probotix */ = { + isa = PBXLegacyTarget; + buildArgumentsString = "$(ACTION) VERBOSE=1 COLOR=0 CONFIG=ProbotixV90 DEBUG=1"; + buildConfigurationList = D4782AAF1D9B16BE00B32136 /* Build configuration list for PBXLegacyTarget "G2 Probotix" */; + buildPhases = ( + ); + buildToolPath = /usr/bin/make; + buildWorkingDirectory = .; + dependencies = ( + ); + name = "G2 Probotix"; + passBuildSettingsInEnvironment = 1; + productName = g3_due; + }; D4AC391A1C7BAB8E0098D685 /* G2 sbv300 */ = { isa = PBXLegacyTarget; buildArgumentsString = "$(ACTION) VERBOSE=1 COLOR=0 CONFIG=sbv300 DEBUG=2"; @@ -411,6 +425,7 @@ D4AC391A1C7BAB8E0098D685 /* G2 sbv300 */, D4F226F31D088A48008ED57C /* G2 gQuintic PrintrbotPlus */, D43FF7141D537A5C00FB5B53 /* G2 gQuadratic Test */, + D4782AAE1D9B16BE00B32136 /* G2 Probotix */, D457112317053BFB00EA19A8 /* index */, ); }; @@ -653,6 +668,22 @@ }; name = Release; }; + D4782AB01D9B16BE00B32136 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + PATH = "$PATH:/usr/local/gcc-arm-none-eabi/bin"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + D4782AB11D9B16BE00B32136 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + PATH = "$PATH:/usr/local/gcc-arm-none-eabi/bin"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; D4AC391C1C7BAB8E0098D685 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -790,6 +821,15 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + D4782AAF1D9B16BE00B32136 /* Build configuration list for PBXLegacyTarget "G2 Probotix" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + D4782AB01D9B16BE00B32136 /* Debug */, + D4782AB11D9B16BE00B32136 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; D4AC391B1C7BAB8E0098D685 /* Build configuration list for PBXLegacyTarget "G2 sbv300" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/g2core/planner.cpp b/g2core/planner.cpp index eb94beb7..a6e35701 100755 --- a/g2core/planner.cpp +++ b/g2core/planner.cpp @@ -172,6 +172,14 @@ stat_t planner_test_assertions() (BAD_MAGIC(mr.magic_start)) || (BAD_MAGIC(mr.magic_end))) { return(cm_panic(STAT_PLANNER_ASSERTION_FAILURE, "planner_test_assertions()")); } + for (uint8_t i=0; i < PLANNER_BUFFER_POOL_SIZE; i++) { + if (mb.bf[i].nx == nullptr) { + _debug_trap("buffer has nullptr for nx"); + } + if (mb.bf[i].pv == nullptr) { + _debug_trap("buffer has nullptr for pv"); + } + } return (STAT_OK); } @@ -697,25 +705,26 @@ static inline void _clear_buffer(mpBuf_t *bf) // the pointers and buffer number during interrupts // We'll have to figure something else out for C, sorry. - bf->clear(); + bf->reset(); } void mp_init_buffers(void) { mpBuf_t *pv, *nx; - uint8_t i, nx_i; - memset(&mb, 0, sizeof(mb)); // clear all values, pointers and status + //memset(&mb, 0, sizeof(mb)); // clear all values, pointers and status mb.magic_start = MAGICNUM; mb.magic_end = MAGICNUM; mb.w = &mb.bf[0]; // init all buffer pointers mb.r = &mb.bf[0]; pv = &mb.bf[PLANNER_BUFFER_POOL_SIZE-1]; - for (i=0; i < PLANNER_BUFFER_POOL_SIZE; i++) { + for (uint8_t i=0; i < PLANNER_BUFFER_POOL_SIZE; i++) { + _clear_buffer(&mb.bf[i]); + uint8_t nx_i = ((i<(PLANNER_BUFFER_POOL_SIZE-1))?(i+1):0); // buffer incr & wrap + mb.bf[i].buffer_number = i; //+++++ number it for diagnostics only (otherwise not used) - nx_i = ((i Date: Tue, 27 Sep 2016 19:51:41 -0400 Subject: [PATCH 02/98] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 9d70f08d..82162837 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ +g2core + [![Build Status](https://travis-ci.org/synthetos/g2.svg?branch=edge)](https://travis-ci.org/synthetos/g2) [![Issues in Ready](https://badge.waffle.io/synthetos/g2.svg?label=ready&title=Ready)](http://waffle.io/synthetos/g2) [![Issues in Progress](https://badge.waffle.io/synthetos/g2.svg?label=in%20progress&title=In%20Progress)](http://waffle.io/synthetos/g2) # g2core - Edge Branch From d2ef41c9fd5bf661fd233b14b08d9b564282a41f Mon Sep 17 00:00:00 2001 From: Rob Giseburt Date: Tue, 27 Sep 2016 21:00:19 -0500 Subject: [PATCH 03/98] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 82162837..2558b988 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -g2core +g2core [![Build Status](https://travis-ci.org/synthetos/g2.svg?branch=edge)](https://travis-ci.org/synthetos/g2) [![Issues in Ready](https://badge.waffle.io/synthetos/g2.svg?label=ready&title=Ready)](http://waffle.io/synthetos/g2) [![Issues in Progress](https://badge.waffle.io/synthetos/g2.svg?label=in%20progress&title=In%20Progress)](http://waffle.io/synthetos/g2) From d0c03418cc7f16981921d5f1aa4a22379c6b145e Mon Sep 17 00:00:00 2001 From: Rob Giseburt Date: Tue, 27 Sep 2016 21:09:10 -0500 Subject: [PATCH 04/98] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2558b988..6592e57f 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -g2core +g2core [![Build Status](https://travis-ci.org/synthetos/g2.svg?branch=edge)](https://travis-ci.org/synthetos/g2) [![Issues in Ready](https://badge.waffle.io/synthetos/g2.svg?label=ready&title=Ready)](http://waffle.io/synthetos/g2) [![Issues in Progress](https://badge.waffle.io/synthetos/g2.svg?label=in%20progress&title=In%20Progress)](http://waffle.io/synthetos/g2) From 0f00a415488768b47f15f93a97416229b78e0e0f Mon Sep 17 00:00:00 2001 From: Rob Giseburt Date: Tue, 27 Sep 2016 21:02:37 -0500 Subject: [PATCH 05/98] ignoring compile_commands.json --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index b54877c5..0a6475fe 100755 --- a/.gitignore +++ b/.gitignore @@ -53,3 +53,5 @@ Tools/gcc-arm-none-eabi-*.tar.bz2 */TinyG2.componentinfo.xml g2core/g2core.componentinfo.xml .tags + +g2core/compile_commands.json From 04c30ba21b6dc2dd01b2fca2d3437d8c05596a9e Mon Sep 17 00:00:00 2001 From: Rob Giseburt Date: Wed, 28 Sep 2016 11:06:56 -0500 Subject: [PATCH 06/98] Added WaterColorBotv2 settings+config --- g2core/boards.mk | 12 +- g2core/g2core.xcodeproj/project.pbxproj | 2 + g2core/settings/settings_watercolorbot_v2.h | 397 ++++++++++++++++++++ 3 files changed, 410 insertions(+), 1 deletion(-) create mode 100755 g2core/settings/settings_watercolorbot_v2.h diff --git a/g2core/boards.mk b/g2core/boards.mk index f906dc06..2dc4380c 100644 --- a/g2core/boards.mk +++ b/g2core/boards.mk @@ -85,7 +85,6 @@ ifeq ("$(CONFIG)","TestQuadratic") SETTINGS_FILE="settings_test.h" endif - ########## # Shopbot configs: @@ -138,5 +137,16 @@ ifeq ("$(CONFIG)","Ultimakerv9k") SETTINGS_FILE="settings_ultimaker.h" endif +########## +# EMSL configs: + +ifeq ("$(CONFIG)","WaterColorBotv2") + ifeq ("$(BOARD)","NONE") + BOARD=gquadratic-b + endif + SETTINGS_FILE="settings_watercolorbot_v2.h" +endif + + include $(wildcard ./board/$(STAR).mk) diff --git a/g2core/g2core.xcodeproj/project.pbxproj b/g2core/g2core.xcodeproj/project.pbxproj index 7751ec2a..bc741a0f 100644 --- a/g2core/g2core.xcodeproj/project.pbxproj +++ b/g2core/g2core.xcodeproj/project.pbxproj @@ -58,6 +58,7 @@ D44E72C21D663B0F00ECD5DD /* coolant.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = coolant.h; sourceTree = ""; }; D4522DC91C45F41D0086AAE6 /* g2core_info.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = g2core_info.h; sourceTree = ""; }; D457117B17053EFA00EA19A8 /* Makefile */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = Makefile; sourceTree = ""; usesTabs = 1; xcLanguageSpecificationIdentifier = xcode.lang.sh; }; + D4782AB21D9B5F9400B32136 /* settings_watercolorbot_v2.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = settings_watercolorbot_v2.h; sourceTree = ""; }; D47B744C1D4925B4004FAB53 /* device */ = {isa = PBXFileReference; lastKnownFileType = folder; path = device; sourceTree = ""; }; D48F5A40172CB1F900D0E055 /* canonical_machine.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = canonical_machine.cpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; D48F5A41172CB1F900D0E055 /* config_app.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = config_app.cpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; @@ -146,6 +147,7 @@ isa = PBXGroup; children = ( D4AC39081C77C1F20098D685 /* settings_default.h */, + D4782AB21D9B5F9400B32136 /* settings_watercolorbot_v2.h */, D4AC39091C77C1F20098D685 /* settings_makeblock.h */, D4AC390A1C77C1F20098D685 /* settings_othermill_test.h */, D4AC390B1C77C1F20098D685 /* settings_othermill.h */, diff --git a/g2core/settings/settings_watercolorbot_v2.h b/g2core/settings/settings_watercolorbot_v2.h new file mode 100755 index 00000000..35aa99fe --- /dev/null +++ b/g2core/settings/settings_watercolorbot_v2.h @@ -0,0 +1,397 @@ +/* + * settings_watercolorbot_v2.h - settings for the WaterColorBot v2 (http://watercolorbot.com/) + * This file is part of the g2core project + * + * Copyright (c) 2016 Alden S. Hart Jr. + * Copyright (c) 2016 Robert Giseburt + * + * This file ("the software") is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2 as published by the + * Free Software Foundation. You should have received a copy of the GNU General Public + * License, version 2 along with the software. If not, see . + * + * As a special exception, you may use this file as part of a software library without + * restriction. Specifically, if other files instantiate templates or use macros or + * inline functions from this file, or you compile this file and link it with other + * files to produce an executable, this file does not by itself cause the resulting + * executable to be covered by the GNU General Public License. This exception does not + * however invalidate any other reasons why the executable file might be covered by the + * GNU General Public License. + * + * THE SOFTWARE IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT WITHOUT ANY + * WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT + * SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/***********************************************************************/ +/**** TestV9 profile - naked board *************************************/ +/***********************************************************************/ + +// ***> NOTE: The init message must be a single line with no CRs or LFs +#define INIT_MESSAGE "Initializing configs to WaterColorBot v2 settings" + +#define JUNCTION_INTEGRATION_TIME 1.50 // cornering - usually between 0.5 and 2.0 (higher is faster) +#define CHORDAL_TOLERANCE 0.01 // chordal accuracy for arc drawing (in mm) + +#define SOFT_LIMIT_ENABLE 0 // 0=off, 1=on +#define HARD_LIMIT_ENABLE 1 // 0=off, 1=on +#define SAFETY_INTERLOCK_ENABLE 1 // 0=off, 1=on + +#define SPINDLE_ENABLE_POLARITY 1 // 0=active low, 1=active high +#define SPINDLE_DIR_POLARITY 0 // 0=clockwise is low, 1=clockwise is high +#define SPINDLE_PAUSE_ON_HOLD true +#define SPINDLE_DWELL_TIME 1.0 + +#define COOLANT_MIST_POLARITY 1 // 0=active low, 1=active high +#define COOLANT_FLOOD_POLARITY 1 // 0=active low, 1=active high +#define COOLANT_PAUSE_ON_HOLD false + +// Communications and reporting settings + +#define COMM_MODE JSON_MODE // one of: TEXT_MODE, JSON_MODE +#define XIO_ENABLE_FLOW_CONTROL FLOW_CONTROL_RTS // FLOW_CONTROL_OFF, FLOW_CONTROL_RTS + +#define TEXT_VERBOSITY TV_VERBOSE // one of: TV_SILENT, TV_VERBOSE +#define JSON_VERBOSITY JV_MESSAGES // one of: JV_SILENT, JV_FOOTER, JV_CONFIGS, JV_MESSAGES, JV_LINENUM, JV_VERBOSE +#define QUEUE_REPORT_VERBOSITY QR_OFF // one of: QR_OFF, QR_SINGLE, QR_TRIPLE + +#define STATUS_REPORT_VERBOSITY SR_FILTERED // one of: SR_OFF, SR_FILTERED, SR_VERBOSE +#define STATUS_REPORT_MIN_MS 100 // milliseconds - enforces a viable minimum +#define STATUS_REPORT_INTERVAL_MS 250 // milliseconds - set $SV=0 to disable + +//#define STATUS_REPORT_DEFAULTS "line","posx","posy","posz","posa","bcr","feed","vel","unit","coor","dist","admo","frmo","momo","stat" +#define STATUS_REPORT_DEFAULTS "line","posx","posy","posz","bcr","feed","vel","momo","stat" + +// Alternate SRs +//#define STATUS_REPORT_DEFAULTS "line","vel","mpox","mpoy","mpoz","mpoa","coor","ofsa","ofsx","ofsy","ofsz","dist","unit","stat","homz","homy","homx","momo" +//#define STATUS_REPORT_DEFAULTS "_ts1","_cs1","_es1","_xs1","_fe1","line","posx","posy","posz","vel","stat" +//#define STATUS_REPORT_DEFAULTS "line","posx","posy","posz","vel","_cs1","_es1","_xs1","_fe1","_cs2","_es2","_xs2","_fe2" +//#define STATUS_REPORT_DEFAULTS "mpox","mpoy","mpoz","mpoa","ofsx","ofsy","ofsz","ofsa","unit","stat","coor","momo","dist","home","hold","macs","cycs","mots","plan","feed" +//#define STATUS_REPORT_DEFAULTS "line","mpox","mpoy","mpoz","mpoa","ofsx","ofsy","ofsz","ofsa","stat","_cs1","_es1","_fe0","_fe1","_fe2","_fe3" +//#define STATUS_REPORT_DEFAULTS "line","mpox","mpoy","mpoz","stat","_ts2","_ps2","_cs2","_es2","_fe2" +//#define STATUS_REPORT_DEFAULTS "line","mpox","mpoy","mpoz","_cs3","_es3","_fe3","_xs3","_cs2","_es2","_fe2","_xs2","stat" +//#define STATUS_REPORT_DEFAULTS "line","posx","posy","posz","posa","feed","vel","unit","coor","dist","frmo","momo","stat","_cs1","_es1","_xs1","_fe1" + +// Gcode startup defaults +#define GCODE_DEFAULT_UNITS MILLIMETERS // MILLIMETERS or INCHES +#define GCODE_DEFAULT_PLANE CANON_PLANE_XY // CANON_PLANE_XY, CANON_PLANE_XZ, or CANON_PLANE_YZ +#define GCODE_DEFAULT_COORD_SYSTEM G54 // G54, G55, G56, G57, G58 or G59 +#define GCODE_DEFAULT_PATH_CONTROL PATH_CONTINUOUS +#define GCODE_DEFAULT_DISTANCE_MODE ABSOLUTE_MODE + +// *** motor settings ************************************************************************************ + +#define MOTOR_POWER_MODE MOTOR_POWERED_IN_CYCLE // default motor power mode (see cmMotorPowerMode in stepper.h) +#define MOTOR_POWER_TIMEOUT 2.00 // motor power timeout in seconds + +#define MOTOR_POWER_MODE MOTOR_POWERED_IN_CYCLE // default motor power mode (see cmMotorPowerMode in stepper.h) +#define MOTOR_POWER_TIMEOUT 2.00 // motor power timeout in seconds + +#define M1_MOTOR_MAP AXIS_Y // 1ma +#define M1_STEP_ANGLE 1.8 // 1sa +#define M1_TRAVEL_PER_REV 91.5 // 1tr +#define M1_MICROSTEPS 8 // 1mi 1,2,4,8 +#define M1_POLARITY 0 // 1po 0=normal, 1=reversed +#define M1_POWER_MODE MOTOR_POWER_MODE // 1pm standard +#define M1_POWER_LEVEL 0.4 + +#define M2_MOTOR_MAP AXIS_X +#define M2_STEP_ANGLE 1.8 +#define M2_TRAVEL_PER_REV 91.5 +#define M2_MICROSTEPS 8 +#define M2_POLARITY 0 +#define M2_POWER_MODE MOTOR_POWER_MODE +#define M2_POWER_LEVEL 0.4 + +#define M3_MOTOR_MAP AXIS_Z +#define M3_STEP_ANGLE 1.8 +#define M3_TRAVEL_PER_REV 2.1166666 +#define M3_MICROSTEPS 8 +#define M3_POLARITY 1 +#define M3_POWER_MODE MOTOR_POWER_MODE +#define M3_POWER_LEVEL 0.50 + +#define M4_MOTOR_MAP AXIS_A +#define M4_STEP_ANGLE 1.8 +#define M4_TRAVEL_PER_REV 360 // degrees moved per motor rev +#define M4_MICROSTEPS 32 +#define M4_POLARITY 0 +#define M4_POWER_MODE MOTOR_POWER_MODE +#define M4_POWER_LEVEL 0.6 + +// *** axis settings ********************************************************************************** + +#define JERK_MAX 30000 + +#define X_AXIS_MODE AXIS_STANDARD // xam see canonical_machine.h cmAxisMode for valid values +#define X_VELOCITY_MAX 50000 // xvm G0 max velocity in mm/min +#define X_FEEDRATE_MAX X_VELOCITY_MAX // xfr G1 max feed rate in mm/min +#define X_TRAVEL_MIN 0 // xtn minimum travel - used by soft limits and homing +#define X_TRAVEL_MAX 400 // xtm maximum travel - used by soft limits and homing +#define X_JERK_MAX JERK_MAX // xjm +#define X_JERK_HIGH_SPEED X_JERK_MAX // xjh +#define X_HOMING_INPUT 1 // xhi input used for homing or 0 to disable +#define X_HOMING_DIRECTION 0 // xhd 0=search moves negative, 1= search moves positive +#define X_SEARCH_VELOCITY 1000 // xsv move in negative direction +#define X_LATCH_VELOCITY 100 // xlv mm/min +#define X_LATCH_BACKOFF 10 // xlb mm +#define X_ZERO_BACKOFF 2 // xzb mm + +#define Y_AXIS_MODE AXIS_STANDARD +#define Y_VELOCITY_MAX 50000 +#define Y_FEEDRATE_MAX Y_VELOCITY_MAX +#define Y_TRAVEL_MIN 0 +#define Y_TRAVEL_MAX 175 +#define Y_JERK_MAX JERK_MAX +#define Y_JERK_HIGH_SPEED Y_JERK_MAX +#define Y_HOMING_INPUT 3 +#define Y_HOMING_DIRECTION 0 +#define Y_SEARCH_VELOCITY 1000 +#define Y_LATCH_VELOCITY 100 +#define Y_LATCH_BACKOFF 10 +#define Y_ZERO_BACKOFF 2 + +#define Z_AXIS_MODE AXIS_STANDARD +#define Z_VELOCITY_MAX 1000 +#define Z_FEEDRATE_MAX Z_VELOCITY_MAX +#define Z_TRAVEL_MIN 0 +#define Z_TRAVEL_MAX 75 +#define Z_JERK_MAX JERK_MAX +#define Z_JERK_HIGH_SPEED Z_JERK_MAX +#define Z_HOMING_INPUT 6 +#define Z_HOMING_DIRECTION 1 +#define Z_SEARCH_VELOCITY 600 +#define Z_LATCH_VELOCITY 100 +#define Z_LATCH_BACKOFF 10 +#define Z_ZERO_BACKOFF 2 + +// Rotary values are chosen to make the motor react the same as X for testing +/*************************************************************************************** + * To calculate the speeds here, in Wolfram Alpha-speak: + * + * c=2*pi*r, r=0.609, d=c/360, s=((S*60)/d), S=40 for s + * c=2*pi*r, r=5.30516476972984, d=c/360, s=((S*60)/d), S=40 for s + * + * Change r to A_RADIUS, and S to the desired speed, in mm/s or mm/s/s/s. + * + * It will return s= as the value you want to enter. + * + * If the value is over 1 million, the code will divide it by 1 million, + * so you have to pre-multiply it by 1000000.0. (The value is in millions, btw.) + * + * Note that you need these to be floating point values, so always have a .0 at the end! + * + ***************************************************************************************/ + +#define A_AXIS_MODE AXIS_RADIUS +#define A_RADIUS 5.30516476972984 +//#define A_VELOCITY_MAX 25920.0 // ~40 mm/s, 2,400 mm/min +//#define A_FEEDRATE_MAX 25920.0/2.0 // ~20 mm/s, 1,200 mm/min +#define A_VELOCITY_MAX 77760.0 // G0 rate ~120 mm/s, 2,400 mm/min +#define A_FEEDRATE_MAX 9720.0 // 9720.0 = G1 rate ~15 mm/s, 900 mm/min +#define A_TRAVEL_MIN 0 +#define A_TRAVEL_MAX 10 +#define A_JERK_MAX 648000 // 1,000 million mm/min^3 = 648000 + // * a million IF it's over a million + // c=2*pi*r, r=5.30516476972984, d=c/360, s=((1000*60)/d) +#define A_HOMING_INPUT 0 +#define A_HOMING_DIRECTION 0 +#define A_SEARCH_VELOCITY 2000 +#define A_LATCH_VELOCITY 2000 +#define A_LATCH_BACKOFF 5 +#define A_ZERO_BACKOFF 2 +#define A_JERK_HIGH_SPEED A_JERK_MAX + +#define B_AXIS_MODE AXIS_DISABLED +#define B_RADIUS 1 +#define B_VELOCITY_MAX 3600 +#define B_FEEDRATE_MAX B_VELOCITY_MAX +#define B_TRAVEL_MIN 0 +#define B_TRAVEL_MAX -1 +//#define B_JERK_MAX 20000000 +#define B_JERK_MAX 20 +#define B_HOMING_INPUT 0 +#define B_HOMING_DIRECTION 0 +#define B_SEARCH_VELOCITY 600 +#define B_LATCH_VELOCITY 100 +#define B_LATCH_BACKOFF 10 +#define B_ZERO_BACKOFF 2 +#define B_JERK_HIGH_SPEED A_JERK_MAX + + +//*** Input / output settings *** +/* + IO_MODE_DISABLED + IO_ACTIVE_LOW aka NORMALLY_OPEN + IO_ACTIVE_HIGH aka NORMALLY_CLOSED + + INPUT_ACTION_NONE + INPUT_ACTION_STOP + INPUT_ACTION_FAST_STOP + INPUT_ACTION_HALT + INPUT_ACTION_RESET + + INPUT_FUNCTION_NONE + INPUT_FUNCTION_LIMIT + INPUT_FUNCTION_INTERLOCK + INPUT_FUNCTION_SHUTDOWN + INPUT_FUNCTION_PANIC +*/ +// Inputs are defined for the g2ref(a) board +// Xmn (board label) +#define DI1_MODE IO_ACTIVE_HIGH +#define DI1_ACTION INPUT_ACTION_NONE +#define DI1_FUNCTION INPUT_FUNCTION_NONE + +// Xmax +#define DI2_MODE IO_MODE_DISABLED +#define DI2_ACTION INPUT_ACTION_NONE +#define DI2_FUNCTION INPUT_FUNCTION_NONE + +// Ymin +#define DI3_MODE IO_MODE_DISABLED +#define DI3_ACTION INPUT_ACTION_NONE +#define DI3_FUNCTION INPUT_FUNCTION_NONE + +// Ymax +#define DI4_MODE IO_ACTIVE_HIGH +#define DI4_ACTION INPUT_ACTION_NONE +#define DI4_FUNCTION INPUT_FUNCTION_NONE + +// Zmin +#define DI5_MODE IO_ACTIVE_LOW // Z probe +#define DI5_ACTION INPUT_ACTION_NONE +#define DI5_FUNCTION INPUT_FUNCTION_NONE + +// Zmax +#define DI6_MODE IO_MODE_DISABLED +#define DI6_ACTION INPUT_ACTION_STOP +#define DI6_FUNCTION INPUT_FUNCTION_NONE + +// Shutdown (Amin on v9 board) +#define DI7_MODE IO_MODE_DISABLED +#define DI7_ACTION INPUT_ACTION_NONE +#define DI7_FUNCTION INPUT_FUNCTION_NONE + +// High Voltage Z Probe In (Amax on v9 board) +#define DI8_MODE IO_ACTIVE_LOW +#define DI8_ACTION INPUT_ACTION_NONE +#define DI8_FUNCTION INPUT_FUNCTION_NONE + +// Hardware interlock input +#define DI9_MODE IO_MODE_DISABLED +#define DI9_ACTION INPUT_ACTION_NONE +#define DI9_FUNCTION INPUT_FUNCTION_NONE + +//Extruder1_PWM +#define DO1_MODE IO_ACTIVE_HIGH + +//Extruder2_PWM +#define DO2_MODE IO_ACTIVE_HIGH + +//Fan1A_PWM +#define DO3_MODE IO_ACTIVE_HIGH + +//Fan1B_PWM +#define DO4_MODE IO_ACTIVE_HIGH + +#define DO5_MODE IO_ACTIVE_HIGH +#define DO6_MODE IO_ACTIVE_HIGH +#define DO7_MODE IO_ACTIVE_HIGH +#define DO8_MODE IO_ACTIVE_HIGH + +//SAFEin (Output) signal +#define DO9_MODE IO_ACTIVE_HIGH + +#define DO10_MODE IO_ACTIVE_HIGH + +//Header Bed FET +#define DO11_MODE IO_ACTIVE_HIGH + +//Indicator_LED +#define DO12_MODE IO_ACTIVE_HIGH + +#define DO13_MODE IO_ACTIVE_HIGH + + +/*** Extruders / Heaters ***/ +/* +#define MIN_FAN_TEMP 40.0 +#define MAX_FAN_TEMP 150.0 + +#define H1_DEFAULT_ENABLE true +#define H1_DEFAULT_P 9.0 +#define H1_DEFAULT_I 0.12 +#define H1_DEFAULT_D 400.0 + +#define H2_DEFAULT_ENABLE false +#define H2_DEFAULT_P 9.0 +#define H2_DEFAULT_I 0.12 +#define H2_DEFAULT_D 400.0 + +#define H3_DEFAULT_ENABLE false +#define H3_DEFAULT_P 9.0 +#define H3_DEFAULT_I 0.12 +#define H3_DEFAULT_D 400.0 +*/ + + +// *** PWM SPINDLE CONTROL *** + +#define P1_PWM_FREQUENCY 100 // in Hz +#define P1_CW_SPEED_LO 1000 // in RPM (arbitrary units) +#define P1_CW_SPEED_HI 2000 +#define P1_CW_PHASE_LO 0.125 // phase [0..1] +#define P1_CW_PHASE_HI 0.2 +#define P1_CCW_SPEED_LO 1000 +#define P1_CCW_SPEED_HI 2000 +#define P1_CCW_PHASE_LO 0.125 +#define P1_CCW_PHASE_HI 0.2 +#define P1_PWM_PHASE_OFF 0.1 + +// *** DEFAULT COORDINATE SYSTEM OFFSETS *** + +#define G54_X_OFFSET 0 // G54 is traditionally set to all zeros +#define G54_Y_OFFSET 0 +#define G54_Z_OFFSET 0 +#define G54_A_OFFSET 0 +#define G54_B_OFFSET 0 +#define G54_C_OFFSET 0 + +#define G55_X_OFFSET (X_TRAVEL_MAX/2) // set to middle of table +#define G55_Y_OFFSET (Y_TRAVEL_MAX/2) +#define G55_Z_OFFSET 0 +#define G55_A_OFFSET 0 +#define G55_B_OFFSET 0 +#define G55_C_OFFSET 0 + +#define G56_X_OFFSET 0 +#define G56_Y_OFFSET 0 +#define G56_Z_OFFSET 0 +#define G56_A_OFFSET 0 +#define G56_B_OFFSET 0 +#define G56_C_OFFSET 0 + +#define G57_X_OFFSET 0 +#define G57_Y_OFFSET 0 +#define G57_Z_OFFSET 0 +#define G57_A_OFFSET 0 +#define G57_B_OFFSET 0 +#define G57_C_OFFSET 0 + +#define G58_X_OFFSET 0 +#define G58_Y_OFFSET 0 +#define G58_Z_OFFSET 0 +#define G58_A_OFFSET 0 +#define G58_B_OFFSET 0 +#define G58_C_OFFSET 0 + +#define G59_X_OFFSET 0 +#define G59_Y_OFFSET 0 +#define G59_Z_OFFSET 0 +#define G59_A_OFFSET 0 +#define G59_B_OFFSET 0 +#define G59_C_OFFSET 0 From 4c94bc7fe36bc2d83fb3309bc543ad6487fcbe4e Mon Sep 17 00:00:00 2001 From: Rob Giseburt Date: Wed, 28 Sep 2016 11:07:48 -0500 Subject: [PATCH 07/98] commented out some planner debugging, minor syntactic adjustment in stepper --- g2core/planner.cpp | 16 ++++++++-------- g2core/stepper.cpp | 17 ++++++++++------- 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/g2core/planner.cpp b/g2core/planner.cpp index a6e35701..853d9586 100755 --- a/g2core/planner.cpp +++ b/g2core/planner.cpp @@ -172,14 +172,14 @@ stat_t planner_test_assertions() (BAD_MAGIC(mr.magic_start)) || (BAD_MAGIC(mr.magic_end))) { return(cm_panic(STAT_PLANNER_ASSERTION_FAILURE, "planner_test_assertions()")); } - for (uint8_t i=0; i < PLANNER_BUFFER_POOL_SIZE; i++) { - if (mb.bf[i].nx == nullptr) { - _debug_trap("buffer has nullptr for nx"); - } - if (mb.bf[i].pv == nullptr) { - _debug_trap("buffer has nullptr for pv"); - } - } +// for (uint8_t i=0; i < PLANNER_BUFFER_POOL_SIZE; i++) { +// if (mb.bf[i].nx == nullptr) { +// _debug_trap("buffer has nullptr for nx"); +// } +// if (mb.bf[i].pv == nullptr) { +// _debug_trap("buffer has nullptr for pv"); +// } +// } return (STAT_OK); } diff --git a/g2core/stepper.cpp b/g2core/stepper.cpp index e3017a6c..32c70d5e 100644 --- a/g2core/stepper.cpp +++ b/g2core/stepper.cpp @@ -279,39 +279,39 @@ void dda_timer_type::interrupt() // process DDAs for each motor if ((st_run.mot[MOTOR_1].substep_accumulator += st_run.mot[MOTOR_1].substep_increment) > 0) { - motor_1.stepStart(); // turn step bit on + motor_1.stepStart(); // turn step bit on st_run.mot[MOTOR_1].substep_accumulator -= st_run.dda_ticks_X_substeps; INCREMENT_ENCODER(MOTOR_1); } if ((st_run.mot[MOTOR_2].substep_accumulator += st_run.mot[MOTOR_2].substep_increment) > 0) { - motor_2.stepStart(); // turn step bit on + motor_2.stepStart(); // turn step bit on st_run.mot[MOTOR_2].substep_accumulator -= st_run.dda_ticks_X_substeps; INCREMENT_ENCODER(MOTOR_2); } #if MOTORS > 2 if ((st_run.mot[MOTOR_3].substep_accumulator += st_run.mot[MOTOR_3].substep_increment) > 0) { - motor_3.stepStart(); // turn step bit on + motor_3.stepStart(); // turn step bit on st_run.mot[MOTOR_3].substep_accumulator -= st_run.dda_ticks_X_substeps; INCREMENT_ENCODER(MOTOR_3); } #endif #if MOTORS > 3 if ((st_run.mot[MOTOR_4].substep_accumulator += st_run.mot[MOTOR_4].substep_increment) > 0) { - motor_4.stepStart(); // turn step bit on + motor_4.stepStart(); // turn step bit on st_run.mot[MOTOR_4].substep_accumulator -= st_run.dda_ticks_X_substeps; INCREMENT_ENCODER(MOTOR_4); } #endif #if MOTORS > 4 if ((st_run.mot[MOTOR_5].substep_accumulator += st_run.mot[MOTOR_5].substep_increment) > 0) { - motor_5.stepStart(); // turn step bit on + motor_5.stepStart(); // turn step bit on st_run.mot[MOTOR_5].substep_accumulator -= st_run.dda_ticks_X_substeps; INCREMENT_ENCODER(MOTOR_5); } #endif #if MOTORS > 5 if ((st_run.mot[MOTOR_6].substep_accumulator += st_run.mot[MOTOR_6].substep_increment) > 0) { - motor_6.stepStart(); // turn step bit on + motor_6.stepStart(); // turn step bit on st_run.mot[MOTOR_6].substep_accumulator -= st_run.dda_ticks_X_substeps; INCREMENT_ENCODER(MOTOR_6); } @@ -499,7 +499,7 @@ static void _load_move() } else { // Motor has 0 steps; might need to energize motor for power mode processing motor_1.motionStopped(); - } + } // accumulate counted steps to the step position and zero out counted steps for the segment currently being loaded ACCUMULATE_ENCODER(MOTOR_1); @@ -608,6 +608,9 @@ static void _load_move() mp_runtime_command(st_pre.bf); } // else null - WARNING - We cannot printf from here!! Causes crashes. + else { + _debug_trap("_load_move called when it's not needed?"); + } // all other cases drop to here (e.g. Null moves after Mcodes skip to here) st_pre.block_type = BLOCK_TYPE_NULL; From d3c3d1d5cc273eea8e2e79ae9b3088256e460e12 Mon Sep 17 00:00:00 2001 From: Rob Giseburt Date: Wed, 28 Sep 2016 11:08:15 -0500 Subject: [PATCH 08/98] update Motate for sam Syscall/Timer/USB fixes --- Motate | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Motate b/Motate index 84f1a21c..3f8186e2 160000 --- a/Motate +++ b/Motate @@ -1 +1 @@ -Subproject commit 84f1a21c14a0e1d1b780c746afc6d19a850f867f +Subproject commit 3f8186e26b3ddde1815a36c810ae94833a84da66 From f8f29baf87ca8fc8beaace7923cc9cf6d8484092 Mon Sep 17 00:00:00 2001 From: Rob Giseburt Date: Wed, 28 Sep 2016 11:14:10 -0500 Subject: [PATCH 09/98] adjusted WaterColorBot default SR. --- g2core/settings/settings_watercolorbot_v2.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/g2core/settings/settings_watercolorbot_v2.h b/g2core/settings/settings_watercolorbot_v2.h index 35aa99fe..4d57e084 100755 --- a/g2core/settings/settings_watercolorbot_v2.h +++ b/g2core/settings/settings_watercolorbot_v2.h @@ -63,7 +63,7 @@ #define STATUS_REPORT_INTERVAL_MS 250 // milliseconds - set $SV=0 to disable //#define STATUS_REPORT_DEFAULTS "line","posx","posy","posz","posa","bcr","feed","vel","unit","coor","dist","admo","frmo","momo","stat" -#define STATUS_REPORT_DEFAULTS "line","posx","posy","posz","bcr","feed","vel","momo","stat" +#define STATUS_REPORT_DEFAULTS "line","posx","posy","posz","feed","vel","momo","stat" // Alternate SRs //#define STATUS_REPORT_DEFAULTS "line","vel","mpox","mpoy","mpoz","mpoa","coor","ofsa","ofsx","ofsy","ofsz","dist","unit","stat","homz","homy","homx","momo" From e4b423c2cddcdda4e538335d0a5c6f725b8db1af Mon Sep 17 00:00:00 2001 From: Rob Giseburt Date: Wed, 28 Sep 2016 11:50:47 -0500 Subject: [PATCH 10/98] Update Motate reference for sam3x USB fix. --- Motate | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Motate b/Motate index 3f8186e2..b6d1c837 160000 --- a/Motate +++ b/Motate @@ -1 +1 @@ -Subproject commit 3f8186e26b3ddde1815a36c810ae94833a84da66 +Subproject commit b6d1c8373b4c2cdd148aaca2def515adffa8336b From 5052b87361b6254d34f1dfc6c5d279d54c58695a Mon Sep 17 00:00:00 2001 From: Rob Giseburt Date: Wed, 28 Sep 2016 16:00:25 -0500 Subject: [PATCH 11/98] Added step_dir_hobbyservo control and wired the gQuadratic up to it. --- g2core/board/gquadratic.mk | 2 +- g2core/board/gquadratic/board_stepper.cpp | 13 +- g2core/board/gquadratic/board_stepper.h | 23 +-- g2core/board/gquadratic/gquadratic-b-pinout.h | 2 +- g2core/board/gquadratic/hardware.h | 2 +- .../board/gquadratic/motate_pin_assignments.h | 6 +- .../step_dir_hobbyservo/step_dir_hobbyservo.h | 153 ++++++++++++++++++ g2core/settings/settings_watercolorbot_v2.h | 28 ++-- 8 files changed, 184 insertions(+), 45 deletions(-) create mode 100644 g2core/device/step_dir_hobbyservo/step_dir_hobbyservo.h diff --git a/g2core/board/gquadratic.mk b/g2core/board/gquadratic.mk index 91010b7c..4fac6247 100755 --- a/g2core/board/gquadratic.mk +++ b/g2core/board/gquadratic.mk @@ -34,7 +34,7 @@ ifeq ("$(BASE_BOARD)","gquadratic") CHIP_LOWERCASE = sams70n19 BOARD_PATH = ./board/gquadratic - SOURCE_DIRS += ${BOARD_PATH} device/step_dir_driver + SOURCE_DIRS += ${BOARD_PATH} device/step_dir_driver device/step_dir_hobbyservo PLATFORM_BASE = ${MOTATE_PATH}/platform/atmel_sam include $(PLATFORM_BASE).mk diff --git a/g2core/board/gquadratic/board_stepper.cpp b/g2core/board/gquadratic/board_stepper.cpp index 183d946c..bc927558 100755 --- a/g2core/board/gquadratic/board_stepper.cpp +++ b/g2core/board/gquadratic/board_stepper.cpp @@ -47,15 +47,8 @@ StepDirStepper motor_2{}; -// StepDirStepper< -// Motate::kSocket3_StepPinNumber, -// Motate::kSocket3_DirPinNumber, -// Motate::kSocket3_EnablePinNumber, -// Motate::kSocket3_Microstep_0PinNumber, -// Motate::kSocket3_Microstep_1PinNumber, -// Motate::kSocket3_Microstep_2PinNumber, -// Motate::kSocket3_VrefPinNumber> motor_3 {}; -// +StepDirHobbyServo motor_3; + // StepDirStepper< // Motate::kSocket4_StepPinNumber, // Motate::kSocket4_DirPinNumber, @@ -83,7 +76,7 @@ StepDirStepper motor_6 {}; -Stepper* Motors[MOTORS] = {&motor_1, &motor_2}; +Stepper* Motors[MOTORS] = {&motor_1, &motor_2, &motor_3}; void board_stepper_init() { for (uint8_t motor = 0; motor < MOTORS; motor++) { Motors[motor]->init(); } diff --git a/g2core/board/gquadratic/board_stepper.h b/g2core/board/gquadratic/board_stepper.h index 1282ff0e..6e044efa 100755 --- a/g2core/board/gquadratic/board_stepper.h +++ b/g2core/board/gquadratic/board_stepper.h @@ -30,6 +30,7 @@ #include "hardware.h" // for MOTORS #include "step_dir_driver.h" +#include "step_dir_hobbyservo.h" extern StepDirStepper motor_2; -// extern StepDirStepper< -// Motate::kSocket3_StepPinNumber, -// Motate::kSocket3_DirPinNumber, -// Motate::kSocket3_EnablePinNumber, -// Motate::kSocket3_Microstep_0PinNumber, -// Motate::kSocket3_Microstep_1PinNumber, -// Motate::kSocket3_Microstep_2PinNumber, -// Motate::kSocket3_VrefPinNumber> motor_3; -// -// extern StepDirStepper< -// Motate::kSocket4_StepPinNumber, -// Motate::kSocket4_DirPinNumber, -// Motate::kSocket4_EnablePinNumber, -// Motate::kSocket4_Microstep_0PinNumber, -// Motate::kSocket4_Microstep_1PinNumber, -// Motate::kSocket4_Microstep_2PinNumber, -// Motate::kSocket4_VrefPinNumber> motor_4; -// + extern StepDirHobbyServo motor_3; + // extern StepDirStepper< // Motate::kSocket5_StepPinNumber, // Motate::kSocket5_DirPinNumber, @@ -89,4 +74,4 @@ extern Stepper* Motors[MOTORS]; void board_stepper_init(); -#endif // BOARD_STEPPER_H_ONCE \ No newline at end of file +#endif // BOARD_STEPPER_H_ONCE diff --git a/g2core/board/gquadratic/gquadratic-b-pinout.h b/g2core/board/gquadratic/gquadratic-b-pinout.h index c4650921..220c7ffd 100755 --- a/g2core/board/gquadratic/gquadratic-b-pinout.h +++ b/g2core/board/gquadratic/gquadratic-b-pinout.h @@ -147,7 +147,7 @@ _MAKE_MOTATE_PIN(kUnassigned18, 'A', 26); // _MAKE_MOTATE_PIN(kSocket1_VrefPinNumber, 'A', 27); // TC2.1 _MAKE_MOTATE_PIN(kSerial_CTS, 'A', 28); // _MAKE_MOTATE_PIN(kUnassigned19, 'A', 29); // Missing in 100-pin package -_MAKE_MOTATE_PIN(kOutput1_PinNumber, 'A', 30); // PWM2 +_MAKE_MOTATE_PIN(kServo1_PinNumber, 'A', 30); // PWM2 _MAKE_MOTATE_PIN(kInput4_PinNumber, 'A', 31); // _MAKE_MOTATE_PIN(kUnassigned20, 'B', 0); // diff --git a/g2core/board/gquadratic/hardware.h b/g2core/board/gquadratic/hardware.h index 1c467915..3b4fc7bc 100755 --- a/g2core/board/gquadratic/hardware.h +++ b/g2core/board/gquadratic/hardware.h @@ -58,7 +58,7 @@ enum hwPlatform { #define AXES 6 // number of axes supported in this version #define HOMING_AXES 4 // number of axes that can be homed (assumes Zxyabc sequence) -#define MOTORS 2 // number of motors on the board +#define MOTORS 3 // number of motors on the board #define COORDS 6 // number of supported coordinate systems (1-6) #define PWMS 2 // number of supported PWM channels diff --git a/g2core/board/gquadratic/motate_pin_assignments.h b/g2core/board/gquadratic/motate_pin_assignments.h index 78050357..c715b3bf 100755 --- a/g2core/board/gquadratic/motate_pin_assignments.h +++ b/g2core/board/gquadratic/motate_pin_assignments.h @@ -215,8 +215,12 @@ pin_number kADC14_PinNumber = 164; // Not physically pinned out pin_number kExternalClock1_PinNumber = 170; // External pins for exporting a clock signal (for Trinamics) +pin_number kServo1_PinNumber = 171; // +pin_number kServo2_PinNumber = 172; // +pin_number kServo3_PinNumber = 173; // -// start next sequence at 171 + +// start next sequence at 174 // blank spots for unassigned pins - all unassigned pins need a unique number (do not re-use numbers) diff --git a/g2core/device/step_dir_hobbyservo/step_dir_hobbyservo.h b/g2core/device/step_dir_hobbyservo/step_dir_hobbyservo.h new file mode 100644 index 00000000..735cf424 --- /dev/null +++ b/g2core/device/step_dir_hobbyservo/step_dir_hobbyservo.h @@ -0,0 +1,153 @@ +/* + * step_dir_hobbyservo.cpp - control over a hobby servo (PWM-driven) using steper Step/Direction/Enable from software + * This file is part of G2 project + * + * Copyright (c) 2016 Alden S. Hart, Jr. + * Copyright (c) 2016 Robert Giseburt + * + * This file ("the software") is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2 as published by the + * Free Software Foundation. You should have received a copy of the GNU General Public + * License, version 2 along with the software. If not, see . + * + * As a special exception, you may use this file as part of a software library without + * restriction. Specifically, if other files instantiate templates or use macros or + * inline functions from this file, or you compile this file and link it with other + * files to produce an executable, this file does not by itself cause the resulting + * executable to be covered by the GNU General Public License. This exception does not + * however invalidate any other reasons why the executable file might be covered by the + * GNU General Public License. + * + * THE SOFTWARE IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT WITHOUT ANY + * WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT + * SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +#ifndef STEPP_DIR_HOBBYSERVO_H_ONCE +#define STEPP_DIR_HOBBYSERVO_H_ONCE + +#include "MotatePins.h" +#include "MotateTimers.h" + +#include "stepper.h" + +using Motate::pin_number; +using Motate::OutputPin; +using Motate::PWMOutputPin; +using Motate::kStartHigh; +using Motate::kNormal; +using Motate::Timeout; + + +// Motor structures +template // Setup a stepper template to hold our pins +struct StepDirHobbyServo : Stepper { + /* stepper pin assignments */ + + int16_t _microsteps_per_step = 1; + bool _step_is_forward = false; + int32_t _position = 0; // in steps from 0 - 6400 for a full "rotation" + int32_t _position_computed = 0; // in steps from 0 - 6400 for a full "rotation" + float _min_value; + float _max_value; + float _value_range; + bool _enabled = false; + PWMOutputPin _pwm_pin; + Motate::Timeout check_timer; + + // sets default pwm freq for all motor vrefs (commented line below also sets HiZ) + StepDirHobbyServo(const uint32_t frequency = 50) : Stepper{}, _pwm_pin{kNormal, frequency} { + _pwm_pin.setFrequency(frequency); // redundant due to a bug + uint16_t _top_value = _pwm_pin.getTopValue(); + float frequency_inv = 1.0/(float)frequency; + _min_value = (float)_top_value / ((frequency_inv)/(750.0/1000000.0)); + _max_value = (float)_top_value / ((frequency_inv)/(2000.0/1000000.0)); + _value_range = _max_value - _min_value; + _position_computed = _min_value; + check_timer.set(1); + }; + + /* Optional override of init */ + + /* Functions that must be implemented in subclasses */ + + bool canStep() override { return true; }; + + void setMicrosteps(const uint8_t microsteps) override { + switch (microsteps) { + case (1): { + _microsteps_per_step = 32; + break; + } + case (2): { + _microsteps_per_step = 16; + break; + } + case (4): { + _microsteps_per_step = 8; + break; + } + case (8): { + _microsteps_per_step = 4; + break; + } + case (16): { + _microsteps_per_step = 2; + break; + } + case (32): { + _microsteps_per_step = 1; + break; + } + } + }; + + void _enableImpl() override { + _enabled = true; + _pwm_pin.setExactDutyCycle(_position_computed, true); + }; + + void _disableImpl() override { + _enabled = false; + _pwm_pin.setExactDutyCycle(0, true); + }; + + void stepStart() override { + if (!_enabled) return; + + if (_step_is_forward) { + _position += _microsteps_per_step; + } else { + _position -= _microsteps_per_step; + } + + if (!check_timer.isPast()) { return; } + check_timer.set(10); + + float used_position = _position; + if (used_position > 6400.0) { + used_position = 6400.0; + } + if (used_position < 0.0) { + used_position = 0.0; + } + + _position_computed = _min_value + ((used_position/6400.0) * _value_range); + _pwm_pin.setExactDutyCycle(_position_computed, true); // apply the change + }; + + void stepEnd() override { + }; + + void setDirection(uint8_t new_direction) override { + _step_is_forward = new_direction; + }; + + void setPowerLevel(float new_pl) override { + ; // ignore this + }; +}; + +#endif // STEPP_DIR_HOBBYSERVO_H_ONCE diff --git a/g2core/settings/settings_watercolorbot_v2.h b/g2core/settings/settings_watercolorbot_v2.h index 4d57e084..7b88be6d 100755 --- a/g2core/settings/settings_watercolorbot_v2.h +++ b/g2core/settings/settings_watercolorbot_v2.h @@ -93,30 +93,34 @@ #define M1_MOTOR_MAP AXIS_Y // 1ma #define M1_STEP_ANGLE 1.8 // 1sa #define M1_TRAVEL_PER_REV 91.5 // 1tr -#define M1_MICROSTEPS 8 // 1mi 1,2,4,8 -#define M1_POLARITY 0 // 1po 0=normal, 1=reversed +#define M1_MICROSTEPS 32 // 1mi 1,2,4,8 +#define M1_POLARITY 1 // 1po 0=normal, 1=reversed #define M1_POWER_MODE MOTOR_POWER_MODE // 1pm standard #define M1_POWER_LEVEL 0.4 #define M2_MOTOR_MAP AXIS_X #define M2_STEP_ANGLE 1.8 #define M2_TRAVEL_PER_REV 91.5 -#define M2_MICROSTEPS 8 +#define M2_MICROSTEPS 32 #define M2_POLARITY 0 #define M2_POWER_MODE MOTOR_POWER_MODE #define M2_POWER_LEVEL 0.4 #define M3_MOTOR_MAP AXIS_Z -#define M3_STEP_ANGLE 1.8 -#define M3_TRAVEL_PER_REV 2.1166666 -#define M3_MICROSTEPS 8 + // This "stepper" is a hobby servo. Note that all hobby + // servo settings are per full servo range, instead of + // per revolution. +#define M3_STEP_ANGLE 1.8 // hobby servos are simulated with 200 "full steps" +#define M3_TRAVEL_PER_REV 26 // this is actually the full travel of the servo, not + // necessarily covering a revolution +#define M3_MICROSTEPS 32 // the max step resolution for a hobby servo is 1/32 #define M3_POLARITY 1 -#define M3_POWER_MODE MOTOR_POWER_MODE -#define M3_POWER_LEVEL 0.50 +#define M3_POWER_MODE MOTOR_ALWAYS_POWERED +#define M3_POWER_LEVEL 0.50 // this is ignored #define M4_MOTOR_MAP AXIS_A #define M4_STEP_ANGLE 1.8 -#define M4_TRAVEL_PER_REV 360 // degrees moved per motor rev +#define M4_TRAVEL_PER_REV 360 // degrees moved per motor rev #define M4_MICROSTEPS 32 #define M4_POLARITY 0 #define M4_POWER_MODE MOTOR_POWER_MODE @@ -124,7 +128,7 @@ // *** axis settings ********************************************************************************** -#define JERK_MAX 30000 +#define JERK_MAX 20000 #define X_AXIS_MODE AXIS_STANDARD // xam see canonical_machine.h cmAxisMode for valid values #define X_VELOCITY_MAX 50000 // xvm G0 max velocity in mm/min @@ -155,11 +159,11 @@ #define Y_ZERO_BACKOFF 2 #define Z_AXIS_MODE AXIS_STANDARD -#define Z_VELOCITY_MAX 1000 +#define Z_VELOCITY_MAX 15000 #define Z_FEEDRATE_MAX Z_VELOCITY_MAX #define Z_TRAVEL_MIN 0 #define Z_TRAVEL_MAX 75 -#define Z_JERK_MAX JERK_MAX +#define Z_JERK_MAX 10000 #define Z_JERK_HIGH_SPEED Z_JERK_MAX #define Z_HOMING_INPUT 6 #define Z_HOMING_DIRECTION 1 From d905ef088b8c12338e850126f8b4daf69708b98f Mon Sep 17 00:00:00 2001 From: Rob Giseburt Date: Thu, 29 Sep 2016 12:49:10 -0500 Subject: [PATCH 12/98] Adjust settings of watercolorbot --- g2core/settings/settings_watercolorbot_v2.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/g2core/settings/settings_watercolorbot_v2.h b/g2core/settings/settings_watercolorbot_v2.h index 7b88be6d..2eb170a9 100755 --- a/g2core/settings/settings_watercolorbot_v2.h +++ b/g2core/settings/settings_watercolorbot_v2.h @@ -163,7 +163,7 @@ #define Z_FEEDRATE_MAX Z_VELOCITY_MAX #define Z_TRAVEL_MIN 0 #define Z_TRAVEL_MAX 75 -#define Z_JERK_MAX 10000 +#define Z_JERK_MAX 5000 #define Z_JERK_HIGH_SPEED Z_JERK_MAX #define Z_HOMING_INPUT 6 #define Z_HOMING_DIRECTION 1 From efd9754552c6ffa34741c5f5dfde151e9534ea2d Mon Sep 17 00:00:00 2001 From: Rob Giseburt Date: Mon, 10 Oct 2016 14:24:19 -0500 Subject: [PATCH 13/98] Added eggbot settings and some neopixel fun to the gquadratic --- g2core/board/gquadratic.mk | 2 +- g2core/board/gquadratic/hardware.cpp | 70 ++++- g2core/boards.mk | 7 + g2core/device/neopixel/neopixel.h | 71 +++-- g2core/g2core.xcodeproj/project.pbxproj | 42 +++ g2core/settings/settings_eggbot.h | 401 ++++++++++++++++++++++++ 6 files changed, 565 insertions(+), 28 deletions(-) create mode 100755 g2core/settings/settings_eggbot.h diff --git a/g2core/board/gquadratic.mk b/g2core/board/gquadratic.mk index 4fac6247..9527cdc1 100755 --- a/g2core/board/gquadratic.mk +++ b/g2core/board/gquadratic.mk @@ -34,7 +34,7 @@ ifeq ("$(BASE_BOARD)","gquadratic") CHIP_LOWERCASE = sams70n19 BOARD_PATH = ./board/gquadratic - SOURCE_DIRS += ${BOARD_PATH} device/step_dir_driver device/step_dir_hobbyservo + SOURCE_DIRS += ${BOARD_PATH} device/step_dir_driver device/step_dir_hobbyservo device/neopixel PLATFORM_BASE = ${MOTATE_PATH}/platform/atmel_sam include $(PLATFORM_BASE).mk diff --git a/g2core/board/gquadratic/hardware.cpp b/g2core/board/gquadratic/hardware.cpp index e11d595c..f40a7928 100755 --- a/g2core/board/gquadratic/hardware.cpp +++ b/g2core/board/gquadratic/hardware.cpp @@ -37,7 +37,37 @@ #include "MotatePower.h" //Motate::ClockOutputPin external_clk_pin {16000000}; // 16MHz optimally -Motate::OutputPin external_clk_pin {Motate::kStartLow}; +//Motate::OutputPin external_clk_pin {Motate::kStartLow}; + +#include "neopixel.h" +#include "canonical_machine.h" + +namespace LEDs { + NeoPixel rgbw_leds {NeoPixelOrder::GRB}; + + RGB_Color_t display_color[15] { + {0, 0, 0, 5}, + {0, 0, 0, 5}, + {0, 0, 0, 5}, + {0, 0, 0, 5}, + {0, 0, 0, 5}, + {0, 0, 0, 5}, + {0, 0, 0, 5}, + {0, 0, 0, 5}, + {0, 0, 0, 5}, + {0, 0, 0, 5}, + {0, 0, 0, 5}, + {0, 0, 0, 5}, + {0, 0, 0, 5}, + {0, 0, 0, 5}, + {0, 0, 0, 5}, + }; + + bool alarm_red = false; // if we are in alarm, the tells us if we're going to red (pulsing) + bool shutdown_white = false; // if we are in shutdown, the tells us if we're going to red (pulsing) + cmMachineState last_see_machine_state; + float old_x_pos = 0.0; +} /* * hardware_init() - lowest level hardware init @@ -46,7 +76,13 @@ Motate::OutputPin external_clk_pin {Motate::k void hardware_init() { board_hardware_init(); - external_clk_pin = 0; // Force external clock to 0 for now. +// external_clk_pin = 0; // Force external clock to 0 for now. + + for (uint8_t pixel = 0; pixel < LEDs::rgbw_leds.count; pixel++) { + LEDs::display_color[pixel].startTransition(100, 0, 0, 0); + LEDs::rgbw_leds.setPixel(pixel, LEDs::display_color[pixel]); + } + LEDs::rgbw_leds.update(); } /* @@ -55,6 +91,36 @@ void hardware_init() stat_t hardware_periodic() { + float x_pos = cm_get_work_position(ACTIVE_MODEL, AXIS_X); + if (fabs(LEDs::old_x_pos - x_pos) > 0.01) { + LEDs::old_x_pos = x_pos; + + float led_pos = x_pos * ((float)(LEDs::rgbw_leds.count-1) / 40); + + for (uint8_t pixel = 0; pixel < LEDs::rgbw_leds.count; pixel++) { + float value = fabs(led_pos - (float)pixel); + if (value < 1.001) { + value = 1.0 - value; + if (LEDs::display_color[pixel].red < value) { + LEDs::display_color[pixel].startTransition(10, value, value, value); + } else { + LEDs::display_color[pixel].startTransition(500, 0, 0, 0); + } + } else { +// LEDs::display_color[pixel].startTransition(500, 0, 0, 0); + } +// LEDs::display_color[pixel].startTransition(100, std::max(0.0f, std::min(40.0f, (float)(x_pos/40.0) )), 0, 0); + } + } + + for (uint8_t pixel = 0; pixel < LEDs::rgbw_leds.count; pixel++) { + if (LEDs::display_color[pixel].update()) { + LEDs::rgbw_leds.setPixel(pixel, LEDs::display_color[pixel]); + } + } + + LEDs::rgbw_leds.update(); + return STAT_OK; } diff --git a/g2core/boards.mk b/g2core/boards.mk index 2dc4380c..1f314564 100644 --- a/g2core/boards.mk +++ b/g2core/boards.mk @@ -147,6 +147,13 @@ ifeq ("$(CONFIG)","WaterColorBotv2") SETTINGS_FILE="settings_watercolorbot_v2.h" endif +ifeq ("$(CONFIG)","EggBot") + ifeq ("$(BOARD)","NONE") + BOARD=gquadratic-b + endif + SETTINGS_FILE="settings_eggbot.h" +endif + include $(wildcard ./board/$(STAR).mk) diff --git a/g2core/device/neopixel/neopixel.h b/g2core/device/neopixel/neopixel.h index b57f5135..4c69f8dc 100755 --- a/g2core/device/neopixel/neopixel.h +++ b/g2core/device/neopixel/neopixel.h @@ -215,6 +215,12 @@ struct RGB_Color_t : NeopixelColorTag { float green; float blue; + enum ColorFilter { + Set = 0, + Lighten, + Darken + }; + const uint32_t _update_timeout_ms; Motate::Timeout _update_timeout; @@ -233,7 +239,18 @@ struct RGB_Color_t : NeopixelColorTag { _update_timeout.set(0); }; - void startTransition(uint32_t milliseconds, float to_red, float to_green, float to_blue) { + void startTransition(uint32_t milliseconds, float to_red, float to_green, float to_blue, ColorFilter cf = Set) { + if (cf == Lighten) { + to_red = std::max(to_red, red); + to_green = std::max(to_green, green); + to_blue = std::max(to_blue, blue); + } + else if (cf == Darken) { + to_red = std::min(to_red, red); + to_green = std::min(to_green, green); + to_blue = std::min(to_blue, blue); + } + _transition_steps_left = 0.5 + (milliseconds / _update_timeout_ms); float h = 1.0 / _transition_steps_left; float h_2 = h * h; @@ -418,6 +435,10 @@ struct NeoPixel { }; void setPixel(uint8_t pixel, uint8_t red, uint8_t green, uint8_t blue, int16_t white = -1) { + uint8_t data_width = 32; + if (!_has_white) { + data_width = 24; + } if (_has_white && (white == -1)) { // Adjust all of the RGB to accomodate white white = std::min(red, std::min(green, blue)); @@ -425,32 +446,32 @@ struct NeoPixel { // green -= white; // blue -= white; } - _period_buffer[0 + 1 + _red_offset + (pixel * 32)] = (red & 0b10000000) ? led_ON : led_OFF; - _period_buffer[1 + 1 + _red_offset + (pixel * 32)] = (red & 0b01000000) ? led_ON : led_OFF; - _period_buffer[2 + 1 + _red_offset + (pixel * 32)] = (red & 0b00100000) ? led_ON : led_OFF; - _period_buffer[3 + 1 + _red_offset + (pixel * 32)] = (red & 0b00010000) ? led_ON : led_OFF; - _period_buffer[4 + 1 + _red_offset + (pixel * 32)] = (red & 0b00001000) ? led_ON : led_OFF; - _period_buffer[5 + 1 + _red_offset + (pixel * 32)] = (red & 0b00000100) ? led_ON : led_OFF; - _period_buffer[6 + 1 + _red_offset + (pixel * 32)] = (red & 0b00000010) ? led_ON : led_OFF; - _period_buffer[7 + 1 + _red_offset + (pixel * 32)] = (red & 0b00000001) ? led_ON : led_OFF; + _period_buffer[0 + 1 + _red_offset + (pixel * data_width)] = (red & 0b10000000) ? led_ON : led_OFF; + _period_buffer[1 + 1 + _red_offset + (pixel * data_width)] = (red & 0b01000000) ? led_ON : led_OFF; + _period_buffer[2 + 1 + _red_offset + (pixel * data_width)] = (red & 0b00100000) ? led_ON : led_OFF; + _period_buffer[3 + 1 + _red_offset + (pixel * data_width)] = (red & 0b00010000) ? led_ON : led_OFF; + _period_buffer[4 + 1 + _red_offset + (pixel * data_width)] = (red & 0b00001000) ? led_ON : led_OFF; + _period_buffer[5 + 1 + _red_offset + (pixel * data_width)] = (red & 0b00000100) ? led_ON : led_OFF; + _period_buffer[6 + 1 + _red_offset + (pixel * data_width)] = (red & 0b00000010) ? led_ON : led_OFF; + _period_buffer[7 + 1 + _red_offset + (pixel * data_width)] = (red & 0b00000001) ? led_ON : led_OFF; - _period_buffer[0 + 1 + _green_offset + (pixel * 32)] = (green & 0b10000000) ? led_ON : led_OFF; - _period_buffer[1 + 1 + _green_offset + (pixel * 32)] = (green & 0b01000000) ? led_ON : led_OFF; - _period_buffer[2 + 1 + _green_offset + (pixel * 32)] = (green & 0b00100000) ? led_ON : led_OFF; - _period_buffer[3 + 1 + _green_offset + (pixel * 32)] = (green & 0b00010000) ? led_ON : led_OFF; - _period_buffer[4 + 1 + _green_offset + (pixel * 32)] = (green & 0b00001000) ? led_ON : led_OFF; - _period_buffer[5 + 1 + _green_offset + (pixel * 32)] = (green & 0b00000100) ? led_ON : led_OFF; - _period_buffer[6 + 1 + _green_offset + (pixel * 32)] = (green & 0b00000010) ? led_ON : led_OFF; - _period_buffer[7 + 1 + _green_offset + (pixel * 32)] = (green & 0b00000001) ? led_ON : led_OFF; + _period_buffer[0 + 1 + _green_offset + (pixel * data_width)] = (green & 0b10000000) ? led_ON : led_OFF; + _period_buffer[1 + 1 + _green_offset + (pixel * data_width)] = (green & 0b01000000) ? led_ON : led_OFF; + _period_buffer[2 + 1 + _green_offset + (pixel * data_width)] = (green & 0b00100000) ? led_ON : led_OFF; + _period_buffer[3 + 1 + _green_offset + (pixel * data_width)] = (green & 0b00010000) ? led_ON : led_OFF; + _period_buffer[4 + 1 + _green_offset + (pixel * data_width)] = (green & 0b00001000) ? led_ON : led_OFF; + _period_buffer[5 + 1 + _green_offset + (pixel * data_width)] = (green & 0b00000100) ? led_ON : led_OFF; + _period_buffer[6 + 1 + _green_offset + (pixel * data_width)] = (green & 0b00000010) ? led_ON : led_OFF; + _period_buffer[7 + 1 + _green_offset + (pixel * data_width)] = (green & 0b00000001) ? led_ON : led_OFF; - _period_buffer[0 + 1 + _blue_offset + (pixel * 32)] = (blue & 0b10000000) ? led_ON : led_OFF; - _period_buffer[1 + 1 + _blue_offset + (pixel * 32)] = (blue & 0b01000000) ? led_ON : led_OFF; - _period_buffer[2 + 1 + _blue_offset + (pixel * 32)] = (blue & 0b00100000) ? led_ON : led_OFF; - _period_buffer[3 + 1 + _blue_offset + (pixel * 32)] = (blue & 0b00010000) ? led_ON : led_OFF; - _period_buffer[4 + 1 + _blue_offset + (pixel * 32)] = (blue & 0b00001000) ? led_ON : led_OFF; - _period_buffer[5 + 1 + _blue_offset + (pixel * 32)] = (blue & 0b00000100) ? led_ON : led_OFF; - _period_buffer[6 + 1 + _blue_offset + (pixel * 32)] = (blue & 0b00000010) ? led_ON : led_OFF; - _period_buffer[7 + 1 + _blue_offset + (pixel * 32)] = (blue & 0b00000001) ? led_ON : led_OFF; + _period_buffer[0 + 1 + _blue_offset + (pixel * data_width)] = (blue & 0b10000000) ? led_ON : led_OFF; + _period_buffer[1 + 1 + _blue_offset + (pixel * data_width)] = (blue & 0b01000000) ? led_ON : led_OFF; + _period_buffer[2 + 1 + _blue_offset + (pixel * data_width)] = (blue & 0b00100000) ? led_ON : led_OFF; + _period_buffer[3 + 1 + _blue_offset + (pixel * data_width)] = (blue & 0b00010000) ? led_ON : led_OFF; + _period_buffer[4 + 1 + _blue_offset + (pixel * data_width)] = (blue & 0b00001000) ? led_ON : led_OFF; + _period_buffer[5 + 1 + _blue_offset + (pixel * data_width)] = (blue & 0b00000100) ? led_ON : led_OFF; + _period_buffer[6 + 1 + _blue_offset + (pixel * data_width)] = (blue & 0b00000010) ? led_ON : led_OFF; + _period_buffer[7 + 1 + _blue_offset + (pixel * data_width)] = (blue & 0b00000001) ? led_ON : led_OFF; if (_has_white) { _period_buffer[0 + 1 + _white_offset + (pixel * 32)] = (white & 0b10000000) ? led_ON : led_OFF; diff --git a/g2core/g2core.xcodeproj/project.pbxproj b/g2core/g2core.xcodeproj/project.pbxproj index bc741a0f..573a6b25 100644 --- a/g2core/g2core.xcodeproj/project.pbxproj +++ b/g2core/g2core.xcodeproj/project.pbxproj @@ -59,6 +59,7 @@ D4522DC91C45F41D0086AAE6 /* g2core_info.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = g2core_info.h; sourceTree = ""; }; D457117B17053EFA00EA19A8 /* Makefile */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = Makefile; sourceTree = ""; usesTabs = 1; xcLanguageSpecificationIdentifier = xcode.lang.sh; }; D4782AB21D9B5F9400B32136 /* settings_watercolorbot_v2.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = settings_watercolorbot_v2.h; sourceTree = ""; }; + D4782AB41D9E2FF300B32136 /* settings_eggbot.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = settings_eggbot.h; sourceTree = ""; }; D47B744C1D4925B4004FAB53 /* device */ = {isa = PBXFileReference; lastKnownFileType = folder; path = device; sourceTree = ""; }; D48F5A40172CB1F900D0E055 /* canonical_machine.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = canonical_machine.cpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; D48F5A41172CB1F900D0E055 /* config_app.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = config_app.cpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; @@ -147,6 +148,7 @@ isa = PBXGroup; children = ( D4AC39081C77C1F20098D685 /* settings_default.h */, + D4782AB41D9E2FF300B32136 /* settings_eggbot.h */, D4782AB21D9B5F9400B32136 /* settings_watercolorbot_v2.h */, D4AC39091C77C1F20098D685 /* settings_makeblock.h */, D4AC390A1C77C1F20098D685 /* settings_othermill_test.h */, @@ -307,6 +309,20 @@ passBuildSettingsInEnvironment = 1; productName = g3_due; }; + D4782AB61D9E39EC00B32136 /* G2 EggBot */ = { + isa = PBXLegacyTarget; + buildArgumentsString = "$(ACTION) VERBOSE=1 COLOR=0 CONFIG=EggBot DEBUG=1"; + buildConfigurationList = D4782AB71D9E39EC00B32136 /* Build configuration list for PBXLegacyTarget "G2 EggBot" */; + buildPhases = ( + ); + buildToolPath = /usr/bin/make; + buildWorkingDirectory = .; + dependencies = ( + ); + name = "G2 EggBot"; + passBuildSettingsInEnvironment = 1; + productName = g3_due; + }; D4AC391A1C7BAB8E0098D685 /* G2 sbv300 */ = { isa = PBXLegacyTarget; buildArgumentsString = "$(ACTION) VERBOSE=1 COLOR=0 CONFIG=sbv300 DEBUG=2"; @@ -429,6 +445,7 @@ D43FF7141D537A5C00FB5B53 /* G2 gQuadratic Test */, D4782AAE1D9B16BE00B32136 /* G2 Probotix */, D457112317053BFB00EA19A8 /* index */, + D4782AB61D9E39EC00B32136 /* G2 EggBot */, ); }; /* End PBXProject section */ @@ -686,6 +703,22 @@ }; name = Release; }; + D4782AB81D9E39EC00B32136 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + PATH = "$PATH:/usr/local/gcc-arm-none-eabi/bin"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + D4782AB91D9E39EC00B32136 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + PATH = "$PATH:/usr/local/gcc-arm-none-eabi/bin"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; D4AC391C1C7BAB8E0098D685 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -832,6 +865,15 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + D4782AB71D9E39EC00B32136 /* Build configuration list for PBXLegacyTarget "G2 EggBot" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + D4782AB81D9E39EC00B32136 /* Debug */, + D4782AB91D9E39EC00B32136 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; D4AC391B1C7BAB8E0098D685 /* Build configuration list for PBXLegacyTarget "G2 sbv300" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/g2core/settings/settings_eggbot.h b/g2core/settings/settings_eggbot.h new file mode 100755 index 00000000..4527a339 --- /dev/null +++ b/g2core/settings/settings_eggbot.h @@ -0,0 +1,401 @@ +/* + * settings_eggbot.h - settings for the EggBot + * This file is part of the g2core project + * + * Copyright (c) 2016 Alden S. Hart Jr. + * Copyright (c) 2016 Robert Giseburt + * + * This file ("the software") is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2 as published by the + * Free Software Foundation. You should have received a copy of the GNU General Public + * License, version 2 along with the software. If not, see . + * + * As a special exception, you may use this file as part of a software library without + * restriction. Specifically, if other files instantiate templates or use macros or + * inline functions from this file, or you compile this file and link it with other + * files to produce an executable, this file does not by itself cause the resulting + * executable to be covered by the GNU General Public License. This exception does not + * however invalidate any other reasons why the executable file might be covered by the + * GNU General Public License. + * + * THE SOFTWARE IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT WITHOUT ANY + * WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT + * SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/***********************************************************************/ +/**** TestV9 profile - naked board *************************************/ +/***********************************************************************/ + +// ***> NOTE: The init message must be a single line with no CRs or LFs +#define INIT_MESSAGE "Initializing configs to WaterColorBot v2 settings" + +#define JUNCTION_INTEGRATION_TIME 1.50 // cornering - usually between 0.5 and 2.0 (higher is faster) +#define CHORDAL_TOLERANCE 0.01 // chordal accuracy for arc drawing (in mm) + +#define SOFT_LIMIT_ENABLE 0 // 0=off, 1=on +#define HARD_LIMIT_ENABLE 1 // 0=off, 1=on +#define SAFETY_INTERLOCK_ENABLE 1 // 0=off, 1=on + +#define SPINDLE_ENABLE_POLARITY 1 // 0=active low, 1=active high +#define SPINDLE_DIR_POLARITY 0 // 0=clockwise is low, 1=clockwise is high +#define SPINDLE_PAUSE_ON_HOLD true +#define SPINDLE_DWELL_TIME 1.0 + +#define COOLANT_MIST_POLARITY 1 // 0=active low, 1=active high +#define COOLANT_FLOOD_POLARITY 1 // 0=active low, 1=active high +#define COOLANT_PAUSE_ON_HOLD false + +// Communications and reporting settings + +#define COMM_MODE JSON_MODE // one of: TEXT_MODE, JSON_MODE +#define XIO_ENABLE_FLOW_CONTROL FLOW_CONTROL_RTS // FLOW_CONTROL_OFF, FLOW_CONTROL_RTS + +#define TEXT_VERBOSITY TV_VERBOSE // one of: TV_SILENT, TV_VERBOSE +#define JSON_VERBOSITY JV_MESSAGES // one of: JV_SILENT, JV_FOOTER, JV_CONFIGS, JV_MESSAGES, JV_LINENUM, JV_VERBOSE +#define QUEUE_REPORT_VERBOSITY QR_OFF // one of: QR_OFF, QR_SINGLE, QR_TRIPLE + +#define STATUS_REPORT_VERBOSITY SR_FILTERED // one of: SR_OFF, SR_FILTERED, SR_VERBOSE +#define STATUS_REPORT_MIN_MS 100 // milliseconds - enforces a viable minimum +#define STATUS_REPORT_INTERVAL_MS 250 // milliseconds - set $SV=0 to disable + +//#define STATUS_REPORT_DEFAULTS "line","posx","posy","posz","posa","bcr","feed","vel","unit","coor","dist","admo","frmo","momo","stat" +#define STATUS_REPORT_DEFAULTS "line","posx","posy","posz","feed","vel","momo","stat" + +// Alternate SRs +//#define STATUS_REPORT_DEFAULTS "line","vel","mpox","mpoy","mpoz","mpoa","coor","ofsa","ofsx","ofsy","ofsz","dist","unit","stat","homz","homy","homx","momo" +//#define STATUS_REPORT_DEFAULTS "_ts1","_cs1","_es1","_xs1","_fe1","line","posx","posy","posz","vel","stat" +//#define STATUS_REPORT_DEFAULTS "line","posx","posy","posz","vel","_cs1","_es1","_xs1","_fe1","_cs2","_es2","_xs2","_fe2" +//#define STATUS_REPORT_DEFAULTS "mpox","mpoy","mpoz","mpoa","ofsx","ofsy","ofsz","ofsa","unit","stat","coor","momo","dist","home","hold","macs","cycs","mots","plan","feed" +//#define STATUS_REPORT_DEFAULTS "line","mpox","mpoy","mpoz","mpoa","ofsx","ofsy","ofsz","ofsa","stat","_cs1","_es1","_fe0","_fe1","_fe2","_fe3" +//#define STATUS_REPORT_DEFAULTS "line","mpox","mpoy","mpoz","stat","_ts2","_ps2","_cs2","_es2","_fe2" +//#define STATUS_REPORT_DEFAULTS "line","mpox","mpoy","mpoz","_cs3","_es3","_fe3","_xs3","_cs2","_es2","_fe2","_xs2","stat" +//#define STATUS_REPORT_DEFAULTS "line","posx","posy","posz","posa","feed","vel","unit","coor","dist","frmo","momo","stat","_cs1","_es1","_xs1","_fe1" + +// Gcode startup defaults +#define GCODE_DEFAULT_UNITS MILLIMETERS // MILLIMETERS or INCHES +#define GCODE_DEFAULT_PLANE CANON_PLANE_XY // CANON_PLANE_XY, CANON_PLANE_XZ, or CANON_PLANE_YZ +#define GCODE_DEFAULT_COORD_SYSTEM G54 // G54, G55, G56, G57, G58 or G59 +#define GCODE_DEFAULT_PATH_CONTROL PATH_CONTINUOUS +#define GCODE_DEFAULT_DISTANCE_MODE ABSOLUTE_MODE + +// *** motor settings ************************************************************************************ + +#define MOTOR_POWER_MODE MOTOR_POWERED_IN_CYCLE // default motor power mode (see cmMotorPowerMode in stepper.h) +#define MOTOR_POWER_TIMEOUT 2.00 // motor power timeout in seconds + +#define MOTOR_POWER_MODE MOTOR_POWERED_IN_CYCLE // default motor power mode (see cmMotorPowerMode in stepper.h) +#define MOTOR_POWER_TIMEOUT 2.00 // motor power timeout in seconds + +#define M1_MOTOR_MAP AXIS_Y // 1ma +#define M1_STEP_ANGLE 1.8 // 1sa +#define M1_TRAVEL_PER_REV 125.66370614 // 1tr +#define M1_MICROSTEPS 32 // 1mi 1,2,4,8 +#define M1_POLARITY 1 // 1po 0=normal, 1=reversed +#define M1_POWER_MODE MOTOR_POWER_MODE // 1pm standard +#define M1_POWER_LEVEL 0.4 + +#define M2_MOTOR_MAP AXIS_X +#define M2_STEP_ANGLE 1.8 +#define M2_TRAVEL_PER_REV 125.66370614 +#define M2_MICROSTEPS 32 +#define M2_POLARITY 1 +#define M2_POWER_MODE MOTOR_POWER_MODE +#define M2_POWER_LEVEL 0.4 + +#define M3_MOTOR_MAP AXIS_Z + // This "stepper" is a hobby servo. Note that all hobby + // servo settings are per full servo range, instead of + // per revolution. +#define M3_STEP_ANGLE 1.8 // hobby servos are simulated with 200 "full steps" +#define M3_TRAVEL_PER_REV 26 // this is actually the full travel of the servo, not + // necessarily covering a revolution +#define M3_MICROSTEPS 32 // the max step resolution for a hobby servo is 1/32 +#define M3_POLARITY 1 +#define M3_POWER_MODE MOTOR_ALWAYS_POWERED +#define M3_POWER_LEVEL 0.50 // this is ignored + +#define M4_MOTOR_MAP AXIS_A +#define M4_STEP_ANGLE 1.8 +#define M4_TRAVEL_PER_REV 360 // degrees moved per motor rev +#define M4_MICROSTEPS 32 +#define M4_POLARITY 0 +#define M4_POWER_MODE MOTOR_POWER_MODE +#define M4_POWER_LEVEL 0.6 + +// *** axis settings ********************************************************************************** + +#define JERK_MAX 20000 + +#define X_AXIS_MODE AXIS_STANDARD // xam see canonical_machine.h cmAxisMode for valid values +#define X_VELOCITY_MAX 50000 // xvm G0 max velocity in mm/min +#define X_FEEDRATE_MAX X_VELOCITY_MAX // xfr G1 max feed rate in mm/min +#define X_TRAVEL_MIN 0 // xtn minimum travel - used by soft limits and homing +#define X_TRAVEL_MAX 400 // xtm maximum travel - used by soft limits and homing +#define X_JERK_MAX JERK_MAX // xjm +#define X_JERK_HIGH_SPEED X_JERK_MAX // xjh +#define X_HOMING_INPUT 1 // xhi input used for homing or 0 to disable +#define X_HOMING_DIRECTION 0 // xhd 0=search moves negative, 1= search moves positive +#define X_SEARCH_VELOCITY 1000 // xsv move in negative direction +#define X_LATCH_VELOCITY 100 // xlv mm/min +#define X_LATCH_BACKOFF 10 // xlb mm +#define X_ZERO_BACKOFF 2 // xzb mm + +#define Y_AXIS_MODE AXIS_STANDARD +#define Y_VELOCITY_MAX 50000 +#define Y_FEEDRATE_MAX Y_VELOCITY_MAX +#define Y_TRAVEL_MIN 0 +#define Y_TRAVEL_MAX 175 +#define Y_JERK_MAX JERK_MAX +#define Y_JERK_HIGH_SPEED Y_JERK_MAX +#define Y_HOMING_INPUT 3 +#define Y_HOMING_DIRECTION 0 +#define Y_SEARCH_VELOCITY 1000 +#define Y_LATCH_VELOCITY 100 +#define Y_LATCH_BACKOFF 10 +#define Y_ZERO_BACKOFF 2 + +#define Z_AXIS_MODE AXIS_STANDARD +#define Z_VELOCITY_MAX 15000 +#define Z_FEEDRATE_MAX Z_VELOCITY_MAX +#define Z_TRAVEL_MIN 0 +#define Z_TRAVEL_MAX 75 +#define Z_JERK_MAX 5000 +#define Z_JERK_HIGH_SPEED Z_JERK_MAX +#define Z_HOMING_INPUT 6 +#define Z_HOMING_DIRECTION 1 +#define Z_SEARCH_VELOCITY 600 +#define Z_LATCH_VELOCITY 100 +#define Z_LATCH_BACKOFF 10 +#define Z_ZERO_BACKOFF 2 + +// Rotary values are chosen to make the motor react the same as X for testing +/*************************************************************************************** + * To calculate the speeds here, in Wolfram Alpha-speak: + * + * c=2*pi*r, r=0.609, d=c/360, s=((S*60)/d), S=40 for s + * c=2*pi*r, r=5.30516476972984, d=c/360, s=((S*60)/d), S=40 for s + * + * Change r to A_RADIUS, and S to the desired speed, in mm/s or mm/s/s/s. + * + * It will return s= as the value you want to enter. + * + * If the value is over 1 million, the code will divide it by 1 million, + * so you have to pre-multiply it by 1000000.0. (The value is in millions, btw.) + * + * Note that you need these to be floating point values, so always have a .0 at the end! + * + ***************************************************************************************/ + +#define A_AXIS_MODE AXIS_RADIUS +#define A_RADIUS 5.30516476972984 +//#define A_VELOCITY_MAX 25920.0 // ~40 mm/s, 2,400 mm/min +//#define A_FEEDRATE_MAX 25920.0/2.0 // ~20 mm/s, 1,200 mm/min +#define A_VELOCITY_MAX 77760.0 // G0 rate ~120 mm/s, 2,400 mm/min +#define A_FEEDRATE_MAX 9720.0 // 9720.0 = G1 rate ~15 mm/s, 900 mm/min +#define A_TRAVEL_MIN 0 +#define A_TRAVEL_MAX 10 +#define A_JERK_MAX 648000 // 1,000 million mm/min^3 = 648000 + // * a million IF it's over a million + // c=2*pi*r, r=5.30516476972984, d=c/360, s=((1000*60)/d) +#define A_HOMING_INPUT 0 +#define A_HOMING_DIRECTION 0 +#define A_SEARCH_VELOCITY 2000 +#define A_LATCH_VELOCITY 2000 +#define A_LATCH_BACKOFF 5 +#define A_ZERO_BACKOFF 2 +#define A_JERK_HIGH_SPEED A_JERK_MAX + +#define B_AXIS_MODE AXIS_DISABLED +#define B_RADIUS 1 +#define B_VELOCITY_MAX 3600 +#define B_FEEDRATE_MAX B_VELOCITY_MAX +#define B_TRAVEL_MIN 0 +#define B_TRAVEL_MAX -1 +//#define B_JERK_MAX 20000000 +#define B_JERK_MAX 20 +#define B_HOMING_INPUT 0 +#define B_HOMING_DIRECTION 0 +#define B_SEARCH_VELOCITY 600 +#define B_LATCH_VELOCITY 100 +#define B_LATCH_BACKOFF 10 +#define B_ZERO_BACKOFF 2 +#define B_JERK_HIGH_SPEED A_JERK_MAX + + +//*** Input / output settings *** +/* + IO_MODE_DISABLED + IO_ACTIVE_LOW aka NORMALLY_OPEN + IO_ACTIVE_HIGH aka NORMALLY_CLOSED + + INPUT_ACTION_NONE + INPUT_ACTION_STOP + INPUT_ACTION_FAST_STOP + INPUT_ACTION_HALT + INPUT_ACTION_RESET + + INPUT_FUNCTION_NONE + INPUT_FUNCTION_LIMIT + INPUT_FUNCTION_INTERLOCK + INPUT_FUNCTION_SHUTDOWN + INPUT_FUNCTION_PANIC +*/ +// Inputs are defined for the g2ref(a) board +// Xmn (board label) +#define DI1_MODE IO_ACTIVE_HIGH +#define DI1_ACTION INPUT_ACTION_NONE +#define DI1_FUNCTION INPUT_FUNCTION_NONE + +// Xmax +#define DI2_MODE IO_MODE_DISABLED +#define DI2_ACTION INPUT_ACTION_NONE +#define DI2_FUNCTION INPUT_FUNCTION_NONE + +// Ymin +#define DI3_MODE IO_MODE_DISABLED +#define DI3_ACTION INPUT_ACTION_NONE +#define DI3_FUNCTION INPUT_FUNCTION_NONE + +// Ymax +#define DI4_MODE IO_ACTIVE_HIGH +#define DI4_ACTION INPUT_ACTION_NONE +#define DI4_FUNCTION INPUT_FUNCTION_NONE + +// Zmin +#define DI5_MODE IO_ACTIVE_LOW // Z probe +#define DI5_ACTION INPUT_ACTION_NONE +#define DI5_FUNCTION INPUT_FUNCTION_NONE + +// Zmax +#define DI6_MODE IO_MODE_DISABLED +#define DI6_ACTION INPUT_ACTION_STOP +#define DI6_FUNCTION INPUT_FUNCTION_NONE + +// Shutdown (Amin on v9 board) +#define DI7_MODE IO_MODE_DISABLED +#define DI7_ACTION INPUT_ACTION_NONE +#define DI7_FUNCTION INPUT_FUNCTION_NONE + +// High Voltage Z Probe In (Amax on v9 board) +#define DI8_MODE IO_ACTIVE_LOW +#define DI8_ACTION INPUT_ACTION_NONE +#define DI8_FUNCTION INPUT_FUNCTION_NONE + +// Hardware interlock input +#define DI9_MODE IO_MODE_DISABLED +#define DI9_ACTION INPUT_ACTION_NONE +#define DI9_FUNCTION INPUT_FUNCTION_NONE + +//Extruder1_PWM +#define DO1_MODE IO_ACTIVE_HIGH + +//Extruder2_PWM +#define DO2_MODE IO_ACTIVE_HIGH + +//Fan1A_PWM +#define DO3_MODE IO_ACTIVE_HIGH + +//Fan1B_PWM +#define DO4_MODE IO_ACTIVE_HIGH + +#define DO5_MODE IO_ACTIVE_HIGH +#define DO6_MODE IO_ACTIVE_HIGH +#define DO7_MODE IO_ACTIVE_HIGH +#define DO8_MODE IO_ACTIVE_HIGH + +//SAFEin (Output) signal +#define DO9_MODE IO_ACTIVE_HIGH + +#define DO10_MODE IO_ACTIVE_HIGH + +//Header Bed FET +#define DO11_MODE IO_ACTIVE_HIGH + +//Indicator_LED +#define DO12_MODE IO_ACTIVE_HIGH + +#define DO13_MODE IO_ACTIVE_HIGH + + +/*** Extruders / Heaters ***/ +/* +#define MIN_FAN_TEMP 40.0 +#define MAX_FAN_TEMP 150.0 + +#define H1_DEFAULT_ENABLE true +#define H1_DEFAULT_P 9.0 +#define H1_DEFAULT_I 0.12 +#define H1_DEFAULT_D 400.0 + +#define H2_DEFAULT_ENABLE false +#define H2_DEFAULT_P 9.0 +#define H2_DEFAULT_I 0.12 +#define H2_DEFAULT_D 400.0 + +#define H3_DEFAULT_ENABLE false +#define H3_DEFAULT_P 9.0 +#define H3_DEFAULT_I 0.12 +#define H3_DEFAULT_D 400.0 +*/ + + +// *** PWM SPINDLE CONTROL *** + +#define P1_PWM_FREQUENCY 100 // in Hz +#define P1_CW_SPEED_LO 1000 // in RPM (arbitrary units) +#define P1_CW_SPEED_HI 2000 +#define P1_CW_PHASE_LO 0.125 // phase [0..1] +#define P1_CW_PHASE_HI 0.2 +#define P1_CCW_SPEED_LO 1000 +#define P1_CCW_SPEED_HI 2000 +#define P1_CCW_PHASE_LO 0.125 +#define P1_CCW_PHASE_HI 0.2 +#define P1_PWM_PHASE_OFF 0.1 + +// *** DEFAULT COORDINATE SYSTEM OFFSETS *** + +#define G54_X_OFFSET 0 // G54 is traditionally set to all zeros +#define G54_Y_OFFSET 0 +#define G54_Z_OFFSET 0 +#define G54_A_OFFSET 0 +#define G54_B_OFFSET 0 +#define G54_C_OFFSET 0 + +#define G55_X_OFFSET (X_TRAVEL_MAX/2) // set to middle of table +#define G55_Y_OFFSET (Y_TRAVEL_MAX/2) +#define G55_Z_OFFSET 0 +#define G55_A_OFFSET 0 +#define G55_B_OFFSET 0 +#define G55_C_OFFSET 0 + +#define G56_X_OFFSET 0 +#define G56_Y_OFFSET 0 +#define G56_Z_OFFSET 0 +#define G56_A_OFFSET 0 +#define G56_B_OFFSET 0 +#define G56_C_OFFSET 0 + +#define G57_X_OFFSET 0 +#define G57_Y_OFFSET 0 +#define G57_Z_OFFSET 0 +#define G57_A_OFFSET 0 +#define G57_B_OFFSET 0 +#define G57_C_OFFSET 0 + +#define G58_X_OFFSET 0 +#define G58_Y_OFFSET 0 +#define G58_Z_OFFSET 0 +#define G58_A_OFFSET 0 +#define G58_B_OFFSET 0 +#define G58_C_OFFSET 0 + +#define G59_X_OFFSET 0 +#define G59_Y_OFFSET 0 +#define G59_Z_OFFSET 0 +#define G59_A_OFFSET 0 +#define G59_B_OFFSET 0 +#define G59_C_OFFSET 0 From 21a197f7369ebc23995a7b4cda634e26c639cf24 Mon Sep 17 00:00:00 2001 From: Rob Giseburt Date: Mon, 10 Oct 2016 14:25:53 -0500 Subject: [PATCH 14/98] Update Motate reference. --- Motate | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Motate b/Motate index b6d1c837..ae140a66 160000 --- a/Motate +++ b/Motate @@ -1 +1 @@ -Subproject commit b6d1c8373b4c2cdd148aaca2def515adffa8336b +Subproject commit ae140a66aa8044556755f383d45909910d8c2da1 From a3db4bb886cb1573ef65cde6608158a37320dff1 Mon Sep 17 00:00:00 2001 From: Rob Giseburt Date: Mon, 10 Oct 2016 14:27:08 -0500 Subject: [PATCH 15/98] Attempt to fix #123. --- g2core/canonical_machine.h | 1 + g2core/plan_exec.cpp | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index 1a7c1991..61c2b8f5 100755 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -324,6 +324,7 @@ typedef struct GCodeState { // Gcode model state - used by model, pl // G82, G83 G84, G85, G86, G87, G88, G89 float target[AXES]; // XYZABC where the move should go + float target_comp[AXES]; // summation compensation (Kahan) overflow value float work_offset[AXES]; // offset from the work coordinate system (for reporting only) float feed_rate; // F - normalized to millimeters/minute or in inverse time mode diff --git a/g2core/plan_exec.cpp b/g2core/plan_exec.cpp index 5627476f..84c57d5b 100755 --- a/g2core/plan_exec.cpp +++ b/g2core/plan_exec.cpp @@ -896,8 +896,17 @@ static stat_t _exec_aline_segment() copy_vector(mr.gm.target, mr.waypoint[mr.section]); } else { float segment_length = mr.segment_velocity * mr.segment_time; + // see https://en.wikipedia.org/wiki/Kahan_summation_algorithm + // for the summation compensation description for (uint8_t a=0; a Date: Thu, 27 Oct 2016 09:50:41 -0500 Subject: [PATCH 16/98] Support for gquintic-b (includes Motate bump). Note: gquintic-a support is removed. --- Motate | 2 +- g2core/board/gquintic.mk | 15 +-- ...quintic-a-pinout.h => gquintic-b-pinout.h} | 108 +++++++++--------- .../board/gquintic/motate_pin_assignments.h | 2 + g2core/g2core.xcodeproj/project.pbxproj | 2 +- 5 files changed, 69 insertions(+), 60 deletions(-) rename g2core/board/gquintic/{gquintic-a-pinout.h => gquintic-b-pinout.h} (68%) diff --git a/Motate b/Motate index ae140a66..8d6488d2 160000 --- a/Motate +++ b/Motate @@ -1 +1 @@ -Subproject commit ae140a66aa8044556755f383d45909910d8c2da1 +Subproject commit 8d6488d2dd70789a2d05c704eccd0c928ae1b909 diff --git a/g2core/board/gquintic.mk b/g2core/board/gquintic.mk index 4f512476..ab60f6cb 100755 --- a/g2core/board/gquintic.mk +++ b/g2core/board/gquintic.mk @@ -6,32 +6,33 @@ # make BOARD=gquintic-a # You can also choose a CONFIG from boards.mk: -# make CONFIG=PrintrbotPlus BOARD=gquintic-a +# make CONFIG=PrintrbotPlus BOARD=gquintic-b ########## # BOARDs for use directly from the make command line (with default settings) or by CONFIGs. -ifeq ("$(BOARD)","gquintic-a") +ifeq ("$(BOARD)","gquintic-b") BASE_BOARD=gquintic - DEVICE_DEFINES += MOTATE_BOARD="gquintic-a" + DEVICE_DEFINES += MOTATE_BOARD="gquintic-b" DEVICE_DEFINES += SETTINGS_FILE=${SETTINGS_FILE} endif ########## -# The general pboard-a BASE_BOARD. +# The general gquintic BASE_BOARD. +# NOTE: rev a is no longer supported! ifeq ("$(BASE_BOARD)","gquintic") _BOARD_FOUND = 1 DEVICE_DEFINES += MOTATE_CONFIG_HAS_USBSERIAL=1 - FIRST_LINK_SOURCES += $(sort $(wildcard ${MOTATE_PATH}/Atmel_sam_common/*.cpp)) $(sort $(wildcard ${MOTATE_PATH}/Atmel_sam4e/*.cpp)) + FIRST_LINK_SOURCES += $(sort $(wildcard ${MOTATE_PATH}/Atmel_sam_common/*.cpp)) $(sort $(wildcard ${MOTATE_PATH}/Atmel_sams70/*.cpp)) - CHIP = SAM4E8C + CHIP = SAMS70N19 export CHIP - CHIP_LOWERCASE = sam4e8c + CHIP_LOWERCASE = sams70n19 BOARD_PATH = ./board/gquintic SOURCE_DIRS += ${BOARD_PATH} device/trinamic diff --git a/g2core/board/gquintic/gquintic-a-pinout.h b/g2core/board/gquintic/gquintic-b-pinout.h similarity index 68% rename from g2core/board/gquintic/gquintic-a-pinout.h rename to g2core/board/gquintic/gquintic-b-pinout.h index 67e9ecd3..fe412515 100755 --- a/g2core/board/gquintic/gquintic-a-pinout.h +++ b/g2core/board/gquintic/gquintic-b-pinout.h @@ -116,44 +116,50 @@ namespace Motate { -// Arduino pin name & function -_MAKE_MOTATE_PIN(kOutput2_PinNumber, 'A', 0); // +// Unused: +// +// +// +// +// + +_MAKE_MOTATE_PIN(kLED_RGBWPixelPinNumber, 'A', 0); // _MAKE_MOTATE_PIN(kOutput1_PinNumber, 'A', 1); // -_MAKE_MOTATE_PIN(kSocket5_EnablePinNumber, 'A', 2); // +_MAKE_MOTATE_PIN(kOutput2_PinNumber, 'A', 2); // _MAKE_MOTATE_PIN(kI2C1_SDAPinNumber, 'A', 3); // _MAKE_MOTATE_PIN(kI2C1_SCLPinNumber, 'A', 4); // -_MAKE_MOTATE_PIN(kUnassigned1, 'A', 5); // +_MAKE_MOTATE_PIN(kOutput11_PinNumber, 'A', 5); // _MAKE_MOTATE_PIN(kExternalClock1_PinNumber, 'A', 6); // CPU_CLK -_MAKE_MOTATE_PIN(kSerial_CTS, 'A', 7); // -_MAKE_MOTATE_PIN(kUnassigned2, 'A', 8); // +_MAKE_MOTATE_PIN(kOutput7_PinNumber, 'A', 7); // +_MAKE_MOTATE_PIN(kSerial_RTS, 'A', 8); // _MAKE_MOTATE_PIN(kSerial_RX, 'A', 9); // _MAKE_MOTATE_PIN(kSerial_TX, 'A', 10); // -_MAKE_MOTATE_PIN(kSocket1_SPISlaveSelectPinNumber, 'A', 11); // -_MAKE_MOTATE_PIN(kSPI0_MISOPinNumber, 'A', 12); // -_MAKE_MOTATE_PIN(kSPI0_MOSIPinNumber, 'A', 13); // -_MAKE_MOTATE_PIN(kSPI0_SCKPinNumber, 'A', 14); // -_MAKE_MOTATE_PIN(kOutput9_PinNumber, 'A', 15); // -_MAKE_MOTATE_PIN(kOutput7_PinNumber, 'A', 16); // +_MAKE_MOTATE_PIN(kSocket2_EnablePinNumber, 'A', 11); // +_MAKE_MOTATE_PIN(kOutput6_PinNumber, 'A', 12); // +_MAKE_MOTATE_PIN(kOutput8_PinNumber, 'A', 13); // +_MAKE_MOTATE_PIN(kSocket1_StepPinNumber, 'A', 14); // +_MAKE_MOTATE_PIN(kOutput3_PinNumber, 'A', 15); // +_MAKE_MOTATE_PIN(kOutput4_PinNumber, 'A', 16); // _MAKE_MOTATE_PIN(kADC3_PinNumber, 'A', 17); // _MAKE_MOTATE_PIN(kADC2_PinNumber, 'A', 18); // _MAKE_MOTATE_PIN(kADC1_PinNumber, 'A', 19); // _MAKE_MOTATE_PIN(kADC0_PinNumber, 'A', 20); // -_MAKE_MOTATE_PIN(kUnassigned3, 'A', 21); // -_MAKE_MOTATE_PIN(kSocket2_SPISlaveSelectPinNumber, 'A', 22); // -_MAKE_MOTATE_PIN(kOutput8_PinNumber, 'A', 23); // -_MAKE_MOTATE_PIN(kOutput10_PinNumber, 'A', 24); // -_MAKE_MOTATE_PIN(kOutput4_PinNumber, 'A', 25); // +_MAKE_MOTATE_PIN(kSerial_CTS, 'A', 21); // +_MAKE_MOTATE_PIN(kSocket1_EnablePinNumber, 'A', 22); // +_MAKE_MOTATE_PIN(kOutput10_PinNumber, 'A', 23); // +_MAKE_MOTATE_PIN(kSocket3_EnablePinNumber, 'A', 24); // +_MAKE_MOTATE_PIN(kSocket2_DirPinNumber, 'A', 25); // _MAKE_MOTATE_PIN(kOutput5_PinNumber, 'A', 26); // On Timer 2! -_MAKE_MOTATE_PIN(kOutput6_PinNumber, 'A', 27); // On Timer 2! -_MAKE_MOTATE_PIN(kUnassigned13, 'A', 28); // DIAG0 -_MAKE_MOTATE_PIN(kInput8_PinNumber, 'A', 29); // +_MAKE_MOTATE_PIN(kSocket3_StepPinNumber, 'A', 27); // On Timer 2! +_MAKE_MOTATE_PIN(kUnassigned1, 'A', 28); // DIAG1 +_MAKE_MOTATE_PIN(kUnassigned2, 'A', 29); // _MAKE_MOTATE_PIN(kInput1_PinNumber, 'A', 30); // -_MAKE_MOTATE_PIN(kInput2_PinNumber, 'A', 31); // +_MAKE_MOTATE_PIN(kInput4_PinNumber, 'A', 31); // _MAKE_MOTATE_PIN(kInput12_PinNumber, 'B', 0); // _MAKE_MOTATE_PIN(kInput11_PinNumber, 'B', 1); // -_MAKE_MOTATE_PIN(kSocket3_SPISlaveSelectPinNumber, 'B', 2); // -_MAKE_MOTATE_PIN(kSerial_RTS, 'B', 3); // +_MAKE_MOTATE_PIN(kSocket1_SPISlaveSelectPinNumber, 'B', 2); // +_MAKE_MOTATE_PIN(kOutputSAFE_PinNumber, 'B', 3); // //_MAKE_MOTATE_PIN( , 'B', 4); // TDI //_MAKE_MOTATE_PIN( , 'B', 5); // TRACESDO //_MAKE_MOTATE_PIN( , 'B', 6); // SWDIO @@ -168,35 +174,35 @@ _MAKE_MOTATE_PIN(kSocket4_SPISlaveSelectPinNumber, 'B', 14); // NOT CONNECTED //_MAKE_MOTATE_PIN( , 'D', 0); // USB_VBUS -_MAKE_MOTATE_PIN(kInput10_PinNumber, 'D', 1); // -_MAKE_MOTATE_PIN(kInput9_PinNumber, 'D', 2); // -_MAKE_MOTATE_PIN(kInput7_PinNumber, 'D', 3); // -_MAKE_MOTATE_PIN(kInput6_PinNumber, 'D', 4); // -_MAKE_MOTATE_PIN(kInput5_PinNumber, 'D', 5); // -_MAKE_MOTATE_PIN(kInput4_PinNumber, 'D', 6); // +_MAKE_MOTATE_PIN(kInput9_PinNumber, 'D', 1); // +_MAKE_MOTATE_PIN(kInput10_PinNumber, 'D', 2); // +_MAKE_MOTATE_PIN(kInput8_PinNumber, 'D', 3); // +_MAKE_MOTATE_PIN(kInput7_PinNumber, 'D', 4); // +_MAKE_MOTATE_PIN(kInput6_PinNumber, 'D', 5); // +_MAKE_MOTATE_PIN(kInput5_PinNumber, 'D', 6); // _MAKE_MOTATE_PIN(kInput3_PinNumber, 'D', 7); // -_MAKE_MOTATE_PIN(kUnassigned11, 'D', 8); // DIAG1 -_MAKE_MOTATE_PIN(kOutputSAFE_PinNumber, 'D', 9); // -_MAKE_MOTATE_PIN(kSocket5_StepPinNumber, 'D', 10); // -_MAKE_MOTATE_PIN(kSocket5_DirPinNumber, 'D', 11); // -_MAKE_MOTATE_PIN(kSocket4_StepPinNumber, 'D', 12); // -_MAKE_MOTATE_PIN(kUnassigned5, 'D', 13); // -_MAKE_MOTATE_PIN(kSocket4_DirPinNumber, 'D', 14); // -_MAKE_MOTATE_PIN(kUnassigned6, 'D', 15); // -_MAKE_MOTATE_PIN(kSocket4_EnablePinNumber, 'D', 16); // -_MAKE_MOTATE_PIN(kSocket3_DirPinNumber, 'D', 17); // -_MAKE_MOTATE_PIN(kUnassigned7, 'D', 18); // -_MAKE_MOTATE_PIN(kSocket3_EnablePinNumber, 'D', 19); // -_MAKE_MOTATE_PIN(kSocket2_StepPinNumber, 'D', 20); // -_MAKE_MOTATE_PIN(kSocket2_DirPinNumber, 'D', 21); // -_MAKE_MOTATE_PIN(kUnassigned8, 'D', 22); // -_MAKE_MOTATE_PIN(kOutput3_PinNumber, 'D', 23); // -_MAKE_MOTATE_PIN(kSocket2_EnablePinNumber, 'D', 24); // -_MAKE_MOTATE_PIN(kSocket1_DirPinNumber, 'D', 25); // -_MAKE_MOTATE_PIN(kSocket1_StepPinNumber, 'D', 26); // -_MAKE_MOTATE_PIN(kSocket1_EnablePinNumber, 'D', 27); // -_MAKE_MOTATE_PIN(kSocket3_StepPinNumber, 'D', 28); // -_MAKE_MOTATE_PIN(kOutput11_PinNumber, 'D', 29); // +_MAKE_MOTATE_PIN(kInput2_PinNumber, 'D', 8); // ] +_MAKE_MOTATE_PIN(kUnassigned3, 'D', 9); // DIAG0 +_MAKE_MOTATE_PIN(kUnassigned4, 'D', 10); // +_MAKE_MOTATE_PIN(kSocket5_StepPinNumber, 'D', 11); // +_MAKE_MOTATE_PIN(kSocket3_SPISlaveSelectPinNumber, 'D', 12); // +_MAKE_MOTATE_PIN(kSocket5_DirPinNumber, 'D', 13); // +_MAKE_MOTATE_PIN(kSocket5_EnablePinNumber, 'D', 14); // +_MAKE_MOTATE_PIN(kUnassigned5, 'D', 15); // +_MAKE_MOTATE_PIN(kSocket4_StepPinNumber, 'D', 16); // +_MAKE_MOTATE_PIN(kSocket4_DirPinNumber, 'D', 17); // +_MAKE_MOTATE_PIN(kSocket3_DirPinNumber, 'D', 18); // +_MAKE_MOTATE_PIN(kUnassigned6, 'D', 19); // +_MAKE_MOTATE_PIN(kSPI0_MISOPinNumber, 'D', 20); // +_MAKE_MOTATE_PIN(kSPI0_MOSIPinNumber, 'D', 21); // +_MAKE_MOTATE_PIN(kSPI0_SCKPinNumber, 'D', 22); // +_MAKE_MOTATE_PIN(kUnassigned7, 'D', 23); // +_MAKE_MOTATE_PIN(kSocket2_StepPinNumber, 'D', 24); // +_MAKE_MOTATE_PIN(kSocket2_SPISlaveSelectPinNumber, 'D', 25); // +_MAKE_MOTATE_PIN(kOutput9_PinNumber, 'D', 26); // +_MAKE_MOTATE_PIN(kSocket1_DirPinNumber, 'D', 27); // +_MAKE_MOTATE_PIN(kSocket4_EnablePinNumber, 'D', 28); // +_MAKE_MOTATE_PIN(kUnassigned8, 'D', 29); // _MAKE_MOTATE_PIN(kUnassigned9, 'D', 30); // INTERRUPT_OUT _MAKE_MOTATE_PIN(kUnassigned10, 'D', 31); // diff --git a/g2core/board/gquintic/motate_pin_assignments.h b/g2core/board/gquintic/motate_pin_assignments.h index 12ec29bf..57cf4ddc 100755 --- a/g2core/board/gquintic/motate_pin_assignments.h +++ b/g2core/board/gquintic/motate_pin_assignments.h @@ -166,6 +166,8 @@ pin_number kSD_ChipSelectPinNumber = 120; pin_number kInterlock_InPinNumber = 121; pin_number kOutputSAFE_PinNumber = 122; // SAFE signal pin_number kLEDPWM_PinNumber = 123; +pin_number kOutputInterrupt_PinNumber = 124; // to-host interrupt signal +pin_number kLED_RGBWPixelPinNumber = 125; // 117; // GRBL / gShield compatibility pins -- Due board ONLY diff --git a/g2core/g2core.xcodeproj/project.pbxproj b/g2core/g2core.xcodeproj/project.pbxproj index 573a6b25..e4d1864c 100644 --- a/g2core/g2core.xcodeproj/project.pbxproj +++ b/g2core/g2core.xcodeproj/project.pbxproj @@ -381,7 +381,7 @@ }; D4F226F31D088A48008ED57C /* G2 gQuintic PrintrbotPlus */ = { isa = PBXLegacyTarget; - buildArgumentsString = "$(ACTION) VERBOSE=1 COLOR=0 CONFIG=PrintrbotPlus BOARD=gquintic-a DEBUG=2"; + buildArgumentsString = "$(ACTION) VERBOSE=1 COLOR=0 CONFIG=PrintrbotPlus BOARD=gquintic-b DEBUG=2"; buildConfigurationList = D4F226F41D088A48008ED57C /* Build configuration list for PBXLegacyTarget "G2 gQuintic PrintrbotPlus" */; buildPhases = ( ); From 3cd3dcbaf3e7c8e01ec9010bc435ab03cafa398c Mon Sep 17 00:00:00 2001 From: Rob Giseburt Date: Thu, 27 Oct 2016 09:54:57 -0500 Subject: [PATCH 17/98] Fixed CONFIG=TestQuintic to refer to gquintic-b --- g2core/boards.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/g2core/boards.mk b/g2core/boards.mk index 1f314564..2643578d 100644 --- a/g2core/boards.mk +++ b/g2core/boards.mk @@ -72,7 +72,7 @@ endif ifeq ("$(CONFIG)","TestQuintic") ifeq ("$(BOARD)","NONE") - BOARD=gquintic-a + BOARD=gquintic-b endif SETTINGS_FILE="settings_test.h" endif From 4de3b5c19244e9a6ec222b9841e6c9261f668057 Mon Sep 17 00:00:00 2001 From: Rob Giseburt Date: Thu, 27 Oct 2016 14:25:14 -0500 Subject: [PATCH 18/98] Corrected some quintic odds and ends --- g2core/board/gquintic.gdb | 2 +- g2core/board/gquintic/gquintic-b-pinout.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/g2core/board/gquintic.gdb b/g2core/board/gquintic.gdb index 3a78d77d..864a9f89 100644 --- a/g2core/board/gquintic.gdb +++ b/g2core/board/gquintic.gdb @@ -4,7 +4,7 @@ target remote | /usr/local/bin/openocd -c "set CHIPNAME ${CHIP}" -f ${MOTATE_PAT source ./board/g2_default.gdb define boot_from_flash - monitor at91sam4 gpnvm set 1 + monitor atsamv gpnvm set 1 end source -s arm.gdb diff --git a/g2core/board/gquintic/gquintic-b-pinout.h b/g2core/board/gquintic/gquintic-b-pinout.h index fe412515..d4dbe127 100755 --- a/g2core/board/gquintic/gquintic-b-pinout.h +++ b/g2core/board/gquintic/gquintic-b-pinout.h @@ -89,7 +89,7 @@ #define ADC2_AVAILABLE 0 #define ADC3_AVAILABLE 0 -#define XIO_HAS_USB 0 +#define XIO_HAS_USB 1 #define XIO_HAS_UART 1 #define XIO_HAS_SPI 0 #define XIO_HAS_I2C 0 From 0968d9649c81ddb7b890b007d4bc1c29e753f58f Mon Sep 17 00:00:00 2001 From: Rob Giseburt Date: Thu, 27 Oct 2016 14:25:26 -0500 Subject: [PATCH 19/98] New motate to get sams70 SPI fixes. --- Motate | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Motate b/Motate index 8d6488d2..1e53d435 160000 --- a/Motate +++ b/Motate @@ -1 +1 @@ -Subproject commit 8d6488d2dd70789a2d05c704eccd0c928ae1b909 +Subproject commit 1e53d435c14c5eb753da72d7d9176192322dbc02 From c1f0bfc8b69b65eaed4882ced45007823114220b Mon Sep 17 00:00:00 2001 From: Rob Giseburt Date: Thu, 27 Oct 2016 16:06:59 -0500 Subject: [PATCH 20/98] Fixes for gQuintic-b timer configuration --- g2core/board/gquintic/gquintic-b-pinout.h | 22 +++++++++++----------- g2core/board/gquintic/hardware.h | 10 +++++----- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/g2core/board/gquintic/gquintic-b-pinout.h b/g2core/board/gquintic/gquintic-b-pinout.h index d4dbe127..4134a229 100755 --- a/g2core/board/gquintic/gquintic-b-pinout.h +++ b/g2core/board/gquintic/gquintic-b-pinout.h @@ -100,17 +100,17 @@ // So we have to explicitly enable them as PWM pins. // Generated with: // perl -e 'for($i=1;$i<14;$i++) { print "#define OUTPUT${i}_PWM 0\n";}' -#define OUTPUT1_PWM 1 // PWM1 - Fet 1 -#define OUTPUT2_PWM 1 // PWM2 - Fet 2 -#define OUTPUT3_PWM 1 // PWM3 - Fan 1 -#define OUTPUT4_PWM 0 // PWM2 - Fan 2 -#define OUTPUT5_PWM 1 // Timer2ch0 - Fan 3 -#define OUTPUT6_PWM 1 // Timer2ch1 -#define OUTPUT7_PWM 0 // PWM2 -#define OUTPUT8_PWM 1 // PWM0 -#define OUTPUT9_PWM 0 // PWM3 or Timer1ch0 -#define OUTPUT10_PWM 0 // PWM1 -#define OUTPUT11_PWM 0 // Can't PWM - Fet 3 +#define OUTPUT1_PWM 1 // TC0,1 - Fet 1 +#define OUTPUT2_PWM 1 // PWM1 - Fet 2 +#define OUTPUT3_PWM 1 // TC1,0 - Fan 1 +#define OUTPUT4_PWM 1 // TC1,1 - Fan 2 +#define OUTPUT5_PWM 1 // TC2,0 - Fan 3 +#define OUTPUT6_PWM 1 // PWM8+0 +#define OUTPUT7_PWM 1 // PWM3 +#define OUTPUT8_PWM 1 // PWM2 +#define OUTPUT9_PWM 0 // PWM2 +#define OUTPUT10_PWM 1 // PWM8+2 +#define OUTPUT11_PWM 1 // PWM8+3 - Fet 3 #define OUTPUT12_PWM 0 // Unused #define OUTPUT13_PWM 0 // Unused diff --git a/g2core/board/gquintic/hardware.h b/g2core/board/gquintic/hardware.h index 78943c2d..5dbe9ac3 100755 --- a/g2core/board/gquintic/hardware.h +++ b/g2core/board/gquintic/hardware.h @@ -128,11 +128,11 @@ using Motate::OutputPin; /**** Motate Definitions ****/ // Timer definitions. See stepper.h and other headers for setup -typedef TimerChannel<0,0> dda_timer_type; // stepper pulse generation in stepper.cpp -typedef TimerChannel<1,0> dwell_timer_type; // dwell timing in stepper.cpp -typedef ServiceCall<0> load_timer_type; // request load timer in stepper.cpp -typedef ServiceCall<1> exec_timer_type; // request exec timer in stepper.cpp -typedef ServiceCall<2> fwd_plan_timer_type; // request exec timer in stepper.cpp +typedef TimerChannel<9, 0> dda_timer_type; // stepper pulse generation in stepper.cpp +typedef TimerChannel<10, 0> dwell_timer_type; // dwell timing in stepper.cpp +typedef ServiceCall<0> load_timer_type; // request load timer in stepper.cpp +typedef ServiceCall<1> exec_timer_type; // request exec timer in stepper.cpp +typedef ServiceCall<2> fwd_plan_timer_type; // request exec timer in stepper.cpp // Pin assignments From e2ba062f8c6533dc656ef06a88527eb94b9297f0 Mon Sep 17 00:00:00 2001 From: Rob Giseburt Date: Fri, 28 Oct 2016 21:33:54 -0500 Subject: [PATCH 21/98] Fixes for Archim, fixed kSerial_(RX|TX|RTS|CTS)PinNumber constant naming on all boards. --- g2core/board/Archim.mk | 2 +- g2core/board/Archim/Archim-pinout.h | 16 +++--- g2core/board/Archim/board_xio.cpp | 57 +++++++++++-------- g2core/board/Archim/board_xio.h | 23 ++++---- g2core/board/Archim/hardware.cpp | 49 +++++++++++++--- g2core/board/ArduinoDue/board_xio.cpp | 4 +- g2core/board/ArduinoDue/board_xio.h | 2 +- g2core/board/ArduinoDue/gShield-pinout.h | 8 +-- .../board/ArduinoDue/shopbotShield-pinout.h | 4 +- g2core/board/G2v9/board_xio.cpp | 4 +- g2core/board/G2v9/board_xio.h | 2 +- g2core/board/G2v9/motate_pin_assignments.h | 8 +-- g2core/board/gquadratic/board_xio.cpp | 4 +- g2core/board/gquadratic/board_xio.h | 2 +- g2core/board/gquadratic/gquadratic-b-pinout.h | 8 +-- .../board/gquadratic/motate_pin_assignments.h | 18 +++--- g2core/board/gquintic/board_xio.cpp | 4 +- g2core/board/gquintic/board_xio.h | 2 +- g2core/board/gquintic/gquintic-b-pinout.h | 8 +-- .../board/gquintic/motate_pin_assignments.h | 16 +++--- g2core/board/printrboardg2/board_xio.cpp | 4 +- g2core/board/printrboardg2/board_xio.h | 2 +- .../printrboardg2/motate_pin_assignments.h | 8 +-- .../printrboardg2/printrboardG2v3-pinout.h | 8 +-- g2core/board/sbv300/board_xio.cpp | 4 +- g2core/board/sbv300/board_xio.h | 2 +- g2core/board/sbv300/motate_pin_assignments.h | 8 +-- 27 files changed, 159 insertions(+), 118 deletions(-) diff --git a/g2core/board/Archim.mk b/g2core/board/Archim.mk index bf8bb2c8..7a2c46ae 100755 --- a/g2core/board/Archim.mk +++ b/g2core/board/Archim.mk @@ -33,7 +33,7 @@ ifeq ("$(BASE_BOARD)","archim") CHIP_LOWERCASE = sam3x8e BOARD_PATH = ./board/Archim - SOURCE_DIRS += ${BOARD_PATH} + SOURCE_DIRS += ${BOARD_PATH} device/step_dir_driver PLATFORM_BASE = ${MOTATE_PATH}/platform/atmel_sam diff --git a/g2core/board/Archim/Archim-pinout.h b/g2core/board/Archim/Archim-pinout.h index 4bab1531..1d49ac1a 100755 --- a/g2core/board/Archim/Archim-pinout.h +++ b/g2core/board/Archim/Archim-pinout.h @@ -84,15 +84,15 @@ namespace Motate { // NOT ALL OF THESE PINS ARE ON ALL PLATFORMS // Undefined pins will be equivalent to Motate::NullPin, and return 1 for Pin<>::isNull(); -pin_number kSerial_RX = 0; -pin_number kSerial_TX = 1; -// pin_number kSerial_RTS = 8; // added later -// pin_number kSerial_CTS = 9; // added later +pin_number kSerial_RXPinNumber = 0; +pin_number kSerial_TXPinNumber = 1; +pin_number kSerial_RTSPinNumber = 2; // added later +pin_number kSerial_CTSPinNumber = 3; // added later -pin_number kSerial0_RX = 0; -pin_number kSerial0_TX = 1; -// pin_number kSerial0_RTS = 8; // added later -// pin_number kSerial0_CTS = 9; // added later +pin_number kSerial0_RXPinNumber = 0; +pin_number kSerial0_TXPinNumber = 1; +pin_number kSerial0_RTSPinNumber = 2; // added later +pin_number kSerial0_CTSPinNumber = 3; // added later pin_number kI2C_SDAPinNumber = 20; pin_number kI2C_SCLPinNumber = 21; diff --git a/g2core/board/Archim/board_xio.cpp b/g2core/board/Archim/board_xio.cpp index 0e6ce2b1..ff0846e1 100755 --- a/g2core/board/Archim/board_xio.cpp +++ b/g2core/board/Archim/board_xio.cpp @@ -32,48 +32,59 @@ #include "board_xio.h" //******** USB ******** +#if XIO_HAS_USB const Motate::USBSettings_t Motate::USBSettings = { /*gVendorID = */ 0x1d50, /*gProductID = */ 0x606d, /*gProductVersion = */ G2CORE_FIRMWARE_VERSION, /*gAttributes = */ kUSBConfigAttributeSelfPowered, - /*gPowerConsumption = */ 500}; -/*gProductVersion = */ // 0.1, + /*gPowerConsumption = */ 500 +}; +/*gProductVersion = */ //0.1, -// Motate::USBDevice< Motate::USBCDC > usb; -Motate::USBDevice usb; +//Motate::USBDevice< Motate::USBCDC > usb; +Motate::USBDevice< Motate::USBCDC, Motate::USBCDC > usb; -decltype(usb.mixin<0>::Serial)& SerialUSB = usb.mixin<0>::Serial; -decltype(usb.mixin<1>::Serial)& SerialUSB1 = usb.mixin<1>::Serial; +decltype(usb.mixin<0>::Serial) &SerialUSB = usb.mixin<0>::Serial; +decltype(usb.mixin<1>::Serial) &SerialUSB1 = usb.mixin<1>::Serial; // 115200 is the default, as well. -// UART Serial {115200, UARTMode::RTSCTSFlowControl}; +//UART Serial {115200, UARTMode::RTSCTSFlowControl}; - -MOTATE_SET_USB_VENDOR_STRING({'S', 'y', 'n', 't', 'h', 'e', 't', 'o', 's'}) -MOTATE_SET_USB_PRODUCT_STRING({'T', 'i', 'n', 'y', 'G', ' ', 'v', '2'}) +MOTATE_SET_USB_VENDOR_STRING( u"Synthetos (http://synthetos.com)" ) +MOTATE_SET_USB_PRODUCT_STRING( u"g2core gQuadratic" ) MOTATE_SET_USB_SERIAL_NUMBER_STRING_FROM_CHIPID() - - +#endif // XIO_HAS_USB //******** SPI ******** -// Motate::SPI spi; - +#if XIO_HAS_SPI +Motate::SPI spi; +#endif //******** UART ******** -// Motate::UART Serial {115200, -// Motate::UARTMode::RTSCTSFlowControl}; +#if XIO_HAS_UART +Motate::UART Serial {115200, Motate::UARTMode::RTSCTSFlowControl}; +#endif - - -void board_xio_init(void) { +void board_hardware_init(void) // called 1st +{ +#if XIO_HAS_USB // Init USB - usb.attach(); // USB setup. Runs in "background" as the rest of this executes + usb.attach(); // USB setup. Runs in "background" as the rest of this executes +#endif // XIO_HAS_USB +} - // Init SPI (handled internally for now) +void board_xio_init(void) // called later than board_hardware_init (there are thing in between) +{ + // Init SPI +#if XIO_HAS_SPI + // handled internally for now +#endif // Init UART - // Serial.init(); -} \ No newline at end of file +#if XIO_HAS_UART + Serial.init(); +#endif +} diff --git a/g2core/board/Archim/board_xio.h b/g2core/board/Archim/board_xio.h index d40e88b3..102698d3 100755 --- a/g2core/board/Archim/board_xio.h +++ b/g2core/board/Archim/board_xio.h @@ -30,6 +30,7 @@ #define board_xio_h //******** USB ******** +#if XIO_HAS_USB #include "MotateUSB.h" #include "MotateUSBCDC.h" @@ -37,23 +38,23 @@ extern Motate::USBDevice usb; extern decltype(usb.mixin<0>::Serial)& SerialUSB; extern decltype(usb.mixin<1>::Serial)& SerialUSB1; - +#endif // XIO_HAS_USB //******** SPI ******** -//#include "MotateSPI.h" -// extern Motate::SPI spi; - - +#if XIO_HAS_SPI +#include "MotateSPI.h" +extern Motate::SPI spi; +#endif //******** UART ******** -#define XIO_HAS_UART 0 -//#include "MotateUART.h" -// extern Motate::UART Serial; - - +#if XIO_HAS_UART +#include "MotateUART.h" +extern Motate::UART Serial; +#endif //******* Generic Functions ******* -void board_xio_init(void); +void board_hardware_init(void); // called 1st +void board_xio_init(void); // called later #endif // board_xio_h diff --git a/g2core/board/Archim/hardware.cpp b/g2core/board/Archim/hardware.cpp index 19731b3a..11d740ef 100755 --- a/g2core/board/Archim/hardware.cpp +++ b/g2core/board/Archim/hardware.cpp @@ -55,6 +55,15 @@ void hw_hard_reset(void) Motate::System::reset(/*boootloader: */ false); // arg=0 resets the system } +/* + * hardware_periodic() - callback from the controller loop - TIME CRITICAL. + */ + +stat_t hardware_periodic() +{ + return STAT_OK; +} + void hw_flash_loader(void) { Motate::System::reset(/*boootloader: */ true); // arg=1 erases FLASH and enters FLASH loader @@ -89,7 +98,27 @@ void _get_id(char *id) stat_t hw_get_fbs(nvObj_t *nv) { nv->valuetype = TYPE_STRING; - ritorno(nv_copy_string(nv, "build")); + ritorno(nv_copy_string(nv, G2CORE_FIRMWARE_BUILD_STRING)); + return (STAT_OK); +} + +/* + * hw_get_fbc() - get configuration settings file + */ + +stat_t hw_get_fbc(nvObj_t *nv) +{ + nv->valuetype = TYPE_STRING; +#ifdef SETTINGS_FILE +#define settings_file_string1(s) #s +#define settings_file_string2(s) settings_file_string1(s) + ritorno(nv_copy_string(nv, settings_file_string2(SETTINGS_FILE))); +#undef settings_file_string1 +#undef settings_file_string2 +#else + ritorno(nv_copy_string(nv, "")); +#endif + return (STAT_OK); } @@ -131,20 +160,22 @@ stat_t hw_set_hv(nvObj_t *nv) #ifdef __TEXT_MODE -static const char fmt_fb[] = "[fb] firmware build%18.2f\n"; -static const char fmt_fbs[] = "[fbs] firmware build \"%32s\"\n"; +static const char fmt_fb[] = "[fb] firmware build %18.2f\n"; +static const char fmt_fbs[] = "[fbs] firmware build \"%s\"\n"; +static const char fmt_fbc[] = "[fbc] firmware config \"%s\"\n"; static const char fmt_fv[] = "[fv] firmware version%16.2f\n"; static const char fmt_cv[] = "[cv] configuration version%11.2f\n"; static const char fmt_hp[] = "[hp] hardware platform%15.2f\n"; static const char fmt_hv[] = "[hv] hardware version%16.2f\n"; static const char fmt_id[] = "[id] g2core ID%21s\n"; -void hw_print_fb(nvObj_t *nv) { text_print(nv, fmt_fb);} // TYPE_FLOAT +void hw_print_fb(nvObj_t *nv) { text_print(nv, fmt_fb);} // TYPE_FLOAT void hw_print_fbs(nvObj_t *nv) { text_print(nv, fmt_fbs);} // TYPE_STRING -void hw_print_fv(nvObj_t *nv) { text_print(nv, fmt_fv);} // TYPE_FLOAT -void hw_print_cv(nvObj_t *nv) { text_print(nv, fmt_cv);} // TYPE_FLOAT -void hw_print_hp(nvObj_t *nv) { text_print(nv, fmt_hp);} // TYPE_FLOAT -void hw_print_hv(nvObj_t *nv) { text_print(nv, fmt_hv);} // TYPE_FLOAT -void hw_print_id(nvObj_t *nv) { text_print(nv, fmt_id);} // TYPE_STRING +void hw_print_fbc(nvObj_t *nv) { text_print(nv, fmt_fbc);} // TYPE_STRING +void hw_print_fv(nvObj_t *nv) { text_print(nv, fmt_fv);} // TYPE_FLOAT +void hw_print_cv(nvObj_t *nv) { text_print(nv, fmt_cv);} // TYPE_FLOAT +void hw_print_hp(nvObj_t *nv) { text_print(nv, fmt_hp);} // TYPE_FLOAT +void hw_print_hv(nvObj_t *nv) { text_print(nv, fmt_hv);} // TYPE_FLOAT +void hw_print_id(nvObj_t *nv) { text_print(nv, fmt_id);} // TYPE_STRING #endif //__TEXT_MODE diff --git a/g2core/board/ArduinoDue/board_xio.cpp b/g2core/board/ArduinoDue/board_xio.cpp index 8df11bc4..04d9a326 100755 --- a/g2core/board/ArduinoDue/board_xio.cpp +++ b/g2core/board/ArduinoDue/board_xio.cpp @@ -47,7 +47,7 @@ decltype(usb.mixin<0>::Serial)& SerialUSB = usb.mixin<0>::Serial; decltype(usb.mixin<1>::Serial)& SerialUSB1 = usb.mixin<1>::Serial; // 115200 is the default, as well. -// UART Serial {115200, UARTMode::RTSCTSFlowControl}; +// UART Serial {115200, UARTMode::RTSCTSFlowControl}; MOTATE_SET_USB_VENDOR_STRING({'S', 'y', 'n', 't', 'h', 'e', 't', 'o', 's'}) @@ -64,7 +64,7 @@ Motate::SPI spi; //******** UART ******** #if XIO_HAS_UART -Motate::UART Serial{ +Motate::UART Serial{ 115200, Motate::UARTMode::RTSCTSFlowControl}; #endif diff --git a/g2core/board/ArduinoDue/board_xio.h b/g2core/board/ArduinoDue/board_xio.h index 207a564c..a7bf7959 100755 --- a/g2core/board/ArduinoDue/board_xio.h +++ b/g2core/board/ArduinoDue/board_xio.h @@ -49,7 +49,7 @@ extern Motate::SPI spi; //******** UART ******** #if XIO_HAS_UART #include "MotateUART.h" -extern Motate::UART Serial; +extern Motate::UART Serial; #endif diff --git a/g2core/board/ArduinoDue/gShield-pinout.h b/g2core/board/ArduinoDue/gShield-pinout.h index 94f258da..314ef41e 100755 --- a/g2core/board/ArduinoDue/gShield-pinout.h +++ b/g2core/board/ArduinoDue/gShield-pinout.h @@ -89,10 +89,10 @@ namespace Motate { // NOT ALL OF THESE PINS ARE ON ALL PLATFORMS // Undefined pins will be equivalent to Motate::NullPin, and return 1 for Pin<>::isNull(); -pin_number kSerial_RX = 0; -pin_number kSerial_TX = 1; -// pin_number kSerial_RTS = 8; // added later -// pin_number kSerial_CTS = 9; // added later +pin_number kSerial_RXPinNumber = 0; +pin_number kSerial_TXPinNumber = 1; +// pin_number kSerial_RTSPinNumber = 8; // added later +// pin_number kSerial_CTSPinNumber = 9; // added later pin_number kSerial0_RX = 0; pin_number kSerial0_TX = 1; diff --git a/g2core/board/ArduinoDue/shopbotShield-pinout.h b/g2core/board/ArduinoDue/shopbotShield-pinout.h index fadf485d..b9ba361e 100755 --- a/g2core/board/ArduinoDue/shopbotShield-pinout.h +++ b/g2core/board/ArduinoDue/shopbotShield-pinout.h @@ -82,8 +82,8 @@ namespace Motate { // NOT ALL OF THESE PINS ARE ON ALL PLATFORMS // Undefined pins will be equivalent to Motate::NullPin, and return 1 for Pin<>::isNull(); -pin_number kSerial_RX = 0; -pin_number kSerial_TX = 1; +pin_number kSerial_RXPinNumber = 0; +pin_number kSerial_TXPinNumber = 1; pin_number kSerial0_RX = 0; pin_number kSerial0_TX = 1; diff --git a/g2core/board/G2v9/board_xio.cpp b/g2core/board/G2v9/board_xio.cpp index 8df11bc4..04d9a326 100755 --- a/g2core/board/G2v9/board_xio.cpp +++ b/g2core/board/G2v9/board_xio.cpp @@ -47,7 +47,7 @@ decltype(usb.mixin<0>::Serial)& SerialUSB = usb.mixin<0>::Serial; decltype(usb.mixin<1>::Serial)& SerialUSB1 = usb.mixin<1>::Serial; // 115200 is the default, as well. -// UART Serial {115200, UARTMode::RTSCTSFlowControl}; +// UART Serial {115200, UARTMode::RTSCTSFlowControl}; MOTATE_SET_USB_VENDOR_STRING({'S', 'y', 'n', 't', 'h', 'e', 't', 'o', 's'}) @@ -64,7 +64,7 @@ Motate::SPI spi; //******** UART ******** #if XIO_HAS_UART -Motate::UART Serial{ +Motate::UART Serial{ 115200, Motate::UARTMode::RTSCTSFlowControl}; #endif diff --git a/g2core/board/G2v9/board_xio.h b/g2core/board/G2v9/board_xio.h index 207a564c..a7bf7959 100755 --- a/g2core/board/G2v9/board_xio.h +++ b/g2core/board/G2v9/board_xio.h @@ -49,7 +49,7 @@ extern Motate::SPI spi; //******** UART ******** #if XIO_HAS_UART #include "MotateUART.h" -extern Motate::UART Serial; +extern Motate::UART Serial; #endif diff --git a/g2core/board/G2v9/motate_pin_assignments.h b/g2core/board/G2v9/motate_pin_assignments.h index c1f50dfa..4239e8e0 100755 --- a/g2core/board/G2v9/motate_pin_assignments.h +++ b/g2core/board/G2v9/motate_pin_assignments.h @@ -39,10 +39,10 @@ namespace Motate { // NOT ALL OF THESE PINS ARE ON ALL PLATFORMS // Undefined pins will be equivalent to Motate::NullPin, and return 1 for Pin<>::isNull(); -pin_number kSerial_RX = 0; -pin_number kSerial_TX = 1; -pin_number kSerial_RTS = 8; // added later -pin_number kSerial_CTS = 9; // added later +pin_number kSerial_RXPinNumber = 0; +pin_number kSerial_TXPinNumber = 1; +pin_number kSerial_RTSPinNumber = 8; // added later +pin_number kSerial_CTSPinNumber = 9; // added later pin_number kSerial0_RX = 0; pin_number kSerial0_TX = 1; diff --git a/g2core/board/gquadratic/board_xio.cpp b/g2core/board/gquadratic/board_xio.cpp index 028c60a5..ff0846e1 100755 --- a/g2core/board/gquadratic/board_xio.cpp +++ b/g2core/board/gquadratic/board_xio.cpp @@ -49,7 +49,7 @@ decltype(usb.mixin<0>::Serial) &SerialUSB = usb.mixin<0>::Serial; decltype(usb.mixin<1>::Serial) &SerialUSB1 = usb.mixin<1>::Serial; // 115200 is the default, as well. -//UART Serial {115200, UARTMode::RTSCTSFlowControl}; +//UART Serial {115200, UARTMode::RTSCTSFlowControl}; MOTATE_SET_USB_VENDOR_STRING( u"Synthetos (http://synthetos.com)" ) MOTATE_SET_USB_PRODUCT_STRING( u"g2core gQuadratic" ) @@ -64,7 +64,7 @@ Motate::SPI spi; //******** UART ******** #if XIO_HAS_UART -Motate::UART Serial {115200, Motate::UARTMode::RTSCTSFlowControl}; +Motate::UART Serial {115200, Motate::UARTMode::RTSCTSFlowControl}; #endif void board_hardware_init(void) // called 1st diff --git a/g2core/board/gquadratic/board_xio.h b/g2core/board/gquadratic/board_xio.h index dc57cd3c..102698d3 100755 --- a/g2core/board/gquadratic/board_xio.h +++ b/g2core/board/gquadratic/board_xio.h @@ -50,7 +50,7 @@ extern Motate::SPI spi; //******** UART ******** #if XIO_HAS_UART #include "MotateUART.h" -extern Motate::UART Serial; +extern Motate::UART Serial; #endif //******* Generic Functions ******* diff --git a/g2core/board/gquadratic/gquadratic-b-pinout.h b/g2core/board/gquadratic/gquadratic-b-pinout.h index 220c7ffd..0eaa3c5d 100755 --- a/g2core/board/gquadratic/gquadratic-b-pinout.h +++ b/g2core/board/gquadratic/gquadratic-b-pinout.h @@ -126,8 +126,8 @@ _MAKE_MOTATE_PIN(kUnassigned1, 'A', 5); // _MAKE_MOTATE_PIN(kUnassigned2, 'A', 6); // Missing in 100-pin package _MAKE_MOTATE_PIN(kUnassigned3, 'A', 7); // _MAKE_MOTATE_PIN(kUnassigned4, 'A', 8); // -_MAKE_MOTATE_PIN(kSerial_RX, 'A', 9); // -_MAKE_MOTATE_PIN(kSerial_TX, 'A', 10); // +_MAKE_MOTATE_PIN(kSerial_RXPinNumber, 'A', 9); // +_MAKE_MOTATE_PIN(kSerial_TXPinNumber, 'A', 10); // _MAKE_MOTATE_PIN(kSocket1_Microstep_1PinNumber, 'A', 11); // _MAKE_MOTATE_PIN(kSocket1_EnablePinNumber, 'A', 12); // _MAKE_MOTATE_PIN(kUnassigned5, 'A', 13); // @@ -145,7 +145,7 @@ _MAKE_MOTATE_PIN(kUnassigned16, 'A', 24); // _MAKE_MOTATE_PIN(kUnassigned17, 'A', 25); // _MAKE_MOTATE_PIN(kUnassigned18, 'A', 26); // _MAKE_MOTATE_PIN(kSocket1_VrefPinNumber, 'A', 27); // TC2.1 -_MAKE_MOTATE_PIN(kSerial_CTS, 'A', 28); // +_MAKE_MOTATE_PIN(kSerial_CTSPinNumber, 'A', 28); // _MAKE_MOTATE_PIN(kUnassigned19, 'A', 29); // Missing in 100-pin package _MAKE_MOTATE_PIN(kServo1_PinNumber, 'A', 30); // PWM2 _MAKE_MOTATE_PIN(kInput4_PinNumber, 'A', 31); // @@ -172,7 +172,7 @@ _MAKE_MOTATE_PIN(kUnassigned25, 'D', 3); // _MAKE_MOTATE_PIN(kUnassigned26, 'D', 4); // _MAKE_MOTATE_PIN(kUnassigned27, 'D', 5); // _MAKE_MOTATE_PIN(kInput3_PinNumber, 'D', 6); // -_MAKE_MOTATE_PIN(kSerial_RTS, 'D', 7); // +_MAKE_MOTATE_PIN(kSerial_RTSPinNumber, 'D', 7); // _MAKE_MOTATE_PIN(kUnassigned28, 'D', 8); // INTERRUPT_OUT _MAKE_MOTATE_PIN(kUnassigned29, 'D', 9); // _MAKE_MOTATE_PIN(kUnassigned30, 'D', 10); // diff --git a/g2core/board/gquadratic/motate_pin_assignments.h b/g2core/board/gquadratic/motate_pin_assignments.h index c715b3bf..9cc268e7 100755 --- a/g2core/board/gquadratic/motate_pin_assignments.h +++ b/g2core/board/gquadratic/motate_pin_assignments.h @@ -30,8 +30,6 @@ #ifndef motate_pin_assignments_h #define motate_pin_assignments_h -#include - // Board pinout is pulled in after naming, so we can use the naming there. namespace Motate { @@ -40,15 +38,15 @@ namespace Motate { // Undefined pins will be equivalent to Motate::NullPin, and return 1 for Pin<>::isNull(); -pin_number kSerial_RX = 0; -pin_number kSerial_TX = 1; -pin_number kSerial_RTS = 2; // added later -pin_number kSerial_CTS = 3; // added later +pin_number kSerial_RXPinNumber = 0; +pin_number kSerial_TXPinNumber = 1; +pin_number kSerial_RTSPinNumber = 2; // added later +pin_number kSerial_CTSPinNumber = 3; // added later -pin_number kSerial0_RX = 0; -pin_number kSerial0_TX = 1; -pin_number kSerial0_RTS = 2; // added later -pin_number kSerial0_CTS = 3; // added later +pin_number kSerial0_RXPinNumber = 0; +pin_number kSerial0_TXPinNumber = 1; +pin_number kSerial0_RTSPinNumber = 2; // added later +pin_number kSerial0_CTSPinNumber = 3; // added later pin_number kI2C_SDAPinNumber = 5; pin_number kI2C_SCLPinNumber = 6; diff --git a/g2core/board/gquintic/board_xio.cpp b/g2core/board/gquintic/board_xio.cpp index 16e90f54..5f280380 100755 --- a/g2core/board/gquintic/board_xio.cpp +++ b/g2core/board/gquintic/board_xio.cpp @@ -49,7 +49,7 @@ decltype(usb.mixin<0>::Serial) &SerialUSB = usb.mixin<0>::Serial; decltype(usb.mixin<1>::Serial) &SerialUSB1 = usb.mixin<1>::Serial; // 115200 is the default, as well. -//UART Serial {115200, UARTMode::RTSCTSFlowControl}; +//UART Serial {115200, UARTMode::RTSCTSFlowControl}; MOTATE_SET_USB_VENDOR_STRING( {'S' ,'y', 'n', 't', 'h', 'e', 't', 'o', 's'} ) MOTATE_SET_USB_PRODUCT_STRING( {'T', 'i', 'n', 'y', 'G', ' ', 'v', '2'} ) @@ -64,7 +64,7 @@ Motate::SPI spi; //******** UART ******** #if XIO_HAS_UART -Motate::UART Serial {115200, Motate::UARTMode::RTSCTSFlowControl}; +Motate::UART Serial {115200, Motate::UARTMode::RTSCTSFlowControl}; #endif void board_hardware_init(void) // called 1st diff --git a/g2core/board/gquintic/board_xio.h b/g2core/board/gquintic/board_xio.h index dc57cd3c..102698d3 100755 --- a/g2core/board/gquintic/board_xio.h +++ b/g2core/board/gquintic/board_xio.h @@ -50,7 +50,7 @@ extern Motate::SPI spi; //******** UART ******** #if XIO_HAS_UART #include "MotateUART.h" -extern Motate::UART Serial; +extern Motate::UART Serial; #endif //******* Generic Functions ******* diff --git a/g2core/board/gquintic/gquintic-b-pinout.h b/g2core/board/gquintic/gquintic-b-pinout.h index 4134a229..75d7c52e 100755 --- a/g2core/board/gquintic/gquintic-b-pinout.h +++ b/g2core/board/gquintic/gquintic-b-pinout.h @@ -131,9 +131,9 @@ _MAKE_MOTATE_PIN(kI2C1_SCLPinNumber, 'A', 4); // _MAKE_MOTATE_PIN(kOutput11_PinNumber, 'A', 5); // _MAKE_MOTATE_PIN(kExternalClock1_PinNumber, 'A', 6); // CPU_CLK _MAKE_MOTATE_PIN(kOutput7_PinNumber, 'A', 7); // -_MAKE_MOTATE_PIN(kSerial_RTS, 'A', 8); // -_MAKE_MOTATE_PIN(kSerial_RX, 'A', 9); // -_MAKE_MOTATE_PIN(kSerial_TX, 'A', 10); // +_MAKE_MOTATE_PIN(kSerial_RTSPinNumber, 'A', 8); // +_MAKE_MOTATE_PIN(kSerial_RXPinNumber, 'A', 9); // +_MAKE_MOTATE_PIN(kSerial_TXPinNumber, 'A', 10); // _MAKE_MOTATE_PIN(kSocket2_EnablePinNumber, 'A', 11); // _MAKE_MOTATE_PIN(kOutput6_PinNumber, 'A', 12); // _MAKE_MOTATE_PIN(kOutput8_PinNumber, 'A', 13); // @@ -144,7 +144,7 @@ _MAKE_MOTATE_PIN(kADC3_PinNumber, 'A', 17); // _MAKE_MOTATE_PIN(kADC2_PinNumber, 'A', 18); // _MAKE_MOTATE_PIN(kADC1_PinNumber, 'A', 19); // _MAKE_MOTATE_PIN(kADC0_PinNumber, 'A', 20); // -_MAKE_MOTATE_PIN(kSerial_CTS, 'A', 21); // +_MAKE_MOTATE_PIN(kSerial_CTSPinNumber, 'A', 21); // _MAKE_MOTATE_PIN(kSocket1_EnablePinNumber, 'A', 22); // _MAKE_MOTATE_PIN(kOutput10_PinNumber, 'A', 23); // _MAKE_MOTATE_PIN(kSocket3_EnablePinNumber, 'A', 24); // diff --git a/g2core/board/gquintic/motate_pin_assignments.h b/g2core/board/gquintic/motate_pin_assignments.h index 57cf4ddc..713163e1 100755 --- a/g2core/board/gquintic/motate_pin_assignments.h +++ b/g2core/board/gquintic/motate_pin_assignments.h @@ -40,15 +40,15 @@ namespace Motate { // Undefined pins will be equivalent to Motate::NullPin, and return 1 for Pin<>::isNull(); -pin_number kSerial_RX = 0; -pin_number kSerial_TX = 1; -pin_number kSerial_RTS = 2; // added later -pin_number kSerial_CTS = 3; // added later +pin_number kSerial_RXPinNumber = 0; +pin_number kSerial_TXPinNumber = 1; +pin_number kSerial_RTSPinNumber = 2; // added later +pin_number kSerial_CTSPinNumber = 3; // added later -pin_number kSerial0_RX = 0; -pin_number kSerial0_TX = 1; -pin_number kSerial0_RTS = 2; // added later -pin_number kSerial0_CTS = 3; // added later +pin_number kSerial0_RXPinNumber = 0; +pin_number kSerial0_TXPinNumber = 1; +pin_number kSerial0_RTSPinNumber = 2; // added later +pin_number kSerial0_CTSPinNumber = 3; // added later pin_number kI2C_SDAPinNumber = 5; pin_number kI2C_SCLPinNumber = 6; diff --git a/g2core/board/printrboardg2/board_xio.cpp b/g2core/board/printrboardg2/board_xio.cpp index f46df5e9..2c217205 100755 --- a/g2core/board/printrboardg2/board_xio.cpp +++ b/g2core/board/printrboardg2/board_xio.cpp @@ -48,7 +48,7 @@ decltype(usb.mixin<0>::Serial) &SerialUSB = usb.mixin<0>::Serial; decltype(usb.mixin<1>::Serial) &SerialUSB1 = usb.mixin<1>::Serial; // 115200 is the default, as well. -//UART Serial {115200, UARTMode::RTSCTSFlowControl}; +//UART Serial {115200, UARTMode::RTSCTSFlowControl}; MOTATE_SET_USB_VENDOR_STRING( u"Synthetos" ) MOTATE_SET_USB_PRODUCT_STRING( u"TinyG v2" ) @@ -63,7 +63,7 @@ Motate::SPI spi; //******** UART ******** #if XIO_HAS_UART -Motate::UART Serial {115200, Motate::UARTMode::RTSCTSFlowControl}; +Motate::UART Serial {115200, Motate::UARTMode::RTSCTSFlowControl}; #endif void board_hardware_init(void) // called 1st diff --git a/g2core/board/printrboardg2/board_xio.h b/g2core/board/printrboardg2/board_xio.h index fc241226..8164ad3c 100755 --- a/g2core/board/printrboardg2/board_xio.h +++ b/g2core/board/printrboardg2/board_xio.h @@ -48,7 +48,7 @@ extern Motate::SPI spi; //******** UART ******** #if XIO_HAS_UART #include "MotateUART.h" -extern Motate::UART Serial; +extern Motate::UART Serial; #endif //******* Generic Functions ******* diff --git a/g2core/board/printrboardg2/motate_pin_assignments.h b/g2core/board/printrboardg2/motate_pin_assignments.h index f3d1e433..d82bcb26 100755 --- a/g2core/board/printrboardg2/motate_pin_assignments.h +++ b/g2core/board/printrboardg2/motate_pin_assignments.h @@ -40,10 +40,10 @@ namespace Motate { // Undefined pins will be equivalent to Motate::NullPin, and return 1 for Pin<>::isNull(); -pin_number kSerial_RX = 0; -pin_number kSerial_TX = 1; -pin_number kSerial_RTS = 2; // added later -pin_number kSerial_CTS = 3; // added later +pin_number kSerial_RXPinNumber = 0; +pin_number kSerial_TXPinNumber = 1; +pin_number kSerial_RTSPinNumber = 2; // added later +pin_number kSerial_CTSPinNumber = 3; // added later pin_number kSerial0_RX = 0; pin_number kSerial0_TX = 1; diff --git a/g2core/board/printrboardg2/printrboardG2v3-pinout.h b/g2core/board/printrboardg2/printrboardG2v3-pinout.h index d2183fdc..85df15db 100755 --- a/g2core/board/printrboardg2/printrboardG2v3-pinout.h +++ b/g2core/board/printrboardg2/printrboardG2v3-pinout.h @@ -130,14 +130,14 @@ _MAKE_MOTATE_PIN(kADC0_PinNumber, 'A', 4); // BED_ADC _MAKE_MOTATE_PIN(kOutput1_PinNumber, 'A', 5); // DO_1 (Extruder1_PWM) _MAKE_MOTATE_PIN(kOutput3_PinNumber, 'A', 6); // DO_3 (Fan1B_PWM) _MAKE_MOTATE_PIN(kOutputSAFE_PinNumber, 'A', 7); // DO_9 (SAFE_PULSES - output from MCU) -_MAKE_MOTATE_PIN(kSerial_RX, 'A', 8); // UART_RX -_MAKE_MOTATE_PIN(kSerial_TX, 'A', 9); // UART_TX +_MAKE_MOTATE_PIN(kSerial_RXPinNumber, 'A', 8); // UART_RX +_MAKE_MOTATE_PIN(kSerial_TXPinNumber, 'A', 9); // UART_TX _MAKE_MOTATE_PIN(kInput5_PinNumber, 'A', 10); // DI_5 (ZMin) _MAKE_MOTATE_PIN(kInput4_PinNumber, 'A', 11); // DI_4 (YMax) _MAKE_MOTATE_PIN(kUnassigned4, 'A', 12); // USART_RX (not used) _MAKE_MOTATE_PIN(kUnassigned5, 'A', 13); // USART_TX (not used) -_MAKE_MOTATE_PIN(kSerial_RTS, 'A', 14); // UART_RTS -_MAKE_MOTATE_PIN(kSerial_CTS, 'A', 15); // UART_CTS +_MAKE_MOTATE_PIN(kSerial_RTSPinNumber, 'A', 14); // UART_RTS +_MAKE_MOTATE_PIN(kSerial_CTSPinNumber, 'A', 15); // UART_CTS _MAKE_MOTATE_PIN(kSocket1_DirPinNumber, 'A', 16); // M1_DIR _MAKE_MOTATE_PIN(kUnassigned6, 'A', 17); // nc _MAKE_MOTATE_PIN(kSocket1_InterruptPinNumber, 'A', 18); // INTERRUPT_OUT diff --git a/g2core/board/sbv300/board_xio.cpp b/g2core/board/sbv300/board_xio.cpp index f586f285..712a89e9 100755 --- a/g2core/board/sbv300/board_xio.cpp +++ b/g2core/board/sbv300/board_xio.cpp @@ -48,7 +48,7 @@ decltype(usb.mixin<0>::Serial) &SerialUSB = usb.mixin<0>::Serial; decltype(usb.mixin<1>::Serial) &SerialUSB1 = usb.mixin<1>::Serial; // 115200 is the default, as well. -//UART Serial {115200, UARTMode::RTSCTSFlowControl}; +//UART Serial {115200, UARTMode::RTSCTSFlowControl}; MOTATE_SET_USB_VENDOR_STRING( {'S' ,'y', 'n', 't', 'h', 'e', 't', 'o', 's'} ) @@ -65,7 +65,7 @@ Motate::SPI spi; //******** UART ******** #if XIO_HAS_UART -Motate::UART Serial{ +Motate::UART Serial{ 115200, Motate::UARTMode::RTSCTSFlowControl}; #endif diff --git a/g2core/board/sbv300/board_xio.h b/g2core/board/sbv300/board_xio.h index 01919f1c..40b42a09 100755 --- a/g2core/board/sbv300/board_xio.h +++ b/g2core/board/sbv300/board_xio.h @@ -48,7 +48,7 @@ extern decltype(usb.mixin<1>::Serial)& SerialUSB1; //******** UART ******** //#include "MotateUART.h" -// extern Motate::UART Serial; +// extern Motate::UART Serial; diff --git a/g2core/board/sbv300/motate_pin_assignments.h b/g2core/board/sbv300/motate_pin_assignments.h index 9268f79b..de1a5dc7 100755 --- a/g2core/board/sbv300/motate_pin_assignments.h +++ b/g2core/board/sbv300/motate_pin_assignments.h @@ -39,10 +39,10 @@ namespace Motate { // NOT ALL OF THESE PINS ARE ON ALL PLATFORMS // Undefined pins will be equivalent to Motate::NullPin, and return 1 for Pin<>::isNull(); -pin_number kSerial_RX = -1; -pin_number kSerial_TX = -1; -pin_number kSerial_RTS = -1; // added later -pin_number kSerial_CTS = -1; // added later +pin_number kSerial_RXPinNumber = -1; +pin_number kSerial_TXPinNumber = -1; +pin_number kSerial_RTSPinNumber = -1; // added later +pin_number kSerial_CTSPinNumber = -1; // added later pin_number kSerial0_RX = -1; pin_number kSerial0_TX = -1; From 94813e5fe46205167afdd0f1e4a52b557db28449 Mon Sep 17 00:00:00 2001 From: Rob Giseburt Date: Fri, 28 Oct 2016 21:48:32 -0500 Subject: [PATCH 22/98] Removing F_CPU and all uses of it. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It’s not longer accurate and mostly unused. It’s use by PWM was inaccurate. --- g2core/board/Archim/hardware.h | 2 -- g2core/board/ArduinoDue/hardware.h | 2 -- g2core/board/G2v9/hardware.h | 2 -- g2core/board/gquadratic/hardware.h | 2 -- g2core/board/gquintic/hardware.h | 2 -- g2core/board/printrboardg2/hardware.h | 2 -- g2core/board/sbv300/hardware.h | 2 -- g2core/pwm.cpp | 8 ++++---- g2core/stepper.cpp | 6 +++--- g2core/stepper.h | 2 +- 10 files changed, 8 insertions(+), 22 deletions(-) diff --git a/g2core/board/Archim/hardware.h b/g2core/board/Archim/hardware.h index 7b3f05c4..d66cae7d 100755 --- a/g2core/board/Archim/hardware.h +++ b/g2core/board/Archim/hardware.h @@ -82,8 +82,6 @@ using Motate::OutputPin; * Global System Defines * *************************/ -#undef F_CPU // CPU clock - set for delays -#define F_CPU 84000000UL #define MILLISECONDS_PER_TICK 1 // MS for system tick (systick * N) #define SYS_ID_DIGITS 12 // actual digits in system ID (up to 16) #define SYS_ID_LEN 16 // total length including dashes and NUL diff --git a/g2core/board/ArduinoDue/hardware.h b/g2core/board/ArduinoDue/hardware.h index ed513965..1b5bbe6b 100755 --- a/g2core/board/ArduinoDue/hardware.h +++ b/g2core/board/ArduinoDue/hardware.h @@ -84,8 +84,6 @@ using Motate::OutputPin; * Global System Defines * *************************/ -#undef F_CPU // CPU clock - set for delays -#define F_CPU 84000000UL #define MILLISECONDS_PER_TICK 1 // MS for system tick (systick * N) #define SYS_ID_DIGITS 12 // actual digits in system ID (up to 16) #define SYS_ID_LEN 16 // total length including dashes and NUL diff --git a/g2core/board/G2v9/hardware.h b/g2core/board/G2v9/hardware.h index 68fa77a5..835dfc44 100755 --- a/g2core/board/G2v9/hardware.h +++ b/g2core/board/G2v9/hardware.h @@ -84,8 +84,6 @@ using Motate::OutputPin; * Global System Defines * *************************/ -#undef F_CPU // CPU clock - set for delays -#define F_CPU 84000000UL #define MILLISECONDS_PER_TICK 1 // MS for system tick (systick * N) #define SYS_ID_DIGITS 12 // actual digits in system ID (up to 16) #define SYS_ID_LEN 16 // total length including dashes and NUL diff --git a/g2core/board/gquadratic/hardware.h b/g2core/board/gquadratic/hardware.h index 3b4fc7bc..069cb2ba 100755 --- a/g2core/board/gquadratic/hardware.h +++ b/g2core/board/gquadratic/hardware.h @@ -85,8 +85,6 @@ using Motate::OutputPin; * Global System Defines * *************************/ -#undef F_CPU // CPU clock - set for delays -#define F_CPU 84000000UL #define MILLISECONDS_PER_TICK 1 // MS for system tick (systick * N) #define SYS_ID_DIGITS 12 // actual digits in system ID (up to 16) #define SYS_ID_LEN 16 // total length including dashes and NUL diff --git a/g2core/board/gquintic/hardware.h b/g2core/board/gquintic/hardware.h index 5dbe9ac3..0fb2d541 100755 --- a/g2core/board/gquintic/hardware.h +++ b/g2core/board/gquintic/hardware.h @@ -83,8 +83,6 @@ using Motate::OutputPin; * Global System Defines * *************************/ -#undef F_CPU // CPU clock - set for delays -#define F_CPU 84000000UL #define MILLISECONDS_PER_TICK 1 // MS for system tick (systick * N) #define SYS_ID_DIGITS 12 // actual digits in system ID (up to 16) #define SYS_ID_LEN 16 // total length including dashes and NUL diff --git a/g2core/board/printrboardg2/hardware.h b/g2core/board/printrboardg2/hardware.h index 91af3784..6046c789 100755 --- a/g2core/board/printrboardg2/hardware.h +++ b/g2core/board/printrboardg2/hardware.h @@ -82,8 +82,6 @@ using Motate::OutputPin; * Global System Defines * *************************/ -#undef F_CPU // CPU clock - set for delays -#define F_CPU 84000000UL #define MILLISECONDS_PER_TICK 1 // MS for system tick (systick * N) #define SYS_ID_DIGITS 12 // actual digits in system ID (up to 16) #define SYS_ID_LEN 16 // total length including dashes and NUL diff --git a/g2core/board/sbv300/hardware.h b/g2core/board/sbv300/hardware.h index 8b930d1e..0e576ab4 100755 --- a/g2core/board/sbv300/hardware.h +++ b/g2core/board/sbv300/hardware.h @@ -82,8 +82,6 @@ using Motate::OutputPin; * Global System Defines * *************************/ -#undef F_CPU // CPU clock - set for delays -#define F_CPU 84000000UL #define MILLISECONDS_PER_TICK 1 // MS for system tick (systick * N) #define SYS_ID_DIGITS 12 // actual digits in system ID (up to 16) #define SYS_ID_LEN 16 // total length including dashes and NUL diff --git a/g2core/pwm.cpp b/g2core/pwm.cpp index f141ea8d..82248fdf 100755 --- a/g2core/pwm.cpp +++ b/g2core/pwm.cpp @@ -45,8 +45,8 @@ static Motate::PWMOutputPin secondary_pwm_pin; //#define PWM_TIMER_TYPE TC1_struct // PWM uses TC1's #define PWM_TIMER_t TC1_t // PWM uses TC1's #define PWM_TIMER_DISABLE 0 // turn timer off (clock = 0 Hz) -#define PWM_MAX_FREQ (F_CPU/256) // max frequency with 8-bits duty cycle precision -#define PWM_MIN_FREQ (F_CPU/64/65536) // min frequency with supported prescaling +//#define PWM_MAX_FREQ (F_CPU/256) // max frequency with 8-bits duty cycle precision +//#define PWM_MIN_FREQ (F_CPU/64/65536) // min frequency with supported prescaling // channel specific defines /* CLKSEL is used to configure default PWM clock operating ranges @@ -95,8 +95,8 @@ void pwm_init() {} stat_t pwm_set_freq(uint8_t chan, float freq) { if (chan > PWMS) { return (STAT_NO_SUCH_DEVICE);} - if (freq < PWM_MIN_FREQ) { return (STAT_INPUT_LESS_THAN_MIN_VALUE);} - if (freq > PWM_MAX_FREQ) { return (STAT_INPUT_EXCEEDS_MAX_VALUE);} + //if (freq < PWM_MIN_FREQ) { return (STAT_INPUT_LESS_THAN_MIN_VALUE);} + //if (freq > PWM_MAX_FREQ) { return (STAT_INPUT_EXCEEDS_MAX_VALUE);} if (chan == PWM_1) { spindle_pwm_pin.setFrequency(freq); diff --git a/g2core/stepper.cpp b/g2core/stepper.cpp index 32c70d5e..74b432df 100644 --- a/g2core/stepper.cpp +++ b/g2core/stepper.cpp @@ -51,7 +51,7 @@ static stRunSingleton_t st_run; static void _load_move(void); // handy macro -#define _f_to_period(f) (uint16_t)((float)F_CPU / (float)f) +//#define _f_to_period(f) (uint16_t)((float)F_CPU / (float)f) /**** Setup motate ****/ @@ -658,7 +658,7 @@ stat_t st_prep_line(float travel_steps[], float following_error[], float segment // - dda_ticks is the integer number of DDA clock ticks needed to play out the segment // - ticks_X_substeps is the maximum depth of the DDA accumulator (as a negative number) - st_pre.dda_period = _f_to_period(FREQUENCY_DDA); // FYI: this is a constant + //st_pre.dda_period = _f_to_period(FREQUENCY_DDA); // FYI: this is a constant st_pre.dda_ticks = (int32_t)(segment_time * 60 * FREQUENCY_DDA);// NB: converts minutes to seconds st_pre.dda_ticks_X_substeps = st_pre.dda_ticks * DDA_SUBSTEPS; @@ -753,7 +753,7 @@ void st_prep_command(void *bf) void st_prep_dwell(float microseconds) { st_pre.block_type = BLOCK_TYPE_DWELL; - st_pre.dda_period = _f_to_period(FREQUENCY_DWELL); + //st_pre.dda_period = _f_to_period(FREQUENCY_DWELL); st_pre.dda_ticks = (uint32_t)((microseconds/1000000) * FREQUENCY_DWELL); st_pre.buffer_state = PREP_BUFFER_OWNED_BY_LOADER; // signal that prep buffer is ready } diff --git a/g2core/stepper.h b/g2core/stepper.h index 0a973ad7..6c1967dd 100644 --- a/g2core/stepper.h +++ b/g2core/stepper.h @@ -413,7 +413,7 @@ typedef struct stPrepSingleton { struct mpBuffer *bf; // static pointer to relevant buffer blockType block_type; // move type (requires planner.h) - uint16_t dda_period; // DDA or dwell clock period setting + //uint16_t dda_period; // DDA or dwell clock period setting (No longer used) uint32_t dda_ticks; // DDA or dwell ticks for the move uint32_t dda_ticks_X_substeps; // DDA ticks scaled by substep factor stPrepMotor_t mot[MOTORS]; // prep time motor structs From dffc597a198372837246fc36a2ab1f896581a1e4 Mon Sep 17 00:00:00 2001 From: Rob Giseburt Date: Fri, 28 Oct 2016 22:15:42 -0500 Subject: [PATCH 23/98] Fix capitalization errors in g2v9 configs. --- g2core/board/G2v9.mk | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/g2core/board/G2v9.mk b/g2core/board/G2v9.mk index 79084ecd..0cd14357 100755 --- a/g2core/board/G2v9.mk +++ b/g2core/board/G2v9.mk @@ -6,7 +6,7 @@ # make BOARD=g2v9k # You can also choose a CONFIG from boards.mk: -# make CONFIG=ShapeokoDualY BOARD=G2v9k +# make CONFIG=ShapeokoDualY BOARD=g2v9k @@ -15,13 +15,13 @@ ifeq ("$(BOARD)","g2v9i") BASE_BOARD=g2v9 - DEVICE_DEFINES += MOTATE_BOARD="G2v9i" + DEVICE_DEFINES += MOTATE_BOARD="g2v9i" DEVICE_DEFINES += SETTINGS_FILE=${SETTINGS_FILE} endif ifeq ("$(BOARD)","g2v9k") BASE_BOARD=g2v9 - DEVICE_DEFINES += MOTATE_BOARD="G2v9k" + DEVICE_DEFINES += MOTATE_BOARD="g2v9k" DEVICE_DEFINES += SETTINGS_FILE=${SETTINGS_FILE} endif From 8c16ae4aba56478f723fb1c3fab5f6aecd76f982 Mon Sep 17 00:00:00 2001 From: Rob Giseburt Date: Fri, 28 Oct 2016 22:21:39 -0500 Subject: [PATCH 24/98] Fixed the correction to G2v9 in the last commit. --- g2core/board/G2v9.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/g2core/board/G2v9.mk b/g2core/board/G2v9.mk index 0cd14357..a99f333c 100755 --- a/g2core/board/G2v9.mk +++ b/g2core/board/G2v9.mk @@ -15,13 +15,13 @@ ifeq ("$(BOARD)","g2v9i") BASE_BOARD=g2v9 - DEVICE_DEFINES += MOTATE_BOARD="g2v9i" + DEVICE_DEFINES += MOTATE_BOARD="G2v9i" DEVICE_DEFINES += SETTINGS_FILE=${SETTINGS_FILE} endif ifeq ("$(BOARD)","g2v9k") BASE_BOARD=g2v9 - DEVICE_DEFINES += MOTATE_BOARD="g2v9k" + DEVICE_DEFINES += MOTATE_BOARD="G2v9k" DEVICE_DEFINES += SETTINGS_FILE=${SETTINGS_FILE} endif From 59e4d07c54619d6de39bc010e16375b9e8c77228 Mon Sep 17 00:00:00 2001 From: Rob Giseburt Date: Sun, 6 Nov 2016 15:59:59 -0600 Subject: [PATCH 25/98] Made motion_mode an enum type. Removed unused recip_jerk. --- g2core/canonical_machine.cpp | 4 ++-- g2core/canonical_machine.h | 12 ++++++------ g2core/gcode_parser.cpp | 1 + g2core/plan_arc.cpp | 2 +- 4 files changed, 10 insertions(+), 9 deletions(-) diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index ec7a3cb8..9892da8a 100755 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -225,7 +225,7 @@ cmCombinedState cm_get_combined_state() * ACTIVE_MODEL cm.am // active model pointer is maintained by state management */ uint32_t cm_get_linenum(const GCodeState_t *gcode_state) { return gcode_state->linenum;} -uint8_t cm_get_motion_mode(const GCodeState_t *gcode_state) { return gcode_state->motion_mode;} +cmMotionMode cm_get_motion_mode(const GCodeState_t *gcode_state) { return gcode_state->motion_mode;} uint8_t cm_get_coord_system(const GCodeState_t *gcode_state) { return gcode_state->coord_system;} uint8_t cm_get_units_mode(const GCodeState_t *gcode_state) { return gcode_state->units_mode;} uint8_t cm_get_select_plane(const GCodeState_t *gcode_state) { return gcode_state->select_plane;} @@ -2311,7 +2311,7 @@ void _cm_recalc_max_junction_accel(const uint8_t axis) { void cm_set_axis_jerk(const uint8_t axis, const float jerk) { cm.a[axis].jerk_max = jerk; - cm.a[axis].recip_jerk = 1/(jerk * JERK_MULTIPLIER); + //cm.a[axis].recip_jerk = 1/(jerk * JERK_MULTIPLIER); // Must recalculate the max_junction_accel now that the jerk has changed. _cm_recalc_max_junction_accel(axis); diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index 61c2b8f5..509df9d4 100755 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -320,7 +320,7 @@ typedef enum { // axis modes (ordered: see _cm_get_feed_time()) */ typedef struct GCodeState { // Gcode model state - used by model, planning and runtime uint32_t linenum; // Gcode block line number - uint8_t motion_mode; // Group1: G0, G1, G2, G3, G38.2, G80, G81, + cmMotionMode motion_mode; // Group1: G0, G1, G2, G3, G38.2, G80, G81, // G82, G83 G84, G85, G86, G87, G88, G89 float target[AXES]; // XYZABC where the move should go @@ -343,7 +343,7 @@ typedef struct GCodeState { // Gcode model state - used by model, pl void reset() { linenum = 0; - motion_mode = 0; + motion_mode = MOTION_MODE_STRAIGHT_TRAVERSE; for (uint8_t i = 0; i< AXES; i++) { target[i] = 0.0; @@ -397,7 +397,7 @@ typedef struct GCodeStateExtended { // Gcode dynamic state extensions - used typedef struct GCodeInput { // Gcode model inputs - meaning depends on context uint8_t next_action; // handles G modal group 1 moves & non-modals - uint8_t motion_mode; // Group1: G0, G1, G2, G3, G38.2, G80, G81, G82 + cmMotionMode motion_mode; // Group1: G0, G1, G2, G3, G38.2, G80, G81, G82 // G83, G84, G85, G86, G87, G88, G89 uint8_t program_flow; // used only by the gcode_parser @@ -497,7 +497,7 @@ typedef struct cmAxis { float travel_min; // min work envelope for soft limits float jerk_max; // max jerk (Jm) in mm/min^3 divided by 1 million float jerk_high; // high speed deceleration jerk (Jh) in mm/min^3 divided by 1 million - float recip_jerk; // stored reciprocal of current jerk value - has the million in it + //float recip_jerk; // stored reciprocal of current jerk value - has the million in it float max_junction_accel; // high speed deceleration jerk (Jh) in mm/min^3 divided by 1 million float junction_dev; // aka cornering delta -- DEPRICATED! float radius; // radius in mm for rotary axis modes @@ -606,7 +606,7 @@ float cm_get_axis_jerk(const uint8_t axis); void cm_set_axis_jerk(const uint8_t axis, const float jerk); uint32_t cm_get_linenum(const GCodeState_t *gcode_state); -uint8_t cm_get_motion_mode(const GCodeState_t *gcode_state); +cmMotionMode cm_get_motion_mode(const GCodeState_t *gcode_state); uint8_t cm_get_coord_system(const GCodeState_t *gcode_state); uint8_t cm_get_units_mode(const GCodeState_t *gcode_state); uint8_t cm_get_select_plane(const GCodeState_t *gcode_state); @@ -701,7 +701,7 @@ stat_t cm_arc_feed(const float target[], const bool target_f[], // G const float radius, const bool radius_f, // radius if radius mode const float P_word, const bool P_word_f, // parameter const bool modal_g1_f, // modal group flag for motion group - const uint8_t motion_mode); // defined motion mode + const cmMotionMode motion_mode); // defined motion mode // Spindle Functions (4.3.7) // see spindle.h for spindle functions - which would go right here diff --git a/g2core/gcode_parser.cpp b/g2core/gcode_parser.cpp index c8095d18..cd591cda 100755 --- a/g2core/gcode_parser.cpp +++ b/g2core/gcode_parser.cpp @@ -697,6 +697,7 @@ static stat_t _execute_gcode_block(char *active_comment) cm.gn.motion_mode); break; } + default: break; } cm_set_absolute_override(MODEL, ABSOLUTE_OVERRIDE_OFF); // un-set absolute override once the move is planned } diff --git a/g2core/plan_arc.cpp b/g2core/plan_arc.cpp index f7c3296f..09977d6a 100755 --- a/g2core/plan_arc.cpp +++ b/g2core/plan_arc.cpp @@ -108,7 +108,7 @@ stat_t cm_arc_feed(const float target[], const bool target_f[], // target en const float radius, const bool radius_f, // radius if radius mode const float P_word, const bool P_word_f, // parameter const bool modal_g1_f, // modal group flag for motion group - const uint8_t motion_mode) // defined motion mode + const cmMotionMode motion_mode) // defined motion mode { // Start setting up the arc and trapping arc specification errors From c9942e5c8328ea12c17f08b0c99bba999dd8a689 Mon Sep 17 00:00:00 2001 From: Rob Giseburt Date: Sun, 6 Nov 2016 16:01:20 -0600 Subject: [PATCH 26/98] Marked Stepper subclasses as `final` for minor optimization gains. --- g2core/device/step_dir_driver/step_dir_driver.h | 2 +- g2core/device/step_dir_hobbyservo/step_dir_hobbyservo.h | 2 +- g2core/device/trinamic/tmc2130.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/g2core/device/step_dir_driver/step_dir_driver.h b/g2core/device/step_dir_driver/step_dir_driver.h index 390cdb65..da3cfc1e 100644 --- a/g2core/device/step_dir_driver/step_dir_driver.h +++ b/g2core/device/step_dir_driver/step_dir_driver.h @@ -49,7 +49,7 @@ template -struct StepDirStepper : Stepper { +struct StepDirStepper final : Stepper { /* stepper pin assignments */ OutputPin _step; diff --git a/g2core/device/step_dir_hobbyservo/step_dir_hobbyservo.h b/g2core/device/step_dir_hobbyservo/step_dir_hobbyservo.h index 735cf424..d631b558 100644 --- a/g2core/device/step_dir_hobbyservo/step_dir_hobbyservo.h +++ b/g2core/device/step_dir_hobbyservo/step_dir_hobbyservo.h @@ -43,7 +43,7 @@ using Motate::Timeout; // Motor structures template // Setup a stepper template to hold our pins -struct StepDirHobbyServo : Stepper { +struct StepDirHobbyServo final : Stepper { /* stepper pin assignments */ int16_t _microsteps_per_step = 1; diff --git a/g2core/device/trinamic/tmc2130.h b/g2core/device/trinamic/tmc2130.h index aa6580bd..8d4b10fb 100644 --- a/g2core/device/trinamic/tmc2130.h +++ b/g2core/device/trinamic/tmc2130.h @@ -46,7 +46,7 @@ template -struct Trinamic2130 : Stepper { +struct Trinamic2130 final : Stepper { // Pins that are directly managed OutputPin _step; OutputPin _dir; From 0e67903521e8e0d0802f23e6041bc4fec37aca02 Mon Sep 17 00:00:00 2001 From: Rob Giseburt Date: Sun, 6 Nov 2016 16:03:03 -0600 Subject: [PATCH 27/98] Made TMC2130 driver setup and queue messages as two steps. (Debuggability.) --- g2core/device/trinamic/tmc2130.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/g2core/device/trinamic/tmc2130.h b/g2core/device/trinamic/tmc2130.h index 8d4b10fb..9c541851 100644 --- a/g2core/device/trinamic/tmc2130.h +++ b/g2core/device/trinamic/tmc2130.h @@ -501,7 +501,8 @@ struct Trinamic2130 final : Stepper { } out_buffer.addr = (uint8_t) next_reg; - _device.queueMessage(_message.setup((uint8_t *)&out_buffer, (uint8_t *)&in_buffer, 5, SPIMessage::DeassertAfter, SPIMessage::KeepTransaction)); + _message.setup((uint8_t *)&out_buffer, (uint8_t *)&in_buffer, 5, SPIMessage::DeassertAfter, SPIMessage::KeepTransaction); + _device.queueMessage(&_message); }; void _doneReadingCallback() @@ -538,7 +539,7 @@ struct Trinamic2130 final : Stepper { _reading_only = false; _transmitting = false; - _startNextReadWrite(); + //_startNextReadWrite(); }; void init() override From baaeb798f64458c5fc712ba458614983da53254a Mon Sep 17 00:00:00 2001 From: Rob Giseburt Date: Sun, 6 Nov 2016 16:03:40 -0600 Subject: [PATCH 28/98] New motate for SamS70 fixes to DMA, SPI, ServiceCall, and Timers. --- Motate | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Motate b/Motate index 1e53d435..8ceefaab 160000 --- a/Motate +++ b/Motate @@ -1 +1 @@ -Subproject commit 1e53d435c14c5eb753da72d7d9176192322dbc02 +Subproject commit 8ceefaab12c238dbe30a0305b16f4157e1ec8a23 From 1258e2cfec89200624c2e0f2d8596a6030d28f86 Mon Sep 17 00:00:00 2001 From: Rob Giseburt Date: Sun, 6 Nov 2016 16:04:10 -0600 Subject: [PATCH 29/98] gQuintic somewhat functional. (Much more testing needed.) --- g2core/board/gquintic/board_stepper.h | 4 ++-- g2core/board/gquintic/hardware.h | 4 +++- g2core/board/gquintic/motate_pin_assignments.h | 6 ------ 3 files changed, 5 insertions(+), 9 deletions(-) diff --git a/g2core/board/gquintic/board_stepper.h b/g2core/board/gquintic/board_stepper.h index f1b90dd3..23b8c4db 100755 --- a/g2core/board/gquintic/board_stepper.h +++ b/g2core/board/gquintic/board_stepper.h @@ -31,7 +31,7 @@ #include "hardware.h" // for MOTORS #include "tmc2130.h" -typedef Motate::SPIBus SPIBus_used_t; +typedef Motate::SPIBus SPIBus_used_t; // These are identical to board_stepper.h, except for the word "extern" and the initialization extern Trinamic2130 load_timer_type; // request load timer in stepper.c typedef ServiceCall<1> exec_timer_type; // request exec timer in stepper.cpp typedef ServiceCall<2> fwd_plan_timer_type; // request exec timer in stepper.cpp +Motate::service_call_number kSPI_ServiceCallNumber = 3; + // Pin assignments pin_number indicator_led_pin_num = Motate::kLED_USBRXPinNumber; diff --git a/g2core/board/gquintic/motate_pin_assignments.h b/g2core/board/gquintic/motate_pin_assignments.h index 713163e1..af029d31 100755 --- a/g2core/board/gquintic/motate_pin_assignments.h +++ b/g2core/board/gquintic/motate_pin_assignments.h @@ -240,12 +240,6 @@ pin_number kUnassigned4 = 251; pin_number kUnassigned3 = 252; pin_number kUnassigned2 = 253; pin_number kUnassigned1 = 254; // 254 is the max.. Do not exceed this number - -/** NOTE: When adding pin definitions here, they must be - * added to ALL board pin assignment files, even if - * they are defined as -1. - **/ - } // namespace Motate // For the SAM3X8C boards, we actually use the same NUMBERING, but have different number to pin linkages From 1e97dfca1b7cb1d6d30945c2133b00cad7c2a4ed Mon Sep 17 00:00:00 2001 From: Rob Giseburt Date: Sun, 6 Nov 2016 16:05:02 -0600 Subject: [PATCH 30/98] Added experimental TRAVERSE_AT_HIGH_JERK setting (defaults to off). --- g2core/plan_line.cpp | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/g2core/plan_line.cpp b/g2core/plan_line.cpp index 9737de72..dbda5949 100755 --- a/g2core/plan_line.cpp +++ b/g2core/plan_line.cpp @@ -35,6 +35,7 @@ #include "report.h" #include "util.h" #include "spindle.h" +#include "settings.h" #include "xio.h" @@ -502,7 +503,22 @@ static void _calculate_jerk(mpBuf_t* bf) for (uint8_t axis = 0; axis < AXES; axis++) { if (fabs(bf->unit[axis]) > 0) { // if this axis is participating in the move - jerk = cm.a[axis].jerk_max / fabs(bf->unit[axis]); + float axis_jerk = 0; +#ifdef TRAVERSE_AT_HIGH_JERK +#warning using experimental feature TRAVERSE_AT_HIGH_JERK! + switch (bf->gm.motion_mode) { + case MOTION_MODE_STRAIGHT_TRAVERSE: + //case MOTION_MODE_STRAIGHT_PROBE: // <-- not sure on this one + axis_jerk = cm.a[axis].jerk_high; + break; + default: + axis_jerk = cm.a[axis].jerk_max; + } +#else + axis_jerk = cm.a[axis].jerk_max; +#endif + + jerk = axis_jerk / fabs(bf->unit[axis]); if (jerk < bf->jerk) { bf->jerk = jerk; // bf->jerk_axis = axis; // +++ diagnostic From e347dee0824ccf2873d4c11c87e4ced3d52737d3 Mon Sep 17 00:00:00 2001 From: Rob Giseburt Date: Tue, 15 Nov 2016 14:45:08 -0600 Subject: [PATCH 31/98] Update Motate for minor MotateBuffer changes --- Motate | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Motate b/Motate index 8ceefaab..437fedea 160000 --- a/Motate +++ b/Motate @@ -1 +1 @@ -Subproject commit 8ceefaab12c238dbe30a0305b16f4157e1ec8a23 +Subproject commit 437fedeaaa1f92c4dee308627dc52a2bc839b28f From 1bc31a6bfd70d412cec7dd68014faade0b45a11f Mon Sep 17 00:00:00 2001 From: Rob Giseburt Date: Tue, 15 Nov 2016 14:47:07 -0600 Subject: [PATCH 32/98] Cleanup and debug of xio. Hunting a crasher. --- g2core/xio.cpp | 56 ++++++++++++++++++++++++++++++++++---------------- 1 file changed, 38 insertions(+), 18 deletions(-) diff --git a/g2core/xio.cpp b/g2core/xio.cpp index 1b94aea7..dcb19ff1 100755 --- a/g2core/xio.cpp +++ b/g2core/xio.cpp @@ -366,7 +366,7 @@ extern xio_t xio; // LineRXBuffer takes the Motate RXBuffer (which handles "transfers", usually DMA), and adds G2 line-reading // semantics to it. template -struct LineRXBuffer : RXBuffer<_size, owner_type, char> { // reserve size of 128bytes +struct LineRXBuffer : RXBuffer<_size, owner_type, char> { typedef RXBuffer<_size, owner_type, char> parent_type; // SUPPORTING STRUCTURES @@ -387,7 +387,6 @@ struct LineRXBuffer : RXBuffer<_size, owner_type, char> { // reserve size of 128 uint16_t _get_next_read_offset() { return ((_read_offset + 1) & (_size-1)); }; - // Convenience function for reset void reset() { _status = HEADER_FREE; @@ -395,6 +394,13 @@ struct LineRXBuffer : RXBuffer<_size, owner_type, char> { // reserve size of 128 _line_count = 0; _read_offset = 0; }; + + // Handle prep in one place + void prep(int16_t start_of_line) { + _status = HEADER_PREPPED; + + _read_offset = start_of_line; + }; }; @@ -432,7 +438,10 @@ struct LineRXBuffer : RXBuffer<_size, owner_type, char> { // reserve size of 128 LineRXBuffer(owner_type owner) : parent_type{owner} {}; - void init() { parent_type::init(); }; + void init() { + parent_type::init(); + _at_start_of_line = true; + }; uint8_t _get_next_write_header_index() { return ((_write_header_index + 1) & (_header_count-1)); }; uint8_t _get_next_first_header_index() { return ((_first_header_index + 1) & (_header_count-1)); }; @@ -447,7 +456,7 @@ struct LineRXBuffer : RXBuffer<_size, owner_type, char> { // reserve size of 128 _first_header->_is_processing = false; if ((_first_header->_status == HEADER_FULL) && (_first_header->_line_count == 0)) { - _first_header->reset(); + _first_header->reset(); // free it _first_header_index = _get_next_first_header_index(); // Point _first_header to the new first header @@ -459,29 +468,29 @@ struct LineRXBuffer : RXBuffer<_size, owner_type, char> { // reserve size of 128 } if ((_write_header_index == _first_header_index) && (_first_header->_status == HEADER_FREE)) { - // PREP it - _first_header->_status = HEADER_PREPPED; + _first_header->prep(_line_start_offset); - _at_start_of_line = true; - _first_header->_read_offset = _line_start_offset; + //_at_start_of_line = true; _restartTransfer(); } }; + // check that we have a valid and available write header and switch to it if we can + // returns true if one was or has been made available, otherwise returns false bool _check_write_header() { - // _status cannot be PROCESSING, since we already cleared those in _free_unused_space() if (_headers[_write_header_index]._status == HEADER_FULL) { uint8_t _next_write_header_index = _get_next_write_header_index(); if (_next_write_header_index == _first_header_index) { // we're full full return false; } - _write_header_index = _next_write_header_index; - - auto _write_header = &_headers[_write_header_index]; - _write_header->_status = HEADER_PREPPED; - _at_start_of_line = true; - _write_header->_read_offset = _line_start_offset; + auto _potential_write_header = &_headers[_next_write_header_index]; + if (_potential_write_header->_status == HEADER_FREE) { + _write_header_index = _next_write_header_index; + _potential_write_header->prep(_line_start_offset); + return true; + } + return false; } return true; }; @@ -547,6 +556,10 @@ struct LineRXBuffer : RXBuffer<_size, owner_type, char> { // reserve size of 128 _last_scan_offset = _scan_offset; while (_is_more_to_scan()) { auto write_header = &_headers[_write_header_index]; + // This is to simply tests later + bool is_adding_to_control_header = + ((HEADER_FILLING == write_header->_status) && + write_header->_is_control); bool ends_line = false; bool is_control = false; @@ -575,7 +588,8 @@ struct LineRXBuffer : RXBuffer<_size, owner_type, char> { // reserve size of 128 (c == ENQ) || // request ENQ/ack (c == CHAR_RESET) || // ^X - reset (aka cancel, terminate) (c == CHAR_ALARM) || // ^D - request job kill (end of transmission) - (cm_has_hold() && c == '%') // flush (only in feedhold) + ((cm_has_hold() || is_adding_to_control_header) && + c == '%') // flush (only in feedhold or part of control header) ) { // Special case: if we're NOT _at_start_of_line, we need to move the @@ -588,11 +602,15 @@ struct LineRXBuffer : RXBuffer<_size, owner_type, char> { // reserve size of 128 _data[next_copy_offset] = _data[copy_offset]; copy_offset = next_copy_offset; } + // Copy the single character to the first character _data[_line_start_offset] = c; + // and note that we are now at the start of the line + _at_start_of_line = true; + // oh, and we need to actually be at the beginning of the line + _scan_offset = _line_start_offset; } - _line_start_offset = _scan_offset; // single-character control is_control = true; @@ -621,7 +639,7 @@ struct LineRXBuffer : RXBuffer<_size, owner_type, char> { // reserve size of 128 } - if (write_header->_status == HEADER_PREPPED) { + if (HEADER_PREPPED == write_header->_status) { write_header->_is_control = is_control; write_header->_status = HEADER_FILLING; } @@ -797,6 +815,8 @@ struct LineRXBuffer : RXBuffer<_size, owner_type, char> { // reserve size of 128 template struct xioDeviceWrapper : xioDeviceWrapperBase { // describes a device for reading and writing Device _dev; + + // TODO - make _buffer_size, _header_count, and _line_buffer_size configurable LineRXBuffer<512, Device> _rx_buffer; TXBuffer<512, Device> _tx_buffer; From 28f08573690026950be48ee85c36275ff028da8e Mon Sep 17 00:00:00 2001 From: Rob Giseburt Date: Wed, 16 Nov 2016 17:11:01 -0600 Subject: [PATCH 33/98] Update Motate for minor tweaks --- Motate | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Motate b/Motate index 437fedea..d487230e 160000 --- a/Motate +++ b/Motate @@ -1 +1 @@ -Subproject commit 437fedeaaa1f92c4dee308627dc52a2bc839b28f +Subproject commit d487230e6111de50db9cd3594d28d6c078c06384 From 5bf4e8b3f6baca64f2881b34e0afdb9179aef71f Mon Sep 17 00:00:00 2001 From: Rob Giseburt Date: Wed, 16 Nov 2016 17:11:37 -0600 Subject: [PATCH 34/98] =?UTF-8?q?rewrite=20xio=20(remove=20=E2=80=9Cheader?= =?UTF-8?q?s=E2=80=9D=20concept).=20Still=20contains=20debugging=20code!?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- g2core/xio.cpp | 401 +++++++++++++++++++------------------------------ 1 file changed, 156 insertions(+), 245 deletions(-) diff --git a/g2core/xio.cpp b/g2core/xio.cpp index dcb19ff1..f4263591 100755 --- a/g2core/xio.cpp +++ b/g2core/xio.cpp @@ -281,6 +281,9 @@ struct xio_t { } } +#pragma GCC push_options +#pragma GCC optimize ("O0") + /* * readline() - read a complete line from a device * @@ -349,6 +352,8 @@ struct xio_t { return (NULL); }; + #pragma GCC pop_options + uint16_t magic_end; }; @@ -362,6 +367,8 @@ extern xio_t xio; // See here for a discussion of what this means if you are not familiar with C++ // https://github.com/synthetos/g2/wiki/Dual-Endpoint-USB-Internals#c-classes-virtual-functions-and-inheritance +#pragma GCC push_options +#pragma GCC optimize ("O0") // LineRXBuffer takes the Motate RXBuffer (which handles "transfers", usually DMA), and adds G2 line-reading // semantics to it. @@ -369,41 +376,6 @@ template { typedef RXBuffer<_size, owner_type, char> parent_type; - // SUPPORTING STRUCTURES - enum _LinesHeaderStatus_t { - HEADER_FREE, - HEADER_PREPPED, - HEADER_FILLING, - HEADER_FULL - }; - - struct _LinesHeader { - _LinesHeaderStatus_t _status; - bool _is_control; - bool _is_processing; - - int16_t _line_count; // number of lines in this group of lines - int16_t _read_offset; // start of the next line to read (first char past PROCESSING line) - - uint16_t _get_next_read_offset() { return ((_read_offset + 1) & (_size-1)); }; - - // Convenience function for reset - void reset() { - _status = HEADER_FREE; - _is_control = false; - _line_count = 0; - _read_offset = 0; - }; - - // Handle prep in one place - void prep(int16_t start_of_line) { - _status = HEADER_PREPPED; - - _read_offset = start_of_line; - }; - }; - - // Let's help the compiler clarify what we mean by a few things: // (This is because of the templating, it needs a little extra clarification.) using parent_type::_data; @@ -418,22 +390,19 @@ struct LineRXBuffer : RXBuffer<_size, owner_type, char> { // START OF LineRXBuffer PROPER static_assert(((_header_count-1)&_header_count)==0, "_header_count must be 2^N"); - char _line_buffer[_line_buffer_size]; // hold excatly one line to return + char _line_buffer[_line_buffer_size]; // hold exactly one line to return uint32_t _line_end_guard = 0xBEEF; // General term usage: // * "index" indicates it's in to _headers array // * "offset" means it's a character in the _data array - - _LinesHeader _headers[_header_count]; // and array that we'll use as a ring buffer of _LinesHeaders - uint8_t _first_header_index; // index into the array of the (current) first item of _headers - uint8_t _write_header_index; // index into the array of the item of _headers we are writing too (unless it's FULL) - uint16_t _scan_offset; // offset into data of the last character scanned uint16_t _line_start_offset; // offset into first character of the line bool _at_start_of_line; // true if the last character scanned was the end of a line + uint16_t _lines_found; // count of complete non-control lines that were found during scanning. + volatile uint16_t _last_scan_offset; // DEBUGGING LineRXBuffer(owner_type owner) : parent_type{owner} {}; @@ -443,58 +412,6 @@ struct LineRXBuffer : RXBuffer<_size, owner_type, char> { _at_start_of_line = true; }; - uint8_t _get_next_write_header_index() { return ((_write_header_index + 1) & (_header_count-1)); }; - uint8_t _get_next_first_header_index() { return ((_first_header_index + 1) & (_header_count-1)); }; - uint8_t _get_next_header_index(uint8_t indx) { return ((indx + 1) & (_header_count-1)); }; - - void _free_unused_space() { - // Headers that were processing OR are now completely empty are now safe to clear,m - // but only in order. - auto _first_header = &_headers[_first_header_index]; - while ((_first_header->_is_processing) || ((_first_header->_status == HEADER_FULL) && (_first_header->_line_count == 0))) { - _read_offset = _first_header->_read_offset; - _first_header->_is_processing = false; - - if ((_first_header->_status == HEADER_FULL) && (_first_header->_line_count == 0)) { - _first_header->reset(); // free it - _first_header_index = _get_next_first_header_index(); - - // Point _first_header to the new first header - _first_header = &_headers[_first_header_index]; - } else { - // We can only clear into the next one if we completely clear this one - break; - } - } - - if ((_write_header_index == _first_header_index) && (_first_header->_status == HEADER_FREE)) { - _first_header->prep(_line_start_offset); - - //_at_start_of_line = true; - - _restartTransfer(); - } - }; - - // check that we have a valid and available write header and switch to it if we can - // returns true if one was or has been made available, otherwise returns false - bool _check_write_header() { - if (_headers[_write_header_index]._status == HEADER_FULL) { - uint8_t _next_write_header_index = _get_next_write_header_index(); - if (_next_write_header_index == _first_header_index) { // we're full full - return false; - } - auto _potential_write_header = &_headers[_next_write_header_index]; - if (_potential_write_header->_status == HEADER_FREE) { - _write_header_index = _next_write_header_index; - _potential_write_header->prep(_line_start_offset); - return true; - } - return false; - } - return true; - }; - uint16_t _get_next_scan_offset() { return ((_scan_offset + 1) & (_size-1)); } @@ -525,21 +442,46 @@ struct LineRXBuffer : RXBuffer<_size, owner_type, char> { // This function is designed to be able to exit from almost any point, and // come back in and resume where it left off. This allows it to scan to the // end of the buffer, then exit. - void _scan_buffer() { - _free_unused_space(); + // + // We return true if we found a control line. + // That control line starts at the character at _line_start_offset, and includes the characters up to + // _scan_offset-1. If there are multiple line-ending chara ("\r\n" for example) _scan_offset will point to the + // *first*. - if (!_check_write_header()) { return; } + // With ascii art (where "." means "invalid data" or "don't care"): + // Example 1 of _scan_buffer() == true: + // _data = "G0X10\n{jvm:5}\n{xvm:1200}\nG0Y10\nG1Z......" + // ^ ^ + // | | + // _line_start_offset | + // _scan_offset + // Example 2 of _scan_buffer() == true: + // _data = "G0X10\n.........{xvm:1200}\nG0Y10\nG1Z......" + // ^ ^ + // | | + // _line_start_offset | + // _scan_offset + + // Example 2 of _scan_buffer() == true: + // _data = "G0X10\n!......" + // ^^ + // || + // _line_start_offset| + // _scan_offset + + // For _scan_buffer() == false, IGNORE _line_start_offset and _scan_offset!!! + // Only use _read_offset, and use _lines_found>0 to determine if _data contains a line to return. + // Also note that _read_offset needs to be moved once the data is copied to _line_buffer! + + bool _scan_buffer() { /* Explanation of cases and how we handle it. * - * Our first task in this loop is two fold: + * Our first task in this loop is two fold (done at the same time): * A) Scan for the next complete line, then classify the line. * B) Scan for a single-character command (!~% ^D, etc), then classify that as a line. * - * Out next task is to then to manage the headers with this new information. We either: - * 1) Add the line to the header, if the write header is FILLING and has the same classification. - * 2) Add the line to the header, and classify it, if the write header is PENDING. - * 3) Mark the current write header as FULL, and then (2) on the next one. + * If we find a line that classifies as "control" then we return true and stop scanning. * * We also have a constraint that we may run out of character at any time. This is okay, and enough * state is kept that we can enter the function at any point with new characters and get the same results. @@ -555,12 +497,6 @@ struct LineRXBuffer : RXBuffer<_size, owner_type, char> { */ _last_scan_offset = _scan_offset; while (_is_more_to_scan()) { - auto write_header = &_headers[_write_header_index]; - // This is to simply tests later - bool is_adding_to_control_header = - ((HEADER_FILLING == write_header->_status) && - write_header->_is_control); - bool ends_line = false; bool is_control = false; @@ -588,8 +524,7 @@ struct LineRXBuffer : RXBuffer<_size, owner_type, char> { (c == ENQ) || // request ENQ/ack (c == CHAR_RESET) || // ^X - reset (aka cancel, terminate) (c == CHAR_ALARM) || // ^D - request job kill (end of transmission) - ((cm_has_hold() || is_adding_to_control_header) && - c == '%') // flush (only in feedhold or part of control header) + (cm_has_hold() && c == '%') // flush (only in feedhold or part of control header) ) { // Special case: if we're NOT _at_start_of_line, we need to move the @@ -611,7 +546,6 @@ struct LineRXBuffer : RXBuffer<_size, owner_type, char> { _scan_offset = _line_start_offset; } - // single-character control is_control = true; ends_line = true; @@ -624,7 +558,14 @@ struct LineRXBuffer : RXBuffer<_size, owner_type, char> { _at_start_of_line = false; } + // bump the _scan_offset + _scan_offset = _get_next_scan_offset(); + if (ends_line) { + // _scan_offset is now one past the end of the line, + // which means it is at the start of a new one + _at_start_of_line = true; + // Here we classify the line. // If we are is_control is already true, it's an already classified // single-character command. @@ -638,149 +579,119 @@ struct LineRXBuffer : RXBuffer<_size, owner_type, char> { // TODO --- } - - if (HEADER_PREPPED == write_header->_status) { - write_header->_is_control = is_control; - write_header->_status = HEADER_FILLING; + if (is_control) { + // we found a control + return true; + } else { + // we did find one more line, though. + _lines_found++; } - else if (write_header->_is_control != is_control) - { - // This line goes into the next header. - // Now we have to end this _write_header and grab another. - - write_header->_status = HEADER_FULL; - if (!_check_write_header()) { - // We just bail if there's not another header available. - return; - } - - // Update the pointer - write_header = &_headers[_write_header_index]; - write_header->_is_control = is_control; - write_header->_status = HEADER_FILLING; - } - - write_header->_line_count++; - _at_start_of_line = true; - } - - // We do this LAST. If we had to exit before this point, - // we will evaluate the same character again. - _scan_offset = _get_next_scan_offset(); + } // if ends_line } //while (_is_more_to_scan()) + return false; // no control was found }; // This is the ONLY external interface in this class char *readline(bool control_only, uint16_t &line_size) { - _scan_buffer(); + bool found_control = _scan_buffer(); - - uint8_t search_header_index = _first_header_index; - auto search_header = &_headers[search_header_index]; - bool found_control = false; - do { - if ((search_header->_status >= HEADER_FILLING) && - search_header->_is_control && - (search_header->_line_count > 0)) { - - found_control = true; - break; - } - if (search_header_index == _write_header_index) - { - break; - } - - search_header_index = _get_next_header_index(search_header_index); - search_header = &_headers[search_header_index]; - } while (1); - - - if (found_control) { - - // When we get here, search_header points to a valid header that we want to either: - // A) Get a single-character command from and return it, OR - // B) Get a full line from and return it. - - // For B, we handle that like any line. But the single chars have to have special - // attention. - - - char c = _data[search_header->_read_offset]; - if ((c == '!') || - (c == '~') || - (c == ENQ) || // request ENQ/ack - (c == CHAR_RESET) || // ^X - reset (aka cancel, terminate) - (c == CHAR_ALARM) || // ^D - request job kill (end of transmission) - (cm_has_hold() && c == '%') // flush (only in feedhold) - ) { - line_size = 1; - - search_header->_read_offset = search_header->_get_next_read_offset(); - search_header->_line_count--; - search_header->_is_processing = true; - - single_char_buffer[0] = c; - single_char_buffer[1] = 0; - - return single_char_buffer; - } - - // fall through to finding the end of the line in search_header - - - } // end if (found_control) - else { - - // Logic to determine that we can safely look at ONLY the first header: - // • We always read all of the command lines first. - // • We have already called _free_unused_space(). - - search_header_index = _first_header_index; - search_header = &_headers[search_header_index]; - - if (control_only || search_header->_is_control || (search_header->_line_count == 0)) { - if ((search_header->_line_count == 0)) { - _restartTransfer(); - } - line_size = 0; - return nullptr; - } - - } // end if (!found_control) - - - - // By the time we get here, search_header points to a valid header that we want to pull the first - // full line from and return it. - - - uint16_t read_offset = search_header->_read_offset; char *dst_ptr = _line_buffer; line_size = 0; - if (_data[read_offset] == 0) { + if (found_control) { + // Optimization: if the control was found at the beginning of _data, we note that now + // and update the _read_offset when we update _line_start_offset + bool ctrl_is_at_beginning_of_data = (_line_start_offset == _read_offset); + + // When we get here, _line_start_offset points to either: + // A) A single-character command, OR + // B) A full line. + // Either way, _scan_offset is one past the end, so we don't care which. + + if (_data[_line_start_offset] == 0) { + _debug_trap("read ran into NULL"); + } + + // scan past any leftover CR or LF from the previous line + while ((_data[_line_start_offset] == '\n') || (_data[_line_start_offset] == '\r')) { + _line_start_offset = (_line_start_offset+1)&(_size-1); + if (_scan_offset == _line_start_offset) { + _debug_trap("read ran into scan (1)"); + } + } + + while ((_scan_offset != _line_start_offset) && (line_size < (_line_buffer_size - 2))) { +// if (!_canBeRead(read_offset)) { // This test should NEVER fail. +// _debug_trap("readline hit unreadable and shouldn't have!"); +// } + + // copy the charater to _line_buffer + char c = _data[_line_start_offset]; + *dst_ptr = c; + + // mark the data as "read" so we don't read it again + _data[_line_start_offset] = 0xFF; + + // update the line_size + line_size++; + + // update read/write positions + dst_ptr++; + _line_start_offset = (_line_start_offset+1)&(_size-1); + if (ctrl_is_at_beginning_of_data) { + _read_offset = _line_start_offset; + } + } + + if (ctrl_is_at_beginning_of_data) { + // attempt to request more data + _restartTransfer(); + } + + return _line_buffer; + } // end if (found_control) + + if (_lines_found == 0) { + // nothing to return + // attempt to request more data + _restartTransfer(); + + line_size = 0; + return nullptr; + } + + + // By the time we get here, we know we have at least one line in _data. + + + if (_data[_read_offset] == 0) { _debug_trap("read ran into NULL"); } // scan past any leftover CR or LF from the previous line - while ((_data[read_offset] == '\n') || (_data[read_offset] == '\r')) { - read_offset = (read_offset+1)&(_size-1); - if (_scan_offset == read_offset) { - _debug_trap("read ran into scan (1)"); + char c = _data[_read_offset]; + while ((c == '\n') || (c == '\r')) { + _read_offset = (_read_offset+1)&(_size-1); + if (_scan_offset == _read_offset) { + _debug_trap("read ran into scan (2)"); } + c = _data[_read_offset]; } while (line_size < (_line_buffer_size - 2)) { - if (!_canBeRead(read_offset)) { // This test should NEVER fail. - _debug_trap("readline hit unreadable and shouldn't have!"); - } - char c = _data[read_offset]; +// if (!_canBeRead(read_offset)) { // This test should NEVER fail. +// _debug_trap("readline hit unreadable and shouldn't have!"); +// } - if ( - c == '\r' || + // skip already-read control data + if (c == 0xff) { + _read_offset = (_read_offset+1)&(_size-1); + continue; + } + + if ( c == '\r' || c == '\n' ) { @@ -792,25 +703,20 @@ struct LineRXBuffer : RXBuffer<_size, owner_type, char> { // update read/write positions dst_ptr++; - read_offset = (read_offset+1)&(_size-1); - if (_scan_offset == read_offset) { - _debug_trap("read ran into scan (2)"); - } + _read_offset = (_read_offset+1)&(_size-1); + + c = _data[_read_offset]; } - // previous character was last one of the line - // update the header's next read position - search_header->_read_offset = (read_offset+1)&(_size-1); - // and line count - search_header->_line_count--; - // and processing flag - search_header->_is_processing = true; + --_lines_found; *dst_ptr = 0; return _line_buffer; }; -}; +}; // LineRXBuffer + +#pragma GCC pop_options template struct xioDeviceWrapper : xioDeviceWrapperBase { // describes a device for reading and writing @@ -863,6 +769,9 @@ struct xioDeviceWrapper : xioDeviceWrapperBase { // describes a device for re return _tx_buffer.write(buffer, len); } +#pragma GCC push_options +#pragma GCC optimize ("O0") + virtual char *readline(devflags_t limit_flags, uint16_t &size) final { if ((limit_flags & flags) && isConnected()) { return _rx_buffer.readline(!(limit_flags & DEV_IS_DATA), size); @@ -872,6 +781,8 @@ struct xioDeviceWrapper : xioDeviceWrapperBase { // describes a device for re return NULL; }; +#pragma GCC pop_options + void _flushLine() { // TODO: Call to flush the RX buffer line structures }; @@ -948,7 +859,7 @@ struct xioDeviceWrapper : xioDeviceWrapperBase { // describes a device for re } // flags & DEV_IS_CONNECTED } }; - }; +}; // ALLOCATIONS // Declare a device wrapper class for SerialUSB and SerialUSB1 From 886229b66027f36202ecbe25ddb0e0e1a5788790 Mon Sep 17 00:00:00 2001 From: Rob Giseburt Date: Wed, 16 Nov 2016 23:33:09 -0600 Subject: [PATCH 35/98] Adjusted xio to work a little better. (Still broken.) --- g2core/xio.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/g2core/xio.cpp b/g2core/xio.cpp index f4263591..21ae2d38 100755 --- a/g2core/xio.cpp +++ b/g2core/xio.cpp @@ -653,6 +653,11 @@ struct LineRXBuffer : RXBuffer<_size, owner_type, char> { return _line_buffer; } // end if (found_control) + if (control_only) { + line_size = 0; + return nullptr; + } + if (_lines_found == 0) { // nothing to return // attempt to request more data @@ -688,6 +693,7 @@ struct LineRXBuffer : RXBuffer<_size, owner_type, char> { // skip already-read control data if (c == 0xff) { _read_offset = (_read_offset+1)&(_size-1); + c = _data[_read_offset]; continue; } @@ -710,6 +716,8 @@ struct LineRXBuffer : RXBuffer<_size, owner_type, char> { --_lines_found; + _restartTransfer(); + *dst_ptr = 0; return _line_buffer; }; From 0176364e8f3dafc327db3327db724b45267210df Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Thu, 17 Nov 2016 09:23:07 -0500 Subject: [PATCH 36/98] Edited xio.cpp comments. No functional changes --- g2core/xio.cpp | 218 +++++++++++++++++++++++-------------------------- 1 file changed, 103 insertions(+), 115 deletions(-) diff --git a/g2core/xio.cpp b/g2core/xio.cpp index 21ae2d38..315930f5 100755 --- a/g2core/xio.cpp +++ b/g2core/xio.cpp @@ -81,7 +81,7 @@ using Motate::TXBuffer; /**** Structures ****/ -// We need a buffer to hold single character commands, like !~% +// We need a buffer to hold single character commands, like !~%, ^x, etc. // We also want it to have a NULL character, so we make it two characters. char single_char_buffer[2] = " "; @@ -100,11 +100,11 @@ struct xioDeviceWrapperBase { // C++ base class for device primit // connection and device management uint8_t caps; // bitfield for capabilities flags (these are persistent) devflags_t flags; // bitfield for device state flags (these are not) - devflags_t next_flags; // bitfield for next-state transitions + devflags_t next_flags; // bitfield for next-state transitions // line reader functions // uint16_t read_index; // index into line being read -// const uint16_t read_buf_size; // static variable set at init time +// const uint16_t read_buf_size; // static variable set at init time // char read_buf[USB_LINE_BUFFER_SIZE]; // buffer for reading lines // Internal use only: @@ -223,16 +223,16 @@ struct xio_t { /* * write() - write a block to a device + * + * There are a few issues with this function that I don't know how to resolve right now: + * 1) If a device fails to write the data, or all the data, then it's ignored + * 2) Only the amount written by the *last* device to match (CTRL|ACTIVE) is returned. + * + * In the current environment, these are not foreseen to cause trouble since these + * are blocking writes and we expect to only really be writing to one device. */ size_t write(const char *buffer, size_t size) { - // There are a few issues with this function that I don't know how to resolve right now: - // 1) If a device fails to write the data, or all the data, then it's ignored - // 2) Only the amount written by the *last* device to match (CTRL|ACTIVE) is returned. - // - // In the current environment, these are not foreseen to cause trouble, - // since these are blocking writes and we expect to only really be writing to one device. - size_t total_written = -1; for (int8_t i = 0; i < _dev_count; ++i) { if (DeviceWrappers[i]->isCtrlAndActive()) { @@ -300,10 +300,10 @@ struct xio_t { * DEV_IS_DATA bits in the device flag field. 'Flags' is loaded with the flags of * the channel that was read on return, or 0 (DEV_FLAGS_CLEAR) if no line was returned. * - * size - Returns the size of the completed buffer, including the NUL termination character. - * Lines may be returned truncated to the length of the serial input buffer if the text - * from the physical device is longer than the read buffer for the device. The size value - * provided as a calling argument is ignored (size doesn't matter). + * size - Returns the size of the completed buffer, including the NUL termination character. + * Lines may be returned truncated to the length of the serial input buffer if the text + * from the physical device is longer than the read buffer for the device. The size value + * provided as a calling argument is ignored (size doesn't matter). * * char * Returns a pointer to the buffer containing the line, or NULL (*0) if no text */ @@ -357,7 +357,7 @@ struct xio_t { uint16_t magic_end; }; -// Declare (but don't define) the xio singelton object now, define it later +// Declare (but don't define) the xio singleton object now, define it later // Why? xioDeviceWrapper uses it, but we need to define it to contain xioDeviceWrapper objects. extern xio_t xio; @@ -420,114 +420,99 @@ struct LineRXBuffer : RXBuffer<_size, owner_type, char> { return _canBeRead(_scan_offset); }; -// // This function skips the "whitespace" at the BEGINNING of a line. -// // This assumes we've already located the end of a line. -// void _scan_past_line_start() { -// while (_is_more_to_scan()) { -// char c = _data[_scan_offset]; -// if (c == '\r' || -// c == '\n' || -// c == '\t' || -// c == ' ') { -// _scan_offset = _get_next_scan_offset(); -// } else { -// break; -// } -// } // end _skipping whitespace -// }; - - - // Make a pass through the buffer to create headers for what has been read. - - // This function is designed to be able to exit from almost any point, and - // come back in and resume where it left off. This allows it to scan to the - // end of the buffer, then exit. - // - // We return true if we found a control line. - // That control line starts at the character at _line_start_offset, and includes the characters up to - // _scan_offset-1. If there are multiple line-ending chara ("\r\n" for example) _scan_offset will point to the - // *first*. - - // With ascii art (where "." means "invalid data" or "don't care"): - // Example 1 of _scan_buffer() == true: - // _data = "G0X10\n{jvm:5}\n{xvm:1200}\nG0Y10\nG1Z......" - // ^ ^ - // | | - // _line_start_offset | - // _scan_offset - - // Example 2 of _scan_buffer() == true: - // _data = "G0X10\n.........{xvm:1200}\nG0Y10\nG1Z......" - // ^ ^ - // | | - // _line_start_offset | - // _scan_offset - - // Example 2 of _scan_buffer() == true: - // _data = "G0X10\n!......" - // ^^ - // || - // _line_start_offset| - // _scan_offset - - // For _scan_buffer() == false, IGNORE _line_start_offset and _scan_offset!!! - // Only use _read_offset, and use _lines_found>0 to determine if _data contains a line to return. - // Also note that _read_offset needs to be moved once the data is copied to _line_buffer! + /* + * _scan_buffer() + * + * Make a pass through the RX DMA buffer to locate any control lines. + * Single character controls, like !, ~, %, and ^x are also considered control "lines" + * + * This function is designed to be able to exit from almost any point, and + * come back in and resume where it left off. This allows it to scan to the + * end of the buffer then exit. When the function is called next it picks up + * where it left off - i.e. avoiding rescanning the entire buffer multiple times. + * + * _scan_buffer() returns true if it finds a control line. + * The control line starts at the character at _line_start_offset and includes + * the characters up to _scan_offset-1. If there are multiple line-ending chars + * ("\r\n" for example) _scan_offset will point to the *first* one. + * + * With ASCII art (where "." means "invalid data" or "don't care"): + * + * Example 1 of _scan_buffer() == true: + * _data = "G0X10\n{jvm:5}\n{xvm:1200}\nG0Y10\nG1Z......" + * ^ ^ + * | | + * _line_start_offset | + * _scan_offset + * + * Example 2 of _scan_buffer() == true: + * _data = "G0X10\n.........{xvm:1200}\nG0Y10\nG1Z......" + * ^ ^ + * | | + * _line_start_offset | + * _scan_offset + * + * Example 2 of _scan_buffer() == true: + * _data = "G0X10\n!......" + * ^^ + * || + * _line_start_offset| + * _scan_offset + * + * For _scan_buffer() == false, IGNORE _line_start_offset and _scan_offset!!! + * Only use _read_offset, and use _lines_found>0 to determine if _data contains a line to return. + * Also note that _read_offset needs to be moved once the data is copied to _line_buffer! + */ + /* Explanation of cases and how we handle it. + * + * Our first task in this loop is two-fold (done at the same time): + * A) Scan the RX DMA buffer for the next complete line, then classify the line. + * B) Scan for a single-character command (!~% ^D, etc), then classify as a control line. + * + * If we find a line that classifies as "control" then we return true and stop scanning. + * + * We also have a constraint that we may run out of characters at any time. This is OK, + * and enough state is kept that we can enter the function at any point with new + * characters added to the RX DMA buffer and get the same results. + * + * Another constraint is that lines MAY have single character commands embedded in them. + * In this case we need to un-embed them. Since we may not have the end of the line yet, + * we need to move the command to the beginning of the line. + * + * Note that _at_start_of_line means that we *just* parsed a character that is *at* the end of the line. + * So, for a \r\n sequence, _at_start_of_line will go true of the \r, and we'll see the \n and it'll stay + * true, then the first non \r or \n char will set it to false, and *then* start the next line. + */ bool _scan_buffer() { - /* Explanation of cases and how we handle it. - * - * Our first task in this loop is two fold (done at the same time): - * A) Scan for the next complete line, then classify the line. - * B) Scan for a single-character command (!~% ^D, etc), then classify that as a line. - * - * If we find a line that classifies as "control" then we return true and stop scanning. - * - * We also have a constraint that we may run out of character at any time. This is okay, and enough - * state is kept that we can enter the function at any point with new characters and get the same results. - * - * Another constraint is that lines MAY have single character commands embedded in them. In this case, - * we need to un-embed them. Since we may not have the end of the line yet, we need to move the command - * to the beginning of the line. - * - * Note that _at_start_of_line means that we *just* parsed a character that is *at* the end of the line. - * So, for a \r\n sequence, _at_start_of_line will go true of the \r, and we'll see the \n and it'll stay - * true, then the first non \r or \n char will set it to false, and *then* start the next line. - * - */ _last_scan_offset = _scan_offset; while (_is_more_to_scan()) { bool ends_line = false; bool is_control = false; - // Look for line endings - // Classify the line char c = _data[_scan_offset]; if (c == 0) { _debug_trap("scan ran into NULL"); } - if (c == '\r' || - c == '\n' - ) { - - // We only mark ends_line for the first end-line char, and if - // _at_start_of_line is already true, this is not the first. - if (!_at_start_of_line) { - ends_line = true; + // Look for line endings + if (c == '\r' || c == '\n') { + if (!_at_start_of_line) { // We only mark ends_line for the first end-line char, and if + ends_line = true; // _at_start_of_line is already true, this is not the first. } } + // Classify the line if it's a single character else if ((c == '!') || (c == '~') || (c == ENQ) || // request ENQ/ack - (c == CHAR_RESET) || // ^X - reset (aka cancel, terminate) + (c == CHAR_RESET) || // ^X - reset (aka cancel, terminate) (c == CHAR_ALARM) || // ^D - request job kill (end of transmission) (cm_has_hold() && c == '%') // flush (only in feedhold or part of control header) ) { - // Special case: if we're NOT _at_start_of_line, we need to move the + // Special case: if we're NOT _at_start_of_line, we need to move the control // character to _line_start_offset. That means moving every character // forward one. THEN we back-track _scan_offset to this new start of line. if (!_at_start_of_line) { @@ -537,13 +522,9 @@ struct LineRXBuffer : RXBuffer<_size, owner_type, char> { _data[next_copy_offset] = _data[copy_offset]; copy_offset = next_copy_offset; } - - // Copy the single character to the first character - _data[_line_start_offset] = c; - // and note that we are now at the start of the line - _at_start_of_line = true; - // oh, and we need to actually be at the beginning of the line - _scan_offset = _line_start_offset; + _data[_line_start_offset] = c; // Copy the single character to the first character + _at_start_of_line = true; // and note that we are now at the start of the line + _scan_offset = _line_start_offset; // oh, and we need to actually be at the beginning of the line } // single-character control @@ -563,7 +544,7 @@ struct LineRXBuffer : RXBuffer<_size, owner_type, char> { if (ends_line) { // _scan_offset is now one past the end of the line, - // which means it is at the start of a new one + // which means it is at the start of a new line _at_start_of_line = true; // Here we classify the line. @@ -579,11 +560,9 @@ struct LineRXBuffer : RXBuffer<_size, owner_type, char> { // TODO --- } - if (is_control) { - // we found a control + if (is_control) { // we found a control return true; - } else { - // we did find one more line, though. + } else { // we did find one more line, though. _lines_found++; } } // if ends_line @@ -591,9 +570,14 @@ struct LineRXBuffer : RXBuffer<_size, owner_type, char> { return false; // no control was found }; - - - // This is the ONLY external interface in this class + /* + * readline() + * + * This is the ONLY external interface in this class + * + * Exit condition should be that _line_start_offset and _scan_offset should be the same. + * If the control was the first char of the buffer it also moves the _data_offset, marking it as read + */ char *readline(bool control_only, uint16_t &line_size) { bool found_control = _scan_buffer(); @@ -719,6 +703,10 @@ struct LineRXBuffer : RXBuffer<_size, owner_type, char> { _restartTransfer(); *dst_ptr = 0; + + if (_line_start_offset != _scan_offset) { // This test should NEVER fail. + _debug_trap("readline exit condition incorrect: _line_start_offset != _scan_offset"); + } return _line_buffer; }; From 98b11d50903fe1832cdedbc1de412884631c3af2 Mon Sep 17 00:00:00 2001 From: Rob Giseburt Date: Fri, 18 Nov 2016 00:40:56 -0600 Subject: [PATCH 37/98] Tweaks to xio --- g2core/xio.cpp | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/g2core/xio.cpp b/g2core/xio.cpp index 315930f5..0632d036 100755 --- a/g2core/xio.cpp +++ b/g2core/xio.cpp @@ -509,7 +509,7 @@ struct LineRXBuffer : RXBuffer<_size, owner_type, char> { (c == ENQ) || // request ENQ/ack (c == CHAR_RESET) || // ^X - reset (aka cancel, terminate) (c == CHAR_ALARM) || // ^D - request job kill (end of transmission) - (cm_has_hold() && c == '%') // flush (only in feedhold or part of control header) + (c == '%' && cm_has_hold()) // flush (only in feedhold or part of control header) ) { // Special case: if we're NOT _at_start_of_line, we need to move the control @@ -580,6 +580,7 @@ struct LineRXBuffer : RXBuffer<_size, owner_type, char> { */ char *readline(bool control_only, uint16_t &line_size) { bool found_control = _scan_buffer(); + _restartTransfer(); char *dst_ptr = _line_buffer; line_size = 0; @@ -616,7 +617,7 @@ struct LineRXBuffer : RXBuffer<_size, owner_type, char> { *dst_ptr = c; // mark the data as "read" so we don't read it again - _data[_line_start_offset] = 0xFF; + //_data[_line_start_offset] = 0xFF; // update the line_size line_size++; @@ -629,10 +630,10 @@ struct LineRXBuffer : RXBuffer<_size, owner_type, char> { } } - if (ctrl_is_at_beginning_of_data) { - // attempt to request more data - _restartTransfer(); - } +// if (ctrl_is_at_beginning_of_data) { +// // attempt to request more data +// _restartTransfer(); +// } return _line_buffer; } // end if (found_control) @@ -644,9 +645,6 @@ struct LineRXBuffer : RXBuffer<_size, owner_type, char> { if (_lines_found == 0) { // nothing to return - // attempt to request more data - _restartTransfer(); - line_size = 0; return nullptr; } @@ -719,8 +717,8 @@ struct xioDeviceWrapper : xioDeviceWrapperBase { // describes a device for re Device _dev; // TODO - make _buffer_size, _header_count, and _line_buffer_size configurable - LineRXBuffer<512, Device> _rx_buffer; - TXBuffer<512, Device> _tx_buffer; + LineRXBuffer<1024, Device> _rx_buffer; + TXBuffer<1024, Device> _tx_buffer; xioDeviceWrapper(Device dev, uint8_t _caps) : xioDeviceWrapperBase(_caps), _dev{dev}, _rx_buffer{_dev}, _tx_buffer{_dev} { From ae2c3a3965235a23ada4c49d4700e23a4d5c9b92 Mon Sep 17 00:00:00 2001 From: Rob Giseburt Date: Fri, 18 Nov 2016 00:45:41 -0600 Subject: [PATCH 38/98] Update Motate to get sam3x USB fixes --- Motate | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Motate b/Motate index d487230e..3f526e59 160000 --- a/Motate +++ b/Motate @@ -1 +1 @@ -Subproject commit d487230e6111de50db9cd3594d28d6c078c06384 +Subproject commit 3f526e594cbd12a708d46d84eda85b2513bc1d52 From 271cc29372de0f74b997868307f3db92399bb8f2 Mon Sep 17 00:00:00 2001 From: Rob Giseburt Date: Fri, 18 Nov 2016 00:56:18 -0600 Subject: [PATCH 39/98] Minor correction to XIO debug trap --- g2core/xio.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/g2core/xio.cpp b/g2core/xio.cpp index 0632d036..32a03909 100755 --- a/g2core/xio.cpp +++ b/g2core/xio.cpp @@ -575,7 +575,7 @@ struct LineRXBuffer : RXBuffer<_size, owner_type, char> { * * This is the ONLY external interface in this class * - * Exit condition should be that _line_start_offset and _scan_offset should be the same. + * Exit condition when a control is found: _line_start_offset and _scan_offset should be the same. * If the control was the first char of the buffer it also moves the _data_offset, marking it as read */ char *readline(bool control_only, uint16_t &line_size) { @@ -635,6 +635,10 @@ struct LineRXBuffer : RXBuffer<_size, owner_type, char> { // _restartTransfer(); // } + if (_line_start_offset != _scan_offset) { // This test should NEVER fail. + _debug_trap("readline exit condition incorrect: _line_start_offset != _scan_offset"); + } + return _line_buffer; } // end if (found_control) @@ -701,10 +705,6 @@ struct LineRXBuffer : RXBuffer<_size, owner_type, char> { _restartTransfer(); *dst_ptr = 0; - - if (_line_start_offset != _scan_offset) { // This test should NEVER fail. - _debug_trap("readline exit condition incorrect: _line_start_offset != _scan_offset"); - } return _line_buffer; }; From b2a8cfb0b111c385e644343b3e69bbf48c7257ff Mon Sep 17 00:00:00 2001 From: Rob Giseburt Date: Fri, 18 Nov 2016 22:19:41 -0600 Subject: [PATCH 40/98] Added SkipSections for handling mixed JSON and gcode in XIO. --- g2core/xio.cpp | 133 +++++++++++++++++++++++++++++++++++-------------- 1 file changed, 96 insertions(+), 37 deletions(-) diff --git a/g2core/xio.cpp b/g2core/xio.cpp index 32a03909..964cfea9 100755 --- a/g2core/xio.cpp +++ b/g2core/xio.cpp @@ -412,6 +412,73 @@ struct LineRXBuffer : RXBuffer<_size, owner_type, char> { _at_start_of_line = true; }; + + struct SkipSections { + struct SkipSection { + uint16_t start_offset; // the offset of the first character to skip + uint16_t end_offset; // the offset of the next character to read after skipping + }; + + static constexpr uint16_t _section_count = 16; + SkipSection _sections[_section_count]; + + uint8_t read_section_idx; // index of the first skip section to skip + uint8_t write_section_idx; // index of the next skip section to populate + + bool is_full() { + return ((write_section_idx+1)&(_section_count-1)) == read_section_idx; + }; + bool is_empty() { + return (write_section_idx == read_section_idx); + }; + + void add_skip(uint16_t start_offset, uint16_t end_offset) { + if (!is_empty()) { + uint8_t last_write_section_idx = write_section_idx; + if (write_section_idx == 0) { + last_write_section_idx = _section_count-1; + } else { + last_write_section_idx--; + } + + if (_sections[last_write_section_idx].end_offset == start_offset) { + _sections[last_write_section_idx].end_offset = end_offset; + return; + } + } + _sections[write_section_idx].start_offset = start_offset; + _sections[write_section_idx].end_offset = end_offset; + write_section_idx = ((write_section_idx+1)&(_section_count-1)); + }; + + void pop_skip() { + _sections[read_section_idx].start_offset = 0; + _sections[read_section_idx].end_offset = 0; + + read_section_idx = ((read_section_idx+1)&(_section_count-1)); + }; + + bool skip(volatile uint16_t &from) { + if (!is_empty()) { + SkipSection &next_skip = _sections[read_section_idx]; + + if (next_skip.start_offset == from) { + from = next_skip.end_offset; + + pop_skip(); + return true; + } + } + return false; + }; + +// const SkipSection& next_skip() { +// return _sections[read_section_idx]; +// } + }; + + SkipSections _skip_sections; + uint16_t _get_next_scan_offset() { return ((_scan_offset + 1) & (_size-1)); } @@ -423,9 +490,12 @@ struct LineRXBuffer : RXBuffer<_size, owner_type, char> { /* * _scan_buffer() * - * Make a pass through the RX DMA buffer to locate any control lines. + * Make a pass through the RX DMA buffer to locate any control lines, and count lines. * Single character controls, like !, ~, %, and ^x are also considered control "lines" * + * _scan_buffer() is called at the beginning of readline, and is effectively the first + * "phase" of readline. + * * This function is designed to be able to exit from almost any point, and * come back in and resume where it left off. This allows it to scan to the * end of the buffer then exit. When the function is called next it picks up @@ -504,28 +574,16 @@ struct LineRXBuffer : RXBuffer<_size, owner_type, char> { } // Classify the line if it's a single character else - if ((c == '!') || - (c == '~') || - (c == ENQ) || // request ENQ/ack - (c == CHAR_RESET) || // ^X - reset (aka cancel, terminate) - (c == CHAR_ALARM) || // ^D - request job kill (end of transmission) - (c == '%' && cm_has_hold()) // flush (only in feedhold or part of control header) - ) { + if (_at_start_of_line && + ((c == '!') || + (c == '~') || + (c == ENQ) || // request ENQ/ack + (c == CHAR_RESET) || // ^X - reset (aka cancel, terminate) + (c == CHAR_ALARM) || // ^D - request job kill (end of transmission) + (c == '%' && cm_has_hold()) // flush (only in feedhold or part of control header) + )) { - // Special case: if we're NOT _at_start_of_line, we need to move the control - // character to _line_start_offset. That means moving every character - // forward one. THEN we back-track _scan_offset to this new start of line. - if (!_at_start_of_line) { - uint16_t copy_offset = _line_start_offset; - while (copy_offset != _scan_offset) { - uint16_t next_copy_offset = (copy_offset+1)&(_size-1); - _data[next_copy_offset] = _data[copy_offset]; - copy_offset = next_copy_offset; - } - _data[_line_start_offset] = c; // Copy the single character to the first character - _at_start_of_line = true; // and note that we are now at the start of the line - _scan_offset = _line_start_offset; // oh, and we need to actually be at the beginning of the line - } + _line_start_offset = _scan_offset; // single-character control is_control = true; @@ -579,7 +637,9 @@ struct LineRXBuffer : RXBuffer<_size, owner_type, char> { * If the control was the first char of the buffer it also moves the _data_offset, marking it as read */ char *readline(bool control_only, uint16_t &line_size) { - bool found_control = _scan_buffer(); + // This is tricky: if we don't have room for more skip_sections, then we + // can't scan any more for controls. So we don't scan, amd hope some lines are read. + bool found_control = _skip_sections.is_full() ? false : _scan_buffer(); _restartTransfer(); char *dst_ptr = _line_buffer; @@ -589,6 +649,9 @@ struct LineRXBuffer : RXBuffer<_size, owner_type, char> { // Optimization: if the control was found at the beginning of _data, we note that now // and update the _read_offset when we update _line_start_offset bool ctrl_is_at_beginning_of_data = (_line_start_offset == _read_offset); + if (!ctrl_is_at_beginning_of_data) { + _skip_sections.add_skip(_line_start_offset, _scan_offset); + } // When we get here, _line_start_offset points to either: // A) A single-character command, OR @@ -607,7 +670,8 @@ struct LineRXBuffer : RXBuffer<_size, owner_type, char> { } } - while ((_scan_offset != _line_start_offset) && (line_size < (_line_buffer_size - 2))) { + while ((_scan_offset != _line_start_offset) && + (line_size < (_line_buffer_size - 2))) { // if (!_canBeRead(read_offset)) { // This test should NEVER fail. // _debug_trap("readline hit unreadable and shouldn't have!"); // } @@ -616,18 +680,16 @@ struct LineRXBuffer : RXBuffer<_size, owner_type, char> { char c = _data[_line_start_offset]; *dst_ptr = c; - // mark the data as "read" so we don't read it again - //_data[_line_start_offset] = 0xFF; - // update the line_size line_size++; // update read/write positions dst_ptr++; _line_start_offset = (_line_start_offset+1)&(_size-1); - if (ctrl_is_at_beginning_of_data) { - _read_offset = _line_start_offset; - } + } + + if (ctrl_is_at_beginning_of_data) { + _read_offset = _scan_offset; } // if (ctrl_is_at_beginning_of_data) { @@ -661,6 +723,9 @@ struct LineRXBuffer : RXBuffer<_size, owner_type, char> { _debug_trap("read ran into NULL"); } + // skip sections will always start at the beginning of a line + _skip_sections.skip(_read_offset); + // scan past any leftover CR or LF from the previous line char c = _data[_read_offset]; while ((c == '\n') || (c == '\r')) { @@ -676,12 +741,7 @@ struct LineRXBuffer : RXBuffer<_size, owner_type, char> { // _debug_trap("readline hit unreadable and shouldn't have!"); // } - // skip already-read control data - if (c == 0xff) { - _read_offset = (_read_offset+1)&(_size-1); - c = _data[_read_offset]; - continue; - } + _read_offset = (_read_offset+1)&(_size-1); if ( c == '\r' || c == '\n' @@ -695,7 +755,6 @@ struct LineRXBuffer : RXBuffer<_size, owner_type, char> { // update read/write positions dst_ptr++; - _read_offset = (_read_offset+1)&(_size-1); c = _data[_read_offset]; } From f9f8df001e35a45e2644ea2e6e1f7fb7d9ec6c5d Mon Sep 17 00:00:00 2001 From: Rob Giseburt Date: Wed, 23 Nov 2016 14:11:21 -0600 Subject: [PATCH 41/98] Vital fix for crash when there was a move with a non-zero body and a zero-length tail. --- g2core/plan_exec.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/g2core/plan_exec.cpp b/g2core/plan_exec.cpp index 84c57d5b..c8657d54 100755 --- a/g2core/plan_exec.cpp +++ b/g2core/plan_exec.cpp @@ -812,6 +812,9 @@ static stat_t _exec_aline_body(mpBuf_t *bf) mr.section_state = SECTION_RUNNING; // uses PERIOD_2 so last segment detection works } if (_exec_aline_segment() == STAT_OK) { // OK means this section is done + if (fp_ZERO(mr.r->tail_length)) { + return(STAT_OK); // ends the move + } mr.section = SECTION_TAIL; mr.section_state = SECTION_NEW; } From 96a5881f070129c4a9978a5d814e4e1fbbd32a75 Mon Sep 17 00:00:00 2001 From: Rob Giseburt Date: Wed, 23 Nov 2016 14:11:42 -0600 Subject: [PATCH 42/98] Formatting adjustments. --- g2core/plan_exec.cpp | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/g2core/plan_exec.cpp b/g2core/plan_exec.cpp index c8657d54..6b28898c 100755 --- a/g2core/plan_exec.cpp +++ b/g2core/plan_exec.cpp @@ -153,9 +153,8 @@ stat_t mp_exec_move() // first-time operations if (bf->buffer_state != MP_BUFFER_RUNNING) { if ((bf->buffer_state < MP_BUFFER_PREPPED) && (cm.motion_state == MOTION_RUN)) { - __asm__("BKPT"); - // rpt_exception(42, "mp_exec_move() buffer is not prepped"); - // ^^^ CAUSES A CRASH. We can't rpt_exception from here! + __asm__("BKPT"); // mp_exec_move() buffer is not prepped + // IMPORTANT: We can't rpt_exception from here! st_prep_null(); return (STAT_NOOP); @@ -168,7 +167,7 @@ stat_t mp_exec_move() if (bf->buffer_state == MP_BUFFER_PREPPED) { if (cm.motion_state == MOTION_RUN) { -// __asm__("BKPT"); // we are running but don't have a block planned + __asm__("BKPT"); // we are running but don't have a block planned } // We need to have it planned. We don't want to do this here, as it @@ -288,7 +287,8 @@ stat_t mp_exec_aline(mpBuf_t *bf) // Start a new move by setting up the runtime singleton (mr) memcpy(&mr.gm, &(bf->gm), sizeof(GCodeState_t)); // copy in the gcode model state - bf->block_state = BLOCK_ACTIVE; // note that this buffer is running -- note the planner doesn't look at block_state + bf->block_state = BLOCK_ACTIVE; // note that this buffer is running + // note the planner doesn't look at block_state mr.block_state = BLOCK_INITIAL_ACTION; mr.section = SECTION_HEAD; mr.section_state = SECTION_NEW; @@ -423,7 +423,7 @@ stat_t mp_exec_aline(mpBuf_t *bf) // Update the run buffer then force a replan of the whole planner queue if (cm.hold_state == FEEDHOLD_DECEL_END) { mr.block_state = BLOCK_INACTIVE; // invalidate mr buffer to reset the new move - bf->block_state = BLOCK_INITIAL_ACTION; // tell _exec to re-use the bf buffer + bf->block_state = BLOCK_INITIAL_ACTION; // tell _exec to re-use the bf buffer bf->length = get_axis_vector_length(mr.target, mr.position);// reset length //bf->entry_vmax = 0; // set bp+0 as hold point @@ -510,11 +510,11 @@ stat_t mp_exec_aline(mpBuf_t *bf) } // There are 4 things that can happen here depending on return conditions: - // status bf->block_state Description - // ----------- -------------- ---------------------------------------- - // STAT_EAGAIN mr buffer has more segments to run - // STAT_OK BLOCK_ACTIVE mr and bf buffers are done - // STAT_OK BLOCK_INITIAL_ACTION mr done; bf must be run again (it's been reused) + // status bf->block_state Description + // ----------- -------------- ---------------------------------------- + // STAT_EAGAIN mr buffer has more segments to run + // STAT_OK BLOCK_ACTIVE mr and bf buffers are done + // STAT_OK BLOCK_INITIAL_ACTION mr done; bf must be run again (it's been reused) // There is no fourth thing. Nobody expects the Spanish Inquisition if (status == STAT_EAGAIN) { From bc79b0050c05a1aae5bc9374623f0393d91b7943 Mon Sep 17 00:00:00 2001 From: Rob Giseburt Date: Wed, 23 Nov 2016 14:13:17 -0600 Subject: [PATCH 43/98] Added semixosting debugging capabilities to stepper.cpp. (Some formatting cleanup too.) --- g2core/stepper.cpp | 49 +++++++++++++++++++++++++++++++++++++++------- 1 file changed, 42 insertions(+), 7 deletions(-) diff --git a/g2core/stepper.cpp b/g2core/stepper.cpp index 74b432df..327d099e 100644 --- a/g2core/stepper.cpp +++ b/g2core/stepper.cpp @@ -40,6 +40,20 @@ #include "controller.h" #include "xio.h" +/**** Debugging output with semihosting ****/ + +#include "MotateDebug.h" + +// Unless debugging, this should always read "#if 0 && ..." +// DON'T COMMIT with anything else! +#if 0 && (IN_DEBUGGER == 1) +template +void stepper_debug(const char (&str)[len]) { Motate::debug.write(str); }; +#else +template +void stepper_debug(const char (&str)[len]) { ; }; +#endif + /**** Allocate structures ****/ stConfig_t st_cfg; @@ -331,13 +345,13 @@ void dda_timer_type::interrupt() namespace Motate { // Must define timer interrupts inside the Motate namespace template<> void dwell_timer_type::interrupt() -{ - dwell_timer.getInterruptCause(); // read SR to clear interrupt condition - if (--st_run.dda_ticks_downcount == 0) { - dwell_timer.stop(); - _load_move(); + { + dwell_timer.getInterruptCause(); // read SR to clear interrupt condition + if (--st_run.dda_ticks_downcount == 0) { + dwell_timer.stop(); + _load_move(); + } } -} } // namespace Motate /**************************************************************************************** @@ -348,9 +362,12 @@ namespace Motate { // Must define timer interrupts inside the Motate void st_request_exec_move() { + stepper_debug("e"); if (st_pre.buffer_state == PREP_BUFFER_OWNED_BY_EXEC) { // bother interrupting exec_timer.setInterruptPending(); + return; } + stepper_debug("!\n"); } namespace Motate { // Define timer inside Motate namespace @@ -359,16 +376,21 @@ namespace Motate { // Define timer inside Motate namespace { exec_timer.getInterruptCause(); // clears the interrupt condition if (st_pre.buffer_state == PREP_BUFFER_OWNED_BY_EXEC) { + stepper_debug("E>"); if (mp_exec_move() != STAT_NOOP) { + stepper_debug("E+\n"); st_pre.buffer_state = PREP_BUFFER_OWNED_BY_LOADER; // flip it back st_request_load_move(); + return; } + stepper_debug("E-\n"); } } } // namespace Motate void st_request_plan_move() { + stepper_debug("p"); fwd_plan_timer.setInterruptPending(); } @@ -377,9 +399,13 @@ namespace Motate { // Define timer inside Motate namespace void fwd_plan_timer_type::interrupt() { fwd_plan_timer.getInterruptCause(); // clears the interrupt condition + stepper_debug("P>"); if (mp_plan_move() != STAT_NOOP) { // We now have a move to exec. + stepper_debug("P+\n"); st_request_exec_move(); + return; } + stepper_debug("P-\n"); } } // namespace Motate @@ -398,7 +424,9 @@ void st_request_load_move() if (st_runtime_isbusy()) { // don't request a load if the runtime is busy return; } + stepper_debug("l"); if (st_pre.buffer_state == PREP_BUFFER_OWNED_BY_LOADER) { // bother interrupting + stepper_debug("_"); load_timer.setInterruptPending(); } } @@ -408,7 +436,9 @@ namespace Motate { // Define timer inside Motate namespace void load_timer_type::interrupt() { load_timer.getInterruptCause(); // read SR to clear interrupt condition + stepper_debug("L>"); _load_move(); + stepper_debug("L+\n"); } } // namespace Motate @@ -453,8 +483,11 @@ static void _load_move() #if (MOTORS > 5) motor_6.motionStopped(); // ...start motor power timeouts #endif + stepper_debug("•"); return; - } + } // if (st_pre.buffer_state != PREP_BUFFER_OWNED_BY_LOADER) + + stepper_debug("^"); // handle aline loads first (most common case) NB: there are no more lines, only alines if (st_pre.block_type == BLOCK_TYPE_ALINE) { @@ -644,6 +677,7 @@ static void _load_move() stat_t st_prep_line(float travel_steps[], float following_error[], float segment_time) { + stepper_debug("😶"); // trap assertion failures and other conditions that would prevent queuing the line if (st_pre.buffer_state != PREP_BUFFER_OWNED_BY_EXEC) { // never supposed to happen return (cm_panic(STAT_INTERNAL_ERROR, "st_prep_line() prep sync error")); @@ -722,6 +756,7 @@ stat_t st_prep_line(float travel_steps[], float following_error[], float segment } st_pre.block_type = BLOCK_TYPE_ALINE; st_pre.buffer_state = PREP_BUFFER_OWNED_BY_LOADER; // signal that prep buffer is ready + stepper_debug("👍🏻"); return (STAT_OK); } From 1061e0de6bb199d2ae18e315f8e71f0319f6fd50 Mon Sep 17 00:00:00 2001 From: Rob Giseburt Date: Wed, 23 Nov 2016 14:14:03 -0600 Subject: [PATCH 44/98] Pumped the priorities of the load, exec, and fwd_plan interrupts. --- g2core/stepper.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/g2core/stepper.cpp b/g2core/stepper.cpp index 327d099e..1dfebdff 100644 --- a/g2core/stepper.cpp +++ b/g2core/stepper.cpp @@ -121,14 +121,14 @@ void stepper_init() dwell_timer.setInterrupts(kInterruptOnOverflow | kInterruptPriorityHighest); // setup software interrupt load timer - load_timer.setInterrupts(kInterruptOnSoftwareTrigger | kInterruptPriorityMedium); + load_timer.setInterrupts(kInterruptOnSoftwareTrigger | kInterruptPriorityHigh); // setup software interrupt exec timer & initial condition - exec_timer.setInterrupts(kInterruptOnSoftwareTrigger | kInterruptPriorityLow); + exec_timer.setInterrupts(kInterruptOnSoftwareTrigger | kInterruptPriorityMedium); st_pre.buffer_state = PREP_BUFFER_OWNED_BY_EXEC; // setup software interrupt forward plan timer & initial condition - fwd_plan_timer.setInterrupts(kInterruptOnSoftwareTrigger | kInterruptPriorityLowest); + fwd_plan_timer.setInterrupts(kInterruptOnSoftwareTrigger | kInterruptPriorityLow); // setup motor power levels and apply power level to stepper drivers for (uint8_t motor=0; motor Date: Wed, 23 Nov 2016 17:26:15 -0600 Subject: [PATCH 45/98] Update motate reference --- Motate | 2 +- g2core/xio.cpp | 31 +++++++++++++++++++++++++++---- 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/Motate b/Motate index 3f526e59..1e1be74e 160000 --- a/Motate +++ b/Motate @@ -1 +1 @@ -Subproject commit 3f526e594cbd12a708d46d84eda85b2513bc1d52 +Subproject commit 1e1be74e8b0dac10af1829ea211fef06f594ab7f diff --git a/g2core/xio.cpp b/g2core/xio.cpp index 964cfea9..d68880f2 100755 --- a/g2core/xio.cpp +++ b/g2core/xio.cpp @@ -640,6 +640,7 @@ struct LineRXBuffer : RXBuffer<_size, owner_type, char> { // This is tricky: if we don't have room for more skip_sections, then we // can't scan any more for controls. So we don't scan, amd hope some lines are read. bool found_control = _skip_sections.is_full() ? false : _scan_buffer(); + _restartTransfer(); char *dst_ptr = _line_buffer; @@ -690,6 +691,32 @@ struct LineRXBuffer : RXBuffer<_size, owner_type, char> { if (ctrl_is_at_beginning_of_data) { _read_offset = _scan_offset; + } else { + // special case: if the return value is '%' + // then we actually consider everything before it to be read + + if ('%' == _line_buffer[0]) { + // Things that must be managed here: + // * _read_offset -- we're skipping data + // * _lines_found -- we shouldn't have any lines "left" + // * _skip_sections -- there's nothing to skip, we just did + + // Things that won't be changed (further): + // * _scan_offset -- we're not changing past where it's scanned + // * _line_start_offset -- we've already adjusted it + // * _at_start_of_line -- should always be true when we're here + + // move the read buffer up to where we're scanning + _read_offset = _scan_offset; + + // note that we have 0 lines (of data) in the buffer + _lines_found = 0; + + // and clear out any skip sections we have + while (!_skip_sections.is_empty()) { + _skip_sections.pop_skip(); + } + } } // if (ctrl_is_at_beginning_of_data) { @@ -697,10 +724,6 @@ struct LineRXBuffer : RXBuffer<_size, owner_type, char> { // _restartTransfer(); // } - if (_line_start_offset != _scan_offset) { // This test should NEVER fail. - _debug_trap("readline exit condition incorrect: _line_start_offset != _scan_offset"); - } - return _line_buffer; } // end if (found_control) From cce4d004ea6fe515590263b30c955fea9683411f Mon Sep 17 00:00:00 2001 From: Rob Giseburt Date: Mon, 28 Nov 2016 10:39:42 -0600 Subject: [PATCH 46/98] Adjusted setting for PrintrBot 1608 (faster, lower power, corrected X axis) --- .../settings/settings_Printrbot_Simple_1608.h | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/g2core/settings/settings_Printrbot_Simple_1608.h b/g2core/settings/settings_Printrbot_Simple_1608.h index 7b24e154..a9a29d4f 100755 --- a/g2core/settings/settings_Printrbot_Simple_1608.h +++ b/g2core/settings/settings_Printrbot_Simple_1608.h @@ -94,11 +94,11 @@ // 80 steps/mm at 1/16 microstepping = 40 mm/rev #define M1_MOTOR_MAP AXIS_X // 1ma #define M1_STEP_ANGLE 1.8 // 1sa -#define M1_TRAVEL_PER_REV 40.132 // 1tr +#define M1_TRAVEL_PER_REV 40.011604 // 1tr #define M1_MICROSTEPS 32 // 1mi 1,2,4,8,16,32 #define M1_POLARITY 0 // 1po 0=normal, 1=reversed #define M1_POWER_MODE MOTOR_POWER_MODE // 1pm standard -#define M1_POWER_LEVEL 0.5 // 1mp +#define M1_POWER_LEVEL 0.35 // 1mp // 80 steps/mm at 1/16 microstepping = 40 mm/rev #define M3_MOTOR_MAP AXIS_Y @@ -107,7 +107,7 @@ #define M3_MICROSTEPS 32 #define M3_POLARITY 0 #define M3_POWER_MODE MOTOR_POWER_MODE -#define M3_POWER_LEVEL 0.5 +#define M3_POWER_LEVEL 0.35 // 2020 steps/mm at 1/16 microstepping = 1.58416 mm/rev #define M2_MOTOR_MAP AXIS_Z @@ -116,7 +116,7 @@ #define M2_MICROSTEPS 32 #define M2_POLARITY 1 #define M2_POWER_MODE MOTOR_POWER_MODE -#define M2_POWER_LEVEL 0.4 +#define M2_POWER_LEVEL 0.3 // 96 steps/mm at 1/16 microstepping = 33.3333 mm/rev #define M4_MOTOR_MAP AXIS_A @@ -125,7 +125,7 @@ #define M4_MICROSTEPS 32 #define M4_POLARITY 1 #define M4_POWER_MODE MOTOR_POWER_MODE -#define M4_POWER_LEVEL 0.4 +#define M4_POWER_LEVEL 0.3 // 96 steps/mm at 1/16 microstepping = 33.3333 mm/rev #define M5_MOTOR_MAP AXIS_B @@ -139,12 +139,12 @@ // *** axis settings ********************************************************************************** #define X_AXIS_MODE AXIS_STANDARD // xam see canonical_machine.h cmAxisMode for valid values -#define X_VELOCITY_MAX 10000 // xvm G0 max velocity in mm/min +#define X_VELOCITY_MAX 15000 // xvm G0 max velocity in mm/min #define X_FEEDRATE_MAX X_VELOCITY_MAX // xfr G1 max feed rate in mm/min #define X_TRAVEL_MIN 0 // xtn minimum travel - used by soft limits and homing #define X_TRAVEL_MAX 215 // xtm travel between switches or crashes -#define X_JERK_MAX 3000 // xjm yes, that's "100 billion" mm/(min^3) -#define X_JERK_HIGH_SPEED 3000 // xjh +#define X_JERK_MAX 6000 // xjm yes, that's "100 billion" mm/(min^3) +#define X_JERK_HIGH_SPEED 6000 // xjh #define X_HOMING_INPUT 4 // xhi input used for homing or 0 to disable #define X_HOMING_DIRECTION 0 // xhd 0=search moves negative, 1= search moves positive #define X_SEARCH_VELOCITY 2500 // xsv move in negative direction @@ -153,12 +153,12 @@ #define X_ZERO_BACKOFF 0.5 // xzb mm #define Y_AXIS_MODE AXIS_STANDARD -#define Y_VELOCITY_MAX 10000 +#define Y_VELOCITY_MAX 15000 #define Y_FEEDRATE_MAX Y_VELOCITY_MAX #define Y_TRAVEL_MIN 0 #define Y_TRAVEL_MAX 152.4 -#define Y_JERK_MAX 3000 -#define Y_JERK_HIGH_SPEED 3000 +#define Y_JERK_MAX 6000 +#define Y_JERK_HIGH_SPEED 6000 #define Y_HOMING_INPUT 1 #define Y_HOMING_DIRECTION 1 #define Y_SEARCH_VELOCITY 3000 @@ -185,7 +185,7 @@ * To calculate the speeds here, in Wolfram Alpha-speak: * * c=2*pi*r, r=0.609, d=c/360, s=((S*60)/d), S=40 for s - * c=2*pi*r, r=5.30516476972984, d=c/360, s=((S*60)/d), S=40 for s + * c=2*pi*r, r=4.28394, d=c/360, s=((S*60)/d), S=40 for s * * Change r to A_RADIUS, and S to the desired speed, in mm/s or mm/s/s/s. * @@ -204,12 +204,12 @@ //#define A_VELOCITY_MAX 25920.0 // ~40 mm/s, 2,400 mm/min //#define A_FEEDRATE_MAX 25920.0/2.0 // ~20 mm/s, 1,200 mm/min #define A_VELOCITY_MAX 77760.0 // G0 rate ~120 mm/s, 2,400 mm/min -#define A_FEEDRATE_MAX 6480 // ~10 mm/s +#define A_FEEDRATE_MAX 16050 // ~10 mm/s //#define A_FEEDRATE_MAX 9720.0 // 9720.0 = G1 rate ~15 mm/s, 900 mm/min #define A_TRAVEL_MIN 0 #define A_TRAVEL_MAX 10 -#define A_JERK_MAX 81000 // 250 million mm/min^3 = 324000 -//#define A_JERK_MAX 162000 // 250 million mm/min^3 = 324000 +//#define A_JERK_MAX 81000 // 250 million mm/min^3 = 324000 +#define A_JERK_MAX 162000 // 250 million mm/min^3 = 324000 //#define A_JERK_MAX 324000 // 500 million mm/min^3 = 324000 //#define A_JERK_MAX 648000 // 1,000 million mm/min^3 = 648000 // * a million IF it's over a million From 7bcc04b55c240a589f653dfa8b24c25bb8528f84 Mon Sep 17 00:00:00 2001 From: Rob Giseburt Date: Tue, 29 Nov 2016 12:44:36 -0600 Subject: [PATCH 47/98] Added shapeoko dual settings. --- g2core/settings/settings_shapeoko375_Dual.h | 256 ++++++++++++++++++++ 1 file changed, 256 insertions(+) create mode 100644 g2core/settings/settings_shapeoko375_Dual.h diff --git a/g2core/settings/settings_shapeoko375_Dual.h b/g2core/settings/settings_shapeoko375_Dual.h new file mode 100644 index 00000000..b787d58c --- /dev/null +++ b/g2core/settings/settings_shapeoko375_Dual.h @@ -0,0 +1,256 @@ +/* + * settings_shapeoko375.h - Shapeoko 375mm table + * This file is part of the TinyG project + * + * Copyright (c) 2010 - 2014 Alden S. Hart, Jr. + * + * This file ("the software") is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2 as published by the + * Free Software Foundation. You should have received a copy of the GNU General Public + * License, version 2 along with the software. If not, see . + * + * As a special exception, you may use this file as part of a software library without + * restriction. Specifically, if other files instantiate templates or use macros or + * inline functions from this file, or you compile this file and link it with other + * files to produce an executable, this file does not by itself cause the resulting + * executable to be covered by the GNU General Public License. This exception does not + * however invalidate any other reasons why the executable file might be covered by the + * GNU General Public License. + * + * THE SOFTWARE IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT WITHOUT ANY + * WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT + * SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +/* Note: The values in this file are the default settings that are loaded + * into a virgin EEPROM, and can be changed using the config commands. + * After initial load the EEPROM values (or changed values) are used. + * + * System and hardware settings that you shouldn't need to change + * are in system.h Application settings that also shouldn't need + * to be changed are in tinyg.h + */ + +/***********************************************************************/ +/**** Shapeoko 375mm profile *******************************************/ +/***********************************************************************/ + +// ***> NOTE: The init message must be a single line with no CRs or LFs +#define INIT_MESSAGE "Initializing configs to Shapeoko 375mm Dual-Y profile" + +//**** GLOBAL / GENERAL SETTINGS ****************************************************** + +// Machine configuration settings + +#define JUNCTION_INTEGRATION_TIME 0.75 // cornering - between 0.10 and 2.00 (higher is faster) +#define CHORDAL_TOLERANCE 0.01 // chordal tolerance for arcs (in mm) + +#define SOFT_LIMIT_ENABLE 0 // 0=off, 1=on +#define HARD_LIMIT_ENABLE 0 // 0=off, 1=on +#define SAFETY_INTERLOCK_ENABLE 1 // 0=off, 1=on + +#define SPINDLE_ENABLE_POLARITY 1 // 0=active low, 1=active high +#define SPINDLE_DIR_POLARITY 0 // 0=clockwise is low, 1=clockwise is high +#define SPINDLE_PAUSE_ON_HOLD true +#define SPINDLE_DWELL_TIME 1.0 + +#define COOLANT_MIST_POLARITY 1 // 0=active low, 1=active high +#define COOLANT_FLOOD_POLARITY 1 // 0=active low, 1=active high +#define COOLANT_PAUSE_ON_HOLD false + +// Communications and reporting settings + +#define COMM_MODE JSON_MODE // one of: TEXT_MODE, JSON_MODE +#define XIO_ENABLE_FLOW_CONTROL FLOW_CONTROL_RTS // FLOW_CONTROL_OFF, FLOW_CONTROL_RTS + +#define TEXT_VERBOSITY TV_VERBOSE // one of: TV_SILENT, TV_VERBOSE +#define JSON_VERBOSITY JV_MESSAGES // one of: JV_SILENT, JV_FOOTER, JV_CONFIGS, JV_MESSAGES, JV_LINENUM, JV_VERBOSE +#define QUEUE_REPORT_VERBOSITY QR_OFF // one of: QR_OFF, QR_SINGLE, QR_TRIPLE + +#define STATUS_REPORT_VERBOSITY SR_FILTERED // one of: SR_OFF, SR_FILTERED, SR_VERBOSE + +#define STATUS_REPORT_MIN_MS 100 // milliseconds - enforces a viable minimum +#define STATUS_REPORT_INTERVAL_MS 250 // milliseconds - set $SV=0 to disable + +//#define STATUS_REPORT_DEFAULTS "line","posx","posy","posz","posa","bcr","feed","vel","unit","coor","dist","admo","frmo","momo","stat" +#define STATUS_REPORT_DEFAULTS "line","posx","posy","posz","bcr","feed","vel","momo","stat" + +// Alternate SRs that report in drawable units +//#define STATUS_REPORT_DEFAULTS "line","vel","mpox","mpoy","mpoz","mpoa","coor","ofsa","ofsx","ofsy","ofsz","dist","unit","stat","homz","homy","homx","momo" +//#define STATUS_REPORT_DEFAULTS "_ts1","_cs1","_es1","_xs1","_fe1","line","posx","posy","posz","vel","stat" + +// Gcode startup defaults +#define GCODE_DEFAULT_UNITS MILLIMETERS // MILLIMETERS or INCHES +#define GCODE_DEFAULT_PLANE CANON_PLANE_XY // CANON_PLANE_XY, CANON_PLANE_XZ, or CANON_PLANE_YZ +#define GCODE_DEFAULT_COORD_SYSTEM G54 // G54, G55, G56, G57, G58 or G59 +#define GCODE_DEFAULT_PATH_CONTROL PATH_CONTINUOUS +#define GCODE_DEFAULT_DISTANCE_MODE ABSOLUTE_MODE + + +// *** motor settings ************************************************************************************ + +#define MOTOR_POWER_MODE MOTOR_POWERED_IN_CYCLE // default motor power mode (see cmMotorPowerMode in stepper.h) +#define MOTOR_POWER_TIMEOUT 20.00 // motor power timeout in seconds + +// *** motor settings *** + +/* Mapping for dual gantry setup */ +#define M1_MOTOR_MAP AXIS_X // 1ma +#define M1_STEP_ANGLE 1.8 // 1sa +#define M1_TRAVEL_PER_REV 36.54 // 1tr +#define M1_MICROSTEPS 32 // 1mi 1,2,4,8 +#define M1_POLARITY 0 // 1po 0=normal, 1=reversed +#define M1_POWER_MODE MOTOR_POWER_MODE // 1pm TRUE=low power idle enabled +#define M1_POWER_LEVEL 0.6 + +#define M2_MOTOR_MAP AXIS_Y +#define M2_STEP_ANGLE 1.8 +#define M2_TRAVEL_PER_REV 36.54 +#define M2_MICROSTEPS 32 +#define M2_POLARITY 1 +#define M2_POWER_MODE MOTOR_POWER_MODE +#define M2_POWER_LEVEL 0.6 + +#define M3_MOTOR_MAP AXIS_Y +#define M3_STEP_ANGLE 1.8 +#define M3_TRAVEL_PER_REV 36.54 +#define M3_MICROSTEPS 32 +#define M3_POLARITY 0 +#define M3_POWER_MODE MOTOR_POWER_MODE +#define M3_POWER_LEVEL 0.6 + +#define M4_MOTOR_MAP AXIS_Z +#define M4_STEP_ANGLE 1.8 +#define M4_TRAVEL_PER_REV 1.25 +#define M4_MICROSTEPS 32 +#define M4_POLARITY 0 +#define M4_POWER_MODE MOTOR_POWER_MODE +#define M4_POWER_LEVEL 0.5 + +// *** axis settings ********************************************************************************** + + +#define X_AXIS_MODE AXIS_STANDARD // xam see canonical_machine.h cmAxisMode for valid values +#define X_VELOCITY_MAX 16000 // xvm G0 max velocity in mm/min +#define X_FEEDRATE_MAX X_VELOCITY_MAX // xfr G1 max feed rate in mm/min +#define X_TRAVEL_MIN 0 // xtn minimum travel - used by soft limits and homing +#define X_TRAVEL_MAX 220 // xtm maximum travel - used by soft limits and homing +#define X_JERK_MAX 5000 // xjm yes, that's "5 billion" mm/(min^3) +#define X_JERK_HIGH_SPEED X_JERK_MAX // xjh +#define X_HOMING_INPUT 1 // xhi input used for homing or 0 to disable +#define X_HOMING_DIR 0 // xhd 0 to search to minimum, 1 to search to maximum +#define X_SEARCH_VELOCITY 3000 // xsv minus means move to minimum switch +#define X_LATCH_VELOCITY 100 // xlv mm/min +#define X_LATCH_BACKOFF 4 // xlb mm +#define X_ZERO_BACKOFF 0.5 // xzb mm + +#define Y_AXIS_MODE AXIS_STANDARD +#define Y_VELOCITY_MAX 16000 +#define Y_FEEDRATE_MAX Y_VELOCITY_MAX +#define Y_TRAVEL_MIN 0 +#define Y_TRAVEL_MAX 220 +#define Y_JERK_MAX 5000 +#define Y_JERK_HIGH_SPEED Y_JERK_MAX +#define Y_HOMING_INPUT 3 +#define Y_HOMING_DIR 0 +#define Y_SEARCH_VELOCITY 3000 +#define Y_LATCH_VELOCITY 100 +#define Y_LATCH_BACKOFF 4 +#define Y_ZERO_BACKOFF 0.5 + +#define Z_AXIS_MODE AXIS_STANDARD +#define Z_VELOCITY_MAX 300 +#define Z_FEEDRATE_MAX Z_VELOCITY_MAX +#define Z_TRAVEL_MIN 0 +#define Z_TRAVEL_MAX 100 +#define Z_JERK_MAX 25 // 50,000,000 +#define Z_JERK_HIGH_SPEED Z_JERK_MAX +#define Z_HOMING_INPUT 5 +#define Z_HOMING_DIR 0 +#define Z_SEARCH_VELOCITY Z_VELOCITY_MAX +#define Z_LATCH_VELOCITY 100 +#define Z_LATCH_BACKOFF 4 +#define Z_ZERO_BACKOFF 0.5 + +//*** Input / output settings *** +/* + IO_MODE_DISABLED + IO_ACTIVE_LOW aka NORMALLY_OPEN + IO_ACTIVE_HIGH aka NORMALLY_CLOSED + + INPUT_ACTION_NONE + INPUT_ACTION_STOP + INPUT_ACTION_FAST_STOP + INPUT_ACTION_HALT + INPUT_ACTION_RESET + + INPUT_FUNCTION_NONE + INPUT_FUNCTION_LIMIT + INPUT_FUNCTION_INTERLOCK + INPUT_FUNCTION_SHUTDOWN + INPUT_FUNCTION_PANIC + */ +// Xmin on v9 board +#define DI1_MODE NORMALLY_CLOSED +//#define DI1_ACTION INPUT_ACTION_STOP +#define DI1_ACTION INPUT_ACTION_NONE +#define DI1_FUNCTION INPUT_FUNCTION_LIMIT + +// Xmax +#define DI2_MODE NORMALLY_CLOSED +//#define DI2_ACTION INPUT_ACTION_STOP +#define DI2_ACTION INPUT_ACTION_NONE +#define DI2_FUNCTION INPUT_FUNCTION_LIMIT + +// Ymin +#define DI3_MODE NORMALLY_CLOSED +//#define DI3_ACTION INPUT_ACTION_STOP +#define DI3_ACTION INPUT_ACTION_NONE +#define DI3_FUNCTION INPUT_FUNCTION_LIMIT + +// Ymax +#define DI4_MODE NORMALLY_CLOSED +//#define DI4_ACTION INPUT_ACTION_STOP +#define DI4_ACTION INPUT_ACTION_NONE +#define DI4_FUNCTION INPUT_FUNCTION_LIMIT + +// Zmin +#define DI5_MODE IO_ACTIVE_HIGH // Z probe +#define DI5_ACTION INPUT_ACTION_NONE +#define DI5_FUNCTION INPUT_FUNCTION_NONE + +// Zmax +#define DI6_MODE NORMALLY_CLOSED +//#define DI6_ACTION INPUT_ACTION_STOP +#define DI6_ACTION INPUT_ACTION_NONE +#define DI6_FUNCTION INPUT_FUNCTION_LIMIT + +// Amin +#define DI7_MODE IO_MODE_DISABLED +#define DI7_ACTION INPUT_ACTION_NONE +#define DI7_FUNCTION INPUT_FUNCTION_NONE + +// Amax +#define DI8_MODE IO_MODE_DISABLED +#define DI8_ACTION INPUT_ACTION_NONE +#define DI8_FUNCTION INPUT_FUNCTION_NONE + +// Hardware interlock input +#define DI9_MODE IO_MODE_DISABLED +#define DI9_ACTION INPUT_ACTION_NONE +#define DI9_FUNCTION INPUT_FUNCTION_NONE + +// *** PWM SPINDLE CONTROL *** + +#define P1_PWM_FREQUENCY 5000 // in Hz +#define P1_CW_SPEED_LO 3000 // in RPM (arbitrary units) +#define P1_CW_SPEED_HI 12000 +#define P1_CW_PHASE_LO 0.15 // phase [0..1] +#define P1_CW_PHASE_HI 0.81 +#define P1_CCW_SPEED_LO 0 +#define P1_CCW_SPEED_HI 0 +#define P1_CCW_PHASE_LO 0.1 +#define P1_CCW_PHASE_HI 0.1 +#define P1_PWM_PHASE_OFF 0.0 From d0c236dc10a150503d84c3348346304824ca04c2 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Wed, 30 Nov 2016 09:09:37 -0500 Subject: [PATCH 48/98] update motate reference --- Motate | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Motate b/Motate index 7bc56538..1e1be74e 160000 --- a/Motate +++ b/Motate @@ -1 +1 @@ -Subproject commit 7bc565384538b7178340b882409afe9eb0f8f7b3 +Subproject commit 1e1be74e8b0dac10af1829ea211fef06f594ab7f From 161ca1b8f9099c247940e06fbee7c8f0088e4899 Mon Sep 17 00:00:00 2001 From: Rob Giseburt Date: Tue, 29 Nov 2016 12:45:15 -0600 Subject: [PATCH 49/98] Fixed v9k spindle not functioning. --- g2core/board/G2v9/G2v9k-pinout.h | 4 +- g2core/board/G2v9/motate_pin_assignments.h | 12 +++--- g2core/pwm.cpp | 44 +++++++--------------- 3 files changed, 21 insertions(+), 39 deletions(-) diff --git a/g2core/board/G2v9/G2v9k-pinout.h b/g2core/board/G2v9/G2v9k-pinout.h index 2e37c76b..71256d3f 100755 --- a/g2core/board/G2v9/G2v9k-pinout.h +++ b/g2core/board/G2v9/G2v9k-pinout.h @@ -119,10 +119,10 @@ _MAKE_MOTATE_PIN(kCoolant_EnablePinNumber, 'A', 1); // Coolant_EnableP _MAKE_MOTATE_PIN(kSocket4_VrefPinNumber, 'A', 2); // Socket4_VrefPinNumber _MAKE_MOTATE_PIN(kSocket5_VrefPinNumber, 'A', 3); // Socket5_VrefPinNumber _MAKE_MOTATE_PIN(kSocket2_Microstep_2PinNumber, 'A', 4); // Socket2_Microstep_2PinNumber -_MAKE_MOTATE_PIN(kOutput3_PinNumber, 'A', 5); // Spindle_EnablePinNumber -- now used for Fan 1 +_MAKE_MOTATE_PIN(kSpindle_EnablePinNumber, 'A', 5); // Spindle_EnablePinNumber _MAKE_MOTATE_PIN(kSocket1_DirPinNumber, 'A', 6); // Socket1_DirPinNumber _MAKE_MOTATE_PIN(kSpindle_DirPinNumber, 'A', 7); // Spindle_DirPinNumber -_MAKE_MOTATE_PIN(kOutput1_PinNumber, 'A', 8); // Spindle_PwmPinNumber -- now used for Extruder 1 +_MAKE_MOTATE_PIN(kSpindle_PwmPinNumber, 'A', 8); // Spindle_PwmPinNumber _MAKE_MOTATE_PIN(kInput2_PinNumber, 'A', 9); // XAxis_MaxPinNumber _MAKE_MOTATE_PIN(kInput3_PinNumber, 'A', 10); // YAxis_MinPinNumber _MAKE_MOTATE_PIN(kInput4_PinNumber, 'A', 11); // YAxis_MaxPinNumber diff --git a/g2core/board/G2v9/motate_pin_assignments.h b/g2core/board/G2v9/motate_pin_assignments.h index 4239e8e0..aca93eaf 100755 --- a/g2core/board/G2v9/motate_pin_assignments.h +++ b/g2core/board/G2v9/motate_pin_assignments.h @@ -139,15 +139,15 @@ pin_number kInput10_PinNumber = 109; pin_number kInput11_PinNumber = 110; pin_number kInput12_PinNumber = 111; +pin_number kSpindle_EnablePinNumber = 112; +pin_number kSpindle_DirPinNumber = 113; +pin_number kSpindle_PwmPinNumber = 114; +pin_number kSpindle_Pwm2PinNumber = 115; +pin_number kCoolant_EnablePinNumber = 116; + // START DEBUG PINS - Convenient pins to hijack for hardware debugging // To reuse a pin for debug change the original pin number to -1 // and uncomment the corresponding debug pin -pin_number kSpindle_EnablePinNumber = 112; // Spindle ON implemented in g2ref -pin_number kSpindle_DirPinNumber = 113; // Spindle ON implemented in g2ref -pin_number kSpindle_PwmPinNumber = -1; // 114; // Not implemented (superseded by Extruder1_PWM) -pin_number kSpindle_Pwm2PinNumber = -1; // 115; // Not implemented (superseded by Fan1B_PWM) -pin_number kCoolant_EnablePinNumber = 116; // Spindle ON implemented in g2ref - pin_number kDebug1_PinNumber = -1; // 112; pin_number kDebug2_PinNumber = -1; // 113; pin_number kDebug3_PinNumber = -1; // 116; // Note the out-of-order numbering & 115 missing diff --git a/g2core/pwm.cpp b/g2core/pwm.cpp index 82248fdf..61589443 100755 --- a/g2core/pwm.cpp +++ b/g2core/pwm.cpp @@ -31,6 +31,8 @@ #include "spindle.h" #include "text_parser.h" #include "pwm.h" +#include "canonical_machine.h" +#include "settings.h" /***** PWM defines, structures and memory allocation *****/ @@ -38,37 +40,8 @@ pwmSingleton_t pwm; // Setup motate PWM pins -static Motate::PWMOutputPin spindle_pwm_pin; -static Motate::PWMOutputPin secondary_pwm_pin; - -// defines common to all PWM channels -//#define PWM_TIMER_TYPE TC1_struct // PWM uses TC1's -#define PWM_TIMER_t TC1_t // PWM uses TC1's -#define PWM_TIMER_DISABLE 0 // turn timer off (clock = 0 Hz) -//#define PWM_MAX_FREQ (F_CPU/256) // max frequency with 8-bits duty cycle precision -//#define PWM_MIN_FREQ (F_CPU/64/65536) // min frequency with supported prescaling - -// channel specific defines -/* CLKSEL is used to configure default PWM clock operating ranges - * These can be changed by pwm_freq() depending on the PWM frequency selected - * - * The useful ranges (assuming a 32 Mhz system clock) are: - * TC_CLKSEL_DIV1_gc - good for about 500 Hz to 125 Khz practical upper limit - * TC_CLKSEL_DIV2_gc - good for about 250 Hz to 62 KHz - * TC_CLKSEL_DIV4_gc - good for about 125 Hz to 31 KHz - * TC_CLKSEL_DIV8_gc - good for about 62 Hz to 16 KHz - * TC_CLKSEL_DIV64_gc - good for about 8 Hz to 2 Khz - */ -#define PWM1_CTRLA_CLKSEL TC_CLKSEL_DIV1_gc // starting clock select value -#define PWM1_CTRLB (3 | TC0_CCBEN_bm) // single slope PWM enabled on channel B -#define PWM1_ISR_vect TCD1_CCB_vect // must match timer assignments in system.h -#define PWM1_INTCTRLB 0 // timer interrupt level (0=off, 1=lo, 2=med, 3=hi) - -#define PWM2_CTRLA_CLKSEL TC_CLKSEL_DIV1_gc -#define PWM2_CTRLB 3 // single slope PWM enabled, no output channel -//#define PWM2_CTRLB (3 | TC0_CCBEN_bm) // single slope PWM enabled on channel B -#define PWM2_ISR_vect TCE1_CCB_vect // must match timer assignments in system.h -#define PWM2_INTCTRLB 0 // timer interrupt level (0=off, 1=lo, 2=med, 3=hi) +Motate::PWMOutputPin spindle_pwm_pin {Motate::kNormal, P1_PWM_FREQUENCY}; +Motate::PWMOutputPin secondary_pwm_pin {Motate::kNormal, P1_PWM_FREQUENCY}; // assume the same frequency, to start with at least /***** PWM code *****/ /* @@ -99,6 +72,9 @@ stat_t pwm_set_freq(uint8_t chan, float freq) //if (freq > PWM_MAX_FREQ) { return (STAT_INPUT_EXCEEDS_MAX_VALUE);} if (chan == PWM_1) { + if (spindle_pwm_pin.canPWM()) { + cm_alarm(STAT_ALARM, "BOOM"); + } spindle_pwm_pin.setFrequency(freq); } else if (chan == PWM_2) { secondary_pwm_pin.setFrequency(freq); @@ -126,8 +102,14 @@ stat_t pwm_set_duty(uint8_t chan, float duty) if (duty > 1.0) { return (STAT_INPUT_EXCEEDS_MAX_VALUE);} if (chan == PWM_1) { + if (spindle_pwm_pin.isNull()) { + cm_alarm(STAT_ALARM, "attempt to turn on a non-existant spindle"); + } spindle_pwm_pin = duty; } else if (chan == PWM_2) { + if (secondary_pwm_pin.isNull()) { + cm_alarm(STAT_ALARM, "attempt to turn on a non-existant spindle"); + } secondary_pwm_pin = duty; } From d5c978a4dc37c13dd9e6c14a8de626df124ad6f3 Mon Sep 17 00:00:00 2001 From: Rob Giseburt Date: Wed, 30 Nov 2016 09:00:36 -0600 Subject: [PATCH 50/98] Adjusted P1_* default settings to not be floats. --- g2core/settings/settings_default.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/g2core/settings/settings_default.h b/g2core/settings/settings_default.h index 233346c3..341948ff 100755 --- a/g2core/settings/settings_default.h +++ b/g2core/settings/settings_default.h @@ -853,13 +853,13 @@ // *** PWM Settings *** // #ifndef P1_PWM_FREQUENCY -#define P1_PWM_FREQUENCY 100.0 // in Hz +#define P1_PWM_FREQUENCY 100 // in Hz #endif #ifndef P1_CW_SPEED_LO -#define P1_CW_SPEED_LO 7900.0 // in RPM (arbitrary units) +#define P1_CW_SPEED_LO 7900 // in RPM (arbitrary units) #endif #ifndef P1_CW_SPEED_HI -#define P1_CW_SPEED_HI 12800.0 +#define P1_CW_SPEED_HI 12800 #endif #ifndef P1_CW_PHASE_LO #define P1_CW_PHASE_LO 0.13 // phase [0..1] From 296a181afba378f896ccab29577a5e6988519aa3 Mon Sep 17 00:00:00 2001 From: Rob Giseburt Date: Tue, 29 Nov 2016 12:45:32 -0600 Subject: [PATCH 51/98] Update Xcode project --- g2core/g2core.xcodeproj/project.pbxproj | 42 ++----------------------- 1 file changed, 3 insertions(+), 39 deletions(-) diff --git a/g2core/g2core.xcodeproj/project.pbxproj b/g2core/g2core.xcodeproj/project.pbxproj index d6ac4fe3..4f588ced 100644 --- a/g2core/g2core.xcodeproj/project.pbxproj +++ b/g2core/g2core.xcodeproj/project.pbxproj @@ -53,6 +53,7 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + D41271CF1DED1D6200470A46 /* settings */ = {isa = PBXFileReference; lastKnownFileType = folder; path = settings; sourceTree = ""; }; D43FF6F51D52C8AF00FB5B53 /* board */ = {isa = PBXFileReference; lastKnownFileType = folder; path = board; sourceTree = ""; }; D44E72C01D663B0300ECD5DD /* coolant.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = coolant.cpp; sourceTree = ""; }; D44E72C21D663B0F00ECD5DD /* coolant.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = coolant.h; sourceTree = ""; }; @@ -98,25 +99,10 @@ D48F5A7F172CB21100D0E055 /* g2core.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = g2core.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; D48F5A80172CB21100D0E055 /* util.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = util.h; sourceTree = ""; }; D48F5A81172CB21100D0E055 /* xio.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = xio.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; - D49177A11D21CFC50029CDEB /* settings_Printrbot_Simple_1403.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = settings_Printrbot_Simple_1403.h; sourceTree = ""; }; - D49177A21D21CFDB0029CDEB /* settings_Printrbot_Simple_1608.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = settings_Printrbot_Simple_1608.h; sourceTree = ""; }; D4922F3F1CB8361B00A565FF /* boards.mk */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = boards.mk; sourceTree = ""; }; D49367D71B87CA8A000BB759 /* temperature.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = temperature.cpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; D49367D81B87CA8A000BB759 /* temperature.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = temperature.h; sourceTree = ""; }; D49367DB1B8E0AF1000BB759 /* error.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = error.h; sourceTree = ""; }; - D4AC39081C77C1F20098D685 /* settings_default.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = settings_default.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; - D4AC39091C77C1F20098D685 /* settings_makeblock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = settings_makeblock.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; - D4AC390A1C77C1F20098D685 /* settings_othermill_test.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = settings_othermill_test.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; - D4AC390B1C77C1F20098D685 /* settings_othermill.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = settings_othermill.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; - D4AC390C1C77C1F20098D685 /* settings_Printrbot_Play.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = settings_Printrbot_Play.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; - D4AC390D1C77C1F20098D685 /* settings_Printrbot_Plus.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = settings_Printrbot_Plus.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; - D4AC390F1C77C1F20098D685 /* settings_probotixV90.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = settings_probotixV90.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; - D4AC39101C77C1F20098D685 /* settings_shapeoko2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = settings_shapeoko2.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; - D4AC39111C77C1F20098D685 /* settings_shopbot_sbv300.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = settings_shopbot_sbv300.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; - D4AC39121C77C1F20098D685 /* settings_shopbot_test.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = settings_shopbot_test.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; - D4AC39131C77C1F20098D685 /* settings_test.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = settings_test.h; sourceTree = ""; }; - D4AC39141C77C1F20098D685 /* settings_Ultimaker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = settings_Ultimaker.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; - D4AC39151C77C1F20098D685 /* settings_zen7x12.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = settings_zen7x12.h; sourceTree = ""; }; D4B6579C18B5C1DE00F8616C /* plan_exec.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = plan_exec.cpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; D4B6579E18B5C21500F8616C /* cycle_jogging.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = cycle_jogging.cpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; D4B6579F18B5C21500F8616C /* cycle_probing.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = cycle_probing.cpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; @@ -142,28 +128,6 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ - D41D13F617374B7D00D522D9 /* settings */ = { - isa = PBXGroup; - children = ( - D4AC39081C77C1F20098D685 /* settings_default.h */, - D4AC39091C77C1F20098D685 /* settings_makeblock.h */, - D4AC390A1C77C1F20098D685 /* settings_othermill_test.h */, - D4AC390B1C77C1F20098D685 /* settings_othermill.h */, - D4AC390C1C77C1F20098D685 /* settings_Printrbot_Play.h */, - D4AC390D1C77C1F20098D685 /* settings_Printrbot_Plus.h */, - D49177A11D21CFC50029CDEB /* settings_Printrbot_Simple_1403.h */, - D49177A21D21CFDB0029CDEB /* settings_Printrbot_Simple_1608.h */, - D4AC390F1C77C1F20098D685 /* settings_probotixV90.h */, - D4AC39101C77C1F20098D685 /* settings_shapeoko2.h */, - D4AC39111C77C1F20098D685 /* settings_shopbot_sbv300.h */, - D4AC39121C77C1F20098D685 /* settings_shopbot_test.h */, - D4AC39131C77C1F20098D685 /* settings_test.h */, - D4AC39141C77C1F20098D685 /* settings_Ultimaker.h */, - D4AC39151C77C1F20098D685 /* settings_zen7x12.h */, - ); - path = settings; - sourceTree = ""; - }; D45710B7170532AC00EA19A8 = { isa = PBXGroup; children = ( @@ -227,7 +191,7 @@ D4922F3F1CB8361B00A565FF /* boards.mk */, D43FF6F51D52C8AF00FB5B53 /* board */, D47B744C1D4925B4004FAB53 /* device */, - D41D13F617374B7D00D522D9 /* settings */, + D41271CF1DED1D6200470A46 /* settings */, D4FEBFF81B0A65E30042EA32 /* index */, ); sourceTree = ""; @@ -307,7 +271,7 @@ }; D4B485B21AB1F3CB00C6614F /* G2 V9 Shapeoko Dual-Y */ = { isa = PBXLegacyTarget; - buildArgumentsString = "$(ACTION) VERBOSE=1 COLOR=0 CONFIG=ShapeokoDualY"; + buildArgumentsString = "$(ACTION) VERBOSE=1 COLOR=0 CONFIG=ShapeokoDualY SETTINGS_FILE=settings_shapeoko375_Dual.h"; buildConfigurationList = D4B485B31AB1F3CB00C6614F /* Build configuration list for PBXLegacyTarget "G2 V9 Shapeoko Dual-Y" */; buildPhases = ( ); From a3752237bbfffdeef2e58be0d9a68f3342e0d571 Mon Sep 17 00:00:00 2001 From: Rob Giseburt Date: Tue, 29 Nov 2016 12:45:53 -0600 Subject: [PATCH 52/98] Adjusted settings default to use an enum instead of hard-coded value. --- g2core/settings/settings_default.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/g2core/settings/settings_default.h b/g2core/settings/settings_default.h index 233346c3..e91e6162 100755 --- a/g2core/settings/settings_default.h +++ b/g2core/settings/settings_default.h @@ -82,7 +82,7 @@ #endif #ifndef SPINDLE_ENABLE_POLARITY -#define SPINDLE_ENABLE_POLARITY 1 // {spep: 0=active low, 1=active high +#define SPINDLE_ENABLE_POLARITY SPINDLE_ACTIVE_HIGH // {spep: 0=active low, 1=active high #endif #ifndef SPINDLE_DIR_POLARITY From 5214a7e2a1cad361b420eba3297cf89934a8169c Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Wed, 30 Nov 2016 18:54:18 -0500 Subject: [PATCH 53/98] Checkpoint a whole of of new commenting on the planner. Not done yet. --- g2core.atsln | 3 - g2core/g2core.cppproj | 14 +-- g2core/g2core_info.h | 2 +- g2core/plan_exec.cpp | 220 ++++++++++++++++++++++++++++++++---------- g2core/plan_line.cpp | 11 ++- g2core/plan_zoid.cpp | 10 +- g2core/planner.cpp | 19 ++-- g2core/planner.h | 133 ++++++++++++++++++++++++- 8 files changed, 327 insertions(+), 85 deletions(-) mode change 100755 => 100644 g2core.atsln mode change 100755 => 100644 g2core/plan_zoid.cpp mode change 100755 => 100644 g2core/planner.cpp mode change 100755 => 100644 g2core/planner.h diff --git a/g2core.atsln b/g2core.atsln old mode 100755 new mode 100644 index 73d8f923..93cd6ae1 --- a/g2core.atsln +++ b/g2core.atsln @@ -3,9 +3,6 @@ Microsoft Visual Studio Solution File, Format Version 12.00 VisualStudioVersion = 14.0.23107.0 MinimumVisualStudioVersion = 10.0.40219.1 Project("{E66E83B9-2572-4076-B26E-6BE79FF3018A}") = "g2core", "g2core\g2core.cppproj", "{44EA8FEC-55D7-4149-8A78-A574FC26BF51}" - ProjectSection(ProjectDependencies) = postProject - {D7779B24-5CD6-4A1B-893C-2CAE8CF7A3A0} = {D7779B24-5CD6-4A1B-893C-2CAE8CF7A3A0} - EndProjectSection EndProject Project("{E66E83B9-2572-4076-B26E-6BE79FF3018A}") = "Motate", "Motate\Motate.cppproj", "{D7779B24-5CD6-4A1B-893C-2CAE8CF7A3A0}" EndProject diff --git a/g2core/g2core.cppproj b/g2core/g2core.cppproj index cec892fb..974faa35 100644 --- a/g2core/g2core.cppproj +++ b/g2core/g2core.cppproj @@ -1,11 +1,11 @@ - + 2.0 7.0 com.Atmel.ARMGCC.CPP {44ea8fec-55d7-4149-8a78-a574fc26bf51} - ATSAMS70N19 + ATSAM3X8C none Executable CPP @@ -68,12 +68,12 @@ - 10000000 + 2000000 SWD com.atmel.avrdbg.tool.atmelice - J41800006366 + J41800030015 Atmel-ICE True @@ -100,9 +100,9 @@ True true - J41800006366 - 0xA11D0A00 - 10000000 + J41800030015 + 0x284E0A60 + 2000000 diff --git a/g2core/g2core_info.h b/g2core/g2core_info.h index d81a3420..f9a5344a 100644 --- a/g2core/g2core_info.h +++ b/g2core/g2core_info.h @@ -21,7 +21,7 @@ #ifndef G2CORE_INFO_H_ONCE #define G2CORE_INFO_H_ONCE -#define G2CORE_FIRMWARE_BUILD 100.12 // Fix UART flow control +#define G2CORE_FIRMWARE_BUILD 100.12 // Changes to USB serial for SAMS70 and SAM8X targets #ifdef GIT_VERSION #define G2CORE_FIRMWARE_BUILD_STRING GIT_VERSION #else diff --git a/g2core/plan_exec.cpp b/g2core/plan_exec.cpp index 7360058d..cebaf810 100644 --- a/g2core/plan_exec.cpp +++ b/g2core/plan_exec.cpp @@ -49,86 +49,186 @@ static void _init_forward_diffs(float v_0, float v_1); /************************************************************************* * mp_plan_move() - call ramping function to plan moves ahead of the exec * - * This should NOT normally be called directly! Instead call st_request_plan_move(). + * mp_plan_move() performs just-in-time forward planning immediately before + * lines and commands are queued to the move execution runtime (exec). + * It examines the currently running buffer and its adjacent buffers to: + * - Stop the system from re-planning or planning something that's not prepped + * - Plan the next available ALINE (movement) block past the COMMAND blocks + * - Skip past/ or pre-plan COMMAND blocks while labeling them as PLANNED + * + * Returns STAT_OK if exec should be called to start (or continue) movement, + * or exit with no action (STAT_NOOP) if exec does not need to be called. + * + **** WARNING **** + **** This function should NOT be called directly! Instead call + **** st_request_plan_move(), which mediates access. Mp_plan_move() is called + **** aggressively from multiple places and multiple interrupt levels, + **** and has a relatively low interrupt level to call its own. + */ +/* + * Forward Planning Background + * + * - Forward planning only occurs once, JIT just ahead of the exec + Forward planning only ever originates from the run buffer (mb.r), only occurs once for each block + * - + * - 'Bootstrap' refers to startup condition w/buffers arriving before movement starts + * - see planner.h / bufferState enum for shorthand used + * - The + */ +/* + * Forward Planning Cases + * + * + * CASE: + * 0. NOT_PREPPED. No lines or commands in planner buffer. Exit with no action + * This case also handles case before a run buffer can be assigned + * + * 1. Bootstrap cases, lines only, N lines in buffer, 2 blocks (JIT planning queue only has plan and run) + * run_buffer next_buffer + * a. NOT_PREPPED don't care Action: exit no action (backplanner is still running) + * b. PREPPED don't care Action: plan line, exit OK (prepped means backplanned) + * c. PLANNED don't care Action: exit no action (cannot plan next buffer beyond current PLANNED buffer) + * + * 1'. Bootstrap cases, lines only, N lines in buffer, N blocks (deeper JIT planning queue) + * run_buffer next_buffer + * a. NOT_PREPPED don't care Action: exit no action (backplanner is still running) + * b. PREPPED don't care Action: plan line, exit OK (prepped means backplanned) + * c. PLANNED, NOT_PREPPED Action: exit no action (cannot plan next buffer beyond current PLANNED buffer) + * d. PLANNED, PREPPED Action: plan the next block into the next planner block if the + * next planner block is NOT the run BLOCK. This can iterate to more blocks + * + * 2. Running cases, lines only, N lines in buffer, 2 blocks + * run_buffer next_buffer + * a. RUNNING NOT_PREPPED Action: exit no action (backplanner is still running) + * b. RUNNING PREPPED Action: plan buffer, exit OK (do a JIT plan) + * c. RUNNING PLANNED Action: exit no action + + * 3. Bootstrap cases, lines and commands mixed, N lines in buffer, 2 blocks + (Note: NOT_PREPPED can be either line or command) + + * run_buffer next/last buffer + * a. NOT_PREPPED (any state) Action: exit no action + * b. PREPPED-LINE (any state) Action: plan line, exit OK + * c. PLANNED-LINE NOT_PREPPED Action: exit no action (cannot plan next buffer beyond current PLANNED buffer) + * d. PLANNED-LINE PREPPED Action: plan the next block into the next planner block if the + * a. PREPPED-CMD(s) NOT_PREPPED Action: set contiguous PREPPED-COMMANDs to PLANNED, exit OK + * b. PREPPED-CMD(s) PREPPED-LINE Action: set contiguous PREPPED-COMMANDs to PLANNED, + * carry forward initial exit_velocity (see note *) + * iterate to PREPPED-LINE, plan line, exit OK. + * + * (*) Use mr.entry_velocity for the run velocity, which is almost always 0, but could be non-0 in a race condition. + * + * 4. Running cases, lines and commands mixed, N lines in buffer, 2 blocks + * All running cases start with first block is running (Note: NOT_PREPPED can be either line or command) + * run_buffer next N buffers terminating buffer + * a. RUNNING-LINE PREPPED-COMAND(s) NOT_PREPPED Action: Call mp_plan_command(), exit OK + * b. RUNNING-LINE PREPPED-COMAND(s) PREPPED-LINE Action: Mark all commands as PLANNED and exit OK + * Plan PREPPED-LINE using exit_velocity of run block + * (We trust exit velocity here because the backplanner has already handled this) + * c. RUNNING-LINE PREPPED-LINE (identical to 2b) Action: plan buffer, exit OK (do a JIT plan) + * d. RUNNING-LINE PLANNED-LINE (identical to 2c) Action: exit no action + * + * e. RUNNING-LINE PLANNED-COMMAND9s) Action: iterate over the PLANNED and PREPPED commands, skipping PLANNED + * f. PLANNED-COMMAND (anything) + * + * g. RUNNING-COMMAND (anything) as cases 4a - 4e, but use mr.entry_velocity + */ + +/* PSEUDOCODE + * + * + * Test the running buffer for early exit conditions. + * (In the motion startup (bootstrap) condition the "running" block is not actually running yet) + * If nothing is actually running, ext immediately (prevents a race condition) + * + * Test the planning buffer + * Explanation: There are 2 cases where this can occur: + (1) nothing is actually running + (2) something is running + The case changes which buffer is passed to calculate _ramps(), and what the entry_velocity is. + + * Code: See if the running buffer is -in-fact- running + * If so, move off the running buffer to the next buffer + * Set the entry velocity for be the exit velocity of the running block * */ + +static stat_t _plan_command(mpBuf_t *bf) +{ + bf->buffer_state = MP_BUFFER_PLANNED; // report that we "planned" something... + return (STAT_OK); +} + stat_t mp_plan_move() { mpBuf_t *bf; - // NULL means nothing's running - this is OK - if ((bf = mp_get_run_buffer()) == NULL) { + // Examine current running buffer for early exit conditions + if ((bf = mp_get_run_buffer()) == NULL) { // NULL means nothing's running - this is OK st_prep_null(); return (STAT_NOOP); } - if (bf->buffer_state < MP_BUFFER_PREPPED) { - // Get outta here. - // We did nothing - return (STAT_NOOP); + return (STAT_NOOP); // get outta here - we did nothing } - - if (bf->block_type != BLOCK_TYPE_ALINE) { - // Nothing to see here... - - bf->buffer_state = MP_BUFFER_PLANNED; - - // report that we "planned" something... +///* + if (bf->block_type != BLOCK_TYPE_ALINE) { // nothing to see here... + bf->buffer_state = MP_BUFFER_PLANNED; // report that we "planned" something... return (STAT_OK); } +//*/ + // Examine the next plannable block(s) NB: at this point bf == bf.r + float entry_velocity = mr.entry_velocity; // used for - // We default to the planning block - mpBlockRuntimeBuf_t* block = mr.p; - - // Default to the planning buffer - float entry_velocity = mr.entry_velocity; - - // At this point, bf == bf.r if (bf->buffer_state == MP_BUFFER_RUNNING) { - // Update bf to bf->nx, set entry_* to mr.r->exit_*. bf = bf->nx; - entry_velocity = mr.r->exit_velocity; + entry_velocity = mr.r->exit_velocity; // set entry_* to mr.r->exit_* if (bf->buffer_state < MP_BUFFER_PREPPED) { - // Get outta here. - // We did nothing - return (STAT_NOOP); + return (STAT_NOOP); // get outta here - we did nothing } - +/* + while (bf->buffer_state < MP_BUFFER_PLANNED) { + if (mp_get_next_buffer(bf)->buffer_state < MP_BUFFER_PREPPED) { // i.e. EMPTY + return (STAT_OK); // ...and invoke an EXEC call + } + return (STAT_NOOP); // get outta here - we did nothing + } +*/ if (bf->block_type != BLOCK_TYPE_ALINE) { - // Nothing to see here... - - bf->buffer_state = MP_BUFFER_PLANNED; - // report that we "planned" something... - return (STAT_OK); + return (_plan_command(bf)); } } if (bf->buffer_state == MP_BUFFER_PLANNED) { - // Get outta here. - // We did nothing - return (STAT_NOOP); + return (STAT_NOOP); // get outta here - we did nothing } + // Pass in the bf buffer that will "link" with the planned block + // The block and the buffer are implicitly linked for exec_aline() + // Calculate ramps for the current planning block and the next PREPPED buffer + // The PREPPED buffer will be set to PLANNED later... + // // Note that that can only be one PLANNED move at a time. // This is to help sync mr.p to point to the next planned mr.bf - // mr.p is only advanced in mp_exec_aline, after mp.r = mr.p. + // mr.p is only advanced in mp_exec_aline(), after mp.r = mr.p. + // This code aligns the buffers and the blocks for exec_aline(). + mpBlockRuntimeBuf_t* block = mr.p; // set a local planning block to the current planning block mp_calculate_ramps(block, bf, entry_velocity); +// mp_calculate_ramps(mr.p, bf, entry_velocity); if (block->exit_velocity > block->cruise_velocity) { - __asm__("BKPT"); // exit > cruise after calculate_block + __asm__("BKPT"); // exit > cruise after calculate_block } if (block->head_length < 0.00001 && block->body_length < 0.00001 && block->tail_length < 0.00001) { - __asm__("BKPT"); // zero or negative length block + __asm__("BKPT"); // zero or negative length block } - bf->buffer_state = MP_BUFFER_PLANNED; + bf->buffer_state = MP_BUFFER_PLANNED; //...here bf->plannable = false; - - // report that we planned something... - return (STAT_OK); + return (STAT_OK); // report that we planned something... } /************************************************************************* @@ -246,12 +346,33 @@ stat_t mp_exec_move() * _NEW - trigger initialization * _RUN1 - run the first part * _RUN2 - run the second part + * + * Important distinction to note: + * - mp_plan move() is called for every type of move + * - mp_exec_move() is called for every type of move + * - mp_exec_aline() is only called for alines */ -/* Note: - * For a version of these routines that execute using the original equation-of-motion - * math (as opposed to the forward difference math) please refer to build 357.xx or earlier. - * Builds 358 onward have only forward difference code. ALso, the Kahan corrections for the - * forward differencing were also been removed shortly after as they were not needed. +/* Synchronization of run BUFFER and run BLOCK + * + * The runtime uses 2 structures for the current move or commend, the run BUFFER + * from the planner queue (mb), and the run BLOCK from the runtime singleton (mr). + * These are synchronized implicitly, but not explicitly referenced, as pointers + * can lead to race conditions. See plan_zoid.cpp / mp_calculate_ramps() for more details + * + * Mp_exec_aline() makes a huge assumption: When it comes time to get a new run block + * (mr.r) it assumes the planner block (mr.p) has been fully planned (JIT planning), + * and is ready for use as the new run block. + * + * When mp_exec_aline() needs to grab a new planner buffer for a new move or command + * (i.e. block state is inactive) it swaps (rolls) the run and planner BLOCKS so that + * mr.p (planner block) is now the mr.r (run block), and the old mr.r block becomes + * available for planning; it becomes mr.p block. + * + * At the same time, it's when finished with its current run buffer (mb.r), it has already + * advanced to the next buffer. mp_exec_move() does this at the end of previous move. + * Or in the bootstrap case, there never was a previous mb.r, so the current one is OK. + * + * As if by magic, the new mb.r aligns with the run block that was just moved in from the planning block */ /**** NOTICE ** NOTICE ** NOTICE **** @@ -290,8 +411,9 @@ stat_t mp_exec_aline(mpBuf_t *bf) mr.section = SECTION_HEAD; mr.section_state = SECTION_NEW; - mr.r = mr.p; - mr.p = mr.p->nx; + // This is the only place in the system where mr.r and mr.p are allowed to be changed + mr.r = mr.p; // we are now going to run the planning block + mr.p = mr.p->nx; // re-use the old running block as the new planning block // Assumptions that are required for this to work: // entry velocity <= cruise velocity && cruise velocity >= exit velocity diff --git a/g2core/plan_line.cpp b/g2core/plan_line.cpp index 3ff78f26..76c35a63 100644 --- a/g2core/plan_line.cpp +++ b/g2core/plan_line.cpp @@ -194,6 +194,7 @@ stat_t mp_aline(GCodeState_t* gm_in) if (fp_ZERO(length)) { sr_request_status_report(SR_REQUEST_TIMED_FULL); // Was SR_REQUEST_IMMEDIATE_FULL return (STAT_MINIMUM_LENGTH_MOVE); +// return (STAT_OK); //+++++ test this } // get a cleared buffer and copy in the Gcode model state @@ -285,13 +286,13 @@ static mpBuf_t* _plan_block(mpBuf_t* bf) } } _calculate_override(bf); // adjust cruise_vmax for feed/traverse override - // bf->plannable_time = bf->pv->plannable_time; // set plannable time - excluding current move + // bf->plannable_time = bf->pv->plannable_time; // set plannable time - excluding current move bf->buffer_state = MP_BUFFER_IN_PROCESS; // +++++ Why do we have to do this here? // bf->pv_group = bf->pv; - bf->hint = NO_HINT; // ensure we've cleared the hints + bf->hint = NO_HINT; // ensure we've cleared the hints // Time: 12us-41us if (bf->nx->plannable) { // read in new buffers until EMPTY return (bf->nx); @@ -319,15 +320,15 @@ static mpBuf_t* _plan_block(mpBuf_t* bf) bf->iterations++; bf->plannable = bf->plannable && !optimal; // Don't accidentally enable plannable! - // Let's be mindful that for ward planning may change exit_vmax, and our exit velocity may be lowered + // Let's be mindful that forward planning may change exit_vmax, and our exit velocity may be lowered braking_velocity = min(braking_velocity, bf->exit_vmax); // We *must* set cruise before exit, and keep it at least as high as exit. bf->cruise_velocity = max(braking_velocity, bf->cruise_velocity); bf->exit_velocity = braking_velocity; - // We have two places where it could be a mixed decel or an asymetric bump, - // dpending on if the pv->exit_vmax is the same as bf.cruise_vmax + // We have two places where it could be a mixed decel or an asymmetric bump, + // depending on if the pv->exit_vmax is the same as bf.cruise_vmax bool test_decel_or_bump = false; // command blocks diff --git a/g2core/plan_zoid.cpp b/g2core/plan_zoid.cpp old mode 100755 new mode 100644 index 8e9c3025..28a54ee4 --- a/g2core/plan_zoid.cpp +++ b/g2core/plan_zoid.cpp @@ -80,7 +80,7 @@ static float _get_meet_velocity(const float v_0, * * Note we use three data structures: mr, bf, and block. * - * bf holds the data from aline and back-planning. For the most part it is immuatable. + * bf holds the data from aline and back-planning. For the most part it is immutable. * * block is the data for forward-planning. There are only two block structures, and they * are for the current block and the next block. @@ -94,8 +94,8 @@ static float _get_meet_velocity(const float v_0, * * All values of block are expected to be setup by mp_calculate_ramps. * - * Quick cheat-sheet on which is in bf and whcih is in block: - * bf: + * Quick cheat-sheet on which is in buffer (bf) and which is in block: + * buffer (bf): * block_type * hint * {cruise,exit}_vmax @@ -290,9 +290,9 @@ void mp_calculate_ramps(mpBlockRuntimeBuf_t* block, mpBuf_t* bf, const float ent // PERFECT_DECELERATION // MIXED_DECELERATION - // All that remians is ASYMMETRIC_BUMP and SYMMETRIC_BUMP. + // All that remains is ASYMMETRIC_BUMP and SYMMETRIC_BUMP. // We don't really care if it's symmetric, since the first test that _get_meet_velocity - // does is for a symmetic move. It's cheaper to just let it do that then to try and prevent it. + // does is for a symmetric move. It's cheaper to just let it do that then to try and prevent it. // *** Requested-Fit cases (2) *** diff --git a/g2core/planner.cpp b/g2core/planner.cpp old mode 100755 new mode 100644 index 853d9586..69aac4ab --- a/g2core/planner.cpp +++ b/g2core/planner.cpp @@ -44,7 +44,7 @@ * functions. Data from the Gcode model is transferred to the motion planner by the mp_xxxx() * functions called by the canonical machine. * - * The planner should only use data in the planner model. When a move (block) is ready for + * The planner should only use data in the planner model. When a move (buffer) is ready for * execution the relevant data from the planner is transferred to the runtime model, * which should also be isolated. * @@ -470,8 +470,8 @@ bool mp_is_phat_city_time() * mp_planner_callback()'s job is to invoke backward planning intelligently. * The flow of control and division of responsibilities for planning is: * - * - mp_aline() receives new Gcode blocks and initializes the local variables - * for the new block. + * - mp_aline() receives new Gcode moves and initializes the local variables + * for the new buffer. * * - mp_planner_callback() is called regularly from the main loop. * It's job is to determine whether or not to call mp_plan_block_list(), @@ -480,9 +480,9 @@ bool mp_is_phat_city_time() * mp_planner_callback() also manages planner state - whether the planner * is IDLE, in STARTUP or in one of the running states. * - * - _plan_block_list() / _planblock() is the backward planning function. + * - _plan_block() is the backward planning function for a single buffer. * - * - Forward planning is just-in-time by the execution runtime + * - Just-in-time forward planning is performed by mp_plan_move() in the plan_exec.cpp runtime executive * * Some Items to note: * @@ -542,12 +542,9 @@ void mp_replan_queue(mpBuf_t *bf) { do { if (bf->buffer_state >= MP_BUFFER_PLANNED) { - // revert from PLANNED state - bf->buffer_state = MP_BUFFER_PREPPED; - } else { - // If it's not "planned" then it's either PREPPED or earlier. - // We don't need to adjust it. - break; + bf->buffer_state = MP_BUFFER_PREPPED; // revert from PLANNED state + } else { // If it's not "planned" then it's either PREPPED or earlier. + break; // We don't need to adjust it. } } while ((bf = mp_get_next_buffer(bf)) != mb.r); diff --git a/g2core/planner.h b/g2core/planner.h old mode 100755 new mode 100644 index 1863b00a..664d19a1 --- a/g2core/planner.h +++ b/g2core/planner.h @@ -25,6 +25,126 @@ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/* + * --- Background on the Planner --- + * + * The planner is a complicated beast that takes a lot of things into account. + * Planner documentation is scattered about and co-located with the functions + * that perform the actions. Key files are: + * + * - planner.h - This file has defines, structures and prototypes. What you would expect + * - planner.cpp - Core and common functions, queue handling, JSON and command handlers + * - plan_line.cpp - Move planning and queuing, backward planning functions + * - plan_zoid.cpp - Move forward planning, velocity contour calculations and crazy math + * - plan_exec.cpp - Runtime execution functions, calls zoid's forward planning functions + * - stepper.cpp/h - Real-time step generation, segment loading, pulls from plan_exec + * - plan_arc.cpp/h- Arc calculation and runtime functions - layer above the rest of this + * + * --- Overview of Operation --- + * + * At high level the planner's job is to reconstruct smooth motion from a set of linear + * approximations while observing and operating within the physical constraints of the + * machine and the physics of motion. Gcode - which consists of a series of into linear + * motion segments - is interpreted, queued to the planner, and joined together to produce + * continuous, synchronized motion. Non-motion commands such as pauses (dwells) and + * peripheral controls such as spindles can also be synchronized in the queue. Arcs are + * just a special case consisting of many linear moves. Arcs are not interpreted directly. + * + * The planner sits in the middle of three system layers: + * - The Gcode interpreter and canonical machine (the 'model'), which feeds... + * - The planner - taking generic commands from the model and queuing them for... + * - The runtime layer - pulling from the planner and driving stepper motors or other devices + * + * The planner queue is the heart of the planner. It's a circular list of ~48 complex structures + * that carry the state of the system needs to execute a linear motion, run a pre-planned command, + * like turning on a spindle, or executing an arbitrary JSON command such as an active comment. + * + * The queue can be viewed as a list of instructions that will execute in exact sequence. + * Some instructions control motion and need to be joined to their forward and backwards + * neighbors so that position, velocity, acceleration, and jerk constraints are not + * violated when moving from one motion to the next. + * + * Others are "commands" that are actually just function callbacks that happen to execute + * at a particular point in time (synchronized with motion commands). Commands can control + * anything you can reasonably program, such as digital IO, serial communications, or + * interpreted commands encoded in JSON. + * + * The buffers in the planner queue are treated as a 'closure' - with all state needed for + * proper execution carried in the planner structure. This is important as it keeps + * model state coherent in a heavily pipelined system. The local copy of the Gcode + * model is carried in the gm structure that is part of each planner buffer. + * See header notes in planner.cpp for more details. + * + * The planner is entered by calling one of: + * - mp_aline() - plan and queue a move with acceleration management + * - mp_dwell() - plan and queue a pause (dwell) to the planner queue + * - mp_queue_command() - queue a canned command + * - mp_json_command() - queue a JSON command for run-time interpretation and execution (M100) + * - mp_json_wait() - queue a JSON wait for run-time interpretation and execution (M101) + * - + * In addition, cm_arc_feed() valaidates and sets up a arc paramewters and calls mp_aline() + * repeatedly to spool out the arc segments into the planner queue. + * + * All the above queueing commands other than mp_aline() are relatively trivial; they just + * post callbacks into the next available planner buffer. Command functions are in 2 parts: + * the part that posts to the queue, and the callback that is executed when the command is + * finally reached in the queue - the _exec(). + * + * All mp_aline() does is some preliminary math and then posts an initialized buffer to + * the planner queue. The rest of the move planning operations takes place in background; + * via mp_planner_callback() called from the main loop, and as 'pulls' from the runtime + * stepper operations. + * + * Motion planning is separated into backward planning and forward planning stages. + * Backward planning is initiated by mp_planner_callback() which is called repeatedly + * from the main loop. Backwards planning is performed by mp_plan_block_list() and + * _plan_block(). It starts at the most recently arrived Gcode block. Backward + * planning can occur multiple times for a given buffer, as new moves arriving + * can make the motion profile more optimal. + * + * Backward planning uses velocity and jerk constraints to set maximum entry, + * travel (cruise) and exit velocities for the moves in the queue. In addition, + * it observes the maximum cornering velocities that adjoining moves can sustain + * in a corner or a 'kink' to ensure that the jerk limit of any axis participating + * in the move is not violated. See mp_planner_callback() header comments for more detail. + * + * Forward planning is performed just-in-time and only once, right before the + * planner runtime needs the next buffer. Forward planning provides the final + * contouring of the move. It is invoked by mp_plan_move() and executed by + * mp_calculate_ramps() in plan_zoid.cpp. + * + * Planner timing operates at a few different levels: + * + * - New lines of ASCII containing commands and moves arriving from the USB are + * parsed and executed as the lowest priority background task from the main loop. + * + * - Backward planning is invoked by a main loop callback, so it also executes as + * a background task, albeit a higher priority one. + * + * - Forward planning and the ultimate preparation of the move for the runtime runs + * as an interrupt as a 'pull' from the planner queue that uses a series of + * interrupts at progressively lower priorities to ensure that the next planner + * buffer is ready before the runtime runs out of forward-planned moves and starves. + * + * Some other functions performed by the planner include: + * + * - Velocity throttling to ensure that very short moves do not execute faster + * than the serial interface can deliver them + * + * - Feedhold and resume operations + * + * - Feed rate override functions and replanning + * + * Some terms that are useful that we try to use consistently: + * + * - buffer - in this context a planner buffer holding a move or a command: mb._ or bf + * - block - a data structure for planning or runtime control. See mp_calculate_ramps() comments + * - move - a linear Gcode move, typically from a G0 or G1 code + * - command - a non-move executable in the planner + * - group - a collection of moves or commands that are treated as a unit + * - line - a line of ASCII gcode or arbitrary text + * - bootstrap - the startup period where the planner collects moves but does not yet execute them + */ #ifndef PLANNER_H_ONCE #define PLANNER_H_ONCE @@ -172,7 +292,12 @@ typedef enum { #define UPDATE_MP_DIAGNOSTICS { mp.plannable_time_ms = mp.plannable_time*60000; } /* - * Planner structures + * Planner structures + * + * You should be aware of the distinction between 'buffers' and 'blocks' + * Please refer to header comments in for important details on buffers and blocks + * - plan_zoid.cpp / mp_calculate_ramps() + * - plan_exec.cpp / mp_exec_aline() */ struct mpBuffer_to_clear { @@ -368,9 +493,9 @@ typedef struct mpMotionRuntimeSingleton { // persistent runtime variables float encoder_steps[MOTORS]; // encoder position in steps - ideally the same as commanded_steps float following_error[MOTORS]; // difference between encoder_steps and commanded steps - mpBlockRuntimeBuf_t *r; // what's running - mpBlockRuntimeBuf_t *p; // what's being planned, p might == r - mpBlockRuntimeBuf_t bf[2]; // the buffer + mpBlockRuntimeBuf_t *r; // block that is running + mpBlockRuntimeBuf_t *p; // block that is being planned, p might == r + mpBlockRuntimeBuf_t bf[2]; // buffer holding the two blocks float entry_velocity; // entry values for the currently running block From ba2193e34e9d1c5e76ccd8ea564ae1136103c428 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Thu, 1 Dec 2016 09:42:57 -0500 Subject: [PATCH 54/98] Planner documentation; remained forward planning functions. --- g2core/plan_exec.cpp | 190 ++++++++++++++++++++----------------------- g2core/plan_line.cpp | 2 +- g2core/planner.cpp | 2 +- g2core/planner.h | 10 +-- g2core/stepper.cpp | 6 +- g2core/stepper.h | 10 ++- 6 files changed, 105 insertions(+), 115 deletions(-) diff --git a/g2core/plan_exec.cpp b/g2core/plan_exec.cpp index cebaf810..70ef8e9a 100644 --- a/g2core/plan_exec.cpp +++ b/g2core/plan_exec.cpp @@ -46,113 +46,101 @@ static stat_t _exec_aline_segment(void); static void _init_forward_diffs(float v_0, float v_1); -/************************************************************************* - * mp_plan_move() - call ramping function to plan moves ahead of the exec +/******************************************************************************* * - * mp_plan_move() performs just-in-time forward planning immediately before + * mp_forward_plan() - plan commands and moves ahead of exec; call ramping for moves + * + **** WARNING **** + * This function should NOT be called directly! + * Instead call st_request_forward_plan(), which mediates access. + * + * mp_forward_plan() performs just-in-time forward planning immediately before * lines and commands are queued to the move execution runtime (exec). + * Unlike backward planning, buffers are only forward planned once. + * + * mp_forward_plan() is called aggressively via st_request_forward_plan(). + * It has a relatively low interrupt level to call its own. + * See also: Planner Overview notes in planner.h + * * It examines the currently running buffer and its adjacent buffers to: + * * - Stop the system from re-planning or planning something that's not prepped * - Plan the next available ALINE (movement) block past the COMMAND blocks * - Skip past/ or pre-plan COMMAND blocks while labeling them as PLANNED * - * Returns STAT_OK if exec should be called to start (or continue) movement, - * or exit with no action (STAT_NOOP) if exec does not need to be called. - * - **** WARNING **** - **** This function should NOT be called directly! Instead call - **** st_request_plan_move(), which mediates access. Mp_plan_move() is called - **** aggressively from multiple places and multiple interrupt levels, - **** and has a relatively low interrupt level to call its own. + * Returns: + * - STAT_OK if exec should be called to kickstart (or continue) movement + * - STAT_NOOP to exit with no action taken (do not call exec) */ /* - * Forward Planning Background - * - * - Forward planning only occurs once, JIT just ahead of the exec - Forward planning only ever originates from the run buffer (mb.r), only occurs once for each block - * - - * - 'Bootstrap' refers to startup condition w/buffers arriving before movement starts - * - see planner.h / bufferState enum for shorthand used - * - The + * --- Forward Planning Processing and Cases --- + * + * These cases describe all possible sequences of buffers in the planner queue starting + * with the currently executing (or about to execute) Run buffer, looking forward + * to more recently arrived buffers. In most cases only one or two buffers need to + * be examined, but contiguous groups of commands may need to be processed. + * + * See planner.h / bufferState enum for shorthand used in the descriptions. + * All cases assume a mix of moves and commands, as noted in the shorthand. + * All cases assume 2 'blocks' - Run block & Plan block. Cases will need to be + * revisited and generalized if more blocks are used in the future (deeper + * forward planning). + * + * 'NOT_PREPPED' refers to any preliminary state below PREPPED, i.e. < PREPPED. + * ' NOT_PREPPED' can be either a move or command, we don't care so it's not specified. + * + * 'COMMAND' or 'COMMAND(s)' refers to one command or a contiguous group of command buffers + * that may be in PREPPED or PLANNED states. Processing is always the same. Plan all + * PREPPED commands and skip past all PLANNED commands. + * + * If '(Note 1)' use mr.entry_velocity for the run velocity (instead of buffer exit velocity). + * In most 'plan move' cases the exit velocity of the run block is propagated forward to + * set the entry velocity of the planned block. In some cases we instead want mr.entry_velocity + * for the run velocity, which is almost always 0, but could be non-0 in a race condition. + * FYI: mr.entry_velocity is set at the end of the last running block in mp_exec_aline(). + * + * If '(Note 2)' we trust exit velocity here because the backplanner has already handled this case + * + * CASE: + * 0. Nothing to do + * + * run_buffer + * ---------- + * a. Run buffer has not yet been initialized (returns NULL) + * b. NOT_PREPPED No lines or commands in planner buffer. Exit with no action + * + * 1. Bootstrap cases (refers to startup phase where moves are collected before starting movement) + * + * run_buffer next N bufs terminal buf Actions + * ---------- ----------- ------------ ---------------------------------- + * a. NOT_PREPPED exit NOOP + * b. PREPPED-MOVE plan move, exit OK + * c. PLANNED-MOVE NOT_PREPPED exit NOOP + * d. PLANNED-MOVE PREPPED-MOVE exit NOOP (don't plan past a PLANNED buffer) + * e. PLANNED-MOVE COMMAND(s) exit NOOP (I had this as plan the cmds, earlier) + * f. COMMAND NOT_PREPPED skip/plan command, exit OK + * g. COMMAND PREPPED-MOVE skip/plan command, plan move (Note 1), exit OK. + * + * 2. Running cases (refers to normal operation w/movement occurring while buffers are arriving) + * + * run_buffer next N bufs terminal buf Actions + * ---------- ----------- ------------ ---------------------------------- + * a. NOT_PREPPED illegal condition, trap, exit NOOP + * b. PREPPED-MOVE illegal condition, trap, exit NOOP + * c. PLANNED-MOVE illegal condition, trap, exit NOOP + * d. RUNNING-MOVE PREPPED-MOVE plan move, exit OK + * e. RUNNING-MOVE PLANNED-MOVE exit NOOP + * f. RUNNING-MOVE COMMAND(s) NOT_PREPPED skip/plan command(s), exit OK + * g. RUNNING-MOVE COMMAND(s) PREPPED-MOVE skip/plan command(s), plan move, exit OK + * h. RUNNING-MOVE COMMAND(s) PLANNED-MOVE illegal condition, trap, exit NOOP (???) + * i. PREPPED-COMMAND illegal condition, trap, exit NOOP + * j. PLANNED-COMMAND illegal condition, trap, exit NOOP + * k. RUNNING-COMMAND PREPPED-MOVE plan move, exit OK + * l. RUNNING-COMMAND PLANNED-MOVE exit NOOP + * m. RUNNING-COMMAND COMMAND(s) NOT_PREPPED skip/plan command(s), exit OK + * n. RUNNING-COMMAND COMMAND(s) PREPPED-MOVE skip/plan command(s), plan move (Note 2), exit OK + * o. RUNNING-COMMAND COMMAND(s) PLANNED-MOVE illegal condition, trap, exit NOOP (???) */ -/* - * Forward Planning Cases - * - * - * CASE: - * 0. NOT_PREPPED. No lines or commands in planner buffer. Exit with no action - * This case also handles case before a run buffer can be assigned - * - * 1. Bootstrap cases, lines only, N lines in buffer, 2 blocks (JIT planning queue only has plan and run) - * run_buffer next_buffer - * a. NOT_PREPPED don't care Action: exit no action (backplanner is still running) - * b. PREPPED don't care Action: plan line, exit OK (prepped means backplanned) - * c. PLANNED don't care Action: exit no action (cannot plan next buffer beyond current PLANNED buffer) - * - * 1'. Bootstrap cases, lines only, N lines in buffer, N blocks (deeper JIT planning queue) - * run_buffer next_buffer - * a. NOT_PREPPED don't care Action: exit no action (backplanner is still running) - * b. PREPPED don't care Action: plan line, exit OK (prepped means backplanned) - * c. PLANNED, NOT_PREPPED Action: exit no action (cannot plan next buffer beyond current PLANNED buffer) - * d. PLANNED, PREPPED Action: plan the next block into the next planner block if the - * next planner block is NOT the run BLOCK. This can iterate to more blocks - * - * 2. Running cases, lines only, N lines in buffer, 2 blocks - * run_buffer next_buffer - * a. RUNNING NOT_PREPPED Action: exit no action (backplanner is still running) - * b. RUNNING PREPPED Action: plan buffer, exit OK (do a JIT plan) - * c. RUNNING PLANNED Action: exit no action - - * 3. Bootstrap cases, lines and commands mixed, N lines in buffer, 2 blocks - (Note: NOT_PREPPED can be either line or command) - - * run_buffer next/last buffer - * a. NOT_PREPPED (any state) Action: exit no action - * b. PREPPED-LINE (any state) Action: plan line, exit OK - * c. PLANNED-LINE NOT_PREPPED Action: exit no action (cannot plan next buffer beyond current PLANNED buffer) - * d. PLANNED-LINE PREPPED Action: plan the next block into the next planner block if the - * a. PREPPED-CMD(s) NOT_PREPPED Action: set contiguous PREPPED-COMMANDs to PLANNED, exit OK - * b. PREPPED-CMD(s) PREPPED-LINE Action: set contiguous PREPPED-COMMANDs to PLANNED, - * carry forward initial exit_velocity (see note *) - * iterate to PREPPED-LINE, plan line, exit OK. - * - * (*) Use mr.entry_velocity for the run velocity, which is almost always 0, but could be non-0 in a race condition. - * - * 4. Running cases, lines and commands mixed, N lines in buffer, 2 blocks - * All running cases start with first block is running (Note: NOT_PREPPED can be either line or command) - * run_buffer next N buffers terminating buffer - * a. RUNNING-LINE PREPPED-COMAND(s) NOT_PREPPED Action: Call mp_plan_command(), exit OK - * b. RUNNING-LINE PREPPED-COMAND(s) PREPPED-LINE Action: Mark all commands as PLANNED and exit OK - * Plan PREPPED-LINE using exit_velocity of run block - * (We trust exit velocity here because the backplanner has already handled this) - * c. RUNNING-LINE PREPPED-LINE (identical to 2b) Action: plan buffer, exit OK (do a JIT plan) - * d. RUNNING-LINE PLANNED-LINE (identical to 2c) Action: exit no action - * - * e. RUNNING-LINE PLANNED-COMMAND9s) Action: iterate over the PLANNED and PREPPED commands, skipping PLANNED - * f. PLANNED-COMMAND (anything) - * - * g. RUNNING-COMMAND (anything) as cases 4a - 4e, but use mr.entry_velocity - */ - -/* PSEUDOCODE - * - * - * Test the running buffer for early exit conditions. - * (In the motion startup (bootstrap) condition the "running" block is not actually running yet) - * If nothing is actually running, ext immediately (prevents a race condition) - * - * Test the planning buffer - * Explanation: There are 2 cases where this can occur: - (1) nothing is actually running - (2) something is running - The case changes which buffer is passed to calculate _ramps(), and what the entry_velocity is. - - * Code: See if the running buffer is -in-fact- running - * If so, move off the running buffer to the next buffer - * Set the entry velocity for be the exit velocity of the running block - * - */ - static stat_t _plan_command(mpBuf_t *bf) { @@ -160,7 +148,7 @@ static stat_t _plan_command(mpBuf_t *bf) return (STAT_OK); } -stat_t mp_plan_move() +stat_t mp_forward_plan() { mpBuf_t *bf; @@ -269,7 +257,7 @@ stat_t mp_exec_move() } // We need to have it planned. We don't want to do this here, as it // might already be happening in a lower interrupt. - st_request_plan_move(); + st_request_forward_plan(); return (STAT_NOOP); } @@ -286,7 +274,7 @@ stat_t mp_exec_move() // This won't call mp_plan_move until we leave this function // (and have called mp_exec_aline via bf->bf_func). // This also allows mp_exec_aline to advance mr.p first. - st_request_plan_move(); + st_request_forward_plan(); } // Manage motion state transitions @@ -652,7 +640,7 @@ stat_t mp_exec_aline(mpBuf_t *bf) cm_cycle_end(); // free buffer & end cycle if planner is empty } } else { - st_request_plan_move(); + st_request_forward_plan(); } } } diff --git a/g2core/plan_line.cpp b/g2core/plan_line.cpp index 76c35a63..8dcfa1e0 100644 --- a/g2core/plan_line.cpp +++ b/g2core/plan_line.cpp @@ -260,7 +260,7 @@ void mp_plan_block_list() } if (mp.planner_state > PLANNER_STARTUP) { if (planned_something && (cm.hold_state != FEEDHOLD_HOLD)) { - st_request_plan_move(); // start motion if runtime is not already busy + st_request_forward_plan(); // start motion if runtime is not already busy } } mp.p = bf; // update planner pointer diff --git a/g2core/planner.cpp b/g2core/planner.cpp index 69aac4ab..a833b14c 100644 --- a/g2core/planner.cpp +++ b/g2core/planner.cpp @@ -792,7 +792,7 @@ void mp_commit_write_buffer(const blockType block_type) if ((mp.planner_state > PLANNER_STARTUP) && (cm.hold_state == FEEDHOLD_OFF)) { // NB: BEWARE! the exec may result in the planner buffer being // processed IMMEDIATELY and then freed - invalidating the contents - st_request_plan_move(); // request an exec if the runtime is not busy + st_request_forward_plan(); // request an exec if the runtime is not busy } } mb.w->plannable = true; // enable block for planning diff --git a/g2core/planner.h b/g2core/planner.h index 664d19a1..d9ab6194 100644 --- a/g2core/planner.h +++ b/g2core/planner.h @@ -26,7 +26,7 @@ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* - * --- Background on the Planner --- + * --- Planner Background --- * * The planner is a complicated beast that takes a lot of things into account. * Planner documentation is scattered about and co-located with the functions @@ -110,7 +110,7 @@ * * Forward planning is performed just-in-time and only once, right before the * planner runtime needs the next buffer. Forward planning provides the final - * contouring of the move. It is invoked by mp_plan_move() and executed by + * contouring of the move. It is invoked by mp_forward_plan() and executed by * mp_calculate_ramps() in plan_zoid.cpp. * * Planner timing operates at a few different levels: @@ -131,7 +131,7 @@ * - Velocity throttling to ensure that very short moves do not execute faster * than the serial interface can deliver them * - * - Feedhold and resume operations + * - Feed hold and cycle start (resume) operations * * - Feed rate override functions and replanning * @@ -590,7 +590,7 @@ void mp_plan_block_forward(mpBuf_t *bf); void mp_calculate_ramps(mpBlockRuntimeBuf_t *block, mpBuf_t *bf, const float entry_velocity); float mp_get_target_length(const float v_0, const float v_1, const mpBuf_t *bf); float mp_get_target_velocity(const float v_0, const float L, const mpBuf_t *bf); // acceleration ONLY -float mp_get_decel_velocity(const float v_0, const float L, const mpBuf_t *bf); // decelleration ONLY +float mp_get_decel_velocity(const float v_0, const float L, const mpBuf_t *bf); // deceleration ONLY float mp_find_t(const float v_0, const float v_1, const float L, const float totalL, const float initial_t, const float T); float mp_calc_v(const float t, const float v_0, const float v_1); // compute the velocity along the curve accelerating from v_0 to v_1, at position t=[0,1] @@ -599,8 +599,8 @@ float mp_calc_j(const float t, const float v_0, const float v_1, const float T); //float mp_calc_l(const float t, const float v_0, const float v_1, const float T); // compute length over curve accelerating from v_0 to v_1, at position t=[0,1], total time T // plan_exec.c functions +stat_t mp_forward_plan(void); stat_t mp_exec_move(void); -stat_t mp_plan_move(void); stat_t mp_exec_aline(mpBuf_t *bf); void mp_exit_hold_state(void); diff --git a/g2core/stepper.cpp b/g2core/stepper.cpp index 1dfebdff..9d5ef6d8 100644 --- a/g2core/stepper.cpp +++ b/g2core/stepper.cpp @@ -388,7 +388,7 @@ namespace Motate { // Define timer inside Motate namespace } } // namespace Motate -void st_request_plan_move() +void st_request_forward_plan() { stepper_debug("p"); fwd_plan_timer.setInterruptPending(); @@ -398,9 +398,9 @@ namespace Motate { // Define timer inside Motate namespace template<> void fwd_plan_timer_type::interrupt() { - fwd_plan_timer.getInterruptCause(); // clears the interrupt condition + fwd_plan_timer.getInterruptCause(); // clears the interrupt condition stepper_debug("P>"); - if (mp_plan_move() != STAT_NOOP) { // We now have a move to exec. + if (mp_forward_plan() != STAT_NOOP) { // We now have a move to exec. stepper_debug("P+\n"); st_request_exec_move(); return; diff --git a/g2core/stepper.h b/g2core/stepper.h index 6c1967dd..b8b22b78 100644 --- a/g2core/stepper.h +++ b/g2core/stepper.h @@ -26,13 +26,15 @@ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* + * --- Stepper Operation Overview --- + * * Coordinated motion (line drawing) is performed using a classic Bresenham DDA. - * A number of additional steps are taken to optimize interpolation and pulse train - * timing accuracy to minimize pulse jitter and make for very smooth motion and surface + * Additional steps are taken to optimize interpolation and pulse train timing + * accuracy to minimize pulse jitter and produce very smooth motion and surface * finish. * * - The DDA is not used as a ramp for acceleration management. Acceleration is computed - * upstream in the motion planner as 5th order (linear snap) equations. These + * upstream in the motion planner as 6th order (linear pop) equations. These * generate accel/decel *segments* that are passed to the DDA for step output. * * - The DDA accepts and processes fractional motor steps as floating point numbers @@ -566,7 +568,7 @@ stat_t st_clc(nvObj_t *nv); void st_set_motor_power(const uint8_t motor); stat_t st_motor_power_callback(void); -void st_request_plan_move(void); +void st_request_forward_plan(void); void st_request_exec_move(void); void st_request_load_move(void); void st_prep_null(void); From ef825354040bee2d1dff7cf64defac9f6bd5f95b Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Thu, 1 Dec 2016 11:13:51 -0500 Subject: [PATCH 55/98] Final (hopefully) comments for mp_forward_plan() before actually coding it up and testing it. --- g2core/plan_exec.cpp | 113 ++++++++++++++++++++++--------------------- g2core/plan_line.cpp | 37 ++++++++------ g2core/planner.h | 4 +- 3 files changed, 82 insertions(+), 72 deletions(-) diff --git a/g2core/plan_exec.cpp b/g2core/plan_exec.cpp index 70ef8e9a..fb53e3e4 100644 --- a/g2core/plan_exec.cpp +++ b/g2core/plan_exec.cpp @@ -47,7 +47,6 @@ static stat_t _exec_aline_segment(void); static void _init_forward_diffs(float v_0, float v_1); /******************************************************************************* - * * mp_forward_plan() - plan commands and moves ahead of exec; call ramping for moves * **** WARNING **** @@ -80,6 +79,10 @@ static void _init_forward_diffs(float v_0, float v_1); * to more recently arrived buffers. In most cases only one or two buffers need to * be examined, but contiguous groups of commands may need to be processed. * + * 'Running' cases are where the run buffer state is RUNNING. Bootstrap handles all other cases. + * 'Bootstrap' occurs during the startup phase where moves are collected before starting movement. + * Conditions that are impossible based on this definition are not listed in the tables below. + * * See planner.h / bufferState enum for shorthand used in the descriptions. * All cases assume a mix of moves and commands, as noted in the shorthand. * All cases assume 2 'blocks' - Run block & Plan block. Cases will need to be @@ -107,39 +110,39 @@ static void _init_forward_diffs(float v_0, float v_1); * run_buffer * ---------- * a. Run buffer has not yet been initialized (returns NULL) - * b. NOT_PREPPED No lines or commands in planner buffer. Exit with no action + * b. NOT_PREPPED No moves or commands in run buffer. Exit with no action * - * 1. Bootstrap cases (refers to startup phase where moves are collected before starting movement) + * 1. Bootstrap cases (buffer state < RUNNING) * * run_buffer next N bufs terminal buf Actions * ---------- ----------- ------------ ---------------------------------- - * a. NOT_PREPPED exit NOOP - * b. PREPPED-MOVE plan move, exit OK - * c. PLANNED-MOVE NOT_PREPPED exit NOOP - * d. PLANNED-MOVE PREPPED-MOVE exit NOOP (don't plan past a PLANNED buffer) - * e. PLANNED-MOVE COMMAND(s) exit NOOP (I had this as plan the cmds, earlier) - * f. COMMAND NOT_PREPPED skip/plan command, exit OK - * g. COMMAND PREPPED-MOVE skip/plan command, plan move (Note 1), exit OK. + * a. PREPPED-MOVE plan move, exit OK + * b. PLANNED-MOVE NOT_PREPPED exit NOOP + * c. PLANNED-MOVE PREPPED-MOVE exit NOOP (don't plan past a PLANNED buffer) + * d. PLANNED-MOVE PLANNED-MOVE trap "impossible" condition, exit NOOP + * e. PLANNED-MOVE COMMAND(s) exit NOOP + * f. PREPPED-COMMAND NOT_PREPPED plan command, exit OK + * g. PREPPED-COMMAND PREPPED-MOVE plan command, plan move (Note 1), exit OK + * h. PREPPED-COMMAND PLANNED-MOVE trap "impossible" condition, exit NOOP + * i. PLANNED-COMMAND NOT_PREPPED skip command, exit OK + * j. PLANNED-COMMAND PREPPED-MOVE skip command, plan move (Note 1), exit OK + * k. PLANNED-COMMAND PLANNED-MOVE exit NOOP * - * 2. Running cases (refers to normal operation w/movement occurring while buffers are arriving) + * 2. Running cases (buffer state == RUNNING) * * run_buffer next N bufs terminal buf Actions * ---------- ----------- ------------ ---------------------------------- - * a. NOT_PREPPED illegal condition, trap, exit NOOP - * b. PREPPED-MOVE illegal condition, trap, exit NOOP - * c. PLANNED-MOVE illegal condition, trap, exit NOOP - * d. RUNNING-MOVE PREPPED-MOVE plan move, exit OK - * e. RUNNING-MOVE PLANNED-MOVE exit NOOP - * f. RUNNING-MOVE COMMAND(s) NOT_PREPPED skip/plan command(s), exit OK - * g. RUNNING-MOVE COMMAND(s) PREPPED-MOVE skip/plan command(s), plan move, exit OK - * h. RUNNING-MOVE COMMAND(s) PLANNED-MOVE illegal condition, trap, exit NOOP (???) - * i. PREPPED-COMMAND illegal condition, trap, exit NOOP - * j. PLANNED-COMMAND illegal condition, trap, exit NOOP - * k. RUNNING-COMMAND PREPPED-MOVE plan move, exit OK - * l. RUNNING-COMMAND PLANNED-MOVE exit NOOP - * m. RUNNING-COMMAND COMMAND(s) NOT_PREPPED skip/plan command(s), exit OK - * n. RUNNING-COMMAND COMMAND(s) PREPPED-MOVE skip/plan command(s), plan move (Note 2), exit OK - * o. RUNNING-COMMAND COMMAND(s) PLANNED-MOVE illegal condition, trap, exit NOOP (???) + * a. RUNNING-MOVE PREPPED-MOVE plan move, exit OK + * b. RUNNING-MOVE PLANNED-MOVE exit NOOP + * c. RUNNING-MOVE COMMAND(s) NOT_PREPPED skip/plan command(s), exit OK + * d. RUNNING-MOVE COMMAND(s) PREPPED-MOVE skip/plan command(s), plan move, exit OK + * e. RUNNING-MOVE COMMAND(s) PLANNED-MOVE exit NOOP + * f. RUNNING-COMMAND PREPPED-MOVE plan move, exit OK + * g. RUNNING-COMMAND PLANNED-MOVE exit NOOP + * h. RUNNING-COMMAND COMMAND(s) NOT_PREPPED skip/plan command(s), exit OK + * i. RUNNING-COMMAND COMMAND(s) PREPPED-MOVE skip/plan command(s), plan move (Note 2), exit OK + * j. RUNNING-COMMAND COMMAND(s) PLANNED-MOVE skip command(s), exit NOOP + * (Note: all COMMAND(s) in j. should be in PLANNED state) */ static stat_t _plan_command(mpBuf_t *bf) @@ -193,11 +196,12 @@ stat_t mp_forward_plan() return (STAT_NOOP); // get outta here - we did nothing } - // Pass in the bf buffer that will "link" with the planned block - // The block and the buffer are implicitly linked for exec_aline() // Calculate ramps for the current planning block and the next PREPPED buffer // The PREPPED buffer will be set to PLANNED later... // + // Pass in the bf buffer that will "link" with the planned block + // The block and the buffer are implicitly linked for exec_aline() + // // Note that that can only be one PLANNED move at a time. // This is to help sync mr.p to point to the next planned mr.bf // mr.p is only advanced in mp_exec_aline(), after mp.r = mr.p. @@ -205,7 +209,6 @@ stat_t mp_forward_plan() mpBlockRuntimeBuf_t* block = mr.p; // set a local planning block to the current planning block mp_calculate_ramps(block, bf, entry_velocity); -// mp_calculate_ramps(mr.p, bf, entry_velocity); if (block->exit_velocity > block->cruise_velocity) { __asm__("BKPT"); // exit > cruise after calculate_block @@ -222,8 +225,8 @@ stat_t mp_forward_plan() /************************************************************************* * mp_exec_move() - execute runtime functions to prep move for steppers * - * Dequeues the buffer queue and executes the move continuations. - * Manages run buffers and other details + * Dequeues the buffer queue and executes the move continuations. + * Manages run buffers and other details */ stat_t mp_exec_move() @@ -237,11 +240,12 @@ stat_t mp_exec_move() } if (bf->block_type == BLOCK_TYPE_ALINE) { // cycle auto-start for lines only + // first-time operations if (bf->buffer_state != MP_BUFFER_RUNNING) { if ((bf->buffer_state < MP_BUFFER_PREPPED) && (cm.motion_state == MOTION_RUN)) { - __asm__("BKPT"); // mp_exec_move() buffer is not prepped - // IMPORTANT: We can't rpt_exception from here! + __asm__("BKPT"); // mp_exec_move() buffer is not prepped + // IMPORTANT: We can't rpt_exception from here! st_prep_null(); return (STAT_NOOP); } @@ -302,24 +306,23 @@ stat_t mp_exec_move() * Returns: * STAT_OK move is done * STAT_EAGAIN move is not finished - has more segments to run - * STAT_NOOP cause no operation from the steppers - do not load the move - * STAT_xxxxx fatal error. Ends the move and frees the bf buffer + * STAT_NOOP cause no operation from the steppers - do not load the move + * STAT_xxxxx fatal error. Ends the move and frees the bf buffer * - * This routine is called from the (LO) interrupt level. The interrupt - * sequencing relies on the behaviors of the routines being exactly correct. - * Each call to _exec_aline() must execute and prep *one and only one* - * segment. If the segment is the not the last segment in the bf buffer the - * _aline() must return STAT_EAGAIN. If it's the last segment it must return - * STAT_OK. If it encounters a fatal error that would terminate the move it - * should return a valid error code. Failure to obey this will introduce - * subtle and very difficult to diagnose bugs (trust me on this). + * This routine is called from the (LO) interrupt level. The interrupt sequencing + * relies on the behaviors of the routines being exactly correct. Each call to + * _exec_aline() must execute and prep *one and only one* segment. If the segment + * is the not the last segment in the bf buffer the _aline() must return STAT_EAGAIN. + * If it's the last segment it must return STAT_OK. If it encounters a fatal error + * that would terminate the move it should return a valid error code. Failure to + * obey this will introduce subtle and very difficult to diagnose bugs (trust us on this). * - * Note 1 Returning STAT_OK ends the move and frees the bf buffer. + * Note 1: Returning STAT_OK ends the move and frees the bf buffer. * Returning STAT_OK at this point does NOT advance position meaning any * position error will be compensated by the next move. * - * Note 2 Solves a potential race condition where the current move ends but the - * new move has not started because the previous move is still being run + * Note 2: Solves a potential race condition where the current move ends but the + * new move has not started because the previous move is still being run * by the steppers. Planning can overwrite the new move. */ /* --- State transitions - hierarchical state machine --- @@ -341,15 +344,16 @@ stat_t mp_exec_move() * - mp_exec_aline() is only called for alines */ /* Synchronization of run BUFFER and run BLOCK + * + * Note first: mp_exec_aline() makes a huge assumption: When it comes time to get a + * new run block (mr.r) it assumes the planner block (mr.p) has been fully planned + * via the JIT forward planning and is ready for use as the new run block. * * The runtime uses 2 structures for the current move or commend, the run BUFFER - * from the planner queue (mb), and the run BLOCK from the runtime singleton (mr). - * These are synchronized implicitly, but not explicitly referenced, as pointers - * can lead to race conditions. See plan_zoid.cpp / mp_calculate_ramps() for more details - * - * Mp_exec_aline() makes a huge assumption: When it comes time to get a new run block - * (mr.r) it assumes the planner block (mr.p) has been fully planned (JIT planning), - * and is ready for use as the new run block. + * from the planner queue (mb.r, aka bf), and the run BLOCK from the runtime + * singleton (mr.r). These structures are synchronized implicitly, but not + * explicitly referenced, as pointers can lead to race conditions. + * See plan_zoid.cpp / mp_calculate_ramps() for more details * * When mp_exec_aline() needs to grab a new planner buffer for a new move or command * (i.e. block state is inactive) it swaps (rolls) the run and planner BLOCKS so that @@ -360,7 +364,8 @@ stat_t mp_exec_move() * advanced to the next buffer. mp_exec_move() does this at the end of previous move. * Or in the bootstrap case, there never was a previous mb.r, so the current one is OK. * - * As if by magic, the new mb.r aligns with the run block that was just moved in from the planning block + * As if by magic, the new mb.r aligns with the run block that was just moved in from + * the planning block. */ /**** NOTICE ** NOTICE ** NOTICE **** diff --git a/g2core/plan_line.cpp b/g2core/plan_line.cpp index 8dcfa1e0..3856dacd 100644 --- a/g2core/plan_line.cpp +++ b/g2core/plan_line.cpp @@ -103,7 +103,7 @@ float mp_get_runtime_work_position(uint8_t axis) { /* * mp_get_runtime_busy() - returns TRUE if motion control busy (i.e. robot is moving) - * mp_runtime_is_idle() - returns TRUE is steppers are not actively moving + * mp_runtime_is_idle() - returns TRUE is steppers are not actively moving * * Use mp_get_runtime_busy() to sync to the queue. If you wait until it returns * FALSE you know the queue is empty and the motors have stopped. @@ -148,31 +148,36 @@ stat_t mp_aline(GCodeState_t* gm_in) float length; // A few notes about the rotated coordinate space: - // These are position PRE-rotation: + // These are positions PRE-rotation: // gm_in.* (anything in gm_in) // // These are positions POST-rotation: - // target_rotated (after the rotiton here, of course) + // target_rotated (after the rotation here, of course) // mp.* (anything in mp, including mp.gm.*) - - // a being target[0], - // b being target[1], - // c being target[2], - // x_1 being cm.rotation_matrix[1][0] - + // // Shorthand: - // target_rotated[0] = a x_0 + b y_0 + c z_0 - // target_rotated[1] = a x_1 + b y_1 + c z_1 - // target_rotated[2] = a x_2 + b y_2 + c z_2 + z_offset + // target_rotated[0] = a x_0 + b y_0 + c z_0 + // target_rotated[1] = a x_1 + b y_1 + c z_1 + // target_rotated[2] = a x_2 + b y_2 + c z_2 + z_offset + // + // With: + // a being target[0], + // b being target[1], + // c being target[2], + // x_1 being cm.rotation_matrix[1][0] - target_rotated[0] = gm_in->target[0] * cm.rotation_matrix[0][0] + gm_in->target[1] * cm.rotation_matrix[0][1] + + target_rotated[0] = gm_in->target[0] * cm.rotation_matrix[0][0] + + gm_in->target[1] * cm.rotation_matrix[0][1] + gm_in->target[2] * cm.rotation_matrix[0][2]; - target_rotated[1] = gm_in->target[0] * cm.rotation_matrix[1][0] + gm_in->target[1] * cm.rotation_matrix[1][1] + + target_rotated[1] = gm_in->target[0] * cm.rotation_matrix[1][0] + + gm_in->target[1] * cm.rotation_matrix[1][1] + gm_in->target[2] * cm.rotation_matrix[1][2]; - target_rotated[2] = gm_in->target[0] * cm.rotation_matrix[2][0] + gm_in->target[1] * cm.rotation_matrix[2][1] + - gm_in->target[2] * cm.rotation_matrix[2][2] + cm.rotation_z_offset; + target_rotated[2] = gm_in->target[0] * cm.rotation_matrix[2][0] + + gm_in->target[1] * cm.rotation_matrix[2][1] + + gm_in->target[2] * cm.rotation_matrix[2][2] + + cm.rotation_z_offset; // copy rotation axes ABC target_rotated[3] = gm_in->target[3]; diff --git a/g2core/planner.h b/g2core/planner.h index d9ab6194..e5dd1c84 100644 --- a/g2core/planner.h +++ b/g2core/planner.h @@ -25,7 +25,7 @@ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/* +/*x * --- Planner Background --- * * The planner is a complicated beast that takes a lot of things into account. @@ -40,7 +40,7 @@ * - stepper.cpp/h - Real-time step generation, segment loading, pulls from plan_exec * - plan_arc.cpp/h- Arc calculation and runtime functions - layer above the rest of this * - * --- Overview of Operation --- + * --- Planner Overview --- * * At high level the planner's job is to reconstruct smooth motion from a set of linear * approximations while observing and operating within the physical constraints of the From a4a7514d9a765d97fc74fd3ed2e988906c594a41 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Thu, 1 Dec 2016 14:53:15 -0500 Subject: [PATCH 56/98] First cut at revised forward planner function --- g2core/plan_exec.cpp | 131 ++++++++++++++++++++++++------------------- 1 file changed, 73 insertions(+), 58 deletions(-) diff --git a/g2core/plan_exec.cpp b/g2core/plan_exec.cpp index fb53e3e4..bcfa1932 100644 --- a/g2core/plan_exec.cpp +++ b/g2core/plan_exec.cpp @@ -96,20 +96,24 @@ static void _init_forward_diffs(float v_0, float v_1); * that may be in PREPPED or PLANNED states. Processing is always the same. Plan all * PREPPED commands and skip past all PLANNED commands. * - * If '(Note 1)' use mr.entry_velocity for the run velocity (instead of buffer exit velocity). - * In most 'plan move' cases the exit velocity of the run block is propagated forward to - * set the entry velocity of the planned block. In some cases we instead want mr.entry_velocity - * for the run velocity, which is almost always 0, but could be non-0 in a race condition. + * Note 1: For MOVEs use the exit velocity of the Run block (mr.r->exit_velocity) as the + * entry velocity of the next adjacent move. + * + * Note 1a: In this special COMMAND case we trust mr.r->exit_velocity because the + * backplanner has already handled this case for us. + * + * Note 2: For COMMANDs use the entry velocity of the current runtime (mr.entry_velocity) + * as the entry velocity for the next adjacent move. mr.entry_velocity is almost always 0, + * but could be non-0 in a race condition. * FYI: mr.entry_velocity is set at the end of the last running block in mp_exec_aline(). * - * If '(Note 2)' we trust exit velocity here because the backplanner has already handled this case * * CASE: * 0. Nothing to do * * run_buffer * ---------- - * a. Run buffer has not yet been initialized (returns NULL) + * a. Run buffer has not yet been initialized (prep null buffer and return NOOP) * b. NOT_PREPPED No moves or commands in run buffer. Exit with no action * * 1. Bootstrap cases (buffer state < RUNNING) @@ -119,13 +123,13 @@ static void _init_forward_diffs(float v_0, float v_1); * a. PREPPED-MOVE plan move, exit OK * b. PLANNED-MOVE NOT_PREPPED exit NOOP * c. PLANNED-MOVE PREPPED-MOVE exit NOOP (don't plan past a PLANNED buffer) - * d. PLANNED-MOVE PLANNED-MOVE trap "impossible" condition, exit NOOP + * d. PLANNED-MOVE PLANNED-MOVE trap illegal condition, exit NOOP * e. PLANNED-MOVE COMMAND(s) exit NOOP * f. PREPPED-COMMAND NOT_PREPPED plan command, exit OK - * g. PREPPED-COMMAND PREPPED-MOVE plan command, plan move (Note 1), exit OK - * h. PREPPED-COMMAND PLANNED-MOVE trap "impossible" condition, exit NOOP + * g. PREPPED-COMMAND PREPPED-MOVE plan command, plan move (Note 2), exit OK + * h. PREPPED-COMMAND PLANNED-MOVE trap illegal condition, exit NOOP * i. PLANNED-COMMAND NOT_PREPPED skip command, exit OK - * j. PLANNED-COMMAND PREPPED-MOVE skip command, plan move (Note 1), exit OK + * j. PLANNED-COMMAND PREPPED-MOVE skip command, plan move (Note 2), exit OK * k. PLANNED-COMMAND PLANNED-MOVE exit NOOP * * 2. Running cases (buffer state == RUNNING) @@ -140,62 +144,31 @@ static void _init_forward_diffs(float v_0, float v_1); * f. RUNNING-COMMAND PREPPED-MOVE plan move, exit OK * g. RUNNING-COMMAND PLANNED-MOVE exit NOOP * h. RUNNING-COMMAND COMMAND(s) NOT_PREPPED skip/plan command(s), exit OK - * i. RUNNING-COMMAND COMMAND(s) PREPPED-MOVE skip/plan command(s), plan move (Note 2), exit OK + * i. RUNNING-COMMAND COMMAND(s) PREPPED-MOVE skip/plan command(s), plan move (Note 1a), exit OK * j. RUNNING-COMMAND COMMAND(s) PLANNED-MOVE skip command(s), exit NOOP * (Note: all COMMAND(s) in j. should be in PLANNED state) */ - -static stat_t _plan_command(mpBuf_t *bf) +/* +static stat_t _plan_command(mpBuf_t *bf) // plan a single command { bf->buffer_state = MP_BUFFER_PLANNED; // report that we "planned" something... return (STAT_OK); } - -stat_t mp_forward_plan() -{ - mpBuf_t *bf; - - // Examine current running buffer for early exit conditions - if ((bf = mp_get_run_buffer()) == NULL) { // NULL means nothing's running - this is OK - st_prep_null(); - return (STAT_NOOP); - } - if (bf->buffer_state < MP_BUFFER_PREPPED) { - return (STAT_NOOP); // get outta here - we did nothing - } -///* - if (bf->block_type != BLOCK_TYPE_ALINE) { // nothing to see here... - bf->buffer_state = MP_BUFFER_PLANNED; // report that we "planned" something... - return (STAT_OK); - } -//*/ - // Examine the next plannable block(s) NB: at this point bf == bf.r - float entry_velocity = mr.entry_velocity; // used for - - if (bf->buffer_state == MP_BUFFER_RUNNING) { - bf = bf->nx; - entry_velocity = mr.r->exit_velocity; // set entry_* to mr.r->exit_* - - if (bf->buffer_state < MP_BUFFER_PREPPED) { - return (STAT_NOOP); // get outta here - we did nothing - } -/* - while (bf->buffer_state < MP_BUFFER_PLANNED) { - if (mp_get_next_buffer(bf)->buffer_state < MP_BUFFER_PREPPED) { // i.e. EMPTY - return (STAT_OK); // ...and invoke an EXEC call - } - return (STAT_NOOP); // get outta here - we did nothing - } */ - if (bf->block_type != BLOCK_TYPE_ALINE) { - return (_plan_command(bf)); +static mpBuf_t *_plan_commands(mpBuf_t *bf) // plan or skip commands; return bf past last command +{ + while (bf->block_type == BLOCK_TYPE_COMMAND) { + if (bf->buffer_state < MP_BUFFER_PLANNED) { // skip buffers that are already planned + bf->buffer_state = MP_BUFFER_PLANNED; // really just a stub, for now +// _plan_command(mpBuf_t *bf); } + bf = bf->nx; } + return (bf); +} - if (bf->buffer_state == MP_BUFFER_PLANNED) { - return (STAT_NOOP); // get outta here - we did nothing - } - +static stat_t _plan_move(mpBuf_t *bf, float entry_velocity) +{ // Calculate ramps for the current planning block and the next PREPPED buffer // The PREPPED buffer will be set to PLANNED later... // @@ -207,21 +180,63 @@ stat_t mp_forward_plan() // mr.p is only advanced in mp_exec_aline(), after mp.r = mr.p. // This code aligns the buffers and the blocks for exec_aline(). - mpBlockRuntimeBuf_t* block = mr.p; // set a local planning block to the current planning block - mp_calculate_ramps(block, bf, entry_velocity); + mpBlockRuntimeBuf_t* block = mr.p; // set a local planning block so it doesn't change on you + mp_calculate_ramps(block, bf, entry_velocity); // (which it will if you don't do this) + // diagnostic traps if (block->exit_velocity > block->cruise_velocity) { __asm__("BKPT"); // exit > cruise after calculate_block } if (block->head_length < 0.00001 && block->body_length < 0.00001 && block->tail_length < 0.00001) { __asm__("BKPT"); // zero or negative length block } - bf->buffer_state = MP_BUFFER_PLANNED; //...here bf->plannable = false; return (STAT_OK); // report that we planned something... } +stat_t mp_forward_plan() +{ + mpBuf_t *bf = mp_get_run_buffer(); + + // Case 0: Examine current running buffer for early exit conditions + if (bf == NULL) { // 0a: NULL means nothing is running - this is OK + st_prep_null(); + return (STAT_NOOP); + } + if (bf->buffer_state < MP_BUFFER_PREPPED) { // 0b: nothing to do. get outta here. + return (STAT_NOOP); + } + + // Case 2: Runtime conditions - preset bf to behave like case 1 conditions + float entry_velocity = mr.entry_velocity; // preset velocity for command cases - Note 2 + if (bf->buffer_state == MP_BUFFER_RUNNING) { + bf = bf->nx; // all you need to do is to move to next buffer + entry_velocity = mr.r->exit_velocity; // set entry_velocity to mr.r->exit_velocity + } + + // run buffer is a command; start cases 1f - 1k, 2c, 2d, 2e, 2h, 2i, 2j + if (bf->block_type != BLOCK_TYPE_ALINE) { // meaning it's a COMMAND + bf = _plan_commands(bf); // plan or skip past already planned commands +// entry_velocity = mr.entry_velocity; // set entry_velocity for Note 1a + }// bf will always be on a non-command at this point + + // process move + if (bf->block_type == BLOCK_TYPE_ALINE) { // do cases 1a - 1e; finish cases 1f - 1k + if (bf->buffer_state == MP_BUFFER_PREPPED) {// do 1a; finish 1f, 1j + return (_plan_move(bf, entry_velocity)); + } else { + // 1d, 1h: diagnostics. Can be commented out. + if ((bf->nx->block_type == BLOCK_TYPE_ALINE) && (bf->nx->buffer_state > MP_BUFFER_PREPPED )) { + __asm__("BKPT"); // illegal condition + } + // do 1b, 1c, 1e; finish 1g, 1j, 1k, 2e, 2j + return (STAT_NOOP); + } + } + return (STAT_OK); // report that we planned something... +} + /************************************************************************* * mp_exec_move() - execute runtime functions to prep move for steppers * From 8fdb1f36dd21ff07de3e8c56dbb3ab0ea1819a58 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Thu, 1 Dec 2016 15:57:23 -0500 Subject: [PATCH 57/98] Reworked _plan_commands() to be safer for race conditions --- g2core/plan_exec.cpp | 55 ++++++++++++++++++++------------------------ 1 file changed, 25 insertions(+), 30 deletions(-) diff --git a/g2core/plan_exec.cpp b/g2core/plan_exec.cpp index bcfa1932..01426627 100644 --- a/g2core/plan_exec.cpp +++ b/g2core/plan_exec.cpp @@ -148,19 +148,13 @@ static void _init_forward_diffs(float v_0, float v_1); * j. RUNNING-COMMAND COMMAND(s) PLANNED-MOVE skip command(s), exit NOOP * (Note: all COMMAND(s) in j. should be in PLANNED state) */ -/* -static stat_t _plan_command(mpBuf_t *bf) // plan a single command -{ - bf->buffer_state = MP_BUFFER_PLANNED; // report that we "planned" something... - return (STAT_OK); -} -*/ + static mpBuf_t *_plan_commands(mpBuf_t *bf) // plan or skip commands; return bf past last command { - while (bf->block_type == BLOCK_TYPE_COMMAND) { - if (bf->buffer_state < MP_BUFFER_PLANNED) { // skip buffers that are already planned - bf->buffer_state = MP_BUFFER_PLANNED; // really just a stub, for now -// _plan_command(mpBuf_t *bf); + // must test for buffer state first as the buffer is only "safe" once it's >= PREPPED + while ((bf->buffer_state >= MP_BUFFER_PREPPED) && (bf->block_type == BLOCK_TYPE_COMMAND)) { + if (bf->buffer_state != MP_BUFFER_PLANNED) { // skip already planned buffers + bf->buffer_state = MP_BUFFER_PLANNED; // "planning" is just setting the state (for now) } bf = bf->nx; } @@ -198,40 +192,41 @@ static stat_t _plan_move(mpBuf_t *bf, float entry_velocity) stat_t mp_forward_plan() { mpBuf_t *bf = mp_get_run_buffer(); - + float entry_velocity; + // Case 0: Examine current running buffer for early exit conditions - if (bf == NULL) { // 0a: NULL means nothing is running - this is OK + if (bf == NULL) { // case 0a: NULL means nothing is running - this is OK st_prep_null(); return (STAT_NOOP); } - if (bf->buffer_state < MP_BUFFER_PREPPED) { // 0b: nothing to do. get outta here. + if (bf->buffer_state < MP_BUFFER_PREPPED) { // case 0b: nothing to do. get outta here. return (STAT_NOOP); } - // Case 2: Runtime conditions - preset bf to behave like case 1 conditions - float entry_velocity = mr.entry_velocity; // preset velocity for command cases - Note 2 + // Case 2: Running cases - move bf past run buffer so it acts like case 1 if (bf->buffer_state == MP_BUFFER_RUNNING) { - bf = bf->nx; // all you need to do is to move to next buffer - entry_velocity = mr.r->exit_velocity; // set entry_velocity to mr.r->exit_velocity + bf = bf->nx; + entry_velocity = mr.r->exit_velocity; // set Note 1 entry_velocity (move cases) + } else { + entry_velocity = mr.entry_velocity; // set Note 2 entry velocity (command cases) } - // run buffer is a command; start cases 1f - 1k, 2c, 2d, 2e, 2h, 2i, 2j + // bf points to command; start cases 1f, 1g, 1h, 1i, 1j, 1k, 2c, 2d, 2e, 2h, 2i, 2j if (bf->block_type != BLOCK_TYPE_ALINE) { // meaning it's a COMMAND - bf = _plan_commands(bf); // plan or skip past already planned commands -// entry_velocity = mr.entry_velocity; // set entry_velocity for Note 1a - }// bf will always be on a non-command at this point - + bf = _plan_commands(bf); // plan commands or skip past already planned commands + // bf now points to the first non-command buffer past the command(s) + if ((bf->block_type == BLOCK_TYPE_ALINE) && (bf->buffer_state > MP_BUFFER_PREPPED )) { // case 1i + entry_velocity = mr.r->exit_velocity; // set entry_velocity for Note 1a + } + } + // bf will always be on a non-command at this point - either a move or empty buffer + // process move if (bf->block_type == BLOCK_TYPE_ALINE) { // do cases 1a - 1e; finish cases 1f - 1k - if (bf->buffer_state == MP_BUFFER_PREPPED) {// do 1a; finish 1f, 1j + if (bf->buffer_state == MP_BUFFER_PREPPED) {// do 1a; finish 1f, 1j, 2d, 2i return (_plan_move(bf, entry_velocity)); } else { - // 1d, 1h: diagnostics. Can be commented out. - if ((bf->nx->block_type == BLOCK_TYPE_ALINE) && (bf->nx->buffer_state > MP_BUFFER_PREPPED )) { - __asm__("BKPT"); // illegal condition - } - // do 1b, 1c, 1e; finish 1g, 1j, 1k, 2e, 2j - return (STAT_NOOP); + return (STAT_NOOP); // do 1b, 1c, 1d, 1e; finish 1g, 1h, 1j, 1k, 2e, 2j } } return (STAT_OK); // report that we planned something... From e5056174fdd6d65d65ccd9eb95300db97b3e05b8 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Fri, 2 Dec 2016 12:00:40 -0500 Subject: [PATCH 58/98] Checkpoint bug fix in forward planning for dwells --- g2core/config.cpp | 20 +++++++++++++++----- g2core/error.h | 0 g2core/gcode_parser.cpp | 0 g2core/plan_exec.cpp | 2 +- g2core/planner.h | 12 ++++++------ 5 files changed, 22 insertions(+), 12 deletions(-) mode change 100755 => 100644 g2core/config.cpp mode change 100755 => 100644 g2core/error.h mode change 100755 => 100644 g2core/gcode_parser.cpp diff --git a/g2core/config.cpp b/g2core/config.cpp old mode 100755 new mode 100644 index 279eff86..5b0b048c --- a/g2core/config.cpp +++ b/g2core/config.cpp @@ -584,7 +584,9 @@ nvObj_t *nv_add_object(const char *token) // add an object to the body usi nvObj_t *nv = nv_body; for (uint8_t i=0; ivaluetype != TYPE_EMPTY) { - if ((nv = nv->nx) == NULL) return(NULL); // not supposed to find a NULL; here for safety + if ((nv = nv->nx) == NULL) { // not supposed to find a NULL; here for safety + return(NULL); + } continue; } // load the index from the token or die trying @@ -600,7 +602,9 @@ nvObj_t *nv_add_integer(const char *token, const uint32_t value)// add an intege nvObj_t *nv = nv_body; for (uint8_t i=0; ivaluetype != TYPE_EMPTY) { - if ((nv = nv->nx) == NULL) return(NULL); // not supposed to find a NULL; here for safety + if ((nv = nv->nx) == NULL) { // not supposed to find a NULL; here for safety + return(NULL); + } continue; } strncpy(nv->token, token, TOKEN_LEN); @@ -616,7 +620,9 @@ nvObj_t *nv_add_data(const char *token, const uint32_t value)// add an integer o nvObj_t *nv = nv_body; for (uint8_t i=0; ivaluetype != TYPE_EMPTY) { - if ((nv = nv->nx) == NULL) return(NULL); // not supposed to find a NULL; here for safety + if ((nv = nv->nx) == NULL) { // not supposed to find a NULL; here for safety + return(NULL); + } continue; } strcpy(nv->token, token); @@ -633,7 +639,9 @@ nvObj_t *nv_add_float(const char *token, const float value) // add a float ob nvObj_t *nv = nv_body; for (uint8_t i=0; ivaluetype != TYPE_EMPTY) { - if ((nv = nv->nx) == NULL) return(NULL); // not supposed to find a NULL; here for safety + if ((nv = nv->nx) == NULL) { // not supposed to find a NULL; here for safety + return(NULL); + } continue; } strncpy(nv->token, token, TOKEN_LEN); @@ -649,7 +657,9 @@ nvObj_t *nv_add_string(const char *token, const char *string) // add a string ob nvObj_t *nv = nv_body; for (uint8_t i=0; ivaluetype != TYPE_EMPTY) { - if ((nv = nv->nx) == NULL) return(NULL); // not supposed to find a NULL; here for safety + if ((nv = nv->nx) == NULL) { // not supposed to find a NULL; here for safety + return(NULL); + } continue; } strncpy(nv->token, token, TOKEN_LEN); diff --git a/g2core/error.h b/g2core/error.h old mode 100755 new mode 100644 diff --git a/g2core/gcode_parser.cpp b/g2core/gcode_parser.cpp old mode 100755 new mode 100644 diff --git a/g2core/plan_exec.cpp b/g2core/plan_exec.cpp index 01426627..28cb26f0 100644 --- a/g2core/plan_exec.cpp +++ b/g2core/plan_exec.cpp @@ -152,7 +152,7 @@ static void _init_forward_diffs(float v_0, float v_1); static mpBuf_t *_plan_commands(mpBuf_t *bf) // plan or skip commands; return bf past last command { // must test for buffer state first as the buffer is only "safe" once it's >= PREPPED - while ((bf->buffer_state >= MP_BUFFER_PREPPED) && (bf->block_type == BLOCK_TYPE_COMMAND)) { + while ((bf->buffer_state >= MP_BUFFER_PREPPED) && (bf->block_type >= BLOCK_TYPE_COMMAND)) { if (bf->buffer_state != MP_BUFFER_PLANNED) { // skip already planned buffers bf->buffer_state = MP_BUFFER_PLANNED; // "planning" is just setting the state (for now) } diff --git a/g2core/planner.h b/g2core/planner.h index e5dd1c84..1d9357a7 100644 --- a/g2core/planner.h +++ b/g2core/planner.h @@ -180,12 +180,12 @@ typedef enum { // bf->buffer_state values in incresing orde } bufferState; typedef enum { // bf->block_type values - BLOCK_TYPE_NULL = 0, // null move - does a no-op - BLOCK_TYPE_ALINE, // acceleration planned line - BLOCK_TYPE_DWELL, // delay with no movement - BLOCK_TYPE_COMMAND, // general command - BLOCK_TYPE_JSON_WAIT, // general command - BLOCK_TYPE_TOOL, // T command + BLOCK_TYPE_NULL = 0, // MUST=0 null move - does a no-op + BLOCK_TYPE_ALINE = 1, // MUST=1 acceleration planned line + BLOCK_TYPE_COMMAND = 2, // MUST=2 general command + BLOCK_TYPE_DWELL, // Gcode dwell + BLOCK_TYPE_JSON_WAIT, // JSON wait command + BLOCK_TYPE_TOOL, // T command (T, not M6 tool change) BLOCK_TYPE_SPINDLE_SPEED, // S command BLOCK_TYPE_STOP, // program stop BLOCK_TYPE_END // program end From 76249331946d9f4e5109455a940daf6fe44b01c4 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Sat, 3 Dec 2016 08:50:40 -0500 Subject: [PATCH 59/98] Patch to stop DDA timer before Dwell timer to address Issue #193 --- g2core/board/Archim/hardware.h | 4 ++-- g2core/board/ArduinoDue/hardware.h | 4 ++-- g2core/board/G2v9/hardware.h | 4 ++-- g2core/board/gquadratic/hardware.h | 14 +++++++------- g2core/planner.h | 5 ----- g2core/stepper.cpp | 15 ++++++++------- 6 files changed, 21 insertions(+), 25 deletions(-) mode change 100755 => 100644 g2core/board/Archim/hardware.h mode change 100755 => 100644 g2core/board/ArduinoDue/hardware.h mode change 100755 => 100644 g2core/board/G2v9/hardware.h mode change 100755 => 100644 g2core/board/gquadratic/hardware.h diff --git a/g2core/board/Archim/hardware.h b/g2core/board/Archim/hardware.h old mode 100755 new mode 100644 index d66cae7d..64caf475 --- a/g2core/board/Archim/hardware.h +++ b/g2core/board/Archim/hardware.h @@ -127,8 +127,8 @@ using Motate::OutputPin; // Timer definitions. See stepper.h and other headers for setup typedef TimerChannel<3,0> dda_timer_type; // stepper pulse generation in stepper.cpp typedef TimerChannel<4,0> dwell_timer_type; // dwell timing in stepper.cpp -typedef ServiceCall<0> load_timer_type; // request load timer in stepper.cpp -typedef ServiceCall<1> exec_timer_type; // request exec timer in stepper.cpp +typedef ServiceCall<0> load_timer_type; // request load timer in stepper.cpp +typedef ServiceCall<1> exec_timer_type; // request exec timer in stepper.cpp typedef ServiceCall<2> fwd_plan_timer_type; // request exec timer in stepper.cpp // Pin assignments diff --git a/g2core/board/ArduinoDue/hardware.h b/g2core/board/ArduinoDue/hardware.h old mode 100755 new mode 100644 index 1b5bbe6b..ec8d48d5 --- a/g2core/board/ArduinoDue/hardware.h +++ b/g2core/board/ArduinoDue/hardware.h @@ -129,8 +129,8 @@ using Motate::OutputPin; // Timer definitions. See stepper.h and other headers for setup typedef TimerChannel<3,0> dda_timer_type; // stepper pulse generation in stepper.cpp typedef TimerChannel<4,0> dwell_timer_type; // dwell timing in stepper.cpp -typedef ServiceCall<0> load_timer_type; // request load timer in stepper.cpp -typedef ServiceCall<1> exec_timer_type; // request exec timer in stepper.cpp +typedef ServiceCall<0> load_timer_type; // request load timer in stepper.cpp +typedef ServiceCall<1> exec_timer_type; // request exec timer in stepper.cpp typedef ServiceCall<2> fwd_plan_timer_type; // request exec timer in stepper.cpp // Pin assignments diff --git a/g2core/board/G2v9/hardware.h b/g2core/board/G2v9/hardware.h old mode 100755 new mode 100644 index 835dfc44..a00fb5d6 --- a/g2core/board/G2v9/hardware.h +++ b/g2core/board/G2v9/hardware.h @@ -129,8 +129,8 @@ using Motate::OutputPin; // Timer definitions. See stepper.h and other headers for setup typedef TimerChannel<3,0> dda_timer_type; // stepper pulse generation in stepper.cpp typedef TimerChannel<4,0> dwell_timer_type; // dwell timing in stepper.cpp -typedef ServiceCall<0> load_timer_type; // request load timer in stepper.cpp -typedef ServiceCall<1> exec_timer_type; // request exec timer in stepper.cpp +typedef ServiceCall<0> load_timer_type; // request load timer in stepper.cpp +typedef ServiceCall<1> exec_timer_type; // request exec timer in stepper.cpp typedef ServiceCall<2> fwd_plan_timer_type; // request exec timer in stepper.cpp // Pin assignments diff --git a/g2core/board/gquadratic/hardware.h b/g2core/board/gquadratic/hardware.h old mode 100755 new mode 100644 index 069cb2ba..5bf1a1fa --- a/g2core/board/gquadratic/hardware.h +++ b/g2core/board/gquadratic/hardware.h @@ -110,8 +110,8 @@ using Motate::OutputPin; * * The following interrupts are defined w/indicated priorities * - * 0 DDA_TIMER (3) for step pulse generation - * 1 DWELL_TIMER (4) for dwell timing + * 0 DDA_TIMER (9) for step pulse generation + * 1 DWELL_TIMER (10) for dwell timing * 2 LOADER software generated interrupt (STIR / SGI) * 3 Serial read character interrupt * 4 EXEC software generated interrupt (STIR / SGI) @@ -128,11 +128,11 @@ using Motate::OutputPin; /**** Motate Definitions ****/ // Timer definitions. See stepper.h and other headers for setup -typedef TimerChannel<9, 0> dda_timer_type; // stepper pulse generation in stepper.cpp -typedef TimerChannel<10, 0> dwell_timer_type; // dwell timing in stepper.cpp -typedef ServiceCall<0> load_timer_type; // request load timer in stepper.cpp -typedef ServiceCall<1> exec_timer_type; // request exec timer in stepper.cpp -typedef ServiceCall<2> fwd_plan_timer_type; // request exec timer in stepper.cpp +typedef TimerChannel<9, 0> dda_timer_type; // stepper pulse generation in stepper.cpp +typedef TimerChannel<10, 0> dwell_timer_type; // dwell timing in stepper.cpp +typedef ServiceCall<0> load_timer_type; // request load timer in stepper.cpp +typedef ServiceCall<1> exec_timer_type; // request exec timer in stepper.cpp +typedef ServiceCall<2> fwd_plan_timer_type; // request exec timer in stepper.cpp // Pin assignments diff --git a/g2core/planner.h b/g2core/planner.h index 1d9357a7..83cc3757 100644 --- a/g2core/planner.h +++ b/g2core/planner.h @@ -381,23 +381,18 @@ struct mpBuffer_to_clear { length = 0.0; block_time = 0.0; override_factor = 0.0; - cruise_velocity = 0.0; exit_velocity = 0.0; - cruise_vset = 0.0; cruise_vmax = 0.0; exit_vmax = 0.0; - absolute_vmax = 0.0; junction_vmax = 0.0; - jerk = 0.0; jerk_sq = 0.0; recip_jerk = 0.0; sqrt_j = 0.0; q_recip_2_sqrt_j = 0.0; - gm.reset(); } }; diff --git a/g2core/stepper.cpp b/g2core/stepper.cpp index 9d5ef6d8..15035508 100644 --- a/g2core/stepper.cpp +++ b/g2core/stepper.cpp @@ -254,7 +254,7 @@ namespace Motate { // Must define timer interrupts inside the Motate template<> void dda_timer_type::interrupt() { - dda_timer.getInterruptCause(); // clear interrupt condition + dda_timer.getInterruptCause(); // clear interrupt condition // clear all steps from the previous interrupt // for (uint8_t motor=0; motor 0) { // Motors[motor]->stepStart(); // turn step bit on @@ -331,9 +331,10 @@ void dda_timer_type::interrupt() } #endif - // process end of segment + // Process end of segment. + // One more interrupt will occur to turn of any pulses set in this pass. if (--st_run.dda_ticks_downcount == 0) { - _load_move(); // load the next move at the current interrupt level + _load_move(); // load the next move at the current interrupt level } } // MOTATE_TIMER_INTERRUPT } // namespace Motate @@ -629,11 +630,12 @@ static void _load_move() //**** do this last **** - dda_timer.start(); // start the DDA timer if not already running + dda_timer.start(); // start the DDA timer if not already running // handle dwells } else if (st_pre.block_type == BLOCK_TYPE_DWELL) { st_run.dda_ticks_downcount = st_pre.dda_ticks; + dda_timer.stop(); // ++++ This is a stopgap. The DDA timer should have been stopped before here dwell_timer.start(); // handle synchronous commands @@ -648,7 +650,7 @@ static void _load_move() // all other cases drop to here (e.g. Null moves after Mcodes skip to here) st_pre.block_type = BLOCK_TYPE_NULL; st_pre.buffer_state = PREP_BUFFER_OWNED_BY_EXEC; // we are done with the prep buffer - flip the flag back - st_request_exec_move(); // exec and prep next move + st_request_exec_move(); // exec and prep next move } /*********************************************************************************** @@ -788,7 +790,6 @@ void st_prep_command(void *bf) void st_prep_dwell(float microseconds) { st_pre.block_type = BLOCK_TYPE_DWELL; - //st_pre.dda_period = _f_to_period(FREQUENCY_DWELL); st_pre.dda_ticks = (uint32_t)((microseconds/1000000) * FREQUENCY_DWELL); st_pre.buffer_state = PREP_BUFFER_OWNED_BY_LOADER; // signal that prep buffer is ready } From 93436ba43b8f03e1a3195642e8bcd38ccc9e64ea Mon Sep 17 00:00:00 2001 From: Rob Giseburt Date: Mon, 5 Dec 2016 15:09:30 -0600 Subject: [PATCH 60/98] Removed erroneous debug_trap that hosed up feedhold (and homing). --- g2core/stepper.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/g2core/stepper.cpp b/g2core/stepper.cpp index 15035508..4c3be1f8 100644 --- a/g2core/stepper.cpp +++ b/g2core/stepper.cpp @@ -642,10 +642,7 @@ static void _load_move() } else if (st_pre.block_type == BLOCK_TYPE_COMMAND) { mp_runtime_command(st_pre.bf); - } // else null - WARNING - We cannot printf from here!! Causes crashes. - else { - _debug_trap("_load_move called when it's not needed?"); - } + } // else null - which is okay in many cases // all other cases drop to here (e.g. Null moves after Mcodes skip to here) st_pre.block_type = BLOCK_TYPE_NULL; From f9793fed25142b3472c4f11b5fa9e4250769ca0b Mon Sep 17 00:00:00 2001 From: Rob Giseburt Date: Mon, 5 Dec 2016 15:10:06 -0600 Subject: [PATCH 61/98] =?UTF-8?q?Proper=20handling=20of=20=E2=80=9C!\n~\n?= =?UTF-8?q?=E2=80=9D=20in=20the=20input=20stream.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- g2core/xio.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/g2core/xio.cpp b/g2core/xio.cpp index d68880f2..65aa76f8 100755 --- a/g2core/xio.cpp +++ b/g2core/xio.cpp @@ -756,6 +756,8 @@ struct LineRXBuffer : RXBuffer<_size, owner_type, char> { if (_scan_offset == _read_offset) { _debug_trap("read ran into scan (2)"); } + // this also counts as the beginning of a line + _skip_sections.skip(_read_offset); c = _data[_read_offset]; } From 6d445db5f36c3c37f26f3e8933a8f17721fc03d2 Mon Sep 17 00:00:00 2001 From: Rob Giseburt Date: Mon, 5 Dec 2016 15:10:31 -0600 Subject: [PATCH 62/98] Handle forward planning past commands a little better. --- g2core/plan_exec.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/g2core/plan_exec.cpp b/g2core/plan_exec.cpp index 28cb26f0..85527f85 100644 --- a/g2core/plan_exec.cpp +++ b/g2core/plan_exec.cpp @@ -283,7 +283,7 @@ stat_t mp_exec_move() mp_planner_time_accounting(); } - if (bf->nx->buffer_state == MP_BUFFER_PREPPED) { + if (bf->nx->buffer_state >= MP_BUFFER_PREPPED) { // We go ahead and *ask* for a forward planning of the next move. // This won't call mp_plan_move until we leave this function // (and have called mp_exec_aline via bf->bf_func). From 6493c1f254d7efd1d94da2b7aa916361994bcff5 Mon Sep 17 00:00:00 2001 From: Rob Giseburt Date: Mon, 5 Dec 2016 15:58:13 -0600 Subject: [PATCH 63/98] Update motate for USB fixes of sam3x family. --- Motate | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Motate b/Motate index 1e1be74e..05faa681 160000 --- a/Motate +++ b/Motate @@ -1 +1 @@ -Subproject commit 1e1be74e8b0dac10af1829ea211fef06f594ab7f +Subproject commit 05faa6817d2605b0da1155023897616808deaa20 From cbd3f9e19fb69520d4350e20e44a90b880a48b22 Mon Sep 17 00:00:00 2001 From: Rob Giseburt Date: Mon, 5 Dec 2016 17:05:35 -0600 Subject: [PATCH 64/98] Switch dwells to the DDA timer, removed dwell_timer. Fixes #193 --- g2core/board/Archim/hardware.h | 3 +- g2core/board/ArduinoDue/hardware.h | 3 +- g2core/board/G2v9/hardware.h | 3 +- g2core/board/gquadratic/hardware.h | 3 +- g2core/board/gquintic/hardware.h | 3 +- g2core/board/printrboardg2/hardware.h | 3 +- g2core/board/sbv300/hardware.h | 3 +- g2core/stepper.cpp | 44 ++++++++++++--------------- 8 files changed, 27 insertions(+), 38 deletions(-) diff --git a/g2core/board/Archim/hardware.h b/g2core/board/Archim/hardware.h index 64caf475..6da17870 100644 --- a/g2core/board/Archim/hardware.h +++ b/g2core/board/Archim/hardware.h @@ -126,8 +126,7 @@ using Motate::OutputPin; // Timer definitions. See stepper.h and other headers for setup typedef TimerChannel<3,0> dda_timer_type; // stepper pulse generation in stepper.cpp -typedef TimerChannel<4,0> dwell_timer_type; // dwell timing in stepper.cpp -typedef ServiceCall<0> load_timer_type; // request load timer in stepper.cpp +typedef TimerChannel<4,0> load_timer_type; // request load timer in stepper.cpp typedef ServiceCall<1> exec_timer_type; // request exec timer in stepper.cpp typedef ServiceCall<2> fwd_plan_timer_type; // request exec timer in stepper.cpp diff --git a/g2core/board/ArduinoDue/hardware.h b/g2core/board/ArduinoDue/hardware.h index ec8d48d5..e01e70d4 100644 --- a/g2core/board/ArduinoDue/hardware.h +++ b/g2core/board/ArduinoDue/hardware.h @@ -128,8 +128,7 @@ using Motate::OutputPin; // Timer definitions. See stepper.h and other headers for setup typedef TimerChannel<3,0> dda_timer_type; // stepper pulse generation in stepper.cpp -typedef TimerChannel<4,0> dwell_timer_type; // dwell timing in stepper.cpp -typedef ServiceCall<0> load_timer_type; // request load timer in stepper.cpp +typedef TimerChannel<4,0> load_timer_type; // request load timer in stepper.cpp typedef ServiceCall<1> exec_timer_type; // request exec timer in stepper.cpp typedef ServiceCall<2> fwd_plan_timer_type; // request exec timer in stepper.cpp diff --git a/g2core/board/G2v9/hardware.h b/g2core/board/G2v9/hardware.h index a00fb5d6..260ed18a 100644 --- a/g2core/board/G2v9/hardware.h +++ b/g2core/board/G2v9/hardware.h @@ -128,8 +128,7 @@ using Motate::OutputPin; // Timer definitions. See stepper.h and other headers for setup typedef TimerChannel<3,0> dda_timer_type; // stepper pulse generation in stepper.cpp -typedef TimerChannel<4,0> dwell_timer_type; // dwell timing in stepper.cpp -typedef ServiceCall<0> load_timer_type; // request load timer in stepper.cpp +typedef TimerChannel<4,0> load_timer_type; // request load timer in stepper.cpp typedef ServiceCall<1> exec_timer_type; // request exec timer in stepper.cpp typedef ServiceCall<2> fwd_plan_timer_type; // request exec timer in stepper.cpp diff --git a/g2core/board/gquadratic/hardware.h b/g2core/board/gquadratic/hardware.h index 5bf1a1fa..a28bf858 100644 --- a/g2core/board/gquadratic/hardware.h +++ b/g2core/board/gquadratic/hardware.h @@ -129,8 +129,7 @@ using Motate::OutputPin; // Timer definitions. See stepper.h and other headers for setup typedef TimerChannel<9, 0> dda_timer_type; // stepper pulse generation in stepper.cpp -typedef TimerChannel<10, 0> dwell_timer_type; // dwell timing in stepper.cpp -typedef ServiceCall<0> load_timer_type; // request load timer in stepper.cpp +typedef TimerChannel<10, 0> load_timer_type; // request load timer in stepper.cpp typedef ServiceCall<1> exec_timer_type; // request exec timer in stepper.cpp typedef ServiceCall<2> fwd_plan_timer_type; // request exec timer in stepper.cpp diff --git a/g2core/board/gquintic/hardware.h b/g2core/board/gquintic/hardware.h index fb7f284e..e7fb56ba 100755 --- a/g2core/board/gquintic/hardware.h +++ b/g2core/board/gquintic/hardware.h @@ -127,8 +127,7 @@ using Motate::OutputPin; // Timer definitions. See stepper.h and other headers for setup typedef TimerChannel<9, 0> dda_timer_type; // stepper pulse generation in stepper.cpp -typedef TimerChannel<10, 0> dwell_timer_type; // dwell timing in stepper.cpp -typedef ServiceCall<0> load_timer_type; // request load timer in stepper.cpp +typedef TimerChannel<10, 0> load_timer_type; // request load timer in stepper.cpp typedef ServiceCall<1> exec_timer_type; // request exec timer in stepper.cpp typedef ServiceCall<2> fwd_plan_timer_type; // request exec timer in stepper.cpp diff --git a/g2core/board/printrboardg2/hardware.h b/g2core/board/printrboardg2/hardware.h index 6046c789..244a2681 100755 --- a/g2core/board/printrboardg2/hardware.h +++ b/g2core/board/printrboardg2/hardware.h @@ -126,8 +126,7 @@ using Motate::OutputPin; // Timer definitions. See stepper.h and other headers for setup typedef TimerChannel<3,0> dda_timer_type; // stepper pulse generation in stepper.cpp -typedef TimerChannel<4,0> dwell_timer_type; // dwell timing in stepper.cpp -typedef ServiceCall<0> load_timer_type; // request load timer in stepper.cpp +typedef TimerChannel<4,0> load_timer_type; // request load timer in stepper.cpp typedef ServiceCall<1> exec_timer_type; // request exec timer in stepper.cpp typedef ServiceCall<2> fwd_plan_timer_type; // request exec timer in stepper.cpp diff --git a/g2core/board/sbv300/hardware.h b/g2core/board/sbv300/hardware.h index 0e576ab4..5ded07eb 100755 --- a/g2core/board/sbv300/hardware.h +++ b/g2core/board/sbv300/hardware.h @@ -126,8 +126,7 @@ using Motate::OutputPin; // Timer definitions. See stepper.h and other headers for setup typedef TimerChannel<3,0> dda_timer_type; // stepper pulse generation in stepper.cpp -typedef TimerChannel<4,0> dwell_timer_type; // dwell timing in stepper.cpp -typedef ServiceCall<0> load_timer_type; // request load timer in stepper.cpp +typedef TimerChannel<4,0> load_timer_type; // request load timer in stepper.cpp typedef ServiceCall<1> exec_timer_type; // request exec timer in stepper.cpp typedef ServiceCall<2> fwd_plan_timer_type; // request exec timer in stepper.cpp diff --git a/g2core/stepper.cpp b/g2core/stepper.cpp index 4c3be1f8..bb765422 100644 --- a/g2core/stepper.cpp +++ b/g2core/stepper.cpp @@ -76,7 +76,6 @@ extern OutputPin debug_pin3; //extern OutputPin debug_pin4; dda_timer_type dda_timer {kTimerUpToMatch, FREQUENCY_DDA}; // stepper pulse generation -dwell_timer_type dwell_timer {kTimerUpToMatch, FREQUENCY_DWELL}; // dwell timer load_timer_type load_timer; // triggers load of next stepper segment exec_timer_type exec_timer; // triggers calculation of next+1 stepper segment fwd_plan_timer_type fwd_plan_timer; // triggers planning of next block @@ -117,9 +116,6 @@ void stepper_init() // If you need more pulse width you need to drop the DDA clock rate dda_timer.setInterrupts(kInterruptOnOverflow | kInterruptPriorityHighest); - // setup DWELL timer - dwell_timer.setInterrupts(kInterruptOnOverflow | kInterruptPriorityHighest); - // setup software interrupt load timer load_timer.setInterrupts(kInterruptOnSoftwareTrigger | kInterruptPriorityHigh); @@ -148,7 +144,6 @@ void stepper_init() void stepper_reset() { dda_timer.stop(); // stop all movement - dwell_timer.stop(); st_run.dda_ticks_downcount = 0; // signal the runtime is not busy st_pre.buffer_state = PREP_BUFFER_OWNED_BY_EXEC; // set to EXEC or it won't restart @@ -339,22 +334,6 @@ void dda_timer_type::interrupt() } // MOTATE_TIMER_INTERRUPT } // namespace Motate -/***** Dwell Interrupt Service Routine ************************************************** - * ISR - DDA timer interrupt routine - service ticks from DDA timer - */ - -namespace Motate { // Must define timer interrupts inside the Motate namespace - template<> - void dwell_timer_type::interrupt() - { - dwell_timer.getInterruptCause(); // read SR to clear interrupt condition - if (--st_run.dda_ticks_downcount == 0) { - dwell_timer.stop(); - _load_move(); - } - } -} // namespace Motate - /**************************************************************************************** * Exec sequencing code - computes and prepares next load segment * st_request_exec_move() - SW interrupt to request to execute a move @@ -635,8 +614,24 @@ static void _load_move() // handle dwells } else if (st_pre.block_type == BLOCK_TYPE_DWELL) { st_run.dda_ticks_downcount = st_pre.dda_ticks; - dda_timer.stop(); // ++++ This is a stopgap. The DDA timer should have been stopped before here - dwell_timer.start(); + st_run.mot[MOTOR_1].substep_accumulator = 0; + st_run.mot[MOTOR_2].substep_accumulator = 0; +#if (MOTORS > 2) + st_run.mot[MOTOR_3].substep_accumulator = 0; +#endif +#if (MOTORS > 3) + st_run.mot[MOTOR_4].substep_accumulator = 0; +#endif +#if (MOTORS > 4) + st_run.mot[MOTOR_5].substep_accumulator = 0; +#endif +#if (MOTORS > 5) + st_run.mot[MOTOR_6].substep_accumulator = 0; +#endif + + //**** do this last **** + // Note: we are using the dda timer for the dwells (we didn't always) + dda_timer.start(); // start the DDA timer if not already running // handle synchronous commands } else if (st_pre.block_type == BLOCK_TYPE_COMMAND) { @@ -787,7 +782,8 @@ void st_prep_command(void *bf) void st_prep_dwell(float microseconds) { st_pre.block_type = BLOCK_TYPE_DWELL; - st_pre.dda_ticks = (uint32_t)((microseconds/1000000) * FREQUENCY_DWELL); + // Note: we are using the dda timer for the dwells (we didn't always) + st_pre.dda_ticks = (uint32_t)((microseconds/1000000) * FREQUENCY_DDA); st_pre.buffer_state = PREP_BUFFER_OWNED_BY_LOADER; // signal that prep buffer is ready } From 57bd8b69595cf792bdf37199b66c0026d6d70beb Mon Sep 17 00:00:00 2001 From: Rob Giseburt Date: Mon, 5 Dec 2016 17:06:38 -0600 Subject: [PATCH 65/98] Update motate reference for more USB work. --- Motate | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Motate b/Motate index 05faa681..5bec1487 160000 --- a/Motate +++ b/Motate @@ -1 +1 @@ -Subproject commit 05faa6817d2605b0da1155023897616808deaa20 +Subproject commit 5bec14874ea3872881128819ac1213c824d04319 From b539445b2a2504113be6fb42024e0289852854f6 Mon Sep 17 00:00:00 2001 From: Rob Giseburt Date: Mon, 5 Dec 2016 21:48:58 -0600 Subject: [PATCH 66/98] Update motate reference for more USB work (again). --- Motate | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Motate b/Motate index 5bec1487..4646d135 160000 --- a/Motate +++ b/Motate @@ -1 +1 @@ -Subproject commit 5bec14874ea3872881128819ac1213c824d04319 +Subproject commit 4646d135cc99e358531ed7c40d94602acd9d1c90 From 9c3f5300890c198965cda17183754c191d3a1147 Mon Sep 17 00:00:00 2001 From: Rob Giseburt Date: Tue, 6 Dec 2016 19:49:14 -0600 Subject: [PATCH 67/98] Forward-porting Printrbot Simple 1608 settings. --- .../settings/settings_Printrbot_Simple_1608.h | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/g2core/settings/settings_Printrbot_Simple_1608.h b/g2core/settings/settings_Printrbot_Simple_1608.h index 7b24e154..a9a29d4f 100755 --- a/g2core/settings/settings_Printrbot_Simple_1608.h +++ b/g2core/settings/settings_Printrbot_Simple_1608.h @@ -94,11 +94,11 @@ // 80 steps/mm at 1/16 microstepping = 40 mm/rev #define M1_MOTOR_MAP AXIS_X // 1ma #define M1_STEP_ANGLE 1.8 // 1sa -#define M1_TRAVEL_PER_REV 40.132 // 1tr +#define M1_TRAVEL_PER_REV 40.011604 // 1tr #define M1_MICROSTEPS 32 // 1mi 1,2,4,8,16,32 #define M1_POLARITY 0 // 1po 0=normal, 1=reversed #define M1_POWER_MODE MOTOR_POWER_MODE // 1pm standard -#define M1_POWER_LEVEL 0.5 // 1mp +#define M1_POWER_LEVEL 0.35 // 1mp // 80 steps/mm at 1/16 microstepping = 40 mm/rev #define M3_MOTOR_MAP AXIS_Y @@ -107,7 +107,7 @@ #define M3_MICROSTEPS 32 #define M3_POLARITY 0 #define M3_POWER_MODE MOTOR_POWER_MODE -#define M3_POWER_LEVEL 0.5 +#define M3_POWER_LEVEL 0.35 // 2020 steps/mm at 1/16 microstepping = 1.58416 mm/rev #define M2_MOTOR_MAP AXIS_Z @@ -116,7 +116,7 @@ #define M2_MICROSTEPS 32 #define M2_POLARITY 1 #define M2_POWER_MODE MOTOR_POWER_MODE -#define M2_POWER_LEVEL 0.4 +#define M2_POWER_LEVEL 0.3 // 96 steps/mm at 1/16 microstepping = 33.3333 mm/rev #define M4_MOTOR_MAP AXIS_A @@ -125,7 +125,7 @@ #define M4_MICROSTEPS 32 #define M4_POLARITY 1 #define M4_POWER_MODE MOTOR_POWER_MODE -#define M4_POWER_LEVEL 0.4 +#define M4_POWER_LEVEL 0.3 // 96 steps/mm at 1/16 microstepping = 33.3333 mm/rev #define M5_MOTOR_MAP AXIS_B @@ -139,12 +139,12 @@ // *** axis settings ********************************************************************************** #define X_AXIS_MODE AXIS_STANDARD // xam see canonical_machine.h cmAxisMode for valid values -#define X_VELOCITY_MAX 10000 // xvm G0 max velocity in mm/min +#define X_VELOCITY_MAX 15000 // xvm G0 max velocity in mm/min #define X_FEEDRATE_MAX X_VELOCITY_MAX // xfr G1 max feed rate in mm/min #define X_TRAVEL_MIN 0 // xtn minimum travel - used by soft limits and homing #define X_TRAVEL_MAX 215 // xtm travel between switches or crashes -#define X_JERK_MAX 3000 // xjm yes, that's "100 billion" mm/(min^3) -#define X_JERK_HIGH_SPEED 3000 // xjh +#define X_JERK_MAX 6000 // xjm yes, that's "100 billion" mm/(min^3) +#define X_JERK_HIGH_SPEED 6000 // xjh #define X_HOMING_INPUT 4 // xhi input used for homing or 0 to disable #define X_HOMING_DIRECTION 0 // xhd 0=search moves negative, 1= search moves positive #define X_SEARCH_VELOCITY 2500 // xsv move in negative direction @@ -153,12 +153,12 @@ #define X_ZERO_BACKOFF 0.5 // xzb mm #define Y_AXIS_MODE AXIS_STANDARD -#define Y_VELOCITY_MAX 10000 +#define Y_VELOCITY_MAX 15000 #define Y_FEEDRATE_MAX Y_VELOCITY_MAX #define Y_TRAVEL_MIN 0 #define Y_TRAVEL_MAX 152.4 -#define Y_JERK_MAX 3000 -#define Y_JERK_HIGH_SPEED 3000 +#define Y_JERK_MAX 6000 +#define Y_JERK_HIGH_SPEED 6000 #define Y_HOMING_INPUT 1 #define Y_HOMING_DIRECTION 1 #define Y_SEARCH_VELOCITY 3000 @@ -185,7 +185,7 @@ * To calculate the speeds here, in Wolfram Alpha-speak: * * c=2*pi*r, r=0.609, d=c/360, s=((S*60)/d), S=40 for s - * c=2*pi*r, r=5.30516476972984, d=c/360, s=((S*60)/d), S=40 for s + * c=2*pi*r, r=4.28394, d=c/360, s=((S*60)/d), S=40 for s * * Change r to A_RADIUS, and S to the desired speed, in mm/s or mm/s/s/s. * @@ -204,12 +204,12 @@ //#define A_VELOCITY_MAX 25920.0 // ~40 mm/s, 2,400 mm/min //#define A_FEEDRATE_MAX 25920.0/2.0 // ~20 mm/s, 1,200 mm/min #define A_VELOCITY_MAX 77760.0 // G0 rate ~120 mm/s, 2,400 mm/min -#define A_FEEDRATE_MAX 6480 // ~10 mm/s +#define A_FEEDRATE_MAX 16050 // ~10 mm/s //#define A_FEEDRATE_MAX 9720.0 // 9720.0 = G1 rate ~15 mm/s, 900 mm/min #define A_TRAVEL_MIN 0 #define A_TRAVEL_MAX 10 -#define A_JERK_MAX 81000 // 250 million mm/min^3 = 324000 -//#define A_JERK_MAX 162000 // 250 million mm/min^3 = 324000 +//#define A_JERK_MAX 81000 // 250 million mm/min^3 = 324000 +#define A_JERK_MAX 162000 // 250 million mm/min^3 = 324000 //#define A_JERK_MAX 324000 // 500 million mm/min^3 = 324000 //#define A_JERK_MAX 648000 // 1,000 million mm/min^3 = 648000 // * a million IF it's over a million From f32b9c3c3ed9d03d046a8614916c26aae7bdad91 Mon Sep 17 00:00:00 2001 From: Rob Giseburt Date: Tue, 6 Dec 2016 21:21:49 -0600 Subject: [PATCH 68/98] Cleanup handling of queue flush, removed xio_flush_read() (unused now) --- g2core/canonical_machine.cpp | 3 ++- g2core/xio.cpp | 43 +++++++++++++++++------------------- g2core/xio.h | 1 - 3 files changed, 22 insertions(+), 25 deletions(-) diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index 9892da8a..7e32038e 100755 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -1683,8 +1683,9 @@ void cm_request_queue_flush() { if ((cm.hold_state != FEEDHOLD_OFF) && // don't honor request unless you are in a feedhold (cm.queue_flush_state == FLUSH_OFF)) { // ...and only once - xio_flush_read(); // flush the input buffers - you can do that now cm.queue_flush_state = FLUSH_REQUESTED; // request planner flush once motion has stopped + + // NOTE: we used to flush the input buffers, but this is handled in xio *prior* to queue flush now } } diff --git a/g2core/xio.cpp b/g2core/xio.cpp index 65aa76f8..d2dd2261 100755 --- a/g2core/xio.cpp +++ b/g2core/xio.cpp @@ -281,9 +281,6 @@ struct xio_t { } } -#pragma GCC push_options -#pragma GCC optimize ("O0") - /* * readline() - read a complete line from a device * @@ -352,8 +349,6 @@ struct xio_t { return (NULL); }; - #pragma GCC pop_options - uint16_t magic_end; }; @@ -367,9 +362,6 @@ extern xio_t xio; // See here for a discussion of what this means if you are not familiar with C++ // https://github.com/synthetos/g2/wiki/Dual-Endpoint-USB-Internals#c-classes-virtual-functions-and-inheritance -#pragma GCC push_options -#pragma GCC optimize ("O0") - // LineRXBuffer takes the Motate RXBuffer (which handles "transfers", usually DMA), and adds G2 line-reading // semantics to it. template @@ -709,7 +701,7 @@ struct LineRXBuffer : RXBuffer<_size, owner_type, char> { // move the read buffer up to where we're scanning _read_offset = _scan_offset; - // note that we have 0 lines (of data) in the buffer + // record that we have 0 lines (of data) in the buffer _lines_found = 0; // and clear out any skip sections we have @@ -790,12 +782,28 @@ struct LineRXBuffer : RXBuffer<_size, owner_type, char> { *dst_ptr = 0; return _line_buffer; - }; + }; // readline + + // this is called from flushRead() + void flush() { + parent_type::flush(); + _scan_offset = _read_offset; + + // This is similar to the % "queue flush" handling above, except we flush + // the scan to the to the read (which was just set tot he write by the parent), + // not the other way around. + + // record that we have 0 lines (of data) in the buffer + _lines_found = 0; + + // and clear out any skip sections we have + while (!_skip_sections.is_empty()) { + _skip_sections.pop_skip(); + } + }; // flush }; // LineRXBuffer -#pragma GCC pop_options - template struct xioDeviceWrapper : xioDeviceWrapperBase { // describes a device for reading and writing Device _dev; @@ -847,9 +855,6 @@ struct xioDeviceWrapper : xioDeviceWrapperBase { // describes a device for re return _tx_buffer.write(buffer, len); } -#pragma GCC push_options -#pragma GCC optimize ("O0") - virtual char *readline(devflags_t limit_flags, uint16_t &size) final { if ((limit_flags & flags) && isConnected()) { return _rx_buffer.readline(!(limit_flags & DEV_IS_DATA), size); @@ -859,8 +864,6 @@ struct xioDeviceWrapper : xioDeviceWrapperBase { // describes a device for re return NULL; }; -#pragma GCC pop_options - void _flushLine() { // TODO: Call to flush the RX buffer line structures }; @@ -1018,7 +1021,6 @@ size_t xio_write(const char *buffer, size_t size) /* * xio_readline() - read a complete line from a device * xio_writeline() - write a complete line to control device - * xio_flush_read() - flush read buffers * * Defers to xio.readline(), etc. */ @@ -1033,11 +1035,6 @@ int16_t xio_writeline(const char *buffer) return xio.writeline(buffer); } -void xio_flush_read() -{ - return xio.flushRead(); -} - bool xio_connected() { return xio.connected(); diff --git a/g2core/xio.h b/g2core/xio.h index 671ba905..0369af21 100755 --- a/g2core/xio.h +++ b/g2core/xio.h @@ -113,7 +113,6 @@ enum xioSPIMode { void xio_init(void); stat_t xio_test_assertions(void); -void xio_flush_read(); size_t xio_write(const uint8_t *buffer, size_t size); char *xio_readline(devflags_t &flags, uint16_t &size); int16_t xio_writeline(const char *buffer); From c98abe153fb5d167f1a7b5c8d54f4d5afa665a19 Mon Sep 17 00:00:00 2001 From: Rob Giseburt Date: Tue, 6 Dec 2016 21:23:30 -0600 Subject: [PATCH 69/98] Update Motate reference for Sam3X USB connection handling. --- Motate | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Motate b/Motate index 4646d135..aefdc1b1 160000 --- a/Motate +++ b/Motate @@ -1 +1 @@ -Subproject commit 4646d135cc99e358531ed7c40d94602acd9d1c90 +Subproject commit aefdc1b1fb933cc2dbfa94624ef3b313446d33ca From 5ff7881f896d8abd16e56fea27ed6c28fe4b16be Mon Sep 17 00:00:00 2001 From: Rob Giseburt Date: Tue, 6 Dec 2016 21:50:31 -0600 Subject: [PATCH 70/98] Update Motate reference for more USB business. --- Motate | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Motate b/Motate index aefdc1b1..652a52c9 160000 --- a/Motate +++ b/Motate @@ -1 +1 @@ -Subproject commit aefdc1b1fb933cc2dbfa94624ef3b313446d33ca +Subproject commit 652a52c95f4f434bd2940a2a666970ea5f6c2fbc From 8a87756275ca88a7744fb448b961f117ded82707 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Wed, 7 Dec 2016 09:14:10 -0500 Subject: [PATCH 71/98] New motate reference and some updates to AS7 project parameters --- g2core/g2core.cppproj | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/g2core/g2core.cppproj b/g2core/g2core.cppproj index 974faa35..6bde58ec 100644 --- a/g2core/g2core.cppproj +++ b/g2core/g2core.cppproj @@ -5,7 +5,7 @@ 7.0 com.Atmel.ARMGCC.CPP {44ea8fec-55d7-4149-8a78-a574fc26bf51} - ATSAM3X8C + ATSAMS70N19 none Executable CPP @@ -22,7 +22,8 @@ 1 3.5.0 SWD - com.atmel.avrdbg.tool.atmelice + + com.atmel.avrdbg.tool.samice J-Link @@ -73,7 +74,7 @@ SWD com.atmel.avrdbg.tool.atmelice - J41800030015 + J41800019454 Atmel-ICE True @@ -100,7 +101,7 @@ True true - J41800030015 + J41800019454 0x284E0A60 2000000 From 535e5b74ca0e2e863ba4e11761797737f44ab6ad Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Wed, 7 Dec 2016 09:14:24 -0500 Subject: [PATCH 72/98] new motate reference From 97b3c2aac352322dbe0837da886418a73222fc6c Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Wed, 7 Dec 2016 11:01:01 -0500 Subject: [PATCH 73/98] Changes to project file to include the revB pinout files --- g2core/g2core.cppproj | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/g2core/g2core.cppproj b/g2core/g2core.cppproj index 6bde58ec..f6402809 100644 --- a/g2core/g2core.cppproj +++ b/g2core/g2core.cppproj @@ -22,8 +22,7 @@ 1 3.5.0 SWD - - + com.atmel.avrdbg.tool.atmelice com.atmel.avrdbg.tool.samice J-Link @@ -102,7 +101,7 @@ true J41800019454 - 0x284E0A60 + 0xA11D0A00 2000000 @@ -1609,7 +1608,7 @@ compile - + compile @@ -1633,7 +1632,7 @@ compile - + compile From fd54697ea42705596b06f0b06eb8d67a568fc3ad Mon Sep 17 00:00:00 2001 From: Rob Giseburt Date: Wed, 7 Dec 2016 11:32:28 -0600 Subject: [PATCH 74/98] Added USB_SERIAL_PORTS_EXPOSED to settings (Options: 1, or 2) --- g2core/board/Archim/board_xio.cpp | 19 +++++++----- g2core/board/Archim/board_xio.h | 14 +++++++-- g2core/board/ArduinoDue/board_xio.cpp | 26 +++++++++------- g2core/board/ArduinoDue/board_xio.h | 19 +++++++++--- g2core/board/G2v9/board_xio.cpp | 27 ++++++++-------- g2core/board/G2v9/board_xio.h | 19 +++++++++--- g2core/board/gquadratic/board_xio.cpp | 21 +++++++------ g2core/board/gquadratic/board_xio.h | 14 +++++++-- g2core/board/gquintic/board_xio.cpp | 21 +++++++------ g2core/board/gquintic/board_xio.h | 14 +++++++-- g2core/board/printrboardg2/board_xio.cpp | 20 +++++++----- g2core/board/printrboardg2/board_xio.h | 19 +++++++++--- g2core/board/sbv300/board_xio.cpp | 39 +++++++++++++----------- g2core/board/sbv300/board_xio.h | 34 +++++++++++++-------- g2core/settings/settings_default.h | 5 +++ g2core/xio.cpp | 7 +++++ 16 files changed, 214 insertions(+), 104 deletions(-) diff --git a/g2core/board/Archim/board_xio.cpp b/g2core/board/Archim/board_xio.cpp index ff0846e1..87ab4dd3 100644 --- a/g2core/board/Archim/board_xio.cpp +++ b/g2core/board/Archim/board_xio.cpp @@ -42,20 +42,23 @@ const Motate::USBSettings_t Motate::USBSettings = { }; /*gProductVersion = */ //0.1, -//Motate::USBDevice< Motate::USBCDC > usb; -Motate::USBDevice< Motate::USBCDC, Motate::USBCDC > usb; +XIOUSBDevice_t usb; + +extern decltype(usb.mixin<0>::Serial)& SerialUSB; +#if USB_SERIAL_PORTS_EXPOSED == 2 +extern decltype(usb.mixin<1>::Serial)& SerialUSB1; +#endif + decltype(usb.mixin<0>::Serial) &SerialUSB = usb.mixin<0>::Serial; -decltype(usb.mixin<1>::Serial) &SerialUSB1 = usb.mixin<1>::Serial; +//decltype(usb.mixin<1>::Serial) &SerialUSB1 = usb.mixin<1>::Serial; -// 115200 is the default, as well. -//UART Serial {115200, UARTMode::RTSCTSFlowControl}; - -MOTATE_SET_USB_VENDOR_STRING( u"Synthetos (http://synthetos.com)" ) -MOTATE_SET_USB_PRODUCT_STRING( u"g2core gQuadratic" ) +MOTATE_SET_USB_VENDOR_STRING( u"Synthetos" ) +MOTATE_SET_USB_PRODUCT_STRING( u"TinyG v2" ) MOTATE_SET_USB_SERIAL_NUMBER_STRING_FROM_CHIPID() #endif // XIO_HAS_USB + //******** SPI ******** #if XIO_HAS_SPI Motate::SPI spi; diff --git a/g2core/board/Archim/board_xio.h b/g2core/board/Archim/board_xio.h index 102698d3..09f20fef 100755 --- a/g2core/board/Archim/board_xio.h +++ b/g2core/board/Archim/board_xio.h @@ -29,15 +29,25 @@ #ifndef board_xio_h #define board_xio_h +#include "settings.h" + //******** USB ******** #if XIO_HAS_USB #include "MotateUSB.h" #include "MotateUSBCDC.h" -// extern Motate::USBDevice< Motate::USBCDC > usb; -extern Motate::USBDevice usb; +#if USB_SERIAL_PORTS_EXPOSED == 1 +typedef Motate::USBDevice< Motate::USBCDC > XIOUSBDevice_t; +#endif +#if USB_SERIAL_PORTS_EXPOSED == 2 +typedef Motate::USBDevice XIOUSBDevice_t; +#endif + +extern XIOUSBDevice_t usb; extern decltype(usb.mixin<0>::Serial)& SerialUSB; +#if USB_SERIAL_PORTS_EXPOSED == 2 extern decltype(usb.mixin<1>::Serial)& SerialUSB1; +#endif #endif // XIO_HAS_USB diff --git a/g2core/board/ArduinoDue/board_xio.cpp b/g2core/board/ArduinoDue/board_xio.cpp index 04d9a326..7f2a0774 100755 --- a/g2core/board/ArduinoDue/board_xio.cpp +++ b/g2core/board/ArduinoDue/board_xio.cpp @@ -32,27 +32,31 @@ #include "board_xio.h" //******** USB ******** +#if XIO_HAS_USB const Motate::USBSettings_t Motate::USBSettings = { /*gVendorID = */ 0x1d50, /*gProductID = */ 0x606d, /*gProductVersion = */ G2CORE_FIRMWARE_VERSION, /*gAttributes = */ kUSBConfigAttributeSelfPowered, - /*gPowerConsumption = */ 500}; -/*gProductVersion = */ // 0.1, + /*gPowerConsumption = */ 500 +}; +/*gProductVersion = */ //0.1, -// Motate::USBDevice< Motate::USBCDC > usb; -Motate::USBDevice usb; +XIOUSBDevice_t usb; -decltype(usb.mixin<0>::Serial)& SerialUSB = usb.mixin<0>::Serial; -decltype(usb.mixin<1>::Serial)& SerialUSB1 = usb.mixin<1>::Serial; - -// 115200 is the default, as well. -// UART Serial {115200, UARTMode::RTSCTSFlowControl}; +extern decltype(usb.mixin<0>::Serial)& SerialUSB; +#if USB_SERIAL_PORTS_EXPOSED == 2 +extern decltype(usb.mixin<1>::Serial)& SerialUSB1; +#endif -MOTATE_SET_USB_VENDOR_STRING({'S', 'y', 'n', 't', 'h', 'e', 't', 'o', 's'}) -MOTATE_SET_USB_PRODUCT_STRING({'T', 'i', 'n', 'y', 'G', ' ', 'v', '2'}) +decltype(usb.mixin<0>::Serial) &SerialUSB = usb.mixin<0>::Serial; +//decltype(usb.mixin<1>::Serial) &SerialUSB1 = usb.mixin<1>::Serial; + +MOTATE_SET_USB_VENDOR_STRING( u"Synthetos" ) +MOTATE_SET_USB_PRODUCT_STRING( u"TinyG v2" ) MOTATE_SET_USB_SERIAL_NUMBER_STRING_FROM_CHIPID() +#endif // XIO_HAS_USB diff --git a/g2core/board/ArduinoDue/board_xio.h b/g2core/board/ArduinoDue/board_xio.h index a7bf7959..31afd8c8 100755 --- a/g2core/board/ArduinoDue/board_xio.h +++ b/g2core/board/ArduinoDue/board_xio.h @@ -29,15 +29,26 @@ #ifndef board_xio_h #define board_xio_h +#include "settings.h" + //******** USB ******** +#if XIO_HAS_USB #include "MotateUSB.h" #include "MotateUSBCDC.h" -// extern Motate::USBDevice< Motate::USBCDC > usb; -extern Motate::USBDevice usb; -extern decltype(usb.mixin<0>::Serial)& SerialUSB; -extern decltype(usb.mixin<1>::Serial)& SerialUSB1; +#if USB_SERIAL_PORTS_EXPOSED == 1 +typedef Motate::USBDevice< Motate::USBCDC > XIOUSBDevice_t; +#endif +#if USB_SERIAL_PORTS_EXPOSED == 2 +typedef Motate::USBDevice XIOUSBDevice_t; +#endif +extern XIOUSBDevice_t usb; +extern decltype(usb.mixin<0>::Serial)& SerialUSB; +#if USB_SERIAL_PORTS_EXPOSED == 2 +extern decltype(usb.mixin<1>::Serial)& SerialUSB1; +#endif +#endif // XIO_HAS_USB //******** SPI ******** diff --git a/g2core/board/G2v9/board_xio.cpp b/g2core/board/G2v9/board_xio.cpp index 04d9a326..09ccaf80 100755 --- a/g2core/board/G2v9/board_xio.cpp +++ b/g2core/board/G2v9/board_xio.cpp @@ -32,28 +32,31 @@ #include "board_xio.h" //******** USB ******** +#if XIO_HAS_USB const Motate::USBSettings_t Motate::USBSettings = { /*gVendorID = */ 0x1d50, /*gProductID = */ 0x606d, /*gProductVersion = */ G2CORE_FIRMWARE_VERSION, /*gAttributes = */ kUSBConfigAttributeSelfPowered, - /*gPowerConsumption = */ 500}; -/*gProductVersion = */ // 0.1, + /*gPowerConsumption = */ 500 +}; +/*gProductVersion = */ //0.1, -// Motate::USBDevice< Motate::USBCDC > usb; -Motate::USBDevice usb; +XIOUSBDevice_t usb; -decltype(usb.mixin<0>::Serial)& SerialUSB = usb.mixin<0>::Serial; -decltype(usb.mixin<1>::Serial)& SerialUSB1 = usb.mixin<1>::Serial; - -// 115200 is the default, as well. -// UART Serial {115200, UARTMode::RTSCTSFlowControl}; +extern decltype(usb.mixin<0>::Serial)& SerialUSB; +#if USB_SERIAL_PORTS_EXPOSED == 2 +extern decltype(usb.mixin<1>::Serial)& SerialUSB1; +#endif -MOTATE_SET_USB_VENDOR_STRING({'S', 'y', 'n', 't', 'h', 'e', 't', 'o', 's'}) -MOTATE_SET_USB_PRODUCT_STRING({'T', 'i', 'n', 'y', 'G', ' ', 'v', '2'}) +decltype(usb.mixin<0>::Serial) &SerialUSB = usb.mixin<0>::Serial; +//decltype(usb.mixin<1>::Serial) &SerialUSB1 = usb.mixin<1>::Serial; + +MOTATE_SET_USB_VENDOR_STRING( u"Synthetos" ) +MOTATE_SET_USB_PRODUCT_STRING( u"TinyG v2" ) MOTATE_SET_USB_SERIAL_NUMBER_STRING_FROM_CHIPID() - +#endif // XIO_HAS_USB //******** SPI ******** diff --git a/g2core/board/G2v9/board_xio.h b/g2core/board/G2v9/board_xio.h index a7bf7959..31afd8c8 100755 --- a/g2core/board/G2v9/board_xio.h +++ b/g2core/board/G2v9/board_xio.h @@ -29,15 +29,26 @@ #ifndef board_xio_h #define board_xio_h +#include "settings.h" + //******** USB ******** +#if XIO_HAS_USB #include "MotateUSB.h" #include "MotateUSBCDC.h" -// extern Motate::USBDevice< Motate::USBCDC > usb; -extern Motate::USBDevice usb; -extern decltype(usb.mixin<0>::Serial)& SerialUSB; -extern decltype(usb.mixin<1>::Serial)& SerialUSB1; +#if USB_SERIAL_PORTS_EXPOSED == 1 +typedef Motate::USBDevice< Motate::USBCDC > XIOUSBDevice_t; +#endif +#if USB_SERIAL_PORTS_EXPOSED == 2 +typedef Motate::USBDevice XIOUSBDevice_t; +#endif +extern XIOUSBDevice_t usb; +extern decltype(usb.mixin<0>::Serial)& SerialUSB; +#if USB_SERIAL_PORTS_EXPOSED == 2 +extern decltype(usb.mixin<1>::Serial)& SerialUSB1; +#endif +#endif // XIO_HAS_USB //******** SPI ******** diff --git a/g2core/board/gquadratic/board_xio.cpp b/g2core/board/gquadratic/board_xio.cpp index ff0846e1..8b4835b2 100755 --- a/g2core/board/gquadratic/board_xio.cpp +++ b/g2core/board/gquadratic/board_xio.cpp @@ -42,20 +42,23 @@ const Motate::USBSettings_t Motate::USBSettings = { }; /*gProductVersion = */ //0.1, -//Motate::USBDevice< Motate::USBCDC > usb; -Motate::USBDevice< Motate::USBCDC, Motate::USBCDC > usb; +XIOUSBDevice_t usb; + +extern decltype(usb.mixin<0>::Serial)& SerialUSB; +#if USB_SERIAL_PORTS_EXPOSED == 2 +extern decltype(usb.mixin<1>::Serial)& SerialUSB1; +#endif + decltype(usb.mixin<0>::Serial) &SerialUSB = usb.mixin<0>::Serial; -decltype(usb.mixin<1>::Serial) &SerialUSB1 = usb.mixin<1>::Serial; +//decltype(usb.mixin<1>::Serial) &SerialUSB1 = usb.mixin<1>::Serial; -// 115200 is the default, as well. -//UART Serial {115200, UARTMode::RTSCTSFlowControl}; - -MOTATE_SET_USB_VENDOR_STRING( u"Synthetos (http://synthetos.com)" ) -MOTATE_SET_USB_PRODUCT_STRING( u"g2core gQuadratic" ) +MOTATE_SET_USB_VENDOR_STRING( u"Synthetos" ) +MOTATE_SET_USB_PRODUCT_STRING( u"TinyG v2" ) MOTATE_SET_USB_SERIAL_NUMBER_STRING_FROM_CHIPID() #endif // XIO_HAS_USB + //******** SPI ******** #if XIO_HAS_SPI Motate::SPI spi; @@ -71,7 +74,7 @@ void board_hardware_init(void) // called 1st { #if XIO_HAS_USB // Init USB - usb.attach(); // USB setup. Runs in "background" as the rest of this executes + usb.attach(); #endif // XIO_HAS_USB } diff --git a/g2core/board/gquadratic/board_xio.h b/g2core/board/gquadratic/board_xio.h index 102698d3..09f20fef 100755 --- a/g2core/board/gquadratic/board_xio.h +++ b/g2core/board/gquadratic/board_xio.h @@ -29,15 +29,25 @@ #ifndef board_xio_h #define board_xio_h +#include "settings.h" + //******** USB ******** #if XIO_HAS_USB #include "MotateUSB.h" #include "MotateUSBCDC.h" -// extern Motate::USBDevice< Motate::USBCDC > usb; -extern Motate::USBDevice usb; +#if USB_SERIAL_PORTS_EXPOSED == 1 +typedef Motate::USBDevice< Motate::USBCDC > XIOUSBDevice_t; +#endif +#if USB_SERIAL_PORTS_EXPOSED == 2 +typedef Motate::USBDevice XIOUSBDevice_t; +#endif + +extern XIOUSBDevice_t usb; extern decltype(usb.mixin<0>::Serial)& SerialUSB; +#if USB_SERIAL_PORTS_EXPOSED == 2 extern decltype(usb.mixin<1>::Serial)& SerialUSB1; +#endif #endif // XIO_HAS_USB diff --git a/g2core/board/gquintic/board_xio.cpp b/g2core/board/gquintic/board_xio.cpp index 5f280380..8b4835b2 100755 --- a/g2core/board/gquintic/board_xio.cpp +++ b/g2core/board/gquintic/board_xio.cpp @@ -42,20 +42,23 @@ const Motate::USBSettings_t Motate::USBSettings = { }; /*gProductVersion = */ //0.1, -//Motate::USBDevice< Motate::USBCDC > usb; -Motate::USBDevice< Motate::USBCDC, Motate::USBCDC > usb; +XIOUSBDevice_t usb; + +extern decltype(usb.mixin<0>::Serial)& SerialUSB; +#if USB_SERIAL_PORTS_EXPOSED == 2 +extern decltype(usb.mixin<1>::Serial)& SerialUSB1; +#endif + decltype(usb.mixin<0>::Serial) &SerialUSB = usb.mixin<0>::Serial; -decltype(usb.mixin<1>::Serial) &SerialUSB1 = usb.mixin<1>::Serial; +//decltype(usb.mixin<1>::Serial) &SerialUSB1 = usb.mixin<1>::Serial; -// 115200 is the default, as well. -//UART Serial {115200, UARTMode::RTSCTSFlowControl}; - -MOTATE_SET_USB_VENDOR_STRING( {'S' ,'y', 'n', 't', 'h', 'e', 't', 'o', 's'} ) -MOTATE_SET_USB_PRODUCT_STRING( {'T', 'i', 'n', 'y', 'G', ' ', 'v', '2'} ) +MOTATE_SET_USB_VENDOR_STRING( u"Synthetos" ) +MOTATE_SET_USB_PRODUCT_STRING( u"TinyG v2" ) MOTATE_SET_USB_SERIAL_NUMBER_STRING_FROM_CHIPID() #endif // XIO_HAS_USB + //******** SPI ******** #if XIO_HAS_SPI Motate::SPI spi; @@ -71,7 +74,7 @@ void board_hardware_init(void) // called 1st { #if XIO_HAS_USB // Init USB - usb.attach(); // USB setup. Runs in "background" as the rest of this executes + usb.attach(); #endif // XIO_HAS_USB } diff --git a/g2core/board/gquintic/board_xio.h b/g2core/board/gquintic/board_xio.h index 102698d3..09f20fef 100755 --- a/g2core/board/gquintic/board_xio.h +++ b/g2core/board/gquintic/board_xio.h @@ -29,15 +29,25 @@ #ifndef board_xio_h #define board_xio_h +#include "settings.h" + //******** USB ******** #if XIO_HAS_USB #include "MotateUSB.h" #include "MotateUSBCDC.h" -// extern Motate::USBDevice< Motate::USBCDC > usb; -extern Motate::USBDevice usb; +#if USB_SERIAL_PORTS_EXPOSED == 1 +typedef Motate::USBDevice< Motate::USBCDC > XIOUSBDevice_t; +#endif +#if USB_SERIAL_PORTS_EXPOSED == 2 +typedef Motate::USBDevice XIOUSBDevice_t; +#endif + +extern XIOUSBDevice_t usb; extern decltype(usb.mixin<0>::Serial)& SerialUSB; +#if USB_SERIAL_PORTS_EXPOSED == 2 extern decltype(usb.mixin<1>::Serial)& SerialUSB1; +#endif #endif // XIO_HAS_USB diff --git a/g2core/board/printrboardg2/board_xio.cpp b/g2core/board/printrboardg2/board_xio.cpp index 2c217205..8b4835b2 100755 --- a/g2core/board/printrboardg2/board_xio.cpp +++ b/g2core/board/printrboardg2/board_xio.cpp @@ -32,6 +32,7 @@ #include "board_xio.h" //******** USB ******** +#if XIO_HAS_USB const Motate::USBSettings_t Motate::USBSettings = { /*gVendorID = */ 0x1d50, /*gProductID = */ 0x606d, @@ -41,18 +42,21 @@ const Motate::USBSettings_t Motate::USBSettings = { }; /*gProductVersion = */ //0.1, -//Motate::USBDevice< Motate::USBCDC > usb; -Motate::USBDevice< Motate::USBCDC, Motate::USBCDC > usb; +XIOUSBDevice_t usb; + +extern decltype(usb.mixin<0>::Serial)& SerialUSB; +#if USB_SERIAL_PORTS_EXPOSED == 2 +extern decltype(usb.mixin<1>::Serial)& SerialUSB1; +#endif + decltype(usb.mixin<0>::Serial) &SerialUSB = usb.mixin<0>::Serial; -decltype(usb.mixin<1>::Serial) &SerialUSB1 = usb.mixin<1>::Serial; - -// 115200 is the default, as well. -//UART Serial {115200, UARTMode::RTSCTSFlowControl}; +//decltype(usb.mixin<1>::Serial) &SerialUSB1 = usb.mixin<1>::Serial; MOTATE_SET_USB_VENDOR_STRING( u"Synthetos" ) MOTATE_SET_USB_PRODUCT_STRING( u"TinyG v2" ) MOTATE_SET_USB_SERIAL_NUMBER_STRING_FROM_CHIPID() +#endif // XIO_HAS_USB //******** SPI ******** @@ -68,8 +72,10 @@ Motate::UART usb; -extern Motate::USBDevice usb; -extern decltype(usb.mixin<0>::Serial)& SerialUSB; -extern decltype(usb.mixin<1>::Serial)& SerialUSB1; +#if USB_SERIAL_PORTS_EXPOSED == 1 +typedef Motate::USBDevice< Motate::USBCDC > XIOUSBDevice_t; +#endif +#if USB_SERIAL_PORTS_EXPOSED == 2 +typedef Motate::USBDevice XIOUSBDevice_t; +#endif +extern XIOUSBDevice_t usb; +extern decltype(usb.mixin<0>::Serial)& SerialUSB; +#if USB_SERIAL_PORTS_EXPOSED == 2 +extern decltype(usb.mixin<1>::Serial)& SerialUSB1; +#endif +#endif // XIO_HAS_USB //******** SPI ******** #if XIO_HAS_SPI diff --git a/g2core/board/sbv300/board_xio.cpp b/g2core/board/sbv300/board_xio.cpp index 712a89e9..8b4835b2 100755 --- a/g2core/board/sbv300/board_xio.cpp +++ b/g2core/board/sbv300/board_xio.cpp @@ -32,6 +32,7 @@ #include "board_xio.h" //******** USB ******** +#if XIO_HAS_USB const Motate::USBSettings_t Motate::USBSettings = { /*gVendorID = */ 0x1d50, /*gProductID = */ 0x606d, @@ -41,20 +42,21 @@ const Motate::USBSettings_t Motate::USBSettings = { }; /*gProductVersion = */ //0.1, -//Motate::USBDevice< Motate::USBCDC > usb; -Motate::USBDevice< Motate::USBCDC, Motate::USBCDC > usb; +XIOUSBDevice_t usb; + +extern decltype(usb.mixin<0>::Serial)& SerialUSB; +#if USB_SERIAL_PORTS_EXPOSED == 2 +extern decltype(usb.mixin<1>::Serial)& SerialUSB1; +#endif + decltype(usb.mixin<0>::Serial) &SerialUSB = usb.mixin<0>::Serial; -decltype(usb.mixin<1>::Serial) &SerialUSB1 = usb.mixin<1>::Serial; +//decltype(usb.mixin<1>::Serial) &SerialUSB1 = usb.mixin<1>::Serial; -// 115200 is the default, as well. -//UART Serial {115200, UARTMode::RTSCTSFlowControl}; - - -MOTATE_SET_USB_VENDOR_STRING( {'S' ,'y', 'n', 't', 'h', 'e', 't', 'o', 's'} ) -MOTATE_SET_USB_PRODUCT_STRING( {'T', 'i', 'n', 'y', 'G', ' ', 'v', '2'} ) +MOTATE_SET_USB_VENDOR_STRING( u"Synthetos" ) +MOTATE_SET_USB_PRODUCT_STRING( u"TinyG v2" ) MOTATE_SET_USB_SERIAL_NUMBER_STRING_FROM_CHIPID() - +#endif // XIO_HAS_USB //******** SPI ******** @@ -65,25 +67,26 @@ Motate::SPI spi; //******** UART ******** #if XIO_HAS_UART -Motate::UART Serial{ - 115200, Motate::UARTMode::RTSCTSFlowControl}; +Motate::UART Serial {115200, Motate::UARTMode::RTSCTSFlowControl}; #endif -void board_hardware_init(void) // called 1st +void board_hardware_init(void) // called 1st { +#if XIO_HAS_USB // Init USB - usb.attach(); // USB setup. Runs in "background" as the rest of this executes + usb.attach(); +#endif // XIO_HAS_USB } -void board_xio_init(void) // called later than board_hardware_init (there are thing in between) +void board_xio_init(void) // called later than board_hardware_init (there are thing in between) { -// Init SPI + // Init SPI #if XIO_HAS_SPI -// handled internally for now + // handled internally for now #endif -// Init UART + // Init UART #if XIO_HAS_UART Serial.init(); #endif diff --git a/g2core/board/sbv300/board_xio.h b/g2core/board/sbv300/board_xio.h index 40b42a09..6bc4421f 100755 --- a/g2core/board/sbv300/board_xio.h +++ b/g2core/board/sbv300/board_xio.h @@ -29,28 +29,38 @@ #ifndef board_xio_h #define board_xio_h +#include "settings.h" + //******** USB ******** +#if XIO_HAS_USB #include "MotateUSB.h" #include "MotateUSBCDC.h" -// extern Motate::USBDevice< Motate::USBCDC > usb; -extern Motate::USBDevice usb; +#if USB_SERIAL_PORTS_EXPOSED == 1 +typedef Motate::USBDevice< Motate::USBCDC > XIOUSBDevice_t; +#endif +#if USB_SERIAL_PORTS_EXPOSED == 2 +typedef Motate::USBDevice XIOUSBDevice_t; +#endif + +extern XIOUSBDevice_t usb; extern decltype(usb.mixin<0>::Serial)& SerialUSB; +#if USB_SERIAL_PORTS_EXPOSED == 2 extern decltype(usb.mixin<1>::Serial)& SerialUSB1; - - +#endif +#endif // XIO_HAS_USB //******** SPI ******** -//#include "MotateSPI.h" -// extern Motate::SPI spi; - - +#if XIO_HAS_SPI +#include "MotateSPI.h" +extern Motate::SPI spi; +#endif //******** UART ******** -//#include "MotateUART.h" -// extern Motate::UART Serial; - - +#if XIO_HAS_UART +#include "MotateUART.h" +extern Motate::UART Serial; +#endif //******* Generic Functions ******* void board_hardware_init(void); // called 1st diff --git a/g2core/settings/settings_default.h b/g2core/settings/settings_default.h index 233346c3..e0566ae7 100755 --- a/g2core/settings/settings_default.h +++ b/g2core/settings/settings_default.h @@ -58,6 +58,11 @@ // *** Machine configuration settings *** // +#ifndef USB_SERIAL_PORTS_EXPOSED +#define USB_SERIAL_PORTS_EXPOSED 1 // Valid options are 1 or 2, only! +#endif + + #ifndef JUNCTION_INTEGRATION_TIME #define JUNCTION_INTEGRATION_TIME 0.75 // {jt: cornering - between 0.05 and 2.00 (max) #endif diff --git a/g2core/xio.cpp b/g2core/xio.cpp index d2dd2261..e1ce0b53 100755 --- a/g2core/xio.cpp +++ b/g2core/xio.cpp @@ -38,6 +38,7 @@ #include "report.h" #include "controller.h" #include "util.h" +#include "settings.h" #include "board_xio.h" @@ -949,10 +950,12 @@ xioDeviceWrapper serialUSB0Wrapper { &SerialUSB, (DEV_CAN_READ | DEV_CAN_WRITE | DEV_CAN_BE_CTRL | DEV_CAN_BE_DATA) }; +#if USB_SERIAL_PORTS_EXPOSED == 2 xioDeviceWrapper serialUSB1Wrapper { &SerialUSB1, (DEV_CAN_READ | DEV_CAN_WRITE | DEV_CAN_BE_CTRL | DEV_CAN_BE_DATA) }; +#endif #endif // XIO_HAS_USB #if XIO_HAS_UART==1 xioDeviceWrapper serial0Wrapper { @@ -966,7 +969,9 @@ xioDeviceWrapper serial0Wrapper { xio_t xio = { #if XIO_HAS_USB == 1 &serialUSB0Wrapper, +#if USB_SERIAL_PORTS_EXPOSED == 2 &serialUSB1Wrapper, +#endif #endif // XIO_HAS_USB #if XIO_HAS_UART == 1 &serial0Wrapper @@ -994,8 +999,10 @@ void xio_init() #if XIO_HAS_USB == 1 serialUSB0Wrapper.init(); +#if USB_SERIAL_PORTS_EXPOSED == 2 serialUSB1Wrapper.init(); #endif +#endif #if XIO_HAS_UART == 1 serial0Wrapper.init(); #endif From b3dfae30293dff303900cfa7fd0e1f40b9a0ee98 Mon Sep 17 00:00:00 2001 From: Rob Giseburt Date: Wed, 7 Dec 2016 11:33:08 -0600 Subject: [PATCH 75/98] Upped Printrbot Simple 1608 JUNCTION_INTEGRATION_TIME to 1.15 --- g2core/settings/settings_Printrbot_Simple_1608.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/g2core/settings/settings_Printrbot_Simple_1608.h b/g2core/settings/settings_Printrbot_Simple_1608.h index a9a29d4f..d9c71c28 100755 --- a/g2core/settings/settings_Printrbot_Simple_1608.h +++ b/g2core/settings/settings_Printrbot_Simple_1608.h @@ -39,7 +39,7 @@ //**** GLOBAL / GENERAL SETTINGS ****************************************************** -#define JUNCTION_INTEGRATION_TIME 1.05 // cornering - between 0.10 and 2.00 (higher is faster) +#define JUNCTION_INTEGRATION_TIME 1.15 // cornering - between 0.10 and 2.00 (higher is faster) #define CHORDAL_TOLERANCE 0.01 // chordal accuracy for arc drawing (in mm) #define SOFT_LIMIT_ENABLE 0 // 0=off, 1=on From b4f29e79bf369a98a02fcfd801fc6660d0b6c787 Mon Sep 17 00:00:00 2001 From: Rob Giseburt Date: Wed, 7 Dec 2016 11:39:08 -0600 Subject: [PATCH 76/98] Updated motate reference (more expressive Dummy_Handler names) --- Motate | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Motate b/Motate index 652a52c9..79c8bcf6 160000 --- a/Motate +++ b/Motate @@ -1 +1 @@ -Subproject commit 652a52c95f4f434bd2940a2a666970ea5f6c2fbc +Subproject commit 79c8bcf69f440a592ab96eaef306a76b97c69707 From b221559bd649a35bf4d30eba603bd890be5056a1 Mon Sep 17 00:00:00 2001 From: Rob Giseburt Date: Wed, 7 Dec 2016 12:13:46 -0600 Subject: [PATCH 77/98] Update Motate reference for USB initialization fixes. --- Motate | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Motate b/Motate index 79c8bcf6..5f87eabb 160000 --- a/Motate +++ b/Motate @@ -1 +1 @@ -Subproject commit 79c8bcf69f440a592ab96eaef306a76b97c69707 +Subproject commit 5f87eabbb50a00a0a81e06c541c3943104bc0487 From 50ceb39b1cd4fe9ef53bb605f9aa78d17f226fe6 Mon Sep 17 00:00:00 2001 From: Rob Giseburt Date: Wed, 7 Dec 2016 16:51:19 -0600 Subject: [PATCH 78/98] Update Motate to get new SysTickEvent::deregister --- Motate | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Motate b/Motate index 5f87eabb..18c93112 160000 --- a/Motate +++ b/Motate @@ -1 +1 @@ -Subproject commit 5f87eabbb50a00a0a81e06c541c3943104bc0487 +Subproject commit 18c93112f1e1e13eb0fa740e185c4b973e4419fc From 650aea05fec3b2abd00579382b7a9d022b113696 Mon Sep 17 00:00:00 2001 From: Rob Giseburt Date: Wed, 7 Dec 2016 16:51:52 -0600 Subject: [PATCH 79/98] Changed Dwells (again) to use SysTickEvents instead of the DDA timer. --- g2core/stepper.cpp | 43 +++++++++++++++++++------------------------ g2core/stepper.h | 7 ++++--- 2 files changed, 23 insertions(+), 27 deletions(-) diff --git a/g2core/stepper.cpp b/g2core/stepper.cpp index bb765422..0413af71 100644 --- a/g2core/stepper.cpp +++ b/g2core/stepper.cpp @@ -80,6 +80,15 @@ load_timer_type load_timer; // triggers load of next stepper segment exec_timer_type exec_timer; // triggers calculation of next+1 stepper segment fwd_plan_timer_type fwd_plan_timer; // triggers planning of next block +// SystickEvent for handling dweels (must be registered before it is active) +Motate::SysTickEvent dwell_systick_event {[&] { + if (--st_run.dwell_ticks_downcount == 0) { + SysTickTimer.unregisterEvent(&dwell_systick_event); + _load_move(); // load the next move at the current interrupt level + } +}, nullptr}; + + /************************************************************************************ **** CODE ************************************************************************** ************************************************************************************/ @@ -145,6 +154,7 @@ void stepper_reset() { dda_timer.stop(); // stop all movement st_run.dda_ticks_downcount = 0; // signal the runtime is not busy + st_run.dwell_ticks_downcount = 0; st_pre.buffer_state = PREP_BUFFER_OWNED_BY_EXEC; // set to EXEC or it won't restart for (uint8_t motor=0; motor 2) - st_run.mot[MOTOR_3].substep_accumulator = 0; -#endif -#if (MOTORS > 3) - st_run.mot[MOTOR_4].substep_accumulator = 0; -#endif -#if (MOTORS > 4) - st_run.mot[MOTOR_5].substep_accumulator = 0; -#endif -#if (MOTORS > 5) - st_run.mot[MOTOR_6].substep_accumulator = 0; -#endif + st_run.dwell_ticks_downcount = st_pre.dwell_ticks; - //**** do this last **** - // Note: we are using the dda timer for the dwells (we didn't always) - dda_timer.start(); // start the DDA timer if not already running + // We now use SysTick events to handle dwells + SysTickTimer.registerEvent(&dwell_systick_event); - // handle synchronous commands + // handle synchronous commands } else if (st_pre.block_type == BLOCK_TYPE_COMMAND) { mp_runtime_command(st_pre.bf); - + } // else null - which is okay in many cases // all other cases drop to here (e.g. Null moves after Mcodes skip to here) @@ -782,8 +777,8 @@ void st_prep_command(void *bf) void st_prep_dwell(float microseconds) { st_pre.block_type = BLOCK_TYPE_DWELL; - // Note: we are using the dda timer for the dwells (we didn't always) - st_pre.dda_ticks = (uint32_t)((microseconds/1000000) * FREQUENCY_DDA); + // we need dwell_ticks to be at least 1 + st_pre.dwell_ticks = std::max((uint32_t)((microseconds/1000000) * FREQUENCY_DWELL), 1UL); st_pre.buffer_state = PREP_BUFFER_OWNED_BY_LOADER; // signal that prep buffer is ready } diff --git a/g2core/stepper.h b/g2core/stepper.h index b8b22b78..5711c1c4 100644 --- a/g2core/stepper.h +++ b/g2core/stepper.h @@ -381,7 +381,8 @@ typedef struct stRunMotor { // one per controlled motor typedef struct stRunSingleton { // Stepper static values and axis parameters magic_t magic_start; // magic number to test memory integrity - uint32_t dda_ticks_downcount; // tick down-counter (unscaled) + uint32_t dda_ticks_downcount; // dda tick down-counter (unscaled) + uint32_t dwell_ticks_downcount; // dwell tick down-counter (unscaled) uint32_t dda_ticks_X_substeps; // ticks multiplied by scaling factor stRunMotor_t mot[MOTORS]; // runtime motor structures magic_t magic_end; @@ -415,8 +416,8 @@ typedef struct stPrepSingleton { struct mpBuffer *bf; // static pointer to relevant buffer blockType block_type; // move type (requires planner.h) - //uint16_t dda_period; // DDA or dwell clock period setting (No longer used) - uint32_t dda_ticks; // DDA or dwell ticks for the move + uint32_t dda_ticks; // DDA ticks for the move + uint32_t dwell_ticks; // dwell ticks remaining uint32_t dda_ticks_X_substeps; // DDA ticks scaled by substep factor stPrepMotor_t mot[MOTORS]; // prep time motor structs magic_t magic_end; From 7b0671f3fda91d76321558ad6d06eca1c0c2df40 Mon Sep 17 00:00:00 2001 From: Rob Giseburt Date: Wed, 7 Dec 2016 16:52:20 -0600 Subject: [PATCH 80/98] =?UTF-8?q?Monor=20cleanup=20in=20XIO=20of=20?= =?UTF-8?q?=E2=80=9C!\n=E2=80=9D=20and=20=E2=80=9C~\n=E2=80=9D=20handling.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- g2core/xio.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/g2core/xio.cpp b/g2core/xio.cpp index e1ce0b53..cc9dc874 100755 --- a/g2core/xio.cpp +++ b/g2core/xio.cpp @@ -612,6 +612,14 @@ struct LineRXBuffer : RXBuffer<_size, owner_type, char> { } if (is_control) { // we found a control + // Quick check for single-character with a \n after it + while (_is_more_to_scan() && + ((_data[_scan_offset] == '\n') || + (_data[_scan_offset] == '\r')) + ) + { + _scan_offset = _get_next_scan_offset(); + } return true; } else { // we did find one more line, though. _lines_found++; @@ -682,6 +690,9 @@ struct LineRXBuffer : RXBuffer<_size, owner_type, char> { _line_start_offset = (_line_start_offset+1)&(_size-1); } + // null-terminate the string + *dst_ptr = 0; + if (ctrl_is_at_beginning_of_data) { _read_offset = _scan_offset; } else { @@ -781,6 +792,7 @@ struct LineRXBuffer : RXBuffer<_size, owner_type, char> { _restartTransfer(); + // null-terminate the string *dst_ptr = 0; return _line_buffer; }; // readline From f2f6d9dc7a85b59cc3f018bcfc80481e440363ba Mon Sep 17 00:00:00 2001 From: Rob Giseburt Date: Wed, 7 Dec 2016 17:33:26 -0600 Subject: [PATCH 81/98] Fix g2v9 not connection over USB --- g2core/board/G2v9/board_xio.h | 5 +- g2core/board/G2v9/hardware.cpp | 1 + g2core/settings/settings_shapeoko375_Dual.h | 256 ++++++++++++++++++++ 3 files changed, 259 insertions(+), 3 deletions(-) create mode 100644 g2core/settings/settings_shapeoko375_Dual.h diff --git a/g2core/board/G2v9/board_xio.h b/g2core/board/G2v9/board_xio.h index 31afd8c8..09f20fef 100755 --- a/g2core/board/G2v9/board_xio.h +++ b/g2core/board/G2v9/board_xio.h @@ -63,9 +63,8 @@ extern Motate::SPI spi; extern Motate::UART Serial; #endif - - //******* Generic Functions ******* -void board_xio_init(void); +void board_hardware_init(void); // called 1st +void board_xio_init(void); // called later #endif // board_xio_h diff --git a/g2core/board/G2v9/hardware.cpp b/g2core/board/G2v9/hardware.cpp index 580ed646..45d63c37 100755 --- a/g2core/board/G2v9/hardware.cpp +++ b/g2core/board/G2v9/hardware.cpp @@ -43,6 +43,7 @@ void hardware_init() { + board_hardware_init(); return; } diff --git a/g2core/settings/settings_shapeoko375_Dual.h b/g2core/settings/settings_shapeoko375_Dual.h new file mode 100644 index 00000000..b787d58c --- /dev/null +++ b/g2core/settings/settings_shapeoko375_Dual.h @@ -0,0 +1,256 @@ +/* + * settings_shapeoko375.h - Shapeoko 375mm table + * This file is part of the TinyG project + * + * Copyright (c) 2010 - 2014 Alden S. Hart, Jr. + * + * This file ("the software") is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2 as published by the + * Free Software Foundation. You should have received a copy of the GNU General Public + * License, version 2 along with the software. If not, see . + * + * As a special exception, you may use this file as part of a software library without + * restriction. Specifically, if other files instantiate templates or use macros or + * inline functions from this file, or you compile this file and link it with other + * files to produce an executable, this file does not by itself cause the resulting + * executable to be covered by the GNU General Public License. This exception does not + * however invalidate any other reasons why the executable file might be covered by the + * GNU General Public License. + * + * THE SOFTWARE IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT WITHOUT ANY + * WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT + * SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +/* Note: The values in this file are the default settings that are loaded + * into a virgin EEPROM, and can be changed using the config commands. + * After initial load the EEPROM values (or changed values) are used. + * + * System and hardware settings that you shouldn't need to change + * are in system.h Application settings that also shouldn't need + * to be changed are in tinyg.h + */ + +/***********************************************************************/ +/**** Shapeoko 375mm profile *******************************************/ +/***********************************************************************/ + +// ***> NOTE: The init message must be a single line with no CRs or LFs +#define INIT_MESSAGE "Initializing configs to Shapeoko 375mm Dual-Y profile" + +//**** GLOBAL / GENERAL SETTINGS ****************************************************** + +// Machine configuration settings + +#define JUNCTION_INTEGRATION_TIME 0.75 // cornering - between 0.10 and 2.00 (higher is faster) +#define CHORDAL_TOLERANCE 0.01 // chordal tolerance for arcs (in mm) + +#define SOFT_LIMIT_ENABLE 0 // 0=off, 1=on +#define HARD_LIMIT_ENABLE 0 // 0=off, 1=on +#define SAFETY_INTERLOCK_ENABLE 1 // 0=off, 1=on + +#define SPINDLE_ENABLE_POLARITY 1 // 0=active low, 1=active high +#define SPINDLE_DIR_POLARITY 0 // 0=clockwise is low, 1=clockwise is high +#define SPINDLE_PAUSE_ON_HOLD true +#define SPINDLE_DWELL_TIME 1.0 + +#define COOLANT_MIST_POLARITY 1 // 0=active low, 1=active high +#define COOLANT_FLOOD_POLARITY 1 // 0=active low, 1=active high +#define COOLANT_PAUSE_ON_HOLD false + +// Communications and reporting settings + +#define COMM_MODE JSON_MODE // one of: TEXT_MODE, JSON_MODE +#define XIO_ENABLE_FLOW_CONTROL FLOW_CONTROL_RTS // FLOW_CONTROL_OFF, FLOW_CONTROL_RTS + +#define TEXT_VERBOSITY TV_VERBOSE // one of: TV_SILENT, TV_VERBOSE +#define JSON_VERBOSITY JV_MESSAGES // one of: JV_SILENT, JV_FOOTER, JV_CONFIGS, JV_MESSAGES, JV_LINENUM, JV_VERBOSE +#define QUEUE_REPORT_VERBOSITY QR_OFF // one of: QR_OFF, QR_SINGLE, QR_TRIPLE + +#define STATUS_REPORT_VERBOSITY SR_FILTERED // one of: SR_OFF, SR_FILTERED, SR_VERBOSE + +#define STATUS_REPORT_MIN_MS 100 // milliseconds - enforces a viable minimum +#define STATUS_REPORT_INTERVAL_MS 250 // milliseconds - set $SV=0 to disable + +//#define STATUS_REPORT_DEFAULTS "line","posx","posy","posz","posa","bcr","feed","vel","unit","coor","dist","admo","frmo","momo","stat" +#define STATUS_REPORT_DEFAULTS "line","posx","posy","posz","bcr","feed","vel","momo","stat" + +// Alternate SRs that report in drawable units +//#define STATUS_REPORT_DEFAULTS "line","vel","mpox","mpoy","mpoz","mpoa","coor","ofsa","ofsx","ofsy","ofsz","dist","unit","stat","homz","homy","homx","momo" +//#define STATUS_REPORT_DEFAULTS "_ts1","_cs1","_es1","_xs1","_fe1","line","posx","posy","posz","vel","stat" + +// Gcode startup defaults +#define GCODE_DEFAULT_UNITS MILLIMETERS // MILLIMETERS or INCHES +#define GCODE_DEFAULT_PLANE CANON_PLANE_XY // CANON_PLANE_XY, CANON_PLANE_XZ, or CANON_PLANE_YZ +#define GCODE_DEFAULT_COORD_SYSTEM G54 // G54, G55, G56, G57, G58 or G59 +#define GCODE_DEFAULT_PATH_CONTROL PATH_CONTINUOUS +#define GCODE_DEFAULT_DISTANCE_MODE ABSOLUTE_MODE + + +// *** motor settings ************************************************************************************ + +#define MOTOR_POWER_MODE MOTOR_POWERED_IN_CYCLE // default motor power mode (see cmMotorPowerMode in stepper.h) +#define MOTOR_POWER_TIMEOUT 20.00 // motor power timeout in seconds + +// *** motor settings *** + +/* Mapping for dual gantry setup */ +#define M1_MOTOR_MAP AXIS_X // 1ma +#define M1_STEP_ANGLE 1.8 // 1sa +#define M1_TRAVEL_PER_REV 36.54 // 1tr +#define M1_MICROSTEPS 32 // 1mi 1,2,4,8 +#define M1_POLARITY 0 // 1po 0=normal, 1=reversed +#define M1_POWER_MODE MOTOR_POWER_MODE // 1pm TRUE=low power idle enabled +#define M1_POWER_LEVEL 0.6 + +#define M2_MOTOR_MAP AXIS_Y +#define M2_STEP_ANGLE 1.8 +#define M2_TRAVEL_PER_REV 36.54 +#define M2_MICROSTEPS 32 +#define M2_POLARITY 1 +#define M2_POWER_MODE MOTOR_POWER_MODE +#define M2_POWER_LEVEL 0.6 + +#define M3_MOTOR_MAP AXIS_Y +#define M3_STEP_ANGLE 1.8 +#define M3_TRAVEL_PER_REV 36.54 +#define M3_MICROSTEPS 32 +#define M3_POLARITY 0 +#define M3_POWER_MODE MOTOR_POWER_MODE +#define M3_POWER_LEVEL 0.6 + +#define M4_MOTOR_MAP AXIS_Z +#define M4_STEP_ANGLE 1.8 +#define M4_TRAVEL_PER_REV 1.25 +#define M4_MICROSTEPS 32 +#define M4_POLARITY 0 +#define M4_POWER_MODE MOTOR_POWER_MODE +#define M4_POWER_LEVEL 0.5 + +// *** axis settings ********************************************************************************** + + +#define X_AXIS_MODE AXIS_STANDARD // xam see canonical_machine.h cmAxisMode for valid values +#define X_VELOCITY_MAX 16000 // xvm G0 max velocity in mm/min +#define X_FEEDRATE_MAX X_VELOCITY_MAX // xfr G1 max feed rate in mm/min +#define X_TRAVEL_MIN 0 // xtn minimum travel - used by soft limits and homing +#define X_TRAVEL_MAX 220 // xtm maximum travel - used by soft limits and homing +#define X_JERK_MAX 5000 // xjm yes, that's "5 billion" mm/(min^3) +#define X_JERK_HIGH_SPEED X_JERK_MAX // xjh +#define X_HOMING_INPUT 1 // xhi input used for homing or 0 to disable +#define X_HOMING_DIR 0 // xhd 0 to search to minimum, 1 to search to maximum +#define X_SEARCH_VELOCITY 3000 // xsv minus means move to minimum switch +#define X_LATCH_VELOCITY 100 // xlv mm/min +#define X_LATCH_BACKOFF 4 // xlb mm +#define X_ZERO_BACKOFF 0.5 // xzb mm + +#define Y_AXIS_MODE AXIS_STANDARD +#define Y_VELOCITY_MAX 16000 +#define Y_FEEDRATE_MAX Y_VELOCITY_MAX +#define Y_TRAVEL_MIN 0 +#define Y_TRAVEL_MAX 220 +#define Y_JERK_MAX 5000 +#define Y_JERK_HIGH_SPEED Y_JERK_MAX +#define Y_HOMING_INPUT 3 +#define Y_HOMING_DIR 0 +#define Y_SEARCH_VELOCITY 3000 +#define Y_LATCH_VELOCITY 100 +#define Y_LATCH_BACKOFF 4 +#define Y_ZERO_BACKOFF 0.5 + +#define Z_AXIS_MODE AXIS_STANDARD +#define Z_VELOCITY_MAX 300 +#define Z_FEEDRATE_MAX Z_VELOCITY_MAX +#define Z_TRAVEL_MIN 0 +#define Z_TRAVEL_MAX 100 +#define Z_JERK_MAX 25 // 50,000,000 +#define Z_JERK_HIGH_SPEED Z_JERK_MAX +#define Z_HOMING_INPUT 5 +#define Z_HOMING_DIR 0 +#define Z_SEARCH_VELOCITY Z_VELOCITY_MAX +#define Z_LATCH_VELOCITY 100 +#define Z_LATCH_BACKOFF 4 +#define Z_ZERO_BACKOFF 0.5 + +//*** Input / output settings *** +/* + IO_MODE_DISABLED + IO_ACTIVE_LOW aka NORMALLY_OPEN + IO_ACTIVE_HIGH aka NORMALLY_CLOSED + + INPUT_ACTION_NONE + INPUT_ACTION_STOP + INPUT_ACTION_FAST_STOP + INPUT_ACTION_HALT + INPUT_ACTION_RESET + + INPUT_FUNCTION_NONE + INPUT_FUNCTION_LIMIT + INPUT_FUNCTION_INTERLOCK + INPUT_FUNCTION_SHUTDOWN + INPUT_FUNCTION_PANIC + */ +// Xmin on v9 board +#define DI1_MODE NORMALLY_CLOSED +//#define DI1_ACTION INPUT_ACTION_STOP +#define DI1_ACTION INPUT_ACTION_NONE +#define DI1_FUNCTION INPUT_FUNCTION_LIMIT + +// Xmax +#define DI2_MODE NORMALLY_CLOSED +//#define DI2_ACTION INPUT_ACTION_STOP +#define DI2_ACTION INPUT_ACTION_NONE +#define DI2_FUNCTION INPUT_FUNCTION_LIMIT + +// Ymin +#define DI3_MODE NORMALLY_CLOSED +//#define DI3_ACTION INPUT_ACTION_STOP +#define DI3_ACTION INPUT_ACTION_NONE +#define DI3_FUNCTION INPUT_FUNCTION_LIMIT + +// Ymax +#define DI4_MODE NORMALLY_CLOSED +//#define DI4_ACTION INPUT_ACTION_STOP +#define DI4_ACTION INPUT_ACTION_NONE +#define DI4_FUNCTION INPUT_FUNCTION_LIMIT + +// Zmin +#define DI5_MODE IO_ACTIVE_HIGH // Z probe +#define DI5_ACTION INPUT_ACTION_NONE +#define DI5_FUNCTION INPUT_FUNCTION_NONE + +// Zmax +#define DI6_MODE NORMALLY_CLOSED +//#define DI6_ACTION INPUT_ACTION_STOP +#define DI6_ACTION INPUT_ACTION_NONE +#define DI6_FUNCTION INPUT_FUNCTION_LIMIT + +// Amin +#define DI7_MODE IO_MODE_DISABLED +#define DI7_ACTION INPUT_ACTION_NONE +#define DI7_FUNCTION INPUT_FUNCTION_NONE + +// Amax +#define DI8_MODE IO_MODE_DISABLED +#define DI8_ACTION INPUT_ACTION_NONE +#define DI8_FUNCTION INPUT_FUNCTION_NONE + +// Hardware interlock input +#define DI9_MODE IO_MODE_DISABLED +#define DI9_ACTION INPUT_ACTION_NONE +#define DI9_FUNCTION INPUT_FUNCTION_NONE + +// *** PWM SPINDLE CONTROL *** + +#define P1_PWM_FREQUENCY 5000 // in Hz +#define P1_CW_SPEED_LO 3000 // in RPM (arbitrary units) +#define P1_CW_SPEED_HI 12000 +#define P1_CW_PHASE_LO 0.15 // phase [0..1] +#define P1_CW_PHASE_HI 0.81 +#define P1_CCW_SPEED_LO 0 +#define P1_CCW_SPEED_HI 0 +#define P1_CCW_PHASE_LO 0.1 +#define P1_CCW_PHASE_HI 0.1 +#define P1_PWM_PHASE_OFF 0.0 From d6fdfa7c76207eddb92785bc936e400910b8981a Mon Sep 17 00:00:00 2001 From: Rob Giseburt Date: Thu, 8 Dec 2016 12:06:06 -0600 Subject: [PATCH 82/98] Xcode project update (settings folder is now a reference) --- g2core/g2core.xcodeproj/project.pbxproj | 44 ++----------------------- 1 file changed, 2 insertions(+), 42 deletions(-) diff --git a/g2core/g2core.xcodeproj/project.pbxproj b/g2core/g2core.xcodeproj/project.pbxproj index e4d1864c..670d7df0 100644 --- a/g2core/g2core.xcodeproj/project.pbxproj +++ b/g2core/g2core.xcodeproj/project.pbxproj @@ -53,13 +53,12 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + D41997401DF9D6A800E0FB51 /* settings */ = {isa = PBXFileReference; lastKnownFileType = folder; path = settings; sourceTree = ""; }; D43FF6F51D52C8AF00FB5B53 /* board */ = {isa = PBXFileReference; lastKnownFileType = folder; path = board; sourceTree = ""; }; D44E72C01D663B0300ECD5DD /* coolant.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = coolant.cpp; sourceTree = ""; }; D44E72C21D663B0F00ECD5DD /* coolant.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = coolant.h; sourceTree = ""; }; D4522DC91C45F41D0086AAE6 /* g2core_info.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = g2core_info.h; sourceTree = ""; }; D457117B17053EFA00EA19A8 /* Makefile */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = Makefile; sourceTree = ""; usesTabs = 1; xcLanguageSpecificationIdentifier = xcode.lang.sh; }; - D4782AB21D9B5F9400B32136 /* settings_watercolorbot_v2.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = settings_watercolorbot_v2.h; sourceTree = ""; }; - D4782AB41D9E2FF300B32136 /* settings_eggbot.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = settings_eggbot.h; sourceTree = ""; }; D47B744C1D4925B4004FAB53 /* device */ = {isa = PBXFileReference; lastKnownFileType = folder; path = device; sourceTree = ""; }; D48F5A40172CB1F900D0E055 /* canonical_machine.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = canonical_machine.cpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; D48F5A41172CB1F900D0E055 /* config_app.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = config_app.cpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; @@ -100,25 +99,10 @@ D48F5A7F172CB21100D0E055 /* g2core.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = g2core.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; D48F5A80172CB21100D0E055 /* util.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = util.h; sourceTree = ""; }; D48F5A81172CB21100D0E055 /* xio.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = xio.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; - D49177A11D21CFC50029CDEB /* settings_Printrbot_Simple_1403.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = settings_Printrbot_Simple_1403.h; sourceTree = ""; }; - D49177A21D21CFDB0029CDEB /* settings_Printrbot_Simple_1608.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = settings_Printrbot_Simple_1608.h; sourceTree = ""; }; D4922F3F1CB8361B00A565FF /* boards.mk */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = boards.mk; sourceTree = ""; }; D49367D71B87CA8A000BB759 /* temperature.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = temperature.cpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; D49367D81B87CA8A000BB759 /* temperature.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = temperature.h; sourceTree = ""; }; D49367DB1B8E0AF1000BB759 /* error.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = error.h; sourceTree = ""; }; - D4AC39081C77C1F20098D685 /* settings_default.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = settings_default.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; - D4AC39091C77C1F20098D685 /* settings_makeblock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = settings_makeblock.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; - D4AC390A1C77C1F20098D685 /* settings_othermill_test.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = settings_othermill_test.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; - D4AC390B1C77C1F20098D685 /* settings_othermill.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = settings_othermill.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; - D4AC390C1C77C1F20098D685 /* settings_Printrbot_Play.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = settings_Printrbot_Play.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; - D4AC390D1C77C1F20098D685 /* settings_Printrbot_Plus.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = settings_Printrbot_Plus.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; - D4AC390F1C77C1F20098D685 /* settings_probotixV90.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = settings_probotixV90.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; - D4AC39101C77C1F20098D685 /* settings_shapeoko2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = settings_shapeoko2.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; - D4AC39111C77C1F20098D685 /* settings_shopbot_sbv300.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = settings_shopbot_sbv300.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; - D4AC39121C77C1F20098D685 /* settings_shopbot_test.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = settings_shopbot_test.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; - D4AC39131C77C1F20098D685 /* settings_test.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = settings_test.h; sourceTree = ""; }; - D4AC39141C77C1F20098D685 /* settings_Ultimaker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = settings_Ultimaker.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; - D4AC39151C77C1F20098D685 /* settings_zen7x12.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = settings_zen7x12.h; sourceTree = ""; }; D4B6579C18B5C1DE00F8616C /* plan_exec.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = plan_exec.cpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; D4B6579E18B5C21500F8616C /* cycle_jogging.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = cycle_jogging.cpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; D4B6579F18B5C21500F8616C /* cycle_probing.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = cycle_probing.cpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; @@ -144,30 +128,6 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ - D41D13F617374B7D00D522D9 /* settings */ = { - isa = PBXGroup; - children = ( - D4AC39081C77C1F20098D685 /* settings_default.h */, - D4782AB41D9E2FF300B32136 /* settings_eggbot.h */, - D4782AB21D9B5F9400B32136 /* settings_watercolorbot_v2.h */, - D4AC39091C77C1F20098D685 /* settings_makeblock.h */, - D4AC390A1C77C1F20098D685 /* settings_othermill_test.h */, - D4AC390B1C77C1F20098D685 /* settings_othermill.h */, - D4AC390C1C77C1F20098D685 /* settings_Printrbot_Play.h */, - D4AC390D1C77C1F20098D685 /* settings_Printrbot_Plus.h */, - D49177A11D21CFC50029CDEB /* settings_Printrbot_Simple_1403.h */, - D49177A21D21CFDB0029CDEB /* settings_Printrbot_Simple_1608.h */, - D4AC390F1C77C1F20098D685 /* settings_probotixV90.h */, - D4AC39101C77C1F20098D685 /* settings_shapeoko2.h */, - D4AC39111C77C1F20098D685 /* settings_shopbot_sbv300.h */, - D4AC39121C77C1F20098D685 /* settings_shopbot_test.h */, - D4AC39131C77C1F20098D685 /* settings_test.h */, - D4AC39141C77C1F20098D685 /* settings_Ultimaker.h */, - D4AC39151C77C1F20098D685 /* settings_zen7x12.h */, - ); - path = settings; - sourceTree = ""; - }; D45710B7170532AC00EA19A8 = { isa = PBXGroup; children = ( @@ -231,7 +191,7 @@ D4922F3F1CB8361B00A565FF /* boards.mk */, D43FF6F51D52C8AF00FB5B53 /* board */, D47B744C1D4925B4004FAB53 /* device */, - D41D13F617374B7D00D522D9 /* settings */, + D41997401DF9D6A800E0FB51 /* settings */, D4FEBFF81B0A65E30042EA32 /* index */, ); sourceTree = ""; From 93825108ccec514a34f264c2e3ecfff03a08b355 Mon Sep 17 00:00:00 2001 From: Rob Giseburt Date: Sun, 11 Dec 2016 13:40:45 -0600 Subject: [PATCH 83/98] Prepping README for 100.13 --- README.md | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 6592e57f..424227f7 100644 --- a/README.md +++ b/README.md @@ -50,7 +50,9 @@ Build 100.xx also significantly advances the project structure to support multip - Included `G10 L20` offset mode - Extended `G38.2` probing to also include `G38.3`, `G38.4`, `G38.5` - Homing can now be set to a non-zero switch. Homing will set to the travel value of the positive or negative switch, as determined by the search direction. This allows homing to home to a maximum - for example - and set the homed location to the non-zero switch. - + - [100.13] Fixes for dwells mixed with gcode moves. + - [100.13] Minor planner refactoring to better handle commands and gcode mixed. (Forward-planning now looks past commands.) + - [100.13] *Experimental!* Optioan `TRAVERSE_AT_HIGH_JERK` (defaults to off, set to 1 in a settings file to enable) will make traverse moves (`G0`) use the high-jerk settings instead of the normal jerk settings. This applies to all axes universally. - **Planner and Motion Changes** - Junction Integration Time - the [`{jt:...}`](https://github.com/synthetos/g2/wiki/Configuring-0.99-System-Groups#jt-junction-integration-time) parameter is now the way to set cornering velocity limits. Cornering now obeys full jerk limitation instead of the centripetal acceleration heuristic, making it much more accurate and more true to the jerk limits set for the machine. JT is a normalized scaled factor that is nominally set to 1.000. Set to less than 1 for slower cornering (less aggressive), greater than 1 (but probably less than 2) for more aggressive cornering. This parameter replaces Junction Acceleration `{ja:...}` and the axis Junction Deviation commands - e.g. `{xjd:0.01}`. @@ -75,9 +77,23 @@ Build 100.xx also significantly advances the project structure to support multip - **Active JSON comments** - i.e. JSON called from Gcode - Added `M100 ({...})` active comment. Currently only supports temperature setting command. - Added `M101 ({...})` "wait-on-event" active comment. Currently only supports temperature wait command. + - Additional note: `M101` will only wait on values that return `true` or `false`, and will only work if given `true` or `false`. + - Valid example: + ``` + M101 ({in1: true}) + ``` + - Using `0` or `1`, or anything except `true` or `false` will *not* work. - **System and Communications** + - [100.13] **Important:** USB will only expose one virtal serial port by default. + - This can be overridden in the settings file with: + ```c++ + // Valid options are 1 or 2 only! + #define USB_SERIAL_PORTS_EXPOSED 1 + ``` + - [100.13] Refactored XIO to handle `!`, `%`, `~`, and JSON commends intermixed with gcode better. + - [100.13] Fixes to USB connection, initialization, and DMA operation for Sam3X-base machines. - Added `Linemode` communication protocol, and provide guidance to use linemode for much simpler and more reliable application-level flow control - Footer format has changed. Checksum is no longer supported and has been removed - Added `ENQ/ACK handshake`. If the host sends an ASCII `ENQ (0x05)` the board should respond with an `ACK (0x06)`. This is provided to facilitate low-level communications startup and automated testing From a70b3d89ec19a42a56d1dc05475081e629a3a766 Mon Sep 17 00:00:00 2001 From: Rob Giseburt Date: Tue, 13 Dec 2016 09:14:14 -0600 Subject: [PATCH 84/98] 100.13 // cleanup in preparation for M7 --- g2core/g2core_info.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/g2core/g2core_info.h b/g2core/g2core_info.h index f9a5344a..42776c31 100644 --- a/g2core/g2core_info.h +++ b/g2core/g2core_info.h @@ -21,7 +21,7 @@ #ifndef G2CORE_INFO_H_ONCE #define G2CORE_INFO_H_ONCE -#define G2CORE_FIRMWARE_BUILD 100.12 // Changes to USB serial for SAMS70 and SAM8X targets +#define G2CORE_FIRMWARE_BUILD 100.13 // cleanup in preparation for M7 #ifdef GIT_VERSION #define G2CORE_FIRMWARE_BUILD_STRING GIT_VERSION #else From 7a3899f1417a22a5abbc1e6591c7bae1aaca1026 Mon Sep 17 00:00:00 2001 From: Rob Giseburt Date: Tue, 13 Dec 2016 12:49:27 -0600 Subject: [PATCH 85/98] First pass at supporting devices that mute. --- g2core/config.cpp | 1 + g2core/controller.cpp | 34 +++- g2core/controller.h | 1 + g2core/error.h | 2 +- g2core/json_parser.cpp | 8 +- g2core/json_parser.h | 5 +- .../settings/settings_Printrbot_Simple_1608.h | 1 + g2core/settings/settings_default.h | 4 + g2core/xio.cpp | 145 +++++++++++++----- g2core/xio.h | 16 +- 10 files changed, 162 insertions(+), 55 deletions(-) diff --git a/g2core/config.cpp b/g2core/config.cpp index 5b0b048c..36166f2b 100644 --- a/g2core/config.cpp +++ b/g2core/config.cpp @@ -692,6 +692,7 @@ nvObj_t *nv_add_conditional_message(const char *string) // conditionally add * Inputs: * json_flags = JSON_OBJECT_FORMAT - print just the body w/o header or footer * json_flags = JSON_RESPONSE_FORMAT - print a full "r" object with footer + * json_flags = JSON_RESPONSE_TO_MUTED_FORMAT - JSON_RESPONSE_FORMAT, but only to muted channels * * text_flags = TEXT_INLINE_PAIRS - print text as name/value pairs on a single line * text_flags = TEXT_INLINE_VALUES - print text as comma separated values on a single line diff --git a/g2core/controller.cpp b/g2core/controller.cpp index b92b029f..34927f08 100755 --- a/g2core/controller.cpp +++ b/g2core/controller.cpp @@ -72,7 +72,7 @@ static stat_t _sync_to_planner(void); static stat_t _sync_to_tx_buffer(void); static stat_t _dispatch_command(void); static stat_t _dispatch_control(void); -static void _dispatch_kernel(void); +static void _dispatch_kernel(const devflags_t flags); static stat_t _controller_state(void); // manage controller state transitions static Motate::OutputPin safe_pin; @@ -191,7 +191,7 @@ static stat_t _dispatch_control() if (cs.controller_state != CONTROLLER_PAUSED) { devflags_t flags = DEV_IS_CTRL; if ((cs.bufp = xio_readline(flags, cs.linelen)) != NULL) { - _dispatch_kernel(); + _dispatch_kernel(flags); } } return (STAT_OK); @@ -202,15 +202,22 @@ static stat_t _dispatch_command() if (cs.controller_state != CONTROLLER_PAUSED) { devflags_t flags = DEV_IS_BOTH; if ((!mp_planner_is_full()) && (cs.bufp = xio_readline(flags, cs.linelen)) != NULL) { - _dispatch_kernel(); + _dispatch_kernel(flags); } } return (STAT_OK); } -static void _dispatch_kernel() +static void _dispatch_kernel(const devflags_t flags) { stat_t status; + + if (flags & DEV_IS_MUTED) { + status = STAT_INPUT_FROM_MUTED_CHANNEL_ERROR; + nv_reset_nv_list(); // get a fresh nvObj list + nv_add_string((const char *)"msg", "lines from muted devices are ignored"); + nv_print_list(status, TEXT_NO_PRINT, JSON_RESPONSE_TO_MUTED_FORMAT); + } while ((*cs.bufp == SPC) || (*cs.bufp == TAB)) { // position past any leading whitespace cs.bufp++; @@ -299,6 +306,23 @@ void controller_set_connected(bool is_connected) { } } +/* + * controller_set_muted(bool) - hook for xio to tell the controller that we + * have/don't have one or more muted devices. + */ + +void controller_set_muted(bool is_muted) { + // TODO: care about text mode + if (is_muted) { + // one channel just got muted. + const bool only_to_muted = true; + xio_writeline("{\"muted\":true}\n", only_to_muted); + } else { + // one channel just got unmuted, announce it (except to the muted) + xio_writeline("{\"muted\":false}\n"); + } +} + /* * controller_parse_control() - return true if command is a control (versus data) * Note: parsing for control is somewhat naiive. This will need to get better @@ -456,4 +480,4 @@ stat_t _test_system_assertions() return (STAT_OK); } - \ No newline at end of file + diff --git a/g2core/controller.h b/g2core/controller.h index e7e2f01e..ad307f88 100755 --- a/g2core/controller.h +++ b/g2core/controller.h @@ -84,6 +84,7 @@ extern controller_t cs; // controller state structure void controller_init(void); void controller_run(void); void controller_set_connected(bool is_connected); +void controller_set_muted(bool is_muted); bool controller_parse_control(char *p); #endif // End of include guard: CONTROLLER_H_ONCE diff --git a/g2core/error.h b/g2core/error.h index 15ff8e65..5c802261 100644 --- a/g2core/error.h +++ b/g2core/error.h @@ -204,7 +204,7 @@ char *get_status_message(stat_t status); #define STAT_MAX_DEPTH_EXCEEDED 115 // JSON exceeded maximum nesting depth #define STAT_VALUE_TYPE_ERROR 116 // JSON value does not agree with variable type -#define STAT_ERROR_117 117 +#define STAT_INPUT_FROM_MUTED_CHANNEL_ERROR 117 // input from a muted channel was ignored #define STAT_ERROR_118 118 #define STAT_ERROR_119 119 diff --git a/g2core/json_parser.cpp b/g2core/json_parser.cpp index 9aa2abdd..7a8859a9 100755 --- a/g2core/json_parser.cpp +++ b/g2core/json_parser.cpp @@ -499,7 +499,9 @@ void json_print_list(stat_t status, uint8_t flags) switch (flags) { case JSON_NO_PRINT: break; case JSON_OBJECT_FORMAT: { json_print_object(nv_body); break; } - case JSON_RESPONSE_FORMAT: { json_print_response(status); break; } + case JSON_RESPONSE_FORMAT: + case JSON_RESPONSE_TO_MUTED_FORMAT: + { json_print_response(status, flags == JSON_RESPONSE_TO_MUTED_FORMAT); break; } } } @@ -522,7 +524,7 @@ void json_print_list(stat_t status, uint8_t flags) * on all the (non-silent) responses. */ -void json_print_response(uint8_t status) +void json_print_response(uint8_t status, const bool only_to_muted /*= false*/) { if (js.json_verbosity == JV_SILENT) { // silent means no responses return; @@ -599,7 +601,7 @@ void json_print_response(uint8_t status) // serialize the JSON response and print it if there were no errors if (json_serialize(nv_header, cs.out_buf, sizeof(cs.out_buf)) >= 0) { - xio_writeline(cs.out_buf); + xio_writeline(cs.out_buf, only_to_muted); } } diff --git a/g2core/json_parser.h b/g2core/json_parser.h index e379ede3..c45894f6 100755 --- a/g2core/json_parser.h +++ b/g2core/json_parser.h @@ -57,7 +57,8 @@ typedef enum { typedef enum { // json output print modes JSON_NO_PRINT = 0, // don't print anything if you find yourself in JSON mode JSON_OBJECT_FORMAT, // print just the body as a json object - JSON_RESPONSE_FORMAT // print the header/body/footer as a response object + JSON_RESPONSE_FORMAT, // print the header/body/footer as a response object + JSON_RESPONSE_TO_MUTED_FORMAT // print the header/body/footer as a response object, only to muted channels } jsonFormats; typedef struct jsSingleton { @@ -85,7 +86,7 @@ void json_parser(char *str); void json_parse_for_exec(char *str, bool execute); uint16_t json_serialize(nvObj_t *nv, char *out_buf, uint16_t size); void json_print_object(nvObj_t *nv); -void json_print_response(uint8_t status); +void json_print_response(uint8_t status, const bool only_to_muted = false); void json_print_list(stat_t status, uint8_t flags); stat_t json_set_jv(nvObj_t *nv); diff --git a/g2core/settings/settings_Printrbot_Simple_1608.h b/g2core/settings/settings_Printrbot_Simple_1608.h index d9c71c28..88c022b1 100755 --- a/g2core/settings/settings_Printrbot_Simple_1608.h +++ b/g2core/settings/settings_Printrbot_Simple_1608.h @@ -59,6 +59,7 @@ #define COMM_MODE JSON_MODE // one of: TEXT_MODE, JSON_MODE #define XIO_ENABLE_FLOW_CONTROL FLOW_CONTROL_RTS // FLOW_CONTROL_OFF, FLOW_CONTROL_RTS +#define XIO_UART_MUTES_WHEN_USB_CONNECTED 1 // Mute the UART when USB connects #define TEXT_VERBOSITY TV_VERBOSE // one of: TV_SILENT, TV_VERBOSE #define JSON_VERBOSITY JV_LINENUM // one of: JV_SILENT, JV_FOOTER, JV_CONFIGS, JV_MESSAGES, JV_LINENUM, JV_VERBOSE diff --git a/g2core/settings/settings_default.h b/g2core/settings/settings_default.h index bb33cdd2..887ed005 100755 --- a/g2core/settings/settings_default.h +++ b/g2core/settings/settings_default.h @@ -141,6 +141,10 @@ #define XIO_ENABLE_FLOW_CONTROL FLOW_CONTROL_RTS // FLOW_CONTROL_OFF, FLOW_CONTROL_XON, FLOW_CONTROL_RTS #endif +#ifndef XIO_UART_MUTES_WHEN_USB_CONNECTED +#define XIO_UART_MUTES_WHEN_USB_CONNECTED 0 // UART will be muted when USB connected (off by default) +#endif + #ifndef JSON_VERBOSITY #define JSON_VERBOSITY JV_MESSAGES // {jv: JV_SILENT, JV_FOOTER, JV_CONFIGS, JV_MESSAGES, JV_LINENUM, JV_VERBOSE #endif diff --git a/g2core/xio.cpp b/g2core/xio.cpp index cc9dc874..7678899b 100755 --- a/g2core/xio.cpp +++ b/g2core/xio.cpp @@ -116,14 +116,18 @@ struct xioDeviceWrapperBase { // C++ base class for device primit // bool canWrite() { return caps & DEV_CAN_WRITE; } // bool canBeCtrl() { return caps & DEV_CAN_BE_CTRL; } // bool canBeData() { return caps & DEV_CAN_BE_DATA; } - bool isAlwaysDataAndCtrl() { return caps & DEV_IS_ALWAYS_BOTH; } bool isCtrl() { return flags & DEV_IS_CTRL; } // called externally: DeviceWrappers[i]->isCtrl() bool isData() { return flags & DEV_IS_DATA; } // subclasses can call directly (no pointer): isCtrl() bool isPrimary() { return flags & DEV_IS_PRIMARY; } + + bool isAlwaysDataAndCtrl() { return caps & DEV_IS_ALWAYS_BOTH; } + bool isMuteAsSecondary() { return caps & DEV_IS_MUTE_SECONDARY; } + bool isConnected() { return flags & DEV_IS_CONNECTED; } bool isNotConnected() { return !(flags & DEV_IS_CONNECTED); } bool isReady() { return flags & DEV_IS_READY; } bool isActive() { return flags & DEV_IS_ACTIVE; } + bool isMuted() { return flags & DEV_IS_MUTED; } // Combination checks bool isCtrlAndActive() { return ((flags & (DEV_IS_CTRL|DEV_IS_ACTIVE)) == (DEV_IS_CTRL|DEV_IS_ACTIVE)); } @@ -143,13 +147,16 @@ struct xioDeviceWrapperBase { // C++ base class for device primit void setAsConnectedAndReady() { flags |= ( DEV_IS_CONNECTED | DEV_IS_READY); }; void setAsPrimaryActiveDualRole() { - if (isAlwaysDataAndCtrl()) { - flags |= (DEV_IS_CTRL | DEV_IS_DATA | DEV_IS_ACTIVE); + if (isAlwaysDataAndCtrl() || isMuteAsSecondary()) { + // In both cases, it cannot be a PRIMARY + // Also, we remove a MUTED flag + flags = (flags & ~DEV_IS_MUTED) | (DEV_IS_CTRL | DEV_IS_DATA | DEV_IS_ACTIVE); } else { flags |= (DEV_IS_CTRL | DEV_IS_DATA | DEV_IS_PRIMARY | DEV_IS_ACTIVE); } }; void setAsActiveData() { flags |= ( DEV_IS_DATA | DEV_IS_ACTIVE); }; + void setAsMuted() { flags = (flags & ~(DEV_IS_PRIMARY | DEV_IS_DATA | DEV_IS_CTRL)) | DEV_IS_MUTED; }; void clearFlags() { flags = DEV_FLAGS_CLEAR; } xioDeviceWrapperBase(uint8_t _caps) : caps(_caps), @@ -201,6 +208,7 @@ struct xio_t { }; void remove_data_from_primary() { + // Why is this first pass here? -RG for (int8_t i = 0; i < _dev_count; ++i) { if (DeviceWrappers[i]->isDataAndActive()) { return; @@ -214,10 +222,28 @@ struct xio_t { } }; - void deactivate_all_channels() { - for(int8_t i = 0; i < _dev_count; ++i) { - DeviceWrappers[i]->clearActive(); + bool check_muted_secondary_channels() { + bool muted_something = false; + for (int8_t i = 0; i < _dev_count; ++i) { + if (DeviceWrappers[i]->isMuteAsSecondary()) { + DeviceWrappers[i]->setAsMuted(); + muted_something = true; + } } + return muted_something; + } + + bool deactivate_and_unmute_channels() { + bool unmuted_something = false; + for(int8_t i = 0; i < _dev_count; ++i) { + if (DeviceWrappers[i]->isMuted()) { + unmuted_something = true; + DeviceWrappers[i]->setAsPrimaryActiveDualRole(); // NOTE: muted secondary devices won't be set PRIMARY + } else { + DeviceWrappers[i]->clearActive(); + } + } + return unmuted_something; }; // ##### Cross-Device read/write/etc. functions @@ -232,11 +258,17 @@ struct xio_t { * In the current environment, these are not foreseen to cause trouble since these * are blocking writes and we expect to only really be writing to one device. */ - size_t write(const char *buffer, size_t size) + size_t write(const char *buffer, size_t size, bool only_to_muted) { size_t total_written = -1; for (int8_t i = 0; i < _dev_count; ++i) { - if (DeviceWrappers[i]->isCtrlAndActive()) { + bool ok_channel = false; + if (!only_to_muted) { + ok_channel = DeviceWrappers[i]->isCtrlAndActive(); + } else { + ok_channel = DeviceWrappers[i]->isMuted(); + } + if (ok_channel) { const char *buf = buffer; int16_t to_write = size; while (to_write > 0) { @@ -256,10 +288,10 @@ struct xio_t { * The input buffer must be NUL terminated */ - int16_t writeline(const char *buffer) + int16_t writeline(const char *buffer, bool only_to_muted) { int16_t len = strlen(buffer); - return write(buffer, len); + return write(buffer, len, only_to_muted); }; /* @@ -331,8 +363,8 @@ struct xio_t { // We only do this second pass if this is not a CTRL-only read if (!checkForCtrlOnly(limit_flags)) { for (uint8_t dev=0; dev < _dev_count; dev++) { - if (!DeviceWrappers[dev]->isActive()) - continue; +// if (!DeviceWrappers[dev]->isActive()) +// continue; ret_buffer = DeviceWrappers[dev]->readline(limit_flags, size); @@ -884,29 +916,60 @@ struct xioDeviceWrapper : xioDeviceWrapperBase { // describes a device for re void connectedStateChanged(bool connected) { if (connected) { if (isNotConnected()) { - //USB0 or UART has just connected - //Case 1: This is the first channel to connect - - // set it as CTRL+DATA+PRIMARY channel - //Case 2: This is the second (or later) channel to connect - - // set it as DATA channel, remove DATA flag from PRIMARY channel - //... inactive channels are counted as closed + // USB0 or UART has just connected + // If one of the devices isAlwaysDataAndCtrl(): + // We treat *it* as if it's the only device connected. + // We treat *the other devices* as if it's NOT connected. + // Case 1: This is the first channel to connect - + // set it as CTRL+DATA+PRIMARY channel + // mark all isMutedAsSecondary() as MUTED, and call controller_set_muted(true) if needed + // Case 2: This is the second (or later) channel to connect - + // Case 2a: This device is !isMuteAsSecondary() + // set it as DATA channel, remove DATA flag from PRIMARY channel + // mark all isMutedAsSecondary() as MUTED, and call controller_set_muted(true) if needed + // ... inactive channels are counted as closed + // Case 2b: This devices isMuteAsSecondary(), and needs to be "muted." + // set it as a MUTED channel, call controller_set_connected(true) + // then controller_set_muted(true) + setAsConnectedAndReady(); if (isAlwaysDataAndCtrl()) { + // Case 1 (ignoring others) setActive(); controller_set_connected(true); + + // Case 2b (not ignoring others) + if (isMuteAsSecondary() && xio.others_connected(this)) { + controller_set_muted(true); // something was muted + } + return; } if(!xio.others_connected(this)) { // Case 1 setAsPrimaryActiveDualRole(); - // report that we now have a connection (only for the first one) + // report that there is now have a connection (only for the first one) controller_set_connected(true); - } else { - // Case 2 + // make sure secondary channels (that don't show up in isConnected) are muted + if (xio.check_muted_secondary_channels()) { + controller_set_muted(true); // something was muted + } + } + else if (isMuteAsSecondary()) { + // Case 2b + setAsMuted(); + controller_set_connected(true); // it DID just just get connected + controller_set_muted(true); // but it muted it too + } + else { + // Case 2a xio.remove_data_from_primary(); + if (xio.check_muted_secondary_channels()) { + controller_set_muted(true); // something was muted + } setAsActiveData(); } } // flags & DEV_IS_DISCONNECTED @@ -916,9 +979,9 @@ struct xioDeviceWrapper : xioDeviceWrapperBase { // describes a device for re //USB0 has just disconnected //Case 1: This channel disconnected while it was a ctrl+data channel (and no other channels are open) - - // finalize this channel + // finalize this channel, unmute muted channels //Case 2: This channel disconnected while it was a primary ctrl channel (and other channels are open) - - // finalize this channel, deactivate other channels + // finalize this channel, unmute muted channels, deactivate other channels //Case 3: This channel disconnected while it was a non-primary ctrl channel (and other channels are open) - // finalize this channel, leave other channels alone //Case 4: This channel disconnected while it was a data channel (and other channels are open, including a primary) @@ -933,20 +996,23 @@ struct xioDeviceWrapper : xioDeviceWrapperBase { // describes a device for re flush(); flushRead(); - if(checkForNotActive(oldflags) || isAlwaysDataAndCtrl()) { + if (checkForNotActive(oldflags) || isAlwaysDataAndCtrl()) { // Case 5a, 5b - } else if(checkForCtrlAndData(oldflags) || !xio.others_connected(this)) { + } else if (checkForCtrlAndData(oldflags) || !xio.others_connected(this)) { // Case 1 - if(!checkForCtrlAndData(oldflags) || xio.others_connected(this)) { - rpt_exception(STAT_XIO_ASSERTION_FAILURE, "xio_dev() assertion error"); // where is this supposed to go!? + if (xio.deactivate_and_unmute_channels()) { + controller_set_muted(false); // something was unmuted + } else { + controller_set_connected(false); } - controller_set_connected(false); - } else if(checkForCtrlAndPrimary(oldflags)) { + } else if (checkForCtrlAndPrimary(oldflags)) { // Case 2 - xio.deactivate_all_channels(); - } else if(checkForCtrl(oldflags)) { + if (xio.deactivate_and_unmute_channels()) { + controller_set_muted(false); // something was unmuted + } + } else if (checkForCtrl(oldflags)) { // Case 3 - } else if(checkForData(oldflags)) { + } else if (checkForData(oldflags)) { // Case 4 xio.remove_data_from_primary(); } @@ -970,9 +1036,14 @@ xioDeviceWrapper serialUSB1Wrapper { #endif #endif // XIO_HAS_USB #if XIO_HAS_UART==1 +#if defined(XIO_UART_MUTES_WHEN_USB_CONNECTED) && (XIO_UART_MUTES_WHEN_USB_CONNECTED==1) +constexpr devflags_t _serial0ExtraFlags = DEV_IS_ALWAYS_BOTH | DEV_IS_MUTE_SECONDARY; +#else +constexpr devflags_t _serial0ExtraFlags = DEV_IS_ALWAYS_BOTH; +#endif xioDeviceWrapper serial0Wrapper { &Serial, - (DEV_CAN_READ | DEV_CAN_WRITE | DEV_IS_ALWAYS_BOTH) + (DEV_CAN_READ | DEV_CAN_WRITE | _serial0ExtraFlags) }; #endif // XIO_HAS_UART @@ -1032,9 +1103,9 @@ stat_t xio_test_assertions() * write() - write a buffer to a device */ -size_t xio_write(const char *buffer, size_t size) +size_t xio_write(const char *buffer, size_t size, bool only_to_muted /*= false*/) { - return xio.write(buffer, size); + return xio.write(buffer, size, only_to_muted); } /* @@ -1049,9 +1120,9 @@ char *xio_readline(devflags_t &flags, uint16_t &size) return xio.readline(flags, size); } -int16_t xio_writeline(const char *buffer) +int16_t xio_writeline(const char *buffer, bool only_to_muted /*= false*/) { - return xio.writeline(buffer); + return xio.writeline(buffer, only_to_muted); } bool xio_connected() diff --git a/g2core/xio.h b/g2core/xio.h index 0369af21..b235f7d1 100755 --- a/g2core/xio.h +++ b/g2core/xio.h @@ -65,17 +65,19 @@ typedef uint16_t devflags_t; // might need to bump to 32 be 16 or 32 // device capabilities flags -#define DEV_CAN_BE_CTRL (0x0001) // device can be a control channel -#define DEV_CAN_BE_DATA (0x0002) // device can be a data channel -#define DEV_IS_ALWAYS_BOTH (0x0004) // device is always a control and a data channel -#define DEV_CAN_READ (0x0010) -#define DEV_CAN_WRITE (0x0020) +#define DEV_CAN_BE_CTRL (0x0001) // device can be a control channel +#define DEV_CAN_BE_DATA (0x0002) // device can be a data channel +#define DEV_IS_ALWAYS_BOTH (0x0004) // device is always a control and a data channel +#define DEV_IS_MUTE_SECONDARY (0x0008) // device is "muted" as a non-primary device +#define DEV_CAN_READ (0x0010) +#define DEV_CAN_WRITE (0x0020) // Device state flags // channel state #define DEV_IS_CTRL (0x0001) // device is set as a control channel #define DEV_IS_DATA (0x0002) // device is set as a data channel #define DEV_IS_PRIMARY (0x0004) // device is the primary control channel +#define DEV_IS_MUTED (0x0008) // device is muted as it is currently the non-primary device // device connection state #define DEV_IS_CONNECTED (0x0020) // device is connected (e.g. USB) @@ -113,9 +115,9 @@ enum xioSPIMode { void xio_init(void); stat_t xio_test_assertions(void); -size_t xio_write(const uint8_t *buffer, size_t size); +size_t xio_write(const char *buffer, size_t size, bool only_to_muted = false); char *xio_readline(devflags_t &flags, uint16_t &size); -int16_t xio_writeline(const char *buffer); +int16_t xio_writeline(const char *buffer, bool only_to_muted = false); bool xio_connected(); stat_t xio_set_spi(nvObj_t *nv); From 1380b2f21ba2a6a6d292a6e15b2ace76c83c642a Mon Sep 17 00:00:00 2001 From: Rob Giseburt Date: Tue, 13 Dec 2016 17:09:31 -0600 Subject: [PATCH 86/98] Finished muted devices capability. --- g2core/controller.cpp | 5 ++++- g2core/xio.cpp | 4 ++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/g2core/controller.cpp b/g2core/controller.cpp index 34927f08..70fb3378 100755 --- a/g2core/controller.cpp +++ b/g2core/controller.cpp @@ -200,7 +200,7 @@ static stat_t _dispatch_control() static stat_t _dispatch_command() { if (cs.controller_state != CONTROLLER_PAUSED) { - devflags_t flags = DEV_IS_BOTH; + devflags_t flags = DEV_IS_BOTH | DEV_IS_MUTED; // expressly state we'll handle muted devices if ((!mp_planner_is_full()) && (cs.bufp = xio_readline(flags, cs.linelen)) != NULL) { _dispatch_kernel(flags); } @@ -217,6 +217,9 @@ static void _dispatch_kernel(const devflags_t flags) nv_reset_nv_list(); // get a fresh nvObj list nv_add_string((const char *)"msg", "lines from muted devices are ignored"); nv_print_list(status, TEXT_NO_PRINT, JSON_RESPONSE_TO_MUTED_FORMAT); + + // It's possible to let some stuff through, but that's not happening yet. + return; } while ((*cs.bufp == SPC) || (*cs.bufp == TAB)) { // position past any leading whitespace diff --git a/g2core/xio.cpp b/g2core/xio.cpp index 7678899b..9de46fed 100755 --- a/g2core/xio.cpp +++ b/g2core/xio.cpp @@ -363,8 +363,8 @@ struct xio_t { // We only do this second pass if this is not a CTRL-only read if (!checkForCtrlOnly(limit_flags)) { for (uint8_t dev=0; dev < _dev_count; dev++) { -// if (!DeviceWrappers[dev]->isActive()) -// continue; + if (!DeviceWrappers[dev]->isActive()) + continue; ret_buffer = DeviceWrappers[dev]->readline(limit_flags, size); From 7245759485893bf950ef53fbbd2d6e3fd23026d6 Mon Sep 17 00:00:00 2001 From: Rob Giseburt Date: Tue, 13 Dec 2016 17:40:09 -0600 Subject: [PATCH 87/98] 100.14 // fix for 198, uart can be muted when USB connects The default behavior is everything connected gets all responses. (Minus behavior for second USB port, which is now disabled by default.) In the settings file being used, you need: ```c++ #define XIO_UART_MUTES_WHEN_USB_CONNECTED 1 // Mute the UART when USB connects ``` --- g2core/g2core_info.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/g2core/g2core_info.h b/g2core/g2core_info.h index 42776c31..15406b61 100644 --- a/g2core/g2core_info.h +++ b/g2core/g2core_info.h @@ -21,7 +21,7 @@ #ifndef G2CORE_INFO_H_ONCE #define G2CORE_INFO_H_ONCE -#define G2CORE_FIRMWARE_BUILD 100.13 // cleanup in preparation for M7 +#define G2CORE_FIRMWARE_BUILD 100.14 // fix for 198, uart can be muted when USB connects #ifdef GIT_VERSION #define G2CORE_FIRMWARE_BUILD_STRING GIT_VERSION #else From 6f18ddccc5ac9a519df3592213884366f66775f9 Mon Sep 17 00:00:00 2001 From: Rob Giseburt Date: Wed, 14 Dec 2016 09:01:47 -0600 Subject: [PATCH 88/98] Updating edge to point to Motate master branch This is *after* Motate master merged with sams70-port --- Motate | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Motate b/Motate index 18c93112..a11381a0 160000 --- a/Motate +++ b/Motate @@ -1 +1 @@ -Subproject commit 18c93112f1e1e13eb0fa740e185c4b973e4419fc +Subproject commit a11381a0a17ced68d07cdfcafb6bb62fc1550cbd From fe2b5a6123debb4126615536cdea8295eeae27fd Mon Sep 17 00:00:00 2001 From: Rob Giseburt Date: Wed, 14 Dec 2016 12:57:14 -0600 Subject: [PATCH 89/98] Update Motate to fix USB connection issue with sam3x MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Problem was that when powered up with USB not connected, it wouldn’t setup the interrupts properly to detect the connection later. --- Motate | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Motate b/Motate index a11381a0..76a56600 160000 --- a/Motate +++ b/Motate @@ -1 +1 @@ -Subproject commit a11381a0a17ced68d07cdfcafb6bb62fc1550cbd +Subproject commit 76a566004e23c8962dd093ff5e42bca7ff7c1209 From 48e02ac8f6e258f10fbedbb91651d33a94bb200d Mon Sep 17 00:00:00 2001 From: Rob Giseburt Date: Wed, 14 Dec 2016 13:08:50 -0600 Subject: [PATCH 90/98] On more Motate update to fix USB for sam3x. --- Motate | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Motate b/Motate index 76a56600..c294c7ce 160000 --- a/Motate +++ b/Motate @@ -1 +1 @@ -Subproject commit 76a566004e23c8962dd093ff5e42bca7ff7c1209 +Subproject commit c294c7ce844696d5232da595dba53ecb3542ede6 From 95f9060dad34d5d0d71fc37a9a041a25b04e530f Mon Sep 17 00:00:00 2001 From: Rob Giseburt Date: Wed, 14 Dec 2016 14:55:20 -0600 Subject: [PATCH 91/98] Wrap every BKPT in ifdef IN_DEBUGGER --- g2core/plan_exec.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/g2core/plan_exec.cpp b/g2core/plan_exec.cpp index 85527f85..8fe4c084 100644 --- a/g2core/plan_exec.cpp +++ b/g2core/plan_exec.cpp @@ -178,12 +178,14 @@ static stat_t _plan_move(mpBuf_t *bf, float entry_velocity) mp_calculate_ramps(block, bf, entry_velocity); // (which it will if you don't do this) // diagnostic traps +#ifdef IN_DEBUGGER if (block->exit_velocity > block->cruise_velocity) { __asm__("BKPT"); // exit > cruise after calculate_block } if (block->head_length < 0.00001 && block->body_length < 0.00001 && block->tail_length < 0.00001) { __asm__("BKPT"); // zero or negative length block } +#endif bf->buffer_state = MP_BUFFER_PLANNED; //...here bf->plannable = false; return (STAT_OK); // report that we planned something... @@ -254,8 +256,10 @@ stat_t mp_exec_move() // first-time operations if (bf->buffer_state != MP_BUFFER_RUNNING) { if ((bf->buffer_state < MP_BUFFER_PREPPED) && (cm.motion_state == MOTION_RUN)) { +#ifdef IN_DEBUGGER __asm__("BKPT"); // mp_exec_move() buffer is not prepped - // IMPORTANT: We can't rpt_exception from here! +#endif + // IMPORTANT: We can't rpt_exception from here! st_prep_null(); return (STAT_NOOP); } @@ -267,7 +271,9 @@ stat_t mp_exec_move() if (bf->buffer_state == MP_BUFFER_PREPPED) { if (cm.motion_state == MOTION_RUN) { +#ifdef IN_DEBUGGER __asm__("BKPT"); // we are running but don't have a block planned +#endif } // We need to have it planned. We don't want to do this here, as it // might already be happening in a lower interrupt. From 2a9fcec6d2c5b95f4bb5553d4b807bb232afdc65 Mon Sep 17 00:00:00 2001 From: Rob Giseburt Date: Wed, 14 Dec 2016 14:55:50 -0600 Subject: [PATCH 92/98] Handle when xio scans a null (usually a rough disconnection). --- g2core/xio.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/g2core/xio.cpp b/g2core/xio.cpp index 9de46fed..6c2c121d 100755 --- a/g2core/xio.cpp +++ b/g2core/xio.cpp @@ -589,6 +589,8 @@ struct LineRXBuffer : RXBuffer<_size, owner_type, char> { if (c == 0) { _debug_trap("scan ran into NULL"); + flush(); // consider the connection and all data trashed + return false; } // Look for line endings From 42e3289f0e99fa708dcf5936589bd763404b7c65 Mon Sep 17 00:00:00 2001 From: Rob Giseburt Date: Wed, 14 Dec 2016 14:56:11 -0600 Subject: [PATCH 93/98] Update Motate for more sam3x USB changes --- Motate | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Motate b/Motate index c294c7ce..edf4f306 160000 --- a/Motate +++ b/Motate @@ -1 +1 @@ -Subproject commit c294c7ce844696d5232da595dba53ecb3542ede6 +Subproject commit edf4f306fc5464e5c3bb73352ecee9a0251984d7 From ff8524a66874ae7f3d66f53283f6ca181b1c98c7 Mon Sep 17 00:00:00 2001 From: Rob Giseburt Date: Thu, 15 Dec 2016 09:35:30 -0600 Subject: [PATCH 94/98] Cleanup board files, and ensure board_hardware_init gets called. Fixes #200 --- g2core/board/Archim/board_xio.cpp | 10 +++------- g2core/board/Archim/hardware.cpp | 1 + g2core/board/ArduinoDue/board_xio.cpp | 14 ++++++-------- g2core/board/ArduinoDue/board_xio.h | 5 ++--- g2core/board/ArduinoDue/hardware.cpp | 1 + g2core/board/G2v9/board_xio.cpp | 14 ++++++-------- g2core/board/gquadratic/board_xio.cpp | 10 +++------- g2core/board/gquintic/board_xio.cpp | 10 +++------- g2core/board/printrboardg2/board_xio.cpp | 10 +++------- g2core/board/sbv300/board_xio.cpp | 10 +++------- g2core/board/sbv300/hardware.cpp | 1 + 11 files changed, 32 insertions(+), 54 deletions(-) diff --git a/g2core/board/Archim/board_xio.cpp b/g2core/board/Archim/board_xio.cpp index 87ab4dd3..ca077c05 100644 --- a/g2core/board/Archim/board_xio.cpp +++ b/g2core/board/Archim/board_xio.cpp @@ -44,14 +44,10 @@ const Motate::USBSettings_t Motate::USBSettings = { XIOUSBDevice_t usb; -extern decltype(usb.mixin<0>::Serial)& SerialUSB; -#if USB_SERIAL_PORTS_EXPOSED == 2 -extern decltype(usb.mixin<1>::Serial)& SerialUSB1; -#endif - - decltype(usb.mixin<0>::Serial) &SerialUSB = usb.mixin<0>::Serial; -//decltype(usb.mixin<1>::Serial) &SerialUSB1 = usb.mixin<1>::Serial; +#if USB_SERIAL_PORTS_EXPOSED == 2 +decltype(usb.mixin<1>::Serial) &SerialUSB1 = usb.mixin<1>::Serial; +#endif MOTATE_SET_USB_VENDOR_STRING( u"Synthetos" ) MOTATE_SET_USB_PRODUCT_STRING( u"TinyG v2" ) diff --git a/g2core/board/Archim/hardware.cpp b/g2core/board/Archim/hardware.cpp index 11d740ef..55d553ef 100755 --- a/g2core/board/Archim/hardware.cpp +++ b/g2core/board/Archim/hardware.cpp @@ -42,6 +42,7 @@ void hardware_init() { + board_hardware_init(); return; } diff --git a/g2core/board/ArduinoDue/board_xio.cpp b/g2core/board/ArduinoDue/board_xio.cpp index 7f2a0774..15639e6a 100755 --- a/g2core/board/ArduinoDue/board_xio.cpp +++ b/g2core/board/ArduinoDue/board_xio.cpp @@ -44,14 +44,10 @@ const Motate::USBSettings_t Motate::USBSettings = { XIOUSBDevice_t usb; -extern decltype(usb.mixin<0>::Serial)& SerialUSB; -#if USB_SERIAL_PORTS_EXPOSED == 2 -extern decltype(usb.mixin<1>::Serial)& SerialUSB1; -#endif - - decltype(usb.mixin<0>::Serial) &SerialUSB = usb.mixin<0>::Serial; -//decltype(usb.mixin<1>::Serial) &SerialUSB1 = usb.mixin<1>::Serial; +#if USB_SERIAL_PORTS_EXPOSED == 2 +decltype(usb.mixin<1>::Serial) &SerialUSB1 = usb.mixin<1>::Serial; +#endif MOTATE_SET_USB_VENDOR_STRING( u"Synthetos" ) MOTATE_SET_USB_PRODUCT_STRING( u"TinyG v2" ) @@ -74,8 +70,10 @@ Motate::UART spi; extern Motate::UART Serial; #endif - - //******* Generic Functions ******* -void board_xio_init(void); +void board_hardware_init(void); // called 1st +void board_xio_init(void); // called later #endif // board_xio_h diff --git a/g2core/board/ArduinoDue/hardware.cpp b/g2core/board/ArduinoDue/hardware.cpp index c688872a..e4886882 100755 --- a/g2core/board/ArduinoDue/hardware.cpp +++ b/g2core/board/ArduinoDue/hardware.cpp @@ -44,6 +44,7 @@ void hardware_init() { + board_hardware_init(); return; } diff --git a/g2core/board/G2v9/board_xio.cpp b/g2core/board/G2v9/board_xio.cpp index 09ccaf80..710433dc 100755 --- a/g2core/board/G2v9/board_xio.cpp +++ b/g2core/board/G2v9/board_xio.cpp @@ -44,14 +44,10 @@ const Motate::USBSettings_t Motate::USBSettings = { XIOUSBDevice_t usb; -extern decltype(usb.mixin<0>::Serial)& SerialUSB; -#if USB_SERIAL_PORTS_EXPOSED == 2 -extern decltype(usb.mixin<1>::Serial)& SerialUSB1; -#endif - - decltype(usb.mixin<0>::Serial) &SerialUSB = usb.mixin<0>::Serial; -//decltype(usb.mixin<1>::Serial) &SerialUSB1 = usb.mixin<1>::Serial; +#if USB_SERIAL_PORTS_EXPOSED == 2 +decltype(usb.mixin<1>::Serial) &SerialUSB1 = usb.mixin<1>::Serial; +#endif MOTATE_SET_USB_VENDOR_STRING( u"Synthetos" ) MOTATE_SET_USB_PRODUCT_STRING( u"TinyG v2" ) @@ -73,8 +69,10 @@ Motate::UART::Serial)& SerialUSB; -#if USB_SERIAL_PORTS_EXPOSED == 2 -extern decltype(usb.mixin<1>::Serial)& SerialUSB1; -#endif - - decltype(usb.mixin<0>::Serial) &SerialUSB = usb.mixin<0>::Serial; -//decltype(usb.mixin<1>::Serial) &SerialUSB1 = usb.mixin<1>::Serial; +#if USB_SERIAL_PORTS_EXPOSED == 2 +decltype(usb.mixin<1>::Serial) &SerialUSB1 = usb.mixin<1>::Serial; +#endif MOTATE_SET_USB_VENDOR_STRING( u"Synthetos" ) MOTATE_SET_USB_PRODUCT_STRING( u"TinyG v2" ) diff --git a/g2core/board/gquintic/board_xio.cpp b/g2core/board/gquintic/board_xio.cpp index 8b4835b2..c48356be 100755 --- a/g2core/board/gquintic/board_xio.cpp +++ b/g2core/board/gquintic/board_xio.cpp @@ -44,14 +44,10 @@ const Motate::USBSettings_t Motate::USBSettings = { XIOUSBDevice_t usb; -extern decltype(usb.mixin<0>::Serial)& SerialUSB; -#if USB_SERIAL_PORTS_EXPOSED == 2 -extern decltype(usb.mixin<1>::Serial)& SerialUSB1; -#endif - - decltype(usb.mixin<0>::Serial) &SerialUSB = usb.mixin<0>::Serial; -//decltype(usb.mixin<1>::Serial) &SerialUSB1 = usb.mixin<1>::Serial; +#if USB_SERIAL_PORTS_EXPOSED == 2 +decltype(usb.mixin<1>::Serial) &SerialUSB1 = usb.mixin<1>::Serial; +#endif MOTATE_SET_USB_VENDOR_STRING( u"Synthetos" ) MOTATE_SET_USB_PRODUCT_STRING( u"TinyG v2" ) diff --git a/g2core/board/printrboardg2/board_xio.cpp b/g2core/board/printrboardg2/board_xio.cpp index 8b4835b2..c48356be 100755 --- a/g2core/board/printrboardg2/board_xio.cpp +++ b/g2core/board/printrboardg2/board_xio.cpp @@ -44,14 +44,10 @@ const Motate::USBSettings_t Motate::USBSettings = { XIOUSBDevice_t usb; -extern decltype(usb.mixin<0>::Serial)& SerialUSB; -#if USB_SERIAL_PORTS_EXPOSED == 2 -extern decltype(usb.mixin<1>::Serial)& SerialUSB1; -#endif - - decltype(usb.mixin<0>::Serial) &SerialUSB = usb.mixin<0>::Serial; -//decltype(usb.mixin<1>::Serial) &SerialUSB1 = usb.mixin<1>::Serial; +#if USB_SERIAL_PORTS_EXPOSED == 2 +decltype(usb.mixin<1>::Serial) &SerialUSB1 = usb.mixin<1>::Serial; +#endif MOTATE_SET_USB_VENDOR_STRING( u"Synthetos" ) MOTATE_SET_USB_PRODUCT_STRING( u"TinyG v2" ) diff --git a/g2core/board/sbv300/board_xio.cpp b/g2core/board/sbv300/board_xio.cpp index 8b4835b2..c48356be 100755 --- a/g2core/board/sbv300/board_xio.cpp +++ b/g2core/board/sbv300/board_xio.cpp @@ -44,14 +44,10 @@ const Motate::USBSettings_t Motate::USBSettings = { XIOUSBDevice_t usb; -extern decltype(usb.mixin<0>::Serial)& SerialUSB; -#if USB_SERIAL_PORTS_EXPOSED == 2 -extern decltype(usb.mixin<1>::Serial)& SerialUSB1; -#endif - - decltype(usb.mixin<0>::Serial) &SerialUSB = usb.mixin<0>::Serial; -//decltype(usb.mixin<1>::Serial) &SerialUSB1 = usb.mixin<1>::Serial; +#if USB_SERIAL_PORTS_EXPOSED == 2 +decltype(usb.mixin<1>::Serial) &SerialUSB1 = usb.mixin<1>::Serial; +#endif MOTATE_SET_USB_VENDOR_STRING( u"Synthetos" ) MOTATE_SET_USB_PRODUCT_STRING( u"TinyG v2" ) diff --git a/g2core/board/sbv300/hardware.cpp b/g2core/board/sbv300/hardware.cpp index 7fbf23b7..ee0cf7fd 100755 --- a/g2core/board/sbv300/hardware.cpp +++ b/g2core/board/sbv300/hardware.cpp @@ -43,6 +43,7 @@ void hardware_init() { + board_hardware_init(); return; } From fb9fb91b9c6e8319bbc6193c636c165ffd8ed268 Mon Sep 17 00:00:00 2001 From: Rob Giseburt Date: Thu, 15 Dec 2016 09:42:57 -0600 Subject: [PATCH 95/98] 100.15 // fix for #200 and other USB issues --- g2core/g2core_info.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/g2core/g2core_info.h b/g2core/g2core_info.h index 15406b61..9beabb32 100644 --- a/g2core/g2core_info.h +++ b/g2core/g2core_info.h @@ -21,7 +21,7 @@ #ifndef G2CORE_INFO_H_ONCE #define G2CORE_INFO_H_ONCE -#define G2CORE_FIRMWARE_BUILD 100.14 // fix for 198, uart can be muted when USB connects +#define G2CORE_FIRMWARE_BUILD 100.15 // fix for #200 and other USB issues #ifdef GIT_VERSION #define G2CORE_FIRMWARE_BUILD_STRING GIT_VERSION #else From da981dea7e253a8359f4bed0ac2ac3c7f0340de0 Mon Sep 17 00:00:00 2001 From: Rob Giseburt Date: Thu, 15 Dec 2016 09:59:41 -0600 Subject: [PATCH 96/98] Removed debugging code that made it to commit on accident. --- g2core/pwm.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/g2core/pwm.cpp b/g2core/pwm.cpp index 61589443..ce740ff5 100755 --- a/g2core/pwm.cpp +++ b/g2core/pwm.cpp @@ -72,9 +72,6 @@ stat_t pwm_set_freq(uint8_t chan, float freq) //if (freq > PWM_MAX_FREQ) { return (STAT_INPUT_EXCEEDS_MAX_VALUE);} if (chan == PWM_1) { - if (spindle_pwm_pin.canPWM()) { - cm_alarm(STAT_ALARM, "BOOM"); - } spindle_pwm_pin.setFrequency(freq); } else if (chan == PWM_2) { secondary_pwm_pin.setFrequency(freq); From 5a0d99a40af2c0c64a9529da0c29f10c7f3a38fc Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Sat, 24 Dec 2016 10:03:19 -0500 Subject: [PATCH 97/98] Fixed $$ lockup problem. Root cause was mis-handling of stale NV lists. --- g2core/config_app.cpp | 8 ++++---- g2core/error.h | 2 +- g2core/g2core.cppproj | 12 ++++++------ g2core/json_parser.cpp | 7 +++++-- 4 files changed, 16 insertions(+), 13 deletions(-) mode change 100755 => 100644 g2core/json_parser.cpp diff --git a/g2core/config_app.cpp b/g2core/config_app.cpp index 9ddff796..6ff570b0 100644 --- a/g2core/config_app.cpp +++ b/g2core/config_app.cpp @@ -1117,7 +1117,7 @@ static stat_t _do_outputs(nvObj_t *nv) // print parameters for all output group } return (STAT_COMPLETE); } -/* + static stat_t _do_heaters(nvObj_t *nv) // print parameters for all heater groups { char group[GROUP_LEN]; @@ -1127,7 +1127,7 @@ static stat_t _do_heaters(nvObj_t *nv) // print parameters for all heater group } return (STAT_COMPLETE); } -*/ + static stat_t _do_all(nvObj_t *nv) // print all parameters { _do_group(nv, (char *)"sys"); // System group @@ -1135,10 +1135,10 @@ static stat_t _do_all(nvObj_t *nv) // print all parameters _do_axes(nv); _do_inputs(nv); _do_outputs(nv); -// _do_heaters(nv); // there are no text mode prints for heaters + _do_heaters(nv); // there are no text mode prints for heaters _do_group(nv, (char *)"p1"); // PWM group _do_offsets(nv); // coordinate system offsets - return (STAT_OK); + return (STAT_COMPLETE); // STAT_COMPLETE suppresses a second JSON write that would cause a fault } /*********************************************************************************** diff --git a/g2core/error.h b/g2core/error.h index 5c802261..ff8ec5a0 100644 --- a/g2core/error.h +++ b/g2core/error.h @@ -204,7 +204,7 @@ char *get_status_message(stat_t status); #define STAT_MAX_DEPTH_EXCEEDED 115 // JSON exceeded maximum nesting depth #define STAT_VALUE_TYPE_ERROR 116 // JSON value does not agree with variable type -#define STAT_INPUT_FROM_MUTED_CHANNEL_ERROR 117 // input from a muted channel was ignored +#define STAT_INPUT_FROM_MUTED_CHANNEL_ERROR 117 // input from a muted channel was ignored #define STAT_ERROR_118 118 #define STAT_ERROR_119 119 diff --git a/g2core/g2core.cppproj b/g2core/g2core.cppproj index f6402809..591d31b0 100644 --- a/g2core/g2core.cppproj +++ b/g2core/g2core.cppproj @@ -5,7 +5,7 @@ 7.0 com.Atmel.ARMGCC.CPP {44ea8fec-55d7-4149-8a78-a574fc26bf51} - ATSAMS70N19 + ATSAM3X8C none Executable CPP @@ -68,12 +68,12 @@ - 2000000 + 10000000 SWD com.atmel.avrdbg.tool.atmelice - J41800019454 + J41800036434 Atmel-ICE True @@ -100,9 +100,9 @@ True true - J41800019454 - 0xA11D0A00 - 2000000 + J41800036434 + 0x284E0A60 + 10000000 diff --git a/g2core/json_parser.cpp b/g2core/json_parser.cpp old mode 100755 new mode 100644 index 7a8859a9..cd9a05d0 --- a/g2core/json_parser.cpp +++ b/g2core/json_parser.cpp @@ -568,10 +568,13 @@ void json_print_response(uint8_t status, const bool only_to_muted /*= false*/) nv->valuetype = TYPE_EMPTY; } } - } while ((nv = nv->nx) != NULL); + } while ((nv = nv->nx) != NULL); // Emergency escape } - // Footer processing + // Footer processing - wind to the end of the populated blocks + if (nv == NULL) { // this can happen when processing a stale list + return; //...that already has a null-terminated footer + } while(nv->valuetype != TYPE_EMPTY) { // find a free nvObj at end of the list... if ((nv = nv->nx) == NULL) { // oops! No free nvObj! rpt_exception(STAT_JSON_OUTPUT_TOO_LONG, "json_print_response() json too long"); // report this as an exception From a647d3a0b573f926503f45b96bdfac15dfb49ec1 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Fri, 30 Dec 2016 08:31:34 -0500 Subject: [PATCH 98/98] Changed build # to 100.16 to reflect accepting PR for $$ fix (Issue #204) --- g2core/g2core_info.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/g2core/g2core_info.h b/g2core/g2core_info.h index 9beabb32..0a04019c 100644 --- a/g2core/g2core_info.h +++ b/g2core/g2core_info.h @@ -21,7 +21,7 @@ #ifndef G2CORE_INFO_H_ONCE #define G2CORE_INFO_H_ONCE -#define G2CORE_FIRMWARE_BUILD 100.15 // fix for #200 and other USB issues +#define G2CORE_FIRMWARE_BUILD 100.16 // fix issue #204 - $$ not working #ifdef GIT_VERSION #define G2CORE_FIRMWARE_BUILD_STRING GIT_VERSION #else