Fix compile error
337
Marlin/HAL.h
|
@ -1,337 +0,0 @@
|
|||
/* **************************************************************************
|
||||
|
||||
Marlin 3D Printer Firmware
|
||||
Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
|
||||
Copyright (c) 2016 Bob Cousins bobcousins42@googlemail.com
|
||||
|
||||
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/>.
|
||||
****************************************************************************/
|
||||
|
||||
/**
|
||||
* Description: HAL for __AVR__
|
||||
*/
|
||||
|
||||
#ifndef _HAL_AVR_H_
|
||||
#define _HAL_AVR_H_
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// Includes
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
#include "fastio.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <Arduino.h>
|
||||
#include <util/delay.h>
|
||||
#include <avr/eeprom.h>
|
||||
#include <avr/pgmspace.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include <avr/io.h>
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// Defines
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
//#define analogInputToDigitalPin(IO) IO
|
||||
|
||||
// Bracket code that shouldn't be interrupted
|
||||
#ifndef CRITICAL_SECTION_START
|
||||
#define CRITICAL_SECTION_START unsigned char _sreg = SREG; cli()
|
||||
#define CRITICAL_SECTION_END SREG = _sreg
|
||||
#endif
|
||||
|
||||
#define ISRS_ENABLED() TEST(SREG, SREG_I)
|
||||
#define ENABLE_ISRS() sei()
|
||||
#define DISABLE_ISRS() cli()
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// Types
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
typedef uint16_t hal_timer_t;
|
||||
#define HAL_TIMER_TYPE_MAX 0xFFFF
|
||||
|
||||
typedef int8_t pin_t;
|
||||
|
||||
#define HAL_SERVO_LIB Servo
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// Public Variables
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
//extern uint8_t MCUSR;
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// Public functions
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
//void cli(void);
|
||||
|
||||
//void _delay_ms(const int delay);
|
||||
|
||||
inline void HAL_clear_reset_source(void) { MCUSR = 0; }
|
||||
inline uint8_t HAL_get_reset_source(void) { return MCUSR; }
|
||||
|
||||
// eeprom
|
||||
//void eeprom_write_byte(unsigned char *pos, unsigned char value);
|
||||
//unsigned char eeprom_read_byte(unsigned char *pos);
|
||||
|
||||
// timers
|
||||
#define HAL_TIMER_RATE ((F_CPU) / 8) // i.e., 2MHz or 2.5MHz
|
||||
|
||||
#define STEP_TIMER_NUM 1
|
||||
#define TEMP_TIMER_NUM 0
|
||||
#define PULSE_TIMER_NUM STEP_TIMER_NUM
|
||||
|
||||
#define TEMP_TIMER_FREQUENCY ((F_CPU) / 64.0 / 256.0)
|
||||
|
||||
#define STEPPER_TIMER_RATE HAL_TIMER_RATE
|
||||
#define STEPPER_TIMER_PRESCALE 8
|
||||
#define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1000000) // Cannot be of type double
|
||||
|
||||
#define PULSE_TIMER_RATE STEPPER_TIMER_RATE // frequency of pulse timer
|
||||
#define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE
|
||||
#define PULSE_TIMER_TICKS_PER_US STEPPER_TIMER_TICKS_PER_US
|
||||
|
||||
#define ENABLE_STEPPER_DRIVER_INTERRUPT() SBI(TIMSK1, OCIE1A)
|
||||
#define DISABLE_STEPPER_DRIVER_INTERRUPT() CBI(TIMSK1, OCIE1A)
|
||||
#define STEPPER_ISR_ENABLED() TEST(TIMSK1, OCIE1A)
|
||||
|
||||
#define ENABLE_TEMPERATURE_INTERRUPT() SBI(TIMSK0, OCIE0B)
|
||||
#define DISABLE_TEMPERATURE_INTERRUPT() CBI(TIMSK0, OCIE0B)
|
||||
#define TEMPERATURE_ISR_ENABLED() TEST(TIMSK0, OCIE0B)
|
||||
|
||||
FORCE_INLINE void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) {
|
||||
UNUSED(frequency);
|
||||
switch (timer_num) {
|
||||
case STEP_TIMER_NUM:
|
||||
// waveform generation = 0100 = CTC
|
||||
SET_WGM(1, CTC_OCRnA);
|
||||
|
||||
// output mode = 00 (disconnected)
|
||||
SET_COMA(1, NORMAL);
|
||||
|
||||
// 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
|
||||
SET_CS(1, PRESCALER_8); // CS 2 = 1/8 prescaler
|
||||
|
||||
// Init Stepper ISR to 122 Hz for quick starting
|
||||
// (F_CPU) / (STEPPER_TIMER_PRESCALE) / frequency
|
||||
OCR1A = 0x4000;
|
||||
TCNT1 = 0;
|
||||
break;
|
||||
|
||||
case TEMP_TIMER_NUM:
|
||||
// Use timer0 for temperature measurement
|
||||
// Interleave temperature interrupt with millies interrupt
|
||||
OCR0B = 128;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#define TIMER_OCR_1 OCR1A
|
||||
#define TIMER_COUNTER_1 TCNT1
|
||||
|
||||
#define TIMER_OCR_0 OCR0A
|
||||
#define TIMER_COUNTER_0 TCNT0
|
||||
|
||||
#define _CAT(a, ...) a ## __VA_ARGS__
|
||||
#define HAL_timer_set_compare(timer, compare) (_CAT(TIMER_OCR_, timer) = compare)
|
||||
#define HAL_timer_get_compare(timer) _CAT(TIMER_OCR_, timer)
|
||||
#define HAL_timer_get_count(timer) _CAT(TIMER_COUNTER_, timer)
|
||||
|
||||
/**
|
||||
* On AVR there is no hardware prioritization and preemption of
|
||||
* interrupts, so this emulates it. The UART has first priority
|
||||
* (otherwise, characters will be lost due to UART overflow).
|
||||
* Then: Stepper, Endstops, Temperature, and -finally- all others.
|
||||
*/
|
||||
#define HAL_timer_isr_prologue(TIMER_NUM)
|
||||
#define HAL_timer_isr_epilogue(TIMER_NUM)
|
||||
|
||||
/* 18 cycles maximum latency */
|
||||
#define HAL_STEP_TIMER_ISR \
|
||||
extern "C" void TIMER1_COMPA_vect (void) __attribute__ ((signal, naked, used, externally_visible)); \
|
||||
extern "C" void TIMER1_COMPA_vect_bottom (void) asm ("TIMER1_COMPA_vect_bottom") __attribute__ ((used, externally_visible, noinline)); \
|
||||
void TIMER1_COMPA_vect (void) { \
|
||||
__asm__ __volatile__ ( \
|
||||
A("push r16") /* 2 Save R16 */ \
|
||||
A("in r16, __SREG__") /* 1 Get SREG */ \
|
||||
A("push r16") /* 2 Save SREG into stack */ \
|
||||
A("lds r16, %[timsk0]") /* 2 Load into R0 the Temperature timer Interrupt mask register */ \
|
||||
A("push r16") /* 2 Save TIMSK0 into the stack */ \
|
||||
A("andi r16,~%[msk0]") /* 1 Disable the temperature ISR */ \
|
||||
A("sts %[timsk0], r16") /* 2 And set the new value */ \
|
||||
A("lds r16, %[timsk1]") /* 2 Load into R0 the stepper timer Interrupt mask register [TIMSK1] */ \
|
||||
A("andi r16,~%[msk1]") /* 1 Disable the stepper ISR */ \
|
||||
A("sts %[timsk1], r16") /* 2 And set the new value */ \
|
||||
A("push r16") /* 2 Save TIMSK1 into stack */ \
|
||||
A("in r16, 0x3B") /* 1 Get RAMPZ register */ \
|
||||
A("push r16") /* 2 Save RAMPZ into stack */ \
|
||||
A("in r16, 0x3C") /* 1 Get EIND register */ \
|
||||
A("push r0") /* C runtime can modify all the following registers without restoring them */ \
|
||||
A("push r1") \
|
||||
A("push r18") \
|
||||
A("push r19") \
|
||||
A("push r20") \
|
||||
A("push r21") \
|
||||
A("push r22") \
|
||||
A("push r23") \
|
||||
A("push r24") \
|
||||
A("push r25") \
|
||||
A("push r26") \
|
||||
A("push r27") \
|
||||
A("push r30") \
|
||||
A("push r31") \
|
||||
A("clr r1") /* C runtime expects this register to be 0 */ \
|
||||
A("call TIMER1_COMPA_vect_bottom") /* Call the bottom handler - No inlining allowed, otherwise registers used are not saved */ \
|
||||
A("pop r31") \
|
||||
A("pop r30") \
|
||||
A("pop r27") \
|
||||
A("pop r26") \
|
||||
A("pop r25") \
|
||||
A("pop r24") \
|
||||
A("pop r23") \
|
||||
A("pop r22") \
|
||||
A("pop r21") \
|
||||
A("pop r20") \
|
||||
A("pop r19") \
|
||||
A("pop r18") \
|
||||
A("pop r1") \
|
||||
A("pop r0") \
|
||||
A("out 0x3C, r16") /* 1 Restore EIND register */ \
|
||||
A("pop r16") /* 2 Get the original RAMPZ register value */ \
|
||||
A("out 0x3B, r16") /* 1 Restore RAMPZ register to its original value */ \
|
||||
A("pop r16") /* 2 Get the original TIMSK1 value but with stepper ISR disabled */ \
|
||||
A("ori r16,%[msk1]") /* 1 Reenable the stepper ISR */ \
|
||||
A("cli") /* 1 Disable global interrupts - Reenabling Stepper ISR can reenter amd temperature can reenter, and we want that, if it happens, after this ISR has ended */ \
|
||||
A("sts %[timsk1], r16") /* 2 And restore the old value - This reenables the stepper ISR */ \
|
||||
A("pop r16") /* 2 Get the temperature timer Interrupt mask register [TIMSK0] */ \
|
||||
A("sts %[timsk0], r16") /* 2 And restore the old value - This reenables the temperature ISR */ \
|
||||
A("pop r16") /* 2 Get the old SREG value */ \
|
||||
A("out __SREG__, r16") /* 1 And restore the SREG value */ \
|
||||
A("pop r16") /* 2 Restore R16 value */ \
|
||||
A("reti") /* 4 Return from interrupt */ \
|
||||
: \
|
||||
: [timsk0] "i" ((uint16_t)&TIMSK0), \
|
||||
[timsk1] "i" ((uint16_t)&TIMSK1), \
|
||||
[msk0] "M" ((uint8_t)(1<<OCIE0B)),\
|
||||
[msk1] "M" ((uint8_t)(1<<OCIE1A)) \
|
||||
: \
|
||||
); \
|
||||
} \
|
||||
void TIMER1_COMPA_vect_bottom(void)
|
||||
|
||||
/* 14 cycles maximum latency */
|
||||
#define HAL_TEMP_TIMER_ISR \
|
||||
extern "C" void TIMER0_COMPB_vect (void) __attribute__ ((signal, naked, used, externally_visible)); \
|
||||
extern "C" void TIMER0_COMPB_vect_bottom(void) asm ("TIMER0_COMPB_vect_bottom") __attribute__ ((used, externally_visible, noinline)); \
|
||||
void TIMER0_COMPB_vect (void) { \
|
||||
__asm__ __volatile__ ( \
|
||||
A("push r16") /* 2 Save R16 */ \
|
||||
A("in r16, __SREG__") /* 1 Get SREG */ \
|
||||
A("push r16") /* 2 Save SREG into stack */ \
|
||||
A("lds r16, %[timsk0]") /* 2 Load into R0 the Temperature timer Interrupt mask register */ \
|
||||
A("andi r16,~%[msk0]") /* 1 Disable the temperature ISR */ \
|
||||
A("sts %[timsk0], r16") /* 2 And set the new value */ \
|
||||
A("sei") /* 1 Enable global interrupts - It is safe, as the temperature ISR is disabled, so we cannot reenter it */ \
|
||||
A("push r16") /* 2 Save TIMSK0 into stack */ \
|
||||
A("in r16, 0x3B") /* 1 Get RAMPZ register */ \
|
||||
A("push r16") /* 2 Save RAMPZ into stack */ \
|
||||
A("in r16, 0x3C") /* 1 Get EIND register */ \
|
||||
A("push r0") /* C runtime can modify all the following registers without restoring them */ \
|
||||
A("push r1") \
|
||||
A("push r18") \
|
||||
A("push r19") \
|
||||
A("push r20") \
|
||||
A("push r21") \
|
||||
A("push r22") \
|
||||
A("push r23") \
|
||||
A("push r24") \
|
||||
A("push r25") \
|
||||
A("push r26") \
|
||||
A("push r27") \
|
||||
A("push r30") \
|
||||
A("push r31") \
|
||||
A("clr r1") /* C runtime expects this register to be 0 */ \
|
||||
A("call TIMER0_COMPB_vect_bottom") /* Call the bottom handler - No inlining allowed, otherwise registers used are not saved */ \
|
||||
A("pop r31") \
|
||||
A("pop r30") \
|
||||
A("pop r27") \
|
||||
A("pop r26") \
|
||||
A("pop r25") \
|
||||
A("pop r24") \
|
||||
A("pop r23") \
|
||||
A("pop r22") \
|
||||
A("pop r21") \
|
||||
A("pop r20") \
|
||||
A("pop r19") \
|
||||
A("pop r18") \
|
||||
A("pop r1") \
|
||||
A("pop r0") \
|
||||
A("out 0x3C, r16") /* 1 Restore EIND register */ \
|
||||
A("pop r16") /* 2 Get the original RAMPZ register value */ \
|
||||
A("out 0x3B, r16") /* 1 Restore RAMPZ register to its original value */ \
|
||||
A("pop r16") /* 2 Get the original TIMSK0 value but with temperature ISR disabled */ \
|
||||
A("ori r16,%[msk0]") /* 1 Enable temperature ISR */ \
|
||||
A("cli") /* 1 Disable global interrupts - We must do this, as we will reenable the temperature ISR, and we don't want to reenter this handler until the current one is done */ \
|
||||
A("sts %[timsk0], r16") /* 2 And restore the old value */ \
|
||||
A("pop r16") /* 2 Get the old SREG */ \
|
||||
A("out __SREG__, r16") /* 1 And restore the SREG value */ \
|
||||
A("pop r16") /* 2 Restore R16 */ \
|
||||
A("reti") /* 4 Return from interrupt */ \
|
||||
: \
|
||||
: [timsk0] "i"((uint16_t)&TIMSK0), \
|
||||
[msk0] "M" ((uint8_t)(1<<OCIE0B)) \
|
||||
: \
|
||||
); \
|
||||
} \
|
||||
void TIMER0_COMPB_vect_bottom(void)
|
||||
|
||||
// ADC
|
||||
#ifdef DIDR2
|
||||
#define HAL_ANALOG_SELECT(pin) do{ if (pin < 8) SBI(DIDR0, pin); else SBI(DIDR2, pin & 0x07); }while(0)
|
||||
#else
|
||||
#define HAL_ANALOG_SELECT(pin) do{ SBI(DIDR0, pin); }while(0)
|
||||
#endif
|
||||
|
||||
inline void HAL_adc_init(void) {
|
||||
ADCSRA = _BV(ADEN) | _BV(ADSC) | _BV(ADIF) | 0x07;
|
||||
DIDR0 = 0;
|
||||
#ifdef DIDR2
|
||||
DIDR2 = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
#define SET_ADMUX_ADCSRA(pin) ADMUX = _BV(REFS0) | (pin & 0x07); SBI(ADCSRA, ADSC)
|
||||
#ifdef MUX5
|
||||
#define HAL_START_ADC(pin) if (pin > 7) ADCSRB = _BV(MUX5); else ADCSRB = 0; SET_ADMUX_ADCSRA(pin)
|
||||
#else
|
||||
#define HAL_START_ADC(pin) ADCSRB = 0; SET_ADMUX_ADCSRA(pin)
|
||||
#endif
|
||||
|
||||
#define HAL_READ_ADC() ADC
|
||||
#define HAL_ADC_READY() !TEST(ADCSRA, ADSC)
|
||||
|
||||
#define GET_PIN_MAP_PIN(index) index
|
||||
#define GET_PIN_MAP_INDEX(pin) pin
|
||||
#define PARSED_PIN_INDEX(code, dval) parser.intval(code, dval)
|
||||
|
||||
#define HAL_SENSITIVE_PINS 0, 1
|
||||
|
||||
#endif // _HAL_AVR_H_
|
|
@ -1,77 +0,0 @@
|
|||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* AVR busy wait delay Cycles routines:
|
||||
*
|
||||
* DELAY_CYCLES(count): Delay execution in cycles
|
||||
* DELAY_NS(count): Delay execution in nanoseconds
|
||||
* DELAY_US(count): Delay execution in microseconds
|
||||
*/
|
||||
|
||||
#ifndef MARLIN_DELAY_H
|
||||
#define MARLIN_DELAY_H
|
||||
|
||||
#define nop() __asm__ __volatile__("nop;\n\t":::)
|
||||
|
||||
FORCE_INLINE static void __delay_4cycles(uint8_t cy) {
|
||||
__asm__ __volatile__(
|
||||
L("1")
|
||||
A("dec %[cnt]")
|
||||
A("nop")
|
||||
A("brne 1b")
|
||||
: [cnt] "+r"(cy) // output: +r means input+output
|
||||
: // input:
|
||||
: "cc" // clobbers:
|
||||
);
|
||||
}
|
||||
|
||||
/* ---------------- Delay in cycles */
|
||||
FORCE_INLINE static void DELAY_CYCLES(uint16_t x) {
|
||||
|
||||
if (__builtin_constant_p(x)) {
|
||||
#define MAXNOPS 4
|
||||
|
||||
if (x <= (MAXNOPS)) {
|
||||
switch (x) { case 4: nop(); case 3: nop(); case 2: nop(); case 1: nop(); }
|
||||
}
|
||||
else {
|
||||
const uint32_t rem = (x) % (MAXNOPS);
|
||||
switch (rem) { case 3: nop(); case 2: nop(); case 1: nop(); }
|
||||
if ((x = (x) / (MAXNOPS)))
|
||||
__delay_4cycles(x); // if need more then 4 nop loop is more optimal
|
||||
}
|
||||
|
||||
#undef MAXNOPS
|
||||
}
|
||||
else
|
||||
__delay_4cycles(x / 4);
|
||||
}
|
||||
#undef nop
|
||||
|
||||
/* ---------------- Delay in nanoseconds */
|
||||
#define DELAY_NS(x) DELAY_CYCLES( (x) * (F_CPU/1000000L) / 1000L )
|
||||
|
||||
/* ---------------- Delay in microseconds */
|
||||
#define DELAY_US(x) DELAY_CYCLES( (x) * (F_CPU/1000000L) )
|
||||
|
||||
#endif // MARLIN_DELAY_H
|
|
@ -1,73 +0,0 @@
|
|||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
#ifndef _DRIVERS_H_
|
||||
#define _DRIVERS_H_
|
||||
|
||||
#include "MarlinConfig.h"
|
||||
|
||||
#define A4988 0x001
|
||||
#define DRV8825 0x002
|
||||
#define LV8729 0x003
|
||||
#define L6470 0x104
|
||||
#define TB6560 0x005
|
||||
#define TB6600 0x006
|
||||
#define TMC2100 0x007
|
||||
#define TMC2130 0x108
|
||||
#define TMC2130_STANDALONE 0x008
|
||||
#define TMC2208 0x109
|
||||
#define TMC2208_STANDALONE 0x009
|
||||
#define TMC26X 0x10A
|
||||
#define TMC26X_STANDALONE 0x00A
|
||||
#define TMC2660 0x10B
|
||||
#define TMC2660_STANDALONE 0x00B
|
||||
|
||||
#define _AXIS_DRIVER_TYPE(A,T) ( defined(A##_DRIVER_TYPE) && (A##_DRIVER_TYPE == T) )
|
||||
|
||||
#define AXIS_DRIVER_TYPE_X(T) _AXIS_DRIVER_TYPE(X,T)
|
||||
#define AXIS_DRIVER_TYPE_Y(T) _AXIS_DRIVER_TYPE(Y,T)
|
||||
#define AXIS_DRIVER_TYPE_Z(T) _AXIS_DRIVER_TYPE(Z,T)
|
||||
#define AXIS_DRIVER_TYPE_X2(T) (ENABLED(X_DUAL_STEPPER_DRIVERS) || ENABLED(DUAL_X_CARRIAGE)) && _AXIS_DRIVER_TYPE(X2,T)
|
||||
#define AXIS_DRIVER_TYPE_Y2(T) (ENABLED(Y_DUAL_STEPPER_DRIVERS) && _AXIS_DRIVER_TYPE(Y2,T))
|
||||
#define AXIS_DRIVER_TYPE_Z2(T) (ENABLED(Z_DUAL_STEPPER_DRIVERS) && _AXIS_DRIVER_TYPE(Z2,T))
|
||||
#define AXIS_DRIVER_TYPE_E0(T) (E_STEPPERS > 0 && _AXIS_DRIVER_TYPE(E0,T))
|
||||
#define AXIS_DRIVER_TYPE_E1(T) (E_STEPPERS > 1 && _AXIS_DRIVER_TYPE(E1,T))
|
||||
#define AXIS_DRIVER_TYPE_E2(T) (E_STEPPERS > 2 && _AXIS_DRIVER_TYPE(E2,T))
|
||||
#define AXIS_DRIVER_TYPE_E3(T) (E_STEPPERS > 3 && _AXIS_DRIVER_TYPE(E3,T))
|
||||
#define AXIS_DRIVER_TYPE_E4(T) (E_STEPPERS > 4 && _AXIS_DRIVER_TYPE(E4,T))
|
||||
|
||||
#define AXIS_DRIVER_TYPE(A,T) AXIS_DRIVER_TYPE_##A(T)
|
||||
|
||||
#define HAS_DRIVER(T) (AXIS_DRIVER_TYPE_X(T) || AXIS_DRIVER_TYPE_X2(T) || \
|
||||
AXIS_DRIVER_TYPE_Y(T) || AXIS_DRIVER_TYPE_Y2(T) || \
|
||||
AXIS_DRIVER_TYPE_Z(T) || AXIS_DRIVER_TYPE_Z2(T) || \
|
||||
AXIS_DRIVER_TYPE_E0(T) || AXIS_DRIVER_TYPE_E1(T) || \
|
||||
AXIS_DRIVER_TYPE_E2(T) || AXIS_DRIVER_TYPE_E3(T) || \
|
||||
AXIS_DRIVER_TYPE_E4(T) )
|
||||
|
||||
// Test for supported TMC drivers that require advanced configuration
|
||||
// Does not match standalone configurations
|
||||
#define HAS_TRINAMIC (HAS_DRIVER(TMC2130) || HAS_DRIVER(TMC2208))
|
||||
|
||||
#define AXIS_IS_TMC(A) ( AXIS_DRIVER_TYPE_##A(TMC2130) || \
|
||||
AXIS_DRIVER_TYPE_##A(TMC2208) )
|
||||
|
||||
#endif // _DRIVERS_H_
|
|
@ -1,40 +0,0 @@
|
|||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* emergency_parser.cpp - Intercept special commands directly in the serial stream
|
||||
*/
|
||||
|
||||
#include "MarlinConfig.h"
|
||||
|
||||
#if ENABLED(EMERGENCY_PARSER)
|
||||
|
||||
#include "emergency_parser.h"
|
||||
|
||||
// Static data members
|
||||
bool EmergencyParser::killed_by_M112; // = false
|
||||
EmergencyParser::State EmergencyParser::state; // = EP_RESET
|
||||
|
||||
// Global instance
|
||||
EmergencyParser emergency_parser;
|
||||
|
||||
#endif // EMERGENCY_PARSER
|
|
@ -1,144 +0,0 @@
|
|||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* emergency_parser.h - Intercept special commands directly in the serial stream
|
||||
*/
|
||||
|
||||
#ifndef _EMERGENCY_PARSER_H_
|
||||
#define _EMERGENCY_PARSER_H_
|
||||
|
||||
// External references
|
||||
extern volatile bool wait_for_user, wait_for_heatup;
|
||||
void quickstop_stepper();
|
||||
|
||||
class EmergencyParser {
|
||||
|
||||
public:
|
||||
|
||||
// Currently looking for: M108, M112, M410
|
||||
enum State : char {
|
||||
EP_RESET,
|
||||
EP_N,
|
||||
EP_M,
|
||||
EP_M1,
|
||||
EP_M10,
|
||||
EP_M108,
|
||||
EP_M11,
|
||||
EP_M112,
|
||||
EP_M4,
|
||||
EP_M41,
|
||||
EP_M410,
|
||||
EP_IGNORE // to '\n'
|
||||
};
|
||||
|
||||
static bool killed_by_M112;
|
||||
static State state;
|
||||
|
||||
EmergencyParser() {}
|
||||
|
||||
__attribute__((always_inline)) inline
|
||||
static void update(const uint8_t c) {
|
||||
|
||||
switch (state) {
|
||||
case EP_RESET:
|
||||
switch (c) {
|
||||
case ' ': break;
|
||||
case 'N': state = EP_N; break;
|
||||
case 'M': state = EP_M; break;
|
||||
default: state = EP_IGNORE;
|
||||
}
|
||||
break;
|
||||
|
||||
case EP_N:
|
||||
switch (c) {
|
||||
case '0': case '1': case '2':
|
||||
case '3': case '4': case '5':
|
||||
case '6': case '7': case '8':
|
||||
case '9': case '-': case ' ': break;
|
||||
case 'M': state = EP_M; break;
|
||||
default: state = EP_IGNORE;
|
||||
}
|
||||
break;
|
||||
|
||||
case EP_M:
|
||||
switch (c) {
|
||||
case ' ': break;
|
||||
case '1': state = EP_M1; break;
|
||||
case '4': state = EP_M4; break;
|
||||
default: state = EP_IGNORE;
|
||||
}
|
||||
break;
|
||||
|
||||
case EP_M1:
|
||||
switch (c) {
|
||||
case '0': state = EP_M10; break;
|
||||
case '1': state = EP_M11; break;
|
||||
default: state = EP_IGNORE;
|
||||
}
|
||||
break;
|
||||
|
||||
case EP_M10:
|
||||
state = (c == '8') ? EP_M108 : EP_IGNORE;
|
||||
break;
|
||||
|
||||
case EP_M11:
|
||||
state = (c == '2') ? EP_M112 : EP_IGNORE;
|
||||
break;
|
||||
|
||||
case EP_M4:
|
||||
state = (c == '1') ? EP_M41 : EP_IGNORE;
|
||||
break;
|
||||
|
||||
case EP_M41:
|
||||
state = (c == '0') ? EP_M410 : EP_IGNORE;
|
||||
break;
|
||||
|
||||
case EP_IGNORE:
|
||||
if (c == '\n') state = EP_RESET;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (c == '\n') {
|
||||
switch (state) {
|
||||
case EP_M108:
|
||||
wait_for_user = wait_for_heatup = false;
|
||||
break;
|
||||
case EP_M112:
|
||||
killed_by_M112 = true;
|
||||
break;
|
||||
case EP_M410:
|
||||
quickstop_stepper();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
state = EP_RESET;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
extern EmergencyParser emergency_parser;
|
||||
|
||||
#endif // _EMERGENCY_PARSER_H_
|
|
@ -1,199 +0,0 @@
|
|||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* fwretract.cpp - Implement firmware-based retraction
|
||||
*/
|
||||
|
||||
#include "MarlinConfig.h"
|
||||
|
||||
#if ENABLED(FWRETRACT)
|
||||
|
||||
#include "fwretract.h"
|
||||
#include "Marlin.h"
|
||||
#include "planner.h"
|
||||
#include "stepper.h"
|
||||
|
||||
FWRetract fwretract; // Single instance - this calls the constructor
|
||||
|
||||
// private:
|
||||
|
||||
#if EXTRUDERS > 1
|
||||
bool FWRetract::retracted_swap[EXTRUDERS]; // Which extruders are swap-retracted
|
||||
#endif
|
||||
|
||||
// public:
|
||||
|
||||
bool FWRetract::autoretract_enabled, // M209 S - Autoretract switch
|
||||
FWRetract::retracted[EXTRUDERS]; // Which extruders are currently retracted
|
||||
float FWRetract::retract_length, // M207 S - G10 Retract length
|
||||
FWRetract::retract_feedrate_mm_s, // M207 F - G10 Retract feedrate
|
||||
FWRetract::retract_zlift, // M207 Z - G10 Retract hop size
|
||||
FWRetract::retract_recover_length, // M208 S - G11 Recover length
|
||||
FWRetract::retract_recover_feedrate_mm_s, // M208 F - G11 Recover feedrate
|
||||
FWRetract::swap_retract_length, // M207 W - G10 Swap Retract length
|
||||
FWRetract::swap_retract_recover_length, // M208 W - G11 Swap Recover length
|
||||
FWRetract::swap_retract_recover_feedrate_mm_s, // M208 R - G11 Swap Recover feedrate
|
||||
FWRetract::hop_amount;
|
||||
|
||||
void FWRetract::reset() {
|
||||
autoretract_enabled = false;
|
||||
retract_length = RETRACT_LENGTH;
|
||||
retract_feedrate_mm_s = RETRACT_FEEDRATE;
|
||||
retract_zlift = RETRACT_ZLIFT;
|
||||
retract_recover_length = RETRACT_RECOVER_LENGTH;
|
||||
retract_recover_feedrate_mm_s = RETRACT_RECOVER_FEEDRATE;
|
||||
swap_retract_length = RETRACT_LENGTH_SWAP;
|
||||
swap_retract_recover_length = RETRACT_RECOVER_LENGTH_SWAP;
|
||||
swap_retract_recover_feedrate_mm_s = RETRACT_RECOVER_FEEDRATE_SWAP;
|
||||
hop_amount = 0.0;
|
||||
|
||||
for (uint8_t i = 0; i < EXTRUDERS; ++i) {
|
||||
retracted[i] = false;
|
||||
#if EXTRUDERS > 1
|
||||
retracted_swap[i] = false;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retract or recover according to firmware settings
|
||||
*
|
||||
* This function handles retract/recover moves for G10 and G11,
|
||||
* plus auto-retract moves sent from G0/G1 when E-only moves are done.
|
||||
*
|
||||
* To simplify the logic, doubled retract/recover moves are ignored.
|
||||
*
|
||||
* Note: Z lift is done transparently to the planner. Aborting
|
||||
* a print between G10 and G11 may corrupt the Z position.
|
||||
*
|
||||
* Note: Auto-retract will apply the set Z hop in addition to any Z hop
|
||||
* included in the G-code. Use M207 Z0 to to prevent double hop.
|
||||
*/
|
||||
void FWRetract::retract(const bool retracting
|
||||
#if EXTRUDERS > 1
|
||||
, bool swapping /* =false */
|
||||
#endif
|
||||
) {
|
||||
|
||||
static float hop_amount = 0.0; // Total amount lifted, for use in recover
|
||||
|
||||
// Prevent two retracts or recovers in a row
|
||||
if (retracted[active_extruder] == retracting) return;
|
||||
|
||||
// Prevent two swap-retract or recovers in a row
|
||||
#if EXTRUDERS > 1
|
||||
// Allow G10 S1 only after G10
|
||||
if (swapping && retracted_swap[active_extruder] == retracting) return;
|
||||
// G11 priority to recover the long retract if activated
|
||||
if (!retracting) swapping = retracted_swap[active_extruder];
|
||||
#else
|
||||
constexpr bool swapping = false;
|
||||
#endif
|
||||
|
||||
/* // debugging
|
||||
SERIAL_ECHOLNPAIR("retracting ", retracting);
|
||||
SERIAL_ECHOLNPAIR("swapping ", swapping);
|
||||
SERIAL_ECHOLNPAIR("active extruder ", active_extruder);
|
||||
for (uint8_t i = 0; i < EXTRUDERS; ++i) {
|
||||
SERIAL_ECHOPAIR("retracted[", i);
|
||||
SERIAL_ECHOLNPAIR("] ", retracted[i]);
|
||||
#if EXTRUDERS > 1
|
||||
SERIAL_ECHOPAIR("retracted_swap[", i);
|
||||
SERIAL_ECHOLNPAIR("] ", retracted_swap[i]);
|
||||
#endif
|
||||
}
|
||||
SERIAL_ECHOLNPAIR("current_position[z] ", current_position[Z_AXIS]);
|
||||
SERIAL_ECHOLNPAIR("current_position[e] ", current_position[E_CART]);
|
||||
SERIAL_ECHOLNPAIR("hop_amount ", hop_amount);
|
||||
//*/
|
||||
|
||||
const float old_feedrate_mm_s = feedrate_mm_s,
|
||||
renormalize = RECIPROCAL(planner.e_factor[active_extruder]),
|
||||
base_retract = swapping ? swap_retract_length : retract_length,
|
||||
old_z = current_position[Z_AXIS],
|
||||
old_e = current_position[E_CART];
|
||||
|
||||
// The current position will be the destination for E and Z moves
|
||||
set_destination_from_current();
|
||||
|
||||
if (retracting) {
|
||||
// Retract by moving from a faux E position back to the current E position
|
||||
feedrate_mm_s = retract_feedrate_mm_s;
|
||||
destination[E_CART] -= base_retract * renormalize;
|
||||
prepare_move_to_destination(); // set_current_to_destination
|
||||
|
||||
// Is a Z hop set, and has the hop not yet been done?
|
||||
if (retract_zlift > 0.01 && !hop_amount) { // Apply hop only once
|
||||
hop_amount += retract_zlift; // Add to the hop total (again, only once)
|
||||
destination[Z_AXIS] += retract_zlift; // Raise Z by the zlift (M207 Z) amount
|
||||
feedrate_mm_s = planner.max_feedrate_mm_s[Z_AXIS]; // Maximum Z feedrate
|
||||
prepare_move_to_destination(); // Raise up, set_current_to_destination
|
||||
}
|
||||
}
|
||||
else {
|
||||
// If a hop was done and Z hasn't changed, undo the Z hop
|
||||
if (hop_amount) {
|
||||
current_position[Z_AXIS] += hop_amount; // Restore the actual Z position
|
||||
SYNC_PLAN_POSITION_KINEMATIC(); // Unspoof the position planner
|
||||
feedrate_mm_s = planner.max_feedrate_mm_s[Z_AXIS]; // Z feedrate to max
|
||||
prepare_move_to_destination(); // Lower Z, set_current_to_destination
|
||||
hop_amount = 0.0; // Clear the hop amount
|
||||
}
|
||||
|
||||
destination[E_CART] += (base_retract + (swapping ? swap_retract_recover_length : retract_recover_length)) * renormalize;
|
||||
feedrate_mm_s = swapping ? swap_retract_recover_feedrate_mm_s : retract_recover_feedrate_mm_s;
|
||||
prepare_move_to_destination(); // Recover E, set_current_to_destination
|
||||
}
|
||||
|
||||
feedrate_mm_s = old_feedrate_mm_s; // Restore original feedrate
|
||||
current_position[Z_AXIS] = old_z; // Restore Z and E positions
|
||||
current_position[E_CART] = old_e;
|
||||
SYNC_PLAN_POSITION_KINEMATIC(); // As if the move never took place
|
||||
|
||||
retracted[active_extruder] = retracting; // Active extruder now retracted / recovered
|
||||
|
||||
// If swap retract/recover update the retracted_swap flag too
|
||||
#if EXTRUDERS > 1
|
||||
if (swapping) retracted_swap[active_extruder] = retracting;
|
||||
#endif
|
||||
|
||||
/* // debugging
|
||||
SERIAL_ECHOLNPAIR("retracting ", retracting);
|
||||
SERIAL_ECHOLNPAIR("swapping ", swapping);
|
||||
SERIAL_ECHOLNPAIR("active_extruder ", active_extruder);
|
||||
for (uint8_t i = 0; i < EXTRUDERS; ++i) {
|
||||
SERIAL_ECHOPAIR("retracted[", i);
|
||||
SERIAL_ECHOLNPAIR("] ", retracted[i]);
|
||||
#if EXTRUDERS > 1
|
||||
SERIAL_ECHOPAIR("retracted_swap[", i);
|
||||
SERIAL_ECHOLNPAIR("] ", retracted_swap[i]);
|
||||
#endif
|
||||
}
|
||||
SERIAL_ECHOLNPAIR("current_position[z] ", current_position[Z_AXIS]);
|
||||
SERIAL_ECHOLNPAIR("current_position[e] ", current_position[E_CART]);
|
||||
SERIAL_ECHOLNPAIR("hop_amount ", hop_amount);
|
||||
//*/
|
||||
|
||||
}
|
||||
|
||||
#endif // FWRETRACT
|
|
@ -1,71 +0,0 @@
|
|||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* fwretract.h - Define firmware-based retraction interface
|
||||
*/
|
||||
|
||||
#ifndef FWRETRACT_H
|
||||
#define FWRETRACT_H
|
||||
|
||||
#include "MarlinConfig.h"
|
||||
|
||||
class FWRetract {
|
||||
public:
|
||||
static bool autoretract_enabled, // M209 S - Autoretract switch
|
||||
retracted[EXTRUDERS]; // Which extruders are currently retracted
|
||||
#if EXTRUDERS > 1
|
||||
static bool retracted_swap[EXTRUDERS]; // Which extruders are swap-retracted
|
||||
#endif
|
||||
static float retract_length, // M207 S - G10 Retract length
|
||||
retract_feedrate_mm_s, // M207 F - G10 Retract feedrate
|
||||
retract_zlift, // M207 Z - G10 Retract hop size
|
||||
retract_recover_length, // M208 S - G11 Recover length
|
||||
retract_recover_feedrate_mm_s, // M208 F - G11 Recover feedrate
|
||||
swap_retract_length, // M207 W - G10 Swap Retract length
|
||||
swap_retract_recover_length, // M208 W - G11 Swap Recover length
|
||||
swap_retract_recover_feedrate_mm_s, // M208 R - G11 Swap Recover feedrate
|
||||
hop_amount;
|
||||
|
||||
FWRetract() { reset(); }
|
||||
|
||||
static void reset();
|
||||
|
||||
static void refresh_autoretract() {
|
||||
for (uint8_t i = 0; i < EXTRUDERS; i++) retracted[i] = false;
|
||||
}
|
||||
|
||||
static void enable_autoretract(const bool enable) {
|
||||
autoretract_enabled = enable;
|
||||
refresh_autoretract();
|
||||
}
|
||||
|
||||
static void retract(const bool retracting
|
||||
#if EXTRUDERS > 1
|
||||
, bool swapping = false
|
||||
#endif
|
||||
);
|
||||
};
|
||||
|
||||
extern FWRetract fwretract;
|
||||
|
||||
#endif // FWRETRACT_H
|
|
@ -1,275 +0,0 @@
|
|||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Spanish
|
||||
*
|
||||
* LCD Menu Messages
|
||||
* See also http://marlinfw.org/docs/development/lcd_language.html
|
||||
*
|
||||
*/
|
||||
#ifndef LANGUAGE_ES_UTF_H
|
||||
#define LANGUAGE_ES_UTF_H
|
||||
|
||||
#define MAPPER_C2C3
|
||||
#define DISPLAY_CHARSET_ISO10646_1
|
||||
#define CHARSIZE 2
|
||||
|
||||
#define WELCOME_MSG MACHINE_NAME _UxGT(" lista.")
|
||||
#define MSG_BACK _UxGT("Atrás")
|
||||
#define MSG_SD_INSERTED _UxGT("Tarjeta colocada")
|
||||
#define MSG_SD_REMOVED _UxGT("Tarjeta retirada")
|
||||
#define MSG_LCD_ENDSTOPS _UxGT("Endstops") // Max length 8 characters
|
||||
#define MSG_MAIN _UxGT("Menú principal")
|
||||
#define MSG_AUTOSTART _UxGT("Inicio automático")
|
||||
#define MSG_DISABLE_STEPPERS _UxGT("Apagar motores")
|
||||
#define MSG_DEBUG_MENU _UxGT("Menú depurar")
|
||||
#define MSG_PROGRESS_BAR_TEST _UxGT("Prueba barra avance")
|
||||
#define MSG_AUTO_HOME _UxGT("Llevar al origen")
|
||||
#define MSG_AUTO_HOME_X _UxGT("Origen X")
|
||||
#define MSG_AUTO_HOME_Y _UxGT("Origen Y")
|
||||
#define MSG_AUTO_HOME_Z _UxGT("Origen Z")
|
||||
#define MSG_TMC_Z_CALIBRATION _UxGT("Calibrar Z")
|
||||
#define MSG_LEVEL_BED_HOMING _UxGT("Origen XYZ")
|
||||
#define MSG_LEVEL_BED_WAITING _UxGT("Iniciar (Presione)")
|
||||
#define MSG_LEVEL_BED_NEXT_POINT _UxGT("Siguiente punto")
|
||||
#define MSG_LEVEL_BED_DONE _UxGT("Nivelación lista!")
|
||||
#define MSG_SET_HOME_OFFSETS _UxGT("Ajustar desfases")
|
||||
#define MSG_HOME_OFFSETS_APPLIED _UxGT("Desfase aplicado")
|
||||
#define MSG_SET_ORIGIN _UxGT("Establecer origen")
|
||||
#define MSG_PREHEAT_1 _UxGT("Precalentar PLA")
|
||||
#define MSG_PREHEAT_1_N MSG_PREHEAT_1 _UxGT(" ")
|
||||
#define MSG_PREHEAT_1_ALL MSG_PREHEAT_1 _UxGT(" Todo")
|
||||
#define MSG_PREHEAT_1_END MSG_PREHEAT_1 _UxGT(" End")
|
||||
#define MSG_PREHEAT_1_BEDONLY MSG_PREHEAT_1 _UxGT(" Cama")
|
||||
#define MSG_PREHEAT_1_SETTINGS MSG_PREHEAT_1 _UxGT(" Config")
|
||||
#define MSG_PREHEAT_2 _UxGT("Precalentar ABS")
|
||||
#define MSG_PREHEAT_2_N MSG_PREHEAT_2 _UxGT(" ")
|
||||
#define MSG_PREHEAT_2_ALL MSG_PREHEAT_2 _UxGT(" Todo")
|
||||
#define MSG_PREHEAT_2_END MSG_PREHEAT_2 _UxGT(" End")
|
||||
#define MSG_PREHEAT_2_BEDONLY MSG_PREHEAT_2 _UxGT(" Cama")
|
||||
#define MSG_PREHEAT_2_SETTINGS MSG_PREHEAT_2 _UxGT(" Config")
|
||||
#define MSG_COOLDOWN _UxGT("Enfriar")
|
||||
#define MSG_SWITCH_PS_ON _UxGT("Encender")
|
||||
#define MSG_SWITCH_PS_OFF _UxGT("Apagar")
|
||||
#define MSG_EXTRUDE _UxGT("Extruir")
|
||||
#define MSG_RETRACT _UxGT("Retraer")
|
||||
#define MSG_MOVE_AXIS _UxGT("Mover ejes")
|
||||
#define MSG_BED_LEVELING _UxGT("Nivelar cama")
|
||||
#define MSG_LEVEL_BED _UxGT("Nivelar cama")
|
||||
#define MSG_MOVING _UxGT("Moviendo...")
|
||||
#define MSG_FREE_XY _UxGT("Libre XY")
|
||||
#define MSG_MOVE_X _UxGT("Mover X")
|
||||
#define MSG_MOVE_Y _UxGT("Mover Y")
|
||||
#define MSG_MOVE_Z _UxGT("Mover Z")
|
||||
#define MSG_MOVE_E _UxGT("Extrusor")
|
||||
#define MSG_MOVE_01MM _UxGT("Mover 0.1mm")
|
||||
#define MSG_MOVE_1MM _UxGT("Mover 1mm")
|
||||
#define MSG_MOVE_10MM _UxGT("Mover 10mm")
|
||||
#define MSG_SPEED _UxGT("Velocidad")
|
||||
#define MSG_BED_Z _UxGT("Cama Z")
|
||||
#define MSG_NOZZLE _UxGT("Boquilla")
|
||||
#define MSG_BED _UxGT("Cama")
|
||||
#define MSG_FAN_SPEED _UxGT("Ventilador")
|
||||
#define MSG_FLOW _UxGT("Flujo")
|
||||
#define MSG_CONTROL _UxGT("Control")
|
||||
#define MSG_MIN _UxGT(" ") LCD_STR_THERMOMETER _UxGT(" Min")
|
||||
#define MSG_MAX _UxGT(" ") LCD_STR_THERMOMETER _UxGT(" Max")
|
||||
#define MSG_FACTOR _UxGT(" ") LCD_STR_THERMOMETER _UxGT(" Fact")
|
||||
#define MSG_AUTOTEMP _UxGT("Temperatura Auto.")
|
||||
#define MSG_ON _UxGT("Encender")
|
||||
#define MSG_OFF _UxGT("Apagar")
|
||||
#define MSG_PID_P _UxGT("PID-P")
|
||||
#define MSG_PID_I _UxGT("PID-I")
|
||||
#define MSG_PID_D _UxGT("PID-D")
|
||||
#define MSG_PID_C _UxGT("PID-C")
|
||||
#define MSG_SELECT _UxGT("Seleccionar")
|
||||
#define MSG_ACC _UxGT("Aceleración")
|
||||
#define MSG_JERK _UxGT("Jerk")
|
||||
#define MSG_VX_JERK _UxGT("Vx-jerk")
|
||||
#define MSG_VY_JERK _UxGT("Vy-jerk")
|
||||
#define MSG_VZ_JERK _UxGT("Vz-jerk")
|
||||
#define MSG_VE_JERK _UxGT("Ve-jerk")
|
||||
#define MSG_VMAX _UxGT("Vmax")
|
||||
#define MSG_VMIN _UxGT("Vmin")
|
||||
#define MSG_VTRAV_MIN _UxGT("Vel. viaje min")
|
||||
#define MSG_ACCELERATION MSG_ACC
|
||||
#define MSG_AMAX _UxGT("Acel. max")
|
||||
#define MSG_A_RETRACT _UxGT("Acel. retrac.")
|
||||
#define MSG_A_TRAVEL _UxGT("Acel. Viaje")
|
||||
#define MSG_STEPS_PER_MM _UxGT("Pasos/mm")
|
||||
#if IS_SCARA
|
||||
#define MSG_ASTEPS _UxGT("A pasos/mm")
|
||||
#define MSG_BSTEPS _UxGT("B pasos/mm")
|
||||
#define MSG_CSTEPS _UxGT("Z pasos/mm")
|
||||
#elif IS_DELTA
|
||||
#define MSG_ASTEPS _UxGT("A pasos/mm")
|
||||
#define MSG_BSTEPS _UxGT("B pasos/mm")
|
||||
#define MSG_CSTEPS _UxGT("C pasos/mm")
|
||||
#else
|
||||
#define MSG_ASTEPS _UxGT("X pasos/mm")
|
||||
#define MSG_BSTEPS _UxGT("Y pasos/mm")
|
||||
#define MSG_CSTEPS _UxGT("Z pasos/mm")
|
||||
#endif
|
||||
#define MSG_ESTEPS _UxGT("E pasos/mm")
|
||||
#define MSG_E1STEPS _UxGT("E1 pasos/mm")
|
||||
#define MSG_E2STEPS _UxGT("E2 pasos/mm")
|
||||
#define MSG_E3STEPS _UxGT("E3 pasos/mm")
|
||||
#define MSG_E4STEPS _UxGT("E4 pasos/mm")
|
||||
#define MSG_E5STEPS _UxGT("E5 pasos/mm")
|
||||
#define MSG_TEMPERATURE _UxGT("Temperatura")
|
||||
#define MSG_MOTION _UxGT("Movimiento")
|
||||
#define MSG_FILAMENT _UxGT("Filamento")
|
||||
#define MSG_VOLUMETRIC_ENABLED _UxGT("E in mm3")
|
||||
#define MSG_FILAMENT_DIAM _UxGT("Fil. Dia.")
|
||||
#define MSG_ADVANCE_K _UxGT("Avance K")
|
||||
#define MSG_CONTRAST _UxGT("Contraste")
|
||||
#define MSG_STORE_EEPROM _UxGT("Guardar memoria")
|
||||
#define MSG_LOAD_EEPROM _UxGT("Cargar memoria")
|
||||
#define MSG_RESTORE_FAILSAFE _UxGT("Restaurar memoria")
|
||||
#define MSG_REFRESH _UxGT("Volver a cargar")
|
||||
#define MSG_WATCH _UxGT("Información")
|
||||
#define MSG_PREPARE _UxGT("Preparar")
|
||||
#define MSG_TUNE _UxGT("Ajustar")
|
||||
#define MSG_PAUSE_PRINT _UxGT("Pausar impresión")
|
||||
#define MSG_RESUME_PRINT _UxGT("Reanudar impresión")
|
||||
#define MSG_STOP_PRINT _UxGT("Detener impresión")
|
||||
#define MSG_CARD_MENU _UxGT("Menú de SD")
|
||||
#define MSG_NO_CARD _UxGT("No hay tarjeta SD")
|
||||
#define MSG_DWELL _UxGT("Reposo...")
|
||||
#define MSG_USERWAIT _UxGT("Esperando órdenes")
|
||||
#define MSG_PRINT_ABORTED _UxGT("Impresión cancelada")
|
||||
#define MSG_NO_MOVE _UxGT("Sin movimiento")
|
||||
#define MSG_KILLED _UxGT("Parada de emergencia")
|
||||
#define MSG_STOPPED _UxGT("Detenida")
|
||||
#define MSG_CONTROL_RETRACT _UxGT("Retraer mm")
|
||||
#define MSG_CONTROL_RETRACT_SWAP _UxGT("Interc. Retraer mm")
|
||||
#define MSG_CONTROL_RETRACTF _UxGT("Retraer V")
|
||||
#define MSG_CONTROL_RETRACT_ZLIFT _UxGT("Levantar mm")
|
||||
#define MSG_CONTROL_RETRACT_RECOVER _UxGT("DesRet mm")
|
||||
#define MSG_CONTROL_RETRACT_RECOVER_SWAP _UxGT("Interc. DesRet mm")
|
||||
#define MSG_CONTROL_RETRACT_RECOVERF _UxGT("DesRet V")
|
||||
#define MSG_AUTORETRACT _UxGT("Retracción Auto.")
|
||||
#define MSG_FILAMENTCHANGE _UxGT("Cambiar filamento")
|
||||
#define MSG_INIT_SDCARD _UxGT("Iniciando tarjeta")
|
||||
#define MSG_CNG_SDCARD _UxGT("Cambiar tarjeta")
|
||||
#define MSG_ZPROBE_OUT _UxGT("Sonda Z fuera")
|
||||
#define MSG_BLTOUCH_SELFTEST _UxGT("BLTouch Auto-Prueba")
|
||||
#define MSG_BLTOUCH_RESET _UxGT("Reiniciar BLTouch")
|
||||
#define MSG_HOME _UxGT("Home") // Used as MSG_HOME " " MSG_X MSG_Y MSG_Z " " MSG_FIRST
|
||||
#define MSG_FIRST _UxGT("primero")
|
||||
#define MSG_ZPROBE_ZOFFSET _UxGT("Desfase Z")
|
||||
#define MSG_BABYSTEP_X _UxGT("Micropaso X")
|
||||
#define MSG_BABYSTEP_Y _UxGT("Micropaso Y")
|
||||
#define MSG_BABYSTEP_Z _UxGT("Micropaso Z")
|
||||
#define MSG_ENDSTOP_ABORT _UxGT("Cancelado - Endstop")
|
||||
#define MSG_HEATING_FAILED_LCD _UxGT("Error: al calentar")
|
||||
#define MSG_ERR_REDUNDANT_TEMP _UxGT("Error: temperatura")
|
||||
#define MSG_THERMAL_RUNAWAY _UxGT("Error: temperatura")
|
||||
#define MSG_ERR_MAXTEMP _UxGT("Error: Temp Máxima")
|
||||
#define MSG_ERR_MINTEMP _UxGT("Error: Temp Mínima")
|
||||
#define MSG_ERR_MAXTEMP_BED _UxGT("Error: Temp Max Cama")
|
||||
#define MSG_ERR_MINTEMP_BED _UxGT("Error: Temp Min Cama")
|
||||
#define MSG_ERR_Z_HOMING MSG_HOME _UxGT(" ") MSG_X MSG_Y _UxGT(" ") MSG_FIRST
|
||||
#define MSG_HALTED _UxGT("IMPRESORA PARADA")
|
||||
#define MSG_PLEASE_RESET _UxGT("Por favor, reinicie")
|
||||
#define MSG_SHORT_DAY _UxGT("d") // One character only
|
||||
#define MSG_SHORT_HOUR _UxGT("h") // One character only
|
||||
#define MSG_SHORT_MINUTE _UxGT("m") // One character only
|
||||
#define MSG_HEATING _UxGT("Calentando...")
|
||||
#define MSG_BED_HEATING _UxGT("Calentando Cama...")
|
||||
#define MSG_DELTA_CALIBRATE _UxGT("Calibración Delta")
|
||||
#define MSG_DELTA_CALIBRATE_X _UxGT("Calibrar X")
|
||||
#define MSG_DELTA_CALIBRATE_Y _UxGT("Calibrar Y")
|
||||
#define MSG_DELTA_CALIBRATE_Z _UxGT("Calibrar Z")
|
||||
#define MSG_DELTA_CALIBRATE_CENTER _UxGT("Calibrar Centro")
|
||||
#define MSG_DELTA_AUTO_CALIBRATE _UxGT("Auto Calibración")
|
||||
#define MSG_DELTA_HEIGHT_CALIBRATE _UxGT("Est. Altura Delta")
|
||||
#define MSG_INFO_MENU _UxGT("Inf. Impresora")
|
||||
#define MSG_INFO_PRINTER_MENU _UxGT("Inf. Impresora")
|
||||
#define MSG_INFO_STATS_MENU _UxGT("Estadísticas Imp.")
|
||||
#define MSG_INFO_BOARD_MENU _UxGT("Inf. Controlador")
|
||||
#define MSG_INFO_THERMISTOR_MENU _UxGT("Termistores")
|
||||
#define MSG_INFO_EXTRUDERS _UxGT("Extrusores")
|
||||
#define MSG_INFO_BAUDRATE _UxGT("Baudios")
|
||||
#define MSG_INFO_PROTOCOL _UxGT("Protocolo")
|
||||
#define MSG_CASE_LIGHT _UxGT("Luz cabina")
|
||||
|
||||
#if LCD_WIDTH > 19
|
||||
#define MSG_INFO_PRINT_COUNT _UxGT("Conteo de impresión")
|
||||
#define MSG_INFO_COMPLETED_PRINTS _UxGT("Completadas")
|
||||
#define MSG_INFO_PRINT_TIME _UxGT("Tiempo total de imp.")
|
||||
#define MSG_INFO_PRINT_LONGEST _UxGT("Impresión más larga")
|
||||
#define MSG_INFO_PRINT_FILAMENT _UxGT("Total de Extrusión")
|
||||
#else
|
||||
#define MSG_INFO_PRINT_COUNT _UxGT("Impresiones")
|
||||
#define MSG_INFO_COMPLETED_PRINTS _UxGT("Completadas")
|
||||
#define MSG_INFO_PRINT_TIME _UxGT("Total")
|
||||
#define MSG_INFO_PRINT_LONGEST _UxGT("Más larga")
|
||||
#define MSG_INFO_PRINT_FILAMENT _UxGT("Extrusión")
|
||||
#endif
|
||||
|
||||
#define MSG_INFO_MIN_TEMP _UxGT("Temperatura mínima")
|
||||
#define MSG_INFO_MAX_TEMP _UxGT("Temperatura máxima")
|
||||
#define MSG_INFO_PSU _UxGT("Fuente de poder")
|
||||
#define MSG_DRIVE_STRENGTH _UxGT("Potencia driver")
|
||||
#define MSG_DAC_PERCENT _UxGT("Driver %")
|
||||
#define MSG_DAC_EEPROM_WRITE _UxGT("Escribe DAC EEPROM")
|
||||
|
||||
#define MSG_FILAMENT_CHANGE_HEADER _UxGT("IMPR. PAUSADA")
|
||||
#define MSG_FILAMENT_CHANGE_OPTION_HEADER _UxGT("OPC. REINICIO:")
|
||||
#define MSG_FILAMENT_CHANGE_OPTION_EXTRUDE _UxGT("Extruir más")
|
||||
#define MSG_FILAMENT_CHANGE_OPTION_RESUME _UxGT("Resumir imp.")
|
||||
|
||||
#define MSG_FILAMENT_CHANGE_MINTEMP _UxGT("Temp Mínima es ")
|
||||
#define MSG_FILAMENT_CHANGE_NOZZLE _UxGT(" Boquilla: ")
|
||||
|
||||
#define MSG_FILAMENT_CHANGE_INIT_1 _UxGT("Esperando iniciar")
|
||||
|
||||
#define MSG_FILAMENT_CHANGE_INSERT_1 _UxGT("Inserte filamento")
|
||||
#define MSG_FILAMENT_CHANGE_INSERT_2 _UxGT("y presione el botón")
|
||||
|
||||
#if LCD_HEIGHT >= 4
|
||||
// Up to 3 lines allowed
|
||||
#define MSG_FILAMENT_CHANGE_INIT_2 _UxGT("del filamento")
|
||||
#define MSG_FILAMENT_CHANGE_INIT_3 _UxGT("cambiar")
|
||||
#define MSG_FILAMENT_CHANGE_INSERT_3 _UxGT("para continuar...")
|
||||
#else // LCD_HEIGHT < 4
|
||||
// Up to 2 lines allowed
|
||||
#define MSG_FILAMENT_CHANGE_INIT_2 _UxGT("del fil. cambiar")
|
||||
#define MSG_FILAMENT_CHANGE_INSERT_1 _UxGT("Inserte filamento")
|
||||
#endif // LCD_HEIGHT < 4
|
||||
|
||||
#define MSG_FILAMENT_CHANGE_UNLOAD_1 _UxGT("Esperado por")
|
||||
#define MSG_FILAMENT_CHANGE_UNLOAD_2 _UxGT("filamento expulsado")
|
||||
#define MSG_FILAMENT_CHANGE_LOAD_1 _UxGT("Esperado por")
|
||||
#define MSG_FILAMENT_CHANGE_LOAD_2 _UxGT("Cargar filamento")
|
||||
#define MSG_FILAMENT_CHANGE_EXTRUDE_1 _UxGT("Esperado por")
|
||||
#define MSG_FILAMENT_CHANGE_EXTRUDE_2 _UxGT("Extruir filamento")
|
||||
#define MSG_FILAMENT_CHANGE_RESUME_1 _UxGT("Esperando imp.")
|
||||
#define MSG_FILAMENT_CHANGE_RESUME_2 _UxGT("para resumir")
|
||||
#define MSG_FILAMENT_CHANGE_HEAT_1 _UxGT("Oprima botón para")
|
||||
#define MSG_FILAMENT_CHANGE_HEAT_2 _UxGT("Calentar la boquilla")
|
||||
#define MSG_FILAMENT_CHANGE_HEATING_1 _UxGT("Calentando boquilla")
|
||||
#define MSG_FILAMENT_CHANGE_HEATING_2 _UxGT("Espere por favor")
|
||||
|
||||
#endif // LANGUAGE_ES_UTF_H
|
|
@ -1,496 +0,0 @@
|
|||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* malyanlcd.cpp
|
||||
*
|
||||
* LCD implementation for Malyan's LCD, a separate ESP8266 MCU running
|
||||
* on Serial1 for the M200 board. This module outputs a pseudo-gcode
|
||||
* wrapped in curly braces which the LCD implementation translates into
|
||||
* actual G-code commands.
|
||||
*
|
||||
* Added to Marlin for Mini/Malyan M200
|
||||
* Unknown commands as of Jan 2018: {H:}
|
||||
* Not currently implemented:
|
||||
* {E:} when sent by LCD. Meaning unknown.
|
||||
*
|
||||
* Notes for connecting to boards that are not Malyan:
|
||||
* The LCD is 3.3v, so if powering from a RAMPS 1.4 board or
|
||||
* other 5v/12v board, use a buck converter to power the LCD and
|
||||
* the 3.3v side of a logic level shifter. Aux1 on the RAMPS board
|
||||
* has Serial1 and 12v, making it perfect for this.
|
||||
* Copyright (c) 2017 Jason Nelson (xC0000005)
|
||||
*/
|
||||
|
||||
#include "MarlinConfig.h"
|
||||
|
||||
#if ENABLED(MALYAN_LCD)
|
||||
|
||||
#if ENABLED(SDSUPPORT)
|
||||
#include "cardreader.h"
|
||||
#include "SdFatConfig.h"
|
||||
#else
|
||||
#define LONG_FILENAME_LENGTH 0
|
||||
#endif
|
||||
|
||||
#include "temperature.h"
|
||||
#include "planner.h"
|
||||
#include "stepper.h"
|
||||
#include "duration_t.h"
|
||||
#include "printcounter.h"
|
||||
#include "parser.h"
|
||||
#include "configuration_store.h"
|
||||
|
||||
#include "Marlin.h"
|
||||
|
||||
#if USE_MARLINSERIAL
|
||||
// Make an exception to use HardwareSerial too
|
||||
#undef HardwareSerial_h
|
||||
#include <HardwareSerial.h>
|
||||
#define USB_STATUS true
|
||||
#else
|
||||
#define USB_STATUS Serial
|
||||
#endif
|
||||
|
||||
// On the Malyan M200, this will be Serial1. On a RAMPS board,
|
||||
// it might not be.
|
||||
#define LCD_SERIAL Serial1
|
||||
|
||||
// This is based on longest sys command + a filename, plus some buffer
|
||||
// in case we encounter some data we don't recognize
|
||||
// There is no evidence a line will ever be this long, but better safe than sorry
|
||||
#define MAX_CURLY_COMMAND (32 + LONG_FILENAME_LENGTH) * 2
|
||||
|
||||
// Track incoming command bytes from the LCD
|
||||
int inbound_count;
|
||||
|
||||
// For sending print completion messages
|
||||
bool last_printing_status = false;
|
||||
|
||||
// Everything written needs the high bit set.
|
||||
void write_to_lcd_P(const char * const message) {
|
||||
char encoded_message[MAX_CURLY_COMMAND];
|
||||
uint8_t message_length = MIN(strlen_P(message), sizeof(encoded_message));
|
||||
|
||||
for (uint8_t i = 0; i < message_length; i++)
|
||||
encoded_message[i] = pgm_read_byte(&message[i]) | 0x80;
|
||||
|
||||
LCD_SERIAL.Print::write(encoded_message, message_length);
|
||||
}
|
||||
|
||||
void write_to_lcd(const char * const message) {
|
||||
char encoded_message[MAX_CURLY_COMMAND];
|
||||
const uint8_t message_length = MIN(strlen(message), sizeof(encoded_message));
|
||||
|
||||
for (uint8_t i = 0; i < message_length; i++)
|
||||
encoded_message[i] = message[i] | 0x80;
|
||||
|
||||
LCD_SERIAL.Print::write(encoded_message, message_length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Process an LCD 'C' command.
|
||||
* These are currently all temperature commands
|
||||
* {C:T0190}
|
||||
* Set temp for hotend to 190
|
||||
* {C:P050}
|
||||
* Set temp for bed to 50
|
||||
*
|
||||
* {C:S09} set feedrate to 90 %.
|
||||
* {C:S12} set feedrate to 120 %.
|
||||
*
|
||||
* the command portion begins after the :
|
||||
*/
|
||||
void process_lcd_c_command(const char* command) {
|
||||
switch (command[0]) {
|
||||
case 'C': {
|
||||
int raw_feedrate = atoi(command + 1);
|
||||
feedrate_percentage = raw_feedrate * 10;
|
||||
feedrate_percentage = constrain(feedrate_percentage, 10, 999);
|
||||
} break;
|
||||
case 'T': {
|
||||
thermalManager.setTargetHotend(atoi(command + 1), 0);
|
||||
} break;
|
||||
case 'P': {
|
||||
thermalManager.setTargetBed(atoi(command + 1));
|
||||
} break;
|
||||
|
||||
default:
|
||||
SERIAL_ECHOLNPAIR("UNKNOWN C COMMAND", command);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Process an LCD 'B' command.
|
||||
* {B:0} results in: {T0:008/195}{T1:000/000}{TP:000/000}{TQ:000C}{TT:000000}
|
||||
* T0/T1 are hot end temperatures, TP is bed, TQ is percent, and TT is probably
|
||||
* time remaining (HH:MM:SS). The UI can't handle displaying a second hotend,
|
||||
* but the stock firmware always sends it, and it's always zero.
|
||||
*/
|
||||
void process_lcd_eb_command(const char* command) {
|
||||
char elapsed_buffer[10];
|
||||
duration_t elapsed;
|
||||
switch (command[0]) {
|
||||
case '0': {
|
||||
elapsed = print_job_timer.duration();
|
||||
sprintf_P(elapsed_buffer, PSTR("%02u%02u%02u"), uint16_t(elapsed.hour()), uint16_t(elapsed.minute()) % 60UL, elapsed.second());
|
||||
|
||||
char message_buffer[MAX_CURLY_COMMAND];
|
||||
sprintf_P(message_buffer,
|
||||
PSTR("{T0:%03.0f/%03i}{T1:000/000}{TP:%03.0f/%03i}{TQ:%03i}{TT:%s}"),
|
||||
thermalManager.degHotend(0),
|
||||
thermalManager.degTargetHotend(0),
|
||||
#if HAS_HEATED_BED
|
||||
thermalManager.degBed(),
|
||||
thermalManager.degTargetBed(),
|
||||
#else
|
||||
0, 0,
|
||||
#endif
|
||||
#if ENABLED(SDSUPPORT)
|
||||
card.percentDone(),
|
||||
#else
|
||||
0,
|
||||
#endif
|
||||
elapsed_buffer);
|
||||
write_to_lcd(message_buffer);
|
||||
} break;
|
||||
|
||||
default:
|
||||
SERIAL_ECHOLNPAIR("UNKNOWN E/B COMMAND", command);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Process an LCD 'J' command.
|
||||
* These are currently all movement commands.
|
||||
* The command portion begins after the :
|
||||
* Move X Axis
|
||||
*
|
||||
* {J:E}{J:X-200}{J:E}
|
||||
* {J:E}{J:X+200}{J:E}
|
||||
* X, Y, Z, A (extruder)
|
||||
*/
|
||||
void process_lcd_j_command(const char* command) {
|
||||
static bool steppers_enabled = false;
|
||||
char axis = command[0];
|
||||
|
||||
switch (axis) {
|
||||
case 'E':
|
||||
// enable or disable steppers
|
||||
// switch to relative
|
||||
enqueue_and_echo_commands_now_P(PSTR("G91"));
|
||||
enqueue_and_echo_commands_now_P(steppers_enabled ? PSTR("M18") : PSTR("M17"));
|
||||
steppers_enabled = !steppers_enabled;
|
||||
break;
|
||||
case 'A':
|
||||
axis = 'E';
|
||||
// fallthru
|
||||
case 'Y':
|
||||
case 'Z':
|
||||
case 'X': {
|
||||
// G0 <AXIS><distance>
|
||||
// The M200 class UI seems to send movement in .1mm values.
|
||||
char cmd[20];
|
||||
sprintf_P(cmd, PSTR("G1 %c%03.1f"), axis, atof(command + 1) / 10.0);
|
||||
enqueue_and_echo_command_now(cmd);
|
||||
} break;
|
||||
default:
|
||||
SERIAL_ECHOLNPAIR("UNKNOWN J COMMAND", command);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Process an LCD 'P' command, related to homing and printing.
|
||||
* Cancel:
|
||||
* {P:X}
|
||||
*
|
||||
* Home all axes:
|
||||
* {P:H}
|
||||
*
|
||||
* Print a file:
|
||||
* {P:000}
|
||||
* The File number is specified as a three digit value.
|
||||
* Printer responds with:
|
||||
* {PRINTFILE:Mini_SNES_Bottom.gcode}
|
||||
* {SYS:BUILD}echo:Now fresh file: Mini_SNES_Bottom.gcode
|
||||
* File opened: Mini_SNES_Bottom.gcode Size: 5805813
|
||||
* File selected
|
||||
* {SYS:BUILD}
|
||||
* T:-2526.8 E:0
|
||||
* T:-2533.0 E:0
|
||||
* T:-2537.4 E:0
|
||||
* Note only the curly brace stuff matters.
|
||||
*/
|
||||
void process_lcd_p_command(const char* command) {
|
||||
|
||||
switch (command[0]) {
|
||||
case 'X':
|
||||
#if ENABLED(SDSUPPORT)
|
||||
// cancel print
|
||||
write_to_lcd_P(PSTR("{SYS:CANCELING}"));
|
||||
last_printing_status = false;
|
||||
card.stopSDPrint(
|
||||
#if SD_RESORT
|
||||
true
|
||||
#endif
|
||||
);
|
||||
clear_command_queue();
|
||||
quickstop_stepper();
|
||||
print_job_timer.stop();
|
||||
thermalManager.disable_all_heaters();
|
||||
#if FAN_COUNT > 0
|
||||
for (uint8_t i = 0; i < FAN_COUNT; i++) fanSpeeds[i] = 0;
|
||||
#endif
|
||||
wait_for_heatup = false;
|
||||
write_to_lcd_P(PSTR("{SYS:STARTED}"));
|
||||
#endif
|
||||
break;
|
||||
case 'H':
|
||||
// Home all axis
|
||||
enqueue_and_echo_commands_now_P(PSTR("G28"));
|
||||
break;
|
||||
default: {
|
||||
#if ENABLED(SDSUPPORT)
|
||||
// Print file 000 - a three digit number indicating which
|
||||
// file to print in the SD card. If it's a directory,
|
||||
// then switch to the directory.
|
||||
|
||||
// Find the name of the file to print.
|
||||
// It's needed to echo the PRINTFILE option.
|
||||
// The {S:L} command should've ensured the SD card was mounted.
|
||||
card.getfilename(atoi(command));
|
||||
|
||||
// There may be a difference in how V1 and V2 LCDs handle subdirectory
|
||||
// prints. Investigate more. This matches the V1 motion controller actions
|
||||
// but the V2 LCD switches to "print" mode on {SYS:DIR} response.
|
||||
if (card.filenameIsDir) {
|
||||
card.chdir(card.filename);
|
||||
write_to_lcd_P(PSTR("{SYS:DIR}"));
|
||||
}
|
||||
else {
|
||||
char message_buffer[MAX_CURLY_COMMAND];
|
||||
sprintf_P(message_buffer, PSTR("{PRINTFILE:%s}"), card.longest_filename());
|
||||
write_to_lcd(message_buffer);
|
||||
write_to_lcd_P(PSTR("{SYS:BUILD}"));
|
||||
card.openAndPrintFile(card.filename);
|
||||
}
|
||||
#endif
|
||||
} break; // default
|
||||
} // switch
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle an lcd 'S' command
|
||||
* {S:I} - Temperature request
|
||||
* {T0:999/000}{T1:000/000}{TP:004/000}
|
||||
*
|
||||
* {S:L} - File Listing request
|
||||
* Printer Response:
|
||||
* {FILE:buttons.gcode}
|
||||
* {FILE:update.bin}
|
||||
* {FILE:nupdate.bin}
|
||||
* {FILE:fcupdate.flg}
|
||||
* {SYS:OK}
|
||||
*/
|
||||
void process_lcd_s_command(const char* command) {
|
||||
switch (command[0]) {
|
||||
case 'I': {
|
||||
// temperature information
|
||||
char message_buffer[MAX_CURLY_COMMAND];
|
||||
sprintf_P(message_buffer, PSTR("{T0:%03.0f/%03i}{T1:000/000}{TP:%03.0f/%03i}"),
|
||||
thermalManager.degHotend(0), thermalManager.degTargetHotend(0),
|
||||
#if HAS_HEATED_BED
|
||||
thermalManager.degBed(), thermalManager.degTargetBed()
|
||||
#else
|
||||
0, 0
|
||||
#endif
|
||||
);
|
||||
write_to_lcd(message_buffer);
|
||||
} break;
|
||||
|
||||
case 'H':
|
||||
// Home all axis
|
||||
enqueue_and_echo_command("G28");
|
||||
break;
|
||||
|
||||
case 'L': {
|
||||
#if ENABLED(SDSUPPORT)
|
||||
if (!card.cardOK) card.initsd();
|
||||
|
||||
// A more efficient way to do this would be to
|
||||
// implement a callback in the ls_SerialPrint code, but
|
||||
// that requires changes to the core cardreader class that
|
||||
// would not benefit the majority of users. Since one can't
|
||||
// select a file for printing during a print, there's
|
||||
// little reason not to do it this way.
|
||||
char message_buffer[MAX_CURLY_COMMAND];
|
||||
uint16_t file_count = card.get_num_Files();
|
||||
for (uint16_t i = 0; i < file_count; i++) {
|
||||
card.getfilename(i);
|
||||
sprintf_P(message_buffer, card.filenameIsDir ? PSTR("{DIR:%s}") : PSTR("{FILE:%s}"), card.longest_filename());
|
||||
write_to_lcd(message_buffer);
|
||||
}
|
||||
|
||||
write_to_lcd_P(PSTR("{SYS:OK}"));
|
||||
#endif
|
||||
} break;
|
||||
|
||||
default:
|
||||
SERIAL_ECHOLNPAIR("UNKNOWN S COMMAND", command);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Receive a curly brace command and translate to G-code.
|
||||
* Currently {E:0} is not handled. Its function is unknown,
|
||||
* but it occurs during the temp window after a sys build.
|
||||
*/
|
||||
void process_lcd_command(const char* command) {
|
||||
const char *current = command;
|
||||
|
||||
current++; // skip the leading {. The trailing one is already gone.
|
||||
byte command_code = *current++;
|
||||
if (*current != ':') {
|
||||
SERIAL_ECHOLNPAIR("UNKNOWN COMMAND FORMAT", command);
|
||||
return;
|
||||
}
|
||||
|
||||
current++; // skip the :
|
||||
|
||||
switch (command_code) {
|
||||
case 'S':
|
||||
process_lcd_s_command(current);
|
||||
break;
|
||||
case 'J':
|
||||
process_lcd_j_command(current);
|
||||
break;
|
||||
case 'P':
|
||||
process_lcd_p_command(current);
|
||||
break;
|
||||
case 'C':
|
||||
process_lcd_c_command(current);
|
||||
break;
|
||||
case 'B':
|
||||
case 'E':
|
||||
process_lcd_eb_command(current);
|
||||
break;
|
||||
default:
|
||||
SERIAL_ECHOLNPAIR("UNKNOWN COMMAND", command);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* UC means connected.
|
||||
* UD means disconnected
|
||||
* The stock firmware considers USB initialized as "connected."
|
||||
*/
|
||||
void update_usb_status(const bool forceUpdate) {
|
||||
static bool last_usb_connected_status = false;
|
||||
// This is mildly different than stock, which
|
||||
// appears to use the usb discovery status.
|
||||
// This is more logical.
|
||||
if (last_usb_connected_status != USB_STATUS || forceUpdate) {
|
||||
last_usb_connected_status = USB_STATUS;
|
||||
write_to_lcd_P(last_usb_connected_status ? PSTR("{R:UC}\r\n") : PSTR("{R:UD}\r\n"));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* - from printer on startup:
|
||||
* {SYS:STARTED}{VER:29}{SYS:STARTED}{R:UD}
|
||||
* The optimize attribute fixes a register Compile
|
||||
* error for amtel.
|
||||
*/
|
||||
void _O2 lcd_update() {
|
||||
static char inbound_buffer[MAX_CURLY_COMMAND];
|
||||
|
||||
// First report USB status.
|
||||
update_usb_status(false);
|
||||
|
||||
// now drain commands...
|
||||
while (LCD_SERIAL.available()) {
|
||||
const byte b = (byte)LCD_SERIAL.read() & 0x7F;
|
||||
inbound_buffer[inbound_count++] = b;
|
||||
if (b == '}' || inbound_count == sizeof(inbound_buffer) - 1) {
|
||||
inbound_buffer[inbound_count - 1] = '\0';
|
||||
process_lcd_command(inbound_buffer);
|
||||
inbound_count = 0;
|
||||
inbound_buffer[0] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
#if ENABLED(SDSUPPORT)
|
||||
// The way last printing status works is simple:
|
||||
// The UI needs to see at least one TQ which is not 100%
|
||||
// and then when the print is complete, one which is.
|
||||
static uint8_t last_percent_done = 100;
|
||||
|
||||
// If there was a print in progress, we need to emit the final
|
||||
// print status as {TQ:100}. Reset last percent done so a new print will
|
||||
// issue a percent of 0.
|
||||
const uint8_t percent_done = card.sdprinting ? card.percentDone() : last_printing_status ? 100 : 0;
|
||||
if (percent_done != last_percent_done) {
|
||||
char message_buffer[10];
|
||||
sprintf_P(message_buffer, PSTR("{TQ:%03i}"), percent_done);
|
||||
write_to_lcd(message_buffer);
|
||||
last_percent_done = percent_done;
|
||||
last_printing_status = card.sdprinting;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* The Malyan LCD actually runs as a separate MCU on Serial 1.
|
||||
* This code's job is to siphon the weird curly-brace commands from
|
||||
* it and translate into gcode, which then gets injected into
|
||||
* the command queue where possible.
|
||||
*/
|
||||
void lcd_init() {
|
||||
inbound_count = 0;
|
||||
LCD_SERIAL.begin(500000);
|
||||
|
||||
// Signal init
|
||||
write_to_lcd_P(PSTR("{SYS:STARTED}\r\n"));
|
||||
|
||||
// send a version that says "unsupported"
|
||||
write_to_lcd_P(PSTR("{VER:99}\r\n"));
|
||||
|
||||
// No idea why it does this twice.
|
||||
write_to_lcd_P(PSTR("{SYS:STARTED}\r\n"));
|
||||
update_usb_status(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set an alert.
|
||||
*/
|
||||
void lcd_setalertstatusPGM(const char* message) {
|
||||
char message_buffer[MAX_CURLY_COMMAND];
|
||||
sprintf_P(message_buffer, PSTR("{E:%s}"), message);
|
||||
write_to_lcd(message_buffer);
|
||||
}
|
||||
|
||||
#endif // MALYAN_LCD
|
|
@ -1,302 +0,0 @@
|
|||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* parser.cpp - Parser for a GCode line, providing a parameter interface.
|
||||
*/
|
||||
|
||||
#include "parser.h"
|
||||
|
||||
#include "Marlin.h"
|
||||
#include "language.h"
|
||||
|
||||
// Must be declared for allocation and to satisfy the linker
|
||||
// Zero values need no initialization.
|
||||
|
||||
bool GCodeParser::volumetric_enabled;
|
||||
|
||||
#if ENABLED(INCH_MODE_SUPPORT)
|
||||
float GCodeParser::linear_unit_factor, GCodeParser::volumetric_unit_factor;
|
||||
#endif
|
||||
|
||||
#if ENABLED(TEMPERATURE_UNITS_SUPPORT)
|
||||
TempUnit GCodeParser::input_temp_units;
|
||||
#endif
|
||||
|
||||
char *GCodeParser::command_ptr,
|
||||
*GCodeParser::string_arg,
|
||||
*GCodeParser::value_ptr;
|
||||
char GCodeParser::command_letter;
|
||||
int GCodeParser::codenum;
|
||||
#if USE_GCODE_SUBCODES
|
||||
uint8_t GCodeParser::subcode;
|
||||
#endif
|
||||
|
||||
#if ENABLED(FASTER_GCODE_PARSER)
|
||||
// Optimized Parameters
|
||||
uint32_t GCodeParser::codebits; // found bits
|
||||
uint8_t GCodeParser::param[26]; // parameter offsets from command_ptr
|
||||
#else
|
||||
char *GCodeParser::command_args; // start of parameters
|
||||
#endif
|
||||
|
||||
// Create a global instance of the GCode parser singleton
|
||||
GCodeParser parser;
|
||||
|
||||
/**
|
||||
* Clear all code-seen (and value pointers)
|
||||
*
|
||||
* Since each param is set/cleared on seen codes,
|
||||
* this may be optimized by commenting out ZERO(param)
|
||||
*/
|
||||
void GCodeParser::reset() {
|
||||
string_arg = NULL; // No whole line argument
|
||||
command_letter = '?'; // No command letter
|
||||
codenum = 0; // No command code
|
||||
#if USE_GCODE_SUBCODES
|
||||
subcode = 0; // No command sub-code
|
||||
#endif
|
||||
#if ENABLED(FASTER_GCODE_PARSER)
|
||||
codebits = 0; // No codes yet
|
||||
//ZERO(param); // No parameters (should be safe to comment out this line)
|
||||
#endif
|
||||
}
|
||||
|
||||
// Populate all fields by parsing a single line of GCode
|
||||
// 58 bytes of SRAM are used to speed up seen/value
|
||||
void GCodeParser::parse(char *p) {
|
||||
|
||||
reset(); // No codes to report
|
||||
|
||||
// Skip spaces
|
||||
while (*p == ' ') ++p;
|
||||
|
||||
// Skip N[-0-9] if included in the command line
|
||||
if (*p == 'N' && NUMERIC_SIGNED(p[1])) {
|
||||
#if ENABLED(FASTER_GCODE_PARSER)
|
||||
//set('N', p + 1); // (optional) Set the 'N' parameter value
|
||||
#endif
|
||||
p += 2; // skip N[-0-9]
|
||||
while (NUMERIC(*p)) ++p; // skip [0-9]*
|
||||
while (*p == ' ') ++p; // skip [ ]*
|
||||
}
|
||||
|
||||
// *p now points to the current command, which should be G, M, or T
|
||||
command_ptr = p;
|
||||
|
||||
// Get the command letter, which must be G, M, or T
|
||||
const char letter = *p++;
|
||||
|
||||
// Nullify asterisk and trailing whitespace
|
||||
char *starpos = strchr(p, '*');
|
||||
if (starpos) {
|
||||
--starpos; // *
|
||||
while (*starpos == ' ') --starpos; // spaces...
|
||||
starpos[1] = '\0';
|
||||
}
|
||||
|
||||
// Bail if the letter is not G, M, or T
|
||||
switch (letter) { case 'G': case 'M': case 'T': break; default: return; }
|
||||
|
||||
// Skip spaces to get the numeric part
|
||||
while (*p == ' ') p++;
|
||||
|
||||
// Bail if there's no command code number
|
||||
if (!NUMERIC(*p)) return;
|
||||
|
||||
// Save the command letter at this point
|
||||
// A '?' signifies an unknown command
|
||||
command_letter = letter;
|
||||
|
||||
// Get the code number - integer digits only
|
||||
codenum = 0;
|
||||
do {
|
||||
codenum *= 10, codenum += *p++ - '0';
|
||||
} while (NUMERIC(*p));
|
||||
|
||||
// Allow for decimal point in command
|
||||
#if USE_GCODE_SUBCODES
|
||||
if (*p == '.') {
|
||||
p++;
|
||||
while (NUMERIC(*p))
|
||||
subcode *= 10, subcode += *p++ - '0';
|
||||
}
|
||||
#endif
|
||||
|
||||
// Skip all spaces to get to the first argument, or nul
|
||||
while (*p == ' ') p++;
|
||||
|
||||
// The command parameters (if any) start here, for sure!
|
||||
|
||||
#if DISABLED(FASTER_GCODE_PARSER)
|
||||
command_args = p; // Scan for parameters in seen()
|
||||
#endif
|
||||
|
||||
// Only use string_arg for these M codes
|
||||
if (letter == 'M') switch (codenum) { case 23: case 28: case 30: case 117: case 118: case 928: string_arg = p; return; default: break; }
|
||||
|
||||
#if ENABLED(DEBUG_GCODE_PARSER)
|
||||
const bool debug = codenum == 800;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Find all parameters, set flags and pointers for fast parsing
|
||||
*
|
||||
* Most codes ignore 'string_arg', but those that want a string will get the right pointer.
|
||||
* The following loop assigns the first "parameter" having no numeric value to 'string_arg'.
|
||||
* This allows M0/M1 with expire time to work: "M0 S5 You Win!"
|
||||
* For 'M118' you must use 'E1' and 'A1' rather than just 'E' or 'A'
|
||||
*/
|
||||
string_arg = NULL;
|
||||
while (const char code = *p++) { // Get the next parameter. A NUL ends the loop
|
||||
|
||||
// Special handling for M32 [P] !/path/to/file.g#
|
||||
// The path must be the last parameter
|
||||
if (code == '!' && letter == 'M' && codenum == 32) {
|
||||
string_arg = p; // Name starts after '!'
|
||||
char * const lb = strchr(p, '#'); // Already seen '#' as SD char (to pause buffering)
|
||||
if (lb) *lb = '\0'; // Safe to mark the end of the filename
|
||||
return;
|
||||
}
|
||||
|
||||
// Arguments MUST be uppercase for fast GCode parsing
|
||||
#if ENABLED(FASTER_GCODE_PARSER)
|
||||
#define PARAM_TEST WITHIN(code, 'A', 'Z')
|
||||
#else
|
||||
#define PARAM_TEST true
|
||||
#endif
|
||||
|
||||
if (PARAM_TEST) {
|
||||
|
||||
while (*p == ' ') p++; // Skip spaces between parameters & values
|
||||
|
||||
const bool has_num = valid_float(p);
|
||||
|
||||
#if ENABLED(DEBUG_GCODE_PARSER)
|
||||
if (debug) {
|
||||
SERIAL_ECHOPAIR("Got letter ", code);
|
||||
SERIAL_ECHOPAIR(" at index ", (int)(p - command_ptr - 1));
|
||||
if (has_num) SERIAL_ECHOPGM(" (has_num)");
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!has_num && !string_arg) { // No value? First time, keep as string_arg
|
||||
string_arg = p - 1;
|
||||
#if ENABLED(DEBUG_GCODE_PARSER)
|
||||
if (debug) SERIAL_ECHOPAIR(" string_arg: ", hex_address((void*)string_arg)); // DEBUG
|
||||
#endif
|
||||
}
|
||||
|
||||
#if ENABLED(DEBUG_GCODE_PARSER)
|
||||
if (debug) SERIAL_EOL();
|
||||
#endif
|
||||
|
||||
#if ENABLED(FASTER_GCODE_PARSER)
|
||||
set(code, has_num ? p : NULL); // Set parameter exists and pointer (NULL for no number)
|
||||
#endif
|
||||
}
|
||||
else if (!string_arg) { // Not A-Z? First time, keep as the string_arg
|
||||
string_arg = p - 1;
|
||||
#if ENABLED(DEBUG_GCODE_PARSER)
|
||||
if (debug) SERIAL_ECHOPAIR(" string_arg: ", hex_address((void*)string_arg)); // DEBUG
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!WITHIN(*p, 'A', 'Z')) { // Another parameter right away?
|
||||
while (*p && DECIMAL_SIGNED(*p)) p++; // Skip over the value section of a parameter
|
||||
while (*p == ' ') p++; // Skip over all spaces
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if ENABLED(CNC_COORDINATE_SYSTEMS)
|
||||
|
||||
// Parse the next parameter as a new command
|
||||
bool GCodeParser::chain() {
|
||||
#if ENABLED(FASTER_GCODE_PARSER)
|
||||
char *next_command = command_ptr;
|
||||
if (next_command) {
|
||||
while (*next_command && *next_command != ' ') ++next_command;
|
||||
while (*next_command == ' ') ++next_command;
|
||||
if (!*next_command) next_command = NULL;
|
||||
}
|
||||
#else
|
||||
const char *next_command = command_args;
|
||||
#endif
|
||||
if (next_command) parse(next_command);
|
||||
return !!next_command;
|
||||
}
|
||||
|
||||
#endif // CNC_COORDINATE_SYSTEMS
|
||||
|
||||
void GCodeParser::unknown_command_error() {
|
||||
SERIAL_ECHO_START();
|
||||
SERIAL_ECHOPAIR(MSG_UNKNOWN_COMMAND, command_ptr);
|
||||
SERIAL_CHAR('"');
|
||||
SERIAL_EOL();
|
||||
}
|
||||
|
||||
#if ENABLED(DEBUG_GCODE_PARSER)
|
||||
|
||||
void GCodeParser::debug() {
|
||||
SERIAL_ECHOPAIR("Command: ", command_ptr);
|
||||
SERIAL_ECHOPAIR(" (", command_letter);
|
||||
SERIAL_ECHO(codenum);
|
||||
SERIAL_ECHOLNPGM(")");
|
||||
#if ENABLED(FASTER_GCODE_PARSER)
|
||||
SERIAL_ECHOPGM(" args: \"");
|
||||
for (char c = 'A'; c <= 'Z'; ++c)
|
||||
if (seen(c)) { SERIAL_CHAR(c); SERIAL_CHAR(' '); }
|
||||
#else
|
||||
SERIAL_ECHOPAIR(" args: \"", command_args);
|
||||
#endif
|
||||
SERIAL_CHAR('"');
|
||||
if (string_arg) {
|
||||
SERIAL_ECHOPGM(" string: \"");
|
||||
SERIAL_ECHO(string_arg);
|
||||
SERIAL_CHAR('"');
|
||||
}
|
||||
SERIAL_ECHOPGM("\n\n");
|
||||
for (char c = 'A'; c <= 'Z'; ++c) {
|
||||
if (seen(c)) {
|
||||
SERIAL_ECHOPAIR("Code '", c); SERIAL_ECHOPGM("':");
|
||||
if (has_value()) {
|
||||
SERIAL_ECHOPAIR("\n float: ", value_float());
|
||||
SERIAL_ECHOPAIR("\n long: ", value_long());
|
||||
SERIAL_ECHOPAIR("\n ulong: ", value_ulong());
|
||||
SERIAL_ECHOPAIR("\n millis: ", value_millis());
|
||||
SERIAL_ECHOPAIR("\n sec-ms: ", value_millis_from_seconds());
|
||||
SERIAL_ECHOPAIR("\n int: ", value_int());
|
||||
SERIAL_ECHOPAIR("\n ushort: ", value_ushort());
|
||||
SERIAL_ECHOPAIR("\n byte: ", (int)value_byte());
|
||||
SERIAL_ECHOPAIR("\n bool: ", (int)value_bool());
|
||||
SERIAL_ECHOPAIR("\n linear: ", value_linear_units());
|
||||
SERIAL_ECHOPAIR("\n celsius: ", value_celsius());
|
||||
}
|
||||
else
|
||||
SERIAL_ECHOPGM(" (no value)");
|
||||
SERIAL_ECHOPGM("\n\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif // DEBUG_GCODE_PARSER
|
341
Marlin/parser.h
|
@ -1,341 +0,0 @@
|
|||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* parser.h - Parser for a GCode line, providing a parameter interface.
|
||||
* Codes like M149 control the way the GCode parser behaves,
|
||||
* so settings for these codes are located in this class.
|
||||
*/
|
||||
|
||||
#ifndef _PARSER_H_
|
||||
#define _PARSER_H_
|
||||
|
||||
#include "enum.h"
|
||||
#include "types.h"
|
||||
#include "MarlinConfig.h"
|
||||
|
||||
//#define DEBUG_GCODE_PARSER
|
||||
#if ENABLED(DEBUG_GCODE_PARSER)
|
||||
#include "hex_print_routines.h"
|
||||
#include "serial.h"
|
||||
#endif
|
||||
|
||||
#define strtof strtod
|
||||
|
||||
/**
|
||||
* GCode parser
|
||||
*
|
||||
* - Parse a single gcode line for its letter, code, subcode, and parameters
|
||||
* - FASTER_GCODE_PARSER:
|
||||
* - Flags existing params (1 bit each)
|
||||
* - Stores value offsets (1 byte each)
|
||||
* - Provide accessors for parameters:
|
||||
* - Parameter exists
|
||||
* - Parameter has value
|
||||
* - Parameter value in different units and types
|
||||
*/
|
||||
class GCodeParser {
|
||||
|
||||
private:
|
||||
static char *value_ptr; // Set by seen, used to fetch the value
|
||||
|
||||
#if ENABLED(FASTER_GCODE_PARSER)
|
||||
static uint32_t codebits; // Parameters pre-scanned
|
||||
static uint8_t param[26]; // For A-Z, offsets into command args
|
||||
#else
|
||||
static char *command_args; // Args start here, for slow scan
|
||||
#endif
|
||||
|
||||
public:
|
||||
|
||||
// Global states for GCode-level units features
|
||||
|
||||
static bool volumetric_enabled;
|
||||
|
||||
#if ENABLED(INCH_MODE_SUPPORT)
|
||||
static float linear_unit_factor, volumetric_unit_factor;
|
||||
#endif
|
||||
|
||||
#if ENABLED(TEMPERATURE_UNITS_SUPPORT)
|
||||
static TempUnit input_temp_units;
|
||||
#endif
|
||||
|
||||
// Command line state
|
||||
static char *command_ptr, // The command, so it can be echoed
|
||||
*string_arg; // string of command line
|
||||
|
||||
static char command_letter; // G, M, or T
|
||||
static int codenum; // 123
|
||||
#if USE_GCODE_SUBCODES
|
||||
static uint8_t subcode; // .1
|
||||
#endif
|
||||
|
||||
#if ENABLED(DEBUG_GCODE_PARSER)
|
||||
static void debug();
|
||||
#endif
|
||||
|
||||
GCodeParser() {
|
||||
#if ENABLED(INCH_MODE_SUPPORT)
|
||||
set_input_linear_units(LINEARUNIT_MM);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Reset is done before parsing
|
||||
static void reset();
|
||||
|
||||
#define LETTER_BIT(N) ((N) - 'A')
|
||||
|
||||
FORCE_INLINE static bool valid_signless(const char * const p) {
|
||||
return NUMERIC(p[0]) || (p[0] == '.' && NUMERIC(p[1])); // .?[0-9]
|
||||
}
|
||||
|
||||
FORCE_INLINE static bool valid_float(const char * const p) {
|
||||
return valid_signless(p) || ((p[0] == '-' || p[0] == '+') && valid_signless(&p[1])); // [-+]?.?[0-9]
|
||||
}
|
||||
|
||||
#if ENABLED(FASTER_GCODE_PARSER)
|
||||
|
||||
FORCE_INLINE static bool valid_int(const char * const p) {
|
||||
return NUMERIC(p[0]) || ((p[0] == '-' || p[0] == '+') && NUMERIC(p[1])); // [-+]?[0-9]
|
||||
}
|
||||
|
||||
// Set the flag and pointer for a parameter
|
||||
static void set(const char c, char * const ptr) {
|
||||
const uint8_t ind = LETTER_BIT(c);
|
||||
if (ind >= COUNT(param)) return; // Only A-Z
|
||||
SBI32(codebits, ind); // parameter exists
|
||||
param[ind] = ptr ? ptr - command_ptr : 0; // parameter offset or 0
|
||||
#if ENABLED(DEBUG_GCODE_PARSER)
|
||||
if (codenum == 800) {
|
||||
SERIAL_ECHOPAIR("Set bit ", (int)ind);
|
||||
SERIAL_ECHOPAIR(" of codebits (", hex_address((void*)(codebits >> 16)));
|
||||
print_hex_word((uint16_t)(codebits & 0xFFFF));
|
||||
SERIAL_ECHOLNPAIR(") | param = ", (int)param[ind]);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// Code seen bit was set. If not found, value_ptr is unchanged.
|
||||
// This allows "if (seen('A')||seen('B'))" to use the last-found value.
|
||||
static bool seen(const char c) {
|
||||
const uint8_t ind = LETTER_BIT(c);
|
||||
if (ind >= COUNT(param)) return false; // Only A-Z
|
||||
const bool b = TEST32(codebits, ind);
|
||||
if (b) {
|
||||
#if ENABLED(DEBUG_GCODE_PARSER)
|
||||
if (codenum == 800) {
|
||||
SERIAL_CHAR('\''); SERIAL_CHAR(c); SERIAL_ECHOLNPGM("' is seen");
|
||||
}
|
||||
#endif
|
||||
char * const ptr = command_ptr + param[ind];
|
||||
value_ptr = param[ind] && valid_float(ptr) ? ptr : (char*)NULL;
|
||||
}
|
||||
return b;
|
||||
}
|
||||
|
||||
static bool seen_any() { return !!codebits; }
|
||||
|
||||
#define SEEN_TEST(L) TEST32(codebits, LETTER_BIT(L))
|
||||
|
||||
#else // !FASTER_GCODE_PARSER
|
||||
|
||||
// Code is found in the string. If not found, value_ptr is unchanged.
|
||||
// This allows "if (seen('A')||seen('B'))" to use the last-found value.
|
||||
static bool seen(const char c) {
|
||||
char *p = strchr(command_args, c);
|
||||
const bool b = !!p;
|
||||
if (b) value_ptr = valid_float(&p[1]) ? &p[1] : (char*)NULL;
|
||||
return b;
|
||||
}
|
||||
|
||||
static bool seen_any() { return *command_args == '\0'; }
|
||||
|
||||
#define SEEN_TEST(L) !!strchr(command_args, L)
|
||||
|
||||
#endif // !FASTER_GCODE_PARSER
|
||||
|
||||
// Seen any axis parameter
|
||||
static bool seen_axis() {
|
||||
return SEEN_TEST('X') || SEEN_TEST('Y') || SEEN_TEST('Z') || SEEN_TEST('E');
|
||||
}
|
||||
|
||||
// Populate all fields by parsing a single line of GCode
|
||||
// This uses 54 bytes of SRAM to speed up seen/value
|
||||
static void parse(char * p);
|
||||
|
||||
#if ENABLED(CNC_COORDINATE_SYSTEMS)
|
||||
// Parse the next parameter as a new command
|
||||
static bool chain();
|
||||
#endif
|
||||
|
||||
// The code value pointer was set
|
||||
FORCE_INLINE static bool has_value() { return value_ptr != NULL; }
|
||||
|
||||
// Seen a parameter with a value
|
||||
inline static bool seenval(const char c) { return seen(c) && has_value(); }
|
||||
|
||||
// Float removes 'E' to prevent scientific notation interpretation
|
||||
inline static float value_float() {
|
||||
if (value_ptr) {
|
||||
char *e = value_ptr;
|
||||
for (;;) {
|
||||
const char c = *e;
|
||||
if (c == '\0' || c == ' ') break;
|
||||
if (c == 'E' || c == 'e') {
|
||||
*e = '\0';
|
||||
const float ret = strtof(value_ptr, NULL);
|
||||
*e = c;
|
||||
return ret;
|
||||
}
|
||||
++e;
|
||||
}
|
||||
return strtof(value_ptr, NULL);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Code value as a long or ulong
|
||||
inline static int32_t value_long() { return value_ptr ? strtol(value_ptr, NULL, 10) : 0L; }
|
||||
inline static uint32_t value_ulong() { return value_ptr ? strtoul(value_ptr, NULL, 10) : 0UL; }
|
||||
|
||||
// Code value for use as time
|
||||
FORCE_INLINE static millis_t value_millis() { return value_ulong(); }
|
||||
FORCE_INLINE static millis_t value_millis_from_seconds() { return value_float() * 1000UL; }
|
||||
|
||||
// Reduce to fewer bits
|
||||
FORCE_INLINE static int16_t value_int() { return (int16_t)value_long(); }
|
||||
FORCE_INLINE static uint16_t value_ushort() { return (uint16_t)value_long(); }
|
||||
inline static uint8_t value_byte() { return (uint8_t)constrain(value_long(), 0, 255); }
|
||||
|
||||
// Bool is true with no value or non-zero
|
||||
inline static bool value_bool() { return !has_value() || !!value_byte(); }
|
||||
|
||||
// Units modes: Inches, Fahrenheit, Kelvin
|
||||
|
||||
#if ENABLED(INCH_MODE_SUPPORT)
|
||||
|
||||
inline static void set_input_linear_units(const LinearUnit units) {
|
||||
switch (units) {
|
||||
case LINEARUNIT_INCH:
|
||||
linear_unit_factor = 25.4;
|
||||
break;
|
||||
case LINEARUNIT_MM:
|
||||
default:
|
||||
linear_unit_factor = 1.0;
|
||||
break;
|
||||
}
|
||||
volumetric_unit_factor = POW(linear_unit_factor, 3.0);
|
||||
}
|
||||
|
||||
inline static float axis_unit_factor(const AxisEnum axis) {
|
||||
return (axis >= E_AXIS && volumetric_enabled ? volumetric_unit_factor : linear_unit_factor);
|
||||
}
|
||||
|
||||
inline static float value_linear_units() { return value_float() * linear_unit_factor; }
|
||||
inline static float value_axis_units(const AxisEnum axis) { return value_float() * axis_unit_factor(axis); }
|
||||
inline static float value_per_axis_unit(const AxisEnum axis) { return value_float() / axis_unit_factor(axis); }
|
||||
|
||||
#else
|
||||
|
||||
FORCE_INLINE static float value_linear_units() { return value_float(); }
|
||||
FORCE_INLINE static float value_axis_units(const AxisEnum a) { UNUSED(a); return value_float(); }
|
||||
FORCE_INLINE static float value_per_axis_unit(const AxisEnum a) { UNUSED(a); return value_float(); }
|
||||
|
||||
#endif
|
||||
|
||||
#if ENABLED(TEMPERATURE_UNITS_SUPPORT)
|
||||
|
||||
inline static void set_input_temp_units(TempUnit units) { input_temp_units = units; }
|
||||
|
||||
#if ENABLED(ULTIPANEL) && DISABLED(DISABLE_M503)
|
||||
|
||||
FORCE_INLINE static char temp_units_code() {
|
||||
return input_temp_units == TEMPUNIT_K ? 'K' : input_temp_units == TEMPUNIT_F ? 'F' : 'C';
|
||||
}
|
||||
FORCE_INLINE static const char* temp_units_name() {
|
||||
return input_temp_units == TEMPUNIT_K ? PSTR("Kelvin") : input_temp_units == TEMPUNIT_F ? PSTR("Fahrenheit") : PSTR("Celsius");
|
||||
}
|
||||
inline static float to_temp_units(const float &f) {
|
||||
switch (input_temp_units) {
|
||||
case TEMPUNIT_F:
|
||||
return f * 0.5555555556 + 32.0;
|
||||
case TEMPUNIT_K:
|
||||
return f + 273.15;
|
||||
case TEMPUNIT_C:
|
||||
default:
|
||||
return f;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // ULTIPANEL && !DISABLE_M503
|
||||
|
||||
inline static float value_celsius() {
|
||||
const float f = value_float();
|
||||
switch (input_temp_units) {
|
||||
case TEMPUNIT_F:
|
||||
return (f - 32.0) * 0.5555555556;
|
||||
case TEMPUNIT_K:
|
||||
return f - 273.15;
|
||||
case TEMPUNIT_C:
|
||||
default:
|
||||
return f;
|
||||
}
|
||||
}
|
||||
|
||||
inline static float value_celsius_diff() {
|
||||
switch (input_temp_units) {
|
||||
case TEMPUNIT_F:
|
||||
return value_float() * 0.5555555556;
|
||||
case TEMPUNIT_C:
|
||||
case TEMPUNIT_K:
|
||||
default:
|
||||
return value_float();
|
||||
}
|
||||
}
|
||||
|
||||
#else // !TEMPERATURE_UNITS_SUPPORT
|
||||
|
||||
FORCE_INLINE static float value_celsius() { return value_float(); }
|
||||
FORCE_INLINE static float value_celsius_diff() { return value_float(); }
|
||||
|
||||
#endif // !TEMPERATURE_UNITS_SUPPORT
|
||||
|
||||
FORCE_INLINE static float value_feedrate() { return value_linear_units(); }
|
||||
|
||||
void unknown_command_error();
|
||||
|
||||
// Provide simple value accessors with default option
|
||||
FORCE_INLINE static float floatval(const char c, const float dval=0.0) { return seenval(c) ? value_float() : dval; }
|
||||
FORCE_INLINE static bool boolval(const char c, const bool dval=false) { return seenval(c) ? value_bool() : (seen(c) ? true : dval); }
|
||||
FORCE_INLINE static uint8_t byteval(const char c, const uint8_t dval=0) { return seenval(c) ? value_byte() : dval; }
|
||||
FORCE_INLINE static int16_t intval(const char c, const int16_t dval=0) { return seenval(c) ? value_int() : dval; }
|
||||
FORCE_INLINE static uint16_t ushortval(const char c, const uint16_t dval=0) { return seenval(c) ? value_ushort() : dval; }
|
||||
FORCE_INLINE static int32_t longval(const char c, const int32_t dval=0) { return seenval(c) ? value_long() : dval; }
|
||||
FORCE_INLINE static uint32_t ulongval(const char c, const uint32_t dval=0) { return seenval(c) ? value_ulong() : dval; }
|
||||
FORCE_INLINE static float linearval(const char c, const float dval=0.0) { return seenval(c) ? value_linear_units() : dval; }
|
||||
FORCE_INLINE static float celsiusval(const char c, const float dval=0.0) { return seenval(c) ? value_celsius() : dval; }
|
||||
|
||||
};
|
||||
|
||||
extern GCodeParser parser;
|
||||
|
||||
#endif // _PARSER_H_
|
|
@ -1,179 +0,0 @@
|
|||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Einsy-Rambo pin assignments
|
||||
*/
|
||||
|
||||
#ifndef __AVR_ATmega2560__
|
||||
#error "Oops! Make sure you have 'Arduino Mega 2560 or Rambo' selected from the 'Tools -> Boards' menu."
|
||||
#endif
|
||||
|
||||
#define BOARD_NAME "Einsy Rambo"
|
||||
|
||||
//
|
||||
// TMC2130 Configuration_adv defaults for EinsyRambo
|
||||
//
|
||||
#if !AXIS_DRIVER_TYPE(X, TMC2130) || !AXIS_DRIVER_TYPE(Y, TMC2130) || !AXIS_DRIVER_TYPE(Z, TMC2130) || !AXIS_DRIVER_TYPE(E0, TMC2130)
|
||||
#error "You must set ([XYZ]|E0)_DRIVER_TYPE to TMC2130 in Configuration.h for EinsyRambo."
|
||||
#endif
|
||||
|
||||
// TMC2130 Diag Pins (currently just for reference)
|
||||
#define X_DIAG_PIN 64
|
||||
#define Y_DIAG_PIN 69
|
||||
#define Z_DIAG_PIN 68
|
||||
#define E0_DIAG_PIN 65
|
||||
|
||||
//
|
||||
// Limit Switches
|
||||
//
|
||||
// Only use Diag Pins when SENSORLESS_HOMING is enabled for the TMC2130 drivers.
|
||||
// Otherwise use a physical endstop based configuration.
|
||||
//
|
||||
// SERVO0_PIN and Z_MIN_PIN configuration for BLTOUCH sensor when combined with SENSORLESS_HOMING.
|
||||
//
|
||||
|
||||
#if DISABLED(SENSORLESS_HOMING)
|
||||
|
||||
#define X_STOP_PIN 12
|
||||
#define Y_STOP_PIN 11
|
||||
#define Z_STOP_PIN 10
|
||||
|
||||
#else
|
||||
|
||||
#define X_STOP_PIN X_DIAG_PIN
|
||||
#define Y_STOP_PIN Y_DIAG_PIN
|
||||
|
||||
#if ENABLED(BLTOUCH)
|
||||
#define Z_STOP_PIN 11 // Y-MIN
|
||||
#define SERVO0_PIN 10 // Z-MIN
|
||||
#else
|
||||
#define Z_STOP_PIN 10
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
//
|
||||
// Z Probe (when not Z_MIN_PIN)
|
||||
//
|
||||
#ifndef Z_MIN_PROBE_PIN
|
||||
#define Z_MIN_PROBE_PIN 10
|
||||
#endif
|
||||
|
||||
//
|
||||
// Steppers
|
||||
//
|
||||
#define X_STEP_PIN 37
|
||||
#define X_DIR_PIN 49
|
||||
#define X_ENABLE_PIN 29
|
||||
#define X_CS_PIN 41
|
||||
|
||||
#define Y_STEP_PIN 36
|
||||
#define Y_DIR_PIN 48
|
||||
#define Y_ENABLE_PIN 28
|
||||
#define Y_CS_PIN 39
|
||||
|
||||
#define Z_STEP_PIN 35
|
||||
#define Z_DIR_PIN 47
|
||||
#define Z_ENABLE_PIN 27
|
||||
#define Z_CS_PIN 67
|
||||
|
||||
#define E0_STEP_PIN 34
|
||||
#define E0_DIR_PIN 43
|
||||
#define E0_ENABLE_PIN 26
|
||||
#define E0_CS_PIN 66
|
||||
|
||||
//
|
||||
// Temperature Sensors
|
||||
//
|
||||
#define TEMP_0_PIN 0 // Analog Input
|
||||
#define TEMP_1_PIN 1 // Analog Input
|
||||
#define TEMP_BED_PIN 2 // Analog Input
|
||||
|
||||
//
|
||||
// Heaters / Fans
|
||||
//
|
||||
#define HEATER_0_PIN 3
|
||||
#define HEATER_BED_PIN 4
|
||||
|
||||
#ifndef FAN_PIN
|
||||
#define FAN_PIN 8
|
||||
#endif
|
||||
|
||||
#ifndef FAN1_PIN
|
||||
#define FAN1_PIN 6
|
||||
#endif
|
||||
|
||||
//
|
||||
// Misc. Functions
|
||||
//
|
||||
#define SDSS 77
|
||||
#define LED_PIN 13
|
||||
#define CASE_LIGHT_PIN 9
|
||||
|
||||
//
|
||||
// M3/M4/M5 - Spindle/Laser Control
|
||||
//
|
||||
// use P1 connector for spindle pins
|
||||
#define SPINDLE_LASER_PWM_PIN 9 // MUST BE HARDWARE PWM
|
||||
#define SPINDLE_LASER_ENABLE_PIN 18 // Pin should have a pullup!
|
||||
#define SPINDLE_DIR_PIN 19
|
||||
|
||||
//
|
||||
// Průša i3 MK2 Multiplexer Support
|
||||
//
|
||||
#define E_MUX0_PIN 17
|
||||
#define E_MUX1_PIN 16
|
||||
#define E_MUX2_PIN 78 // 84 in MK2 Firmware, with BEEPER as 78
|
||||
|
||||
//
|
||||
// LCD / Controller
|
||||
//
|
||||
#if ENABLED(ULTRA_LCD)
|
||||
|
||||
#define KILL_PIN 32
|
||||
|
||||
#if ENABLED(NEWPANEL)
|
||||
|
||||
#if ENABLED(CR10_STOCKDISPLAY)
|
||||
#define LCD_PINS_RS 85
|
||||
#define LCD_PINS_ENABLE 71
|
||||
#define LCD_PINS_D4 70
|
||||
#define BTN_EN1 61
|
||||
#define BTN_EN2 59
|
||||
#else
|
||||
#define LCD_PINS_RS 82
|
||||
#define LCD_PINS_ENABLE 61
|
||||
#define LCD_PINS_D4 59
|
||||
#define LCD_PINS_D5 70
|
||||
#define LCD_PINS_D6 85
|
||||
#define LCD_PINS_D7 71
|
||||
#define BTN_EN1 14
|
||||
#define BTN_EN2 72
|
||||
#endif
|
||||
|
||||
#define BTN_ENC 9 // AUX-2
|
||||
#define BEEPER_PIN 84 // AUX-4
|
||||
#define SD_DETECT_PIN 15
|
||||
|
||||
#endif // NEWPANEL
|
||||
#endif // ULTRA_LCD
|
|
@ -1,193 +0,0 @@
|
|||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Einsy-Retro pin assignments
|
||||
*/
|
||||
|
||||
#ifndef __AVR_ATmega2560__
|
||||
#error "Oops! Make sure you have 'Arduino Mega 2560 or Rambo' selected from the 'Tools -> Boards' menu."
|
||||
#endif
|
||||
|
||||
#define BOARD_NAME "Einsy Retro"
|
||||
|
||||
//
|
||||
// TMC2130 Configuration_adv defaults for EinsyRetro
|
||||
//
|
||||
#if !AXIS_DRIVER_TYPE(X, TMC2130) || !AXIS_DRIVER_TYPE(Y, TMC2130) || !AXIS_DRIVER_TYPE(Z, TMC2130) || !AXIS_DRIVER_TYPE(E0, TMC2130)
|
||||
#error "You must set ([XYZ]|E0)_DRIVER_TYPE to TMC2130 in Configuration.h for EinsyRetro."
|
||||
#endif
|
||||
|
||||
// TMC2130 Diag Pins (currently just for reference)
|
||||
#define X_DIAG_PIN 64
|
||||
#define Y_DIAG_PIN 69
|
||||
#define Z_DIAG_PIN 68
|
||||
#define E0_DIAG_PIN 65
|
||||
|
||||
//
|
||||
// Limit Switches
|
||||
//
|
||||
// Only use Diag Pins when SENSORLESS_HOMING is enabled for the TMC2130 drivers.
|
||||
// Otherwise use a physical endstop based configuration.
|
||||
//
|
||||
// SERVO0_PIN and Z_MIN_PIN configuration for BLTOUCH sensor when combined with SENSORLESS_HOMING.
|
||||
//
|
||||
|
||||
#if DISABLED(SENSORLESS_HOMING)
|
||||
|
||||
#define X_MIN_PIN 12
|
||||
#define Y_MIN_PIN 11
|
||||
#define Z_MIN_PIN 10
|
||||
#define X_MAX_PIN 81
|
||||
#define Y_MAX_PIN 57
|
||||
|
||||
#else
|
||||
|
||||
#if X_HOME_DIR == -1
|
||||
#define X_MIN_PIN X_DIAG_PIN
|
||||
#define X_MAX_PIN 81
|
||||
#else
|
||||
#define X_MIN_PIN 12
|
||||
#define X_MAX_PIN X_DIAG_PIN
|
||||
#endif
|
||||
|
||||
#if Y_HOME_DIR == -1
|
||||
#define Y_MIN_PIN Y_DIAG_PIN
|
||||
#define Y_MAX_PIN 57
|
||||
#else
|
||||
#define Y_MIN_PIN 11
|
||||
#define Y_MAX_PIN Y_DIAG_PIN
|
||||
#endif
|
||||
|
||||
#if ENABLED(BLTOUCH)
|
||||
#define Z_MIN_PIN 11 // Y-MIN
|
||||
#define SERVO0_PIN 10 // Z-MIN
|
||||
#else
|
||||
#define Z_MIN_PIN 10
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#define Z_MAX_PIN 7
|
||||
|
||||
//
|
||||
// Z Probe (when not Z_MIN_PIN)
|
||||
//
|
||||
#ifndef Z_MIN_PROBE_PIN
|
||||
#define Z_MIN_PROBE_PIN 10
|
||||
#endif
|
||||
|
||||
//
|
||||
// Steppers
|
||||
//
|
||||
#define X_STEP_PIN 37
|
||||
#define X_DIR_PIN 49
|
||||
#define X_ENABLE_PIN 29
|
||||
#define X_CS_PIN 41
|
||||
|
||||
#define Y_STEP_PIN 36
|
||||
#define Y_DIR_PIN 48
|
||||
#define Y_ENABLE_PIN 28
|
||||
#define Y_CS_PIN 39
|
||||
|
||||
#define Z_STEP_PIN 35
|
||||
#define Z_DIR_PIN 47
|
||||
#define Z_ENABLE_PIN 27
|
||||
#define Z_CS_PIN 67
|
||||
|
||||
#define E0_STEP_PIN 34
|
||||
#define E0_DIR_PIN 43
|
||||
#define E0_ENABLE_PIN 26
|
||||
#define E0_CS_PIN 66
|
||||
|
||||
//
|
||||
// Temperature Sensors
|
||||
//
|
||||
#define TEMP_0_PIN 0 // Analog Input
|
||||
#define TEMP_1_PIN 1 // Analog Input
|
||||
#define TEMP_BED_PIN 2 // Analog Input
|
||||
|
||||
//
|
||||
// Heaters / Fans
|
||||
//
|
||||
#define HEATER_0_PIN 3
|
||||
#define HEATER_BED_PIN 4
|
||||
|
||||
#ifndef FAN_PIN
|
||||
#define FAN_PIN 8
|
||||
#endif
|
||||
#define FAN1_PIN 6
|
||||
|
||||
//
|
||||
// Misc. Functions
|
||||
//
|
||||
#define SDSS 53
|
||||
#define LED_PIN 13
|
||||
#define CASE_LIGHT_PIN 9
|
||||
|
||||
//
|
||||
// M3/M4/M5 - Spindle/Laser Control
|
||||
//
|
||||
// use P1 connector for spindle pins
|
||||
#define SPINDLE_LASER_PWM_PIN 9 // MUST BE HARDWARE PWM
|
||||
#define SPINDLE_LASER_ENABLE_PIN 18 // Pin should have a pullup!
|
||||
#define SPINDLE_DIR_PIN 19
|
||||
|
||||
//
|
||||
// Průša i3 MK2 Multiplexer Support
|
||||
//
|
||||
#define E_MUX0_PIN 17
|
||||
#define E_MUX1_PIN 16
|
||||
#define E_MUX2_PIN 78 // 84 in MK2 Firmware, with BEEPER as 78
|
||||
|
||||
//
|
||||
// LCD / Controller
|
||||
//
|
||||
#if ENABLED(ULTRA_LCD)
|
||||
|
||||
#define KILL_PIN 32
|
||||
|
||||
#if ENABLED(NEWPANEL)
|
||||
|
||||
#if ENABLED(CR10_STOCKDISPLAY)
|
||||
#define LCD_PINS_RS 85
|
||||
#define LCD_PINS_ENABLE 71
|
||||
#define LCD_PINS_D4 70
|
||||
#define BTN_EN1 18
|
||||
#define BTN_EN2 19
|
||||
#else
|
||||
#define LCD_PINS_RS 82
|
||||
#define LCD_PINS_ENABLE 18
|
||||
#define LCD_PINS_D4 19
|
||||
#define LCD_PINS_D5 70
|
||||
#define LCD_PINS_D6 85
|
||||
#define LCD_PINS_D7 71
|
||||
#define BTN_EN1 14
|
||||
#define BTN_EN2 72
|
||||
#endif
|
||||
|
||||
#define BTN_ENC 9 // AUX-2
|
||||
#define BEEPER_PIN 84 // AUX-4
|
||||
#define SD_DETECT_PIN 15
|
||||
|
||||
#endif // NEWPANEL
|
||||
#endif // ULTRA_LCD
|
|
@ -1,54 +0,0 @@
|
|||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Melzi (Malyan M150) pin assignments
|
||||
*/
|
||||
|
||||
#define BOARD_NAME "Melzi (Malyan)"
|
||||
#include "pins_MELZI.h"
|
||||
|
||||
#undef LCD_SDSS
|
||||
#undef LCD_PINS_RS
|
||||
#undef LCD_PINS_ENABLE
|
||||
#undef LCD_PINS_D4
|
||||
#undef BTN_EN1
|
||||
#undef BTN_EN2
|
||||
#undef BTN_ENC
|
||||
|
||||
#define LCD_PINS_RS 17 // ST9720 CS
|
||||
#define LCD_PINS_ENABLE 16 // ST9720 DAT
|
||||
#define LCD_PINS_D4 11 // ST9720 CLK
|
||||
#define BTN_EN1 30
|
||||
#define BTN_EN2 29
|
||||
#define BTN_ENC 28
|
||||
|
||||
// Alter timing for graphical display
|
||||
#ifndef ST7920_DELAY_1
|
||||
#define ST7920_DELAY_1 DELAY_NS(125)
|
||||
#endif
|
||||
#ifndef ST7920_DELAY_2
|
||||
#define ST7920_DELAY_2 DELAY_NS(125)
|
||||
#endif
|
||||
#ifndef ST7920_DELAY_3
|
||||
#define ST7920_DELAY_3 DELAY_NS(125)
|
||||
#endif
|
|
@ -1,61 +0,0 @@
|
|||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Melzi pin assignments
|
||||
*/
|
||||
|
||||
#define BOARD_NAME "Melzi (Tronxy)"
|
||||
#include "pins_MELZI.h"
|
||||
|
||||
#undef Z_ENABLE_PIN
|
||||
#undef LCD_PINS_RS
|
||||
#undef LCD_PINS_ENABLE
|
||||
#undef LCD_PINS_D4
|
||||
#undef LCD_PINS_D5
|
||||
#undef LCD_PINS_D6
|
||||
#undef LCD_PINS_D7
|
||||
#undef BTN_EN1
|
||||
#undef BTN_EN2
|
||||
#undef BTN_ENC
|
||||
#undef LCD_SDSS
|
||||
|
||||
#define Z_ENABLE_PIN 14
|
||||
#define LCD_PINS_RS 30
|
||||
#define LCD_PINS_ENABLE 28
|
||||
#define LCD_PINS_D4 16
|
||||
#define LCD_PINS_D5 17
|
||||
#define LCD_PINS_D6 27
|
||||
#define LCD_PINS_D7 29
|
||||
#define BTN_EN1 10
|
||||
#define BTN_EN2 11
|
||||
#define BTN_ENC 26
|
||||
|
||||
#ifndef ST7920_DELAY_1
|
||||
#define ST7920_DELAY_1 DELAY_NS(0)
|
||||
#endif
|
||||
#ifndef ST7920_DELAY_2
|
||||
#define ST7920_DELAY_2 DELAY_NS(125)
|
||||
#endif
|
||||
#ifndef ST7920_DELAY_3
|
||||
#define ST7920_DELAY_3 DELAY_NS(0)
|
||||
#endif
|
|
@ -1,41 +0,0 @@
|
|||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* MKS BASE v1.5 with A4982 stepper drivers and digital micro-stepping
|
||||
*/
|
||||
|
||||
#include "pins_MKS_BASE.h"
|
||||
|
||||
/**
|
||||
* Microstepping pins
|
||||
*/
|
||||
#define X_MS1_PIN 5 // Digital 3 / Pin 5 / PE3 / SERVO2_PIN
|
||||
#define X_MS2_PIN 6 // Digital 6 / Pin 14 / PH3 / SERVO1_PIN
|
||||
#define Y_MS1_PIN 59 // Analog 5 / Pin 92 / PF5
|
||||
#define Y_MS2_PIN 58 // Analog 4 / Pin 93 / PF4
|
||||
#define Z_MS1_PIN 22 // Digital 22 / Pin 78 / PA0
|
||||
#define Z_MS2_PIN 39 // Digital 39 / Pin 70 / PG2
|
||||
#define E0_MS1_PIN 63 // Analog 9 / Pin 86 / PK1
|
||||
#define E0_MS2_PIN 64 // Analog 10 / Pin 87 / PK2
|
||||
#define E1_MS1_PIN 57 // Analog 3 / Pin 93 / PF3
|
||||
#define E1_MS2_PIN 4 // Digital 4 / Pin 1 / PG5 / SERVO3_PIN
|
|
@ -1,35 +0,0 @@
|
|||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* MKS BASE with Heroic HR4982 stepper drivers
|
||||
*/
|
||||
|
||||
#include "pins_MKS_BASE_15.h"
|
||||
|
||||
/**
|
||||
* Some new boards use HR4982 (Heroic) instead of the A4982 (Allegro) stepper drivers.
|
||||
* Most the functionality is similar, the HR variant obviously doesn't work with diode
|
||||
* smoothers (no fast decay). And the Heroic has a 128 µStepping mode where the A4982
|
||||
* is doing quarter steps (MS1=0, MS2=1).
|
||||
*/
|
||||
#define HEROIC_STEPPER_DRIVERS
|
|
@ -1,144 +0,0 @@
|
|||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Arduino Mega with RAMPS v1.4 adjusted pin assignments
|
||||
*
|
||||
* MKS GEN v1.3 (Extruder, Fan, Bed)
|
||||
* MKS GEN v1.3 (Extruder, Extruder, Fan, Bed)
|
||||
* MKS GEN v1.4 (Extruder, Fan, Bed)
|
||||
* MKS GEN v1.4 (Extruder, Extruder, Fan, Bed)
|
||||
*/
|
||||
|
||||
#if HOTENDS > 2 || E_STEPPERS > 2
|
||||
#error "MKS GEN 1.3/1.4 supports up to 2 hotends / E-steppers. Comment out this line to continue."
|
||||
#endif
|
||||
|
||||
#define BOARD_NAME "MKS GEN >= v1.3"
|
||||
|
||||
//
|
||||
// Heaters / Fans
|
||||
//
|
||||
// Power outputs EFBF or EFBE
|
||||
#define MOSFET_D_PIN 7
|
||||
|
||||
//
|
||||
// PSU / SERVO
|
||||
//
|
||||
// If POWER_SUPPLY is specified, always hijack Servo 3
|
||||
//
|
||||
#if POWER_SUPPLY > 0
|
||||
#define SERVO3_PIN -1
|
||||
#define PS_ON_PIN 4
|
||||
#endif
|
||||
|
||||
#include "pins_RAMPS.h"
|
||||
|
||||
//
|
||||
// LCD / Controller
|
||||
//
|
||||
#if ENABLED(VIKI2) || ENABLED(miniVIKI)
|
||||
/**
|
||||
* VIKI2 Has two groups of wires with...
|
||||
*
|
||||
* +Vin + Input supply, requires 120ma for LCD and mSD card
|
||||
* GND Ground Pin
|
||||
* MOSI Data input for LCD and SD
|
||||
* MISO Data output for SD
|
||||
* SCK Clock for LCD and SD
|
||||
* AO Reg. Sel for LCD
|
||||
* LCS Chip Select for LCD
|
||||
* SDCS Chip Select for SD
|
||||
* SDCD Card Detect pin for SD
|
||||
* ENCA Encoder output A
|
||||
* ENCB Encoder output B
|
||||
* ENCBTN Encoder button switch
|
||||
*
|
||||
* BTN Panel mounted button switch
|
||||
* BUZZER Piezo buzzer
|
||||
* BLUE-LED Blue LED ring pin (3 to 5v, mosfet buffered)
|
||||
* RED-LED Red LED ring pin (3 to 5v, mosfet buffered)
|
||||
*
|
||||
* This configuration uses the following arrangement:
|
||||
*
|
||||
* EXP1 D37 = EN2 D35 = EN1 EXP2 D50 = MISO D52 = SCK
|
||||
* D17 = BLUE D16 = RED D31 = ENC D53 = SDCS
|
||||
* D23 = KILL D25 = BUZZ D33 = --- D51 = MOSI
|
||||
* D27 = A0 D29 = LCS D49 = SDCD RST = ---
|
||||
* GND = GND 5V = 5V GND = --- D41 = ---
|
||||
*/
|
||||
|
||||
#undef BTN_EN1
|
||||
#undef BTN_EN2
|
||||
#undef BTN_ENC
|
||||
#undef DOGLCD_A0
|
||||
#undef DOGLCD_CS
|
||||
#undef SD_DETECT_PIN
|
||||
#undef BEEPER_PIN
|
||||
#undef KILL_PIN
|
||||
|
||||
//
|
||||
// VIKI2 12-wire lead
|
||||
//
|
||||
|
||||
// orange/white SDCD
|
||||
#define SD_DETECT_PIN 49
|
||||
|
||||
// white ENCA
|
||||
#define BTN_EN1 35
|
||||
|
||||
// green ENCB
|
||||
#define BTN_EN2 37
|
||||
|
||||
// purple ENCBTN
|
||||
#define BTN_ENC 31
|
||||
|
||||
// brown A0
|
||||
#define DOGLCD_A0 27
|
||||
|
||||
// green/white LCS
|
||||
#define DOGLCD_CS 29
|
||||
|
||||
// 50 gray MISO
|
||||
// 51 yellow MOSI
|
||||
// 52 orange SCK
|
||||
|
||||
// blue SDCS
|
||||
//#define SDSS 53
|
||||
|
||||
//
|
||||
// VIKI2 4-wire lead
|
||||
//
|
||||
|
||||
// blue BTN
|
||||
#define KILL_PIN 23
|
||||
|
||||
// green BUZZER
|
||||
#define BEEPER_PIN 25
|
||||
|
||||
// yellow RED-LED
|
||||
#define STAT_LED_RED_PIN 16
|
||||
|
||||
// white BLUE-LED
|
||||
#define STAT_LED_BLUE_PIN 17
|
||||
|
||||
#endif
|
|
@ -1,29 +0,0 @@
|
|||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#if HOTENDS > 1 || E_STEPPERS > 1
|
||||
#error "Ender-4 supports only 1 hotend / E-stepper. Comment out this line to continue."
|
||||
#endif
|
||||
|
||||
#define BOARD_NAME "Ender-4"
|
||||
|
||||
#include "pins_RAMPS.h"
|
|
@ -1,41 +0,0 @@
|
|||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Arduino Mega with RAMPS v1.3 for Anycubic
|
||||
*/
|
||||
|
||||
#ifndef BOARD_NAME
|
||||
#define BOARD_NAME "Anycubic RAMPS 1.3"
|
||||
#endif
|
||||
|
||||
#define IS_RAMPS_EFB
|
||||
#define RAMPS_D9_PIN 44
|
||||
#define FAN2_PIN 9
|
||||
#define ORIG_E0_AUTO_FAN_PIN 9
|
||||
|
||||
#include "pins_RAMPS_13.h"
|
||||
|
||||
#undef E1_STEP_PIN
|
||||
#undef E1_DIR_PIN
|
||||
#undef E1_ENABLE_PIN
|
||||
#undef E1_CS_PIN
|
|
@ -1,232 +0,0 @@
|
|||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Arduino Mega with RAMPS v1.4 for Anycubic
|
||||
*/
|
||||
|
||||
#ifndef BOARD_NAME
|
||||
#define BOARD_NAME "Anycubic RAMPS 1.4"
|
||||
#endif
|
||||
|
||||
#define LARGE_FLASH true
|
||||
|
||||
// Misc PINs
|
||||
#define BUZZER 31
|
||||
#define SDPOWER -1
|
||||
#define SDSS 53
|
||||
#define LED_PIN 13
|
||||
#define Z_MIN_PROBE_PIN 2
|
||||
#define FIL_RUNOUT_PIN 19
|
||||
|
||||
#ifdef OutageTest
|
||||
#define OUTAGETEST_PIN 79
|
||||
#define OUTAGECON_PIN 58
|
||||
#endif
|
||||
|
||||
// Steppers
|
||||
#define X_STEP_PIN 54
|
||||
#define X_DIR_PIN 55
|
||||
#define X_ENABLE_PIN 38
|
||||
|
||||
#define Y_STEP_PIN 60
|
||||
#define Y_DIR_PIN 61
|
||||
#define Y_ENABLE_PIN 56
|
||||
|
||||
#define Y2_STEP_PIN 36
|
||||
#define Y2_DIR_PIN 34
|
||||
#define Y2_ENABLE_PIN 30
|
||||
|
||||
#define Z_STEP_PIN 46
|
||||
#define Z_DIR_PIN 48
|
||||
#define Z_ENABLE_PIN 62
|
||||
|
||||
#define Z2_STEP_PIN 36
|
||||
#define Z2_DIR_PIN 34
|
||||
#define Z2_ENABLE_PIN 30
|
||||
|
||||
#define E0_STEP_PIN 26
|
||||
#define E0_DIR_PIN 28
|
||||
#define E0_ENABLE_PIN 24
|
||||
|
||||
// EndStops
|
||||
#define X_MIN_PIN 3
|
||||
#define Y_MIN_PIN 42
|
||||
#define Z_MIN_PIN 18
|
||||
|
||||
#define X_MAX_PIN 43
|
||||
#define Y_MAX_PIN -1
|
||||
#define Z_MAX_PIN -1
|
||||
|
||||
// Fans
|
||||
#define FAN_PIN 9
|
||||
#define FAN2_PIN 44
|
||||
#define ORIG_E0_AUTO_FAN_PIN 44
|
||||
#define CONTROLLER_FAN_PIN 7
|
||||
|
||||
// Heaters
|
||||
#define HEATER_0_PIN 10
|
||||
#define HEATER_1_PIN 45
|
||||
#define HEATER_BED_PIN 8
|
||||
|
||||
// Temperatursensoren
|
||||
#define TEMP_0_PIN 13
|
||||
#define TEMP_1_PIN 15
|
||||
#define TEMP_2_PIN 12
|
||||
#define TEMP_BED_PIN 14
|
||||
|
||||
// Servos
|
||||
#ifdef NUM_SERVOS
|
||||
#define SERVO0_PIN 11
|
||||
|
||||
#if NUM_SERVOS > 1
|
||||
#define SERVO1_PIN 6
|
||||
#endif
|
||||
|
||||
#if NUM_SERVOS > 2
|
||||
#define SERVO2_PIN 5
|
||||
#endif
|
||||
|
||||
#if NUM_SERVOS > 3
|
||||
#define SERVO3_PIN 4
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(ANYCUBIC_TFT_MODEL)
|
||||
#define BEEPER_PIN 31
|
||||
#define SD_DETECT_PIN 49
|
||||
#endif
|
||||
|
||||
// LCD
|
||||
#if defined(REPRAP_DISCOUNT_SMART_CONTROLLER) || defined(G3D_PANEL) || defined(ANYCUBIC_TFT_MODEL)
|
||||
#define KILL_PIN 41
|
||||
#else
|
||||
#define KILL_PIN -1
|
||||
#endif
|
||||
|
||||
#ifdef ULTRA_LCD
|
||||
#ifdef NEWPANEL
|
||||
#define LCD_PINS_RS 16
|
||||
#define LCD_PINS_ENABLE 17
|
||||
#define LCD_PINS_D4 23
|
||||
#define LCD_PINS_D5 25
|
||||
#define LCD_PINS_D6 27
|
||||
#define LCD_PINS_D7 29
|
||||
|
||||
#ifdef REPRAP_DISCOUNT_SMART_CONTROLLER
|
||||
#define BEEPER_PIN 37
|
||||
|
||||
#define BTN_EN1 31
|
||||
#define BTN_EN2 33
|
||||
#define BTN_ENC 35
|
||||
|
||||
#define SD_DETECT_PIN 49
|
||||
#elif defined(LCD_I2C_PANELOLU2)
|
||||
#define BTN_EN1 47 //reverse if the encoder turns the wrong way.
|
||||
#define BTN_EN2 43
|
||||
#define BTN_ENC 32
|
||||
#define SDSS 53
|
||||
#define SD_DETECT_PIN -1
|
||||
#define KILL_PIN 41
|
||||
#elif defined(LCD_I2C_VIKI)
|
||||
#define BTN_EN1 22 //reverse if the encoder turns the wrong way.
|
||||
#define BTN_EN2 7
|
||||
#define BTN_ENC -1
|
||||
#define SDSS 53
|
||||
#define SD_DETECT_PIN 49
|
||||
#elif defined(FULL_GRAPHIC_SMALL_PANEL)
|
||||
#define BEEPER_PIN 37
|
||||
|
||||
// Pins for DOGM SPI LCD Support
|
||||
#define DOGLCD_A0 23
|
||||
#define DOGLCD_CS 27
|
||||
#define LCD_PIN_BL 25 // backlight LED on PA3
|
||||
|
||||
#define KILL_PIN 41
|
||||
// GLCD features
|
||||
//#define LCD_CONTRAST 190
|
||||
// Uncomment screen orientation
|
||||
// #define LCD_SCREEN_ROT_90
|
||||
// #define LCD_SCREEN_ROT_180
|
||||
// #define LCD_SCREEN_ROT_270
|
||||
//The encoder and click button
|
||||
#define BTN_EN1 33
|
||||
#define BTN_EN2 -1
|
||||
#define BTN_ENC 35 //the click switch
|
||||
//not connected to a pin
|
||||
#define SD_DETECT_PIN 49
|
||||
#elif defined(MULTIPANEL)
|
||||
// #define BEEPER_PIN 37
|
||||
// Pins for DOGM SPI LCD Support
|
||||
#define DOGLCD_A0 17
|
||||
#define DOGLCD_CS 16
|
||||
#define LCD_PIN_BL 23 // backlight LED on A11/D65
|
||||
#define SDSS 53
|
||||
|
||||
#define KILL_PIN 64
|
||||
// GLCD features
|
||||
//#define LCD_CONTRAST 190
|
||||
// Uncomment screen orientation
|
||||
// #define LCD_SCREEN_ROT_90
|
||||
// #define LCD_SCREEN_ROT_180
|
||||
// #define LCD_SCREEN_ROT_270
|
||||
//The encoder and click button
|
||||
#define BTN_EN1 -1
|
||||
#define BTN_EN2 33
|
||||
#define BTN_ENC 35 //the click switch
|
||||
//not connected to a pin
|
||||
#define SD_DETECT_PIN 49
|
||||
#else
|
||||
//arduino pin which triggers an piezzo beeper
|
||||
#define BEEPER_PIN 31 // Beeper on AUX-4
|
||||
|
||||
//buttons are directly attached using AUX-2
|
||||
#ifdef REPRAPWORLD_KEYPAD
|
||||
#define BTN_EN1 64 // encoder
|
||||
#define BTN_EN2 59 // encoder
|
||||
#define BTN_ENC 63 // enter button
|
||||
#define SHIFT_OUT 40 // shift register
|
||||
#define SHIFT_CLK 44 // shift register
|
||||
#define SHIFT_LD 42 // shift register
|
||||
#else
|
||||
#define BTN_EN1 37
|
||||
#define BTN_EN2 35
|
||||
#define BTN_ENC -1 //the click
|
||||
#endif
|
||||
|
||||
#ifdef G3D_PANEL
|
||||
#define SD_DETECT_PIN 49
|
||||
#else
|
||||
#define SD_DETECT_PIN -1 // Ramps does not use this port
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#define LCD_PINS_RS 16
|
||||
#define LCD_PINS_ENABLE 17
|
||||
#define LCD_PINS_D4 23
|
||||
#define LCD_PINS_D5 25
|
||||
#define LCD_PINS_D6 27
|
||||
#define LCD_PINS_D7 29
|
||||
|
||||
#endif
|
||||
#endif
|
117
Marlin/power.cpp
|
@ -1,117 +0,0 @@
|
|||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* power.cpp - power control
|
||||
*/
|
||||
|
||||
#include "MarlinConfig.h"
|
||||
|
||||
#if ENABLED(AUTO_POWER_CONTROL)
|
||||
|
||||
#include "power.h"
|
||||
#include "temperature.h"
|
||||
#include "stepper_indirection.h"
|
||||
|
||||
Power powerManager;
|
||||
|
||||
millis_t Power::lastPowerOn;
|
||||
|
||||
bool Power::is_power_needed() {
|
||||
#if ENABLED(AUTO_POWER_FANS)
|
||||
for (uint8_t i = 0; i < FAN_COUNT; i++) if (fanSpeeds[i] > 0) return true;
|
||||
#endif
|
||||
|
||||
#if ENABLED(AUTO_POWER_E_FANS)
|
||||
HOTEND_LOOP() if (thermalManager.autofan_speed[e] > 0) return true;
|
||||
#endif
|
||||
|
||||
#if ENABLED(AUTO_POWER_CONTROLLERFAN) && HAS_CONTROLLER_FAN && ENABLED(USE_CONTROLLER_FAN)
|
||||
if (controllerFanSpeed > 0) return true;
|
||||
#endif
|
||||
|
||||
// If any of the drivers or the bed are enabled...
|
||||
if (X_ENABLE_READ == X_ENABLE_ON || Y_ENABLE_READ == Y_ENABLE_ON || Z_ENABLE_READ == Z_ENABLE_ON
|
||||
#if HAS_HEATED_BED
|
||||
|| thermalManager.soft_pwm_amount_bed > 0
|
||||
#endif
|
||||
#if HAS_X2_ENABLE
|
||||
|| X2_ENABLE_READ == X_ENABLE_ON
|
||||
#endif
|
||||
#if HAS_Y2_ENABLE
|
||||
|| Y2_ENABLE_READ == Y_ENABLE_ON
|
||||
#endif
|
||||
#if HAS_Z2_ENABLE
|
||||
|| Z2_ENABLE_READ == Z_ENABLE_ON
|
||||
#endif
|
||||
|| E0_ENABLE_READ == E_ENABLE_ON
|
||||
#if E_STEPPERS > 1
|
||||
|| E1_ENABLE_READ == E_ENABLE_ON
|
||||
#if E_STEPPERS > 2
|
||||
|| E2_ENABLE_READ == E_ENABLE_ON
|
||||
#if E_STEPPERS > 3
|
||||
|| E3_ENABLE_READ == E_ENABLE_ON
|
||||
#if E_STEPPERS > 4
|
||||
|| E4_ENABLE_READ == E_ENABLE_ON
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
) return true;
|
||||
|
||||
HOTEND_LOOP() if (thermalManager.degTargetHotend(e) > 0) return true;
|
||||
#if HAS_HEATED_BED
|
||||
if (thermalManager.degTargetBed() > 0) return true;
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void Power::check() {
|
||||
static millis_t nextPowerCheck = 0;
|
||||
millis_t ms = millis();
|
||||
if (ELAPSED(ms, nextPowerCheck)) {
|
||||
nextPowerCheck = ms + 2500UL;
|
||||
if (is_power_needed())
|
||||
power_on();
|
||||
else if (!lastPowerOn || ELAPSED(ms, lastPowerOn + (POWER_TIMEOUT) * 1000UL))
|
||||
power_off();
|
||||
}
|
||||
}
|
||||
|
||||
void Power::power_on() {
|
||||
lastPowerOn = millis();
|
||||
if (!powersupply_on) {
|
||||
PSU_PIN_ON();
|
||||
|
||||
#if HAS_TRINAMIC
|
||||
delay(100); // Wait for power to settle
|
||||
restore_stepper_drivers();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void Power::power_off() {
|
||||
if (powersupply_on) PSU_PIN_OFF();
|
||||
}
|
||||
|
||||
#endif // AUTO_POWER_CONTROL
|
|
@ -1,44 +0,0 @@
|
|||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* power.h - power control
|
||||
*/
|
||||
|
||||
#ifndef POWER_H
|
||||
#define POWER_H
|
||||
|
||||
#include "types.h"
|
||||
|
||||
class Power {
|
||||
public:
|
||||
static void check();
|
||||
static void power_on();
|
||||
static void power_off();
|
||||
private:
|
||||
static millis_t lastPowerOn;
|
||||
static bool is_power_needed();
|
||||
};
|
||||
|
||||
extern Power powerManager;
|
||||
|
||||
#endif // POWER_H
|
|
@ -1,284 +0,0 @@
|
|||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* power_loss_recovery.cpp - Resume an SD print after power-loss
|
||||
*/
|
||||
|
||||
#include "MarlinConfig.h"
|
||||
|
||||
#if ENABLED(POWER_LOSS_RECOVERY)
|
||||
|
||||
#include "power_loss_recovery.h"
|
||||
|
||||
#include "cardreader.h"
|
||||
#include "planner.h"
|
||||
#include "printcounter.h"
|
||||
#include "serial.h"
|
||||
#include "temperature.h"
|
||||
#include "ultralcd.h"
|
||||
|
||||
// Recovery data
|
||||
job_recovery_info_t job_recovery_info;
|
||||
JobRecoveryPhase job_recovery_phase = JOB_RECOVERY_IDLE;
|
||||
uint8_t job_recovery_commands_count; //=0
|
||||
char job_recovery_commands[BUFSIZE + APPEND_CMD_COUNT][MAX_CMD_SIZE];
|
||||
// Extern
|
||||
extern uint8_t active_extruder, commands_in_queue, cmd_queue_index_r;
|
||||
|
||||
#if ENABLED(DEBUG_POWER_LOSS_RECOVERY)
|
||||
void debug_print_job_recovery(const bool recovery) {
|
||||
SERIAL_PROTOCOLLNPGM("---- Job Recovery Info ----");
|
||||
SERIAL_PROTOCOLPAIR("valid_head:", int(job_recovery_info.valid_head));
|
||||
SERIAL_PROTOCOLLNPAIR(" valid_foot:", int(job_recovery_info.valid_foot));
|
||||
if (job_recovery_info.valid_head) {
|
||||
if (job_recovery_info.valid_head == job_recovery_info.valid_foot) {
|
||||
SERIAL_PROTOCOLPGM("current_position: ");
|
||||
LOOP_XYZE(i) {
|
||||
SERIAL_PROTOCOL(job_recovery_info.current_position[i]);
|
||||
if (i < E_AXIS) SERIAL_CHAR(',');
|
||||
}
|
||||
SERIAL_EOL();
|
||||
SERIAL_PROTOCOLLNPAIR("feedrate: ", job_recovery_info.feedrate);
|
||||
|
||||
#if HOTENDS > 1
|
||||
SERIAL_PROTOCOLLNPAIR("active_hotend: ", int(job_recovery_info.active_hotend));
|
||||
#endif
|
||||
|
||||
SERIAL_PROTOCOLPGM("target_temperature: ");
|
||||
HOTEND_LOOP() {
|
||||
SERIAL_PROTOCOL(job_recovery_info.target_temperature[e]);
|
||||
if (e < HOTENDS - 1) SERIAL_CHAR(',');
|
||||
}
|
||||
SERIAL_EOL();
|
||||
|
||||
#if HAS_HEATED_BED
|
||||
SERIAL_PROTOCOLLNPAIR("target_temperature_bed: ", job_recovery_info.target_temperature_bed);
|
||||
#endif
|
||||
|
||||
#if FAN_COUNT
|
||||
SERIAL_PROTOCOLPGM("fanSpeeds: ");
|
||||
for (int8_t i = 0; i < FAN_COUNT; i++) {
|
||||
SERIAL_PROTOCOL(job_recovery_info.fanSpeeds[i]);
|
||||
if (i < FAN_COUNT - 1) SERIAL_CHAR(',');
|
||||
}
|
||||
SERIAL_EOL();
|
||||
#endif
|
||||
|
||||
#if HAS_LEVELING
|
||||
SERIAL_PROTOCOLPAIR("leveling: ", int(job_recovery_info.leveling));
|
||||
SERIAL_PROTOCOLLNPAIR(" fade: ", int(job_recovery_info.fade));
|
||||
#endif
|
||||
SERIAL_PROTOCOLLNPAIR("cmd_queue_index_r: ", int(job_recovery_info.cmd_queue_index_r));
|
||||
SERIAL_PROTOCOLLNPAIR("commands_in_queue: ", int(job_recovery_info.commands_in_queue));
|
||||
if (recovery)
|
||||
for (uint8_t i = 0; i < job_recovery_commands_count; i++) SERIAL_PROTOCOLLNPAIR("> ", job_recovery_commands[i]);
|
||||
else
|
||||
for (uint8_t i = 0; i < job_recovery_info.commands_in_queue; i++) SERIAL_PROTOCOLLNPAIR("> ", job_recovery_info.command_queue[i]);
|
||||
SERIAL_PROTOCOLLNPAIR("sd_filename: ", job_recovery_info.sd_filename);
|
||||
SERIAL_PROTOCOLLNPAIR("sdpos: ", job_recovery_info.sdpos);
|
||||
SERIAL_PROTOCOLLNPAIR("print_job_elapsed: ", job_recovery_info.print_job_elapsed);
|
||||
}
|
||||
else
|
||||
SERIAL_PROTOCOLLNPGM("INVALID DATA");
|
||||
}
|
||||
SERIAL_PROTOCOLLNPGM("---------------------------");
|
||||
}
|
||||
#endif // DEBUG_POWER_LOSS_RECOVERY
|
||||
|
||||
/**
|
||||
* Check for Print Job Recovery during setup()
|
||||
*
|
||||
* If a saved state exists, populate job_recovery_commands with
|
||||
* commands to restore the machine state and continue the file.
|
||||
*/
|
||||
void check_print_job_recovery() {
|
||||
memset(&job_recovery_info, 0, sizeof(job_recovery_info));
|
||||
ZERO(job_recovery_commands);
|
||||
|
||||
if (!card.cardOK) card.initsd();
|
||||
|
||||
if (card.cardOK) {
|
||||
|
||||
#if ENABLED(DEBUG_POWER_LOSS_RECOVERY)
|
||||
SERIAL_PROTOCOLLNPAIR("Init job recovery info. Size: ", int(sizeof(job_recovery_info)));
|
||||
#endif
|
||||
|
||||
if (card.jobRecoverFileExists()) {
|
||||
card.openJobRecoveryFile(true);
|
||||
card.loadJobRecoveryInfo();
|
||||
card.closeJobRecoveryFile();
|
||||
//card.removeJobRecoveryFile();
|
||||
|
||||
if (job_recovery_info.valid_head && job_recovery_info.valid_head == job_recovery_info.valid_foot) {
|
||||
|
||||
uint8_t ind = 0;
|
||||
|
||||
#if HAS_LEVELING
|
||||
strcpy_P(job_recovery_commands[ind++], PSTR("M420 S0 Z0")); // Leveling off before G92 or G28
|
||||
#endif
|
||||
|
||||
strcpy_P(job_recovery_commands[ind++], PSTR("G92.0 Z0")); // Ensure Z is equal to 0
|
||||
strcpy_P(job_recovery_commands[ind++], PSTR("G1 Z2")); // Raise Z by 2mm (we hope!)
|
||||
strcpy_P(job_recovery_commands[ind++], PSTR("G28 R0"
|
||||
#if ENABLED(MARLIN_DEV_MODE)
|
||||
" S"
|
||||
#elif !IS_KINEMATIC
|
||||
" X Y" // Home X and Y for Cartesian
|
||||
#endif
|
||||
));
|
||||
|
||||
char str_1[16], str_2[16];
|
||||
|
||||
#if HAS_LEVELING
|
||||
if (job_recovery_info.fade || job_recovery_info.leveling) {
|
||||
// Restore leveling state before G92 sets Z
|
||||
// This ensures the steppers correspond to the native Z
|
||||
dtostrf(job_recovery_info.fade, 1, 1, str_1);
|
||||
sprintf_P(job_recovery_commands[ind++], PSTR("M420 S%i Z%s"), int(job_recovery_info.leveling), str_1);
|
||||
}
|
||||
#endif
|
||||
|
||||
dtostrf(job_recovery_info.current_position[Z_AXIS] + 2, 1, 3, str_1);
|
||||
dtostrf(job_recovery_info.current_position[E_CART]
|
||||
#if ENABLED(SAVE_EACH_CMD_MODE)
|
||||
- 5
|
||||
#endif
|
||||
, 1, 3, str_2
|
||||
);
|
||||
sprintf_P(job_recovery_commands[ind++], PSTR("G92.0 Z%s E%s"), str_1, str_2); // Current Z + 2 and E
|
||||
|
||||
uint8_t r = job_recovery_info.cmd_queue_index_r, c = job_recovery_info.commands_in_queue;
|
||||
while (c--) {
|
||||
strcpy(job_recovery_commands[ind++], job_recovery_info.command_queue[r]);
|
||||
r = (r + 1) % BUFSIZE;
|
||||
}
|
||||
|
||||
if (job_recovery_info.sd_filename[0] == '/') job_recovery_info.sd_filename[0] = ' ';
|
||||
sprintf_P(job_recovery_commands[ind++], PSTR("M23 %s"), job_recovery_info.sd_filename);
|
||||
sprintf_P(job_recovery_commands[ind++], PSTR("M24 S%ld T%ld"), job_recovery_info.sdpos, job_recovery_info.print_job_elapsed);
|
||||
|
||||
job_recovery_commands_count = ind;
|
||||
|
||||
#if ENABLED(DEBUG_POWER_LOSS_RECOVERY)
|
||||
debug_print_job_recovery(true);
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
if (job_recovery_info.valid_head != job_recovery_info.valid_foot)
|
||||
LCD_ALERTMESSAGEPGM("INVALID DATA");
|
||||
memset(&job_recovery_info, 0, sizeof(job_recovery_info));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the current machine state to the power-loss recovery file
|
||||
*/
|
||||
void save_job_recovery_info() {
|
||||
#if SAVE_INFO_INTERVAL_MS > 0
|
||||
static millis_t next_save_ms; // = 0; // Init on reset
|
||||
millis_t ms = millis();
|
||||
#endif
|
||||
if (
|
||||
// Save on every command
|
||||
#if ENABLED(SAVE_EACH_CMD_MODE)
|
||||
true
|
||||
#else
|
||||
// Save if power loss pin is triggered
|
||||
#if PIN_EXISTS(POWER_LOSS)
|
||||
READ(POWER_LOSS_PIN) == POWER_LOSS_STATE ||
|
||||
#endif
|
||||
// Save if interval is elapsed
|
||||
#if SAVE_INFO_INTERVAL_MS > 0
|
||||
ELAPSED(ms, next_save_ms) ||
|
||||
#endif
|
||||
// Save on every new Z height
|
||||
(current_position[Z_AXIS] > 0 && current_position[Z_AXIS] > job_recovery_info.current_position[Z_AXIS])
|
||||
#endif
|
||||
) {
|
||||
#if SAVE_INFO_INTERVAL_MS > 0
|
||||
next_save_ms = ms + SAVE_INFO_INTERVAL_MS;
|
||||
#endif
|
||||
|
||||
// Head and foot will match if valid data was saved
|
||||
if (!++job_recovery_info.valid_head) ++job_recovery_info.valid_head; // non-zero in sequence
|
||||
job_recovery_info.valid_foot = job_recovery_info.valid_head;
|
||||
|
||||
// Machine state
|
||||
COPY(job_recovery_info.current_position, current_position);
|
||||
job_recovery_info.feedrate = feedrate_mm_s;
|
||||
|
||||
#if HOTENDS > 1
|
||||
job_recovery_info.active_hotend = active_extruder;
|
||||
#endif
|
||||
|
||||
COPY(job_recovery_info.target_temperature, thermalManager.target_temperature);
|
||||
|
||||
#if HAS_HEATED_BED
|
||||
job_recovery_info.target_temperature_bed = thermalManager.target_temperature_bed;
|
||||
#endif
|
||||
|
||||
#if FAN_COUNT
|
||||
COPY(job_recovery_info.fanSpeeds, fanSpeeds);
|
||||
#endif
|
||||
|
||||
#if HAS_LEVELING
|
||||
job_recovery_info.leveling = planner.leveling_active;
|
||||
job_recovery_info.fade = (
|
||||
#if ENABLED(ENABLE_LEVELING_FADE_HEIGHT)
|
||||
planner.z_fade_height
|
||||
#else
|
||||
0
|
||||
#endif
|
||||
);
|
||||
#endif
|
||||
|
||||
// Commands in the queue
|
||||
job_recovery_info.cmd_queue_index_r = cmd_queue_index_r;
|
||||
job_recovery_info.commands_in_queue = commands_in_queue;
|
||||
COPY(job_recovery_info.command_queue, command_queue);
|
||||
|
||||
// Elapsed print job time
|
||||
job_recovery_info.print_job_elapsed = print_job_timer.duration();
|
||||
|
||||
// SD file position
|
||||
card.getAbsFilename(job_recovery_info.sd_filename);
|
||||
job_recovery_info.sdpos = card.getIndex();
|
||||
|
||||
#if ENABLED(DEBUG_POWER_LOSS_RECOVERY)
|
||||
SERIAL_PROTOCOLLNPGM("Saving...");
|
||||
debug_print_job_recovery(false);
|
||||
#endif
|
||||
|
||||
card.openJobRecoveryFile(false);
|
||||
(void)card.saveJobRecoveryInfo();
|
||||
|
||||
// If power-loss pin was triggered, write just once then kill
|
||||
#if PIN_EXISTS(POWER_LOSS)
|
||||
if (READ(POWER_LOSS_PIN) == POWER_LOSS_STATE) kill(MSG_POWER_LOSS_RECOVERY);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#endif // POWER_LOSS_RECOVERY
|
|
@ -1,99 +0,0 @@
|
|||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* power_loss_recovery.h - Resume an SD print after power-loss
|
||||
*/
|
||||
|
||||
#ifndef _POWER_LOSS_RECOVERY_H_
|
||||
#define _POWER_LOSS_RECOVERY_H_
|
||||
|
||||
#include "cardreader.h"
|
||||
#include "types.h"
|
||||
#include "MarlinConfig.h"
|
||||
|
||||
#define SAVE_INFO_INTERVAL_MS 0
|
||||
//#define SAVE_EACH_CMD_MODE
|
||||
//#define DEBUG_POWER_LOSS_RECOVERY
|
||||
|
||||
typedef struct {
|
||||
uint8_t valid_head;
|
||||
|
||||
// Machine state
|
||||
float current_position[NUM_AXIS], feedrate;
|
||||
|
||||
#if HOTENDS > 1
|
||||
uint8_t active_hotend;
|
||||
#endif
|
||||
|
||||
int16_t target_temperature[HOTENDS];
|
||||
|
||||
#if HAS_HEATED_BED
|
||||
int16_t target_temperature_bed;
|
||||
#endif
|
||||
|
||||
#if FAN_COUNT
|
||||
int16_t fanSpeeds[FAN_COUNT];
|
||||
#endif
|
||||
|
||||
#if HAS_LEVELING
|
||||
bool leveling;
|
||||
float fade;
|
||||
#endif
|
||||
|
||||
// Command queue
|
||||
uint8_t cmd_queue_index_r, commands_in_queue;
|
||||
char command_queue[BUFSIZE][MAX_CMD_SIZE];
|
||||
|
||||
// SD Filename and position
|
||||
char sd_filename[MAXPATHNAMELENGTH];
|
||||
uint32_t sdpos;
|
||||
|
||||
// Job elapsed time
|
||||
millis_t print_job_elapsed;
|
||||
|
||||
uint8_t valid_foot;
|
||||
} job_recovery_info_t;
|
||||
|
||||
extern job_recovery_info_t job_recovery_info;
|
||||
|
||||
enum JobRecoveryPhase : unsigned char {
|
||||
JOB_RECOVERY_IDLE,
|
||||
JOB_RECOVERY_MAYBE,
|
||||
JOB_RECOVERY_YES,
|
||||
JOB_RECOVERY_DONE
|
||||
};
|
||||
extern JobRecoveryPhase job_recovery_phase;
|
||||
|
||||
#if HAS_LEVELING
|
||||
#define APPEND_CMD_COUNT 9
|
||||
#else
|
||||
#define APPEND_CMD_COUNT 7
|
||||
#endif
|
||||
|
||||
extern char job_recovery_commands[BUFSIZE + APPEND_CMD_COUNT][MAX_CMD_SIZE];
|
||||
extern uint8_t job_recovery_commands_count;
|
||||
|
||||
void check_print_job_recovery();
|
||||
void save_job_recovery_info();
|
||||
|
||||
#endif // _POWER_LOSS_RECOVERY_H_
|
|
@ -1,61 +0,0 @@
|
|||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* runout.cpp - Runout sensor support
|
||||
*/
|
||||
|
||||
#include "MarlinConfig.h"
|
||||
|
||||
#if ENABLED(FILAMENT_RUNOUT_SENSOR)
|
||||
|
||||
#include "runout.h"
|
||||
|
||||
FilamentRunoutSensor runout;
|
||||
|
||||
bool FilamentRunoutSensor::filament_ran_out; // = false
|
||||
uint8_t FilamentRunoutSensor::runout_count; // = 0
|
||||
|
||||
void FilamentRunoutSensor::setup() {
|
||||
|
||||
#if ENABLED(FIL_RUNOUT_PULLUP)
|
||||
#define INIT_RUNOUT_PIN(P) SET_INPUT_PULLUP(P)
|
||||
#else
|
||||
#define INIT_RUNOUT_PIN(P) SET_INPUT(P)
|
||||
#endif
|
||||
|
||||
INIT_RUNOUT_PIN(FIL_RUNOUT_PIN);
|
||||
#if NUM_RUNOUT_SENSORS > 1
|
||||
INIT_RUNOUT_PIN(FIL_RUNOUT2_PIN);
|
||||
#if NUM_RUNOUT_SENSORS > 2
|
||||
INIT_RUNOUT_PIN(FIL_RUNOUT3_PIN);
|
||||
#if NUM_RUNOUT_SENSORS > 3
|
||||
INIT_RUNOUT_PIN(FIL_RUNOUT4_PIN);
|
||||
#if NUM_RUNOUT_SENSORS > 4
|
||||
INIT_RUNOUT_PIN(FIL_RUNOUT5_PIN);
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif // FILAMENT_RUNOUT_SENSOR
|
|
@ -1,85 +0,0 @@
|
|||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* runout.h - Runout sensor support
|
||||
*/
|
||||
|
||||
#ifndef _RUNOUT_H_
|
||||
#define _RUNOUT_H_
|
||||
|
||||
#include "cardreader.h"
|
||||
#include "printcounter.h"
|
||||
#include "stepper.h"
|
||||
#include "Marlin.h"
|
||||
|
||||
#include "MarlinConfig.h"
|
||||
|
||||
#define FIL_RUNOUT_THRESHOLD 5
|
||||
|
||||
class FilamentRunoutSensor {
|
||||
public:
|
||||
FilamentRunoutSensor() {}
|
||||
|
||||
static void setup();
|
||||
|
||||
FORCE_INLINE static void reset() { runout_count = 0; filament_ran_out = false; }
|
||||
|
||||
FORCE_INLINE static void run() {
|
||||
if ((IS_SD_PRINTING() || print_job_timer.isRunning()) && check() && !filament_ran_out) {
|
||||
filament_ran_out = true;
|
||||
enqueue_and_echo_commands_P(PSTR(FILAMENT_RUNOUT_SCRIPT));
|
||||
planner.synchronize();
|
||||
}
|
||||
}
|
||||
private:
|
||||
static bool filament_ran_out;
|
||||
static uint8_t runout_count;
|
||||
|
||||
FORCE_INLINE static bool check() {
|
||||
#if NUM_RUNOUT_SENSORS < 2
|
||||
// A single sensor applying to all extruders
|
||||
const bool is_out = READ(FIL_RUNOUT_PIN) == FIL_RUNOUT_INVERTING;
|
||||
#else
|
||||
// Read the sensor for the active extruder
|
||||
bool is_out;
|
||||
switch (active_extruder) {
|
||||
case 0: is_out = READ(FIL_RUNOUT_PIN) == FIL_RUNOUT_INVERTING; break;
|
||||
case 1: is_out = READ(FIL_RUNOUT2_PIN) == FIL_RUNOUT_INVERTING; break;
|
||||
#if NUM_RUNOUT_SENSORS > 2
|
||||
case 2: is_out = READ(FIL_RUNOUT3_PIN) == FIL_RUNOUT_INVERTING; break;
|
||||
#if NUM_RUNOUT_SENSORS > 3
|
||||
case 3: is_out = READ(FIL_RUNOUT4_PIN) == FIL_RUNOUT_INVERTING; break;
|
||||
#if NUM_RUNOUT_SENSORS > 4
|
||||
case 4: is_out = READ(FIL_RUNOUT5_PIN) == FIL_RUNOUT_INVERTING; break;
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
return (is_out ? ++runout_count : (runout_count = 0)) > FIL_RUNOUT_THRESHOLD;
|
||||
}
|
||||
};
|
||||
|
||||
extern FilamentRunoutSensor runout;
|
||||
|
||||
#endif // _RUNOUT_H_
|
|
@ -1,493 +0,0 @@
|
|||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* status_screen_DOGM.h
|
||||
*
|
||||
* Standard Status Screen for Graphical Display
|
||||
*/
|
||||
|
||||
#ifndef _STATUS_SCREEN_DOGM_H_
|
||||
#define _STATUS_SCREEN_DOGM_H_
|
||||
|
||||
FORCE_INLINE void _draw_centered_temp(const int16_t temp, const uint8_t x, const uint8_t y) {
|
||||
const char * const str = itostr3(temp);
|
||||
u8g.setPrintPos(x - (str[0] != ' ' ? 0 : str[1] != ' ' ? 1 : 2) * DOG_CHAR_WIDTH / 2, y);
|
||||
lcd_print(str);
|
||||
lcd_printPGM(PSTR(LCD_STR_DEGREE " "));
|
||||
}
|
||||
|
||||
#ifndef HEAT_INDICATOR_X
|
||||
#define HEAT_INDICATOR_X 8
|
||||
#endif
|
||||
|
||||
FORCE_INLINE void _draw_heater_status(const uint8_t x, const int8_t heater, const bool blink) {
|
||||
#if !HEATER_IDLE_HANDLER
|
||||
UNUSED(blink);
|
||||
#endif
|
||||
|
||||
#if HAS_HEATED_BED
|
||||
const bool isBed = heater < 0;
|
||||
#else
|
||||
constexpr bool isBed = false;
|
||||
#endif
|
||||
|
||||
if (PAGE_UNDER(7)) {
|
||||
#if HEATER_IDLE_HANDLER
|
||||
const bool is_idle = (
|
||||
#if HAS_HEATED_BED
|
||||
isBed ? thermalManager.is_bed_idle() :
|
||||
#endif
|
||||
thermalManager.is_heater_idle(heater)
|
||||
);
|
||||
|
||||
if (blink || !is_idle)
|
||||
#endif
|
||||
_draw_centered_temp(0.5f + (
|
||||
#if HAS_HEATED_BED
|
||||
isBed ? thermalManager.degTargetBed() :
|
||||
#endif
|
||||
thermalManager.degTargetHotend(heater)
|
||||
), x, 7
|
||||
);
|
||||
}
|
||||
|
||||
if (PAGE_CONTAINS(21, 28)) {
|
||||
_draw_centered_temp(0.5f + (
|
||||
#if HAS_HEATED_BED
|
||||
isBed ? thermalManager.degBed() :
|
||||
#endif
|
||||
thermalManager.degHotend(heater)
|
||||
), x, 28
|
||||
);
|
||||
|
||||
if (PAGE_CONTAINS(17, 20)) {
|
||||
const uint8_t h = isBed ? 7 : HEAT_INDICATOR_X,
|
||||
y = isBed ? 18 : 17;
|
||||
if (
|
||||
#if HAS_HEATED_BED
|
||||
isBed ? thermalManager.isHeatingBed() :
|
||||
#endif
|
||||
thermalManager.isHeatingHotend(heater)
|
||||
) {
|
||||
u8g.setColorIndex(0); // white on black
|
||||
u8g.drawBox(x + h, y, 2, 2);
|
||||
u8g.setColorIndex(1); // black on white
|
||||
}
|
||||
else
|
||||
u8g.drawBox(x + h, y, 2, 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Before homing, blink '123' <-> '???'.
|
||||
// Homed but unknown... '123' <-> ' '.
|
||||
// Homed and known, display constantly.
|
||||
//
|
||||
FORCE_INLINE void _draw_axis_value(const AxisEnum axis, const char *value, const bool blink) {
|
||||
if (blink)
|
||||
lcd_print(value);
|
||||
else {
|
||||
if (!TEST(axis_homed, axis))
|
||||
while (const char c = *value++) lcd_print(c <= '.' ? c : '?');
|
||||
else {
|
||||
#if DISABLED(HOME_AFTER_DEACTIVATE) && DISABLED(DISABLE_REDUCED_ACCURACY_WARNING)
|
||||
if (!TEST(axis_known_position, axis))
|
||||
lcd_printPGM(axis == Z_AXIS ? PSTR(" ") : PSTR(" "));
|
||||
else
|
||||
#endif
|
||||
lcd_print(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline void lcd_implementation_status_message(const bool blink) {
|
||||
#if ENABLED(STATUS_MESSAGE_SCROLLING)
|
||||
static bool last_blink = false;
|
||||
|
||||
// Get the UTF8 character count of the string
|
||||
uint8_t slen = utf8_strlen(lcd_status_message);
|
||||
|
||||
// If the string fits into the LCD, just print it and do not scroll it
|
||||
if (slen <= LCD_WIDTH) {
|
||||
|
||||
// The string isn't scrolling and may not fill the screen
|
||||
lcd_print_utf(lcd_status_message);
|
||||
|
||||
// Fill the rest with spaces
|
||||
while (slen < LCD_WIDTH) {
|
||||
u8g.print(' ');
|
||||
++slen;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// String is larger than the available space in screen.
|
||||
|
||||
// Get a pointer to the next valid UTF8 character
|
||||
const char *stat = lcd_status_message + status_scroll_offset;
|
||||
|
||||
// Get the string remaining length
|
||||
const uint8_t rlen = utf8_strlen(stat);
|
||||
|
||||
// If we have enough characters to display
|
||||
if (rlen >= LCD_WIDTH) {
|
||||
// The remaining string fills the screen - Print it
|
||||
lcd_print_utf(stat, LCD_WIDTH);
|
||||
}
|
||||
else {
|
||||
// The remaining string does not completely fill the screen
|
||||
lcd_print_utf(stat, LCD_WIDTH); // The string leaves space
|
||||
uint8_t chars = LCD_WIDTH - rlen; // Amount of space left in characters
|
||||
|
||||
u8g.print('.'); // Always at 1+ spaces left, draw a dot
|
||||
if (--chars) { // Draw a second dot if there's space
|
||||
u8g.print('.');
|
||||
if (--chars) // Print a second copy of the message
|
||||
lcd_print_utf(lcd_status_message, LCD_WIDTH - (rlen + 2));
|
||||
}
|
||||
}
|
||||
if (last_blink != blink) {
|
||||
last_blink = blink;
|
||||
|
||||
// Adjust by complete UTF8 characters
|
||||
if (status_scroll_offset < slen) {
|
||||
status_scroll_offset++;
|
||||
while (!START_OF_UTF8_CHAR(lcd_status_message[status_scroll_offset]))
|
||||
status_scroll_offset++;
|
||||
}
|
||||
else
|
||||
status_scroll_offset = 0;
|
||||
}
|
||||
}
|
||||
#else
|
||||
UNUSED(blink);
|
||||
|
||||
// Get the UTF8 character count of the string
|
||||
uint8_t slen = utf8_strlen(lcd_status_message);
|
||||
|
||||
// Just print the string to the LCD
|
||||
lcd_print_utf(lcd_status_message, LCD_WIDTH);
|
||||
|
||||
// Fill the rest with spaces if there are missing spaces
|
||||
while (slen < LCD_WIDTH) {
|
||||
u8g.print(' ');
|
||||
++slen;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void lcd_implementation_status_screen() {
|
||||
|
||||
const bool blink = lcd_blink();
|
||||
|
||||
#if FAN_ANIM_FRAMES > 2
|
||||
static bool old_blink;
|
||||
static uint8_t fan_frame;
|
||||
if (old_blink != blink) {
|
||||
old_blink = blink;
|
||||
if (!fanSpeeds[0] || ++fan_frame >= FAN_ANIM_FRAMES) fan_frame = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Status Menu Font
|
||||
lcd_setFont(FONT_STATUSMENU);
|
||||
|
||||
//
|
||||
// Fan Animation
|
||||
//
|
||||
// Draws the whole heading image as a B/W bitmap rather than
|
||||
// drawing the elements separately.
|
||||
// This was done as an optimization, as it was slower to draw
|
||||
// multiple parts compared to a single bitmap.
|
||||
//
|
||||
// The bitmap:
|
||||
// - May be offset in X
|
||||
// - Includes all nozzle(s), bed(s), and the fan.
|
||||
//
|
||||
// TODO:
|
||||
//
|
||||
// - Only draw the whole header on the first
|
||||
// entry to the status screen. Nozzle, bed, and
|
||||
// fan outline bits don't change.
|
||||
//
|
||||
if (PAGE_UNDER(STATUS_SCREENHEIGHT + 1)) {
|
||||
|
||||
u8g.drawBitmapP(
|
||||
STATUS_SCREEN_X, STATUS_SCREEN_Y,
|
||||
(STATUS_SCREENWIDTH + 7) / 8, STATUS_SCREENHEIGHT,
|
||||
#if HAS_FAN0
|
||||
#if FAN_ANIM_FRAMES > 2
|
||||
fan_frame == 1 ? status_screen1_bmp :
|
||||
fan_frame == 2 ? status_screen2_bmp :
|
||||
#if FAN_ANIM_FRAMES > 3
|
||||
fan_frame == 3 ? status_screen3_bmp :
|
||||
#endif
|
||||
#else
|
||||
blink && fanSpeeds[0] ? status_screen1_bmp :
|
||||
#endif
|
||||
#endif
|
||||
status_screen0_bmp
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
// Temperature Graphics and Info
|
||||
//
|
||||
|
||||
if (PAGE_UNDER(28)) {
|
||||
// Extruders
|
||||
HOTEND_LOOP() _draw_heater_status(STATUS_SCREEN_HOTEND_TEXT_X(e), e, blink);
|
||||
|
||||
// Heated bed
|
||||
#if HOTENDS < 4 && HAS_HEATED_BED
|
||||
_draw_heater_status(STATUS_SCREEN_BED_TEXT_X, -1, blink);
|
||||
#endif
|
||||
|
||||
#if HAS_FAN0
|
||||
if (PAGE_CONTAINS(STATUS_SCREEN_FAN_TEXT_Y - 7, STATUS_SCREEN_FAN_TEXT_Y)) {
|
||||
// Fan
|
||||
const int16_t per = ((fanSpeeds[0] + 1) * 100) / 256;
|
||||
if (per) {
|
||||
u8g.setPrintPos(STATUS_SCREEN_FAN_TEXT_X, STATUS_SCREEN_FAN_TEXT_Y);
|
||||
lcd_print(itostr3(per));
|
||||
u8g.print('%');
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if ENABLED(SDSUPPORT)
|
||||
//
|
||||
// SD Card Symbol
|
||||
//
|
||||
if (card.isFileOpen() && PAGE_CONTAINS(42 - (TALL_FONT_CORRECTION), 51 - (TALL_FONT_CORRECTION))) {
|
||||
// Upper box
|
||||
u8g.drawBox(42, 42 - (TALL_FONT_CORRECTION), 8, 7); // 42-48 (or 41-47)
|
||||
// Right edge
|
||||
u8g.drawBox(50, 44 - (TALL_FONT_CORRECTION), 2, 5); // 44-48 (or 43-47)
|
||||
// Bottom hollow box
|
||||
u8g.drawFrame(42, 49 - (TALL_FONT_CORRECTION), 10, 4); // 49-52 (or 48-51)
|
||||
// Corner pixel
|
||||
u8g.drawPixel(50, 43 - (TALL_FONT_CORRECTION)); // 43 (or 42)
|
||||
}
|
||||
#endif // SDSUPPORT
|
||||
|
||||
#if ENABLED(SDSUPPORT) || ENABLED(LCD_SET_PROGRESS_MANUALLY)
|
||||
//
|
||||
// Progress bar frame
|
||||
//
|
||||
#define PROGRESS_BAR_X 54
|
||||
#define PROGRESS_BAR_WIDTH (LCD_PIXEL_WIDTH - PROGRESS_BAR_X)
|
||||
|
||||
if (PAGE_CONTAINS(49, 52 - (TALL_FONT_CORRECTION))) // 49-52 (or 49-51)
|
||||
u8g.drawFrame(
|
||||
PROGRESS_BAR_X, 49,
|
||||
PROGRESS_BAR_WIDTH, 4 - (TALL_FONT_CORRECTION)
|
||||
);
|
||||
|
||||
#if DISABLED(LCD_SET_PROGRESS_MANUALLY)
|
||||
const uint8_t progress_bar_percent = card.percentDone();
|
||||
#endif
|
||||
|
||||
if (progress_bar_percent > 1) {
|
||||
|
||||
//
|
||||
// Progress bar solid part
|
||||
//
|
||||
|
||||
if (PAGE_CONTAINS(50, 51 - (TALL_FONT_CORRECTION))) // 50-51 (or just 50)
|
||||
u8g.drawBox(
|
||||
PROGRESS_BAR_X + 1, 50,
|
||||
(uint16_t)((PROGRESS_BAR_WIDTH - 2) * progress_bar_percent * 0.01), 2 - (TALL_FONT_CORRECTION)
|
||||
);
|
||||
|
||||
//
|
||||
// SD Percent Complete
|
||||
//
|
||||
|
||||
#if ENABLED(DOGM_SD_PERCENT)
|
||||
if (PAGE_CONTAINS(41, 48)) {
|
||||
// Percent complete
|
||||
u8g.setPrintPos(55, 48);
|
||||
u8g.print(itostr3(progress_bar_percent));
|
||||
u8g.print('%');
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
//
|
||||
// Elapsed Time
|
||||
//
|
||||
|
||||
#if DISABLED(DOGM_SD_PERCENT)
|
||||
#define SD_DURATION_X (PROGRESS_BAR_X + (PROGRESS_BAR_WIDTH / 2) - len * (DOG_CHAR_WIDTH / 2))
|
||||
#else
|
||||
#define SD_DURATION_X (LCD_PIXEL_WIDTH - len * DOG_CHAR_WIDTH)
|
||||
#endif
|
||||
|
||||
if (PAGE_CONTAINS(41, 48)) {
|
||||
char buffer[10];
|
||||
duration_t elapsed = print_job_timer.duration();
|
||||
bool has_days = (elapsed.value >= 60*60*24L);
|
||||
uint8_t len = elapsed.toDigital(buffer, has_days);
|
||||
u8g.setPrintPos(SD_DURATION_X, 48);
|
||||
lcd_print(buffer);
|
||||
}
|
||||
|
||||
#endif // SDSUPPORT || LCD_SET_PROGRESS_MANUALLY
|
||||
|
||||
//
|
||||
// XYZ Coordinates
|
||||
//
|
||||
|
||||
#define XYZ_BASELINE (30 + INFO_FONT_HEIGHT)
|
||||
|
||||
#define X_LABEL_POS 3
|
||||
#define X_VALUE_POS 11
|
||||
#define XYZ_SPACING 40
|
||||
|
||||
#if ENABLED(XYZ_HOLLOW_FRAME)
|
||||
#define XYZ_FRAME_TOP 29
|
||||
#define XYZ_FRAME_HEIGHT INFO_FONT_HEIGHT + 3
|
||||
#else
|
||||
#define XYZ_FRAME_TOP 30
|
||||
#define XYZ_FRAME_HEIGHT INFO_FONT_HEIGHT + 1
|
||||
#endif
|
||||
|
||||
static char xstring[5], ystring[5], zstring[7];
|
||||
#if ENABLED(FILAMENT_LCD_DISPLAY)
|
||||
static char wstring[5], mstring[4];
|
||||
#endif
|
||||
|
||||
// At the first page, regenerate the XYZ strings
|
||||
if (page.page == 0) {
|
||||
strcpy(xstring, ftostr4sign(LOGICAL_X_POSITION(current_position[X_AXIS])));
|
||||
strcpy(ystring, ftostr4sign(LOGICAL_Y_POSITION(current_position[Y_AXIS])));
|
||||
strcpy(zstring, ftostr52sp(LOGICAL_Z_POSITION(current_position[Z_AXIS])));
|
||||
#if ENABLED(FILAMENT_LCD_DISPLAY)
|
||||
strcpy(wstring, ftostr12ns(filament_width_meas));
|
||||
strcpy(mstring, itostr3(100.0 * (
|
||||
parser.volumetric_enabled
|
||||
? planner.volumetric_area_nominal / planner.volumetric_multiplier[FILAMENT_SENSOR_EXTRUDER_NUM]
|
||||
: planner.volumetric_multiplier[FILAMENT_SENSOR_EXTRUDER_NUM]
|
||||
)
|
||||
));
|
||||
#endif
|
||||
}
|
||||
|
||||
if (PAGE_CONTAINS(XYZ_FRAME_TOP, XYZ_FRAME_TOP + XYZ_FRAME_HEIGHT - 1)) {
|
||||
|
||||
#if ENABLED(XYZ_HOLLOW_FRAME)
|
||||
u8g.drawFrame(0, XYZ_FRAME_TOP, LCD_PIXEL_WIDTH, XYZ_FRAME_HEIGHT); // 8: 29-40 7: 29-39
|
||||
#else
|
||||
u8g.drawBox(0, XYZ_FRAME_TOP, LCD_PIXEL_WIDTH, XYZ_FRAME_HEIGHT); // 8: 30-39 7: 30-37
|
||||
#endif
|
||||
|
||||
if (PAGE_CONTAINS(XYZ_BASELINE - (INFO_FONT_HEIGHT - 1), XYZ_BASELINE)) {
|
||||
|
||||
#if DISABLED(XYZ_HOLLOW_FRAME)
|
||||
u8g.setColorIndex(0); // white on black
|
||||
#endif
|
||||
|
||||
u8g.setPrintPos(0 * XYZ_SPACING + X_LABEL_POS, XYZ_BASELINE);
|
||||
lcd_printPGM(PSTR(MSG_X));
|
||||
u8g.setPrintPos(0 * XYZ_SPACING + X_VALUE_POS, XYZ_BASELINE);
|
||||
_draw_axis_value(X_AXIS, xstring, blink);
|
||||
|
||||
u8g.setPrintPos(1 * XYZ_SPACING + X_LABEL_POS, XYZ_BASELINE);
|
||||
lcd_printPGM(PSTR(MSG_Y));
|
||||
u8g.setPrintPos(1 * XYZ_SPACING + X_VALUE_POS, XYZ_BASELINE);
|
||||
_draw_axis_value(Y_AXIS, ystring, blink);
|
||||
|
||||
u8g.setPrintPos(2 * XYZ_SPACING + X_LABEL_POS, XYZ_BASELINE);
|
||||
lcd_printPGM(PSTR(MSG_Z));
|
||||
u8g.setPrintPos(2 * XYZ_SPACING + X_VALUE_POS, XYZ_BASELINE);
|
||||
_draw_axis_value(Z_AXIS, zstring, blink);
|
||||
|
||||
#if DISABLED(XYZ_HOLLOW_FRAME)
|
||||
u8g.setColorIndex(1); // black on white
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Feedrate
|
||||
//
|
||||
|
||||
if (PAGE_CONTAINS(51 - INFO_FONT_HEIGHT, 49)) {
|
||||
lcd_setFont(FONT_MENU);
|
||||
u8g.setPrintPos(3, 50);
|
||||
lcd_print(LCD_STR_FEEDRATE[0]);
|
||||
|
||||
lcd_setFont(FONT_STATUSMENU);
|
||||
u8g.setPrintPos(12, 50);
|
||||
lcd_print(itostr3(feedrate_percentage));
|
||||
u8g.print('%');
|
||||
|
||||
//
|
||||
// Filament sensor display if SD is disabled
|
||||
//
|
||||
#if ENABLED(FILAMENT_LCD_DISPLAY) && DISABLED(SDSUPPORT)
|
||||
u8g.setPrintPos(56, 50);
|
||||
lcd_print(wstring);
|
||||
u8g.setPrintPos(102, 50);
|
||||
lcd_print(mstring);
|
||||
u8g.print('%');
|
||||
lcd_setFont(FONT_MENU);
|
||||
u8g.setPrintPos(47, 50);
|
||||
lcd_print(LCD_STR_FILAM_DIA);
|
||||
u8g.setPrintPos(93, 50);
|
||||
lcd_print(LCD_STR_FILAM_MUL);
|
||||
#endif
|
||||
}
|
||||
|
||||
//
|
||||
// Status line
|
||||
//
|
||||
|
||||
#define STATUS_BASELINE (55 + INFO_FONT_HEIGHT)
|
||||
|
||||
if (PAGE_CONTAINS(STATUS_BASELINE - (INFO_FONT_HEIGHT - 1), STATUS_BASELINE)) {
|
||||
u8g.setPrintPos(0, STATUS_BASELINE);
|
||||
|
||||
#if ENABLED(FILAMENT_LCD_DISPLAY) && ENABLED(SDSUPPORT)
|
||||
if (PENDING(millis(), previous_lcd_status_ms + 5000UL)) { //Display both Status message line and Filament display on the last line
|
||||
lcd_implementation_status_message(blink);
|
||||
}
|
||||
else {
|
||||
lcd_printPGM(PSTR(LCD_STR_FILAM_DIA));
|
||||
u8g.print(':');
|
||||
lcd_print(wstring);
|
||||
lcd_printPGM(PSTR(" " LCD_STR_FILAM_MUL));
|
||||
u8g.print(':');
|
||||
lcd_print(mstring);
|
||||
u8g.print('%');
|
||||
}
|
||||
#else
|
||||
lcd_implementation_status_message(blink);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#endif // _STATUS_SCREEN_DOGM_H_
|
|
@ -1,972 +0,0 @@
|
|||
/**
|
||||
* Lightweight Status Screen for the RepRapDiscount Full
|
||||
* Graphics Smart Controller (ST7920-based 128x64 LCD)
|
||||
*
|
||||
* (c) 2017 Aleph Objects, Inc.
|
||||
*
|
||||
* The code in this page is free software: you can
|
||||
* redistribute it and/or modify it under the terms of the GNU
|
||||
* General Public License (GNU GPL) as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option)
|
||||
* any later version. The code is distributed WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU GPL for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implementation of a Status Screen for the RepRapDiscount
|
||||
* Full Graphics Smart Controller using native ST7920 commands
|
||||
* instead of U8Glib.
|
||||
*
|
||||
* This alternative Status Screen makes use of the built-in character
|
||||
* generation capabilities of the ST7920 to update the Status Screen
|
||||
* with less SPI traffic and CPU use. In particular:
|
||||
*
|
||||
* - The fan and bed animations are handled using custom characters
|
||||
* that are stored in CGRAM. This allows for the animation to be
|
||||
* updated by writing a single character to the text-buffer (DDRAM).
|
||||
*
|
||||
* - All the information in the Status Screen is text that is written
|
||||
* to DDRAM, so the work of generating the bitmaps is offloaded to
|
||||
* the ST7920 rather than being render by U8Glib on the MCU.
|
||||
*
|
||||
* - The graphics buffer (GDRAM) is only used for static graphics
|
||||
* elements (nozzle and feedrate bitmaps) and for the progress
|
||||
* bar, so updates are sporadic.
|
||||
*/
|
||||
|
||||
#include "status_screen_lite_ST7920_class.h"
|
||||
|
||||
#include "duration_t.h"
|
||||
|
||||
#define BUFFER_WIDTH 256
|
||||
#define BUFFER_HEIGHT 32
|
||||
|
||||
#define DDRAM_LINE_1 0x00
|
||||
#define DDRAM_LINE_2 0x10
|
||||
#define DDRAM_LINE_3 0x08
|
||||
#define DDRAM_LINE_4 0x18
|
||||
|
||||
ST7920_Lite_Status_Screen::st7920_state_t ST7920_Lite_Status_Screen::current_bits;
|
||||
|
||||
void ST7920_Lite_Status_Screen::cmd(const uint8_t cmd) {
|
||||
if (!current_bits.synced || !current_bits.cmd) {
|
||||
current_bits.synced = true;
|
||||
current_bits.cmd = true;
|
||||
sync_cmd();
|
||||
}
|
||||
write_byte(cmd);
|
||||
}
|
||||
|
||||
void ST7920_Lite_Status_Screen::begin_data() {
|
||||
if (!current_bits.synced || current_bits.cmd) {
|
||||
current_bits.synced = true;
|
||||
current_bits.cmd = false;
|
||||
sync_dat();
|
||||
}
|
||||
}
|
||||
|
||||
void ST7920_Lite_Status_Screen::write_str(const char *str) {
|
||||
while (*str) write_byte(*str++);
|
||||
}
|
||||
|
||||
void ST7920_Lite_Status_Screen::write_str(const char *str, uint8_t len) {
|
||||
while (*str && len--) write_byte(*str++);
|
||||
}
|
||||
|
||||
void ST7920_Lite_Status_Screen::write_str_P(const char * const str) {
|
||||
const char *p_str = (const char *)str;
|
||||
while (char c = pgm_read_byte_near(p_str++)) write_byte(c);
|
||||
}
|
||||
|
||||
void ST7920_Lite_Status_Screen::write_str(progmem_str str) {
|
||||
write_str_P((const char*)str);
|
||||
}
|
||||
|
||||
void ST7920_Lite_Status_Screen::write_number(const int16_t value, const uint8_t digits/*=3*/) {
|
||||
char str[7];
|
||||
const char *fmt;
|
||||
switch (digits) {
|
||||
case 6: fmt = PSTR("%6d"); break;
|
||||
case 5: fmt = PSTR("%5d"); break;
|
||||
case 4: fmt = PSTR("%4d"); break;
|
||||
case 3: fmt = PSTR("%3d"); break;
|
||||
case 2: fmt = PSTR("%2d"); break;
|
||||
case 1: fmt = PSTR("%1d"); break;
|
||||
}
|
||||
sprintf_P(str, fmt, value);
|
||||
write_str(str);
|
||||
}
|
||||
|
||||
void ST7920_Lite_Status_Screen::display_status(const bool display_on, const bool cursor_on, const bool blink_on) {
|
||||
extended_function_set(false);
|
||||
cmd(0b00001000 |
|
||||
(display_on ? 0b0100 : 0) |
|
||||
(cursor_on ? 0b0010 : 0) |
|
||||
(blink_on ? 0b0001 : 0)
|
||||
);
|
||||
}
|
||||
|
||||
// Sets the extended and graphics bits simultaneously, regardless of
|
||||
// the current state. This is a helper function for extended_function_set()
|
||||
// and graphics()
|
||||
void ST7920_Lite_Status_Screen::_extended_function_set(const bool extended, const bool graphics) {
|
||||
cmd( 0b00100000 |
|
||||
(extended ? 0b00000100 : 0) |
|
||||
(graphics ? 0b00000010 : 0)
|
||||
);
|
||||
current_bits.extended = extended;
|
||||
current_bits.graphics = graphics;
|
||||
}
|
||||
|
||||
void ST7920_Lite_Status_Screen::extended_function_set(const bool extended) {
|
||||
if (extended != current_bits.extended)
|
||||
_extended_function_set(extended, current_bits.graphics);
|
||||
}
|
||||
|
||||
void ST7920_Lite_Status_Screen::graphics(const bool graphics) {
|
||||
if (graphics != current_bits.graphics)
|
||||
_extended_function_set(current_bits.extended, graphics);
|
||||
}
|
||||
|
||||
void ST7920_Lite_Status_Screen::entry_mode_select(const bool ac_increase, const bool shift) {
|
||||
extended_function_set(false);
|
||||
cmd(0b00000100 |
|
||||
(ac_increase ? 0b00000010 : 0) |
|
||||
(shift ? 0b00000001 : 0)
|
||||
);
|
||||
}
|
||||
|
||||
// Sets the sa bit regardless of the current state. This is a helper
|
||||
// function for scroll_or_addr_select()
|
||||
void ST7920_Lite_Status_Screen::_scroll_or_addr_select(const bool sa) {
|
||||
extended_function_set(true);
|
||||
cmd(0b00100010 |
|
||||
(sa ? 0b000001 : 0)
|
||||
);
|
||||
current_bits.sa = sa;
|
||||
}
|
||||
|
||||
void ST7920_Lite_Status_Screen::scroll_or_addr_select(const bool sa) {
|
||||
if (sa != current_bits.sa)
|
||||
_scroll_or_addr_select(sa);
|
||||
}
|
||||
|
||||
void ST7920_Lite_Status_Screen::set_ddram_address(const uint8_t addr) {
|
||||
extended_function_set(false);
|
||||
cmd(0b10000000 | (addr & 0b00111111));
|
||||
}
|
||||
|
||||
void ST7920_Lite_Status_Screen::set_cgram_address(const uint8_t addr) {
|
||||
extended_function_set(false);
|
||||
cmd(0b01000000 | (addr & 0b00111111));
|
||||
}
|
||||
|
||||
void ST7920_Lite_Status_Screen::set_gdram_address(const uint8_t x, const uint8_t y) {
|
||||
extended_function_set(true);
|
||||
cmd(0b10000000 | (y & 0b01111111));
|
||||
cmd(0b10000000 | (x & 0b00001111));
|
||||
}
|
||||
|
||||
void ST7920_Lite_Status_Screen::clear() {
|
||||
extended_function_set(false);
|
||||
cmd(0x00000001);
|
||||
delay(15); //delay for CGRAM clear
|
||||
}
|
||||
|
||||
void ST7920_Lite_Status_Screen::home() {
|
||||
extended_function_set(false);
|
||||
cmd(0x00000010);
|
||||
}
|
||||
|
||||
/* This fills the entire text buffer with spaces */
|
||||
void ST7920_Lite_Status_Screen::clear_ddram() {
|
||||
set_ddram_address(DDRAM_LINE_1);
|
||||
begin_data();
|
||||
for (uint8_t i = 64; i--;) write_byte(' ');
|
||||
}
|
||||
|
||||
/* This fills the entire graphics buffer with zeros */
|
||||
void ST7920_Lite_Status_Screen::clear_gdram() {
|
||||
for (uint8_t y = 0; y < BUFFER_HEIGHT; y++) {
|
||||
set_gdram_address(0, y);
|
||||
begin_data();
|
||||
for (uint8_t i = (BUFFER_WIDTH) / 16; i--;) write_word(0);
|
||||
}
|
||||
}
|
||||
|
||||
void ST7920_Lite_Status_Screen::load_cgram_icon(const uint16_t addr, const void *data) {
|
||||
const uint16_t *p_word = (const uint16_t *)data;
|
||||
set_cgram_address(addr);
|
||||
begin_data();
|
||||
for (uint8_t i = 16; i--;)
|
||||
write_word(pgm_read_word_near(p_word++));
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw an icon in GDRAM. Position specified in DDRAM
|
||||
* coordinates. i.e., X from 1 to 8, Y from 1 to 4.
|
||||
*/
|
||||
void ST7920_Lite_Status_Screen::draw_gdram_icon(uint8_t x, uint8_t y, const void *data) {
|
||||
const uint16_t *p_word = (const uint16_t *)data;
|
||||
if (y > 2) { // Handle display folding
|
||||
y -= 2;
|
||||
x += 8;
|
||||
}
|
||||
--x;
|
||||
--y;
|
||||
for (int i = 0; i < 16; i++) {
|
||||
set_gdram_address(x, i + y * 16);
|
||||
begin_data();
|
||||
write_word(pgm_read_word_near(p_word++));
|
||||
}
|
||||
}
|
||||
|
||||
/************************** ICON DEFINITIONS *************************************/
|
||||
|
||||
#define CGRAM_ICON_1_ADDR 0x00
|
||||
#define CGRAM_ICON_2_ADDR 0x10
|
||||
#define CGRAM_ICON_3_ADDR 0x20
|
||||
#define CGRAM_ICON_4_ADDR 0x30
|
||||
|
||||
#define CGRAM_ICON_1_WORD 0x00
|
||||
#define CGRAM_ICON_2_WORD 0x02
|
||||
#define CGRAM_ICON_3_WORD 0x04
|
||||
#define CGRAM_ICON_4_WORD 0x06
|
||||
|
||||
const uint8_t degree_symbol_y_top = 1;
|
||||
PROGMEM const uint8_t degree_symbol[] = {
|
||||
0b00110000,
|
||||
0b01001000,
|
||||
0b01001000,
|
||||
0b00110000,
|
||||
};
|
||||
|
||||
const uint16_t nozzle_icon[] PROGMEM = {
|
||||
0b0000000000000000,
|
||||
0b0000000000000000,
|
||||
0b0000111111110000,
|
||||
0b0001111111111000,
|
||||
0b0001111111111000,
|
||||
0b0001111111111000,
|
||||
0b0000111111110000,
|
||||
0b0000111111110000,
|
||||
0b0001111111111000,
|
||||
0b0001111111111000,
|
||||
0b0001111111111000,
|
||||
0b0000011111100000,
|
||||
0b0000001111000000,
|
||||
0b0000000110000000,
|
||||
0b0000000000000000,
|
||||
0b0000000000000000
|
||||
};
|
||||
|
||||
const uint16_t bed_icon[] PROGMEM = {
|
||||
0b0000000000000000,
|
||||
0b0000000000000000,
|
||||
0b0000000000000000,
|
||||
0b0000000000000000,
|
||||
0b0000000000000000,
|
||||
0b0000000000000000,
|
||||
0b0000000000000000,
|
||||
0b0000000000000000,
|
||||
0b0000000000000000,
|
||||
0b0000000000000000,
|
||||
0b0000000000000000,
|
||||
0b0111111111111110,
|
||||
0b0111111111111110,
|
||||
0b0110000000000110,
|
||||
0b0000000000000000,
|
||||
0b0000000000000000
|
||||
};
|
||||
|
||||
const uint16_t heat1_icon[] PROGMEM = {
|
||||
0b0000000000000000,
|
||||
0b0010001000100000,
|
||||
0b0001000100010000,
|
||||
0b0000100010001000,
|
||||
0b0000100010001000,
|
||||
0b0001000100010000,
|
||||
0b0010001000100000,
|
||||
0b0010001000100000,
|
||||
0b0001000100010000,
|
||||
0b0000100010001000,
|
||||
0b0000000000000000,
|
||||
0b0000000000000000,
|
||||
0b0000000000000000,
|
||||
0b0000000000000000,
|
||||
0b0000000000000000,
|
||||
0b0000000000000000
|
||||
};
|
||||
|
||||
const uint16_t heat2_icon[] PROGMEM = {
|
||||
0b0000000000000000,
|
||||
0b0000100010001000,
|
||||
0b0000100010001000,
|
||||
0b0001000100010000,
|
||||
0b0010001000100000,
|
||||
0b0010001000100000,
|
||||
0b0001000100010000,
|
||||
0b0000100010001000,
|
||||
0b0000100010001000,
|
||||
0b0001000100010000,
|
||||
0b0000000000000000,
|
||||
0b0000000000000000,
|
||||
0b0000000000000000,
|
||||
0b0000000000000000,
|
||||
0b0000000000000000,
|
||||
0b0000000000000000
|
||||
};
|
||||
|
||||
const uint16_t fan1_icon[] PROGMEM = {
|
||||
0b0000000000000000,
|
||||
0b0111111111111110,
|
||||
0b0111000000001110,
|
||||
0b0110001111000110,
|
||||
0b0100001111000010,
|
||||
0b0100000110000010,
|
||||
0b0101100000011010,
|
||||
0b0101110110111010,
|
||||
0b0101100000011010,
|
||||
0b0100000110000010,
|
||||
0b0100001111000010,
|
||||
0b0110001111000110,
|
||||
0b0111000000001110,
|
||||
0b0111111111111110,
|
||||
0b0000000000000000,
|
||||
0b0000000000000000
|
||||
};
|
||||
|
||||
const uint16_t fan2_icon[] PROGMEM = {
|
||||
0b0000000000000000,
|
||||
0b0111111111111110,
|
||||
0b0111000000001110,
|
||||
0b0110010000100110,
|
||||
0b0100111001110010,
|
||||
0b0101111001111010,
|
||||
0b0100110000110010,
|
||||
0b0100000110000010,
|
||||
0b0100110000110010,
|
||||
0b0101111001111010,
|
||||
0b0100111001110010,
|
||||
0b0110010000100110,
|
||||
0b0111000000001110,
|
||||
0b0111111111111110,
|
||||
0b0000000000000000,
|
||||
0b0000000000000000
|
||||
};
|
||||
|
||||
const uint16_t feedrate_icon[] PROGMEM = {
|
||||
0b0000000000000000,
|
||||
0b0111111000000000,
|
||||
0b0110000000000000,
|
||||
0b0110000000000000,
|
||||
0b0110000000000000,
|
||||
0b0111111011111000,
|
||||
0b0110000011001100,
|
||||
0b0110000011001100,
|
||||
0b0110000011001100,
|
||||
0b0110000011111000,
|
||||
0b0000000011001100,
|
||||
0b0000000011001100,
|
||||
0b0000000011001100,
|
||||
0b0000000011001100,
|
||||
0b0000000000000000,
|
||||
0b0000000000000000
|
||||
};
|
||||
|
||||
/************************** MAIN SCREEN *************************************/
|
||||
|
||||
// The ST7920 does not have a degree character, but we
|
||||
// can fake it by writing it to GDRAM.
|
||||
// This function takes as an argument character positions
|
||||
// i.e x is [1-16], while the y position is [1-4]
|
||||
void ST7920_Lite_Status_Screen::draw_degree_symbol(uint8_t x, uint8_t y, bool draw) {
|
||||
const uint8_t *p_bytes = degree_symbol;
|
||||
if (y > 2) {
|
||||
// Handle display folding
|
||||
y -= 2;
|
||||
x += 16;
|
||||
}
|
||||
x -= 1;
|
||||
y -= 1;
|
||||
const bool oddChar = x & 1;
|
||||
const uint8_t x_word = x >> 1;
|
||||
const uint8_t y_top = degree_symbol_y_top;
|
||||
const uint8_t y_bot = y_top + sizeof(degree_symbol)/sizeof(degree_symbol[0]);
|
||||
for (uint8_t i = y_top; i < y_bot; i++) {
|
||||
uint8_t byte = pgm_read_byte_near(p_bytes++);
|
||||
set_gdram_address(x_word,i+y*16);
|
||||
begin_data();
|
||||
if (draw) {
|
||||
write_byte(oddChar ? 0x00 : byte);
|
||||
write_byte(oddChar ? byte : 0x00);
|
||||
}
|
||||
else
|
||||
write_word(0x0000);
|
||||
}
|
||||
}
|
||||
|
||||
void ST7920_Lite_Status_Screen::draw_static_elements() {
|
||||
scroll_or_addr_select(0);
|
||||
|
||||
// Load the animated bed and fan icons
|
||||
load_cgram_icon(CGRAM_ICON_1_ADDR, heat1_icon);
|
||||
load_cgram_icon(CGRAM_ICON_2_ADDR, heat2_icon);
|
||||
load_cgram_icon(CGRAM_ICON_3_ADDR, fan1_icon);
|
||||
load_cgram_icon(CGRAM_ICON_4_ADDR, fan2_icon);
|
||||
|
||||
// Draw the static icons in GDRAM
|
||||
draw_gdram_icon(1, 1, nozzle_icon);
|
||||
#if HOTENDS > 1
|
||||
draw_gdram_icon(1,2,nozzle_icon);
|
||||
draw_gdram_icon(1,3,bed_icon);
|
||||
#else
|
||||
draw_gdram_icon(1,2,bed_icon);
|
||||
#endif
|
||||
draw_gdram_icon(6,2,feedrate_icon);
|
||||
|
||||
// Draw the initial fan icon
|
||||
draw_fan_icon(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Although this is undocumented, the ST7920 allows the character
|
||||
* data buffer (DDRAM) to be used in conjunction with the graphics
|
||||
* bitmap buffer (CGRAM). The contents of the graphics buffer is
|
||||
* XORed with the data from the character generator. This allows
|
||||
* us to make the progess bar out of graphical data (the bar) and
|
||||
* text data (the percentage).
|
||||
*/
|
||||
void ST7920_Lite_Status_Screen::draw_progress_bar(const uint8_t value) {
|
||||
#if HOTENDS == 1
|
||||
// If we have only one extruder, draw a long progress bar on the third line
|
||||
const uint8_t top = 1, // Top in pixels
|
||||
bottom = 13, // Bottom in pixels
|
||||
left = 12, // Left edge, in 16-bit words
|
||||
width = 4; // Width of progress bar, in 16-bit words
|
||||
#else
|
||||
const uint8_t top = 16 + 1,
|
||||
bottom = 16 + 13,
|
||||
left = 5,
|
||||
width = 3;
|
||||
#endif
|
||||
const uint8_t char_pcnt = 100 / width; // How many percent does each 16-bit word represent?
|
||||
|
||||
// Draw the progress bar as a bitmap in CGRAM
|
||||
for (uint8_t y = top; y <= bottom; y++) {
|
||||
set_gdram_address(left, y);
|
||||
begin_data();
|
||||
for (uint8_t x = 0; x < width; x++) {
|
||||
uint16_t gfx_word = 0x0000;
|
||||
if ((x + 1) * char_pcnt <= value)
|
||||
gfx_word = 0xFFFF; // Draw completely filled bytes
|
||||
else if ((x * char_pcnt) < value)
|
||||
gfx_word = int(0x8000) >> (value % char_pcnt) * 16 / char_pcnt; // Draw partially filled bytes
|
||||
|
||||
// Draw the frame around the progress bar
|
||||
if (y == top || y == bottom)
|
||||
gfx_word = 0xFFFF; // Draw top/bottom border
|
||||
else if (x == width - 1)
|
||||
gfx_word |= 0x0001; // Draw right border
|
||||
else if (x == 0)
|
||||
gfx_word |= 0x8000; // Draw left border
|
||||
write_word(gfx_word);
|
||||
}
|
||||
}
|
||||
|
||||
// Draw the percentage as text in DDRAM
|
||||
#if HOTENDS == 1
|
||||
set_ddram_address(DDRAM_LINE_3 + 4);
|
||||
begin_data();
|
||||
write_byte(' ');
|
||||
#else
|
||||
set_ddram_address(DDRAM_LINE_2 + left);
|
||||
begin_data();
|
||||
#endif
|
||||
|
||||
// Draw centered
|
||||
if (value > 9) {
|
||||
write_number(value, 4);
|
||||
write_str(F("% "));
|
||||
}
|
||||
else {
|
||||
write_number(value, 3);
|
||||
write_str(F("% "));
|
||||
}
|
||||
}
|
||||
|
||||
void ST7920_Lite_Status_Screen::draw_fan_icon(const bool whichIcon) {
|
||||
set_ddram_address(DDRAM_LINE_1 + 5);
|
||||
begin_data();
|
||||
write_word(whichIcon ? CGRAM_ICON_3_WORD : CGRAM_ICON_4_WORD);
|
||||
}
|
||||
|
||||
void ST7920_Lite_Status_Screen::draw_heat_icon(const bool whichIcon, const bool heating) {
|
||||
set_ddram_address(
|
||||
#if HOTENDS == 1
|
||||
DDRAM_LINE_2
|
||||
#else
|
||||
DDRAM_LINE_3
|
||||
#endif
|
||||
);
|
||||
begin_data();
|
||||
if (heating)
|
||||
write_word(whichIcon ? CGRAM_ICON_1_WORD : CGRAM_ICON_2_WORD);
|
||||
else {
|
||||
write_byte(' ');
|
||||
write_byte(' ');
|
||||
}
|
||||
}
|
||||
|
||||
#define FAR(a,b) (((a > b) ? (a-b) : (b-a)) > 2)
|
||||
|
||||
static struct {
|
||||
bool E1_show_target : 1;
|
||||
bool E2_show_target : 1;
|
||||
#if HAS_HEATED_BED
|
||||
bool bed_show_target : 1;
|
||||
#endif
|
||||
} display_state = {
|
||||
true, true
|
||||
#if HAS_HEATED_BED
|
||||
, true
|
||||
#endif
|
||||
};
|
||||
|
||||
void ST7920_Lite_Status_Screen::draw_temps(uint8_t line, const int16_t temp, const int16_t target, bool showTarget, bool targetStateChange) {
|
||||
switch (line) {
|
||||
case 1: set_ddram_address(DDRAM_LINE_1 + 1); break;
|
||||
case 2: set_ddram_address(DDRAM_LINE_2 + 1); break;
|
||||
case 3: set_ddram_address(DDRAM_LINE_3 + 1); break;
|
||||
case 4: set_ddram_address(DDRAM_LINE_3 + 1); break;
|
||||
}
|
||||
begin_data();
|
||||
write_number(temp);
|
||||
|
||||
if (showTarget) {
|
||||
write_str(F("\x1A"));
|
||||
write_number(target);
|
||||
};
|
||||
|
||||
if (targetStateChange) {
|
||||
if (!showTarget) write_str(F(" "));
|
||||
draw_degree_symbol(6, line, !showTarget);
|
||||
draw_degree_symbol(10, line, showTarget);
|
||||
}
|
||||
}
|
||||
|
||||
void ST7920_Lite_Status_Screen::draw_extruder_1_temp(const int16_t temp, const int16_t target, bool forceUpdate) {
|
||||
const bool show_target = target && FAR(temp, target);
|
||||
draw_temps(1, temp, target, show_target, display_state.E1_show_target != show_target || forceUpdate);
|
||||
display_state.E1_show_target = show_target;
|
||||
}
|
||||
|
||||
void ST7920_Lite_Status_Screen::draw_extruder_2_temp(const int16_t temp, const int16_t target, bool forceUpdate) {
|
||||
const bool show_target = target && FAR(temp, target);
|
||||
draw_temps(2, temp, target, show_target, display_state.E2_show_target != show_target || forceUpdate);
|
||||
display_state.E2_show_target = show_target;
|
||||
}
|
||||
|
||||
#if HAS_HEATED_BED
|
||||
void ST7920_Lite_Status_Screen::draw_bed_temp(const int16_t temp, const int16_t target, bool forceUpdate) {
|
||||
const bool show_target = target && FAR(temp, target);
|
||||
draw_temps(2
|
||||
#if HOTENDS > 1
|
||||
+ 1
|
||||
#endif
|
||||
, temp, target, show_target, display_state.bed_show_target != show_target || forceUpdate
|
||||
);
|
||||
display_state.bed_show_target = show_target;
|
||||
}
|
||||
#endif
|
||||
|
||||
void ST7920_Lite_Status_Screen::draw_fan_speed(const uint8_t value) {
|
||||
set_ddram_address(DDRAM_LINE_1 + 6);
|
||||
begin_data();
|
||||
write_number(value, 3);
|
||||
write_byte('%');
|
||||
}
|
||||
|
||||
void ST7920_Lite_Status_Screen::draw_print_time(const duration_t &elapsed) {
|
||||
#if HOTENDS == 1
|
||||
set_ddram_address(DDRAM_LINE_3);
|
||||
#else
|
||||
set_ddram_address(DDRAM_LINE_3 + 5);
|
||||
#endif
|
||||
char str[7];
|
||||
str[elapsed.toDigital(str)] = ' ';
|
||||
begin_data();
|
||||
write_str(str, 6);
|
||||
}
|
||||
|
||||
void ST7920_Lite_Status_Screen::draw_feedrate_percentage(const uint8_t percentage) {
|
||||
// We only have enough room for the feedrate when
|
||||
// we have one extruder
|
||||
#if HOTENDS == 1
|
||||
set_ddram_address(DDRAM_LINE_2 + 6);
|
||||
begin_data();
|
||||
write_number(percentage, 3);
|
||||
write_byte('%');
|
||||
#endif
|
||||
}
|
||||
|
||||
void ST7920_Lite_Status_Screen::draw_status_message(const char *str) {
|
||||
set_ddram_address(DDRAM_LINE_4);
|
||||
begin_data();
|
||||
const uint8_t lcd_len = 16;
|
||||
#if ENABLED(STATUS_MESSAGE_SCROLLING)
|
||||
|
||||
uint8_t slen = utf8_strlen(str);
|
||||
|
||||
// If the string fits into the LCD, just print it and do not scroll it
|
||||
if (slen <= lcd_len) {
|
||||
|
||||
// The string isn't scrolling and may not fill the screen
|
||||
write_str(str);
|
||||
|
||||
// Fill the rest with spaces
|
||||
while (slen < lcd_len) {
|
||||
write_byte(' ');
|
||||
++slen;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// String is larger than the available space in screen.
|
||||
|
||||
// Get a pointer to the next valid UTF8 character
|
||||
const char *stat = str + status_scroll_offset;
|
||||
|
||||
// Get the string remaining length
|
||||
const uint8_t rlen = utf8_strlen(stat);
|
||||
|
||||
// If we have enough characters to display
|
||||
if (rlen >= lcd_len) {
|
||||
// The remaining string fills the screen - Print it
|
||||
write_str(stat, lcd_len);
|
||||
}
|
||||
else {
|
||||
// The remaining string does not completely fill the screen
|
||||
write_str(stat); // The string leaves space
|
||||
uint8_t chars = lcd_len - rlen; // Amount of space left in characters
|
||||
|
||||
write_byte('.'); // Always at 1+ spaces left, draw a dot
|
||||
if (--chars) { // Draw a second dot if there's space
|
||||
write_byte('.');
|
||||
if (--chars)
|
||||
write_str(str, chars); // Print a second copy of the message
|
||||
}
|
||||
}
|
||||
|
||||
// Adjust by complete UTF8 characters
|
||||
if (status_scroll_offset < slen) {
|
||||
status_scroll_offset++;
|
||||
while (!START_OF_UTF8_CHAR(str[status_scroll_offset]))
|
||||
status_scroll_offset++;
|
||||
}
|
||||
else
|
||||
status_scroll_offset = 0;
|
||||
}
|
||||
#else
|
||||
// Get the UTF8 character count of the string
|
||||
uint8_t slen = utf8_strlen(str);
|
||||
|
||||
// Just print the string to the LCD
|
||||
write_str(str, lcd_len);
|
||||
|
||||
// Fill the rest with spaces if there are missing spaces
|
||||
while (slen < lcd_len) {
|
||||
write_byte(' ');
|
||||
++slen;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void ST7920_Lite_Status_Screen::draw_position(const float x, const float y, const float z, bool position_known) {
|
||||
char str[7];
|
||||
set_ddram_address(DDRAM_LINE_4);
|
||||
begin_data();
|
||||
|
||||
// If position is unknown, flash the labels.
|
||||
const unsigned char alt_label = position_known ? 0 : (lcd_blink() ? ' ' : 0);
|
||||
|
||||
dtostrf(x, -4, 0, str);
|
||||
write_byte(alt_label ? alt_label : 'X');
|
||||
write_str(str, 4);
|
||||
|
||||
dtostrf(y, -4, 0, str);
|
||||
write_byte(alt_label ? alt_label : 'Y');
|
||||
write_str(str, 4);
|
||||
|
||||
dtostrf(z, -5, 1, str);
|
||||
write_byte(alt_label ? alt_label : 'Z');
|
||||
write_str(str, 5);
|
||||
}
|
||||
|
||||
bool ST7920_Lite_Status_Screen::indicators_changed() {
|
||||
// We only add the target temperatures to the checksum
|
||||
// because the actual temps fluctuate so by updating
|
||||
// them only during blinks we gain a bit of stability.
|
||||
const bool blink = lcd_blink();
|
||||
const uint8_t feedrate_perc = feedrate_percentage;
|
||||
const uint8_t fan_speed = ((fanSpeeds[0] + 1) * 100) / 256;
|
||||
const int16_t extruder_1_target = thermalManager.degTargetHotend(0);
|
||||
#if HOTENDS > 1
|
||||
const int16_t extruder_2_target = thermalManager.degTargetHotend(1);
|
||||
#endif
|
||||
#if HAS_HEATED_BED
|
||||
const int16_t bed_target = thermalManager.degTargetBed();
|
||||
#endif
|
||||
static uint16_t last_checksum = 0;
|
||||
const uint16_t checksum = blink ^ feedrate_perc ^ fan_speed ^ extruder_1_target
|
||||
#if HOTENDS > 1
|
||||
^ extruder_2_target
|
||||
#endif
|
||||
#if HAS_HEATED_BED
|
||||
^ bed_target
|
||||
#endif
|
||||
;
|
||||
if (last_checksum == checksum) return false;
|
||||
last_checksum = checksum;
|
||||
return true;
|
||||
}
|
||||
|
||||
void ST7920_Lite_Status_Screen::update_indicators(const bool forceUpdate) {
|
||||
if (forceUpdate || indicators_changed()) {
|
||||
const bool blink = lcd_blink();
|
||||
const duration_t elapsed = print_job_timer.duration();
|
||||
const uint8_t feedrate_perc = feedrate_percentage;
|
||||
const uint8_t fan_speed = ((fanSpeeds[0] + 1) * 100) / 256;
|
||||
const int16_t extruder_1_temp = thermalManager.degHotend(0),
|
||||
extruder_1_target = thermalManager.degTargetHotend(0);
|
||||
#if HOTENDS > 1
|
||||
const int16_t extruder_2_temp = thermalManager.degHotend(1),
|
||||
extruder_2_target = thermalManager.degTargetHotend(1);
|
||||
#endif
|
||||
#if HAS_HEATED_BED
|
||||
const int16_t bed_temp = thermalManager.degBed(),
|
||||
bed_target = thermalManager.degTargetBed();
|
||||
#endif
|
||||
|
||||
draw_extruder_1_temp(extruder_1_temp, extruder_1_target, forceUpdate);
|
||||
#if HOTENDS > 1
|
||||
draw_extruder_2_temp(extruder_2_temp, extruder_2_target, forceUpdate);
|
||||
#endif
|
||||
#if HAS_HEATED_BED
|
||||
draw_bed_temp(bed_temp, bed_target, forceUpdate);
|
||||
#endif
|
||||
draw_fan_speed(fan_speed);
|
||||
draw_print_time(elapsed);
|
||||
draw_feedrate_percentage(feedrate_perc);
|
||||
|
||||
// Update the fan and bed animations
|
||||
if (fan_speed > 0) draw_fan_icon(blink);
|
||||
#if HAS_HEATED_BED
|
||||
if (bed_target > 0)
|
||||
draw_heat_icon(blink, true);
|
||||
else
|
||||
draw_heat_icon(false, false);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
bool ST7920_Lite_Status_Screen::position_changed() {
|
||||
const float x_pos = current_position[X_AXIS],
|
||||
y_pos = current_position[Y_AXIS],
|
||||
z_pos = current_position[Z_AXIS];
|
||||
const uint8_t checksum = uint8_t(x_pos) ^ uint8_t(y_pos) ^ uint8_t(z_pos);
|
||||
|
||||
static uint8_t last_checksum = 0;
|
||||
if (last_checksum == checksum) return false;
|
||||
last_checksum = checksum;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ST7920_Lite_Status_Screen::status_changed() {
|
||||
uint8_t checksum = 0;
|
||||
for (const char *p = lcd_status_message; *p; p++) checksum ^= *p;
|
||||
static uint8_t last_checksum = 0;
|
||||
if (last_checksum == checksum) return false;
|
||||
last_checksum = checksum;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ST7920_Lite_Status_Screen::blink_changed() {
|
||||
static uint8_t last_blink = 0;
|
||||
const bool blink = lcd_blink();
|
||||
if (last_blink == blink) return false;
|
||||
last_blink = blink;
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifndef STATUS_EXPIRE_SECONDS
|
||||
#define STATUS_EXPIRE_SECONDS 20
|
||||
#endif
|
||||
|
||||
void ST7920_Lite_Status_Screen::update_status_or_position(bool forceUpdate) {
|
||||
|
||||
#if STATUS_EXPIRE_SECONDS
|
||||
static uint8_t countdown = 0;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* There is only enough room in the display for either the
|
||||
* status message or the position, not both, so we choose
|
||||
* one or another. Whenever the status message changes,
|
||||
* we show it for a number of consecutive seconds, but
|
||||
* then go back to showing the position as soon as the
|
||||
* head moves, i.e:
|
||||
*
|
||||
* countdown > 1 -- Show status
|
||||
* countdown = 1 -- Show status, until movement
|
||||
* countdown = 0 -- Show position
|
||||
*
|
||||
* If STATUS_EXPIRE_SECONDS is zero, the position display
|
||||
* will be disabled and only the status will be shown.
|
||||
*/
|
||||
if (forceUpdate || status_changed()) {
|
||||
#if ENABLED(STATUS_MESSAGE_SCROLLING)
|
||||
status_scroll_offset = 0;
|
||||
#endif
|
||||
#if STATUS_EXPIRE_SECONDS
|
||||
countdown = lcd_status_message[0] ? STATUS_EXPIRE_SECONDS : 0;
|
||||
#endif
|
||||
draw_status_message(lcd_status_message);
|
||||
blink_changed(); // Clear changed flag
|
||||
}
|
||||
#if !STATUS_EXPIRE_SECONDS
|
||||
#if ENABLED(STATUS_MESSAGE_SCROLLING)
|
||||
else
|
||||
draw_status_message(lcd_status_message);
|
||||
#endif
|
||||
#else
|
||||
else if (countdown > 1 && blink_changed()) {
|
||||
countdown--;
|
||||
#if ENABLED(STATUS_MESSAGE_SCROLLING)
|
||||
draw_status_message(lcd_status_message);
|
||||
#endif
|
||||
}
|
||||
else if (countdown > 0 && blink_changed()) {
|
||||
if (position_changed()) {
|
||||
countdown--;
|
||||
forceUpdate = true;
|
||||
}
|
||||
#if ENABLED(STATUS_MESSAGE_SCROLLING)
|
||||
draw_status_message(lcd_status_message);
|
||||
#endif
|
||||
}
|
||||
if (countdown == 0 && (forceUpdate || position_changed() ||
|
||||
#if DISABLED(DISABLE_REDUCED_ACCURACY_WARNING)
|
||||
blink_changed()
|
||||
#endif
|
||||
)) {
|
||||
draw_position(
|
||||
current_position[X_AXIS],
|
||||
current_position[Y_AXIS],
|
||||
current_position[Z_AXIS],
|
||||
#if ENABLED(DISABLE_REDUCED_ACCURACY_WARNING)
|
||||
true
|
||||
#else
|
||||
all_axes_known()
|
||||
#endif
|
||||
);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void ST7920_Lite_Status_Screen::update_progress(const bool forceUpdate) {
|
||||
#if ENABLED(LCD_SET_PROGRESS_MANUALLY) || ENABLED(SDSUPPORT)
|
||||
|
||||
#if DISABLED(LCD_SET_PROGRESS_MANUALLY)
|
||||
uint8_t progress_bar_percent = 0;
|
||||
#endif
|
||||
|
||||
#if ENABLED(SDSUPPORT)
|
||||
// Progress bar % comes from SD when actively printing
|
||||
if (IS_SD_PRINTING()) progress_bar_percent = card.percentDone();
|
||||
#endif
|
||||
|
||||
// Since the progress bar involves writing
|
||||
// quite a few bytes to GDRAM, only do this
|
||||
// when an update is actually necessary.
|
||||
|
||||
static uint8_t last_progress = 0;
|
||||
if (!forceUpdate && last_progress == progress_bar_percent) return;
|
||||
last_progress = progress_bar_percent;
|
||||
|
||||
draw_progress_bar(progress_bar_percent);
|
||||
|
||||
#else
|
||||
|
||||
UNUSED(forceUpdate);
|
||||
|
||||
#endif // LCD_SET_PROGRESS_MANUALLY || SDSUPPORT
|
||||
}
|
||||
|
||||
void ST7920_Lite_Status_Screen::update(const bool forceUpdate) {
|
||||
cs();
|
||||
update_indicators(forceUpdate);
|
||||
update_status_or_position(forceUpdate);
|
||||
update_progress(forceUpdate);
|
||||
ncs();
|
||||
}
|
||||
|
||||
void ST7920_Lite_Status_Screen::reset_state_from_unknown() {
|
||||
_extended_function_set(true, true); // Do it twice as only one bit
|
||||
_extended_function_set(true, true); // get set at a time.
|
||||
_scroll_or_addr_select(false);
|
||||
}
|
||||
|
||||
void ST7920_Lite_Status_Screen::on_entry() {
|
||||
cs();
|
||||
reset_state_from_unknown();
|
||||
clear();
|
||||
clear_gdram();
|
||||
draw_static_elements();
|
||||
update(true);
|
||||
ncs();
|
||||
}
|
||||
|
||||
void ST7920_Lite_Status_Screen::on_exit() {
|
||||
cs();
|
||||
clear();
|
||||
_extended_function_set(true, true); // Restore state to what u8g expects.
|
||||
ncs();
|
||||
}
|
||||
|
||||
// This is called prior to the KILL screen to
|
||||
// clear the screen so we don't end up with a
|
||||
// garbled display.
|
||||
void ST7920_Lite_Status_Screen::clear_text_buffer() {
|
||||
cs();
|
||||
reset_state_from_unknown();
|
||||
clear();
|
||||
_extended_function_set(true, true); // Restore state to what u8g expects.
|
||||
ncs();
|
||||
}
|
||||
|
||||
static void lcd_implementation_status_screen() {
|
||||
ST7920_Lite_Status_Screen::update(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* In order to properly update the lite Status Screen,
|
||||
* we must know when we have entered and left the
|
||||
* Status Screen. Since the ultralcd code is not
|
||||
* set up for doing this, we call this function before
|
||||
* each update indicating whether the current screen
|
||||
* is the Status Screen.
|
||||
*
|
||||
* This function keeps track of whether we have left or
|
||||
* entered the Status Screen and calls the on_entry()
|
||||
* and on_exit() methods for cleanup.
|
||||
*/
|
||||
static void lcd_in_status(const bool inStatus) {
|
||||
static bool lastInStatus = false;
|
||||
if (lastInStatus == inStatus) return;
|
||||
if ((lastInStatus = inStatus))
|
||||
ST7920_Lite_Status_Screen::on_entry();
|
||||
else
|
||||
ST7920_Lite_Status_Screen::on_exit();
|
||||
}
|
|
@ -1,111 +0,0 @@
|
|||
/**
|
||||
* Lightweight Status Screen for the RepRapDiscount Full
|
||||
* Graphics Smart Controller (ST7920-based 128x64 LCD)
|
||||
*
|
||||
* (c) 2017 Aleph Objects, Inc.
|
||||
*
|
||||
* The code in this page is free software: you can
|
||||
* redistribute it and/or modify it under the terms of the GNU
|
||||
* General Public License (GNU GPL) as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option)
|
||||
* any later version. The code is distributed WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU GPL for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef STATUS_SCREEN_LITE_ST7920_CLASS_H
|
||||
#define STATUS_SCREEN_LITE_ST7920_CLASS_H
|
||||
|
||||
#include "macros.h"
|
||||
#include "duration_t.h"
|
||||
|
||||
typedef const __FlashStringHelper *progmem_str;
|
||||
|
||||
class ST7920_Lite_Status_Screen {
|
||||
private:
|
||||
static struct st7920_state_t {
|
||||
uint8_t synced : 1; // Whether a sync has been sent
|
||||
uint8_t cmd : 1; // Whether the sync was cmd or data
|
||||
uint8_t extended : 1;
|
||||
uint8_t graphics : 1;
|
||||
uint8_t sa : 1;
|
||||
} current_bits;
|
||||
|
||||
static void cs();
|
||||
static void ncs();
|
||||
static void sync_cmd();
|
||||
static void sync_dat();
|
||||
static void write_byte(const uint8_t w);
|
||||
|
||||
FORCE_INLINE static void write_word(const uint16_t w) {
|
||||
write_byte((w >> 8) & 0xFF);
|
||||
write_byte((w >> 0) & 0xFF);
|
||||
}
|
||||
|
||||
static void cmd(const uint8_t cmd);
|
||||
static void begin_data();
|
||||
|
||||
static void write_str(const char *str);
|
||||
static void write_str(const char *str, const uint8_t len);
|
||||
static void write_str_P(const char * const str);
|
||||
static void write_str(progmem_str str);
|
||||
static void write_number(const int16_t value, const uint8_t digits=3);
|
||||
|
||||
static void _extended_function_set(const bool extended, const bool graphics);
|
||||
static void _scroll_or_addr_select(const bool sa);
|
||||
static void reset_state_from_unknown();
|
||||
|
||||
static void home();
|
||||
static void display_status(const bool display_on, const bool cursor_on, const bool blink_on);
|
||||
static void extended_function_set(const bool extended);
|
||||
static void graphics(const bool graphics);
|
||||
static void entry_mode_select(const bool ac_increase, const bool shift);
|
||||
static void scroll_or_addr_select(const bool sa);
|
||||
static void set_ddram_address(const uint8_t addr);
|
||||
static void set_cgram_address(const uint8_t addr);
|
||||
static void set_gdram_address(const uint8_t x, const uint8_t y);
|
||||
|
||||
static void clear();
|
||||
static void clear_ddram();
|
||||
static void clear_gdram();
|
||||
|
||||
static void load_cgram_icon(const uint16_t addr, const void *data);
|
||||
static void draw_gdram_icon(uint8_t x, uint8_t y, const void *data);
|
||||
|
||||
static uint8_t string_checksum(const char *str);
|
||||
|
||||
protected:
|
||||
static void draw_degree_symbol(uint8_t x, uint8_t y, bool draw);
|
||||
static void draw_static_elements();
|
||||
static void draw_progress_bar(const uint8_t value);
|
||||
static void draw_fan_icon(const bool whichIcon);
|
||||
static void draw_heat_icon(const bool whichIcon, const bool heating);
|
||||
static void draw_temps(uint8_t line, const int16_t temp, const int16_t target, bool showTarget, bool targetStateChange);
|
||||
static void draw_extruder_1_temp(const int16_t temp, const int16_t target, bool forceUpdate = false);
|
||||
static void draw_extruder_2_temp(const int16_t temp, const int16_t target, bool forceUpdate = false);
|
||||
static void draw_bed_temp(const int16_t temp, const int16_t target, bool forceUpdate = false);
|
||||
static void draw_fan_speed(const uint8_t value);
|
||||
static void draw_print_time(const duration_t &elapsed);
|
||||
static void draw_feedrate_percentage(const uint8_t percentage);
|
||||
static void draw_status_message(const char *str);
|
||||
static void draw_position(const float x, const float y, const float z, bool position_known = true);
|
||||
|
||||
static bool indicators_changed();
|
||||
static bool position_changed();
|
||||
static bool blink_changed();
|
||||
static bool status_changed();
|
||||
|
||||
static void update_indicators(const bool forceUpdate);
|
||||
static void update_position(const bool forceUpdate, bool resetChecksum);
|
||||
static void update_status_or_position(bool forceUpdate);
|
||||
static void update_progress(const bool forceUpdate);
|
||||
|
||||
public:
|
||||
static void update(const bool forceUpdate);
|
||||
static void on_entry();
|
||||
static void on_exit();
|
||||
static void clear_text_buffer();
|
||||
};
|
||||
|
||||
#endif // STATUS_SCREEN_LITE_ST7920_CLASS_H
|
|
@ -1,39 +0,0 @@
|
|||
/**
|
||||
* Lightweight Status Screen for the RepRapDiscount Full
|
||||
* Graphics Smart Controller (ST7920-based 128x64 LCD)
|
||||
*
|
||||
* (c) 2017 Aleph Objects, Inc.
|
||||
*
|
||||
* The code in this page is free software: you can
|
||||
* redistribute it and/or modify it under the terms of the GNU
|
||||
* General Public License (GNU GPL) as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option)
|
||||
* any later version. The code is distributed WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU GPL for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "status_screen_lite_ST7920_class.h"
|
||||
|
||||
void ST7920_Lite_Status_Screen::cs() {
|
||||
ST7920_CS();
|
||||
current_bits.synced = false;
|
||||
}
|
||||
|
||||
void ST7920_Lite_Status_Screen::ncs() {
|
||||
ST7920_NCS();
|
||||
current_bits.synced = false;
|
||||
}
|
||||
|
||||
void ST7920_Lite_Status_Screen::sync_cmd() {
|
||||
ST7920_SET_CMD();
|
||||
}
|
||||
|
||||
void ST7920_Lite_Status_Screen::sync_dat() {
|
||||
ST7920_SET_DAT();
|
||||
}
|
||||
|
||||
void ST7920_Lite_Status_Screen::write_byte(const uint8_t data) {
|
||||
ST7920_WRITE_BYTE(data);
|
||||
}
|
|
@ -1,64 +0,0 @@
|
|||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
// 100k bed thermistor in JGAurora A5. Calibrated by Sam Pinches 21st Jan 2018 using cheap k-type thermocouple inserted into heater block, using TM-902C meter.
|
||||
const short temptable_15[][2] PROGMEM = {
|
||||
{ OV( 31), 275 },
|
||||
{ OV( 33), 270 },
|
||||
{ OV( 35), 260 },
|
||||
{ OV( 38), 253 },
|
||||
{ OV( 41), 248 },
|
||||
{ OV( 48), 239 },
|
||||
{ OV( 56), 232 },
|
||||
{ OV( 66), 222 },
|
||||
{ OV( 78), 212 },
|
||||
{ OV( 93), 206 },
|
||||
{ OV( 106), 199 },
|
||||
{ OV( 118), 191 },
|
||||
{ OV( 130), 186 },
|
||||
{ OV( 158), 176 },
|
||||
{ OV( 187), 167 },
|
||||
{ OV( 224), 158 },
|
||||
{ OV( 270), 148 },
|
||||
{ OV( 321), 137 },
|
||||
{ OV( 379), 127 },
|
||||
{ OV( 446), 117 },
|
||||
{ OV( 518), 106 },
|
||||
{ OV( 593), 96 },
|
||||
{ OV( 668), 86 },
|
||||
{ OV( 739), 76 },
|
||||
{ OV( 767), 72 },
|
||||
{ OV( 830), 62 },
|
||||
{ OV( 902), 48 },
|
||||
{ OV( 926), 45 },
|
||||
{ OV( 955), 35 },
|
||||
{ OV( 966), 30 },
|
||||
{ OV( 977), 25 },
|
||||
{ OV( 985), 20 },
|
||||
{ OV( 993), 15 },
|
||||
{ OV( 999), 10 },
|
||||
{ OV(1004), 5 },
|
||||
{ OV(1008), 0 },
|
||||
{ OV(1012), -5 },
|
||||
{ OV(1016), -10 },
|
||||
{ OV(1020), -15 }
|
||||
};
|
|
@ -1,57 +0,0 @@
|
|||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
// 100k Zonestar thermistor. Adjusted By Hally
|
||||
const short temptable_501[][2] PROGMEM = {
|
||||
{OV( 1), 713},
|
||||
{OV( 14), 300}, // Top rating 300C
|
||||
{OV( 16), 290},
|
||||
{OV( 19), 280},
|
||||
{OV( 23), 270},
|
||||
{OV( 27), 260},
|
||||
{OV( 31), 250},
|
||||
{OV( 37), 240},
|
||||
{OV( 47), 230},
|
||||
{OV( 57), 220},
|
||||
{OV( 68), 210},
|
||||
{OV( 84), 200},
|
||||
{OV( 100), 190},
|
||||
{OV( 128), 180},
|
||||
{OV( 155), 170},
|
||||
{OV( 189), 160},
|
||||
{OV( 230), 150},
|
||||
{OV( 278), 140},
|
||||
{OV( 336), 130},
|
||||
{OV( 402), 120},
|
||||
{OV( 476), 110},
|
||||
{OV( 554), 100},
|
||||
{OV( 635), 90},
|
||||
{OV( 713), 80},
|
||||
{OV( 784), 70},
|
||||
{OV( 846), 60},
|
||||
{OV( 897), 50},
|
||||
{OV( 937), 40},
|
||||
{OV( 966), 30},
|
||||
{OV( 986), 20},
|
||||
{OV(1000), 10},
|
||||
{OV(1010), 0}
|
||||
};
|
|
@ -1,631 +0,0 @@
|
|||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "MarlinConfig.h"
|
||||
|
||||
#if HAS_TRINAMIC
|
||||
|
||||
#include "tmc_util.h"
|
||||
#include "Marlin.h"
|
||||
#include "printcounter.h"
|
||||
#include "duration_t.h"
|
||||
#include "stepper_indirection.h"
|
||||
|
||||
#if ENABLED(TMC_DEBUG)
|
||||
#include "planner.h"
|
||||
#endif
|
||||
|
||||
bool report_tmc_status = false;
|
||||
|
||||
/**
|
||||
* Check for over temperature or short to ground error flags.
|
||||
* Report and log warning of overtemperature condition.
|
||||
* Reduce driver current in a persistent otpw condition.
|
||||
* Keep track of otpw counter so we don't reduce current on a single instance,
|
||||
* and so we don't repeatedly report warning before the condition is cleared.
|
||||
*/
|
||||
#if ENABLED(MONITOR_DRIVER_STATUS)
|
||||
struct TMC_driver_data {
|
||||
uint32_t drv_status;
|
||||
bool is_otpw;
|
||||
bool is_ot;
|
||||
bool is_error;
|
||||
};
|
||||
#if HAS_DRIVER(TMC2130)
|
||||
static uint32_t get_pwm_scale(TMC2130Stepper &st) { return st.PWM_SCALE(); }
|
||||
static uint8_t get_status_response(TMC2130Stepper &st) { return st.status_response & 0xF; }
|
||||
static TMC_driver_data get_driver_data(TMC2130Stepper &st) {
|
||||
constexpr uint32_t OTPW_bm = 0x4000000UL;
|
||||
constexpr uint8_t OTPW_bp = 26;
|
||||
constexpr uint32_t OT_bm = 0x2000000UL;
|
||||
constexpr uint8_t OT_bp = 25;
|
||||
constexpr uint8_t DRIVER_ERROR_bm = 0x2UL;
|
||||
constexpr uint8_t DRIVER_ERROR_bp = 1;
|
||||
TMC_driver_data data;
|
||||
data.drv_status = st.DRV_STATUS();
|
||||
data.is_otpw = (data.drv_status & OTPW_bm) >> OTPW_bp;
|
||||
data.is_ot = (data.drv_status & OT_bm) >> OT_bp;
|
||||
data.is_error = (st.status_response & DRIVER_ERROR_bm) >> DRIVER_ERROR_bp;
|
||||
return data;
|
||||
}
|
||||
#endif
|
||||
#if HAS_DRIVER(TMC2208)
|
||||
static uint32_t get_pwm_scale(TMC2208Stepper &st) { return st.pwm_scale_sum(); }
|
||||
static uint8_t get_status_response(TMC2208Stepper &st) {
|
||||
uint32_t drv_status = st.DRV_STATUS();
|
||||
uint8_t gstat = st.GSTAT();
|
||||
uint8_t response = 0;
|
||||
response |= (drv_status >> (31-3)) & 0b1000;
|
||||
response |= gstat & 0b11;
|
||||
return response;
|
||||
}
|
||||
static TMC_driver_data get_driver_data(TMC2208Stepper &st) {
|
||||
constexpr uint32_t OTPW_bm = 0b1ul;
|
||||
constexpr uint8_t OTPW_bp = 0;
|
||||
constexpr uint32_t OT_bm = 0b10ul;
|
||||
constexpr uint8_t OT_bp = 1;
|
||||
TMC_driver_data data;
|
||||
data.drv_status = st.DRV_STATUS();
|
||||
data.is_otpw = (data.drv_status & OTPW_bm) >> OTPW_bp;
|
||||
data.is_ot = (data.drv_status & OT_bm) >> OT_bp;
|
||||
data.is_error = st.drv_err();
|
||||
return data;
|
||||
}
|
||||
#endif
|
||||
|
||||
template<typename TMC>
|
||||
void monitor_tmc_driver(TMC &st, const TMC_AxisEnum axis, uint8_t &otpw_cnt) {
|
||||
TMC_driver_data data = get_driver_data(st);
|
||||
|
||||
#if ENABLED(STOP_ON_ERROR)
|
||||
if (data.is_error) {
|
||||
SERIAL_EOL();
|
||||
_tmc_say_axis(axis);
|
||||
SERIAL_ECHOLNPGM(" driver error detected:");
|
||||
if (data.is_ot) SERIAL_ECHOLNPGM("overtemperature");
|
||||
if (st.s2ga()) SERIAL_ECHOLNPGM("short to ground (coil A)");
|
||||
if (st.s2gb()) SERIAL_ECHOLNPGM("short to ground (coil B)");
|
||||
#if ENABLED(TMC_DEBUG)
|
||||
tmc_report_all();
|
||||
#endif
|
||||
kill(PSTR("Driver error"));
|
||||
}
|
||||
#endif
|
||||
|
||||
// Report if a warning was triggered
|
||||
if (data.is_otpw && otpw_cnt == 0) {
|
||||
char timestamp[10];
|
||||
duration_t elapsed = print_job_timer.duration();
|
||||
const bool has_days = (elapsed.value > 60*60*24L);
|
||||
(void)elapsed.toDigital(timestamp, has_days);
|
||||
SERIAL_EOL();
|
||||
SERIAL_ECHO(timestamp);
|
||||
SERIAL_ECHOPGM(": ");
|
||||
_tmc_say_axis(axis);
|
||||
SERIAL_ECHOPGM(" driver overtemperature warning! (");
|
||||
SERIAL_ECHO(st.getCurrent());
|
||||
SERIAL_ECHOLNPGM("mA)");
|
||||
}
|
||||
#if CURRENT_STEP_DOWN > 0
|
||||
// Decrease current if is_otpw is true and driver is enabled and there's been more than 4 warnings
|
||||
if (data.is_otpw && st.isEnabled() && otpw_cnt > 4) {
|
||||
st.setCurrent(st.getCurrent() - CURRENT_STEP_DOWN, R_SENSE, HOLD_MULTIPLIER);
|
||||
#if ENABLED(REPORT_CURRENT_CHANGE)
|
||||
_tmc_say_axis(axis);
|
||||
SERIAL_ECHOLNPAIR(" current decreased to ", st.getCurrent());
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
if (data.is_otpw) {
|
||||
otpw_cnt++;
|
||||
st.flag_otpw = true;
|
||||
}
|
||||
else if (otpw_cnt > 0) otpw_cnt = 0;
|
||||
|
||||
if (report_tmc_status) {
|
||||
const uint32_t pwm_scale = get_pwm_scale(st);
|
||||
_tmc_say_axis(axis);
|
||||
SERIAL_ECHOPAIR(":", pwm_scale);
|
||||
SERIAL_ECHOPGM(" |0b"); SERIAL_PRINT(get_status_response(st), BIN);
|
||||
SERIAL_ECHOPGM("| ");
|
||||
if (data.is_error) SERIAL_CHAR('E');
|
||||
else if (data.is_ot) SERIAL_CHAR('O');
|
||||
else if (data.is_otpw) SERIAL_CHAR('W');
|
||||
else if (otpw_cnt > 0) SERIAL_PRINT(otpw_cnt, DEC);
|
||||
else if (st.flag_otpw) SERIAL_CHAR('F');
|
||||
SERIAL_CHAR('\t');
|
||||
}
|
||||
}
|
||||
|
||||
#define HAS_HW_COMMS(ST) AXIS_DRIVER_TYPE(ST, TMC2130) || (AXIS_DRIVER_TYPE(ST, TMC2208) && defined(ST##_HARDWARE_SERIAL))
|
||||
|
||||
void monitor_tmc_driver() {
|
||||
static millis_t next_cOT = 0;
|
||||
if (ELAPSED(millis(), next_cOT)) {
|
||||
next_cOT = millis() + 500;
|
||||
#if HAS_HW_COMMS(X)
|
||||
static uint8_t x_otpw_cnt = 0;
|
||||
monitor_tmc_driver(stepperX, TMC_X, x_otpw_cnt);
|
||||
#endif
|
||||
#if HAS_HW_COMMS(Y)
|
||||
static uint8_t y_otpw_cnt = 0;
|
||||
monitor_tmc_driver(stepperY, TMC_Y, y_otpw_cnt);
|
||||
#endif
|
||||
#if HAS_HW_COMMS(Z)
|
||||
static uint8_t z_otpw_cnt = 0;
|
||||
monitor_tmc_driver(stepperZ, TMC_Z, z_otpw_cnt);
|
||||
#endif
|
||||
#if HAS_HW_COMMS(X2)
|
||||
static uint8_t x2_otpw_cnt = 0;
|
||||
monitor_tmc_driver(stepperX2, TMC_X, x2_otpw_cnt);
|
||||
#endif
|
||||
#if HAS_HW_COMMS(Y2)
|
||||
static uint8_t y2_otpw_cnt = 0;
|
||||
monitor_tmc_driver(stepperY2, TMC_Y, y2_otpw_cnt);
|
||||
#endif
|
||||
#if HAS_HW_COMMS(Z2)
|
||||
static uint8_t z2_otpw_cnt = 0;
|
||||
monitor_tmc_driver(stepperZ2, TMC_Z, z2_otpw_cnt);
|
||||
#endif
|
||||
#if HAS_HW_COMMS(E0)
|
||||
static uint8_t e0_otpw_cnt = 0;
|
||||
monitor_tmc_driver(stepperE0, TMC_E0, e0_otpw_cnt);
|
||||
#endif
|
||||
#if HAS_HW_COMMS(E1)
|
||||
static uint8_t e1_otpw_cnt = 0;
|
||||
monitor_tmc_driver(stepperE1, TMC_E1, e1_otpw_cnt);
|
||||
#endif
|
||||
#if HAS_HW_COMMS(E2)
|
||||
static uint8_t e2_otpw_cnt = 0;
|
||||
monitor_tmc_driver(stepperE2, TMC_E2, e2_otpw_cnt);
|
||||
#endif
|
||||
#if HAS_HW_COMMS(E3)
|
||||
static uint8_t e3_otpw_cnt = 0;
|
||||
monitor_tmc_driver(stepperE3, TMC_E3, e3_otpw_cnt);
|
||||
#endif
|
||||
#if HAS_HW_COMMS(E4)
|
||||
static uint8_t e4_otpw_cnt = 0;
|
||||
monitor_tmc_driver(stepperE4, TMC_E4, e4_otpw_cnt);
|
||||
#endif
|
||||
|
||||
if (report_tmc_status) SERIAL_EOL();
|
||||
}
|
||||
}
|
||||
|
||||
#endif // MONITOR_DRIVER_STATUS
|
||||
|
||||
void _tmc_say_axis(const TMC_AxisEnum axis) {
|
||||
static const char ext_X[] PROGMEM = "X", ext_Y[] PROGMEM = "Y", ext_Z[] PROGMEM = "Z",
|
||||
ext_X2[] PROGMEM = "X2", ext_Y2[] PROGMEM = "Y2", ext_Z2[] PROGMEM = "Z2",
|
||||
ext_E0[] PROGMEM = "E0", ext_E1[] PROGMEM = "E1",
|
||||
ext_E2[] PROGMEM = "E2", ext_E3[] PROGMEM = "E3",
|
||||
ext_E4[] PROGMEM = "E4";
|
||||
static const char* const tmc_axes[] PROGMEM = { ext_X, ext_Y, ext_Z, ext_X2, ext_Y2, ext_Z2, ext_E0, ext_E1, ext_E2, ext_E3, ext_E4 };
|
||||
serialprintPGM((char*)pgm_read_ptr(&tmc_axes[axis]));
|
||||
}
|
||||
|
||||
void _tmc_say_current(const TMC_AxisEnum axis, const uint16_t curr) {
|
||||
_tmc_say_axis(axis);
|
||||
SERIAL_ECHOLNPAIR(" driver current: ", curr);
|
||||
}
|
||||
void _tmc_say_otpw(const TMC_AxisEnum axis, const bool otpw) {
|
||||
_tmc_say_axis(axis);
|
||||
SERIAL_ECHOPGM(" temperature prewarn triggered: ");
|
||||
serialprintPGM(otpw ? PSTR("true") : PSTR("false"));
|
||||
SERIAL_EOL();
|
||||
}
|
||||
void _tmc_say_otpw_cleared(const TMC_AxisEnum axis) {
|
||||
_tmc_say_axis(axis);
|
||||
SERIAL_ECHOLNPGM(" prewarn flag cleared");
|
||||
}
|
||||
void _tmc_say_pwmthrs(const TMC_AxisEnum axis, const uint32_t thrs) {
|
||||
_tmc_say_axis(axis);
|
||||
SERIAL_ECHOLNPAIR(" stealthChop max speed: ", thrs);
|
||||
}
|
||||
void _tmc_say_sgt(const TMC_AxisEnum axis, const int8_t sgt) {
|
||||
_tmc_say_axis(axis);
|
||||
SERIAL_ECHOPGM(" homing sensitivity: ");
|
||||
SERIAL_PRINTLN(sgt, DEC);
|
||||
}
|
||||
|
||||
#if ENABLED(TMC_DEBUG)
|
||||
|
||||
enum TMC_debug_enum : char {
|
||||
TMC_CODES,
|
||||
TMC_ENABLED,
|
||||
TMC_CURRENT,
|
||||
TMC_RMS_CURRENT,
|
||||
TMC_MAX_CURRENT,
|
||||
TMC_IRUN,
|
||||
TMC_IHOLD,
|
||||
TMC_CS_ACTUAL,
|
||||
TMC_PWM_SCALE,
|
||||
TMC_VSENSE,
|
||||
TMC_STEALTHCHOP,
|
||||
TMC_MICROSTEPS,
|
||||
TMC_TSTEP,
|
||||
TMC_TPWMTHRS,
|
||||
TMC_TPWMTHRS_MMS,
|
||||
TMC_OTPW,
|
||||
TMC_OTPW_TRIGGERED,
|
||||
TMC_TOFF,
|
||||
TMC_TBL,
|
||||
TMC_HEND,
|
||||
TMC_HSTRT,
|
||||
TMC_SGT
|
||||
};
|
||||
enum TMC_drv_status_enum : char {
|
||||
TMC_DRV_CODES,
|
||||
TMC_STST,
|
||||
TMC_OLB,
|
||||
TMC_OLA,
|
||||
TMC_S2GB,
|
||||
TMC_S2GA,
|
||||
TMC_DRV_OTPW,
|
||||
TMC_OT,
|
||||
TMC_STALLGUARD,
|
||||
TMC_DRV_CS_ACTUAL,
|
||||
TMC_FSACTIVE,
|
||||
TMC_SG_RESULT,
|
||||
TMC_DRV_STATUS_HEX,
|
||||
TMC_T157,
|
||||
TMC_T150,
|
||||
TMC_T143,
|
||||
TMC_T120,
|
||||
TMC_STEALTH,
|
||||
TMC_S2VSB,
|
||||
TMC_S2VSA
|
||||
};
|
||||
static void drv_status_print_hex(const TMC_AxisEnum axis, const uint32_t drv_status) {
|
||||
_tmc_say_axis(axis);
|
||||
SERIAL_ECHOPGM(" = 0x");
|
||||
for (int B = 24; B >= 8; B -= 8){
|
||||
SERIAL_PRINT((drv_status >> (B + 4)) & 0xF, HEX);
|
||||
SERIAL_PRINT((drv_status >> B) & 0xF, HEX);
|
||||
SERIAL_CHAR(':');
|
||||
}
|
||||
SERIAL_PRINT((drv_status >> 4) & 0xF, HEX);
|
||||
SERIAL_PRINT((drv_status) & 0xF, HEX);
|
||||
SERIAL_EOL();
|
||||
}
|
||||
|
||||
#if HAS_DRIVER(TMC2130)
|
||||
static void tmc_status(TMC2130Stepper &st, const TMC_debug_enum i) {
|
||||
switch (i) {
|
||||
case TMC_PWM_SCALE: SERIAL_PRINT(st.PWM_SCALE(), DEC); break;
|
||||
case TMC_TSTEP: SERIAL_ECHO(st.TSTEP()); break;
|
||||
case TMC_SGT: SERIAL_PRINT(st.sgt(), DEC); break;
|
||||
case TMC_STEALTHCHOP: serialprintPGM(st.stealthChop() ? PSTR("true") : PSTR("false")); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
static void tmc_parse_drv_status(TMC2130Stepper &st, const TMC_drv_status_enum i) {
|
||||
switch (i) {
|
||||
case TMC_STALLGUARD: if (st.stallguard()) SERIAL_CHAR('X'); break;
|
||||
case TMC_SG_RESULT: SERIAL_PRINT(st.sg_result(), DEC); break;
|
||||
case TMC_FSACTIVE: if (st.fsactive()) SERIAL_CHAR('X'); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if HAS_DRIVER(TMC2208)
|
||||
static void tmc_status(TMC2208Stepper &st, const TMC_debug_enum i) {
|
||||
switch (i) {
|
||||
case TMC_TSTEP: { uint32_t data = 0; st.TSTEP(&data); SERIAL_PROTOCOL(data); break; }
|
||||
case TMC_PWM_SCALE: SERIAL_PRINT(st.pwm_scale_sum(), DEC); break;
|
||||
case TMC_STEALTHCHOP: serialprintPGM(st.stealth() ? PSTR("true") : PSTR("false")); break;
|
||||
case TMC_S2VSA: if (st.s2vsa()) SERIAL_CHAR('X'); break;
|
||||
case TMC_S2VSB: if (st.s2vsb()) SERIAL_CHAR('X'); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
static void tmc_parse_drv_status(TMC2208Stepper &st, const TMC_drv_status_enum i) {
|
||||
switch (i) {
|
||||
case TMC_T157: if (st.t157()) SERIAL_CHAR('X'); break;
|
||||
case TMC_T150: if (st.t150()) SERIAL_CHAR('X'); break;
|
||||
case TMC_T143: if (st.t143()) SERIAL_CHAR('X'); break;
|
||||
case TMC_T120: if (st.t120()) SERIAL_CHAR('X'); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
template <typename TMC>
|
||||
static void tmc_status(TMC &st, const TMC_AxisEnum axis, const TMC_debug_enum i, const float spmm) {
|
||||
SERIAL_ECHO('\t');
|
||||
switch (i) {
|
||||
case TMC_CODES: _tmc_say_axis(axis); break;
|
||||
case TMC_ENABLED: serialprintPGM(st.isEnabled() ? PSTR("true") : PSTR("false")); break;
|
||||
case TMC_CURRENT: SERIAL_ECHO(st.getCurrent()); break;
|
||||
case TMC_RMS_CURRENT: SERIAL_PROTOCOL(st.rms_current()); break;
|
||||
case TMC_MAX_CURRENT: SERIAL_PRINT((float)st.rms_current() * 1.41, 0); break;
|
||||
case TMC_IRUN:
|
||||
SERIAL_PRINT(st.irun(), DEC);
|
||||
SERIAL_ECHOPGM("/31");
|
||||
break;
|
||||
case TMC_IHOLD:
|
||||
SERIAL_PRINT(st.ihold(), DEC);
|
||||
SERIAL_ECHOPGM("/31");
|
||||
break;
|
||||
case TMC_CS_ACTUAL:
|
||||
SERIAL_PRINT(st.cs_actual(), DEC);
|
||||
SERIAL_ECHOPGM("/31");
|
||||
break;
|
||||
|
||||
case TMC_VSENSE: serialprintPGM(st.vsense() ? PSTR("1=.18") : PSTR("0=.325")); break;
|
||||
|
||||
case TMC_MICROSTEPS: SERIAL_ECHO(st.microsteps()); break;
|
||||
case TMC_TPWMTHRS: {
|
||||
uint32_t tpwmthrs_val = st.TPWMTHRS();
|
||||
SERIAL_ECHO(tpwmthrs_val);
|
||||
}
|
||||
break;
|
||||
case TMC_TPWMTHRS_MMS: {
|
||||
uint32_t tpwmthrs_val = st.TPWMTHRS();
|
||||
if (tpwmthrs_val)
|
||||
SERIAL_ECHO(12650000UL * st.microsteps() / (256 * tpwmthrs_val * spmm));
|
||||
else
|
||||
SERIAL_CHAR('-');
|
||||
}
|
||||
break;
|
||||
case TMC_OTPW: serialprintPGM(st.otpw() ? PSTR("true") : PSTR("false")); break;
|
||||
case TMC_OTPW_TRIGGERED: serialprintPGM(st.getOTPW() ? PSTR("true") : PSTR("false")); break;
|
||||
case TMC_TOFF: SERIAL_PRINT(st.toff(), DEC); break;
|
||||
case TMC_TBL: SERIAL_PRINT(st.blank_time(), DEC); break;
|
||||
case TMC_HEND: SERIAL_PRINT(st.hysteresis_end(), DEC); break;
|
||||
case TMC_HSTRT: SERIAL_PRINT(st.hysteresis_start(), DEC); break;
|
||||
default: tmc_status(st, i); break;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename TMC>
|
||||
static void tmc_parse_drv_status(TMC &st, const TMC_AxisEnum axis, const TMC_drv_status_enum i) {
|
||||
SERIAL_CHAR('\t');
|
||||
switch (i) {
|
||||
case TMC_DRV_CODES: _tmc_say_axis(axis); break;
|
||||
case TMC_STST: if (st.stst()) SERIAL_CHAR('X'); break;
|
||||
case TMC_OLB: if (st.olb()) SERIAL_CHAR('X'); break;
|
||||
case TMC_OLA: if (st.ola()) SERIAL_CHAR('X'); break;
|
||||
case TMC_S2GB: if (st.s2gb()) SERIAL_CHAR('X'); break;
|
||||
case TMC_S2GA: if (st.s2ga()) SERIAL_CHAR('X'); break;
|
||||
case TMC_DRV_OTPW: if (st.otpw()) SERIAL_CHAR('X'); break;
|
||||
case TMC_OT: if (st.ot()) SERIAL_CHAR('X'); break;
|
||||
case TMC_DRV_CS_ACTUAL: SERIAL_PRINT(st.cs_actual(), DEC); break;
|
||||
case TMC_DRV_STATUS_HEX:drv_status_print_hex(axis, st.DRV_STATUS()); break;
|
||||
default: tmc_parse_drv_status(st, i); break;
|
||||
}
|
||||
}
|
||||
|
||||
static void tmc_debug_loop(const TMC_debug_enum i) {
|
||||
#if AXIS_IS_TMC(X)
|
||||
tmc_status(stepperX, TMC_X, i, planner.axis_steps_per_mm[X_AXIS]);
|
||||
#endif
|
||||
#if AXIS_IS_TMC(X2)
|
||||
tmc_status(stepperX2, TMC_X2, i, planner.axis_steps_per_mm[X_AXIS]);
|
||||
#endif
|
||||
|
||||
#if AXIS_IS_TMC(Y)
|
||||
tmc_status(stepperY, TMC_Y, i, planner.axis_steps_per_mm[Y_AXIS]);
|
||||
#endif
|
||||
#if AXIS_IS_TMC(Y2)
|
||||
tmc_status(stepperY2, TMC_Y2, i, planner.axis_steps_per_mm[Y_AXIS]);
|
||||
#endif
|
||||
|
||||
#if AXIS_IS_TMC(Z)
|
||||
tmc_status(stepperZ, TMC_Z, i, planner.axis_steps_per_mm[Z_AXIS]);
|
||||
#endif
|
||||
#if AXIS_IS_TMC(Z2)
|
||||
tmc_status(stepperZ2, TMC_Z2, i, planner.axis_steps_per_mm[Z_AXIS]);
|
||||
#endif
|
||||
|
||||
#if AXIS_IS_TMC(E0)
|
||||
tmc_status(stepperE0, TMC_E0, i, planner.axis_steps_per_mm[E_AXIS]);
|
||||
#endif
|
||||
#if AXIS_IS_TMC(E1)
|
||||
tmc_status(stepperE1, TMC_E1, i, planner.axis_steps_per_mm[E_AXIS
|
||||
#if ENABLED(DISTINCT_E_FACTORS)
|
||||
+ 1
|
||||
#endif
|
||||
]);
|
||||
#endif
|
||||
#if AXIS_IS_TMC(E2)
|
||||
tmc_status(stepperE2, TMC_E2, i, planner.axis_steps_per_mm[E_AXIS
|
||||
#if ENABLED(DISTINCT_E_FACTORS)
|
||||
+ 2
|
||||
#endif
|
||||
]);
|
||||
#endif
|
||||
#if AXIS_IS_TMC(E3)
|
||||
tmc_status(stepperE3, TMC_E3, i, planner.axis_steps_per_mm[E_AXIS
|
||||
#if ENABLED(DISTINCT_E_FACTORS)
|
||||
+ 3
|
||||
#endif
|
||||
]);
|
||||
#endif
|
||||
#if AXIS_IS_TMC(E4)
|
||||
tmc_status(stepperE4, TMC_E4, i, planner.axis_steps_per_mm[E_AXIS
|
||||
#if ENABLED(DISTINCT_E_FACTORS)
|
||||
+ 4
|
||||
#endif
|
||||
]);
|
||||
#endif
|
||||
|
||||
SERIAL_EOL();
|
||||
}
|
||||
|
||||
static void drv_status_loop(const TMC_drv_status_enum i) {
|
||||
#if AXIS_IS_TMC(X)
|
||||
tmc_parse_drv_status(stepperX, TMC_X, i);
|
||||
#endif
|
||||
#if AXIS_IS_TMC(X2)
|
||||
tmc_parse_drv_status(stepperX2, TMC_X2, i);
|
||||
#endif
|
||||
|
||||
#if AXIS_IS_TMC(Y)
|
||||
tmc_parse_drv_status(stepperY, TMC_Y, i);
|
||||
#endif
|
||||
#if AXIS_IS_TMC(Y2)
|
||||
tmc_parse_drv_status(stepperY2, TMC_Y2, i);
|
||||
#endif
|
||||
|
||||
#if AXIS_IS_TMC(Z)
|
||||
tmc_parse_drv_status(stepperZ, TMC_Z, i);
|
||||
#endif
|
||||
#if AXIS_IS_TMC(Z2)
|
||||
tmc_parse_drv_status(stepperZ2, TMC_Z2, i);
|
||||
#endif
|
||||
|
||||
#if AXIS_IS_TMC(E0)
|
||||
tmc_parse_drv_status(stepperE0, TMC_E0, i);
|
||||
#endif
|
||||
#if AXIS_IS_TMC(E1)
|
||||
tmc_parse_drv_status(stepperE1, TMC_E1, i);
|
||||
#endif
|
||||
#if AXIS_IS_TMC(E2)
|
||||
tmc_parse_drv_status(stepperE2, TMC_E2, i);
|
||||
#endif
|
||||
#if AXIS_IS_TMC(E3)
|
||||
tmc_parse_drv_status(stepperE3, TMC_E3, i);
|
||||
#endif
|
||||
#if AXIS_IS_TMC(E4)
|
||||
tmc_parse_drv_status(stepperE4, TMC_E4, i);
|
||||
#endif
|
||||
|
||||
SERIAL_EOL();
|
||||
}
|
||||
|
||||
/**
|
||||
* M122 report functions
|
||||
*/
|
||||
void tmc_set_report_status(const bool status) {
|
||||
if ((report_tmc_status = status))
|
||||
SERIAL_ECHOLNPGM("axis:pwm_scale |status_response|");
|
||||
}
|
||||
|
||||
void tmc_report_all() {
|
||||
#define TMC_REPORT(LABEL, ITEM) do{ SERIAL_ECHOPGM(LABEL); tmc_debug_loop(ITEM); }while(0)
|
||||
#define DRV_REPORT(LABEL, ITEM) do{ SERIAL_ECHOPGM(LABEL); drv_status_loop(ITEM); }while(0)
|
||||
TMC_REPORT("\t", TMC_CODES);
|
||||
TMC_REPORT("Enabled\t", TMC_ENABLED);
|
||||
TMC_REPORT("Set current", TMC_CURRENT);
|
||||
TMC_REPORT("RMS current", TMC_RMS_CURRENT);
|
||||
TMC_REPORT("MAX current", TMC_MAX_CURRENT);
|
||||
TMC_REPORT("Run current", TMC_IRUN);
|
||||
TMC_REPORT("Hold current", TMC_IHOLD);
|
||||
TMC_REPORT("CS actual\t", TMC_CS_ACTUAL);
|
||||
TMC_REPORT("PWM scale\t", TMC_PWM_SCALE);
|
||||
TMC_REPORT("vsense\t", TMC_VSENSE);
|
||||
TMC_REPORT("stealthChop", TMC_STEALTHCHOP);
|
||||
TMC_REPORT("msteps\t", TMC_MICROSTEPS);
|
||||
TMC_REPORT("tstep\t", TMC_TSTEP);
|
||||
TMC_REPORT("pwm\nthreshold\t", TMC_TPWMTHRS);
|
||||
TMC_REPORT("[mm/s]\t", TMC_TPWMTHRS_MMS);
|
||||
TMC_REPORT("OT prewarn", TMC_OTPW);
|
||||
TMC_REPORT("OT prewarn has\n"
|
||||
"been triggered", TMC_OTPW_TRIGGERED);
|
||||
TMC_REPORT("off time\t", TMC_TOFF);
|
||||
TMC_REPORT("blank time", TMC_TBL);
|
||||
TMC_REPORT("hysteresis\n-end\t", TMC_HEND);
|
||||
TMC_REPORT("-start\t", TMC_HSTRT);
|
||||
TMC_REPORT("Stallguard thrs", TMC_SGT);
|
||||
|
||||
DRV_REPORT("DRVSTATUS", TMC_DRV_CODES);
|
||||
#if HAS_DRIVER(TMC2130)
|
||||
DRV_REPORT("stallguard\t", TMC_STALLGUARD);
|
||||
DRV_REPORT("sg_result\t", TMC_SG_RESULT);
|
||||
DRV_REPORT("fsactive\t", TMC_FSACTIVE);
|
||||
#endif
|
||||
DRV_REPORT("stst\t", TMC_STST);
|
||||
DRV_REPORT("olb\t", TMC_OLB);
|
||||
DRV_REPORT("ola\t", TMC_OLA);
|
||||
DRV_REPORT("s2gb\t", TMC_S2GB);
|
||||
DRV_REPORT("s2ga\t", TMC_S2GA);
|
||||
DRV_REPORT("otpw\t", TMC_DRV_OTPW);
|
||||
DRV_REPORT("ot\t", TMC_OT);
|
||||
#if HAS_DRIVER(TMC2208)
|
||||
DRV_REPORT("157C\t", TMC_T157);
|
||||
DRV_REPORT("150C\t", TMC_T150);
|
||||
DRV_REPORT("143C\t", TMC_T143);
|
||||
DRV_REPORT("120C\t", TMC_T120);
|
||||
DRV_REPORT("s2vsa\t", TMC_S2VSA);
|
||||
DRV_REPORT("s2vsb\t", TMC_S2VSB);
|
||||
#endif
|
||||
DRV_REPORT("Driver registers:", TMC_DRV_STATUS_HEX);
|
||||
SERIAL_EOL();
|
||||
}
|
||||
|
||||
#endif // TMC_DEBUG
|
||||
|
||||
#if ENABLED(SENSORLESS_HOMING)
|
||||
|
||||
void tmc_sensorless_homing(TMC2130Stepper &st, const bool enable/*=true*/) {
|
||||
st.coolstep_min_speed(enable ? 1024UL * 1024UL - 1UL : 0);
|
||||
#if ENABLED(STEALTHCHOP)
|
||||
st.stealthChop(!enable);
|
||||
#endif
|
||||
st.diag1_stall(enable ? 1 : 0);
|
||||
}
|
||||
|
||||
#endif // SENSORLESS_HOMING
|
||||
|
||||
#if HAS_DRIVER(TMC2130)
|
||||
#define SET_CS_PIN(st) OUT_WRITE(st##_CS_PIN, HIGH)
|
||||
void tmc_init_cs_pins() {
|
||||
#if AXIS_DRIVER_TYPE(X, TMC2130)
|
||||
SET_CS_PIN(X);
|
||||
#endif
|
||||
#if AXIS_DRIVER_TYPE(Y, TMC2130)
|
||||
SET_CS_PIN(Y);
|
||||
#endif
|
||||
#if AXIS_DRIVER_TYPE(Z, TMC2130)
|
||||
SET_CS_PIN(Z);
|
||||
#endif
|
||||
#if AXIS_DRIVER_TYPE(X2, TMC2130)
|
||||
SET_CS_PIN(X2);
|
||||
#endif
|
||||
#if AXIS_DRIVER_TYPE(Y2, TMC2130)
|
||||
SET_CS_PIN(Y2);
|
||||
#endif
|
||||
#if AXIS_DRIVER_TYPE(Z2, TMC2130)
|
||||
SET_CS_PIN(Z2);
|
||||
#endif
|
||||
#if AXIS_DRIVER_TYPE(E0, TMC2130)
|
||||
SET_CS_PIN(E0);
|
||||
#endif
|
||||
#if AXIS_DRIVER_TYPE(E1, TMC2130)
|
||||
SET_CS_PIN(E1);
|
||||
#endif
|
||||
#if AXIS_DRIVER_TYPE(E2, TMC2130)
|
||||
SET_CS_PIN(E2);
|
||||
#endif
|
||||
#if AXIS_DRIVER_TYPE(E3, TMC2130)
|
||||
SET_CS_PIN(E3);
|
||||
#endif
|
||||
#if AXIS_DRIVER_TYPE(E4, TMC2130)
|
||||
SET_CS_PIN(E4);
|
||||
#endif
|
||||
}
|
||||
#endif // TMC2130
|
||||
|
||||
#endif // HAS_TRINAMIC
|
|
@ -1,107 +0,0 @@
|
|||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _TMC_UTIL_H_
|
||||
#define _TMC_UTIL_H_
|
||||
|
||||
#include "MarlinConfig.h"
|
||||
|
||||
#if HAS_DRIVER(TMC2130)
|
||||
#include <TMC2130Stepper.h>
|
||||
#endif
|
||||
|
||||
#if HAS_DRIVER(TMC2208)
|
||||
#include <TMC2208Stepper.h>
|
||||
#endif
|
||||
|
||||
extern bool report_tmc_status;
|
||||
|
||||
enum TMC_AxisEnum : char { TMC_X, TMC_Y, TMC_Z, TMC_X2, TMC_Y2, TMC_Z2, TMC_E0, TMC_E1, TMC_E2, TMC_E3, TMC_E4 };
|
||||
|
||||
constexpr uint32_t _tmc_thrs(const uint16_t msteps, const int32_t thrs, const uint32_t spmm) {
|
||||
return 12650000UL * msteps / (256 * thrs * spmm);
|
||||
}
|
||||
|
||||
void _tmc_say_axis(const TMC_AxisEnum axis);
|
||||
void _tmc_say_current(const TMC_AxisEnum axis, const uint16_t curr);
|
||||
void _tmc_say_otpw(const TMC_AxisEnum axis, const bool otpw);
|
||||
void _tmc_say_otpw_cleared(const TMC_AxisEnum axis);
|
||||
void _tmc_say_pwmthrs(const TMC_AxisEnum axis, const uint32_t thrs);
|
||||
void _tmc_say_sgt(const TMC_AxisEnum axis, const int8_t sgt);
|
||||
|
||||
template<typename TMC>
|
||||
void tmc_get_current(TMC &st, const TMC_AxisEnum axis) {
|
||||
_tmc_say_current(axis, st.getCurrent());
|
||||
}
|
||||
template<typename TMC>
|
||||
void tmc_set_current(TMC &st, const int mA) {
|
||||
st.setCurrent(mA, R_SENSE, HOLD_MULTIPLIER);
|
||||
}
|
||||
template<typename TMC>
|
||||
void tmc_report_otpw(TMC &st, const TMC_AxisEnum axis) {
|
||||
_tmc_say_otpw(axis, st.getOTPW());
|
||||
}
|
||||
template<typename TMC>
|
||||
void tmc_clear_otpw(TMC &st, const TMC_AxisEnum axis) {
|
||||
st.clear_otpw();
|
||||
_tmc_say_otpw_cleared(axis);
|
||||
}
|
||||
template<typename TMC>
|
||||
void tmc_get_pwmthrs(TMC &st, const TMC_AxisEnum axis, const uint16_t spmm) {
|
||||
_tmc_say_pwmthrs(axis, _tmc_thrs(st.microsteps(), st.TPWMTHRS(), spmm));
|
||||
}
|
||||
template<typename TMC>
|
||||
void tmc_set_pwmthrs(TMC &st, const int32_t thrs, const uint32_t spmm) {
|
||||
st.TPWMTHRS(_tmc_thrs(st.microsteps(), thrs, spmm));
|
||||
}
|
||||
template<typename TMC>
|
||||
void tmc_get_sgt(TMC &st, const TMC_AxisEnum axis) {
|
||||
_tmc_say_sgt(axis, st.sgt());
|
||||
}
|
||||
template<typename TMC>
|
||||
void tmc_set_sgt(TMC &st, const int8_t sgt_val) {
|
||||
st.sgt(sgt_val);
|
||||
}
|
||||
|
||||
void monitor_tmc_driver();
|
||||
|
||||
#if ENABLED(TMC_DEBUG)
|
||||
void tmc_set_report_status(const bool status);
|
||||
void tmc_report_all();
|
||||
#endif
|
||||
|
||||
/**
|
||||
* TMC2130 specific sensorless homing using stallGuard2.
|
||||
* stallGuard2 only works when in spreadCycle mode.
|
||||
* spreadCycle and stealthChop are mutually exclusive.
|
||||
*
|
||||
* Defined here because of limitations with templates and headers.
|
||||
*/
|
||||
#if ENABLED(SENSORLESS_HOMING)
|
||||
void tmc_sensorless_homing(TMC2130Stepper &st, const bool enable=true);
|
||||
#endif
|
||||
|
||||
#if HAS_DRIVER(TMC2130)
|
||||
void tmc_init_cs_pins();
|
||||
#endif
|
||||
|
||||
#endif // _TMC_UTIL_H_
|
|
@ -1,47 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
#
|
||||
# travis_at_home
|
||||
#
|
||||
# Run all Travis test builds at home to save time finding typos
|
||||
# Make sure to have 'arduino' somewhere in your PATH
|
||||
#
|
||||
|
||||
LOG="travis-out.txt"
|
||||
|
||||
cd `dirname "$0"`/../..
|
||||
|
||||
TRAVIS_BUILD_DIR=`pwd`
|
||||
echo $'Tests for '$TRAVIS_BUILD_DIR$' ...\n' >"$LOG"
|
||||
|
||||
# Add a temporary execution PATH
|
||||
export PATH="./buildroot/bin:$PATH"
|
||||
|
||||
# Scan .travis.yml and run config/build commands only
|
||||
X=1
|
||||
while read P; do
|
||||
|
||||
# Command lines start with a hyphen
|
||||
if [[ $P =~ ^-\ (([^ ]+)(\ .*)?)$ ]]; then
|
||||
WORD="${BASH_REMATCH[2]}" ; # The first word
|
||||
CMD="${BASH_REMATCH[1]}" ; # The whole command
|
||||
RUN=1 ; BUILD=0
|
||||
case "$WORD" in
|
||||
cp|opt_*|pins_*|use_*|restore_*|gen*) ;;
|
||||
build_*) BUILD=1 ;;
|
||||
*) RUN=0 ;;
|
||||
esac
|
||||
|
||||
# Runnable command
|
||||
if [[ $RUN == 1 ]]; then
|
||||
echo "$CMD" >>"$LOG"
|
||||
RESULT=$( eval "$CMD >>\"$LOG\" 2>&1" )
|
||||
if [[ $BUILD == 1 ]]; then
|
||||
echo "--- Build $X done."
|
||||
echo >>"$LOG"
|
||||
X=$((X+1))
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
done <.travis.yml
|
||||
|
||||
cd - >/dev/null
|
|
@ -1,20 +0,0 @@
|
|||
{
|
||||
"build": {
|
||||
"core": "teensy",
|
||||
"extra_flags": "-DTEENSY2PP",
|
||||
"f_cpu": "16000000L",
|
||||
"mcu": "at90usb1286"
|
||||
},
|
||||
"frameworks": [
|
||||
"arduino"
|
||||
],
|
||||
"name": "at90usb1286.json",
|
||||
"upload": {
|
||||
"maximum_ram_size": 8192,
|
||||
"maximum_size": 122880,
|
||||
"require_upload_port": true,
|
||||
"protocol": ""
|
||||
},
|
||||
"url": "https://github.com/MarlinFirmware/Marlin",
|
||||
"vendor": "various"
|
||||
}
|
|
@ -1,141 +0,0 @@
|
|||
#
|
||||
# Builds custom upload command
|
||||
# 1) Run platformio as a subprocess to find a COM port
|
||||
# 2) Build the upload command
|
||||
# 3) Exit and let upload tool do the work
|
||||
#
|
||||
# This script runs between completion of the library/dependencies installation and compilation.
|
||||
#
|
||||
# Will continue on if a COM port isn't found so that the compilation can be done.
|
||||
#
|
||||
|
||||
import subprocess
|
||||
import os
|
||||
import sys
|
||||
from SCons.Script import DefaultEnvironment
|
||||
import platform
|
||||
current_OS = platform.system()
|
||||
|
||||
env = DefaultEnvironment()
|
||||
|
||||
build_type = os.environ.get("BUILD_TYPE", 'Not Set')
|
||||
|
||||
|
||||
if not(build_type == 'upload' or build_type == 'traceback' or build_type == 'Not Set') :
|
||||
env.Replace(UPLOAD_PROTOCOL = 'teensy-gui') # run normal Teensy2 scripts
|
||||
else:
|
||||
com_first = ''
|
||||
com_last = ''
|
||||
com_CDC = ''
|
||||
description_first = ''
|
||||
description_last = ''
|
||||
description_CDC = ''
|
||||
|
||||
#
|
||||
# grab the first com port that pops up unless we find one we know for sure
|
||||
# is a CDC device
|
||||
#
|
||||
def get_com_port(com_search_text, descr_search_text, start):
|
||||
|
||||
global com_first
|
||||
global com_last
|
||||
global com_CDC
|
||||
global description_first
|
||||
global description_last
|
||||
global description_CDC
|
||||
|
||||
|
||||
print '\nLooking for Serial Port\n'
|
||||
|
||||
# stream output from subprocess and split it into lines
|
||||
pio_subprocess = subprocess.Popen(['platformio', 'device', 'list'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
|
||||
looking_for_description = False
|
||||
for line in iter(pio_subprocess.stdout.readline, ''):
|
||||
if 0 <= line.find(com_search_text):
|
||||
looking_for_description = True
|
||||
com_last = line.replace('\n', '')
|
||||
if com_first == '':
|
||||
com_first = com_last
|
||||
if 0 <= line.find(descr_search_text) and looking_for_description:
|
||||
looking_for_description = False
|
||||
description_last = line[ start : ]
|
||||
if description_first == '':
|
||||
description_first = description_last
|
||||
if 0 <= description_last.find('CDC'):
|
||||
com_CDC = com_last
|
||||
description_CDC = description_last
|
||||
|
||||
if com_CDC == '' and not(com_first == ''):
|
||||
com_CDC = com_first
|
||||
description_CDC = description_first
|
||||
elif com_CDC == '':
|
||||
com_CDC = 'COM_PORT_NOT_FOUND'
|
||||
|
||||
while 0 <= com_CDC.find('\n'):
|
||||
com_CDC = com_CDC.replace('\n', '')
|
||||
while 0 <= com_CDC.find('\r'):
|
||||
com_CDC = com_CDC.replace('\r', '')
|
||||
|
||||
if com_CDC == 'COM_PORT_NOT_FOUND':
|
||||
print com_CDC, '\n'
|
||||
else:
|
||||
print 'FOUND: ' ,com_CDC
|
||||
print 'DESCRIPTION: ', description_CDC , '\n'
|
||||
|
||||
if current_OS == 'Windows':
|
||||
|
||||
get_com_port('COM', 'Hardware ID:', 13)
|
||||
|
||||
# avrdude_conf_path = env.get("PIOHOME_DIR") + '\\packages\\toolchain-atmelavr\\etc\\avrdude.conf'
|
||||
avrdude_conf_path = 'buildroot\\share\\atom\\avrdude.conf'
|
||||
|
||||
avrdude_exe_path = 'buildroot\\share\\atom\\avrdude_5.10.exe'
|
||||
|
||||
# source_path = env.get("PROJECTBUILD_DIR") + '\\' + env.get("PIOENV") + '\\firmware.hex'
|
||||
source_path = '.pioenvs\\' + env.get("PIOENV") + '\\firmware.hex'
|
||||
|
||||
upload_string = avrdude_exe_path + ' -p usb1286 -c avr109 -P ' + com_CDC + ' -U flash:w:' + source_path + ':i'
|
||||
|
||||
|
||||
if current_OS == 'Darwin': # MAC
|
||||
|
||||
get_com_port('usbmodem', 'Description:', 13)
|
||||
|
||||
# avrdude_conf_path = env.get("PIOHOME_DIR") + '/packages/toolchain-atmelavr/etc/avrdude.conf'
|
||||
avrdude_conf_path = 'buildroot/share/atom/avrdude_macOS.conf'
|
||||
|
||||
|
||||
avrdude_exe_path = 'buildroot/share/atom/avrdude_5.10_macOS'
|
||||
|
||||
# source_path = env.get("PROJECTBUILD_DIR") + '/' + env.get("PIOENV") + '/firmware.hex'
|
||||
source_path = '.pioenvs/' + env.get("PIOENV") + '/firmware.hex'
|
||||
|
||||
|
||||
# upload_string = 'avrdude -p usb1286 -c avr109 -P ' + com_CDC + ' -U flash:w:' + source_path + ':i'
|
||||
upload_string = avrdude_exe_path + ' -p usb1286 -c avr109 -P ' + com_CDC + ' -C ' + avrdude_conf_path + ' -U flash:w:' + source_path + ':i'
|
||||
print 'upload_string: ', upload_string
|
||||
|
||||
|
||||
|
||||
if current_OS == 'Linux':
|
||||
|
||||
get_com_port('/dev/tty', 'Description:', 13)
|
||||
|
||||
# avrdude_conf_path = env.get("PIOHOME_DIR") + '/packages/toolchain-atmelavr/etc/avrdude.conf'
|
||||
avrdude_conf_path = 'buildroot/share/atom/avrdude_linux.conf'
|
||||
|
||||
|
||||
avrdude_exe_path = 'buildroot/share/atom/avrdude_5.10_linux'
|
||||
# source_path = env.get("PROJECTBUILD_DIR") + '/' + env.get("PIOENV") + '/firmware.hex'
|
||||
source_path = '.pioenvs/' + env.get("PIOENV") + '/firmware.hex'
|
||||
|
||||
# upload_string = 'avrdude -p usb1286 -c avr109 -P ' + com_CDC + ' -U flash:w:' + source_path + ':i'
|
||||
upload_string = avrdude_exe_path + ' -p usb1286 -c avr109 -P ' + com_CDC + ' -C ' + avrdude_conf_path + ' -U flash:w:' + source_path + ':i'
|
||||
|
||||
|
||||
env.Replace(
|
||||
UPLOADCMD = upload_string,
|
||||
MAXIMUM_RAM_SIZE = 8192,
|
||||
MAXIMUM_SIZE = 130048
|
||||
)
|
|
@ -1,42 +0,0 @@
|
|||
#
|
||||
# Builds custom upload command
|
||||
# 1) Run platformio as a subprocess to find a COM port
|
||||
# 2) Build the upload command
|
||||
# 3) Exit and let upload tool do the work
|
||||
#
|
||||
# This script runs between completion of the library/dependencies installation and compilation.
|
||||
#
|
||||
# Will continue on if a COM port isn't found so that the compilation can be done.
|
||||
#
|
||||
|
||||
import os
|
||||
import sys
|
||||
from SCons.Script import DefaultEnvironment
|
||||
import platform
|
||||
current_OS = platform.system()
|
||||
|
||||
env = DefaultEnvironment()
|
||||
|
||||
build_type = os.environ.get("BUILD_TYPE", 'Not Set')
|
||||
if not(build_type == 'upload' or build_type == 'traceback' or build_type == 'Not Set') :
|
||||
env.Replace(UPLOAD_PROTOCOL = 'teensy-gui') # run normal Teensy2 scripts
|
||||
else:
|
||||
|
||||
if current_OS == 'Windows':
|
||||
avrdude_conf_path = env.get("PIOHOME_DIR") + '\\packages\\toolchain-atmelavr\\etc\\avrdude.conf'
|
||||
|
||||
source_path = env.get("PROJECTBUILD_DIR") + '\\' + env.get("PIOENV") + '\\firmware.hex'
|
||||
|
||||
upload_string = 'avrdude -p usb1286 -c flip1 -C ' + avrdude_conf_path + ' -U flash:w:' + source_path + ':i'
|
||||
|
||||
else:
|
||||
source_path = env.get("PROJECTBUILD_DIR") + '/' + env.get("PIOENV") + '/firmware.hex'
|
||||
|
||||
upload_string = 'avrdude -p usb1286 -c flip1 -U flash:w:' + source_path + ':i'
|
||||
|
||||
|
||||
env.Replace(
|
||||
UPLOADCMD = upload_string,
|
||||
MAXIMUM_RAM_SIZE = 8192,
|
||||
MAXIMUM_SIZE = 130048
|
||||
)
|
|
@ -1,27 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
#
|
||||
# mffp
|
||||
#
|
||||
# Push the given commit (or HEAD) upstream immediately.
|
||||
# By default: `git push upstream HEAD:bugfix-1.1.x`
|
||||
#
|
||||
|
||||
[[ $# < 3 && $1 != "-h" && $1 != "--help" ]] || { echo "Usage: `basename $0` [1|2] [commit-id]" 1>&2 ; exit 1; }
|
||||
|
||||
if [[ $1 == '1' || $1 == '2' ]]; then
|
||||
MFINFO=$(mfinfo "$1") || exit 1
|
||||
REF=${2:-HEAD}
|
||||
else
|
||||
MFINFO=$(mfinfo) || exit 1
|
||||
REF=${1:-HEAD}
|
||||
fi
|
||||
|
||||
IFS=' ' read -a INFO <<< "$MFINFO"
|
||||
ORG=${INFO[0]}
|
||||
TARG=${INFO[3]}
|
||||
|
||||
if [[ $ORG == "MarlinFirmware" ]]; then
|
||||
git push upstream $REF:$TARG
|
||||
else
|
||||
echo "Not a MarlinFirmware working copy."; exit 1
|
||||
fi
|
|
@ -1,25 +0,0 @@
|
|||
{
|
||||
"folders":
|
||||
[
|
||||
{
|
||||
"file_exclude_patterns":
|
||||
[
|
||||
"Marlin/platformio.ini",
|
||||
"Marlin/.travis.yml",
|
||||
"Marlin/.gitignore",
|
||||
"Marlin/*/platformio.ini",
|
||||
"Marlin/*/.travis.yml",
|
||||
"Marlin/*/.gitignore"
|
||||
],
|
||||
"folder_exclude_patterns":
|
||||
[
|
||||
".pio*",
|
||||
"Marlin/lib",
|
||||
"datatmp",
|
||||
"Marlin/*/src",
|
||||
".vscode"
|
||||
],
|
||||
"path": "../../.."
|
||||
}
|
||||
]
|
||||
}
|
|
@ -1,40 +0,0 @@
|
|||
Overview:
|
||||
1) Install Sublime
|
||||
2) Install Deviot (?optional?)
|
||||
3) Install WebDevShell (this will execute the auto-build script)
|
||||
4) Copy the menu configuration to the proper Sublime directory
|
||||
5) Add platformio to your path (usually not needed)
|
||||
|
||||
|
||||
Sublime with autobuild
|
||||
Tools
|
||||
Install Package Control
|
||||
Tools
|
||||
Command Palette
|
||||
Package Control: Install Package
|
||||
type in deviot and click on it
|
||||
Tools
|
||||
Command Palette
|
||||
Package Control: Install Package
|
||||
type in WebDevShell and click on it
|
||||
|
||||
in Sublime, open Marlin directory with "platformio.ini" in it
|
||||
|
||||
starting in the top level directory, go to the folder "Buildroot/shared/Sublime"
|
||||
copy the folder "auto_build_sublime_menu" and contents to:
|
||||
Windows
|
||||
\Users\your_user_name\AppData\Roaming\Sublime Text 3\Packages
|
||||
Linux
|
||||
/home/your_user_name/.config/sublime-text-3/Packages/User
|
||||
macOS (Click on the Finder's 'Go' menu and hold down Option to open...)
|
||||
~/Library/Application Support/Sublime Text 3/Packages/User
|
||||
|
||||
The menu should now be visible
|
||||
|
||||
If you get an error message that says "file not found" and "subprocess.Popen(['platformio' ... "
|
||||
then you'll need to add platformio to your path.
|
||||
macOS
|
||||
sudo nano /etc/paths
|
||||
add these to the bottom
|
||||
/Users/bob/.platformio
|
||||
/Users/bob/.platformio/penv/bin
|
|
@ -1,66 +0,0 @@
|
|||
[
|
||||
|
||||
{
|
||||
"caption": "Auto Build",
|
||||
"children": [
|
||||
{
|
||||
"caption": "PIO Build",
|
||||
"command": "webdevshell",
|
||||
"args": {
|
||||
"command": "python buildroot/share/atom/auto_build.py build"
|
||||
}
|
||||
},
|
||||
{
|
||||
"caption": "PIO Clean",
|
||||
"command": "webdevshell",
|
||||
"args": {
|
||||
"command": "python buildroot/share/atom/auto_build.py clean"
|
||||
}
|
||||
},
|
||||
{
|
||||
"caption": "PIO Upload",
|
||||
"command": "webdevshell",
|
||||
"args": {
|
||||
"command": "python buildroot/share/atom/auto_build.py upload"
|
||||
}
|
||||
},
|
||||
{
|
||||
"caption": "PIO Upload (traceback)",
|
||||
"command": "webdevshell",
|
||||
"args": {
|
||||
"command": "python buildroot/share/atom/auto_build.py traceback"
|
||||
}
|
||||
},
|
||||
{
|
||||
"caption": "PIO Upload using Programmer",
|
||||
"command": "webdevshell",
|
||||
"args": {
|
||||
"command": "python buildroot/share/atom/auto_build.py program"
|
||||
}
|
||||
},
|
||||
{
|
||||
"caption": "PIO Test",
|
||||
"command": "webdevshell",
|
||||
"args": {
|
||||
"command": "python buildroot/share/atom/auto_build.py test"
|
||||
}
|
||||
},
|
||||
{
|
||||
"caption": "PIO Debug",
|
||||
"command": "webdevshell",
|
||||
"args": {
|
||||
"command": "python buildroot/share/atom/auto_build.py debug"
|
||||
}
|
||||
},
|
||||
{
|
||||
"caption": "PIO Remote",
|
||||
"command": "webdevshell",
|
||||
"args": {
|
||||
"command": "python buildroot/share/atom/auto_build.py remote"
|
||||
}
|
||||
}
|
||||
],
|
||||
"id": "AutoBuild",
|
||||
"mnemonic": "A"
|
||||
}
|
||||
]
|
|
@ -1,2 +0,0 @@
|
|||
out
|
||||
node_modules
|
|
@ -1,9 +0,0 @@
|
|||
.vscode/**
|
||||
.vscode-test/**
|
||||
out/test/**
|
||||
test/**
|
||||
src/**
|
||||
**/*.map
|
||||
.gitignore
|
||||
tsconfig.json
|
||||
vsc-extension-quickstart.md
|
|
@ -1,52 +0,0 @@
|
|||
# Auto Build support for Visual Studio Code
|
||||
This `Visual Studio Code` extension provides access to the `Auto Build` script.
|
||||
|
||||
## Installation
|
||||
|
||||
Get the MarlinFirmware repository from GitHub. Open the directory `buildroot/share/vscode` and copy the `AutoBuildMarlin` folder to the `Visual Studio Code` extension directory. Relaunch `Visual Studio Code` to complete the installation.
|
||||
|
||||
To find the `Visual Studio Code` extension directory:
|
||||
|
||||
- Windows - Use Windows Explorer's address bar to open `C:/Users/USERNAME/.vscode/extensions`.
|
||||
- Mac - Use the Finder's `Go` menu to open `~/.vscode/extensions`.
|
||||
- Linux - In the Terminal type `open ~/.vscode/extensions`.
|
||||
|
||||
### 3. Install the PlatformIO extension
|
||||
Click on `View` > `Command Palette...`
|
||||
|
||||
![](./resources/view_command_palette.png)
|
||||
|
||||
Find and click on `Extensions: Install Extensions`
|
||||
|
||||
![](./resources/install_extensions.png)
|
||||
|
||||
Type `platformio` into the search box and click on `Install` under `PlatformIO IDE`.
|
||||
|
||||
![](./resources/platformio_install.png)
|
||||
|
||||
## Usage
|
||||
|
||||
This extension adds the Auto Build icon ![](./media/AB.svg) to the Activities bar.
|
||||
|
||||
### 1. Open the Marlin folder
|
||||
Click on `File` > `Open Folder...`
|
||||
|
||||
![](./resources/Open_Folder.png)
|
||||
|
||||
This brings up the `Open Folder` dialog. Select the folder that has the `platformio.ini` file in it.
|
||||
|
||||
![](./resources/Open_Marlin.png)
|
||||
|
||||
You should see something like the following. If not, click on the Explorer icon in the Activities bar.
|
||||
|
||||
![](./resources/Activity_bar.png)
|
||||
|
||||
### 2. Click on the Auto Build Icon ![](./media/AB.svg)
|
||||
This brings up the Auto Build menu icon bar.
|
||||
![](./resources/AB_menu.png)
|
||||
|
||||
### 3. Click on one of the four icons
|
||||
- ![](./resources/B_small.svg) - Clicking on it starts `PIO Build`
|
||||
- ![](./resources/C_small.svg) - Clicking on it starts `PIO Clean`
|
||||
- ![](./resources/U_small.svg) - Clicking on it starts `PIO Upload`
|
||||
- ![](./resources/Ut_small.svg) - Clicking on it starts `PIO Upload (traceback)`
|
|
@ -1,37 +0,0 @@
|
|||
'use strict';
|
||||
|
||||
var vscode = require('vscode');
|
||||
|
||||
function activate(context) {
|
||||
|
||||
console.log('Extension "AutoBuildMarlin" is now active!');
|
||||
|
||||
var NEXT_TERM_ID = 1;
|
||||
var pio_build = vscode.commands.registerCommand('piobuild', function () {
|
||||
const terminal = vscode.window.createTerminal(`#${NEXT_TERM_ID++}`);
|
||||
terminal.sendText("python buildroot/share/atom/auto_build.py build");
|
||||
});
|
||||
var pio_clean = vscode.commands.registerCommand('pioclean', function () {
|
||||
const terminal = vscode.window.createTerminal(`#${NEXT_TERM_ID++}`);
|
||||
terminal.sendText("python buildroot/share/atom/auto_build.py clean");
|
||||
});
|
||||
var pio_upload = vscode.commands.registerCommand('pioupload', function () {
|
||||
const terminal = vscode.window.createTerminal(`#${NEXT_TERM_ID++}`);
|
||||
terminal.sendText("python buildroot/share/atom/auto_build.py upload");
|
||||
});
|
||||
var pio_traceback = vscode.commands.registerCommand('piotraceback', function () {
|
||||
const terminal = vscode.window.createTerminal(`#${NEXT_TERM_ID++}`);
|
||||
terminal.sendText("python buildroot/share/atom/auto_build.py traceback");
|
||||
});
|
||||
|
||||
context.subscriptions.push(pio_build);
|
||||
context.subscriptions.push(pio_clean);
|
||||
context.subscriptions.push(pio_upload);
|
||||
context.subscriptions.push(pio_traceback);
|
||||
}
|
||||
exports.activate = activate;
|
||||
|
||||
// this method is called when your extension is deactivated
|
||||
function deactivate() {
|
||||
}
|
||||
exports.deactivate = deactivate;
|
|
@ -1,12 +0,0 @@
|
|||
<svg width="50" height="40" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<!-- Created with SVG-edit - http://svg-edit.googlecode.com/ -->
|
||||
<title>VScode view icon</title>
|
||||
<g stroke="null">
|
||||
<title>Layer 2</title>
|
||||
<text stroke="#000000" transform="matrix(0.8130887717336464,0,0,1,5.526016946709532,0) " xml:space="preserve" text-anchor="middle" font-family="serif" font-size="24" id="svg_2" y="28.27701" x="24.48401" stroke-width="0" fill="#ffffff">AB</text>
|
||||
</g>
|
||||
<g>
|
||||
<title>Layer 1</title>
|
||||
<rect fill-opacity="0" id="svg_1" height="28" width="28" y="6" x="11" stroke-width="0.5" stroke="#ffffff" fill="#000000"/>
|
||||
</g>
|
||||
</svg>
|
Before Width: | Height: | Size: 666 B |
|
@ -1,96 +0,0 @@
|
|||
{
|
||||
"name": "auto-build",
|
||||
"displayName": "Auto Build Marlin",
|
||||
"description": "Auto Build Marlin for VS code",
|
||||
"version": "0.1.0",
|
||||
"publisher": "marlinfirmware",
|
||||
"engines": {
|
||||
"vscode": "^1.23.0"
|
||||
},
|
||||
"enableProposedApi": true,
|
||||
"categories": [
|
||||
"Other"
|
||||
],
|
||||
"activationEvents": [
|
||||
"onCommand:piobuild",
|
||||
"onCommand:pioclean",
|
||||
"onCommand:pioupload",
|
||||
"onCommand:piotraceback"
|
||||
],
|
||||
"main": "./extension",
|
||||
"contributes": {
|
||||
"viewsContainers": {
|
||||
"activitybar": [
|
||||
{
|
||||
"id": "auto-build",
|
||||
"title": "Auto Build Marlin",
|
||||
"icon": "media/AB.svg"
|
||||
}
|
||||
]
|
||||
},
|
||||
"views": {
|
||||
"auto-build": [
|
||||
{
|
||||
"id": "autobuild",
|
||||
"name": " "
|
||||
}
|
||||
]
|
||||
},
|
||||
"commands": [
|
||||
{
|
||||
"command": "piobuild",
|
||||
"title": "PIO Build",
|
||||
"icon": "resources/B32x32_white.svg"
|
||||
},
|
||||
{
|
||||
"command": "pioclean",
|
||||
"title": "PIO Clean",
|
||||
"icon": "resources/C32x32_white.svg"
|
||||
},
|
||||
{
|
||||
"command": "pioupload",
|
||||
"title": "PIO Upload",
|
||||
"icon": "resources/U32x32_white.svg"
|
||||
},
|
||||
{
|
||||
"command": "piotraceback",
|
||||
"title": "PIO Upload (traceback)",
|
||||
"icon": "resources/Ut32x32_white.svg"
|
||||
}
|
||||
],
|
||||
"menus": {
|
||||
"view/title": [
|
||||
{
|
||||
"command": "piobuild",
|
||||
"group": "navigation@1"
|
||||
},
|
||||
{
|
||||
"command": "pioclean",
|
||||
"group": "navigation@2"
|
||||
},
|
||||
{
|
||||
"command": "pioupload",
|
||||
"group": "navigation@3"
|
||||
},
|
||||
{
|
||||
"command": "piotraceback",
|
||||
"group": "navigation@4"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"vscode:prepublish": "npm run compile",
|
||||
"compile": "tsc -p ./",
|
||||
"watch": "tsc -watch -p ./",
|
||||
"postinstall": "node ./node_modules/vscode/bin/install",
|
||||
"test": "npm run compile && node ./node_modules/vscode/bin/test"
|
||||
},
|
||||
"devDependencies": {
|
||||
"vscode": "^1.1.17",
|
||||
"typescript": "^2.6.1",
|
||||
"tslint": "^5.8.0",
|
||||
"@types/node": "^7.0.43",
|
||||
"@types/mocha": "^2.2.42"
|
||||
}
|
||||
}
|
Before Width: | Height: | Size: 23 KiB |
Before Width: | Height: | Size: 37 KiB |
|
@ -1 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="480px" height="480px" viewBox="0 0 24 24" preserveAspectRatio="xMidYMid meet" ><rect id="svgEditorBackground" x="0" y="0" width="24" height="24" style="fill: black; stroke: black;"/><text style="fill:white;font-family:Arial;font-size:14px;font-weight:lighter;stroke:white;stroke-width:0.3;" x="7.75" y="16.8" id="e2_texte" dy="" dx="">B</text></svg>
|
Before Width: | Height: | Size: 440 B |
|
@ -1 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="610px" height="390px" viewBox="-9.02564 0 50.0513 32" preserveAspectRatio="xMidYMid meet" ><rect id="svgEditorBackground" x="0" y="0" width="32" height="32" style="fill: black; stroke: black;"/><text style="fill:white;font-family:Arial;font-size:45px;stroke:white;stroke-width:0.5;font-style:normal;font-weight:lighter;" x="2.18804" y="32.2188" id="e1_texte" dy="" dx="">B</text></svg>
|
Before Width: | Height: | Size: 476 B |
|
@ -1 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="28px" height="28px" viewBox="0 0 28 28" preserveAspectRatio="xMidYMid meet" ><rect id="svgEditorBackground" x="0" y="0" width="28" height="28" style="fill:black; stroke:black;"/><text style="fill:white;font-family:Arial;font-size:24px;stroke:white;font-weight:lighter;stroke-width:0.4;" x="7.18702" y="22.6128" id="e1_texte" dy="" dx="">B</text></svg>
|
Before Width: | Height: | Size: 442 B |
Before Width: | Height: | Size: 12 KiB |
|
@ -1 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="610px" height="390px" viewBox="-9.02564 0 50.0513 32" preserveAspectRatio="xMidYMid meet" ><rect id="svgEditorBackground" x="0" y="0" width="32" height="32" style="fill: black; stroke: black;"/><text style="font-family: Arial; font-size:42px; font-style: normal; font-weight: lighter; stroke: white; stroke-width: 0.5;fill:white;" x="0.437605" y="31.1795" id="e2_texte" dy="" dx="">C</text></svg>
|
Before Width: | Height: | Size: 487 B |
|
@ -1 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="28px" height="28px" viewBox="0 0 28 28" preserveAspectRatio="xMidYMid meet" ><rect id="svgEditorBackground" x="0" y="0" width="28" height="28" style="fill: black; stroke: black;"/><text style="fill:white;font-family:Arial;font-size:24px;font-weight:lighter;stroke:white;stroke-width:0.4;" x="5.51903" y="23.0989" id="e1_texte" dy="" dx="">C</text></svg>
|
Before Width: | Height: | Size: 444 B |
Before Width: | Height: | Size: 3.5 KiB |
Before Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 56 KiB |
|
@ -1 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="610px" height="390px" viewBox="-9.02564 0 50.0513 32" preserveAspectRatio="xMidYMid meet" ><rect id="svgEditorBackground" x="0" y="0" width="32" height="32" style="fill: black; stroke: black;"/><text style="fill:white;font-family:Arial;font-size:42px;font-weight:lighter;stroke:white;stroke-width:0.5;" x="3.06325" y="31.1795" id="e4_texte" dy="" dx="">T</text></svg>
|
Before Width: | Height: | Size: 458 B |
Before Width: | Height: | Size: 8.3 KiB |
|
@ -1 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="610px" height="390px" viewBox="-9.02564 0 50.0513 32" preserveAspectRatio="xMidYMid meet" ><rect id="svgEditorBackground" x="0" y="0" width="32" height="32" style="fill: black; stroke: black;"/><text style="fill:white;font-family:Arial;font-size:42px;font-weight:lighter;stroke:white;stroke-width:0.5;" x="0.71111" y="31.2342" id="e3_texte" dy="" dx="">U</text></svg>
|
Before Width: | Height: | Size: 458 B |
|
@ -1 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="28px" height="28px" viewBox="0 0 28 28" preserveAspectRatio="xMidYMid meet" ><rect id="svgEditorBackground" x="0" y="0" width="28" height="28" style="fill: black; stroke: black;"/><text style="fill:white;font-family:Arial;font-size:24px;font-weight:lighter;stroke:white;stroke-width:0.4;" x="5.17808" y="22.0335" id="e2_texte" dy="" dx="">U</text></svg>
|
Before Width: | Height: | Size: 444 B |
Before Width: | Height: | Size: 4.2 KiB |
|
@ -1 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="610px" height="390px" viewBox="-9.02564 0 50.0513 32" preserveAspectRatio="xMidYMid meet" ><rect id="svgEditorBackground" x="0" y="0" width="32" height="32" style="fill: black; stroke: black;"/><text style="fill: white; font-family: Arial; font-size:42px; font-weight: lighter; stroke: white; stroke-width: 0.5;font-stretch:condensed;" x="-2.40683" y="31.0701" id="e6_texte" dy="" dx="">Ut</text></svg>
|
Before Width: | Height: | Size: 493 B |
|
@ -1 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="28px" height="28px" viewBox="0 0 28 28" preserveAspectRatio="xMidYMid meet" ><rect id="svgEditorBackground" x="0" y="0" width="28" height="28" style="fill: black; stroke: black;"/><text style="fill:white;font-family:Arial;font-size:24px;font-weight:lighter;font-stretch:condensed;stroke:white;stroke-width:0.4;" x="3.34551" y="22.8858" id="e3_texte" dy="" dx="">Ut</text></svg>
|
Before Width: | Height: | Size: 468 B |
Before Width: | Height: | Size: 3.3 KiB |
Before Width: | Height: | Size: 25 KiB |
Before Width: | Height: | Size: 10 KiB |
|
@ -1,12 +0,0 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"target": "es6",
|
||||
"outDir": "out",
|
||||
"lib": [
|
||||
"es6"
|
||||
],
|
||||
"sourceMap": true,
|
||||
"rootDir": "."
|
||||
}
|
||||
}
|
|
@ -1,357 +0,0 @@
|
|||
{
|
||||
"patterns": {
|
||||
"P1": {
|
||||
"expression": "(path):(line)"
|
||||
},
|
||||
"P2": {
|
||||
"expression": "(path)\\s+(line)",
|
||||
"path": "(?:\\/[\\w\\.\\-]+)+"
|
||||
}
|
||||
},
|
||||
"commands": [
|
||||
{
|
||||
"namespace": "process-palette",
|
||||
"action": "PIO Build",
|
||||
"command": "python buildroot/share/atom/auto_build.py build",
|
||||
"arguments": [],
|
||||
"cwd": "{projectPath}",
|
||||
"inputDialogs": [],
|
||||
"env": {},
|
||||
"keystroke": null,
|
||||
"stream": true,
|
||||
"outputTarget": "panel",
|
||||
"outputBufferSize": 80000,
|
||||
"maxCompleted": 3,
|
||||
"autoShowOutput": true,
|
||||
"autoHideOutput": false,
|
||||
"scrollLockEnabled": false,
|
||||
"singular": true,
|
||||
"promptToSave": true,
|
||||
"saveOption": "none",
|
||||
"patterns": [
|
||||
"default"
|
||||
],
|
||||
"successOutput": "{stdout}",
|
||||
"errorOutput": "{stdout}\n{stderr}",
|
||||
"fatalOutput": "Failed to execute : {fullCommand}\n{stdout}\n{stderr}",
|
||||
"startMessage": "",
|
||||
"successMessage": "Executed : {fullCommand}",
|
||||
"errorMessage": "Executed : {fullCommand}\nReturned with code {exitStatus}\n{stderr}",
|
||||
"fatalMessage": "Failed to execute : {fullCommand}\n{stdout}\n{stderr}",
|
||||
"menus": [
|
||||
"Auto Build"
|
||||
],
|
||||
"startScript": null,
|
||||
"successScript": null,
|
||||
"errorScript": null,
|
||||
"scriptOnStart": false,
|
||||
"scriptOnSuccess": false,
|
||||
"scriptOnError": false,
|
||||
"notifyOnStart": false,
|
||||
"notifyOnSuccess": true,
|
||||
"notifyOnError": true,
|
||||
"input": null
|
||||
},
|
||||
{
|
||||
"namespace": "process-palette",
|
||||
"action": "PIO Clean",
|
||||
"command": "python buildroot/share/atom/auto_build.py clean",
|
||||
"arguments": [],
|
||||
"cwd": "{projectPath}",
|
||||
"inputDialogs": [],
|
||||
"env": {},
|
||||
"keystroke": null,
|
||||
"stream": true,
|
||||
"outputTarget": "panel",
|
||||
"outputBufferSize": 80000,
|
||||
"maxCompleted": 3,
|
||||
"autoShowOutput": true,
|
||||
"autoHideOutput": false,
|
||||
"scrollLockEnabled": false,
|
||||
"singular": false,
|
||||
"promptToSave": true,
|
||||
"saveOption": "none",
|
||||
"patterns": [
|
||||
"default"
|
||||
],
|
||||
"successOutput": "{stdout}",
|
||||
"errorOutput": "{stdout}\n{stderr}",
|
||||
"fatalOutput": "Failed to execute : {fullCommand}\n{stdout}\n{stderr}",
|
||||
"startMessage": null,
|
||||
"successMessage": "Executed : {fullCommand}",
|
||||
"errorMessage": "Executed : {fullCommand}\nReturned with code {exitStatus}\n{stderr}",
|
||||
"fatalMessage": "Failed to execute : {fullCommand}\n{stdout}\n{stderr}",
|
||||
"menus": [
|
||||
"Auto Build"
|
||||
],
|
||||
"startScript": null,
|
||||
"successScript": null,
|
||||
"errorScript": null,
|
||||
"scriptOnStart": false,
|
||||
"scriptOnSuccess": false,
|
||||
"scriptOnError": false,
|
||||
"notifyOnStart": false,
|
||||
"notifyOnSuccess": true,
|
||||
"notifyOnError": true,
|
||||
"input": null
|
||||
},
|
||||
{
|
||||
"namespace": "process-palette",
|
||||
"action": "PIO Upload",
|
||||
"command": "python buildroot/share/atom/auto_build.py upload",
|
||||
"arguments": [],
|
||||
"cwd": "{projectPath}",
|
||||
"inputDialogs": [],
|
||||
"env": {},
|
||||
"keystroke": null,
|
||||
"stream": true,
|
||||
"outputTarget": "panel",
|
||||
"outputBufferSize": 80000,
|
||||
"maxCompleted": 3,
|
||||
"autoShowOutput": true,
|
||||
"autoHideOutput": false,
|
||||
"scrollLockEnabled": false,
|
||||
"singular": false,
|
||||
"promptToSave": true,
|
||||
"saveOption": "none",
|
||||
"patterns": [
|
||||
"default"
|
||||
],
|
||||
"successOutput": "{stdout}",
|
||||
"errorOutput": "{stdout}\n{stderr}",
|
||||
"fatalOutput": "Failed to execute : {fullCommand}\n{stdout}\n{stderr}",
|
||||
"startMessage": null,
|
||||
"successMessage": "Executed : {fullCommand}",
|
||||
"errorMessage": "Executed : {fullCommand}\nReturned with code {exitStatus}\n{stderr}",
|
||||
"fatalMessage": "Failed to execute : {fullCommand}\n{stdout}\n{stderr}",
|
||||
"menus": [
|
||||
"Auto Build"
|
||||
],
|
||||
"startScript": null,
|
||||
"successScript": null,
|
||||
"errorScript": null,
|
||||
"scriptOnStart": false,
|
||||
"scriptOnSuccess": false,
|
||||
"scriptOnError": false,
|
||||
"notifyOnStart": false,
|
||||
"notifyOnSuccess": true,
|
||||
"notifyOnError": true,
|
||||
"input": null
|
||||
},
|
||||
{
|
||||
"namespace": "process-palette",
|
||||
"action": "PIO Upload (traceback)",
|
||||
"command": "python buildroot/share/atom/auto_build.py traceback",
|
||||
"arguments": [],
|
||||
"cwd": "{projectPath}",
|
||||
"inputDialogs": [],
|
||||
"env": {},
|
||||
"keystroke": null,
|
||||
"stream": true,
|
||||
"outputTarget": "panel",
|
||||
"outputBufferSize": 80000,
|
||||
"maxCompleted": 3,
|
||||
"autoShowOutput": true,
|
||||
"autoHideOutput": false,
|
||||
"scrollLockEnabled": false,
|
||||
"singular": false,
|
||||
"promptToSave": true,
|
||||
"saveOption": "none",
|
||||
"patterns": [
|
||||
"default"
|
||||
],
|
||||
"successOutput": "{stdout}",
|
||||
"errorOutput": "{stdout}\n{stderr}",
|
||||
"fatalOutput": "Failed to execute : {fullCommand}\n{stdout}\n{stderr}",
|
||||
"startMessage": null,
|
||||
"successMessage": "Executed : {fullCommand}",
|
||||
"errorMessage": "Executed : {fullCommand}\nReturned with code {exitStatus}\n{stderr}",
|
||||
"fatalMessage": "Failed to execute : {fullCommand}\n{stdout}\n{stderr}",
|
||||
"menus": [
|
||||
"Auto Build"
|
||||
],
|
||||
"startScript": null,
|
||||
"successScript": null,
|
||||
"errorScript": null,
|
||||
"scriptOnStart": false,
|
||||
"scriptOnSuccess": false,
|
||||
"scriptOnError": false,
|
||||
"notifyOnStart": false,
|
||||
"notifyOnSuccess": true,
|
||||
"notifyOnError": true,
|
||||
"input": null
|
||||
},
|
||||
{
|
||||
"namespace": "process-palette",
|
||||
"action": "PIO Upload using Programmer",
|
||||
"command": "python buildroot/share/atom/auto_build.py program",
|
||||
"arguments": [],
|
||||
"cwd": "{projectPath}",
|
||||
"inputDialogs": [],
|
||||
"env": {},
|
||||
"keystroke": null,
|
||||
"stream": true,
|
||||
"outputTarget": "panel",
|
||||
"outputBufferSize": 80000,
|
||||
"maxCompleted": 3,
|
||||
"autoShowOutput": true,
|
||||
"autoHideOutput": false,
|
||||
"scrollLockEnabled": false,
|
||||
"singular": false,
|
||||
"promptToSave": true,
|
||||
"saveOption": "none",
|
||||
"patterns": [
|
||||
"default"
|
||||
],
|
||||
"successOutput": "{stdout}",
|
||||
"errorOutput": "{stdout}\n{stderr}",
|
||||
"fatalOutput": "Failed to execute : {fullCommand}\n{stdout}\n{stderr}",
|
||||
"startMessage": null,
|
||||
"successMessage": "Executed : {fullCommand}",
|
||||
"errorMessage": "Executed : {fullCommand}\nReturned with code {exitStatus}\n{stderr}",
|
||||
"fatalMessage": "Failed to execute : {fullCommand}\n{stdout}\n{stderr}",
|
||||
"menus": [
|
||||
"Auto Build"
|
||||
],
|
||||
"startScript": null,
|
||||
"successScript": null,
|
||||
"errorScript": null,
|
||||
"scriptOnStart": false,
|
||||
"scriptOnSuccess": false,
|
||||
"scriptOnError": false,
|
||||
"notifyOnStart": false,
|
||||
"notifyOnSuccess": true,
|
||||
"notifyOnError": true,
|
||||
"input": null
|
||||
},
|
||||
{
|
||||
"namespace": "process-palette",
|
||||
"action": "PIO Test",
|
||||
"command": "python buildroot/share/atom/auto_build.py test",
|
||||
"arguments": [],
|
||||
"cwd": "{projectPath}",
|
||||
"inputDialogs": [],
|
||||
"env": {},
|
||||
"keystroke": null,
|
||||
"stream": true,
|
||||
"outputTarget": "panel",
|
||||
"outputBufferSize": 80000,
|
||||
"maxCompleted": 3,
|
||||
"autoShowOutput": true,
|
||||
"autoHideOutput": false,
|
||||
"scrollLockEnabled": false,
|
||||
"singular": false,
|
||||
"promptToSave": true,
|
||||
"saveOption": "none",
|
||||
"patterns": [
|
||||
"default"
|
||||
],
|
||||
"successOutput": "{stdout}",
|
||||
"errorOutput": "{stdout}\n{stderr}",
|
||||
"fatalOutput": "Failed to execute : {fullCommand}\n{stdout}\n{stderr}",
|
||||
"startMessage": null,
|
||||
"successMessage": "Executed : {fullCommand}",
|
||||
"errorMessage": "Executed : {fullCommand}\nReturned with code {exitStatus}\n{stderr}",
|
||||
"fatalMessage": "Failed to execute : {fullCommand}\n{stdout}\n{stderr}",
|
||||
"menus": [
|
||||
"Auto Build"
|
||||
],
|
||||
"startScript": null,
|
||||
"successScript": null,
|
||||
"errorScript": null,
|
||||
"scriptOnStart": false,
|
||||
"scriptOnSuccess": false,
|
||||
"scriptOnError": false,
|
||||
"notifyOnStart": false,
|
||||
"notifyOnSuccess": true,
|
||||
"notifyOnError": true,
|
||||
"input": null
|
||||
},
|
||||
{
|
||||
"namespace": "process-palette",
|
||||
"action": "PIO Debug",
|
||||
"command": "python buildroot/share/atom/auto_build.py debug",
|
||||
"arguments": [],
|
||||
"cwd": "{projectPath}",
|
||||
"inputDialogs": [],
|
||||
"env": {},
|
||||
"keystroke": null,
|
||||
"stream": true,
|
||||
"outputTarget": "panel",
|
||||
"outputBufferSize": 80000,
|
||||
"maxCompleted": 3,
|
||||
"autoShowOutput": true,
|
||||
"autoHideOutput": false,
|
||||
"scrollLockEnabled": false,
|
||||
"singular": false,
|
||||
"promptToSave": true,
|
||||
"saveOption": "none",
|
||||
"patterns": [
|
||||
"default"
|
||||
],
|
||||
"successOutput": "{stdout}",
|
||||
"errorOutput": "{stdout}\n{stderr}",
|
||||
"fatalOutput": "Failed to execute : {fullCommand}\n{stdout}\n{stderr}",
|
||||
"startMessage": null,
|
||||
"successMessage": "Executed : {fullCommand}",
|
||||
"errorMessage": "Executed : {fullCommand}\nReturned with code {exitStatus}\n{stderr}",
|
||||
"fatalMessage": "Failed to execute : {fullCommand}\n{stdout}\n{stderr}",
|
||||
"menus": [
|
||||
"Auto Build"
|
||||
],
|
||||
"startScript": null,
|
||||
"successScript": null,
|
||||
"errorScript": null,
|
||||
"scriptOnStart": false,
|
||||
"scriptOnSuccess": false,
|
||||
"scriptOnError": false,
|
||||
"notifyOnStart": false,
|
||||
"notifyOnSuccess": true,
|
||||
"notifyOnError": true,
|
||||
"input": null
|
||||
},
|
||||
{
|
||||
"namespace": "process-palette",
|
||||
"action": "PIO Remote",
|
||||
"command": "python buildroot/share/atom/auto_build.py remote",
|
||||
"arguments": [],
|
||||
"cwd": "{projectPath}",
|
||||
"inputDialogs": [],
|
||||
"env": {},
|
||||
"keystroke": null,
|
||||
"stream": true,
|
||||
"outputTarget": "panel",
|
||||
"outputBufferSize": 80000,
|
||||
"maxCompleted": 3,
|
||||
"autoShowOutput": true,
|
||||
"autoHideOutput": false,
|
||||
"scrollLockEnabled": false,
|
||||
"singular": false,
|
||||
"promptToSave": true,
|
||||
"saveOption": "none",
|
||||
"patterns": [
|
||||
"default"
|
||||
],
|
||||
"successOutput": "{stdout}",
|
||||
"errorOutput": "{stdout}\n{stderr}",
|
||||
"fatalOutput": "Failed to execute : {fullCommand}\n{stdout}\n{stderr}",
|
||||
"startMessage": null,
|
||||
"successMessage": "Executed : {fullCommand}",
|
||||
"errorMessage": "Executed : {fullCommand}\nReturned with code {exitStatus}\n{stderr}",
|
||||
"fatalMessage": "Failed to execute : {fullCommand}\n{stdout}\n{stderr}",
|
||||
"menus": [
|
||||
"Auto Build"
|
||||
],
|
||||
"startScript": null,
|
||||
"successScript": null,
|
||||
"errorScript": null,
|
||||
"scriptOnStart": false,
|
||||
"scriptOnSuccess": false,
|
||||
"scriptOnError": false,
|
||||
"notifyOnStart": false,
|
||||
"notifyOnSuccess": true,
|
||||
"notifyOnError": true,
|
||||
"input": null
|
||||
}
|
||||
]
|
||||
}
|