diff options
author | Jenna Fox <a@creativepony.com> | 2012-09-29 16:58:01 -0700 |
---|---|---|
committer | Jenna Fox <a@creativepony.com> | 2012-09-29 16:58:01 -0700 |
commit | 35cc54629ade1abfb801b832534f6c7f45eff20c (patch) | |
tree | 15798a560eef8fbb72c5545f29619816e58a436a /commandline/main.c | |
parent | 71649f3ec1b38fa4e38dffc77cc7eec314daa6a1 (diff) | |
parent | 2f46526de0ed0c9de27c58d4438b9c98e9b5a3c5 (diff) | |
download | micronucleus-35cc54629ade1abfb801b832534f6c7f45eff20c.tar.gz micronucleus-35cc54629ade1abfb801b832534f6c7f45eff20c.tar.bz2 micronucleus-35cc54629ade1abfb801b832534f6c7f45eff20c.zip |
Merge pull request #9 from kehribar/master
Experimental C commandline application has been added.
Diffstat (limited to 'commandline/main.c')
-rw-r--r-- | commandline/main.c | 265 |
1 files changed, 0 insertions, 265 deletions
diff --git a/commandline/main.c b/commandline/main.c deleted file mode 100644 index 725e2ea..0000000 --- a/commandline/main.c +++ /dev/null @@ -1,265 +0,0 @@ -/* Name: main.c - * Project: AVR bootloader HID - * Author: Christian Starkjohann - * Creation Date: 2007-03-19 - * Tabsize: 4 - * Copyright: (c) 2007 by OBJECTIVE DEVELOPMENT Software GmbH - * License: Proprietary, free under certain conditions. See Documentation. - * This Revision: $Id: main.c 787 2010-05-30 20:54:25Z cs $ - */ - -#include <stdio.h> -#include <string.h> -#include <stdlib.h> -#include <errno.h> -#include "usbcalls.h" - -#define IDENT_VENDOR_NUM 0x16c0 -#define IDENT_VENDOR_STRING "creativepony.com" -#define IDENT_PRODUCT_NUM 1503 -#define IDENT_PRODUCT_STRING "uBoot" - -// extra delays before more USB requests for tiny85 compatibility while chip frozen -// this number could be lower than 16000 - minimum will be greater than 9000 (erase and write) -#define TINY85_POSTWRITE_DELAY 16000 - -/* ------------------------------------------------------------------------- */ - -static char dataBuffer[65536 + 256]; /* buffer for file data */ -static int startAddress, endAddress; -static char leaveBootLoader = 0; - -/* ------------------------------------------------------------------------- */ - -static int parseUntilColon(FILE *fp) -{ -int c; - - do{ - c = getc(fp); - }while(c != ':' && c != EOF); - return c; -} - -static int parseHex(FILE *fp, int numDigits) -{ -int i; -char temp[9]; - - for(i = 0; i < numDigits; i++) - temp[i] = getc(fp); - temp[i] = 0; - return strtol(temp, NULL, 16); -} - -/* ------------------------------------------------------------------------- */ - -static int parseIntelHex(char *hexfile, char buffer[65536 + 256], int *startAddr, int *endAddr) -{ -int address, base, d, segment, i, lineLen, sum; -FILE *input; - - input = fopen(hexfile, "r"); - if(input == NULL){ - fprintf(stderr, "error opening %s: %s\n", hexfile, strerror(errno)); - return 1; - } - while(parseUntilColon(input) == ':'){ - sum = 0; - sum += lineLen = parseHex(input, 2); - base = address = parseHex(input, 4); - sum += address >> 8; - sum += address; - sum += segment = parseHex(input, 2); /* segment value? */ - if(segment != 0) /* ignore lines where this byte is not 0 */ - continue; - for(i = 0; i < lineLen ; i++){ - d = parseHex(input, 2); - buffer[address++] = d; - sum += d; - } - sum += parseHex(input, 2); - if((sum & 0xff) != 0){ - fprintf(stderr, "Warning: Checksum error between address 0x%x and 0x%x\n", base, address); - } - if(*startAddr > base) - *startAddr = base; - if(*endAddr < address) - *endAddr = address; - } - fclose(input); - return 0; -} - -/* ------------------------------------------------------------------------- */ - -char *usbErrorMessage(int errCode) -{ -static char buffer[80]; - - switch(errCode){ - case USB_ERROR_ACCESS: return "Access to device denied"; - case USB_ERROR_NOTFOUND: return "The specified device was not found"; - case USB_ERROR_BUSY: return "The device is used by another application"; - case USB_ERROR_IO: return "Communication error with device"; - default: - sprintf(buffer, "Unknown USB error %d", errCode); - return buffer; - } - return NULL; /* not reached */ -} - -static int getUsbInt(char *buffer, int numBytes) -{ -int shift = 0, value = 0, i; - - for(i = 0; i < numBytes; i++){ - value |= ((int)*buffer & 0xff) << shift; - shift += 8; - buffer++; - } - return value; -} - -static void setUsbInt(char *buffer, int value, int numBytes) -{ -int i; - - for(i = 0; i < numBytes; i++){ - *buffer++ = value; - value >>= 8; - } -} - -/* ------------------------------------------------------------------------- */ - -typedef struct deviceInfo{ - char reportId; - char pageSize[2]; // TODO: change this to one byte? - char flashSize[4]; // TODO: change this to two bytes? -}deviceInfo_t; - -typedef struct deviceData{ - char reportId; - char address[3]; - char data[64]; -}deviceData_t; - -static int uploadData(char *dataBuffer, int startAddr, int endAddr) -{ -usbDevice_t *dev = NULL; -int err = 0, len, pageSize, deviceSize; -union{ - char bytes[1]; - deviceInfo_t info; - deviceData_t data; -} buffer; - - if((err = usbOpenDevice(&dev, IDENT_VENDOR_NUM, IDENT_VENDOR_STRING, IDENT_PRODUCT_NUM, IDENT_PRODUCT_STRING, 1)) != 0){ - fprintf(stderr, "Error opening HIDBoot device: %s\n", usbErrorMessage(err)); - goto errorOccurred; - } - len = sizeof(buffer); - if(endAddr > startAddr){ // we need to upload data - if((err = usbGetReport(dev, USB_HID_REPORT_TYPE_FEATURE, 1, buffer.bytes, &len)) != 0){ - fprintf(stderr, "Error reading page size: %s\n", usbErrorMessage(err)); - goto errorOccurred; - } - if(len < sizeof(buffer.info)){ - fprintf(stderr, "Not enough bytes in device info report (%d instead of %d)\n", len, (int)sizeof(buffer.info)); - err = -1; - goto errorOccurred; - } - pageSize = getUsbInt(buffer.info.pageSize, 2); - deviceSize = getUsbInt(buffer.info.flashSize, 4); - printf("Page size = %d (0x%x)\n", pageSize, pageSize); - printf("Device size = %d (0x%x)\n", deviceSize, deviceSize); - if(endAddr > deviceSize){ - fprintf(stderr, "Data (%d bytes) exceeds remaining flash size!\n", endAddr); - err = -1; - goto errorOccurred; - } - - startAddr -= startAddr % pageSize; // round down to start of page - endAddr = (endAddr - (endAddr % pageSize)) + pageSize; // round up to next whole page - printf("Uploading %d (0x%x) bytes starting at %d (0x%x)\n", endAddr - startAddr, endAddr - startAddr, startAddr, startAddr); - while(startAddr < endAddr){ - buffer.data.reportId = 2; - memcpy(buffer.data.data, dataBuffer + startAddr, pageSize); - setUsbInt(buffer.data.address, startAddr, 3); - printf("\r0x%05x ... 0x%05x", startAddr, startAddr + pageSize); - fflush(stdout); - if((err = usbSetReport(dev, USB_HID_REPORT_TYPE_FEATURE, buffer.bytes, sizeof(buffer.data))) != 0){ - fprintf(stderr, "Error uploading data block: %s\n", usbErrorMessage(err)); - goto errorOccurred; - } - startAddr += pageSize; - - // special tiny85 chillout session - chip freezes during write, so we - // need to make sure we don't send it any requests while it's busy - // erasing and writing - usleep(TINY85_POSTWRITE_DELAY); // regular page write duration - } - printf("\n"); - } - if(leaveBootLoader){ - /* and now leave boot loader: */ - buffer.info.reportId = 1; - usbSetReport(dev, USB_HID_REPORT_TYPE_FEATURE, buffer.bytes, sizeof(buffer.info)); - /* Ignore errors here. If the device reboots before we poll the response, - * this request fails. - */ - } -errorOccurred: - if(dev != NULL) - usbCloseDevice(dev); - return err; -} - -/* ------------------------------------------------------------------------- */ - -static void printUsage(char *pname) -{ - fprintf(stderr, "usage: %s [-r] [<intel-hexfile>]\n", pname); -} - -int main(int argc, char **argv) -{ -char *file = NULL; - - if(argc < 2){ - printUsage(argv[0]); - return 1; - } - if(strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0){ - printUsage(argv[0]); - return 1; - } - if(strcmp(argv[1], "-r") == 0){ - leaveBootLoader = 1; - if(argc >= 3){ - file = argv[2]; - } - }else{ - file = argv[1]; - } - startAddress = sizeof(dataBuffer); - endAddress = 0; - if(file != NULL){ // an upload file was given, load the data - memset(dataBuffer, -1, sizeof(dataBuffer)); - if(parseIntelHex(file, dataBuffer, &startAddress, &endAddress)) - return 1; - if(startAddress >= endAddress){ - fprintf(stderr, "No data in input file, exiting.\n"); - return 0; - } - } - // if no file was given, endAddress is less than startAddress and no data is uploaded - if(uploadData(dataBuffer, startAddress, endAddress)) - return 1; - return 0; -} - -/* ------------------------------------------------------------------------- */ - - |