Permalink
Browse files

commandline (hid) bootloader

  • Loading branch information...
1 parent 704b0fb commit fb40a50a63279ed81a24253cf2d3bc048e090289 @patricksebastien committed Oct 16, 2010
View
@@ -0,0 +1,268 @@
+/* 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"
+
+//by default
+#define IDENT_VENDOR_NUM 0x16c0
+#define IDENT_VENDOR_STRING "obdev.at"
+#define IDENT_PRODUCT_NUM 1503
+#define IDENT_PRODUCT_STRING "HIDBoot"
+
+/* ------------------------------------------------------------------------- */
+//to adjust (via workinprogress)?
+
+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];
+ char flashSize[4];
+}deviceInfo_t;
+
+typedef struct deviceData{
+ char reportId;
+ char address[3];
+ char data[128];
+}deviceData_t;
+
+static int uploadData(char *dataBuffer, int startAddr, int endAddr)
+{
+usbDevice_t *dev = NULL;
+int err = 0, len, mask, 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); %d bytes remaining\n", deviceSize, deviceSize, deviceSize - 2048);
+ if(endAddr > deviceSize - 2048){
+ fprintf(stderr, "Data (%d bytes) exceeds remaining flash size!\n", endAddr);
+ err = -1;
+ goto errorOccurred;
+ }
+ if(pageSize < 128){
+ mask = 127;
+ }else{
+ mask = pageSize - 1;
+ }
+ startAddr &= ~mask; /* round down */
+ endAddr = (endAddr + mask) & ~mask; /* round up */
+ 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, 128);
+ setUsbInt(buffer.data.address, startAddr, 3);
+ printf("\r0x%05x ... 0x%05x", startAddr, startAddr + (int)sizeof(buffer.data.data));
+ 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 += sizeof(buffer.data.data);
+ }
+ 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];
+ }
+
+
+ fprintf(stderr, "TESTING.\n");
+
+
+
+ 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;
+}
+
+/* ------------------------------------------------------------------------- */
+
+
View
@@ -0,0 +1,46 @@
+# Name: Makefile
+# Project: Automator
+# Author: Christian Starkjohann
+# Creation Date: 2006-02-01
+# Tabsize: 4
+# Copyright: (c) 2006 by OBJECTIVE DEVELOPMENT Software GmbH
+# License: Proprietary, free under certain conditions. See Documentation.
+# This Revision: $Id: Makefile 281 2007-03-20 13:22:10Z cs $
+
+# Please read the definitions below and edit them as appropriate for your
+# system:
+
+# Use the following 3 lines on Unix and Mac OS X:
+USBFLAGS= `libusb-config --cflags`
+USBLIBS= `libusb-config --libs`
+EXE_SUFFIX=
+
+# Use the following 3 lines on Windows and comment out the 3 above:
+#USBFLAGS=
+#USBLIBS= -lhid -lusb -lsetupapi
+#EXE_SUFFIX= .exe
+
+CC= gcc
+CXX= g++
+CFLAGS= -O2 -Wall $(USBFLAGS)
+LIBS= $(USBLIBS)
+ARCH_COMPILE=
+ARCH_LINK=
+
+OBJ= main.o usbcalls.o
+PROGRAM= bootloadHID$(EXE_SUFFIX)
+
+all: $(PROGRAM)
+
+$(PROGRAM): $(OBJ)
+ $(CC) $(ARCH_LINK) $(CFLAGS) -o $(PROGRAM) $(OBJ) $(LIBS)
+
+
+strip: $(PROGRAM)
+ strip $(PROGRAM)
+
+clean:
+ rm -f $(OBJ) $(PROGRAM)
+
+.c.o:
+ $(CC) $(ARCH_COMPILE) $(CFLAGS) -c $*.c -o $*.o
@@ -0,0 +1,18 @@
+# Name: Makefile.windows
+# Project: Automator
+# Author: Christian Starkjohann
+# Creation Date: 2006-02-20
+# Tabsize: 4
+# Copyright: (c) 2006 by OBJECTIVE DEVELOPMENT Software GmbH
+# License: Proprietary, free under certain conditions. See Documentation.
+# This Revision: $Id$
+
+# You may use this file with
+# make -f Makefile.windows
+# on Windows with MinGW instead of editing the main Makefile.
+
+include Makefile
+
+USBFLAGS=
+USBLIBS= -lhid -lusb -lsetupapi
+EXE_SUFFIX= .exe
View
Binary file not shown.
View
@@ -0,0 +1,13 @@
+:100000000C943E000C9448000C9448000C9448005A
+:100010000C9448000C9448000C9448000C94480040
+:100020000C9448000C9448000C9448000C94480030
+:100030000C9448000C9448000C9448000C94480020
+:100040000C9448000C9448000C9448000C94480010
+:100050000C9448000C9448000C9448000C94480000
+:100060000C9448000C9448000C9448000C944800F0
+:100070000C9448000C9448000C94480011241FBEB6
+:10008000CFEFD0E1DEBFCDBF0E944A000C945900F3
+:100090000C9400008FEF87B928E331E086B180959A
+:1000A00088B988E592E0F9013197F1F70197D9F71E
+:0600B000F5CFF894FFCF2C
+:00000001FF
View
@@ -0,0 +1,50 @@
+/* Name: hidsdi.h
+ * Project: usbcalls library
+ * Author: Christian Starkjohann
+ * Creation Date: 2006-02-02
+ * Tabsize: 4
+ * Copyright: (c) 2006 by OBJECTIVE DEVELOPMENT Software GmbH
+ * License: Proprietary, free under certain conditions. See Documentation.
+ * This Revision: $Id: hidsdi.h 281 2007-03-20 13:22:10Z cs $
+ */
+
+/*
+General Description
+This file is a replacement for hidsdi.h from the Windows DDK. It defines some
+of the types and function prototypes of this header for our project. If you
+have the Windows DDK version of this file or a version shipped with MinGW, use
+that instead.
+*/
+
+#ifndef _HIDSDI_H
+#define _HIDSDI_H
+
+#include <pshpack4.h>
+
+#include <ddk/hidusage.h>
+#include <ddk/hidpi.h>
+
+typedef struct{
+ ULONG Size;
+ USHORT VendorID;
+ USHORT ProductID;
+ USHORT VersionNumber;
+}HIDD_ATTRIBUTES;
+
+void __stdcall HidD_GetHidGuid(OUT LPGUID hidGuid);
+
+BOOLEAN __stdcall HidD_GetAttributes(IN HANDLE device, OUT HIDD_ATTRIBUTES *attributes);
+
+BOOLEAN __stdcall HidD_GetManufacturerString(IN HANDLE device, OUT void *buffer, IN ULONG bufferLen);
+BOOLEAN __stdcall HidD_GetProductString(IN HANDLE device, OUT void *buffer, IN ULONG bufferLen);
+BOOLEAN __stdcall HidD_GetSerialNumberString(IN HANDLE device, OUT void *buffer, IN ULONG bufferLen);
+
+BOOLEAN __stdcall HidD_GetFeature(IN HANDLE device, OUT void *reportBuffer, IN ULONG bufferLen);
+BOOLEAN __stdcall HidD_SetFeature(IN HANDLE device, IN void *reportBuffer, IN ULONG bufferLen);
+
+BOOLEAN __stdcall HidD_GetNumInputBuffers(IN HANDLE device, OUT ULONG *numBuffers);
+BOOLEAN __stdcall HidD_SetNumInputBuffers(IN HANDLE device, OUT ULONG numBuffers);
+
+#include <poppack.h>
+
+#endif
Oops, something went wrong.

0 comments on commit fb40a50

Please sign in to comment.