From ea20c05260569bdfc0520fd88d368b779011e0d0 Mon Sep 17 00:00:00 2001 From: Rob Giseburt Date: Tue, 27 Sep 2016 16:46:54 -0500 Subject: [PATCH 01/76] 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/76] 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/76] 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/76] 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/76] 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/76] 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/76] 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/76] 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/76] 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/76] 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/76] 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/76] 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/76] 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/76] 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/76] 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/76] 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/76] 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/76] 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/76] 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/76] 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/76] 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/76] 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/76] 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/76] 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/76] 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/76] 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/76] 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/76] 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/76] 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/76] 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/76] 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/76] 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/76] 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/76] =?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/76] 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/76] 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/76] 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/76] 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/76] 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/76] 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/76] 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/76] 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/76] 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/76] 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/76] 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 d0c236dc10a150503d84c3348346304824ca04c2 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Wed, 30 Nov 2016 09:09:37 -0500 Subject: [PATCH 46/76] 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 5214a7e2a1cad361b420eba3297cf89934a8169c Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Wed, 30 Nov 2016 18:54:18 -0500 Subject: [PATCH 47/76] 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 48/76] 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 49/76] 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 50/76] 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 51/76] 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 52/76] 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 53/76] 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 54/76] 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 55/76] =?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 56/76] 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 57/76] 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 58/76] 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 59/76] 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 60/76] 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 61/76] 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 62/76] 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 63/76] 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 64/76] 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 65/76] 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 66/76] 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 67/76] 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 68/76] 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 69/76] 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 70/76] 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 71/76] 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 72/76] 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 73/76] 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 74/76] =?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 75/76] 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 3999533a8bb613349674cfc8c89257991cb6eab8 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Thu, 8 Dec 2016 07:58:30 -0500 Subject: [PATCH 76/76] Updated AS7 project file for SAM3x part and a different programmer (Editorial gripe: The part and tool selections really should not be in the project file - but the .atsuo file which can be kept local, but we have no control over this. Maybe someone at Atmel/Microchip). --- g2core/g2core.cppproj | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/g2core/g2core.cppproj b/g2core/g2core.cppproj index f6402809..4669f074 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 @@ -73,7 +73,7 @@ SWD com.atmel.avrdbg.tool.atmelice - J41800019454 + J41800030015 Atmel-ICE True @@ -100,8 +100,8 @@ True true - J41800019454 - 0xA11D0A00 + J41800030015 + 0x284E0A60 2000000