From 4ffa4dd8fdf00476fcc38077e81aa92e162c3ba1 Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Wed, 27 May 2020 09:44:28 +0300 Subject: [PATCH 1/5] Fix missing start on MK3/S --- Firmware/Marlin_main.cpp | 10 +++++++--- Firmware/optiboot_w25x20cl.cpp | 8 ++++---- Firmware/optiboot_w25x20cl.h | 2 +- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index a0ef5591..61f0c132 100755 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -1016,9 +1016,10 @@ void setup() #ifdef W25X20CL bool w25x20cl_success = w25x20cl_init(); + uint8_t optiboot_status = 1; if (w25x20cl_success) { - optiboot_w25x20cl_enter(); + optiboot_status = optiboot_w25x20cl_enter(); #if (LANG_MODE != 0) //secondary language support update_sec_lang_from_external_flash(); #endif //(LANG_MODE != 0) @@ -1064,9 +1065,12 @@ void setup() } MYSERIAL.begin(BAUDRATE); fdev_setup_stream(uartout, uart_putchar, NULL, _FDEV_SETUP_WRITE); //setup uart out stream -#ifndef W25X20CL +#if !((LANG_MODE == 1) && defined(W25X20CL)) || (LANG_MODE == 0) SERIAL_PROTOCOLLNPGM("start"); -#endif //W25X20CL +#else + if (optiboot_status == 1) + SERIAL_PROTOCOLLNPGM("start"); +#endif stdout = uartout; SERIAL_ECHO_START; printf_P(PSTR(" " FW_VERSION_FULL "\n")); diff --git a/Firmware/optiboot_w25x20cl.cpp b/Firmware/optiboot_w25x20cl.cpp index 584c32fe..7cc44801 100644 --- a/Firmware/optiboot_w25x20cl.cpp +++ b/Firmware/optiboot_w25x20cl.cpp @@ -99,9 +99,9 @@ struct block_t; extern struct block_t *block_buffer; //! @brief Enter an STK500 compatible Optiboot boot loader waiting for flashing the languages to an external flash memory. -void optiboot_w25x20cl_enter() +uint8_t optiboot_w25x20cl_enter() { - if (boot_app_flags & BOOT_APP_FLG_USER0) return; + if (boot_app_flags & BOOT_APP_FLG_USER0) return 1; uint8_t ch; uint8_t rampz = 0; register uint16_t address = 0; @@ -144,12 +144,12 @@ void optiboot_w25x20cl_enter() delayMicroseconds(1); if (++ boot_timer > boot_timeout) // Timeout expired, continue with the application. - return; + return 0; } ch = UDR0; if (pgm_read_byte(ptr ++) != ch) // Magic was not received correctly, continue with the application - return; + return 0; watchdogReset(); } // Send the cfm magic string. diff --git a/Firmware/optiboot_w25x20cl.h b/Firmware/optiboot_w25x20cl.h index dc7d4395..95c6465f 100644 --- a/Firmware/optiboot_w25x20cl.h +++ b/Firmware/optiboot_w25x20cl.h @@ -1,6 +1,6 @@ #ifndef OPTIBOOT_W25X20CL_H #define OPTIBOOT_W25X20CL_H -extern void optiboot_w25x20cl_enter(); +extern uint8_t optiboot_w25x20cl_enter(); #endif /* OPTIBOOT_W25X20CL_H */ From f11ab17746d573325e16f62b7b5d430a03a5f2df Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Wed, 27 May 2020 09:59:17 +0300 Subject: [PATCH 2/5] Fix warning --- Firmware/Marlin_main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index 61f0c132..a57915c6 100755 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -1065,7 +1065,7 @@ void setup() } MYSERIAL.begin(BAUDRATE); fdev_setup_stream(uartout, uart_putchar, NULL, _FDEV_SETUP_WRITE); //setup uart out stream -#if !((LANG_MODE == 1) && defined(W25X20CL)) || (LANG_MODE == 0) +#ifndef W25X20CL SERIAL_PROTOCOLLNPGM("start"); #else if (optiboot_status == 1) From e985d17bd11a35cecf162db8f4e1e6a3c3b52b89 Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Wed, 27 May 2020 10:16:44 +0300 Subject: [PATCH 3/5] Document code --- Firmware/optiboot_w25x20cl.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Firmware/optiboot_w25x20cl.cpp b/Firmware/optiboot_w25x20cl.cpp index 7cc44801..231e7760 100644 --- a/Firmware/optiboot_w25x20cl.cpp +++ b/Firmware/optiboot_w25x20cl.cpp @@ -99,6 +99,8 @@ struct block_t; extern struct block_t *block_buffer; //! @brief Enter an STK500 compatible Optiboot boot loader waiting for flashing the languages to an external flash memory. +//! @return 1 if "start\n" was not sent. Optiboot was skipped +//! @return 0 if "start\n" was sent. Optiboot ran normally. No need to send "start\n" in setup() uint8_t optiboot_w25x20cl_enter() { if (boot_app_flags & BOOT_APP_FLG_USER0) return 1; From b1e446ef97b16a75a79d42c461c4fd46b1aa9f4d Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Wed, 27 May 2020 13:50:02 +0300 Subject: [PATCH 4/5] Remember the serial characters during Optiboot initialization --- Firmware/Marlin_main.cpp | 13 +++++++------ Firmware/optiboot_w25x20cl.cpp | 14 +++++++------- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index a57915c6..68c5d4b0 100755 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -1014,6 +1014,12 @@ void setup() lcd_splash(); Sound_Init(); // also guarantee "SET_OUTPUT(BEEPER)" + selectedSerialPort = eeprom_read_byte((uint8_t*)EEPROM_SECOND_SERIAL_ACTIVE); + if (selectedSerialPort == 0xFF) selectedSerialPort = 0; + MYSERIAL.begin(BAUDRATE); + fdev_setup_stream(uartout, uart_putchar, NULL, _FDEV_SETUP_WRITE); //setup uart out stream + stdout = uartout; + #ifdef W25X20CL bool w25x20cl_success = w25x20cl_init(); uint8_t optiboot_status = 1; @@ -1041,15 +1047,13 @@ void setup() if ((farm_mode == 0xFF && farm_no == 0) || ((uint16_t)farm_no == 0xFFFF)) farm_mode = false; //if farm_mode has not been stored to eeprom yet and farm number is set to zero or EEPROM is fresh, deactivate farm mode if ((uint16_t)farm_no == 0xFFFF) farm_no = 0; - - selectedSerialPort = eeprom_read_byte((uint8_t*)EEPROM_SECOND_SERIAL_ACTIVE); - if (selectedSerialPort == 0xFF) selectedSerialPort = 0; if (farm_mode) { no_response = true; //we need confirmation by recieving PRUSA thx important_status = 8; prusa_statistics(8); selectedSerialPort = 1; + MYSERIAL.begin(BAUDRATE); #ifdef TMC2130 //increased extruder current (PFW363) tmc2130_current_h[E_AXIS] = 36; @@ -1063,15 +1067,12 @@ void setup() if(!(eeprom_read_byte((uint8_t*)EEPROM_FAN_CHECK_ENABLED))) eeprom_update_byte((unsigned char *)EEPROM_FAN_CHECK_ENABLED,true); } - MYSERIAL.begin(BAUDRATE); - fdev_setup_stream(uartout, uart_putchar, NULL, _FDEV_SETUP_WRITE); //setup uart out stream #ifndef W25X20CL SERIAL_PROTOCOLLNPGM("start"); #else if (optiboot_status == 1) SERIAL_PROTOCOLLNPGM("start"); #endif - stdout = uartout; SERIAL_ECHO_START; printf_P(PSTR(" " FW_VERSION_FULL "\n")); diff --git a/Firmware/optiboot_w25x20cl.cpp b/Firmware/optiboot_w25x20cl.cpp index 231e7760..64869485 100644 --- a/Firmware/optiboot_w25x20cl.cpp +++ b/Firmware/optiboot_w25x20cl.cpp @@ -122,38 +122,38 @@ uint8_t optiboot_w25x20cl_enter() unsigned long boot_timer = 0; const char *ptr = entry_magic_send; const char *end = strlen_P(entry_magic_send) + ptr; - // Initialize the serial line. - UCSR0A |= (1 << U2X0); - UBRR0L = (((float)(F_CPU))/(((float)(115200))*8.0)-1.0+0.5); - UCSR0B = (1 << RXEN0) | (1 << TXEN0); // Flush the serial line. while (RECV_READY) { watchdogReset(); // Dummy register read (discard) (void)(*(char *)UDR0); } + MYSERIAL.flush(); //clear RX buffer + int SerialHead = rx_buffer.head; // Send the initial magic string. while (ptr != end) putch(pgm_read_byte(ptr ++)); watchdogReset(); - // Wait for one second until a magic string (constant entry_magic) is received + // Wait for two seconds until a magic string (constant entry_magic) is received // from the serial line. ptr = entry_magic_receive; end = strlen_P(entry_magic_receive) + ptr; while (ptr != end) { - while (! RECV_READY) { + while (rx_buffer.head == SerialHead) { watchdogReset(); delayMicroseconds(1); if (++ boot_timer > boot_timeout) // Timeout expired, continue with the application. return 0; } - ch = UDR0; + ch = rx_buffer.buffer[SerialHead]; + SerialHead = (unsigned int)(SerialHead + 1) % RX_BUFFER_SIZE; if (pgm_read_byte(ptr ++) != ch) // Magic was not received correctly, continue with the application return 0; watchdogReset(); } + cbi(UCSR0B, RXCIE0); //disable the MarlinSerial0 interrupt // Send the cfm magic string. ptr = entry_magic_cfm; while (ptr != end) From c84aef3a288e75796fd30eec6164bab79062b6c3 Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Wed, 27 May 2020 17:40:14 +0300 Subject: [PATCH 5/5] Handle second serial port correctly --- Firmware/Marlin_main.cpp | 5 +++-- Firmware/optiboot_w25x20cl.cpp | 8 ++++++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index 68c5d4b0..651aeb81 100755 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -1014,8 +1014,9 @@ void setup() lcd_splash(); Sound_Init(); // also guarantee "SET_OUTPUT(BEEPER)" - selectedSerialPort = eeprom_read_byte((uint8_t*)EEPROM_SECOND_SERIAL_ACTIVE); + selectedSerialPort = eeprom_read_byte((uint8_t *)EEPROM_SECOND_SERIAL_ACTIVE); if (selectedSerialPort == 0xFF) selectedSerialPort = 0; + eeprom_update_byte((uint8_t *)EEPROM_SECOND_SERIAL_ACTIVE, selectedSerialPort); MYSERIAL.begin(BAUDRATE); fdev_setup_stream(uartout, uart_putchar, NULL, _FDEV_SETUP_WRITE); //setup uart out stream stdout = uartout; @@ -1070,7 +1071,7 @@ void setup() #ifndef W25X20CL SERIAL_PROTOCOLLNPGM("start"); #else - if (optiboot_status == 1) + if ((optiboot_status != 0) || (selectedSerialPort != 0)) SERIAL_PROTOCOLLNPGM("start"); #endif SERIAL_ECHO_START; diff --git a/Firmware/optiboot_w25x20cl.cpp b/Firmware/optiboot_w25x20cl.cpp index 64869485..dce4074e 100644 --- a/Firmware/optiboot_w25x20cl.cpp +++ b/Firmware/optiboot_w25x20cl.cpp @@ -122,12 +122,14 @@ uint8_t optiboot_w25x20cl_enter() unsigned long boot_timer = 0; const char *ptr = entry_magic_send; const char *end = strlen_P(entry_magic_send) + ptr; + const uint8_t selectedSerialPort_bak = selectedSerialPort; // Flush the serial line. while (RECV_READY) { watchdogReset(); // Dummy register read (discard) (void)(*(char *)UDR0); } + selectedSerialPort = 0; //switch to Serial0 MYSERIAL.flush(); //clear RX buffer int SerialHead = rx_buffer.head; // Send the initial magic string. @@ -143,14 +145,20 @@ uint8_t optiboot_w25x20cl_enter() watchdogReset(); delayMicroseconds(1); if (++ boot_timer > boot_timeout) + { // Timeout expired, continue with the application. + selectedSerialPort = selectedSerialPort_bak; //revert Serial setting return 0; + } } ch = rx_buffer.buffer[SerialHead]; SerialHead = (unsigned int)(SerialHead + 1) % RX_BUFFER_SIZE; if (pgm_read_byte(ptr ++) != ch) + { // Magic was not received correctly, continue with the application + selectedSerialPort = selectedSerialPort_bak; //revert Serial setting return 0; + } watchdogReset(); } cbi(UCSR0B, RXCIE0); //disable the MarlinSerial0 interrupt