├── apple_codes.c ├── assets └── image.jpg ├── kbrd_codes.h ├── main.c ├── main.h ├── makefile ├── nec_defaults.h ├── readme.md ├── usbconfig.h ├── usbdrv ├── Changelog.txt ├── CommercialLicense.txt ├── License.txt ├── Readme.txt ├── USB-ID-FAQ.txt ├── USB-IDs-for-free.txt ├── asmcommon.inc ├── oddebug.c ├── oddebug.h ├── usbconfig-prototype.h ├── usbdrv.c ├── usbdrv.h ├── usbdrvasm.S ├── usbdrvasm.asm ├── usbdrvasm12.inc ├── usbdrvasm128.inc ├── usbdrvasm15.inc ├── usbdrvasm16.inc ├── usbdrvasm165.inc ├── usbdrvasm18-crc.inc ├── usbdrvasm20.inc └── usbportability.h ├── usr_prog.c └── xbmc_keys.h /apple_codes.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define APPLECODE_ID 0x87EE // this was discovered by experimentation 5 | 6 | static uint32_t apple_code_check(uint32_t ircode) 7 | { 8 | if ((ircode & 0xFFFF) != APPLECODE_ID) // doesn't match means not Apple 9 | { 10 | return 0; 11 | } 12 | 13 | //ircode &= 0x00FF0000; 14 | ircode >>= 16; // just makes the switch case more efficient 15 | uint8_t c = ircode; 16 | switch (c) 17 | { 18 | // discovered by experimentation 19 | case 0x0A: 20 | return BUT_APPLE_UP; 21 | case 0x0C: 22 | return BUT_APPLE_DOWN; 23 | case 0x09: 24 | return BUT_APPLE_LEFT; 25 | case 0x06: 26 | return BUT_APPLE_RIGHT; 27 | case 0x5F: 28 | return BUT_APPLE_PLAYPAUSE; 29 | case 0x03: 30 | return BUT_APPLE_MENU; 31 | case 0x5C: 32 | return BUT_APPLE_SELECT; 33 | default: 34 | return 0; 35 | } 36 | } -------------------------------------------------------------------------------- /assets/image.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adafruit/IRKey/44ea72a1142ae43aea40ccf8c77d674704ffc945/assets/image.jpg -------------------------------------------------------------------------------- /kbrd_codes.h: -------------------------------------------------------------------------------- 1 | #ifndef KBRD_CODES_H 2 | #define KBRD_CODES_H 3 | 4 | // obtained from USB HID keyboard usage table 5 | // bits 0-7 is the report ID, multimedia keys have ID=2, normal keys have ID=1, sysctrl=3, mouse=4 6 | // bits 8-15 is the modifier for normal keys 7 | // bits 16-23 is reserved 8 | // bits 24-31 is the keycode 9 | 10 | #define KEYCODE_KB_VOL_UP 0x8002 // do not use 11 | #define KEYCODE_KB_VOL_DOWN 0x8102 // do not use 12 | #define KEYCODE_VOL_UP 0xE902 13 | #define KEYCODE_VOL_DOWN 0xEA02 14 | #define KEYCODE_SCAN_NEXT_TRACK 0xB502 15 | #define KEYCODE_SCAN_PREV_TRACK 0xB602 16 | #define KEYCODE_STOP 0xB702 17 | #define KEYCODE_PLAYPAUSE 0xCD02 18 | #define KEYCODE_MUTE 0xE202 19 | #define KEYCODE_BASSBOOST 0xE502 20 | #define KEYCODE_LOUDNESS 0xE702 21 | #define KEYCODE_ENTER 0x28000001 22 | #define KEYCODE_BACKSPACE 0x2A000001 23 | #define KEYCODE_ESC 0x29000001 24 | #define KEYCODE_TAB 0x2B000001 25 | #define KEYCODE_SPACE 0x2C000001 26 | #define KEYCODE_INSERT 0x49000001 27 | #define KEYCODE_HOME 0x4A000001 28 | #define KEYCODE_PAGE_UP 0x4B000001 29 | #define KEYCODE_DELETE 0x4C000001 30 | #define KEYCODE_END 0x4D000001 31 | #define KEYCODE_PAGE_DOWN 0x4E000001 32 | #define KEYCODE_PRINTSCREEN 0x46000001 33 | #define KEYCODE_ARROW_RIGHT 0x4F000001 34 | #define KEYCODE_ARROW_LEFT 0x50000001 35 | #define KEYCODE_ARROW_DOWN 0x51000001 36 | #define KEYCODE_ARROW_UP 0x52000001 37 | #define KEYCODE_KB_EXECUTE 0x7402 38 | #define KEYCODE_KB_HELP 0x7502 39 | #define KEYCODE_KB_MENU 0x7602 40 | #define KEYCODE_KB_SELECT 0x7702 41 | #define KEYCODE_KB_STOP 0x7802 42 | #define KEYCODE_KB_AGAIN 0x7902 43 | #define KEYCODE_KB_UNDO 0x7A02 44 | #define KEYCODE_KB_CUT 0x7B02 45 | #define KEYCODE_KB_COPY 0x7C02 46 | #define KEYCODE_KB_PASTE 0x7D02 47 | #define KEYCODE_KB_FIND 0x7E02 48 | #define KEYCODE_KB_MUTE 0x7F02 // do not use 49 | #define KEYCODE_1 0x1E000001 50 | #define KEYCODE_2 0x1F000001 51 | #define KEYCODE_3 0x20000001 52 | #define KEYCODE_4 0x21000001 53 | #define KEYCODE_5 0x22000001 54 | #define KEYCODE_6 0x23000001 55 | #define KEYCODE_7 0x24000001 56 | #define KEYCODE_8 0x25000001 57 | #define KEYCODE_9 0x26000001 58 | #define KEYCODE_0 0x27000001 59 | #define KEYCODE_A 0x04000001 60 | #define KEYCODE_B 0x05000001 61 | #define KEYCODE_C 0x06000001 62 | #define KEYCODE_D 0x07000001 63 | #define KEYCODE_E 0x08000001 64 | #define KEYCODE_F 0x09000001 65 | #define KEYCODE_G 0x0A000001 66 | #define KEYCODE_H 0x0B000001 67 | #define KEYCODE_I 0x0C000001 68 | #define KEYCODE_J 0x0D000001 69 | #define KEYCODE_K 0x0E000001 70 | #define KEYCODE_L 0x0F000001 71 | #define KEYCODE_M 0x10000001 72 | #define KEYCODE_N 0x11000001 73 | #define KEYCODE_O 0x12000001 74 | #define KEYCODE_P 0x13000001 75 | #define KEYCODE_Q 0x14000001 76 | #define KEYCODE_R 0x15000001 77 | #define KEYCODE_S 0x16000001 78 | #define KEYCODE_T 0x17000001 79 | #define KEYCODE_U 0x18000001 80 | #define KEYCODE_V 0x19000001 81 | #define KEYCODE_W 0x1A000001 82 | #define KEYCODE_X 0x1B000001 83 | #define KEYCODE_Y 0x1C000001 84 | #define KEYCODE_Z 0x1D000001 85 | #define KEYCODE_COMMA 0x36000001 86 | #define KEYCODE_PERIOD 0x37000001 87 | #define KEYCODE_MINUS 0x2D000001 88 | #define KEYCODE_EQUAL 0x2E000001 89 | #define KEYCODE_BACKSLASH 0x31000001 90 | #define KEYCODE_SQBRAK_LEFT 0x2F000001 91 | #define KEYCODE_SQBRAK_RIGHT 0x30000001 92 | #define KEYCODE_SLASH 0x38000001 93 | #define KEYCODE_F1 0x3A000001 94 | #define KEYCODE_F2 0x3B000001 95 | #define KEYCODE_F3 0x3C000001 96 | #define KEYCODE_F4 0x3D000001 97 | #define KEYCODE_F5 0x3E000001 98 | #define KEYCODE_F6 0x3F000001 99 | #define KEYCODE_F7 0x40000001 100 | #define KEYCODE_F8 0x41000001 101 | #define KEYCODE_F9 0x42000001 102 | #define KEYCODE_F10 0x43000001 103 | #define KEYCODE_F11 0x44000001 104 | #define KEYCODE_F12 0x45000001 105 | #define KEYCODE_APP 0x65000001 106 | #define KEYCODE_SYS_POWER 0x0103 107 | #define KEYCODE_SYS_SLEEP 0x0203 108 | #define KEYCODE_SYS_WAKE 0x0303 109 | #define KEYCODE_LEFT_CONTROL 0xE0000001 110 | #define KEYCODE_LEFT_SHIFT 0xE1000001 111 | #define KEYCODE_LEFT_ALT 0xE2000001 112 | #define KEYCODE_LEFT_GUI 0xE3000001 113 | #define KEYCODE_RIGHT_CONTROL 0xE4000001 114 | #define KEYCODE_RIGHT_SHIFT 0xE5000001 115 | #define KEYCODE_RIGHT_ALT 0xE6000001 116 | #define KEYCODE_RIGHT_GUI 0xE7000001 117 | #define KEYCODE_MOD_LEFT_CONTROL 0x0101 118 | #define KEYCODE_MOD_LEFT_SHIFT 0x0201 119 | #define KEYCODE_MOD_LEFT_ALT 0x0401 120 | #define KEYCODE_MOD_LEFT_GUI 0x0801 121 | #define KEYCODE_MOD_RIGHT_CONTROL 0x1001 122 | #define KEYCODE_MOD_RIGHT_SHIFT 0x2001 123 | #define KEYCODE_MOD_RIGHT_ALT 0x4001 124 | #define KEYCODE_MOD_RIGHT_GUI 0x8001 125 | 126 | #define MOUSECODE_UP 0x80000004 127 | #define MOUSECODE_DOWN 0x7F000004 128 | #define MOUSECODE_LEFT 0x00800004 129 | #define MOUSECODE_RIGHT 0x007F0004 130 | #define MOUSECODE_BUT_RIGHT 0x00000104 131 | #define MOUSECODE_BUT_MIDDLE 0x00000204 132 | #define MOUSECODE_BUT_LEFT 0x00000404 133 | // well since we are cheating by using uint32_t instead of a struct, we can't fit the mouse wheel in here 134 | 135 | #endif -------------------------------------------------------------------------------- /main.h: -------------------------------------------------------------------------------- 1 | #ifndef main_h 2 | #define main_h 3 | 4 | #include 5 | #include 6 | #include // descriptor must be stored in flash memory 7 | 8 | #include "kbrd_codes.h" 9 | #include "xbmc_keys.h" 10 | #include "nec_defaults.h" 11 | 12 | // compilation settings check 13 | #if defined(__AVR_ATtiny85__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny25__) 14 | #if F_CPU != 16500000 15 | #error "ATtiny MCU used but not at 16.5 MHz" 16 | #endif 17 | #else 18 | #if F_CPU != 12000000 19 | #error "Clock speed is not 12 MHz" 20 | #endif 21 | #endif 22 | 23 | // hardware pin mapping 24 | #define IN_PORTx PORTB 25 | #define IN_DDRx DDRB 26 | #define IN_PINx PINB 27 | #define IN_PINNUM 2 28 | #define IN_PINMASK _BV(IN_PINNUM) 29 | #define JMP_PORTx PORTB 30 | #define JMP_DDRx DDRB 31 | #define JMP_PINx PINB 32 | #define JMP_PINNUM 1 33 | #define JMP_PINMASK _BV(JMP_PINNUM) 34 | #define LED_PORTx PORTB 35 | #define LED_DDRx DDRB 36 | #define LED_PINx PINB 37 | #define LED_PINNUM 0 38 | #define LED_PINMASK _BV(LED_PINNUM) 39 | 40 | // timing constants 41 | #if (F_CPU == 12000000) 42 | #define PULSEWIDTH_INITIAL_9MS 100 43 | #define PULSEWIDTH_ON_MIN 3 44 | #define PULSEWIDTH_BIT_THRESHOLD 13 // 1125 us 45 | #define PULSEWIDTH_2MS 23 46 | #define PULSEWIDTH_3MS 35 47 | #define PULSEWIDTH_4MS 47 48 | #define PULSEWIDTH_5MS 59 49 | #define TMR1_TIMEOUT_90MS 67 50 | #define TMR1_TIMEOUT_120MS 90 51 | #define TMR1_TIMEOUT_3S 9 52 | #define TMR1_TIMEOUT_5S 15 53 | #elif (F_CPU == 16500000) 54 | #define PULSEWIDTH_INITIAL_9MS 137 55 | #define PULSEWIDTH_ON_MIN 4 56 | #define PULSEWIDTH_BIT_THRESHOLD 18 // 1125 us 57 | #define PULSEWIDTH_2MS 32 58 | #define PULSEWIDTH_3MS 48 59 | #define PULSEWIDTH_4MS 65 60 | #define PULSEWIDTH_5MS 81 61 | #define TMR1_TIMEOUT_90MS 90 62 | #define TMR1_TIMEOUT_120MS 120 63 | #define TMR1_TIMEOUT_3S 12 64 | #define TMR1_TIMEOUT_5S 20 65 | #endif 66 | 67 | // data structure for boot protocol keyboard report 68 | // see HID1_11.pdf appendix B section 1 69 | typedef struct { 70 | uint8_t report_id; 71 | uint8_t modifier; 72 | uint8_t reserved; 73 | uint8_t keycode[5]; 74 | } keyboard_report_t; 75 | 76 | // result return codes for ir_cap() 77 | typedef enum 78 | { 79 | IRCAP_NOTHING, 80 | IRCAP_BUSY, 81 | IRCAP_NEWKEY, 82 | IRCAP_REPEATKEY, 83 | IRCAP_ERROR 84 | } 85 | ircap_res_t; 86 | 87 | typedef struct 88 | { 89 | const uint32_t c; 90 | const char* s; 91 | } 92 | code_desc_t; 93 | 94 | ircap_res_t ir_cap(uint32_t*); 95 | void usbPollWrapper(); 96 | uint32_t ir_to_kb(uint32_t); 97 | uint32_t usr_ir_to_kb(uint32_t); 98 | void usr_prog(); 99 | 100 | #endif -------------------------------------------------------------------------------- /makefile: -------------------------------------------------------------------------------- 1 | ################################## 2 | ## Makefile for project: IR-Keyboard, for Adafruit Industries, by Frank Zhao 3 | ################################## 4 | 5 | ## General Flags 6 | PROJECT = irkeyboard 7 | MCU = attiny85 8 | BURNMCU = attiny85 9 | BURNPROGRAMMER = usbtiny 10 | TARGET = ./$(PROJECT).elf 11 | CC = avr-gcc 12 | CCXX = avr-g++ 13 | 14 | USER_ENABLED_OPTIONS = 15 | USER_ENABLED_OPTIONS += -DENABLE_CONSUMER 16 | USER_ENABLED_OPTIONS += -DENABLE_SYS_CONTROL 17 | USER_ENABLED_OPTIONS += -DENABLE_MOUSE 18 | #USER_ENABLED_OPTIONS += -DENABLE_FULL_DEBUG 19 | #USER_ENABLED_OPTIONS += -DENABLE_TIMEBUFF_DEBUG 20 | #USER_ENABLED_OPTIONS += -DENABLE_UNKNOWN_DEBUG 21 | USER_ENABLED_OPTIONS += -DENABLE_PROG_DEBUG 22 | USER_ENABLED_OPTIONS += -DENABLE_DEFAULT_CODES 23 | USER_ENABLED_OPTIONS += -DENABLE_APPLE_DEFAULTS 24 | USER_ENABLED_OPTIONS += -DENABLE_MMKEY_TRANSLATE 25 | 26 | ## Flags common to C, ASM, and Linker 27 | COMMON = -mmcu=$(MCU) 28 | 29 | ## Flags common to C only 30 | CFLAGS = $(COMMON) 31 | CONLYFLAGS = -std=gnu99 32 | CFLAGS += -Wall -gdwarf-2 -DF_CPU=16500000UL 33 | CFLAGS += $(USER_ENABLED_OPTIONS) 34 | CFLAGS += -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -ffunction-sections -fdata-sections 35 | CFLAGS += -MD -MP -MT $(*F).o 36 | 37 | ## Flags common to ASM only 38 | ASMFLAGS = $(COMMON) 39 | ASMFLAGS += $(CFLAGS) 40 | ASMFLAGS += -x assembler-with-cpp -Wa,-gdwarf2 41 | ASMFLAGS += 42 | 43 | ## Flags common to CPP/CXX only 44 | CXXFLAGS = $(COMMON) 45 | CXXFLAGS += $(CFLAGS) 46 | CXXFLAGS += -std=c99 47 | 48 | ## Flags common to Linker only 49 | LDFLAGS = $(COMMON) 50 | LDFLAGS += -Wl,-Map=./$(PROJECT).map 51 | LDFLAGS += -Wl,--gc-sections 52 | 53 | ## Flags for Intel HEX file production 54 | HEX_FLASH_FLAGS = -R .eeprom -R .fuse -R .lock -R .signature 55 | 56 | HEX_EEPROM_FLAGS = -j .eeprom 57 | HEX_EEPROM_FLAGS += --set-section-flags=.eeprom="alloc,load" 58 | HEX_EEPROM_FLAGS += --change-section-lma .eeprom=0 --no-change-warnings 59 | 60 | ## Include Directories 61 | INCLUDES = -I'.' 62 | 63 | ## Libraries 64 | LIBS = -lm -lc 65 | 66 | ## Link these object files to be made 67 | OBJECTS = main.o usr_prog.o usbdrv.o usbdrvasm.o 68 | 69 | ## Link objects specified by users 70 | LINKONLYOBJECTS = 71 | 72 | ## Compile 73 | 74 | all: $(TARGET) 75 | 76 | main.o: ./main.c 77 | $(CC) $(INCLUDES) $(CFLAGS) $(CONLYFLAGS) -c $< 78 | 79 | usr_prog.o: ./usr_prog.c 80 | $(CC) $(INCLUDES) $(CFLAGS) $(CONLYFLAGS) -c $< 81 | 82 | usbdrv.o: ./usbdrv/usbdrv.c 83 | $(CC) $(INCLUDES) $(CFLAGS) $(CONLYFLAGS) -c $< 84 | 85 | usbdrvasm.o: ./usbdrv/usbdrvasm.S 86 | $(CC) $(INCLUDES) $(ASMFLAGS) -c $< 87 | 88 | 89 | 90 | ## Link 91 | $(TARGET): $(OBJECTS) 92 | -rm -rf $(TARGET) ./$(PROJECT).map 93 | $(CC) $(LDFLAGS) $(OBJECTS) $(LINKONLYOBJECTS) $(LIBDIRS) $(LIBS) -o $(TARGET) 94 | -rm -rf $(OBJECTS) main.d usbdrv.d usbdrvasm.d 95 | -rm -rf ./$(PROJECT).hex ./$(PROJECT).eep ./$(PROJECT).lss 96 | avr-objcopy -O ihex $(HEX_FLASH_FLAGS) $(TARGET) ./$(PROJECT).hex 97 | avr-objcopy $(HEX_FLASH_FLAGS) -O ihex $(TARGET) ./$(PROJECT).eep || exit 0 98 | avr-objdump -h -S $(TARGET) >> ./$(PROJECT).lss 99 | @avr-size -C --mcu=${MCU} ${TARGET} 100 | 101 | ## Program 102 | burn: 103 | avrdude -B 3 -p $(BURNMCU) -c $(BURNPROGRAMMER) -U flash:w:./$(PROJECT).hex:a 104 | 105 | burnfuses: 106 | avrdude -B 10 -p $(BURNMCU) -c $(BURNPROGRAMMER) -U lfuse:w:0xF1:m -U hfuse:w:0xD7:m -U efuse:w:0xFE:m 107 | 108 | ## Clean target 109 | .PHONY: clean 110 | clean: 111 | -rm -rf $(OBJECTS) main.d usbdrv.d usbdrvasm.d ./$(PROJECT).elf ./$(PROJECT).map ./$(PROJECT).lss ./$(PROJECT).hex ./$(PROJECT).eep 112 | -------------------------------------------------------------------------------- /nec_defaults.h: -------------------------------------------------------------------------------- 1 | #ifndef NEC_CONFIG_H 2 | #define NEC_CONFIG_H 3 | 4 | #include 5 | 6 | // _AF_ means buttons on the Adafruit remote 7 | // _SDR_ means the remote that came with Frank's TV tuner 8 | // _APPLE_ means the official "Apple Remote Control" 9 | 10 | // map IR remote button to emulated keyboard keycode 11 | // on the left is the "modifier 12 | #define BUT_AF_VOL_DOWN KEYCODE_MINUS 13 | #define BUT_AF_PLAYPAUSE KEYCODE_SPACE 14 | #define BUT_AF_VOL_UP KEYCODE_EQUAL 15 | #define BUT_AF_SETUP KEYCODE_ESC 16 | #define BUT_AF_UP KEYCODE_ARROW_UP 17 | #define BUT_AF_STOPMODE KEYCODE_X 18 | #define BUT_AF_LEFT KEYCODE_ARROW_LEFT 19 | #define BUT_AF_ENTERSAVE KEYCODE_ENTER 20 | #define BUT_AF_RIGHT KEYCODE_ARROW_RIGHT 21 | #define BUT_AF_010 KEYCODE_0 22 | #define BUT_AF_DOWN KEYCODE_ARROW_DOWN 23 | #define BUT_AF_RETURN KEYCODE_BACKSPACE 24 | #define BUT_AF_1 KEYCODE_1 25 | #define BUT_AF_2 KEYCODE_2 26 | #define BUT_AF_3 KEYCODE_3 27 | #define BUT_AF_4 KEYCODE_4 28 | #define BUT_AF_5 KEYCODE_5 29 | #define BUT_AF_6 KEYCODE_6 30 | #define BUT_AF_7 KEYCODE_7 31 | #define BUT_AF_8 KEYCODE_8 32 | #define BUT_AF_9 KEYCODE_9 33 | 34 | #define BUT_SDR_MUTE KEYCODE_MUTE 35 | #define BUT_SDR_EPG KEYCODE_APP 36 | #define BUT_SDR_LIVETV KEYCODE_F1 37 | #define BUT_SDR_POWER KEYCODE_SYS_SLEEP 38 | #define BUT_SDR_1 KEYCODE_1 39 | #define BUT_SDR_2 KEYCODE_2 40 | #define BUT_SDR_3 KEYCODE_3 41 | #define BUT_SDR_STEREO KEYCODE_F2 42 | #define BUT_SDR_4 KEYCODE_4 43 | #define BUT_SDR_5 KEYCODE_5 44 | #define BUT_SDR_6 KEYCODE_6 45 | #define BUT_SDR_SNAPSHOT KEYCODE_F3 46 | #define BUT_SDR_7 KEYCODE_7 47 | #define BUT_SDR_8 KEYCODE_8 48 | #define BUT_SDR_9 KEYCODE_9 49 | #define BUT_SDR_ZOOM KEYCODE_F4 50 | #define BUT_SDR_RECALL KEYCODE_BACKSPACE 51 | #define BUT_SDR_0 KEYCODE_0 52 | #define BUT_SDR_CHAN_UP KEYCODE_ARROW_UP 53 | #define BUT_SDR_VOL_UP KEYCODE_VOL_UP 54 | #define BUT_SDR_TELETEXT KEYCODE_F5 55 | #define BUT_SDR_REC KEYCODE_F6 56 | #define BUT_SDR_CHAN_DOWN KEYCODE_ARROW_DOWN 57 | #define BUT_SDR_VOL_DOWN KEYCODE_VOL_DOWN 58 | #define BUT_SDR_STOP KEYCODE_STOP 59 | #define BUT_SDR_PAUSE KEYCODE_PLAYPAUSE 60 | #define BUT_SDR_SOURCE KEYCODE_ENTER 61 | #define BUT_SDR_FAVORITE KEYCODE_HOME 62 | 63 | #define BUT_APPLE_UP KEYCODE_EQUAL 64 | #define BUT_APPLE_DOWN KEYCODE_MINUS 65 | #define BUT_APPLE_LEFT KEYCODE_ARROW_LEFT 66 | #define BUT_APPLE_RIGHT KEYCODE_ARROW_RIGHT 67 | #define BUT_APPLE_PLAYPAUSE KEYCODE_SPACE 68 | #define BUT_APPLE_MENU KEYCODE_ESC 69 | #define BUT_APPLE_SELECT KEYCODE_ENTER 70 | 71 | #define IR_BUT_PAIRS { \ 72 | 0xFF00BF00, BUT_AF_VOL_DOWN, \ 73 | 0xFE01BF00, BUT_AF_PLAYPAUSE, \ 74 | 0xFD02BF00, BUT_AF_VOL_UP, \ 75 | 0xFB04BF00, BUT_AF_SETUP, \ 76 | 0xFA05BF00, BUT_AF_UP, \ 77 | 0xF906BF00, BUT_AF_STOPMODE, \ 78 | 0xF708BF00, BUT_AF_LEFT, \ 79 | 0xF609BF00, BUT_AF_ENTERSAVE, \ 80 | 0xF50ABF00, BUT_AF_RIGHT, \ 81 | 0xF30CBF00, BUT_AF_010, \ 82 | 0xF20DBF00, BUT_AF_DOWN, \ 83 | 0xF10EBF00, BUT_AF_RETURN, \ 84 | 0xEF10BF00, BUT_AF_1, \ 85 | 0xEE11BF00, BUT_AF_2, \ 86 | 0xED12BF00, BUT_AF_3, \ 87 | 0xEB14BF00, BUT_AF_4, \ 88 | 0xEA15BF00, BUT_AF_5, \ 89 | 0xE916BF00, BUT_AF_6, \ 90 | 0xE718BF00, BUT_AF_7, \ 91 | 0xE619BF00, BUT_AF_8, \ 92 | 0xE51ABF00, BUT_AF_9, \ 93 | 0xEC136B86, BUT_SDR_MUTE, \ 94 | 0xEE116B86, BUT_SDR_EPG, \ 95 | 0xE31C6B86, BUT_SDR_LIVETV, \ 96 | 0xED126B86, BUT_SDR_POWER, \ 97 | 0xFE016B86, BUT_SDR_1, \ 98 | 0xFD026B86, BUT_SDR_2, \ 99 | 0xFC036B86, BUT_SDR_3, \ 100 | 0xF20D6B86, BUT_SDR_STEREO, \ 101 | 0xFB046B86, BUT_SDR_4, \ 102 | 0xFA056B86, BUT_SDR_5, \ 103 | 0xF9066B86, BUT_SDR_6, \ 104 | 0xE6196B86, BUT_SDR_SNAPSHOT, \ 105 | 0xF8076B86, BUT_SDR_7, \ 106 | 0xF7086B86, BUT_SDR_8, \ 107 | 0xF6096B86, BUT_SDR_9, \ 108 | 0xEF106B86, BUT_SDR_ZOOM, \ 109 | 0xF50A6B86, BUT_SDR_RECALL, \ 110 | 0xFF006B86, BUT_SDR_0, \ 111 | 0xF40B6B86, BUT_SDR_CHAN_UP, \ 112 | 0xF30C6B86, BUT_SDR_VOL_UP, \ 113 | 0xE41B6B86, BUT_SDR_TELETEXT, \ 114 | 0xE21D6B86, BUT_SDR_REC, \ 115 | 0xEA156B86, BUT_SDR_CHAN_DOWN, \ 116 | 0xE7186B86, BUT_SDR_VOL_DOWN, \ 117 | 0xF10E6B86, BUT_SDR_STOP, \ 118 | 0xE11E6B86, BUT_SDR_PAUSE, \ 119 | 0xF00F6B86, BUT_SDR_SOURCE, \ 120 | 0xE51A6B86, BUT_SDR_FAVORITE, \ 121 | 0,0,} // null terminate to signal end of table 122 | 123 | #ifdef ENABLE_APPLE_DEFAULTS 124 | #include 125 | #endif 126 | 127 | #endif 128 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # Firmware burned into the Adafruit IRKey IR Remote -> Keyboard adapter 2 | 3 | 4 | 5 | Check the Makefile for fuses and avrdude commands. 6 | 7 | The IRKey adds an IR remote receiver to any computer, laptop, tablet...any computer with a USB port. This little board slides into any USB A port, and shows up as an every-day USB keyboard. The onboard ATiny85 microcontroller listens for IR remote signals and converts them to keypresses. We bundle this with our remote with 21 buttons so it controls nearly anything you want. For ultra-hackers, you can re-program the firmware to customize it however you wish, [check out the GitHub repository for the firmware.](https://github.com/adafruit/IRKey) 8 | 9 | IRKey is designed for use with our mini IR remote, but won't work with any other remote... so be aware it isn't "plug & play" with your home remote! 10 | 11 | It's great for controlling an XBMC computer, but also nice when you want to make a clicker for watching videos or playing music on your computer or laptop. Since it's just a USB keyboard, no drivers are required for any operating systems. 12 | 13 | There are two modes: ASCII and Multimedia key. ASCII mode is default, there's a single blink on startup to let you know. The output is all ASCII-type characters that any keyboard can generate. Multimedia mode has two blinks on startup, and sends MM key's as seen on some keyboards. This will let you do stuff like control your computer's speaker volume at any time, or iTunes, even if it's in the background. 14 | 15 | - "Vol-" -> '-' in ASCII mode or 'Volume down' in Multimedia Key mode 16 | - "Vol+" -> '=' in ASCII mode or 'Volume up' in Multimedia Key mode 17 | - "Play/pause" -> ' ' (space) in ASCII mode or 'Play/Pause' in Multimedia Key mode 18 | - "Setup" -> Escape key in ASCII mode or 'Menu" in Multimedia Key mode 19 | - "Stop/Mode" -> 'x' in ASCII mode or 'Stop' in Multimedia Key mode 20 | - Up/Down/Left/Right -> Arrow keys in ASCII mode or Volume Up/Down and Prev/Next track in Multimedia Key mode 21 | - Enter/Save -> Enter key 22 | - Reverse -> Backspace key 23 | - 0 thru 9 -> '0' thru '9' 24 | 25 | You can switch between modes by waiting until the IRKey is plugged in and working and pressing down the mini button for one second. The LED will blink to show you that the modes have switched. 26 | 27 | ## License 28 | 29 | Adafruit invests time and resources providing this open source design, 30 | please support Adafruit and open-source hardware by purchasing 31 | products from Adafruit! 32 | 33 | Written by Frank Zhao, for Adafruit Industries 34 | (c) 2013 35 | Based on V-USB 36 | 37 | Licensed under GPL v2 38 | 39 | All text above must be included in any redistribution 40 | -------------------------------------------------------------------------------- /usbdrv/Changelog.txt: -------------------------------------------------------------------------------- 1 | This file documents changes in the firmware-only USB driver for atmel's AVR 2 | microcontrollers. New entries are always appended to the end of the file. 3 | Scroll down to the bottom to see the most recent changes. 4 | 5 | 2005-04-01: 6 | - Implemented endpoint 1 as interrupt-in endpoint. 7 | - Moved all configuration options to usbconfig.h which is not part of the 8 | driver. 9 | - Changed interface for usbVendorSetup(). 10 | - Fixed compatibility with ATMega8 device. 11 | - Various minor optimizations. 12 | 13 | 2005-04-11: 14 | - Changed interface to application: Use usbFunctionSetup(), usbFunctionRead() 15 | and usbFunctionWrite() now. Added configuration options to choose which 16 | of these functions to compile in. 17 | - Assembler module delivers receive data non-inverted now. 18 | - Made register and bit names compatible with more AVR devices. 19 | 20 | 2005-05-03: 21 | - Allow address of usbRxBuf on any memory page as long as the buffer does 22 | not cross 256 byte page boundaries. 23 | - Better device compatibility: works with Mega88 now. 24 | - Code optimization in debugging module. 25 | - Documentation updates. 26 | 27 | 2006-01-02: 28 | - Added (free) default Vendor- and Product-IDs bought from voti.nl. 29 | - Added USBID-License.txt file which defines the rules for using the free 30 | shared VID/PID pair. 31 | - Added Readme.txt to the usbdrv directory which clarifies administrative 32 | issues. 33 | 34 | 2006-01-25: 35 | - Added "configured state" to become more standards compliant. 36 | - Added "HALT" state for interrupt endpoint. 37 | - Driver passes the "USB Command Verifier" test from usb.org now. 38 | - Made "serial number" a configuration option. 39 | - Minor optimizations, we now recommend compiler option "-Os" for best 40 | results. 41 | - Added a version number to usbdrv.h 42 | 43 | 2006-02-03: 44 | - New configuration variable USB_BUFFER_SECTION for the memory section where 45 | the USB rx buffer will go. This defaults to ".bss" if not defined. Since 46 | this buffer MUST NOT cross 256 byte pages (not even touch a page at the 47 | end), the user may want to pass a linker option similar to 48 | "-Wl,--section-start=.mybuffer=0x800060". 49 | - Provide structure for usbRequest_t. 50 | - New defines for USB constants. 51 | - Prepared for HID implementations. 52 | - Increased data size limit for interrupt transfers to 8 bytes. 53 | - New macro usbInterruptIsReady() to query interrupt buffer state. 54 | 55 | 2006-02-18: 56 | - Ensure that the data token which is sent as an ack to an OUT transfer is 57 | always zero sized. This fixes a bug where the host reports an error after 58 | sending an out transfer to the device, although all data arrived at the 59 | device. 60 | - Updated docs in usbdrv.h to reflect changed API in usbFunctionWrite(). 61 | 62 | * Release 2006-02-20 63 | 64 | - Give a compiler warning when compiling with debugging turned on. 65 | - Added Oleg Semyonov's changes for IAR-cc compatibility. 66 | - Added new (optional) functions usbDeviceConnect() and usbDeviceDisconnect() 67 | (also thanks to Oleg!). 68 | - Rearranged tests in usbPoll() to save a couple of instructions in the most 69 | likely case that no actions are pending. 70 | - We need a delay between the SET ADDRESS request until the new address 71 | becomes active. This delay was handled in usbPoll() until now. Since the 72 | spec says that the delay must not exceed 2ms, previous versions required 73 | aggressive polling during the enumeration phase. We have now moved the 74 | handling of the delay into the interrupt routine. 75 | - We must not reply with NAK to a SETUP transaction. We can only achieve this 76 | by making sure that the rx buffer is empty when SETUP tokens are expected. 77 | We therefore don't pass zero sized data packets from the status phase of 78 | a transfer to usbPoll(). This change MAY cause troubles if you rely on 79 | receiving a less than 8 bytes long packet in usbFunctionWrite() to 80 | identify the end of a transfer. usbFunctionWrite() will NEVER be called 81 | with a zero length. 82 | 83 | * Release 2006-03-14 84 | 85 | - Improved IAR C support: tiny memory model, more devices 86 | - Added template usbconfig.h file under the name usbconfig-prototype.h 87 | 88 | * Release 2006-03-26 89 | 90 | - Added provision for one more interrupt-in endpoint (endpoint 3). 91 | - Added provision for one interrupt-out endpoint (endpoint 1). 92 | - Added flowcontrol macros for USB. 93 | - Added provision for custom configuration descriptor. 94 | - Allow ANY two port bits for D+ and D-. 95 | - Merged (optional) receive endpoint number into global usbRxToken variable. 96 | - Use USB_CFG_IOPORTNAME instead of USB_CFG_IOPORT. We now construct the 97 | variable name from the single port letter instead of computing the address 98 | of related ports from the output-port address. 99 | 100 | * Release 2006-06-26 101 | 102 | - Updated documentation in usbdrv.h and usbconfig-prototype.h to reflect the 103 | new features. 104 | - Removed "#warning" directives because IAR does not understand them. Use 105 | unused static variables instead to generate a warning. 106 | - Do not include when compiling with IAR. 107 | - Introduced USB_CFG_DESCR_PROPS_* in usbconfig.h to configure how each 108 | USB descriptor should be handled. It is now possible to provide descriptor 109 | data in Flash, RAM or dynamically at runtime. 110 | - STALL is now a status in usbTxLen* instead of a message. We can now conform 111 | to the spec and leave the stall status pending until it is cleared. 112 | - Made usbTxPacketCnt1 and usbTxPacketCnt3 public. This allows the 113 | application code to reset data toggling on interrupt pipes. 114 | 115 | * Release 2006-07-18 116 | 117 | - Added an #if !defined __ASSEMBLER__ to the warning in usbdrv.h. This fixes 118 | an assembler error. 119 | - usbDeviceDisconnect() takes pull-up resistor to high impedance now. 120 | 121 | * Release 2007-02-01 122 | 123 | - Merged in some code size improvements from usbtiny (thanks to Dick 124 | Streefland for these optimizations!) 125 | - Special alignment requirement for usbRxBuf not required any more. Thanks 126 | again to Dick Streefland for this hint! 127 | - Reverted to "#warning" instead of unused static variables -- new versions 128 | of IAR CC should handle this directive. 129 | - Changed Open Source license to GNU GPL v2 in order to make linking against 130 | other free libraries easier. We no longer require publication of the 131 | circuit diagrams, but we STRONGLY encourage it. If you improve the driver 132 | itself, PLEASE grant us a royalty free license to your changes for our 133 | commercial license. 134 | 135 | * Release 2007-03-29 136 | 137 | - New configuration option "USB_PUBLIC" in usbconfig.h. 138 | - Set USB version number to 1.10 instead of 1.01. 139 | - Code used USB_CFG_DESCR_PROPS_STRING_DEVICE and 140 | USB_CFG_DESCR_PROPS_STRING_PRODUCT inconsistently. Changed all occurrences 141 | to USB_CFG_DESCR_PROPS_STRING_PRODUCT. 142 | - New assembler module for 16.5 MHz RC oscillator clock with PLL in receiver 143 | code. 144 | - New assembler module for 16 MHz crystal. 145 | - usbdrvasm.S contains common code only, clock-specific parts have been moved 146 | to usbdrvasm12.S, usbdrvasm16.S and usbdrvasm165.S respectively. 147 | 148 | * Release 2007-06-25 149 | 150 | - 16 MHz module: Do SE0 check in stuffed bits as well. 151 | 152 | * Release 2007-07-07 153 | 154 | - Define hi8(x) for IAR compiler to limit result to 8 bits. This is necessary 155 | for negative values. 156 | - Added 15 MHz module contributed by V. Bosch. 157 | - Interrupt vector name can now be configured. This is useful if somebody 158 | wants to use a different hardware interrupt than INT0. 159 | 160 | * Release 2007-08-07 161 | 162 | - Moved handleIn3 routine in usbdrvasm16.S so that relative jump range is 163 | not exceeded. 164 | - More config options: USB_RX_USER_HOOK(), USB_INITIAL_DATATOKEN, 165 | USB_COUNT_SOF 166 | - USB_INTR_PENDING can now be a memory address, not just I/O 167 | 168 | * Release 2007-09-19 169 | 170 | - Split out common parts of assembler modules into separate include file 171 | - Made endpoint numbers configurable so that given interface definitions 172 | can be matched. See USB_CFG_EP3_NUMBER in usbconfig-prototype.h. 173 | - Store endpoint number for interrupt/bulk-out so that usbFunctionWriteOut() 174 | can handle any number of endpoints. 175 | - Define usbDeviceConnect() and usbDeviceDisconnect() even if no 176 | USB_CFG_PULLUP_IOPORTNAME is defined. Directly set D+ and D- to 0 in this 177 | case. 178 | 179 | * Release 2007-12-01 180 | 181 | - Optimize usbDeviceConnect() and usbDeviceDisconnect() for less code size 182 | when USB_CFG_PULLUP_IOPORTNAME is not defined. 183 | 184 | * Release 2007-12-13 185 | 186 | - Renamed all include-only assembler modules from *.S to *.inc so that 187 | people don't add them to their project sources. 188 | - Distribute leap bits in tx loop more evenly for 16 MHz module. 189 | - Use "macro" and "endm" instead of ".macro" and ".endm" for IAR 190 | - Avoid compiler warnings for constant expr range by casting some values in 191 | USB descriptors. 192 | 193 | * Release 2008-01-21 194 | 195 | - Fixed bug in 15 and 16 MHz module where the new address set with 196 | SET_ADDRESS was already accepted at the next NAK or ACK we send, not at 197 | the next data packet we send. This caused problems when the host polled 198 | too fast. Thanks to Alexander Neumann for his help and patience debugging 199 | this issue! 200 | 201 | * Release 2008-02-05 202 | 203 | - Fixed bug in 16.5 MHz module where a register was used in the interrupt 204 | handler before it was pushed. This bug was introduced with version 205 | 2007-09-19 when common parts were moved to a separate file. 206 | - Optimized CRC routine (thanks to Reimar Doeffinger). 207 | 208 | * Release 2008-02-16 209 | 210 | - Removed outdated IAR compatibility stuff (code sections). 211 | - Added hook macros for USB_RESET_HOOK() and USB_SET_ADDRESS_HOOK(). 212 | - Added optional routine usbMeasureFrameLength() for calibration of the 213 | internal RC oscillator. 214 | 215 | * Release 2008-02-28 216 | 217 | - USB_INITIAL_DATATOKEN defaults to USBPID_DATA1 now, which means that we 218 | start with sending USBPID_DATA0. 219 | - Changed defaults in usbconfig-prototype.h 220 | - Added free USB VID/PID pair for MIDI class devices 221 | - Restructured AVR-USB as separate package, not part of PowerSwitch any more. 222 | 223 | * Release 2008-04-18 224 | 225 | - Restructured usbdrv.c so that it is easier to read and understand. 226 | - Better code optimization with gcc 4. 227 | - If a second interrupt in endpoint is enabled, also add it to config 228 | descriptor. 229 | - Added config option for long transfers (above 254 bytes), see 230 | USB_CFG_LONG_TRANSFERS in usbconfig.h. 231 | - Added 20 MHz module contributed by Jeroen Benschop. 232 | 233 | * Release 2008-05-13 234 | 235 | - Fixed bug in libs-host/hiddata.c function usbhidGetReport(): length 236 | was not incremented, pointer to length was incremented instead. 237 | - Added code to command line tool(s) which claims an interface. This code 238 | is disabled by default, but may be necessary on newer Linux kernels. 239 | - Added usbconfig.h option "USB_CFG_CHECK_DATA_TOGGLING". 240 | - New header "usbportability.h" prepares ports to other development 241 | environments. 242 | - Long transfers (above 254 bytes) did not work when usbFunctionRead() was 243 | used to supply the data. Fixed this bug. [Thanks to Alexander Neumann!] 244 | - In hiddata.c (example code for sending/receiving data over HID), use 245 | USB_RECIP_DEVICE instead of USB_RECIP_INTERFACE for control transfers so 246 | that we need not claim the interface. 247 | - in usbPoll() loop 20 times polling for RESET state instead of 10 times. 248 | This accounts for the higher clock rates we now support. 249 | - Added a module for 12.8 MHz RC oscillator with PLL in receiver loop. 250 | - Added hook to SOF code so that oscillator can be tuned to USB frame clock. 251 | - Added timeout to waitForJ loop. Helps preventing unexpected hangs. 252 | - Added example code for oscillator tuning to libs-device (thanks to 253 | Henrik Haftmann for the idea to this routine). 254 | - Implemented option USB_CFG_SUPPRESS_INTR_CODE. 255 | 256 | * Release 2008-10-22 257 | 258 | - Fixed libs-device/osctune.h: OSCCAL is memory address on ATMega88 and 259 | similar, not offset of 0x20 needs to be added. 260 | - Allow distribution under GPLv3 for those who have to link against other 261 | code distributed under GPLv3. 262 | 263 | * Release 2008-11-26 264 | 265 | - Removed libusb-win32 dependency for hid-data example in Makefile.windows. 266 | It was never required and confused many people. 267 | - Added extern uchar usbRxToken to usbdrv.h. 268 | - Integrated a module with CRC checks at 18 MHz by Lukas Schrittwieser. 269 | 270 | * Release 2009-03-23 271 | 272 | - Hid-mouse example used settings from hid-data example, fixed that. 273 | - Renamed project to V-USB due to a trademark issue with Atmel(r). 274 | - Changed CommercialLicense.txt and USBID-License.txt to make the 275 | background of USB ID registration clearer. 276 | 277 | * Release 2009-04-15 278 | 279 | - Changed CommercialLicense.txt to reflect the new range of PIDs from 280 | Jason Kotzin. 281 | - Removed USBID-License.txt in favor of USB-IDs-for-free.txt and 282 | USB-ID-FAQ.txt 283 | - Fixed a bug in the 12.8 MHz module: End Of Packet decection was made in 284 | the center between bit 0 and 1 of each byte. This is where the data lines 285 | are expected to change and the sampled data may therefore be nonsense. 286 | We therefore check EOP ONLY if bits 0 AND 1 have both been read as 0 on D-. 287 | - Fixed a bitstuffing problem in the 16 MHz module: If bit 6 was stuffed, 288 | the unstuffing code in the receiver routine was 1 cycle too long. If 289 | multiple bytes had the unstuffing in bit 6, the error summed up until the 290 | receiver was out of sync. 291 | - Included option for faster CRC routine. 292 | Thanks to Slawomir Fras (BoskiDialer) for this code! 293 | - Updated bits in Configuration Descriptor's bmAttributes according to 294 | USB 1.1 (in particular bit 7, it is a must-be-set bit now). 295 | 296 | * Release 2009-08-22 297 | 298 | - Moved first DBG1() after odDebugInit() in all examples. 299 | - Use vector INT0_vect instead of SIG_INTERRUPT0 if defined. This makes 300 | V-USB compatible with the new "p" suffix devices (e.g. ATMega328p). 301 | - USB_CFG_CLOCK_KHZ setting is now required in usbconfig.h (no default any 302 | more). 303 | - New option USB_CFG_DRIVER_FLASH_PAGE allows boot loaders on devices with 304 | more than 64 kB flash. 305 | - Built-in configuration descriptor allows custom definition for second 306 | endpoint now. 307 | 308 | * Release 2010-07-15 309 | 310 | - Fixed bug in usbDriverSetup() which prevented descriptor sizes above 255 311 | bytes. 312 | - Avoid a compiler warning for unused parameter in usbHandleResetHook() when 313 | compiler option -Wextra is enabled. 314 | - Fixed wrong hex value for some IDs in USB-IDs-for-free.txt. 315 | - Keep a define for USBATTR_BUSPOWER, although the flag does not exist 316 | in USB 1.1 any more. Set it to 0. This is for backward compatibility. 317 | 318 | * Release 2012-01-09 319 | 320 | - Define a separate (defined) type for usbMsgPtr so that projects using a 321 | tiny memory model can define it to an 8 bit type in usbconfig.h. This 322 | change also saves a couple of bytes when using a scalar 16 bit type. 323 | - Inserted "const" keyword for all PROGMEM declarations because new GCC 324 | requires it. 325 | - Fixed problem with dependence of usbportability.h on usbconfig.h. This 326 | problem occurred with IAR CC only. 327 | - Prepared repository for github.com. 328 | 329 | * Release 2012-12-06 -------------------------------------------------------------------------------- /usbdrv/CommercialLicense.txt: -------------------------------------------------------------------------------- 1 | V-USB Driver Software License Agreement 2 | Version 2012-07-09 3 | 4 | THIS LICENSE AGREEMENT GRANTS YOU CERTAIN RIGHTS IN A SOFTWARE. YOU CAN 5 | ENTER INTO THIS AGREEMENT AND ACQUIRE THE RIGHTS OUTLINED BELOW BY PAYING 6 | THE AMOUNT ACCORDING TO SECTION 4 ("PAYMENT") TO OBJECTIVE DEVELOPMENT. 7 | 8 | 9 | 1 DEFINITIONS 10 | 11 | 1.1 "OBJECTIVE DEVELOPMENT" shall mean OBJECTIVE DEVELOPMENT Software GmbH, 12 | Grosse Schiffgasse 1A/7, 1020 Wien, AUSTRIA. 13 | 14 | 1.2 "You" shall mean the Licensee. 15 | 16 | 1.3 "V-USB" shall mean all files included in the package distributed under 17 | the name "vusb" by OBJECTIVE DEVELOPMENT (http://www.obdev.at/vusb/) 18 | unless otherwise noted. This includes the firmware-only USB device 19 | implementation for Atmel AVR microcontrollers, some simple device examples 20 | and host side software examples and libraries. 21 | 22 | 23 | 2 LICENSE GRANTS 24 | 25 | 2.1 Source Code. OBJECTIVE DEVELOPMENT shall furnish you with the source 26 | code of V-USB. 27 | 28 | 2.2 Distribution and Use. OBJECTIVE DEVELOPMENT grants you the 29 | non-exclusive right to use, copy and distribute V-USB with your hardware 30 | product(s), restricted by the limitations in section 3 below. 31 | 32 | 2.3 Modifications. OBJECTIVE DEVELOPMENT grants you the right to modify 33 | the source code and your copy of V-USB according to your needs. 34 | 35 | 2.4 USB IDs. OBJECTIVE DEVELOPMENT furnishes you with one or two USB 36 | Product ID(s), sent to you in e-mail. These Product IDs are reserved 37 | exclusively for you. OBJECTIVE DEVELOPMENT has obtained USB Product ID 38 | ranges under the Vendor ID 5824 from Wouter van Ooijen (Van Ooijen 39 | Technische Informatica, www.voti.nl) and under the Vendor ID 8352 from 40 | Jason Kotzin (now flirc.tv, Inc.). Both owners of the Vendor IDs have 41 | obtained these IDs from the USB Implementers Forum, Inc. (www.usb.org). 42 | OBJECTIVE DEVELOPMENT disclaims all liability which might arise from the 43 | assignment of USB IDs. 44 | 45 | 2.5 USB Certification. Although not part of this agreement, we want to make 46 | it clear that you cannot become USB certified when you use V-USB or a USB 47 | Product ID assigned by OBJECTIVE DEVELOPMENT. AVR microcontrollers don't 48 | meet the electrical specifications required by the USB specification and 49 | the USB Implementers Forum certifies only members who bought a Vendor ID of 50 | their own. 51 | 52 | 53 | 3 LICENSE RESTRICTIONS 54 | 55 | 3.1 Number of Units. Only one of the following three definitions is 56 | applicable. Which one is determined by the amount you pay to OBJECTIVE 57 | DEVELOPMENT, see section 4 ("Payment") below. 58 | 59 | Hobby License: You may use V-USB according to section 2 above in no more 60 | than 5 hardware units. These units must not be sold for profit. 61 | 62 | Entry Level License: You may use V-USB according to section 2 above in no 63 | more than 150 hardware units. 64 | 65 | Professional License: You may use V-USB according to section 2 above in 66 | any number of hardware units, except for large scale production ("unlimited 67 | fair use"). Quantities below 10,000 units are not considered large scale 68 | production. If your reach quantities which are obviously large scale 69 | production, you must pay a license fee of 0.10 EUR per unit for all units 70 | above 10,000. 71 | 72 | 3.2 Rental. You may not rent, lease, or lend V-USB or otherwise encumber 73 | any copy of V-USB, or any of the rights granted herein. 74 | 75 | 3.3 Transfer. You may not transfer your rights under this Agreement to 76 | another party without OBJECTIVE DEVELOPMENT's prior written consent. If 77 | such consent is obtained, you may permanently transfer this License to 78 | another party. The recipient of such transfer must agree to all terms and 79 | conditions of this Agreement. 80 | 81 | 3.4 Reservation of Rights. OBJECTIVE DEVELOPMENT retains all rights not 82 | expressly granted. 83 | 84 | 3.5 Non-Exclusive Rights. Your license rights under this Agreement are 85 | non-exclusive. 86 | 87 | 3.6 Third Party Rights. This Agreement cannot grant you rights controlled 88 | by third parties. In particular, you are not allowed to use the USB logo or 89 | other trademarks owned by the USB Implementers Forum, Inc. without their 90 | consent. Since such consent depends on USB certification, it should be 91 | noted that V-USB will not pass certification because it does not 92 | implement checksum verification and the microcontroller ports do not meet 93 | the electrical specifications. 94 | 95 | 96 | 4 PAYMENT 97 | 98 | The payment amount depends on the variation of this agreement (according to 99 | section 3.1) into which you want to enter. Concrete prices are listed on 100 | OBJECTIVE DEVELOPMENT's web site, usually at 101 | http://www.obdev.at/vusb/license.html. You agree to pay the amount listed 102 | there to OBJECTIVE DEVELOPMENT or OBJECTIVE DEVELOPMENT's payment processor 103 | or reseller. 104 | 105 | 106 | 5 COPYRIGHT AND OWNERSHIP 107 | 108 | V-USB is protected by copyright laws and international copyright 109 | treaties, as well as other intellectual property laws and treaties. V-USB 110 | is licensed, not sold. 111 | 112 | 113 | 6 TERM AND TERMINATION 114 | 115 | 6.1 Term. This Agreement shall continue indefinitely. However, OBJECTIVE 116 | DEVELOPMENT may terminate this Agreement and revoke the granted license and 117 | USB-IDs if you fail to comply with any of its terms and conditions. 118 | 119 | 6.2 Survival of Terms. All provisions regarding secrecy, confidentiality 120 | and limitation of liability shall survive termination of this agreement. 121 | 122 | 123 | 7 DISCLAIMER OF WARRANTY AND LIABILITY 124 | 125 | LIMITED WARRANTY. V-USB IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY 126 | KIND. TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, OBJECTIVE 127 | DEVELOPMENT AND ITS SUPPLIERS HEREBY DISCLAIM ALL WARRANTIES, EITHER 128 | EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 129 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE, AND 130 | NON-INFRINGEMENT, WITH REGARD TO V-USB, AND THE PROVISION OF OR FAILURE 131 | TO PROVIDE SUPPORT SERVICES. THIS LIMITED WARRANTY GIVES YOU SPECIFIC LEGAL 132 | RIGHTS. YOU MAY HAVE OTHERS, WHICH VARY FROM STATE/JURISDICTION TO 133 | STATE/JURISDICTION. 134 | 135 | LIMITATION OF LIABILITY. TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, 136 | IN NO EVENT SHALL OBJECTIVE DEVELOPMENT OR ITS SUPPLIERS BE LIABLE FOR ANY 137 | SPECIAL, INCIDENTAL, INDIRECT, OR CONSEQUENTIAL DAMAGES WHATSOEVER 138 | (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, 139 | BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR ANY OTHER PECUNIARY 140 | LOSS) ARISING OUT OF THE USE OF OR INABILITY TO USE V-USB OR THE 141 | PROVISION OF OR FAILURE TO PROVIDE SUPPORT SERVICES, EVEN IF OBJECTIVE 142 | DEVELOPMENT HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. IN ANY 143 | CASE, OBJECTIVE DEVELOPMENT'S ENTIRE LIABILITY UNDER ANY PROVISION OF THIS 144 | AGREEMENT SHALL BE LIMITED TO THE AMOUNT ACTUALLY PAID BY YOU FOR V-USB. 145 | 146 | 147 | 8 MISCELLANEOUS TERMS 148 | 149 | 8.1 Marketing. OBJECTIVE DEVELOPMENT has the right to mention for marketing 150 | purposes that you entered into this agreement. 151 | 152 | 8.2 Entire Agreement. This document represents the entire agreement between 153 | OBJECTIVE DEVELOPMENT and you. It may only be modified in writing signed by 154 | an authorized representative of both, OBJECTIVE DEVELOPMENT and you. 155 | 156 | 8.3 Severability. In case a provision of these terms and conditions should 157 | be or become partly or entirely invalid, ineffective, or not executable, 158 | the validity of all other provisions shall not be affected. 159 | 160 | 8.4 Applicable Law. This agreement is governed by the laws of the Republic 161 | of Austria. 162 | 163 | 8.5 Responsible Courts. The responsible courts in Vienna/Austria will have 164 | exclusive jurisdiction regarding all disputes in connection with this 165 | agreement. 166 | 167 | -------------------------------------------------------------------------------- /usbdrv/License.txt: -------------------------------------------------------------------------------- 1 | OBJECTIVE DEVELOPMENT GmbH's V-USB driver software is distributed under the 2 | terms and conditions of the GNU GPL version 2 or the GNU GPL version 3. It is 3 | your choice whether you apply the terms of version 2 or version 3. The full 4 | text of GPLv2 is included below. In addition to the requirements in the GPL, 5 | we STRONGLY ENCOURAGE you to do the following: 6 | 7 | (1) Publish your entire project on a web site and drop us a note with the URL. 8 | Use the form at http://www.obdev.at/vusb/feedback.html for your submission. 9 | 10 | (2) Adhere to minimum publication standards. Please include AT LEAST: 11 | - a circuit diagram in PDF, PNG or GIF format 12 | - full source code for the host software 13 | - a Readme.txt file in ASCII format which describes the purpose of the 14 | project and what can be found in which directories and which files 15 | - a reference to http://www.obdev.at/vusb/ 16 | 17 | (3) If you improve the driver firmware itself, please give us a free license 18 | to your modifications for our commercial license offerings. 19 | 20 | 21 | 22 | GNU GENERAL PUBLIC LICENSE 23 | Version 2, June 1991 24 | 25 | Copyright (C) 1989, 1991 Free Software Foundation, Inc. 26 | 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 27 | Everyone is permitted to copy and distribute verbatim copies 28 | of this license document, but changing it is not allowed. 29 | 30 | Preamble 31 | 32 | The licenses for most software are designed to take away your 33 | freedom to share and change it. By contrast, the GNU General Public 34 | License is intended to guarantee your freedom to share and change free 35 | software--to make sure the software is free for all its users. This 36 | General Public License applies to most of the Free Software 37 | Foundation's software and to any other program whose authors commit to 38 | using it. (Some other Free Software Foundation software is covered by 39 | the GNU Library General Public License instead.) You can apply it to 40 | your programs, too. 41 | 42 | When we speak of free software, we are referring to freedom, not 43 | price. Our General Public Licenses are designed to make sure that you 44 | have the freedom to distribute copies of free software (and charge for 45 | this service if you wish), that you receive source code or can get it 46 | if you want it, that you can change the software or use pieces of it 47 | in new free programs; and that you know you can do these things. 48 | 49 | To protect your rights, we need to make restrictions that forbid 50 | anyone to deny you these rights or to ask you to surrender the rights. 51 | These restrictions translate to certain responsibilities for you if you 52 | distribute copies of the software, or if you modify it. 53 | 54 | For example, if you distribute copies of such a program, whether 55 | gratis or for a fee, you must give the recipients all the rights that 56 | you have. You must make sure that they, too, receive or can get the 57 | source code. And you must show them these terms so they know their 58 | rights. 59 | 60 | We protect your rights with two steps: (1) copyright the software, and 61 | (2) offer you this license which gives you legal permission to copy, 62 | distribute and/or modify the software. 63 | 64 | Also, for each author's protection and ours, we want to make certain 65 | that everyone understands that there is no warranty for this free 66 | software. If the software is modified by someone else and passed on, we 67 | want its recipients to know that what they have is not the original, so 68 | that any problems introduced by others will not reflect on the original 69 | authors' reputations. 70 | 71 | Finally, any free program is threatened constantly by software 72 | patents. We wish to avoid the danger that redistributors of a free 73 | program will individually obtain patent licenses, in effect making the 74 | program proprietary. To prevent this, we have made it clear that any 75 | patent must be licensed for everyone's free use or not licensed at all. 76 | 77 | The precise terms and conditions for copying, distribution and 78 | modification follow. 79 | 80 | GNU GENERAL PUBLIC LICENSE 81 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 82 | 83 | 0. This License applies to any program or other work which contains 84 | a notice placed by the copyright holder saying it may be distributed 85 | under the terms of this General Public License. The "Program", below, 86 | refers to any such program or work, and a "work based on the Program" 87 | means either the Program or any derivative work under copyright law: 88 | that is to say, a work containing the Program or a portion of it, 89 | either verbatim or with modifications and/or translated into another 90 | language. (Hereinafter, translation is included without limitation in 91 | the term "modification".) Each licensee is addressed as "you". 92 | 93 | Activities other than copying, distribution and modification are not 94 | covered by this License; they are outside its scope. The act of 95 | running the Program is not restricted, and the output from the Program 96 | is covered only if its contents constitute a work based on the 97 | Program (independent of having been made by running the Program). 98 | Whether that is true depends on what the Program does. 99 | 100 | 1. You may copy and distribute verbatim copies of the Program's 101 | source code as you receive it, in any medium, provided that you 102 | conspicuously and appropriately publish on each copy an appropriate 103 | copyright notice and disclaimer of warranty; keep intact all the 104 | notices that refer to this License and to the absence of any warranty; 105 | and give any other recipients of the Program a copy of this License 106 | along with the Program. 107 | 108 | You may charge a fee for the physical act of transferring a copy, and 109 | you may at your option offer warranty protection in exchange for a fee. 110 | 111 | 2. You may modify your copy or copies of the Program or any portion 112 | of it, thus forming a work based on the Program, and copy and 113 | distribute such modifications or work under the terms of Section 1 114 | above, provided that you also meet all of these conditions: 115 | 116 | a) You must cause the modified files to carry prominent notices 117 | stating that you changed the files and the date of any change. 118 | 119 | b) You must cause any work that you distribute or publish, that in 120 | whole or in part contains or is derived from the Program or any 121 | part thereof, to be licensed as a whole at no charge to all third 122 | parties under the terms of this License. 123 | 124 | c) If the modified program normally reads commands interactively 125 | when run, you must cause it, when started running for such 126 | interactive use in the most ordinary way, to print or display an 127 | announcement including an appropriate copyright notice and a 128 | notice that there is no warranty (or else, saying that you provide 129 | a warranty) and that users may redistribute the program under 130 | these conditions, and telling the user how to view a copy of this 131 | License. (Exception: if the Program itself is interactive but 132 | does not normally print such an announcement, your work based on 133 | the Program is not required to print an announcement.) 134 | 135 | These requirements apply to the modified work as a whole. If 136 | identifiable sections of that work are not derived from the Program, 137 | and can be reasonably considered independent and separate works in 138 | themselves, then this License, and its terms, do not apply to those 139 | sections when you distribute them as separate works. But when you 140 | distribute the same sections as part of a whole which is a work based 141 | on the Program, the distribution of the whole must be on the terms of 142 | this License, whose permissions for other licensees extend to the 143 | entire whole, and thus to each and every part regardless of who wrote it. 144 | 145 | Thus, it is not the intent of this section to claim rights or contest 146 | your rights to work written entirely by you; rather, the intent is to 147 | exercise the right to control the distribution of derivative or 148 | collective works based on the Program. 149 | 150 | In addition, mere aggregation of another work not based on the Program 151 | with the Program (or with a work based on the Program) on a volume of 152 | a storage or distribution medium does not bring the other work under 153 | the scope of this License. 154 | 155 | 3. You may copy and distribute the Program (or a work based on it, 156 | under Section 2) in object code or executable form under the terms of 157 | Sections 1 and 2 above provided that you also do one of the following: 158 | 159 | a) Accompany it with the complete corresponding machine-readable 160 | source code, which must be distributed under the terms of Sections 161 | 1 and 2 above on a medium customarily used for software interchange; or, 162 | 163 | b) Accompany it with a written offer, valid for at least three 164 | years, to give any third party, for a charge no more than your 165 | cost of physically performing source distribution, a complete 166 | machine-readable copy of the corresponding source code, to be 167 | distributed under the terms of Sections 1 and 2 above on a medium 168 | customarily used for software interchange; or, 169 | 170 | c) Accompany it with the information you received as to the offer 171 | to distribute corresponding source code. (This alternative is 172 | allowed only for noncommercial distribution and only if you 173 | received the program in object code or executable form with such 174 | an offer, in accord with Subsection b above.) 175 | 176 | The source code for a work means the preferred form of the work for 177 | making modifications to it. For an executable work, complete source 178 | code means all the source code for all modules it contains, plus any 179 | associated interface definition files, plus the scripts used to 180 | control compilation and installation of the executable. However, as a 181 | special exception, the source code distributed need not include 182 | anything that is normally distributed (in either source or binary 183 | form) with the major components (compiler, kernel, and so on) of the 184 | operating system on which the executable runs, unless that component 185 | itself accompanies the executable. 186 | 187 | If distribution of executable or object code is made by offering 188 | access to copy from a designated place, then offering equivalent 189 | access to copy the source code from the same place counts as 190 | distribution of the source code, even though third parties are not 191 | compelled to copy the source along with the object code. 192 | 193 | 4. You may not copy, modify, sublicense, or distribute the Program 194 | except as expressly provided under this License. Any attempt 195 | otherwise to copy, modify, sublicense or distribute the Program is 196 | void, and will automatically terminate your rights under this License. 197 | However, parties who have received copies, or rights, from you under 198 | this License will not have their licenses terminated so long as such 199 | parties remain in full compliance. 200 | 201 | 5. You are not required to accept this License, since you have not 202 | signed it. However, nothing else grants you permission to modify or 203 | distribute the Program or its derivative works. These actions are 204 | prohibited by law if you do not accept this License. Therefore, by 205 | modifying or distributing the Program (or any work based on the 206 | Program), you indicate your acceptance of this License to do so, and 207 | all its terms and conditions for copying, distributing or modifying 208 | the Program or works based on it. 209 | 210 | 6. Each time you redistribute the Program (or any work based on the 211 | Program), the recipient automatically receives a license from the 212 | original licensor to copy, distribute or modify the Program subject to 213 | these terms and conditions. You may not impose any further 214 | restrictions on the recipients' exercise of the rights granted herein. 215 | You are not responsible for enforcing compliance by third parties to 216 | this License. 217 | 218 | 7. If, as a consequence of a court judgment or allegation of patent 219 | infringement or for any other reason (not limited to patent issues), 220 | conditions are imposed on you (whether by court order, agreement or 221 | otherwise) that contradict the conditions of this License, they do not 222 | excuse you from the conditions of this License. If you cannot 223 | distribute so as to satisfy simultaneously your obligations under this 224 | License and any other pertinent obligations, then as a consequence you 225 | may not distribute the Program at all. For example, if a patent 226 | license would not permit royalty-free redistribution of the Program by 227 | all those who receive copies directly or indirectly through you, then 228 | the only way you could satisfy both it and this License would be to 229 | refrain entirely from distribution of the Program. 230 | 231 | If any portion of this section is held invalid or unenforceable under 232 | any particular circumstance, the balance of the section is intended to 233 | apply and the section as a whole is intended to apply in other 234 | circumstances. 235 | 236 | It is not the purpose of this section to induce you to infringe any 237 | patents or other property right claims or to contest validity of any 238 | such claims; this section has the sole purpose of protecting the 239 | integrity of the free software distribution system, which is 240 | implemented by public license practices. Many people have made 241 | generous contributions to the wide range of software distributed 242 | through that system in reliance on consistent application of that 243 | system; it is up to the author/donor to decide if he or she is willing 244 | to distribute software through any other system and a licensee cannot 245 | impose that choice. 246 | 247 | This section is intended to make thoroughly clear what is believed to 248 | be a consequence of the rest of this License. 249 | 250 | 8. If the distribution and/or use of the Program is restricted in 251 | certain countries either by patents or by copyrighted interfaces, the 252 | original copyright holder who places the Program under this License 253 | may add an explicit geographical distribution limitation excluding 254 | those countries, so that distribution is permitted only in or among 255 | countries not thus excluded. In such case, this License incorporates 256 | the limitation as if written in the body of this License. 257 | 258 | 9. The Free Software Foundation may publish revised and/or new versions 259 | of the General Public License from time to time. Such new versions will 260 | be similar in spirit to the present version, but may differ in detail to 261 | address new problems or concerns. 262 | 263 | Each version is given a distinguishing version number. If the Program 264 | specifies a version number of this License which applies to it and "any 265 | later version", you have the option of following the terms and conditions 266 | either of that version or of any later version published by the Free 267 | Software Foundation. If the Program does not specify a version number of 268 | this License, you may choose any version ever published by the Free Software 269 | Foundation. 270 | 271 | 10. If you wish to incorporate parts of the Program into other free 272 | programs whose distribution conditions are different, write to the author 273 | to ask for permission. For software which is copyrighted by the Free 274 | Software Foundation, write to the Free Software Foundation; we sometimes 275 | make exceptions for this. Our decision will be guided by the two goals 276 | of preserving the free status of all derivatives of our free software and 277 | of promoting the sharing and reuse of software generally. 278 | 279 | NO WARRANTY 280 | 281 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 282 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 283 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 284 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 285 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 286 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 287 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 288 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 289 | REPAIR OR CORRECTION. 290 | 291 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 292 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 293 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 294 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 295 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 296 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 297 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 298 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 299 | POSSIBILITY OF SUCH DAMAGES. 300 | 301 | END OF TERMS AND CONDITIONS 302 | 303 | How to Apply These Terms to Your New Programs 304 | 305 | If you develop a new program, and you want it to be of the greatest 306 | possible use to the public, the best way to achieve this is to make it 307 | free software which everyone can redistribute and change under these terms. 308 | 309 | To do so, attach the following notices to the program. It is safest 310 | to attach them to the start of each source file to most effectively 311 | convey the exclusion of warranty; and each file should have at least 312 | the "copyright" line and a pointer to where the full notice is found. 313 | 314 | 315 | Copyright (C) 316 | 317 | This program is free software; you can redistribute it and/or modify 318 | it under the terms of the GNU General Public License as published by 319 | the Free Software Foundation; either version 2 of the License, or 320 | (at your option) any later version. 321 | 322 | This program is distributed in the hope that it will be useful, 323 | but WITHOUT ANY WARRANTY; without even the implied warranty of 324 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 325 | GNU General Public License for more details. 326 | 327 | You should have received a copy of the GNU General Public License 328 | along with this program; if not, write to the Free Software 329 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 330 | 331 | 332 | Also add information on how to contact you by electronic and paper mail. 333 | 334 | If the program is interactive, make it output a short notice like this 335 | when it starts in an interactive mode: 336 | 337 | Gnomovision version 69, Copyright (C) year name of author 338 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 339 | This is free software, and you are welcome to redistribute it 340 | under certain conditions; type `show c' for details. 341 | 342 | The hypothetical commands `show w' and `show c' should show the appropriate 343 | parts of the General Public License. Of course, the commands you use may 344 | be called something other than `show w' and `show c'; they could even be 345 | mouse-clicks or menu items--whatever suits your program. 346 | 347 | You should also get your employer (if you work as a programmer) or your 348 | school, if any, to sign a "copyright disclaimer" for the program, if 349 | necessary. Here is a sample; alter the names: 350 | 351 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 352 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 353 | 354 | , 1 April 1989 355 | Ty Coon, President of Vice 356 | 357 | This General Public License does not permit incorporating your program into 358 | proprietary programs. If your program is a subroutine library, you may 359 | consider it more useful to permit linking proprietary applications with the 360 | library. If this is what you want to do, use the GNU Library General 361 | Public License instead of this License. 362 | -------------------------------------------------------------------------------- /usbdrv/Readme.txt: -------------------------------------------------------------------------------- 1 | This is the Readme file to Objective Development's firmware-only USB driver 2 | for Atmel AVR microcontrollers. For more information please visit 3 | http://www.obdev.at/vusb/ 4 | 5 | This directory contains the USB firmware only. Copy it as-is to your own 6 | project and add all .c and .S files to your project (these files are marked 7 | with an asterisk in the list below). Then copy usbconfig-prototype.h as 8 | usbconfig.h to your project and edit it according to your configuration. 9 | 10 | 11 | TECHNICAL DOCUMENTATION 12 | ======================= 13 | The technical documentation (API) for the firmware driver is contained in the 14 | file "usbdrv.h". Please read all of it carefully! Configuration options are 15 | documented in "usbconfig-prototype.h". 16 | 17 | The driver consists of the following files: 18 | Readme.txt ............. The file you are currently reading. 19 | Changelog.txt .......... Release notes for all versions of the driver. 20 | usbdrv.h ............... Driver interface definitions and technical docs. 21 | * usbdrv.c ............... High level language part of the driver. Link this 22 | module to your code! 23 | * usbdrvasm.S ............ Assembler part of the driver. This module is mostly 24 | a stub and includes one of the usbdrvasm*.S files 25 | depending on processor clock. Link this module to 26 | your code! 27 | usbdrvasm*.inc ......... Assembler routines for particular clock frequencies. 28 | Included by usbdrvasm.S, don't link it directly! 29 | asmcommon.inc .......... Common assembler routines. Included by 30 | usbdrvasm*.inc, don't link it directly! 31 | usbconfig-prototype.h .. Prototype for your own usbdrv.h file. 32 | * oddebug.c .............. Debug functions. Only used when DEBUG_LEVEL is 33 | defined to a value greater than 0. Link this module 34 | to your code! 35 | oddebug.h .............. Interface definitions of the debug module. 36 | usbportability.h ....... Header with compiler-dependent stuff. 37 | usbdrvasm.asm .......... Compatibility stub for IAR-C-compiler. Use this 38 | module instead of usbdrvasm.S when you assembler 39 | with IAR's tools. 40 | License.txt ............ Open Source license for this driver. 41 | CommercialLicense.txt .. Optional commercial license for this driver. 42 | USB-ID-FAQ.txt ......... General infos about USB Product- and Vendor-IDs. 43 | USB-IDs-for-free.txt ... List and terms of use for free shared PIDs. 44 | 45 | (*) ... These files should be linked to your project. 46 | 47 | 48 | CPU CORE CLOCK FREQUENCY 49 | ======================== 50 | We supply assembler modules for clock frequencies of 12 MHz, 12.8 MHz, 15 MHz, 51 | 16 MHz, 16.5 MHz 18 MHz and 20 MHz. Other clock rates are not supported. The 52 | actual clock rate must be configured in usbconfig.h. 53 | 54 | 12 MHz Clock 55 | This is the traditional clock rate of V-USB because it's the lowest clock 56 | rate where the timing constraints of the USB spec can be met. 57 | 58 | 15 MHz Clock 59 | Similar to 12 MHz, but some NOPs inserted. On the other hand, the higher clock 60 | rate allows for some loops which make the resulting code size somewhat smaller 61 | than the 12 MHz version. 62 | 63 | 16 MHz Clock 64 | This clock rate has been added for users of the Arduino board and other 65 | ready-made boards which come with a fixed 16 MHz crystal. It's also an option 66 | if you need the slightly higher clock rate for performance reasons. Since 67 | 16 MHz is not divisible by the USB low speed bit clock of 1.5 MHz, the code 68 | is somewhat tricky and has to insert a leap cycle every third byte. 69 | 70 | 12.8 MHz and 16.5 MHz Clock 71 | The assembler modules for these clock rates differ from the other modules 72 | because they have been built for an RC oscillator with only 1% precision. The 73 | receiver code inserts leap cycles to compensate for clock deviations. 1% is 74 | also the precision which can be achieved by calibrating the internal RC 75 | oscillator of the AVR. Please note that only AVRs with internal 64 MHz PLL 76 | oscillator can reach 16.5 MHz with the RC oscillator. This includes the very 77 | popular ATTiny25, ATTiny45, ATTiny85 series as well as the ATTiny26. Almost 78 | all AVRs can reach 12.8 MHz, although this is outside the specified range. 79 | 80 | See the EasyLogger example at http://www.obdev.at/vusb/easylogger.html for 81 | code which calibrates the RC oscillator based on the USB frame clock. 82 | 83 | 18 MHz Clock 84 | This module is closer to the USB specification because it performs an on the 85 | fly CRC check for incoming packets. Packets with invalid checksum are 86 | discarded as required by the spec. If you also implement checks for data 87 | PID toggling on application level (see option USB_CFG_CHECK_DATA_TOGGLING 88 | in usbconfig.h for more info), this ensures data integrity. Due to the CRC 89 | tables and alignment requirements, this code is bigger than modules for other 90 | clock rates. To activate this module, you must define USB_CFG_CHECK_CRC to 1 91 | and USB_CFG_CLOCK_KHZ to 18000 in usbconfig.h. 92 | 93 | 20 MHz Clock 94 | This module is for people who won't do it with less than the maximum. Since 95 | 20 MHz is not divisible by the USB low speed bit clock of 1.5 MHz, the code 96 | uses similar tricks as the 16 MHz module to insert leap cycles. 97 | 98 | 99 | USB IDENTIFIERS 100 | =============== 101 | Every USB device needs a vendor- and a product-identifier (VID and PID). VIDs 102 | are obtained from usb.org for a price of 1,500 USD. Once you have a VID, you 103 | can assign PIDs at will. 104 | 105 | Since an entry level cost of 1,500 USD is too high for most small companies 106 | and hobbyists, we provide some VID/PID pairs for free. See the file 107 | USB-IDs-for-free.txt for details. 108 | 109 | Objective Development also has some license offerings which include product 110 | IDs. See http://www.obdev.at/vusb/ for details. 111 | 112 | 113 | DEVELOPMENT SYSTEM 114 | ================== 115 | This driver has been developed and optimized for the GNU compiler version 3 116 | and 4. We recommend that you use the GNU compiler suite because it is freely 117 | available. V-USB has also been ported to the IAR compiler and assembler. It 118 | has been tested with IAR 4.10B/W32 and 4.12A/W32 on an ATmega8 with the 119 | "small" and "tiny" memory model. Not every release is tested with IAR CC and 120 | the driver may therefore fail to compile with IAR. Please note that gcc is 121 | more efficient for usbdrv.c because this module has been deliberately 122 | optimized for gcc. 123 | 124 | Gcc version 3 produces smaller code than version 4 due to new optimizing 125 | capabilities which don't always improve things on 8 bit CPUs. The code size 126 | generated by gcc 4 can be reduced with the compiler options 127 | -fno-move-loop-invariants, -fno-tree-scev-cprop and 128 | -fno-inline-small-functions in addition to -Os. On devices with more than 129 | 8k of flash memory, we also recommend the linker option --relax (written as 130 | -Wl,--relax for gcc) to convert absolute calls into relative where possible. 131 | 132 | For more information about optimizing options see: 133 | 134 | http://www.tty1.net/blog/2008-04-29-avr-gcc-optimisations_en.html 135 | 136 | These optimizations are good for gcc 4.x. Version 3.x of gcc does not support 137 | most of these options and produces good code anyway. 138 | 139 | 140 | USING V-USB FOR FREE 141 | ==================== 142 | The AVR firmware driver is published under the GNU General Public License 143 | Version 2 (GPL2) and the GNU General Public License Version 3 (GPL3). It is 144 | your choice whether you apply the terms of version 2 or version 3. 145 | 146 | If you decide for the free GPL2 or GPL3, we STRONGLY ENCOURAGE you to do the 147 | following things IN ADDITION to the obligations from the GPL: 148 | 149 | (1) Publish your entire project on a web site and drop us a note with the URL. 150 | Use the form at http://www.obdev.at/vusb/feedback.html for your submission. 151 | If you don't have a web site, you can publish the project in obdev's 152 | documentation wiki at 153 | http://www.obdev.at/goto.php?t=vusb-wiki&p=hosted-projects. 154 | 155 | (2) Adhere to minimum publication standards. Please include AT LEAST: 156 | - a circuit diagram in PDF, PNG or GIF format 157 | - full source code for the host software 158 | - a Readme.txt file in ASCII format which describes the purpose of the 159 | project and what can be found in which directories and which files 160 | - a reference to http://www.obdev.at/vusb/ 161 | 162 | (3) If you improve the driver firmware itself, please give us a free license 163 | to your modifications for our commercial license offerings. 164 | 165 | 166 | COMMERCIAL LICENSES FOR V-USB 167 | ============================= 168 | If you don't want to publish your source code under the terms of the GPL, 169 | you can simply pay money for V-USB. As an additional benefit you get 170 | USB PIDs for free, reserved exclusively to you. See the file 171 | "CommercialLicense.txt" for details. 172 | 173 | -------------------------------------------------------------------------------- /usbdrv/USB-ID-FAQ.txt: -------------------------------------------------------------------------------- 1 | Version 2012-07-09 2 | 3 | ========================== 4 | WHY DO WE NEED THESE IDs? 5 | ========================== 6 | 7 | USB is more than a low level protocol for data transport. It also defines a 8 | common set of requests which must be understood by all devices. And as part 9 | of these common requests, the specification defines data structures, the 10 | USB Descriptors, which are used to describe the properties of the device. 11 | 12 | From the perspective of an operating system, it is therefore possible to find 13 | out basic properties of a device (such as e.g. the manufacturer and the name 14 | of the device) without a device-specific driver. This is essential because 15 | the operating system can choose a driver to load based on this information 16 | (Plug-And-Play). 17 | 18 | Among the most important properties in the Device Descriptor are the USB 19 | Vendor- and Product-ID. Both are 16 bit integers. The most simple form of 20 | driver matching is based on these IDs. The driver announces the Vendor- and 21 | Product-IDs of the devices it can handle and the operating system loads the 22 | appropriate driver when the device is connected. 23 | 24 | It is obvious that this technique only works if the pair Vendor- plus 25 | Product-ID is unique: Only devices which require the same driver can have the 26 | same pair of IDs. 27 | 28 | 29 | ===================================================== 30 | HOW DOES THE USB STANDARD ENSURE THAT IDs ARE UNIQUE? 31 | ===================================================== 32 | 33 | Since it is so important that USB IDs are unique, the USB Implementers Forum, 34 | Inc. (usb.org) needs a way to enforce this legally. It is not forbidden by 35 | law to build a device and assign it any random numbers as IDs. Usb.org 36 | therefore needs an agreement to regulate the use of USB IDs. The agreement 37 | binds only parties who agreed to it, of course. Everybody else is free to use 38 | any numbers for their IDs. 39 | 40 | So how can usb.org ensure that every manufacturer of USB devices enters into 41 | an agreement with them? They do it via trademark licensing. Usb.org has 42 | registered the trademark "USB", all associated logos and related terms. If 43 | you want to put an USB logo on your product or claim that it is USB 44 | compliant, you must license these trademarks from usb.org. And this is where 45 | you enter into an agreement. See the "USB-IF Trademark License Agreement and 46 | Usage Guidelines for the USB-IF Logo" at 47 | http://www.usb.org/developers/logo_license/. 48 | 49 | Licensing the USB trademarks requires that you buy a USB Vendor-ID from 50 | usb.org (one-time fee of ca. 2,000 USD), that you become a member of usb.org 51 | (yearly fee of ca. 4,000 USD) and that you meet all the technical 52 | specifications from the USB spec. 53 | 54 | This means that most hobbyists and small companies will never be able to 55 | become USB compliant, just because membership is so expensive. And you can't 56 | be compliant with a driver based on V-USB anyway, because the AVR's port pins 57 | don't meet the electrical specifications for USB. So, in principle, all 58 | hobbyists and small companies are free to choose any random numbers for their 59 | IDs. They have nothing to lose... 60 | 61 | There is one exception worth noting, though: If you use a sub-component which 62 | implements USB, the vendor of the sub-components may guarantee USB 63 | compliance. This might apply to some or all of FTDI's solutions. 64 | 65 | 66 | ======================================================================= 67 | WHY SHOULD YOU OBTAIN USB IDs EVEN IF YOU DON'T LICENSE USB TRADEMARKS? 68 | ======================================================================= 69 | 70 | You have learned in the previous section that you are free to choose any 71 | numbers for your IDs anyway. So why not do exactly this? There is still the 72 | technical issue. If you choose IDs which are already in use by somebody else, 73 | operating systems will load the wrong drivers and your device won't work. 74 | Even if you choose IDs which are not currently in use, they may be in use in 75 | the next version of the operating system or even after an automatic update. 76 | 77 | So what you need is a pair of Vendor- and Product-IDs for which you have the 78 | guarantee that no USB compliant product uses them. This implies that no 79 | operating system will ever ship with drivers responsible for these IDs. 80 | 81 | 82 | ============================================== 83 | HOW DOES OBJECTIVE DEVELOPMENT HANDLE USB IDs? 84 | ============================================== 85 | 86 | Objective Development gives away pairs of USB-IDs with their V-USB licenses. 87 | In order to ensure that these IDs are unique, Objective Development has an 88 | agreement with the company/person who has bought the USB Vendor-ID from 89 | usb.org. This agreement ensures that a range of USB Product-IDs is reserved 90 | for assignment by Objective Development and that the owner of the Vendor-ID 91 | won't give it to anybody else. 92 | 93 | This means that you have to trust three parties to ensure uniqueness of 94 | your IDs: 95 | 96 | - Objective Development, that they don't give the same PID to more than 97 | one person. 98 | - The owner of the Vendor-ID that they don't assign PIDs from the range 99 | assigned to Objective Development to anybody else. 100 | - Usb.org that they don't assign the same Vendor-ID a second time. 101 | 102 | 103 | ================================== 104 | WHO IS THE OWNER OF THE VENDOR-ID? 105 | ================================== 106 | 107 | Objective Development has obtained ranges of USB Product-IDs under two 108 | Vendor-IDs: Under Vendor-ID 5824 from Wouter van Ooijen (Van Ooijen 109 | Technische Informatica, www.voti.nl) and under Vendor-ID 8352 from Jason 110 | Kotzin (now flirc.tv, Inc.). Both VID owners have received their Vendor-ID 111 | directly from usb.org. 112 | 113 | 114 | ========================================================================= 115 | CAN I USE USB-IDs FROM OBJECTIVE DEVELOPMENT WITH OTHER DRIVERS/HARDWARE? 116 | ========================================================================= 117 | 118 | The short answer is: Yes. All you get is a guarantee that the IDs are never 119 | assigned to anybody else. What more do you need? 120 | 121 | 122 | ============================ 123 | WHAT ABOUT SHARED ID PAIRS? 124 | ============================ 125 | 126 | Objective Development has reserved some PID/VID pairs for shared use. You 127 | have no guarantee of uniqueness for them, except that no USB compliant device 128 | uses them. In order to avoid technical problems, we must ensure that all 129 | devices with the same pair of IDs use the same driver on kernel level. For 130 | details, see the file USB-IDs-for-free.txt. 131 | 132 | 133 | ====================================================== 134 | I HAVE HEARD THAT SUB-LICENSING OF USB-IDs IS ILLEGAL? 135 | ====================================================== 136 | 137 | A 16 bit integer number cannot be protected by copyright laws. It is not 138 | sufficiently complex. And since none of the parties involved entered into the 139 | USB-IF Trademark License Agreement, we are not bound by this agreement. So 140 | there is no reason why it should be illegal to sub-license USB-IDs. 141 | 142 | 143 | ============================================= 144 | WHO IS LIABLE IF THERE ARE INCOMPATIBILITIES? 145 | ============================================= 146 | 147 | Objective Development disclaims all liabilities which might arise from the 148 | assignment of IDs. If you guarantee product features to your customers 149 | without proper disclaimer, YOU are liable for that. 150 | -------------------------------------------------------------------------------- /usbdrv/USB-IDs-for-free.txt: -------------------------------------------------------------------------------- 1 | Version 2009-08-22 2 | 3 | =========================== 4 | FREE USB-IDs FOR SHARED USE 5 | =========================== 6 | 7 | Objective Development has reserved a set of USB Product-IDs for use according 8 | to the guidelines outlined below. For more information about the concept of 9 | USB IDs please see the file USB-ID-FAQ.txt. Objective Development guarantees 10 | that the IDs listed below are not used by any USB compliant devices. 11 | 12 | 13 | ==================== 14 | MECHANISM OF SHARING 15 | ==================== 16 | 17 | From a technical point of view, two different devices can share the same USB 18 | Vendor- and Product-ID if they require the same driver on operating system 19 | level. We make use of this fact by assigning separate IDs for various device 20 | classes. On application layer, devices must be distinguished by their textual 21 | name or serial number. We offer separate sets of IDs for discrimination by 22 | textual name and for serial number. 23 | 24 | Examples for shared use of USB IDs are included with V-USB in the "examples" 25 | subdirectory. 26 | 27 | 28 | ====================================== 29 | IDs FOR DISCRIMINATION BY TEXTUAL NAME 30 | ====================================== 31 | 32 | If you use one of the IDs listed below, your device and host-side software 33 | must conform to these rules: 34 | 35 | (1) The USB device MUST provide a textual representation of the manufacturer 36 | and product identification. The manufacturer identification MUST be available 37 | at least in USB language 0x0409 (English/US). 38 | 39 | (2) The textual manufacturer identification MUST contain either an Internet 40 | domain name (e.g. "mycompany.com") registered and owned by you, or an e-mail 41 | address under your control (e.g. "myname@gmx.net"). You can embed the domain 42 | name or e-mail address in any string you like, e.g. "Objective Development 43 | http://www.obdev.at/vusb/". 44 | 45 | (3) You are responsible for retaining ownership of the domain or e-mail 46 | address for as long as any of your products are in use. 47 | 48 | (4) You may choose any string for the textual product identification, as long 49 | as this string is unique within the scope of your textual manufacturer 50 | identification. 51 | 52 | (5) Application side device look-up MUST be based on the textual manufacturer 53 | and product identification in addition to VID/PID matching. The driver 54 | matching MUST be a comparison of the entire strings, NOT a sub-string match. 55 | 56 | (6) For devices which implement a particular USB device class (e.g. HID), the 57 | operating system's default class driver MUST be used. If an operating system 58 | driver for Vendor Class devices is needed, this driver must be libusb or 59 | libusb-win32 (see http://libusb.org/ and 60 | http://libusb-win32.sourceforge.net/). 61 | 62 | Table if IDs for discrimination by textual name: 63 | 64 | PID dec (hex) | VID dec (hex) | Description of use 65 | ==============+===============+============================================ 66 | 1500 (0x05dc) | 5824 (0x16c0) | For Vendor Class devices with libusb 67 | --------------+---------------+-------------------------------------------- 68 | 1503 (0x05df) | 5824 (0x16c0) | For generic HID class devices (which are 69 | | | NOT mice, keyboards or joysticks) 70 | --------------+---------------+-------------------------------------------- 71 | 1505 (0x05e1) | 5824 (0x16c0) | For CDC-ACM class devices (modems) 72 | --------------+---------------+-------------------------------------------- 73 | 1508 (0x05e4) | 5824 (0x16c0) | For MIDI class devices 74 | --------------+---------------+-------------------------------------------- 75 | 76 | Note that Windows caches the textual product- and vendor-description for 77 | mice, keyboards and joysticks. Name-bsed discrimination is therefore not 78 | recommended for these device classes. 79 | 80 | 81 | ======================================= 82 | IDs FOR DISCRIMINATION BY SERIAL NUMBER 83 | ======================================= 84 | 85 | If you use one of the IDs listed below, your device and host-side software 86 | must conform to these rules: 87 | 88 | (1) The USB device MUST provide a textual representation of the serial 89 | number, unless ONLY the operating system's default class driver is used. 90 | The serial number string MUST be available at least in USB language 0x0409 91 | (English/US). 92 | 93 | (2) The serial number MUST start with either an Internet domain name (e.g. 94 | "mycompany.com") registered and owned by you, or an e-mail address under your 95 | control (e.g. "myname@gmx.net"), both terminated with a colon (":") character. 96 | You MAY append any string you like for further discrimination of your devices. 97 | 98 | (3) You are responsible for retaining ownership of the domain or e-mail 99 | address for as long as any of your products are in use. 100 | 101 | (5) Application side device look-up MUST be based on the serial number string 102 | in addition to VID/PID matching. The matching must start at the first 103 | character of the serial number string and include the colon character 104 | terminating your domain or e-mail address. It MAY stop anywhere after that. 105 | 106 | (6) For devices which implement a particular USB device class (e.g. HID), the 107 | operating system's default class driver MUST be used. If an operating system 108 | driver for Vendor Class devices is needed, this driver must be libusb or 109 | libusb-win32 (see http://libusb.org/ and 110 | http://libusb-win32.sourceforge.net/). 111 | 112 | (7) If ONLY the operating system's default class driver is used, e.g. for 113 | mice, keyboards, joysticks, CDC or MIDI devices and no discrimination by an 114 | application is needed, the serial number may be omitted. 115 | 116 | 117 | Table if IDs for discrimination by serial number string: 118 | 119 | PID dec (hex) | VID dec (hex) | Description of use 120 | ===============+===============+=========================================== 121 | 10200 (0x27d8) | 5824 (0x16c0) | For Vendor Class devices with libusb 122 | ---------------+---------------+------------------------------------------- 123 | 10201 (0x27d9) | 5824 (0x16c0) | For generic HID class devices (which are 124 | | | NOT mice, keyboards or joysticks) 125 | ---------------+---------------+------------------------------------------- 126 | 10202 (0x27da) | 5824 (0x16c0) | For USB Mice 127 | ---------------+---------------+------------------------------------------- 128 | 10203 (0x27db) | 5824 (0x16c0) | For USB Keyboards 129 | ---------------+---------------+------------------------------------------- 130 | 10204 (0x27dc) | 5824 (0x16c0) | For USB Joysticks 131 | ---------------+---------------+------------------------------------------- 132 | 10205 (0x27dd) | 5824 (0x16c0) | For CDC-ACM class devices (modems) 133 | ---------------+---------------+------------------------------------------- 134 | 10206 (0x27de) | 5824 (0x16c0) | For MIDI class devices 135 | ---------------+---------------+------------------------------------------- 136 | 137 | 138 | ================= 139 | ORIGIN OF USB-IDs 140 | ================= 141 | 142 | OBJECTIVE DEVELOPMENT Software GmbH has obtained all VID/PID pairs listed 143 | here from Wouter van Ooijen (see www.voti.nl) for exclusive disposition. 144 | Wouter van Ooijen has obtained the VID from the USB Implementers Forum, Inc. 145 | (see www.usb.org). The VID is registered for the company name "Van Ooijen 146 | Technische Informatica". 147 | 148 | 149 | ========== 150 | DISCLAIMER 151 | ========== 152 | 153 | OBJECTIVE DEVELOPMENT Software GmbH disclaims all liability for any 154 | problems which are caused by the shared use of these VID/PID pairs. 155 | -------------------------------------------------------------------------------- /usbdrv/asmcommon.inc: -------------------------------------------------------------------------------- 1 | /* Name: asmcommon.inc 2 | * Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers 3 | * Author: Christian Starkjohann 4 | * Creation Date: 2007-11-05 5 | * Tabsize: 4 6 | * Copyright: (c) 2007 by OBJECTIVE DEVELOPMENT Software GmbH 7 | * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) 8 | */ 9 | 10 | /* Do not link this file! Link usbdrvasm.S instead, which includes the 11 | * appropriate implementation! 12 | */ 13 | 14 | /* 15 | General Description: 16 | This file contains assembler code which is shared among the USB driver 17 | implementations for different CPU cocks. Since the code must be inserted 18 | in the middle of the module, it's split out into this file and #included. 19 | 20 | Jump destinations called from outside: 21 | sofError: Called when no start sequence was found. 22 | se0: Called when a package has been successfully received. 23 | overflow: Called when receive buffer overflows. 24 | doReturn: Called after sending data. 25 | 26 | Outside jump destinations used by this module: 27 | waitForJ: Called to receive an already arriving packet. 28 | sendAckAndReti: 29 | sendNakAndReti: 30 | sendCntAndReti: 31 | usbSendAndReti: 32 | 33 | The following macros must be defined before this file is included: 34 | .macro POP_STANDARD 35 | .endm 36 | .macro POP_RETI 37 | .endm 38 | */ 39 | 40 | #define token x1 41 | 42 | overflow: 43 | ldi x2, 1< 0 13 | 14 | #warning "Never compile production devices with debugging enabled" 15 | 16 | static void uartPutc(char c) 17 | { 18 | while(!(ODDBG_USR & (1 << ODDBG_UDRE))); /* wait for data register empty */ 19 | ODDBG_UDR = c; 20 | } 21 | 22 | static uchar hexAscii(uchar h) 23 | { 24 | h &= 0xf; 25 | if(h >= 10) 26 | h += 'a' - (uchar)10 - '0'; 27 | h += '0'; 28 | return h; 29 | } 30 | 31 | static void printHex(uchar c) 32 | { 33 | uartPutc(hexAscii(c >> 4)); 34 | uartPutc(hexAscii(c)); 35 | } 36 | 37 | void odDebug(uchar prefix, uchar *data, uchar len) 38 | { 39 | printHex(prefix); 40 | uartPutc(':'); 41 | while(len--){ 42 | uartPutc(' '); 43 | printHex(*data++); 44 | } 45 | uartPutc('\r'); 46 | uartPutc('\n'); 47 | } 48 | 49 | #endif 50 | -------------------------------------------------------------------------------- /usbdrv/oddebug.h: -------------------------------------------------------------------------------- 1 | /* Name: oddebug.h 2 | * Project: AVR library 3 | * Author: Christian Starkjohann 4 | * Creation Date: 2005-01-16 5 | * Tabsize: 4 6 | * Copyright: (c) 2005 by OBJECTIVE DEVELOPMENT Software GmbH 7 | * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) 8 | */ 9 | 10 | #ifndef __oddebug_h_included__ 11 | #define __oddebug_h_included__ 12 | 13 | /* 14 | General Description: 15 | This module implements a function for debug logs on the serial line of the 16 | AVR microcontroller. Debugging can be configured with the define 17 | 'DEBUG_LEVEL'. If this macro is not defined or defined to 0, all debugging 18 | calls are no-ops. If it is 1, DBG1 logs will appear, but not DBG2. If it is 19 | 2, DBG1 and DBG2 logs will be printed. 20 | 21 | A debug log consists of a label ('prefix') to indicate which debug log created 22 | the output and a memory block to dump in hex ('data' and 'len'). 23 | */ 24 | 25 | 26 | #ifndef F_CPU 27 | # define F_CPU 12000000 /* 12 MHz */ 28 | #endif 29 | 30 | /* make sure we have the UART defines: */ 31 | #include "usbportability.h" 32 | 33 | #ifndef uchar 34 | # define uchar unsigned char 35 | #endif 36 | 37 | #if DEBUG_LEVEL > 0 && !(defined TXEN || defined TXEN0) /* no UART in device */ 38 | # warning "Debugging disabled because device has no UART" 39 | # undef DEBUG_LEVEL 40 | #endif 41 | 42 | #ifndef DEBUG_LEVEL 43 | # define DEBUG_LEVEL 0 44 | #endif 45 | 46 | /* ------------------------------------------------------------------------- */ 47 | 48 | #if DEBUG_LEVEL > 0 49 | # define DBG1(prefix, data, len) odDebug(prefix, data, len) 50 | #else 51 | # define DBG1(prefix, data, len) 52 | #endif 53 | 54 | #if DEBUG_LEVEL > 1 55 | # define DBG2(prefix, data, len) odDebug(prefix, data, len) 56 | #else 57 | # define DBG2(prefix, data, len) 58 | #endif 59 | 60 | /* ------------------------------------------------------------------------- */ 61 | 62 | #if DEBUG_LEVEL > 0 63 | extern void odDebug(uchar prefix, uchar *data, uchar len); 64 | 65 | /* Try to find our control registers; ATMEL likes to rename these */ 66 | 67 | #if defined UBRR 68 | # define ODDBG_UBRR UBRR 69 | #elif defined UBRRL 70 | # define ODDBG_UBRR UBRRL 71 | #elif defined UBRR0 72 | # define ODDBG_UBRR UBRR0 73 | #elif defined UBRR0L 74 | # define ODDBG_UBRR UBRR0L 75 | #endif 76 | 77 | #if defined UCR 78 | # define ODDBG_UCR UCR 79 | #elif defined UCSRB 80 | # define ODDBG_UCR UCSRB 81 | #elif defined UCSR0B 82 | # define ODDBG_UCR UCSR0B 83 | #endif 84 | 85 | #if defined TXEN 86 | # define ODDBG_TXEN TXEN 87 | #else 88 | # define ODDBG_TXEN TXEN0 89 | #endif 90 | 91 | #if defined USR 92 | # define ODDBG_USR USR 93 | #elif defined UCSRA 94 | # define ODDBG_USR UCSRA 95 | #elif defined UCSR0A 96 | # define ODDBG_USR UCSR0A 97 | #endif 98 | 99 | #if defined UDRE 100 | # define ODDBG_UDRE UDRE 101 | #else 102 | # define ODDBG_UDRE UDRE0 103 | #endif 104 | 105 | #if defined UDR 106 | # define ODDBG_UDR UDR 107 | #elif defined UDR0 108 | # define ODDBG_UDR UDR0 109 | #endif 110 | 111 | static inline void odDebugInit(void) 112 | { 113 | ODDBG_UCR |= (1< max 25 cycles interrupt disable 38 | ;max stack usage: [ret(2), YL, SREG, YH, shift, x1, x2, x3, cnt, x4] = 11 bytes 39 | ;Numbers in brackets are maximum cycles since SOF. 40 | USB_INTR_VECTOR: 41 | ;order of registers pushed: YL, SREG [sofError], YH, shift, x1, x2, x3, cnt 42 | push YL ;2 [35] push only what is necessary to sync with edge ASAP 43 | in YL, SREG ;1 [37] 44 | push YL ;2 [39] 45 | ;---------------------------------------------------------------------------- 46 | ; Synchronize with sync pattern: 47 | ;---------------------------------------------------------------------------- 48 | ;sync byte (D-) pattern LSb to MSb: 01010100 [1 = idle = J, 0 = K] 49 | ;sync up with J to K edge during sync pattern -- use fastest possible loops 50 | ;The first part waits at most 1 bit long since we must be in sync pattern. 51 | ;YL is guarenteed to be < 0x80 because I flag is clear. When we jump to 52 | ;waitForJ, ensure that this prerequisite is met. 53 | waitForJ: 54 | inc YL 55 | sbis USBIN, USBMINUS 56 | brne waitForJ ; just make sure we have ANY timeout 57 | waitForK: 58 | ;The following code results in a sampling window of 1/4 bit which meets the spec. 59 | sbis USBIN, USBMINUS 60 | rjmp foundK 61 | sbis USBIN, USBMINUS 62 | rjmp foundK 63 | sbis USBIN, USBMINUS 64 | rjmp foundK 65 | sbis USBIN, USBMINUS 66 | rjmp foundK 67 | sbis USBIN, USBMINUS 68 | rjmp foundK 69 | #if USB_COUNT_SOF 70 | lds YL, usbSofCount 71 | inc YL 72 | sts usbSofCount, YL 73 | #endif /* USB_COUNT_SOF */ 74 | #ifdef USB_SOF_HOOK 75 | USB_SOF_HOOK 76 | #endif 77 | rjmp sofError 78 | foundK: 79 | ;{3, 5} after falling D- edge, average delay: 4 cycles [we want 4 for center sampling] 80 | ;we have 1 bit time for setup purposes, then sample again. Numbers in brackets 81 | ;are cycles from center of first sync (double K) bit after the instruction 82 | push YH ;2 [2] 83 | lds YL, usbInputBufOffset;2 [4] 84 | clr YH ;1 [5] 85 | subi YL, lo8(-(usbRxBuf));1 [6] 86 | sbci YH, hi8(-(usbRxBuf));1 [7] 87 | 88 | sbis USBIN, USBMINUS ;1 [8] we want two bits K [sample 1 cycle too early] 89 | rjmp haveTwoBitsK ;2 [10] 90 | pop YH ;2 [11] undo the push from before 91 | rjmp waitForK ;2 [13] this was not the end of sync, retry 92 | haveTwoBitsK: 93 | ;---------------------------------------------------------------------------- 94 | ; push more registers and initialize values while we sample the first bits: 95 | ;---------------------------------------------------------------------------- 96 | push shift ;2 [16] 97 | push x1 ;2 [12] 98 | push x2 ;2 [14] 99 | 100 | in x1, USBIN ;1 [17] <-- sample bit 0 101 | ldi shift, 0xff ;1 [18] 102 | bst x1, USBMINUS ;1 [19] 103 | bld shift, 0 ;1 [20] 104 | push x3 ;2 [22] 105 | push cnt ;2 [24] 106 | 107 | in x2, USBIN ;1 [25] <-- sample bit 1 108 | ser x3 ;1 [26] [inserted init instruction] 109 | eor x1, x2 ;1 [27] 110 | bst x1, USBMINUS ;1 [28] 111 | bld shift, 1 ;1 [29] 112 | ldi cnt, USB_BUFSIZE;1 [30] [inserted init instruction] 113 | rjmp rxbit2 ;2 [32] 114 | 115 | ;---------------------------------------------------------------------------- 116 | ; Receiver loop (numbers in brackets are cycles within byte after instr) 117 | ;---------------------------------------------------------------------------- 118 | 119 | unstuff0: ;1 (branch taken) 120 | andi x3, ~0x01 ;1 [15] 121 | mov x1, x2 ;1 [16] x2 contains last sampled (stuffed) bit 122 | in x2, USBIN ;1 [17] <-- sample bit 1 again 123 | ori shift, 0x01 ;1 [18] 124 | rjmp didUnstuff0 ;2 [20] 125 | 126 | unstuff1: ;1 (branch taken) 127 | mov x2, x1 ;1 [21] x1 contains last sampled (stuffed) bit 128 | andi x3, ~0x02 ;1 [22] 129 | ori shift, 0x02 ;1 [23] 130 | nop ;1 [24] 131 | in x1, USBIN ;1 [25] <-- sample bit 2 again 132 | rjmp didUnstuff1 ;2 [27] 133 | 134 | unstuff2: ;1 (branch taken) 135 | andi x3, ~0x04 ;1 [29] 136 | ori shift, 0x04 ;1 [30] 137 | mov x1, x2 ;1 [31] x2 contains last sampled (stuffed) bit 138 | nop ;1 [32] 139 | in x2, USBIN ;1 [33] <-- sample bit 3 140 | rjmp didUnstuff2 ;2 [35] 141 | 142 | unstuff3: ;1 (branch taken) 143 | in x2, USBIN ;1 [34] <-- sample stuffed bit 3 [one cycle too late] 144 | andi x3, ~0x08 ;1 [35] 145 | ori shift, 0x08 ;1 [36] 146 | rjmp didUnstuff3 ;2 [38] 147 | 148 | unstuff4: ;1 (branch taken) 149 | andi x3, ~0x10 ;1 [40] 150 | in x1, USBIN ;1 [41] <-- sample stuffed bit 4 151 | ori shift, 0x10 ;1 [42] 152 | rjmp didUnstuff4 ;2 [44] 153 | 154 | unstuff5: ;1 (branch taken) 155 | andi x3, ~0x20 ;1 [48] 156 | in x2, USBIN ;1 [49] <-- sample stuffed bit 5 157 | ori shift, 0x20 ;1 [50] 158 | rjmp didUnstuff5 ;2 [52] 159 | 160 | unstuff6: ;1 (branch taken) 161 | andi x3, ~0x40 ;1 [56] 162 | in x1, USBIN ;1 [57] <-- sample stuffed bit 6 163 | ori shift, 0x40 ;1 [58] 164 | rjmp didUnstuff6 ;2 [60] 165 | 166 | ; extra jobs done during bit interval: 167 | ; bit 0: store, clear [SE0 is unreliable here due to bit dribbling in hubs] 168 | ; bit 1: se0 check 169 | ; bit 2: overflow check 170 | ; bit 3: recovery from delay [bit 0 tasks took too long] 171 | ; bit 4: none 172 | ; bit 5: none 173 | ; bit 6: none 174 | ; bit 7: jump, eor 175 | rxLoop: 176 | eor x3, shift ;1 [0] reconstruct: x3 is 0 at bit locations we changed, 1 at others 177 | in x1, USBIN ;1 [1] <-- sample bit 0 178 | st y+, x3 ;2 [3] store data 179 | ser x3 ;1 [4] 180 | nop ;1 [5] 181 | eor x2, x1 ;1 [6] 182 | bst x2, USBMINUS;1 [7] 183 | bld shift, 0 ;1 [8] 184 | in x2, USBIN ;1 [9] <-- sample bit 1 (or possibly bit 0 stuffed) 185 | andi x2, USBMASK ;1 [10] 186 | breq se0 ;1 [11] SE0 check for bit 1 187 | andi shift, 0xf9 ;1 [12] 188 | didUnstuff0: 189 | breq unstuff0 ;1 [13] 190 | eor x1, x2 ;1 [14] 191 | bst x1, USBMINUS;1 [15] 192 | bld shift, 1 ;1 [16] 193 | rxbit2: 194 | in x1, USBIN ;1 [17] <-- sample bit 2 (or possibly bit 1 stuffed) 195 | andi shift, 0xf3 ;1 [18] 196 | breq unstuff1 ;1 [19] do remaining work for bit 1 197 | didUnstuff1: 198 | subi cnt, 1 ;1 [20] 199 | brcs overflow ;1 [21] loop control 200 | eor x2, x1 ;1 [22] 201 | bst x2, USBMINUS;1 [23] 202 | bld shift, 2 ;1 [24] 203 | in x2, USBIN ;1 [25] <-- sample bit 3 (or possibly bit 2 stuffed) 204 | andi shift, 0xe7 ;1 [26] 205 | breq unstuff2 ;1 [27] 206 | didUnstuff2: 207 | eor x1, x2 ;1 [28] 208 | bst x1, USBMINUS;1 [29] 209 | bld shift, 3 ;1 [30] 210 | didUnstuff3: 211 | andi shift, 0xcf ;1 [31] 212 | breq unstuff3 ;1 [32] 213 | in x1, USBIN ;1 [33] <-- sample bit 4 214 | eor x2, x1 ;1 [34] 215 | bst x2, USBMINUS;1 [35] 216 | bld shift, 4 ;1 [36] 217 | didUnstuff4: 218 | andi shift, 0x9f ;1 [37] 219 | breq unstuff4 ;1 [38] 220 | nop2 ;2 [40] 221 | in x2, USBIN ;1 [41] <-- sample bit 5 222 | eor x1, x2 ;1 [42] 223 | bst x1, USBMINUS;1 [43] 224 | bld shift, 5 ;1 [44] 225 | didUnstuff5: 226 | andi shift, 0x3f ;1 [45] 227 | breq unstuff5 ;1 [46] 228 | nop2 ;2 [48] 229 | in x1, USBIN ;1 [49] <-- sample bit 6 230 | eor x2, x1 ;1 [50] 231 | bst x2, USBMINUS;1 [51] 232 | bld shift, 6 ;1 [52] 233 | didUnstuff6: 234 | cpi shift, 0x02 ;1 [53] 235 | brlo unstuff6 ;1 [54] 236 | nop2 ;2 [56] 237 | in x2, USBIN ;1 [57] <-- sample bit 7 238 | eor x1, x2 ;1 [58] 239 | bst x1, USBMINUS;1 [59] 240 | bld shift, 7 ;1 [60] 241 | didUnstuff7: 242 | cpi shift, 0x04 ;1 [61] 243 | brsh rxLoop ;2 [63] loop control 244 | unstuff7: 245 | andi x3, ~0x80 ;1 [63] 246 | ori shift, 0x80 ;1 [64] 247 | in x2, USBIN ;1 [65] <-- sample stuffed bit 7 248 | nop ;1 [66] 249 | rjmp didUnstuff7 ;2 [68] 250 | 251 | macro POP_STANDARD ; 12 cycles 252 | pop cnt 253 | pop x3 254 | pop x2 255 | pop x1 256 | pop shift 257 | pop YH 258 | endm 259 | macro POP_RETI ; 5 cycles 260 | pop YL 261 | out SREG, YL 262 | pop YL 263 | endm 264 | 265 | #include "asmcommon.inc" 266 | 267 | ;---------------------------------------------------------------------------- 268 | ; Transmitting data 269 | ;---------------------------------------------------------------------------- 270 | 271 | txByteLoop: 272 | txBitloop: 273 | stuffN1Delay: ; [03] 274 | ror shift ;[-5] [11] [59] 275 | brcc doExorN1 ;[-4] [60] 276 | subi x4, 1 ;[-3] 277 | brne commonN1 ;[-2] 278 | lsl shift ;[-1] compensate ror after rjmp stuffDelay 279 | nop ;[00] stuffing consists of just waiting 8 cycles 280 | rjmp stuffN1Delay ;[01] after ror, C bit is reliably clear 281 | 282 | sendNakAndReti: ;0 [-19] 19 cycles until SOP 283 | ldi x3, USBPID_NAK ;1 [-18] 284 | rjmp usbSendX3 ;2 [-16] 285 | sendAckAndReti: ;0 [-19] 19 cycles until SOP 286 | ldi x3, USBPID_ACK ;1 [-18] 287 | rjmp usbSendX3 ;2 [-16] 288 | sendCntAndReti: ;0 [-17] 17 cycles until SOP 289 | mov x3, cnt ;1 [-16] 290 | usbSendX3: ;0 [-16] 291 | ldi YL, 20 ;1 [-15] 'x3' is R20 292 | ldi YH, 0 ;1 [-14] 293 | ldi cnt, 2 ;1 [-13] 294 | ; rjmp usbSendAndReti fallthrough 295 | 296 | ; USB spec says: 297 | ; idle = J 298 | ; J = (D+ = 0), (D- = 1) or USBOUT = 0x01 299 | ; K = (D+ = 1), (D- = 0) or USBOUT = 0x02 300 | ; Spec allows 7.5 bit times from EOP to SOP for replies (= 60 cycles) 301 | 302 | ;usbSend: 303 | ;pointer to data in 'Y' 304 | ;number of bytes in 'cnt' -- including sync byte 305 | ;uses: x1...x2, x4, shift, cnt, Y [x1 = mirror USBOUT, x2 = USBMASK, x4 = bitstuff cnt] 306 | ;Numbers in brackets are time since first bit of sync pattern is sent (start of instruction) 307 | usbSendAndReti: 308 | in x2, USBDDR ;[-12] 12 cycles until SOP 309 | ori x2, USBMASK ;[-11] 310 | sbi USBOUT, USBMINUS ;[-10] prepare idle state; D+ and D- must have been 0 (no pullups) 311 | out USBDDR, x2 ;[-8] <--- acquire bus 312 | in x1, USBOUT ;[-7] port mirror for tx loop 313 | ldi shift, 0x40 ;[-6] sync byte is first byte sent (we enter loop after ror) 314 | ldi x2, USBMASK ;[-5] 315 | push x4 ;[-4] 316 | doExorN1: 317 | eor x1, x2 ;[-2] [06] [62] 318 | ldi x4, 6 ;[-1] [07] [63] 319 | commonN1: 320 | stuffN2Delay: 321 | out USBOUT, x1 ;[00] [08] [64] <--- set bit 322 | ror shift ;[01] 323 | brcc doExorN2 ;[02] 324 | subi x4, 1 ;[03] 325 | brne commonN2 ;[04] 326 | lsl shift ;[05] compensate ror after rjmp stuffDelay 327 | rjmp stuffN2Delay ;[06] after ror, C bit is reliably clear 328 | doExorN2: 329 | eor x1, x2 ;[04] [12] 330 | ldi x4, 6 ;[05] [13] 331 | commonN2: 332 | nop ;[06] [14] 333 | subi cnt, 171 ;[07] [15] trick: (3 * 171) & 0xff = 1 334 | out USBOUT, x1 ;[08] [16] <--- set bit 335 | brcs txBitloop ;[09] [25] [41] 336 | 337 | stuff6Delay: 338 | ror shift ;[42] [50] 339 | brcc doExor6 ;[43] 340 | subi x4, 1 ;[44] 341 | brne common6 ;[45] 342 | lsl shift ;[46] compensate ror after rjmp stuffDelay 343 | nop ;[47] stuffing consists of just waiting 8 cycles 344 | rjmp stuff6Delay ;[48] after ror, C bit is reliably clear 345 | doExor6: 346 | eor x1, x2 ;[45] [53] 347 | ldi x4, 6 ;[46] 348 | common6: 349 | stuff7Delay: 350 | ror shift ;[47] [55] 351 | out USBOUT, x1 ;[48] <--- set bit 352 | brcc doExor7 ;[49] 353 | subi x4, 1 ;[50] 354 | brne common7 ;[51] 355 | lsl shift ;[52] compensate ror after rjmp stuffDelay 356 | rjmp stuff7Delay ;[53] after ror, C bit is reliably clear 357 | doExor7: 358 | eor x1, x2 ;[51] [59] 359 | ldi x4, 6 ;[52] 360 | common7: 361 | ld shift, y+ ;[53] 362 | tst cnt ;[55] 363 | out USBOUT, x1 ;[56] <--- set bit 364 | brne txByteLoop ;[57] 365 | 366 | ;make SE0: 367 | cbr x1, USBMASK ;[58] prepare SE0 [spec says EOP may be 15 to 18 cycles] 368 | lds x2, usbNewDeviceAddr;[59] 369 | lsl x2 ;[61] we compare with left shifted address 370 | subi YL, 2 + 20 ;[62] Only assign address on data packets, not ACK/NAK in x3 371 | sbci YH, 0 ;[63] 372 | out USBOUT, x1 ;[00] <-- out SE0 -- from now 2 bits = 16 cycles until bus idle 373 | ;2006-03-06: moved transfer of new address to usbDeviceAddr from C-Code to asm: 374 | ;set address only after data packet was sent, not after handshake 375 | breq skipAddrAssign ;[01] 376 | sts usbDeviceAddr, x2 ; if not skipped: SE0 is one cycle longer 377 | skipAddrAssign: 378 | ;end of usbDeviceAddress transfer 379 | ldi x2, 1< 10.0 cycles per bit, 80.0 cycles per byte 29 | ; Numbers in brackets are clocks counted from center of last sync bit 30 | ; when instruction starts 31 | 32 | ;---------------------------------------------------------------------------- 33 | ; order of registers pushed: 34 | ; YL, SREG [sofError] YH, shift, x1, x2, x3, bitcnt, cnt, x4 35 | ;---------------------------------------------------------------------------- 36 | USB_INTR_VECTOR: 37 | push YL ;2 push only what is necessary to sync with edge ASAP 38 | in YL, SREG ;1 39 | push YL ;2 40 | ;---------------------------------------------------------------------------- 41 | ; Synchronize with sync pattern: 42 | ; 43 | ; sync byte (D-) pattern LSb to MSb: 01010100 [1 = idle = J, 0 = K] 44 | ; sync up with J to K edge during sync pattern -- use fastest possible loops 45 | ;The first part waits at most 1 bit long since we must be in sync pattern. 46 | ;YL is guarenteed to be < 0x80 because I flag is clear. When we jump to 47 | ;waitForJ, ensure that this prerequisite is met. 48 | waitForJ: 49 | inc YL 50 | sbis USBIN, USBMINUS 51 | brne waitForJ ; just make sure we have ANY timeout 52 | ;------------------------------------------------------------------------------- 53 | ; The following code results in a sampling window of < 1/4 bit 54 | ; which meets the spec. 55 | ;------------------------------------------------------------------------------- 56 | waitForK: ;- 57 | sbis USBIN, USBMINUS ;1 [00] <-- sample 58 | rjmp foundK ;2 [01] 59 | sbis USBIN, USBMINUS ; <-- sample 60 | rjmp foundK 61 | sbis USBIN, USBMINUS ; <-- sample 62 | rjmp foundK 63 | sbis USBIN, USBMINUS ; <-- sample 64 | rjmp foundK 65 | sbis USBIN, USBMINUS ; <-- sample 66 | rjmp foundK 67 | sbis USBIN, USBMINUS ; <-- sample 68 | rjmp foundK 69 | #if USB_COUNT_SOF 70 | lds YL, usbSofCount 71 | inc YL 72 | sts usbSofCount, YL 73 | #endif /* USB_COUNT_SOF */ 74 | #ifdef USB_SOF_HOOK 75 | USB_SOF_HOOK 76 | #endif 77 | rjmp sofError 78 | ;------------------------------------------------------------------------------ 79 | ; {3, 5} after falling D- edge, average delay: 4 cycles [we want 5 for 80 | ; center sampling] 81 | ; we have 1 bit time for setup purposes, then sample again. 82 | ; Numbers in brackets are cycles from center of first sync (double K) 83 | ; bit after the instruction 84 | ;------------------------------------------------------------------------------ 85 | foundK: ;- [02] 86 | lds YL, usbInputBufOffset;2 [03+04] tx loop 87 | push YH ;2 [05+06] 88 | clr YH ;1 [07] 89 | subi YL, lo8(-(usbRxBuf)) ;1 [08] [rx loop init] 90 | sbci YH, hi8(-(usbRxBuf)) ;1 [09] [rx loop init] 91 | push shift ;2 [10+11] 92 | ser shift ;1 [12] 93 | sbis USBIN, USBMINUS ;1 [-1] [13] <--sample:we want two bits K (sample 1 cycle too early) 94 | rjmp haveTwoBitsK ;2 [00] [14] 95 | pop shift ;2 [15+16] undo the push from before 96 | pop YH ;2 [17+18] undo the push from before 97 | rjmp waitForK ;2 [19+20] this was not the end of sync, retry 98 | ; The entire loop from waitForK until rjmp waitForK above must not exceed two 99 | ; bit times (= 20 cycles). 100 | 101 | ;---------------------------------------------------------------------------- 102 | ; push more registers and initialize values while we sample the first bits: 103 | ;---------------------------------------------------------------------------- 104 | haveTwoBitsK: ;- [01] 105 | push x1 ;2 [02+03] 106 | push x2 ;2 [04+05] 107 | push x3 ;2 [06+07] 108 | push bitcnt ;2 [08+09] 109 | in x1, USBIN ;1 [00] [10] <-- sample bit 0 110 | bst x1, USBMINUS ;1 [01] 111 | bld shift, 0 ;1 [02] 112 | push cnt ;2 [03+04] 113 | ldi cnt, USB_BUFSIZE ;1 [05] 114 | push x4 ;2 [06+07] tx loop 115 | rjmp rxLoop ;2 [08] 116 | ;---------------------------------------------------------------------------- 117 | ; Receiver loop (numbers in brackets are cycles within byte after instr) 118 | ;---------------------------------------------------------------------------- 119 | unstuff0: ;- [07] (branch taken) 120 | andi x3, ~0x01 ;1 [08] 121 | mov x1, x2 ;1 [09] x2 contains last sampled (stuffed) bit 122 | in x2, USBIN ;1 [00] [10] <-- sample bit 1 again 123 | andi x2, USBMASK ;1 [01] 124 | breq se0Hop ;1 [02] SE0 check for bit 1 125 | ori shift, 0x01 ;1 [03] 0b00000001 126 | nop ;1 [04] 127 | rjmp didUnstuff0 ;2 [05] 128 | ;----------------------------------------------------- 129 | unstuff1: ;- [05] (branch taken) 130 | mov x2, x1 ;1 [06] x1 contains last sampled (stuffed) bit 131 | andi x3, ~0x02 ;1 [07] 132 | ori shift, 0x02 ;1 [08] 0b00000010 133 | nop ;1 [09] 134 | in x1, USBIN ;1 [00] [10] <-- sample bit 2 again 135 | andi x1, USBMASK ;1 [01] 136 | breq se0Hop ;1 [02] SE0 check for bit 2 137 | rjmp didUnstuff1 ;2 [03] 138 | ;----------------------------------------------------- 139 | unstuff2: ;- [05] (branch taken) 140 | andi x3, ~0x04 ;1 [06] 141 | ori shift, 0x04 ;1 [07] 0b00000100 142 | mov x1, x2 ;1 [08] x2 contains last sampled (stuffed) bit 143 | nop ;1 [09] 144 | in x2, USBIN ;1 [00] [10] <-- sample bit 3 145 | andi x2, USBMASK ;1 [01] 146 | breq se0Hop ;1 [02] SE0 check for bit 3 147 | rjmp didUnstuff2 ;2 [03] 148 | ;----------------------------------------------------- 149 | unstuff3: ;- [00] [10] (branch taken) 150 | in x2, USBIN ;1 [01] [11] <-- sample stuffed bit 3 one cycle too late 151 | andi x2, USBMASK ;1 [02] 152 | breq se0Hop ;1 [03] SE0 check for stuffed bit 3 153 | andi x3, ~0x08 ;1 [04] 154 | ori shift, 0x08 ;1 [05] 0b00001000 155 | rjmp didUnstuff3 ;2 [06] 156 | ;---------------------------------------------------------------------------- 157 | ; extra jobs done during bit interval: 158 | ; 159 | ; bit 0: store, clear [SE0 is unreliable here due to bit dribbling in hubs], 160 | ; overflow check, jump to the head of rxLoop 161 | ; bit 1: SE0 check 162 | ; bit 2: SE0 check, recovery from delay [bit 0 tasks took too long] 163 | ; bit 3: SE0 check, recovery from delay [bit 0 tasks took too long] 164 | ; bit 4: SE0 check, none 165 | ; bit 5: SE0 check, none 166 | ; bit 6: SE0 check, none 167 | ; bit 7: SE0 check, reconstruct: x3 is 0 at bit locations we changed, 1 at others 168 | ;---------------------------------------------------------------------------- 169 | rxLoop: ;- [09] 170 | in x2, USBIN ;1 [00] [10] <-- sample bit 1 (or possibly bit 0 stuffed) 171 | andi x2, USBMASK ;1 [01] 172 | brne SkipSe0Hop ;1 [02] 173 | se0Hop: ;- [02] 174 | rjmp se0 ;2 [03] SE0 check for bit 1 175 | SkipSe0Hop: ;- [03] 176 | ser x3 ;1 [04] 177 | andi shift, 0xf9 ;1 [05] 0b11111001 178 | breq unstuff0 ;1 [06] 179 | didUnstuff0: ;- [06] 180 | eor x1, x2 ;1 [07] 181 | bst x1, USBMINUS ;1 [08] 182 | bld shift, 1 ;1 [09] 183 | in x1, USBIN ;1 [00] [10] <-- sample bit 2 (or possibly bit 1 stuffed) 184 | andi x1, USBMASK ;1 [01] 185 | breq se0Hop ;1 [02] SE0 check for bit 2 186 | andi shift, 0xf3 ;1 [03] 0b11110011 187 | breq unstuff1 ;1 [04] do remaining work for bit 1 188 | didUnstuff1: ;- [04] 189 | eor x2, x1 ;1 [05] 190 | bst x2, USBMINUS ;1 [06] 191 | bld shift, 2 ;1 [07] 192 | nop2 ;2 [08+09] 193 | in x2, USBIN ;1 [00] [10] <-- sample bit 3 (or possibly bit 2 stuffed) 194 | andi x2, USBMASK ;1 [01] 195 | breq se0Hop ;1 [02] SE0 check for bit 3 196 | andi shift, 0xe7 ;1 [03] 0b11100111 197 | breq unstuff2 ;1 [04] 198 | didUnstuff2: ;- [04] 199 | eor x1, x2 ;1 [05] 200 | bst x1, USBMINUS ;1 [06] 201 | bld shift, 3 ;1 [07] 202 | didUnstuff3: ;- [07] 203 | andi shift, 0xcf ;1 [08] 0b11001111 204 | breq unstuff3 ;1 [09] 205 | in x1, USBIN ;1 [00] [10] <-- sample bit 4 206 | andi x1, USBMASK ;1 [01] 207 | breq se0Hop ;1 [02] SE0 check for bit 4 208 | eor x2, x1 ;1 [03] 209 | bst x2, USBMINUS ;1 [04] 210 | bld shift, 4 ;1 [05] 211 | didUnstuff4: ;- [05] 212 | andi shift, 0x9f ;1 [06] 0b10011111 213 | breq unstuff4 ;1 [07] 214 | nop2 ;2 [08+09] 215 | in x2, USBIN ;1 [00] [10] <-- sample bit 5 216 | andi x2, USBMASK ;1 [01] 217 | breq se0 ;1 [02] SE0 check for bit 5 218 | eor x1, x2 ;1 [03] 219 | bst x1, USBMINUS ;1 [04] 220 | bld shift, 5 ;1 [05] 221 | didUnstuff5: ;- [05] 222 | andi shift, 0x3f ;1 [06] 0b00111111 223 | breq unstuff5 ;1 [07] 224 | nop2 ;2 [08+09] 225 | in x1, USBIN ;1 [00] [10] <-- sample bit 6 226 | andi x1, USBMASK ;1 [01] 227 | breq se0 ;1 [02] SE0 check for bit 6 228 | eor x2, x1 ;1 [03] 229 | bst x2, USBMINUS ;1 [04] 230 | bld shift, 6 ;1 [05] 231 | didUnstuff6: ;- [05] 232 | cpi shift, 0x02 ;1 [06] 0b00000010 233 | brlo unstuff6 ;1 [07] 234 | nop2 ;2 [08+09] 235 | in x2, USBIN ;1 [00] [10] <-- sample bit 7 236 | andi x2, USBMASK ;1 [01] 237 | breq se0 ;1 [02] SE0 check for bit 7 238 | eor x1, x2 ;1 [03] 239 | bst x1, USBMINUS ;1 [04] 240 | bld shift, 7 ;1 [05] 241 | didUnstuff7: ;- [05] 242 | cpi shift, 0x04 ;1 [06] 0b00000100 243 | brlo unstuff7 ;1 [07] 244 | eor x3, shift ;1 [08] reconstruct: x3 is 0 at bit locations we changed, 1 at others 245 | nop ;1 [09] 246 | in x1, USBIN ;1 [00] [10] <-- sample bit 0 247 | st y+, x3 ;2 [01+02] store data 248 | eor x2, x1 ;1 [03] 249 | bst x2, USBMINUS ;1 [04] 250 | bld shift, 0 ;1 [05] 251 | subi cnt, 1 ;1 [06] 252 | brcs overflow ;1 [07] 253 | rjmp rxLoop ;2 [08] 254 | ;----------------------------------------------------- 255 | unstuff4: ;- [08] 256 | andi x3, ~0x10 ;1 [09] 257 | in x1, USBIN ;1 [00] [10] <-- sample stuffed bit 4 258 | andi x1, USBMASK ;1 [01] 259 | breq se0 ;1 [02] SE0 check for stuffed bit 4 260 | ori shift, 0x10 ;1 [03] 261 | rjmp didUnstuff4 ;2 [04] 262 | ;----------------------------------------------------- 263 | unstuff5: ;- [08] 264 | ori shift, 0x20 ;1 [09] 265 | in x2, USBIN ;1 [00] [10] <-- sample stuffed bit 5 266 | andi x2, USBMASK ;1 [01] 267 | breq se0 ;1 [02] SE0 check for stuffed bit 5 268 | andi x3, ~0x20 ;1 [03] 269 | rjmp didUnstuff5 ;2 [04] 270 | ;----------------------------------------------------- 271 | unstuff6: ;- [08] 272 | andi x3, ~0x40 ;1 [09] 273 | in x1, USBIN ;1 [00] [10] <-- sample stuffed bit 6 274 | andi x1, USBMASK ;1 [01] 275 | breq se0 ;1 [02] SE0 check for stuffed bit 6 276 | ori shift, 0x40 ;1 [03] 277 | rjmp didUnstuff6 ;2 [04] 278 | ;----------------------------------------------------- 279 | unstuff7: ;- [08] 280 | andi x3, ~0x80 ;1 [09] 281 | in x2, USBIN ;1 [00] [10] <-- sample stuffed bit 7 282 | andi x2, USBMASK ;1 [01] 283 | breq se0 ;1 [02] SE0 check for stuffed bit 7 284 | ori shift, 0x80 ;1 [03] 285 | rjmp didUnstuff7 ;2 [04] 286 | 287 | macro POP_STANDARD ; 16 cycles 288 | pop x4 289 | pop cnt 290 | pop bitcnt 291 | pop x3 292 | pop x2 293 | pop x1 294 | pop shift 295 | pop YH 296 | endm 297 | macro POP_RETI ; 5 cycles 298 | pop YL 299 | out SREG, YL 300 | pop YL 301 | endm 302 | 303 | #include "asmcommon.inc" 304 | 305 | ;--------------------------------------------------------------------------- 306 | ; USB spec says: 307 | ; idle = J 308 | ; J = (D+ = 0), (D- = 1) 309 | ; K = (D+ = 1), (D- = 0) 310 | ; Spec allows 7.5 bit times from EOP to SOP for replies 311 | ;--------------------------------------------------------------------------- 312 | bitstuffN: ;- [04] 313 | eor x1, x4 ;1 [05] 314 | clr x2 ;1 [06] 315 | nop ;1 [07] 316 | rjmp didStuffN ;1 [08] 317 | ;--------------------------------------------------------------------------- 318 | bitstuff6: ;- [04] 319 | eor x1, x4 ;1 [05] 320 | clr x2 ;1 [06] 321 | rjmp didStuff6 ;1 [07] 322 | ;--------------------------------------------------------------------------- 323 | bitstuff7: ;- [02] 324 | eor x1, x4 ;1 [03] 325 | clr x2 ;1 [06] 326 | nop ;1 [05] 327 | rjmp didStuff7 ;1 [06] 328 | ;--------------------------------------------------------------------------- 329 | sendNakAndReti: ;- [-19] 330 | ldi x3, USBPID_NAK ;1 [-18] 331 | rjmp sendX3AndReti ;1 [-17] 332 | ;--------------------------------------------------------------------------- 333 | sendAckAndReti: ;- [-17] 334 | ldi cnt, USBPID_ACK ;1 [-16] 335 | sendCntAndReti: ;- [-16] 336 | mov x3, cnt ;1 [-15] 337 | sendX3AndReti: ;- [-15] 338 | ldi YL, 20 ;1 [-14] x3==r20 address is 20 339 | ldi YH, 0 ;1 [-13] 340 | ldi cnt, 2 ;1 [-12] 341 | ; rjmp usbSendAndReti fallthrough 342 | ;--------------------------------------------------------------------------- 343 | ;usbSend: 344 | ;pointer to data in 'Y' 345 | ;number of bytes in 'cnt' -- including sync byte [range 2 ... 12] 346 | ;uses: x1...x4, btcnt, shift, cnt, Y 347 | ;Numbers in brackets are time since first bit of sync pattern is sent 348 | ;We need not to match the transfer rate exactly because the spec demands 349 | ;only 1.5% precision anyway. 350 | usbSendAndReti: ;- [-13] 13 cycles until SOP 351 | in x2, USBDDR ;1 [-12] 352 | ori x2, USBMASK ;1 [-11] 353 | sbi USBOUT, USBMINUS ;2 [-09-10] prepare idle state; D+ and D- must have been 0 (no pullups) 354 | in x1, USBOUT ;1 [-08] port mirror for tx loop 355 | out USBDDR, x2 ;1 [-07] <- acquire bus 356 | ; need not init x2 (bitstuff history) because sync starts with 0 357 | ldi x4, USBMASK ;1 [-06] exor mask 358 | ldi shift, 0x80 ;1 [-05] sync byte is first byte sent 359 | ldi bitcnt, 6 ;1 [-04] 360 | txBitLoop: ;- [-04] [06] 361 | sbrs shift, 0 ;1 [-03] [07] 362 | eor x1, x4 ;1 [-02] [08] 363 | ror shift ;1 [-01] [09] 364 | didStuffN: ;- [09] 365 | out USBOUT, x1 ;1 [00] [10] <-- out N 366 | ror x2 ;1 [01] 367 | cpi x2, 0xfc ;1 [02] 368 | brcc bitstuffN ;1 [03] 369 | dec bitcnt ;1 [04] 370 | brne txBitLoop ;1 [05] 371 | sbrs shift, 0 ;1 [06] 372 | eor x1, x4 ;1 [07] 373 | ror shift ;1 [08] 374 | didStuff6: ;- [08] 375 | nop ;1 [09] 376 | out USBOUT, x1 ;1 [00] [10] <-- out 6 377 | ror x2 ;1 [01] 378 | cpi x2, 0xfc ;1 [02] 379 | brcc bitstuff6 ;1 [03] 380 | sbrs shift, 0 ;1 [04] 381 | eor x1, x4 ;1 [05] 382 | ror shift ;1 [06] 383 | ror x2 ;1 [07] 384 | didStuff7: ;- [07] 385 | ldi bitcnt, 6 ;1 [08] 386 | cpi x2, 0xfc ;1 [09] 387 | out USBOUT, x1 ;1 [00] [10] <-- out 7 388 | brcc bitstuff7 ;1 [01] 389 | ld shift, y+ ;2 [02+03] 390 | dec cnt ;1 [04] 391 | brne txBitLoop ;1 [05] 392 | makeSE0: 393 | cbr x1, USBMASK ;1 [06] prepare SE0 [spec says EOP may be 19 to 23 cycles] 394 | lds x2, usbNewDeviceAddr;2 [07+08] 395 | lsl x2 ;1 [09] we compare with left shifted address 396 | ;2006-03-06: moved transfer of new address to usbDeviceAddr from C-Code to asm: 397 | ;set address only after data packet was sent, not after handshake 398 | out USBOUT, x1 ;1 [00] [10] <-- out SE0-- from now 2 bits==20 cycl. until bus idle 399 | subi YL, 20 + 2 ;1 [01] Only assign address on data packets, not ACK/NAK in x3 400 | sbci YH, 0 ;1 [02] 401 | breq skipAddrAssign ;1 [03] 402 | sts usbDeviceAddr, x2 ;2 [04+05] if not skipped: SE0 is one cycle longer 403 | ;---------------------------------------------------------------------------- 404 | ;end of usbDeviceAddress transfer 405 | skipAddrAssign: ;- [03/04] 406 | ldi x2, 1< 10.6666666 cycles per bit, 85.333333333 cycles per byte 29 | ; Numbers in brackets are clocks counted from center of last sync bit 30 | ; when instruction starts 31 | 32 | USB_INTR_VECTOR: 33 | ;order of registers pushed: YL, SREG YH, [sofError], bitcnt, shift, x1, x2, x3, x4, cnt 34 | push YL ;[-25] push only what is necessary to sync with edge ASAP 35 | in YL, SREG ;[-23] 36 | push YL ;[-22] 37 | push YH ;[-20] 38 | ;---------------------------------------------------------------------------- 39 | ; Synchronize with sync pattern: 40 | ;---------------------------------------------------------------------------- 41 | ;sync byte (D-) pattern LSb to MSb: 01010100 [1 = idle = J, 0 = K] 42 | ;sync up with J to K edge during sync pattern -- use fastest possible loops 43 | ;The first part waits at most 1 bit long since we must be in sync pattern. 44 | ;YL is guarenteed to be < 0x80 because I flag is clear. When we jump to 45 | ;waitForJ, ensure that this prerequisite is met. 46 | waitForJ: 47 | inc YL 48 | sbis USBIN, USBMINUS 49 | brne waitForJ ; just make sure we have ANY timeout 50 | waitForK: 51 | ;The following code results in a sampling window of < 1/4 bit which meets the spec. 52 | sbis USBIN, USBMINUS ;[-15] 53 | rjmp foundK ;[-14] 54 | sbis USBIN, USBMINUS 55 | rjmp foundK 56 | sbis USBIN, USBMINUS 57 | rjmp foundK 58 | sbis USBIN, USBMINUS 59 | rjmp foundK 60 | sbis USBIN, USBMINUS 61 | rjmp foundK 62 | sbis USBIN, USBMINUS 63 | rjmp foundK 64 | #if USB_COUNT_SOF 65 | lds YL, usbSofCount 66 | inc YL 67 | sts usbSofCount, YL 68 | #endif /* USB_COUNT_SOF */ 69 | #ifdef USB_SOF_HOOK 70 | USB_SOF_HOOK 71 | #endif 72 | rjmp sofError 73 | foundK: ;[-12] 74 | ;{3, 5} after falling D- edge, average delay: 4 cycles [we want 5 for center sampling] 75 | ;we have 1 bit time for setup purposes, then sample again. Numbers in brackets 76 | ;are cycles from center of first sync (double K) bit after the instruction 77 | push bitcnt ;[-12] 78 | ; [---] ;[-11] 79 | lds YL, usbInputBufOffset;[-10] 80 | ; [---] ;[-9] 81 | clr YH ;[-8] 82 | subi YL, lo8(-(usbRxBuf));[-7] [rx loop init] 83 | sbci YH, hi8(-(usbRxBuf));[-6] [rx loop init] 84 | push shift ;[-5] 85 | ; [---] ;[-4] 86 | ldi bitcnt, 0x55 ;[-3] [rx loop init] 87 | sbis USBIN, USBMINUS ;[-2] we want two bits K (sample 2 cycles too early) 88 | rjmp haveTwoBitsK ;[-1] 89 | pop shift ;[0] undo the push from before 90 | pop bitcnt ;[2] undo the push from before 91 | rjmp waitForK ;[4] this was not the end of sync, retry 92 | ; The entire loop from waitForK until rjmp waitForK above must not exceed two 93 | ; bit times (= 21 cycles). 94 | 95 | ;---------------------------------------------------------------------------- 96 | ; push more registers and initialize values while we sample the first bits: 97 | ;---------------------------------------------------------------------------- 98 | haveTwoBitsK: 99 | push x1 ;[1] 100 | push x2 ;[3] 101 | push x3 ;[5] 102 | ldi shift, 0 ;[7] 103 | ldi x3, 1<<4 ;[8] [rx loop init] first sample is inverse bit, compensate that 104 | push x4 ;[9] == leap 105 | 106 | in x1, USBIN ;[11] <-- sample bit 0 107 | andi x1, USBMASK ;[12] 108 | bst x1, USBMINUS ;[13] 109 | bld shift, 7 ;[14] 110 | push cnt ;[15] 111 | ldi leap, 0 ;[17] [rx loop init] 112 | ldi cnt, USB_BUFSIZE;[18] [rx loop init] 113 | rjmp rxbit1 ;[19] arrives at [21] 114 | 115 | ;---------------------------------------------------------------------------- 116 | ; Receiver loop (numbers in brackets are cycles within byte after instr) 117 | ;---------------------------------------------------------------------------- 118 | 119 | ; duration of unstuffing code should be 10.66666667 cycles. We adjust "leap" 120 | ; accordingly to approximate this value in the long run. 121 | 122 | unstuff6: 123 | andi x2, USBMASK ;[03] 124 | ori x3, 1<<6 ;[04] will not be shifted any more 125 | andi shift, ~0x80;[05] 126 | mov x1, x2 ;[06] sampled bit 7 is actually re-sampled bit 6 127 | subi leap, -1 ;[07] total duration = 11 bits -> subtract 1/3 128 | rjmp didUnstuff6 ;[08] 129 | 130 | unstuff7: 131 | ori x3, 1<<7 ;[09] will not be shifted any more 132 | in x2, USBIN ;[00] [10] re-sample bit 7 133 | andi x2, USBMASK ;[01] 134 | andi shift, ~0x80;[02] 135 | subi leap, 2 ;[03] total duration = 10 bits -> add 1/3 136 | rjmp didUnstuff7 ;[04] 137 | 138 | unstuffEven: 139 | ori x3, 1<<6 ;[09] will be shifted right 6 times for bit 0 140 | in x1, USBIN ;[00] [10] 141 | andi shift, ~0x80;[01] 142 | andi x1, USBMASK ;[02] 143 | breq se0 ;[03] 144 | subi leap, -1 ;[04] total duration = 11 bits -> subtract 1/3 145 | nop2 ;[05] 146 | rjmp didUnstuffE ;[06] 147 | 148 | unstuffOdd: 149 | ori x3, 1<<5 ;[09] will be shifted right 4 times for bit 1 150 | in x2, USBIN ;[00] [10] 151 | andi shift, ~0x80;[01] 152 | andi x2, USBMASK ;[02] 153 | breq se0 ;[03] 154 | subi leap, -1 ;[04] total duration = 11 bits -> subtract 1/3 155 | nop2 ;[05] 156 | rjmp didUnstuffO ;[06] 157 | 158 | rxByteLoop: 159 | andi x1, USBMASK ;[03] 160 | eor x2, x1 ;[04] 161 | subi leap, 1 ;[05] 162 | brpl skipLeap ;[06] 163 | subi leap, -3 ;1 one leap cycle every 3rd byte -> 85 + 1/3 cycles per byte 164 | nop ;1 165 | skipLeap: 166 | subi x2, 1 ;[08] 167 | ror shift ;[09] 168 | didUnstuff6: 169 | cpi shift, 0xfc ;[10] 170 | in x2, USBIN ;[00] [11] <-- sample bit 7 171 | brcc unstuff6 ;[01] 172 | andi x2, USBMASK ;[02] 173 | eor x1, x2 ;[03] 174 | subi x1, 1 ;[04] 175 | ror shift ;[05] 176 | didUnstuff7: 177 | cpi shift, 0xfc ;[06] 178 | brcc unstuff7 ;[07] 179 | eor x3, shift ;[08] reconstruct: x3 is 1 at bit locations we changed, 0 at others 180 | st y+, x3 ;[09] store data 181 | rxBitLoop: 182 | in x1, USBIN ;[00] [11] <-- sample bit 0/2/4 183 | andi x1, USBMASK ;[01] 184 | eor x2, x1 ;[02] 185 | andi x3, 0x3f ;[03] topmost two bits reserved for 6 and 7 186 | subi x2, 1 ;[04] 187 | ror shift ;[05] 188 | cpi shift, 0xfc ;[06] 189 | brcc unstuffEven ;[07] 190 | didUnstuffE: 191 | lsr x3 ;[08] 192 | lsr x3 ;[09] 193 | rxbit1: 194 | in x2, USBIN ;[00] [10] <-- sample bit 1/3/5 195 | andi x2, USBMASK ;[01] 196 | breq se0 ;[02] 197 | eor x1, x2 ;[03] 198 | subi x1, 1 ;[04] 199 | ror shift ;[05] 200 | cpi shift, 0xfc ;[06] 201 | brcc unstuffOdd ;[07] 202 | didUnstuffO: 203 | subi bitcnt, 0xab;[08] == addi 0x55, 0x55 = 0x100/3 204 | brcs rxBitLoop ;[09] 205 | 206 | subi cnt, 1 ;[10] 207 | in x1, USBIN ;[00] [11] <-- sample bit 6 208 | brcc rxByteLoop ;[01] 209 | rjmp overflow 210 | 211 | macro POP_STANDARD ; 14 cycles 212 | pop cnt 213 | pop x4 214 | pop x3 215 | pop x2 216 | pop x1 217 | pop shift 218 | pop bitcnt 219 | endm 220 | macro POP_RETI ; 7 cycles 221 | pop YH 222 | pop YL 223 | out SREG, YL 224 | pop YL 225 | endm 226 | 227 | #include "asmcommon.inc" 228 | 229 | ; USB spec says: 230 | ; idle = J 231 | ; J = (D+ = 0), (D- = 1) 232 | ; K = (D+ = 1), (D- = 0) 233 | ; Spec allows 7.5 bit times from EOP to SOP for replies 234 | 235 | bitstuffN: 236 | eor x1, x4 ;[5] 237 | ldi x2, 0 ;[6] 238 | nop2 ;[7] 239 | nop ;[9] 240 | out USBOUT, x1 ;[10] <-- out 241 | rjmp didStuffN ;[0] 242 | 243 | bitstuff6: 244 | eor x1, x4 ;[5] 245 | ldi x2, 0 ;[6] Carry is zero due to brcc 246 | rol shift ;[7] compensate for ror shift at branch destination 247 | rjmp didStuff6 ;[8] 248 | 249 | bitstuff7: 250 | ldi x2, 0 ;[2] Carry is zero due to brcc 251 | rjmp didStuff7 ;[3] 252 | 253 | 254 | sendNakAndReti: 255 | ldi x3, USBPID_NAK ;[-18] 256 | rjmp sendX3AndReti ;[-17] 257 | sendAckAndReti: 258 | ldi cnt, USBPID_ACK ;[-17] 259 | sendCntAndReti: 260 | mov x3, cnt ;[-16] 261 | sendX3AndReti: 262 | ldi YL, 20 ;[-15] x3==r20 address is 20 263 | ldi YH, 0 ;[-14] 264 | ldi cnt, 2 ;[-13] 265 | ; rjmp usbSendAndReti fallthrough 266 | 267 | ;usbSend: 268 | ;pointer to data in 'Y' 269 | ;number of bytes in 'cnt' -- including sync byte [range 2 ... 12] 270 | ;uses: x1...x4, btcnt, shift, cnt, Y 271 | ;Numbers in brackets are time since first bit of sync pattern is sent 272 | ;We don't match the transfer rate exactly (don't insert leap cycles every third 273 | ;byte) because the spec demands only 1.5% precision anyway. 274 | usbSendAndReti: ; 12 cycles until SOP 275 | in x2, USBDDR ;[-12] 276 | ori x2, USBMASK ;[-11] 277 | sbi USBOUT, USBMINUS;[-10] prepare idle state; D+ and D- must have been 0 (no pullups) 278 | in x1, USBOUT ;[-8] port mirror for tx loop 279 | out USBDDR, x2 ;[-7] <- acquire bus 280 | ; need not init x2 (bitstuff history) because sync starts with 0 281 | ldi x4, USBMASK ;[-6] exor mask 282 | ldi shift, 0x80 ;[-5] sync byte is first byte sent 283 | txByteLoop: 284 | ldi bitcnt, 0x35 ;[-4] [6] binary 0011 0101 285 | txBitLoop: 286 | sbrs shift, 0 ;[-3] [7] 287 | eor x1, x4 ;[-2] [8] 288 | out USBOUT, x1 ;[-1] [9] <-- out N 289 | ror shift ;[0] [10] 290 | ror x2 ;[1] 291 | didStuffN: 292 | cpi x2, 0xfc ;[2] 293 | brcc bitstuffN ;[3] 294 | lsr bitcnt ;[4] 295 | brcc txBitLoop ;[5] 296 | brne txBitLoop ;[6] 297 | 298 | sbrs shift, 0 ;[7] 299 | eor x1, x4 ;[8] 300 | didStuff6: 301 | out USBOUT, x1 ;[-1] [9] <-- out 6 302 | ror shift ;[0] [10] 303 | ror x2 ;[1] 304 | cpi x2, 0xfc ;[2] 305 | brcc bitstuff6 ;[3] 306 | ror shift ;[4] 307 | didStuff7: 308 | ror x2 ;[5] 309 | sbrs x2, 7 ;[6] 310 | eor x1, x4 ;[7] 311 | nop ;[8] 312 | cpi x2, 0xfc ;[9] 313 | out USBOUT, x1 ;[-1][10] <-- out 7 314 | brcc bitstuff7 ;[0] [11] 315 | ld shift, y+ ;[1] 316 | dec cnt ;[3] 317 | brne txByteLoop ;[4] 318 | ;make SE0: 319 | cbr x1, USBMASK ;[5] prepare SE0 [spec says EOP may be 21 to 25 cycles] 320 | lds x2, usbNewDeviceAddr;[6] 321 | lsl x2 ;[8] we compare with left shifted address 322 | subi YL, 20 + 2 ;[9] Only assign address on data packets, not ACK/NAK in x3 323 | sbci YH, 0 ;[10] 324 | out USBOUT, x1 ;[11] <-- out SE0 -- from now 2 bits = 22 cycles until bus idle 325 | ;2006-03-06: moved transfer of new address to usbDeviceAddr from C-Code to asm: 326 | ;set address only after data packet was sent, not after handshake 327 | breq skipAddrAssign ;[0] 328 | sts usbDeviceAddr, x2; if not skipped: SE0 is one cycle longer 329 | skipAddrAssign: 330 | ;end of usbDeviceAddress transfer 331 | ldi x2, 1< max 52 cycles interrupt disable 31 | ;max stack usage: [ret(2), r0, SREG, YL, YH, shift, x1, x2, x3, x4, cnt] = 12 bytes 32 | ;nominal frequency: 16.5 MHz -> 11 cycles per bit 33 | ; 16.3125 MHz < F_CPU < 16.6875 MHz (+/- 1.1%) 34 | ; Numbers in brackets are clocks counted from center of last sync bit 35 | ; when instruction starts 36 | 37 | 38 | USB_INTR_VECTOR: 39 | ;order of registers pushed: YL, SREG [sofError], r0, YH, shift, x1, x2, x3, x4, cnt 40 | push YL ;[-23] push only what is necessary to sync with edge ASAP 41 | in YL, SREG ;[-21] 42 | push YL ;[-20] 43 | ;---------------------------------------------------------------------------- 44 | ; Synchronize with sync pattern: 45 | ;---------------------------------------------------------------------------- 46 | ;sync byte (D-) pattern LSb to MSb: 01010100 [1 = idle = J, 0 = K] 47 | ;sync up with J to K edge during sync pattern -- use fastest possible loops 48 | ;The first part waits at most 1 bit long since we must be in sync pattern. 49 | ;YL is guarenteed to be < 0x80 because I flag is clear. When we jump to 50 | ;waitForJ, ensure that this prerequisite is met. 51 | waitForJ: 52 | inc YL 53 | sbis USBIN, USBMINUS 54 | brne waitForJ ; just make sure we have ANY timeout 55 | waitForK: 56 | ;The following code results in a sampling window of < 1/4 bit which meets the spec. 57 | sbis USBIN, USBMINUS ;[-15] 58 | rjmp foundK ;[-14] 59 | sbis USBIN, USBMINUS 60 | rjmp foundK 61 | sbis USBIN, USBMINUS 62 | rjmp foundK 63 | sbis USBIN, USBMINUS 64 | rjmp foundK 65 | sbis USBIN, USBMINUS 66 | rjmp foundK 67 | sbis USBIN, USBMINUS 68 | rjmp foundK 69 | #if USB_COUNT_SOF 70 | lds YL, usbSofCount 71 | inc YL 72 | sts usbSofCount, YL 73 | #endif /* USB_COUNT_SOF */ 74 | #ifdef USB_SOF_HOOK 75 | USB_SOF_HOOK 76 | #endif 77 | rjmp sofError 78 | foundK: ;[-12] 79 | ;{3, 5} after falling D- edge, average delay: 4 cycles [we want 5 for center sampling] 80 | ;we have 1 bit time for setup purposes, then sample again. Numbers in brackets 81 | ;are cycles from center of first sync (double K) bit after the instruction 82 | push r0 ;[-12] 83 | ; [---] ;[-11] 84 | push YH ;[-10] 85 | ; [---] ;[-9] 86 | lds YL, usbInputBufOffset;[-8] 87 | ; [---] ;[-7] 88 | clr YH ;[-6] 89 | subi YL, lo8(-(usbRxBuf));[-5] [rx loop init] 90 | sbci YH, hi8(-(usbRxBuf));[-4] [rx loop init] 91 | mov r0, x2 ;[-3] [rx loop init] 92 | sbis USBIN, USBMINUS ;[-2] we want two bits K (sample 2 cycles too early) 93 | rjmp haveTwoBitsK ;[-1] 94 | pop YH ;[0] undo the pushes from before 95 | pop r0 ;[2] 96 | rjmp waitForK ;[4] this was not the end of sync, retry 97 | ; The entire loop from waitForK until rjmp waitForK above must not exceed two 98 | ; bit times (= 22 cycles). 99 | 100 | ;---------------------------------------------------------------------------- 101 | ; push more registers and initialize values while we sample the first bits: 102 | ;---------------------------------------------------------------------------- 103 | haveTwoBitsK: ;[1] 104 | push shift ;[1] 105 | push x1 ;[3] 106 | push x2 ;[5] 107 | push x3 ;[7] 108 | ldi shift, 0xff ;[9] [rx loop init] 109 | ori x3, 0xff ;[10] [rx loop init] == ser x3, clear zero flag 110 | 111 | in x1, USBIN ;[11] <-- sample bit 0 112 | bst x1, USBMINUS ;[12] 113 | bld shift, 0 ;[13] 114 | push x4 ;[14] == phase 115 | ; [---] ;[15] 116 | push cnt ;[16] 117 | ; [---] ;[17] 118 | ldi phase, 0 ;[18] [rx loop init] 119 | ldi cnt, USB_BUFSIZE;[19] [rx loop init] 120 | rjmp rxbit1 ;[20] 121 | ; [---] ;[21] 122 | 123 | ;---------------------------------------------------------------------------- 124 | ; Receiver loop (numbers in brackets are cycles within byte after instr) 125 | ;---------------------------------------------------------------------------- 126 | /* 127 | byte oriented operations done during loop: 128 | bit 0: store data 129 | bit 1: SE0 check 130 | bit 2: overflow check 131 | bit 3: catch up 132 | bit 4: rjmp to achieve conditional jump range 133 | bit 5: PLL 134 | bit 6: catch up 135 | bit 7: jump, fixup bitstuff 136 | ; 87 [+ 2] cycles 137 | ------------------------------------------------------------------ 138 | */ 139 | continueWithBit5: 140 | in x2, USBIN ;[055] <-- bit 5 141 | eor r0, x2 ;[056] 142 | or phase, r0 ;[057] 143 | sbrc phase, USBMINUS ;[058] 144 | lpm ;[059] optional nop3; modifies r0 145 | in phase, USBIN ;[060] <-- phase 146 | eor x1, x2 ;[061] 147 | bst x1, USBMINUS ;[062] 148 | bld shift, 5 ;[063] 149 | andi shift, 0x3f ;[064] 150 | in x1, USBIN ;[065] <-- bit 6 151 | breq unstuff5 ;[066] *** unstuff escape 152 | eor phase, x1 ;[067] 153 | eor x2, x1 ;[068] 154 | bst x2, USBMINUS ;[069] 155 | bld shift, 6 ;[070] 156 | didUnstuff6: ;[ ] 157 | in r0, USBIN ;[071] <-- phase 158 | cpi shift, 0x02 ;[072] 159 | brlo unstuff6 ;[073] *** unstuff escape 160 | didUnstuff5: ;[ ] 161 | nop2 ;[074] 162 | ; [---] ;[075] 163 | in x2, USBIN ;[076] <-- bit 7 164 | eor x1, x2 ;[077] 165 | bst x1, USBMINUS ;[078] 166 | bld shift, 7 ;[079] 167 | didUnstuff7: ;[ ] 168 | eor r0, x2 ;[080] 169 | or phase, r0 ;[081] 170 | in r0, USBIN ;[082] <-- phase 171 | cpi shift, 0x04 ;[083] 172 | brsh rxLoop ;[084] 173 | ; [---] ;[085] 174 | unstuff7: ;[ ] 175 | andi x3, ~0x80 ;[085] 176 | ori shift, 0x80 ;[086] 177 | in x2, USBIN ;[087] <-- sample stuffed bit 7 178 | nop ;[088] 179 | rjmp didUnstuff7 ;[089] 180 | ; [---] ;[090] 181 | ;[080] 182 | 183 | unstuff5: ;[067] 184 | eor phase, x1 ;[068] 185 | andi x3, ~0x20 ;[069] 186 | ori shift, 0x20 ;[070] 187 | in r0, USBIN ;[071] <-- phase 188 | mov x2, x1 ;[072] 189 | nop ;[073] 190 | nop2 ;[074] 191 | ; [---] ;[075] 192 | in x1, USBIN ;[076] <-- bit 6 193 | eor r0, x1 ;[077] 194 | or phase, r0 ;[078] 195 | eor x2, x1 ;[079] 196 | bst x2, USBMINUS ;[080] 197 | bld shift, 6 ;[081] no need to check bitstuffing, we just had one 198 | in r0, USBIN ;[082] <-- phase 199 | rjmp didUnstuff5 ;[083] 200 | ; [---] ;[084] 201 | ;[074] 202 | 203 | unstuff6: ;[074] 204 | andi x3, ~0x40 ;[075] 205 | in x1, USBIN ;[076] <-- bit 6 again 206 | ori shift, 0x40 ;[077] 207 | nop2 ;[078] 208 | ; [---] ;[079] 209 | rjmp didUnstuff6 ;[080] 210 | ; [---] ;[081] 211 | ;[071] 212 | 213 | unstuff0: ;[013] 214 | eor r0, x2 ;[014] 215 | or phase, r0 ;[015] 216 | andi x2, USBMASK ;[016] check for SE0 217 | in r0, USBIN ;[017] <-- phase 218 | breq didUnstuff0 ;[018] direct jump to se0 would be too long 219 | andi x3, ~0x01 ;[019] 220 | ori shift, 0x01 ;[020] 221 | mov x1, x2 ;[021] mov existing sample 222 | in x2, USBIN ;[022] <-- bit 1 again 223 | rjmp didUnstuff0 ;[023] 224 | ; [---] ;[024] 225 | ;[014] 226 | 227 | unstuff1: ;[024] 228 | eor r0, x1 ;[025] 229 | or phase, r0 ;[026] 230 | andi x3, ~0x02 ;[027] 231 | in r0, USBIN ;[028] <-- phase 232 | ori shift, 0x02 ;[029] 233 | mov x2, x1 ;[030] 234 | rjmp didUnstuff1 ;[031] 235 | ; [---] ;[032] 236 | ;[022] 237 | 238 | unstuff2: ;[035] 239 | eor r0, x2 ;[036] 240 | or phase, r0 ;[037] 241 | andi x3, ~0x04 ;[038] 242 | in r0, USBIN ;[039] <-- phase 243 | ori shift, 0x04 ;[040] 244 | mov x1, x2 ;[041] 245 | rjmp didUnstuff2 ;[042] 246 | ; [---] ;[043] 247 | ;[033] 248 | 249 | unstuff3: ;[043] 250 | in x2, USBIN ;[044] <-- bit 3 again 251 | eor r0, x2 ;[045] 252 | or phase, r0 ;[046] 253 | andi x3, ~0x08 ;[047] 254 | ori shift, 0x08 ;[048] 255 | nop ;[049] 256 | in r0, USBIN ;[050] <-- phase 257 | rjmp didUnstuff3 ;[051] 258 | ; [---] ;[052] 259 | ;[042] 260 | 261 | unstuff4: ;[053] 262 | andi x3, ~0x10 ;[054] 263 | in x1, USBIN ;[055] <-- bit 4 again 264 | ori shift, 0x10 ;[056] 265 | rjmp didUnstuff4 ;[057] 266 | ; [---] ;[058] 267 | ;[048] 268 | 269 | rxLoop: ;[085] 270 | eor x3, shift ;[086] reconstruct: x3 is 0 at bit locations we changed, 1 at others 271 | in x1, USBIN ;[000] <-- bit 0 272 | st y+, x3 ;[001] 273 | ; [---] ;[002] 274 | eor r0, x1 ;[003] 275 | or phase, r0 ;[004] 276 | eor x2, x1 ;[005] 277 | in r0, USBIN ;[006] <-- phase 278 | ser x3 ;[007] 279 | bst x2, USBMINUS ;[008] 280 | bld shift, 0 ;[009] 281 | andi shift, 0xf9 ;[010] 282 | rxbit1: ;[ ] 283 | in x2, USBIN ;[011] <-- bit 1 284 | breq unstuff0 ;[012] *** unstuff escape 285 | andi x2, USBMASK ;[013] SE0 check for bit 1 286 | didUnstuff0: ;[ ] Z only set if we detected SE0 in bitstuff 287 | breq se0 ;[014] 288 | eor r0, x2 ;[015] 289 | or phase, r0 ;[016] 290 | in r0, USBIN ;[017] <-- phase 291 | eor x1, x2 ;[018] 292 | bst x1, USBMINUS ;[019] 293 | bld shift, 1 ;[020] 294 | andi shift, 0xf3 ;[021] 295 | didUnstuff1: ;[ ] 296 | in x1, USBIN ;[022] <-- bit 2 297 | breq unstuff1 ;[023] *** unstuff escape 298 | eor r0, x1 ;[024] 299 | or phase, r0 ;[025] 300 | subi cnt, 1 ;[026] overflow check 301 | brcs overflow ;[027] 302 | in r0, USBIN ;[028] <-- phase 303 | eor x2, x1 ;[029] 304 | bst x2, USBMINUS ;[030] 305 | bld shift, 2 ;[031] 306 | andi shift, 0xe7 ;[032] 307 | didUnstuff2: ;[ ] 308 | in x2, USBIN ;[033] <-- bit 3 309 | breq unstuff2 ;[034] *** unstuff escape 310 | eor r0, x2 ;[035] 311 | or phase, r0 ;[036] 312 | eor x1, x2 ;[037] 313 | bst x1, USBMINUS ;[038] 314 | in r0, USBIN ;[039] <-- phase 315 | bld shift, 3 ;[040] 316 | andi shift, 0xcf ;[041] 317 | didUnstuff3: ;[ ] 318 | breq unstuff3 ;[042] *** unstuff escape 319 | nop ;[043] 320 | in x1, USBIN ;[044] <-- bit 4 321 | eor x2, x1 ;[045] 322 | bst x2, USBMINUS ;[046] 323 | bld shift, 4 ;[047] 324 | didUnstuff4: ;[ ] 325 | eor r0, x1 ;[048] 326 | or phase, r0 ;[049] 327 | in r0, USBIN ;[050] <-- phase 328 | andi shift, 0x9f ;[051] 329 | breq unstuff4 ;[052] *** unstuff escape 330 | rjmp continueWithBit5;[053] 331 | ; [---] ;[054] 332 | 333 | macro POP_STANDARD ; 16 cycles 334 | pop cnt 335 | pop x4 336 | pop x3 337 | pop x2 338 | pop x1 339 | pop shift 340 | pop YH 341 | pop r0 342 | endm 343 | macro POP_RETI ; 5 cycles 344 | pop YL 345 | out SREG, YL 346 | pop YL 347 | endm 348 | 349 | #include "asmcommon.inc" 350 | 351 | 352 | ; USB spec says: 353 | ; idle = J 354 | ; J = (D+ = 0), (D- = 1) 355 | ; K = (D+ = 1), (D- = 0) 356 | ; Spec allows 7.5 bit times from EOP to SOP for replies 357 | 358 | bitstuff7: 359 | eor x1, x4 ;[4] 360 | ldi x2, 0 ;[5] 361 | nop2 ;[6] C is zero (brcc) 362 | rjmp didStuff7 ;[8] 363 | 364 | bitstuffN: 365 | eor x1, x4 ;[5] 366 | ldi x2, 0 ;[6] 367 | lpm ;[7] 3 cycle NOP, modifies r0 368 | out USBOUT, x1 ;[10] <-- out 369 | rjmp didStuffN ;[0] 370 | 371 | #define bitStatus x3 372 | 373 | sendNakAndReti: 374 | ldi cnt, USBPID_NAK ;[-19] 375 | rjmp sendCntAndReti ;[-18] 376 | sendAckAndReti: 377 | ldi cnt, USBPID_ACK ;[-17] 378 | sendCntAndReti: 379 | mov r0, cnt ;[-16] 380 | ldi YL, 0 ;[-15] R0 address is 0 381 | ldi YH, 0 ;[-14] 382 | ldi cnt, 2 ;[-13] 383 | ; rjmp usbSendAndReti fallthrough 384 | 385 | ;usbSend: 386 | ;pointer to data in 'Y' 387 | ;number of bytes in 'cnt' -- including sync byte [range 2 ... 12] 388 | ;uses: x1...x4, shift, cnt, Y 389 | ;Numbers in brackets are time since first bit of sync pattern is sent 390 | usbSendAndReti: ; 12 cycles until SOP 391 | in x2, USBDDR ;[-12] 392 | ori x2, USBMASK ;[-11] 393 | sbi USBOUT, USBMINUS;[-10] prepare idle state; D+ and D- must have been 0 (no pullups) 394 | in x1, USBOUT ;[-8] port mirror for tx loop 395 | out USBDDR, x2 ;[-7] <- acquire bus 396 | ; need not init x2 (bitstuff history) because sync starts with 0 397 | ldi x4, USBMASK ;[-6] exor mask 398 | ldi shift, 0x80 ;[-5] sync byte is first byte sent 399 | ldi bitStatus, 0xff ;[-4] init bit loop counter, works for up to 12 bytes 400 | byteloop: 401 | bitloop: 402 | sbrs shift, 0 ;[8] [-3] 403 | eor x1, x4 ;[9] [-2] 404 | out USBOUT, x1 ;[10] [-1] <-- out 405 | ror shift ;[0] 406 | ror x2 ;[1] 407 | didStuffN: 408 | cpi x2, 0xfc ;[2] 409 | brcc bitstuffN ;[3] 410 | nop ;[4] 411 | subi bitStatus, 37 ;[5] 256 / 7 ~=~ 37 412 | brcc bitloop ;[6] when we leave the loop, bitStatus has almost the initial value 413 | sbrs shift, 0 ;[7] 414 | eor x1, x4 ;[8] 415 | ror shift ;[9] 416 | didStuff7: 417 | out USBOUT, x1 ;[10] <-- out 418 | ror x2 ;[0] 419 | cpi x2, 0xfc ;[1] 420 | brcc bitstuff7 ;[2] 421 | ld shift, y+ ;[3] 422 | dec cnt ;[5] 423 | brne byteloop ;[6] 424 | ;make SE0: 425 | cbr x1, USBMASK ;[7] prepare SE0 [spec says EOP may be 21 to 25 cycles] 426 | lds x2, usbNewDeviceAddr;[8] 427 | lsl x2 ;[10] we compare with left shifted address 428 | out USBOUT, x1 ;[11] <-- out SE0 -- from now 2 bits = 22 cycles until bus idle 429 | ;2006-03-06: moved transfer of new address to usbDeviceAddr from C-Code to asm: 430 | ;set address only after data packet was sent, not after handshake 431 | subi YL, 2 ;[0] Only assign address on data packets, not ACK/NAK in r0 432 | sbci YH, 0 ;[1] 433 | breq skipAddrAssign ;[2] 434 | sts usbDeviceAddr, x2; if not skipped: SE0 is one cycle longer 435 | skipAddrAssign: 436 | ;end of usbDeviceAddress transfer 437 | ldi x2, 1< 13.333333 cycles per bit, 106.666667 cycles per byte 37 | ; Numbers in brackets are clocks counted from center of last sync bit 38 | ; when instruction starts 39 | ;register use in receive loop: 40 | ; shift assembles the byte currently being received 41 | ; x1 holds the D+ and D- line state 42 | ; x2 holds the previous line state 43 | ; x4 (leap) is used to add a leap cycle once every three bytes received 44 | ; X3 (leap2) is used to add a leap cycle once every three stuff bits received 45 | ; bitcnt is used to determine when a stuff bit is due 46 | ; cnt holds the number of bytes left in the receive buffer 47 | 48 | USB_INTR_VECTOR: 49 | ;order of registers pushed: YL, SREG YH, [sofError], bitcnt, shift, x1, x2, x3, x4, cnt 50 | push YL ;[-28] push only what is necessary to sync with edge ASAP 51 | in YL, SREG ;[-26] 52 | push YL ;[-25] 53 | push YH ;[-23] 54 | ;---------------------------------------------------------------------------- 55 | ; Synchronize with sync pattern: 56 | ;---------------------------------------------------------------------------- 57 | ;sync byte (D-) pattern LSb to MSb: 01010100 [1 = idle = J, 0 = K] 58 | ;sync up with J to K edge during sync pattern -- use fastest possible loops 59 | ;The first part waits at most 1 bit long since we must be in sync pattern. 60 | ;YL is guarenteed to be < 0x80 because I flag is clear. When we jump to 61 | ;waitForJ, ensure that this prerequisite is met. 62 | waitForJ: 63 | inc YL 64 | sbis USBIN, USBMINUS 65 | brne waitForJ ; just make sure we have ANY timeout 66 | waitForK: 67 | ;The following code results in a sampling window of < 1/4 bit which meets the spec. 68 | sbis USBIN, USBMINUS ;[-19] 69 | rjmp foundK ;[-18] 70 | sbis USBIN, USBMINUS 71 | rjmp foundK 72 | sbis USBIN, USBMINUS 73 | rjmp foundK 74 | sbis USBIN, USBMINUS 75 | rjmp foundK 76 | sbis USBIN, USBMINUS 77 | rjmp foundK 78 | sbis USBIN, USBMINUS 79 | rjmp foundK 80 | sbis USBIN, USBMINUS 81 | rjmp foundK 82 | sbis USBIN, USBMINUS 83 | rjmp foundK 84 | sbis USBIN, USBMINUS 85 | rjmp foundK 86 | #if USB_COUNT_SOF 87 | lds YL, usbSofCount 88 | inc YL 89 | sts usbSofCount, YL 90 | #endif /* USB_COUNT_SOF */ 91 | #ifdef USB_SOF_HOOK 92 | USB_SOF_HOOK 93 | #endif 94 | rjmp sofError 95 | foundK: ;[-16] 96 | ;{3, 5} after falling D- edge, average delay: 4 cycles 97 | ;bit0 should be at 34 for center sampling. Currently at 4 so 30 cylces till bit 0 sample 98 | ;use 1 bit time for setup purposes, then sample again. Numbers in brackets 99 | ;are cycles from center of first sync (double K) bit after the instruction 100 | push bitcnt ;[-16] 101 | ; [---] ;[-15] 102 | lds YL, usbInputBufOffset;[-14] 103 | ; [---] ;[-13] 104 | clr YH ;[-12] 105 | subi YL, lo8(-(usbRxBuf));[-11] [rx loop init] 106 | sbci YH, hi8(-(usbRxBuf));[-10] [rx loop init] 107 | push shift ;[-9] 108 | ; [---] ;[-8] 109 | ldi shift,0x40 ;[-7] set msb to "1" so processing bit7 can be detected 110 | nop2 ;[-6] 111 | ; [---] ;[-5] 112 | ldi bitcnt, 5 ;[-4] [rx loop init] 113 | sbis USBIN, USBMINUS ;[-3] we want two bits K (sample 3 cycles too early) 114 | rjmp haveTwoBitsK ;[-2] 115 | pop shift ;[-1] undo the push from before 116 | pop bitcnt ;[1] 117 | rjmp waitForK ;[3] this was not the end of sync, retry 118 | ; The entire loop from waitForK until rjmp waitForK above must not exceed two 119 | ; bit times (= 27 cycles). 120 | 121 | ;---------------------------------------------------------------------------- 122 | ; push more registers and initialize values while we sample the first bits: 123 | ;---------------------------------------------------------------------------- 124 | haveTwoBitsK: 125 | push x1 ;[0] 126 | push x2 ;[2] 127 | push x3 ;[4] (leap2) 128 | ldi leap2, 0x55 ;[6] add leap cycle on 2nd,5th,8th,... stuff bit 129 | push x4 ;[7] == leap 130 | ldi leap, 0x55 ;[9] skip leap cycle on 2nd,5th,8th,... byte received 131 | push cnt ;[10] 132 | ldi cnt, USB_BUFSIZE ;[12] [rx loop init] 133 | ldi x2, 1< 38 | #ifndef __IAR_SYSTEMS_ASM__ 39 | # include 40 | #endif 41 | 42 | #define __attribute__(arg) /* not supported on IAR */ 43 | 44 | #ifdef __IAR_SYSTEMS_ASM__ 45 | # define __ASSEMBLER__ /* IAR does not define standard macro for asm */ 46 | #endif 47 | 48 | #ifdef __HAS_ELPM__ 49 | # define PROGMEM __farflash 50 | #else 51 | # define PROGMEM __flash 52 | #endif 53 | 54 | #define USB_READ_FLASH(addr) (*(PROGMEM char *)(addr)) 55 | 56 | /* The following definitions are not needed by the driver, but may be of some 57 | * help if you port a gcc based project to IAR. 58 | */ 59 | #define cli() __disable_interrupt() 60 | #define sei() __enable_interrupt() 61 | #define wdt_reset() __watchdog_reset() 62 | #define _BV(x) (1 << (x)) 63 | 64 | /* assembler compatibility macros */ 65 | #define nop2 rjmp $+2 /* jump to next instruction */ 66 | #define XL r26 67 | #define XH r27 68 | #define YL r28 69 | #define YH r29 70 | #define ZL r30 71 | #define ZH r31 72 | #define lo8(x) LOW(x) 73 | #define hi8(x) (((x)>>8) & 0xff) /* not HIGH to allow XLINK to make a proper range check */ 74 | 75 | /* Depending on the device you use, you may get problems with the way usbdrv.h 76 | * handles the differences between devices. Since IAR does not use #defines 77 | * for MCU registers, we can't check for the existence of a particular 78 | * register with an #ifdef. If the autodetection mechanism fails, include 79 | * definitions for the required USB_INTR_* macros in your usbconfig.h. See 80 | * usbconfig-prototype.h and usbdrv.h for details. 81 | */ 82 | 83 | /* ------------------------------------------------------------------------- */ 84 | #elif __CODEVISIONAVR__ /* check for CodeVision AVR */ 85 | /* ------------------------------------------------------------------------- */ 86 | /* This port is not working (yet) */ 87 | 88 | /* #define F_CPU _MCU_CLOCK_FREQUENCY_ seems to be defined automatically */ 89 | 90 | #include 91 | #include 92 | 93 | #define __attribute__(arg) /* not supported on IAR */ 94 | 95 | #define PROGMEM __flash 96 | #define USB_READ_FLASH(addr) (*(PROGMEM char *)(addr)) 97 | 98 | #ifndef __ASSEMBLER__ 99 | static inline void cli(void) 100 | { 101 | #asm("cli"); 102 | } 103 | static inline void sei(void) 104 | { 105 | #asm("sei"); 106 | } 107 | #endif 108 | #define _delay_ms(t) delay_ms(t) 109 | #define _BV(x) (1 << (x)) 110 | #define USB_CFG_USE_SWITCH_STATEMENT 1 /* macro for if() cascase fails for unknown reason */ 111 | 112 | #define macro .macro 113 | #define endm .endmacro 114 | #define nop2 rjmp .+0 /* jump to next instruction */ 115 | 116 | /* ------------------------------------------------------------------------- */ 117 | #else /* default development environment is avr-gcc/avr-libc */ 118 | /* ------------------------------------------------------------------------- */ 119 | 120 | #include 121 | #ifdef __ASSEMBLER__ 122 | # define _VECTOR(N) __vector_ ## N /* io.h does not define this for asm */ 123 | #else 124 | # include 125 | #endif 126 | 127 | #if USB_CFG_DRIVER_FLASH_PAGE 128 | # define USB_READ_FLASH(addr) pgm_read_byte_far(((long)USB_CFG_DRIVER_FLASH_PAGE << 16) | (long)(addr)) 129 | #else 130 | # define USB_READ_FLASH(addr) pgm_read_byte(addr) 131 | #endif 132 | 133 | #define macro .macro 134 | #define endm .endm 135 | #define nop2 rjmp .+0 /* jump to next instruction */ 136 | 137 | #endif /* development environment */ 138 | 139 | /* for conveniecne, ensure that PRG_RDB exists */ 140 | #ifndef PRG_RDB 141 | # define PRG_RDB(addr) USB_READ_FLASH(addr) 142 | #endif 143 | #endif /* __usbportability_h_INCLUDED__ */ 144 | -------------------------------------------------------------------------------- /usr_prog.c: -------------------------------------------------------------------------------- 1 | #include "main.h" 2 | #include 3 | #include 4 | #include 5 | 6 | // sorry, i can only place string tables in flash by declaring them seperately 7 | const PROGMEM char descstr_menu[] = "escape"; 8 | const PROGMEM char descstr_select[] = "enter"; 9 | const PROGMEM char descstr_playpause[] = "space"; 10 | const PROGMEM char descstr_volup[] = "up arrow"; 11 | const PROGMEM char descstr_voldn[] = "down arrow"; 12 | const PROGMEM char descstr_next[] = "right arrow"; 13 | const PROGMEM char descstr_prev[] = "left arrow"; 14 | /* 15 | const PROGMEM char descstr_stop[] = "stop"; 16 | const PROGMEM char descstr_mute[] = "mute"; 17 | const PROGMEM char descstr_power[] = "power"; 18 | const PROGMEM char descstr_rec[] = "rec"; 19 | const PROGMEM char descstr_epg[] = "epg"; 20 | const PROGMEM char descstr_livetv[] = "live tv"; 21 | const PROGMEM char descstr_stereo[] = "stereo"; 22 | const PROGMEM char descstr_snapshot[] = "snapshot"; 23 | const PROGMEM char descstr_zoom[] = "zoom"; 24 | const PROGMEM char descstr_recall[] = "recall"; 25 | const PROGMEM char descstr_teletext[] = "teletext"; 26 | const PROGMEM char descstr_source[] = "source"; 27 | const PROGMEM char descstr_fav[] = "favorite"; 28 | //*/ 29 | 30 | #include "kbrd_codes.h" 31 | // pair up the action and the description here 32 | const PROGMEM code_desc_t code_desc_tbl[] = { // remember to change the count! 33 | { .c = KEYCODE_ARROW_UP , .s = descstr_volup }, 34 | { .c = KEYCODE_ARROW_DOWN , .s = descstr_voldn }, 35 | { .c = KEYCODE_ARROW_RIGHT , .s = descstr_next }, 36 | { .c = KEYCODE_ARROW_LEFT , .s = descstr_prev }, 37 | { .c = KEYCODE_SPACE , .s = descstr_playpause }, 38 | { .c = KEYCODE_ENTER , .s = descstr_select }, 39 | { .c = KEYCODE_ESC , .s = descstr_menu }, 40 | /* 41 | { .c = KEYCODE_STOP , .s = descstr_stop }, 42 | { .c = KEYCODE_SYS_SLEEP , .s = descstr_power }, 43 | { .c = KEYCODE_R , .s = descstr_rec }, 44 | { .c = KEYCODE_BACKSPACE , .s = descstr_recall }, 45 | { .c = XMBC_EPGTVGUIDE , .s = descstr_epg }, 46 | { .c = KEYCODE_L , .s = descstr_livetv }, 47 | { .c = KEYCODE_F2 , .s = descstr_stereo }, 48 | { .c = KEYCODE_PRINTSCREEN , .s = descstr_snapshot }, 49 | { .c = KEYCODE_Z , .s = descstr_zoom }, 50 | { .c = XMBC_NEXTSUBTITLE , .s = descstr_teletext }, 51 | { .c = KEYCODE_S , .s = descstr_source }, 52 | { .c = KEYCODE_F , .s = descstr_fav }, 53 | //*/ 54 | 55 | { .c = 0 , .s = 0 }, // null terminated to signal end of table 56 | }; 57 | 58 | static char desc_buff[32]; 59 | 60 | void usr_prog() 61 | { 62 | printf_P(PSTR("\nWelcome to IR Keyboard Programming Mode\n")); 63 | 64 | for (int i = 0; ; i++) 65 | { 66 | code_desc_t cd; 67 | memcpy_PF((void*)&cd, (uint_farptr_t)&(code_desc_tbl[i]), sizeof(code_desc_t)); 68 | if (cd.c == 0 || cd.c == 0xFFFFFFFF) { 69 | // null termination found or flash memory empty 70 | break; 71 | } 72 | strcpy_PF((void*)desc_buff, (uint_farptr_t)cd.s); 73 | printf_P(PSTR("Press \"%s\""), desc_buff); // prompt the user 74 | static uint32_t ir_code; 75 | TCNT1 = 0; 76 | if (bit_is_set(TIFR, TOV1)) TIFR |= _BV(TOV1); 77 | uint8_t tmr1_ovf_cnt = 0; 78 | while (1) 79 | { 80 | usbPollWrapper(); 81 | 82 | ircap_res_t r = ir_cap(&ir_code); 83 | 84 | if (r != IRCAP_NOTHING) { 85 | tmr1_ovf_cnt = 0; 86 | } 87 | 88 | if (bit_is_set(TIFR, TOV1)) { 89 | TIFR |= _BV(TOV1); 90 | tmr1_ovf_cnt++; 91 | } 92 | 93 | if (r == IRCAP_NEWKEY) { 94 | eeprom_update_dword((uint32_t*)(i * sizeof(uint32_t)), ir_code); 95 | #ifdef ENABLE_PROG_DEBUG 96 | printf_P(PSTR(" [Read 0x%04X%04X]"), 97 | (unsigned int)((ir_code & 0xFFFF0000) >> 16), 98 | (unsigned int)(ir_code & 0xFFFF)); 99 | // split into 16 bit chunks due to suspected stdio bug 100 | #endif 101 | 102 | printf_P(PSTR(" OK!\n")); 103 | break; 104 | } 105 | else if (tmr1_ovf_cnt >= TMR1_TIMEOUT_5S) { // took too long 106 | uint32_t ic = eeprom_read_dword((uint32_t*)(i * sizeof(uint32_t))); 107 | if (ic == 0 && ic == 0xFFFFFFFF) { 108 | eeprom_update_dword((uint32_t*)(i * sizeof(uint32_t)), 0x01); // insert empty placeholder that is neither null nor empty 109 | } 110 | printf_P(PSTR(", nevermind\n")); 111 | break; 112 | } 113 | } 114 | } 115 | 116 | printf_P(PSTR("All Done!\n")); 117 | } 118 | 119 | uint32_t usr_ir_to_kb(uint32_t ir) 120 | { 121 | for (int i = 0; ; i++) 122 | { 123 | usbPollWrapper(); 124 | uint32_t ic = eeprom_read_dword((uint32_t*)(i * sizeof(uint32_t))); 125 | if (ic == 0 || ic == 0xFFFFFFFF) { 126 | // null termination found or empty 127 | break; 128 | } 129 | if (ic == ir) { 130 | code_desc_t cd; 131 | memcpy_PF((void*)&cd, (uint_farptr_t)&(code_desc_tbl[i]), sizeof(code_desc_t)); 132 | return cd.c; 133 | } 134 | } 135 | 136 | return 0; 137 | } 138 | -------------------------------------------------------------------------------- /xbmc_keys.h: -------------------------------------------------------------------------------- 1 | #ifndef xbmc_keys_h 2 | #define xbmc_keys_h 3 | 4 | #include 5 | 6 | #define XBMC_AUDIODELAY KEYCODE_A 7 | #define XBMC_SCHEDULERECORDINGTIMERS KEYCODE_B 8 | #define XBMC_CONTEXTUALMENU KEYCODE_C 9 | #define XBMC_MOVEDOWN KEYCODE_D 10 | #define XBMC_EPGTVGUIDE KEYCODE_E 11 | #define XBMC_FASTFORWARD KEYCODE_F 12 | #define XBMC_CHANNELSWINDOW KEYCODE_H 13 | #define XBMC_INFO KEYCODE_I 14 | #define XBMC_RADIOCHANNELSWINDOW KEYCODE_J 15 | #define XBMC_RECORDINGSWINDOW KEYCODE_K 16 | #define XBMC_NEXTSUBTITLE KEYCODE_L 17 | #define XBMC_LOCKPRESET KEYCODE_L 18 | #define XBMC_NOWPLAYING KEYCODE_N 19 | #define XBMC_PLAYERCONTROLS KEYCODE_M 20 | #define XBMC_DIAGNOSTICINFO KEYCODE_O 21 | #define XBMC_PLAY KEYCODE_P 22 | #define XBMC_QUEUE KEYCODE_Q 23 | #define XBMC_REWIND KEYCODE_R 24 | #define XBMC_SHUTDOWNMENU KEYCODE_S 25 | #define XBMC_TOGGLESUBTITLES KEYCODE_T 26 | #define XBMC_MARKEDASWATCHED KEYCODE_W 27 | #define XBMC_STOP KEYCODE_X 28 | #define XBMC_PAUSE_PLAY KEYCODE_SPACE 29 | #define XBMC_LEFT KEYCODE_ARROW_LEFT 30 | #define XBMC_RIGHT KEYCODE_ARROW_RIGHT 31 | #define XBMC_UP KEYCODE_ARROW_UP 32 | #define XBMC_DOWN KEYCODE_ARROW_DOWN 33 | #define XBMC_PAGEUP KEYCODE_PAGE_UP 34 | #define XBMC_PAGEDOWN KEYCODE_PAGE_DOWN 35 | #define XBMC_SELECT KEYCODE_ENTER 36 | #define XBMC_BACK KEYCODE_BACKSPACE 37 | #define XBMC_ZOOM KEYCODE_Z 38 | #define XBMC_PREVIOUSMENU_HOMESCREEN KEYCODE_ESC 39 | #define XBMC_SKIPFORWARD KEYCODE_PERIOD 40 | #define XBMC_SKIPBACKWARD KEYCODE_COMMA 41 | #define XBMC_FULLSCREENMODE KEYCODE_TAB 42 | #define XBMC_SCREENSHOT KEYCODE_PRINTSCREEN 43 | #define XBMC_VOLUMEDOWN KEYCODE_MINUS 44 | #define XBMC_VOLUMEUP KEYCODE_EQUAL 45 | #define XBMC_TOGGLEAPPLWINDOWEDMODE KEYCODE_BACKSLASH 46 | #define XBMC_STEPFORWARD10MIN KEYCODE_BRACKET_LEFT 47 | #define XBMC_STEPBACKWARD10MIN KEYCODE_BRACKET_RIGHT 48 | #define XBMC_EXITXBMCEDEN KEYCODE_END 49 | #define XBMC_EXITXBMCFRODO 0x4D000101 // ctrl+end 50 | #define XBMC_DELETEFILE_REMOVEFROMPLAYLIST KEYCODE_DELETE 51 | 52 | #endif --------------------------------------------------------------------------------