diff options
| author | cpldcpu <cpldcpu@gmail.com> | 2014-01-05 17:29:28 +0100 | 
|---|---|---|
| committer | cpldcpu <cpldcpu@gmail.com> | 2014-01-05 17:29:28 +0100 | 
| commit | 385cc20f4911b6260cdda8d550a034b2506d538b (patch) | |
| tree | 51d65bb03219f5cbe1c431471580fdc334e6329d | |
| parent | 4614182cbc1fa442bf58be4e8a9e86f3bdf74341 (diff) | |
| download | micronucleus-385cc20f4911b6260cdda8d550a034b2506d538b.tar.gz micronucleus-385cc20f4911b6260cdda8d550a034b2506d538b.tar.bz2 micronucleus-385cc20f4911b6260cdda8d550a034b2506d538b.zip | |
commandline: reset vector patching in commandline tool
| -rw-r--r-- | commandline/library/micronucleus_lib.c | 34 | ||||
| -rw-r--r-- | commandline/library/micronucleus_lib.h | 9 | ||||
| -rw-r--r-- | commandline/micronucleus.c | 33 | 
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(¤t_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) { | 
