Commit d4504571 authored by MagoKimbra's avatar MagoKimbra

Update and fix

parent 49ff3bfa
......@@ -44,8 +44,8 @@
//#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.
//#define NO_TIMEOUTS 1000 // Milliseconds
//#define ADVANCED_OK // Uncomment to include more info in ok command
#define NO_TIMEOUTS 1000 // Milliseconds
//#define ADVANCED_OK // Uncomment to include more info in ok command
/***********************************************************************/
......
......@@ -350,8 +350,8 @@
* (i.e. the software might assume it can be done instantaneously) *
* *
*****************************************************************************************/
#define DEFAULT_XYJERK 10.0 // (mm/sec)
#define DEFAULT_ZJERK 0.4 // (mm/sec)
#define DEFAULT_XYJERK 20.0 // (mm/sec)
#define DEFAULT_ZJERK 20.0 // (mm/sec)
// max initial speed for retract moves E0... (mm/sec) per extruder
#define DEFAULT_EJERK {5.0, 5.0, 5.0, 5.0}
/*****************************************************************************************/
......
......@@ -93,7 +93,6 @@
* *
*****************************************************************************************/
#define AUTOTEMP
#define AUTOTEMP_OLDWEIGHT 0.98
/*****************************************************************************************/
......@@ -983,6 +982,8 @@
//#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
// 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
// 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.
......@@ -1480,4 +1481,4 @@
//#define WATCHDOG_RESET_MANUAL
/*****************************************************************************************/
#endif
\ No newline at end of file
#endif
# 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.
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
......@@ -70,7 +70,6 @@
#include <SPI.h>
#endif
#if ENABLED(FIRMWARE_TEST)
#include "firmware_test.h"
#endif
......@@ -167,6 +166,7 @@
* M119 - Output Endstop status to serial port
* M120 - Enable 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)
* M127 - Solenoid Air Valve Closed (BariCUDA vent to atmospheric pressure 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
static uint8_t target_extruder;
bool no_wait_for_cooling = true;
bool target_direction;
bool software_endstops = true;
unsigned long printer_usage_seconds;
......@@ -993,11 +994,14 @@ void get_command() {
command[serial_count] = 0; // terminate string
// this item in the queue is not from sd
#if ENABLED(SDSUPPORT)
fromsd[cmd_queue_index_w] = false;
#endif
char* npos = strchr(command, 'N');
#if ENABLED(SDSUPPORT)
fromsd[cmd_queue_index_w] = false;
#endif
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, '*');
if (npos) {
boolean M110 = strstr_P(command, PSTR("M110")) != NULL;
if (M110) {
......@@ -1027,6 +1031,7 @@ void get_command() {
gcode_line_error(PSTR(MSG_ERR_NO_LINENUMBER_WITH_CHECKSUM), false);
return;
}
// Movement commands alert when stopped
if (IsStopped()) {
char* gpos = strchr(command, 'G');
......@@ -1043,10 +1048,13 @@ void get_command() {
}
}
}
// If command was e-stop process now
if (strcmp(command, "M112") == 0) kill(PSTR(MSG_KILLED));
cmd_queue_index_w = (cmd_queue_index_w + 1) % BUFSIZE;
commands_in_queue += 1;
serial_count = 0; //clear buffer
} else if (serial_char == '\\') { // Handle escapes
if (MYSERIAL.available() > 0 && commands_in_queue < BUFSIZE) {
......@@ -1060,51 +1068,57 @@ void get_command() {
if (!comment_mode) command_queue[cmd_queue_index_w][serial_count++] = serial_char;
}
}
#if ENABLED(SDSUPPORT)
if (!card.sdprinting || serial_count) return;
// '#' 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.
// this character _can_ occur in serial com, due to checksums. however, no checksums are used in SD printing
static bool stop_buffering = false;
if (commands_in_queue == 0) stop_buffering = false;
while (!card.eof() && commands_in_queue < BUFSIZE && !stop_buffering) {
int16_t n = card.get();
serial_char = (char)n;
if (serial_char == '\n' || serial_char == '\r' ||
((serial_char == '#' || serial_char == ':') && !comment_mode) ||
serial_count >= (MAX_CMD_SIZE - 1) || n == -1
) {
if (card.eof()) {
ECHO_EM(MSG_FILE_PRINTED);
print_job_stop_ms = millis();
char time[30];
millis_t t = (print_job_stop_ms - print_job_start_ms) / 1000;
int hours = t / 60 / 60, minutes = (t / 60) % 60;
sprintf_P(time, PSTR("%i " MSG_END_HOUR " %i " MSG_END_MINUTE), hours, minutes);
ECHO_LV(DB, time);
lcd_setstatus(time, true);
card.printingHasFinished();
card.checkautostart(true);
}
if (serial_char == '#') stop_buffering = true;
if (!serial_count) {
#if ENABLED(SDSUPPORT)
if (!card.sdprinting || serial_count) return;
// '#' 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.
// this character _can_ occur in serial com, due to checksums. however, no checksums are used in SD printing
static bool stop_buffering = false;
if (commands_in_queue == 0) stop_buffering = false;
while (!card.eof() && commands_in_queue < BUFSIZE && !stop_buffering) {
int16_t n = card.get();
serial_char = (char)n;
if (serial_char == '\n' || serial_char == '\r' ||
((serial_char == '#' || serial_char == ':') && !comment_mode) ||
serial_count >= (MAX_CMD_SIZE - 1) || n == -1
) {
if (card.eof()) {
ECHO_EM(MSG_FILE_PRINTED);
print_job_stop_ms = millis();
char time[30];
millis_t t = (print_job_stop_ms - print_job_start_ms) / 1000;
int hours = t / 60 / 60, minutes = (t / 60) % 60;
sprintf_P(time, PSTR("%i " MSG_END_HOUR " %i " MSG_END_MINUTE), hours, minutes);
ECHO_LV(DB, time);
lcd_setstatus(time, true);
card.printingHasFinished();
card.checkautostart(true);
}
if (serial_char == '#') stop_buffering = true;
if (!serial_count) {
comment_mode = false; //for new command
return; //if empty line
}
command_queue[cmd_queue_index_w][serial_count] = 0; //terminate string
// if (!comment_mode) {
fromsd[cmd_queue_index_w] = true;
commands_in_queue += 1;
cmd_queue_index_w = (cmd_queue_index_w + 1) % BUFSIZE;
// }
comment_mode = false; //for new command
return; //if empty line
serial_count = 0; //clear buffer
}
else {
if (serial_char == ';') comment_mode = true;
if (!comment_mode) command_queue[cmd_queue_index_w][serial_count++] = serial_char;
}
command_queue[cmd_queue_index_w][serial_count] = 0; //terminate string
// if (!comment_mode) {
fromsd[cmd_queue_index_w] = true;
commands_in_queue += 1;
cmd_queue_index_w = (cmd_queue_index_w + 1) % BUFSIZE;
// }
comment_mode = false; //for new command
serial_count = 0; //clear buffer
} else {
if (serial_char == ';') comment_mode = true;
if (!comment_mode) command_queue[cmd_queue_index_w][serial_count++] = serial_char;
}
}
#endif // SDSUPPORT
#endif // SDSUPPORT
}
bool code_has_value() {
......@@ -1160,34 +1174,34 @@ XYZ_CONSTS_FROM_CONFIG(signed char, home_dir, HOME_DIR);
#if ENABLED(DUAL_X_CARRIAGE)
#define DXC_FULL_CONTROL_MODE 0
#define DXC_AUTO_PARK_MODE 1
#define DXC_DUPLICATION_MODE 2
static int dual_x_carriage_mode = DEFAULT_DUAL_X_CARRIAGE_MODE;
static float x_home_pos(int extruder) {
if (extruder == 0)
return base_home_pos(X_AXIS) + home_offset[X_AXIS];
else
// In dual carriage mode the extruder offset provides an override of the
// second X-carriage offset when homed - otherwise X2_HOME_POS is used.
// This allow soft recalibration of the second extruder offset position without firmware reflash
// (through the M218 command).
return (hotend_offset[X_AXIS][1] > 0) ? hotend_offset[X_AXIS][1] : X2_HOME_POS;
}
#define DXC_FULL_CONTROL_MODE 0
#define DXC_AUTO_PARK_MODE 1
#define DXC_DUPLICATION_MODE 2
static int x_home_dir(int extruder) {
return (extruder == 0) ? X_HOME_DIR : X2_HOME_DIR;
}
static int dual_x_carriage_mode = DEFAULT_DUAL_X_CARRIAGE_MODE;
static float x_home_pos(int extruder) {
if (extruder == 0)
return base_home_pos(X_AXIS) + home_offset[X_AXIS];
else
// In dual carriage mode the extruder offset provides an override of the
// second X-carriage offset when homed - otherwise X2_HOME_POS is used.
// This allow soft recalibration of the second extruder offset position without firmware reflash
// (through the M218 command).
return (hotend_offset[X_AXIS][1] > 0) ? hotend_offset[X_AXIS][1] : X2_HOME_POS;
}
static int x_home_dir(int extruder) {
return (extruder == 0) ? X_HOME_DIR : X2_HOME_DIR;
}
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 float raised_parked_position[NUM_AXIS]; // 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_extruder_temp_offset = 0; // used in mode 2
bool extruder_duplication_enabled = false; // used in mode 2
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 float raised_parked_position[NUM_AXIS]; // 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_extruder_temp_offset = 0; // used in mode 2
bool extruder_duplication_enabled = false; // used in mode 2
#endif //DUAL_X_CARRIAGE
......@@ -1199,71 +1213,72 @@ void print_xyz(const char* prefix, const float x, const float y, const float z,
ECHO_M(")");
if (eol) ECHO_E;
}
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);
}
static void set_axis_is_at_home(AxisEnum axis) {
#if ENABLED(DUAL_X_CARRIAGE)
if (axis == X_AXIS) {
if (active_extruder != 0) {
current_position[X_AXIS] = x_home_pos(active_extruder);
min_pos[X_AXIS] = X2_MIN_POS;
max_pos[X_AXIS] = max(hotend_offset[X_AXIS][1], X2_MAX_POS);
return;
} else if (dual_x_carriage_mode == DXC_DUPLICATION_MODE) {
float xoff = home_offset[X_AXIS];
current_position[X_AXIS] = base_home_pos(X_AXIS) + xoff;
min_pos[X_AXIS] = base_min_pos(X_AXIS) + xoff;
max_pos[X_AXIS] = min(base_max_pos(X_AXIS) + xoff, max(hotend_offset[X_AXIS][1], X2_MAX_POS) - duplicate_hotend_x_offset);
return;
#if ENABLED(DUAL_X_CARRIAGE)
if (axis == X_AXIS) {
if (active_extruder != 0) {
current_position[X_AXIS] = x_home_pos(active_extruder);
min_pos[X_AXIS] = X2_MIN_POS;
max_pos[X_AXIS] = max(hotend_offset[X_AXIS][1], X2_MAX_POS);
return;
} else if (dual_x_carriage_mode == DXC_DUPLICATION_MODE) {
float xoff = home_offset[X_AXIS];
current_position[X_AXIS] = base_home_pos(X_AXIS) + xoff;
min_pos[X_AXIS] = base_min_pos(X_AXIS) + xoff;
max_pos[X_AXIS] = min(base_max_pos(X_AXIS) + xoff, max(hotend_offset[X_AXIS][1], X2_MAX_POS) - duplicate_hotend_x_offset);
return;
}
}
}
#endif
#endif
#if MECH(SCARA)
if (axis == X_AXIS || axis == Y_AXIS) {
float homeposition[3];
for (int i = 0; i < 3; i++) homeposition[i] = base_home_pos(i);
// ECHO_MV("homeposition[x]= ", homeposition[0]);
// ECHO_EMV("homeposition[y]= ", homeposition[1]);
// Works out real Home position angles using inverse kinematics,
// and calculates homing offset using forward kinematics
calculate_delta(homeposition);
// ECHO_MV("base Theta= ", delta[X_AXIS]);
// ECHO_EMV(" base Psi+Theta=", delta[Y_AXIS]);
for (int i = 0; i < 2; i++) delta[i] -= home_offset[i];
// ECHO_MV("addhome X=", home_offset[X_AXIS]);
// ECHO_MV(" addhome Y=", home_offset[Y_AXIS]);
// ECHO_MV(" addhome Theta=", delta[X_AXIS]);
// ECHO_EMV(" addhome Psi+Theta=", delta[Y_AXIS]);
calculate_SCARA_forward_Transform(delta);
// ECHO_MV("Delta X=", delta[X_AXIS]);
// ECHO_EMV(" Delta Y=", delta[Y_AXIS]);
current_position[axis] = delta[axis];
// SCARA home positions are based on configuration since the actual limits are determined by the
// inverse kinematic transform.
min_pos[axis] = base_min_pos(axis); // + (delta[axis] - base_home_pos(axis));
max_pos[axis] = base_max_pos(axis); // + (delta[axis] - base_home_pos(axis));
} else {
#if MECH(SCARA)
if (axis == X_AXIS || axis == Y_AXIS) {
float homeposition[3];
for (int i = 0; i < 3; i++) homeposition[i] = base_home_pos(i);
// ECHO_MV("homeposition[x]= ", homeposition[0]);
// ECHO_EMV("homeposition[y]= ", homeposition[1]);
// Works out real Home position angles using inverse kinematics,
// and calculates homing offset using forward kinematics
calculate_delta(homeposition);
// ECHO_MV("base Theta= ", delta[X_AXIS]);
// ECHO_EMV(" base Psi+Theta=", delta[Y_AXIS]);
for (int i = 0; i < 2; i++) delta[i] -= home_offset[i];
// ECHO_MV("addhome X=", home_offset[X_AXIS]);
// ECHO_MV(" addhome Y=", home_offset[Y_AXIS]);
// ECHO_MV(" addhome Theta=", delta[X_AXIS]);
// ECHO_EMV(" addhome Psi+Theta=", delta[Y_AXIS]);
calculate_SCARA_forward_Transform(delta);
// ECHO_MV("Delta X=", delta[X_AXIS]);
// ECHO_EMV(" Delta Y=", delta[Y_AXIS]);
current_position[axis] = delta[axis];
// SCARA home positions are based on configuration since the actual limits are determined by the
// inverse kinematic transform.
min_pos[axis] = base_min_pos(axis); // + (delta[axis] - base_home_pos(axis));
max_pos[axis] = base_max_pos(axis); // + (delta[axis] - base_home_pos(axis));
} else {
current_position[axis] = base_home_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];
}
#elif MECH(DELTA)
current_position[axis] = base_home_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];
#else
current_position[axis] = base_home_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];
}
#elif MECH(DELTA)
current_position[axis] = base_home_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];
#else
current_position[axis] = base_home_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];
#endif
#if ENABLED(AUTO_BED_LEVELING_FEATURE) && Z_HOME_DIR < 0
if (axis == Z_AXIS) current_position[Z_AXIS] -= zprobe_zoffset;
#endif
#endif
#if ENABLED(AUTO_BED_LEVELING_FEATURE) && Z_HOME_DIR < 0
if (axis == Z_AXIS) current_position[Z_AXIS] -= zprobe_zoffset;
#endif
if (debugLevel & DEBUG_INFO) {
ECHO_SMV(DB, "set_axis_is_at_home ", (unsigned long)axis);
ECHO_MV(" > (home_offset[axis]==", home_offset[axis]);
......@@ -1276,17 +1291,12 @@ static void set_axis_is_at_home(AxisEnum axis) {
*/
inline void set_homing_bump_feedrate(AxisEnum axis) {
const int homing_bump_divisor[] = HOMING_BUMP_DIVISOR;
#if MECH(DELTA)
if (homing_bump_divisor[X_AXIS] >= 1)
feedrate = homing_feedrate[axis] / homing_bump_divisor[X_AXIS];
#else // No DELTA
if (homing_bump_divisor[axis] >= 1)
feedrate = homing_feedrate[axis] / homing_bump_divisor[axis];
#endif
else {
feedrate = homing_feedrate[axis] / 10;
int hbd = homing_bump_divisor[axis];
if (hbd < 1) {
hbd = 10;
ECHO_LM(ER, MSG_ERR_HOMING_DIV);
}
feedrate = homing_feedrate[axis] / hbd;
}
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);
......@@ -1716,12 +1726,14 @@ static void clean_up_after_endstop_move() {
#endif // CARTESIAN || COREXY || COREXZ || SCARA
#if MECH(DELTA)
static void homeaxis(AxisEnum axis) {
#define HOMEAXIS_DO(LETTER) \
((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);
current_position[axis] = 0;
......@@ -1986,9 +1998,9 @@ static void clean_up_after_endstop_move() {
float high_endstop = 0;
float low_endstop = 0;
for(int x = 0; x < 3; x++) {
if (endstop_adj[x] > high_endstop) high_endstop = endstop_adj[x];
if (endstop_adj[x] < low_endstop) low_endstop = endstop_adj[x];
for (int8_t i = 0; i < 3; i++) {
if (endstop_adj[i] > high_endstop) high_endstop = endstop_adj[i];
if (endstop_adj[i] < low_endstop) low_endstop = endstop_adj[i];
}
if (high_endstop > 0) {
......@@ -2000,7 +2012,7 @@ static void clean_up_after_endstop_move() {
set_delta_constants();
}
bed_safe_z = Z_RAISE_BETWEEN_PROBINGS - z_probe_offset[Z_AXIS];
bed_safe_z = 20;
}
int fix_tower_errors() {
......@@ -2033,7 +2045,7 @@ static void clean_up_after_endstop_move() {
ECHO_LMV(DB, "z_diff = ", z_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;
xz_equal = false;
yz_equal = false;
......@@ -2056,17 +2068,17 @@ static void clean_up_after_endstop_move() {
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");
t1_err = false;
t2_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 ((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 - y_diff) < 0.00001) err_tower = 2;
if (abs(high_diff - z_diff) < 0.00001) err_tower = 3;
......@@ -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 == false) and (t3_err == true)) err_tower = 2;
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 == 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;
......@@ -2103,7 +2117,7 @@ static void clean_up_after_endstop_move() {
ECHO_LM(DB, "Tower geometry OK");
}
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 ((tower_adj[0] != 0) or (tower_adj[3] != 0)) {
ECHO_LM(DB, "Tower 1 has already been adjusted");
......@@ -2522,7 +2536,7 @@ static void clean_up_after_endstop_move() {
probe_count ++;
} while ((probe_done == false) and (probe_count < 20));
bed_safe_z = probe_z + 2;
bed_safe_z = probe_z + 5;
return probe_z;
}
......@@ -2647,7 +2661,7 @@ static void clean_up_after_endstop_move() {
}
refresh_cmd_timeout();
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();
}
......@@ -4701,17 +4715,13 @@ inline void gcode_M42() {
sample_set[n] = current_position[Z_AXIS];
//
// Get the current mean for the data points we have so far
//
sum = 0.0;
for (uint8_t j = 0; j <= n; j++) sum += sample_set[j];
mean = sum / (n + 1);
//
// Now, use that mean to calculate the standard deviation for the
// data points we have so far
//
sum = 0.0;
for (uint8_t j = 0; j <= n; j++) {
float ss = sample_set[j] - mean;
......@@ -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]);
}
// 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.
//
// 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
// detects and reports any corruption within the free memory block that may have
// happened due to errant firmware.
// M100 D Does a hex display of the free memory block along with a flag for any errant
// data that does not match the expected value.
// 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
//
//
/**
* 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.
*
* 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
* detects and reports any corruption within the free memory block that may have
* happened due to errant firmware.
* M100 D Does a hex display of the free memory block along with a flag for any errant
* data that does not match the expected value.
* 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
*
*/
#if ENABLED(M100_FREE_MEMORY_WATCHER)
inline void gcode_M100() {
static int m100_not_initialized = 1;
unsigned char* sp, *ptr;
int i, j, n;
//
// 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
// up from the bottom of the block. Solid 0xE5's indicate nothing has
......@@ -4930,32 +4940,28 @@ inline void gcode_M92() {
// 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
// the right hand column to help spotting them.
//
#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;
//
// 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.
//
ECHO_M("\n__brkval : ");
prt_hex_word( (unsigned int) ptr );
prt_hex_word((unsigned int) ptr);
ptr = (unsigned char*) ((unsigned long) ptr & 0xfff0);
sp = top_of_stack();
ECHO_M("\nStack Pointer : ");
prt_hex_word( (unsigned int) sp );
prt_hex_word((unsigned int) sp);
ECHO_M("\n");
sp = (unsigned char*) ((unsigned long) sp | 0x000f);
n = sp - ptr;
//
// This is the main loop of the Dump command.
//
while ( ptr < sp ) {
prt_hex_word( (unsigned int) ptr); // Print the address
while (ptr < sp) {
prt_hex_word((unsigned int) ptr); // Print the address
ECHO_M(":");
for(i = 0; i < 16; i++) { // and 16 data bytes
prt_hex_byte( *(ptr+i));
......@@ -4981,11 +4987,9 @@ inline void gcode_M92() {
}
#endif
//
// 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.
//
if ( code_seen('F') ) {
if (code_seen('F')) {
int max_addr = (int) __brkval;
int max_cnt = 0;
int block_cnt = 0;
......@@ -4994,69 +4998,64 @@ inline void gcode_M92() {
n = sp - ptr;
// 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) {
j = how_many_E5s_are_here( (unsigned char*) ptr+i );
j = how_many_E5s_are_here((unsigned char*) ptr + i);
if ( j > 8) {
ECHO_MV("Found ", j );
ECHO_M(" bytes free at 0x");
prt_hex_word( (int) ptr+i );
prt_hex_word((int) ptr + i);
ECHO_M("\n");
i += j;
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_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_M("\nDone.\n");
return;
}
//
// 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.
//
#if ENABLED(M100_FREE_MEMORY_CORRUPTOR)
if ( code_seen('C') ) {
int x; // x gets the # of locations to corrupt within the memory pool
if (code_seen('C')) {
int x; // x gets the # of locations to corrupt within the memory pool
x = code_value();
ECHO_EM("Corrupting free memory block.\n");
ptr = (unsigned char*) __brkval;
ECHO_MV("\n__brkval : ",(long) ptr );
ECHO_MV("\n__brkval : ",(long) ptr);
ptr += 8;
sp = top_of_stack();
ECHO_MV("\nStack Pointer : ",(long) sp );
ECHO_MV("\nStack Pointer : ",(long) sp);
ECHO_EM("\n");
n = sp - ptr - 64; // -64 just to keep us from finding interrupt activity that
// has altered the stack.
j = n / (x+1);
j = n / (x + 1);
for(i = 1; i <= x; i++) {
*(ptr+(i*j)) = i;
*(ptr + (i * j)) = i;
ECHO_M("\nCorrupting address: 0x");
prt_hex_word( (unsigned int) (ptr+(i*j)) );
prt_hex_word((unsigned int) (ptr + (i * j)));
}
ECHO_EM("\n");
return;
}
#endif
//
// M100 I Initializes the free memory pool so it can be watched and prints vital
// statistics that define the free memory pool.
//
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.
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.
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.
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.
ptr += 8;
sp = top_of_stack();
......@@ -5073,9 +5072,9 @@ inline void gcode_M92() {
*(ptr+i) = (unsigned char) 0xe5;
for(i = 0; i < n; i++) {
if ( *(ptr+i) != (unsigned char) 0xe5 ) {
ECHO_MV("? address : ", (unsigned long) ptr+i );
ECHO_MV("=", *(ptr+i) );
if ( *(ptr + i) != (unsigned char) 0xe5) {
ECHO_MV("? address : ", (unsigned long) ptr + i);
ECHO_MV("=", *(ptr + i));
ECHO_EM("\n");
}
}
......@@ -5086,6 +5085,7 @@ inline void gcode_M92() {
return;
}
#endif
/**
* M104: Set hot end temperature
*/
......@@ -5348,6 +5348,18 @@ inline void gcode_M120() { enable_endstops(true); }
*/
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 HAS(HEATER_1)
/**
......@@ -7223,6 +7235,8 @@ void process_next_command() {
gcode_M120(); break;
case 121: // M121 Disable endstops
gcode_M121(); break;
case 122: // M121 Disable or enable software endstops
gcode_M122(); break;
#if ENABLED(BARICUDA)
// PWM for HEATER_1_PIN
......@@ -7467,7 +7481,7 @@ void ok_to_send() {
}
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[Y_AXIS], min_pos[Y_AXIS]);
......@@ -7479,7 +7493,7 @@ void clamp_to_software_endstops(float target[3]) {
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[Y_AXIS], max_pos[Y_AXIS]);
NOMORE(target[Z_AXIS], max_pos[Z_AXIS]);
......@@ -7514,7 +7528,7 @@ void clamp_to_software_endstops(float target[3]) {
float difference[NUM_AXIS];
float addDistance[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];
......@@ -7740,7 +7754,7 @@ void plan_arc(
// Initialize the extruder 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)
......
......@@ -17,15 +17,14 @@
#include "firmware_test.h"
static char serial_answer;
void FirmwareTest()
{
void FirmwareTest() {
ECHO_EM("---------- FIRMWARE TEST --------------");
ECHO_EM("--------- by MarlinKimbra -------------");
ECHO_EV(MSG_FWTEST_01);
ECHO_EV(MSG_FWTEST_02);
ECHO_EV(MSG_FWTEST_YES_NO);
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();
}
if (serial_answer=='y' || serial_answer=='Y') {
......@@ -33,13 +32,12 @@ void FirmwareTest()
ECHO_EM(" ");
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) {
ECHO_M("MIN ENDSTOP X: ");
ECHO_EV(MSG_ENDSTOP_OPEN);
}
else
{
else {
ECHO_M("X ENDSTOP ");
ECHO_EM(MSG_FWTEST_ERROR);
ECHO_M(MSG_FWTEST_INVERT);
......@@ -62,26 +60,24 @@ void FirmwareTest()
ECHO_EM("X");
ECHO_EV(MSG_FWTEST_YES);
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();
}
if (READ(X_MIN_PIN)^X_MIN_ENDSTOP_INVERTING) {
ECHO_M("MIN ENDSTOP X: ");
ECHO_EV(MSG_ENDSTOP_HIT);
}
else
{
else {
ECHO_M("X ");
ECHO_EV(MSG_FWTEST_ENDSTOP_ERR);
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) {
ECHO_M("MAX ENDSTOP X: ");
ECHO_EV(MSG_ENDSTOP_OPEN);
}
else
{
else {
ECHO_M("X ENDSTOP ");
ECHO_EM(MSG_FWTEST_ERROR);
ECHO_M(MSG_FWTEST_INVERT);
......@@ -104,15 +100,14 @@ void FirmwareTest()
ECHO_EM("X");
ECHO_EV(MSG_FWTEST_YES);
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();
}
if (READ(X_MAX_PIN)^X_MAX_ENDSTOP_INVERTING) {
ECHO_M("MAX ENDSTOP X: ");
ECHO_EV(MSG_ENDSTOP_HIT);
}
else
{
else {
ECHO_M("X ");
ECHO_EV(MSG_FWTEST_ENDSTOP_ERR);
return;
......@@ -131,13 +126,12 @@ void FirmwareTest()
ECHO_EM(" ");
ECHO_EM("***** ENDSTOP Y *****");
#if EXIST(Y_MIN_PIN) && Y_MIN_PIN > -1 && Y_HOME_DIR == -1
if (!READ(Y_MIN_PIN)^Y_MIN_ENDSTOP_INVERTING){
#if PIN_EXISTS(Y_MIN_PIN) && Y_HOME_DIR == -1
if (!READ(Y_MIN_PIN)^Y_MIN_ENDSTOP_INVERTING) {
ECHO_M("MIN ENDSTOP Y: ");
ECHO_EV(MSG_ENDSTOP_OPEN);
}
else
{
else {
ECHO_M("Y ENDSTOP ");
ECHO_EM(MSG_FWTEST_ERROR);
ECHO_M(MSG_FWTEST_INVERT);
......@@ -160,26 +154,24 @@ void FirmwareTest()
ECHO_EM("Y");
ECHO_EV(MSG_FWTEST_YES);
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();
}
if (READ(Y_MIN_PIN)^Y_MIN_ENDSTOP_INVERTING){
if (READ(Y_MIN_PIN)^Y_MIN_ENDSTOP_INVERTING) {
ECHO_M("MIN ENDSTOP Y: ");
ECHO_EV(MSG_ENDSTOP_HIT);
}
else
{
else {
ECHO_M("Y ");
ECHO_EV(MSG_FWTEST_ENDSTOP_ERR);
return;
}
#elif EXIST(Y_MAX_PIN) && Y_MAX_PIN > -1 && Y_HOME_DIR == 1
if (!READ(Y_MAX_PIN)^Y_MAX_ENDSTOP_INVERTING){
#elif PIN_EXISTS(Y_MAX_PIN) && Y_HOME_DIR == 1
if (!READ(Y_MAX_PIN)^Y_MAX_ENDSTOP_INVERTING) {
ECHO_M("MAX ENDSTOP Y: ");
ECHO_EV(MSG_ENDSTOP_OPEN);
}
else
{
else {
ECHO_M("Y ENDSTOP ");
ECHO_EM(MSG_FWTEST_ERROR);
ECHO_M(MSG_FWTEST_INVERT);
......@@ -202,15 +194,14 @@ void FirmwareTest()
ECHO_EM("Y");
ECHO_EV(MSG_FWTEST_YES);
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();
}
if (READ(Y_MAX_PIN)^Y_MAX_ENDSTOP_INVERTING){
if (READ(Y_MAX_PIN)^Y_MAX_ENDSTOP_INVERTING) {
ECHO_M("MAX ENDSTOP Y: ");
ECHO_EV(MSG_ENDSTOP_HIT);
}
else
{
else {
ECHO_M("Y ");
ECHO_EV(MSG_FWTEST_ENDSTOP_ERR);
return;
......@@ -229,13 +220,12 @@ void FirmwareTest()
ECHO_EM(" ");
ECHO_EM("***** ENDSTOP Z *****");
#if EXIST(Z_MIN_PIN) && Z_MIN_PIN > -1 && Z_HOME_DIR == -1
if (!READ(Z_MIN_PIN)^Z_MIN_ENDSTOP_INVERTING){
#if PIN_EXISTS(Z_MIN_PIN) && Z_HOME_DIR == -1
if (!READ(Z_MIN_PIN)^Z_MIN_ENDSTOP_INVERTING) {
ECHO_M("MIN ENDSTOP Z: ");
ECHO_EV(MSG_ENDSTOP_OPEN);
}
else
{
else {
ECHO_M("Z ENDSTOP ");
ECHO_EM(MSG_FWTEST_ERROR);
ECHO_M(MSG_FWTEST_INVERT);
......@@ -258,26 +248,24 @@ void FirmwareTest()
ECHO_EM("Z");
ECHO_EV(MSG_FWTEST_YES);
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();
}
if (READ(Z_MIN_PIN)^Z_MIN_ENDSTOP_INVERTING){
if (READ(Z_MIN_PIN)^Z_MIN_ENDSTOP_INVERTING) {
ECHO_M("MIN ENDSTOP Z: ");
ECHO_EV(MSG_ENDSTOP_HIT);
}
else
{
else {
ECHO_M("Z ");
ECHO_EV(MSG_FWTEST_ENDSTOP_ERR);
return;
}
#elif EXIST(Z_MAX_PIN) && Z_MAX_PIN > -1 && Z_HOME_DIR == 1
if (!READ(Z_MAX_PIN)^Z_MAX_ENDSTOP_INVERTING){
#elif PIN_EXISTS(Z_MAX_PIN) && Z_HOME_DIR == 1
if (!READ(Z_MAX_PIN)^Z_MAX_ENDSTOP_INVERTING) {
ECHO_M("MAX ENDSTOP Z: ");
ECHO_EV(MSG_ENDSTOP_OPEN);
}
else
{
else {
ECHO_M("Z ENDSTOP ");
ECHO_EM(MSG_FWTEST_ERROR);
ECHO_M(MSG_FWTEST_INVERT);
......@@ -300,15 +288,14 @@ void FirmwareTest()
ECHO_EM("Z");
ECHO_EV(MSG_FWTEST_YES);
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();
}
if (READ(Z_MAX_PIN)^Z_MAX_ENDSTOP_INVERTING){
if (READ(Z_MAX_PIN)^Z_MAX_ENDSTOP_INVERTING) {
ECHO_M("MAX ENDSTOP Z: ");
ECHO_EV(MSG_ENDSTOP_HIT);
}
else
{
else {
ECHO_M("Z ");
ECHO_EV(MSG_FWTEST_ENDSTOP_ERR);
return;
......@@ -337,14 +324,14 @@ void FirmwareTest()
// Reset position to 0
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]);
ECHO_EM("***** TEST MOTOR *****");
ECHO_EV(MSG_FWTEST_ATTENTION);
ECHO_EV(MSG_FWTEST_YES);
serial_answer = ' ';
while(serial_answer!='y' && serial_answer!='Y'){
while (serial_answer!='y' && serial_answer!='Y') {
serial_answer = MYSERIAL.read();
}
ECHO_EV(MSG_FWTEST_04);
......@@ -357,18 +344,17 @@ void FirmwareTest()
ECHO_EV(MSG_FWTEST_XAXIS);
ECHO_EV(MSG_FWTEST_YES_NO);
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();
}
if(serial_answer=='y' || serial_answer=='Y'){
if (serial_answer=='y' || serial_answer=='Y') {
ECHO_EM("MOTOR X ");
ECHO_M(MSG_FWTEST_OK);
}
else
{
else {
ECHO_M(MSG_FWTEST_INVERT);
ECHO_M("#define INVERT_X_DIR ");
ECHO_M(MSG_FWTEST_INTO);
ECHO_M(MSG_FWTEST_INTO);
#if MECH(CARTESIAN)
ECHO_EM("Configuration_Cartesian.h");
#elif MECH(COREXY)
......@@ -390,18 +376,17 @@ void FirmwareTest()
ECHO_EV(MSG_FWTEST_YAXIS);
ECHO_EV(MSG_FWTEST_YES_NO);
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();
}
if(serial_answer=='y' || serial_answer=='Y'){
if (serial_answer=='y' || serial_answer=='Y') {
ECHO_EM("MOTOR Y ");
ECHO_M(MSG_FWTEST_OK);
}
else
{
else {
ECHO_M(MSG_FWTEST_INVERT);
ECHO_M("#define INVERT_Y_DIR ");
ECHO_M(MSG_FWTEST_INTO);
ECHO_M(MSG_FWTEST_INTO);
#if MECH(CARTESIAN)
ECHO_EM("Configuration_Cartesian.h");
#elif MECH(COREXY)
......@@ -423,18 +408,17 @@ void FirmwareTest()
ECHO_EV(MSG_FWTEST_ZAXIS);
ECHO_EV(MSG_FWTEST_YES_NO);
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();
}
if(serial_answer=='y' || serial_answer=='Y'){
if (serial_answer=='y' || serial_answer=='Y') {
ECHO_EM("MOTOR Z ");
ECHO_M(MSG_FWTEST_OK);
}
else
{
else {
ECHO_M(MSG_FWTEST_INVERT);
ECHO_M("#define INVERT_Z_DIR ");
ECHO_M(MSG_FWTEST_INTO);
ECHO_M(MSG_FWTEST_INTO);
#if MECH(CARTESIAN)
ECHO_EM("Configuration_Cartesian.h");
#elif MECH(COREXY)
......@@ -453,4 +437,4 @@ void FirmwareTest()
ECHO_EM(" ");
ECHO_V(MSG_FWTEST_END);
}
#endif
\ No newline at end of file
#endif
#ifndef MACROS_H
#define MACROS_H
// Compiler warning on unused varable.
#define UNUSED(x) (void) (x)
// Macros for bit masks
#define BIT(b) (1<<(b))
#define TEST(n,b) (((n)&BIT(b))!=0)
......
......@@ -32,6 +32,7 @@
NexPage Pmenu = NexPage(3, 0, "menu");
NexPage Psdcard = NexPage(4, 0, "sdcard");
NexPage Psetup = NexPage(5, 0, "setup");
NexPage Pmove = NexPage(6, 0, "move");
// Text
NexText Hotend0 = NexText(1, 1, "t0");
......@@ -41,7 +42,6 @@
NexText LedStatus = NexText(1, 7, "t4");
NexText LedCoord = NexText(1, 8, "t5");
NexText set0 = NexText(2, 2, "set0");
NexText set1 = NexText(2, 15, "set1");
NexText sdrow0 = NexText(4, 3, "t0");
NexText sdrow1 = NexText(4, 4, "t1");
NexText sdrow2 = NexText(4, 5, "t2");
......@@ -58,6 +58,9 @@
NexPicture Hend1 = NexPicture(1, 14, "p4");
NexPicture Hend2 = NexPicture(1, 15, "p5");
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 Folder1 = NexPicture(4, 10, "p1");
NexPicture Folder2 = NexPicture(4, 11, "p2");
......@@ -65,7 +68,16 @@
NexPicture Folder4 = NexPicture(4, 13, "p4");
NexPicture Folder5 = NexPicture(4, 14, "p5");
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
NexProgressBar sdbar = NexProgressBar(1, 26, "j0");
......@@ -92,6 +104,7 @@
// Variable
NexVar Hotend = NexVar(1, 20, "he");
NexVar set1 = NexVar(2, 17, "set1");
NexVar Bed = NexVar(1, 21, "bed");
NexVar filename0 = NexVar(4, 19, "va0");
NexVar filename1 = NexVar(4, 20, "va1");
......@@ -99,6 +112,7 @@
NexVar filename3 = NexVar(4, 22, "va3");
NexVar filename4 = NexVar(4, 23, "va4");
NexVar filename5 = NexVar(4, 24, "va5");
NexVar movecmd = NexVar(6, 18, "vacmd");
NexTouch *nex_listen_list[] =
{
......@@ -107,6 +121,8 @@
&MSD,
&MSetup,
&Fanpic,
&NPlay,
&NStop,
&hot0,
&hot1,
&hot2,
......@@ -121,7 +137,17 @@
&sdrow4,
&sdrow5,
&Folderup,
&Exit,
&Exit1,
&Exit2,
&Exit3,
&XYHome,
&XYUp,
&XYRight,
&XYDown,
&XYLeft,
&ZHome,
&ZUp,
&ZDown,
NULL
};
......@@ -266,21 +292,21 @@
}
void sdlistPopCallback(void *ptr) {
uint32_t number = 0;
sdlist.getValue(&number);
number = slidermaxval - number;
setrowsdcard(number);
uint32_t number = 0;
sdlist.getValue(&number);
number = slidermaxval - number;
setrowsdcard(number);
}
static void menu_action_sdfile(const char* filename) {
char cmd[30];
char* c;
sprintf_P(cmd, PSTR("M23 %s"), filename);
for(c = &cmd[4]; *c; c++) *c = tolower(*c);
enqueuecommand(cmd);
enqueuecommands_P(PSTR("M24"));
setpageInfo();
}
char cmd[30];
char* c;
sprintf_P(cmd, PSTR("M23 %s"), filename);
for(c = &cmd[4]; *c; c++) *c = tolower(*c);
enqueuecommand(cmd);
enqueuecommands_P(PSTR("M24"));
setpageInfo();
}
static void menu_action_sddirectory(const char* filename) {
card.chdir(filename);
......@@ -330,13 +356,14 @@
setpagesdcard();
}
void ExitPopCallback(void *ptr) {
setpageInfo();
}
#endif
void ExitPopCallback(void *ptr) {
setpageInfo();
}
void PstartPopCallback(void *ptr) {
setpageInfo();
setpageInfo();
}
void hotPopCallback(void *ptr) {
......@@ -400,13 +427,17 @@
}
void setpagePopCallback(void *ptr) {
if (ptr == &Menu)
if (ptr == &Menu) {
PageInfo = false;
Pmenu.show();
if (ptr == &MSetup)
}
else if (ptr == &MSetup) {
PageInfo = false;
Psetup.show();
}
#if ENABLED(SDSUPPORT)
if (ptr == &MSD)
else if (ptr == &MSD)
setpagesdcard();
#endif
}
......@@ -416,6 +447,31 @@
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() {
delay(1000);
NextionON = nexInit();
......@@ -425,12 +481,16 @@
} else {
ECHO_LM(DB, "Nextion LCD connected!");
Pstart.attachPop(PstartPopCallback);
Pstart.attachPop(ExitPopCallback);
Exit1.attachPop(ExitPopCallback);
Exit3.attachPop(ExitPopCallback);
#if ENABLED(SDSUPPORT)
MSD.attachPop(setpagePopCallback, &MSD);
sdlist.attachPop(sdlistPopCallback);
Exit.attachPop(ExitPopCallback);
Exit2.attachPop(ExitPopCallback);
NPlay.attachPop(PlayPausePopCallback);
NStop.attachPop(StopPopCallback);
#endif
#if HAS_TEMP_0
......@@ -444,11 +504,19 @@
#endif
Menu.attachPop(setpagePopCallback, &Menu);
MSetup.attachPop(setpagePopCallback, &Menu);
MSetup.attachPop(setpagePopCallback, &MSetup);
Fanpic.attachPop(setfanPopCallback, &Fanpic);
m11.attachPop(sethotPopCallback, &m11);
tup.attachPop(settempPopCallback, &tup);
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();
}
......@@ -479,7 +547,7 @@
}
static void coordtoLCD() {
char *valuetemp;
char* valuetemp;
memset(buffer, 0, sizeof(buffer));
strcat(buffer, "X");
......@@ -545,13 +613,29 @@
coordtoLCD();
#if ENABLED(SDSUPPORT)
if (card.cardOK)
if (card.cardOK) {
MSD.setPic(7);
else
NPlay.setPic(38);
NStop.setPic(41);
}
else {
MSD.setPic(6);
if (IS_SD_PRINTING)
// Progress bar solid part
sdbar.setValue(card.percentDone());
NPlay.setPic(39);
NStop.setPic(42);
}
if (card.isFileOpen()) {
if (card.sdprinting) {
// Progress bar solid part
sdbar.setValue(card.percentDone());
NPlay.setPic(38);
}
else {
NPlay.setPic(40);
}
}
#endif
next_lcd_update_ms = ms + LCD_UPDATE_INTERVAL;
......
......@@ -4,12 +4,13 @@
#if ENABLED(NEXTION)
#define LCD_UPDATE_INTERVAL 5000
void PstartPopCallback(void *ptr);
void ExitUpPopCallback(void *ptr);
void setpagePopCallback(void *ptr);
void hotPopCallback(void *ptr);
void sethotPopCallback(void *ptr);
void settempPopCallback(void *ptr);
void setfanPopCallback(void *ptr);
void setmovePopCallback(void *ptr);
void lcd_update();
void lcd_init();
void lcd_setstatus(const char* message, const bool persist = false);
......@@ -22,7 +23,8 @@
void sdfilePopCallback(void *ptr);
void sdfolderPopCallback(void *ptr);
void sdfolderUpPopCallback(void *ptr);
void ExitUpPopCallback(void *ptr);
void PlayPausePopCallback(void *ptr);
void StopPopCallback(void *ptr);
#endif
FORCE_INLINE bool lcd_hasstatus() { return false; }
......
......@@ -45,10 +45,11 @@
#if HAS(DIGIPOTSS)
#include <SPI.h>
#endif
//===========================================================================
//============================= 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
//===========================================================================
......@@ -61,8 +62,8 @@ static unsigned char out_bits = 0; // The next stepping-bits to be output
static unsigned int cleaning_buffer_counter;
#if ENABLED(Z_DUAL_ENDSTOPS)
static bool performing_homing = false,
locked_z_motor = false,
static bool performing_homing = false,
locked_z_motor = false,
locked_z2_motor = false;
#endif
......@@ -92,7 +93,7 @@ static volatile char endstop_hit_bits = 0; // use X_MIN, Y_MIN, Z_MIN and Z_PROB
#else
static uint16_t
#endif
old_endstop_bits = 0; // use X_MIN, X_MAX... Z_MAX, Z_PROBE, Z2_MIN, Z2_MAX
old_endstop_bits = 0; // use X_MIN, X_MAX... Z_MAX, Z_PROBE, Z2_MIN, Z2_MAX
#if ENABLED(ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED)
bool abort_on_endstop_hit = false;
......@@ -150,11 +151,13 @@ volatile signed char count_direction[NUM_AXIS] = { 1, 1, 1, 1 };
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, 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, Z2_MIN) && (count_direction[Z_AXIS] < 0)) && !locked_z2_motor) Z2_STEP_WRITE(v); \
} \
} else { \
} \
else { \
Z_STEP_WRITE(v); \
Z2_STEP_WRITE(v); \
}
......@@ -174,24 +177,24 @@ volatile signed char count_direction[NUM_AXIS] = { 1, 1, 1, 1 };
// r27 to store the byte 1 of the 24 bit result
#define MultiU16X8toH16(intRes, charIn1, intIn2) \
asm volatile ( \
"clr r26 \n\t" \
"mul %A1, %B2 \n\t" \
"movw %A0, r0 \n\t" \
"mul %A1, %A2 \n\t" \
"add %A0, r1 \n\t" \
"adc %B0, r26 \n\t" \
"lsr r0 \n\t" \
"adc %A0, r26 \n\t" \
"adc %B0, r26 \n\t" \
"clr r1 \n\t" \
: \
"=&r" (intRes) \
: \
"d" (charIn1), \
"d" (intIn2) \
: \
"r26" \
)
"clr r26 \n\t" \
"mul %A1, %B2 \n\t" \
"movw %A0, r0 \n\t" \
"mul %A1, %A2 \n\t" \
"add %A0, r1 \n\t" \
"adc %B0, r26 \n\t" \
"lsr r0 \n\t" \
"adc %A0, r26 \n\t" \
"adc %B0, r26 \n\t" \
"clr r1 \n\t" \
: \
"=&r" (intRes) \
: \
"d" (charIn1), \
"d" (intIn2) \
: \
"r26" \
)
// intRes = longIn1 * longIn2 >> 24
// uses:
......@@ -205,49 +208,49 @@ volatile signed char count_direction[NUM_AXIS] = { 1, 1, 1, 1 };
//
#define MultiU24X32toH16(intRes, longIn1, longIn2) \
asm volatile ( \
"clr r26 \n\t" \
"mul %A1, %B2 \n\t" \
"mov r27, r1 \n\t" \
"mul %B1, %C2 \n\t" \
"movw %A0, r0 \n\t" \
"mul %C1, %C2 \n\t" \
"add %B0, r0 \n\t" \
"mul %C1, %B2 \n\t" \
"add %A0, r0 \n\t" \
"adc %B0, r1 \n\t" \
"mul %A1, %C2 \n\t" \
"add r27, r0 \n\t" \
"adc %A0, r1 \n\t" \
"adc %B0, r26 \n\t" \
"mul %B1, %B2 \n\t" \
"add r27, r0 \n\t" \
"adc %A0, r1 \n\t" \
"adc %B0, r26 \n\t" \
"mul %C1, %A2 \n\t" \
"add r27, r0 \n\t" \
"adc %A0, r1 \n\t" \
"adc %B0, r26 \n\t" \
"mul %B1, %A2 \n\t" \
"add r27, r1 \n\t" \
"adc %A0, r26 \n\t" \
"adc %B0, r26 \n\t" \
"lsr r27 \n\t" \
"adc %A0, r26 \n\t" \
"adc %B0, r26 \n\t" \
"mul %D2, %A1 \n\t" \
"add %A0, r0 \n\t" \
"adc %B0, r1 \n\t" \
"mul %D2, %B1 \n\t" \
"add %B0, r0 \n\t" \
"clr r1 \n\t" \
: \
"=&r" (intRes) \
: \
"d" (longIn1), \
"d" (longIn2) \
: \
"r26" , "r27" \
)
"clr r26 \n\t" \
"mul %A1, %B2 \n\t" \
"mov r27, r1 \n\t" \
"mul %B1, %C2 \n\t" \
"movw %A0, r0 \n\t" \
"mul %C1, %C2 \n\t" \
"add %B0, r0 \n\t" \
"mul %C1, %B2 \n\t" \
"add %A0, r0 \n\t" \
"adc %B0, r1 \n\t" \
"mul %A1, %C2 \n\t" \
"add r27, r0 \n\t" \
"adc %A0, r1 \n\t" \
"adc %B0, r26 \n\t" \
"mul %B1, %B2 \n\t" \
"add r27, r0 \n\t" \
"adc %A0, r1 \n\t" \
"adc %B0, r26 \n\t" \
"mul %C1, %A2 \n\t" \
"add r27, r0 \n\t" \
"adc %A0, r1 \n\t" \
"adc %B0, r26 \n\t" \
"mul %B1, %A2 \n\t" \
"add r27, r1 \n\t" \
"adc %A0, r26 \n\t" \
"adc %B0, r26 \n\t" \
"lsr r27 \n\t" \
"adc %A0, r26 \n\t" \
"adc %B0, r26 \n\t" \
"mul %D2, %A1 \n\t" \
"add %A0, r0 \n\t" \
"adc %B0, r1 \n\t" \
"mul %D2, %B1 \n\t" \
"add %B0, r0 \n\t" \
"clr r1 \n\t" \
: \
"=&r" (intRes) \
: \
"d" (longIn1), \
"d" (longIn2) \
: \
"r26" , "r27" \
)
// Some useful constants
......@@ -311,7 +314,7 @@ void enable_endstops(bool check) {
// Check endstops
inline void update_endstops() {
#if ENABLED(Z_DUAL_ENDSTOPS)
uint16_t
#else
......@@ -339,7 +342,7 @@ inline void update_endstops() {
_ENDSTOP_HIT(AXIS); \
step_events_completed = current_block->step_event_count; \
}
#if MECH(COREXY)
// Head direction in -X axis for CoreXY bots.
// If DeltaX == -DeltaY, the movement is only in Y axis
......@@ -351,7 +354,7 @@ inline void update_endstops() {
if ((current_block->steps[A_AXIS] != current_block->steps[C_AXIS]) || (TEST(out_bits, A_AXIS) == TEST(out_bits, C_AXIS))) {
if (TEST(out_bits, X_HEAD))
#else
if (TEST(out_bits, X_AXIS)) // stepping along -X axis (regular Cartesian bot)
if (TEST(out_bits, X_AXIS)) // stepping along -X axis (regular Cartesian bot)
#endif
{ // -direction
#if ENABLED(DUAL_X_CARRIAGE)
......@@ -414,13 +417,13 @@ inline void update_endstops() {
#if ENABLED(Z_DUAL_ENDSTOPS)
SET_ENDSTOP_BIT(Z, MIN);
#if HAS(Z2_MIN)
SET_ENDSTOP_BIT(Z2, MIN);
#else
COPY_BIT(current_endstop_bits, Z_MIN, Z2_MIN);
#endif
#if HAS(Z2_MIN)
SET_ENDSTOP_BIT(Z2, MIN);
#else
COPY_BIT(current_endstop_bits, Z_MIN, Z2_MIN);
#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
endstops_trigsteps[Z_AXIS] = count_position[Z_AXIS];
......@@ -431,14 +434,14 @@ inline void update_endstops() {
#else // !Z_DUAL_ENDSTOPS
UPDATE_ENDSTOP(Z, MIN);
#endif // !Z_DUAL_ENDSTOPS
#endif // Z_MIN_PIN
#if ENABLED(Z_PROBE_ENDSTOP)
UPDATE_ENDSTOP(Z, PROBE);
if (TEST_ENDSTOP(Z_PROBE))
{
if (TEST_ENDSTOP(Z_PROBE)) {
endstops_trigsteps[Z_AXIS] = count_position[Z_AXIS];
endstop_hit_bits |= BIT(Z_PROBE);
}
......@@ -450,13 +453,13 @@ inline void update_endstops() {
#if ENABLED(Z_DUAL_ENDSTOPS)
SET_ENDSTOP_BIT(Z, MAX);
#if HAS(Z2_MAX)
SET_ENDSTOP_BIT(Z2, MAX);
#else
COPY_BIT(current_endstop_bits, Z_MAX, Z2_MAX);
#endif
#if HAS(Z2_MAX)
SET_ENDSTOP_BIT(Z2, MAX);
#else
COPY_BIT(current_endstop_bits, Z_MAX, Z2_MAX);
#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
endstops_trigsteps[Z_AXIS] = count_position[Z_AXIS];
......@@ -474,7 +477,7 @@ inline void update_endstops() {
}
#if MECH(COREXZ)
}
#endif
#endif
old_endstop_bits = current_endstop_bits;
}
......@@ -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);
step_rate -= (F_CPU / 500000); // Correct for minimal speed
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 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);
timer = (unsigned short)pgm_read_word_near(table_address) - timer;
}
else { // lower step rates
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+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)
return timer;
......@@ -728,7 +731,6 @@ ISR(TIMER1_COMPA_vect) {
step_events_completed++;
if (step_events_completed >= current_block->step_event_count) break;
}
// Calculate new timer value
unsigned short timer;
unsigned short step_rate;
......@@ -745,19 +747,20 @@ ISR(TIMER1_COMPA_vect) {
timer = calc_timer(acc_step_rate);
OCR1A = timer;
acceleration_time += timer;
#if ENABLED(ADVANCE)
for(int8_t i=0; i < step_loops; i++) {
for (int8_t i = 0; i < step_loops; i++) {
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
e_steps[current_block->active_driver] += ((advance >>8) - old_advance);
old_advance = advance >>8;
e_steps[current_block->active_driver] += ((advance >> 8) - old_advance);
old_advance = advance >> 8;
#endif
#endif // ADVANCE
}
else if (step_events_completed > (unsigned long)current_block->decelerate_after) {
MultiU24X32toH16(step_rate, deceleration_time, current_block->acceleration_rate);
if (step_rate > acc_step_rate) { // Check step_rate stays positive
......@@ -776,13 +779,13 @@ ISR(TIMER1_COMPA_vect) {
OCR1A = timer;
deceleration_time += timer;
#if ENABLED(ADVANCE)
for(int8_t i=0; i < step_loops; i++) {
for (int8_t i = 0; i < step_loops; i++) {
advance -= advance_rate;
}
if (advance < final_advance) advance = final_advance;
// Do E steps + advance steps
e_steps[current_block->active_driver] += ((advance >>8) - old_advance);
old_advance = advance >>8;
e_steps[current_block->active_driver] += ((advance >> 8) - old_advance);
old_advance = advance >> 8;
#endif //ADVANCE
}
else {
......@@ -805,12 +808,11 @@ ISR(TIMER1_COMPA_vect) {
unsigned char old_OCR0A;
// Timer interrupt for E. e_steps is set in the main routine;
// Timer 0 is shared with millies
ISR(TIMER0_COMPA_vect)
{
ISR(TIMER0_COMPA_vect) {
old_OCR0A += 52; // ~10kHz interrupt (250000 / 26 = 9615kHz)
OCR0A = old_OCR0A;
// 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) {
E0_STEP_WRITE(INVERT_E_STEP_PIN);
if (e_steps[0] < 0) {
......@@ -838,52 +840,51 @@ ISR(TIMER1_COMPA_vect) {
E0_STEP_WRITE(!INVERT_E_STEP_PIN);
}
}
#if DRIVER_EXTRUDERS > 1
if (e_steps[1] != 0) {
E1_STEP_WRITE(INVERT_E_STEP_PIN);
if (e_steps[1] < 0) {
E1_DIR_WRITE(INVERT_E1_DIR);
e_steps[1]++;
E1_STEP_WRITE(!INVERT_E_STEP_PIN);
}
else if (e_steps[1] > 0) {
E1_DIR_WRITE(!INVERT_E1_DIR);
e_steps[1]--;
E1_STEP_WRITE(!INVERT_E_STEP_PIN);
}
}
#endif
#if DRIVER_EXTRUDERS > 2
if (e_steps[2] != 0) {
E2_STEP_WRITE(INVERT_E_STEP_PIN);
if (e_steps[2] < 0) {
E2_DIR_WRITE(INVERT_E2_DIR);
e_steps[2]++;
E2_STEP_WRITE(!INVERT_E_STEP_PIN);
}
else if (e_steps[2] > 0) {
E2_DIR_WRITE(!INVERT_E2_DIR);
e_steps[2]--;
E2_STEP_WRITE(!INVERT_E_STEP_PIN);
#if DRIVER_EXTRUDERS > 1
if (e_steps[1] != 0) {
E1_STEP_WRITE(INVERT_E_STEP_PIN);
if (e_steps[1] < 0) {
E1_DIR_WRITE(INVERT_E1_DIR);
e_steps[1]++;
E1_STEP_WRITE(!INVERT_E_STEP_PIN);
}
else if (e_steps[1] > 0) {
E1_DIR_WRITE(!INVERT_E1_DIR);
e_steps[1]--;
E1_STEP_WRITE(!INVERT_E_STEP_PIN);
}
}
}
#endif
#if DRIVER_EXTRUDERS > 3
if (e_steps[3] != 0) {
E3_STEP_WRITE(INVERT_E_STEP_PIN);
if (e_steps[3] < 0) {
E3_DIR_WRITE(INVERT_E3_DIR);
e_steps[3]++;
E3_STEP_WRITE(!INVERT_E_STEP_PIN);
#endif
#if DRIVER_EXTRUDERS > 2
if (e_steps[2] != 0) {
E2_STEP_WRITE(INVERT_E_STEP_PIN);
if (e_steps[2] < 0) {
E2_DIR_WRITE(INVERT_E2_DIR);
e_steps[2]++;
E2_STEP_WRITE(!INVERT_E_STEP_PIN);
}
else if (e_steps[2] > 0) {
E2_DIR_WRITE(!INVERT_E2_DIR);
e_steps[2]--;
E2_STEP_WRITE(!INVERT_E_STEP_PIN);
}
}
else if (e_steps[3] > 0) {
E3_DIR_WRITE(!INVERT_E3_DIR);
e_steps[3]--;
E3_STEP_WRITE(!INVERT_E_STEP_PIN);
#endif
#if DRIVER_EXTRUDERS > 3
if (e_steps[3] != 0) {
E3_STEP_WRITE(INVERT_E_STEP_PIN);
if (e_steps[3] < 0) {
E3_DIR_WRITE(INVERT_E3_DIR);
e_steps[3]++;
E3_STEP_WRITE(!INVERT_E_STEP_PIN);
}
else if (e_steps[3] > 0) {
E3_DIR_WRITE(!INVERT_E3_DIR);
e_steps[3]--;
E3_STEP_WRITE(!INVERT_E_STEP_PIN);
}
}
}
#endif
#endif
}
}
#endif // ADVANCE
......@@ -1116,15 +1117,14 @@ void st_init() {
TCCR1A &= ~BIT(WGM10);
// output mode = 00 (disconnected)
TCCR1A &= ~(3<<COM1A0);
TCCR1A &= ~(3<<COM1B0);
TCCR1A &= ~(3 << COM1A0);
TCCR1A &= ~(3 << COM1B0);
// Set the timer pre-scaler
// 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
// sure to regenerate speed_lookuptable.h with
// create_speed_lookuptable.py
TCCR1B = (TCCR1B & ~(0x07<<CS10)) | (2<<CS10);
TCCR1B = (TCCR1B & ~(0x07 << CS10)) | (2 << CS10);
OCR1A = 0x4000;
TCNT1 = 0;
......@@ -1151,7 +1151,7 @@ void st_init() {
*/
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;
count_position[X_AXIS] = x;
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)
CRITICAL_SECTION_END;
}
void st_set_e_position(const long &e) {
void st_set_e_position(const long& e) {
CRITICAL_SECTION_START;
count_position[E_AXIS] = e;
CRITICAL_SECTION_END;
......@@ -1245,7 +1245,7 @@ void quickStop() {
_APPLY_DIR(AXIS, old_pin); \
}
switch(axis) {
switch (axis) {
case X_AXIS:
BABYSTEP_AXIS(x, X, false);
......@@ -1272,16 +1272,16 @@ void quickStop() {
old_y_dir_pin = Y_DIR_READ,
old_z_dir_pin = Z_DIR_READ;
//setup new step
X_DIR_WRITE(INVERT_X_DIR^z_direction);
Y_DIR_WRITE(INVERT_Y_DIR^z_direction);
Z_DIR_WRITE(INVERT_Z_DIR^z_direction);
//perform step
X_DIR_WRITE(INVERT_X_DIR ^ z_direction);
Y_DIR_WRITE(INVERT_Y_DIR ^ z_direction);
Z_DIR_WRITE(INVERT_Z_DIR ^ z_direction);
// perform step
X_STEP_WRITE(!INVERT_X_STEP_PIN);
Y_STEP_WRITE(!INVERT_Y_STEP_PIN);
Z_STEP_WRITE(!INVERT_Z_STEP_PIN);
delayMicroseconds(2);
X_STEP_WRITE(INVERT_X_STEP_PIN);
Y_STEP_WRITE(INVERT_Y_STEP_PIN);
X_STEP_WRITE(INVERT_X_STEP_PIN);
Y_STEP_WRITE(INVERT_Y_STEP_PIN);
Z_STEP_WRITE(INVERT_Z_STEP_PIN);
//get old pin state back.
X_DIR_WRITE(old_x_dir_pin);
......@@ -1301,11 +1301,14 @@ void quickStop() {
// From Arduino DigitalPotControl example
void digitalPotWrite(int address, int value) {
#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(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);
#else
UNUSED(address);
UNUSED(value);
#endif
}
......@@ -1318,7 +1321,7 @@ void digipot_init() {
pinMode(DIGIPOTSS_PIN, OUTPUT);
for (int i = 0; i <= 4; i++) {
//digitalPotWrite(digipot_ch[i], digipot_motor_current[i]);
digipot_current(i,digipot_motor_current[i]);
digipot_current(i, digipot_motor_current[i]);
}
#endif
#if HAS(MOTOR_CURRENT_PWM_XY)
......@@ -1346,31 +1349,33 @@ void digipot_current(uint8_t driver, int current) {
#if HAS(DIGIPOTSS)
const uint8_t digipot_ch[] = DIGIPOT_CHANNELS;
digitalPotWrite(digipot_ch[driver], current);
#endif
#if HAS(MOTOR_CURRENT_PWM_XY)
switch(driver) {
#elif HAS(MOTOR_CURRENT_PWM_XY)
switch (driver) {
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 2: analogWrite(MOTOR_CURRENT_PWM_E_PIN, 255L * current / MOTOR_CURRENT_PWM_RANGE); break;
}
#else
UNUSED(driver);
UNUSED(current);
#endif
}
void microstep_init() {
#if HAS(MICROSTEPS_E1)
pinMode(E1_MS1_PIN,OUTPUT);
pinMode(E1_MS2_PIN,OUTPUT);
pinMode(E1_MS1_PIN, OUTPUT);
pinMode(E1_MS2_PIN, OUTPUT);
#endif
#if HAS(MICROSTEPS)
pinMode(X_MS1_PIN,OUTPUT);
pinMode(X_MS2_PIN,OUTPUT);
pinMode(Y_MS1_PIN,OUTPUT);
pinMode(Y_MS2_PIN,OUTPUT);
pinMode(Z_MS1_PIN,OUTPUT);
pinMode(Z_MS2_PIN,OUTPUT);
pinMode(E0_MS1_PIN,OUTPUT);
pinMode(E0_MS2_PIN,OUTPUT);
pinMode(X_MS1_PIN, OUTPUT);
pinMode(X_MS2_PIN, OUTPUT);
pinMode(Y_MS1_PIN, OUTPUT);
pinMode(Y_MS2_PIN, OUTPUT);
pinMode(Z_MS1_PIN, OUTPUT);
pinMode(Z_MS2_PIN, OUTPUT);
pinMode(E0_MS1_PIN, OUTPUT);
pinMode(E0_MS2_PIN, OUTPUT);
const uint8_t microstep_modes[] = MICROSTEP_MODES;
for (uint16_t i = 0; i < COUNT(microstep_modes); i++)
microstep_mode(i, microstep_modes[i]);
......@@ -1378,7 +1383,7 @@ void microstep_init() {
}
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 1: digitalWrite(Y_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) {
case 4: digitalWrite(E1_MS1_PIN, ms1); break;
#endif
}
if (ms2 >= 0) switch(driver) {
if (ms2 >= 0) switch (driver) {
case 0: digitalWrite(X_MS2_PIN, ms2); break;
case 1: digitalWrite(Y_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) {
}
void microstep_mode(uint8_t driver, uint8_t stepping_mode) {
switch(stepping_mode) {
case 1: microstep_ms(driver,MICROSTEP1); break;
case 2: microstep_ms(driver,MICROSTEP2); break;
case 4: microstep_ms(driver,MICROSTEP4); break;
case 8: microstep_ms(driver,MICROSTEP8); break;
case 16: microstep_ms(driver,MICROSTEP16); break;
switch (stepping_mode) {
case 1: microstep_ms(driver, MICROSTEP1); break;
case 2: microstep_ms(driver, MICROSTEP2); break;
case 4: microstep_ms(driver, MICROSTEP4); break;
case 8: microstep_ms(driver, MICROSTEP8); break;
case 16: microstep_ms(driver, MICROSTEP16); break;
#if MB(ALLIGATOR)
case 32: microstep_ms(driver,MICROSTEP32); break;
case 32: microstep_ms(driver, MICROSTEP32); break;
#endif
}
}
......
/*
temperature.cpp - temperature control
Part of Marlin
Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
......@@ -45,7 +45,7 @@
//================================== 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)
#endif
......@@ -85,18 +85,18 @@ float current_temperature_bed = 0.0;
#endif
unsigned char soft_pwm_bed;
#if ENABLED(BABYSTEPPING)
volatile int babystepsTodo[3] = { 0 };
#endif
#if ENABLED(FILAMENT_SENSOR)
int current_raw_filwidth = 0; //Holds measured filament diameter - one extruder only
#endif
#endif
#if ENABLED(THERMAL_PROTECTION_HOTENDS) || ENABLED(THERMAL_PROTECTION_BED)
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)
static TRState thermal_runaway_state_machine[4] = { TRReset, TRReset, TRReset, TRReset };
static millis_t thermal_runaway_timer[4]; // = {0,0,0,0};
......@@ -150,7 +150,6 @@ static volatile bool temp_meas_ready = false;
#else //PIDTEMPBED
static millis_t next_bed_check_ms;
#endif //PIDTEMPBED
static unsigned char soft_pwm[HOTENDS];
#if ENABLED(FAN_SOFT_PWM)
......@@ -164,7 +163,7 @@ static unsigned char soft_pwm[HOTENDS];
#endif
#if HAS(AUTO_FAN)
static millis_t next_auto_fan_check_ms;
#endif
#endif
#if ENABLED(PIDTEMP)
float Kp[HOTENDS], Ki[HOTENDS], Kd[HOTENDS], Kc[HOTENDS];
......@@ -183,10 +182,10 @@ static int maxttemp[HOTENDS] = ARRAY_BY_HOTENDS1(16383);
#endif
#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 };
#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 );
#endif
......@@ -199,6 +198,10 @@ static void updateTemperaturesFromRawValues();
millis_t watch_heater_next_ms[HOTENDS] = { 0 };
#endif
#if DISABLED(SOFT_PWM_SCALE)
#define SOFT_PWM_SCALE 0
#endif
#if ENABLED(FILAMENT_SENSOR)
static int meas_shift_index; //used to point to a delayed sample in buffer for filament width sensor
#endif
......@@ -400,6 +403,9 @@ void updatePID() {
for (int h = 0; h < HOTENDS; 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
#if ENABLED(PIDTEMPBED)
temp_iState_max_bed = PID_BED_INTEGRAL_DRIVE_MAX / bedKi;
......@@ -426,14 +432,13 @@ void setExtruderAutoFanState(int pin, bool state) {
void checkExtruderAutoFans() {
uint8_t fanState = 0;
// which fan pins need to be turned on?
// which fan pins need to be turned on?
#if HAS(AUTO_FAN_0)
if (current_temperature[0] > EXTRUDER_AUTO_FAN_TEMPERATURE)
if (current_temperature[0] > EXTRUDER_AUTO_FAN_TEMPERATURE)
fanState |= 1;
#endif
#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)
fanState |= 1;
else
......@@ -441,24 +446,22 @@ void checkExtruderAutoFans() {
}
#endif
#if HAS(AUTO_FAN_2)
if (current_temperature[2] > EXTRUDER_AUTO_FAN_TEMPERATURE)
{
if (EXTRUDER_2_AUTO_FAN_PIN == EXTRUDER_0_AUTO_FAN_PIN)
if (current_temperature[2] > EXTRUDER_AUTO_FAN_TEMPERATURE) {
if (EXTRUDER_2_AUTO_FAN_PIN == EXTRUDER_0_AUTO_FAN_PIN)
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)
fanState |= 2;
else
fanState |= 4;
}
#endif
#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)
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)
fanState |= 2;
else if (EXTRUDER_3_AUTO_FAN_PIN == EXTRUDER_2_AUTO_FAN_PIN)
else if (EXTRUDER_3_AUTO_FAN_PIN == EXTRUDER_2_AUTO_FAN_PIN)
fanState |= 4;
else
fanState |= 8;
......@@ -491,7 +494,7 @@ void checkExtruderAutoFans() {
//
// 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;
if (IsRunning()) {
ECHO_S(ER);
......@@ -527,7 +530,7 @@ float get_pid_output(int h) {
pid_output = constrain(target_temperature[h], 0, PID_MAX);
#else
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];
if (pid_error[h] > PID_FUNCTIONAL_RANGE) {
pid_output = BANG_MAX;
......@@ -556,7 +559,8 @@ float get_pid_output(int h) {
if (e_position > last_position[active_extruder]) {
lpq[lpq_ptr++] = e_position - last_position[active_extruder];
last_position[active_extruder] = e_position;
} else {
}
else {
lpq[lpq_ptr++] = 0;
}
if (lpq_ptr >= lpq_len) lpq_ptr = 0;
......@@ -738,7 +742,7 @@ void manage_heater() {
#endif
#if TEMP_SENSOR_BED != 0
#if ENABLED(THERMAL_PROTECTION_BED)
thermal_runaway_protection(&thermal_runaway_bed_state_machine, &thermal_runaway_bed_timer, current_temperature_bed, target_temperature_bed, -1, THERMAL_PROTECTION_BED_PERIOD, THERMAL_PROTECTION_BED_HYSTERESIS);
#endif
......@@ -795,24 +799,24 @@ static float analog2temp(int raw, uint8_t e) {
if (heater_ttbl_map[e] != NULL) {
float celsius = 0;
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++) {
if (PGM_RD_W((*tt)[i][0]) > raw) {
celsius = PGM_RD_W((*tt)[i-1][1]) +
(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][0]) - PGM_RD_W((*tt)[i-1][0]));
celsius = PGM_RD_W((*tt)[i - 1][1]) +
(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][0]) - PGM_RD_W((*tt)[i - 1][0]));
break;
}
}
// 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 ((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()
......@@ -824,22 +828,27 @@ static float analog2tempBed(int raw) {
for (i = 1; i < BEDTEMPTABLE_LEN; i++) {
if (PGM_RD_W(BEDTEMPTABLE[i][0]) > raw) {
celsius = PGM_RD_W(BEDTEMPTABLE[i-1][1]) +
(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][0]) - PGM_RD_W(BEDTEMPTABLE[i-1][0]));
celsius = PGM_RD_W(BEDTEMPTABLE[i - 1][1]) +
(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][0]) - PGM_RD_W(BEDTEMPTABLE[i - 1][0]));
break;
}
}
// 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;
#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
UNUSED(raw);
return 0;
#endif
}
......@@ -888,6 +897,7 @@ static void updateTemperaturesFromRawValues() {
// Reset the watchdog after we know we have a temperature measurement.
watchdog_reset();
#endif
CRITICAL_SECTION_START;
temp_meas_ready = false;
CRITICAL_SECTION_END;
......@@ -951,8 +961,8 @@ static void updateTemperaturesFromRawValues() {
void tp_init() {
#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
MCUCR=BIT(JTD);
MCUCR=BIT(JTD);
MCUCR = BIT(JTD);
MCUCR = BIT(JTD);
#endif
// Finish init of mult hotends arrays
......@@ -970,9 +980,7 @@ void tp_init() {
}
#if ENABLED(PID_ADD_EXTRUSION_RATE)
for (int e = 0; e < EXTRUDERS; e++) {
last_position[e] = 0;
}
for (int e = 0; e < EXTRUDERS; e++) last_position[e] = 0;
#endif
#if HAS(HEATER_0)
......@@ -1011,7 +1019,7 @@ void tp_init() {
digitalWrite(SS_PIN, HIGH);
#endif
OUT_WRITE(MAX6675_SS,HIGH);
OUT_WRITE(MAX6675_SS, HIGH);
#endif // HEATER_0_USES_MAX6675
......@@ -1173,21 +1181,22 @@ void tp_init() {
* their target temperature by a configurable margin.
* This is called when the temperature is set. (M104, M109)
*/
void start_watching_heater(int e) {
if (degHotend(e) < degTargetHotend(e) - (WATCH_TEMP_INCREASE + TEMP_HYSTERESIS + 1)) {
watch_target_temp[e] = degHotend(e) + WATCH_TEMP_INCREASE;
watch_heater_next_ms[e] = millis() + WATCH_TEMP_PERIOD * 1000UL;
void start_watching_heater(int h) {
if (degHotend(h) < degTargetHotend(h) - (WATCH_TEMP_INCREASE + TEMP_HYSTERESIS + 1)) {
watch_target_temp[h] = degHotend(h) + WATCH_TEMP_INCREASE;
watch_heater_next_ms[h] = millis() + WATCH_TEMP_PERIOD * 1000UL;
}
else
watch_heater_next_ms[e] = 0;
watch_heater_next_ms[h] = 0;
}
#endif
#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) {
static float tr_last_temperature = 0.0;
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_target_temperature[HOTENDS + 1] = { 0.0 };
/*
ECHO_SM(DB, "Thermal Thermal Runaway Running. Heater ID: ");
if (heater_id < 0) ECHO_M("bed"); else ECHO_V(heater_id);
......@@ -1204,49 +1213,31 @@ void tp_init() {
*state = TRReset;
switch (*state) {
case TRReset: {
case TRReset:
*timer = 0;
*state = TRInactive;
}
// Inactive state waits for a target temperature to be set
case TRInactive: {
case TRInactive:
if (target_temperature > 0) {
tr_last_temperature = temperature;
tr_target_temperature[heater_index] = target_temperature;
*timer = millis();
*state = TRFirstHeating;
}
}
break;
break;
// 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;
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
case TRStable: {
case TRStable:
// 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();
}
// If the timer goes too long without a reset, trigger shutdown
else if (millis() > *timer + period_seconds * 1000UL) {
// If the timer goes too long without a reset, trigger shutdown
else if (millis() > *timer + period_seconds * 1000UL)
*state = TRRunaway;
}
}
break;
case TRRunaway: {
break;
case TRRunaway:
_temp_error(heater_id, PSTR(MSG_T_THERMAL_RUNAWAY), PSTR(MSG_THERMAL_RUNAWAY));
}
}
}
......@@ -1322,13 +1313,13 @@ void disable_all_heaters() {
// read MSB
SPDR = 0;
for (;(SPSR & BIT(SPIF)) == 0;);
for (; (SPSR & BIT(SPIF)) == 0;);
max6675_temp = SPDR;
max6675_temp <<= 8;
// read LSB
SPDR = 0;
for (;(SPSR & BIT(SPIF)) == 0;);
for (; (SPSR & BIT(SPIF)) == 0;);
max6675_temp |= SPDR;
// disable TT_MAX6675
......@@ -1404,6 +1395,7 @@ static void set_current_temp_raw() {
* - Step the babysteps value for each axis towards 0
*/
ISR(TIMER0_COMPB_vect) {
static unsigned char temp_count = 0;
static TempState temp_state = StartupDelay;
static unsigned char pwm_count = BIT(SOFT_PWM_SCALE);
......@@ -1533,6 +1525,7 @@ ISR(TIMER0_COMPB_vect) {
pwm_count &= 0x7f;
#else // SLOW_PWM_HEATERS
/*
* SLOW PWM HEATERS
*
......@@ -1682,8 +1675,7 @@ ISR(TIMER0_COMPB_vect) {
#endif
// Prepare or measure a sensor, each one every 14th frame
switch(temp_state) {
switch (temp_state) {
case PrepareTemp_0:
#if HAS(TEMP_0)
START_ADC(TEMP_0_PIN);
......@@ -1765,8 +1757,8 @@ ISR(TIMER0_COMPB_vect) {
#if HAS(FILAMENT_SENSOR)
// 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.
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 -= (raw_filwidth_value >> 7); //multiply raw_filwidth_value by 127/128
raw_filwidth_value += ((unsigned long)ADC << 7); //add new ADC reading
}
#endif
temp_state = Prepare_POWCONSUMPTION;
......@@ -1868,7 +1860,7 @@ ISR(TIMER0_COMPB_vect) {
#if ENABLED(BABYSTEPPING)
for (uint8_t axis = X_AXIS; axis <= Z_AXIS; axis++) {
int curTodo = babystepsTodo[axis]; //get rid of volatile for performance
if (curTodo > 0) {
babystep(axis,/*fwd*/true);
babystepsTodo[axis]--; //fewer to do next time
......
......@@ -19,17 +19,17 @@
*/
#ifndef TEMPERATURE_H
#define TEMPERATURE_H
#define TEMPERATURE_H
// public functions
void tp_init(); //initialize the heating
void manage_heater(); //it is critical that this is called periodically.
#if ENABLED(FILAMENT_SENSOR)
// For converting raw Filament Width to milimeters
float analog2widthFil();
// For converting raw Filament Width to milimeters
float analog2widthFil();
// For converting raw Filament Width to an extrusion ratio
// For converting raw Filament Width to an extrusion ratio
int widthFil_to_size_ratio();
#endif
......@@ -80,7 +80,7 @@ extern float current_temperature_bed;
#if ENABLED(BABYSTEPPING)
extern volatile int babystepsTodo[3];
#endif
//high level conversion routines, for use outside of temperature.cpp
//inline so that there is no performance decrease.
//deg=degreeCelsius
......@@ -102,16 +102,16 @@ FORCE_INLINE float degTargetHotend(uint8_t hotend) { return target_temperature[H
FORCE_INLINE float degTargetBed() { return target_temperature_bed; }
#if ENABLED(THERMAL_PROTECTION_HOTENDS)
void start_watching_heater(int e=0);
void start_watching_heater(int h = 0);
#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;
#if ENABLED(THERMAL_PROTECTION_HOTENDS)
start_watching_heater(HOTEND_ARG);
#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 isHeatingBed() { return target_temperature_bed > current_temperature_bed; }
......
......@@ -339,10 +339,14 @@ static void lcd_status_screen() {
lcd_status_message[0] = '\0';
expire_status_ms = 0;
}
} else
}
else {
expire_status_ms += LCD_UPDATE_INTERVAL;
} else
}
}
else {
expire_status_ms = 0;
}
#else
expire_status_ms = 0;
#endif // SDSUPPORT
......@@ -377,7 +381,8 @@ static void lcd_status_screen() {
ignore_click = wait_for_unclick = false;
else
current_click = false;
} else if (current_click) {
}
else if (current_click) {
lcd_quick_feedback();
wait_for_unclick = true;
current_click = false;
......@@ -399,7 +404,7 @@ static void lcd_status_screen() {
#if ENABLED(ULTIPANEL_FEEDMULTIPLY)
// Dead zone at 100% feedrate
if ((feedrate_multiplier < 100 && (feedrate_multiplier + int(encoderPosition)) > 100) ||
(feedrate_multiplier > 100 && (feedrate_multiplier + int(encoderPosition)) < 100)) {
(feedrate_multiplier > 100 && (feedrate_multiplier + int(encoderPosition)) < 100)) {
encoderPosition = 0;
feedrate_multiplier = 100;
}
......@@ -472,13 +477,15 @@ static void lcd_main_menu() {
else
MENU_ITEM(function, MSG_RESUME_PRINT, lcd_sdcard_resume);
MENU_ITEM(function, MSG_STOP_PRINT, lcd_sdcard_stop);
} else {
}
else {
MENU_ITEM(submenu, MSG_CARD_MENU, lcd_sdcard_menu);
#if !PIN_EXISTS(SD_DETECT)
MENU_ITEM(gcode, MSG_CNG_SDCARD, PSTR("M21")); // SD-card changed by user
#endif
}
} else {
}
else {
MENU_ITEM(submenu, MSG_NO_CARD, lcd_sdcard_menu);
#if !PIN_EXISTS(SD_DETECT)
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() {
#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) {
babystepsTodo[axis] += (int)encoderPosition;
encoderPosition = 0;
......@@ -1644,31 +1651,31 @@ void lcd_init() {
SET_INPUT(BTN_EN2);
WRITE(BTN_EN1,HIGH);
WRITE(BTN_EN2,HIGH);
#if BTN_ENC > 0
SET_INPUT(BTN_ENC);
WRITE(BTN_ENC,HIGH);
#endif
#if ENABLED(REPRAPWORLD_KEYPAD)
pinMode(SHIFT_CLK,OUTPUT);
pinMode(SHIFT_LD,OUTPUT);
pinMode(SHIFT_OUT,INPUT);
WRITE(SHIFT_OUT,HIGH);
WRITE(SHIFT_LD,HIGH);
#endif
#else // Not NEWPANEL
#if ENABLED(SR_LCD_2W_NL) // Non latching 2 wire shift register
pinMode (SR_DATA_PIN, OUTPUT);
pinMode (SR_CLK_PIN, OUTPUT);
#elif ENABLED(SHIFT_CLK)
pinMode(SHIFT_CLK,OUTPUT);
pinMode(SHIFT_LD,OUTPUT);
pinMode(SHIFT_EN,OUTPUT);
pinMode(SHIFT_OUT,INPUT);
WRITE(SHIFT_OUT,HIGH);
WRITE(SHIFT_LD,HIGH);
WRITE(SHIFT_EN,LOW);
#endif // SR_LCD_2W_NL
#endif//!NEWPANEL
#if BTN_ENC > 0
SET_INPUT(BTN_ENC);
WRITE(BTN_ENC,HIGH);
#endif
#if ENABLED(REPRAPWORLD_KEYPAD)
pinMode(SHIFT_CLK,OUTPUT);
pinMode(SHIFT_LD,OUTPUT);
pinMode(SHIFT_OUT,INPUT);
WRITE(SHIFT_OUT,HIGH);
WRITE(SHIFT_LD,HIGH);
#endif
#else // Not NEWPANEL
#if ENABLED(SR_LCD_2W_NL) // Non latching 2 wire shift register
pinMode (SR_DATA_PIN, OUTPUT);
pinMode (SR_CLK_PIN, OUTPUT);
#elif ENABLED(SHIFT_CLK)
pinMode(SHIFT_CLK,OUTPUT);
pinMode(SHIFT_LD,OUTPUT);
pinMode(SHIFT_EN,OUTPUT);
pinMode(SHIFT_OUT,INPUT);
WRITE(SHIFT_OUT,HIGH);
WRITE(SHIFT_LD,HIGH);
WRITE(SHIFT_EN,LOW);
#endif // SR_LCD_2W_NL
#endif//!NEWPANEL
#if ENABLED(SDSUPPORT) && PIN_EXISTS(SD_DETECT)
pinMode(SD_DETECT_PIN, INPUT);
......
#include "base.h"
#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
void watchdog_init()
{
// Initialize watchdog with a 4 sec interrupt time
void watchdog_init() {
#if ENABLED(WATCHDOG_RESET_MANUAL)
//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.
// 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.
wdt_reset();
_WD_CONTROL_REG = _BV(_WD_CHANGE_BIT) | _BV(WDE);
_WD_CONTROL_REG = _BV(WDIE) | WDTO_4S;
......@@ -27,23 +17,18 @@ void watchdog_init()
#endif
}
/// reset watchdog. MUST be called every 1s after init or avr will reset.
void watchdog_reset()
{
wdt_reset();
}
//===========================================================================
//=================================== ISR ===================================
//===========================================================================
// Watchdog timer interrupt, called if main program blocks >1sec and manual reset is enabled.
#if ENABLED(WATCHDOG_RESET_MANUAL)
ISR(WDT_vect) {
ECHO_LM(ER, MSG_WATCHDOG_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 // USE_WATCHDOG
ISR(WDT_vect) {
SERIAL_ERROR_START;
SERIAL_ERRORLNPGM("Something is wrong, please turn off the printer.");
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 //WATCHDOG_RESET_MANUAL
#endif //USE_WATCHDOG
#ifndef 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();
// 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
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