Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/prusa3d/PrusaSlicer.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbubnikv <bubnikv@gmail.com>2018-06-14 16:03:16 +0300
committerbubnikv <bubnikv@gmail.com>2018-06-14 16:03:16 +0300
commitcbe72e6cad44f20a58e97e4fe48cb725354f1659 (patch)
tree152d3b7cea1a0899921a6735ee811c28077d906f
parent2cd0c64b964c54b41ac54ab14c2ad31a309bb55d (diff)
Firwmare updater for the Einsy external flash memory,fwupdater_languages
to be used as a storage for localization strings. Hacked into the avrdude Arduino STK500 (not STK500v2) protocol.
-rw-r--r--xs/CMakeLists.txt16
-rw-r--r--xs/src/avrdude/arduino.c51
-rw-r--r--xs/src/avrdude/stk500.c123
-rw-r--r--xs/src/slic3r/GUI/FirmwareDialog.cpp14
4 files changed, 147 insertions, 57 deletions
diff --git a/xs/CMakeLists.txt b/xs/CMakeLists.txt
index 9c61fa729..f606d863b 100644
--- a/xs/CMakeLists.txt
+++ b/xs/CMakeLists.txt
@@ -336,8 +336,6 @@ add_library(semver STATIC
)
-add_subdirectory(src/avrdude)
-
# Generate the Slic3r Perl module (XS) typemap file.
set(MyTypemap ${CMAKE_CURRENT_BINARY_DIR}/typemap)
add_custom_command(
@@ -500,12 +498,12 @@ if (WIN32 AND ";${PerlEmbed_CCFLAGS};" MATCHES ";[-/]Od;")
message("Old CMAKE_CXX_FLAGS_RELEASE: ${CMAKE_CXX_FLAGS_RELEASE}")
message("Old CMAKE_CXX_FLAGS_RELWITHDEBINFO: ${CMAKE_CXX_FLAGS_RELEASE}")
message("Old CMAKE_CXX_FLAGS: ${CMAKE_CXX_FLAGS_RELEASE}")
- set(CMAKE_CXX_FLAGS_RELEASE "/MD /Od /Zi /EHsc /DNDEBUG")
- set(CMAKE_C_FLAGS_RELEASE "/MD /Od /Zi /DNDEBUG")
- set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "/MD /Od /Zi /EHsc /DNDEBUG")
- set(CMAKE_C_FLAGS_RELWITHDEBINFO "/MD /Od /Zi /DNDEBUG")
- set(CMAKE_CXX_FLAGS "/MD /Od /Zi /EHsc /DNDEBUG")
- set(CMAKE_C_FLAGS "/MD /Od /Zi /DNDEBUG")
+ set(CMAKE_CXX_FLAGS_RELEASE "/MD /Od /Zi /EHsc /DNDEBUG /DWIN32")
+ set(CMAKE_C_FLAGS_RELEASE "/MD /Od /Zi /DNDEBUG /DWIN32")
+ set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "/MD /Od /Zi /EHsc /DNDEBUG /DWIN32")
+ set(CMAKE_C_FLAGS_RELWITHDEBINFO "/MD /Od /Zi /DNDEBUG /DWIN32")
+ set(CMAKE_CXX_FLAGS "/MD /Od /Zi /EHsc /DNDEBUG /DWIN32")
+ set(CMAKE_C_FLAGS "/MD /Od /Zi /DNDEBUG /DWIN32")
endif()
# The following line will add -fPIC on Linux to make the XS.so rellocable.
add_definitions(${PerlEmbed_CCCDLFLAGS})
@@ -513,6 +511,8 @@ if (WIN32)
target_link_libraries(XS ${PERL_LIBRARY})
endif()
+add_subdirectory(src/avrdude)
+
## REQUIRED packages
# Find and configure boost
diff --git a/xs/src/avrdude/arduino.c b/xs/src/avrdude/arduino.c
index 566f56abd..886a43f0b 100644
--- a/xs/src/avrdude/arduino.c
+++ b/xs/src/avrdude/arduino.c
@@ -102,6 +102,57 @@ static int arduino_open(PROGRAMMER * pgm, char * port)
*/
stk500_drain(pgm, 0);
+{
+ //FIXME initialization sequence for programming the external FLASH.
+ const char entry_magic_send [] = "start\n";
+ const char entry_magic_receive[] = "w25x20cl_enter\n";
+ const char entry_magic_cfm [] = "w25x20cl_cfm\n";
+ const char *entry_magic_ptr = entry_magic_send;
+ struct timeval tv;
+ double tstart, tnow;
+ char c;
+ gettimeofday(&tv, NULL);
+ tstart = tv.tv_sec;
+ while (*entry_magic_ptr != 0) {
+ if (serial_recv(&pgm->fd, &c, 1) < 0)
+ goto timedout;
+ printf("Received: %c (%d)\n", c, (int)c);
+ if (c != *entry_magic_ptr ++) {
+ avrdude_message(MSG_INFO, "%s: stk500v2_recv(): MK3 printer emited incorrect start code\n", progname);
+ return -1;
+ }
+ gettimeofday(&tv, NULL);
+ tnow = tv.tv_sec;
+ if (tnow-tstart > 2.) { // wuff - signed/unsigned/overflow
+ timedout:
+ avrdude_message(MSG_INFO, "%s: stk500v2_recv(): MK3 printer did not boot up on time\n", progname);
+ return -1;
+ }
+ }
+ if (serial_send(&pgm->fd, entry_magic_receive, strlen(entry_magic_receive)) < 0) {
+ avrdude_message(MSG_INFO, "%s: stk500v2_send(): failed to send command to serial port\n",progname);
+ return -1;
+ }
+
+ entry_magic_ptr = entry_magic_cfm;
+ while (*entry_magic_ptr != 0) {
+ if (serial_recv(&pgm->fd, &c, 1) < 0)
+ goto timedout2;
+ printf("Received: %c (%d)\n", c, (int)c);
+ if (c != *entry_magic_ptr++) {
+ avrdude_message(MSG_INFO, "%s: stk500v2_recv(): MK3 printer emited incorrect start code\n", progname);
+ return -1;
+ }
+ gettimeofday(&tv, NULL);
+ tnow = tv.tv_sec;
+ if (tnow - tstart > 2.) { // wuff - signed/unsigned/overflow
+ timedout2:
+ avrdude_message(MSG_INFO, "%s: stk500v2_recv(): MK3 printer did not boot up on time\n", progname);
+ return -1;
+ }
+ }
+}
+
if (stk500_getsync(pgm) < 0)
return -1;
diff --git a/xs/src/avrdude/stk500.c b/xs/src/avrdude/stk500.c
index 5d2d3c1df..63deb228f 100644
--- a/xs/src/avrdude/stk500.c
+++ b/xs/src/avrdude/stk500.c
@@ -716,11 +716,14 @@ static int stk500_loadaddr(PROGRAMMER * pgm, AVRMEM * mem, unsigned int addr)
}
buf[0] = Cmnd_STK_LOAD_ADDRESS;
- buf[1] = addr & 0xff;
- buf[2] = (addr >> 8) & 0xff;
- buf[3] = Sync_CRC_EOP;
-
- stk500_send(pgm, buf, 4);
+ // Workaround for the infamous ';' bug in the Prusa3D usb to serial converter.
+ // Send the binary data by nibbles to avoid transmitting the ';' character.
+ buf[1] = addr & 0x0f;
+ buf[2] = addr & 0xf0;
+ buf[3] = (addr >> 8) & 0x0f;
+ buf[4] = (addr >> 8) & 0xf0;
+ buf[5] = Sync_CRC_EOP;
+ stk500_send(pgm, buf, 6);
if (stk500_recv(pgm, buf, 1) < 0)
return -1;
@@ -765,7 +768,9 @@ static int stk500_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
int block_size;
int tries;
unsigned int n;
- unsigned int i;
+ unsigned int i, j;
+ unsigned int prusa3d_semicolon_workaround_round = 0;
+ bool has_semicolon = false;
if (strcmp(m->desc, "flash") == 0) {
memtype = 'F';
@@ -806,44 +811,64 @@ static int stk500_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
tries++;
stk500_loadaddr(pgm, m, addr/a_div);
- /* build command block and avoid multiple send commands as it leads to a crash
- of the silabs usb serial driver on mac os x */
- i = 0;
- buf[i++] = Cmnd_STK_PROG_PAGE;
- buf[i++] = (block_size >> 8) & 0xff;
- buf[i++] = block_size & 0xff;
- buf[i++] = memtype;
- memcpy(&buf[i], &m->buf[addr], block_size);
- i += block_size;
- buf[i++] = Sync_CRC_EOP;
- stk500_send( pgm, buf, i);
+ for (i = 0; i < n_bytes; ++ i)
+ if (m->buf[addr + i] == ';') {
+ has_semicolon = true;
+ break;
+ }
- if (stk500_recv(pgm, buf, 1) < 0)
- return -1;
- if (buf[0] == Resp_STK_NOSYNC) {
- if (tries > 33) {
- avrdude_message(MSG_INFO, "\n%s: stk500_paged_write(): can't get into sync\n",
- progname);
- return -3;
+ for (prusa3d_semicolon_workaround_round = 0; prusa3d_semicolon_workaround_round < (has_semicolon ? 2 : 1); ++ prusa3d_semicolon_workaround_round) {
+ /* build command block and avoid multiple send commands as it leads to a crash
+ of the silabs usb serial driver on mac os x */
+ i = 0;
+ buf[i++] = Cmnd_STK_PROG_PAGE;
+ // Workaround for the infamous ';' bug in the Prusa3D usb to serial converter.
+ // Send the binary data by nibbles to avoid transmitting the ';' character.
+ buf[i++] = (block_size >> 8) & 0xf0;
+ buf[i++] = (block_size >> 8) & 0x0f;
+ buf[i++] = block_size & 0xf0;
+ buf[i++] = block_size & 0x0f;
+ buf[i++] = memtype;
+ if (has_semicolon) {
+ for (j = 0; j < block_size; ++i, ++ j) {
+ buf[i] = m->buf[addr + j];
+ if (buf[i] == ';')
+ buf[i] |= (prusa3d_semicolon_workaround_round ? 0xf0 : 0x0f);
+ }
+ } else {
+ memcpy(&buf[i], &m->buf[addr], block_size);
+ i += block_size;
+ }
+ buf[i++] = Sync_CRC_EOP;
+ stk500_send( pgm, buf, i);
+
+ if (stk500_recv(pgm, buf, 1) < 0)
+ return -1;
+ if (buf[0] == Resp_STK_NOSYNC) {
+ if (tries > 33) {
+ avrdude_message(MSG_INFO, "\n%s: stk500_paged_write(): can't get into sync\n",
+ progname);
+ return -3;
+ }
+ if (stk500_getsync(pgm) < 0)
+ return -1;
+ goto retry;
+ }
+ else if (buf[0] != Resp_STK_INSYNC) {
+ avrdude_message(MSG_INFO, "\n%s: stk500_paged_write(): (a) protocol error, "
+ "expect=0x%02x, resp=0x%02x\n",
+ progname, Resp_STK_INSYNC, buf[0]);
+ return -4;
+ }
+
+ if (stk500_recv(pgm, buf, 1) < 0)
+ return -1;
+ if (buf[0] != Resp_STK_OK) {
+ avrdude_message(MSG_INFO, "\n%s: stk500_paged_write(): (a) protocol error, "
+ "expect=0x%02x, resp=0x%02x\n",
+ progname, Resp_STK_INSYNC, buf[0]);
+ return -5;
}
- if (stk500_getsync(pgm) < 0)
- return -1;
- goto retry;
- }
- else if (buf[0] != Resp_STK_INSYNC) {
- avrdude_message(MSG_INFO, "\n%s: stk500_paged_write(): (a) protocol error, "
- "expect=0x%02x, resp=0x%02x\n",
- progname, Resp_STK_INSYNC, buf[0]);
- return -4;
- }
-
- if (stk500_recv(pgm, buf, 1) < 0)
- return -1;
- if (buf[0] != Resp_STK_OK) {
- avrdude_message(MSG_INFO, "\n%s: stk500_paged_write(): (a) protocol error, "
- "expect=0x%02x, resp=0x%02x\n",
- progname, Resp_STK_INSYNC, buf[0]);
- return -5;
}
}
@@ -893,11 +918,15 @@ static int stk500_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
tries++;
stk500_loadaddr(pgm, m, addr/a_div);
buf[0] = Cmnd_STK_READ_PAGE;
- buf[1] = (block_size >> 8) & 0xff;
- buf[2] = block_size & 0xff;
- buf[3] = memtype;
- buf[4] = Sync_CRC_EOP;
- stk500_send(pgm, buf, 5);
+ // Workaround for the infamous ';' bug in the Prusa3D usb to serial converter.
+ // Send the binary data by nibbles to avoid transmitting the ';' character.
+ buf[1] = (block_size >> 8) & 0xf0;
+ buf[2] = (block_size >> 8) & 0x0f;
+ buf[3] = block_size & 0xf0;
+ buf[4] = block_size & 0x0f;
+ buf[5] = memtype;
+ buf[6] = Sync_CRC_EOP;
+ stk500_send(pgm, buf, 7);
if (stk500_recv(pgm, buf, 1) < 0)
return -1;
diff --git a/xs/src/slic3r/GUI/FirmwareDialog.cpp b/xs/src/slic3r/GUI/FirmwareDialog.cpp
index 8ea9d2d6e..94c1d2c48 100644
--- a/xs/src/slic3r/GUI/FirmwareDialog.cpp
+++ b/xs/src/slic3r/GUI/FirmwareDialog.cpp
@@ -166,11 +166,19 @@ void FirmwareDialog::priv::perform_upload()
std::vector<std::string> args {{
"-v",
"-p", "atmega2560",
- "-c", "wiring",
+ // Using the "Wiring" mode to program Rambo or Einsy, using the STK500v2 protocol (not the STK500).
+ // The Prusa's avrdude is patched to never send semicolons inside the data packets, as the USB to serial chip
+ // is flashed with a buggy firmware.
+// "-c", "wiring",
+ // Using the "Arduino" mode to program Einsy's external flash with languages, using the STK500 protocol (not the STK500v2).
+ // The Prusa's avrdude is patched again to never send semicolons inside the data packets.
+ "-c", "arduino",
"-P", port,
"-b", "115200", // XXX: is this ok to hardcode?
"-D",
- "-U", (boost::format("flash:w:%1%:i") % filename.ToStdString()).str()
+ "-u", // disable safe mode
+ "-U", (boost::format("flash:w:%1%:i") % filename.ToStdString()).str(),
+// "-v", "-v", "-v", "-v", "-v", // enable super verbose mode, logging each serial line exchange
}};
BOOST_LOG_TRIVIAL(info) << "Invoking avrdude, arguments: "
@@ -186,6 +194,8 @@ void FirmwareDialog::priv::perform_upload()
.sys_config(avrdude_config)
.args(args)
.on_message(std::move([q](const char *msg, unsigned /* size */) {
+ // Debugging output to console, useful when avrdude is executed in a super verbose mode (with -v -v -v).
+ // printf("%s", msg);
auto evt = new wxCommandEvent(EVT_AVRDUDE, q->GetId());
evt->SetExtraLong(AE_MESSAGE);
evt->SetString(msg);