Commit d4504571 authored by MagoKimbra's avatar MagoKimbra

Update and fix

parent 49ff3bfa
...@@ -44,7 +44,7 @@ ...@@ -44,7 +44,7 @@
//#define FIRMWARE_TEST // ONLY BAUDRATE 115200 //#define FIRMWARE_TEST // ONLY BAUDRATE 115200
// Some particular clients re-start sending commands only after receiving a 'wait' when there is a bed serial-connection. // Some particular clients re-start sending commands only after receiving a 'wait' when there is a bed serial-connection.
//#define NO_TIMEOUTS 1000 // Milliseconds #define NO_TIMEOUTS 1000 // Milliseconds
//#define ADVANCED_OK // Uncomment to include more info in ok command //#define ADVANCED_OK // Uncomment to include more info in ok command
/***********************************************************************/ /***********************************************************************/
......
...@@ -350,8 +350,8 @@ ...@@ -350,8 +350,8 @@
* (i.e. the software might assume it can be done instantaneously) * * (i.e. the software might assume it can be done instantaneously) *
* * * *
*****************************************************************************************/ *****************************************************************************************/
#define DEFAULT_XYJERK 10.0 // (mm/sec) #define DEFAULT_XYJERK 20.0 // (mm/sec)
#define DEFAULT_ZJERK 0.4 // (mm/sec) #define DEFAULT_ZJERK 20.0 // (mm/sec)
// max initial speed for retract moves E0... (mm/sec) per extruder // max initial speed for retract moves E0... (mm/sec) per extruder
#define DEFAULT_EJERK {5.0, 5.0, 5.0, 5.0} #define DEFAULT_EJERK {5.0, 5.0, 5.0, 5.0}
/*****************************************************************************************/ /*****************************************************************************************/
......
...@@ -93,7 +93,6 @@ ...@@ -93,7 +93,6 @@
* * * *
*****************************************************************************************/ *****************************************************************************************/
#define AUTOTEMP #define AUTOTEMP
#define AUTOTEMP_OLDWEIGHT 0.98 #define AUTOTEMP_OLDWEIGHT 0.98
/*****************************************************************************************/ /*****************************************************************************************/
...@@ -983,6 +982,8 @@ ...@@ -983,6 +982,8 @@
//#define SDEXTRASLOW // Use even slower SD transfer mode (not normally needed - uncomment if you're getting volume init error) //#define SDEXTRASLOW // Use even slower SD transfer mode (not normally needed - uncomment if you're getting volume init error)
//#define SD_CHECK_AND_RETRY // Use CRC checks and retries on the SD communication //#define SD_CHECK_AND_RETRY // Use CRC checks and retries on the SD communication
// Decomment thi if you are external SD without DETECT_PIN
//#define SD_DISABLED_DETECT
// Some RAMPS and other boards don't detect when an SD card is inserted. You can work // Some RAMPS and other boards don't detect when an SD card is inserted. You can work
// around this by connecting a push button or single throw switch to the pin defined // around this by connecting a push button or single throw switch to the pin defined
// as SD_DETECT_PIN in your board's pins definitions. // as SD_DETECT_PIN in your board's pins definitions.
......
# Sprinter Arduino Project Makefile
#
# Makefile Based on:
# Arduino 0011 Makefile
# Arduino adaptation by mellis, eighthave, oli.keller
# Marlin adaption by Daid
#
# This has been tested with Arduino 0022.
#
# This makefile allows you to build sketches from the command line
# without the Arduino environment (or Java).
#
# Detailed instructions for using the makefile:
#
# 1. Modify the line containg "ARDUINO_INSTALL_DIR" to point to the directory that
# contains the Arduino installation (for example, under Mac OS X, this
# might be /Applications/Arduino.app/Contents/Resources/Java).
#
# 2. Modify the line containing "UPLOAD_PORT" to refer to the filename
# representing the USB or serial connection to your Arduino board
# (e.g. UPLOAD_PORT = /dev/tty.USB0). If the exact name of this file
# changes, you can use * as a wildcard (e.g. UPLOAD_PORT = /dev/tty.usb*).
#
# 3. Set the line containing "MCU" to match your board's processor.
# Older one's are atmega8 based, newer ones like Arduino Mini, Bluetooth
# or Diecimila have the atmega168. If you're using a LilyPad Arduino,
# change F_CPU to 8000000. If you are using Gen7 electronics, you
# probably need to use 20000000. Either way, you must regenerate
# the speed lookup table with create_speed_lookuptable.py.
#
# 4. Type "make" and press enter to compile/verify your program.
#
# 5. Type "make upload", reset your Arduino board, and press enter to
# upload your program to the Arduino board.
#
# Note that all settings are set with ?=, this means you can override them
# from the commandline with "make HARDWARE_MOTHERBOARD=71" for example
# This defined the board you are compiling for (see boards.h for the options)
HARDWARE_MOTHERBOARD ?= 11
# Arduino source install directory, and version number
# On most linuxes this will be /usr/share/arduino
ARDUINO_INSTALL_DIR ?= /usr/share/arduino
ARDUINO_VERSION ?= 105
# You can optionally set a path to the avr-gcc tools. Requires a trailing slash. (ex: /usr/local/avr-gcc/bin)
AVR_TOOLS_PATH ?=
#Programmer configuration
UPLOAD_RATE ?= 115200
AVRDUDE_PROGRAMMER ?= wiring
# on most linuxes this will be /dev/ttyACM0 or /dev/ttyACM1
UPLOAD_PORT ?= /dev/arduino
#Directory used to build files in, contains all the build files, from object files to the final hex file
#on linux it is best to put an absolute path like /home/username/tmp .
BUILD_DIR ?= applet
# This defines whether Liquid_TWI2 support will be built
LIQUID_TWI2 ?= 0
# this defines if Wire is needed
WIRE ?= 0
############################################################################
# Below here nothing should be changed...
# Here the Arduino variant is selected by the board type
# HARDWARE_VARIANT = "arduino", "Sanguino", "Gen7", ...
# MCU = "atmega1280", "Mega2560", "atmega2560", "atmega644p", ...
#Gen7
ifeq ($(HARDWARE_MOTHERBOARD),10)
HARDWARE_VARIANT ?= Gen7
MCU ?= atmega644
F_CPU ?= 20000000
else ifeq ($(HARDWARE_MOTHERBOARD),11)
HARDWARE_VARIANT ?= Gen7
MCU ?= atmega644p
F_CPU ?= 20000000
else ifeq ($(HARDWARE_MOTHERBOARD),12)
HARDWARE_VARIANT ?= Gen7
MCU ?= atmega644p
F_CPU ?= 20000000
else ifeq ($(HARDWARE_MOTHERBOARD),13)
HARDWARE_VARIANT ?= Gen7
MCU ?= atmega1284p
F_CPU ?= 20000000
#RAMPS
else ifeq ($(HARDWARE_MOTHERBOARD),3)
HARDWARE_VARIANT ?= arduino
MCU ?= atmega2560
else ifeq ($(HARDWARE_MOTHERBOARD),33)
HARDWARE_VARIANT ?= arduino
MCU ?= atmega2560
else ifeq ($(HARDWARE_MOTHERBOARD),34)
HARDWARE_VARIANT ?= arduino
MCU ?= atmega2560
#Gen6
else ifeq ($(HARDWARE_MOTHERBOARD),5)
HARDWARE_VARIANT ?= Gen6
MCU ?= atmega644p
else ifeq ($(HARDWARE_MOTHERBOARD),51)
HARDWARE_VARIANT ?= Gen6
MCU ?= atmega644p
#Sanguinololu
else ifeq ($(HARDWARE_MOTHERBOARD),6)
HARDWARE_VARIANT ?= Sanguino
MCU ?= atmega644p
else ifeq ($(HARDWARE_MOTHERBOARD),62)
HARDWARE_VARIANT ?= Sanguino
MCU ?= atmega644p
else ifeq ($(HARDWARE_MOTHERBOARD),63)
HARDWARE_VARIANT ?= Sanguino
MCU ?= atmega644p
else ifeq ($(HARDWARE_MOTHERBOARD),65)
HARDWARE_VARIANT ?= Sanguino
MCU ?= atmega1284p
else ifeq ($(HARDWARE_MOTHERBOARD),66)
HARDWARE_VARIANT ?= Sanguino
MCU ?= atmega1284p
#Ultimaker
else ifeq ($(HARDWARE_MOTHERBOARD),7)
HARDWARE_VARIANT ?= arduino
MCU ?= atmega2560
else ifeq ($(HARDWARE_MOTHERBOARD),71)
HARDWARE_VARIANT ?= arduino
MCU ?= atmega1280
#Teensylu
else ifeq ($(HARDWARE_MOTHERBOARD),8)
HARDWARE_VARIANT ?= Teensy
MCU ?= at90usb1286
else ifeq ($(HARDWARE_MOTHERBOARD),81)
HARDWARE_VARIANT ?= Teensy
MCU ?= at90usb1286
else ifeq ($(HARDWARE_MOTHERBOARD),82)
HARDWARE_VARIANT ?= Teensy
MCU ?= at90usb646
else ifeq ($(HARDWARE_MOTHERBOARD),83)
HARDWARE_VARIANT ?= Teensy
MCU ?= at90usb1286
else ifeq ($(HARDWARE_MOTHERBOARD),84)
HARDWARE_VARIANT ?= Teensy
MCU ?= at90usb1286
#Gen3+
else ifeq ($(HARDWARE_MOTHERBOARD),9)
HARDWARE_VARIANT ?= Sanguino
MCU ?= atmega644p
#Gen3 Monolithic Electronics
else ifeq ($(HARDWARE_MOTHERBOARD),22)
HARDWARE_VARIANT ?= Sanguino
MCU ?= atmega644p
#Megatronics
else ifeq ($(HARDWARE_MOTHERBOARD),70)
HARDWARE_VARIANT ?= arduino
MCU ?= atmega2560
#Alpha OMCA board
else ifeq ($(HARDWARE_MOTHERBOARD),90)
HARDWARE_VARIANT ?= SanguinoA
MCU ?= atmega644
#Final OMCA board
else ifeq ($(HARDWARE_MOTHERBOARD),91)
HARDWARE_VARIANT ?= Sanguino
MCU ?= atmega644p
#Rambo
else ifeq ($(HARDWARE_MOTHERBOARD),301)
HARDWARE_VARIANT ?= arduino
MCU ?= atmega2560
# Azteeg
else ifeq ($(HARDWARE_MOTHERBOARD),67)
HARDWARE_VARIANT ?= arduino
MCU ?= atmega2560
else ifeq ($(HARDWARE_MOTHERBOARD),68)
HARDWARE_VARIANT ?= arduino
MCU ?= atmega2560
endif
# Be sure to regenerate speed_lookuptable.h with create_speed_lookuptable.py
# if you are setting this to something other than 16MHz
# Set to 16Mhz if not yet set.
F_CPU ?= 16000000
# Arduino containd the main source code for the Arduino
# Libraries, the "hardware variant" are for boards
# that derives from that, and their source are present in
# the main Marlin source directory
ifeq ($(HARDWARE_VARIANT), arduino)
HARDWARE_DIR = $(ARDUINO_INSTALL_DIR)/hardware
else
ifeq ($(shell [ $(ARDUINO_VERSION) -ge 100 ] && echo true), true)
HARDWARE_DIR = ../ArduinoAddons/Arduino_1.x.x
else
HARDWARE_DIR = ../ArduinoAddons/Arduino_0.xx
endif
endif
HARDWARE_SRC = $(HARDWARE_DIR)/$(HARDWARE_VARIANT)/cores/arduino
TARGET = $(notdir $(CURDIR))
# VPATH tells make to look into these directory for source files,
# there is no need to specify explicit pathnames as long as the
# directory is added here
VPATH = .
VPATH += $(BUILD_DIR)
VPATH += $(HARDWARE_SRC)
ifeq ($(HARDWARE_VARIANT), $(filter $(HARDWARE_VARIANT),arduino Teensy))
VPATH += $(ARDUINO_INSTALL_DIR)/libraries/LiquidCrystal
VPATH += $(ARDUINO_INSTALL_DIR)/libraries/SPI
ifeq ($(LIQUID_TWI2), 1)
VPATH += $(ARDUINO_INSTALL_DIR)/libraries/Wire
VPATH += $(ARDUINO_INSTALL_DIR)/libraries/Wire/utility
VPATH += $(ARDUINO_INSTALL_DIR)/libraries/LiquidTWI2
endif
ifeq ($(WIRE), 1)
VPATH += $(ARDUINO_INSTALL_DIR)/libraries/Wire
VPATH += $(ARDUINO_INSTALL_DIR)/libraries/Wire/utility
endif
else
VPATH += $(HARDWARE_DIR)/libraries/LiquidCrystal
VPATH += $(HARDWARE_DIR)/libraries/SPI
ifeq ($(LIQUID_TWI2), 1)
VPATH += $(HARDWARE_DIR)/libraries/Wire
VPATH += $(HARDWARE_DIR)/libraries/Wire/utility
VPATH += $(HARDWARE_DIR)/libraries/LiquidTWI2
endif
ifeq ($(WIRE), 1)
VPATH += $(HARDWARE_DIR)/libraries/Wire
VPATH += $(HARDWARE_DIR)/libraries/Wire/utility
endif
endif
ifeq ($(HARDWARE_VARIANT), arduino)
HARDWARE_SUB_VARIANT ?= mega
VPATH += $(ARDUINO_INSTALL_DIR)/hardware/arduino/variants/$(HARDWARE_SUB_VARIANT)
else
HARDWARE_SUB_VARIANT ?= standard
VPATH += $(HARDWARE_DIR)/$(HARDWARE_VARIANT)/variants/$(HARDWARE_SUB_VARIANT)
endif
SRC = wiring.c \
wiring_analog.c wiring_digital.c \
wiring_pulse.c \
wiring_shift.c WInterrupts.c
ifeq ($(HARDWARE_VARIANT), Teensy)
SRC = wiring.c
VPATH += $(ARDUINO_INSTALL_DIR)/hardware/teensy/cores/teensy
endif
CXXSRC = WMath.cpp WString.cpp Print.cpp Marlin_main.cpp \
MarlinSerial.cpp Sd2Card.cpp SdBaseFile.cpp SdFatUtil.cpp \
SdFile.cpp SdVolume.cpp planner.cpp stepper.cpp \
temperature.cpp cardreader.cpp configuration_store.cpp \
watchdog.cpp SPI.cpp servo.cpp Tone.cpp ultralcd.cpp digipot_mcp4451.cpp \
vector_3.cpp qr_solve.cpp buzzer.cpp
ifeq ($(LIQUID_TWI2), 0)
CXXSRC += LiquidCrystal.cpp
else
SRC += twi.c
CXXSRC += Wire.cpp LiquidTWI2.cpp
endif
ifeq ($(WIRE), 1)
SRC += twi.c
CXXSRC += Wire.cpp
endif
#Check for Arduino 1.0.0 or higher and use the correct sourcefiles for that version
ifeq ($(shell [ $(ARDUINO_VERSION) -ge 100 ] && echo true), true)
CXXSRC += main.cpp
else
SRC += pins_arduino.c main.c
endif
FORMAT = ihex
# Name of this Makefile (used for "make depend").
MAKEFILE = Makefile
# Debugging format.
# Native formats for AVR-GCC's -g are stabs [default], or dwarf-2.
# AVR (extended) COFF requires stabs, plus an avr-objcopy run.
DEBUG = stabs
OPT = s
DEFINES ?=
# Program settings
CC = $(AVR_TOOLS_PATH)avr-gcc
CXX = $(AVR_TOOLS_PATH)avr-g++
OBJCOPY = $(AVR_TOOLS_PATH)avr-objcopy
OBJDUMP = $(AVR_TOOLS_PATH)avr-objdump
AR = $(AVR_TOOLS_PATH)avr-ar
SIZE = $(AVR_TOOLS_PATH)avr-size
NM = $(AVR_TOOLS_PATH)avr-nm
AVRDUDE = avrdude
REMOVE = rm -f
MV = mv -f
# Place -D or -U options here
CDEFS = -DF_CPU=$(F_CPU) ${addprefix -D , $(DEFINES)}
CXXDEFS = $(CDEFS)
ifeq ($(HARDWARE_VARIANT), Teensy)
CDEFS += -DUSB_SERIAL
SRC += usb.c pins_teensy.c
CXXSRC += usb_api.cpp
endif
# Add all the source directories as include directories too
CINCS = ${addprefix -I ,${VPATH}}
CXXINCS = ${addprefix -I ,${VPATH}}
# Compiler flag to set the C Standard level.
# c89 - "ANSI" C
# gnu89 - c89 plus GCC extensions
# c99 - ISO C99 standard (not yet fully implemented)
# gnu99 - c99 plus GCC extensions
#CSTANDARD = -std=gnu99
CDEBUG = -g$(DEBUG)
CWARN = -Wall -Wstrict-prototypes
CTUNING = -funsigned-char -funsigned-bitfields -fpack-struct \
-fshort-enums -w -ffunction-sections -fdata-sections \
-DARDUINO=$(ARDUINO_VERSION)
ifneq ($(HARDWARE_MOTHERBOARD),)
CTUNING += -DMOTHERBOARD=${HARDWARE_MOTHERBOARD}
endif
#CEXTRA = -Wa,-adhlns=$(<:.c=.lst)
CEXTRA = -fno-use-cxa-atexit
CFLAGS := $(CDEBUG) $(CDEFS) $(CINCS) -O$(OPT) $(CWARN) $(CEXTRA) $(CTUNING)
CXXFLAGS := $(CDEFS) $(CINCS) -O$(OPT) -Wall $(CEXTRA) $(CTUNING)
#ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs
LDFLAGS = -lm
# Programming support using avrdude. Settings and variables.
AVRDUDE_PORT = $(UPLOAD_PORT)
AVRDUDE_WRITE_FLASH = -Uflash:w:$(BUILD_DIR)/$(TARGET).hex:i
ifeq ($(shell uname -s), Linux)
AVRDUDE_CONF = /etc/avrdude/avrdude.conf
else
AVRDUDE_CONF = $(ARDUINO_INSTALL_DIR)/hardware/tools/avr/etc/avrdude.conf
endif
AVRDUDE_FLAGS = -D -C$(AVRDUDE_CONF) \
-p$(MCU) -P$(AVRDUDE_PORT) -c$(AVRDUDE_PROGRAMMER) \
-b$(UPLOAD_RATE)
# Define all object files.
OBJ = ${patsubst %.c, $(BUILD_DIR)/%.o, ${SRC}}
OBJ += ${patsubst %.cpp, $(BUILD_DIR)/%.o, ${CXXSRC}}
OBJ += ${patsubst %.S, $(BUILD_DIR)/%.o, ${ASRC}}
# Define all listing files.
LST = $(ASRC:.S=.lst) $(CXXSRC:.cpp=.lst) $(SRC:.c=.lst)
# Combine all necessary flags and optional flags.
# Add target processor to flags.
ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS)
ALL_CXXFLAGS = -mmcu=$(MCU) $(CXXFLAGS)
ALL_ASFLAGS = -mmcu=$(MCU) -x assembler-with-cpp $(ASFLAGS)
# set V=1 (eg, "make V=1") to print the full commands etc.
ifneq ($V,1)
Pecho=@echo
P=@
else
Pecho=@:
P=
endif
# Default target.
all: sizeafter
build: $(BUILD_DIR) elf hex
# Creates the object directory
$(BUILD_DIR):
$P mkdir -p $(BUILD_DIR)
elf: $(BUILD_DIR)/$(TARGET).elf
hex: $(BUILD_DIR)/$(TARGET).hex
eep: $(BUILD_DIR)/$(TARGET).eep
lss: $(BUILD_DIR)/$(TARGET).lss
sym: $(BUILD_DIR)/$(TARGET).sym
# Program the device.
# Do not try to reset an arduino if it's not one
upload: $(BUILD_DIR)/$(TARGET).hex
ifeq (${AVRDUDE_PROGRAMMER}, arduino)
stty hup < $(UPLOAD_PORT); true
endif
$(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH)
ifeq (${AVRDUDE_PROGRAMMER}, arduino)
stty -hup < $(UPLOAD_PORT); true
endif
# Display size of file.
HEXSIZE = $(SIZE) --target=$(FORMAT) $(BUILD_DIR)/$(TARGET).hex
ELFSIZE = $(SIZE) --mcu=$(MCU) -C $(BUILD_DIR)/$(TARGET).elf; \
$(SIZE) $(BUILD_DIR)/$(TARGET).elf
sizebefore:
$P if [ -f $(BUILD_DIR)/$(TARGET).elf ]; then echo; echo $(MSG_SIZE_BEFORE); $(HEXSIZE); echo; fi
sizeafter: build
$P if [ -f $(BUILD_DIR)/$(TARGET).elf ]; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); echo; fi
# Convert ELF to COFF for use in debugging / simulating in AVR Studio or VMLAB.
COFFCONVERT=$(OBJCOPY) --debugging \
--change-section-address .data-0x800000 \
--change-section-address .bss-0x800000 \
--change-section-address .noinit-0x800000 \
--change-section-address .eeprom-0x810000
coff: $(BUILD_DIR)/$(TARGET).elf
$(COFFCONVERT) -O coff-avr $(BUILD_DIR)/$(TARGET).elf $(TARGET).cof
extcoff: $(TARGET).elf
$(COFFCONVERT) -O coff-ext-avr $(BUILD_DIR)/$(TARGET).elf $(TARGET).cof
.SUFFIXES: .elf .hex .eep .lss .sym
.PRECIOUS: .o
.elf.hex:
$(Pecho) " COPY $@"
$P $(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@
.elf.eep:
-$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \
--change-section-lma .eeprom=0 -O $(FORMAT) $< $@
# Create extended listing file from ELF output file.
.elf.lss:
$(OBJDUMP) -h -S $< > $@
# Create a symbol table from ELF output file.
.elf.sym:
$(NM) -n $< > $@
# Link: create ELF output file from library.
$(BUILD_DIR)/$(TARGET).elf: $(OBJ) Configuration.h
$(Pecho) " CXX $@"
$P $(CC) $(ALL_CXXFLAGS) -Wl,--gc-sections -o $@ -L. $(OBJ) $(LDFLAGS)
$(BUILD_DIR)/%.o: %.c Configuration.h Configuration_adv.h $(MAKEFILE)
$(Pecho) " CC $<"
$P $(CC) -MMD -c $(ALL_CFLAGS) $< -o $@
$(BUILD_DIR)/%.o: $(BUILD_DIR)/%.cpp Configuration.h Configuration_adv.h $(MAKEFILE)
$(Pecho) " CXX $<"
$P $(CXX) -MMD -c $(ALL_CXXFLAGS) $< -o $@
$(BUILD_DIR)/%.o: %.cpp Configuration.h Configuration_adv.h $(MAKEFILE)
$(Pecho) " CXX $<"
$P $(CXX) -MMD -c $(ALL_CXXFLAGS) $< -o $@
# Target: clean project.
clean:
$(Pecho) " RM $(BUILD_DIR)/*"
$P $(REMOVE) $(BUILD_DIR)/$(TARGET).hex $(BUILD_DIR)/$(TARGET).eep $(BUILD_DIR)/$(TARGET).cof $(BUILD_DIR)/$(TARGET).elf \
$(BUILD_DIR)/$(TARGET).map $(BUILD_DIR)/$(TARGET).sym $(BUILD_DIR)/$(TARGET).lss $(BUILD_DIR)/$(TARGET).cpp \
$(OBJ) $(LST) $(SRC:.c=.s) $(SRC:.c=.d) $(CXXSRC:.cpp=.s) $(CXXSRC:.cpp=.d)
$(Pecho) " RMDIR $(BUILD_DIR)/"
$P rm -rf $(BUILD_DIR)
.PHONY: all build elf hex eep lss sym program coff extcoff clean depend sizebefore sizeafter
# Automaticaly include the dependency files created by gcc
-include ${wildcard $(BUILD_DIR)/*.d}
/** /**
* Marlin Firmware * MarlinKimbra Firmware
* *
* Based on Sprinter and grbl. * Based on Sprinter and grbl.
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
...@@ -70,7 +70,6 @@ ...@@ -70,7 +70,6 @@
#include <SPI.h> #include <SPI.h>
#endif #endif
#if ENABLED(FIRMWARE_TEST) #if ENABLED(FIRMWARE_TEST)
#include "firmware_test.h" #include "firmware_test.h"
#endif #endif
...@@ -167,6 +166,7 @@ ...@@ -167,6 +166,7 @@
* M119 - Output Endstop status to serial port * M119 - Output Endstop status to serial port
* M120 - Enable endstop detection * M120 - Enable endstop detection
* M121 - Disable endstop detection * M121 - Disable endstop detection
* M122 - S<1=true/0=false> Enable or disable check software endstop
* M126 - Solenoid Air Valve Open (BariCUDA support by jmil) * M126 - Solenoid Air Valve Open (BariCUDA support by jmil)
* M127 - Solenoid Air Valve Closed (BariCUDA vent to atmospheric pressure by jmil) * M127 - Solenoid Air Valve Closed (BariCUDA vent to atmospheric pressure by jmil)
* M128 - EtoP Open (BariCUDA EtoP = electricity to air pressure transducer by jmil) * M128 - EtoP Open (BariCUDA EtoP = electricity to air pressure transducer by jmil)
...@@ -305,6 +305,7 @@ millis_t print_job_stop_ms = 0; ///< Print job stop time ...@@ -305,6 +305,7 @@ millis_t print_job_stop_ms = 0; ///< Print job stop time
static uint8_t target_extruder; static uint8_t target_extruder;
bool no_wait_for_cooling = true; bool no_wait_for_cooling = true;
bool target_direction; bool target_direction;
bool software_endstops = true;
unsigned long printer_usage_seconds; unsigned long printer_usage_seconds;
...@@ -993,11 +994,14 @@ void get_command() { ...@@ -993,11 +994,14 @@ void get_command() {
command[serial_count] = 0; // terminate string command[serial_count] = 0; // terminate string
// this item in the queue is not from sd // this item in the queue is not from sd
#if ENABLED(SDSUPPORT) #if ENABLED(SDSUPPORT)
fromsd[cmd_queue_index_w] = false; fromsd[cmd_queue_index_w] = false;
#endif #endif
char* npos = strchr(command, 'N');
while (*command == ' ') command++; // skip any leading spaces
char* npos = (*command == 'N') ? command : NULL; // Require the N parameter to start the line
char* apos = strchr(command, '*'); char* apos = strchr(command, '*');
if (npos) { if (npos) {
boolean M110 = strstr_P(command, PSTR("M110")) != NULL; boolean M110 = strstr_P(command, PSTR("M110")) != NULL;
if (M110) { if (M110) {
...@@ -1027,6 +1031,7 @@ void get_command() { ...@@ -1027,6 +1031,7 @@ void get_command() {
gcode_line_error(PSTR(MSG_ERR_NO_LINENUMBER_WITH_CHECKSUM), false); gcode_line_error(PSTR(MSG_ERR_NO_LINENUMBER_WITH_CHECKSUM), false);
return; return;
} }
// Movement commands alert when stopped // Movement commands alert when stopped
if (IsStopped()) { if (IsStopped()) {
char* gpos = strchr(command, 'G'); char* gpos = strchr(command, 'G');
...@@ -1043,10 +1048,13 @@ void get_command() { ...@@ -1043,10 +1048,13 @@ void get_command() {
} }
} }
} }
// If command was e-stop process now // If command was e-stop process now
if (strcmp(command, "M112") == 0) kill(PSTR(MSG_KILLED)); if (strcmp(command, "M112") == 0) kill(PSTR(MSG_KILLED));
cmd_queue_index_w = (cmd_queue_index_w + 1) % BUFSIZE; cmd_queue_index_w = (cmd_queue_index_w + 1) % BUFSIZE;
commands_in_queue += 1; commands_in_queue += 1;
serial_count = 0; //clear buffer serial_count = 0; //clear buffer
} else if (serial_char == '\\') { // Handle escapes } else if (serial_char == '\\') { // Handle escapes
if (MYSERIAL.available() > 0 && commands_in_queue < BUFSIZE) { if (MYSERIAL.available() > 0 && commands_in_queue < BUFSIZE) {
...@@ -1060,13 +1068,17 @@ void get_command() { ...@@ -1060,13 +1068,17 @@ void get_command() {
if (!comment_mode) command_queue[cmd_queue_index_w][serial_count++] = serial_char; if (!comment_mode) command_queue[cmd_queue_index_w][serial_count++] = serial_char;
} }
} }
#if ENABLED(SDSUPPORT)
#if ENABLED(SDSUPPORT)
if (!card.sdprinting || serial_count) return; if (!card.sdprinting || serial_count) return;
// '#' stops reading from SD to the buffer prematurely, so procedural macro calls are possible // '#' stops reading from SD to the buffer prematurely, so procedural macro calls are possible
// if it occurs, stop_buffering is triggered and the buffer is ran dry. // if it occurs, stop_buffering is triggered and the buffer is ran dry.
// this character _can_ occur in serial com, due to checksums. however, no checksums are used in SD printing // this character _can_ occur in serial com, due to checksums. however, no checksums are used in SD printing
static bool stop_buffering = false; static bool stop_buffering = false;
if (commands_in_queue == 0) stop_buffering = false; if (commands_in_queue == 0) stop_buffering = false;
while (!card.eof() && commands_in_queue < BUFSIZE && !stop_buffering) { while (!card.eof() && commands_in_queue < BUFSIZE && !stop_buffering) {
int16_t n = card.get(); int16_t n = card.get();
serial_char = (char)n; serial_char = (char)n;
...@@ -1087,6 +1099,7 @@ void get_command() { ...@@ -1087,6 +1099,7 @@ void get_command() {
card.checkautostart(true); card.checkautostart(true);
} }
if (serial_char == '#') stop_buffering = true; if (serial_char == '#') stop_buffering = true;
if (!serial_count) { if (!serial_count) {
comment_mode = false; //for new command comment_mode = false; //for new command
return; //if empty line return; //if empty line
...@@ -1099,12 +1112,13 @@ void get_command() { ...@@ -1099,12 +1112,13 @@ void get_command() {
// } // }
comment_mode = false; //for new command comment_mode = false; //for new command
serial_count = 0; //clear buffer serial_count = 0; //clear buffer
} else { }
else {
if (serial_char == ';') comment_mode = true; if (serial_char == ';') comment_mode = true;
if (!comment_mode) command_queue[cmd_queue_index_w][serial_count++] = serial_char; if (!comment_mode) command_queue[cmd_queue_index_w][serial_count++] = serial_char;
} }
} }
#endif // SDSUPPORT #endif // SDSUPPORT
} }
bool code_has_value() { bool code_has_value() {
...@@ -1160,13 +1174,13 @@ XYZ_CONSTS_FROM_CONFIG(signed char, home_dir, HOME_DIR); ...@@ -1160,13 +1174,13 @@ XYZ_CONSTS_FROM_CONFIG(signed char, home_dir, HOME_DIR);
#if ENABLED(DUAL_X_CARRIAGE) #if ENABLED(DUAL_X_CARRIAGE)
#define DXC_FULL_CONTROL_MODE 0 #define DXC_FULL_CONTROL_MODE 0
#define DXC_AUTO_PARK_MODE 1 #define DXC_AUTO_PARK_MODE 1
#define DXC_DUPLICATION_MODE 2 #define DXC_DUPLICATION_MODE 2
static int dual_x_carriage_mode = DEFAULT_DUAL_X_CARRIAGE_MODE; static int dual_x_carriage_mode = DEFAULT_DUAL_X_CARRIAGE_MODE;
static float x_home_pos(int extruder) { static float x_home_pos(int extruder) {
if (extruder == 0) if (extruder == 0)
return base_home_pos(X_AXIS) + home_offset[X_AXIS]; return base_home_pos(X_AXIS) + home_offset[X_AXIS];
else else
...@@ -1175,19 +1189,19 @@ static float x_home_pos(int extruder) { ...@@ -1175,19 +1189,19 @@ static float x_home_pos(int extruder) {
// This allow soft recalibration of the second extruder offset position without firmware reflash // This allow soft recalibration of the second extruder offset position without firmware reflash
// (through the M218 command). // (through the M218 command).
return (hotend_offset[X_AXIS][1] > 0) ? hotend_offset[X_AXIS][1] : X2_HOME_POS; return (hotend_offset[X_AXIS][1] > 0) ? hotend_offset[X_AXIS][1] : X2_HOME_POS;
} }
static int x_home_dir(int extruder) { static int x_home_dir(int extruder) {
return (extruder == 0) ? X_HOME_DIR : X2_HOME_DIR; return (extruder == 0) ? X_HOME_DIR : X2_HOME_DIR;
} }
static float inactive_extruder_x_pos = X2_MAX_POS; // used in mode 0 & 1 static float inactive_extruder_x_pos = X2_MAX_POS; // used in mode 0 & 1
static bool active_extruder_parked = false; // used in mode 1 & 2 static bool active_extruder_parked = false; // used in mode 1 & 2
static float raised_parked_position[NUM_AXIS]; // used in mode 1 static float raised_parked_position[NUM_AXIS]; // used in mode 1
static millis_t delayed_move_time = 0; // used in mode 1 static millis_t delayed_move_time = 0; // used in mode 1
static float duplicate_hotend_x_offset = DEFAULT_DUPLICATION_X_OFFSET; // used in mode 2 static float duplicate_hotend_x_offset = DEFAULT_DUPLICATION_X_OFFSET; // used in mode 2
static float duplicate_extruder_temp_offset = 0; // used in mode 2 static float duplicate_extruder_temp_offset = 0; // used in mode 2
bool extruder_duplication_enabled = false; // used in mode 2 bool extruder_duplication_enabled = false; // used in mode 2
#endif //DUAL_X_CARRIAGE #endif //DUAL_X_CARRIAGE
...@@ -1199,12 +1213,13 @@ void print_xyz(const char* prefix, const float x, const float y, const float z, ...@@ -1199,12 +1213,13 @@ void print_xyz(const char* prefix, const float x, const float y, const float z,
ECHO_M(")"); ECHO_M(")");
if (eol) ECHO_E; if (eol) ECHO_E;
} }
void print_xyz(const char* prefix, const float xyz[], bool eol = true) { void print_xyz(const char* prefix, const float xyz[], bool eol = true) {
print_xyz(prefix, xyz[X_AXIS], xyz[Y_AXIS], xyz[Z_AXIS], eol); print_xyz(prefix, xyz[X_AXIS], xyz[Y_AXIS], xyz[Z_AXIS], eol);
} }
static void set_axis_is_at_home(AxisEnum axis) { static void set_axis_is_at_home(AxisEnum axis) {
#if ENABLED(DUAL_X_CARRIAGE) #if ENABLED(DUAL_X_CARRIAGE)
if (axis == X_AXIS) { if (axis == X_AXIS) {
if (active_extruder != 0) { if (active_extruder != 0) {
current_position[X_AXIS] = x_home_pos(active_extruder); current_position[X_AXIS] = x_home_pos(active_extruder);
...@@ -1219,9 +1234,9 @@ static void set_axis_is_at_home(AxisEnum axis) { ...@@ -1219,9 +1234,9 @@ static void set_axis_is_at_home(AxisEnum axis) {
return; return;
} }
} }
#endif #endif
#if MECH(SCARA) #if MECH(SCARA)
if (axis == X_AXIS || axis == Y_AXIS) { if (axis == X_AXIS || axis == Y_AXIS) {
float homeposition[3]; float homeposition[3];
for (int i = 0; i < 3; i++) homeposition[i] = base_home_pos(i); for (int i = 0; i < 3; i++) homeposition[i] = base_home_pos(i);
...@@ -1250,19 +1265,19 @@ static void set_axis_is_at_home(AxisEnum axis) { ...@@ -1250,19 +1265,19 @@ static void set_axis_is_at_home(AxisEnum axis) {
min_pos[axis] = base_min_pos(axis) + home_offset[axis]; min_pos[axis] = base_min_pos(axis) + home_offset[axis];
max_pos[axis] = base_max_pos(axis) + home_offset[axis]; max_pos[axis] = base_max_pos(axis) + home_offset[axis];
} }
#elif MECH(DELTA) #elif MECH(DELTA)
current_position[axis] = base_home_pos[axis] + home_offset[axis]; current_position[axis] = base_home_pos[axis] + home_offset[axis];
min_pos[axis] = base_min_pos(axis) + home_offset[axis]; min_pos[axis] = base_min_pos(axis) + home_offset[axis];
max_pos[axis] = base_max_pos[axis] + home_offset[axis]; max_pos[axis] = base_max_pos[axis] + home_offset[axis];
#else #else
current_position[axis] = base_home_pos(axis) + home_offset[axis]; current_position[axis] = base_home_pos(axis) + home_offset[axis];
min_pos[axis] = base_min_pos(axis) + home_offset[axis]; min_pos[axis] = base_min_pos(axis) + home_offset[axis];
max_pos[axis] = base_max_pos(axis) + home_offset[axis]; max_pos[axis] = base_max_pos(axis) + home_offset[axis];
#endif #endif
#if ENABLED(AUTO_BED_LEVELING_FEATURE) && Z_HOME_DIR < 0 #if ENABLED(AUTO_BED_LEVELING_FEATURE) && Z_HOME_DIR < 0
if (axis == Z_AXIS) current_position[Z_AXIS] -= zprobe_zoffset; if (axis == Z_AXIS) current_position[Z_AXIS] -= zprobe_zoffset;
#endif #endif
if (debugLevel & DEBUG_INFO) { if (debugLevel & DEBUG_INFO) {
ECHO_SMV(DB, "set_axis_is_at_home ", (unsigned long)axis); ECHO_SMV(DB, "set_axis_is_at_home ", (unsigned long)axis);
...@@ -1276,17 +1291,12 @@ static void set_axis_is_at_home(AxisEnum axis) { ...@@ -1276,17 +1291,12 @@ static void set_axis_is_at_home(AxisEnum axis) {
*/ */
inline void set_homing_bump_feedrate(AxisEnum axis) { inline void set_homing_bump_feedrate(AxisEnum axis) {
const int homing_bump_divisor[] = HOMING_BUMP_DIVISOR; const int homing_bump_divisor[] = HOMING_BUMP_DIVISOR;
#if MECH(DELTA) int hbd = homing_bump_divisor[axis];
if (homing_bump_divisor[X_AXIS] >= 1) if (hbd < 1) {
feedrate = homing_feedrate[axis] / homing_bump_divisor[X_AXIS]; hbd = 10;
#else // No DELTA
if (homing_bump_divisor[axis] >= 1)
feedrate = homing_feedrate[axis] / homing_bump_divisor[axis];
#endif
else {
feedrate = homing_feedrate[axis] / 10;
ECHO_LM(ER, MSG_ERR_HOMING_DIV); ECHO_LM(ER, MSG_ERR_HOMING_DIV);
} }
feedrate = homing_feedrate[axis] / hbd;
} }
inline void line_to_current_position() { inline void line_to_current_position() {
plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], feedrate/60, active_extruder, active_driver); plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], feedrate/60, active_extruder, active_driver);
...@@ -1716,12 +1726,14 @@ static void clean_up_after_endstop_move() { ...@@ -1716,12 +1726,14 @@ static void clean_up_after_endstop_move() {
#endif // CARTESIAN || COREXY || COREXZ || SCARA #endif // CARTESIAN || COREXY || COREXZ || SCARA
#if MECH(DELTA) #if MECH(DELTA)
static void homeaxis(AxisEnum axis) { static void homeaxis(AxisEnum axis) {
#define HOMEAXIS_DO(LETTER) \ #define HOMEAXIS_DO(LETTER) \
((LETTER##_MIN_PIN > -1 && LETTER##_HOME_DIR==-1) || (LETTER##_MAX_PIN > -1 && LETTER##_HOME_DIR==1)) ((LETTER##_MIN_PIN > -1 && LETTER##_HOME_DIR==-1) || (LETTER##_MAX_PIN > -1 && LETTER##_HOME_DIR==1))
if (axis == X_AXIS ? HOMEAXIS_DO(X) : axis == Y_AXIS ? HOMEAXIS_DO(Y) : axis == Z_AXIS ? HOMEAXIS_DO(Z) : 0) { if (axis == X_AXIS ? HOMEAXIS_DO(X) :
axis == Y_AXIS ? HOMEAXIS_DO(Y) :
axis == Z_AXIS ? HOMEAXIS_DO(Z) :
0) {
int axis_home_dir = home_dir(axis); int axis_home_dir = home_dir(axis);
current_position[axis] = 0; current_position[axis] = 0;
...@@ -1986,9 +1998,9 @@ static void clean_up_after_endstop_move() { ...@@ -1986,9 +1998,9 @@ static void clean_up_after_endstop_move() {
float high_endstop = 0; float high_endstop = 0;
float low_endstop = 0; float low_endstop = 0;
for(int x = 0; x < 3; x++) { for (int8_t i = 0; i < 3; i++) {
if (endstop_adj[x] > high_endstop) high_endstop = endstop_adj[x]; if (endstop_adj[i] > high_endstop) high_endstop = endstop_adj[i];
if (endstop_adj[x] < low_endstop) low_endstop = endstop_adj[x]; if (endstop_adj[i] < low_endstop) low_endstop = endstop_adj[i];
} }
if (high_endstop > 0) { if (high_endstop > 0) {
...@@ -2000,7 +2012,7 @@ static void clean_up_after_endstop_move() { ...@@ -2000,7 +2012,7 @@ static void clean_up_after_endstop_move() {
set_delta_constants(); set_delta_constants();
} }
bed_safe_z = Z_RAISE_BETWEEN_PROBINGS - z_probe_offset[Z_AXIS]; bed_safe_z = 20;
} }
int fix_tower_errors() { int fix_tower_errors() {
...@@ -2033,7 +2045,7 @@ static void clean_up_after_endstop_move() { ...@@ -2033,7 +2045,7 @@ static void clean_up_after_endstop_move() {
ECHO_LMV(DB, "z_diff = ", z_diff, 5); ECHO_LMV(DB, "z_diff = ", z_diff, 5);
ECHO_LMV(DB, "high_diff = ", high_diff, 5); ECHO_LMV(DB, "high_diff = ", high_diff, 5);
//Are all errors equal? (within defined precision) // Are all errors equal? (within defined precision)
xy_equal = false; xy_equal = false;
xz_equal = false; xz_equal = false;
yz_equal = false; yz_equal = false;
...@@ -2056,17 +2068,17 @@ static void clean_up_after_endstop_move() { ...@@ -2056,17 +2068,17 @@ static void clean_up_after_endstop_move() {
ECHO_LMV(DB, "Opp Range = ", high_opp - low_opp, 5); ECHO_LMV(DB, "Opp Range = ", high_opp - low_opp, 5);
if (high_opp - low_opp < ac_prec) { if (high_opp - low_opp <= ac_prec) {
ECHO_LM(DB, "Opposite Points within Limits - Adjustment not required"); ECHO_LM(DB, "Opposite Points within Limits - Adjustment not required");
t1_err = false; t1_err = false;
t2_err = false; t2_err = false;
t3_err = false; t3_err = false;
} }
//All Towers have errors // All Towers have errors
if ((t1_err == true) and (t2_err == true) and (t3_err == true)) { if ((t1_err == true) and (t2_err == true) and (t3_err == true)) {
if ((xy_equal == false) or (xz_equal == false) or (yz_equal == false)) { if ((xy_equal == false) or (xz_equal == false) or (yz_equal == false)) {
//Errors not equal .. select the tower that needs to be adjusted // Errors not equal .. select the tower that needs to be adjusted
if (abs(high_diff - x_diff) < 0.00001) err_tower = 1; if (abs(high_diff - x_diff) < 0.00001) err_tower = 1;
if (abs(high_diff - y_diff) < 0.00001) err_tower = 2; if (abs(high_diff - y_diff) < 0.00001) err_tower = 2;
if (abs(high_diff - z_diff) < 0.00001) err_tower = 3; if (abs(high_diff - z_diff) < 0.00001) err_tower = 3;
...@@ -2081,12 +2093,14 @@ static void clean_up_after_endstop_move() { ...@@ -2081,12 +2093,14 @@ static void clean_up_after_endstop_move() {
} }
} }
//Two tower errors /*
// Two tower errors
if ((t1_err == true) and (t2_err == true) and (t3_err == false)) err_tower = 3; if ((t1_err == true) and (t2_err == true) and (t3_err == false)) err_tower = 3;
if ((t1_err == true) and (t2_err == false) and (t3_err == true)) err_tower = 2; if ((t1_err == true) and (t2_err == false) and (t3_err == true)) err_tower = 2;
if ((t1_err == false) and (t2_err == true) and (t3_err == true)) err_tower = 1; if ((t1_err == false) and (t2_err == true) and (t3_err == true)) err_tower = 1;
*/
//Single tower error // Single tower error
if ((t1_err == true) and (t2_err == false) and (t3_err == false)) err_tower = 1; if ((t1_err == true) and (t2_err == false) and (t3_err == false)) err_tower = 1;
if ((t1_err == false) and (t2_err == true) and (t3_err == false)) err_tower = 2; if ((t1_err == false) and (t2_err == true) and (t3_err == false)) err_tower = 2;
if ((t1_err == false) and (t2_err == false) and (t3_err == true)) err_tower = 3; if ((t1_err == false) and (t2_err == false) and (t3_err == true)) err_tower = 3;
...@@ -2103,7 +2117,7 @@ static void clean_up_after_endstop_move() { ...@@ -2103,7 +2117,7 @@ static void clean_up_after_endstop_move() {
ECHO_LM(DB, "Tower geometry OK"); ECHO_LM(DB, "Tower geometry OK");
} }
else { else {
//If a tower has been adjusted previously.. continue to correct by adjusting that tower! (but only if the difference between the opp points is still large) // If a tower has been adjusted previously.. continue to correct by adjusting that tower! (but only if the difference between the opp points is still large)
if (high_opp - low_opp > ac_prec * 2) { if (high_opp - low_opp > ac_prec * 2) {
if ((tower_adj[0] != 0) or (tower_adj[3] != 0)) { if ((tower_adj[0] != 0) or (tower_adj[3] != 0)) {
ECHO_LM(DB, "Tower 1 has already been adjusted"); ECHO_LM(DB, "Tower 1 has already been adjusted");
...@@ -2522,7 +2536,7 @@ static void clean_up_after_endstop_move() { ...@@ -2522,7 +2536,7 @@ static void clean_up_after_endstop_move() {
probe_count ++; probe_count ++;
} while ((probe_done == false) and (probe_count < 20)); } while ((probe_done == false) and (probe_count < 20));
bed_safe_z = probe_z + 2; bed_safe_z = probe_z + 5;
return probe_z; return probe_z;
} }
...@@ -2647,7 +2661,7 @@ static void clean_up_after_endstop_move() { ...@@ -2647,7 +2661,7 @@ static void clean_up_after_endstop_move() {
} }
refresh_cmd_timeout(); refresh_cmd_timeout();
calculate_delta(destination); calculate_delta(destination);
plan_buffer_line(delta[X_AXIS], delta[Y_AXIS], delta[Z_AXIS], destination[E_AXIS], feedrate*feedrate_multiplier/60/100.0, active_extruder, active_driver); plan_buffer_line(delta[X_AXIS], delta[Y_AXIS], delta[Z_AXIS], destination[E_AXIS], feedrate * feedrate_multiplier / 60 / 100.0, active_extruder, active_driver);
set_current_to_destination(); set_current_to_destination();
} }
...@@ -4701,17 +4715,13 @@ inline void gcode_M42() { ...@@ -4701,17 +4715,13 @@ inline void gcode_M42() {
sample_set[n] = current_position[Z_AXIS]; sample_set[n] = current_position[Z_AXIS];
//
// Get the current mean for the data points we have so far // Get the current mean for the data points we have so far
//
sum = 0.0; sum = 0.0;
for (uint8_t j = 0; j <= n; j++) sum += sample_set[j]; for (uint8_t j = 0; j <= n; j++) sum += sample_set[j];
mean = sum / (n + 1); mean = sum / (n + 1);
//
// Now, use that mean to calculate the standard deviation for the // Now, use that mean to calculate the standard deviation for the
// data points we have so far // data points we have so far
//
sum = 0.0; sum = 0.0;
for (uint8_t j = 0; j <= n; j++) { for (uint8_t j = 0; j <= n; j++) {
float ss = sample_set[j] - mean; float ss = sample_set[j] - mean;
...@@ -4899,30 +4909,30 @@ inline void gcode_M92() { ...@@ -4899,30 +4909,30 @@ inline void gcode_M92() {
plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]);
} }
// M100 Free Memory Watcher /**
// * M100 Free Memory Watcher
// This code watches the free memory block between the bottom of the heap and the top of the stack. *
// This memory block is initialized and watched via the M100 command. * This code watches the free memory block between the bottom of the heap and the top of the stack.
// * This memory block is initialized and watched via the M100 command.
// M100 I Initializes the free memory block and prints vitals statistics about the area *
// M100 F Identifies how much of the free memory block remains free and unused. It also * M100 I Initializes the free memory block and prints vitals statistics about the area
// detects and reports any corruption within the free memory block that may have * M100 F Identifies how much of the free memory block remains free and unused. It also
// happened due to errant firmware. * detects and reports any corruption within the free memory block that may have
// M100 D Does a hex display of the free memory block along with a flag for any errant * happened due to errant firmware.
// data that does not match the expected value. * M100 D Does a hex display of the free memory block along with a flag for any errant
// M100 C x Corrupts x locations within the free memory block. This is useful to check the * data that does not match the expected value.
// correctness of the M100 F and M100 D commands. * M100 C x Corrupts x locations within the free memory block. This is useful to check the
// * correctness of the M100 F and M100 D commands.
// Initial version by Roxy-3DPrintBoard *
// * Initial version by Roxy-3DPrintBoard
// *
*/
#if ENABLED(M100_FREE_MEMORY_WATCHER) #if ENABLED(M100_FREE_MEMORY_WATCHER)
inline void gcode_M100() { inline void gcode_M100() {
static int m100_not_initialized = 1; static int m100_not_initialized = 1;
unsigned char* sp, *ptr; unsigned char* sp, *ptr;
int i, j, n; int i, j, n;
//
// M100 D dumps the free memory block from __brkval to the stack pointer. // M100 D dumps the free memory block from __brkval to the stack pointer.
// malloc() eats memory from the start of the block and the stack grows // malloc() eats memory from the start of the block and the stack grows
// up from the bottom of the block. Solid 0xE5's indicate nothing has // up from the bottom of the block. Solid 0xE5's indicate nothing has
...@@ -4930,32 +4940,28 @@ inline void gcode_M92() { ...@@ -4930,32 +4940,28 @@ inline void gcode_M92() {
// the block of 0xE5's. If there is, that would indicate memory corruption // the block of 0xE5's. If there is, that would indicate memory corruption
// probably caused by bad pointers. Any unexpected values will be flagged in // probably caused by bad pointers. Any unexpected values will be flagged in
// the right hand column to help spotting them. // the right hand column to help spotting them.
//
#if ENABLED(M100_FREE_MEMORY_DUMPER) // Comment out to remove Dump sub-command #if ENABLED(M100_FREE_MEMORY_DUMPER) // Comment out to remove Dump sub-command
if ( code_seen('D') ) { if (code_seen('D')) {
ptr = (unsigned char*) __brkval; ptr = (unsigned char*) __brkval;
//
// We want to start and end the dump on a nice 16 byte boundry even though // We want to start and end the dump on a nice 16 byte boundry even though
// the values we are using are not 16 byte aligned. // the values we are using are not 16 byte aligned.
// //
ECHO_M("\n__brkval : "); ECHO_M("\n__brkval : ");
prt_hex_word( (unsigned int) ptr ); prt_hex_word((unsigned int) ptr);
ptr = (unsigned char*) ((unsigned long) ptr & 0xfff0); ptr = (unsigned char*) ((unsigned long) ptr & 0xfff0);
sp = top_of_stack(); sp = top_of_stack();
ECHO_M("\nStack Pointer : "); ECHO_M("\nStack Pointer : ");
prt_hex_word( (unsigned int) sp ); prt_hex_word((unsigned int) sp);
ECHO_M("\n"); ECHO_M("\n");
sp = (unsigned char*) ((unsigned long) sp | 0x000f); sp = (unsigned char*) ((unsigned long) sp | 0x000f);
n = sp - ptr; n = sp - ptr;
//
// This is the main loop of the Dump command. // This is the main loop of the Dump command.
// while (ptr < sp) {
while ( ptr < sp ) { prt_hex_word((unsigned int) ptr); // Print the address
prt_hex_word( (unsigned int) ptr); // Print the address
ECHO_M(":"); ECHO_M(":");
for(i = 0; i < 16; i++) { // and 16 data bytes for(i = 0; i < 16; i++) { // and 16 data bytes
prt_hex_byte( *(ptr+i)); prt_hex_byte( *(ptr+i));
...@@ -4981,11 +4987,9 @@ inline void gcode_M92() { ...@@ -4981,11 +4987,9 @@ inline void gcode_M92() {
} }
#endif #endif
//
// M100 F requests the code to return the number of free bytes in the memory pool along with // M100 F requests the code to return the number of free bytes in the memory pool along with
// other vital statistics that define the memory pool. // other vital statistics that define the memory pool.
// if (code_seen('F')) {
if ( code_seen('F') ) {
int max_addr = (int) __brkval; int max_addr = (int) __brkval;
int max_cnt = 0; int max_cnt = 0;
int block_cnt = 0; int block_cnt = 0;
...@@ -4994,69 +4998,64 @@ inline void gcode_M92() { ...@@ -4994,69 +4998,64 @@ inline void gcode_M92() {
n = sp - ptr; n = sp - ptr;
// Scan through the range looking for the biggest block of 0xE5's we can find // Scan through the range looking for the biggest block of 0xE5's we can find
for (i = 0; i < n; i++) {
for(i = 0; i < n; i++) {
if ( *(ptr+i) == (unsigned char) 0xe5) { if ( *(ptr+i) == (unsigned char) 0xe5) {
j = how_many_E5s_are_here( (unsigned char*) ptr+i ); j = how_many_E5s_are_here((unsigned char*) ptr + i);
if ( j > 8) { if ( j > 8) {
ECHO_MV("Found ", j ); ECHO_MV("Found ", j );
ECHO_M(" bytes free at 0x"); ECHO_M(" bytes free at 0x");
prt_hex_word( (int) ptr+i ); prt_hex_word((int) ptr + i);
ECHO_M("\n"); ECHO_M("\n");
i += j; i += j;
block_cnt++; block_cnt++;
} }
if ( j>max_cnt) { // We don't do anything with this information yet if (j > max_cnt) { // We don't do anything with this information yet
max_cnt = j; // but we do know where the biggest free memory block is. max_cnt = j; // but we do know where the biggest free memory block is.
max_addr = (int) ptr+i; max_addr = (int) ptr + i;
} }
} }
} }
if (block_cnt>1) if (block_cnt > 1)
ECHO_EM("\nMemory Corruption detected in free memory area.\n"); ECHO_EM("\nMemory Corruption detected in free memory area.\n");
ECHO_M("\nDone.\n"); ECHO_M("\nDone.\n");
return; return;
} }
//
// M100 C x Corrupts x locations in the free memory pool and reports the locations of the corruption. // M100 C x Corrupts x locations in the free memory pool and reports the locations of the corruption.
// This is useful to check the correctness of the M100 D and the M100 F commands. // This is useful to check the correctness of the M100 D and the M100 F commands.
//
#if ENABLED(M100_FREE_MEMORY_CORRUPTOR) #if ENABLED(M100_FREE_MEMORY_CORRUPTOR)
if ( code_seen('C') ) { if (code_seen('C')) {
int x; // x gets the # of locations to corrupt within the memory pool int x; // x gets the # of locations to corrupt within the memory pool
x = code_value(); x = code_value();
ECHO_EM("Corrupting free memory block.\n"); ECHO_EM("Corrupting free memory block.\n");
ptr = (unsigned char*) __brkval; ptr = (unsigned char*) __brkval;
ECHO_MV("\n__brkval : ",(long) ptr ); ECHO_MV("\n__brkval : ",(long) ptr);
ptr += 8; ptr += 8;
sp = top_of_stack(); sp = top_of_stack();
ECHO_MV("\nStack Pointer : ",(long) sp ); ECHO_MV("\nStack Pointer : ",(long) sp);
ECHO_EM("\n"); ECHO_EM("\n");
n = sp - ptr - 64; // -64 just to keep us from finding interrupt activity that n = sp - ptr - 64; // -64 just to keep us from finding interrupt activity that
// has altered the stack. // has altered the stack.
j = n / (x+1); j = n / (x + 1);
for(i = 1; i <= x; i++) { for(i = 1; i <= x; i++) {
*(ptr+(i*j)) = i; *(ptr + (i * j)) = i;
ECHO_M("\nCorrupting address: 0x"); ECHO_M("\nCorrupting address: 0x");
prt_hex_word( (unsigned int) (ptr+(i*j)) ); prt_hex_word((unsigned int) (ptr + (i * j)));
} }
ECHO_EM("\n"); ECHO_EM("\n");
return; return;
} }
#endif #endif
//
// M100 I Initializes the free memory pool so it can be watched and prints vital // M100 I Initializes the free memory pool so it can be watched and prints vital
// statistics that define the free memory pool. // statistics that define the free memory pool.
// if (m100_not_initialized || code_seen('I')) { // If no sub-command is specified, the first time
if (m100_not_initialized || code_seen('I') ) { // If no sub-command is specified, the first time
ECHO_EM("Initializing free memory block.\n"); // this happens, it will Initialize. ECHO_EM("Initializing free memory block.\n"); // this happens, it will Initialize.
ptr = (unsigned char*) __brkval; // Repeated M100 with no sub-command will not destroy the ptr = (unsigned char*) __brkval; // Repeated M100 with no sub-command will not destroy the
ECHO_MV("\n__brkval : ",(long) ptr ); // state of the initialized free memory pool. ECHO_MV("\n__brkval : ",(long) ptr); // state of the initialized free memory pool.
ptr += 8; ptr += 8;
sp = top_of_stack(); sp = top_of_stack();
...@@ -5073,9 +5072,9 @@ inline void gcode_M92() { ...@@ -5073,9 +5072,9 @@ inline void gcode_M92() {
*(ptr+i) = (unsigned char) 0xe5; *(ptr+i) = (unsigned char) 0xe5;
for(i = 0; i < n; i++) { for(i = 0; i < n; i++) {
if ( *(ptr+i) != (unsigned char) 0xe5 ) { if ( *(ptr + i) != (unsigned char) 0xe5) {
ECHO_MV("? address : ", (unsigned long) ptr+i ); ECHO_MV("? address : ", (unsigned long) ptr + i);
ECHO_MV("=", *(ptr+i) ); ECHO_MV("=", *(ptr + i));
ECHO_EM("\n"); ECHO_EM("\n");
} }
} }
...@@ -5086,6 +5085,7 @@ inline void gcode_M92() { ...@@ -5086,6 +5085,7 @@ inline void gcode_M92() {
return; return;
} }
#endif #endif
/** /**
* M104: Set hot end temperature * M104: Set hot end temperature
*/ */
...@@ -5348,6 +5348,18 @@ inline void gcode_M120() { enable_endstops(true); } ...@@ -5348,6 +5348,18 @@ inline void gcode_M120() { enable_endstops(true); }
*/ */
inline void gcode_M121() { enable_endstops(false); } inline void gcode_M121() { enable_endstops(false); }
/**
* M122: Disable or enable software endstops
*/
inline void gcode_M122() {
if (code_seen('S')) {
if (code_value() == 0)
software_endstops = false;
else
software_endstops = true;
}
}
#if ENABLED(BARICUDA) #if ENABLED(BARICUDA)
#if HAS(HEATER_1) #if HAS(HEATER_1)
/** /**
...@@ -7223,6 +7235,8 @@ void process_next_command() { ...@@ -7223,6 +7235,8 @@ void process_next_command() {
gcode_M120(); break; gcode_M120(); break;
case 121: // M121 Disable endstops case 121: // M121 Disable endstops
gcode_M121(); break; gcode_M121(); break;
case 122: // M121 Disable or enable software endstops
gcode_M122(); break;
#if ENABLED(BARICUDA) #if ENABLED(BARICUDA)
// PWM for HEATER_1_PIN // PWM for HEATER_1_PIN
...@@ -7467,7 +7481,7 @@ void ok_to_send() { ...@@ -7467,7 +7481,7 @@ void ok_to_send() {
} }
void clamp_to_software_endstops(float target[3]) { void clamp_to_software_endstops(float target[3]) {
if (SOFTWARE_MIN_ENDSTOPS) { if (SOFTWARE_MIN_ENDSTOPS && software_endstops) {
NOLESS(target[X_AXIS], min_pos[X_AXIS]); NOLESS(target[X_AXIS], min_pos[X_AXIS]);
NOLESS(target[Y_AXIS], min_pos[Y_AXIS]); NOLESS(target[Y_AXIS], min_pos[Y_AXIS]);
...@@ -7479,7 +7493,7 @@ void clamp_to_software_endstops(float target[3]) { ...@@ -7479,7 +7493,7 @@ void clamp_to_software_endstops(float target[3]) {
NOLESS(target[Z_AXIS], min_pos[Z_AXIS] + negative_z_offset); NOLESS(target[Z_AXIS], min_pos[Z_AXIS] + negative_z_offset);
} }
if (SOFTWARE_MAX_ENDSTOPS) { if (SOFTWARE_MAX_ENDSTOPS && software_endstops) {
NOMORE(target[X_AXIS], max_pos[X_AXIS]); NOMORE(target[X_AXIS], max_pos[X_AXIS]);
NOMORE(target[Y_AXIS], max_pos[Y_AXIS]); NOMORE(target[Y_AXIS], max_pos[Y_AXIS]);
NOMORE(target[Z_AXIS], max_pos[Z_AXIS]); NOMORE(target[Z_AXIS], max_pos[Z_AXIS]);
...@@ -7514,7 +7528,7 @@ void clamp_to_software_endstops(float target[3]) { ...@@ -7514,7 +7528,7 @@ void clamp_to_software_endstops(float target[3]) {
float difference[NUM_AXIS]; float difference[NUM_AXIS];
float addDistance[NUM_AXIS]; float addDistance[NUM_AXIS];
float fractions[NUM_AXIS]; float fractions[NUM_AXIS];
float frfm = feedrate/60*feedrate_multiplier/100.0; float frfm = feedrate / 60 * feedrate_multiplier / 100.0;
for (int8_t i = 0; i < NUM_AXIS; i++) difference[i] = target[i] - current_position[i]; for (int8_t i = 0; i < NUM_AXIS; i++) difference[i] = target[i] - current_position[i];
...@@ -7740,7 +7754,7 @@ void plan_arc( ...@@ -7740,7 +7754,7 @@ void plan_arc(
// Initialize the extruder axis // Initialize the extruder axis
arc_target[E_AXIS] = current_position[E_AXIS]; arc_target[E_AXIS] = current_position[E_AXIS];
float feed_rate = feedrate*feedrate_multiplier/60/100.0; float feed_rate = feedrate * feedrate_multiplier / 60 / 100.0;
for (i = 1; i < segments; i++) { // Increment (segments-1) for (i = 1; i < segments; i++) { // Increment (segments-1)
......
...@@ -17,15 +17,14 @@ ...@@ -17,15 +17,14 @@
#include "firmware_test.h" #include "firmware_test.h"
static char serial_answer; static char serial_answer;
void FirmwareTest() void FirmwareTest() {
{
ECHO_EM("---------- FIRMWARE TEST --------------"); ECHO_EM("---------- FIRMWARE TEST --------------");
ECHO_EM("--------- by MarlinKimbra -------------"); ECHO_EM("--------- by MarlinKimbra -------------");
ECHO_EV(MSG_FWTEST_01); ECHO_EV(MSG_FWTEST_01);
ECHO_EV(MSG_FWTEST_02); ECHO_EV(MSG_FWTEST_02);
ECHO_EV(MSG_FWTEST_YES_NO); ECHO_EV(MSG_FWTEST_YES_NO);
serial_answer = ' '; serial_answer = ' ';
while(serial_answer!='y' && serial_answer!='Y' && serial_answer!='n' && serial_answer!='N') { while (serial_answer!='y' && serial_answer!='Y' && serial_answer!='n' && serial_answer!='N') {
serial_answer = MYSERIAL.read(); serial_answer = MYSERIAL.read();
} }
if (serial_answer=='y' || serial_answer=='Y') { if (serial_answer=='y' || serial_answer=='Y') {
...@@ -33,13 +32,12 @@ void FirmwareTest() ...@@ -33,13 +32,12 @@ void FirmwareTest()
ECHO_EM(" "); ECHO_EM(" ");
ECHO_EM("***** ENDSTOP X *****"); ECHO_EM("***** ENDSTOP X *****");
#if EXIST(X_MIN_PIN) && X_MIN_PIN > -1 && X_HOME_DIR == -1 #if PIN_EXISTS(X_MIN_PIN) && (X_HOME_DIR == -1)
if (!READ(X_MIN_PIN)^X_MIN_ENDSTOP_INVERTING) { if (!READ(X_MIN_PIN)^X_MIN_ENDSTOP_INVERTING) {
ECHO_M("MIN ENDSTOP X: "); ECHO_M("MIN ENDSTOP X: ");
ECHO_EV(MSG_ENDSTOP_OPEN); ECHO_EV(MSG_ENDSTOP_OPEN);
} }
else else {
{
ECHO_M("X ENDSTOP "); ECHO_M("X ENDSTOP ");
ECHO_EM(MSG_FWTEST_ERROR); ECHO_EM(MSG_FWTEST_ERROR);
ECHO_M(MSG_FWTEST_INVERT); ECHO_M(MSG_FWTEST_INVERT);
...@@ -62,26 +60,24 @@ void FirmwareTest() ...@@ -62,26 +60,24 @@ void FirmwareTest()
ECHO_EM("X"); ECHO_EM("X");
ECHO_EV(MSG_FWTEST_YES); ECHO_EV(MSG_FWTEST_YES);
serial_answer = ' '; serial_answer = ' ';
while(serial_answer!='y' && serial_answer!='Y' && !(READ(X_MIN_PIN)^X_MIN_ENDSTOP_INVERTING)){ while (serial_answer!='y' && serial_answer!='Y' && !(READ(X_MIN_PIN)^X_MIN_ENDSTOP_INVERTING)) {
serial_answer = MYSERIAL.read(); serial_answer = MYSERIAL.read();
} }
if (READ(X_MIN_PIN)^X_MIN_ENDSTOP_INVERTING) { if (READ(X_MIN_PIN)^X_MIN_ENDSTOP_INVERTING) {
ECHO_M("MIN ENDSTOP X: "); ECHO_M("MIN ENDSTOP X: ");
ECHO_EV(MSG_ENDSTOP_HIT); ECHO_EV(MSG_ENDSTOP_HIT);
} }
else else {
{
ECHO_M("X "); ECHO_M("X ");
ECHO_EV(MSG_FWTEST_ENDSTOP_ERR); ECHO_EV(MSG_FWTEST_ENDSTOP_ERR);
return; return;
} }
#elif EXIST(X_MAX_PIN) && X_MAX_PIN > -1 && X_HOME_DIR == 1 #elif PIN_EXISTS(X_MAX_PIN) && X_HOME_DIR == 1
if (!READ(X_MAX_PIN)^X_MAX_ENDSTOP_INVERTING) { if (!READ(X_MAX_PIN)^X_MAX_ENDSTOP_INVERTING) {
ECHO_M("MAX ENDSTOP X: "); ECHO_M("MAX ENDSTOP X: ");
ECHO_EV(MSG_ENDSTOP_OPEN); ECHO_EV(MSG_ENDSTOP_OPEN);
} }
else else {
{
ECHO_M("X ENDSTOP "); ECHO_M("X ENDSTOP ");
ECHO_EM(MSG_FWTEST_ERROR); ECHO_EM(MSG_FWTEST_ERROR);
ECHO_M(MSG_FWTEST_INVERT); ECHO_M(MSG_FWTEST_INVERT);
...@@ -104,15 +100,14 @@ void FirmwareTest() ...@@ -104,15 +100,14 @@ void FirmwareTest()
ECHO_EM("X"); ECHO_EM("X");
ECHO_EV(MSG_FWTEST_YES); ECHO_EV(MSG_FWTEST_YES);
serial_answer = ' '; serial_answer = ' ';
while(serial_answer!='y' && serial_answer!='Y' && !(READ(X_MAX_PIN)^X_MAX_ENDSTOP_INVERTING)) { while (serial_answer!='y' && serial_answer!='Y' && !(READ(X_MAX_PIN)^X_MAX_ENDSTOP_INVERTING)) {
serial_answer = MYSERIAL.read(); serial_answer = MYSERIAL.read();
} }
if (READ(X_MAX_PIN)^X_MAX_ENDSTOP_INVERTING) { if (READ(X_MAX_PIN)^X_MAX_ENDSTOP_INVERTING) {
ECHO_M("MAX ENDSTOP X: "); ECHO_M("MAX ENDSTOP X: ");
ECHO_EV(MSG_ENDSTOP_HIT); ECHO_EV(MSG_ENDSTOP_HIT);
} }
else else {
{
ECHO_M("X "); ECHO_M("X ");
ECHO_EV(MSG_FWTEST_ENDSTOP_ERR); ECHO_EV(MSG_FWTEST_ENDSTOP_ERR);
return; return;
...@@ -131,13 +126,12 @@ void FirmwareTest() ...@@ -131,13 +126,12 @@ void FirmwareTest()
ECHO_EM(" "); ECHO_EM(" ");
ECHO_EM("***** ENDSTOP Y *****"); ECHO_EM("***** ENDSTOP Y *****");
#if EXIST(Y_MIN_PIN) && Y_MIN_PIN > -1 && Y_HOME_DIR == -1 #if PIN_EXISTS(Y_MIN_PIN) && Y_HOME_DIR == -1
if (!READ(Y_MIN_PIN)^Y_MIN_ENDSTOP_INVERTING){ if (!READ(Y_MIN_PIN)^Y_MIN_ENDSTOP_INVERTING) {
ECHO_M("MIN ENDSTOP Y: "); ECHO_M("MIN ENDSTOP Y: ");
ECHO_EV(MSG_ENDSTOP_OPEN); ECHO_EV(MSG_ENDSTOP_OPEN);
} }
else else {
{
ECHO_M("Y ENDSTOP "); ECHO_M("Y ENDSTOP ");
ECHO_EM(MSG_FWTEST_ERROR); ECHO_EM(MSG_FWTEST_ERROR);
ECHO_M(MSG_FWTEST_INVERT); ECHO_M(MSG_FWTEST_INVERT);
...@@ -160,26 +154,24 @@ void FirmwareTest() ...@@ -160,26 +154,24 @@ void FirmwareTest()
ECHO_EM("Y"); ECHO_EM("Y");
ECHO_EV(MSG_FWTEST_YES); ECHO_EV(MSG_FWTEST_YES);
serial_answer = ' '; serial_answer = ' ';
while(serial_answer!='y' && serial_answer!='Y' && !(READ(Y_MIN_PIN)^Y_MIN_ENDSTOP_INVERTING)){ while (serial_answer!='y' && serial_answer!='Y' && !(READ(Y_MIN_PIN)^Y_MIN_ENDSTOP_INVERTING)) {
serial_answer = MYSERIAL.read(); serial_answer = MYSERIAL.read();
} }
if (READ(Y_MIN_PIN)^Y_MIN_ENDSTOP_INVERTING){ if (READ(Y_MIN_PIN)^Y_MIN_ENDSTOP_INVERTING) {
ECHO_M("MIN ENDSTOP Y: "); ECHO_M("MIN ENDSTOP Y: ");
ECHO_EV(MSG_ENDSTOP_HIT); ECHO_EV(MSG_ENDSTOP_HIT);
} }
else else {
{
ECHO_M("Y "); ECHO_M("Y ");
ECHO_EV(MSG_FWTEST_ENDSTOP_ERR); ECHO_EV(MSG_FWTEST_ENDSTOP_ERR);
return; return;
} }
#elif EXIST(Y_MAX_PIN) && Y_MAX_PIN > -1 && Y_HOME_DIR == 1 #elif PIN_EXISTS(Y_MAX_PIN) && Y_HOME_DIR == 1
if (!READ(Y_MAX_PIN)^Y_MAX_ENDSTOP_INVERTING){ if (!READ(Y_MAX_PIN)^Y_MAX_ENDSTOP_INVERTING) {
ECHO_M("MAX ENDSTOP Y: "); ECHO_M("MAX ENDSTOP Y: ");
ECHO_EV(MSG_ENDSTOP_OPEN); ECHO_EV(MSG_ENDSTOP_OPEN);
} }
else else {
{
ECHO_M("Y ENDSTOP "); ECHO_M("Y ENDSTOP ");
ECHO_EM(MSG_FWTEST_ERROR); ECHO_EM(MSG_FWTEST_ERROR);
ECHO_M(MSG_FWTEST_INVERT); ECHO_M(MSG_FWTEST_INVERT);
...@@ -202,15 +194,14 @@ void FirmwareTest() ...@@ -202,15 +194,14 @@ void FirmwareTest()
ECHO_EM("Y"); ECHO_EM("Y");
ECHO_EV(MSG_FWTEST_YES); ECHO_EV(MSG_FWTEST_YES);
serial_answer = ' '; serial_answer = ' ';
while(serial_answer!='y' && serial_answer!='Y' && !(READ(Y_MAX_PIN)^Y_MAX_ENDSTOP_INVERTING)){ while (serial_answer!='y' && serial_answer!='Y' && !(READ(Y_MAX_PIN)^Y_MAX_ENDSTOP_INVERTING)) {
serial_answer = MYSERIAL.read(); serial_answer = MYSERIAL.read();
} }
if (READ(Y_MAX_PIN)^Y_MAX_ENDSTOP_INVERTING){ if (READ(Y_MAX_PIN)^Y_MAX_ENDSTOP_INVERTING) {
ECHO_M("MAX ENDSTOP Y: "); ECHO_M("MAX ENDSTOP Y: ");
ECHO_EV(MSG_ENDSTOP_HIT); ECHO_EV(MSG_ENDSTOP_HIT);
} }
else else {
{
ECHO_M("Y "); ECHO_M("Y ");
ECHO_EV(MSG_FWTEST_ENDSTOP_ERR); ECHO_EV(MSG_FWTEST_ENDSTOP_ERR);
return; return;
...@@ -229,13 +220,12 @@ void FirmwareTest() ...@@ -229,13 +220,12 @@ void FirmwareTest()
ECHO_EM(" "); ECHO_EM(" ");
ECHO_EM("***** ENDSTOP Z *****"); ECHO_EM("***** ENDSTOP Z *****");
#if EXIST(Z_MIN_PIN) && Z_MIN_PIN > -1 && Z_HOME_DIR == -1 #if PIN_EXISTS(Z_MIN_PIN) && Z_HOME_DIR == -1
if (!READ(Z_MIN_PIN)^Z_MIN_ENDSTOP_INVERTING){ if (!READ(Z_MIN_PIN)^Z_MIN_ENDSTOP_INVERTING) {
ECHO_M("MIN ENDSTOP Z: "); ECHO_M("MIN ENDSTOP Z: ");
ECHO_EV(MSG_ENDSTOP_OPEN); ECHO_EV(MSG_ENDSTOP_OPEN);
} }
else else {
{
ECHO_M("Z ENDSTOP "); ECHO_M("Z ENDSTOP ");
ECHO_EM(MSG_FWTEST_ERROR); ECHO_EM(MSG_FWTEST_ERROR);
ECHO_M(MSG_FWTEST_INVERT); ECHO_M(MSG_FWTEST_INVERT);
...@@ -258,26 +248,24 @@ void FirmwareTest() ...@@ -258,26 +248,24 @@ void FirmwareTest()
ECHO_EM("Z"); ECHO_EM("Z");
ECHO_EV(MSG_FWTEST_YES); ECHO_EV(MSG_FWTEST_YES);
serial_answer = ' '; serial_answer = ' ';
while(serial_answer!='y' && serial_answer!='Y' && !(READ(Z_MIN_PIN)^Z_MIN_ENDSTOP_INVERTING)){ while (serial_answer!='y' && serial_answer!='Y' && !(READ(Z_MIN_PIN)^Z_MIN_ENDSTOP_INVERTING)) {
serial_answer = MYSERIAL.read(); serial_answer = MYSERIAL.read();
} }
if (READ(Z_MIN_PIN)^Z_MIN_ENDSTOP_INVERTING){ if (READ(Z_MIN_PIN)^Z_MIN_ENDSTOP_INVERTING) {
ECHO_M("MIN ENDSTOP Z: "); ECHO_M("MIN ENDSTOP Z: ");
ECHO_EV(MSG_ENDSTOP_HIT); ECHO_EV(MSG_ENDSTOP_HIT);
} }
else else {
{
ECHO_M("Z "); ECHO_M("Z ");
ECHO_EV(MSG_FWTEST_ENDSTOP_ERR); ECHO_EV(MSG_FWTEST_ENDSTOP_ERR);
return; return;
} }
#elif EXIST(Z_MAX_PIN) && Z_MAX_PIN > -1 && Z_HOME_DIR == 1 #elif PIN_EXISTS(Z_MAX_PIN) && Z_HOME_DIR == 1
if (!READ(Z_MAX_PIN)^Z_MAX_ENDSTOP_INVERTING){ if (!READ(Z_MAX_PIN)^Z_MAX_ENDSTOP_INVERTING) {
ECHO_M("MAX ENDSTOP Z: "); ECHO_M("MAX ENDSTOP Z: ");
ECHO_EV(MSG_ENDSTOP_OPEN); ECHO_EV(MSG_ENDSTOP_OPEN);
} }
else else {
{
ECHO_M("Z ENDSTOP "); ECHO_M("Z ENDSTOP ");
ECHO_EM(MSG_FWTEST_ERROR); ECHO_EM(MSG_FWTEST_ERROR);
ECHO_M(MSG_FWTEST_INVERT); ECHO_M(MSG_FWTEST_INVERT);
...@@ -300,15 +288,14 @@ void FirmwareTest() ...@@ -300,15 +288,14 @@ void FirmwareTest()
ECHO_EM("Z"); ECHO_EM("Z");
ECHO_EV(MSG_FWTEST_YES); ECHO_EV(MSG_FWTEST_YES);
serial_answer = ' '; serial_answer = ' ';
while(serial_answer!='y' && serial_answer!='Y' && !(READ(Z_MAX_PIN)^Z_MAX_ENDSTOP_INVERTING)){ while (serial_answer!='y' && serial_answer!='Y' && !(READ(Z_MAX_PIN)^Z_MAX_ENDSTOP_INVERTING)) {
serial_answer = MYSERIAL.read(); serial_answer = MYSERIAL.read();
} }
if (READ(Z_MAX_PIN)^Z_MAX_ENDSTOP_INVERTING){ if (READ(Z_MAX_PIN)^Z_MAX_ENDSTOP_INVERTING) {
ECHO_M("MAX ENDSTOP Z: "); ECHO_M("MAX ENDSTOP Z: ");
ECHO_EV(MSG_ENDSTOP_HIT); ECHO_EV(MSG_ENDSTOP_HIT);
} }
else else {
{
ECHO_M("Z "); ECHO_M("Z ");
ECHO_EV(MSG_FWTEST_ENDSTOP_ERR); ECHO_EV(MSG_FWTEST_ENDSTOP_ERR);
return; return;
...@@ -337,14 +324,14 @@ void FirmwareTest() ...@@ -337,14 +324,14 @@ void FirmwareTest()
// Reset position to 0 // Reset position to 0
st_synchronize(); st_synchronize();
for(int8_t i=0; i < NUM_AXIS; i++) current_position[i] = 0; for (int8_t i = 0; i < NUM_AXIS; i++) current_position[i] = 0;
plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]);
ECHO_EM("***** TEST MOTOR *****"); ECHO_EM("***** TEST MOTOR *****");
ECHO_EV(MSG_FWTEST_ATTENTION); ECHO_EV(MSG_FWTEST_ATTENTION);
ECHO_EV(MSG_FWTEST_YES); ECHO_EV(MSG_FWTEST_YES);
serial_answer = ' '; serial_answer = ' ';
while(serial_answer!='y' && serial_answer!='Y'){ while (serial_answer!='y' && serial_answer!='Y') {
serial_answer = MYSERIAL.read(); serial_answer = MYSERIAL.read();
} }
ECHO_EV(MSG_FWTEST_04); ECHO_EV(MSG_FWTEST_04);
...@@ -357,15 +344,14 @@ void FirmwareTest() ...@@ -357,15 +344,14 @@ void FirmwareTest()
ECHO_EV(MSG_FWTEST_XAXIS); ECHO_EV(MSG_FWTEST_XAXIS);
ECHO_EV(MSG_FWTEST_YES_NO); ECHO_EV(MSG_FWTEST_YES_NO);
serial_answer = ' '; serial_answer = ' ';
while(serial_answer!='y' && serial_answer!='Y' && serial_answer!='n' && serial_answer!='N'){ while (serial_answer!='y' && serial_answer!='Y' && serial_answer!='n' && serial_answer!='N') {
serial_answer = MYSERIAL.read(); serial_answer = MYSERIAL.read();
} }
if(serial_answer=='y' || serial_answer=='Y'){ if (serial_answer=='y' || serial_answer=='Y') {
ECHO_EM("MOTOR X "); ECHO_EM("MOTOR X ");
ECHO_M(MSG_FWTEST_OK); ECHO_M(MSG_FWTEST_OK);
} }
else else {
{
ECHO_M(MSG_FWTEST_INVERT); ECHO_M(MSG_FWTEST_INVERT);
ECHO_M("#define INVERT_X_DIR "); ECHO_M("#define INVERT_X_DIR ");
ECHO_M(MSG_FWTEST_INTO); ECHO_M(MSG_FWTEST_INTO);
...@@ -390,15 +376,14 @@ void FirmwareTest() ...@@ -390,15 +376,14 @@ void FirmwareTest()
ECHO_EV(MSG_FWTEST_YAXIS); ECHO_EV(MSG_FWTEST_YAXIS);
ECHO_EV(MSG_FWTEST_YES_NO); ECHO_EV(MSG_FWTEST_YES_NO);
serial_answer = ' '; serial_answer = ' ';
while(serial_answer!='y' && serial_answer!='Y' && serial_answer!='n' && serial_answer!='N'){ while (serial_answer!='y' && serial_answer!='Y' && serial_answer!='n' && serial_answer!='N') {
serial_answer = MYSERIAL.read(); serial_answer = MYSERIAL.read();
} }
if(serial_answer=='y' || serial_answer=='Y'){ if (serial_answer=='y' || serial_answer=='Y') {
ECHO_EM("MOTOR Y "); ECHO_EM("MOTOR Y ");
ECHO_M(MSG_FWTEST_OK); ECHO_M(MSG_FWTEST_OK);
} }
else else {
{
ECHO_M(MSG_FWTEST_INVERT); ECHO_M(MSG_FWTEST_INVERT);
ECHO_M("#define INVERT_Y_DIR "); ECHO_M("#define INVERT_Y_DIR ");
ECHO_M(MSG_FWTEST_INTO); ECHO_M(MSG_FWTEST_INTO);
...@@ -423,15 +408,14 @@ void FirmwareTest() ...@@ -423,15 +408,14 @@ void FirmwareTest()
ECHO_EV(MSG_FWTEST_ZAXIS); ECHO_EV(MSG_FWTEST_ZAXIS);
ECHO_EV(MSG_FWTEST_YES_NO); ECHO_EV(MSG_FWTEST_YES_NO);
serial_answer = ' '; serial_answer = ' ';
while(serial_answer!='y' && serial_answer!='Y' && serial_answer!='n' && serial_answer!='N'){ while (serial_answer!='y' && serial_answer!='Y' && serial_answer!='n' && serial_answer!='N') {
serial_answer = MYSERIAL.read(); serial_answer = MYSERIAL.read();
} }
if(serial_answer=='y' || serial_answer=='Y'){ if (serial_answer=='y' || serial_answer=='Y') {
ECHO_EM("MOTOR Z "); ECHO_EM("MOTOR Z ");
ECHO_M(MSG_FWTEST_OK); ECHO_M(MSG_FWTEST_OK);
} }
else else {
{
ECHO_M(MSG_FWTEST_INVERT); ECHO_M(MSG_FWTEST_INVERT);
ECHO_M("#define INVERT_Z_DIR "); ECHO_M("#define INVERT_Z_DIR ");
ECHO_M(MSG_FWTEST_INTO); ECHO_M(MSG_FWTEST_INTO);
......
#ifndef MACROS_H #ifndef MACROS_H
#define MACROS_H #define MACROS_H
// Compiler warning on unused varable.
#define UNUSED(x) (void) (x)
// Macros for bit masks // Macros for bit masks
#define BIT(b) (1<<(b)) #define BIT(b) (1<<(b))
#define TEST(n,b) (((n)&BIT(b))!=0) #define TEST(n,b) (((n)&BIT(b))!=0)
......
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
NexPage Pmenu = NexPage(3, 0, "menu"); NexPage Pmenu = NexPage(3, 0, "menu");
NexPage Psdcard = NexPage(4, 0, "sdcard"); NexPage Psdcard = NexPage(4, 0, "sdcard");
NexPage Psetup = NexPage(5, 0, "setup"); NexPage Psetup = NexPage(5, 0, "setup");
NexPage Pmove = NexPage(6, 0, "move");
// Text // Text
NexText Hotend0 = NexText(1, 1, "t0"); NexText Hotend0 = NexText(1, 1, "t0");
...@@ -41,7 +42,6 @@ ...@@ -41,7 +42,6 @@
NexText LedStatus = NexText(1, 7, "t4"); NexText LedStatus = NexText(1, 7, "t4");
NexText LedCoord = NexText(1, 8, "t5"); NexText LedCoord = NexText(1, 8, "t5");
NexText set0 = NexText(2, 2, "set0"); NexText set0 = NexText(2, 2, "set0");
NexText set1 = NexText(2, 15, "set1");
NexText sdrow0 = NexText(4, 3, "t0"); NexText sdrow0 = NexText(4, 3, "t0");
NexText sdrow1 = NexText(4, 4, "t1"); NexText sdrow1 = NexText(4, 4, "t1");
NexText sdrow2 = NexText(4, 5, "t2"); NexText sdrow2 = NexText(4, 5, "t2");
...@@ -58,6 +58,9 @@ ...@@ -58,6 +58,9 @@
NexPicture Hend1 = NexPicture(1, 14, "p4"); NexPicture Hend1 = NexPicture(1, 14, "p4");
NexPicture Hend2 = NexPicture(1, 15, "p5"); NexPicture Hend2 = NexPicture(1, 15, "p5");
NexPicture Fanpic = NexPicture(1, 19, "p6"); NexPicture Fanpic = NexPicture(1, 19, "p6");
NexPicture NPlay = NexPicture(1, 27, "p7");
NexPicture NStop = NexPicture(1, 28, "p8");
NexPicture Exit1 = NexPicture(3, 4, "p3");
NexPicture Folder0 = NexPicture(4, 9, "p0"); NexPicture Folder0 = NexPicture(4, 9, "p0");
NexPicture Folder1 = NexPicture(4, 10, "p1"); NexPicture Folder1 = NexPicture(4, 10, "p1");
NexPicture Folder2 = NexPicture(4, 11, "p2"); NexPicture Folder2 = NexPicture(4, 11, "p2");
...@@ -65,7 +68,16 @@ ...@@ -65,7 +68,16 @@
NexPicture Folder4 = NexPicture(4, 13, "p4"); NexPicture Folder4 = NexPicture(4, 13, "p4");
NexPicture Folder5 = NexPicture(4, 14, "p5"); NexPicture Folder5 = NexPicture(4, 14, "p5");
NexPicture Folderup = NexPicture(4, 15, "p6"); NexPicture Folderup = NexPicture(4, 15, "p6");
NexPicture Exit = NexPicture(4, 16, "p7"); NexPicture Exit2 = NexPicture(4, 16, "p7");
NexPicture Exit3 = NexPicture(5, 4, "p3");
NexPicture XYHome = NexPicture(6, 5, "p4");
NexPicture XYUp = NexPicture(6, 6, "p5");
NexPicture XYRight = NexPicture(6, 7, "p6");
NexPicture XYDown = NexPicture(6, 8, "p7");
NexPicture XYLeft = NexPicture(6, 9, "p8");
NexPicture ZHome = NexPicture(6, 10, "p9");
NexPicture ZUp = NexPicture(6, 11, "p10");
NexPicture ZDown = NexPicture(6, 12, "p11");
// Progress Bar // Progress Bar
NexProgressBar sdbar = NexProgressBar(1, 26, "j0"); NexProgressBar sdbar = NexProgressBar(1, 26, "j0");
...@@ -92,6 +104,7 @@ ...@@ -92,6 +104,7 @@
// Variable // Variable
NexVar Hotend = NexVar(1, 20, "he"); NexVar Hotend = NexVar(1, 20, "he");
NexVar set1 = NexVar(2, 17, "set1");
NexVar Bed = NexVar(1, 21, "bed"); NexVar Bed = NexVar(1, 21, "bed");
NexVar filename0 = NexVar(4, 19, "va0"); NexVar filename0 = NexVar(4, 19, "va0");
NexVar filename1 = NexVar(4, 20, "va1"); NexVar filename1 = NexVar(4, 20, "va1");
...@@ -99,6 +112,7 @@ ...@@ -99,6 +112,7 @@
NexVar filename3 = NexVar(4, 22, "va3"); NexVar filename3 = NexVar(4, 22, "va3");
NexVar filename4 = NexVar(4, 23, "va4"); NexVar filename4 = NexVar(4, 23, "va4");
NexVar filename5 = NexVar(4, 24, "va5"); NexVar filename5 = NexVar(4, 24, "va5");
NexVar movecmd = NexVar(6, 18, "vacmd");
NexTouch *nex_listen_list[] = NexTouch *nex_listen_list[] =
{ {
...@@ -107,6 +121,8 @@ ...@@ -107,6 +121,8 @@
&MSD, &MSD,
&MSetup, &MSetup,
&Fanpic, &Fanpic,
&NPlay,
&NStop,
&hot0, &hot0,
&hot1, &hot1,
&hot2, &hot2,
...@@ -121,7 +137,17 @@ ...@@ -121,7 +137,17 @@
&sdrow4, &sdrow4,
&sdrow5, &sdrow5,
&Folderup, &Folderup,
&Exit, &Exit1,
&Exit2,
&Exit3,
&XYHome,
&XYUp,
&XYRight,
&XYDown,
&XYLeft,
&ZHome,
&ZUp,
&ZDown,
NULL NULL
}; };
...@@ -330,10 +356,11 @@ ...@@ -330,10 +356,11 @@
setpagesdcard(); setpagesdcard();
} }
#endif
void ExitPopCallback(void *ptr) { void ExitPopCallback(void *ptr) {
setpageInfo(); setpageInfo();
} }
#endif
void PstartPopCallback(void *ptr) { void PstartPopCallback(void *ptr) {
setpageInfo(); setpageInfo();
...@@ -400,13 +427,17 @@ ...@@ -400,13 +427,17 @@
} }
void setpagePopCallback(void *ptr) { void setpagePopCallback(void *ptr) {
if (ptr == &Menu) if (ptr == &Menu) {
PageInfo = false;
Pmenu.show(); Pmenu.show();
if (ptr == &MSetup) }
else if (ptr == &MSetup) {
PageInfo = false;
Psetup.show(); Psetup.show();
}
#if ENABLED(SDSUPPORT) #if ENABLED(SDSUPPORT)
if (ptr == &MSD) else if (ptr == &MSD)
setpagesdcard(); setpagesdcard();
#endif #endif
} }
...@@ -416,6 +447,31 @@ ...@@ -416,6 +447,31 @@
else fanSpeed = 255; else fanSpeed = 255;
} }
void setmovePopCallback(void *ptr) {
memset(buffer, 0, sizeof(buffer));
movecmd.getText(buffer, sizeof(buffer));
enqueuecommands_P(PSTR("G91"));
enqueuecommands_P(buffer);
enqueuecommands_P(PSTR("G90"));
}
void PlayPausePopCallback(void *ptr) {
if (card.cardOK && card.isFileOpen()) {
if (card.sdprinting)
card.pauseSDPrint();
else
card.startFileprint();
}
}
void StopPopCallback(void *ptr) {
quickStop();
card.sdprinting = false;
card.closeFile();
autotempShutdown();
lcd_setstatus(MSG_PRINT_ABORTED, true);
}
void lcd_init() { void lcd_init() {
delay(1000); delay(1000);
NextionON = nexInit(); NextionON = nexInit();
...@@ -425,12 +481,16 @@ ...@@ -425,12 +481,16 @@
} else { } else {
ECHO_LM(DB, "Nextion LCD connected!"); ECHO_LM(DB, "Nextion LCD connected!");
Pstart.attachPop(PstartPopCallback); Pstart.attachPop(ExitPopCallback);
Exit1.attachPop(ExitPopCallback);
Exit3.attachPop(ExitPopCallback);
#if ENABLED(SDSUPPORT) #if ENABLED(SDSUPPORT)
MSD.attachPop(setpagePopCallback, &MSD); MSD.attachPop(setpagePopCallback, &MSD);
sdlist.attachPop(sdlistPopCallback); sdlist.attachPop(sdlistPopCallback);
Exit.attachPop(ExitPopCallback); Exit2.attachPop(ExitPopCallback);
NPlay.attachPop(PlayPausePopCallback);
NStop.attachPop(StopPopCallback);
#endif #endif
#if HAS_TEMP_0 #if HAS_TEMP_0
...@@ -444,11 +504,19 @@ ...@@ -444,11 +504,19 @@
#endif #endif
Menu.attachPop(setpagePopCallback, &Menu); Menu.attachPop(setpagePopCallback, &Menu);
MSetup.attachPop(setpagePopCallback, &Menu); MSetup.attachPop(setpagePopCallback, &MSetup);
Fanpic.attachPop(setfanPopCallback, &Fanpic); Fanpic.attachPop(setfanPopCallback, &Fanpic);
m11.attachPop(sethotPopCallback, &m11); m11.attachPop(sethotPopCallback, &m11);
tup.attachPop(settempPopCallback, &tup); tup.attachPop(settempPopCallback, &tup);
tdown.attachPop(settempPopCallback, &tdown); tdown.attachPop(settempPopCallback, &tdown);
XYHome.attachPop(setmovePopCallback);
XYUp.attachPop(setmovePopCallback);
XYRight.attachPop(setmovePopCallback);
XYDown.attachPop(setmovePopCallback);
XYLeft.attachPop(setmovePopCallback);
ZHome.attachPop(setmovePopCallback);
ZUp.attachPop(setmovePopCallback);
ZDown.attachPop(setmovePopCallback);
startimer.enable(); startimer.enable();
} }
...@@ -479,7 +547,7 @@ ...@@ -479,7 +547,7 @@
} }
static void coordtoLCD() { static void coordtoLCD() {
char *valuetemp; char* valuetemp;
memset(buffer, 0, sizeof(buffer)); memset(buffer, 0, sizeof(buffer));
strcat(buffer, "X"); strcat(buffer, "X");
...@@ -545,13 +613,29 @@ ...@@ -545,13 +613,29 @@
coordtoLCD(); coordtoLCD();
#if ENABLED(SDSUPPORT) #if ENABLED(SDSUPPORT)
if (card.cardOK)
if (card.cardOK) {
MSD.setPic(7); MSD.setPic(7);
else NPlay.setPic(38);
NStop.setPic(41);
}
else {
MSD.setPic(6); MSD.setPic(6);
if (IS_SD_PRINTING) NPlay.setPic(39);
NStop.setPic(42);
}
if (card.isFileOpen()) {
if (card.sdprinting) {
// Progress bar solid part // Progress bar solid part
sdbar.setValue(card.percentDone()); sdbar.setValue(card.percentDone());
NPlay.setPic(38);
}
else {
NPlay.setPic(40);
}
}
#endif #endif
next_lcd_update_ms = ms + LCD_UPDATE_INTERVAL; next_lcd_update_ms = ms + LCD_UPDATE_INTERVAL;
......
...@@ -4,12 +4,13 @@ ...@@ -4,12 +4,13 @@
#if ENABLED(NEXTION) #if ENABLED(NEXTION)
#define LCD_UPDATE_INTERVAL 5000 #define LCD_UPDATE_INTERVAL 5000
void PstartPopCallback(void *ptr); void ExitUpPopCallback(void *ptr);
void setpagePopCallback(void *ptr); void setpagePopCallback(void *ptr);
void hotPopCallback(void *ptr); void hotPopCallback(void *ptr);
void sethotPopCallback(void *ptr); void sethotPopCallback(void *ptr);
void settempPopCallback(void *ptr); void settempPopCallback(void *ptr);
void setfanPopCallback(void *ptr); void setfanPopCallback(void *ptr);
void setmovePopCallback(void *ptr);
void lcd_update(); void lcd_update();
void lcd_init(); void lcd_init();
void lcd_setstatus(const char* message, const bool persist = false); void lcd_setstatus(const char* message, const bool persist = false);
...@@ -22,7 +23,8 @@ ...@@ -22,7 +23,8 @@
void sdfilePopCallback(void *ptr); void sdfilePopCallback(void *ptr);
void sdfolderPopCallback(void *ptr); void sdfolderPopCallback(void *ptr);
void sdfolderUpPopCallback(void *ptr); void sdfolderUpPopCallback(void *ptr);
void ExitUpPopCallback(void *ptr); void PlayPausePopCallback(void *ptr);
void StopPopCallback(void *ptr);
#endif #endif
FORCE_INLINE bool lcd_hasstatus() { return false; } FORCE_INLINE bool lcd_hasstatus() { return false; }
......
...@@ -45,10 +45,11 @@ ...@@ -45,10 +45,11 @@
#if HAS(DIGIPOTSS) #if HAS(DIGIPOTSS)
#include <SPI.h> #include <SPI.h>
#endif #endif
//=========================================================================== //===========================================================================
//============================= public variables ============================ //============================= public variables ============================
//=========================================================================== //===========================================================================
block_t *current_block; // A pointer to the block currently being traced block_t* current_block; // A pointer to the block currently being traced
//=========================================================================== //===========================================================================
...@@ -150,11 +151,13 @@ volatile signed char count_direction[NUM_AXIS] = { 1, 1, 1, 1 }; ...@@ -150,11 +151,13 @@ volatile signed char count_direction[NUM_AXIS] = { 1, 1, 1, 1 };
if (Z_HOME_DIR > 0) {\ if (Z_HOME_DIR > 0) {\
if (!(TEST(old_endstop_bits, Z_MAX) && (count_direction[Z_AXIS] > 0)) && !locked_z_motor) Z_STEP_WRITE(v); \ if (!(TEST(old_endstop_bits, Z_MAX) && (count_direction[Z_AXIS] > 0)) && !locked_z_motor) Z_STEP_WRITE(v); \
if (!(TEST(old_endstop_bits, Z2_MAX) && (count_direction[Z_AXIS] > 0)) && !locked_z2_motor) Z2_STEP_WRITE(v); \ if (!(TEST(old_endstop_bits, Z2_MAX) && (count_direction[Z_AXIS] > 0)) && !locked_z2_motor) Z2_STEP_WRITE(v); \
} else {\ } \
else { \
if (!(TEST(old_endstop_bits, Z_MIN) && (count_direction[Z_AXIS] < 0)) && !locked_z_motor) Z_STEP_WRITE(v); \ if (!(TEST(old_endstop_bits, Z_MIN) && (count_direction[Z_AXIS] < 0)) && !locked_z_motor) Z_STEP_WRITE(v); \
if (!(TEST(old_endstop_bits, Z2_MIN) && (count_direction[Z_AXIS] < 0)) && !locked_z2_motor) Z2_STEP_WRITE(v); \ if (!(TEST(old_endstop_bits, Z2_MIN) && (count_direction[Z_AXIS] < 0)) && !locked_z2_motor) Z2_STEP_WRITE(v); \
} \ } \
} else { \ } \
else { \
Z_STEP_WRITE(v); \ Z_STEP_WRITE(v); \
Z2_STEP_WRITE(v); \ Z2_STEP_WRITE(v); \
} }
...@@ -420,7 +423,7 @@ inline void update_endstops() { ...@@ -420,7 +423,7 @@ inline void update_endstops() {
COPY_BIT(current_endstop_bits, Z_MIN, Z2_MIN); COPY_BIT(current_endstop_bits, Z_MIN, Z2_MIN);
#endif #endif
byte z_test = TEST_ENDSTOP(Z_MIN) << 0 + TEST_ENDSTOP(Z2_MIN) << 1; // bit 0 for Z, bit 1 for Z2 byte z_test = TEST_ENDSTOP(Z_MIN) | (TEST_ENDSTOP(Z2_MIN) << 1); // bit 0 for Z, bit 1 for Z2
if (z_test && current_block->steps[Z_AXIS] > 0) { // z_test = Z_MIN || Z2_MIN if (z_test && current_block->steps[Z_AXIS] > 0) { // z_test = Z_MIN || Z2_MIN
endstops_trigsteps[Z_AXIS] = count_position[Z_AXIS]; endstops_trigsteps[Z_AXIS] = count_position[Z_AXIS];
...@@ -431,14 +434,14 @@ inline void update_endstops() { ...@@ -431,14 +434,14 @@ inline void update_endstops() {
#else // !Z_DUAL_ENDSTOPS #else // !Z_DUAL_ENDSTOPS
UPDATE_ENDSTOP(Z, MIN); UPDATE_ENDSTOP(Z, MIN);
#endif // !Z_DUAL_ENDSTOPS #endif // !Z_DUAL_ENDSTOPS
#endif // Z_MIN_PIN #endif // Z_MIN_PIN
#if ENABLED(Z_PROBE_ENDSTOP) #if ENABLED(Z_PROBE_ENDSTOP)
UPDATE_ENDSTOP(Z, PROBE); UPDATE_ENDSTOP(Z, PROBE);
if (TEST_ENDSTOP(Z_PROBE)) if (TEST_ENDSTOP(Z_PROBE)) {
{
endstops_trigsteps[Z_AXIS] = count_position[Z_AXIS]; endstops_trigsteps[Z_AXIS] = count_position[Z_AXIS];
endstop_hit_bits |= BIT(Z_PROBE); endstop_hit_bits |= BIT(Z_PROBE);
} }
...@@ -456,7 +459,7 @@ inline void update_endstops() { ...@@ -456,7 +459,7 @@ inline void update_endstops() {
COPY_BIT(current_endstop_bits, Z_MAX, Z2_MAX); COPY_BIT(current_endstop_bits, Z_MAX, Z2_MAX);
#endif #endif
byte z_test = TEST_ENDSTOP(Z_MAX) << 0 + TEST_ENDSTOP(Z2_MAX) << 1; // bit 0 for Z, bit 1 for Z2 byte z_test = TEST_ENDSTOP(Z_MAX) | (TEST_ENDSTOP(Z2_MAX) << 1); // bit 0 for Z, bit 1 for Z2
if (z_test && current_block->steps[Z_AXIS] > 0) { // t_test = Z_MAX || Z2_MAX if (z_test && current_block->steps[Z_AXIS] > 0) { // t_test = Z_MAX || Z2_MAX
endstops_trigsteps[Z_AXIS] = count_position[Z_AXIS]; endstops_trigsteps[Z_AXIS] = count_position[Z_AXIS];
...@@ -518,17 +521,17 @@ FORCE_INLINE unsigned short calc_timer(unsigned short step_rate) { ...@@ -518,17 +521,17 @@ FORCE_INLINE unsigned short calc_timer(unsigned short step_rate) {
if (step_rate < (F_CPU / 500000)) step_rate = (F_CPU / 500000); if (step_rate < (F_CPU / 500000)) step_rate = (F_CPU / 500000);
step_rate -= (F_CPU / 500000); // Correct for minimal speed step_rate -= (F_CPU / 500000); // Correct for minimal speed
if (step_rate >= (8 * 256)) { // higher step rate if (step_rate >= (8 * 256)) { // higher step rate
unsigned short table_address = (unsigned short)&speed_lookuptable_fast[(unsigned char)(step_rate>>8)][0]; unsigned short table_address = (unsigned short)&speed_lookuptable_fast[(unsigned char)(step_rate >> 8)][0];
unsigned char tmp_step_rate = (step_rate & 0x00ff); unsigned char tmp_step_rate = (step_rate & 0x00ff);
unsigned short gain = (unsigned short)pgm_read_word_near(table_address+2); unsigned short gain = (unsigned short)pgm_read_word_near(table_address + 2);
MultiU16X8toH16(timer, tmp_step_rate, gain); MultiU16X8toH16(timer, tmp_step_rate, gain);
timer = (unsigned short)pgm_read_word_near(table_address) - timer; timer = (unsigned short)pgm_read_word_near(table_address) - timer;
} }
else { // lower step rates else { // lower step rates
unsigned short table_address = (unsigned short)&speed_lookuptable_slow[0][0]; unsigned short table_address = (unsigned short)&speed_lookuptable_slow[0][0];
table_address += ((step_rate)>>1) & 0xfffc; table_address += ((step_rate) >> 1) & 0xfffc;
timer = (unsigned short)pgm_read_word_near(table_address); timer = (unsigned short)pgm_read_word_near(table_address);
timer -= (((unsigned short)pgm_read_word_near(table_address+2) * (unsigned char)(step_rate & 0x0007))>>3); timer -= (((unsigned short)pgm_read_word_near(table_address + 2) * (unsigned char)(step_rate & 0x0007)) >> 3);
} }
if (timer < 100) { timer = 100; MYSERIAL.print(MSG_STEPPER_TOO_HIGH); MYSERIAL.println(step_rate); }//(20kHz this should never happen) if (timer < 100) { timer = 100; MYSERIAL.print(MSG_STEPPER_TOO_HIGH); MYSERIAL.println(step_rate); }//(20kHz this should never happen)
return timer; return timer;
...@@ -728,7 +731,6 @@ ISR(TIMER1_COMPA_vect) { ...@@ -728,7 +731,6 @@ ISR(TIMER1_COMPA_vect) {
step_events_completed++; step_events_completed++;
if (step_events_completed >= current_block->step_event_count) break; if (step_events_completed >= current_block->step_event_count) break;
} }
// Calculate new timer value // Calculate new timer value
unsigned short timer; unsigned short timer;
unsigned short step_rate; unsigned short step_rate;
...@@ -745,19 +747,20 @@ ISR(TIMER1_COMPA_vect) { ...@@ -745,19 +747,20 @@ ISR(TIMER1_COMPA_vect) {
timer = calc_timer(acc_step_rate); timer = calc_timer(acc_step_rate);
OCR1A = timer; OCR1A = timer;
acceleration_time += timer; acceleration_time += timer;
#if ENABLED(ADVANCE) #if ENABLED(ADVANCE)
for(int8_t i=0; i < step_loops; i++) {
for (int8_t i = 0; i < step_loops; i++) {
advance += advance_rate; advance += advance_rate;
} }
//if (advance > current_block->advance) advance = current_block->advance; // if (advance > current_block->advance) advance = current_block->advance;
// Do E steps + advance steps // Do E steps + advance steps
e_steps[current_block->active_driver] += ((advance >>8) - old_advance); e_steps[current_block->active_driver] += ((advance >> 8) - old_advance);
old_advance = advance >>8; old_advance = advance >> 8;
#endif #endif // ADVANCE
} }
else if (step_events_completed > (unsigned long)current_block->decelerate_after) { else if (step_events_completed > (unsigned long)current_block->decelerate_after) {
MultiU24X32toH16(step_rate, deceleration_time, current_block->acceleration_rate); MultiU24X32toH16(step_rate, deceleration_time, current_block->acceleration_rate);
if (step_rate > acc_step_rate) { // Check step_rate stays positive if (step_rate > acc_step_rate) { // Check step_rate stays positive
...@@ -776,13 +779,13 @@ ISR(TIMER1_COMPA_vect) { ...@@ -776,13 +779,13 @@ ISR(TIMER1_COMPA_vect) {
OCR1A = timer; OCR1A = timer;
deceleration_time += timer; deceleration_time += timer;
#if ENABLED(ADVANCE) #if ENABLED(ADVANCE)
for(int8_t i=0; i < step_loops; i++) { for (int8_t i = 0; i < step_loops; i++) {
advance -= advance_rate; advance -= advance_rate;
} }
if (advance < final_advance) advance = final_advance; if (advance < final_advance) advance = final_advance;
// Do E steps + advance steps // Do E steps + advance steps
e_steps[current_block->active_driver] += ((advance >>8) - old_advance); e_steps[current_block->active_driver] += ((advance >> 8) - old_advance);
old_advance = advance >>8; old_advance = advance >> 8;
#endif //ADVANCE #endif //ADVANCE
} }
else { else {
...@@ -805,12 +808,11 @@ ISR(TIMER1_COMPA_vect) { ...@@ -805,12 +808,11 @@ ISR(TIMER1_COMPA_vect) {
unsigned char old_OCR0A; unsigned char old_OCR0A;
// Timer interrupt for E. e_steps is set in the main routine; // Timer interrupt for E. e_steps is set in the main routine;
// Timer 0 is shared with millies // Timer 0 is shared with millies
ISR(TIMER0_COMPA_vect) ISR(TIMER0_COMPA_vect) {
{
old_OCR0A += 52; // ~10kHz interrupt (250000 / 26 = 9615kHz) old_OCR0A += 52; // ~10kHz interrupt (250000 / 26 = 9615kHz)
OCR0A = old_OCR0A; OCR0A = old_OCR0A;
// Set E direction (Depends on E direction + advance) // Set E direction (Depends on E direction + advance)
for(unsigned char i=0; i<4;i++) { for (unsigned char i = 0; i < 4; i++) {
if (e_steps[0] != 0) { if (e_steps[0] != 0) {
E0_STEP_WRITE(INVERT_E_STEP_PIN); E0_STEP_WRITE(INVERT_E_STEP_PIN);
if (e_steps[0] < 0) { if (e_steps[0] < 0) {
...@@ -883,7 +885,6 @@ ISR(TIMER1_COMPA_vect) { ...@@ -883,7 +885,6 @@ ISR(TIMER1_COMPA_vect) {
} }
} }
#endif #endif
} }
} }
#endif // ADVANCE #endif // ADVANCE
...@@ -1116,15 +1117,14 @@ void st_init() { ...@@ -1116,15 +1117,14 @@ void st_init() {
TCCR1A &= ~BIT(WGM10); TCCR1A &= ~BIT(WGM10);
// output mode = 00 (disconnected) // output mode = 00 (disconnected)
TCCR1A &= ~(3<<COM1A0); TCCR1A &= ~(3 << COM1A0);
TCCR1A &= ~(3<<COM1B0); TCCR1A &= ~(3 << COM1B0);
// Set the timer pre-scaler // Set the timer pre-scaler
// Generally we use a divider of 8, resulting in a 2MHz timer // Generally we use a divider of 8, resulting in a 2MHz timer
// frequency on a 16MHz MCU. If you are going to change this, be // frequency on a 16MHz MCU. If you are going to change this, be
// sure to regenerate speed_lookuptable.h with // sure to regenerate speed_lookuptable.h with
// create_speed_lookuptable.py // create_speed_lookuptable.py
TCCR1B = (TCCR1B & ~(0x07<<CS10)) | (2<<CS10); TCCR1B = (TCCR1B & ~(0x07 << CS10)) | (2 << CS10);
OCR1A = 0x4000; OCR1A = 0x4000;
TCNT1 = 0; TCNT1 = 0;
...@@ -1151,7 +1151,7 @@ void st_init() { ...@@ -1151,7 +1151,7 @@ void st_init() {
*/ */
void st_synchronize() { while (blocks_queued()) idle(); } void st_synchronize() { while (blocks_queued()) idle(); }
void st_set_position(const long &x, const long &y, const long &z, const long &e) { void st_set_position(const long& x, const long& y, const long& z, const long& e) {
CRITICAL_SECTION_START; CRITICAL_SECTION_START;
count_position[X_AXIS] = x; count_position[X_AXIS] = x;
count_position[Y_AXIS] = y; count_position[Y_AXIS] = y;
...@@ -1160,7 +1160,7 @@ void st_set_position(const long &x, const long &y, const long &z, const long &e) ...@@ -1160,7 +1160,7 @@ void st_set_position(const long &x, const long &y, const long &z, const long &e)
CRITICAL_SECTION_END; CRITICAL_SECTION_END;
} }
void st_set_e_position(const long &e) { void st_set_e_position(const long& e) {
CRITICAL_SECTION_START; CRITICAL_SECTION_START;
count_position[E_AXIS] = e; count_position[E_AXIS] = e;
CRITICAL_SECTION_END; CRITICAL_SECTION_END;
...@@ -1245,7 +1245,7 @@ void quickStop() { ...@@ -1245,7 +1245,7 @@ void quickStop() {
_APPLY_DIR(AXIS, old_pin); \ _APPLY_DIR(AXIS, old_pin); \
} }
switch(axis) { switch (axis) {
case X_AXIS: case X_AXIS:
BABYSTEP_AXIS(x, X, false); BABYSTEP_AXIS(x, X, false);
...@@ -1272,10 +1272,10 @@ void quickStop() { ...@@ -1272,10 +1272,10 @@ void quickStop() {
old_y_dir_pin = Y_DIR_READ, old_y_dir_pin = Y_DIR_READ,
old_z_dir_pin = Z_DIR_READ; old_z_dir_pin = Z_DIR_READ;
//setup new step //setup new step
X_DIR_WRITE(INVERT_X_DIR^z_direction); X_DIR_WRITE(INVERT_X_DIR ^ z_direction);
Y_DIR_WRITE(INVERT_Y_DIR^z_direction); Y_DIR_WRITE(INVERT_Y_DIR ^ z_direction);
Z_DIR_WRITE(INVERT_Z_DIR^z_direction); Z_DIR_WRITE(INVERT_Z_DIR ^ z_direction);
//perform step // perform step
X_STEP_WRITE(!INVERT_X_STEP_PIN); X_STEP_WRITE(!INVERT_X_STEP_PIN);
Y_STEP_WRITE(!INVERT_Y_STEP_PIN); Y_STEP_WRITE(!INVERT_Y_STEP_PIN);
Z_STEP_WRITE(!INVERT_Z_STEP_PIN); Z_STEP_WRITE(!INVERT_Z_STEP_PIN);
...@@ -1301,11 +1301,14 @@ void quickStop() { ...@@ -1301,11 +1301,14 @@ void quickStop() {
// From Arduino DigitalPotControl example // From Arduino DigitalPotControl example
void digitalPotWrite(int address, int value) { void digitalPotWrite(int address, int value) {
#if HAS(DIGIPOTSS) #if HAS(DIGIPOTSS)
digitalWrite(DIGIPOTSS_PIN,LOW); // take the SS pin low to select the chip digitalWrite(DIGIPOTSS_PIN, LOW); // take the SS pin low to select the chip
SPI.transfer(address); // send in the address and value via SPI: SPI.transfer(address); // send in the address and value via SPI:
SPI.transfer(value); SPI.transfer(value);
digitalWrite(DIGIPOTSS_PIN,HIGH); // take the SS pin high to de-select the chip: digitalWrite(DIGIPOTSS_PIN, HIGH); // take the SS pin high to de-select the chip:
//delay(10); //delay(10);
#else
UNUSED(address);
UNUSED(value);
#endif #endif
} }
...@@ -1318,7 +1321,7 @@ void digipot_init() { ...@@ -1318,7 +1321,7 @@ void digipot_init() {
pinMode(DIGIPOTSS_PIN, OUTPUT); pinMode(DIGIPOTSS_PIN, OUTPUT);
for (int i = 0; i <= 4; i++) { for (int i = 0; i <= 4; i++) {
//digitalPotWrite(digipot_ch[i], digipot_motor_current[i]); //digitalPotWrite(digipot_ch[i], digipot_motor_current[i]);
digipot_current(i,digipot_motor_current[i]); digipot_current(i, digipot_motor_current[i]);
} }
#endif #endif
#if HAS(MOTOR_CURRENT_PWM_XY) #if HAS(MOTOR_CURRENT_PWM_XY)
...@@ -1346,31 +1349,33 @@ void digipot_current(uint8_t driver, int current) { ...@@ -1346,31 +1349,33 @@ void digipot_current(uint8_t driver, int current) {
#if HAS(DIGIPOTSS) #if HAS(DIGIPOTSS)
const uint8_t digipot_ch[] = DIGIPOT_CHANNELS; const uint8_t digipot_ch[] = DIGIPOT_CHANNELS;
digitalPotWrite(digipot_ch[driver], current); digitalPotWrite(digipot_ch[driver], current);
#endif #elif HAS(MOTOR_CURRENT_PWM_XY)
#if HAS(MOTOR_CURRENT_PWM_XY) switch (driver) {
switch(driver) {
case 0: analogWrite(MOTOR_CURRENT_PWM_XY_PIN, 255L * current / MOTOR_CURRENT_PWM_RANGE); break; case 0: analogWrite(MOTOR_CURRENT_PWM_XY_PIN, 255L * current / MOTOR_CURRENT_PWM_RANGE); break;
case 1: analogWrite(MOTOR_CURRENT_PWM_Z_PIN, 255L * current / MOTOR_CURRENT_PWM_RANGE); break; case 1: analogWrite(MOTOR_CURRENT_PWM_Z_PIN, 255L * current / MOTOR_CURRENT_PWM_RANGE); break;
case 2: analogWrite(MOTOR_CURRENT_PWM_E_PIN, 255L * current / MOTOR_CURRENT_PWM_RANGE); break; case 2: analogWrite(MOTOR_CURRENT_PWM_E_PIN, 255L * current / MOTOR_CURRENT_PWM_RANGE); break;
} }
#else
UNUSED(driver);
UNUSED(current);
#endif #endif
} }
void microstep_init() { void microstep_init() {
#if HAS(MICROSTEPS_E1) #if HAS(MICROSTEPS_E1)
pinMode(E1_MS1_PIN,OUTPUT); pinMode(E1_MS1_PIN, OUTPUT);
pinMode(E1_MS2_PIN,OUTPUT); pinMode(E1_MS2_PIN, OUTPUT);
#endif #endif
#if HAS(MICROSTEPS) #if HAS(MICROSTEPS)
pinMode(X_MS1_PIN,OUTPUT); pinMode(X_MS1_PIN, OUTPUT);
pinMode(X_MS2_PIN,OUTPUT); pinMode(X_MS2_PIN, OUTPUT);
pinMode(Y_MS1_PIN,OUTPUT); pinMode(Y_MS1_PIN, OUTPUT);
pinMode(Y_MS2_PIN,OUTPUT); pinMode(Y_MS2_PIN, OUTPUT);
pinMode(Z_MS1_PIN,OUTPUT); pinMode(Z_MS1_PIN, OUTPUT);
pinMode(Z_MS2_PIN,OUTPUT); pinMode(Z_MS2_PIN, OUTPUT);
pinMode(E0_MS1_PIN,OUTPUT); pinMode(E0_MS1_PIN, OUTPUT);
pinMode(E0_MS2_PIN,OUTPUT); pinMode(E0_MS2_PIN, OUTPUT);
const uint8_t microstep_modes[] = MICROSTEP_MODES; const uint8_t microstep_modes[] = MICROSTEP_MODES;
for (uint16_t i = 0; i < COUNT(microstep_modes); i++) for (uint16_t i = 0; i < COUNT(microstep_modes); i++)
microstep_mode(i, microstep_modes[i]); microstep_mode(i, microstep_modes[i]);
...@@ -1378,7 +1383,7 @@ void microstep_init() { ...@@ -1378,7 +1383,7 @@ void microstep_init() {
} }
void microstep_ms(uint8_t driver, int8_t ms1, int8_t ms2) { void microstep_ms(uint8_t driver, int8_t ms1, int8_t ms2) {
if (ms1 >= 0) switch(driver) { if (ms1 >= 0) switch (driver) {
case 0: digitalWrite(X_MS1_PIN, ms1); break; case 0: digitalWrite(X_MS1_PIN, ms1); break;
case 1: digitalWrite(Y_MS1_PIN, ms1); break; case 1: digitalWrite(Y_MS1_PIN, ms1); break;
case 2: digitalWrite(Z_MS1_PIN, ms1); break; case 2: digitalWrite(Z_MS1_PIN, ms1); break;
...@@ -1387,7 +1392,7 @@ void microstep_ms(uint8_t driver, int8_t ms1, int8_t ms2) { ...@@ -1387,7 +1392,7 @@ void microstep_ms(uint8_t driver, int8_t ms1, int8_t ms2) {
case 4: digitalWrite(E1_MS1_PIN, ms1); break; case 4: digitalWrite(E1_MS1_PIN, ms1); break;
#endif #endif
} }
if (ms2 >= 0) switch(driver) { if (ms2 >= 0) switch (driver) {
case 0: digitalWrite(X_MS2_PIN, ms2); break; case 0: digitalWrite(X_MS2_PIN, ms2); break;
case 1: digitalWrite(Y_MS2_PIN, ms2); break; case 1: digitalWrite(Y_MS2_PIN, ms2); break;
case 2: digitalWrite(Z_MS2_PIN, ms2); break; case 2: digitalWrite(Z_MS2_PIN, ms2); break;
...@@ -1399,14 +1404,14 @@ void microstep_ms(uint8_t driver, int8_t ms1, int8_t ms2) { ...@@ -1399,14 +1404,14 @@ void microstep_ms(uint8_t driver, int8_t ms1, int8_t ms2) {
} }
void microstep_mode(uint8_t driver, uint8_t stepping_mode) { void microstep_mode(uint8_t driver, uint8_t stepping_mode) {
switch(stepping_mode) { switch (stepping_mode) {
case 1: microstep_ms(driver,MICROSTEP1); break; case 1: microstep_ms(driver, MICROSTEP1); break;
case 2: microstep_ms(driver,MICROSTEP2); break; case 2: microstep_ms(driver, MICROSTEP2); break;
case 4: microstep_ms(driver,MICROSTEP4); break; case 4: microstep_ms(driver, MICROSTEP4); break;
case 8: microstep_ms(driver,MICROSTEP8); break; case 8: microstep_ms(driver, MICROSTEP8); break;
case 16: microstep_ms(driver,MICROSTEP16); break; case 16: microstep_ms(driver, MICROSTEP16); break;
#if MB(ALLIGATOR) #if MB(ALLIGATOR)
case 32: microstep_ms(driver,MICROSTEP32); break; case 32: microstep_ms(driver, MICROSTEP32); break;
#endif #endif
} }
} }
......
...@@ -45,7 +45,7 @@ ...@@ -45,7 +45,7 @@
//================================== macros ================================= //================================== macros =================================
//=========================================================================== //===========================================================================
#if ENABLED(K1) // Defined in Configuration.h in the PID settings #if ENABLED(K1) // Defined in Configuration_base.h in the PID settings
#define K2 (1.0 - K1) #define K2 (1.0 - K1)
#endif #endif
...@@ -96,7 +96,7 @@ unsigned char soft_pwm_bed; ...@@ -96,7 +96,7 @@ unsigned char soft_pwm_bed;
#if ENABLED(THERMAL_PROTECTION_HOTENDS) || ENABLED(THERMAL_PROTECTION_BED) #if ENABLED(THERMAL_PROTECTION_HOTENDS) || ENABLED(THERMAL_PROTECTION_BED)
enum TRState { TRReset, TRInactive, TRFirstHeating, TRStable, TRRunaway }; enum TRState { TRReset, TRInactive, TRFirstHeating, TRStable, TRRunaway };
void thermal_runaway_protection(TRState *state, millis_t *timer, float temperature, float target_temperature, int heater_id, int period_seconds, int hysteresis_degc); void thermal_runaway_protection(TRState* state, millis_t* timer, float temperature, float target_temperature, int heater_id, int period_seconds, int hysteresis_degc);
#if ENABLED(THERMAL_PROTECTION_HOTENDS) #if ENABLED(THERMAL_PROTECTION_HOTENDS)
static TRState thermal_runaway_state_machine[4] = { TRReset, TRReset, TRReset, TRReset }; static TRState thermal_runaway_state_machine[4] = { TRReset, TRReset, TRReset, TRReset };
static millis_t thermal_runaway_timer[4]; // = {0,0,0,0}; static millis_t thermal_runaway_timer[4]; // = {0,0,0,0};
...@@ -150,7 +150,6 @@ static volatile bool temp_meas_ready = false; ...@@ -150,7 +150,6 @@ static volatile bool temp_meas_ready = false;
#else //PIDTEMPBED #else //PIDTEMPBED
static millis_t next_bed_check_ms; static millis_t next_bed_check_ms;
#endif //PIDTEMPBED #endif //PIDTEMPBED
static unsigned char soft_pwm[HOTENDS]; static unsigned char soft_pwm[HOTENDS];
#if ENABLED(FAN_SOFT_PWM) #if ENABLED(FAN_SOFT_PWM)
...@@ -183,10 +182,10 @@ static int maxttemp[HOTENDS] = ARRAY_BY_HOTENDS1(16383); ...@@ -183,10 +182,10 @@ static int maxttemp[HOTENDS] = ARRAY_BY_HOTENDS1(16383);
#endif #endif
#if ENABLED(TEMP_SENSOR_1_AS_REDUNDANT) #if ENABLED(TEMP_SENSOR_1_AS_REDUNDANT)
static void *heater_ttbl_map[2] = {(void *)HEATER_0_TEMPTABLE, (void *)HEATER_1_TEMPTABLE }; static void* heater_ttbl_map[2] = {(void*)HEATER_0_TEMPTABLE, (void*)HEATER_1_TEMPTABLE };
static uint8_t heater_ttbllen_map[2] = { HEATER_0_TEMPTABLE_LEN, HEATER_1_TEMPTABLE_LEN }; static uint8_t heater_ttbllen_map[2] = { HEATER_0_TEMPTABLE_LEN, HEATER_1_TEMPTABLE_LEN };
#else #else
static void *heater_ttbl_map[HOTENDS] = ARRAY_BY_HOTENDS( (void *)HEATER_0_TEMPTABLE, (void *)HEATER_1_TEMPTABLE, (void *)HEATER_2_TEMPTABLE, (void *)HEATER_3_TEMPTABLE ); static void* heater_ttbl_map[HOTENDS] = ARRAY_BY_HOTENDS( (void*)HEATER_0_TEMPTABLE, (void*)HEATER_1_TEMPTABLE, (void*)HEATER_2_TEMPTABLE, (void*)HEATER_3_TEMPTABLE );
static uint8_t heater_ttbllen_map[HOTENDS] = ARRAY_BY_HOTENDS( HEATER_0_TEMPTABLE_LEN, HEATER_1_TEMPTABLE_LEN, HEATER_2_TEMPTABLE_LEN, HEATER_3_TEMPTABLE_LEN ); static uint8_t heater_ttbllen_map[HOTENDS] = ARRAY_BY_HOTENDS( HEATER_0_TEMPTABLE_LEN, HEATER_1_TEMPTABLE_LEN, HEATER_2_TEMPTABLE_LEN, HEATER_3_TEMPTABLE_LEN );
#endif #endif
...@@ -199,6 +198,10 @@ static void updateTemperaturesFromRawValues(); ...@@ -199,6 +198,10 @@ static void updateTemperaturesFromRawValues();
millis_t watch_heater_next_ms[HOTENDS] = { 0 }; millis_t watch_heater_next_ms[HOTENDS] = { 0 };
#endif #endif
#if DISABLED(SOFT_PWM_SCALE)
#define SOFT_PWM_SCALE 0
#endif
#if ENABLED(FILAMENT_SENSOR) #if ENABLED(FILAMENT_SENSOR)
static int meas_shift_index; //used to point to a delayed sample in buffer for filament width sensor static int meas_shift_index; //used to point to a delayed sample in buffer for filament width sensor
#endif #endif
...@@ -400,6 +403,9 @@ void updatePID() { ...@@ -400,6 +403,9 @@ void updatePID() {
for (int h = 0; h < HOTENDS; h++) { for (int h = 0; h < HOTENDS; h++) {
temp_iState_max[h] = PID_INTEGRAL_DRIVE_MAX / PID_PARAM(Ki,h); temp_iState_max[h] = PID_INTEGRAL_DRIVE_MAX / PID_PARAM(Ki,h);
} }
#if ENABLED(PID_ADD_EXTRUSION_RATE)
for (int e = 0; e < EXTRUDERS; e++) last_position[e] = 0;
#endif
#endif #endif
#if ENABLED(PIDTEMPBED) #if ENABLED(PIDTEMPBED)
temp_iState_max_bed = PID_BED_INTEGRAL_DRIVE_MAX / bedKi; temp_iState_max_bed = PID_BED_INTEGRAL_DRIVE_MAX / bedKi;
...@@ -432,8 +438,7 @@ void checkExtruderAutoFans() { ...@@ -432,8 +438,7 @@ void checkExtruderAutoFans() {
fanState |= 1; fanState |= 1;
#endif #endif
#if HAS(AUTO_FAN_1) #if HAS(AUTO_FAN_1)
if (current_temperature[1] > EXTRUDER_AUTO_FAN_TEMPERATURE) if (current_temperature[1] > EXTRUDER_AUTO_FAN_TEMPERATURE) {
{
if (EXTRUDER_1_AUTO_FAN_PIN == EXTRUDER_0_AUTO_FAN_PIN) if (EXTRUDER_1_AUTO_FAN_PIN == EXTRUDER_0_AUTO_FAN_PIN)
fanState |= 1; fanState |= 1;
else else
...@@ -441,8 +446,7 @@ void checkExtruderAutoFans() { ...@@ -441,8 +446,7 @@ void checkExtruderAutoFans() {
} }
#endif #endif
#if HAS(AUTO_FAN_2) #if HAS(AUTO_FAN_2)
if (current_temperature[2] > EXTRUDER_AUTO_FAN_TEMPERATURE) if (current_temperature[2] > EXTRUDER_AUTO_FAN_TEMPERATURE) {
{
if (EXTRUDER_2_AUTO_FAN_PIN == EXTRUDER_0_AUTO_FAN_PIN) if (EXTRUDER_2_AUTO_FAN_PIN == EXTRUDER_0_AUTO_FAN_PIN)
fanState |= 1; fanState |= 1;
else if (EXTRUDER_2_AUTO_FAN_PIN == EXTRUDER_1_AUTO_FAN_PIN) else if (EXTRUDER_2_AUTO_FAN_PIN == EXTRUDER_1_AUTO_FAN_PIN)
...@@ -452,8 +456,7 @@ void checkExtruderAutoFans() { ...@@ -452,8 +456,7 @@ void checkExtruderAutoFans() {
} }
#endif #endif
#if HAS(AUTO_FAN_3) #if HAS(AUTO_FAN_3)
if (current_temperature[3] > EXTRUDER_AUTO_FAN_TEMPERATURE) if (current_temperature[3] > EXTRUDER_AUTO_FAN_TEMPERATURE) {
{
if (EXTRUDER_3_AUTO_FAN_PIN == EXTRUDER_0_AUTO_FAN_PIN) if (EXTRUDER_3_AUTO_FAN_PIN == EXTRUDER_0_AUTO_FAN_PIN)
fanState |= 1; fanState |= 1;
else if (EXTRUDER_3_AUTO_FAN_PIN == EXTRUDER_1_AUTO_FAN_PIN) else if (EXTRUDER_3_AUTO_FAN_PIN == EXTRUDER_1_AUTO_FAN_PIN)
...@@ -491,7 +494,7 @@ void checkExtruderAutoFans() { ...@@ -491,7 +494,7 @@ void checkExtruderAutoFans() {
// //
// Temperature Error Handlers // Temperature Error Handlers
// //
inline void _temp_error(int h, const char *serial_msg, const char *lcd_msg) { inline void _temp_error(int h, const char* serial_msg, const char* lcd_msg) {
static bool killed = false; static bool killed = false;
if (IsRunning()) { if (IsRunning()) {
ECHO_S(ER); ECHO_S(ER);
...@@ -527,7 +530,7 @@ float get_pid_output(int h) { ...@@ -527,7 +530,7 @@ float get_pid_output(int h) {
pid_output = constrain(target_temperature[h], 0, PID_MAX); pid_output = constrain(target_temperature[h], 0, PID_MAX);
#else #else
pid_error[h] = target_temperature[h] - current_temperature[h]; pid_error[h] = target_temperature[h] - current_temperature[h];
dTerm[h] = K2 * PID_PARAM(Kd,h) * (current_temperature[h] - temp_dState[h]) + K1 * dTerm[h]; dTerm[h] = K2 * PID_PARAM(Kd, h) * (current_temperature[h] - temp_dState[h]) + K1 * dTerm[h];
temp_dState[h] = current_temperature[h]; temp_dState[h] = current_temperature[h];
if (pid_error[h] > PID_FUNCTIONAL_RANGE) { if (pid_error[h] > PID_FUNCTIONAL_RANGE) {
pid_output = BANG_MAX; pid_output = BANG_MAX;
...@@ -556,7 +559,8 @@ float get_pid_output(int h) { ...@@ -556,7 +559,8 @@ float get_pid_output(int h) {
if (e_position > last_position[active_extruder]) { if (e_position > last_position[active_extruder]) {
lpq[lpq_ptr++] = e_position - last_position[active_extruder]; lpq[lpq_ptr++] = e_position - last_position[active_extruder];
last_position[active_extruder] = e_position; last_position[active_extruder] = e_position;
} else { }
else {
lpq[lpq_ptr++] = 0; lpq[lpq_ptr++] = 0;
} }
if (lpq_ptr >= lpq_len) lpq_ptr = 0; if (lpq_ptr >= lpq_len) lpq_ptr = 0;
...@@ -795,24 +799,24 @@ static float analog2temp(int raw, uint8_t e) { ...@@ -795,24 +799,24 @@ static float analog2temp(int raw, uint8_t e) {
if (heater_ttbl_map[e] != NULL) { if (heater_ttbl_map[e] != NULL) {
float celsius = 0; float celsius = 0;
uint8_t i; uint8_t i;
short (*tt)[][2] = (short (*)[][2])(heater_ttbl_map[e]); short(*tt)[][2] = (short(*)[][2])(heater_ttbl_map[e]);
for (i = 1; i < heater_ttbllen_map[e]; i++) { for (i = 1; i < heater_ttbllen_map[e]; i++) {
if (PGM_RD_W((*tt)[i][0]) > raw) { if (PGM_RD_W((*tt)[i][0]) > raw) {
celsius = PGM_RD_W((*tt)[i-1][1]) + celsius = PGM_RD_W((*tt)[i - 1][1]) +
(raw - PGM_RD_W((*tt)[i-1][0])) * (raw - PGM_RD_W((*tt)[i - 1][0])) *
(float)(PGM_RD_W((*tt)[i][1]) - PGM_RD_W((*tt)[i-1][1])) / (float)(PGM_RD_W((*tt)[i][1]) - PGM_RD_W((*tt)[i - 1][1])) /
(float)(PGM_RD_W((*tt)[i][0]) - PGM_RD_W((*tt)[i-1][0])); (float)(PGM_RD_W((*tt)[i][0]) - PGM_RD_W((*tt)[i - 1][0]));
break; break;
} }
} }
// Overflow: Set to last value in the table // Overflow: Set to last value in the table
if (i == heater_ttbllen_map[e]) celsius = PGM_RD_W((*tt)[i-1][1]); if (i == heater_ttbllen_map[e]) celsius = PGM_RD_W((*tt)[i - 1][1]);
return celsius; return celsius;
} }
return ((raw * ((5.0 * 100.0) / 1023.0) / OVERSAMPLENR) * TEMP_SENSOR_AD595_GAIN) + TEMP_SENSOR_AD595_OFFSET; return ((raw * ((5.0 * 100.0) / 1024.0) / OVERSAMPLENR) * TEMP_SENSOR_AD595_GAIN) + TEMP_SENSOR_AD595_OFFSET;
} }
// Derived from RepRap FiveD extruder::getTemperature() // Derived from RepRap FiveD extruder::getTemperature()
...@@ -824,22 +828,27 @@ static float analog2tempBed(int raw) { ...@@ -824,22 +828,27 @@ static float analog2tempBed(int raw) {
for (i = 1; i < BEDTEMPTABLE_LEN; i++) { for (i = 1; i < BEDTEMPTABLE_LEN; i++) {
if (PGM_RD_W(BEDTEMPTABLE[i][0]) > raw) { if (PGM_RD_W(BEDTEMPTABLE[i][0]) > raw) {
celsius = PGM_RD_W(BEDTEMPTABLE[i-1][1]) + celsius = PGM_RD_W(BEDTEMPTABLE[i - 1][1]) +
(raw - PGM_RD_W(BEDTEMPTABLE[i-1][0])) * (raw - PGM_RD_W(BEDTEMPTABLE[i - 1][0])) *
(float)(PGM_RD_W(BEDTEMPTABLE[i][1]) - PGM_RD_W(BEDTEMPTABLE[i-1][1])) / (float)(PGM_RD_W(BEDTEMPTABLE[i][1]) - PGM_RD_W(BEDTEMPTABLE[i - 1][1])) /
(float)(PGM_RD_W(BEDTEMPTABLE[i][0]) - PGM_RD_W(BEDTEMPTABLE[i-1][0])); (float)(PGM_RD_W(BEDTEMPTABLE[i][0]) - PGM_RD_W(BEDTEMPTABLE[i - 1][0]));
break; break;
} }
} }
// Overflow: Set to last value in the table // Overflow: Set to last value in the table
if (i == BEDTEMPTABLE_LEN) celsius = PGM_RD_W(BEDTEMPTABLE[i-1][1]); if (i == BEDTEMPTABLE_LEN) celsius = PGM_RD_W(BEDTEMPTABLE[i - 1][1]);
return celsius; return celsius;
#elif ENABLED(BED_USES_AD595) #elif ENABLED(BED_USES_AD595)
return ((raw * ((5.0 * 100.0) / 1023.0) / OVERSAMPLENR) * TEMP_SENSOR_AD595_GAIN) + TEMP_SENSOR_AD595_OFFSET;
return ((raw * ((5.0 * 100.0) / 1024.0) / OVERSAMPLENR) * TEMP_SENSOR_AD595_GAIN) + TEMP_SENSOR_AD595_OFFSET;
#else #else
UNUSED(raw);
return 0; return 0;
#endif #endif
} }
...@@ -888,6 +897,7 @@ static void updateTemperaturesFromRawValues() { ...@@ -888,6 +897,7 @@ static void updateTemperaturesFromRawValues() {
// Reset the watchdog after we know we have a temperature measurement. // Reset the watchdog after we know we have a temperature measurement.
watchdog_reset(); watchdog_reset();
#endif #endif
CRITICAL_SECTION_START; CRITICAL_SECTION_START;
temp_meas_ready = false; temp_meas_ready = false;
CRITICAL_SECTION_END; CRITICAL_SECTION_END;
...@@ -951,8 +961,8 @@ static void updateTemperaturesFromRawValues() { ...@@ -951,8 +961,8 @@ static void updateTemperaturesFromRawValues() {
void tp_init() { void tp_init() {
#if MB(RUMBA) && ((TEMP_SENSOR_0==-1)||(TEMP_SENSOR_1==-1)||(TEMP_SENSOR_2==-1)||(TEMP_SENSOR_BED==-1)) #if MB(RUMBA) && ((TEMP_SENSOR_0==-1)||(TEMP_SENSOR_1==-1)||(TEMP_SENSOR_2==-1)||(TEMP_SENSOR_BED==-1))
// disable RUMBA JTAG in case the thermocouple extension is plugged on top of JTAG connector // disable RUMBA JTAG in case the thermocouple extension is plugged on top of JTAG connector
MCUCR=BIT(JTD); MCUCR = BIT(JTD);
MCUCR=BIT(JTD); MCUCR = BIT(JTD);
#endif #endif
// Finish init of mult hotends arrays // Finish init of mult hotends arrays
...@@ -970,9 +980,7 @@ void tp_init() { ...@@ -970,9 +980,7 @@ void tp_init() {
} }
#if ENABLED(PID_ADD_EXTRUSION_RATE) #if ENABLED(PID_ADD_EXTRUSION_RATE)
for (int e = 0; e < EXTRUDERS; e++) { for (int e = 0; e < EXTRUDERS; e++) last_position[e] = 0;
last_position[e] = 0;
}
#endif #endif
#if HAS(HEATER_0) #if HAS(HEATER_0)
...@@ -1011,7 +1019,7 @@ void tp_init() { ...@@ -1011,7 +1019,7 @@ void tp_init() {
digitalWrite(SS_PIN, HIGH); digitalWrite(SS_PIN, HIGH);
#endif #endif
OUT_WRITE(MAX6675_SS,HIGH); OUT_WRITE(MAX6675_SS, HIGH);
#endif // HEATER_0_USES_MAX6675 #endif // HEATER_0_USES_MAX6675
...@@ -1173,21 +1181,22 @@ void tp_init() { ...@@ -1173,21 +1181,22 @@ void tp_init() {
* their target temperature by a configurable margin. * their target temperature by a configurable margin.
* This is called when the temperature is set. (M104, M109) * This is called when the temperature is set. (M104, M109)
*/ */
void start_watching_heater(int e) { void start_watching_heater(int h) {
if (degHotend(e) < degTargetHotend(e) - (WATCH_TEMP_INCREASE + TEMP_HYSTERESIS + 1)) { if (degHotend(h) < degTargetHotend(h) - (WATCH_TEMP_INCREASE + TEMP_HYSTERESIS + 1)) {
watch_target_temp[e] = degHotend(e) + WATCH_TEMP_INCREASE; watch_target_temp[h] = degHotend(h) + WATCH_TEMP_INCREASE;
watch_heater_next_ms[e] = millis() + WATCH_TEMP_PERIOD * 1000UL; watch_heater_next_ms[h] = millis() + WATCH_TEMP_PERIOD * 1000UL;
} }
else else
watch_heater_next_ms[e] = 0; watch_heater_next_ms[h] = 0;
} }
#endif #endif
#if ENABLED(THERMAL_PROTECTION_HOTENDS) || ENABLED(THERMAL_PROTECTION_BED) #if ENABLED(THERMAL_PROTECTION_HOTENDS) || ENABLED(THERMAL_PROTECTION_BED)
void thermal_runaway_protection(TRState *state, millis_t *timer, float temperature, float target_temperature, int heater_id, int period_seconds, int hysteresis_degc) { void thermal_runaway_protection(TRState* state, millis_t* timer, float temperature, float target_temperature, int heater_id, int period_seconds, int hysteresis_degc) {
static float tr_last_temperature = 0.0;
static float tr_target_temperature[HOTENDS + 1] = { 0.0 }; static float tr_target_temperature[HOTENDS + 1] = { 0.0 };
/* /*
ECHO_SM(DB, "Thermal Thermal Runaway Running. Heater ID: "); ECHO_SM(DB, "Thermal Thermal Runaway Running. Heater ID: ");
if (heater_id < 0) ECHO_M("bed"); else ECHO_V(heater_id); if (heater_id < 0) ECHO_M("bed"); else ECHO_V(heater_id);
...@@ -1204,51 +1213,33 @@ void tp_init() { ...@@ -1204,51 +1213,33 @@ void tp_init() {
*state = TRReset; *state = TRReset;
switch (*state) { switch (*state) {
case TRReset: { case TRReset:
*timer = 0; *timer = 0;
*state = TRInactive; *state = TRInactive;
}
// Inactive state waits for a target temperature to be set // Inactive state waits for a target temperature to be set
case TRInactive: { case TRInactive:
if (target_temperature > 0) { if (target_temperature > 0) {
tr_last_temperature = temperature;
tr_target_temperature[heater_index] = target_temperature; tr_target_temperature[heater_index] = target_temperature;
*timer = millis();
*state = TRFirstHeating; *state = TRFirstHeating;
} }
}
break; break;
// When first heating, wait for the temperature to be reached then go to Stable state // When first heating, wait for the temperature to be reached then go to Stable state
// If the heater takes too long to reach the target temperature the sistem will be halt. case TRFirstHeating:
case TRFirstHeating: {
if (temperature >= tr_target_temperature[heater_index]) *state = TRStable; if (temperature >= tr_target_temperature[heater_index]) *state = TRStable;
else if (temperature == tr_last_temperature) {
if (millis() > *timer + period_seconds * 1000UL) {
*state = TRRunaway;
}
}
else {
*timer = millis();
}
}
break; break;
// While the temperature is stable watch for a bad temperature // While the temperature is stable watch for a bad temperature
case TRStable: { case TRStable:
// If the temperature is over the target (-hysteresis) restart the timer // If the temperature is over the target (-hysteresis) restart the timer
if (temperature >= tr_target_temperature[heater_index] - hysteresis_degc) { if (temperature >= tr_target_temperature[heater_index] - hysteresis_degc)
*timer = millis(); *timer = millis();
}
// If the timer goes too long without a reset, trigger shutdown // If the timer goes too long without a reset, trigger shutdown
else if (millis() > *timer + period_seconds * 1000UL) { else if (millis() > *timer + period_seconds * 1000UL)
*state = TRRunaway; *state = TRRunaway;
}
}
break; break;
case TRRunaway: { case TRRunaway:
_temp_error(heater_id, PSTR(MSG_T_THERMAL_RUNAWAY), PSTR(MSG_THERMAL_RUNAWAY)); _temp_error(heater_id, PSTR(MSG_T_THERMAL_RUNAWAY), PSTR(MSG_THERMAL_RUNAWAY));
} }
} }
}
#endif // THERMAL_PROTECTION_HOTENDS || THERMAL_PROTECTION_BED #endif // THERMAL_PROTECTION_HOTENDS || THERMAL_PROTECTION_BED
...@@ -1322,13 +1313,13 @@ void disable_all_heaters() { ...@@ -1322,13 +1313,13 @@ void disable_all_heaters() {
// read MSB // read MSB
SPDR = 0; SPDR = 0;
for (;(SPSR & BIT(SPIF)) == 0;); for (; (SPSR & BIT(SPIF)) == 0;);
max6675_temp = SPDR; max6675_temp = SPDR;
max6675_temp <<= 8; max6675_temp <<= 8;
// read LSB // read LSB
SPDR = 0; SPDR = 0;
for (;(SPSR & BIT(SPIF)) == 0;); for (; (SPSR & BIT(SPIF)) == 0;);
max6675_temp |= SPDR; max6675_temp |= SPDR;
// disable TT_MAX6675 // disable TT_MAX6675
...@@ -1404,6 +1395,7 @@ static void set_current_temp_raw() { ...@@ -1404,6 +1395,7 @@ static void set_current_temp_raw() {
* - Step the babysteps value for each axis towards 0 * - Step the babysteps value for each axis towards 0
*/ */
ISR(TIMER0_COMPB_vect) { ISR(TIMER0_COMPB_vect) {
static unsigned char temp_count = 0; static unsigned char temp_count = 0;
static TempState temp_state = StartupDelay; static TempState temp_state = StartupDelay;
static unsigned char pwm_count = BIT(SOFT_PWM_SCALE); static unsigned char pwm_count = BIT(SOFT_PWM_SCALE);
...@@ -1533,6 +1525,7 @@ ISR(TIMER0_COMPB_vect) { ...@@ -1533,6 +1525,7 @@ ISR(TIMER0_COMPB_vect) {
pwm_count &= 0x7f; pwm_count &= 0x7f;
#else // SLOW_PWM_HEATERS #else // SLOW_PWM_HEATERS
/* /*
* SLOW PWM HEATERS * SLOW PWM HEATERS
* *
...@@ -1682,8 +1675,7 @@ ISR(TIMER0_COMPB_vect) { ...@@ -1682,8 +1675,7 @@ ISR(TIMER0_COMPB_vect) {
#endif #endif
// Prepare or measure a sensor, each one every 14th frame // Prepare or measure a sensor, each one every 14th frame
switch(temp_state) { switch (temp_state) {
case PrepareTemp_0: case PrepareTemp_0:
#if HAS(TEMP_0) #if HAS(TEMP_0)
START_ADC(TEMP_0_PIN); START_ADC(TEMP_0_PIN);
...@@ -1765,8 +1757,8 @@ ISR(TIMER0_COMPB_vect) { ...@@ -1765,8 +1757,8 @@ ISR(TIMER0_COMPB_vect) {
#if HAS(FILAMENT_SENSOR) #if HAS(FILAMENT_SENSOR)
// raw_filwidth_value += ADC; //remove to use an IIR filter approach // raw_filwidth_value += ADC; //remove to use an IIR filter approach
if (ADC > 102) { //check that ADC is reading a voltage > 0.5 volts, otherwise don't take in the data. if (ADC > 102) { //check that ADC is reading a voltage > 0.5 volts, otherwise don't take in the data.
raw_filwidth_value -= (raw_filwidth_value>>7); //multiply raw_filwidth_value by 127/128 raw_filwidth_value -= (raw_filwidth_value >> 7); //multiply raw_filwidth_value by 127/128
raw_filwidth_value += ((unsigned long)ADC<<7); //add new ADC reading raw_filwidth_value += ((unsigned long)ADC << 7); //add new ADC reading
} }
#endif #endif
temp_state = Prepare_POWCONSUMPTION; temp_state = Prepare_POWCONSUMPTION;
......
...@@ -102,16 +102,16 @@ FORCE_INLINE float degTargetHotend(uint8_t hotend) { return target_temperature[H ...@@ -102,16 +102,16 @@ FORCE_INLINE float degTargetHotend(uint8_t hotend) { return target_temperature[H
FORCE_INLINE float degTargetBed() { return target_temperature_bed; } FORCE_INLINE float degTargetBed() { return target_temperature_bed; }
#if ENABLED(THERMAL_PROTECTION_HOTENDS) #if ENABLED(THERMAL_PROTECTION_HOTENDS)
void start_watching_heater(int e=0); void start_watching_heater(int h = 0);
#endif #endif
FORCE_INLINE void setTargetHotend(const float &celsius, uint8_t hotend) { FORCE_INLINE void setTargetHotend(const float& celsius, uint8_t hotend) {
target_temperature[HOTEND_ARG] = celsius; target_temperature[HOTEND_ARG] = celsius;
#if ENABLED(THERMAL_PROTECTION_HOTENDS) #if ENABLED(THERMAL_PROTECTION_HOTENDS)
start_watching_heater(HOTEND_ARG); start_watching_heater(HOTEND_ARG);
#endif #endif
} }
FORCE_INLINE void setTargetBed(const float &celsius) { target_temperature_bed = celsius; } FORCE_INLINE void setTargetBed(const float& celsius) { target_temperature_bed = celsius; }
FORCE_INLINE bool isHeatingHotend(uint8_t hotend) { return target_temperature[HOTEND_ARG] > current_temperature[HOTEND_ARG]; } FORCE_INLINE bool isHeatingHotend(uint8_t hotend) { return target_temperature[HOTEND_ARG] > current_temperature[HOTEND_ARG]; }
FORCE_INLINE bool isHeatingBed() { return target_temperature_bed > current_temperature_bed; } FORCE_INLINE bool isHeatingBed() { return target_temperature_bed > current_temperature_bed; }
......
...@@ -339,10 +339,14 @@ static void lcd_status_screen() { ...@@ -339,10 +339,14 @@ static void lcd_status_screen() {
lcd_status_message[0] = '\0'; lcd_status_message[0] = '\0';
expire_status_ms = 0; expire_status_ms = 0;
} }
} else }
else {
expire_status_ms += LCD_UPDATE_INTERVAL; expire_status_ms += LCD_UPDATE_INTERVAL;
} else }
}
else {
expire_status_ms = 0; expire_status_ms = 0;
}
#else #else
expire_status_ms = 0; expire_status_ms = 0;
#endif // SDSUPPORT #endif // SDSUPPORT
...@@ -377,7 +381,8 @@ static void lcd_status_screen() { ...@@ -377,7 +381,8 @@ static void lcd_status_screen() {
ignore_click = wait_for_unclick = false; ignore_click = wait_for_unclick = false;
else else
current_click = false; current_click = false;
} else if (current_click) { }
else if (current_click) {
lcd_quick_feedback(); lcd_quick_feedback();
wait_for_unclick = true; wait_for_unclick = true;
current_click = false; current_click = false;
...@@ -472,13 +477,15 @@ static void lcd_main_menu() { ...@@ -472,13 +477,15 @@ static void lcd_main_menu() {
else else
MENU_ITEM(function, MSG_RESUME_PRINT, lcd_sdcard_resume); MENU_ITEM(function, MSG_RESUME_PRINT, lcd_sdcard_resume);
MENU_ITEM(function, MSG_STOP_PRINT, lcd_sdcard_stop); MENU_ITEM(function, MSG_STOP_PRINT, lcd_sdcard_stop);
} else { }
else {
MENU_ITEM(submenu, MSG_CARD_MENU, lcd_sdcard_menu); MENU_ITEM(submenu, MSG_CARD_MENU, lcd_sdcard_menu);
#if !PIN_EXISTS(SD_DETECT) #if !PIN_EXISTS(SD_DETECT)
MENU_ITEM(gcode, MSG_CNG_SDCARD, PSTR("M21")); // SD-card changed by user MENU_ITEM(gcode, MSG_CNG_SDCARD, PSTR("M21")); // SD-card changed by user
#endif #endif
} }
} else { }
else {
MENU_ITEM(submenu, MSG_NO_CARD, lcd_sdcard_menu); MENU_ITEM(submenu, MSG_NO_CARD, lcd_sdcard_menu);
#if !PIN_EXISTS(SD_DETECT) #if !PIN_EXISTS(SD_DETECT)
MENU_ITEM(gcode, MSG_INIT_SDCARD, PSTR("M21")); // Manually initialize the SD-card via user interface MENU_ITEM(gcode, MSG_INIT_SDCARD, PSTR("M21")); // Manually initialize the SD-card via user interface
...@@ -509,7 +516,7 @@ void lcd_set_home_offsets() { ...@@ -509,7 +516,7 @@ void lcd_set_home_offsets() {
#if ENABLED(BABYSTEPPING) #if ENABLED(BABYSTEPPING)
static void _lcd_babystep(menuFunc_t menu, int axis, const char *msg) { static void _lcd_babystep(menuFunc_t menu, int axis, const char* msg) {
if (encoderPosition != 0) { if (encoderPosition != 0) {
babystepsTodo[axis] += (int)encoderPosition; babystepsTodo[axis] += (int)encoderPosition;
encoderPosition = 0; encoderPosition = 0;
...@@ -1655,7 +1662,7 @@ void lcd_init() { ...@@ -1655,7 +1662,7 @@ void lcd_init() {
WRITE(SHIFT_OUT,HIGH); WRITE(SHIFT_OUT,HIGH);
WRITE(SHIFT_LD,HIGH); WRITE(SHIFT_LD,HIGH);
#endif #endif
#else // Not NEWPANEL #else // Not NEWPANEL
#if ENABLED(SR_LCD_2W_NL) // Non latching 2 wire shift register #if ENABLED(SR_LCD_2W_NL) // Non latching 2 wire shift register
pinMode (SR_DATA_PIN, OUTPUT); pinMode (SR_DATA_PIN, OUTPUT);
pinMode (SR_CLK_PIN, OUTPUT); pinMode (SR_CLK_PIN, OUTPUT);
...@@ -1668,7 +1675,7 @@ void lcd_init() { ...@@ -1668,7 +1675,7 @@ void lcd_init() {
WRITE(SHIFT_LD,HIGH); WRITE(SHIFT_LD,HIGH);
WRITE(SHIFT_EN,LOW); WRITE(SHIFT_EN,LOW);
#endif // SR_LCD_2W_NL #endif // SR_LCD_2W_NL
#endif//!NEWPANEL #endif//!NEWPANEL
#if ENABLED(SDSUPPORT) && PIN_EXISTS(SD_DETECT) #if ENABLED(SDSUPPORT) && PIN_EXISTS(SD_DETECT)
pinMode(SD_DETECT_PIN, INPUT); pinMode(SD_DETECT_PIN, INPUT);
......
#include "base.h" #include "base.h"
#if ENABLED(USE_WATCHDOG) #if ENABLED(USE_WATCHDOG)
#include <avr/wdt.h>
#include "whatchdog.h"
//===========================================================================
//============================ private variables ============================
//===========================================================================
//===========================================================================
//================================ functions ================================
//===========================================================================
#include "watchdog.h"
/// intialise watch dog with a 4 sec interrupt time // Initialize watchdog with a 4 sec interrupt time
void watchdog_init() void watchdog_init() {
{
#if ENABLED(WATCHDOG_RESET_MANUAL) #if ENABLED(WATCHDOG_RESET_MANUAL)
//We enable the watchdog timer, but only for the interrupt. // We enable the watchdog timer, but only for the interrupt.
//Take care, as this requires the correct order of operation, with interrupts disabled. See the datasheet of any AVR chip for details. // Take care, as this requires the correct order of operation, with interrupts disabled. See the datasheet of any AVR chip for details.
wdt_reset(); wdt_reset();
_WD_CONTROL_REG = _BV(_WD_CHANGE_BIT) | _BV(WDE); _WD_CONTROL_REG = _BV(_WD_CHANGE_BIT) | _BV(WDE);
_WD_CONTROL_REG = _BV(WDIE) | WDTO_4S; _WD_CONTROL_REG = _BV(WDIE) | WDTO_4S;
...@@ -27,23 +17,18 @@ void watchdog_init() ...@@ -27,23 +17,18 @@ void watchdog_init()
#endif #endif
} }
/// reset watchdog. MUST be called every 1s after init or avr will reset.
void watchdog_reset()
{
wdt_reset();
}
//=========================================================================== //===========================================================================
//=================================== ISR =================================== //=================================== ISR ===================================
//=========================================================================== //===========================================================================
// Watchdog timer interrupt, called if main program blocks >1sec and manual reset is enabled. // Watchdog timer interrupt, called if main program blocks >1sec and manual reset is enabled.
#if ENABLED(WATCHDOG_RESET_MANUAL) #if ENABLED(WATCHDOG_RESET_MANUAL)
ISR(WDT_vect) { ISR(WDT_vect) {
ECHO_LM(ER, MSG_WATCHDOG_RESET); SERIAL_ERROR_START;
kill(PSTR("ERR:Please Reset")); // kill blocks //16 characters so it fits on a 16x2 display SERIAL_ERRORLNPGM("Something is wrong, please turn off the printer.");
while(1); // wait for user or serial reset kill(PSTR("ERR:Please Reset")); //kill blocks //16 characters so it fits on a 16x2 display
} while (1); //wait for user or serial reset
#endif // RESET_MANUAL }
#endif //WATCHDOG_RESET_MANUAL
#endif // USE_WATCHDOG
#endif //USE_WATCHDOG
#ifndef WATCHDOG_H #ifndef WATCHDOG_H
#define WATCHDOG_H #define WATCHDOG_H
// initialize watch dog with a 1 sec interrupt time #include "Marlin_main.h"
#include <avr/wdt.h>
// Initialize watchdog with a 4 second interrupt time
void watchdog_init(); void watchdog_init();
// pad the dog/reset watchdog. MUST be called at least every second after the first watchdog_init or AVR will go into emergency procedures..
void watchdog_reset(); // Reset watchdog. MUST be called at least every 4 seconds after the
// first watchdog_init or AVR will go into emergency procedures.
inline void watchdog_reset() { wdt_reset(); }
#endif #endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment