From b8525f80435748c24c9ce63805d9363c1b031f67 Mon Sep 17 00:00:00 2001 From: Robert Pelnar Date: Mon, 20 Nov 2017 20:09:54 +0100 Subject: [PATCH] Print class printf function (experimental, disabled by default) LiquidCrystal VT100 escape codes (EraseScreen, CursorHome, ...) Stream support for lcd and uart, fprintf and printf (stdout=uartout) Dcodes enabled, code reduced, printf used Splash screen with esc codes --- .../marlin/avr/cores/arduino/Print.cpp | 45 ++++ .../hardware/marlin/avr/cores/arduino/Print.h | 12 +- Firmware/Configuration_prusa.h | 2 +- Firmware/Dcodes.cpp | 207 +++++++++--------- Firmware/LiquidCrystal.cpp | 143 +++++++++++- Firmware/LiquidCrystal.h | 11 +- Firmware/Marlin.h | 6 + Firmware/Marlin_main.cpp | 43 +++- 8 files changed, 359 insertions(+), 110 deletions(-) diff --git a/ArduinoAddons/Arduino_1.6.x/hardware/marlin/avr/cores/arduino/Print.cpp b/ArduinoAddons/Arduino_1.6.x/hardware/marlin/avr/cores/arduino/Print.cpp index 5df56306..17dc50c1 100755 --- a/ArduinoAddons/Arduino_1.6.x/hardware/marlin/avr/cores/arduino/Print.cpp +++ b/ArduinoAddons/Arduino_1.6.x/hardware/marlin/avr/cores/arduino/Print.cpp @@ -262,3 +262,48 @@ size_t Print::printFloat(double number, uint8_t digits) return n; } + + +//printf +#ifdef _Print_printf + +#include + +#define PRINTF_BUF 80 // define the tmp buffer size (change if desired) + +void Print::printf(const char *format, ...) +{ + char buf[PRINTF_BUF]; + va_list ap; + va_start(ap, format); + vsnprintf(buf, sizeof(buf), format, ap); + for(char *p = &buf[0]; *p; p++) // emulate cooked mode for newlines + { + if(*p == '\n') + write('\r'); + write(*p); + } + va_end(ap); +} +#ifdef F // check to see if F() macro is available +void Print::printf(const __FlashStringHelper *format, ...) +{ + char buf[PRINTF_BUF]; + va_list ap; + va_start(ap, format); +#ifdef __AVR__ + vsnprintf_P(buf, sizeof(buf), (const char *)format, ap); // progmem for AVR +#else + vsnprintf(buf, sizeof(buf), (const char *)format, ap); // for the rest of the world +#endif + for(char *p = &buf[0]; *p; p++) // emulate cooked mode for newlines + { + if(*p == '\n') + write('\r'); + write(*p); + } + va_end(ap); +} +#endif + +#endif //_Print_printf \ No newline at end of file diff --git a/ArduinoAddons/Arduino_1.6.x/hardware/marlin/avr/cores/arduino/Print.h b/ArduinoAddons/Arduino_1.6.x/hardware/marlin/avr/cores/arduino/Print.h index 7b53aa4d..20cf5378 100755 --- a/ArduinoAddons/Arduino_1.6.x/hardware/marlin/avr/cores/arduino/Print.h +++ b/ArduinoAddons/Arduino_1.6.x/hardware/marlin/avr/cores/arduino/Print.h @@ -31,6 +31,8 @@ #define OCT 8 #define BIN 2 +//#define _Print_printf + class Print { private: @@ -79,6 +81,14 @@ class Print size_t println(double, int = 2); size_t println(const Printable&); size_t println(void); + +//printf +#ifdef _Print_printf + void printf(const char *format, ...); +#ifdef F // check to see if F() macro is available + void printf(const __FlashStringHelper *format, ...); +#endif +#endif //_Print_printf }; -#endif +#endif \ No newline at end of file diff --git a/Firmware/Configuration_prusa.h b/Firmware/Configuration_prusa.h index c9d77255..1ee2ba03 100644 --- a/Firmware/Configuration_prusa.h +++ b/Firmware/Configuration_prusa.h @@ -82,7 +82,7 @@ const bool Z_MIN_ENDSTOP_INVERTING = false; // set to true to invert the logic o //DEBUG //#define _NO_ASM -//#define DEBUG_DCODES //D codes +#define DEBUG_DCODES //D codes #if 1 //#define DEBUG_FSENSOR_LOG //Reports fsensor status to serial //#define DEBUG_CRASHDET_COUNTERS //Display crash-detection counters on LCD diff --git a/Firmware/Dcodes.cpp b/Firmware/Dcodes.cpp index 84ce6dc8..7041da79 100644 --- a/Firmware/Dcodes.cpp +++ b/Firmware/Dcodes.cpp @@ -9,6 +9,8 @@ #include +#define FLASHSIZE 0x40000 + #define RAMSIZE 0x2000 #define boot_src_addr (*((uint32_t*)(RAMSIZE - 16))) #define boot_dst_addr (*((uint32_t*)(RAMSIZE - 12))) @@ -25,23 +27,53 @@ extern float current_temperature_pinda; extern float axis_steps_per_unit[NUM_AXIS]; -inline void serial_print_hex_nibble(uint8_t val) +inline void print_hex_nibble(uint8_t val) { - MYSERIAL.write((val > 9)?(val - 10 + 'a'):(val + '0')); + putchar((val > 9)?(val - 10 + 'a'):(val + '0')); } -void serial_print_hex_byte(uint8_t val) +void print_hex_byte(uint8_t val) { - serial_print_hex_nibble(val >> 4); - serial_print_hex_nibble(val & 15); + print_hex_nibble(val >> 4); + print_hex_nibble(val & 15); } -void serial_print_hex_word(uint16_t val) +void print_hex_word(uint16_t val) { - serial_print_hex_byte(val >> 8); - serial_print_hex_byte(val & 255); + print_hex_byte(val >> 8); + print_hex_byte(val & 255); } +void print_mem(uint32_t address, uint16_t count, uint8_t type, uint8_t countperline = 16) +{ + while (count) + { + if (type == 2) + print_hex_nibble(address >> 16); + print_hex_word(address); + putchar(' '); + uint8_t count_line = countperline; + while (count && count_line) + { + uint8_t data = 0; + switch (type) + { + case 0: data = *((uint8_t*)address++); break; + case 1: data = eeprom_read_byte((uint8_t*)address++); break; + case 2: data = pgm_read_byte_far((uint8_t*)address++); break; + } + putchar(' '); + print_hex_byte(data); + count_line--; + count--; + } + putchar('\n'); + } +} + +//#define LOG(args...) printf(args) +#define LOG(args...) + int parse_hex(char* hex, uint8_t* data, int count) { int parsed = 0; @@ -68,7 +100,7 @@ int parse_hex(char* hex, uint8_t* data, int count) void dcode_0() { if (*(strchr_pointer + 1) == 0) return; - MYSERIAL.println("D0 - Reset"); + LOG("D0 - Reset\n"); if (code_seen('B')) //bootloader { cli(); @@ -85,7 +117,7 @@ void dcode_0() void dcode_1() { - MYSERIAL.println("D1 - Clear EEPROM and RESET"); + LOG("D1 - Clear EEPROM and RESET\n"); cli(); for (int i = 0; i < 8192; i++) eeprom_write_byte((unsigned char*)i, (unsigned char)0xff); @@ -95,7 +127,7 @@ void dcode_1() void dcode_2() { - MYSERIAL.println("D2 - Read/Write RAM"); + LOG("D2 - Read/Write RAM\n"); uint16_t address = 0x0000; //default 0x0000 uint16_t count = 0x2000; //default 0x2000 (entire ram) if (code_seen('A')) // Address (0x0000-0x1fff) @@ -113,34 +145,32 @@ void dcode_2() { for (int i = 0; i < count; i++) *((uint8_t*)(address + i)) = data[i]; - MYSERIAL.print(count, DEC); - MYSERIAL.println(" bytes written to RAM at address "); - serial_print_hex_word(address); - MYSERIAL.write('\n'); + LOG("%d bytes written to RAM at address %04x", count, address); } else count = 0; } - while (count) + print_mem(address, count, 0); +/* while (count) { - serial_print_hex_word(address); - MYSERIAL.write(' '); + print_hex_word(address); + putchar(' '); uint8_t countperline = 16; while (count && countperline) { uint8_t data = *((uint8_t*)address++); - MYSERIAL.write(' '); - serial_print_hex_byte(data); + putchar(' '); + print_hex_byte(data); countperline--; count--; } - MYSERIAL.write('\n'); - } + putchar('\n'); + }*/ } void dcode_3() { - MYSERIAL.println("D3 - Read/Write EEPROM"); + LOG("D3 - Read/Write EEPROM\n"); uint16_t address = 0x0000; //default 0x0000 uint16_t count = 0x2000; //default 0x2000 (entire eeprom) if (code_seen('A')) // Address (0x0000-0x1fff) @@ -158,34 +188,35 @@ void dcode_3() { for (int i = 0; i < count; i++) eeprom_write_byte((uint8_t*)(address + i), data[i]); - MYSERIAL.print(count, DEC); - MYSERIAL.println(" bytes written to EEPROM at address "); - serial_print_hex_word(address); - MYSERIAL.write('\n'); + LOG(count, DEC); + LOG(" bytes written to EEPROM at address "); + print_hex_word(address); + putchar('\n'); } else count = 0; } - while (count) + print_mem(address, count, 1); +/* while (count) { - serial_print_hex_word(address); - MYSERIAL.write(' '); + print_hex_word(address); + putchar(' '); uint8_t countperline = 16; while (count && countperline) { uint8_t data = eeprom_read_byte((uint8_t*)address++); - MYSERIAL.write(' '); - serial_print_hex_byte(data); + putchar(' '); + print_hex_byte(data); countperline--; count--; } - MYSERIAL.write('\n'); - } + putchar('\n'); + }*/ } void dcode_4() { - MYSERIAL.println("D4 - Read/Write PIN"); + LOG("D4 - Read/Write PIN\n"); if (code_seen('P')) // Pin (0-255) { int pin = (int)code_value(); @@ -206,18 +237,15 @@ void dcode_4() else { int val = (digitalRead(pin) != LOW)?1:0; - MYSERIAL.print("PIN"); - MYSERIAL.print(pin); - MYSERIAL.print("="); - MYSERIAL.println(val); + printf("PIN%d=%d", pin, val); } } } } - +/* void dcode_5() { - MYSERIAL.println("D5 - Read/Write FLASH"); + LOG("D5 - Read/Write FLASH\n"); uint32_t address = 0x0000; //default 0x0000 uint16_t count = 0x0400; //default 0x0400 (1kb block) if (code_seen('A')) // Address (0x00000-0x3ffff) @@ -241,17 +269,17 @@ void dcode_5() { if (bErase) { - MYSERIAL.print(count, DEC); - MYSERIAL.println(" bytes of FLASH at address "); - serial_print_hex_word(address); - MYSERIAL.write(" will be erased\n"); + LOG(count, DEC); + LOG(" bytes of FLASH at address "); + print_hex_word(address); + putchar(" will be erased\n"); } if (bCopy) { - MYSERIAL.print(count, DEC); - MYSERIAL.println(" bytes will be written to FLASH at address "); - serial_print_hex_word(address); - MYSERIAL.write('\n'); + LOG(count, DEC); + LOG(" bytes will be written to FLASH at address "); + print_hex_word(address); + putchar('\n'); } cli(); boot_app_magic = 0x55aa55aa; @@ -264,30 +292,31 @@ void dcode_5() } while (count) { - serial_print_hex_nibble(address >> 16); - serial_print_hex_word(address); - MYSERIAL.write(' '); + print_hex_nibble(address >> 16); + print_hex_word(address); + putchar(' '); uint8_t countperline = 16; while (count && countperline) { uint8_t data = pgm_read_byte_far((uint8_t*)address++); - MYSERIAL.write(' '); - serial_print_hex_byte(data); + putchar(' '); + print_hex_byte(data); countperline--; count--; } - MYSERIAL.write('\n'); + putchar('\n'); } } +*/ void dcode_6() { - MYSERIAL.println("D6 - Read/Write external FLASH"); + LOG("D6 - Read/Write external FLASH\n"); } void dcode_7() { - MYSERIAL.println("D7 - Read/Write Bootloader"); + LOG("D7 - Read/Write Bootloader\n"); /* cli(); boot_app_magic = 0x55aa55aa; @@ -302,23 +331,23 @@ void dcode_7() void dcode_8() { - MYSERIAL.println("D8 - Read/Write PINDA"); + LOG("D8 - Read/Write PINDA\n"); uint8_t cal_status = calibration_status_pinda(); float temp_pinda = current_temperature_pinda; float offset_z = temp_compensation_pinda_thermistor_offset(temp_pinda); if ((strchr_pointer[1+1] == '?') || (strchr_pointer[1+1] == 0)) { - MYSERIAL.print("cal_status="); - MYSERIAL.println(cal_status?"1":"0"); + LOG("cal_status="); + LOG(cal_status?"1\n":"0\n"); for (uint8_t i = 0; i < 6; i++) { - MYSERIAL.print("temp_pinda="); - MYSERIAL.print(35 + i * 5, DEC); - MYSERIAL.print("C, temp_shift="); + LOG("temp_pinda="); + LOG(35 + i * 5, DEC); + LOG("C, temp_shift="); uint16_t offs = 0; if (i > 0) offs = eeprom_read_word(((uint16_t*)EEPROM_PROBE_TEMP_SHIFT) + (i - 1)); - MYSERIAL.print(((float)offs) / axis_steps_per_unit[Z_AXIS], 3); - MYSERIAL.println("mm"); + LOG(((float)offs) / axis_steps_per_unit[Z_AXIS], 3); + LOG("mm\n"); } } else if (strchr_pointer[1+1] == '!') @@ -341,21 +370,21 @@ void dcode_8() offset_z = code_value(); } } - MYSERIAL.print("temp_pinda="); - MYSERIAL.println(temp_pinda); - MYSERIAL.print("offset_z="); - MYSERIAL.println(offset_z, 3); + LOG("temp_pinda="); + LOG(temp_pinda); + LOG("offset_z="); + LOG(offset_z, 3); } void dcode_10() {//Tell the printer that XYZ calibration went OK - MYSERIAL.println("D10 - XYZ calibration = OK"); + LOG("D10 - XYZ calibration = OK\n"); calibration_status_store(CALIBRATION_STATUS_LIVE_ADJUST); } void dcode_12() {//Reset Filament error, Power loss and crash counter ( Do it before every print and you can get stats for the print ) - MYSERIAL.println("D12 - Reset failstat counters"); + LOG("D12 - Reset failstat counters\n"); eeprom_update_byte((uint8_t*)EEPROM_CRASH_COUNT, 0x00); eeprom_update_byte((uint8_t*)EEPROM_FERROR_COUNT, 0x00); eeprom_update_byte((uint8_t*)EEPROM_POWER_COUNT, 0x00); @@ -368,59 +397,37 @@ void dcode_2130() void dcode_9125() { - MYSERIAL.println("D9125 - PAT9125"); + LOG("D9125 - PAT9125\n"); if ((strchr_pointer[1+4] == '?') || (strchr_pointer[1+4] == 0)) { - MYSERIAL.print("res_x="); - MYSERIAL.print(pat9125_xres, DEC); - MYSERIAL.print(" res_y="); - MYSERIAL.print(pat9125_yres, DEC); - MYSERIAL.print(" x="); - MYSERIAL.print(pat9125_x, DEC); - MYSERIAL.print(" y="); - MYSERIAL.print(pat9125_y, DEC); - MYSERIAL.print(" b="); - MYSERIAL.print(pat9125_b, DEC); - MYSERIAL.print(" s="); - MYSERIAL.println(pat9125_s, DEC); + printf("res_x=%d res_y=%d x=%d y=%d b=%d s=%d\n", pat9125_xres, pat9125_yres, pat9125_x, pat9125_y, pat9125_b, pat9125_s); return; } if (strchr_pointer[1+4] == '!') { pat9125_update(); - MYSERIAL.print("x="); - MYSERIAL.print(pat9125_x, DEC); - MYSERIAL.print(" y="); - MYSERIAL.print(pat9125_y, DEC); - MYSERIAL.print(" b="); - MYSERIAL.print(pat9125_b, DEC); - MYSERIAL.print(" s="); - MYSERIAL.println(pat9125_s, DEC); + printf("x=%d y=%d b=%d s=%d\n", pat9125_x, pat9125_y, pat9125_b, pat9125_s); return; } if (code_seen('R')) { unsigned char res = (int)code_value(); - MYSERIAL.print("pat9125_init(xres=yres="); - MYSERIAL.print(res, DEC); - MYSERIAL.print(")="); - MYSERIAL.println(pat9125_init(res, res), DEC); + LOG("pat9125_init(xres=yres=%d)=%d\n", res, pat9125_init(res, res)); } if (code_seen('X')) { pat9125_x = (int)code_value(); - MYSERIAL.print("pat9125_x="); - MYSERIAL.print(pat9125_x, DEC); + LOG("pat9125_x=%d\n", pat9125_x); } if (code_seen('Y')) { pat9125_y = (int)code_value(); - MYSERIAL.print("pat9125_y="); - MYSERIAL.print(pat9125_y, DEC); + LOG("pat9125_y=%d\n", pat9125_y); } if (code_seen('L')) { fsensor_log = (int)code_value(); + LOG("fsensor_log=%d\n", fsensor_log); } } diff --git a/Firmware/LiquidCrystal.cpp b/Firmware/LiquidCrystal.cpp index 88ac6dea..cd572756 100644 --- a/Firmware/LiquidCrystal.cpp +++ b/Firmware/LiquidCrystal.cpp @@ -156,6 +156,8 @@ void LiquidCrystal::begin(uint8_t cols, uint8_t lines, uint8_t dotsize) { command(LCD_ENTRYMODESET | _displaymode); delayMicroseconds(60); + _escape[0] = 0; + } @@ -354,10 +356,149 @@ inline void LiquidCrystal::command(uint8_t value) { } inline size_t LiquidCrystal::write(uint8_t value) { + if (_escape[0] || (value == 0x1b)) + return escape_write(value); send(value, HIGH); return 1; // assume sucess } +//Supported VT100 escape codes: +//EraseScreen "\x1b[2J" +//CursorHome "\x1b[%d;%dH" +//CursorShow "\x1b[?25h" +//CursorHide "\x1b[?25l" + +inline size_t LiquidCrystal::escape_write(uint8_t chr) +{ +#define escape_cnt (_escape[0]) //escape character counter +#define is_num_msk (_escape[1]) //numeric character bit mask +#define chr_is_num (is_num_msk & 0x01) //current character is numeric +#define e_2_is_num (is_num_msk & 0x04) //escape char 2 is numeric +#define e_3_is_num (is_num_msk & 0x08) //... +#define e_4_is_num (is_num_msk & 0x10) +#define e_5_is_num (is_num_msk & 0x20) +#define e_6_is_num (is_num_msk & 0x40) +#define e_7_is_num (is_num_msk & 0x80) +#define e2_num (_escape[2] - '0') //number from character 2 +#define e3_num (_escape[3] - '0') //number from character 3 +#define e23_num (10*e2_num+e3_num) //number from characters 2 and 3 +#define e4_num (_escape[4] - '0') //number from character 4 +#define e5_num (_escape[5] - '0') //number from character 5 +#define e45_num (10*e4_num+e5_num) //number from characters 4 and 5 +#define e6_num (_escape[6] - '0') //number from character 6 +#define e56_num (10*e5_num+e6_num) //number from characters 5 and 6 + if (escape_cnt > 1) // escape length > 1 = "\x1b[" + { + _escape[escape_cnt] = chr; // store current char + if ((chr >= '0') && (chr <= '9')) // char is numeric + is_num_msk |= (1 | (1 << escape_cnt)); //set mask + else + is_num_msk &= ~1; //clear mask + } + switch (escape_cnt++) + { + case 0: + if (chr == 0x1b) return 1; // escape = "\x1b" + break; + case 1: + is_num_msk = 0x00; // reset 'is number' bit mask + if (chr == '[') return 1; // escape = "\x1b[" + break; + case 2: + switch (chr) + { + case '2': return 1; // escape = "\x1b[2" + case '?': return 1; // escape = "\x1b[?" + default: + if (chr_is_num) return 1; // escape = "\x1b[%1d" + } + break; + case 3: + switch (_escape[2]) + { + case '?': // escape = "\x1b[?" + if (chr == '2') return 1; // escape = "\x1b[?2" + break; + case '2': + if (chr == 'J') // escape = "\x1b[2J" + { clear(); break; } // EraseScreen + default: + if (e_2_is_num && // escape = "\x1b[%1d" + ((chr == ';') || // escape = "\x1b[%1d;" + chr_is_num)) // escape = "\x1b[%2d" + return 1; + } + break; + case 4: + switch (_escape[2]) + { + case '?': // "\x1b[?" + if ((_escape[3] == '2') && (chr == '5')) return 1; // escape = "\x1b[?25" + break; + default: + if (e_2_is_num) // escape = "\x1b[%1d" + { + if ((_escape[3] == ';') && chr_is_num) return 1; // escape = "\x1b[%1d;%1d" + else if (e_3_is_num && (chr == ';')) return 1; // escape = "\x1b[%2d;" + } + } + break; + case 5: + switch (_escape[2]) + { + case '?': + if ((_escape[3] == '2') && (_escape[4] == '5')) // escape = "\x1b[?25" + switch (chr) + { + case 'h': // escape = "\x1b[?25h" + void cursor(); // CursorShow + break; + case 'l': // escape = "\x1b[?25l" + noCursor(); // CursorHide + break; + } + break; + default: + if (e_2_is_num) // escape = "\x1b[%1d" + { + if ((_escape[3] == ';') && e_4_is_num) // escape = "\x1b%1d;%1dH" + { + if (chr == 'H') // escape = "\x1b%1d;%1dH" + setCursor(e4_num, e2_num); // CursorHome + else if (chr_is_num) + return 1; // escape = "\x1b%1d;%2d" + } + else if (e_3_is_num && (_escape[4] == ';') && chr_is_num) + return 1; // escape = "\x1b%2d;%1d" + } + } + break; + case 6: + if (e_2_is_num) // escape = "\x1b[%1d" + { + if ((_escape[3] == ';') && e_4_is_num && e_5_is_num && (chr == 'H')) // escape = "\x1b%1d;%2dH" + setCursor(e45_num, e2_num); // CursorHome + else if (e_3_is_num && (_escape[4] == ';') && e_5_is_num) // escape = "\x1b%2d;%1d" + { + if (chr == 'H') // escape = "\x1b%2d;%1dH" + setCursor(e5_num, e23_num); // CursorHome + else if (chr_is_num) // "\x1b%2d;%2d" + return 1; + } + } + break; + case 7: + if (e_2_is_num && e_3_is_num && (_escape[4] == ';')) // "\x1b[%2d;" + if (e_5_is_num && e_6_is_num && (chr == 'H')) // "\x1b[%2d;%2dH" + setCursor(e56_num, e23_num); // CursorHome + break; + } + escape_cnt = 0; // reset escape +end: + return 1; // assume sucess +} + + /************ low level data pushing commands **********/ // write either command or data, with automatic 4/8-bit selection @@ -402,4 +543,4 @@ void LiquidCrystal::write8bits(uint8_t value) { } pulseEnable(); -} +} \ No newline at end of file diff --git a/Firmware/LiquidCrystal.h b/Firmware/LiquidCrystal.h index 523303b0..ad3d5caa 100644 --- a/Firmware/LiquidCrystal.h +++ b/Firmware/LiquidCrystal.h @@ -103,6 +103,15 @@ private: uint8_t _initialized; uint8_t _numlines,_currline; + + uint8_t _escape[8]; + size_t escape_write(uint8_t value); + }; -#endif +#define ESC_2J "\x1b[2J" +#define ESC_25h "\x1b[?25h" +#define ESC_25l "\x1b[?25l" +#define ESC_H(c,r) "\x1b["#r";"#c"H" + +#endif \ No newline at end of file diff --git a/Firmware/Marlin.h b/Firmware/Marlin.h index 975a8b0b..93cab1e6 100644 --- a/Firmware/Marlin.h +++ b/Firmware/Marlin.h @@ -62,6 +62,12 @@ #define MYSERIAL MSerial #endif +extern FILE _lcdout; +#define lcdout (&_lcdout) + +extern FILE _uartout; +#define uartout (&_uartout) + #define SERIAL_PROTOCOL(x) (MYSERIAL.print(x)) #define SERIAL_PROTOCOL_F(x,y) (MYSERIAL.print(x,y)) #define SERIAL_PROTOCOLPGM(x) (serialprintPGM(PSTR(x))) diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index 8d9cff23..6d7cfeb8 100644 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -720,7 +720,32 @@ void factory_reset(char level, bool quiet) } +#include "LiquidCrystal.h" +extern LiquidCrystal lcd; +FILE _lcdout = {0}; + +int lcd_putchar(char c, FILE *stream) +{ + lcd.write(c); + return 0; +} + +FILE _uartout = {0}; + +int uart_putchar(char c, FILE *stream) +{ + MYSERIAL.write(c); + return 0; +} + +void lcd_splash() +{ +// lcd_print_at_PGM(0, 1, PSTR(" Original Prusa ")); +// lcd_print_at_PGM(0, 2, PSTR(" 3D Printers ")); +// lcd.print_P(PSTR("\x1b[1;3HOriginal Prusa\x1b[2;4H3D Printers")); + fputs_P(PSTR(ESC_2J ESC_H(3,1) "Original Prusa" ESC_H(4,2) "3D Printers"), lcdout); +} // "Setup" function is called by the Arduino framework on startup. // Before startup, the Timers-functions (PWM)/Analog RW and HardwareSerial provided by the Arduino-code @@ -728,8 +753,8 @@ void factory_reset(char level, bool quiet) void setup() { lcd_init(); - lcd_print_at_PGM(0, 1, PSTR(" Original Prusa ")); - lcd_print_at_PGM(0, 2, PSTR(" 3D Printers ")); + fdev_setup_stream(lcdout, lcd_putchar, NULL, _FDEV_SETUP_WRITE); //setup lcdout stream + lcd_splash(); setup_killpin(); setup_powerhold(); farm_mode = eeprom_read_byte((uint8_t*)EEPROM_FARM_MODE); @@ -744,6 +769,8 @@ void setup() else selectedSerialPort = 0; MYSERIAL.begin(BAUDRATE); + fdev_setup_stream(uartout, uart_putchar, NULL, _FDEV_SETUP_WRITE); //setup uart out stream + stdout = uartout; SERIAL_PROTOCOLLNPGM("start"); SERIAL_ECHO_START; @@ -794,7 +821,11 @@ void setup() // loads data from EEPROM if available else uses defaults (and resets step acceleration rate) Config_RetrieveSettings(EEPROM_OFFSET); SdFatUtil::set_stack_guard(); //writes magic number at the end of static variables to protect against overwriting static memory by stack + tp_init(); // Initialize temperature loop + + lcd_splash(); // we need to do this again, because tp_init() kills lcd + plan_init(); // Initialize planner; watchdog_init(); @@ -833,12 +864,11 @@ void setup() } #endif //PAT9125 - + st_init(); // Initialize stepper, this enables interrupts! setup_photpin(); - lcd_print_at_PGM(0, 1, PSTR(" Original Prusa ")); // we need to do this again for some reason, no time to research - lcd_print_at_PGM(0, 2, PSTR(" 3D Printers ")); + servo_init(); // Reset the machine correction matrix. // It does not make sense to load the correction matrix until the machine is homed. @@ -5853,7 +5883,8 @@ case 404: //M404 Enter the nominal filament width (3mm, 1.75mm ) N<3.0> or disp case 4: // D4 - Read/Write PIN dcode_4(); break; case 5: // D5 - Read/Write FLASH - dcode_5(); break; +// dcode_5(); break; + break; case 6: // D6 - Read/Write external FLASH dcode_6(); break; case 7: // D7 - Read/Write Bootloader