From 8c4fabbb1dc701d497c409aa4f5aded894d15bb6 Mon Sep 17 00:00:00 2001 From: ihsan Kehribar Date: Sat, 29 Sep 2012 21:38:48 +0300 Subject: Initial commit for commandline C application. --- commandline/library/littleWire_util.c | 12 ++ commandline/library/littleWire_util.h | 13 +++ commandline/library/micronucleus_lib.c | 102 +++++++++++++++++ commandline/library/micronucleus_lib.h | 87 ++++++++++++++ commandline/library/opendevice.c | 203 +++++++++++++++++++++++++++++++++ commandline/library/opendevice.h | 81 +++++++++++++ 6 files changed, 498 insertions(+) create mode 100644 commandline/library/littleWire_util.c create mode 100644 commandline/library/littleWire_util.h create mode 100644 commandline/library/micronucleus_lib.c create mode 100644 commandline/library/micronucleus_lib.h create mode 100644 commandline/library/opendevice.c create mode 100644 commandline/library/opendevice.h (limited to 'commandline/library') diff --git a/commandline/library/littleWire_util.c b/commandline/library/littleWire_util.c new file mode 100644 index 0000000..d711302 --- /dev/null +++ b/commandline/library/littleWire_util.c @@ -0,0 +1,12 @@ + +#include + +/* Delay in miliseconds */ +void delay(unsigned int duration) +{ + #ifdef LINUX + usleep(duration*1000); + #else + Sleep(duration); + #endif +} diff --git a/commandline/library/littleWire_util.h b/commandline/library/littleWire_util.h new file mode 100644 index 0000000..dac8623 --- /dev/null +++ b/commandline/library/littleWire_util.h @@ -0,0 +1,13 @@ +#ifndef LITTLEWIRE_UTIL_H +#define LITTLEWIRE_UTIL_H + +#ifdef LINUX + #include +#else + #include +#endif + +/* Delay in miliseconds */ +void delay(unsigned int duration); + +#endif diff --git a/commandline/library/micronucleus_lib.c b/commandline/library/micronucleus_lib.c new file mode 100644 index 0000000..8e01427 --- /dev/null +++ b/commandline/library/micronucleus_lib.c @@ -0,0 +1,102 @@ +/* + Created: September 2012 + by ihsan Kehribar + + Permission is hereby granted, free of charge, to any person obtaining a copy of + this software and associated documentation files (the "Software"), to deal in + the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do + so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ + +/***************************************************************/ +/* See the micronucleus_lib.h for the function descriptions/comments */ +/***************************************************************/ +#include "micronucleus_lib.h" +#include "littleWire_util.h" + +micronucleus* micronucleus_connect() +{ + micronucleus *tempHandle = NULL; + + usb_init(); + usbOpenDevice(&tempHandle, VENDOR_ID, "*", PRODUCT_ID, "*", "*", NULL, NULL ); + + return tempHandle; +} + +int micronucleus_getDeviceInfo(micronucleus* deviceHandle, unsigned int* availableMemory, unsigned char* deviceSize, unsigned char* sleepAmount) +{ + int res; + res = usb_control_msg(deviceHandle, 0xC0, 0, 0, 0, rxBuffer, 4, USB_TIMEOUT); + + if(res!=4) + return -1; + + *availableMemory = (rxBuffer[0]<<8) + rxBuffer[1]; + *deviceSize = rxBuffer[2]; + *sleepAmount = rxBuffer[3]; + + return 0; +} + +int micronucleus_eraseFlash(micronucleus* deviceHandle, unsigned int sleepAmount) +{ + int res; + res = usb_control_msg(deviceHandle, 0xC0, 2, 0, 0, rxBuffer, 0, USB_TIMEOUT); + delay(sleepAmount); + if(res!=0) + return -1; + else + return 0; +} + +int micronucleus_writeFlash(micronucleus* deviceHandle, unsigned int startAddress, unsigned int endAddress, unsigned char* buffer, unsigned char sleepAmount) +{ + unsigned char tempBuffer[64]; + unsigned int i; + unsigned int k; + unsigned int res; + + for(i=startAddress;i<(endAddress);i+=64) + { + for(k=0;k<64;k++) + tempBuffer[k]=buffer[i+k]; + + res = usb_control_msg(deviceHandle, + USB_ENDPOINT_OUT| USB_TYPE_VENDOR | USB_RECIP_DEVICE, + 1, + 64,i, + tempBuffer, 64, + USB_TIMEOUT); + delay(sleepAmount); + if(res!=64) return -1; + } + + return 0; +} + +int micronucleus_startApp(micronucleus* deviceHandle) +{ + int res; + res = usb_control_msg(deviceHandle, 0xC0, 4, 0, 0, rxBuffer, 0, USB_TIMEOUT); + if(res!=0) + return -1; + else + return 0; +} + + + diff --git a/commandline/library/micronucleus_lib.h b/commandline/library/micronucleus_lib.h new file mode 100644 index 0000000..8a004e4 --- /dev/null +++ b/commandline/library/micronucleus_lib.h @@ -0,0 +1,87 @@ +#ifndef MICRONUCLEUS_LIB_H +#define MICRONUCLEUS_LIB_H + +/* + Created: September 2012 + by ihsan Kehribar + + Permission is hereby granted, free of charge, to any person obtaining a copy of + this software and associated documentation files (the "Software"), to deal in + the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do + so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ + +/******************************************************************************** +* Header files +********************************************************************************/ +#if defined(LINUX) + #include // this is libusb, see http://libusb.sourceforge.net/ +#else + #include // this is libusb, see http://libusb.sourceforge.net/ +#endif +#include "opendevice.h" // common code moved to separate module +/*******************************************************************************/ + +/******************************************************************************** +* USB details +********************************************************************************/ +#define VENDOR_ID 0x16D0 +#define PRODUCT_ID 0x0753 +#define USB_TIMEOUT 0xFFFF +#define RX_BUFFER_SIZE 64 +#define TX_BUFFER_SIZE 64 +/*******************************************************************************/ + +/******************************************************************************** +* Declearations +********************************************************************************/ +typedef usb_dev_handle micronucleus; +unsigned char rxBuffer[RX_BUFFER_SIZE]; /* This has to be unsigned for the data's sake */ +unsigned char tBuffer[TX_BUFFER_SIZE]; /* This has to be unsigned for the data's sake */ +/*******************************************************************************/ + +/******************************************************************************** +* Try to connect to the device +* Returns: device handle for success, NULL for fail +********************************************************************************/ +micronucleus* micronucleus_connect(); +/*******************************************************************************/ + +/******************************************************************************** +* Get the device info +********************************************************************************/ +int micronucleus_getDeviceInfo(micronucleus* deviceHandle, unsigned int* availableMemory, unsigned char* deviceSize, unsigned char* sleepAmount); +/*******************************************************************************/ + +/******************************************************************************** +* Erase the flash memory +********************************************************************************/ +int micronucleus_eraseFlash(micronucleus* deviceHandle,unsigned int sleepAmount); +/*******************************************************************************/ + +/******************************************************************************** +* Write the flash memory +********************************************************************************/ +int micronucleus_writeFlash(micronucleus* deviceHandle, unsigned int startAddress, unsigned int endAddress, unsigned char* buffer, unsigned char sleepAmount); +/*******************************************************************************/ + +/******************************************************************************** +* Starts the user application +********************************************************************************/ +int micronucleus_startApp(micronucleus* deviceHandle); +/*******************************************************************************/ + +#endif diff --git a/commandline/library/opendevice.c b/commandline/library/opendevice.c new file mode 100644 index 0000000..137f50c --- /dev/null +++ b/commandline/library/opendevice.c @@ -0,0 +1,203 @@ +/* Name: opendevice.c + * Project: V-USB host-side library + * Author: Christian Starkjohann + * Creation Date: 2008-04-10 + * Tabsize: 4 + * Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH + * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) + * This Revision: $Id: opendevice.c 740 2009-04-13 18:23:31Z cs $ + */ + +/* +General Description: +The functions in this module can be used to find and open a device based on +libusb or libusb-win32. +*/ + +#include +#include "opendevice.h" + +/* ------------------------------------------------------------------------- */ + +#define MATCH_SUCCESS 1 +#define MATCH_FAILED 0 +#define MATCH_ABORT -1 + +/* private interface: match text and p, return MATCH_SUCCESS, MATCH_FAILED, or MATCH_ABORT. */ +static int _shellStyleMatch(char *text, char *p) +{ +int last, matched, reverse; + + for(; *p; text++, p++){ + if(*text == 0 && *p != '*') + return MATCH_ABORT; + switch(*p){ + case '\\': + /* Literal match with following character. */ + p++; + /* FALLTHROUGH */ + default: + if(*text != *p) + return MATCH_FAILED; + continue; + case '?': + /* Match anything. */ + continue; + case '*': + while(*++p == '*') + /* Consecutive stars act just like one. */ + continue; + if(*p == 0) + /* Trailing star matches everything. */ + return MATCH_SUCCESS; + while(*text) + if((matched = _shellStyleMatch(text++, p)) != MATCH_FAILED) + return matched; + return MATCH_ABORT; + case '[': + reverse = p[1] == '^'; + if(reverse) /* Inverted character class. */ + p++; + matched = MATCH_FAILED; + if(p[1] == ']' || p[1] == '-') + if(*++p == *text) + matched = MATCH_SUCCESS; + for(last = *p; *++p && *p != ']'; last = *p) + if (*p == '-' && p[1] != ']' ? *text <= *++p && *text >= last : *text == *p) + matched = MATCH_SUCCESS; + if(matched == reverse) + return MATCH_FAILED; + continue; + } + } + return *text == 0; +} + +/* public interface for shell style matching: returns 0 if fails, 1 if matches */ +static int shellStyleMatch(char *text, char *pattern) +{ + if(pattern == NULL) /* NULL pattern is synonymous to "*" */ + return 1; + return _shellStyleMatch(text, pattern) == MATCH_SUCCESS; +} + +/* ------------------------------------------------------------------------- */ + +int usbGetStringAscii(usb_dev_handle *dev, int index, char *buf, int buflen) +{ +char buffer[256]; +int rval, i; + + if((rval = usb_get_string_simple(dev, index, buf, buflen)) >= 0) /* use libusb version if it works */ + return rval; + if((rval = usb_control_msg(dev, USB_ENDPOINT_IN, USB_REQ_GET_DESCRIPTOR, (USB_DT_STRING << 8) + index, 0x0409, buffer, sizeof(buffer), 5000)) < 0) + return rval; + if(buffer[1] != USB_DT_STRING){ + *buf = 0; + return 0; + } + if((unsigned char)buffer[0] < rval) + rval = (unsigned char)buffer[0]; + rval /= 2; + /* lossy conversion to ISO Latin1: */ + for(i=1;i buflen) /* destination buffer overflow */ + break; + buf[i-1] = buffer[2 * i]; + if(buffer[2 * i + 1] != 0) /* outside of ISO Latin1 range */ + buf[i-1] = '?'; + } + buf[i-1] = 0; + return i-1; +} + +/* ------------------------------------------------------------------------- */ + +int usbOpenDevice(usb_dev_handle **device, int vendorID, char *vendorNamePattern, int productID, char *productNamePattern, char *serialNamePattern, FILE *printMatchingDevicesFp, FILE *warningsFp) +{ +struct usb_bus *bus; +struct usb_device *dev; +usb_dev_handle *handle = NULL; +int errorCode = USBOPEN_ERR_NOTFOUND; + + usb_find_busses(); + usb_find_devices(); + for(bus = usb_get_busses(); bus; bus = bus->next){ + for(dev = bus->devices; dev; dev = dev->next){ /* iterate over all devices on all busses */ + if((vendorID == 0 || dev->descriptor.idVendor == vendorID) + && (productID == 0 || dev->descriptor.idProduct == productID)){ + char vendor[256], product[256], serial[256]; + int len; + handle = usb_open(dev); /* we need to open the device in order to query strings */ + if(!handle){ + errorCode = USBOPEN_ERR_ACCESS; + if(warningsFp != NULL) + fprintf(warningsFp, "Warning: cannot open VID=0x%04x PID=0x%04x: %s\n", dev->descriptor.idVendor, dev->descriptor.idProduct, usb_strerror()); + continue; + } + /* now check whether the names match: */ + len = vendor[0] = 0; + if(dev->descriptor.iManufacturer > 0){ + len = usbGetStringAscii(handle, dev->descriptor.iManufacturer, vendor, sizeof(vendor)); + } + if(len < 0){ + errorCode = USBOPEN_ERR_ACCESS; + if(warningsFp != NULL) + fprintf(warningsFp, "Warning: cannot query manufacturer for VID=0x%04x PID=0x%04x: %s\n", dev->descriptor.idVendor, dev->descriptor.idProduct, usb_strerror()); + }else{ + errorCode = USBOPEN_ERR_NOTFOUND; + /* printf("seen device from vendor ->%s<-\n", vendor); */ + if(shellStyleMatch(vendor, vendorNamePattern)){ + len = product[0] = 0; + if(dev->descriptor.iProduct > 0){ + len = usbGetStringAscii(handle, dev->descriptor.iProduct, product, sizeof(product)); + } + if(len < 0){ + errorCode = USBOPEN_ERR_ACCESS; + if(warningsFp != NULL) + fprintf(warningsFp, "Warning: cannot query product for VID=0x%04x PID=0x%04x: %s\n", dev->descriptor.idVendor, dev->descriptor.idProduct, usb_strerror()); + }else{ + errorCode = USBOPEN_ERR_NOTFOUND; + /* printf("seen product ->%s<-\n", product); */ + if(shellStyleMatch(product, productNamePattern)){ + len = serial[0] = 0; + if(dev->descriptor.iSerialNumber > 0){ + len = usbGetStringAscii(handle, dev->descriptor.iSerialNumber, serial, sizeof(serial)); + } + if(len < 0){ + errorCode = USBOPEN_ERR_ACCESS; + if(warningsFp != NULL) + fprintf(warningsFp, "Warning: cannot query serial for VID=0x%04x PID=0x%04x: %s\n", dev->descriptor.idVendor, dev->descriptor.idProduct, usb_strerror()); + } + if(shellStyleMatch(serial, serialNamePattern)){ + if(printMatchingDevicesFp != NULL){ + if(serial[0] == 0){ + fprintf(printMatchingDevicesFp, "VID=0x%04x PID=0x%04x vendor=\"%s\" product=\"%s\"\n", dev->descriptor.idVendor, dev->descriptor.idProduct, vendor, product); + }else{ + fprintf(printMatchingDevicesFp, "VID=0x%04x PID=0x%04x vendor=\"%s\" product=\"%s\" serial=\"%s\"\n", dev->descriptor.idVendor, dev->descriptor.idProduct, vendor, product, serial); + } + }else{ + break; + } + } + } + } + } + } + usb_close(handle); + handle = NULL; + } + } + if(handle) /* we have found a deice */ + break; + } + if(handle != NULL){ + errorCode = 0; + *device = handle; + } + if(printMatchingDevicesFp != NULL) /* never return an error for listing only */ + errorCode = 0; + return errorCode; +} + +/* ------------------------------------------------------------------------- */ diff --git a/commandline/library/opendevice.h b/commandline/library/opendevice.h new file mode 100644 index 0000000..a23ed41 --- /dev/null +++ b/commandline/library/opendevice.h @@ -0,0 +1,81 @@ +/* Name: opendevice.h + * Project: V-USB host-side library + * Author: Christian Starkjohann + * Creation Date: 2008-04-10 + * Tabsize: 4 + * Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH + * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) + * This Revision: $Id: opendevice.h 755 2009-08-03 17:01:21Z cs $ + */ + +/* +General Description: +This module offers additional functionality for host side drivers based on +libusb or libusb-win32. It includes a function to find and open a device +based on numeric IDs and textual description. It also includes a function to +obtain textual descriptions from a device. + +To use this functionality, simply copy opendevice.c and opendevice.h into your +project and add them to your Makefile. You may modify and redistribute these +files according to the GNU General Public License (GPL) version 2 or 3. +*/ + +#ifndef __OPENDEVICE_H_INCLUDED__ +#define __OPENDEVICE_H_INCLUDED__ + +#if defined(LINUX) + #include // this is libusb, see http://libusb.sourceforge.net/ +#else + #include // this is libusb, see http://libusb.sourceforge.net/ +#endif +#include + +int usbGetStringAscii(usb_dev_handle *dev, int index, char *buf, int buflen); +/* This function gets a string descriptor from the device. 'index' is the + * string descriptor index. The string is returned in ISO Latin 1 encoding in + * 'buf' and it is terminated with a 0-character. The buffer size must be + * passed in 'buflen' to prevent buffer overflows. A libusb device handle + * must be given in 'dev'. + * Returns: The length of the string (excluding the terminating 0) or + * a negative number in case of an error. If there was an error, use + * usb_strerror() to obtain the error message. + */ + +int usbOpenDevice(usb_dev_handle **device, int vendorID, char *vendorNamePattern, int productID, char *productNamePattern, char *serialNamePattern, FILE *printMatchingDevicesFp, FILE *warningsFp); +/* This function iterates over all devices on all USB busses and searches for + * a device. Matching is done first by means of Vendor- and Product-ID (passed + * in 'vendorID' and 'productID'. An ID of 0 matches any numeric ID (wildcard). + * When a device matches by its IDs, matching by names is performed. Name + * matching can be done on textual vendor name ('vendorNamePattern'), product + * name ('productNamePattern') and serial number ('serialNamePattern'). A + * device matches only if all non-null pattern match. If you don't care about + * a string, pass NULL for the pattern. Patterns are Unix shell style pattern: + * '*' stands for 0 or more characters, '?' for one single character, a list + * of characters in square brackets for a single character from the list + * (dashes are allowed to specify a range) and if the lis of characters begins + * with a caret ('^'), it matches one character which is NOT in the list. + * Other parameters to the function: If 'warningsFp' is not NULL, warning + * messages are printed to this file descriptor with fprintf(). If + * 'printMatchingDevicesFp' is not NULL, no device is opened but matching + * devices are printed to the given file descriptor with fprintf(). + * If a device is opened, the resulting USB handle is stored in '*device'. A + * pointer to a "usb_dev_handle *" type variable must be passed here. + * Returns: 0 on success, an error code (see defines below) on failure. + */ + +/* usbOpenDevice() error codes: */ +#define USBOPEN_SUCCESS 0 /* no error */ +#define USBOPEN_ERR_ACCESS 1 /* not enough permissions to open device */ +#define USBOPEN_ERR_IO 2 /* I/O error */ +#define USBOPEN_ERR_NOTFOUND 3 /* device not found */ + + +/* Obdev's free USB IDs, see USB-IDs-for-free.txt for details */ + +#define USB_VID_OBDEV_SHARED 5824 /* obdev's shared vendor ID */ +#define USB_PID_OBDEV_SHARED_CUSTOM 1500 /* shared PID for custom class devices */ +#define USB_PID_OBDEV_SHARED_HID 1503 /* shared PID for HIDs except mice & keyboards */ +#define USB_PID_OBDEV_SHARED_CDCACM 1505 /* shared PID for CDC Modem devices */ +#define USB_PID_OBDEV_SHARED_MIDI 1508 /* shared PID for MIDI class devices */ + +#endif /* __OPENDEVICE_H_INCLUDED__ */ -- cgit v1.2.3