summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--commandline/library/micronucleus_lib.c34
-rw-r--r--commandline/library/micronucleus_lib.h9
-rw-r--r--commandline/micronucleus.c33
3 files changed, 58 insertions, 18 deletions
diff --git a/commandline/library/micronucleus_lib.c b/commandline/library/micronucleus_lib.c
index eaeaf38..51b42e7 100644
--- a/commandline/library/micronucleus_lib.c
+++ b/commandline/library/micronucleus_lib.c
@@ -28,7 +28,7 @@
#include "micronucleus_lib.h"
#include "littleWire_util.h"
-micronucleus* micronucleus_connect() {
+micronucleus* micronucleus_connect(int fast_mode) {
micronucleus *nucleus = NULL;
struct usb_bus *busses;
@@ -69,8 +69,15 @@ micronucleus* micronucleus_connect() {
nucleus->page_size = buffer[2];
nucleus->pages = (nucleus->flash_size / nucleus->page_size);
if (nucleus->pages * nucleus->page_size < nucleus->flash_size) nucleus->pages += 1;
- nucleus->write_sleep = buffer[3];
- nucleus->erase_sleep = nucleus->write_sleep * nucleus->pages;
+
+ if ((nucleus->version.major>=2)&&(!fast_mode)) {
+ // firmware v2 reports more aggressive write times. Add 2ms if fast mode is not used.
+ nucleus->write_sleep = buffer[3]+2;
+ nucleus->erase_sleep = nucleus->write_sleep * nucleus->pages;
+ } else {
+ nucleus->write_sleep = buffer[3];
+ nucleus->erase_sleep = nucleus->write_sleep * nucleus->pages;
+ }
}
}
}
@@ -122,6 +129,7 @@ int micronucleus_writeFlash(micronucleus* deviceHandle, unsigned int program_siz
unsigned int page_address; // address within this page when copying buffer
unsigned int res;
unsigned int pagecontainsdata;
+ unsigned int userReset;
for (address = 0; address < deviceHandle->flash_size; address += deviceHandle->page_size) {
// work around a bug in older bootloader versions
@@ -142,6 +150,26 @@ int micronucleus_writeFlash(micronucleus* deviceHandle, unsigned int program_siz
}
}
+ // Reset vector patching is done in the host tool in micronucleus >=2
+ if (deviceHandle->version.major >=2)
+ {
+ if ( address == 0 )
+ // save user reset vector (bootloader will patch with its vector)
+ userReset = page_buffer [1] * 0x100 + page_buffer [0];
+
+ if ( address >= deviceHandle->flash_size - deviceHandle->page_size )
+ {
+ // move user reset vector to end of last page
+ // The reset vector is always the last vector in the tinyvectortable
+ unsigned user_reset_addr = (deviceHandle->pages*deviceHandle->page_size)-2;
+ unsigned data = (userReset + 0x1000 - user_reset_addr/2) & ~0x1000;
+
+ page_buffer [user_reset_addr - address + 0] = data >> 0 & 0xff;
+ page_buffer [user_reset_addr - address + 1] = data >> 8 & 0xff;
+ }
+ }
+
+
// always write last page so bootloader can insert the tiny vector table
if ( address >= deviceHandle->flash_size - deviceHandle->page_size )
pagecontainsdata = 1;
diff --git a/commandline/library/micronucleus_lib.h b/commandline/library/micronucleus_lib.h
index 9118ace..d9f4999 100644
--- a/commandline/library/micronucleus_lib.h
+++ b/commandline/library/micronucleus_lib.h
@@ -44,11 +44,12 @@
#define MICRONUCLEUS_VENDOR_ID 0x16D0
#define MICRONUCLEUS_PRODUCT_ID 0x0753
#define MICRONUCLEUS_USB_TIMEOUT 0xFFFF
-#define MICRONUCLEUS_MAX_MAJOR_VERSION 1
+#define MICRONUCLEUS_MAX_MAJOR_VERSION 2
+
/*******************************************************************************/
/********************************************************************************
-* Declearations
+* Declarations
********************************************************************************/
//typedef usb_dev_handle micronucleus;
// representing version number of micronucleus device
@@ -57,6 +58,8 @@ typedef struct _micronucleus_version {
unsigned char minor;
} micronucleus_version;
+#define MICRONUCLEUS_COMMANDLINE_VERSION "Commandline tool version: 2.0a2"
+
// handle representing one micronucleus device
typedef struct _micronucleus {
usb_dev_handle *device;
@@ -77,7 +80,7 @@ typedef void (*micronucleus_callback)(float progress);
* Try to connect to the device
* Returns: device handle for success, NULL for fail
********************************************************************************/
-micronucleus* micronucleus_connect();
+micronucleus* micronucleus_connect(int fast_mode);
/*******************************************************************************/
/********************************************************************************
diff --git a/commandline/micronucleus.c b/commandline/micronucleus.c
index b7d49ab..4ef829a 100644
--- a/commandline/micronucleus.c
+++ b/commandline/micronucleus.c
@@ -54,6 +54,7 @@ static char* progress_friendly_name; // name of progress section
static int dump_progress = 0; // output computer friendly progress info
static int use_ansi = 0; // output ansi control character stuff
static int erase_only = 0; // only erase, dont't write file
+static int fast_mode = 0; // normal mode adds 2ms to page writing times and waits longer for connect.
static int timeout = 0;
/*****************************************************************************/
@@ -69,11 +70,12 @@ int main(int argc, char **argv) {
int run = 0;
int file_type = FILE_TYPE_INTEL_HEX;
int arg_pointer = 1;
- char* usage = "usage: micronucleus [--run] [--dump-progress] [--type intel-hex|raw] [--no-ansi] [--timeout integer] [--erase-only] filename";
+ char* usage = "usage: micronucleus [--run] [--dump-progress] [--fast-mode] [--type intel-hex|raw] [--no-ansi] [--timeout integer] [--erase-only] filename";
progress_step = 0;
progress_total_steps = 5; // steps: waiting, connecting, parsing, erasing, writing, (running)?
dump_progress = 0;
erase_only = 0;
+ fast_mode=0;
timeout = 0; // no timeout by default
//#if defined(WIN)
// use_ansi = 0;
@@ -104,6 +106,8 @@ int main(int argc, char **argv) {
puts(" for driving GUIs");
puts(" --erase-only: Erase the device without programming. Fills the");
puts(" program memory with 0xFFFF. Any files are ignored.");
+ puts(" --fast-mode: Speed up the timing of micronucleus. Do not use if");
+ puts(" you encounter USB errors. ");
puts(" --run: Ask bootloader to run the program when finished");
puts(" uploading provided program");
//#ifndef WIN
@@ -112,11 +116,15 @@ int main(int argc, char **argv) {
puts(" --timeout [integer]: Timeout after waiting specified number of seconds");
puts(" filename: Path to intel hex or raw data file to upload,");
puts(" or \"-\" to read from stdin");
+ puts("");
+ puts(MICRONUCLEUS_COMMANDLINE_VERSION);
return EXIT_SUCCESS;
} else if (strcmp(argv[arg_pointer], "--dump-progress") == 0) {
dump_progress = 1;
} else if (strcmp(argv[arg_pointer], "--no-ansi") == 0) {
use_ansi = 0;
+ } else if (strcmp(argv[arg_pointer], "--fast-mode") == 0) {
+ fast_mode = 1;
} else if (strcmp(argv[arg_pointer], "--erase-only") == 0) {
erase_only = 1;
progress_total_steps -= 1;
@@ -149,7 +157,7 @@ int main(int argc, char **argv) {
while (my_device == NULL) {
delay(100);
- my_device = micronucleus_connect();
+ my_device = micronucleus_connect(fast_mode);
time(&current_time);
if (timeout && start_time + timeout < current_time) {
@@ -164,17 +172,18 @@ int main(int argc, char **argv) {
printf("> Device is found!\n");
- // wait for CONNECT_WAIT milliseconds with progress output
- float wait = 0.0f;
- setProgressData("connecting", 2);
- while (wait < CONNECT_WAIT) {
- printProgress((wait / ((float) CONNECT_WAIT)) * 0.9f);
- wait += 50.0f;
- delay(50);
+ if (!fast_mode) {
+ // wait for CONNECT_WAIT milliseconds with progress output
+ float wait = 0.0f;
+ setProgressData("connecting", 2);
+ while (wait < CONNECT_WAIT) {
+ printProgress((wait / ((float) CONNECT_WAIT)) * 0.9f);
+ wait += 50.0f;
+ delay(50);
+ }
}
-
- //my_device = micronucleus_connect();
printProgress(1.0);
+ //my_device = micronucleus_connect();
// if (my_device->page_size == 64) {
// printf("> Device looks like ATtiny85!\n");
@@ -239,7 +248,7 @@ int main(int argc, char **argv) {
int deciseconds_till_reconnect_notice = 50; // notice after 5 seconds
while (my_device == NULL) {
delay(100);
- my_device = micronucleus_connect();
+ my_device = micronucleus_connect(fast_mode);
deciseconds_till_reconnect_notice -= 1;
if (deciseconds_till_reconnect_notice == 0) {