From c89a70619e7ec76447a7e329e1971e9c1dfa1684 Mon Sep 17 00:00:00 2001 From: fishsoupisgood Date: Fri, 2 Oct 2020 10:14:08 +0100 Subject: fish --- .gitignore | 1 + Makefile | 38 ++++++++ flasher/.gitignore | 3 + flasher/Makefile | 46 +++++++++ flasher/README | 1 + flasher/hidsdi.h | 50 ++++++++++ flasher/main.c | 260 ++++++++++++++++++++++++++++++++++++++++++++++++++ flasher/usb-libusb.c | 203 +++++++++++++++++++++++++++++++++++++++ flasher/usbcalls.c | 20 ++++ flasher/usbcalls.h | 81 ++++++++++++++++ schematic.png | Bin 0 -> 64064 bytes set_color/.gitignore | 3 + set_color/Makefile | 8 ++ set_color/set_color.c | 202 +++++++++++++++++++++++++++++++++++++++ 14 files changed, 916 insertions(+) create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 flasher/.gitignore create mode 100644 flasher/Makefile create mode 100644 flasher/README create mode 100644 flasher/hidsdi.h create mode 100644 flasher/main.c create mode 100644 flasher/usb-libusb.c create mode 100644 flasher/usbcalls.c create mode 100644 flasher/usbcalls.h create mode 100644 schematic.png create mode 100644 set_color/.gitignore create mode 100644 set_color/Makefile create mode 100644 set_color/set_color.c diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2b8800b --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +firmware diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..5dae6a5 --- /dev/null +++ b/Makefile @@ -0,0 +1,38 @@ +FW=firmware/ymdk_ymd09_32a_jmm.hex + + +default: ${FW} + +flash: flasher/bootloadHID ${FW} + flasher/bootloadHID -r ${FW} + + +flasher/bootloadHID: + make -C flasher + +firmware/ymdk_ymd09_32a_jmm.hex: firmware/quantum/version.h + make -C firmware -r -R -f build_keyboard.mk KEYBOARD=ymdk/ymd09_32a KEYMAP=jmm VERBOSE= COLOR=true SILENT=false + + + +firmware/quantum/version.h: firmware/submodules.stamp + make -C firmware list-keyboards + +clean: firmware/submodules.stamp + make -C firmware clean + /bin/rm -f firmware/ymdk_ymd09_32a_jmm.hex + /bin/rm -f firmware/quantum/version.h + make -C flasher clean + +firmware/submodules.stamp: firmware/checkout.stamp + (cd firmware && git submodule init ) + (cd firmware && git submodule update ) + touch $@ + +firmware/checkout.stamp: + git clone ssh://git@git.panaceas.org/git/avr/qmk/firmware firmware + touch $@ + + + + diff --git a/flasher/.gitignore b/flasher/.gitignore new file mode 100644 index 0000000..037024c --- /dev/null +++ b/flasher/.gitignore @@ -0,0 +1,3 @@ +*~ +*.o +bootloadHID diff --git a/flasher/Makefile b/flasher/Makefile new file mode 100644 index 0000000..60c5687 --- /dev/null +++ b/flasher/Makefile @@ -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$ + +# 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 diff --git a/flasher/README b/flasher/README new file mode 100644 index 0000000..4bb76fe --- /dev/null +++ b/flasher/README @@ -0,0 +1 @@ +nicked from bootloadhid diff --git a/flasher/hidsdi.h b/flasher/hidsdi.h new file mode 100644 index 0000000..1d116dd --- /dev/null +++ b/flasher/hidsdi.h @@ -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$ + */ + +/* +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 + +#include +#include + +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 + +#endif diff --git a/flasher/main.c b/flasher/main.c new file mode 100644 index 0000000..282ee5f --- /dev/null +++ b/flasher/main.c @@ -0,0 +1,260 @@ +/* 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$ + */ + +#include +#include +#include +#include +#include "usbcalls.h" + +#define IDENT_VENDOR_NUM 0x16c0 +#define IDENT_VENDOR_STRING "obdev.at" +#define IDENT_PRODUCT_NUM 1503 +#define IDENT_PRODUCT_STRING "HIDBoot" + +/* ------------------------------------------------------------------------- */ + +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] []\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; +} + +/* ------------------------------------------------------------------------- */ + + diff --git a/flasher/usb-libusb.c b/flasher/usb-libusb.c new file mode 100644 index 0000000..c0bd2a1 --- /dev/null +++ b/flasher/usb-libusb.c @@ -0,0 +1,203 @@ +/* Name: usb-libusb.c + * 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$ + */ + +/* +General Description: +This module implements USB HID report receiving/sending based on libusb. It +does not read and parse the report descriptor. You must therefore be careful +to pass correctly formatted data blocks of correct size. In order to be +compatible with the Windows implementation, we add a zero report ID for all +reports which don't have an ID. Since we don't parse the descriptor, the caller +must tell us whether report IDs are used or not in usbOpenDevice(). + +The implementation of dummy report IDs is a hack. Whether they are used is +stored in a global variable, not in the device structure (just laziness, don't +want to allocate memory for that). If you open more than one device and the +devices differ in report ID usage, you must change the code. +*/ + +#include +#include +#include + +#define usbDevice usb_dev_handle /* use libusb's device structure */ +#include "usbcalls.h" + +/* ------------------------------------------------------------------------- */ + +#define USBRQ_HID_GET_REPORT 0x01 +#define USBRQ_HID_SET_REPORT 0x09 + +static int usesReportIDs; + +/* ------------------------------------------------------------------------- */ + +static int usbGetStringAscii(usb_dev_handle *dev, int index, int langid, char *buf, int buflen) +{ +char buffer[256]; +int rval, i; + + if((rval = usb_control_msg(dev, USB_ENDPOINT_IN, USB_REQ_GET_DESCRIPTOR, (USB_DT_STRING << 8) + index, langid, buffer, sizeof(buffer), 1000)) < 0) + return rval; + if(buffer[1] != USB_DT_STRING) + 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(usbDevice_t **device, int vendor, char *vendorName, int product, char *productName, int _usesReportIDs) +{ +struct usb_bus *bus; +struct usb_device *dev; +usb_dev_handle *handle = NULL; +int errorCode = USB_ERROR_NOTFOUND; +static int didUsbInit = 0; + + if(!didUsbInit){ + usb_init(); + didUsbInit = 1; + } + usb_find_busses(); + usb_find_devices(); + for(bus=usb_get_busses(); bus; bus=bus->next){ + for(dev=bus->devices; dev; dev=dev->next){ + if(dev->descriptor.idVendor == vendor && dev->descriptor.idProduct == product){ + char string[256]; + int len; + handle = usb_open(dev); /* we need to open the device in order to query strings */ + if(!handle){ + errorCode = USB_ERROR_ACCESS; + fprintf(stderr, "Warning: cannot open USB device: %s\n", usb_strerror()); + continue; + } + if(vendorName == NULL && productName == NULL){ /* name does not matter */ + break; + } + /* now check whether the names match: */ + len = usbGetStringAscii(handle, dev->descriptor.iManufacturer, 0x0409, string, sizeof(string)); + if(len < 0){ + errorCode = USB_ERROR_IO; + fprintf(stderr, "Warning: cannot query manufacturer for device: %s\n", usb_strerror()); + }else{ + errorCode = USB_ERROR_NOTFOUND; + /* fprintf(stderr, "seen device from vendor ->%s<-\n", string); */ + if(strcmp(string, vendorName) == 0){ + len = usbGetStringAscii(handle, dev->descriptor.iProduct, 0x0409, string, sizeof(string)); + if(len < 0){ + errorCode = USB_ERROR_IO; + fprintf(stderr, "Warning: cannot query product for device: %s\n", usb_strerror()); + }else{ + errorCode = USB_ERROR_NOTFOUND; + /* fprintf(stderr, "seen product ->%s<-\n", string); */ + if(strcmp(string, productName) == 0) + break; + } + } + } + usb_close(handle); + handle = NULL; + } + } + if(handle) + break; + } + if(handle != NULL){ + int rval, retries = 3; + if(usb_set_configuration(handle, 1)){ + fprintf(stderr, "Warning: could not set configuration: %s\n", usb_strerror()); + } + /* now try to claim the interface and detach the kernel HID driver on + * linux and other operating systems which support the call. + */ + while((rval = usb_claim_interface(handle, 0)) != 0 && retries-- > 0){ +#ifdef LIBUSB_HAS_DETACH_KERNEL_DRIVER_NP + if(usb_detach_kernel_driver_np(handle, 0) < 0){ + fprintf(stderr, "Warning: could not detach kernel HID driver: %s\n", usb_strerror()); + } +#endif + } +#ifndef __APPLE__ + if(rval != 0) + fprintf(stderr, "Warning: could not claim interface\n"); +#endif +/* Continue anyway, even if we could not claim the interface. Control transfers + * should still work. + */ + errorCode = 0; + *device = handle; + usesReportIDs = _usesReportIDs; + } + return errorCode; +} + +/* ------------------------------------------------------------------------- */ + +void usbCloseDevice(usbDevice_t *device) +{ + if(device != NULL) + usb_close(device); +} + +/* ------------------------------------------------------------------------- */ + +int usbSetReport(usbDevice_t *device, int reportType, char *buffer, int len) +{ +int bytesSent; + + if(!usesReportIDs){ + buffer++; /* skip dummy report ID */ + len--; + } + bytesSent = usb_control_msg(device, USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_ENDPOINT_OUT, USBRQ_HID_SET_REPORT, reportType << 8 | buffer[0], 0, buffer, len, 5000); + if(bytesSent != len){ + if(bytesSent < 0) + fprintf(stderr, "Error sending message: %s\n", usb_strerror()); + return USB_ERROR_IO; + } + return 0; +} + +/* ------------------------------------------------------------------------- */ + +int usbGetReport(usbDevice_t *device, int reportType, int reportNumber, char *buffer, int *len) +{ +int bytesReceived, maxLen = *len; + + if(!usesReportIDs){ + buffer++; /* make room for dummy report ID */ + maxLen--; + } + bytesReceived = usb_control_msg(device, USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_ENDPOINT_IN, USBRQ_HID_GET_REPORT, reportType << 8 | reportNumber, 0, buffer, maxLen, 5000); + if(bytesReceived < 0){ + fprintf(stderr, "Error sending message: %s\n", usb_strerror()); + return USB_ERROR_IO; + } + *len = bytesReceived; + if(!usesReportIDs){ + buffer[-1] = reportNumber; /* add dummy report ID */ + //*len++; + } + return 0; +} + +/* ------------------------------------------------------------------------- */ + + diff --git a/flasher/usbcalls.c b/flasher/usbcalls.c new file mode 100644 index 0000000..0527aef --- /dev/null +++ b/flasher/usbcalls.c @@ -0,0 +1,20 @@ +/* Name: usbcalls.c + * 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$ + */ + +/* This file includes the appropriate implementation based on platform + * specific defines. + */ + +#if defined(WIN32) +# include "usb-windows.c" +#else +/* e.g. defined(__APPLE__) */ +# include "usb-libusb.c" +#endif diff --git a/flasher/usbcalls.h b/flasher/usbcalls.h new file mode 100644 index 0000000..43bd1cc --- /dev/null +++ b/flasher/usbcalls.h @@ -0,0 +1,81 @@ +/* Name: usbcalls.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$ + */ + +#ifndef __usbcalls_h_INCLUDED__ +#define __usbcalls_h_INCLUDED__ + +/* +General Description: +This module implements an abstraction layer for access to USB/HID communication +functions. An implementation based on libusb (portable to Linux, FreeBSD and +Mac OS X) and a native implementation for Windows are provided. +*/ + +/* ------------------------------------------------------------------------ */ + +#define USB_HID_REPORT_TYPE_INPUT 1 +#define USB_HID_REPORT_TYPE_OUTPUT 2 +#define USB_HID_REPORT_TYPE_FEATURE 3 +/* Numeric constants for 'reportType' parameters */ + +#define USB_ERROR_NONE 0 +#define USB_ERROR_ACCESS 1 +#define USB_ERROR_NOTFOUND 2 +#define USB_ERROR_BUSY 16 +#define USB_ERROR_IO 5 +/* These are the error codes which can be returned by functions of this + * module. + */ + +/* ------------------------------------------------------------------------ */ + +typedef struct usbDevice usbDevice_t; +/* This type represents a USB device internally. Only opaque pointers to this + * type are available outside the module implementation. + */ + +/* ------------------------------------------------------------------------ */ + +int usbOpenDevice(usbDevice_t **device, int vendor, char *vendorName, int product, char *productName, int usesReportIDs); +/* This function opens a USB device. 'vendor' and 'product' are the numeric + * Vendor-ID and Product-ID of the device we want to open. If 'vendorName' and + * 'productName' are both not NULL, only devices with matching manufacturer- + * and product name strings are accepted. If the device uses report IDs, + * 'usesReportIDs' must be set to a non-zero value. + * Returns: If a matching device has been found, USB_ERROR_NONE is returned and + * '*device' is set to an opaque pointer representing the device. The device + * must be closed with usbCloseDevice(). If the device has not been found or + * opening failed, an error code is returned. + */ +void usbCloseDevice(usbDevice_t *device); +/* Every device opened with usbOpenDevice() must be closed with this function. + */ +int usbSetReport(usbDevice_t *device, int reportType, char *buffer, int len); +/* This function sends a report to the device. 'reportType' specifies the type + * of report (see USB_HID_REPORT_TYPE* constants). The report ID must be in the + * first byte of buffer and the length 'len' of the report is specified + * including this report ID. If no report IDs are used, buffer[0] must be set + * to 0 (dummy report ID). + * Returns: 0 on success, an error code otherwise. + */ +int usbGetReport(usbDevice_t *device, int reportType, int reportID, char *buffer, int *len); +/* This function obtains a report from the device. 'reportType' specifies the + * type of report (see USB_HID_REPORT_TYPE* constants). The requested report ID + * is passed in 'reportID'. The caller must pass a buffer of the size of the + * expected report in 'buffer' and initialize the variable in '*len' to the + * total size of this buffer. Upon successful return, the report (prefixed with + * a report ID) is in 'buffer' and the actual length of the report is returned + * in '*len'. + * Returns: 0 on success, an error code otherwise. + */ + +/* ------------------------------------------------------------------------ */ + +#endif /* __usbcalls_h_INCLUDED__ */ diff --git a/schematic.png b/schematic.png new file mode 100644 index 0000000..c4fb741 Binary files /dev/null and b/schematic.png differ diff --git a/set_color/.gitignore b/set_color/.gitignore new file mode 100644 index 0000000..f48b557 --- /dev/null +++ b/set_color/.gitignore @@ -0,0 +1,3 @@ +*~ +*.o +set_color diff --git a/set_color/Makefile b/set_color/Makefile new file mode 100644 index 0000000..8e9c91a --- /dev/null +++ b/set_color/Makefile @@ -0,0 +1,8 @@ +default:set_color + ./$< + +set_color:set_color.c + + +clean: + /bin/rm -f set_color diff --git a/set_color/set_color.c b/set_color/set_color.c new file mode 100644 index 0000000..9dc9fdc --- /dev/null +++ b/set_color/set_color.c @@ -0,0 +1,202 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Hidraw Userspace Example + * + * Copyright (c) 2010 Alan Ott + * Copyright (c) 2010 Signal 11 Software + * + * The code may be used by anyone for any purpose, + * and can serve as a starting point for developing + * applications using hidraw. + */ + +/* Linux */ +#include +#include +#include + +/* Unix */ +#include +#include +#include +#include +#include + +/* C */ +#include +#include +#include +#include +#include + + +typedef struct +{ + uint8_t r; + uint8_t g; + uint8_t b; +} C; + +#define N_LEDS 9 + +static unsigned map[N_LEDS]={2,1,0,3,4,5,8,7,6}; + +C current[N_LEDS]; +C last[N_LEDS]; + + +void +sync_leds (int fd) +{ + unsigned i; + uint8_t buf[8]; + + for (i = 0; i < N_LEDS; ++i) + { + /* Send a Report to the Device */ + if ((last[i].r != current[i].r) + || (last[i].g != current[i].g) || (last[i].b != current[i].b)) + { + buf[0] = 0x05; + buf[1] = map[i]; + buf[2] = current[i].r; + buf[3] = current[i].g; + buf[4] = current[i].b; + write (fd, buf, 8); + usleep (1000); + last[i] = current[i]; + } + } +} + +unsigned f(int v) +{ +v-=5; +if (v<0) return 0; +return v; +} + + +void fade_leds(int fd) +{ +unsigned i; + for (i = 0; i < N_LEDS; ++i) + { + current[i].r=f(current[i].r); + current[i].g=f(current[i].g); + current[i].b=f(current[i].b); + + } + + sync_leds(fd); + +} + +int +open_kb (int *fds) +{ + struct hidraw_devinfo info; + unsigned i; + int n = 0; + for (i = 0; i < 128; ++i) + { + int fd; + char device[128]; + char buf[128]; + sprintf (device, "/dev/hidraw%d", i); + fd = open (device, O_RDWR | O_NONBLOCK); + if (fd < 0) + continue; + + memset (buf, 0, sizeof (buf)); + ioctl (fd, HIDIOCGRAWNAME (256), buf); + buf[sizeof (buf) - 1] = 0; + + + if (strcmp (buf, "YMDK YMD09_32A")) + { + close (fd); + fd = -1; + continue; + } + + fds[n++] = fd; + + } + + + if (n < 2) + { + printf ("Devices not found\n"); + return -1; + } + return 0; +} + +int +main (int argc, char **argv) +{ + int fds[2]; + fd_set rfds; + ssize_t len; + char buf[32]; + struct timeval tv; + + unsigned j, k; + + memset (last, 0xff, sizeof (last)); + + if (open_kb (fds)) + return -1; + + +current[4].g=0xff; + + FD_ZERO (&rfds); + sync_leds (fds[1]); + + tv.tv_sec=0; +tv.tv_usec=0; + + for (;;) + { + FD_SET (fds[0], &rfds); + + if (!tv.tv_usec) + tv.tv_usec=20000; + + switch (select (fds[0] + 1, &rfds, NULL, NULL, &tv)) + { + case -1: + break; + case 1: + + len = read (fds[0], buf, sizeof (buf)); + + if (len < 3) + break; + + for (j = 2; j < len; ++j) + { + if (!buf[j]) continue; + k = buf[j] - 4; + + + current[k].r = rand() & 0xff ; + current[k].g = rand() & 0xff ; + current[k].b = rand() & 0xff ; + } + + sync_leds (fds[1]); + + break; + case 0: + fade_leds(fds[1]); + } + + } + + close (fds[1]); + close (fds[0]); + return 0; +} -- cgit v1.2.3