From 385cc20f4911b6260cdda8d550a034b2506d538b Mon Sep 17 00:00:00 2001 From: cpldcpu Date: Sun, 5 Jan 2014 17:29:28 +0100 Subject: commandline: reset vector patching in commandline tool --- commandline/library/micronucleus_lib.c | 34 +++++++++++++++++++++++++++++++--- commandline/library/micronucleus_lib.h | 9 ++++++--- 2 files changed, 37 insertions(+), 6 deletions(-) (limited to 'commandline/library') 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); /*******************************************************************************/ /******************************************************************************** -- cgit v1.2.3