diff options
author | Daniel Friesel <derf@finalrewind.org> | 2016-01-01 18:54:56 +0100 |
---|---|---|
committer | Daniel Friesel <derf@finalrewind.org> | 2016-01-01 18:54:56 +0100 |
commit | b1bd27388c8e09d5dba666377e01fbc5070be754 (patch) | |
tree | 7e7dca262d1f28a25bfb453d552873f0b574ec88 | |
parent | fbb504f520a6acb25ab891e0c66896dd2be8621d (diff) |
simplify USB protocol
-rw-r--r-- | commandline/i2c-util.c | 28 | ||||
-rw-r--r-- | firmware/main.c | 72 | ||||
-rw-r--r-- | firmware/usbconfig.h | 8 |
3 files changed, 30 insertions, 78 deletions
diff --git a/commandline/i2c-util.c b/commandline/i2c-util.c index f8aa18d..772aae7 100644 --- a/commandline/i2c-util.c +++ b/commandline/i2c-util.c @@ -32,12 +32,14 @@ obtained from http://libusb.sourceforge.net/. #define PSCMD_ECHO 0 #define PSCMD_GET 1 -#define PSCMD_ON 2 -#define PSCMD_OFF 3 +#define PSCMD_SET 2 /* These are the vendor specific SETUP commands implemented by our USB device */ -char bit_sda = 6; -char bit_scl = 7; +unsigned char bit_sda = 6; +unsigned char bit_scl = 7; + +unsigned char val_sda = 1; +unsigned char val_scl = 1; usb_dev_handle *handle = NULL; @@ -179,8 +181,8 @@ unsigned char get_status() USB_ENDPOINT_IN, PSCMD_GET, 0, 0, (char *)buffer, sizeof(buffer), 5000); - if (nBytes < 2) { - fprintf(stderr, "ERR: read status: got %d bytes, expected 2\n", + if (nBytes < 1) { + fprintf(stderr, "ERR: read status: got %d bytes, expected 1\n", nBytes); exit(1); } @@ -240,9 +242,11 @@ void set_sda(char value) // discarded unsigned char buffer[8]; + val_sda = value; + usb_control_msg(handle, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN, - (value ? PSCMD_ON : PSCMD_OFF), 0, bit_sda, + PSCMD_SET, 0, (val_sda << bit_sda) | (val_scl << bit_scl), (char *)buffer, sizeof(buffer), 5000); } @@ -251,9 +255,11 @@ void set_scl(char value) // discarded unsigned char buffer[8]; + val_scl = value; + usb_control_msg(handle, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN, - (value ? PSCMD_ON : PSCMD_OFF), 0, bit_scl, + PSCMD_SET, 0, (val_sda << bit_sda) | (val_scl << bit_scl), (char *)buffer, sizeof(buffer), 5000); } @@ -333,10 +339,10 @@ void i2c_init() { usb_init(); if (usbOpenDevice - (&handle, USBDEV_SHARED_VENDOR, "www.obdev.at", - USBDEV_SHARED_PRODUCT, "PowerSwitch") != 0) { + (&handle, USBDEV_SHARED_VENDOR, "finalrewind.org", + USBDEV_SHARED_PRODUCT, "VUSB-I2C") != 0) { fprintf(stderr, - "Could not find USB device \"PowerSwitch\" with vid=0x%x pid=0x%x\n", + "Could not find USB device \"VUSB-I2C\" with vid=0x%x pid=0x%x\n", USBDEV_SHARED_VENDOR, USBDEV_SHARED_PRODUCT); exit(1); } diff --git a/firmware/main.c b/firmware/main.c index c6694d2..5a863e9 100644 --- a/firmware/main.c +++ b/firmware/main.c @@ -31,80 +31,24 @@ Application examples: #ifndef TEST_DRIVER_SIZE /* define this to check out size of pure driver */ -static uchar actionTimers[8]; -static uchar permstatus = 255; - -/* This is the AT90S2313 version of the routine. Change for others. */ -static void outputByte(uchar b) -{ - DDRB = ~b; -} - -static uchar computeTemporaryChanges(void) -{ - return 0; -} - -static void computeOutputStatus(void) -{ - outputByte(permstatus); -} - -/* We poll for the timer interrupt instead of declaring an interrupt handler - * with global interrupts enabled. This saves recursion depth. Our timer does - * not need high precision and does not run at a high rate anyway. - */ -static void timerInterrupt(void) -{ -static uchar prescaler; -uchar i; - - if(!prescaler--){ - prescaler = 8; /* rate = 12M / 1024 * 256 * 9 */ - for(i=0;i<8;i++){ - if(actionTimers[i]) - actionTimers[i]--; - } - computeOutputStatus(); - } -} - USB_PUBLIC uchar usbFunctionSetup(uchar data[8]) { usbRequest_t *rq = (void *)data; -uchar status = permstatus; static uchar replyBuf[2]; usbMsgPtr = replyBuf; - if(rq->bRequest == 0){ /* ECHO */ + if(rq->bRequest == 0) { /* ECHO */ replyBuf[0] = rq->wValue.bytes[0]; replyBuf[1] = rq->wValue.bytes[1]; return 2; } - if(rq->bRequest == 1){ /* GET_STATUS -> result = 2 bytes */ + if(rq->bRequest == 1) { /* GET_STATUS -> result = 1 bytes */ replyBuf[0] = PINB; - replyBuf[1] = computeTemporaryChanges(); - return 2; + return 1; } - if(rq->bRequest == 2 || rq->bRequest == 3){ /* SWITCH_ON or SWITCH_OFF, index = bit number */ - uchar bit = rq->wIndex.bytes[0] & 7; - uchar mask = 1 << bit; - uchar needChange, isOn = status & mask; - if(rq->bRequest == 2){ /* SWITCH_ON */ - status |= mask; - needChange = !isOn; - }else{ /* SWITCH_OFF */ - status &= ~mask; - needChange = isOn; - } - if(rq->wValue.bytes[0] == 0){ /* duration == 0 -> permanent switch */ - actionTimers[bit] = 0; - permstatus = status; - }else if(needChange){ /* temporary switch: value = duration in 200ms units */ - actionTimers[bit] = rq->wValue.bytes[0]; - } + if(rq->bRequest == 2) { /* SET_STATUS. Payload byte is output. */ + DDRB = ~(rq->wIndex.bytes[0]); } - computeOutputStatus(); return 0; } @@ -131,7 +75,6 @@ uchar i; * that it should re-enumerate the device. Otherwise the host's and device's * concept of the device-ID would be out of sync. */ - computeOutputStatus(); /* set output status before we do the delay */ usbDeviceDisconnect(); /* enforce re-enumeration, do this while interrupts are disabled! */ i = 0; while(--i){ /* fake USB disconnect for > 500 ms */ @@ -147,7 +90,10 @@ uchar i; usbPoll(); if(TIFR & (1 << TOV0)){ TIFR |= 1 << TOV0; /* clear pending flag */ - timerInterrupt(); + /* + * a periodic (low-frequency, low-accuracy) loop function can + * be placed here. + */ } } return 0; diff --git a/firmware/usbconfig.h b/firmware/usbconfig.h index beaec6a..585d16d 100644 --- a/firmware/usbconfig.h +++ b/firmware/usbconfig.h @@ -141,8 +141,8 @@ the newest features and options. #define USB_CFG_DEVICE_VERSION 0x00, 0x01 /* Version number of the device: Minor number first, then major number. */ -#define USB_CFG_VENDOR_NAME 'w', 'w', 'w', '.', 'o', 'b', 'd', 'e', 'v', '.', 'a', 't' -#define USB_CFG_VENDOR_NAME_LEN 12 +#define USB_CFG_VENDOR_NAME 'f', 'i', 'n', 'a', 'l', 'r', 'e', 'w', 'i', 'n', 'd', '.', 'o', 'r', 'g' +#define USB_CFG_VENDOR_NAME_LEN 15 /* These two values define the vendor name returned by the USB device. The name * must be given as a list of characters under single quotes. The characters * are interpreted as Unicode (UTF-16) entities. @@ -151,8 +151,8 @@ the newest features and options. * obdev's free shared VID/PID pair. See the file USBID-License.txt for * details. */ -#define USB_CFG_DEVICE_NAME 'P', 'o', 'w', 'e', 'r', 'S', 'w', 'i', 't', 'c', 'h' -#define USB_CFG_DEVICE_NAME_LEN 11 +#define USB_CFG_DEVICE_NAME 'V', 'U', 'S', 'B', '-', 'I', '2', 'C' +#define USB_CFG_DEVICE_NAME_LEN 8 /* Same as above for the device name. If you don't want a device name, undefine * the macros. See the file USBID-License.txt before you assign a name. */ |