diff options
-rw-r--r-- | avr/1wire.c | 130 | ||||
-rw-r--r-- | avr/1wire.h | 27 | ||||
-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.c | 164 | ||||
-rw-r--r-- | avr/main_jtag.c | 198 | ||||
-rw-r--r-- | avr/main_jtag.c.orig | 196 | ||||
-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.c | 312 | ||||
-rwxr-xr-x | pc/a.out | bin | 0 -> 12696 bytes | |||
-rw-r--r-- | pc/main.c | 134 | ||||
-rw-r--r-- | pc/usbtest.c | 199 |
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 @@ -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/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 @@ -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 Binary files differnew file mode 100755 index 0000000..f1b6c1b --- /dev/null +++ b/pc/a.out 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; +} |