summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Jung <flo@windfisch.org>2015-11-29 00:30:43 +0100
committerFlorian Jung <flo@windfisch.org>2015-11-29 00:30:43 +0100
commit84b980994934d54b3dad6dd2184830f4464b9933 (patch)
tree9e5eb6fb283e791ff50f85c6d97d28ccc7dca6b6
parent1923a8c9121788804a4e307688b6c45993f58205 (diff)
usb hello world \o/
-rw-r--r--avr/1wire.c130
-rw-r--r--avr/1wire.h27
-rw-r--r--avr/LICENSE (renamed from LICENSE)0
-rw-r--r--avr/Makefile (renamed from Makefile)10
-rw-r--r--avr/README (renamed from README)0
-rw-r--r--avr/main.c164
-rw-r--r--avr/main_jtag.c198
-rw-r--r--avr/main_jtag.c.orig196
-rw-r--r--avr/usbdrv/Changelog.txt (renamed from usbdrv/Changelog.txt)0
-rw-r--r--avr/usbdrv/CommercialLicense.txt (renamed from usbdrv/CommercialLicense.txt)0
-rw-r--r--avr/usbdrv/License.txt (renamed from usbdrv/License.txt)0
-rw-r--r--avr/usbdrv/Readme.txt (renamed from usbdrv/Readme.txt)0
-rw-r--r--avr/usbdrv/USB-ID-FAQ.txt (renamed from usbdrv/USB-ID-FAQ.txt)0
-rw-r--r--avr/usbdrv/USB-IDs-for-free.txt (renamed from usbdrv/USB-IDs-for-free.txt)0
-rw-r--r--avr/usbdrv/asmcommon.inc (renamed from usbdrv/asmcommon.inc)0
-rw-r--r--avr/usbdrv/oddebug.c (renamed from usbdrv/oddebug.c)0
-rw-r--r--avr/usbdrv/oddebug.h (renamed from usbdrv/oddebug.h)0
-rw-r--r--avr/usbdrv/usbconfig-prototype.h (renamed from usbdrv/usbconfig-prototype.h)0
-rw-r--r--avr/usbdrv/usbconfig.h (renamed from usbdrv/usbconfig.h)16
-rw-r--r--avr/usbdrv/usbdrv.c (renamed from usbdrv/usbdrv.c)0
-rw-r--r--avr/usbdrv/usbdrv.h (renamed from usbdrv/usbdrv.h)0
-rw-r--r--avr/usbdrv/usbdrvasm.S (renamed from usbdrv/usbdrvasm.S)0
-rw-r--r--avr/usbdrv/usbdrvasm.asm (renamed from usbdrv/usbdrvasm.asm)0
-rw-r--r--avr/usbdrv/usbdrvasm12.inc (renamed from usbdrv/usbdrvasm12.inc)0
-rw-r--r--avr/usbdrv/usbdrvasm128.inc (renamed from usbdrv/usbdrvasm128.inc)0
-rw-r--r--avr/usbdrv/usbdrvasm15.inc (renamed from usbdrv/usbdrvasm15.inc)0
-rw-r--r--avr/usbdrv/usbdrvasm16.inc (renamed from usbdrv/usbdrvasm16.inc)0
-rw-r--r--avr/usbdrv/usbdrvasm165.inc (renamed from usbdrv/usbdrvasm165.inc)0
-rw-r--r--avr/usbdrv/usbdrvasm18-crc.inc (renamed from usbdrv/usbdrvasm18-crc.inc)0
-rw-r--r--avr/usbdrv/usbdrvasm20.inc (renamed from usbdrv/usbdrvasm20.inc)0
-rw-r--r--avr/usbdrv/usbportability.h (renamed from usbdrv/usbportability.h)0
-rw-r--r--main.c312
-rwxr-xr-xpc/a.outbin0 -> 12696 bytes
-rw-r--r--pc/main.c134
-rw-r--r--pc/usbtest.c199
35 files changed, 1062 insertions, 324 deletions
diff --git a/avr/1wire.c b/avr/1wire.c
new file mode 100644
index 0000000..237abb9
--- /dev/null
+++ b/avr/1wire.c
@@ -0,0 +1,130 @@
+/************************************************************************/
+/* */
+/* Access Dallas 1-Wire Devices */
+/* */
+/* Author: Peter Dannegger */
+/* danni@specs.de */
+/* */
+/************************************************************************/
+#include <util/delay.h>
+#include <avr/io.h>
+#include <avr/interrupt.h>
+
+#ifndef W1_PIN
+#define W1_PIN PA0
+#define W1_IN PINA
+#define W1_OUT PORTA
+#define W1_DDR DDRA
+#endif
+
+uint8_t buff[2];
+
+uint8_t w1_reset(void)
+{
+ uint8_t err;
+
+ W1_OUT &= ~(1<<W1_PIN);
+ W1_DDR |= 1<<W1_PIN;
+ _delay_us(480 ); // 480 us
+ cli();
+ W1_DDR &= ~(1<<W1_PIN);
+ _delay_us( 66 );
+ err = W1_IN & (1<<W1_PIN); // no presence detect
+ sei();
+ _delay_us( 480 - 66 );
+ if( (W1_IN & (1<<W1_PIN)) == 0 ) // short circuit
+ err = 1;
+ return err;
+}
+
+
+uint8_t w1_bit_io( uint8_t b )
+{
+ cli();
+ W1_DDR |= 1<<W1_PIN;
+ _delay_us( 1 );
+ if( b )
+ W1_DDR &= ~(1<<W1_PIN);
+ _delay_us( 15 - 1 );
+ if( (W1_IN & (1<<W1_PIN)) == 0 )
+ b = 0;
+ _delay_us( 60 - 15 );
+ W1_DDR &= ~(1<<W1_PIN);
+ sei();
+ return b;
+}
+
+
+uint w1_byte_wr( uint8_t b )
+{
+ uint8_t i = 8, j;
+ do{
+ j = w1_bit_io( b & 1 );
+ b >>= 1;
+ if( j )
+ b |= 0x80;
+ }while( --i );
+ return b;
+}
+
+
+uint w1_byte_rd( void )
+{
+ return w1_byte_wr( 0xFF );
+}
+
+
+uint8_t w1_rom_search( uint8_t diff, uint8_t idata *id )
+{
+ uint8_t i, j, next_diff;
+ uint8_t b;
+
+ if( w1_reset() )
+ return PRESENCE_ERR; // error, no device found
+ w1_byte_wr( SEARCH_ROM ); // ROM search command
+ next_diff = LAST_DEVICE; // unchanged on last device
+ i = 8 * 8; // 8 bytes
+ do{
+ j = 8; // 8 bits
+ do{
+ b = w1_bit_io( 1 ); // read bit
+ if( w1_bit_io( 1 ) ){ // read complement bit
+ if( b ) // 11
+ return DATA_ERR; // data error
+ }else{
+ if( !b ){ // 00 = 2 devices
+ if( diff > i ||
+ ((*id & 1) && diff != i) ){
+ b = 1; // now 1
+ next_diff = i; // next pass 0
+ }
+ }
+ }
+ w1_bit_io( b ); // write bit
+ *id >>= 1;
+ if( b ) // store bit
+ *id |= 0x80;
+ i--;
+ }while( --j );
+ id++; // next byte
+ }while( i );
+ return next_diff; // to continue search
+}
+
+
+void w1_command( uint8_t command, uint8_t idata *id )
+{
+ uint8_t i;
+ w1_reset();
+ if( id ){
+ w1_byte_wr( MATCH_ROM ); // to a single device
+ i = 8;
+ do{
+ w1_byte_wr( *id );
+ id++;
+ }while( --i );
+ }else{
+ w1_byte_wr( SKIP_ROM ); // to all devices
+ }
+ w1_byte_wr( command );
+}
diff --git a/avr/1wire.h b/avr/1wire.h
new file mode 100644
index 0000000..d5657ad
--- /dev/null
+++ b/avr/1wire.h
@@ -0,0 +1,27 @@
+#ifndef _1wire_h_
+#define _1wire_h_
+#define MATCH_ROM 0x55
+#define SKIP_ROM 0xCC
+#define SEARCH_ROM 0xF0
+
+#define CONVERT_T 0x44 // DS1820 commands
+#define READ 0xBE
+#define WRITE 0x4E
+#define EE_WRITE 0x48
+#define EE_RECALL 0xB8
+
+#define SEARCH_FIRST 0xFF // start new search
+#define PRESENCE_ERR 0xFF
+#define DATA_ERR 0xFE
+#define LAST_DEVICE 0x00 // last device found
+// 0x01 ... 0x40: continue searching
+
+uint8_t w1_reset(void);
+
+uint8_t w1_byte_wr( uint8_t b );
+uint8_t w1_byte_rd( void );
+
+uint8_t w1_rom_search( uint8_t diff, uint8_t idata *id );
+
+void w1_command( uint8_t command, uint8_t idata *id );
+#endif
diff --git a/LICENSE b/avr/LICENSE
index 94a9ed0..94a9ed0 100644
--- a/LICENSE
+++ b/avr/LICENSE
diff --git a/Makefile b/avr/Makefile
index 4335bc9..13bdd94 100644
--- a/Makefile
+++ b/avr/Makefile
@@ -371,13 +371,13 @@ all: begin directories gccversion sizebefore build sizeafter end
directories: .dep obj obj/usbdrv
.dep:
- mkdir .dep
+ mkdir -p .dep
obj:
- mkdir obj
+ mkdir -p obj
-obj/usbdrv: obj
- mkdir obj/usbdrv
+obj/usbdrv:
+ mkdir -p obj/usbdrv
# Change the build target to build a HEX file or a library.
build: elf hex eep lss sym
@@ -433,6 +433,8 @@ program: $(TARGET).hex $(TARGET).eep
$(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH)
$(AVRDUDE_WRITE_EEPROM)
+usbboot: $(TARGET).hex
+ /home/flo/kruschkram/hass/avrusbboot.2006-06-25/software/avrusbboot $(TARGET).hex
# Generate avr-gdb config/init file which does the following:
# define the reset signal, load the target file, connect to target, and set
diff --git a/README b/avr/README
index 16c75d9..16c75d9 100644
--- a/README
+++ b/avr/README
diff --git a/avr/main.c b/avr/main.c
new file mode 100644
index 0000000..d350637
--- /dev/null
+++ b/avr/main.c
@@ -0,0 +1,164 @@
+/*
+ Project: DS1992 memory iButton dumper
+ Author: Florian Jung (flo@windfisch.org)
+ Copyright: (c) 2015 by Florian Jung
+ License: GNU GPL v3 (see LICENSE)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License version 3 as
+ published by the Free Software Foundation.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+ This project is based on the code for the AVR ATtiny USB Tutorial at
+ http://codeandlife.com/ by Joonas Pihlajamaa, joonas.pihlajamaa@iki.fi,
+ which is in turn based on the V-USB example code by Christian Starkjohann
+ (Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH)
+*/
+
+#include <avr/io.h>
+#include <avr/interrupt.h>
+#include <avr/wdt.h>
+#include <avr/eeprom.h>
+#include <util/delay.h>
+#include <string.h>
+
+#include "usbdrv/usbdrv.h"
+
+
+#define LED_BLUE (1<<5)
+#define LED_RED (1<<4)
+#define LED_GREEN (1<<3)
+
+
+#define FUNC_READ 0x42
+#define FUNC_WRITE 0x21
+
+#define FUNC_START_BOOTLOADER 30
+#define FUNC_GET_TYPE 0xFE
+
+void jump_to_bootloader(void)
+{
+ cli();
+ wdt_enable(WDTO_15MS);
+ while (1);
+}
+
+static uchar replyBuffer[130]="Hello world initial";
+usbMsgLen_t usbFunctionSetup(uchar data[8])
+{
+ usbRequest_t *rq = (void *) data;
+ int len = 1;
+
+ switch (rq->bRequest)
+ {
+ case FUNC_GET_TYPE:
+ replyBuffer[0]=10;
+ len = 1;
+ break;
+ case FUNC_START_BOOTLOADER:
+ jump_to_bootloader();
+ len = 0;
+ break;
+ case FUNC_READ:
+ return USB_NO_MSG;
+
+ case FUNC_WRITE:
+ PORTC ^= LED_RED;
+ //strcpy(replyBuffer, "Hello world");
+ len = strlen(replyBuffer)+1;
+ break;
+ }
+
+ usbMsgPtr = replyBuffer;
+ return len;
+}
+
+volatile int count = 5;
+
+uchar usbFunctionWrite(uint8_t * data, uchar len)
+{
+ memcpy(replyBuffer,data,len);
+ replyBuffer[len]='\0';
+
+ return len;
+}
+
+
+
+void usb_disconnect()
+{
+ USB_INTR_ENABLE &= ~(1 << USB_INTR_ENABLE_BIT);
+ usbDeviceDisconnect();
+}
+
+void usb_reconnect()
+{
+ cli();
+ usbDeviceDisconnect(); // enforce re-enumeration
+ for (int i = 0; i < 250; i++)
+ { // wait 500 ms
+ wdt_reset(); // keep the watchdog happy
+ _delay_ms(10);
+ }
+ usbDeviceConnect();
+ USB_INTR_ENABLE |= (1 << USB_INTR_ENABLE_BIT);
+ sei();
+}
+
+
+int main(void)
+{
+ uint32_t c = 0;
+
+ DDRC = 0x38; // LEDs as output
+ PORTC |= LED_BLUE | LED_RED | LED_GREEN;
+ DDRD &= ~0xF3; // connector ports as input
+ DDRB &= ~0x3C;
+ PORTD &= ~0xF3; // disable pullups for unused ports
+ PORTB &= ~0x0C;
+ PORTB |= 0x30; // enable pullups for PB4 and 5
+
+ cli();
+
+ wdt_enable(WDTO_1S); // enable 1s watchdog timer
+
+ usbInit();
+
+ usbDeviceDisconnect(); // enforce re-enumeration
+ for (int i = 0; i < 250; i++)
+ { // wait 500 ms
+ wdt_reset(); // keep the watchdog happy
+ _delay_ms(10);
+ }
+ usbDeviceConnect();
+
+ sei(); // Enable interrupts after re-enumeration
+
+ while (1)
+ {
+ wdt_reset(); // keep the watchdog happy
+ usbPoll();
+
+ if (++c % 3000 == 0) PORTC^=LED_BLUE;
+ /*if ( (c / 3000) % 40 == 0)
+ {
+ PORTC &= ~LED_RED;
+ usb_disconnect();
+ }
+ else if ((c / 3000) % 40 == 20)
+ {
+ usb_reconnect();
+ PORTC |= LED_RED;
+ }*/
+ }
+
+ jump_to_bootloader();
+ return 0;
+}
diff --git a/avr/main_jtag.c b/avr/main_jtag.c
new file mode 100644
index 0000000..b5142d4
--- /dev/null
+++ b/avr/main_jtag.c
@@ -0,0 +1,198 @@
+/************************************************************************************************
+ * Project: USB AVR-ISP
+ * Author: Christian Ulrich
+ * Contact: christian at ullihome dot de
+ *
+ * Creation Date: 2008-12-10
+ * Copyright: (c) 2008 by Christian Ulrich
+ * License: GPLv2 for private use
+ * commercial use prohibited
+ *
+ * Changes:
+ ***********************************************************************************************/
+
+#include <avr/io.h>
+#include <avr/interrupt.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <avr/pgmspace.h>
+#include <avr/eeprom.h>
+#include <util/delay.h>
+#include <avr/wdt.h>
+#include "usbdrv.h"
+#include "usbconfig.h"
+#include "led.h"
+#include "timer.h"
+#include "main.h"
+#include "jtag.h"
+
+#define FUNC_READ_CHAIN 1
+#define FUNC_WRITE_CHAIN 2
+#define FUNC_TAP_STATE 3
+#define FUNC_GET_TAP_STATE 4
+#define FUNC_OPEN 5
+#define FUNC_CLOSE 6
+#define FUNC_SHIFTBITS 7
+#define FUNC_CHAINSIZE 8
+#define FUNC_EXECCHAIN 9
+
+#define FUNC_START_BOOTLOADER 30
+#define FUNC_GET_TYPE 0xFE
+
+#define STATE_IDLE 0
+#define STATE_READ 1
+#define STATE_WRITE 2
+
+uint8_t usb_state = STATE_IDLE;
+
+#ifndef USBASP_COMPATIBLE
+led_t leds[] = {{4,LED_OFF,LED_OFF},
+ {3,LED_OFF,LED_OFF},
+ {5,LED_OFF,LED_OFF}
+};
+#else
+led_t leds[] = {{0,LED_OFF,LED_OFF},
+ {1,LED_OFF,LED_OFF},
+ {3,LED_OFF,LED_OFF}
+};
+#endif
+const uint8_t led_count = sizeof(leds)/sizeof(led_t);
+
+
+#define MAX_CHAINSIZE 900
+unsigned char JTAG_CHAIN[MAX_CHAINSIZE];
+unsigned int chainpos = 0;
+
+int main(void)
+{
+ extern uchar usbNewDeviceAddr;
+ uint8_t i;
+ PORTC |= (1<<PC2);
+//Reconnect USB
+ usbDeviceDisconnect(); /* enforce re-enumeration, do this while interrupts are disabled! */
+ i = 0;
+ while(--i)
+ _delay_ms(2);
+ usbDeviceConnect();
+ usbInit();
+ sei();
+
+
+ leds[LED_RED].frequency = LED_ON;
+ LED_init();
+ for (i=0; i<3; i++)
+ TIMER_delay(250);
+ leds[LED_RED].frequency = LED_OFF;
+
+ while(1)
+ {
+ usbPoll();
+ LED_poll();
+ if(usbNewDeviceAddr)
+ leds[LED_BLUE].frequency = LED_ON;
+ }
+}
+
+static uchar replyBuffer[8];
+
+uint8_t usbFunctionSetup(uint8_t data[8])
+{
+ uchar len = 0;
+
+ usb_state = STATE_IDLE;
+ if(data[1] == FUNC_GET_TYPE)
+ {
+ replyBuffer[0] = 10;
+ len = 1;
+ }
+ else if(data[1] == FUNC_START_BOOTLOADER)
+ {
+ cli();
+ wdt_enable(WDTO_15MS);
+ while(1);
+ len = 0;
+ }
+ else if(data[1] == FUNC_READ_CHAIN)
+ {
+ chainpos = 0;
+ usb_state = STATE_READ;
+ len = 0xff;
+ }
+ else if(data[1] == FUNC_WRITE_CHAIN)
+ {
+ chainpos = 0;
+ usb_state = STATE_WRITE;
+ len = 0xff;
+ }
+ else if(data[1] == FUNC_TAP_STATE)
+ {
+ JTAG_goto_tap_state(data[2]);
+ len = 0;
+ }
+ else if(data[1] == FUNC_GET_TAP_STATE)
+ {
+ replyBuffer[0] = JTAG_TAP_STATE;
+ len = 1;
+ }
+ else if(data[1] == FUNC_OPEN)
+ {
+ leds[LED_BLUE].frequency = LED_ON;
+ JTAG_attatch();
+ len = 0;
+ }
+ else if(data[1] == FUNC_CLOSE)
+ {
+ leds[LED_BLUE].frequency = LED_OFF;
+ JTAG_detatch();
+ len = 0;
+ }
+ else if(data[1] == FUNC_SHIFTBITS)
+ {
+ replyBuffer[0] = JTAG_shift_bits(data[2],data[3]);
+ len = 1;
+ }
+ else if(data[1] == FUNC_CHAINSIZE)
+ {
+ replyBuffer[0] = chainpos;
+ replyBuffer[1] = chainpos>>8;
+ len = 2;
+ }
+ else if (data[1] == FUNC_EXECCHAIN)
+ {
+ /* unsigned char i;
+ for (i = 0; i < len / 2; i++)
+ {
+ unsigned char z = JTAG_CHAIN[i];
+ JTAG_CHAIN[i] = JTAG_CHAIN[len - i - 1];
+ JTAG_CHAIN[len - i - 1] = z;
+ }*/
+ JTAG_shift_bytes(JTAG_CHAIN,chainpos);
+ leds[LED_GREEN].counter = 10;
+ leds[LED_GREEN].frequency = LED_FLASH_NEG;
+ }
+ leds[LED_BLUE].counter = 10;
+ leds[LED_BLUE].frequency = LED_FLASH_NEG;
+ usbMsgPtr = replyBuffer;
+ return len;
+}
+
+uint8_t usbFunctionRead( uint8_t *data, uint8_t len )
+{
+ if (usb_state != STATE_READ)
+ return 0xff;
+ uint8_t asize = 0;
+ memcpy(data,&JTAG_CHAIN[chainpos],len);
+ chainpos += len;
+ asize+=len;
+ return asize;
+}
+
+uint8_t usbFunctionWrite( uint8_t *data, uint8_t len )
+{
+ if (usb_state != STATE_WRITE)
+ return 0xff;
+ memcpy(&JTAG_CHAIN[chainpos],data,len);
+ chainpos += len;
+ return len;
+}
diff --git a/avr/main_jtag.c.orig b/avr/main_jtag.c.orig
new file mode 100644
index 0000000..70cccb7
--- /dev/null
+++ b/avr/main_jtag.c.orig
@@ -0,0 +1,196 @@
+/************************************************************************************************
+ * Project: USB AVR-ISP
+ * Author: Christian Ulrich
+ * Contact: christian at ullihome dot de
+ *
+ * Creation Date: 2008-12-10
+ * Copyright: (c) 2008 by Christian Ulrich
+ * License: GPLv2 for private use
+ * commercial use prohibited
+ *
+ * Changes:
+ ***********************************************************************************************/
+
+#include <avr/io.h>
+#include <avr/interrupt.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <avr/pgmspace.h>
+#include <avr/eeprom.h>
+#include <util/delay.h>
+#include <avr/wdt.h>
+#include "usbdrv.h"
+#include "usbconfig.h"
+#include "led.h"
+#include "timer.h"
+#include "main.h"
+#include "jtag.h"
+
+#define FUNC_READ_CHAIN 1
+#define FUNC_WRITE_CHAIN 2
+#define FUNC_TAP_STATE 3
+#define FUNC_GET_TAP_STATE 4
+#define FUNC_OPEN 5
+#define FUNC_CLOSE 6
+#define FUNC_SHIFTBITS 7
+#define FUNC_CHAINSIZE 8
+#define FUNC_EXECCHAIN 9
+
+#define FUNC_START_BOOTLOADER 30
+#define FUNC_GET_TYPE 0xFE
+
+#define STATE_IDLE 0
+#define STATE_READ 1
+#define STATE_WRITE 2
+
+uint8_t usb_state = STATE_IDLE;
+
+#ifndef USBASP_COMPATIBLE
+led_t leds[] = {{4,LED_OFF,LED_OFF},
+ {3,LED_OFF,LED_OFF},
+ {5,LED_OFF,LED_OFF}};
+#else
+led_t leds[] = {{0,LED_OFF,LED_OFF},
+ {1,LED_OFF,LED_OFF},
+ {3,LED_OFF,LED_OFF}};
+#endif
+const uint8_t led_count = sizeof(leds)/sizeof(led_t);
+
+
+#define MAX_CHAINSIZE 900
+unsigned char JTAG_CHAIN[MAX_CHAINSIZE];
+unsigned int chainpos = 0;
+
+int main(void)
+{
+ extern uchar usbNewDeviceAddr;
+ uint8_t i;
+ PORTC |= (1<<PC2);
+//Reconnect USB
+ usbDeviceDisconnect(); /* enforce re-enumeration, do this while interrupts are disabled! */
+ i = 0;
+ while(--i)
+ _delay_ms(2);
+ usbDeviceConnect();
+ usbInit();
+ sei();
+
+
+ leds[LED_RED].frequency = LED_ON;
+ LED_init();
+ for (i=0;i<3;i++)
+ TIMER_delay(250);
+ leds[LED_RED].frequency = LED_OFF;
+
+ while(1)
+ {
+ usbPoll();
+ LED_poll();
+ if(usbNewDeviceAddr)
+ leds[LED_BLUE].frequency = LED_ON;
+ }
+}
+
+static uchar replyBuffer[8];
+
+uint8_t usbFunctionSetup(uint8_t data[8])
+{
+ uchar len = 0;
+
+ usb_state = STATE_IDLE;
+ if(data[1] == FUNC_GET_TYPE)
+ {
+ replyBuffer[0] = 10;
+ len = 1;
+ }
+ else if(data[1] == FUNC_START_BOOTLOADER)
+ {
+ cli();
+ wdt_enable(WDTO_15MS);
+ while(1);
+ len = 0;
+ }
+ else if(data[1] == FUNC_READ_CHAIN)
+ {
+ chainpos = 0;
+ usb_state = STATE_READ;
+ len = 0xff;
+ }
+ else if(data[1] == FUNC_WRITE_CHAIN)
+ {
+ chainpos = 0;
+ usb_state = STATE_WRITE;
+ len = 0xff;
+ }
+ else if(data[1] == FUNC_TAP_STATE)
+ {
+ JTAG_goto_tap_state(data[2]);
+ len = 0;
+ }
+ else if(data[1] == FUNC_GET_TAP_STATE)
+ {
+ replyBuffer[0] = JTAG_TAP_STATE;
+ len = 1;
+ }
+ else if(data[1] == FUNC_OPEN)
+ {
+ leds[LED_BLUE].frequency = LED_ON;
+ JTAG_attatch();
+ len = 0;
+ }
+ else if(data[1] == FUNC_CLOSE)
+ {
+ leds[LED_BLUE].frequency = LED_OFF;
+ JTAG_detatch();
+ len = 0;
+ }
+ else if(data[1] == FUNC_SHIFTBITS)
+ {
+ replyBuffer[0] = JTAG_shift_bits(data[2],data[3]);
+ len = 1;
+ }
+ else if(data[1] == FUNC_CHAINSIZE)
+ {
+ replyBuffer[0] = chainpos;
+ replyBuffer[1] = chainpos>>8;
+ len = 2;
+ }
+ else if (data[1] == FUNC_EXECCHAIN)
+ {
+/* unsigned char i;
+ for (i = 0; i < len / 2; i++)
+ {
+ unsigned char z = JTAG_CHAIN[i];
+ JTAG_CHAIN[i] = JTAG_CHAIN[len - i - 1];
+ JTAG_CHAIN[len - i - 1] = z;
+ }*/
+ JTAG_shift_bytes(JTAG_CHAIN,chainpos);
+ leds[LED_GREEN].counter = 10;
+ leds[LED_GREEN].frequency = LED_FLASH_NEG;
+ }
+ leds[LED_BLUE].counter = 10;
+ leds[LED_BLUE].frequency = LED_FLASH_NEG;
+ usbMsgPtr = replyBuffer;
+ return len;
+}
+
+uint8_t usbFunctionRead( uint8_t *data, uint8_t len )
+{
+ if (usb_state != STATE_READ)
+ return 0xff;
+ uint8_t asize = 0;
+ memcpy(data,&JTAG_CHAIN[chainpos],len);
+ chainpos += len;
+ asize+=len;
+ return asize;
+}
+
+uint8_t usbFunctionWrite( uint8_t *data, uint8_t len )
+{
+ if (usb_state != STATE_WRITE)
+ return 0xff;
+ memcpy(&JTAG_CHAIN[chainpos],data,len);
+ chainpos += len;
+ return len;
+}
diff --git a/usbdrv/Changelog.txt b/avr/usbdrv/Changelog.txt
index 79b5215..79b5215 100644
--- a/usbdrv/Changelog.txt
+++ b/avr/usbdrv/Changelog.txt
diff --git a/usbdrv/CommercialLicense.txt b/avr/usbdrv/CommercialLicense.txt
index de1a2b0..de1a2b0 100644
--- a/usbdrv/CommercialLicense.txt
+++ b/avr/usbdrv/CommercialLicense.txt
diff --git a/usbdrv/License.txt b/avr/usbdrv/License.txt
index 4460cfb..4460cfb 100644
--- a/usbdrv/License.txt
+++ b/avr/usbdrv/License.txt
diff --git a/usbdrv/Readme.txt b/avr/usbdrv/Readme.txt
index 970dc66..970dc66 100644
--- a/usbdrv/Readme.txt
+++ b/avr/usbdrv/Readme.txt
diff --git a/usbdrv/USB-ID-FAQ.txt b/avr/usbdrv/USB-ID-FAQ.txt
index a4a6bd6..a4a6bd6 100644
--- a/usbdrv/USB-ID-FAQ.txt
+++ b/avr/usbdrv/USB-ID-FAQ.txt
diff --git a/usbdrv/USB-IDs-for-free.txt b/avr/usbdrv/USB-IDs-for-free.txt
index d46517d..d46517d 100644
--- a/usbdrv/USB-IDs-for-free.txt
+++ b/avr/usbdrv/USB-IDs-for-free.txt
diff --git a/usbdrv/asmcommon.inc b/avr/usbdrv/asmcommon.inc
index d2a4f7c..d2a4f7c 100644
--- a/usbdrv/asmcommon.inc
+++ b/avr/usbdrv/asmcommon.inc
diff --git a/usbdrv/oddebug.c b/avr/usbdrv/oddebug.c
index 19bf142..19bf142 100644
--- a/usbdrv/oddebug.c
+++ b/avr/usbdrv/oddebug.c
diff --git a/usbdrv/oddebug.h b/avr/usbdrv/oddebug.h
index 851f84d..851f84d 100644
--- a/usbdrv/oddebug.h
+++ b/avr/usbdrv/oddebug.h
diff --git a/usbdrv/usbconfig-prototype.h b/avr/usbdrv/usbconfig-prototype.h
index 93721c2..93721c2 100644
--- a/usbdrv/usbconfig-prototype.h
+++ b/avr/usbdrv/usbconfig-prototype.h
diff --git a/usbdrv/usbconfig.h b/avr/usbdrv/usbconfig.h
index c70f9a7..073a464 100644
--- a/usbdrv/usbconfig.h
+++ b/avr/usbdrv/usbconfig.h
@@ -228,7 +228,7 @@ extern void hadUsbReset(void); // define the function for usbdrv.c
* with libusb: 0x16c0/0x5dc. Use this VID/PID pair ONLY if you understand
* the implications!
*/
-#define USB_CFG_DEVICE_ID 0xdb, 0x27 /* = 0x27db = 'keyboard' */
+#define USB_CFG_DEVICE_ID 0xdc, 0x05 /* = 0x27db = 'keyboard' */
/* This is the ID of the product, low byte first. It is interpreted in the
* scope of the vendor ID. If you have registered your own VID with usb.org
* or if you have licensed a PID from somebody else, define it here. Otherwise
@@ -252,8 +252,8 @@ extern void hadUsbReset(void); // define the function for usbdrv.c
* obdev's free shared VID/PID pair. See the file USB-IDs-for-free.txt for
* details.
*/
-#define USB_CFG_DEVICE_NAME 'R', 'o', 't', 'a', 'r', 'y', ' ', 'D', 'i', 'a', 'l'
-#define USB_CFG_DEVICE_NAME_LEN 11
+#define USB_CFG_DEVICE_NAME 'D', 'S', '1', '9', '9', '2', ' ', 'D', 'u', 'm', 'p', 'e', 'r'
+#define USB_CFG_DEVICE_NAME_LEN 13
/* Same as above for the device name. If you don't want a device name, undefine
* the macros. See the file USB-IDs-for-free.txt before you assign a name if
* you use a shared VID/PID.
@@ -267,20 +267,20 @@ extern void hadUsbReset(void); // define the function for usbdrv.c
* to fine tune control over USB descriptors such as the string descriptor
* for the serial number.
*/
-#define USB_CFG_DEVICE_CLASS 0 /* set to 0 if deferred to interface */
+#define USB_CFG_DEVICE_CLASS 0xff /* set to 0 if deferred to interface */
#define USB_CFG_DEVICE_SUBCLASS 0
/* See USB specification if you want to conform to an existing device class.
* Class 0xff is "vendor specific".
*/
-#define USB_CFG_INTERFACE_CLASS 0x03 // HID
-#define USB_CFG_INTERFACE_SUBCLASS 0x01 // Boot
-#define USB_CFG_INTERFACE_PROTOCOL 0x01 // Keyboard
+#define USB_CFG_INTERFACE_CLASS 0xff
+#define USB_CFG_INTERFACE_SUBCLASS 0x00
+#define USB_CFG_INTERFACE_PROTOCOL 0x00
/* See USB specification if you want to conform to an existing device class or
* protocol. The following classes must be set at interface level:
* HID class is 3, no subclass and protocol required (but may be useful!)
* CDC class is 2, use subclass 2 and protocol 1 for ACM
*/
-#define USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH 63
+#define USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH 0
/* Define this to the length of the HID report descriptor, if you implement
* an HID device. Otherwise don't define it or define it to 0.
* If you use this define, you must add a PROGMEM character array named
diff --git a/usbdrv/usbdrv.c b/avr/usbdrv/usbdrv.c
index d838935..d838935 100644
--- a/usbdrv/usbdrv.c
+++ b/avr/usbdrv/usbdrv.c
diff --git a/usbdrv/usbdrv.h b/avr/usbdrv/usbdrv.h
index 3fe84d5..3fe84d5 100644
--- a/usbdrv/usbdrv.h
+++ b/avr/usbdrv/usbdrv.h
diff --git a/usbdrv/usbdrvasm.S b/avr/usbdrv/usbdrvasm.S
index 32ce8ef..32ce8ef 100644
--- a/usbdrv/usbdrvasm.S
+++ b/avr/usbdrv/usbdrvasm.S
diff --git a/usbdrv/usbdrvasm.asm b/avr/usbdrv/usbdrvasm.asm
index fb66934..fb66934 100644
--- a/usbdrv/usbdrvasm.asm
+++ b/avr/usbdrv/usbdrvasm.asm
diff --git a/usbdrv/usbdrvasm12.inc b/avr/usbdrv/usbdrvasm12.inc
index d3bd056..d3bd056 100644
--- a/usbdrv/usbdrvasm12.inc
+++ b/avr/usbdrv/usbdrvasm12.inc
diff --git a/usbdrv/usbdrvasm128.inc b/avr/usbdrv/usbdrvasm128.inc
index 8f67bcc..8f67bcc 100644
--- a/usbdrv/usbdrvasm128.inc
+++ b/avr/usbdrv/usbdrvasm128.inc
diff --git a/usbdrv/usbdrvasm15.inc b/avr/usbdrv/usbdrvasm15.inc
index 33bcf0e..33bcf0e 100644
--- a/usbdrv/usbdrvasm15.inc
+++ b/avr/usbdrv/usbdrvasm15.inc
diff --git a/usbdrv/usbdrvasm16.inc b/avr/usbdrv/usbdrvasm16.inc
index 25b84e6..25b84e6 100644
--- a/usbdrv/usbdrvasm16.inc
+++ b/avr/usbdrv/usbdrvasm16.inc
diff --git a/usbdrv/usbdrvasm165.inc b/avr/usbdrv/usbdrvasm165.inc
index ae91588..ae91588 100644
--- a/usbdrv/usbdrvasm165.inc
+++ b/avr/usbdrv/usbdrvasm165.inc
diff --git a/usbdrv/usbdrvasm18-crc.inc b/avr/usbdrv/usbdrvasm18-crc.inc
index 0ff2f42..0ff2f42 100644
--- a/usbdrv/usbdrvasm18-crc.inc
+++ b/avr/usbdrv/usbdrvasm18-crc.inc
diff --git a/usbdrv/usbdrvasm20.inc b/avr/usbdrv/usbdrvasm20.inc
index 5027edd..5027edd 100644
--- a/usbdrv/usbdrvasm20.inc
+++ b/avr/usbdrv/usbdrvasm20.inc
diff --git a/usbdrv/usbportability.h b/avr/usbdrv/usbportability.h
index 0a861d0..0a861d0 100644
--- a/usbdrv/usbportability.h
+++ b/avr/usbdrv/usbportability.h
diff --git a/main.c b/main.c
deleted file mode 100644
index bad8df1..0000000
--- a/main.c
+++ /dev/null
@@ -1,312 +0,0 @@
-/*
- Project: Rotary-Dial-To-USB Interface
- Author: Florian Jung (flo@windfisch.org)
- Copyright: (c) 2014 by Florian Jung and partially others (see below)
- License: GNU GPL v3 (see LICENSE)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License version 3 as
- published by the Free Software Foundation.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-
- This project is based on the code for the AVR ATtiny USB Tutorial at
- http://codeandlife.com/ by Joonas Pihlajamaa, joonas.pihlajamaa@iki.fi,
- which is in turn based on the V-USB example code by Christian Starkjohann
- (Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH)
-*/
-
-#include <avr/io.h>
-#include <avr/interrupt.h>
-#include <avr/wdt.h>
-#include <avr/eeprom.h>
-#include <util/delay.h>
-
-#include "usbdrv/usbdrv.h"
-
-// ************************
-// *** USB HID ROUTINES ***
-// ************************
-
-// From Frank Zhao's USB Business Card project
-// http://www.frank-zhao.com/cache/usbbusinesscard_details.php
-PROGMEM const char
- usbHidReportDescriptor[USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH] = {
- 0x05, 0x01, // USAGE_PAGE (Generic Desktop)
- 0x09, 0x06, // USAGE (Keyboard)
- 0xa1, 0x01, // COLLECTION (Application)
- 0x75, 0x01, // REPORT_SIZE (1)
- 0x95, 0x08, // REPORT_COUNT (8)
- 0x05, 0x07, // USAGE_PAGE (Keyboard)(Key Codes)
- 0x19, 0xe0, // USAGE_MINIMUM (Keyboard LeftControl)(224)
- 0x29, 0xe7, // USAGE_MAXIMUM (Keyboard Right GUI)(231)
- 0x15, 0x00, // LOGICAL_MINIMUM (0)
- 0x25, 0x01, // LOGICAL_MAXIMUM (1)
- 0x81, 0x02, // INPUT (Data,Var,Abs) ; Modifier byte
- 0x95, 0x01, // REPORT_COUNT (1)
- 0x75, 0x08, // REPORT_SIZE (8)
- 0x81, 0x03, // INPUT (Cnst,Var,Abs) ; Reserved byte
- 0x95, 0x05, // REPORT_COUNT (5)
- 0x75, 0x01, // REPORT_SIZE (1)
- 0x05, 0x08, // USAGE_PAGE (LEDs)
- 0x19, 0x01, // USAGE_MINIMUM (Num Lock)
- 0x29, 0x05, // USAGE_MAXIMUM (Kana)
- 0x91, 0x02, // OUTPUT (Data,Var,Abs) ; LED report
- 0x95, 0x01, // REPORT_COUNT (1)
- 0x75, 0x03, // REPORT_SIZE (3)
- 0x91, 0x03, // OUTPUT (Cnst,Var,Abs) ; LED report padding
- 0x95, 0x06, // REPORT_COUNT (6)
- 0x75, 0x08, // REPORT_SIZE (8)
- 0x15, 0x00, // LOGICAL_MINIMUM (0)
- 0x25, 0x65, // LOGICAL_MAXIMUM (101)
- 0x05, 0x07, // USAGE_PAGE (Keyboard)(Key Codes)
- 0x19, 0x00, // USAGE_MINIMUM (Reserved (no event indicated))(0)
- 0x29, 0x65, // USAGE_MAXIMUM (Keyboard Application)(101)
- 0x81, 0x00, // INPUT (Data,Ary,Abs)
- 0xc0 // END_COLLECTION
-};
-
-typedef struct
-{
- uint8_t modifier;
- uint8_t reserved;
- uint8_t keycode[6];
-} keyboard_report_t;
-
-static keyboard_report_t keyboard_report; // sent to PC
-volatile static uchar LED_state = 0xff; // received from PC
-static uchar idleRate; // repeat rate for keyboards
-
-
-#define LED_BLUE (1<<5)
-#define LED_RED (1<<4)
-#define LED_GREEN (1<<3)
-
-usbMsgLen_t usbFunctionSetup(uchar data[8])
-{
- usbRequest_t *rq = (void *) data;
-
- if ((rq->bmRequestType & USBRQ_TYPE_MASK) == USBRQ_TYPE_CLASS)
- {
- switch (rq->bRequest)
- {
- case USBRQ_HID_GET_REPORT: // send "no keys pressed" if asked here
- // wValue: ReportType (highbyte), ReportID (lowbyte)
- usbMsgPtr = (void *) &keyboard_report; // we only have this one
- keyboard_report.modifier = 0;
- keyboard_report.keycode[0] = 0;
- return sizeof(keyboard_report);
-
- case USBRQ_HID_SET_REPORT: // if wLength == 1, should be LED state
- return (rq->wLength.word == 1) ? USB_NO_MSG : 0;
-
- case USBRQ_HID_GET_IDLE: // send idle rate to PC as required by spec
- usbMsgPtr = &idleRate;
- return 1;
-
- case USBRQ_HID_SET_IDLE: // save idle rate as required by spec
- idleRate = rq->wValue.bytes[1];
- return 0;
- }
- }
-
- return 0; // by default don't return any data
-}
-
-usbMsgLen_t usbFunctionWrite(uint8_t * data, uchar len)
-{
- if (data[0] == LED_state)
- return 1;
- else
- LED_state = data[0];
-
- return 1; // Data read, not expecting more
-}
-
-// Now only supports letters 'a' to 'z' and 0 (NULL) to clear buttons
-void buildReport(int n)
-{
- keyboard_report.modifier = 0;
-
- if (n > 0 && n <= 10)
- keyboard_report.keycode[0] = 29+n;
- else if (n == 0)
- keyboard_report.keycode[0] = 39;
- else if (n == -2)
- keyboard_report.keycode[0] = 40; // enter
- else if (n == -1)
- keyboard_report.keycode[0] = 0;
-}
-
-#define STATE_WAIT 0
-#define STATE_SEND_KEY 1
-#define STATE_RELEASE_KEY 2
-
-void jump_to_bootloader(void)
-{
- cli();
- wdt_enable(WDTO_15MS);
- while (1);
-}
-
-
-#define DEBOUNCE_MAX 100
-uint8_t idle_stable = 42;
-uint8_t pulse_stable = 42;
-uint16_t idlectr = DEBOUNCE_MAX;
-uint16_t pulsectr = DEBOUNCE_MAX;
-
-uint8_t oldidle = 42;
-uint8_t oldpulse = 42;
-
-int main()
-{
- int key_to_send;
- int n_pulses = 0;
-
- uchar i, button_release_counter = 0, state = STATE_WAIT;
-
- DDRC = 0x38; // LEDs as output
- PORTC |= LED_BLUE | LED_RED | LED_GREEN;
- DDRD &= ~0xF3; // connector ports as input
- DDRB &= ~0x3C;
- PORTD &= ~0xF3; // disable pullups for unused ports
- PORTB &= ~0x0C;
- PORTB |= 0x30; // enable pullups for PB4 and 5
-
- cli();
-
- for (i = 0; i < sizeof(keyboard_report); i++) // clear report initially
- ((uchar *) & keyboard_report)[i] = 0;
-
- wdt_enable(WDTO_1S); // enable 1s watchdog timer
-
- usbInit();
-
- usbDeviceDisconnect(); // enforce re-enumeration
- for (i = 0; i < 250; i++)
- { // wait 500 ms
- wdt_reset(); // keep the watchdog happy
- _delay_ms(10);
- }
- usbDeviceConnect();
-
- sei(); // Enable interrupts after re-enumeration
- uint32_t j;
-
- while (1)
- {
- wdt_reset(); // keep the watchdog happy
- usbPoll();
-
-
- // characters are sent when messageState == STATE_SEND and after receiving
- // the initial LED state from PC (good way to wait until device is recognized)
-
- int idle = (PINB & 0x10);
- int pulse = (PINB & 0x20);
-
- if (idle != idle_stable)
- {
- idlectr++;
- if (idlectr > DEBOUNCE_MAX)
- idle_stable = idle;
- }
- else
- idlectr=0;
-
- if (pulse != pulse_stable)
- {
- pulsectr++;
- if (pulsectr > DEBOUNCE_MAX)
- pulse_stable = pulse;
- }
- else
- pulsectr=0;
-
- if (pulse_stable)
- PORTC &= ~LED_RED;
- else
- PORTC |= LED_RED;
-
- if (idle_stable)
- PORTC |= LED_GREEN;
- else
- PORTC &= ~LED_GREEN;
-
-
- if (oldidle == 42) // init
- {
- oldidle = idle_stable;
- oldpulse = pulse_stable;
- }
-
- if (oldidle && !idle_stable)
- n_pulses = 0;
-
- if (!oldidle == 0 && idle_stable)
- {
- if (n_pulses > 17)
- jump_to_bootloader();
-
- // also check if some time has elapsed since last button press
- if (state == STATE_WAIT && button_release_counter == 255)
- {
- if (n_pulses >= 1 && n_pulses <=10)
- {
- state = STATE_SEND_KEY;
- key_to_send = n_pulses;
- }
- }
-
- button_release_counter = 0; // now button needs to be released a while until retrigger
-
- }
-
- if (!oldpulse && pulse_stable)
- n_pulses++;
-
- oldidle = idle_stable;
- oldpulse = pulse_stable;
-
-
- if (button_release_counter < 255)
- button_release_counter++; // increase release counter
-
-
-
- if (usbInterruptIsReady() && state != STATE_WAIT && LED_state != 0xff)
- {
- switch (state)
- {
- case STATE_SEND_KEY:
- buildReport(key_to_send);
- state = STATE_RELEASE_KEY; // release next
- PORTC &= ~LED_BLUE;
- break;
-
- case STATE_RELEASE_KEY:
- buildReport(-1);
- state = STATE_WAIT; // go back to waiting
- PORTC |= LED_BLUE;
- break;
-
- default:
- state = STATE_WAIT; // should not happen
- }
-
- // start sending
- usbSetInterrupt((void *) &keyboard_report, sizeof(keyboard_report));
- }
- }
-
- jump_to_bootloader();
- return 0;
-}
diff --git a/pc/a.out b/pc/a.out
new file mode 100755
index 0000000..f1b6c1b
--- /dev/null
+++ b/pc/a.out
Binary files differ
diff --git a/pc/main.c b/pc/main.c
new file mode 100644
index 0000000..fe0d75d
--- /dev/null
+++ b/pc/main.c
@@ -0,0 +1,134 @@
+/* Name: set-led.c
+ * Project: custom-class, a basic USB example
+ * 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)
+ */
+
+/*
+General Description:
+This is the host-side driver for the custom-class example device. It searches
+the USB for the LEDControl device and sends the requests understood by this
+device.
+This program must be linked with libusb on Unix and libusb-win32 on Windows.
+See http://libusb.sourceforge.net/ or http://libusb-win32.sourceforge.net/
+respectively.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <usb.h> /* this is libusb */
+#include "opendevice.h" /* common code moved to separate module */
+
+#include "../firmware/requests.h" /* custom request numbers */
+#include "../firmware/usbconfig.h" /* device's VID/PID and names */
+
+static void usage(char *name)
+{
+ fprintf(stderr, "usage:\n");
+ fprintf(stderr, " %s on ....... turn on LED\n", name);
+ fprintf(stderr, " %s off ...... turn off LED\n", name);
+ fprintf(stderr, " %s status ... ask current status of LED\n", name);
+#if ENABLE_TEST
+ fprintf(stderr, " %s test ..... run driver reliability test\n", name);
+#endif /* ENABLE_TEST */
+}
+
+int main(int argc, char **argv)
+{
+usb_dev_handle *handle = NULL;
+const unsigned char rawVid[2] = {USB_CFG_VENDOR_ID}, rawPid[2] = {USB_CFG_DEVICE_ID};
+char vendor[] = {USB_CFG_VENDOR_NAME, 0}, product[] = {USB_CFG_DEVICE_NAME, 0};
+char buffer[4];
+int cnt, vid, pid, isOn;
+
+ usb_init();
+ if(argc < 2){ /* we need at least one argument */
+ usage(argv[0]);
+ exit(1);
+ }
+ /* compute VID/PID from usbconfig.h so that there is a central source of information */
+ vid = rawVid[1] * 256 + rawVid[0];
+ pid = rawPid[1] * 256 + rawPid[0];
+ /* The following function is in opendevice.c: */
+ if(usbOpenDevice(&handle, vid, vendor, pid, product, NULL, NULL, NULL) != 0){
+ fprintf(stderr, "Could not find USB device \"%s\" with vid=0x%x pid=0x%x\n", product, vid, pid);
+ exit(1);
+ }
+ /* Since we use only control endpoint 0, we don't need to choose a
+ * configuration and interface. Reading device descriptor and setting a
+ * configuration and interface is done through endpoint 0 after all.
+ * However, newer versions of Linux require that we claim an interface
+ * even for endpoint 0. Enable the following code if your operating system
+ * needs it: */
+#if 0
+ int retries = 1, usbConfiguration = 1, usbInterface = 0;
+ if(usb_set_configuration(handle, usbConfiguration) && showWarnings){
+ 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((len = usb_claim_interface(handle, usbInterface)) != 0 && retries-- > 0){
+#ifdef LIBUSB_HAS_DETACH_KERNEL_DRIVER_NP
+ if(usb_detach_kernel_driver_np(handle, 0) < 0 && showWarnings){
+ fprintf(stderr, "Warning: could not detach kernel driver: %s\n", usb_strerror());
+ }
+#endif
+ }
+#endif
+
+ if(strcasecmp(argv[1], "status") == 0){
+ cnt = usb_control_msg(handle, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN, CUSTOM_RQ_GET_STATUS, 0, 0, buffer, sizeof(buffer), 5000);
+ if(cnt < 1){
+ if(cnt < 0){
+ fprintf(stderr, "USB error: %s\n", usb_strerror());
+ }else{
+ fprintf(stderr, "only %d bytes received.\n", cnt);
+ }
+ }else{
+ printf("LED is %s\n", buffer[0] ? "on" : "off");
+ }
+ }else if((isOn = (strcasecmp(argv[1], "on") == 0)) || strcasecmp(argv[1], "off") == 0){
+ cnt = usb_control_msg(handle, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_OUT, CUSTOM_RQ_SET_STATUS, isOn, 0, buffer, 0, 5000);
+ if(cnt < 0){
+ fprintf(stderr, "USB error: %s\n", usb_strerror());
+ }
+#if ENABLE_TEST
+ }else if(strcasecmp(argv[1], "test") == 0){
+ int i;
+ srandomdev();
+ for(i = 0; i < 50000; i++){
+ int value = random() & 0xffff, index = random() & 0xffff;
+ int rxValue, rxIndex;
+ if((i+1) % 100 == 0){
+ fprintf(stderr, "\r%05d", i+1);
+ fflush(stderr);
+ }
+ cnt = usb_control_msg(handle, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN, CUSTOM_RQ_ECHO, value, index, buffer, sizeof(buffer), 5000);
+ if(cnt < 0){
+ fprintf(stderr, "\nUSB error in iteration %d: %s\n", i, usb_strerror());
+ break;
+ }else if(cnt != 4){
+ fprintf(stderr, "\nerror in iteration %d: %d bytes received instead of 4\n", i, cnt);
+ break;
+ }
+ rxValue = ((int)buffer[0] & 0xff) | (((int)buffer[1] & 0xff) << 8);
+ rxIndex = ((int)buffer[2] & 0xff) | (((int)buffer[3] & 0xff) << 8);
+ if(rxValue != value || rxIndex != index){
+ fprintf(stderr, "\ndata error in iteration %d:\n", i);
+ fprintf(stderr, "rxValue = 0x%04x value = 0x%04x\n", rxValue, value);
+ fprintf(stderr, "rxIndex = 0x%04x index = 0x%04x\n", rxIndex, index);
+ }
+ }
+ fprintf(stderr, "\nTest completed.\n");
+#endif /* ENABLE_TEST */
+ }else{
+ usage(argv[0]);
+ exit(1);
+ }
+ usb_close(handle);
+ return 0;
+}
diff --git a/pc/usbtest.c b/pc/usbtest.c
new file mode 100644
index 0000000..002add4
--- /dev/null
+++ b/pc/usbtest.c
@@ -0,0 +1,199 @@
+/**
+ * Project: AVR ATtiny USB Tutorial at http://codeandlife.com/
+ * Author: Joonas Pihlajamaa, joonas.pihlajamaa@iki.fi
+ * Based on V-USB example code by Christian Starkjohann
+ * Copyright: (C) 2012 by Joonas Pihlajamaa
+ * License: GNU GPL v3 (see License.txt)
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <usb.h>
+
+// used to get descriptor strings for device identification
+static int usbGetDescriptorString(usb_dev_handle *dev, int index, int langid,
+ char *buf, int buflen)
+{
+ char buffer[256];
+ int rval, i;
+
+ // make standard request GET_DESCRIPTOR, type string and given index
+ // (e.g. dev->iProduct)
+ rval = usb_control_msg(dev,
+ USB_TYPE_STANDARD | USB_RECIP_DEVICE | USB_ENDPOINT_IN,
+ USB_REQ_GET_DESCRIPTOR, (USB_DT_STRING << 8) + index, langid,
+ buffer, sizeof(buffer), 1000);
+
+ if(rval < 0) // error
+ return rval;
+
+ // rval should be bytes read, but buffer[0] contains the actual response size
+ if((unsigned char)buffer[0] < rval)
+ rval = (unsigned char)buffer[0]; // string is shorter than bytes read
+
+ if(buffer[1] != USB_DT_STRING) // second byte is the data type
+ return 0; // invalid return type
+
+ // we're dealing with UTF-16LE here so actual chars is half of rval,
+ // and index 0 doesn't count
+ rval /= 2;
+
+ // lossy conversion to ISO Latin1
+ for(i = 1; i < rval && i < buflen; i++)
+ {
+ if(buffer[2 * i + 1] == 0)
+ buf[i-1] = buffer[2 * i];
+ else
+ buf[i-1] = '?'; // outside of ISO Latin1 range
+ }
+ buf[i-1] = 0;
+
+ return i-1;
+}
+
+static usb_dev_handle * usbOpenDevice(int vendor, char *vendorName,
+ int product, char *productName)
+{
+ struct usb_bus *bus;
+ struct usb_device *dev;
+ char devVendor[256], devProduct[256];
+
+ usb_dev_handle * handle = NULL;
+
+ usb_set_debug(3);
+
+ usb_init();
+ 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)
+ continue;
+
+ // we need to open the device in order to query strings
+ if(!(handle = usb_open(dev)))
+ {
+ fprintf(stderr, "Warning: cannot open USB device: %s\n",
+ usb_strerror());
+ continue;
+ }
+
+ // get vendor name
+ if(usbGetDescriptorString(handle, dev->descriptor.iManufacturer, 0x0409, devVendor, sizeof(devVendor)) < 0)
+ {
+ fprintf(stderr,
+ "Warning: cannot query manufacturer for device: %s\n",
+ usb_strerror());
+ usb_close(handle);
+ continue;
+ }
+
+ // get product name
+ if(usbGetDescriptorString(handle, dev->descriptor.iProduct,
+ 0x0409, devProduct, sizeof(devVendor)) < 0)
+ {
+ fprintf(stderr,
+ "Warning: cannot query product for device: %s\n",
+ usb_strerror());
+ usb_close(handle);
+ continue;
+ }
+
+ if(strcmp(devVendor, vendorName) == 0 &&
+ strcmp(devProduct, productName) == 0)
+ return handle;
+ else
+ usb_close(handle);
+ }
+ }
+
+ return NULL;
+}
+
+int main(int argc, char **argv)
+{
+ usb_dev_handle *handle = NULL;
+ int nBytes = 0;
+ char buffer[256];
+
+ handle = usbOpenDevice(0x16C0, "windfisch.org", 0x05DC, "DS1992 Dumper");
+
+ if(handle == NULL)
+ {
+ fprintf(stderr, "Could not find USB device!\n");
+ exit(1);
+ }
+
+ printf("got device\n");
+
+ // read from device
+ nBytes = usb_control_msg(handle,
+ USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN,
+ 0x21, 0, 0, (char *)buffer, sizeof(buffer), 1000);
+ printf("Got %d bytes: %s;\n", nBytes, buffer);
+
+ // write to device
+ nBytes = usb_control_msg(handle,
+ USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_OUT,
+ 0x42, 0, 0, "Tschuess", strlen("Tschuess"), 1000);
+ printf("Wrote %d bytes\n", nBytes);
+
+
+
+
+ // read from device
+ nBytes = usb_control_msg(handle,
+ USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN,
+ 0x21, 0, 0, (char *)buffer, sizeof(buffer), 1000);
+ printf("Got %d bytes: %s;\n", nBytes, buffer);
+
+/*
+
+ nBytes = usb_control_msg(handle,
+ USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN,
+ 0x42, 0,0,
+ (char *)buffer, sizeof(buffer), 5000);
+ if(strcmp(argv[1], "on") == 0)
+ {
+ nBytes = usb_control_msg(handle,
+ USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN,
+ USB_LED_ON, 0, 0, (char *)buffer, sizeof(buffer), 5000);
+ }
+ else if(strcmp(argv[1], "off") == 0)
+ {
+ nBytes = usb_control_msg(handle,
+ USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN,
+ USB_LED_OFF, 0, 0, (char *)buffer, sizeof(buffer), 5000);
+ }
+ else if(strcmp(argv[1], "out") == 0)
+ {
+ nBytes = usb_control_msg(handle,
+ USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN,
+ USB_DATA_OUT, 0, 0, (char *)buffer, sizeof(buffer), 5000);
+ printf("Got %d bytes: %s\n", nBytes, buffer);
+ }
+ else if(strcmp(argv[1], "write") == 0)
+ {
+ nBytes = usb_control_msg(handle,
+ USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN,
+ USB_DATA_WRITE, 'T' + ('E' << 8), 'S' + ('T' << 8),
+ (char *)buffer, sizeof(buffer), 5000);
+ }
+ else if(strcmp(argv[1], "in") == 0 && argc > 2)
+ {
+ nBytes = usb_control_msg(handle,
+ USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_OUT,
+ USB_DATA_IN, 0, 0, argv[2], strlen(argv[2])+1, 5000);
+ }
+*/
+ if(nBytes < 0)
+ fprintf(stderr, "USB error: %s\n", usb_strerror());
+
+ usb_close(handle);
+
+ return 0;
+}