├── LICENSE ├── README.md ├── UsbKeyboard ├── ArduinoNotes.txt ├── Changelog.txt ├── CommercialLicense.txt ├── License.txt ├── Readme.txt ├── USB-ID-FAQ.txt ├── USB-IDs-for-free.txt ├── USBID-License.txt ├── UsbKeyboard.h ├── asmcommon.inc ├── examples │ └── UsbKeyboardDemo1 │ │ └── UsbKeyboardDemo1.pde ├── oddebug.c ├── oddebug.h ├── usbconfig-prototype.h ├── usbconfig.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 ├── clockwork_keypad_ATMEGA168PA.hex ├── clockworkpi_keypad.ino └── keymaps.png /README.md: -------------------------------------------------------------------------------- 1 | # Keypad 2 | GameShell's Keypad arduino code. 3 | ## clockwork Keypad Schematic 4 | https://github.com/clockworkpi/GameShellDocs/blob/master/clockwork_Keypad_Schematic.pdf 5 | ## Keymaps 6 | ![Keymaps](https://github.com/clockworkpi/Keypad/blob/master/keymaps.png) 7 | -------------------------------------------------------------------------------- /UsbKeyboard/ArduinoNotes.txt: -------------------------------------------------------------------------------- 1 | Notes On Integrating AVRUSB with Arduino 2 | ======================================== 3 | 4 | * Note the license(s) under which AVRUSB is distributed. 5 | 6 | * See also: http://code.rancidbacon.com/ProjectLogArduinoUSB 7 | 8 | * Note: The pins we use on the PCB (not protoboard) hardware shield are: 9 | 10 | INT0 == PD2 == IC Pin 4 == Arduino Digital Pin 2 == D+ 11 | 12 | ---- == PD4 == -------- == Arduino Digital Pin 4 == D- 13 | 14 | ---- == PD5 == -------- == Arduino Digital Pin 5 == pull-up 15 | 16 | (DONE: Change to not use PD3 so INT1 is left free?) 17 | 18 | * In order to compile a valid 'usbconfig.h' file must exit. The content of this 19 | file will vary depending on whether the device is a generic USB device, 20 | generic HID device or specific class of HID device for example. 21 | 22 | The file 'usbconfig-prototype.h' can be used as a starting point, however 23 | it might be easier to use the 'usbconfig.h' from one of the example projects. 24 | 25 | TODO: Specify the settings that need to be changed to match the shield 26 | design we use. 27 | 28 | * (NOTE: Initial 'usbconfig.h' used will be based on the file from 29 | 'HIDKeys.2007-03-29'.) (Note: Have now upgraded to V-USB 2009-08-22.) 30 | 31 | * Versions of the Arduino IDE prior to 0018 won't compile our library 32 | so it needs to be pre-compiled with: 33 | 34 | avr-g++ -Wall -Os -I. -DF_CPU=16000000 -mmcu=atmega168 -c usbdrvasm.S -c usbdrv.c 35 | -------------------------------------------------------------------------------- /UsbKeyboard/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 | -------------------------------------------------------------------------------- /UsbKeyboard/CommercialLicense.txt: -------------------------------------------------------------------------------- 1 | V-USB Driver Software License Agreement 2 | Version 2009-08-03 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 (Clay Logic, www.claylogic.com). Both owners of the Vendor IDs 41 | have obtained these IDs from the USB Implementers Forum, Inc. 42 | (www.usb.org). OBJECTIVE DEVELOPMENT disclaims all liability which might 43 | arise from the 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 | -------------------------------------------------------------------------------- /UsbKeyboard/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 usbdrv.h unless you use the default 53 | 12 MHz. 54 | 55 | 12 MHz Clock 56 | This is the traditional clock rate of V-USB because it's the lowest clock 57 | rate where the timing constraints of the USB spec can be met. 58 | 59 | 15 MHz Clock 60 | Similar to 12 MHz, but some NOPs inserted. On the other hand, the higher clock 61 | rate allows for some loops which make the resulting code size somewhat smaller 62 | than the 12 MHz version. 63 | 64 | 16 MHz Clock 65 | This clock rate has been added for users of the Arduino board and other 66 | ready-made boards which come with a fixed 16 MHz crystal. It's also an option 67 | if you need the slightly higher clock rate for performance reasons. Since 68 | 16 MHz is not divisible by the USB low speed bit clock of 1.5 MHz, the code 69 | is somewhat tricky and has to insert a leap cycle every third byte. 70 | 71 | 12.8 MHz and 16.5 MHz Clock 72 | The assembler modules for these clock rates differ from the other modules 73 | because they have been built for an RC oscillator with only 1% precision. The 74 | receiver code inserts leap cycles to compensate for clock deviations. 1% is 75 | also the precision which can be achieved by calibrating the internal RC 76 | oscillator of the AVR. Please note that only AVRs with internal 64 MHz PLL 77 | oscillator can reach 16.5 MHz with the RC oscillator. This includes the very 78 | popular ATTiny25, ATTiny45, ATTiny85 series as well as the ATTiny26. Almost 79 | all AVRs can reach 12.8 MHz, although this is outside the specified range. 80 | 81 | See the EasyLogger example at http://www.obdev.at/vusb/easylogger.html for 82 | code which calibrates the RC oscillator based on the USB frame clock. 83 | 84 | 18 MHz Clock 85 | This module is closer to the USB specification because it performs an on the 86 | fly CRC check for incoming packets. Packets with invalid checksum are 87 | discarded as required by the spec. If you also implement checks for data 88 | PID toggling on application level (see option USB_CFG_CHECK_DATA_TOGGLING 89 | in usbconfig.h for more info), this ensures data integrity. Due to the CRC 90 | tables and alignment requirements, this code is bigger than modules for other 91 | clock rates. To activate this module, you must define USB_CFG_CHECK_CRC to 1 92 | and USB_CFG_CLOCK_KHZ to 18000 in usbconfig.h. 93 | 94 | 20 MHz Clock 95 | This module is for people who won't do it with less than the maximum. Since 96 | 20 MHz is not divisible by the USB low speed bit clock of 1.5 MHz, the code 97 | uses similar tricks as the 16 MHz module to insert leap cycles. 98 | 99 | 100 | USB IDENTIFIERS 101 | =============== 102 | Every USB device needs a vendor- and a product-identifier (VID and PID). VIDs 103 | are obtained from usb.org for a price of 1,500 USD. Once you have a VID, you 104 | can assign PIDs at will. 105 | 106 | Since an entry level cost of 1,500 USD is too high for most small companies 107 | and hobbyists, we provide some VID/PID pairs for free. See the file 108 | USB-IDs-for-free.txt for details. 109 | 110 | Objective Development also has some license offerings which include product 111 | IDs. See http://www.obdev.at/vusb/ for details. 112 | 113 | 114 | DEVELOPMENT SYSTEM 115 | ================== 116 | This driver has been developed and optimized for the GNU compiler version 3 117 | (gcc 3). It does work well with gcc 4, but with bigger code size. We recommend 118 | that you use the GNU compiler suite because it is freely available. V-USB 119 | has also been ported to the IAR compiler and assembler. It has been tested 120 | with IAR 4.10B/W32 and 4.12A/W32 on an ATmega8 with the "small" and "tiny" 121 | memory model. Not every release is tested with IAR CC and the driver may 122 | therefore fail to compile with IAR. Please note that gcc is more efficient for 123 | usbdrv.c because this module has been deliberately optimized for gcc. 124 | 125 | 126 | USING V-USB FOR FREE 127 | ==================== 128 | The AVR firmware driver is published under the GNU General Public License 129 | Version 2 (GPL2) and the GNU General Public License Version 3 (GPL3). It is 130 | your choice whether you apply the terms of version 2 or version 3. 131 | 132 | If you decide for the free GPL2 or GPL3, we STRONGLY ENCOURAGE you to do the 133 | following things IN ADDITION to the obligations from the GPL: 134 | 135 | (1) Publish your entire project on a web site and drop us a note with the URL. 136 | Use the form at http://www.obdev.at/vusb/feedback.html for your submission. 137 | If you don't have a web site, you can publish the project in obdev's 138 | documentation wiki at 139 | http://www.obdev.at/goto.php?t=vusb-wiki&p=hosted-projects. 140 | 141 | (2) Adhere to minimum publication standards. Please include AT LEAST: 142 | - a circuit diagram in PDF, PNG or GIF format 143 | - full source code for the host software 144 | - a Readme.txt file in ASCII format which describes the purpose of the 145 | project and what can be found in which directories and which files 146 | - a reference to http://www.obdev.at/vusb/ 147 | 148 | (3) If you improve the driver firmware itself, please give us a free license 149 | to your modifications for our commercial license offerings. 150 | 151 | 152 | COMMERCIAL LICENSES FOR V-USB 153 | ============================= 154 | If you don't want to publish your source code under the terms of the GPL, 155 | you can simply pay money for V-USB. As an additional benefit you get 156 | USB PIDs for free, reserved exclusively to you. See the file 157 | "CommercialLicense.txt" for details. 158 | 159 | -------------------------------------------------------------------------------- /UsbKeyboard/USB-ID-FAQ.txt: -------------------------------------------------------------------------------- 1 | Version 2009-08-22 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 (Clay Logic, www.claylogic.com). Both VID owners have received their 111 | Vendor-ID 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 | -------------------------------------------------------------------------------- /UsbKeyboard/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. The serial number string MUST be available at least in USB language 90 | 0x0409 (English/US). 91 | 92 | (2) The serial number MUST start with either an Internet domain name (e.g. 93 | "mycompany.com") registered and owned by you, or an e-mail address under your 94 | control (e.g. "myname@gmx.net"), both terminated with a colon (":") character. 95 | You MAY append any string you like for further discrimination of your devices. 96 | 97 | (3) You are responsible for retaining ownership of the domain or e-mail 98 | address for as long as any of your products are in use. 99 | 100 | (5) Application side device look-up MUST be based on the serial number string 101 | in addition to VID/PID matching. The matching must start at the first 102 | character of the serial number string and include the colon character 103 | terminating your domain or e-mail address. It MAY stop anywhere after that. 104 | 105 | (6) For devices which implement a particular USB device class (e.g. HID), the 106 | operating system's default class driver MUST be used. If an operating system 107 | driver for Vendor Class devices is needed, this driver must be libusb or 108 | libusb-win32 (see http://libusb.org/ and 109 | http://libusb-win32.sourceforge.net/). 110 | 111 | Table if IDs for discrimination by serial number string: 112 | 113 | PID dec (hex) | VID dec (hex) | Description of use 114 | ===============+===============+=========================================== 115 | 10200 (0x27d8) | 5824 (0x16c0) | For Vendor Class devices with libusb 116 | ---------------+---------------+------------------------------------------- 117 | 10201 (0x27d9) | 5824 (0x16c0) | For generic HID class devices (which are 118 | | | NOT mice, keyboards or joysticks) 119 | ---------------+---------------+------------------------------------------- 120 | 10202 (0x27da) | 5824 (0x16c0) | For USB Mice 121 | ---------------+---------------+------------------------------------------- 122 | 10203 (0x27db) | 5824 (0x16c0) | For USB Keyboards 123 | ---------------+---------------+------------------------------------------- 124 | 10204 (0x27db) | 5824 (0x16c0) | For USB Joysticks 125 | ---------------+---------------+------------------------------------------- 126 | 10205 (0x27dc) | 5824 (0x16c0) | For CDC-ACM class devices (modems) 127 | ---------------+---------------+------------------------------------------- 128 | 10206 (0x27dd) | 5824 (0x16c0) | For MIDI class devices 129 | ---------------+---------------+------------------------------------------- 130 | 131 | 132 | ================= 133 | ORIGIN OF USB-IDs 134 | ================= 135 | 136 | OBJECTIVE DEVELOPMENT Software GmbH has obtained all VID/PID pairs listed 137 | here from Wouter van Ooijen (see www.voti.nl) for exclusive disposition. 138 | Wouter van Ooijen has obtained the VID from the USB Implementers Forum, Inc. 139 | (see www.usb.org). The VID is registered for the company name "Van Ooijen 140 | Technische Informatica". 141 | 142 | 143 | ========== 144 | DISCLAIMER 145 | ========== 146 | 147 | OBJECTIVE DEVELOPMENT Software GmbH disclaims all liability for any 148 | problems which are caused by the shared use of these VID/PID pairs. 149 | -------------------------------------------------------------------------------- /UsbKeyboard/USBID-License.txt: -------------------------------------------------------------------------------- 1 | Royalty-Free Non-Exclusive Use of USB Product-IDs 2 | ================================================= 3 | 4 | Version 2009-04-13 5 | 6 | Strictly speaking, this is not a license. You can't give a license to use 7 | a simple number (such as e.g. 1500) for any purpose. This is a set of rules 8 | which should make it possible to build USB devices without the requirement 9 | for individual USB IDs. If you break one of the rules, you will run into 10 | technical problems sooner or later, but you don't risk legal trouble. 11 | 12 | 13 | OBJECTIVE DEVELOPMENT Software GmbH hereby grants you the non-exclusive 14 | right to use four USB.org vendor-ID (VID) / product-ID (PID) pairs with 15 | products based on Objective Development's firmware-only USB driver for 16 | Atmel AVR microcontrollers: 17 | 18 | * VID = 5824 (=0x16c0) / PID = 1500 (=0x5dc) for devices implementing no 19 | USB device class (vendor-class devices with USB class = 0xff). Devices 20 | using this pair will be referred to as "VENDOR CLASS" devices. 21 | 22 | * VID = 5824 (=0x16c0) / PID = 1503 (=0x5df) for HID class devices 23 | (excluding mice and keyboards). Devices using this pair will be referred 24 | to as "HID CLASS" devices. 25 | 26 | * VID = 5824 (=0x16c0) / PID = 1505 (=0x5e1) for CDC class modem devices 27 | Devices using this pair will be referred to as "CDC-ACM CLASS" devices. 28 | 29 | * VID = 5824 (=0x16c0) / PID = 1508 (=0x5e4) for MIDI class devices 30 | Devices using this pair will be referred to as "MIDI CLASS" devices. 31 | 32 | Since the granted right is non-exclusive, the same VID/PID pairs may be 33 | used by many companies and individuals for different products. To avoid 34 | conflicts, your device and host driver software MUST adhere to the rules 35 | outlined below. 36 | 37 | OBJECTIVE DEVELOPMENT Software GmbH has obtained these VID/PID pairs from 38 | Wouter van Ooijen (see www.voti.nl) for exclusive disposition. Wouter van 39 | Ooijen has obtained the VID from the USB Implementers Forum, Inc. 40 | (see www.usb.org). The VID is registered for the company name 41 | "Van Ooijen Technische Informatica". 42 | 43 | 44 | RULES AND RESTRICTIONS 45 | ====================== 46 | 47 | (1) The USB device MUST provide a textual representation of the 48 | manufacturer and product identification. The manufacturer identification 49 | MUST be available at least in USB language 0x0409 (English/US). 50 | 51 | (2) The textual manufacturer identification MUST contain either an Internet 52 | domain name (e.g. "mycompany.com") registered and owned by you, or an 53 | e-mail address under your control (e.g. "myname@gmx.net"). You can embed 54 | the domain name or e-mail address in any string you like, e.g. "Objective 55 | Development http://www.obdev.at/vusb/". 56 | 57 | (3) You are responsible for retaining ownership of the domain or e-mail 58 | address for as long as any of your products are in use. 59 | 60 | (4) You may choose any string for the textual product identification, as 61 | long as this string is unique within the scope of your textual manufacturer 62 | identification. 63 | 64 | (5) Matching of device-specific drivers MUST be based on the textual 65 | manufacturer and product identification in addition to the usual VID/PID 66 | matching. This means that operating system features which are based on 67 | VID/PID matching only (e.g. Windows kernel level drivers, automatic actions 68 | when the device is plugged in etc) MUST NOT be used. The driver matching 69 | MUST be a comparison of the entire strings, NOT a sub-string match. For 70 | CDC-ACM CLASS and MIDI CLASS devices, a generic class driver should be used 71 | and the matching is based on the USB device class. 72 | 73 | (6) The extent to which VID/PID matching is allowed for non device-specific 74 | drivers or features depends on the operating system and particular VID/PID 75 | pair used: 76 | 77 | * Mac OS X, Linux, FreeBSD and other Unixes: No VID/PID matching is 78 | required and hence no VID/PID-only matching is allowed at all. 79 | 80 | * Windows: The operating system performs VID/PID matching for the kernel 81 | level driver. You are REQUIRED to use libusb-win32 (see 82 | http://libusb-win32.sourceforge.net/) as the kernel level driver for 83 | VENDOR CLASS devices. HID CLASS devices all use the generic HID class 84 | driver shipped with Windows, except mice and keyboards. You therefore 85 | MUST NOT use any of the shared VID/PID pairs for mice or keyboards. 86 | CDC-ACM CLASS devices require a ".inf" file which matches on the VID/PID 87 | pair. This ".inf" file MUST load the "usbser" driver to configure the 88 | device as modem (COM-port). 89 | 90 | (7) OBJECTIVE DEVELOPMENT Software GmbH disclaims all liability for any 91 | problems which are caused by the shared use of these VID/PID pairs. You 92 | have been warned that the sharing of VID/PID pairs may cause problems. If 93 | you want to avoid them, get your own VID/PID pair for exclusive use. 94 | 95 | 96 | HOW TO IMPLEMENT THESE RULES 97 | ============================ 98 | 99 | The following rules are for VENDOR CLASS and HID CLASS devices. CDC-ACM 100 | CLASS and MIDI CLASS devices use the operating system's class driver and 101 | don't need a custom driver. 102 | 103 | The host driver MUST iterate over all devices with the given VID/PID 104 | numbers in their device descriptors and query the string representation for 105 | the manufacturer name in USB language 0x0409 (English/US). It MUST compare 106 | the ENTIRE string with your textual manufacturer identification chosen in 107 | (2) above. A substring search for your domain or e-mail address is NOT 108 | acceptable. The driver MUST NOT touch the device (other than querying the 109 | descriptors) unless the strings match. 110 | 111 | For all USB devices with matching VID/PID and textual manufacturer 112 | identification, the host driver must query the textual product 113 | identification and string-compare it with the name of the product it can 114 | control. It may only initialize the device if the product matches exactly. 115 | 116 | Objective Development provides examples for these matching rules with the 117 | "PowerSwitch" project (using libusb) and with the "Automator" project 118 | (using Windows calls on Windows and libusb on Unix). 119 | 120 | 121 | Technical Notes: 122 | ================ 123 | 124 | Sharing the same VID/PID pair among devices is possible as long as ALL 125 | drivers which match the VID/PID also perform matching on the textual 126 | identification strings. This is easy on all operating systems except 127 | Windows, since Windows establishes a static connection between the VID/PID 128 | pair and a kernel level driver. All devices with the same VID/PID pair must 129 | therefore use THE SAME kernel level driver. 130 | 131 | We therefore demand that you use libusb-win32 for VENDOR CLASS devices. 132 | This is a generic kernel level driver which allows all types of USB access 133 | for user space applications. This is only a partial solution of the 134 | problem, though, because different device drivers may come with different 135 | versions of libusb-win32 and they may not work with the libusb version of 136 | the respective other driver. You are therefore encouraged to test your 137 | driver against a broad range of libusb-win32 versions. Do not use new 138 | features in new versions, or check for their existence before you use them. 139 | When a new libusb-win32 becomes available, make sure that your driver is 140 | compatible with it. 141 | 142 | For HID CLASS devices it is necessary that all those devices bind to the 143 | same kernel driver: Microsoft's generic USB HID driver. This is true for 144 | all HID devices except those with a specialized driver. Currently, the only 145 | HIDs with specialized drivers are mice and keyboards. You therefore MUST 146 | NOT use a shared VID/PID with mouse and keyboard devices. 147 | 148 | Sharing the same VID/PID among different products is unusual and probably 149 | violates the USB specification. If you do it, you do it at your own risk. 150 | 151 | To avoid possible incompatibilities, we highly recommend that you get your 152 | own VID/PID pair if you intend to sell your product. Objective 153 | Development's commercial licenses for V-USB include a PID for 154 | unrestricted exclusive use. 155 | -------------------------------------------------------------------------------- /UsbKeyboard/UsbKeyboard.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Based on Obdev's AVRUSB code and under the same license. 3 | * 4 | * TODO: Make a proper file header. :-) 5 | */ 6 | #ifndef __UsbKeyboard_h__ 7 | #define __UsbKeyboard_h__ 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | #include "usbdrv.h" 14 | 15 | // TODO: Work around Arduino 12 issues better. 16 | //#include 17 | //#undef int() 18 | 19 | typedef uint8_t byte; 20 | 21 | 22 | #define BUFFER_SIZE 7 // Minimum of 2: 1 for modifiers + 1 for keystroke 23 | 24 | 25 | static uchar idleRate; // in 4 ms units 26 | 27 | 28 | /* We use a simplifed keyboard report descriptor which does not support the 29 | * boot protocol. We don't allow setting status LEDs and but we do allow 30 | * simultaneous key presses. 31 | * The report descriptor has been created with usb.org's "HID Descriptor Tool" 32 | * which can be downloaded from http://www.usb.org/developers/hidpage/. 33 | * Redundant entries (such as LOGICAL_MINIMUM and USAGE_PAGE) have been omitted 34 | * for the second INPUT item. 35 | */ 36 | const PROGMEM char usbHidReportDescriptor[35] = { /* USB report descriptor */ 37 | 0x05, 0x01, // USAGE_PAGE (Generic Desktop) 38 | 0x09, 0x06, // USAGE (Keyboard) 39 | 0xa1, 0x01, // COLLECTION (Application) 40 | 0x05, 0x07, // USAGE_PAGE (Keyboard) 41 | 0x19, 0xe0, // USAGE_MINIMUM (Keyboard LeftControl) 42 | 0x29, 0xe7, // USAGE_MAXIMUM (Keyboard Right GUI) 43 | 0x15, 0x00, // LOGICAL_MINIMUM (0) 44 | 0x25, 0x01, // LOGICAL_MAXIMUM (1) 45 | 0x75, 0x01, // REPORT_SIZE (1) 46 | 0x95, 0x08, // REPORT_COUNT (8) 47 | 0x81, 0x02, // INPUT (Data,Var,Abs) 48 | 0x95, BUFFER_SIZE-1, // REPORT_COUNT (simultaneous keystrokes) 49 | 0x75, 0x08, // REPORT_SIZE (8) 50 | 0x25, 0x65, // LOGICAL_MAXIMUM (101) 51 | 0x19, 0x00, // USAGE_MINIMUM (Reserved (no event indicated)) 52 | 0x29, 0x65, // USAGE_MAXIMUM (Keyboard Application) 53 | 0x81, 0x00, // INPUT (Data,Ary,Abs) 54 | 0xc0 // END_COLLECTION 55 | }; 56 | 57 | 58 | typedef struct 59 | { 60 | uint8_t modifiers; 61 | uint8_t keys[6]; 62 | } KeyReport; 63 | 64 | /* Keyboard usage values, see usb.org's HID-usage-tables document, chapter 65 | * 10 Keyboard/Keypad Page for more codes. 66 | */ 67 | #define MOD_CONTROL_LEFT (1<<0) 68 | #define MOD_SHIFT_LEFT (1<<1) 69 | #define MOD_ALT_LEFT (1<<2) 70 | #define MOD_GUI_LEFT (1<<3) 71 | #define MOD_CONTROL_RIGHT (1<<4) 72 | #define MOD_SHIFT_RIGHT (1<<5) 73 | #define MOD_ALT_RIGHT (1<<6) 74 | #define MOD_GUI_RIGHT (1<<7) 75 | 76 | #define KEY_A 4 77 | #define KEY_B 5 78 | #define KEY_C 6 79 | #define KEY_D 7 80 | #define KEY_E 8 81 | #define KEY_F 9 82 | #define KEY_G 10 83 | #define KEY_H 11 84 | #define KEY_I 12 85 | #define KEY_J 13 86 | #define KEY_K 14 87 | #define KEY_L 15 88 | #define KEY_M 16 89 | #define KEY_N 17 90 | #define KEY_O 18 91 | #define KEY_P 19 92 | #define KEY_Q 20 93 | #define KEY_R 21 94 | #define KEY_S 22 95 | #define KEY_T 23 96 | #define KEY_U 24 97 | #define KEY_V 25 98 | #define KEY_W 26 99 | #define KEY_X 27 100 | #define KEY_Y 28 101 | #define KEY_Z 29 102 | #define KEY_1 30 103 | #define KEY_2 31 104 | #define KEY_3 32 105 | #define KEY_4 33 106 | #define KEY_5 34 107 | #define KEY_6 35 108 | #define KEY_7 36 109 | #define KEY_8 37 110 | #define KEY_9 38 111 | #define KEY_0 39 112 | 113 | #define KEY_ENTER 40 114 | 115 | #define KEY_SPACE 44 116 | 117 | #define KEY_F1 58 118 | #define KEY_F2 59 119 | #define KEY_F3 60 120 | #define KEY_F4 61 121 | #define KEY_F5 62 122 | #define KEY_F6 63 123 | #define KEY_F7 64 124 | #define KEY_F8 65 125 | #define KEY_F9 66 126 | #define KEY_F10 67 127 | #define KEY_F11 68 128 | #define KEY_F12 69 129 | 130 | #define KEY_ARROW_LEFT 0x50 131 | 132 | 133 | class UsbKeyboardDevice { 134 | public: 135 | UsbKeyboardDevice () { 136 | PORTD = 0; // TODO: Only for USB pins? 137 | DDRD |= ~USBMASK; 138 | 139 | cli(); 140 | usbDeviceDisconnect(); 141 | _delay_ms(250); 142 | usbDeviceConnect(); 143 | 144 | 145 | usbInit(); 146 | 147 | sei(); 148 | 149 | // TODO: Remove the next two lines once we fix 150 | // missing first keystroke bug properly. 151 | memset(reportBuffer, 0, sizeof(reportBuffer)); 152 | usbSetInterrupt(reportBuffer, sizeof(reportBuffer)); 153 | } 154 | 155 | void update() { 156 | usbPoll(); 157 | } 158 | 159 | void sendKeyStroke(byte keyStroke) { 160 | sendKeyStroke(keyStroke, 0); 161 | } 162 | 163 | void sendKeyStroke(byte keyStroke, byte modifiers) { 164 | 165 | while (!usbInterruptIsReady()) { 166 | // Note: We wait until we can send keystroke 167 | // so we know the previous keystroke was 168 | // sent. 169 | } 170 | 171 | memset(reportBuffer, 0, sizeof(reportBuffer)); 172 | 173 | reportBuffer[0] = modifiers; 174 | reportBuffer[1] = keyStroke; 175 | 176 | usbSetInterrupt(reportBuffer, sizeof(reportBuffer)); 177 | 178 | while (!usbInterruptIsReady()) { 179 | // Note: We wait until we can send keystroke 180 | // so we know the previous keystroke was 181 | // sent. 182 | } 183 | 184 | // This stops endlessly repeating keystrokes: 185 | memset(reportBuffer, 0, sizeof(reportBuffer)); 186 | usbSetInterrupt(reportBuffer, sizeof(reportBuffer)); 187 | 188 | } 189 | 190 | size_t press(uint8_t k) 191 | { 192 | uint8_t i, j; 193 | 194 | // Add k to the key report only if it's not already present 195 | // and if there is an empty slot. 196 | for(j = 0; j < sizeof(_keyReport.keys); j++) { 197 | if(_keyReport.keys[j] == k) { 198 | break; 199 | } 200 | } 201 | if (j == sizeof(_keyReport.keys)) { 202 | for (i = 0; i < sizeof(_keyReport.keys); i++) { 203 | if (_keyReport.keys[i] == 0x00) { 204 | _keyReport.keys[i] = k; 205 | break; 206 | } 207 | } 208 | if (i == sizeof(_keyReport.keys)) { 209 | return 0; 210 | } 211 | } 212 | 213 | usbSetInterrupt((uint8_t*)&_keyReport, sizeof(_keyReport)); 214 | 215 | return 1; 216 | } 217 | 218 | size_t release(uint8_t k) 219 | { 220 | uint8_t i; 221 | 222 | // Test the key report to see if k is present. Clear it if it exists. 223 | // Check all positions in case the key is present more than once (which it shouldn't be) 224 | for (i = 0; i < sizeof(_keyReport.keys); i++) { 225 | if (0 != k && _keyReport.keys[i] == k) { 226 | _keyReport.keys[i] = 0x00; 227 | } 228 | } 229 | 230 | usbSetInterrupt((uint8_t*)&_keyReport, sizeof(_keyReport)); 231 | 232 | return 1; 233 | } 234 | 235 | KeyReport _keyReport; 236 | 237 | //private: TODO: Make friend? 238 | uchar reportBuffer[4]; // buffer for HID reports [ 1 modifier byte + (len-1) key strokes] 239 | 240 | }; 241 | 242 | UsbKeyboardDevice UsbKeyboard = UsbKeyboardDevice(); 243 | 244 | #ifdef __cplusplus 245 | extern "C"{ 246 | #endif 247 | // USB_PUBLIC uchar usbFunctionSetup 248 | uchar usbFunctionSetup(uchar data[8]) 249 | { 250 | usbRequest_t *rq = (usbRequest_t *)((void *)data); 251 | 252 | usbMsgPtr = UsbKeyboard.reportBuffer; // 253 | if((rq->bmRequestType & USBRQ_TYPE_MASK) == USBRQ_TYPE_CLASS){ 254 | /* class request type */ 255 | 256 | if(rq->bRequest == USBRQ_HID_GET_REPORT){ 257 | /* wValue: ReportType (highbyte), ReportID (lowbyte) */ 258 | 259 | /* we only have one report type, so don't look at wValue */ 260 | // TODO: Ensure it's okay not to return anything here? 261 | return 0; 262 | 263 | }else if(rq->bRequest == USBRQ_HID_GET_IDLE){ 264 | // usbMsgPtr = &idleRate; 265 | // return 1; 266 | return 0; 267 | }else if(rq->bRequest == USBRQ_HID_SET_IDLE){ 268 | idleRate = rq->wValue.bytes[1]; 269 | } 270 | }else{ 271 | /* no vendor specific requests implemented */ 272 | } 273 | return 0; 274 | } 275 | #ifdef __cplusplus 276 | } // extern "C" 277 | #endif 278 | 279 | 280 | #endif // __UsbKeyboard_h__ 281 | -------------------------------------------------------------------------------- /UsbKeyboard/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 | * Revision: $Id$ 9 | */ 10 | 11 | /* Do not link this file! Link usbdrvasm.S instead, which includes the 12 | * appropriate implementation! 13 | */ 14 | 15 | /* 16 | General Description: 17 | This file contains assembler code which is shared among the USB driver 18 | implementations for different CPU cocks. Since the code must be inserted 19 | in the middle of the module, it's split out into this file and #included. 20 | 21 | Jump destinations called from outside: 22 | sofError: Called when no start sequence was found. 23 | se0: Called when a package has been successfully received. 24 | overflow: Called when receive buffer overflows. 25 | doReturn: Called after sending data. 26 | 27 | Outside jump destinations used by this module: 28 | waitForJ: Called to receive an already arriving packet. 29 | sendAckAndReti: 30 | sendNakAndReti: 31 | sendCntAndReti: 32 | usbSendAndReti: 33 | 34 | The following macros must be defined before this file is included: 35 | .macro POP_STANDARD 36 | .endm 37 | .macro POP_RETI 38 | .endm 39 | */ 40 | 41 | #define token x1 42 | 43 | overflow: 44 | ldi x2, 1< 0 14 | 15 | #warning "Never compile production devices with debugging enabled" 16 | 17 | static void uartPutc(char c) 18 | { 19 | while(!(ODDBG_USR & (1 << ODDBG_UDRE))); /* wait for data register empty */ 20 | ODDBG_UDR = c; 21 | } 22 | 23 | static uchar hexAscii(uchar h) 24 | { 25 | h &= 0xf; 26 | if(h >= 10) 27 | h += 'a' - (uchar)10 - '0'; 28 | h += '0'; 29 | return h; 30 | } 31 | 32 | static void printHex(uchar c) 33 | { 34 | uartPutc(hexAscii(c >> 4)); 35 | uartPutc(hexAscii(c)); 36 | } 37 | 38 | void odDebug(uchar prefix, uchar *data, uchar len) 39 | { 40 | printHex(prefix); 41 | uartPutc(':'); 42 | while(len--){ 43 | uartPutc(' '); 44 | printHex(*data++); 45 | } 46 | uartPutc('\r'); 47 | uartPutc('\n'); 48 | } 49 | 50 | #endif 51 | -------------------------------------------------------------------------------- /UsbKeyboard/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 | * This Revision: $Id: oddebug.h 692 2008-11-07 15:07:40Z cs $ 9 | */ 10 | 11 | #ifndef __oddebug_h_included__ 12 | #define __oddebug_h_included__ 13 | 14 | /* 15 | General Description: 16 | This module implements a function for debug logs on the serial line of the 17 | AVR microcontroller. Debugging can be configured with the define 18 | 'DEBUG_LEVEL'. If this macro is not defined or defined to 0, all debugging 19 | calls are no-ops. If it is 1, DBG1 logs will appear, but not DBG2. If it is 20 | 2, DBG1 and DBG2 logs will be printed. 21 | 22 | A debug log consists of a label ('prefix') to indicate which debug log created 23 | the output and a memory block to dump in hex ('data' and 'len'). 24 | */ 25 | 26 | 27 | #ifndef F_CPU 28 | # define F_CPU 12000000 /* 12 MHz */ 29 | #endif 30 | 31 | /* make sure we have the UART defines: */ 32 | #include "usbportability.h" 33 | 34 | #ifndef uchar 35 | # define uchar unsigned char 36 | #endif 37 | 38 | #if DEBUG_LEVEL > 0 && !(defined TXEN || defined TXEN0) /* no UART in device */ 39 | # warning "Debugging disabled because device has no UART" 40 | # undef DEBUG_LEVEL 41 | #endif 42 | 43 | #ifndef DEBUG_LEVEL 44 | # define DEBUG_LEVEL 0 45 | #endif 46 | 47 | /* ------------------------------------------------------------------------- */ 48 | 49 | #if DEBUG_LEVEL > 0 50 | # define DBG1(prefix, data, len) odDebug(prefix, data, len) 51 | #else 52 | # define DBG1(prefix, data, len) 53 | #endif 54 | 55 | #if DEBUG_LEVEL > 1 56 | # define DBG2(prefix, data, len) odDebug(prefix, data, len) 57 | #else 58 | # define DBG2(prefix, data, len) 59 | #endif 60 | 61 | /* ------------------------------------------------------------------------- */ 62 | 63 | #if DEBUG_LEVEL > 0 64 | extern void odDebug(uchar prefix, uchar *data, uchar len); 65 | 66 | /* Try to find our control registers; ATMEL likes to rename these */ 67 | 68 | #if defined UBRR 69 | # define ODDBG_UBRR UBRR 70 | #elif defined UBRRL 71 | # define ODDBG_UBRR UBRRL 72 | #elif defined UBRR0 73 | # define ODDBG_UBRR UBRR0 74 | #elif defined UBRR0L 75 | # define ODDBG_UBRR UBRR0L 76 | #endif 77 | 78 | #if defined UCR 79 | # define ODDBG_UCR UCR 80 | #elif defined UCSRB 81 | # define ODDBG_UCR UCSRB 82 | #elif defined UCSR0B 83 | # define ODDBG_UCR UCSR0B 84 | #endif 85 | 86 | #if defined TXEN 87 | # define ODDBG_TXEN TXEN 88 | #else 89 | # define ODDBG_TXEN TXEN0 90 | #endif 91 | 92 | #if defined USR 93 | # define ODDBG_USR USR 94 | #elif defined UCSRA 95 | # define ODDBG_USR UCSRA 96 | #elif defined UCSR0A 97 | # define ODDBG_USR UCSR0A 98 | #endif 99 | 100 | #if defined UDRE 101 | # define ODDBG_UDRE UDRE 102 | #else 103 | # define ODDBG_UDRE UDRE0 104 | #endif 105 | 106 | #if defined UDR 107 | # define ODDBG_UDR UDR 108 | #elif defined UDR0 109 | # define ODDBG_UDR UDR0 110 | #endif 111 | 112 | static inline void odDebugInit(void) 113 | { 114 | ODDBG_UCR |= (1< max 25 cycles interrupt disable 39 | ;max stack usage: [ret(2), YL, SREG, YH, shift, x1, x2, x3, cnt, x4] = 11 bytes 40 | ;Numbers in brackets are maximum cycles since SOF. 41 | USB_INTR_VECTOR: 42 | ;order of registers pushed: YL, SREG [sofError], YH, shift, x1, x2, x3, cnt 43 | push YL ;2 [35] push only what is necessary to sync with edge ASAP 44 | in YL, SREG ;1 [37] 45 | push YL ;2 [39] 46 | ;---------------------------------------------------------------------------- 47 | ; Synchronize with sync pattern: 48 | ;---------------------------------------------------------------------------- 49 | ;sync byte (D-) pattern LSb to MSb: 01010100 [1 = idle = J, 0 = K] 50 | ;sync up with J to K edge during sync pattern -- use fastest possible loops 51 | ;The first part waits at most 1 bit long since we must be in sync pattern. 52 | ;YL is guarenteed to be < 0x80 because I flag is clear. When we jump to 53 | ;waitForJ, ensure that this prerequisite is met. 54 | waitForJ: 55 | inc YL 56 | sbis USBIN, USBMINUS 57 | brne waitForJ ; just make sure we have ANY timeout 58 | waitForK: 59 | ;The following code results in a sampling window of 1/4 bit which meets the spec. 60 | sbis USBIN, USBMINUS 61 | rjmp foundK 62 | sbis USBIN, USBMINUS 63 | rjmp foundK 64 | sbis USBIN, USBMINUS 65 | rjmp foundK 66 | sbis USBIN, USBMINUS 67 | rjmp foundK 68 | sbis USBIN, USBMINUS 69 | rjmp foundK 70 | #if USB_COUNT_SOF 71 | lds YL, usbSofCount 72 | inc YL 73 | sts usbSofCount, YL 74 | #endif /* USB_COUNT_SOF */ 75 | #ifdef USB_SOF_HOOK 76 | USB_SOF_HOOK 77 | #endif 78 | rjmp sofError 79 | foundK: 80 | ;{3, 5} after falling D- edge, average delay: 4 cycles [we want 4 for center sampling] 81 | ;we have 1 bit time for setup purposes, then sample again. Numbers in brackets 82 | ;are cycles from center of first sync (double K) bit after the instruction 83 | push YH ;2 [2] 84 | lds YL, usbInputBufOffset;2 [4] 85 | clr YH ;1 [5] 86 | subi YL, lo8(-(usbRxBuf));1 [6] 87 | sbci YH, hi8(-(usbRxBuf));1 [7] 88 | 89 | sbis USBIN, USBMINUS ;1 [8] we want two bits K [sample 1 cycle too early] 90 | rjmp haveTwoBitsK ;2 [10] 91 | pop YH ;2 [11] undo the push from before 92 | rjmp waitForK ;2 [13] this was not the end of sync, retry 93 | haveTwoBitsK: 94 | ;---------------------------------------------------------------------------- 95 | ; push more registers and initialize values while we sample the first bits: 96 | ;---------------------------------------------------------------------------- 97 | push shift ;2 [16] 98 | push x1 ;2 [12] 99 | push x2 ;2 [14] 100 | 101 | in x1, USBIN ;1 [17] <-- sample bit 0 102 | ldi shift, 0xff ;1 [18] 103 | bst x1, USBMINUS ;1 [19] 104 | bld shift, 0 ;1 [20] 105 | push x3 ;2 [22] 106 | push cnt ;2 [24] 107 | 108 | in x2, USBIN ;1 [25] <-- sample bit 1 109 | ser x3 ;1 [26] [inserted init instruction] 110 | eor x1, x2 ;1 [27] 111 | bst x1, USBMINUS ;1 [28] 112 | bld shift, 1 ;1 [29] 113 | ldi cnt, USB_BUFSIZE;1 [30] [inserted init instruction] 114 | rjmp rxbit2 ;2 [32] 115 | 116 | ;---------------------------------------------------------------------------- 117 | ; Receiver loop (numbers in brackets are cycles within byte after instr) 118 | ;---------------------------------------------------------------------------- 119 | 120 | unstuff0: ;1 (branch taken) 121 | andi x3, ~0x01 ;1 [15] 122 | mov x1, x2 ;1 [16] x2 contains last sampled (stuffed) bit 123 | in x2, USBIN ;1 [17] <-- sample bit 1 again 124 | ori shift, 0x01 ;1 [18] 125 | rjmp didUnstuff0 ;2 [20] 126 | 127 | unstuff1: ;1 (branch taken) 128 | mov x2, x1 ;1 [21] x1 contains last sampled (stuffed) bit 129 | andi x3, ~0x02 ;1 [22] 130 | ori shift, 0x02 ;1 [23] 131 | nop ;1 [24] 132 | in x1, USBIN ;1 [25] <-- sample bit 2 again 133 | rjmp didUnstuff1 ;2 [27] 134 | 135 | unstuff2: ;1 (branch taken) 136 | andi x3, ~0x04 ;1 [29] 137 | ori shift, 0x04 ;1 [30] 138 | mov x1, x2 ;1 [31] x2 contains last sampled (stuffed) bit 139 | nop ;1 [32] 140 | in x2, USBIN ;1 [33] <-- sample bit 3 141 | rjmp didUnstuff2 ;2 [35] 142 | 143 | unstuff3: ;1 (branch taken) 144 | in x2, USBIN ;1 [34] <-- sample stuffed bit 3 [one cycle too late] 145 | andi x3, ~0x08 ;1 [35] 146 | ori shift, 0x08 ;1 [36] 147 | rjmp didUnstuff3 ;2 [38] 148 | 149 | unstuff4: ;1 (branch taken) 150 | andi x3, ~0x10 ;1 [40] 151 | in x1, USBIN ;1 [41] <-- sample stuffed bit 4 152 | ori shift, 0x10 ;1 [42] 153 | rjmp didUnstuff4 ;2 [44] 154 | 155 | unstuff5: ;1 (branch taken) 156 | andi x3, ~0x20 ;1 [48] 157 | in x2, USBIN ;1 [49] <-- sample stuffed bit 5 158 | ori shift, 0x20 ;1 [50] 159 | rjmp didUnstuff5 ;2 [52] 160 | 161 | unstuff6: ;1 (branch taken) 162 | andi x3, ~0x40 ;1 [56] 163 | in x1, USBIN ;1 [57] <-- sample stuffed bit 6 164 | ori shift, 0x40 ;1 [58] 165 | rjmp didUnstuff6 ;2 [60] 166 | 167 | ; extra jobs done during bit interval: 168 | ; bit 0: store, clear [SE0 is unreliable here due to bit dribbling in hubs] 169 | ; bit 1: se0 check 170 | ; bit 2: overflow check 171 | ; bit 3: recovery from delay [bit 0 tasks took too long] 172 | ; bit 4: none 173 | ; bit 5: none 174 | ; bit 6: none 175 | ; bit 7: jump, eor 176 | rxLoop: 177 | eor x3, shift ;1 [0] reconstruct: x3 is 0 at bit locations we changed, 1 at others 178 | in x1, USBIN ;1 [1] <-- sample bit 0 179 | st y+, x3 ;2 [3] store data 180 | ser x3 ;1 [4] 181 | nop ;1 [5] 182 | eor x2, x1 ;1 [6] 183 | bst x2, USBMINUS;1 [7] 184 | bld shift, 0 ;1 [8] 185 | in x2, USBIN ;1 [9] <-- sample bit 1 (or possibly bit 0 stuffed) 186 | andi x2, USBMASK ;1 [10] 187 | breq se0 ;1 [11] SE0 check for bit 1 188 | andi shift, 0xf9 ;1 [12] 189 | didUnstuff0: 190 | breq unstuff0 ;1 [13] 191 | eor x1, x2 ;1 [14] 192 | bst x1, USBMINUS;1 [15] 193 | bld shift, 1 ;1 [16] 194 | rxbit2: 195 | in x1, USBIN ;1 [17] <-- sample bit 2 (or possibly bit 1 stuffed) 196 | andi shift, 0xf3 ;1 [18] 197 | breq unstuff1 ;1 [19] do remaining work for bit 1 198 | didUnstuff1: 199 | subi cnt, 1 ;1 [20] 200 | brcs overflow ;1 [21] loop control 201 | eor x2, x1 ;1 [22] 202 | bst x2, USBMINUS;1 [23] 203 | bld shift, 2 ;1 [24] 204 | in x2, USBIN ;1 [25] <-- sample bit 3 (or possibly bit 2 stuffed) 205 | andi shift, 0xe7 ;1 [26] 206 | breq unstuff2 ;1 [27] 207 | didUnstuff2: 208 | eor x1, x2 ;1 [28] 209 | bst x1, USBMINUS;1 [29] 210 | bld shift, 3 ;1 [30] 211 | didUnstuff3: 212 | andi shift, 0xcf ;1 [31] 213 | breq unstuff3 ;1 [32] 214 | in x1, USBIN ;1 [33] <-- sample bit 4 215 | eor x2, x1 ;1 [34] 216 | bst x2, USBMINUS;1 [35] 217 | bld shift, 4 ;1 [36] 218 | didUnstuff4: 219 | andi shift, 0x9f ;1 [37] 220 | breq unstuff4 ;1 [38] 221 | nop2 ;2 [40] 222 | in x2, USBIN ;1 [41] <-- sample bit 5 223 | eor x1, x2 ;1 [42] 224 | bst x1, USBMINUS;1 [43] 225 | bld shift, 5 ;1 [44] 226 | didUnstuff5: 227 | andi shift, 0x3f ;1 [45] 228 | breq unstuff5 ;1 [46] 229 | nop2 ;2 [48] 230 | in x1, USBIN ;1 [49] <-- sample bit 6 231 | eor x2, x1 ;1 [50] 232 | bst x2, USBMINUS;1 [51] 233 | bld shift, 6 ;1 [52] 234 | didUnstuff6: 235 | cpi shift, 0x02 ;1 [53] 236 | brlo unstuff6 ;1 [54] 237 | nop2 ;2 [56] 238 | in x2, USBIN ;1 [57] <-- sample bit 7 239 | eor x1, x2 ;1 [58] 240 | bst x1, USBMINUS;1 [59] 241 | bld shift, 7 ;1 [60] 242 | didUnstuff7: 243 | cpi shift, 0x04 ;1 [61] 244 | brsh rxLoop ;2 [63] loop control 245 | unstuff7: 246 | andi x3, ~0x80 ;1 [63] 247 | ori shift, 0x80 ;1 [64] 248 | in x2, USBIN ;1 [65] <-- sample stuffed bit 7 249 | nop ;1 [66] 250 | rjmp didUnstuff7 ;2 [68] 251 | 252 | macro POP_STANDARD ; 12 cycles 253 | pop cnt 254 | pop x3 255 | pop x2 256 | pop x1 257 | pop shift 258 | pop YH 259 | endm 260 | macro POP_RETI ; 5 cycles 261 | pop YL 262 | out SREG, YL 263 | pop YL 264 | endm 265 | 266 | #include "asmcommon.inc" 267 | 268 | ;---------------------------------------------------------------------------- 269 | ; Transmitting data 270 | ;---------------------------------------------------------------------------- 271 | 272 | txByteLoop: 273 | txBitloop: 274 | stuffN1Delay: ; [03] 275 | ror shift ;[-5] [11] [59] 276 | brcc doExorN1 ;[-4] [60] 277 | subi x4, 1 ;[-3] 278 | brne commonN1 ;[-2] 279 | lsl shift ;[-1] compensate ror after rjmp stuffDelay 280 | nop ;[00] stuffing consists of just waiting 8 cycles 281 | rjmp stuffN1Delay ;[01] after ror, C bit is reliably clear 282 | 283 | sendNakAndReti: ;0 [-19] 19 cycles until SOP 284 | ldi x3, USBPID_NAK ;1 [-18] 285 | rjmp usbSendX3 ;2 [-16] 286 | sendAckAndReti: ;0 [-19] 19 cycles until SOP 287 | ldi x3, USBPID_ACK ;1 [-18] 288 | rjmp usbSendX3 ;2 [-16] 289 | sendCntAndReti: ;0 [-17] 17 cycles until SOP 290 | mov x3, cnt ;1 [-16] 291 | usbSendX3: ;0 [-16] 292 | ldi YL, 20 ;1 [-15] 'x3' is R20 293 | ldi YH, 0 ;1 [-14] 294 | ldi cnt, 2 ;1 [-13] 295 | ; rjmp usbSendAndReti fallthrough 296 | 297 | ; USB spec says: 298 | ; idle = J 299 | ; J = (D+ = 0), (D- = 1) or USBOUT = 0x01 300 | ; K = (D+ = 1), (D- = 0) or USBOUT = 0x02 301 | ; Spec allows 7.5 bit times from EOP to SOP for replies (= 60 cycles) 302 | 303 | ;usbSend: 304 | ;pointer to data in 'Y' 305 | ;number of bytes in 'cnt' -- including sync byte 306 | ;uses: x1...x2, x4, shift, cnt, Y [x1 = mirror USBOUT, x2 = USBMASK, x4 = bitstuff cnt] 307 | ;Numbers in brackets are time since first bit of sync pattern is sent (start of instruction) 308 | usbSendAndReti: 309 | in x2, USBDDR ;[-12] 12 cycles until SOP 310 | ori x2, USBMASK ;[-11] 311 | sbi USBOUT, USBMINUS ;[-10] prepare idle state; D+ and D- must have been 0 (no pullups) 312 | out USBDDR, x2 ;[-8] <--- acquire bus 313 | in x1, USBOUT ;[-7] port mirror for tx loop 314 | ldi shift, 0x40 ;[-6] sync byte is first byte sent (we enter loop after ror) 315 | ldi x2, USBMASK ;[-5] 316 | push x4 ;[-4] 317 | doExorN1: 318 | eor x1, x2 ;[-2] [06] [62] 319 | ldi x4, 6 ;[-1] [07] [63] 320 | commonN1: 321 | stuffN2Delay: 322 | out USBOUT, x1 ;[00] [08] [64] <--- set bit 323 | ror shift ;[01] 324 | brcc doExorN2 ;[02] 325 | subi x4, 1 ;[03] 326 | brne commonN2 ;[04] 327 | lsl shift ;[05] compensate ror after rjmp stuffDelay 328 | rjmp stuffN2Delay ;[06] after ror, C bit is reliably clear 329 | doExorN2: 330 | eor x1, x2 ;[04] [12] 331 | ldi x4, 6 ;[05] [13] 332 | commonN2: 333 | nop ;[06] [14] 334 | subi cnt, 171 ;[07] [15] trick: (3 * 171) & 0xff = 1 335 | out USBOUT, x1 ;[08] [16] <--- set bit 336 | brcs txBitloop ;[09] [25] [41] 337 | 338 | stuff6Delay: 339 | ror shift ;[42] [50] 340 | brcc doExor6 ;[43] 341 | subi x4, 1 ;[44] 342 | brne common6 ;[45] 343 | lsl shift ;[46] compensate ror after rjmp stuffDelay 344 | nop ;[47] stuffing consists of just waiting 8 cycles 345 | rjmp stuff6Delay ;[48] after ror, C bit is reliably clear 346 | doExor6: 347 | eor x1, x2 ;[45] [53] 348 | ldi x4, 6 ;[46] 349 | common6: 350 | stuff7Delay: 351 | ror shift ;[47] [55] 352 | out USBOUT, x1 ;[48] <--- set bit 353 | brcc doExor7 ;[49] 354 | subi x4, 1 ;[50] 355 | brne common7 ;[51] 356 | lsl shift ;[52] compensate ror after rjmp stuffDelay 357 | rjmp stuff7Delay ;[53] after ror, C bit is reliably clear 358 | doExor7: 359 | eor x1, x2 ;[51] [59] 360 | ldi x4, 6 ;[52] 361 | common7: 362 | ld shift, y+ ;[53] 363 | tst cnt ;[55] 364 | out USBOUT, x1 ;[56] <--- set bit 365 | brne txByteLoop ;[57] 366 | 367 | ;make SE0: 368 | cbr x1, USBMASK ;[58] prepare SE0 [spec says EOP may be 15 to 18 cycles] 369 | lds x2, usbNewDeviceAddr;[59] 370 | lsl x2 ;[61] we compare with left shifted address 371 | subi YL, 2 + 20 ;[62] Only assign address on data packets, not ACK/NAK in x3 372 | sbci YH, 0 ;[63] 373 | out USBOUT, x1 ;[00] <-- out SE0 -- from now 2 bits = 16 cycles until bus idle 374 | ;2006-03-06: moved transfer of new address to usbDeviceAddr from C-Code to asm: 375 | ;set address only after data packet was sent, not after handshake 376 | breq skipAddrAssign ;[01] 377 | sts usbDeviceAddr, x2 ; if not skipped: SE0 is one cycle longer 378 | skipAddrAssign: 379 | ;end of usbDeviceAddress transfer 380 | ldi x2, 1< 10.0 cycles per bit, 80.0 cycles per byte 30 | ; Numbers in brackets are clocks counted from center of last sync bit 31 | ; when instruction starts 32 | 33 | ;---------------------------------------------------------------------------- 34 | ; order of registers pushed: 35 | ; YL, SREG [sofError] YH, shift, x1, x2, x3, bitcnt, cnt, x4 36 | ;---------------------------------------------------------------------------- 37 | USB_INTR_VECTOR: 38 | push YL ;2 push only what is necessary to sync with edge ASAP 39 | in YL, SREG ;1 40 | push YL ;2 41 | ;---------------------------------------------------------------------------- 42 | ; Synchronize with sync pattern: 43 | ; 44 | ; sync byte (D-) pattern LSb to MSb: 01010100 [1 = idle = J, 0 = K] 45 | ; sync up with J to K edge during sync pattern -- use fastest possible loops 46 | ;The first part waits at most 1 bit long since we must be in sync pattern. 47 | ;YL is guarenteed to be < 0x80 because I flag is clear. When we jump to 48 | ;waitForJ, ensure that this prerequisite is met. 49 | waitForJ: 50 | inc YL 51 | sbis USBIN, USBMINUS 52 | brne waitForJ ; just make sure we have ANY timeout 53 | ;------------------------------------------------------------------------------- 54 | ; The following code results in a sampling window of < 1/4 bit 55 | ; which meets the spec. 56 | ;------------------------------------------------------------------------------- 57 | waitForK: ;- 58 | sbis USBIN, USBMINUS ;1 [00] <-- sample 59 | rjmp foundK ;2 [01] 60 | sbis USBIN, USBMINUS ; <-- sample 61 | rjmp foundK 62 | sbis USBIN, USBMINUS ; <-- sample 63 | rjmp foundK 64 | sbis USBIN, USBMINUS ; <-- sample 65 | rjmp foundK 66 | sbis USBIN, USBMINUS ; <-- sample 67 | rjmp foundK 68 | sbis USBIN, USBMINUS ; <-- sample 69 | rjmp foundK 70 | #if USB_COUNT_SOF 71 | lds YL, usbSofCount 72 | inc YL 73 | sts usbSofCount, YL 74 | #endif /* USB_COUNT_SOF */ 75 | #ifdef USB_SOF_HOOK 76 | USB_SOF_HOOK 77 | #endif 78 | rjmp sofError 79 | ;------------------------------------------------------------------------------ 80 | ; {3, 5} after falling D- edge, average delay: 4 cycles [we want 5 for 81 | ; center sampling] 82 | ; we have 1 bit time for setup purposes, then sample again. 83 | ; Numbers in brackets are cycles from center of first sync (double K) 84 | ; bit after the instruction 85 | ;------------------------------------------------------------------------------ 86 | foundK: ;- [02] 87 | lds YL, usbInputBufOffset;2 [03+04] tx loop 88 | push YH ;2 [05+06] 89 | clr YH ;1 [07] 90 | subi YL, lo8(-(usbRxBuf)) ;1 [08] [rx loop init] 91 | sbci YH, hi8(-(usbRxBuf)) ;1 [09] [rx loop init] 92 | push shift ;2 [10+11] 93 | ser shift ;1 [12] 94 | sbis USBIN, USBMINUS ;1 [-1] [13] <--sample:we want two bits K (sample 1 cycle too early) 95 | rjmp haveTwoBitsK ;2 [00] [14] 96 | pop shift ;2 [15+16] undo the push from before 97 | pop YH ;2 [17+18] undo the push from before 98 | rjmp waitForK ;2 [19+20] this was not the end of sync, retry 99 | ; The entire loop from waitForK until rjmp waitForK above must not exceed two 100 | ; bit times (= 20 cycles). 101 | 102 | ;---------------------------------------------------------------------------- 103 | ; push more registers and initialize values while we sample the first bits: 104 | ;---------------------------------------------------------------------------- 105 | haveTwoBitsK: ;- [01] 106 | push x1 ;2 [02+03] 107 | push x2 ;2 [04+05] 108 | push x3 ;2 [06+07] 109 | push bitcnt ;2 [08+09] 110 | in x1, USBIN ;1 [00] [10] <-- sample bit 0 111 | bst x1, USBMINUS ;1 [01] 112 | bld shift, 0 ;1 [02] 113 | push cnt ;2 [03+04] 114 | ldi cnt, USB_BUFSIZE ;1 [05] 115 | push x4 ;2 [06+07] tx loop 116 | rjmp rxLoop ;2 [08] 117 | ;---------------------------------------------------------------------------- 118 | ; Receiver loop (numbers in brackets are cycles within byte after instr) 119 | ;---------------------------------------------------------------------------- 120 | unstuff0: ;- [07] (branch taken) 121 | andi x3, ~0x01 ;1 [08] 122 | mov x1, x2 ;1 [09] x2 contains last sampled (stuffed) bit 123 | in x2, USBIN ;1 [00] [10] <-- sample bit 1 again 124 | andi x2, USBMASK ;1 [01] 125 | breq se0Hop ;1 [02] SE0 check for bit 1 126 | ori shift, 0x01 ;1 [03] 0b00000001 127 | nop ;1 [04] 128 | rjmp didUnstuff0 ;2 [05] 129 | ;----------------------------------------------------- 130 | unstuff1: ;- [05] (branch taken) 131 | mov x2, x1 ;1 [06] x1 contains last sampled (stuffed) bit 132 | andi x3, ~0x02 ;1 [07] 133 | ori shift, 0x02 ;1 [08] 0b00000010 134 | nop ;1 [09] 135 | in x1, USBIN ;1 [00] [10] <-- sample bit 2 again 136 | andi x1, USBMASK ;1 [01] 137 | breq se0Hop ;1 [02] SE0 check for bit 2 138 | rjmp didUnstuff1 ;2 [03] 139 | ;----------------------------------------------------- 140 | unstuff2: ;- [05] (branch taken) 141 | andi x3, ~0x04 ;1 [06] 142 | ori shift, 0x04 ;1 [07] 0b00000100 143 | mov x1, x2 ;1 [08] x2 contains last sampled (stuffed) bit 144 | nop ;1 [09] 145 | in x2, USBIN ;1 [00] [10] <-- sample bit 3 146 | andi x2, USBMASK ;1 [01] 147 | breq se0Hop ;1 [02] SE0 check for bit 3 148 | rjmp didUnstuff2 ;2 [03] 149 | ;----------------------------------------------------- 150 | unstuff3: ;- [00] [10] (branch taken) 151 | in x2, USBIN ;1 [01] [11] <-- sample stuffed bit 3 one cycle too late 152 | andi x2, USBMASK ;1 [02] 153 | breq se0Hop ;1 [03] SE0 check for stuffed bit 3 154 | andi x3, ~0x08 ;1 [04] 155 | ori shift, 0x08 ;1 [05] 0b00001000 156 | rjmp didUnstuff3 ;2 [06] 157 | ;---------------------------------------------------------------------------- 158 | ; extra jobs done during bit interval: 159 | ; 160 | ; bit 0: store, clear [SE0 is unreliable here due to bit dribbling in hubs], 161 | ; overflow check, jump to the head of rxLoop 162 | ; bit 1: SE0 check 163 | ; bit 2: SE0 check, recovery from delay [bit 0 tasks took too long] 164 | ; bit 3: SE0 check, recovery from delay [bit 0 tasks took too long] 165 | ; bit 4: SE0 check, none 166 | ; bit 5: SE0 check, none 167 | ; bit 6: SE0 check, none 168 | ; bit 7: SE0 check, reconstruct: x3 is 0 at bit locations we changed, 1 at others 169 | ;---------------------------------------------------------------------------- 170 | rxLoop: ;- [09] 171 | in x2, USBIN ;1 [00] [10] <-- sample bit 1 (or possibly bit 0 stuffed) 172 | andi x2, USBMASK ;1 [01] 173 | brne SkipSe0Hop ;1 [02] 174 | se0Hop: ;- [02] 175 | rjmp se0 ;2 [03] SE0 check for bit 1 176 | SkipSe0Hop: ;- [03] 177 | ser x3 ;1 [04] 178 | andi shift, 0xf9 ;1 [05] 0b11111001 179 | breq unstuff0 ;1 [06] 180 | didUnstuff0: ;- [06] 181 | eor x1, x2 ;1 [07] 182 | bst x1, USBMINUS ;1 [08] 183 | bld shift, 1 ;1 [09] 184 | in x1, USBIN ;1 [00] [10] <-- sample bit 2 (or possibly bit 1 stuffed) 185 | andi x1, USBMASK ;1 [01] 186 | breq se0Hop ;1 [02] SE0 check for bit 2 187 | andi shift, 0xf3 ;1 [03] 0b11110011 188 | breq unstuff1 ;1 [04] do remaining work for bit 1 189 | didUnstuff1: ;- [04] 190 | eor x2, x1 ;1 [05] 191 | bst x2, USBMINUS ;1 [06] 192 | bld shift, 2 ;1 [07] 193 | nop2 ;2 [08+09] 194 | in x2, USBIN ;1 [00] [10] <-- sample bit 3 (or possibly bit 2 stuffed) 195 | andi x2, USBMASK ;1 [01] 196 | breq se0Hop ;1 [02] SE0 check for bit 3 197 | andi shift, 0xe7 ;1 [03] 0b11100111 198 | breq unstuff2 ;1 [04] 199 | didUnstuff2: ;- [04] 200 | eor x1, x2 ;1 [05] 201 | bst x1, USBMINUS ;1 [06] 202 | bld shift, 3 ;1 [07] 203 | didUnstuff3: ;- [07] 204 | andi shift, 0xcf ;1 [08] 0b11001111 205 | breq unstuff3 ;1 [09] 206 | in x1, USBIN ;1 [00] [10] <-- sample bit 4 207 | andi x1, USBMASK ;1 [01] 208 | breq se0Hop ;1 [02] SE0 check for bit 4 209 | eor x2, x1 ;1 [03] 210 | bst x2, USBMINUS ;1 [04] 211 | bld shift, 4 ;1 [05] 212 | didUnstuff4: ;- [05] 213 | andi shift, 0x9f ;1 [06] 0b10011111 214 | breq unstuff4 ;1 [07] 215 | nop2 ;2 [08+09] 216 | in x2, USBIN ;1 [00] [10] <-- sample bit 5 217 | andi x2, USBMASK ;1 [01] 218 | breq se0 ;1 [02] SE0 check for bit 5 219 | eor x1, x2 ;1 [03] 220 | bst x1, USBMINUS ;1 [04] 221 | bld shift, 5 ;1 [05] 222 | didUnstuff5: ;- [05] 223 | andi shift, 0x3f ;1 [06] 0b00111111 224 | breq unstuff5 ;1 [07] 225 | nop2 ;2 [08+09] 226 | in x1, USBIN ;1 [00] [10] <-- sample bit 6 227 | andi x1, USBMASK ;1 [01] 228 | breq se0 ;1 [02] SE0 check for bit 6 229 | eor x2, x1 ;1 [03] 230 | bst x2, USBMINUS ;1 [04] 231 | bld shift, 6 ;1 [05] 232 | didUnstuff6: ;- [05] 233 | cpi shift, 0x02 ;1 [06] 0b00000010 234 | brlo unstuff6 ;1 [07] 235 | nop2 ;2 [08+09] 236 | in x2, USBIN ;1 [00] [10] <-- sample bit 7 237 | andi x2, USBMASK ;1 [01] 238 | breq se0 ;1 [02] SE0 check for bit 7 239 | eor x1, x2 ;1 [03] 240 | bst x1, USBMINUS ;1 [04] 241 | bld shift, 7 ;1 [05] 242 | didUnstuff7: ;- [05] 243 | cpi shift, 0x04 ;1 [06] 0b00000100 244 | brlo unstuff7 ;1 [07] 245 | eor x3, shift ;1 [08] reconstruct: x3 is 0 at bit locations we changed, 1 at others 246 | nop ;1 [09] 247 | in x1, USBIN ;1 [00] [10] <-- sample bit 0 248 | st y+, x3 ;2 [01+02] store data 249 | eor x2, x1 ;1 [03] 250 | bst x2, USBMINUS ;1 [04] 251 | bld shift, 0 ;1 [05] 252 | subi cnt, 1 ;1 [06] 253 | brcs overflow ;1 [07] 254 | rjmp rxLoop ;2 [08] 255 | ;----------------------------------------------------- 256 | unstuff4: ;- [08] 257 | andi x3, ~0x10 ;1 [09] 258 | in x1, USBIN ;1 [00] [10] <-- sample stuffed bit 4 259 | andi x1, USBMASK ;1 [01] 260 | breq se0 ;1 [02] SE0 check for stuffed bit 4 261 | ori shift, 0x10 ;1 [03] 262 | rjmp didUnstuff4 ;2 [04] 263 | ;----------------------------------------------------- 264 | unstuff5: ;- [08] 265 | ori shift, 0x20 ;1 [09] 266 | in x2, USBIN ;1 [00] [10] <-- sample stuffed bit 5 267 | andi x2, USBMASK ;1 [01] 268 | breq se0 ;1 [02] SE0 check for stuffed bit 5 269 | andi x3, ~0x20 ;1 [03] 270 | rjmp didUnstuff5 ;2 [04] 271 | ;----------------------------------------------------- 272 | unstuff6: ;- [08] 273 | andi x3, ~0x40 ;1 [09] 274 | in x1, USBIN ;1 [00] [10] <-- sample stuffed bit 6 275 | andi x1, USBMASK ;1 [01] 276 | breq se0 ;1 [02] SE0 check for stuffed bit 6 277 | ori shift, 0x40 ;1 [03] 278 | rjmp didUnstuff6 ;2 [04] 279 | ;----------------------------------------------------- 280 | unstuff7: ;- [08] 281 | andi x3, ~0x80 ;1 [09] 282 | in x2, USBIN ;1 [00] [10] <-- sample stuffed bit 7 283 | andi x2, USBMASK ;1 [01] 284 | breq se0 ;1 [02] SE0 check for stuffed bit 7 285 | ori shift, 0x80 ;1 [03] 286 | rjmp didUnstuff7 ;2 [04] 287 | 288 | macro POP_STANDARD ; 16 cycles 289 | pop x4 290 | pop cnt 291 | pop bitcnt 292 | pop x3 293 | pop x2 294 | pop x1 295 | pop shift 296 | pop YH 297 | endm 298 | macro POP_RETI ; 5 cycles 299 | pop YL 300 | out SREG, YL 301 | pop YL 302 | endm 303 | 304 | #include "asmcommon.inc" 305 | 306 | ;--------------------------------------------------------------------------- 307 | ; USB spec says: 308 | ; idle = J 309 | ; J = (D+ = 0), (D- = 1) 310 | ; K = (D+ = 1), (D- = 0) 311 | ; Spec allows 7.5 bit times from EOP to SOP for replies 312 | ;--------------------------------------------------------------------------- 313 | bitstuffN: ;- [04] 314 | eor x1, x4 ;1 [05] 315 | clr x2 ;1 [06] 316 | nop ;1 [07] 317 | rjmp didStuffN ;1 [08] 318 | ;--------------------------------------------------------------------------- 319 | bitstuff6: ;- [04] 320 | eor x1, x4 ;1 [05] 321 | clr x2 ;1 [06] 322 | rjmp didStuff6 ;1 [07] 323 | ;--------------------------------------------------------------------------- 324 | bitstuff7: ;- [02] 325 | eor x1, x4 ;1 [03] 326 | clr x2 ;1 [06] 327 | nop ;1 [05] 328 | rjmp didStuff7 ;1 [06] 329 | ;--------------------------------------------------------------------------- 330 | sendNakAndReti: ;- [-19] 331 | ldi x3, USBPID_NAK ;1 [-18] 332 | rjmp sendX3AndReti ;1 [-17] 333 | ;--------------------------------------------------------------------------- 334 | sendAckAndReti: ;- [-17] 335 | ldi cnt, USBPID_ACK ;1 [-16] 336 | sendCntAndReti: ;- [-16] 337 | mov x3, cnt ;1 [-15] 338 | sendX3AndReti: ;- [-15] 339 | ldi YL, 20 ;1 [-14] x3==r20 address is 20 340 | ldi YH, 0 ;1 [-13] 341 | ldi cnt, 2 ;1 [-12] 342 | ; rjmp usbSendAndReti fallthrough 343 | ;--------------------------------------------------------------------------- 344 | ;usbSend: 345 | ;pointer to data in 'Y' 346 | ;number of bytes in 'cnt' -- including sync byte [range 2 ... 12] 347 | ;uses: x1...x4, btcnt, shift, cnt, Y 348 | ;Numbers in brackets are time since first bit of sync pattern is sent 349 | ;We need not to match the transfer rate exactly because the spec demands 350 | ;only 1.5% precision anyway. 351 | usbSendAndReti: ;- [-13] 13 cycles until SOP 352 | in x2, USBDDR ;1 [-12] 353 | ori x2, USBMASK ;1 [-11] 354 | sbi USBOUT, USBMINUS ;2 [-09-10] prepare idle state; D+ and D- must have been 0 (no pullups) 355 | in x1, USBOUT ;1 [-08] port mirror for tx loop 356 | out USBDDR, x2 ;1 [-07] <- acquire bus 357 | ; need not init x2 (bitstuff history) because sync starts with 0 358 | ldi x4, USBMASK ;1 [-06] exor mask 359 | ldi shift, 0x80 ;1 [-05] sync byte is first byte sent 360 | ldi bitcnt, 6 ;1 [-04] 361 | txBitLoop: ;- [-04] [06] 362 | sbrs shift, 0 ;1 [-03] [07] 363 | eor x1, x4 ;1 [-02] [08] 364 | ror shift ;1 [-01] [09] 365 | didStuffN: ;- [09] 366 | out USBOUT, x1 ;1 [00] [10] <-- out N 367 | ror x2 ;1 [01] 368 | cpi x2, 0xfc ;1 [02] 369 | brcc bitstuffN ;1 [03] 370 | dec bitcnt ;1 [04] 371 | brne txBitLoop ;1 [05] 372 | sbrs shift, 0 ;1 [06] 373 | eor x1, x4 ;1 [07] 374 | ror shift ;1 [08] 375 | didStuff6: ;- [08] 376 | nop ;1 [09] 377 | out USBOUT, x1 ;1 [00] [10] <-- out 6 378 | ror x2 ;1 [01] 379 | cpi x2, 0xfc ;1 [02] 380 | brcc bitstuff6 ;1 [03] 381 | sbrs shift, 0 ;1 [04] 382 | eor x1, x4 ;1 [05] 383 | ror shift ;1 [06] 384 | ror x2 ;1 [07] 385 | didStuff7: ;- [07] 386 | ldi bitcnt, 6 ;1 [08] 387 | cpi x2, 0xfc ;1 [09] 388 | out USBOUT, x1 ;1 [00] [10] <-- out 7 389 | brcc bitstuff7 ;1 [01] 390 | ld shift, y+ ;2 [02+03] 391 | dec cnt ;1 [04] 392 | brne txBitLoop ;1 [05] 393 | makeSE0: 394 | cbr x1, USBMASK ;1 [06] prepare SE0 [spec says EOP may be 19 to 23 cycles] 395 | lds x2, usbNewDeviceAddr;2 [07+08] 396 | lsl x2 ;1 [09] we compare with left shifted address 397 | ;2006-03-06: moved transfer of new address to usbDeviceAddr from C-Code to asm: 398 | ;set address only after data packet was sent, not after handshake 399 | out USBOUT, x1 ;1 [00] [10] <-- out SE0-- from now 2 bits==20 cycl. until bus idle 400 | subi YL, 20 + 2 ;1 [01] Only assign address on data packets, not ACK/NAK in x3 401 | sbci YH, 0 ;1 [02] 402 | breq skipAddrAssign ;1 [03] 403 | sts usbDeviceAddr, x2 ;2 [04+05] if not skipped: SE0 is one cycle longer 404 | ;---------------------------------------------------------------------------- 405 | ;end of usbDeviceAddress transfer 406 | skipAddrAssign: ;- [03/04] 407 | ldi x2, 1< 10.6666666 cycles per bit, 85.333333333 cycles per byte 30 | ; Numbers in brackets are clocks counted from center of last sync bit 31 | ; when instruction starts 32 | 33 | USB_INTR_VECTOR: 34 | ;order of registers pushed: YL, SREG YH, [sofError], bitcnt, shift, x1, x2, x3, x4, cnt 35 | push YL ;[-25] push only what is necessary to sync with edge ASAP 36 | in YL, SREG ;[-23] 37 | push YL ;[-22] 38 | push YH ;[-20] 39 | ;---------------------------------------------------------------------------- 40 | ; Synchronize with sync pattern: 41 | ;---------------------------------------------------------------------------- 42 | ;sync byte (D-) pattern LSb to MSb: 01010100 [1 = idle = J, 0 = K] 43 | ;sync up with J to K edge during sync pattern -- use fastest possible loops 44 | ;The first part waits at most 1 bit long since we must be in sync pattern. 45 | ;YL is guarenteed to be < 0x80 because I flag is clear. When we jump to 46 | ;waitForJ, ensure that this prerequisite is met. 47 | waitForJ: 48 | inc YL 49 | sbis USBIN, USBMINUS 50 | brne waitForJ ; just make sure we have ANY timeout 51 | waitForK: 52 | ;The following code results in a sampling window of < 1/4 bit which meets the spec. 53 | sbis USBIN, USBMINUS ;[-15] 54 | rjmp foundK ;[-14] 55 | sbis USBIN, USBMINUS 56 | rjmp foundK 57 | sbis USBIN, USBMINUS 58 | rjmp foundK 59 | sbis USBIN, USBMINUS 60 | rjmp foundK 61 | sbis USBIN, USBMINUS 62 | rjmp foundK 63 | sbis USBIN, USBMINUS 64 | rjmp foundK 65 | #if USB_COUNT_SOF 66 | lds YL, usbSofCount 67 | inc YL 68 | sts usbSofCount, YL 69 | #endif /* USB_COUNT_SOF */ 70 | #ifdef USB_SOF_HOOK 71 | USB_SOF_HOOK 72 | #endif 73 | rjmp sofError 74 | foundK: ;[-12] 75 | ;{3, 5} after falling D- edge, average delay: 4 cycles [we want 5 for center sampling] 76 | ;we have 1 bit time for setup purposes, then sample again. Numbers in brackets 77 | ;are cycles from center of first sync (double K) bit after the instruction 78 | push bitcnt ;[-12] 79 | ; [---] ;[-11] 80 | lds YL, usbInputBufOffset;[-10] 81 | ; [---] ;[-9] 82 | clr YH ;[-8] 83 | subi YL, lo8(-(usbRxBuf));[-7] [rx loop init] 84 | sbci YH, hi8(-(usbRxBuf));[-6] [rx loop init] 85 | push shift ;[-5] 86 | ; [---] ;[-4] 87 | ldi bitcnt, 0x55 ;[-3] [rx loop init] 88 | sbis USBIN, USBMINUS ;[-2] we want two bits K (sample 2 cycles too early) 89 | rjmp haveTwoBitsK ;[-1] 90 | pop shift ;[0] undo the push from before 91 | pop bitcnt ;[2] undo the push from before 92 | rjmp waitForK ;[4] this was not the end of sync, retry 93 | ; The entire loop from waitForK until rjmp waitForK above must not exceed two 94 | ; bit times (= 21 cycles). 95 | 96 | ;---------------------------------------------------------------------------- 97 | ; push more registers and initialize values while we sample the first bits: 98 | ;---------------------------------------------------------------------------- 99 | haveTwoBitsK: 100 | push x1 ;[1] 101 | push x2 ;[3] 102 | push x3 ;[5] 103 | ldi shift, 0 ;[7] 104 | ldi x3, 1<<4 ;[8] [rx loop init] first sample is inverse bit, compensate that 105 | push x4 ;[9] == leap 106 | 107 | in x1, USBIN ;[11] <-- sample bit 0 108 | andi x1, USBMASK ;[12] 109 | bst x1, USBMINUS ;[13] 110 | bld shift, 7 ;[14] 111 | push cnt ;[15] 112 | ldi leap, 0 ;[17] [rx loop init] 113 | ldi cnt, USB_BUFSIZE;[18] [rx loop init] 114 | rjmp rxbit1 ;[19] arrives at [21] 115 | 116 | ;---------------------------------------------------------------------------- 117 | ; Receiver loop (numbers in brackets are cycles within byte after instr) 118 | ;---------------------------------------------------------------------------- 119 | 120 | ; duration of unstuffing code should be 10.66666667 cycles. We adjust "leap" 121 | ; accordingly to approximate this value in the long run. 122 | 123 | unstuff6: 124 | andi x2, USBMASK ;[03] 125 | ori x3, 1<<6 ;[04] will not be shifted any more 126 | andi shift, ~0x80;[05] 127 | mov x1, x2 ;[06] sampled bit 7 is actually re-sampled bit 6 128 | subi leap, -1 ;[07] total duration = 11 bits -> subtract 1/3 129 | rjmp didUnstuff6 ;[08] 130 | 131 | unstuff7: 132 | ori x3, 1<<7 ;[09] will not be shifted any more 133 | in x2, USBIN ;[00] [10] re-sample bit 7 134 | andi x2, USBMASK ;[01] 135 | andi shift, ~0x80;[02] 136 | subi leap, 2 ;[03] total duration = 10 bits -> add 1/3 137 | rjmp didUnstuff7 ;[04] 138 | 139 | unstuffEven: 140 | ori x3, 1<<6 ;[09] will be shifted right 6 times for bit 0 141 | in x1, USBIN ;[00] [10] 142 | andi shift, ~0x80;[01] 143 | andi x1, USBMASK ;[02] 144 | breq se0 ;[03] 145 | subi leap, -1 ;[04] total duration = 11 bits -> subtract 1/3 146 | nop2 ;[05] 147 | rjmp didUnstuffE ;[06] 148 | 149 | unstuffOdd: 150 | ori x3, 1<<5 ;[09] will be shifted right 4 times for bit 1 151 | in x2, USBIN ;[00] [10] 152 | andi shift, ~0x80;[01] 153 | andi x2, USBMASK ;[02] 154 | breq se0 ;[03] 155 | subi leap, -1 ;[04] total duration = 11 bits -> subtract 1/3 156 | nop2 ;[05] 157 | rjmp didUnstuffO ;[06] 158 | 159 | rxByteLoop: 160 | andi x1, USBMASK ;[03] 161 | eor x2, x1 ;[04] 162 | subi leap, 1 ;[05] 163 | brpl skipLeap ;[06] 164 | subi leap, -3 ;1 one leap cycle every 3rd byte -> 85 + 1/3 cycles per byte 165 | nop ;1 166 | skipLeap: 167 | subi x2, 1 ;[08] 168 | ror shift ;[09] 169 | didUnstuff6: 170 | cpi shift, 0xfc ;[10] 171 | in x2, USBIN ;[00] [11] <-- sample bit 7 172 | brcc unstuff6 ;[01] 173 | andi x2, USBMASK ;[02] 174 | eor x1, x2 ;[03] 175 | subi x1, 1 ;[04] 176 | ror shift ;[05] 177 | didUnstuff7: 178 | cpi shift, 0xfc ;[06] 179 | brcc unstuff7 ;[07] 180 | eor x3, shift ;[08] reconstruct: x3 is 1 at bit locations we changed, 0 at others 181 | st y+, x3 ;[09] store data 182 | rxBitLoop: 183 | in x1, USBIN ;[00] [11] <-- sample bit 0/2/4 184 | andi x1, USBMASK ;[01] 185 | eor x2, x1 ;[02] 186 | andi x3, 0x3f ;[03] topmost two bits reserved for 6 and 7 187 | subi x2, 1 ;[04] 188 | ror shift ;[05] 189 | cpi shift, 0xfc ;[06] 190 | brcc unstuffEven ;[07] 191 | didUnstuffE: 192 | lsr x3 ;[08] 193 | lsr x3 ;[09] 194 | rxbit1: 195 | in x2, USBIN ;[00] [10] <-- sample bit 1/3/5 196 | andi x2, USBMASK ;[01] 197 | breq se0 ;[02] 198 | eor x1, x2 ;[03] 199 | subi x1, 1 ;[04] 200 | ror shift ;[05] 201 | cpi shift, 0xfc ;[06] 202 | brcc unstuffOdd ;[07] 203 | didUnstuffO: 204 | subi bitcnt, 0xab;[08] == addi 0x55, 0x55 = 0x100/3 205 | brcs rxBitLoop ;[09] 206 | 207 | subi cnt, 1 ;[10] 208 | in x1, USBIN ;[00] [11] <-- sample bit 6 209 | brcc rxByteLoop ;[01] 210 | rjmp overflow 211 | 212 | macro POP_STANDARD ; 14 cycles 213 | pop cnt 214 | pop x4 215 | pop x3 216 | pop x2 217 | pop x1 218 | pop shift 219 | pop bitcnt 220 | endm 221 | macro POP_RETI ; 7 cycles 222 | pop YH 223 | pop YL 224 | out SREG, YL 225 | pop YL 226 | endm 227 | 228 | #include "asmcommon.inc" 229 | 230 | ; USB spec says: 231 | ; idle = J 232 | ; J = (D+ = 0), (D- = 1) 233 | ; K = (D+ = 1), (D- = 0) 234 | ; Spec allows 7.5 bit times from EOP to SOP for replies 235 | 236 | bitstuffN: 237 | eor x1, x4 ;[5] 238 | ldi x2, 0 ;[6] 239 | nop2 ;[7] 240 | nop ;[9] 241 | out USBOUT, x1 ;[10] <-- out 242 | rjmp didStuffN ;[0] 243 | 244 | bitstuff6: 245 | eor x1, x4 ;[5] 246 | ldi x2, 0 ;[6] Carry is zero due to brcc 247 | rol shift ;[7] compensate for ror shift at branch destination 248 | rjmp didStuff6 ;[8] 249 | 250 | bitstuff7: 251 | ldi x2, 0 ;[2] Carry is zero due to brcc 252 | rjmp didStuff7 ;[3] 253 | 254 | 255 | sendNakAndReti: 256 | ldi x3, USBPID_NAK ;[-18] 257 | rjmp sendX3AndReti ;[-17] 258 | sendAckAndReti: 259 | ldi cnt, USBPID_ACK ;[-17] 260 | sendCntAndReti: 261 | mov x3, cnt ;[-16] 262 | sendX3AndReti: 263 | ldi YL, 20 ;[-15] x3==r20 address is 20 264 | ldi YH, 0 ;[-14] 265 | ldi cnt, 2 ;[-13] 266 | ; rjmp usbSendAndReti fallthrough 267 | 268 | ;usbSend: 269 | ;pointer to data in 'Y' 270 | ;number of bytes in 'cnt' -- including sync byte [range 2 ... 12] 271 | ;uses: x1...x4, btcnt, shift, cnt, Y 272 | ;Numbers in brackets are time since first bit of sync pattern is sent 273 | ;We don't match the transfer rate exactly (don't insert leap cycles every third 274 | ;byte) because the spec demands only 1.5% precision anyway. 275 | usbSendAndReti: ; 12 cycles until SOP 276 | in x2, USBDDR ;[-12] 277 | ori x2, USBMASK ;[-11] 278 | sbi USBOUT, USBMINUS;[-10] prepare idle state; D+ and D- must have been 0 (no pullups) 279 | in x1, USBOUT ;[-8] port mirror for tx loop 280 | out USBDDR, x2 ;[-7] <- acquire bus 281 | ; need not init x2 (bitstuff history) because sync starts with 0 282 | ldi x4, USBMASK ;[-6] exor mask 283 | ldi shift, 0x80 ;[-5] sync byte is first byte sent 284 | txByteLoop: 285 | ldi bitcnt, 0x35 ;[-4] [6] binary 0011 0101 286 | txBitLoop: 287 | sbrs shift, 0 ;[-3] [7] 288 | eor x1, x4 ;[-2] [8] 289 | out USBOUT, x1 ;[-1] [9] <-- out N 290 | ror shift ;[0] [10] 291 | ror x2 ;[1] 292 | didStuffN: 293 | cpi x2, 0xfc ;[2] 294 | brcc bitstuffN ;[3] 295 | lsr bitcnt ;[4] 296 | brcc txBitLoop ;[5] 297 | brne txBitLoop ;[6] 298 | 299 | sbrs shift, 0 ;[7] 300 | eor x1, x4 ;[8] 301 | didStuff6: 302 | out USBOUT, x1 ;[-1] [9] <-- out 6 303 | ror shift ;[0] [10] 304 | ror x2 ;[1] 305 | cpi x2, 0xfc ;[2] 306 | brcc bitstuff6 ;[3] 307 | ror shift ;[4] 308 | didStuff7: 309 | ror x2 ;[5] 310 | sbrs x2, 7 ;[6] 311 | eor x1, x4 ;[7] 312 | nop ;[8] 313 | cpi x2, 0xfc ;[9] 314 | out USBOUT, x1 ;[-1][10] <-- out 7 315 | brcc bitstuff7 ;[0] [11] 316 | ld shift, y+ ;[1] 317 | dec cnt ;[3] 318 | brne txByteLoop ;[4] 319 | ;make SE0: 320 | cbr x1, USBMASK ;[5] prepare SE0 [spec says EOP may be 21 to 25 cycles] 321 | lds x2, usbNewDeviceAddr;[6] 322 | lsl x2 ;[8] we compare with left shifted address 323 | subi YL, 20 + 2 ;[9] Only assign address on data packets, not ACK/NAK in x3 324 | sbci YH, 0 ;[10] 325 | out USBOUT, x1 ;[11] <-- out SE0 -- from now 2 bits = 22 cycles until bus idle 326 | ;2006-03-06: moved transfer of new address to usbDeviceAddr from C-Code to asm: 327 | ;set address only after data packet was sent, not after handshake 328 | breq skipAddrAssign ;[0] 329 | sts usbDeviceAddr, x2; if not skipped: SE0 is one cycle longer 330 | skipAddrAssign: 331 | ;end of usbDeviceAddress transfer 332 | ldi x2, 1< max 52 cycles interrupt disable 32 | ;max stack usage: [ret(2), r0, SREG, YL, YH, shift, x1, x2, x3, x4, cnt] = 12 bytes 33 | ;nominal frequency: 16.5 MHz -> 11 cycles per bit 34 | ; 16.3125 MHz < F_CPU < 16.6875 MHz (+/- 1.1%) 35 | ; Numbers in brackets are clocks counted from center of last sync bit 36 | ; when instruction starts 37 | 38 | 39 | USB_INTR_VECTOR: 40 | ;order of registers pushed: YL, SREG [sofError], r0, YH, shift, x1, x2, x3, x4, cnt 41 | push YL ;[-23] push only what is necessary to sync with edge ASAP 42 | in YL, SREG ;[-21] 43 | push YL ;[-20] 44 | ;---------------------------------------------------------------------------- 45 | ; Synchronize with sync pattern: 46 | ;---------------------------------------------------------------------------- 47 | ;sync byte (D-) pattern LSb to MSb: 01010100 [1 = idle = J, 0 = K] 48 | ;sync up with J to K edge during sync pattern -- use fastest possible loops 49 | ;The first part waits at most 1 bit long since we must be in sync pattern. 50 | ;YL is guarenteed to be < 0x80 because I flag is clear. When we jump to 51 | ;waitForJ, ensure that this prerequisite is met. 52 | waitForJ: 53 | inc YL 54 | sbis USBIN, USBMINUS 55 | brne waitForJ ; just make sure we have ANY timeout 56 | waitForK: 57 | ;The following code results in a sampling window of < 1/4 bit which meets the spec. 58 | sbis USBIN, USBMINUS ;[-15] 59 | rjmp foundK ;[-14] 60 | sbis USBIN, USBMINUS 61 | rjmp foundK 62 | sbis USBIN, USBMINUS 63 | rjmp foundK 64 | sbis USBIN, USBMINUS 65 | rjmp foundK 66 | sbis USBIN, USBMINUS 67 | rjmp foundK 68 | sbis USBIN, USBMINUS 69 | rjmp foundK 70 | #if USB_COUNT_SOF 71 | lds YL, usbSofCount 72 | inc YL 73 | sts usbSofCount, YL 74 | #endif /* USB_COUNT_SOF */ 75 | #ifdef USB_SOF_HOOK 76 | USB_SOF_HOOK 77 | #endif 78 | rjmp sofError 79 | foundK: ;[-12] 80 | ;{3, 5} after falling D- edge, average delay: 4 cycles [we want 5 for center sampling] 81 | ;we have 1 bit time for setup purposes, then sample again. Numbers in brackets 82 | ;are cycles from center of first sync (double K) bit after the instruction 83 | push r0 ;[-12] 84 | ; [---] ;[-11] 85 | push YH ;[-10] 86 | ; [---] ;[-9] 87 | lds YL, usbInputBufOffset;[-8] 88 | ; [---] ;[-7] 89 | clr YH ;[-6] 90 | subi YL, lo8(-(usbRxBuf));[-5] [rx loop init] 91 | sbci YH, hi8(-(usbRxBuf));[-4] [rx loop init] 92 | mov r0, x2 ;[-3] [rx loop init] 93 | sbis USBIN, USBMINUS ;[-2] we want two bits K (sample 2 cycles too early) 94 | rjmp haveTwoBitsK ;[-1] 95 | pop YH ;[0] undo the pushes from before 96 | pop r0 ;[2] 97 | rjmp waitForK ;[4] 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 (= 22 cycles). 100 | 101 | ;---------------------------------------------------------------------------- 102 | ; push more registers and initialize values while we sample the first bits: 103 | ;---------------------------------------------------------------------------- 104 | haveTwoBitsK: ;[1] 105 | push shift ;[1] 106 | push x1 ;[3] 107 | push x2 ;[5] 108 | push x3 ;[7] 109 | ldi shift, 0xff ;[9] [rx loop init] 110 | ori x3, 0xff ;[10] [rx loop init] == ser x3, clear zero flag 111 | 112 | in x1, USBIN ;[11] <-- sample bit 0 113 | bst x1, USBMINUS ;[12] 114 | bld shift, 0 ;[13] 115 | push x4 ;[14] == phase 116 | ; [---] ;[15] 117 | push cnt ;[16] 118 | ; [---] ;[17] 119 | ldi phase, 0 ;[18] [rx loop init] 120 | ldi cnt, USB_BUFSIZE;[19] [rx loop init] 121 | rjmp rxbit1 ;[20] 122 | ; [---] ;[21] 123 | 124 | ;---------------------------------------------------------------------------- 125 | ; Receiver loop (numbers in brackets are cycles within byte after instr) 126 | ;---------------------------------------------------------------------------- 127 | /* 128 | byte oriented operations done during loop: 129 | bit 0: store data 130 | bit 1: SE0 check 131 | bit 2: overflow check 132 | bit 3: catch up 133 | bit 4: rjmp to achieve conditional jump range 134 | bit 5: PLL 135 | bit 6: catch up 136 | bit 7: jump, fixup bitstuff 137 | ; 87 [+ 2] cycles 138 | ------------------------------------------------------------------ 139 | */ 140 | continueWithBit5: 141 | in x2, USBIN ;[055] <-- bit 5 142 | eor r0, x2 ;[056] 143 | or phase, r0 ;[057] 144 | sbrc phase, USBMINUS ;[058] 145 | lpm ;[059] optional nop3; modifies r0 146 | in phase, USBIN ;[060] <-- phase 147 | eor x1, x2 ;[061] 148 | bst x1, USBMINUS ;[062] 149 | bld shift, 5 ;[063] 150 | andi shift, 0x3f ;[064] 151 | in x1, USBIN ;[065] <-- bit 6 152 | breq unstuff5 ;[066] *** unstuff escape 153 | eor phase, x1 ;[067] 154 | eor x2, x1 ;[068] 155 | bst x2, USBMINUS ;[069] 156 | bld shift, 6 ;[070] 157 | didUnstuff6: ;[ ] 158 | in r0, USBIN ;[071] <-- phase 159 | cpi shift, 0x02 ;[072] 160 | brlo unstuff6 ;[073] *** unstuff escape 161 | didUnstuff5: ;[ ] 162 | nop2 ;[074] 163 | ; [---] ;[075] 164 | in x2, USBIN ;[076] <-- bit 7 165 | eor x1, x2 ;[077] 166 | bst x1, USBMINUS ;[078] 167 | bld shift, 7 ;[079] 168 | didUnstuff7: ;[ ] 169 | eor r0, x2 ;[080] 170 | or phase, r0 ;[081] 171 | in r0, USBIN ;[082] <-- phase 172 | cpi shift, 0x04 ;[083] 173 | brsh rxLoop ;[084] 174 | ; [---] ;[085] 175 | unstuff7: ;[ ] 176 | andi x3, ~0x80 ;[085] 177 | ori shift, 0x80 ;[086] 178 | in x2, USBIN ;[087] <-- sample stuffed bit 7 179 | nop ;[088] 180 | rjmp didUnstuff7 ;[089] 181 | ; [---] ;[090] 182 | ;[080] 183 | 184 | unstuff5: ;[067] 185 | eor phase, x1 ;[068] 186 | andi x3, ~0x20 ;[069] 187 | ori shift, 0x20 ;[070] 188 | in r0, USBIN ;[071] <-- phase 189 | mov x2, x1 ;[072] 190 | nop ;[073] 191 | nop2 ;[074] 192 | ; [---] ;[075] 193 | in x1, USBIN ;[076] <-- bit 6 194 | eor r0, x1 ;[077] 195 | or phase, r0 ;[078] 196 | eor x2, x1 ;[079] 197 | bst x2, USBMINUS ;[080] 198 | bld shift, 6 ;[081] no need to check bitstuffing, we just had one 199 | in r0, USBIN ;[082] <-- phase 200 | rjmp didUnstuff5 ;[083] 201 | ; [---] ;[084] 202 | ;[074] 203 | 204 | unstuff6: ;[074] 205 | andi x3, ~0x40 ;[075] 206 | in x1, USBIN ;[076] <-- bit 6 again 207 | ori shift, 0x40 ;[077] 208 | nop2 ;[078] 209 | ; [---] ;[079] 210 | rjmp didUnstuff6 ;[080] 211 | ; [---] ;[081] 212 | ;[071] 213 | 214 | unstuff0: ;[013] 215 | eor r0, x2 ;[014] 216 | or phase, r0 ;[015] 217 | andi x2, USBMASK ;[016] check for SE0 218 | in r0, USBIN ;[017] <-- phase 219 | breq didUnstuff0 ;[018] direct jump to se0 would be too long 220 | andi x3, ~0x01 ;[019] 221 | ori shift, 0x01 ;[020] 222 | mov x1, x2 ;[021] mov existing sample 223 | in x2, USBIN ;[022] <-- bit 1 again 224 | rjmp didUnstuff0 ;[023] 225 | ; [---] ;[024] 226 | ;[014] 227 | 228 | unstuff1: ;[024] 229 | eor r0, x1 ;[025] 230 | or phase, r0 ;[026] 231 | andi x3, ~0x02 ;[027] 232 | in r0, USBIN ;[028] <-- phase 233 | ori shift, 0x02 ;[029] 234 | mov x2, x1 ;[030] 235 | rjmp didUnstuff1 ;[031] 236 | ; [---] ;[032] 237 | ;[022] 238 | 239 | unstuff2: ;[035] 240 | eor r0, x2 ;[036] 241 | or phase, r0 ;[037] 242 | andi x3, ~0x04 ;[038] 243 | in r0, USBIN ;[039] <-- phase 244 | ori shift, 0x04 ;[040] 245 | mov x1, x2 ;[041] 246 | rjmp didUnstuff2 ;[042] 247 | ; [---] ;[043] 248 | ;[033] 249 | 250 | unstuff3: ;[043] 251 | in x2, USBIN ;[044] <-- bit 3 again 252 | eor r0, x2 ;[045] 253 | or phase, r0 ;[046] 254 | andi x3, ~0x08 ;[047] 255 | ori shift, 0x08 ;[048] 256 | nop ;[049] 257 | in r0, USBIN ;[050] <-- phase 258 | rjmp didUnstuff3 ;[051] 259 | ; [---] ;[052] 260 | ;[042] 261 | 262 | unstuff4: ;[053] 263 | andi x3, ~0x10 ;[054] 264 | in x1, USBIN ;[055] <-- bit 4 again 265 | ori shift, 0x10 ;[056] 266 | rjmp didUnstuff4 ;[057] 267 | ; [---] ;[058] 268 | ;[048] 269 | 270 | rxLoop: ;[085] 271 | eor x3, shift ;[086] reconstruct: x3 is 0 at bit locations we changed, 1 at others 272 | in x1, USBIN ;[000] <-- bit 0 273 | st y+, x3 ;[001] 274 | ; [---] ;[002] 275 | eor r0, x1 ;[003] 276 | or phase, r0 ;[004] 277 | eor x2, x1 ;[005] 278 | in r0, USBIN ;[006] <-- phase 279 | ser x3 ;[007] 280 | bst x2, USBMINUS ;[008] 281 | bld shift, 0 ;[009] 282 | andi shift, 0xf9 ;[010] 283 | rxbit1: ;[ ] 284 | in x2, USBIN ;[011] <-- bit 1 285 | breq unstuff0 ;[012] *** unstuff escape 286 | andi x2, USBMASK ;[013] SE0 check for bit 1 287 | didUnstuff0: ;[ ] Z only set if we detected SE0 in bitstuff 288 | breq se0 ;[014] 289 | eor r0, x2 ;[015] 290 | or phase, r0 ;[016] 291 | in r0, USBIN ;[017] <-- phase 292 | eor x1, x2 ;[018] 293 | bst x1, USBMINUS ;[019] 294 | bld shift, 1 ;[020] 295 | andi shift, 0xf3 ;[021] 296 | didUnstuff1: ;[ ] 297 | in x1, USBIN ;[022] <-- bit 2 298 | breq unstuff1 ;[023] *** unstuff escape 299 | eor r0, x1 ;[024] 300 | or phase, r0 ;[025] 301 | subi cnt, 1 ;[026] overflow check 302 | brcs overflow ;[027] 303 | in r0, USBIN ;[028] <-- phase 304 | eor x2, x1 ;[029] 305 | bst x2, USBMINUS ;[030] 306 | bld shift, 2 ;[031] 307 | andi shift, 0xe7 ;[032] 308 | didUnstuff2: ;[ ] 309 | in x2, USBIN ;[033] <-- bit 3 310 | breq unstuff2 ;[034] *** unstuff escape 311 | eor r0, x2 ;[035] 312 | or phase, r0 ;[036] 313 | eor x1, x2 ;[037] 314 | bst x1, USBMINUS ;[038] 315 | in r0, USBIN ;[039] <-- phase 316 | bld shift, 3 ;[040] 317 | andi shift, 0xcf ;[041] 318 | didUnstuff3: ;[ ] 319 | breq unstuff3 ;[042] *** unstuff escape 320 | nop ;[043] 321 | in x1, USBIN ;[044] <-- bit 4 322 | eor x2, x1 ;[045] 323 | bst x2, USBMINUS ;[046] 324 | bld shift, 4 ;[047] 325 | didUnstuff4: ;[ ] 326 | eor r0, x1 ;[048] 327 | or phase, r0 ;[049] 328 | in r0, USBIN ;[050] <-- phase 329 | andi shift, 0x9f ;[051] 330 | breq unstuff4 ;[052] *** unstuff escape 331 | rjmp continueWithBit5;[053] 332 | ; [---] ;[054] 333 | 334 | macro POP_STANDARD ; 16 cycles 335 | pop cnt 336 | pop x4 337 | pop x3 338 | pop x2 339 | pop x1 340 | pop shift 341 | pop YH 342 | pop r0 343 | endm 344 | macro POP_RETI ; 5 cycles 345 | pop YL 346 | out SREG, YL 347 | pop YL 348 | endm 349 | 350 | #include "asmcommon.inc" 351 | 352 | 353 | ; USB spec says: 354 | ; idle = J 355 | ; J = (D+ = 0), (D- = 1) 356 | ; K = (D+ = 1), (D- = 0) 357 | ; Spec allows 7.5 bit times from EOP to SOP for replies 358 | 359 | bitstuff7: 360 | eor x1, x4 ;[4] 361 | ldi x2, 0 ;[5] 362 | nop2 ;[6] C is zero (brcc) 363 | rjmp didStuff7 ;[8] 364 | 365 | bitstuffN: 366 | eor x1, x4 ;[5] 367 | ldi x2, 0 ;[6] 368 | lpm ;[7] 3 cycle NOP, modifies r0 369 | out USBOUT, x1 ;[10] <-- out 370 | rjmp didStuffN ;[0] 371 | 372 | #define bitStatus x3 373 | 374 | sendNakAndReti: 375 | ldi cnt, USBPID_NAK ;[-19] 376 | rjmp sendCntAndReti ;[-18] 377 | sendAckAndReti: 378 | ldi cnt, USBPID_ACK ;[-17] 379 | sendCntAndReti: 380 | mov r0, cnt ;[-16] 381 | ldi YL, 0 ;[-15] R0 address is 0 382 | ldi YH, 0 ;[-14] 383 | ldi cnt, 2 ;[-13] 384 | ; rjmp usbSendAndReti fallthrough 385 | 386 | ;usbSend: 387 | ;pointer to data in 'Y' 388 | ;number of bytes in 'cnt' -- including sync byte [range 2 ... 12] 389 | ;uses: x1...x4, shift, cnt, Y 390 | ;Numbers in brackets are time since first bit of sync pattern is sent 391 | usbSendAndReti: ; 12 cycles until SOP 392 | in x2, USBDDR ;[-12] 393 | ori x2, USBMASK ;[-11] 394 | sbi USBOUT, USBMINUS;[-10] prepare idle state; D+ and D- must have been 0 (no pullups) 395 | in x1, USBOUT ;[-8] port mirror for tx loop 396 | out USBDDR, x2 ;[-7] <- acquire bus 397 | ; need not init x2 (bitstuff history) because sync starts with 0 398 | ldi x4, USBMASK ;[-6] exor mask 399 | ldi shift, 0x80 ;[-5] sync byte is first byte sent 400 | ldi bitStatus, 0xff ;[-4] init bit loop counter, works for up to 12 bytes 401 | byteloop: 402 | bitloop: 403 | sbrs shift, 0 ;[8] [-3] 404 | eor x1, x4 ;[9] [-2] 405 | out USBOUT, x1 ;[10] [-1] <-- out 406 | ror shift ;[0] 407 | ror x2 ;[1] 408 | didStuffN: 409 | cpi x2, 0xfc ;[2] 410 | brcc bitstuffN ;[3] 411 | nop ;[4] 412 | subi bitStatus, 37 ;[5] 256 / 7 ~=~ 37 413 | brcc bitloop ;[6] when we leave the loop, bitStatus has almost the initial value 414 | sbrs shift, 0 ;[7] 415 | eor x1, x4 ;[8] 416 | ror shift ;[9] 417 | didStuff7: 418 | out USBOUT, x1 ;[10] <-- out 419 | ror x2 ;[0] 420 | cpi x2, 0xfc ;[1] 421 | brcc bitstuff7 ;[2] 422 | ld shift, y+ ;[3] 423 | dec cnt ;[5] 424 | brne byteloop ;[6] 425 | ;make SE0: 426 | cbr x1, USBMASK ;[7] prepare SE0 [spec says EOP may be 21 to 25 cycles] 427 | lds x2, usbNewDeviceAddr;[8] 428 | lsl x2 ;[10] we compare with left shifted address 429 | out USBOUT, x1 ;[11] <-- out SE0 -- from now 2 bits = 22 cycles until bus idle 430 | ;2006-03-06: moved transfer of new address to usbDeviceAddr from C-Code to asm: 431 | ;set address only after data packet was sent, not after handshake 432 | subi YL, 2 ;[0] Only assign address on data packets, not ACK/NAK in r0 433 | sbci YH, 0 ;[1] 434 | breq skipAddrAssign ;[2] 435 | sts usbDeviceAddr, x2; if not skipped: SE0 is one cycle longer 436 | skipAddrAssign: 437 | ;end of usbDeviceAddress transfer 438 | ldi x2, 1< 13.333333 cycles per bit, 106.666667 cycles per byte 38 | ; Numbers in brackets are clocks counted from center of last sync bit 39 | ; when instruction starts 40 | ;register use in receive loop: 41 | ; shift assembles the byte currently being received 42 | ; x1 holds the D+ and D- line state 43 | ; x2 holds the previous line state 44 | ; x4 (leap) is used to add a leap cycle once every three bytes received 45 | ; X3 (leap2) is used to add a leap cycle once every three stuff bits received 46 | ; bitcnt is used to determine when a stuff bit is due 47 | ; cnt holds the number of bytes left in the receive buffer 48 | 49 | USB_INTR_VECTOR: 50 | ;order of registers pushed: YL, SREG YH, [sofError], bitcnt, shift, x1, x2, x3, x4, cnt 51 | push YL ;[-28] push only what is necessary to sync with edge ASAP 52 | in YL, SREG ;[-26] 53 | push YL ;[-25] 54 | push YH ;[-23] 55 | ;---------------------------------------------------------------------------- 56 | ; Synchronize with sync pattern: 57 | ;---------------------------------------------------------------------------- 58 | ;sync byte (D-) pattern LSb to MSb: 01010100 [1 = idle = J, 0 = K] 59 | ;sync up with J to K edge during sync pattern -- use fastest possible loops 60 | ;The first part waits at most 1 bit long since we must be in sync pattern. 61 | ;YL is guarenteed to be < 0x80 because I flag is clear. When we jump to 62 | ;waitForJ, ensure that this prerequisite is met. 63 | waitForJ: 64 | inc YL 65 | sbis USBIN, USBMINUS 66 | brne waitForJ ; just make sure we have ANY timeout 67 | waitForK: 68 | ;The following code results in a sampling window of < 1/4 bit which meets the spec. 69 | sbis USBIN, USBMINUS ;[-19] 70 | rjmp foundK ;[-18] 71 | sbis USBIN, USBMINUS 72 | rjmp foundK 73 | sbis USBIN, USBMINUS 74 | rjmp foundK 75 | sbis USBIN, USBMINUS 76 | rjmp foundK 77 | sbis USBIN, USBMINUS 78 | rjmp foundK 79 | sbis USBIN, USBMINUS 80 | rjmp foundK 81 | sbis USBIN, USBMINUS 82 | rjmp foundK 83 | sbis USBIN, USBMINUS 84 | rjmp foundK 85 | sbis USBIN, USBMINUS 86 | rjmp foundK 87 | #if USB_COUNT_SOF 88 | lds YL, usbSofCount 89 | inc YL 90 | sts usbSofCount, YL 91 | #endif /* USB_COUNT_SOF */ 92 | #ifdef USB_SOF_HOOK 93 | USB_SOF_HOOK 94 | #endif 95 | rjmp sofError 96 | foundK: ;[-16] 97 | ;{3, 5} after falling D- edge, average delay: 4 cycles 98 | ;bit0 should be at 34 for center sampling. Currently at 4 so 30 cylces till bit 0 sample 99 | ;use 1 bit time for setup purposes, then sample again. Numbers in brackets 100 | ;are cycles from center of first sync (double K) bit after the instruction 101 | push bitcnt ;[-16] 102 | ; [---] ;[-15] 103 | lds YL, usbInputBufOffset;[-14] 104 | ; [---] ;[-13] 105 | clr YH ;[-12] 106 | subi YL, lo8(-(usbRxBuf));[-11] [rx loop init] 107 | sbci YH, hi8(-(usbRxBuf));[-10] [rx loop init] 108 | push shift ;[-9] 109 | ; [---] ;[-8] 110 | ldi shift,0x40 ;[-7] set msb to "1" so processing bit7 can be detected 111 | nop2 ;[-6] 112 | ; [---] ;[-5] 113 | ldi bitcnt, 5 ;[-4] [rx loop init] 114 | sbis USBIN, USBMINUS ;[-3] we want two bits K (sample 3 cycles too early) 115 | rjmp haveTwoBitsK ;[-2] 116 | pop shift ;[-1] undo the push from before 117 | pop bitcnt ;[1] 118 | rjmp waitForK ;[3] this was not the end of sync, retry 119 | ; The entire loop from waitForK until rjmp waitForK above must not exceed two 120 | ; bit times (= 27 cycles). 121 | 122 | ;---------------------------------------------------------------------------- 123 | ; push more registers and initialize values while we sample the first bits: 124 | ;---------------------------------------------------------------------------- 125 | haveTwoBitsK: 126 | push x1 ;[0] 127 | push x2 ;[2] 128 | push x3 ;[4] (leap2) 129 | ldi leap2, 0x55 ;[6] add leap cycle on 2nd,5th,8th,... stuff bit 130 | push x4 ;[7] == leap 131 | ldi leap, 0x55 ;[9] skip leap cycle on 2nd,5th,8th,... byte received 132 | push cnt ;[10] 133 | ldi cnt, USB_BUFSIZE ;[12] [rx loop init] 134 | ldi x2, 1< 39 | #ifndef __IAR_SYSTEMS_ASM__ 40 | # include 41 | #endif 42 | 43 | #define __attribute__(arg) /* not supported on IAR */ 44 | 45 | #ifdef __IAR_SYSTEMS_ASM__ 46 | # define __ASSEMBLER__ /* IAR does not define standard macro for asm */ 47 | #endif 48 | 49 | #ifdef __HAS_ELPM__ 50 | # define PROGMEM __farflash 51 | #else 52 | # define PROGMEM __flash 53 | #endif 54 | 55 | #define USB_READ_FLASH(addr) (*(PROGMEM char *)(addr)) 56 | 57 | /* The following definitions are not needed by the driver, but may be of some 58 | * help if you port a gcc based project to IAR. 59 | */ 60 | #define cli() __disable_interrupt() 61 | #define sei() __enable_interrupt() 62 | #define wdt_reset() __watchdog_reset() 63 | #define _BV(x) (1 << (x)) 64 | 65 | /* assembler compatibility macros */ 66 | #define nop2 rjmp $+2 /* jump to next instruction */ 67 | #define XL r26 68 | #define XH r27 69 | #define YL r28 70 | #define YH r29 71 | #define ZL r30 72 | #define ZH r31 73 | #define lo8(x) LOW(x) 74 | #define hi8(x) (((x)>>8) & 0xff) /* not HIGH to allow XLINK to make a proper range check */ 75 | 76 | /* Depending on the device you use, you may get problems with the way usbdrv.h 77 | * handles the differences between devices. Since IAR does not use #defines 78 | * for MCU registers, we can't check for the existence of a particular 79 | * register with an #ifdef. If the autodetection mechanism fails, include 80 | * definitions for the required USB_INTR_* macros in your usbconfig.h. See 81 | * usbconfig-prototype.h and usbdrv.h for details. 82 | */ 83 | 84 | /* ------------------------------------------------------------------------- */ 85 | #elif __CODEVISIONAVR__ /* check for CodeVision AVR */ 86 | /* ------------------------------------------------------------------------- */ 87 | /* This port is not working (yet) */ 88 | 89 | /* #define F_CPU _MCU_CLOCK_FREQUENCY_ seems to be defined automatically */ 90 | 91 | #include 92 | #include 93 | 94 | #define __attribute__(arg) /* not supported on IAR */ 95 | 96 | #define PROGMEM __flash 97 | #define USB_READ_FLASH(addr) (*(PROGMEM char *)(addr)) 98 | 99 | #ifndef __ASSEMBLER__ 100 | static inline void cli(void) 101 | { 102 | #asm("cli"); 103 | } 104 | static inline void sei(void) 105 | { 106 | #asm("sei"); 107 | } 108 | #endif 109 | #define _delay_ms(t) delay_ms(t) 110 | #define _BV(x) (1 << (x)) 111 | #define USB_CFG_USE_SWITCH_STATEMENT 1 /* macro for if() cascase fails for unknown reason */ 112 | 113 | #define macro .macro 114 | #define endm .endmacro 115 | #define nop2 rjmp .+0 /* jump to next instruction */ 116 | 117 | /* ------------------------------------------------------------------------- */ 118 | #else /* default development environment is avr-gcc/avr-libc */ 119 | /* ------------------------------------------------------------------------- */ 120 | 121 | #include 122 | #ifdef __ASSEMBLER__ 123 | # define _VECTOR(N) __vector_ ## N /* io.h does not define this for asm */ 124 | #else 125 | # include 126 | #endif 127 | 128 | #define USB_READ_FLASH(addr) pgm_read_byte(addr) 129 | 130 | #define macro .macro 131 | #define endm .endm 132 | #define nop2 rjmp .+0 /* jump to next instruction */ 133 | 134 | #endif /* development environment */ 135 | 136 | /* for conveniecne, ensure that PRG_RDB exists */ 137 | #ifndef PRG_RDB 138 | # define PRG_RDB(addr) USB_READ_FLASH(addr) 139 | #endif 140 | #endif /* __usbportability_h_INCLUDED__ */ 141 | -------------------------------------------------------------------------------- /clockwork_keypad_ATMEGA168PA.hex: -------------------------------------------------------------------------------- 1 | :100000000C94AC000C9413030C94D4000C94D40006 2 | :100010000C94D4000C94D4000C94D4000C94D40010 3 | :100020000C94D4000C94D4000C94D4000C94D40000 4 | :100030000C94D4000C94D4000C94D4000C94D400F0 5 | :100040000C94B0020C94D4000C947E020C945802D0 6 | :100050000C94D4000C94D4000C94D4000C94D400D0 7 | :100060000C94D4000C94D40000000000250028005B 8 | :100070002B0000000000240027002A0005010906CB 9 | :10008000A101050719E029E715002501750195086B 10 | :100090008102950675082565190029658100C0183B 11 | :1000A000035500730062004B006500790062006F29 12 | :1000B000006100720064002003720061006E006342 13 | :1000C00000690064006200610063006F006E002E32 14 | :1000D0000063006F006D000403090409022200019F 15 | :1000E0000100803209040000010300000009210121 16 | :1000F0000100012223000705810308000A120110F4 17 | :100100000100000008424231E1000101020001004B 18 | :100110000000002300260029000404040404040451 19 | :1001200004020202020202030303030303010204A6 20 | :100130000810204080010204081020010204081069 21 | :100140002000000008000201000003040700000076 22 | :10015000000000000000340411241FBECFEFD4E0E3 23 | :10016000DEBFCDBF11E0A0E0B1E0E6E2FFE002C0FB 24 | :1001700005900D92AE36B107D9F722E0AEE6B1E0B8 25 | :1001800001C01D92A537B207E1F710E0CCEAD0E03C 26 | :1001900004C02197FE010E948607CB3AD107C9F718 27 | :1001A0000E948C040C9491070C940000CF92DF9273 28 | :1001B000EF92FF920F931F93CF93DF936C017A011D 29 | :1001C0008B01C0E0D0E0CE15DF0589F0D8016D913C 30 | :1001D0008D01D601ED91FC910190F081E02DC601D9 31 | :1001E0000995892B11F47E0102C02196ECCFC7013D 32 | :1001F000DF91CF911F910F91FF90EF90DF90CF9003 33 | :100200000895089580E090E00895FC01538D448D99 34 | :10021000252F30E0842F90E0821B930B541710F0B1 35 | :10022000CF96089501970895FC01918D828D9817BE 36 | :1002300061F0828DDF01A80FB11D5D968C91928DCA 37 | :100240009F5F9F73928F90E008958FEF9FEF0895C7 38 | :10025000FC01918D828D981731F0828DE80FF11D90 39 | :10026000858D90E008958FEF9FEF0895FC01918DAB 40 | :10027000228D892F90E0805C9F4F821B91098F73A4 41 | :10028000992708958AE991E00E94360121E0892B9F 42 | :1002900009F420E0822F0895FC01848DDF01A80F6E 43 | :1002A000B11DA35ABF4F2C91848D90E001968F739E 44 | :1002B0009927848FA689B7892C93A089B1898C91BD 45 | :1002C00080648C93938D848D981306C00288F38983 46 | :1002D000E02D80818F7D80830895EF92FF920F93B0 47 | :1002E0001F93CF93DF93EC0181E0888F9B8D8C8DE2 48 | :1002F000981305C0E889F989808185FD24C0F62E10 49 | :100300000B8D10E00F5F1F4F0F731127E02E8C8DA8 50 | :10031000E8120CC00FB607FCFACFE889F989808192 51 | :1003200085FFF5CFCE010E944C01F1CF8B8DFE01F0 52 | :10033000E80FF11DE35AFF4FF0820B8FEA89FB892A 53 | :100340008081806207C0EE89FF896083E889F9892E 54 | :1003500080818064808381E090E0DF91CF911F9164 55 | :100360000F91FF90EF900895CF93DF93EC01888D6C 56 | :100370008823C9F0EA89FB89808185FD05C0A889A9 57 | :10038000B9898C9186FD0FC00FB607FCF5CF80812F 58 | :1003900085FFF2CFA889B9898C9185FFEDCFCE0179 59 | :1003A0000E944C01E7CFDF91CF91089580E090E06B 60 | :1003B000892B29F00E94420181110C9400000895BC 61 | :1003C0008E3008F08E508770806480937C0080911E 62 | :1003D0007A00806480937A0080917A0086FDFCCF59 63 | :1003E000809178002091790090E0922B08953FB79A 64 | :1003F000F8948091730190917401A0917501B0916E 65 | :10040000760126B5A89B05C02F3F19F00196A11DC6 66 | :10041000B11D3FBFBA2FA92F982F8827820F911D9A 67 | :10042000A11DB11DBC01CD0142E0660F771F881FE1 68 | :10043000991F4A95D1F70895CF93C62F20914D0269 69 | :1004400024FF07C030914E0228E8232720934E0254 70 | :1004500003C02AE520934D02DC01EFE4F2E09C2F7B 71 | :100460009E0F8D918193892F8E1B1816D4F36C2FBC 72 | :100470008FE492E00E940F03CC5FC0934D02CF91B6 73 | :100480000895E8E3F2E096E09E0F882321F02081B2 74 | :10049000281301C0108231969E13F7CF67E087E3DF 75 | :1004A00092E00E941C0281E090E008950E948C0777 76 | :1004B0001F920F920FB60F9211242F933F934F93D9 77 | :1004C0005F936F937F938F939F93AF93BF93EF93BC 78 | :1004D000FF938AE991E00E944C01FF91EF91BF9157 79 | :1004E000AF919F918F917F916F915F914F913F91CC 80 | :1004F0002F910F900FBE0F901F9018951F920F9283 81 | :100500000FB60F9211242F938F939F93EF93FF9326 82 | :10051000E091AA01F091AB018081E091B001F091EE 83 | :10052000B10182FD12C090818091B3018F5F8F7302 84 | :100530002091B401821751F0E091B301F0E0E6564A 85 | :10054000FE4F958F8093B30101C08081FF91EF91A1 86 | :100550009F918F912F910F900FBE0F901F90189524 87 | :100560001F920F920FB60F9211242F933F938F93E8 88 | :100570009F93AF93BF9380916F0190917001A09171 89 | :100580007101B091720130916E0123E0230F2D377C 90 | :1005900020F40196A11DB11D05C026E8230F029687 91 | :1005A000A11DB11D20936E0180936F019093700186 92 | :1005B000A0937101B09372018091730190917401C5 93 | :1005C000A0917501B09176010196A11DB11D809396 94 | :1005D000730190937401A0937501B0937601BF915C 95 | :1005E000AF919F918F913F912F910F900FBE0F90E0 96 | :1005F0001F901895A82FB92F80E090E041E050EAB5 97 | :10060000609530E009C02D9182279795879510F06D 98 | :1006100084279527305EC8F36F5FA8F30895EADF5B 99 | :100620008D939D930895CF93CFB7CF93DF93C395C9 100 | :100630004C9BE9F74C9B0BC04C9B09C04C9B07C0E3 101 | :100640004C9B05C04C9B03C04C9B01C08BC06F935F 102 | :10065000C0915B02DD27C15ADD4F2F9365E54C9BAE 103 | :1006600003C02F916F91E6CF0F931F934F9320E01C 104 | :1006700040E15F9309B1047104FB27F93F9350E017 105 | :100680003BE039C0147140642F77012F5F5F1EC0BB 106 | :10069000406819B114712F7752501FC0406409B1DE 107 | :1006A0002F770471D1F15F5F00C023C0406219B1A0 108 | :1006B0002F77147191F15F5F00C025C0047110277E 109 | :1006C000515012F45D5F0000115027952C3F19B175 110 | :1006D000C8F614710127015027952C3FC8F6422710 111 | :1006E000499309B1047110274F73115027952C3F7E 112 | :1006F000A8F64695469519B1147179F00127015075 113 | :1007000027952C3F98F66B5A60F3315009B1B0F63B 114 | :1007100000C011E01CBB002719C03B503195C31B22 115 | :10072000D04011E01CBB0881033C09F10B34F9F007 116 | :10073000209159021981110F1213EDCF4A81441FE4 117 | :10074000093651F10D3211F0013E29F700935E0296 118 | :100750003F915F914F911F910F912F916F91CCB36A 119 | :10076000C0FD65CFDF91CF91CFBFCF91189520917C 120 | :100770005E02222369F310915C02112391F534305B 121 | :1007800092F130935C0220935A0210915B023BE09D 122 | :10079000311B30935B0227C000915C0201300CF5E5 123 | :1007A0000AE54F7049F43091010134FD1DC00093FA 124 | :1007B0000101C2E4D2E01CC030914D0234FD14C0EE 125 | :1007C00000934D02CEE4D2E013C0052710E000C034 126 | :1007D00000000BB91AC0052710E0221F1DC010E051 127 | :1007E00021C04AE502C032ED432FC4E1D0E032E03F 128 | :1007F0001AB114615C9A0BB11AB954E120E865E3AF 129 | :1008000020FF05270BB9279517951C3FF0F6669535 130 | :10081000B8F7B1F720FF05270BB9279517951C3FAF 131 | :10082000D0F62795179517FF052700001C3F0BB939 132 | :10083000B0F629913A9519F70B7E10915D02110FD0 133 | :10084000C651D0400BB911F01093590211E01CBBF6 134 | :1008500000611AB11B7E402F4B7E54E05A95F1F790 135 | :100860000BB91AB94BB974CFEAE9F1E013821282DD 136 | :1008700088EE93E0A0E0B0E084839583A683B783FD 137 | :1008800080E691E09183808385EC90E09587848772 138 | :1008900084EC90E09787868780EC90E0918B808B4A 139 | :1008A00081EC90E0938B828B82EC90E0958B848B33 140 | :1008B00086EC90E0978B868B118E128E138E148EA1 141 | :1008C0001BB88AB18B6E8AB9F89455985D982FEF52 142 | :1008D00084E39CE0215080409040E1F700C000009C 143 | :1008E000559A5D9AE9E6F0E0808182608083E89A1B 144 | :1008F000EDE4F2E08BE481838AE5808378941092C2 145 | :100900003E0210923F02109240021092410264E0B7 146 | :100910008EE392E00C941C02CF93DF931F92CDB72D 147 | :10092000DEB7789484B5826084BD84B5816084BD6F 148 | :1009300085B5826085BD85B5816085BD80916E007D 149 | :10094000816080936E0010928100809181008260AE 150 | :1009500080938100809181008160809381008091EB 151 | :1009600080008160809380008091B10084608093DA 152 | :10097000B1008091B00081608093B00080917A00D6 153 | :10098000846080937A0080917A00826080937A00FC 154 | :1009900080917A00816080937A0080917A008068EB 155 | :1009A00080937A001092C10080916E0010926E00C8 156 | :1009B000AEE3B1E0ECE7CE2EE1E0DE2E20E030E069 157 | :1009C0004FEF50E0293031053CF58D919C91119706 158 | :1009D0009927FC01E35DFE4F6491FC01E75EFE4F49 159 | :1009E00084918823C9F090E0880F991FFC01EE588C 160 | :1009F000FF4F05911491FC01E859FF4FE590F490E9 161 | :100A00009FB7F894F8018081609586238083F70171 162 | :100A10008081862380839FBFF601419351936F01AC 163 | :100A20002F5F3F4F12962F30310509F0CBCFE09169 164 | :100A3000AA01F091AB0182E08083E091A601F091E0 165 | :100A4000A7011082E091A801F091A90180E18083C3 166 | :100A50001092B201E091AE01F091AF0186E0808387 167 | :100A6000E091AC01F091AD01808180618083E091E3 168 | :100A7000AC01F091AD01808188608083E091AC0190 169 | :100A8000F091AD01808180688083E091AC01F091AC 170 | :100A9000AD0180818F7D80835CE7252E50E0352E6F 171 | :100AA00044244A94512C88E392E026E0280F2983BD 172 | :100AB00080915C02835087FDB6C090915B022091CB 173 | :100AC0005A022D3209F0ADC0883009F0AAC0ECE01E 174 | :100AD000F0E0E91BF109E15AFD4F83EC80934202FB 175 | :100AE0008AE580930101109279018081807689F0F6 176 | :100AF0002EE332E030937B0120937A01803209F0BB 177 | :100B000086C081818A3009F082C083818093770119 178 | :100B10007EC0928110924B028181811106C0109299 179 | :100B20004C022BE432E082E06DC0853019F49093E2 180 | :100B30005D0265C0863009F04CC08381813041F48C 181 | :100B40008DEF90E090937B0180937A0182E13DC02C 182 | :100B5000823041F48BED90E090937B0180937A0199 183 | :100B600082E233C08330F1F4911108C087ED90E048 184 | :100B700090937B0180937A0184E027C0913041F407 185 | :100B800087EB90E090937B0180937A0180E21DC017 186 | :100B90009230D1F48FE990E090937B0180937A01B9 187 | :100BA00088E113C0813241F48DEE90E090937B0197 188 | :100BB00080937A0189E009C0823231F430927B015E 189 | :100BC00020927A0183E201C080E090E49093790161 190 | :100BD0001FC0883069F0893019F4909378010FC0F4 191 | :100BE0008A3049F08B3059F48BE480934E0207C071 192 | :100BF00028E731E002C02BE432E081E003C02BE4BF 193 | :100C000032E080E030937B0120937A0101C080E0E4 194 | :100C10009781911104C09681981708F4892F8093C9 195 | :100C2000000110925C028091010184FF48C0809114 196 | :100C300000018F3F09F443C0182F893008F018E0F5 197 | :100C4000811B809300019091420288E8892780935C 198 | :100C50004202112331F120917A0130917B01809180 199 | :100C6000790186FF0BC0A3E4B2E0F901812F820F66 200 | :100C700094919D9331968E13FBCF09C0D901E3E483 201 | :100C8000F2E0812F8E0F9D9191938E13FCCF8FEF09 202 | :100C9000810F90E00196820F931F90937B018093C8 203 | :100CA0007A01612F83E492E00E940F0364E0610FF8 204 | :100CB0006C3019F08FEF809300016093010184E1A3 205 | :100CC00099B1947131F48150D9F710925D0210926C 206 | :100CD00059020E94F7014B015C0148EEC42E43E02B 207 | :100CE000D42EE12CF12C0E94F701DC01CB018819F4 208 | :100CF0009909AA09BB09883E9340A105B10558F09E 209 | :100D000081E0C81AD108E108F108A8EE8A0EA3E034 210 | :100D10009A1EA11CB11CC114D104E104F10419F7FD 211 | :100D200090E2A92E91E0B92E22E0C22E21E0D22E2F 212 | :100D30000EE311E03CE7832E31E0932EE12CF12C01 213 | :100D4000F9E0EF16F1040CF047C0D8018D919C91A9 214 | :100D50009927FC01EF5BFE4F3491FC01E35DFE4FF0 215 | :100D60002491FC01E75EFE4FE491EE2309F43FC0BD 216 | :100D7000332339F1333091F038F43130A9F0323087 217 | :100D800001F584B58F7D12C0373091F03830A1F075 218 | :100D90003430B9F4809180008F7D03C08091800051 219 | :100DA0008F77809380000DC084B58F7784BD09C094 220 | :100DB0008091B0008F7703C08091B0008F7D8093C9 221 | :100DC000B000F0E0EE0FFF1FE15FFE4FA591B49180 222 | :100DD000EC912E2361F01DC0F80180810E94E0019A 223 | :100DE00064EF71E00E945E076130710591F081E06F 224 | :100DF0000E94E0018D509E4F873E9340B0F085E009 225 | :100E00000E94E0018D509E4F873E934008F052C0F3 226 | :100E10000CC0D4018D919C918F3F910579F00E9477 227 | :100E20004102F4015182408209C0F5016080718065 228 | :100E3000D4018D919C9168167906B1F4FFEFEF1AF9 229 | :100E4000FF0A22E0820E911C82E0A80EB11CA2E0F3 230 | :100E5000CA0ED11C0E5F1F4FBFE0EB16F10409F064 231 | :100E60006FCF0E94D60124CE8F3F910511F00E94D2 232 | :100E70004102262DE8E3F2E08191821791F0B981D9 233 | :100E8000BE13FACF80E090E0FC01E95CFD4F3181B8 234 | :100E9000311102C0218305C0019686309105A1F76A 235 | :100EA00005C067E087E392E00E941C02F4017182B2 236 | :100EB0006082C4CFD6016D907C90BACF97FB072E8D 237 | :100EC00016F4009407D077FD09D00E94720707FC42 238 | :100ED00005D03EF4909581959F4F0895709561954A 239 | :100EE0007F4F0895AA1BBB1B51E107C0AA1FBB1F60 240 | :100EF000A617B70710F0A61BB70B881F991F5A95A6 241 | :100F0000A9F780959095BC01CD010895EE0FFF1FC4 242 | :100F10000590F491E02D099481E090E0F8940C9410 243 | :060F20009107F894FFCFD9 244 | :100F2600FF5A5200500051004F000C0018000D00EF 245 | :100F36000E00280029002C000F0012001C000B00D8 246 | :100F46005200500051004F0012001C000B000F0011 247 | :100F560057002A0056004D004E004B004A00030081 248 | :100F660006000700080009000A000B000C000D002F 249 | :100F76000000020003000400060007000000000055 250 | :0E0F86006D01D6000501B401360114012801E9 251 | :103800000C94341C0C94511C0C94511C0C94511CA1 252 | :103810000C94511C0C94511C0C94511C0C94511C74 253 | :103820000C94511C0C94511C0C94511C0C94511C64 254 | :103830000C94511C0C94511C0C94511C0C94511C54 255 | :103840000C94511C0C94511C0C94511C0C94511C44 256 | :103850000C94511C0C94511C0C94511C0C94511C34 257 | :103860000C94511C0C94511C11241FBECFEFD4E0BA 258 | :10387000DEBFCDBF11E0A0E0B1E0E4EAFFE302C0AB 259 | :1038800005900D92A230B107D9F712E0A2E0B1E0A5 260 | :1038900001C01D92AD30B107E1F70E94361D0C94B6 261 | :1038A000D01F0C94001C982F9595959595959595FE 262 | :1038B000905D8F708A307CF0282F295A8091C0004B 263 | :1038C00085FFFCCF9093C6008091C00085FFFCCFA0 264 | :1038D0002093C6000895282F205DF0CF982F809167 265 | :1038E000C00085FFFCCF9093C6000895EF92FF9231 266 | :1038F0000F931F93EE24FF2487018091C00087FD62 267 | :1039000017C00894E11CF11C011D111D81E4E8168B 268 | :1039100082E4F8068FE0080780E0180770F3E09172 269 | :103920000401F091050109958091C00087FFE9CF5E 270 | :103930008091C6001F910F91FF90EF9008950E9413 271 | :10394000761C982F8091C00085FFFCCF9093C60015 272 | :1039500091362CF490330CF09053892F089597559D 273 | :10396000892F08951F930E949F1C182F0E949F1C4F 274 | :103970001295107F810F1F910895882351F0982F81 275 | :1039800091508091C00087FFFCCF8091C6009923A1 276 | :10399000B9F708951F93182F0E94761C803249F0C2 277 | :1039A000809103018F5F809303018530C1F01F91E7 278 | :1039B00008958091C00085FFFCCF84E18093C6000C 279 | :1039C0008091C00085FFFCCF1093C6008091C0009D 280 | :1039D00085FFFCCF80E18093C6001F910895E091A0 281 | :1039E0000401F091050109951F9108950E94761C2C 282 | :1039F000803241F0809103018F5F80930301853015 283 | :103A000081F008958091C00085FFFCCF84E1809310 284 | :103A1000C6008091C00085FFFCCF80E18093C60086 285 | :103A20000895E0910401F09105010995089510921F 286 | :103A30000A028823D1F090E040E951E02D9A28EE67 287 | :103A400033E0FA013197F1F721503040D1F72D984A 288 | :103A500028EE33E0FA013197F1F721503040D1F7E9 289 | :103A60009F5F981758F380930A0208953F924F92F0 290 | :103A70005F926F927F928F929F92AF92BF92CF92FE 291 | :103A8000DF92EF92FF920F931F93CF93DF9300008B 292 | :103A900083E38093C4001092C50088E18093C10045 293 | :103AA00086E08093C2005098589A259A81E00E943F 294 | :103AB000171D44E1F42E3EE1E32E24E9D22E96E0D8 295 | :103AC000C92E80E1B82EAA24A39401E4902E16E515 296 | :103AD000812EB2E57B2EA0E26A2EF9E45F2EE3E5AB 297 | :103AE0004E2E70E5372E0E94761C8033B1F1813363 298 | :103AF00009F441C0803409F479C0813409F48CC0E0 299 | :103B0000823471F1853409F47BC0803531F182351E 300 | :103B100021F1813511F1853509F48DC0863509F41F 301 | :103B20009DC0843609F4AEC0843709F41BC18537C3 302 | :103B300009F485C1863709F47AC0809103018F5F4B 303 | :103B400080930301853079F6E0910401F09105013D 304 | :103B500009950E94761C803351F60E94F61CC3CF53 305 | :103B600093E18091C00087FFFCCF8091C60099232C 306 | :103B7000A1F39150F6CF0E94761C8032F1F680912D 307 | :103B8000C00085FFFCCFF092C6008091C00085FF89 308 | :103B9000FCCF9092C6008091C00085FFFCCF809240 309 | :103BA000C6008091C00085FFFCCF7092C600809156 310 | :103BB000C00085FFFCCF6092C6008091C00085FFE9 311 | :103BC000FCCF5092C6008091C00085FFFCCF409290 312 | :103BD000C6008091C00085FFFCCF3092C600809166 313 | :103BE000C00085FFFCCFB092C6007DCF0E94761C3E 314 | :103BF000863808F4B2CF0E94761C0E94F61C73CF60 315 | :103C000094E08091C00087FFFCCF8091C60099238B 316 | :103C100009F4A3CF9150F5CF0E94761C8038D1F0E3 317 | :103C2000813861F1823809F499C0883979F080E0EF 318 | :103C30000E94CA1C58CF0E94761C809306010E94E5 319 | :103C4000761C809307010E94F61C4DCF83E00E94F2 320 | :103C5000CA1C49CF82E00E94CA1C45CF0E94761C34 321 | :103C6000803309F486C192E08091C00087FFFCCFC9 322 | :103C70008091C6009923D9F29150F6CF81E00E943D 323 | :103C8000CA1C31CF0E94761C809309020E94761CC8 324 | :103C90008093080280910C028E7F80930C020E9418 325 | :103CA000761C853429F480910C02816080930C028B 326 | :103CB0008091080290910902892B89F000E010E0C0 327 | :103CC0000E94761CF801E85FFE4F80830F5F1F4F54 328 | :103CD00080910802909109020817190788F30E9441 329 | :103CE000761C803209F029CF80910C0280FFD1C070 330 | :103CF0004091060150910701440F551F5093070151 331 | :103D000040930601A0910802B09109021097C9F0F2 332 | :103D1000E8E0F1E09A01BD016E0F7F1FF999FECF37 333 | :103D200032BD21BD819180BDFA9AF99A2F5F3F4F34 334 | :103D3000E617F70799F74A0F5B1F50930701409367 335 | :103D400006018091C00085FFFCCFF092C6008091F3 336 | :103D5000C00085FFFCCFB092C600C5CE80E10E94B6 337 | :103D6000CA1CC1CE0E94761C809309020E94761C58 338 | :103D7000809308028091060190910701880F991F96 339 | :103D800090930701809306010E94761C853409F404 340 | :103D90007AC080910C028E7F80930C020E94761C68 341 | :103DA000803209F0A0CE8091C00085FFFCCFF09258 342 | :103DB000C600A0910802B09109021097B9F1809154 343 | :103DC0000C02182F1170082F0270E0910601F0917B 344 | :103DD00007019F012F5F3F4FB90140E050E01123E1 345 | :103DE000B1F4002339F494918091C00085FFFCCF99 346 | :103DF0009093C6004F5F5F4FCB010196F9014A17C0 347 | :103E00005B0780F4BC012F5F3F4F112351F3F999F9 348 | :103E1000FECFF2BDE1BDF89A90B58091C00085FF5C 349 | :103E2000FCCFE6CF70930701609306018091C0003C 350 | :103E300085FDD9CE8091C00085FFF8CFD4CE0E94F9 351 | :103E4000761C803209F079CE8091C00085FFFCCFCE 352 | :103E5000F092C6008091C00085FFFCCFE092C600C2 353 | :103E60008091C00085FFFCCFD092C6008091C00039 354 | :103E700085FFFCCFC092C6008091C00085FFFCCFBB 355 | :103E8000B092C60030CE80910C02816080930C020B 356 | :103E900085CF809107018823880F880B8A21809322 357 | :103EA0000B028091060190910701880F991F909352 358 | :103EB0000701809306018091080280FF09C080916C 359 | :103EC00008029091090201969093090280930802DA 360 | :103ED000F894F999FECF1127E0910601F0910701BE 361 | :103EE000C8E0D1E08091080290910902103091F46D 362 | :103EF0000091570001700130D9F303E0009357009F 363 | :103F0000E8950091570001700130D9F301E1009369 364 | :103F10005700E89509901990009157000170013001 365 | :103F2000D9F301E000935700E8951395103498F009 366 | :103F300011270091570001700130D9F305E000937B 367 | :103F40005700E8950091570001700130D9F301E165 368 | :103F500000935700E8953296029709F0C7CF1030CA 369 | :103F600011F00296E5CF11248091C00085FFE9CEC3 370 | :103F7000ECCE0E94761C0E94761C182F0E94761CA4 371 | :103F8000112351F0113021F086E00E94CA1CABCD04 372 | :103F900084E90E94CA1CA7CD8EE10E94CA1CA3CD51 373 | :043FA000F894FFCFC3 374 | :023FA40080009B 375 | :0400000300003800C1 376 | :00000001FF 377 | -------------------------------------------------------------------------------- /clockworkpi_keypad.ino: -------------------------------------------------------------------------------- 1 | // CLOCKWORK Keypad Arduino driver 2 | // For more information please visit https://forum.clockworkpi.com 3 | // HAPPY HACKING 4 | 5 | #include "UsbKeyboard.h" 6 | 7 | #define KEY_ENTER 0x28 // Keyboard Return (ENTER) 8 | #define KEY_ESCAPE 0x29 // Keyboard Escape 9 | #define KEY_BACKSPACE 0x2A // Keyboard Backspace 10 | #define KEY_SPACE 0x2C // Keyboard Space 11 | #define KEY_DASH 0x2D // Keyboard - and _ 12 | #define KEY_EQUAL 0x2E // Keyboard = and + 13 | #define KEY_HOME 0x4A // Keyboard Home 14 | #define KEY_PAGE_UP 0x4B // Keyboard Page Up 15 | #define KEY_END 0x4D // Keyboard End 16 | #define KEY_PAGE_DOWN 0x4E // Keyboard Page Down 17 | #define KEY_RIGHT_ARROW 0x4F // Keyboard Right Arrow 18 | #define KEY_LEFT_ARROW 0x50 // Keyboard Left Arrow 19 | #define KEY_DOWN_ARROW 0x51 // Keyboard Down Arrow 20 | #define KEY_UP_ARROW 0x52 // Keyboard Up Arrow 21 | #define KEY_NUM_DASH 0x56 // Keyboard Num Pad - 22 | #define KEY_NUM_PLUS 0x57 // Keyboard Num Pad + 23 | 24 | #define KEY_OFF 1 25 | #define KEY_ON 0 26 | #define ADC_BOUNDARY 500 27 | #define DIGITAL_KEY_NUM 9 28 | #define ANALOG_KEY_NUM 6 29 | #define KEY_NUM (DIGITAL_KEY_NUM + ANALOG_KEY_NUM) 30 | #define SHIFT_KEY_NUM 2 31 | #define KEY_NULL 0xff 32 | 33 | #define KEYPAD_UP KEY_UP_ARROW 34 | #define KEYPAD_LEFT KEY_LEFT_ARROW 35 | #define KEYPAD_DOWN KEY_DOWN_ARROW 36 | #define KEYPAD_RIGHT KEY_RIGHT_ARROW 37 | #define KEYPAD_Y KEY_I 38 | #define KEYPAD_X KEY_U 39 | #define KEYPAD_A KEY_J 40 | #define KEYPAD_B KEY_K 41 | #define KEYPAD_MENU KEY_ESCAPE 42 | #define KEYPAD_SELECT KEY_SPACE 43 | #define KEYPAD_START KEY_ENTER 44 | #define KEYPAD_LIGHT1 KEY_L 45 | #define KEYPAD_LIGHT2 KEY_O 46 | #define KEYPAD_LIGHT4 KEY_Y 47 | #define KEYPAD_LIGHT5 KEY_H 48 | 49 | #define KEYPAD_UP_SHIFT KEY_UP_ARROW 50 | #define KEYPAD_LEFT_SHIFT KEY_LEFT_ARROW 51 | #define KEYPAD_DOWN_SHIFT KEY_DOWN_ARROW 52 | #define KEYPAD_RIGHT_SHIFT KEY_RIGHT_ARROW 53 | #define KEYPAD_Y_SHIFT KEY_O 54 | #define KEYPAD_X_SHIFT KEY_Y 55 | #define KEYPAD_A_SHIFT KEY_H 56 | #define KEYPAD_B_SHIFT KEY_L 57 | #define KEYPAD_MENU_SHIFT KEY_BACKSPACE 58 | #define KEYPAD_SELECT_SHIFT KEY_NUM_DASH 59 | #define KEYPAD_START_SHIFT KEY_NUM_PLUS 60 | #define KEYPAD_LIGHT1_SHIFT KEY_END 61 | #define KEYPAD_LIGHT2_SHIFT KEY_PAGE_DOWN 62 | #define KEYPAD_LIGHT4_SHIFT KEY_PAGE_UP 63 | #define KEYPAD_LIGHT5_SHIFT KEY_HOME 64 | 65 | const int pins[KEY_NUM] = {3, 6, 7, 8, 9, 10, 11, 12, 13, 0, 2, 3, 4, 6, 7}; 66 | const int shift_pins[SHIFT_KEY_NUM] = {1, 5}; 67 | 68 | const int keys[KEY_NUM] = 69 | { 70 | KEYPAD_UP, KEYPAD_LEFT, KEYPAD_DOWN, KEYPAD_RIGHT, KEYPAD_Y, KEYPAD_X, KEYPAD_A, KEYPAD_B, KEYPAD_START, 71 | KEYPAD_MENU, KEYPAD_SELECT, KEYPAD_LIGHT1, KEYPAD_LIGHT2, KEYPAD_LIGHT4, KEYPAD_LIGHT5 72 | }; 73 | const int shift_keys[KEY_NUM] = 74 | { 75 | KEYPAD_UP_SHIFT, KEYPAD_LEFT_SHIFT, KEYPAD_DOWN_SHIFT, KEYPAD_RIGHT_SHIFT, KEYPAD_Y_SHIFT, KEYPAD_X_SHIFT, KEYPAD_A_SHIFT, KEYPAD_B_SHIFT, KEYPAD_START_SHIFT, 76 | KEYPAD_MENU_SHIFT, KEYPAD_SELECT_SHIFT, KEYPAD_LIGHT1_SHIFT, KEYPAD_LIGHT2_SHIFT, KEYPAD_LIGHT4_SHIFT, KEYPAD_LIGHT5_SHIFT 77 | }; 78 | 79 | int old_keys[KEY_NUM]; 80 | 81 | bool shift_key_pressed() 82 | { 83 | for(int i = 0; i < SHIFT_KEY_NUM; i++) 84 | { 85 | if(analogRead(shift_pins[i]) /ADC_BOUNDARY == KEY_ON) 86 | return true; 87 | } 88 | return false; 89 | } 90 | 91 | void setup() 92 | { 93 | TIMSK0 &= !(1 << TOIE0); 94 | 95 | for(int i = 0; i < KEY_NUM; i++) 96 | { 97 | if(i < DIGITAL_KEY_NUM) 98 | { 99 | pinMode(pins[i], INPUT); 100 | } 101 | old_keys[i] = KEY_NULL; 102 | } 103 | Serial.begin(115200); 104 | } 105 | 106 | void loop() 107 | { 108 | int on_off, key; 109 | 110 | UsbKeyboard.update(); 111 | delay(1000); 112 | 113 | for(int i = 0; i < KEY_NUM; i++) 114 | { 115 | if( i < DIGITAL_KEY_NUM) 116 | { 117 | on_off = digitalRead(pins[i]); 118 | } 119 | else 120 | { 121 | on_off = analogRead(pins[i])/ADC_BOUNDARY; 122 | } 123 | 124 | if(on_off == KEY_OFF) 125 | { 126 | if(old_keys[i] != KEY_NULL) 127 | { 128 | UsbKeyboard.release(old_keys[i]); 129 | old_keys[i] = KEY_NULL; 130 | } 131 | } 132 | else 133 | { 134 | if(shift_key_pressed()) 135 | { 136 | key = shift_keys[i]; 137 | } 138 | else 139 | { 140 | key = keys[i]; 141 | } 142 | 143 | if(key != old_keys[i]) 144 | { 145 | if(old_keys[i] != KEY_NULL) 146 | { 147 | UsbKeyboard.release(old_keys[i]); 148 | } 149 | UsbKeyboard.press(key); 150 | old_keys[i] = key; 151 | } 152 | } 153 | } 154 | } 155 | -------------------------------------------------------------------------------- /keymaps.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/clockworkpi/Keypad/9935fdc40d0389c4c6ad25a9aeb516cfb3a28f70/keymaps.png --------------------------------------------------------------------------------