cfc6a3a87a
With this change a mechanical or optical switch may be used to check the availability of the filament and when the filament runs out an M600 (filament change) command is issued. This is only done while printing with an SD card. This feature was requested several times (issue #679), but the requests were not accepted since it was believed that this situation should be handled at host side. However during an SD print the control is totally on firmware and I think that during an SD print it should be handled by the firmware. The original code was posted at reprap forum (http://forums.reprap.org/read.php?1,297350) by Lazymonk. I have only corrected some bugs of the code and improved it by adding definitions to the configuration.h in order to make it more standardized.
290 lines
9 KiB
C
290 lines
9 KiB
C
// Tonokip RepRap firmware rewrite based off of Hydra-mmm firmware.
|
|
// License: 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"
|
|
#endif
|
|
|
|
// Arduino < 1.0.0 does not define this, so we need to do it ourselves
|
|
#ifndef analogInputToDigitalPin
|
|
#define analogInputToDigitalPin(p) ((p) + 0xA0)
|
|
#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'))
|
|
|
|
|
|
extern const char errormagic[] PROGMEM;
|
|
extern const char echomagic[] PROGMEM;
|
|
|
|
#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)))
|
|
|
|
#define SERIAL_EOL MYSERIAL.write('\n')
|
|
|
|
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 Program memory. 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(bool ignore_stepper_queue=false);
|
|
|
|
#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
|
|
|
|
#if (EXTRUDERS > 3) && defined(E3_ENABLE_PIN) && (E3_ENABLE_PIN > -1)
|
|
#define enable_e3() WRITE(E3_ENABLE_PIN, E_ENABLE_ON)
|
|
#define disable_e3() WRITE(E3_ENABLE_PIN,!E_ENABLE_ON)
|
|
#else
|
|
#define enable_e3() /* nothing */
|
|
#define disable_e3() /* nothing */
|
|
#endif
|
|
|
|
enum AxisEnum {X_AXIS=0, Y_AXIS=1, Z_AXIS=2, E_AXIS=3, X_HEAD=4, Y_HEAD=5};
|
|
//X_HEAD and Y_HEAD is used for systems that don't have a 1:1 relationship between X_AXIS and X Head movement, like CoreXY bots.
|
|
|
|
void FlushSerialRequestResend();
|
|
void ClearToSend();
|
|
|
|
void get_coordinates();
|
|
#ifdef DELTA
|
|
void calculate_delta(float cartesian[3]);
|
|
extern float delta[3];
|
|
#endif
|
|
#ifdef SCARA
|
|
void calculate_delta(float cartesian[3]);
|
|
void calculate_SCARA_forward_Transform(float f_scara[3]);
|
|
#endif
|
|
void prepare_move();
|
|
void kill();
|
|
void Stop();
|
|
|
|
#ifdef FILAMENT_RUNOUT_SENSOR
|
|
void filrunout();
|
|
#endif
|
|
|
|
bool IsStopped();
|
|
|
|
bool enquecommand(const char *cmd); //put a single ASCII command at the end of the current buffer or return false when it is full
|
|
void enquecommands_P(const char *cmd); //put one or many ASCII commands at the end of the current buffer, read from flash
|
|
|
|
void prepare_arc_move(char isclockwise);
|
|
void clamp_to_software_endstops(float target[3]);
|
|
|
|
void refresh_cmd_timeout(void);
|
|
|
|
#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) for all extruders
|
|
extern bool volumetric_enabled;
|
|
extern int extruder_multiply[EXTRUDERS]; // sets extrude multiply factor (in percent) for each extruder individually
|
|
extern float filament_size[EXTRUDERS]; // cross-sectional area of filament (in millimeters), typically around 1.75 or 2.85, 0 disables the volumetric calculations for the extruder.
|
|
extern float volumetric_multiplier[EXTRUDERS]; // reciprocal of cross-sectional area of filament (in square millimeters), stored this way to reduce computational burden in planner
|
|
extern float current_position[NUM_AXIS] ;
|
|
extern float add_homing[3];
|
|
#ifdef DELTA
|
|
extern float endstop_adj[3];
|
|
extern float delta_radius;
|
|
extern float delta_diagonal_rod;
|
|
extern float delta_segments_per_second;
|
|
void recalc_delta_settings(float radius, float diagonal_rod);
|
|
#endif
|
|
#ifdef SCARA
|
|
extern float axis_scaling[3]; // Build size scaling
|
|
#endif
|
|
extern float min_pos[3];
|
|
extern float max_pos[3];
|
|
extern bool axis_known_position[3];
|
|
extern float zprobe_zoffset;
|
|
extern int fanSpeed;
|
|
#ifdef BARICUDA
|
|
extern int ValvePressure;
|
|
extern int EtoPPressure;
|
|
#endif
|
|
|
|
#ifdef FAN_SOFT_PWM
|
|
extern unsigned char fanSpeedSoftPwm;
|
|
#endif
|
|
|
|
#ifdef FILAMENT_SENSOR
|
|
extern float filament_width_nominal; //holds the theoretical filament diameter ie., 3.00 or 1.75
|
|
extern bool filament_sensor; //indicates that filament sensor readings should control extrusion
|
|
extern float filament_width_meas; //holds the filament diameter as accurately measured
|
|
extern signed char measurement_delay[]; //ring buffer to delay measurement
|
|
extern int delay_index1, delay_index2; //index into ring buffer
|
|
extern float delay_dist; //delay distance counter
|
|
extern int meas_delay_cm; //delay distance
|
|
#endif
|
|
|
|
#ifdef FWRETRACT
|
|
extern bool autoretract_enabled;
|
|
extern bool retracted[EXTRUDERS];
|
|
extern float retract_length, retract_length_swap, retract_feedrate, retract_zlift;
|
|
extern float retract_recover_length, retract_recover_length_swap, retract_recover_feedrate;
|
|
#endif
|
|
|
|
extern unsigned long starttime;
|
|
extern unsigned long stoptime;
|
|
|
|
// Handling multiple extruders pins
|
|
extern uint8_t active_extruder;
|
|
|
|
#ifdef DIGIPOT_I2C
|
|
extern void digipot_i2c_set_current( int channel, float current );
|
|
extern void digipot_i2c_init();
|
|
#endif
|
|
|
|
#endif
|
|
|
|
extern void calculate_volumetric_multipliers();
|
|
|