|
|
|
// Tonokip RepRap firmware rewrite based off of Hydra-mmm firmware.
|
|
|
|
// Licence: GPL
|
|
|
|
|
|
|
|
#ifndef MARLIN_H
|
|
|
|
#define MARLIN_H
|
|
|
|
|
|
|
|
#define FORCE_INLINE __attribute__((always_inline)) inline
|
|
|
|
|
|
|
|
#include <math.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <inttypes.h>
|
|
|
|
|
|
|
|
#include <util/delay.h>
|
|
|
|
#include <avr/pgmspace.h>
|
|
|
|
#include <avr/eeprom.h>
|
|
|
|
#include <avr/interrupt.h>
|
|
|
|
|
|
|
|
|
|
|
|
#include "fastio.h"
|
|
|
|
#include "Configuration.h"
|
|
|
|
#include "pins.h"
|
|
|
|
|
|
|
|
#ifndef AT90USB
|
|
|
|
#define HardwareSerial_h // trick to disable the standard HWserial
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if (ARDUINO >= 100)
|
|
|
|
# include "Arduino.h"
|
|
|
|
#else
|
|
|
|
# include "WProgram.h"
|
|
|
|
//Arduino < 1.0.0 does not define this, so we need to do it ourselfs
|
|
|
|
# define analogInputToDigitalPin(p) ((p) + A0)
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef AT90USB
|
|
|
|
#include "HardwareSerial.h"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include "MarlinSerial.h"
|
|
|
|
|
|
|
|
#ifndef cbi
|
|
|
|
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
|
|
|
|
#endif
|
|
|
|
#ifndef sbi
|
|
|
|
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include "WString.h"
|
|
|
|
|
|
|
|
#ifdef AT90USB
|
|
|
|
#ifdef BTENABLED
|
|
|
|
#define MYSERIAL bt
|
|
|
|
#else
|
|
|
|
#define MYSERIAL Serial
|
|
|
|
#endif // BTENABLED
|
|
|
|
#else
|
|
|
|
#define MYSERIAL MSerial
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#define SERIAL_PROTOCOL(x) (MYSERIAL.print(x))
|
|
|
|
#define SERIAL_PROTOCOL_F(x,y) (MYSERIAL.print(x,y))
|
|
|
|
#define SERIAL_PROTOCOLPGM(x) (serialprintPGM(PSTR(x)))
|
|
|
|
#define SERIAL_PROTOCOLLN(x) (MYSERIAL.print(x),MYSERIAL.write('\n'))
|
|
|
|
#define SERIAL_PROTOCOLLNPGM(x) (serialprintPGM(PSTR(x)),MYSERIAL.write('\n'))
|
|
|
|
|
|
|
|
|
|
|
|
const char errormagic[] PROGMEM ="Error:";
|
|
|
|
const char echomagic[] PROGMEM ="echo:";
|
|
|
|
#define SERIAL_ERROR_START (serialprintPGM(errormagic))
|
|
|
|
#define SERIAL_ERROR(x) SERIAL_PROTOCOL(x)
|
|
|
|
#define SERIAL_ERRORPGM(x) SERIAL_PROTOCOLPGM(x)
|
|
|
|
#define SERIAL_ERRORLN(x) SERIAL_PROTOCOLLN(x)
|
|
|
|
#define SERIAL_ERRORLNPGM(x) SERIAL_PROTOCOLLNPGM(x)
|
|
|
|
|
|
|
|
#define SERIAL_ECHO_START (serialprintPGM(echomagic))
|
|
|
|
#define SERIAL_ECHO(x) SERIAL_PROTOCOL(x)
|
|
|
|
#define SERIAL_ECHOPGM(x) SERIAL_PROTOCOLPGM(x)
|
|
|
|
#define SERIAL_ECHOLN(x) SERIAL_PROTOCOLLN(x)
|
|
|
|
#define SERIAL_ECHOLNPGM(x) SERIAL_PROTOCOLLNPGM(x)
|
|
|
|
|
|
|
|
#define SERIAL_ECHOPAIR(name,value) (serial_echopair_P(PSTR(name),(value)))
|
|
|
|
|
|
|
|
void serial_echopair_P(const char *s_P, float v);
|
|
|
|
void serial_echopair_P(const char *s_P, double v);
|
|
|
|
void serial_echopair_P(const char *s_P, unsigned long v);
|
|
|
|
|
|
|
|
|
|
|
|
//things to write to serial from Programmemory. saves 400 to 2k of RAM.
|
|
|
|
FORCE_INLINE void serialprintPGM(const char *str)
|
|
|
|
{
|
|
|
|
char ch=pgm_read_byte(str);
|
|
|
|
while(ch)
|
|
|
|
{
|
|
|
|
MYSERIAL.write(ch);
|
|
|
|
ch=pgm_read_byte(++str);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void get_command();
|
|
|
|
void process_commands();
|
|
|
|
|
|
|
|
void manage_inactivity();
|
|
|
|
|
|
|
|
#if defined(DUAL_X_CARRIAGE) && defined(X_ENABLE_PIN) && X_ENABLE_PIN > -1 \
|
|
|
|
&& defined(X2_ENABLE_PIN) && X2_ENABLE_PIN > -1
|
|
|
|
#define enable_x() do { WRITE(X_ENABLE_PIN, X_ENABLE_ON); WRITE(X2_ENABLE_PIN, X_ENABLE_ON); } while (0)
|
|
|
|
#define disable_x() do { WRITE(X_ENABLE_PIN,!X_ENABLE_ON); WRITE(X2_ENABLE_PIN,!X_ENABLE_ON); axis_known_position[X_AXIS] = false; } while (0)
|
|
|
|
#elif defined(X_ENABLE_PIN) && X_ENABLE_PIN > -1
|
|
|
|
#define enable_x() WRITE(X_ENABLE_PIN, X_ENABLE_ON)
|
|
|
|
#define disable_x() { WRITE(X_ENABLE_PIN,!X_ENABLE_ON); axis_known_position[X_AXIS] = false; }
|
|
|
|
#else
|
|
|
|
#define enable_x() ;
|
|
|
|
#define disable_x() ;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if defined(Y_ENABLE_PIN) && Y_ENABLE_PIN > -1
|
|
|
|
#ifdef Y_DUAL_STEPPER_DRIVERS
|
|
|
|
#define enable_y() { WRITE(Y_ENABLE_PIN, Y_ENABLE_ON); WRITE(Y2_ENABLE_PIN, Y_ENABLE_ON); }
|
|
|
|
#define disable_y() { WRITE(Y_ENABLE_PIN,!Y_ENABLE_ON); WRITE(Y2_ENABLE_PIN, !Y_ENABLE_ON); axis_known_position[Y_AXIS] = false; }
|
|
|
|
#else
|
|
|
|
#define enable_y() WRITE(Y_ENABLE_PIN, Y_ENABLE_ON)
|
|
|
|
#define disable_y() { WRITE(Y_ENABLE_PIN,!Y_ENABLE_ON); axis_known_position[Y_AXIS] = false; }
|
|
|
|
#endif
|
|
|
|
#else
|
|
|
|
#define enable_y() ;
|
|
|
|
#define disable_y() ;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if defined(Z_ENABLE_PIN) && Z_ENABLE_PIN > -1
|
|
|
|
#ifdef Z_DUAL_STEPPER_DRIVERS
|
|
|
|
#define enable_z() { WRITE(Z_ENABLE_PIN, Z_ENABLE_ON); WRITE(Z2_ENABLE_PIN, Z_ENABLE_ON); }
|
|
|
|
#define disable_z() { WRITE(Z_ENABLE_PIN,!Z_ENABLE_ON); WRITE(Z2_ENABLE_PIN,!Z_ENABLE_ON); axis_known_position[Z_AXIS] = false; }
|
|
|
|
#else
|
|
|
|
#define enable_z() WRITE(Z_ENABLE_PIN, Z_ENABLE_ON)
|
|
|
|
#define disable_z() { WRITE(Z_ENABLE_PIN,!Z_ENABLE_ON); axis_known_position[Z_AXIS] = false; }
|
|
|
|
#endif
|
|
|
|
#else
|
|
|
|
#define enable_z() ;
|
|
|
|
#define disable_z() ;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if defined(E0_ENABLE_PIN) && (E0_ENABLE_PIN > -1)
|
|
|
|
#define enable_e0() WRITE(E0_ENABLE_PIN, E_ENABLE_ON)
|
|
|
|
#define disable_e0() WRITE(E0_ENABLE_PIN,!E_ENABLE_ON)
|
|
|
|
#else
|
|
|
|
#define enable_e0() /* nothing */
|
|
|
|
#define disable_e0() /* nothing */
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if (EXTRUDERS > 1) && defined(E1_ENABLE_PIN) && (E1_ENABLE_PIN > -1)
|
|
|
|
#define enable_e1() WRITE(E1_ENABLE_PIN, E_ENABLE_ON)
|
|
|
|
#define disable_e1() WRITE(E1_ENABLE_PIN,!E_ENABLE_ON)
|
|
|
|
#else
|
|
|
|
#define enable_e1() /* nothing */
|
|
|
|
#define disable_e1() /* nothing */
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if (EXTRUDERS > 2) && defined(E2_ENABLE_PIN) && (E2_ENABLE_PIN > -1)
|
|
|
|
#define enable_e2() WRITE(E2_ENABLE_PIN, E_ENABLE_ON)
|
|
|
|
#define disable_e2() WRITE(E2_ENABLE_PIN,!E_ENABLE_ON)
|
|
|
|
#else
|
|
|
|
#define enable_e2() /* nothing */
|
|
|
|
#define disable_e2() /* nothing */
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
enum AxisEnum {X_AXIS=0, Y_AXIS=1, Z_AXIS=2, E_AXIS=3};
|
|
|
|
|
|
|
|
|
|
|
|
void FlushSerialRequestResend();
|
|
|
|
void ClearToSend();
|
|
|
|
|
|
|
|
void get_coordinates();
|
|
|
|
#ifdef DELTA
|
|
|
|
void calculate_delta(float cartesian[3]);
|
|
|
|
extern float delta[3];
|
|
|
|
#endif
|
|
|
|
void prepare_move();
|
|
|
|
void kill();
|
|
|
|
void Stop();
|
|
|
|
|
|
|
|
bool IsStopped();
|
|
|
|
|
|
|
|
void enquecommand(const char *cmd); //put an ascii command at the end of the current buffer.
|
|
|
|
void enquecommand_P(const char *cmd); //put an ascii command at the end of the current buffer, read from flash
|
|
|
|
void prepare_arc_move(char isclockwise);
|
|
|
|
void clamp_to_software_endstops(float target[3]);
|
|
|
|
|
|
|
|
#ifdef FAST_PWM_FAN
|
|
|
|
void setPwmFrequency(uint8_t pin, int val);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef CRITICAL_SECTION_START
|
|
|
|
#define CRITICAL_SECTION_START unsigned char _sreg = SREG; cli();
|
|
|
|
#define CRITICAL_SECTION_END SREG = _sreg;
|
|
|
|
#endif //CRITICAL_SECTION_START
|
|
|
|
|
|
|
|
extern float homing_feedrate[];
|
|
|
|
extern bool axis_relative_modes[];
|
|
|
|
extern int feedmultiply;
|
|
|
|
extern int extrudemultiply; // Sets extrude multiply factor (in percent)
|
|
|
|
extern float current_position[NUM_AXIS] ;
|
|
|
|
extern float add_homeing[3];
|
|
|
|
#ifdef DELTA
|
|
|
|
extern float endstop_adj[3];
|
|
|
|
#endif
|
M206: always use homing ("homeing") offsets
Previously the parameters set in M206 would only be used if a G82
command was sent with specific axis home values. This limits its
usefulness.
Really, we should have a way to adjust the XYZ homing of a machine in
the eeprom. So as the first stage of this, make M206 affect every
home command. The values set using M206 are now added to the
configuration variables [XYZ]_HOME_POS.
This is achieved by replacing all uses of [XYZ]_HOME_POS in the code
by a new home_pos[] which includes the adjustment. We also have to
adjust the uses of [XYZ]_{MIN,MAX}_POS similarly - see below.
To allow axis_is_at_home to be written as a function taking an axis
index rather than a macro taking an axis letter, we provide
constant arrays in program memory containing the values of
[XYZ]_{MIN,MAX,HOME}_POS from the compiled-in configuration.
This is done with some helper macros to deal with the declaration
(XYZ_CONSTS_FROM_CONFIG) and definition of the inline function which
does the program memory access.
We also introduce the overloaded function read_pgm_any, whose
instances are produced with DEFINE_PGM_READ_ANY, which allows the
access functions to automatically produce the correct type.
The type- and pointer-massaging code in the access function boils
down, when compiled, to a simple program memory access.
A question arises: if the M206 offset is set, should this adjustment
to the home position shift or change the possible range of movement
permitted by the software endstops ?
The documentation in Configuration.h describes these limits as:
// Travel limits after homing
Since this is a file containing physical limits, and actual suggested
values for these configuration parameters appear to include a certain
amount of slop, I've taken the view that these should be regarded as
nominal physical distances from the limit switches, and that the
permissible travel should be unaffected by M206.
So for example with the (rather unrealistic)
#define X_HOME_DIR -1
#define X_MIN_POS -20
#define X_HOME_POS 0
#define X_MAX_POS 100
no matter the setting of M206 X, the machine would be permitted
to move from 20mm "beyond" the limit switch trigger point in
the negative X direction and 100mm away from the limit switch in
the positive X direction, for a total travel of 120mm.
With M206 X-10 that would be considered to correspond to X coordinates
-30 to +90. With M206 X+10 that would be considered to correspond to
X coordinates -10 to +110.
fixes #200 (in ErikZalm/Marlin).
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
13 years ago
|
|
|
extern float min_pos[3];
|
|
|
|
extern float max_pos[3];
|
|
|
|
extern bool axis_known_position[3];
|
|
|
|
extern int fanSpeed;
|
|
|
|
#ifdef BARICUDA
|
|
|
|
extern int ValvePressure;
|
|
|
|
extern int EtoPPressure;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef FAN_SOFT_PWM
|
|
|
|
extern unsigned char fanSpeedSoftPwm;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef FWRETRACT
|
|
|
|
extern bool autoretract_enabled;
|
|
|
|
extern bool retracted;
|
|
|
|
extern float retract_length, retract_feedrate, retract_zlift;
|
|
|
|
extern float retract_recover_length, retract_recover_feedrate;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
extern unsigned long starttime;
|
|
|
|
extern unsigned long stoptime;
|
|
|
|
|
|
|
|
// Handling multiple extruders pins
|
|
|
|
extern uint8_t active_extruder;
|
|
|
|
|
|
|
|
#endif
|