Merge pull request #6202 from thinkyhead/rc_fix_broken_ubl

Patching up UBL, vetting recent commits
master
Scott Lahteine 7 years ago committed by GitHub
commit 34b23ff312

@ -128,7 +128,7 @@
extern bool code_value_bool(); extern bool code_value_bool();
extern bool code_has_value(); extern bool code_has_value();
extern void lcd_init(); extern void lcd_init();
extern void lcd_setstatuspgm(const char* const message, uint8_t level); extern void lcd_setstatuspgm(const char* const message, const uint8_t level);
#define PLANNER_XY_FEEDRATE() (min(planner.max_feedrate_mm_s[X_AXIS], planner.max_feedrate_mm_s[Y_AXIS])) //bob #define PLANNER_XY_FEEDRATE() (min(planner.max_feedrate_mm_s[X_AXIS], planner.max_feedrate_mm_s[Y_AXIS])) //bob
bool prepare_move_to_destination_cartesian(); bool prepare_move_to_destination_cartesian();
void line_to_destination(); void line_to_destination();
@ -156,7 +156,7 @@
// won't leave us in a bad state. // won't leave us in a bad state.
float valid_trig_angle(float); float valid_trig_angle(float);
mesh_index_pair find_closest_circle_to_print(float, float); mesh_index_pair find_closest_circle_to_print(const float&, const float&);
static float extrusion_multiplier = EXTRUSION_MULTIPLIER, static float extrusion_multiplier = EXTRUSION_MULTIPLIER,
retraction_multiplier = RETRACTION_MULTIPLIER, retraction_multiplier = RETRACTION_MULTIPLIER,
@ -183,8 +183,8 @@
int i, xi, yi; int i, xi, yi;
mesh_index_pair location; mesh_index_pair location;
// Don't allow Mesh Validation without homing first // Don't allow Mesh Validation without homing first,
// If the paramter parsing did not go OK, we abort the command // or if the parameter parsing did not go OK, abort
if (axis_unhomed_error(true, true, true) || parse_G26_parameters()) return; if (axis_unhomed_error(true, true, true) || parse_G26_parameters()) return;
if (current_position[Z_AXIS] < Z_CLEARANCE_BETWEEN_PROBES) { if (current_position[Z_AXIS] < Z_CLEARANCE_BETWEEN_PROBES) {
@ -391,8 +391,8 @@
return d; return d;
} }
mesh_index_pair find_closest_circle_to_print( float X, float Y) { mesh_index_pair find_closest_circle_to_print(const float &X, const float &Y) {
float f, mx, my, dx, dy, closest = 99999.99; float closest = 99999.99;
mesh_index_pair return_val; mesh_index_pair return_val;
return_val.x_index = return_val.y_index = -1; return_val.x_index = return_val.y_index = -1;
@ -400,28 +400,27 @@
for (uint8_t i = 0; i < UBL_MESH_NUM_X_POINTS; i++) { for (uint8_t i = 0; i < UBL_MESH_NUM_X_POINTS; i++) {
for (uint8_t j = 0; j < UBL_MESH_NUM_Y_POINTS; j++) { for (uint8_t j = 0; j < UBL_MESH_NUM_Y_POINTS; j++) {
if (!is_bit_set(circle_flags, i, j)) { if (!is_bit_set(circle_flags, i, j)) {
mx = ubl.mesh_index_to_xpos[i]; // We found a circle that needs to be printed const float mx = ubl.mesh_index_to_xpos[i], // We found a circle that needs to be printed
my = ubl.mesh_index_to_ypos[j]; my = ubl.mesh_index_to_ypos[j];
dx = X - mx; // Get the distance to this intersection // Get the distance to this intersection
dy = Y - my; float f = HYPOT(X - mx, Y - my);
f = HYPOT(dx, dy);
dx = x_pos - mx; // It is possible that we are being called with the values // It is possible that we are being called with the values
dy = y_pos - my; // to let us find the closest circle to the start position. // to let us find the closest circle to the start position.
f += HYPOT(dx, dy) / 15.0; // But if this is not the case, // But if this is not the case, add a small weighting to the
// we are going to add in a small // distance calculation to help it choose a better place to continue.
// weighting to the distance calculation to help it choose f += HYPOT(x_pos - mx, y_pos - my) / 15.0;
// a better place to continue.
// Add in the specified amount of Random Noise to our search
if (random_deviation > 1.0) if (random_deviation > 1.0)
f += random(0.0, random_deviation); // Add in the specified amount of Random Noise to our search f += random(0.0, random_deviation);
if (f < closest) { if (f < closest) {
closest = f; // We found a closer location that is still closest = f; // We found a closer location that is still
return_val.x_index = i; // un-printed --- save the data for it return_val.x_index = i; // un-printed --- save the data for it
return_val.y_index = j; return_val.y_index = j;
return_val.distance= closest; return_val.distance = closest;
} }
} }
} }

@ -39,19 +39,7 @@
#include "types.h" #include "types.h"
#include "fastio.h" #include "fastio.h"
#include "utility.h" #include "utility.h"
#include "serial.h"
#ifdef USBCON
#include "HardwareSerial.h"
#if ENABLED(BLUETOOTH)
#define MYSERIAL bluetoothSerial
#else
#define MYSERIAL Serial
#endif // BLUETOOTH
#else
#include "MarlinSerial.h"
#define MYSERIAL customizedSerial
#endif
#include "WString.h" #include "WString.h"
#if ENABLED(PRINTCOUNTER) #if ENABLED(PRINTCOUNTER)
@ -60,54 +48,6 @@
#include "stopwatch.h" #include "stopwatch.h"
#endif #endif
extern const char echomagic[] PROGMEM;
extern const char errormagic[] PROGMEM;
#define SERIAL_CHAR(x) (MYSERIAL.write(x))
#define SERIAL_EOL SERIAL_CHAR('\n')
#define SERIAL_PROTOCOLCHAR(x) SERIAL_CHAR(x)
#define SERIAL_PROTOCOL(x) (MYSERIAL.print(x))
#define SERIAL_PROTOCOL_F(x,y) (MYSERIAL.print(x,y))
#define SERIAL_PROTOCOLPGM(x) (serialprintPGM(PSTR(x)))
#define SERIAL_PROTOCOLLN(x) do{ MYSERIAL.print(x); SERIAL_EOL; }while(0)
#define SERIAL_PROTOCOLLNPGM(x) (serialprintPGM(PSTR(x "\n")))
#define SERIAL_PROTOCOLPAIR(name, value) (serial_echopair_P(PSTR(name),(value)))
#define SERIAL_PROTOCOLLNPAIR(name, value) do{ SERIAL_PROTOCOLPAIR(name, value); SERIAL_EOL; }while(0)
#define SERIAL_ECHO_START (serialprintPGM(echomagic))
#define SERIAL_ECHO(x) SERIAL_PROTOCOL(x)
#define SERIAL_ECHOPGM(x) SERIAL_PROTOCOLPGM(x)
#define SERIAL_ECHOLN(x) SERIAL_PROTOCOLLN(x)
#define SERIAL_ECHOLNPGM(x) SERIAL_PROTOCOLLNPGM(x)
#define SERIAL_ECHOPAIR(name,value) SERIAL_PROTOCOLPAIR(name, value)
#define SERIAL_ECHOLNPAIR(name, value) SERIAL_PROTOCOLLNPAIR(name, value)
#define SERIAL_ECHO_F(x,y) SERIAL_PROTOCOL_F(x,y)
#define SERIAL_ERROR_START (serialprintPGM(errormagic))
#define SERIAL_ERROR(x) SERIAL_PROTOCOL(x)
#define SERIAL_ERRORPGM(x) SERIAL_PROTOCOLPGM(x)
#define SERIAL_ERRORLN(x) SERIAL_PROTOCOLLN(x)
#define SERIAL_ERRORLNPGM(x) SERIAL_PROTOCOLLNPGM(x)
void serial_echopair_P(const char* s_P, const char *v);
void serial_echopair_P(const char* s_P, char v);
void serial_echopair_P(const char* s_P, int v);
void serial_echopair_P(const char* s_P, long v);
void serial_echopair_P(const char* s_P, float v);
void serial_echopair_P(const char* s_P, double v);
void serial_echopair_P(const char* s_P, unsigned int v);
void serial_echopair_P(const char* s_P, unsigned long v);
FORCE_INLINE void serial_echopair_P(const char* s_P, uint8_t v) { serial_echopair_P(s_P, (int)v); }
FORCE_INLINE void serial_echopair_P(const char* s_P, uint16_t v) { serial_echopair_P(s_P, (int)v); }
FORCE_INLINE void serial_echopair_P(const char* s_P, bool v) { serial_echopair_P(s_P, (int)v); }
FORCE_INLINE void serial_echopair_P(const char* s_P, void *v) { serial_echopair_P(s_P, (unsigned long)v); }
// Things to write to serial from Program memory. Saves 400 to 2k of RAM.
FORCE_INLINE void serialprintPGM(const char* str) {
while (char ch = pgm_read_byte(str++)) MYSERIAL.write(ch);
}
void idle( void idle(
#if ENABLED(FILAMENT_CHANGE_FEATURE) #if ENABLED(FILAMENT_CHANGE_FEATURE)
bool no_stepper_sleep = false // pass true to keep steppers from disabling on timeout bool no_stepper_sleep = false // pass true to keep steppers from disabling on timeout

@ -33,21 +33,111 @@
#include "stepper.h" #include "stepper.h"
#include "Marlin.h" #include "Marlin.h"
#ifndef USBCON // Disable HardwareSerial.cpp to support chips without a UART (Attiny, etc.)
// this next line disables the entire HardwareSerial.cpp,
// this is so I can support Attiny series and any other chip without a UART
#if defined(UBRRH) || defined(UBRR0H) || defined(UBRR1H) || defined(UBRR2H) || defined(UBRR3H)
#if UART_PRESENT(SERIAL_PORT) #if !defined(USBCON) && (defined(UBRRH) || defined(UBRR0H) || defined(UBRR1H) || defined(UBRR2H) || defined(UBRR3H))
#if UART_PRESENT(SERIAL_PORT)
ring_buffer_r rx_buffer = { { 0 }, 0, 0 }; ring_buffer_r rx_buffer = { { 0 }, 0, 0 };
#if TX_BUFFER_SIZE > 0 #if TX_BUFFER_SIZE > 0
ring_buffer_t tx_buffer = { { 0 }, 0, 0 }; ring_buffer_t tx_buffer = { { 0 }, 0, 0 };
static bool _written; static bool _written;
#endif #endif
#endif #endif
#if ENABLED(EMERGENCY_PARSER)
#include "language.h"
// Currently looking for: M108, M112, M410
// If you alter the parser please don't forget to update the capabilities in Conditionals_post.h
FORCE_INLINE void emergency_parser(const unsigned char c) {
static e_parser_state state = state_RESET;
switch (state) {
case state_RESET:
switch (c) {
case ' ': break;
case 'N': state = state_N; break;
case 'M': state = state_M; break;
default: state = state_IGNORE;
}
break;
case state_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 = state_M; break;
default: state = state_IGNORE;
}
break;
case state_M:
switch (c) {
case ' ': break;
case '1': state = state_M1; break;
case '4': state = state_M4; break;
default: state = state_IGNORE;
}
break;
case state_M1:
switch (c) {
case '0': state = state_M10; break;
case '1': state = state_M11; break;
default: state = state_IGNORE;
}
break;
case state_M10:
state = (c == '8') ? state_M108 : state_IGNORE;
break;
case state_M11:
state = (c == '2') ? state_M112 : state_IGNORE;
break;
case state_M4:
state = (c == '1') ? state_M41 : state_IGNORE;
break;
case state_M41:
state = (c == '0') ? state_M410 : state_IGNORE;
break;
case state_IGNORE:
if (c == '\n') state = state_RESET;
break;
default:
if (c == '\n') {
switch (state) {
case state_M108:
wait_for_user = wait_for_heatup = false;
break;
case state_M112:
kill(PSTR(MSG_KILLED));
break;
case state_M410:
quickstop_stepper();
break;
default:
break;
}
state = state_RESET;
}
}
}
#endif
FORCE_INLINE void store_char(unsigned char c) { FORCE_INLINE void store_char(unsigned char c) {
CRITICAL_SECTION_START; CRITICAL_SECTION_START;
uint8_t h = rx_buffer.head; uint8_t h = rx_buffer.head;
uint8_t i = (uint8_t)(h + 1) & (RX_BUFFER_SIZE - 1); uint8_t i = (uint8_t)(h + 1) & (RX_BUFFER_SIZE - 1);
@ -65,9 +155,9 @@ FORCE_INLINE void store_char(unsigned char c) {
#if ENABLED(EMERGENCY_PARSER) #if ENABLED(EMERGENCY_PARSER)
emergency_parser(c); emergency_parser(c);
#endif #endif
} }
#if TX_BUFFER_SIZE > 0 #if TX_BUFFER_SIZE > 0
FORCE_INLINE void _tx_udr_empty_irq(void) { FORCE_INLINE void _tx_udr_empty_irq(void) {
// If interrupts are enabled, there must be more data in the output // If interrupts are enabled, there must be more data in the output
@ -95,22 +185,18 @@ FORCE_INLINE void store_char(unsigned char c) {
} }
#endif #endif
#endif // TX_BUFFER_SIZE #endif // TX_BUFFER_SIZE
#ifdef M_USARTx_RX_vect #ifdef M_USARTx_RX_vect
ISR(M_USARTx_RX_vect) { ISR(M_USARTx_RX_vect) {
unsigned char c = M_UDRx; unsigned char c = M_UDRx;
store_char(c); store_char(c);
} }
#endif #endif
// Constructors ////////////////////////////////////////////////////////////////
MarlinSerial::MarlinSerial() { }
// Public Methods ////////////////////////////////////////////////////////////// // Public Methods
void MarlinSerial::begin(long baud) { void MarlinSerial::begin(long baud) {
uint16_t baud_setting; uint16_t baud_setting;
bool useU2X = true; bool useU2X = true;
@ -143,30 +229,30 @@ void MarlinSerial::begin(long baud) {
CBI(M_UCSRxB, M_UDRIEx); CBI(M_UCSRxB, M_UDRIEx);
_written = false; _written = false;
#endif #endif
} }
void MarlinSerial::end() { void MarlinSerial::end() {
CBI(M_UCSRxB, M_RXENx); CBI(M_UCSRxB, M_RXENx);
CBI(M_UCSRxB, M_TXENx); CBI(M_UCSRxB, M_TXENx);
CBI(M_UCSRxB, M_RXCIEx); CBI(M_UCSRxB, M_RXCIEx);
CBI(M_UCSRxB, M_UDRIEx); CBI(M_UCSRxB, M_UDRIEx);
} }
void MarlinSerial::checkRx(void) { void MarlinSerial::checkRx(void) {
if (TEST(M_UCSRxA, M_RXCx)) { if (TEST(M_UCSRxA, M_RXCx)) {
uint8_t c = M_UDRx; uint8_t c = M_UDRx;
store_char(c); store_char(c);
} }
} }
int MarlinSerial::peek(void) { int MarlinSerial::peek(void) {
CRITICAL_SECTION_START; CRITICAL_SECTION_START;
int v = rx_buffer.head == rx_buffer.tail ? -1 : rx_buffer.buffer[rx_buffer.tail]; int v = rx_buffer.head == rx_buffer.tail ? -1 : rx_buffer.buffer[rx_buffer.tail];
CRITICAL_SECTION_END; CRITICAL_SECTION_END;
return v; return v;
} }
int MarlinSerial::read(void) { int MarlinSerial::read(void) {
int v; int v;
CRITICAL_SECTION_START; CRITICAL_SECTION_START;
uint8_t t = rx_buffer.tail; uint8_t t = rx_buffer.tail;
@ -179,17 +265,17 @@ int MarlinSerial::read(void) {
} }
CRITICAL_SECTION_END; CRITICAL_SECTION_END;
return v; return v;
} }
uint8_t MarlinSerial::available(void) { uint8_t MarlinSerial::available(void) {
CRITICAL_SECTION_START; CRITICAL_SECTION_START;
uint8_t h = rx_buffer.head, uint8_t h = rx_buffer.head,
t = rx_buffer.tail; t = rx_buffer.tail;
CRITICAL_SECTION_END; CRITICAL_SECTION_END;
return (uint8_t)(RX_BUFFER_SIZE + h - t) & (RX_BUFFER_SIZE - 1); return (uint8_t)(RX_BUFFER_SIZE + h - t) & (RX_BUFFER_SIZE - 1);
} }
void MarlinSerial::flush(void) { void MarlinSerial::flush(void) {
// RX // RX
// don't reverse this or there may be problems if the RX interrupt // don't reverse this or there may be problems if the RX interrupt
// occurs after reading the value of rx_buffer_head but before writing // occurs after reading the value of rx_buffer_head but before writing
@ -199,9 +285,9 @@ void MarlinSerial::flush(void) {
CRITICAL_SECTION_START; CRITICAL_SECTION_START;
rx_buffer.head = rx_buffer.tail; rx_buffer.head = rx_buffer.tail;
CRITICAL_SECTION_END; CRITICAL_SECTION_END;
} }
#if TX_BUFFER_SIZE > 0 #if TX_BUFFER_SIZE > 0
uint8_t MarlinSerial::availableForWrite(void) { uint8_t MarlinSerial::availableForWrite(void) {
CRITICAL_SECTION_START; CRITICAL_SECTION_START;
uint8_t h = tx_buffer.head; uint8_t h = tx_buffer.head;
@ -270,38 +356,38 @@ void MarlinSerial::flush(void) {
} }
// If we get here, nothing is queued anymore (DRIE is disabled) and // If we get here, nothing is queued anymore (DRIE is disabled) and
// the hardware finished tranmission (TXC is set). // the hardware finished tranmission (TXC is set).
} }
#else #else
void MarlinSerial::write(uint8_t c) { void MarlinSerial::write(uint8_t c) {
while (!TEST(M_UCSRxA, M_UDREx)) while (!TEST(M_UCSRxA, M_UDREx))
; ;
M_UDRx = c; M_UDRx = c;
} }
#endif #endif
// end NEW // end NEW
/// imports from print.h /// imports from print.h
void MarlinSerial::print(char c, int base) { void MarlinSerial::print(char c, int base) {
print((long) c, base); print((long) c, base);
} }
void MarlinSerial::print(unsigned char b, int base) { void MarlinSerial::print(unsigned char b, int base) {
print((unsigned long) b, base); print((unsigned long) b, base);
} }
void MarlinSerial::print(int n, int base) { void MarlinSerial::print(int n, int base) {
print((long) n, base); print((long) n, base);
} }
void MarlinSerial::print(unsigned int n, int base) { void MarlinSerial::print(unsigned int n, int base) {
print((unsigned long) n, base); print((unsigned long) n, base);
} }
void MarlinSerial::print(long n, int base) { void MarlinSerial::print(long n, int base) {
if (base == 0) { if (base == 0) {
write(n); write(n);
} }
@ -315,70 +401,70 @@ void MarlinSerial::print(long n, int base) {
else { else {
printNumber(n, base); printNumber(n, base);
} }
} }
void MarlinSerial::print(unsigned long n, int base) { void MarlinSerial::print(unsigned long n, int base) {
if (base == 0) write(n); if (base == 0) write(n);
else printNumber(n, base); else printNumber(n, base);
} }
void MarlinSerial::print(double n, int digits) { void MarlinSerial::print(double n, int digits) {
printFloat(n, digits); printFloat(n, digits);
} }
void MarlinSerial::println(void) { void MarlinSerial::println(void) {
print('\r'); print('\r');
print('\n'); print('\n');
} }
void MarlinSerial::println(const String& s) { void MarlinSerial::println(const String& s) {
print(s); print(s);
println(); println();
} }
void MarlinSerial::println(const char c[]) { void MarlinSerial::println(const char c[]) {
print(c); print(c);
println(); println();
} }
void MarlinSerial::println(char c, int base) { void MarlinSerial::println(char c, int base) {
print(c, base); print(c, base);
println(); println();
} }
void MarlinSerial::println(unsigned char b, int base) { void MarlinSerial::println(unsigned char b, int base) {
print(b, base); print(b, base);
println(); println();
} }
void MarlinSerial::println(int n, int base) { void MarlinSerial::println(int n, int base) {
print(n, base); print(n, base);
println(); println();
} }
void MarlinSerial::println(unsigned int n, int base) { void MarlinSerial::println(unsigned int n, int base) {
print(n, base); print(n, base);
println(); println();
} }
void MarlinSerial::println(long n, int base) { void MarlinSerial::println(long n, int base) {
print(n, base); print(n, base);
println(); println();
} }
void MarlinSerial::println(unsigned long n, int base) { void MarlinSerial::println(unsigned long n, int base) {
print(n, base); print(n, base);
println(); println();
} }
void MarlinSerial::println(double n, int digits) { void MarlinSerial::println(double n, int digits) {
print(n, digits); print(n, digits);
println(); println();
} }
// Private Methods ///////////////////////////////////////////////////////////// // Private Methods
void MarlinSerial::printNumber(unsigned long n, uint8_t base) { void MarlinSerial::printNumber(unsigned long n, uint8_t base) {
if (n) { if (n) {
unsigned char buf[8 * sizeof(long)]; // Enough space for base 2 unsigned char buf[8 * sizeof(long)]; // Enough space for base 2
int8_t i = 0; int8_t i = 0;
@ -391,9 +477,9 @@ void MarlinSerial::printNumber(unsigned long n, uint8_t base) {
} }
else else
print('0'); print('0');
} }
void MarlinSerial::printFloat(double number, uint8_t digits) { void MarlinSerial::printFloat(double number, uint8_t digits) {
// Handle negative numbers // Handle negative numbers
if (number < 0.0) { if (number < 0.0) {
print('-'); print('-');
@ -423,105 +509,14 @@ void MarlinSerial::printFloat(double number, uint8_t digits) {
remainder -= toPrint; remainder -= toPrint;
} }
} }
} }
// Preinstantiate Objects //////////////////////////////////////////////////////
MarlinSerial customizedSerial; // Preinstantiate
MarlinSerial customizedSerial;
#endif // whole file #endif // !USBCON && (UBRRH || UBRR0H || UBRR1H || UBRR2H || UBRR3H)
#endif // !USBCON
// For AT90USB targets use the UART for BT interfacing // For AT90USB targets use the UART for BT interfacing
#if defined(USBCON) && ENABLED(BLUETOOTH) #if defined(USBCON) && ENABLED(BLUETOOTH)
HardwareSerial bluetoothSerial; HardwareSerial bluetoothSerial;
#endif #endif
#if ENABLED(EMERGENCY_PARSER)
// Currently looking for: M108, M112, M410
// If you alter the parser please don't forget to update the capabilities in Conditionals_post.h
FORCE_INLINE void emergency_parser(unsigned char c) {
static e_parser_state state = state_RESET;
switch (state) {
case state_RESET:
switch (c) {
case ' ': break;
case 'N': state = state_N; break;
case 'M': state = state_M; break;
default: state = state_IGNORE;
}
break;
case state_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 = state_M; break;
default: state = state_IGNORE;
}
break;
case state_M:
switch (c) {
case ' ': break;
case '1': state = state_M1; break;
case '4': state = state_M4; break;
default: state = state_IGNORE;
}
break;
case state_M1:
switch (c) {
case '0': state = state_M10; break;
case '1': state = state_M11; break;
default: state = state_IGNORE;
}
break;
case state_M10:
state = (c == '8') ? state_M108 : state_IGNORE;
break;
case state_M11:
state = (c == '2') ? state_M112 : state_IGNORE;
break;
case state_M4:
state = (c == '1') ? state_M41 : state_IGNORE;
break;
case state_M41:
state = (c == '0') ? state_M410 : state_IGNORE;
break;
case state_IGNORE:
if (c == '\n') state = state_RESET;
break;
default:
if (c == '\n') {
switch (state) {
case state_M108:
wait_for_user = wait_for_heatup = false;
break;
case state_M112:
kill(PSTR(MSG_KILLED));
break;
case state_M410:
quickstop_stepper();
break;
default:
break;
}
state = state_RESET;
}
}
}
#endif

@ -29,8 +29,8 @@
*/ */
#ifndef MarlinSerial_h #ifndef MARLINSERIAL_H
#define MarlinSerial_h #define MARLINSERIAL_H
#include "MarlinConfig.h" #include "MarlinConfig.h"
@ -52,8 +52,7 @@
#define SERIAL_REGNAME_INTERNAL(registerbase,number,suffix) registerbase##number##suffix #define SERIAL_REGNAME_INTERNAL(registerbase,number,suffix) registerbase##number##suffix
#endif #endif
// Registers used by MarlinSerial class (these are expanded // Registers used by MarlinSerial class (expanded depending on selected serial port)
// depending on selected serial port
#define M_UCSRxA SERIAL_REGNAME(UCSR,SERIAL_PORT,A) // defines M_UCSRxA to be UCSRnA where n is the serial port number #define M_UCSRxA SERIAL_REGNAME(UCSR,SERIAL_PORT,A) // defines M_UCSRxA to be UCSRnA where n is the serial port number
#define M_UCSRxB SERIAL_REGNAME(UCSR,SERIAL_PORT,B) #define M_UCSRxB SERIAL_REGNAME(UCSR,SERIAL_PORT,B)
#define M_RXENx SERIAL_REGNAME(RXEN,SERIAL_PORT,) #define M_RXENx SERIAL_REGNAME(RXEN,SERIAL_PORT,)
@ -70,63 +69,56 @@
#define M_U2Xx SERIAL_REGNAME(U2X,SERIAL_PORT,) #define M_U2Xx SERIAL_REGNAME(U2X,SERIAL_PORT,)
#define M_USARTx_UDRE_vect SERIAL_REGNAME(USART,SERIAL_PORT,_UDRE_vect) #define M_USARTx_UDRE_vect SERIAL_REGNAME(USART,SERIAL_PORT,_UDRE_vect)
#define DEC 10 #define DEC 10
#define HEX 16 #define HEX 16
#define OCT 8 #define OCT 8
#define BIN 2 #define BIN 2
#define BYTE 0 #define BYTE 0
#ifndef USBCON #ifndef USBCON
// Define constants and variables for buffering incoming serial data. We're // Define constants and variables for buffering incoming serial data. We're
// using a ring buffer (I think), in which rx_buffer_head is the index of the // using a ring buffer (I think), in which rx_buffer_head is the index of the
// location to which to write the next incoming character and rx_buffer_tail // location to which to write the next incoming character and rx_buffer_tail
// is the index of the location from which to read. // is the index of the location from which to read.
// 256 is the max limit due to uint8_t head and tail. Use only powers of 2. (...,16,32,64,128,256) // 256 is the max limit due to uint8_t head and tail. Use only powers of 2. (...,16,32,64,128,256)
#ifndef RX_BUFFER_SIZE #ifndef RX_BUFFER_SIZE
#define RX_BUFFER_SIZE 128 #define RX_BUFFER_SIZE 128
#endif #endif
#ifndef TX_BUFFER_SIZE #ifndef TX_BUFFER_SIZE
#define TX_BUFFER_SIZE 32 #define TX_BUFFER_SIZE 32
#endif #endif
#if !((RX_BUFFER_SIZE == 256) ||(RX_BUFFER_SIZE == 128) ||(RX_BUFFER_SIZE == 64) ||(RX_BUFFER_SIZE == 32) ||(RX_BUFFER_SIZE == 16) ||(RX_BUFFER_SIZE == 8) ||(RX_BUFFER_SIZE == 4) ||(RX_BUFFER_SIZE == 2)) #if !((RX_BUFFER_SIZE == 256) ||(RX_BUFFER_SIZE == 128) ||(RX_BUFFER_SIZE == 64) ||(RX_BUFFER_SIZE == 32) ||(RX_BUFFER_SIZE == 16) ||(RX_BUFFER_SIZE == 8) ||(RX_BUFFER_SIZE == 4) ||(RX_BUFFER_SIZE == 2))
#error "RX_BUFFER_SIZE has to be a power of 2 and >= 2" #error "RX_BUFFER_SIZE has to be a power of 2 and >= 2"
#endif #endif
#if !((TX_BUFFER_SIZE == 256) ||(TX_BUFFER_SIZE == 128) ||(TX_BUFFER_SIZE == 64) ||(TX_BUFFER_SIZE == 32) ||(TX_BUFFER_SIZE == 16) ||(TX_BUFFER_SIZE == 8) ||(TX_BUFFER_SIZE == 4) ||(TX_BUFFER_SIZE == 2) ||(TX_BUFFER_SIZE == 0)) #if !((TX_BUFFER_SIZE == 256) ||(TX_BUFFER_SIZE == 128) ||(TX_BUFFER_SIZE == 64) ||(TX_BUFFER_SIZE == 32) ||(TX_BUFFER_SIZE == 16) ||(TX_BUFFER_SIZE == 8) ||(TX_BUFFER_SIZE == 4) ||(TX_BUFFER_SIZE == 2) ||(TX_BUFFER_SIZE == 0))
#error TX_BUFFER_SIZE has to be a power of 2 or 0 #error TX_BUFFER_SIZE has to be a power of 2 or 0
#endif #endif
struct ring_buffer_r { struct ring_buffer_r {
unsigned char buffer[RX_BUFFER_SIZE]; unsigned char buffer[RX_BUFFER_SIZE];
volatile uint8_t head; volatile uint8_t head;
volatile uint8_t tail; volatile uint8_t tail;
}; };
#if TX_BUFFER_SIZE > 0 #if TX_BUFFER_SIZE > 0
struct ring_buffer_t { struct ring_buffer_t {
unsigned char buffer[TX_BUFFER_SIZE]; unsigned char buffer[TX_BUFFER_SIZE];
volatile uint8_t head; volatile uint8_t head;
volatile uint8_t tail; volatile uint8_t tail;
}; };
#endif #endif
#if UART_PRESENT(SERIAL_PORT) #if UART_PRESENT(SERIAL_PORT)
extern ring_buffer_r rx_buffer; extern ring_buffer_r rx_buffer;
#if TX_BUFFER_SIZE > 0 #if TX_BUFFER_SIZE > 0
extern ring_buffer_t tx_buffer; extern ring_buffer_t tx_buffer;
#endif #endif
#endif #endif
#if ENABLED(EMERGENCY_PARSER)
#include "language.h"
void emergency_parser(unsigned char c);
#endif
class MarlinSerial { //: public Stream class MarlinSerial { //: public Stream
public: public:
MarlinSerial(); MarlinSerial() {};
static void begin(long); static void begin(long);
static void end(); static void end();
static int peek(void); static int peek(void);
@ -168,9 +160,10 @@ class MarlinSerial { //: public Stream
static void println(unsigned long, int = DEC); static void println(unsigned long, int = DEC);
static void println(double, int = 2); static void println(double, int = 2);
static void println(void); static void println(void);
}; };
extern MarlinSerial customizedSerial;
extern MarlinSerial customizedSerial;
#endif // !USBCON #endif // !USBCON
// Use the UART for Bluetooth in AT90USB configurations // Use the UART for Bluetooth in AT90USB configurations
@ -178,4 +171,4 @@ extern MarlinSerial customizedSerial;
extern HardwareSerial bluetoothSerial; extern HardwareSerial bluetoothSerial;
#endif #endif
#endif #endif // MARLINSERIAL_H

@ -447,8 +447,6 @@ volatile bool wait_for_heatup = true;
volatile bool wait_for_user = false; volatile bool wait_for_user = false;
#endif #endif
const char errormagic[] PROGMEM = "Error:";
const char echomagic[] PROGMEM = "echo:";
const char axis_codes[XYZE] = {'X', 'Y', 'Z', 'E'}; const char axis_codes[XYZE] = {'X', 'Y', 'Z', 'E'};
// Number of characters read in the current line of serial input // Number of characters read in the current line of serial input
@ -696,14 +694,6 @@ void set_current_from_steppers_for_axis(const AxisEnum axis);
void plan_cubic_move(const float offset[4]); void plan_cubic_move(const float offset[4]);
#endif #endif
void serial_echopair_P(const char* s_P, const char *v) { serialprintPGM(s_P); SERIAL_ECHO(v); }
void serial_echopair_P(const char* s_P, char v) { serialprintPGM(s_P); SERIAL_CHAR(v); }
void serial_echopair_P(const char* s_P, int v) { serialprintPGM(s_P); SERIAL_ECHO(v); }
void serial_echopair_P(const char* s_P, long v) { serialprintPGM(s_P); SERIAL_ECHO(v); }
void serial_echopair_P(const char* s_P, float v) { serialprintPGM(s_P); SERIAL_ECHO(v); }
void serial_echopair_P(const char* s_P, double v) { serialprintPGM(s_P); SERIAL_ECHO(v); }
void serial_echopair_P(const char* s_P, unsigned long v) { serialprintPGM(s_P); SERIAL_ECHO(v); }
void tool_change(const uint8_t tmp_extruder, const float fr_mm_s=0.0, bool no_move=false); void tool_change(const uint8_t tmp_extruder, const float fr_mm_s=0.0, bool no_move=false);
static void report_current_position(); static void report_current_position();
@ -1789,15 +1779,10 @@ static void clean_up_after_endstop_or_probe_move() {
SERIAL_ECHOLNPGM(" " MSG_FIRST); SERIAL_ECHOLNPGM(" " MSG_FIRST);
#if ENABLED(ULTRA_LCD) #if ENABLED(ULTRA_LCD)
char message[3 * (LCD_WIDTH) + 1] = ""; // worst case is kana.utf with up to 3*LCD_WIDTH+1 lcd_status_printf_P(0, PSTR(MSG_HOME " %s%s%s " MSG_FIRST), xx ? MSG_X : "", yy ? MSG_Y : "", zz ? MSG_Z : "");
strcat_P(message, PSTR(MSG_HOME " "));
if (xx) strcat_P(message, PSTR(MSG_X));
if (yy) strcat_P(message, PSTR(MSG_Y));
if (zz) strcat_P(message, PSTR(MSG_Z));
strcat_P(message, PSTR(" " MSG_FIRST));
lcd_setstatus(message);
#endif #endif
return true; return true;
} }
return false; return false;
} }
@ -5153,7 +5138,6 @@ inline void gcode_M31() {
char buffer[21]; char buffer[21];
duration_t elapsed = print_job_timer.duration(); duration_t elapsed = print_job_timer.duration();
elapsed.toString(buffer); elapsed.toString(buffer);
lcd_setstatus(buffer); lcd_setstatus(buffer);
SERIAL_ECHO_START; SERIAL_ECHO_START;
@ -5700,7 +5684,7 @@ inline void gcode_M104() {
} }
#endif #endif
if (code_value_temp_abs() > thermalManager.degHotend(target_extruder)) status_printf(0, PSTR("E%i %s"), target_extruder + 1, MSG_HEATING); if (code_value_temp_abs() > thermalManager.degHotend(target_extruder)) lcd_status_printf_P(0, PSTR("E%i %s"), target_extruder + 1, MSG_HEATING);
} }
#if ENABLED(AUTOTEMP) #if ENABLED(AUTOTEMP)
@ -5898,7 +5882,7 @@ inline void gcode_M109() {
else print_job_timer.start(); else print_job_timer.start();
#endif #endif
if (thermalManager.isHeatingHotend(target_extruder)) status_printf(0, PSTR("E%i %s"), target_extruder + 1, MSG_HEATING); if (thermalManager.isHeatingHotend(target_extruder)) lcd_status_printf_P(0, PSTR("E%i %s"), target_extruder + 1, MSG_HEATING);
} }
#if ENABLED(AUTOTEMP) #if ENABLED(AUTOTEMP)
@ -8903,7 +8887,7 @@ void process_next_command() {
gcode_G28(); gcode_G28();
break; break;
#if PLANNER_LEVELING && !ENABLED(AUTO_BED_LEVELING_UBL) || ENABLED(AUTO_BED_LEVELING_UBL) && ENABLED(UBL_G26_MESH_EDITING) #if PLANNER_LEVELING || ENABLED(AUTO_BED_LEVELING_UBL)
case 29: // G29 Detailed Z probe, probes the bed at 3 or more points, case 29: // G29 Detailed Z probe, probes the bed at 3 or more points,
// or provides access to the UBL System if enabled. // or provides access to the UBL System if enabled.
gcode_G29(); gcode_G29();
@ -10175,6 +10159,8 @@ void set_current_from_steppers_for_axis(const AxisEnum axis) {
/** /**
* Prepare a linear move in a Cartesian setup. * Prepare a linear move in a Cartesian setup.
* If Mesh Bed Leveling is enabled, perform a mesh move. * If Mesh Bed Leveling is enabled, perform a mesh move.
*
* Returns true if the caller didn't update current_position.
*/ */
inline bool prepare_move_to_destination_cartesian() { inline bool prepare_move_to_destination_cartesian() {
// Do not use feedrate_percentage for E or Z only moves // Do not use feedrate_percentage for E or Z only moves
@ -10190,9 +10176,7 @@ void set_current_from_steppers_for_axis(const AxisEnum axis) {
else else
#elif ENABLED(AUTO_BED_LEVELING_UBL) #elif ENABLED(AUTO_BED_LEVELING_UBL)
if (ubl.state.active) { if (ubl.state.active) {
ubl_line_to_destination(MMS_SCALED(feedrate_mm_s), active_extruder); ubl_line_to_destination(MMS_SCALED(feedrate_mm_s), active_extruder);
return false; return false;
} }
else else

@ -29,6 +29,7 @@
#if ENABLED(AUTO_BED_LEVELING_UBL) #if ENABLED(AUTO_BED_LEVELING_UBL)
#define UBL_VERSION "1.00"
#define UBL_OK false #define UBL_OK false
#define UBL_ERR true #define UBL_ERR true
@ -98,9 +99,6 @@
float g29_correction_fade_height = 10.0, float g29_correction_fade_height = 10.0,
g29_fade_height_multiplier = 1.0 / 10.0; // It's cheaper to do a floating point multiply than divide, g29_fade_height_multiplier = 1.0 / 10.0; // It's cheaper to do a floating point multiply than divide,
// so keep this value and its reciprocal. // so keep this value and its reciprocal.
#else
const float g29_correction_fade_height = 10.0,
g29_fade_height_multiplier = 1.0 / 10.0;
#endif #endif
// If you change this struct, adjust TOTAL_STRUCT_SIZE // If you change this struct, adjust TOTAL_STRUCT_SIZE
@ -118,8 +116,7 @@
class unified_bed_leveling { class unified_bed_leveling {
private: private:
static float last_specified_z, static float last_specified_z;
fade_scaling_factor_for_current_height;
public: public:
@ -307,32 +304,29 @@
} }
/** /**
* This routine is used to scale the Z correction depending upon the current nozzle height. It is * This function sets the Z leveling fade factor based on the given Z height,
* optimized for speed. It avoids floating point operations by checking if the requested scaling * only re-calculating when necessary.
* factor is going to be the same as the last time the function calculated a value. If so, it just
* returns it.
* *
* It returns a scaling factor of 1.0 if UBL is inactive. * Returns 1.0 if g29_correction_fade_height is 0.0.
* It returns a scaling factor of 0.0 if Z is past the specified 'Fade Height' * Returns 0.0 if Z is past the specified 'Fade Height'.
*/ */
#if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT)
static FORCE_INLINE float fade_scaling_factor_for_z(const float &lz) { static FORCE_INLINE float fade_scaling_factor_for_z(const float &lz) {
if (state.g29_correction_fade_height == 0.0) return 1.0;
static float fade_scaling_factor = 1.0;
const float rz = RAW_Z_POSITION(lz); const float rz = RAW_Z_POSITION(lz);
if (last_specified_z != rz) { if (last_specified_z != rz) {
last_specified_z = rz; last_specified_z = rz;
fade_scaling_factor_for_current_height = fade_scaling_factor =
state.active && rz < state.g29_correction_fade_height rz < state.g29_correction_fade_height
? 1.0 - (rz * state.g29_fade_height_multiplier) ? 1.0 - (rz * state.g29_fade_height_multiplier)
: 0.0; : 0.0;
} }
return fade_scaling_factor_for_current_height; return fade_scaling_factor;
} }
#else
static constexpr float fade_scaling_factor_for_z(const float &lz) { UNUSED(lz); return 1.0; }
#endif #endif
}; // class unified_bed_leveling }; // class unified_bed_leveling

@ -61,7 +61,6 @@
float unified_bed_leveling::z_values[UBL_MESH_NUM_X_POINTS][UBL_MESH_NUM_Y_POINTS], float unified_bed_leveling::z_values[UBL_MESH_NUM_X_POINTS][UBL_MESH_NUM_Y_POINTS],
unified_bed_leveling::last_specified_z, unified_bed_leveling::last_specified_z,
unified_bed_leveling::fade_scaling_factor_for_current_height,
unified_bed_leveling::mesh_index_to_xpos[UBL_MESH_NUM_X_POINTS + 1], // +1 safety margin for now, until determinism prevails unified_bed_leveling::mesh_index_to_xpos[UBL_MESH_NUM_X_POINTS + 1], // +1 safety margin for now, until determinism prevails
unified_bed_leveling::mesh_index_to_ypos[UBL_MESH_NUM_Y_POINTS + 1]; unified_bed_leveling::mesh_index_to_ypos[UBL_MESH_NUM_Y_POINTS + 1];
@ -102,8 +101,9 @@
* updated, but until then, we try to ease the transition * updated, but until then, we try to ease the transition
* for our Beta testers. * for our Beta testers.
*/ */
if (ubl.state.g29_fade_height_multiplier != 1.0 / ubl.state.g29_correction_fade_height) { const float recip = ubl.state.g29_correction_fade_height ? 1.0 / ubl.state.g29_correction_fade_height : 1.0;
ubl.state.g29_fade_height_multiplier = 1.0 / ubl.state.g29_correction_fade_height; if (ubl.state.g29_fade_height_multiplier != recip) {
ubl.state.g29_fade_height_multiplier = recip;
store_state(); store_state();
} }
#endif #endif
@ -160,7 +160,6 @@
ZERO(z_values); ZERO(z_values);
last_specified_z = -999.9; last_specified_z = -999.9;
fade_scaling_factor_for_current_height = 0.0;
} }
void unified_bed_leveling::invalidate() { void unified_bed_leveling::invalidate() {

@ -307,7 +307,8 @@
static float x_pos, y_pos, measured_z, card_thickness = 0.0, ubl_constant = 0.0; static float x_pos, y_pos, measured_z, card_thickness = 0.0, ubl_constant = 0.0;
#if ENABLED(ULTRA_LCD) #if ENABLED(ULTRA_LCD)
void lcd_setstatus(const char* message, bool persist); extern void lcd_setstatus(const char* message, const bool persist);
extern void lcd_setstatuspgm(const char* message, const uint8_t level);
#endif #endif
void gcode_G29() { void gcode_G29() {
@ -655,7 +656,7 @@
if (ELAPSED(millis(), nxt)) { if (ELAPSED(millis(), nxt)) {
SERIAL_PROTOCOLLNPGM("\nZ-Offset Adjustment Stopped."); SERIAL_PROTOCOLLNPGM("\nZ-Offset Adjustment Stopped.");
do_blocking_move_to_z(Z_CLEARANCE_DEPLOY_PROBE); do_blocking_move_to_z(Z_CLEARANCE_DEPLOY_PROBE);
lcd_setstatus("Z-Offset Stopped", true); lcd_setstatuspgm("Z-Offset Stopped");
restore_ubl_active_state_and_leave(); restore_ubl_active_state_and_leave();
goto LEAVE; goto LEAVE;
} }
@ -673,7 +674,8 @@
LEAVE: LEAVE:
#if ENABLED(ULTRA_LCD) #if ENABLED(ULTRA_LCD)
lcd_setstatus(" ", true); lcd_reset_alert_level();
lcd_setstatuspgm("");
lcd_quick_feedback(); lcd_quick_feedback();
#endif #endif
@ -977,7 +979,7 @@
bool g29_parameter_parsing() { bool g29_parameter_parsing() {
#if ENABLED(ULTRA_LCD) #if ENABLED(ULTRA_LCD)
lcd_setstatus("Doing G29 UBL !", true); lcd_setstatuspgm("Doing G29 UBL!");
lcd_quick_feedback(); lcd_quick_feedback();
#endif #endif
@ -1088,7 +1090,7 @@
ubl_state_recursion_chk++; ubl_state_recursion_chk++;
if (ubl_state_recursion_chk != 1) { if (ubl_state_recursion_chk != 1) {
SERIAL_ECHOLNPGM("save_ubl_active_state_and_disabled() called multiple times in a row."); SERIAL_ECHOLNPGM("save_ubl_active_state_and_disabled() called multiple times in a row.");
lcd_setstatus("save_UBL_active() error", true); lcd_setstatuspgm("save_UBL_active() error");
lcd_quick_feedback(); lcd_quick_feedback();
return; return;
} }
@ -1099,7 +1101,7 @@
void restore_ubl_active_state_and_leave() { void restore_ubl_active_state_and_leave() {
if (--ubl_state_recursion_chk) { if (--ubl_state_recursion_chk) {
SERIAL_ECHOLNPGM("restore_ubl_active_state_and_leave() called too many times."); SERIAL_ECHOLNPGM("restore_ubl_active_state_and_leave() called too many times.");
lcd_setstatus("restore_UBL_active() error", true); lcd_setstatuspgm("restore_UBL_active() error");
lcd_quick_feedback(); lcd_quick_feedback();
return; return;
} }
@ -1114,7 +1116,7 @@
void g29_what_command() { void g29_what_command() {
const uint16_t k = E2END - ubl.eeprom_start; const uint16_t k = E2END - ubl.eeprom_start;
SERIAL_PROTOCOLPGM("Unified Bed Leveling System Version 1.00 "); SERIAL_PROTOCOLPGM("Unified Bed Leveling System Version " UBL_VERSION " ");
if (ubl.state.active) if (ubl.state.active)
SERIAL_PROTOCOLCHAR('A'); SERIAL_PROTOCOLCHAR('A');
else else
@ -1132,8 +1134,7 @@
safe_delay(50); safe_delay(50);
#if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT)
SERIAL_PROTOCOLPAIR("g29_correction_fade_height : ", ubl.state.g29_correction_fade_height); SERIAL_PROTOCOLLNPAIR("g29_correction_fade_height : ", ubl.state.g29_correction_fade_height);
SERIAL_EOL;
#endif #endif
SERIAL_PROTOCOLPGM("z_offset: "); SERIAL_PROTOCOLPGM("z_offset: ");
@ -1340,7 +1341,7 @@
memset(not_done, 0xFF, sizeof(not_done)); memset(not_done, 0xFF, sizeof(not_done));
#if ENABLED(ULTRA_LCD) #if ENABLED(ULTRA_LCD)
lcd_setstatus("Fine Tuning Mesh.", true); lcd_setstatuspgm("Fine Tuning Mesh");
#endif #endif
do_blocking_move_to_z(Z_CLEARANCE_DEPLOY_PROBE); do_blocking_move_to_z(Z_CLEARANCE_DEPLOY_PROBE);
@ -1399,7 +1400,7 @@
lcd_return_to_status(); lcd_return_to_status();
//SERIAL_PROTOCOLLNPGM("\nFine Tuning of Mesh Stopped."); //SERIAL_PROTOCOLLNPGM("\nFine Tuning of Mesh Stopped.");
do_blocking_move_to_z(Z_CLEARANCE_DEPLOY_PROBE); do_blocking_move_to_z(Z_CLEARANCE_DEPLOY_PROBE);
lcd_setstatus("Mesh Editing Stopped", true); lcd_setstatuspgm("Mesh Editing Stopped");
while (ubl_lcd_clicked()) idle(); while (ubl_lcd_clicked()) idle();
@ -1427,9 +1428,9 @@
do_blocking_move_to_xy(lx, ly); do_blocking_move_to_xy(lx, ly);
#if ENABLED(ULTRA_LCD) #if ENABLED(ULTRA_LCD)
lcd_setstatus("Done Editing Mesh", true); lcd_setstatuspgm("Done Editing Mesh");
#endif #endif
SERIAL_ECHOLNPGM("Done Editing Mesh."); SERIAL_ECHOLNPGM("Done Editing Mesh");
} }
#endif // AUTO_BED_LEVELING_UBL #endif // AUTO_BED_LEVELING_UBL

@ -170,9 +170,7 @@ void Endstops::report_state() {
SERIAL_EOL; SERIAL_EOL;
#if ENABLED(ULTRA_LCD) #if ENABLED(ULTRA_LCD)
char msg[3 * strlen(MSG_LCD_ENDSTOPS) + 8 + 1]; // Room for a UTF 8 string lcd_status_printf_P(0, PSTR(MSG_LCD_ENDSTOPS " %c %c %c %c"), chrX, chrY, chrZ, chrP);
sprintf_P(msg, PSTR(MSG_LCD_ENDSTOPS " %c %c %c %c"), chrX, chrY, chrZ, chrP);
lcd_setstatus(msg);
#endif #endif
hit_on_purpose(); hit_on_purpose();

@ -0,0 +1,34 @@
/**
* 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 "serial.h"
const char errormagic[] PROGMEM = "Error:";
const char echomagic[] PROGMEM = "echo:";
void serial_echopair_P(const char* s_P, const char *v) { serialprintPGM(s_P); SERIAL_ECHO(v); }
void serial_echopair_P(const char* s_P, char v) { serialprintPGM(s_P); SERIAL_CHAR(v); }
void serial_echopair_P(const char* s_P, int v) { serialprintPGM(s_P); SERIAL_ECHO(v); }
void serial_echopair_P(const char* s_P, long v) { serialprintPGM(s_P); SERIAL_ECHO(v); }
void serial_echopair_P(const char* s_P, float v) { serialprintPGM(s_P); SERIAL_ECHO(v); }
void serial_echopair_P(const char* s_P, double v) { serialprintPGM(s_P); SERIAL_ECHO(v); }
void serial_echopair_P(const char* s_P, unsigned long v) { serialprintPGM(s_P); SERIAL_ECHO(v); }

@ -0,0 +1,88 @@
/**
* 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 __SERIAL_H__
#define __SERIAL_H__
#ifdef USBCON
#include "HardwareSerial.h"
#if ENABLED(BLUETOOTH)
#define MYSERIAL bluetoothSerial
#else
#define MYSERIAL Serial
#endif // BLUETOOTH
#else
#include "MarlinSerial.h"
#define MYSERIAL customizedSerial
#endif
extern const char echomagic[] PROGMEM;
extern const char errormagic[] PROGMEM;
#define SERIAL_CHAR(x) (MYSERIAL.write(x))
#define SERIAL_EOL SERIAL_CHAR('\n')
#define SERIAL_PROTOCOLCHAR(x) SERIAL_CHAR(x)
#define SERIAL_PROTOCOL(x) (MYSERIAL.print(x))
#define SERIAL_PROTOCOL_F(x,y) (MYSERIAL.print(x,y))
#define SERIAL_PROTOCOLPGM(x) (serialprintPGM(PSTR(x)))
#define SERIAL_PROTOCOLLN(x) do{ MYSERIAL.print(x); SERIAL_EOL; }while(0)
#define SERIAL_PROTOCOLLNPGM(x) (serialprintPGM(PSTR(x "\n")))
#define SERIAL_PROTOCOLPAIR(name, value) (serial_echopair_P(PSTR(name),(value)))
#define SERIAL_PROTOCOLLNPAIR(name, value) do{ SERIAL_PROTOCOLPAIR(name, value); SERIAL_EOL; }while(0)
#define SERIAL_ECHO_START (serialprintPGM(echomagic))
#define SERIAL_ECHO(x) SERIAL_PROTOCOL(x)
#define SERIAL_ECHOPGM(x) SERIAL_PROTOCOLPGM(x)
#define SERIAL_ECHOLN(x) SERIAL_PROTOCOLLN(x)
#define SERIAL_ECHOLNPGM(x) SERIAL_PROTOCOLLNPGM(x)
#define SERIAL_ECHOPAIR(name,value) SERIAL_PROTOCOLPAIR(name, value)
#define SERIAL_ECHOLNPAIR(name, value) SERIAL_PROTOCOLLNPAIR(name, value)
#define SERIAL_ECHO_F(x,y) SERIAL_PROTOCOL_F(x,y)
#define SERIAL_ERROR_START (serialprintPGM(errormagic))
#define SERIAL_ERROR(x) SERIAL_PROTOCOL(x)
#define SERIAL_ERRORPGM(x) SERIAL_PROTOCOLPGM(x)
#define SERIAL_ERRORLN(x) SERIAL_PROTOCOLLN(x)
#define SERIAL_ERRORLNPGM(x) SERIAL_PROTOCOLLNPGM(x)
void serial_echopair_P(const char* s_P, const char *v);
void serial_echopair_P(const char* s_P, char v);
void serial_echopair_P(const char* s_P, int v);
void serial_echopair_P(const char* s_P, long v);
void serial_echopair_P(const char* s_P, float v);
void serial_echopair_P(const char* s_P, double v);
void serial_echopair_P(const char* s_P, unsigned int v);
void serial_echopair_P(const char* s_P, unsigned long v);
FORCE_INLINE void serial_echopair_P(const char* s_P, uint8_t v) { serial_echopair_P(s_P, (int)v); }
FORCE_INLINE void serial_echopair_P(const char* s_P, uint16_t v) { serial_echopair_P(s_P, (int)v); }
FORCE_INLINE void serial_echopair_P(const char* s_P, bool v) { serial_echopair_P(s_P, (int)v); }
FORCE_INLINE void serial_echopair_P(const char* s_P, void *v) { serial_echopair_P(s_P, (unsigned long)v); }
//
// Functions for serial printing from PROGMEM. (Saves loads of SRAM.)
//
FORCE_INLINE void serialprintPGM(const char* str) {
while (char ch = pgm_read_byte(str++)) MYSERIAL.write(ch);
}
#endif // __SERIAL_H__

@ -677,7 +677,7 @@ void kill_screen(const char* lcd_msg) {
thermalManager.autotempShutdown(); thermalManager.autotempShutdown();
#endif #endif
wait_for_heatup = false; wait_for_heatup = false;
lcd_setstatus(MSG_PRINT_ABORTED, true); lcd_setstatuspgm(PSTR(MSG_PRINT_ABORTED), true);
} }
#endif // SDSUPPORT #endif // SDSUPPORT
@ -3552,30 +3552,30 @@ void lcd_finishstatus(bool persist=false) {
bool lcd_hasstatus() { return (lcd_status_message[0] != '\0'); } bool lcd_hasstatus() { return (lcd_status_message[0] != '\0'); }
void lcd_setstatus(const char* const message, bool persist) { void lcd_setstatus(const char * const message, const bool persist) {
if (lcd_status_message_level > 0) return; if (lcd_status_message_level > 0) return;
strncpy(lcd_status_message, message, 3 * (LCD_WIDTH)); strncpy(lcd_status_message, message, 3 * (LCD_WIDTH));
lcd_finishstatus(persist); lcd_finishstatus(persist);
} }
void lcd_setstatuspgm(const char* const message, uint8_t level) { void lcd_setstatuspgm(const char * const message, const uint8_t level) {
if (level < lcd_status_message_level) return; if (level < lcd_status_message_level) return;
lcd_status_message_level = level; lcd_status_message_level = level;
strncpy_P(lcd_status_message, message, 3 * (LCD_WIDTH)); strncpy_P(lcd_status_message, message, 3 * (LCD_WIDTH));
lcd_finishstatus(level > 0); lcd_finishstatus(level > 0);
} }
void status_printf(uint8_t level, const char *status, ...) { void lcd_status_printf_P(const uint8_t level, const char * const fmt, ...) {
if (level < lcd_status_message_level) return; if (level < lcd_status_message_level) return;
lcd_status_message_level = level; lcd_status_message_level = level;
va_list args; va_list args;
va_start(args, status); va_start(args, fmt);
vsnprintf_P(lcd_status_message, 3 * (LCD_WIDTH), status, args); vsnprintf_P(lcd_status_message, 3 * (LCD_WIDTH), fmt, args);
va_end(args); va_end(args);
lcd_finishstatus(level > 0); lcd_finishstatus(level > 0);
} }
void lcd_setalertstatuspgm(const char* const message) { void lcd_setalertstatuspgm(const char * const message) {
lcd_setstatuspgm(message, 1); lcd_setstatuspgm(message, 1);
#if ENABLED(ULTIPANEL) #if ENABLED(ULTIPANEL)
lcd_return_to_status(); lcd_return_to_status();

@ -39,7 +39,7 @@
bool lcd_hasstatus(); bool lcd_hasstatus();
void lcd_setstatus(const char* message, const bool persist=false); void lcd_setstatus(const char* message, const bool persist=false);
void lcd_setstatuspgm(const char* message, const uint8_t level=0); void lcd_setstatuspgm(const char* message, const uint8_t level=0);
void status_printf(uint8_t level, const char *Status, ...); void lcd_status_printf_P(const uint8_t level, const char * const fmt, ...);
void lcd_setalertstatuspgm(const char* message); void lcd_setalertstatuspgm(const char* message);
void lcd_reset_alert_level(); void lcd_reset_alert_level();
void lcd_kill_screen(); void lcd_kill_screen();
@ -154,7 +154,7 @@
inline bool lcd_hasstatus() { return false; } inline bool lcd_hasstatus() { return false; }
inline void lcd_setstatus(const char* const message, const bool persist=false) { UNUSED(message); UNUSED(persist); } inline void lcd_setstatus(const char* const message, const bool persist=false) { UNUSED(message); UNUSED(persist); }
inline void lcd_setstatuspgm(const char* const message, const uint8_t level=0) { UNUSED(message); UNUSED(level); } inline void lcd_setstatuspgm(const char* const message, const uint8_t level=0) { UNUSED(message); UNUSED(level); }
inline void status_printf(uint8_t level, const char *status, ...) { UNUSED(level); UNUSED(status); } inline void lcd_status_printf_P(const uint8_t level, const char * const fmt, ...) { UNUSED(level); UNUSED(fmt); }
inline void lcd_buttons_update() {} inline void lcd_buttons_update() {}
inline void lcd_reset_alert_level() {} inline void lcd_reset_alert_level() {}
inline bool lcd_detected() { return true; } inline bool lcd_detected() { return true; }

Loading…
Cancel
Save