From 22f511fa97873905ea940ae58bf1259c620858f1 Mon Sep 17 00:00:00 2001 From: Jarno Lehtinen Date: Wed, 6 Apr 2022 12:36:16 +0300 Subject: [PATCH] Create old2.txt --- C64_4joy_adapter/old2.txt | 3343 +++++++++++++++++++++++++++++++++++++ 1 file changed, 3343 insertions(+) create mode 100644 C64_4joy_adapter/old2.txt diff --git a/C64_4joy_adapter/old2.txt b/C64_4joy_adapter/old2.txt new file mode 100644 index 0000000..6aa2d7d --- /dev/null +++ b/C64_4joy_adapter/old2.txt @@ -0,0 +1,3343 @@ + +C:\Users\lehti\AppData\Local\Temp\arduino_build_972304\c64_4joystick-adapter.ino.elf: file format elf32-avr + + +Disassembly of section .text: + +00000000 <__vectors>: + 0: 0c 94 bf 00 jmp 0x17e ; 0x17e <__ctors_end> + 4: 0c 94 e7 00 jmp 0x1ce ; 0x1ce <__bad_interrupt> + 8: 0c 94 e7 00 jmp 0x1ce ; 0x1ce <__bad_interrupt> + c: 0c 94 70 06 jmp 0xce0 ; 0xce0 <__vector_3> + 10: 0c 94 5d 06 jmp 0xcba ; 0xcba <__vector_4> + 14: 0c 94 e7 00 jmp 0x1ce ; 0x1ce <__bad_interrupt> + 18: 0c 94 e7 00 jmp 0x1ce ; 0x1ce <__bad_interrupt> + 1c: 0c 94 e7 00 jmp 0x1ce ; 0x1ce <__bad_interrupt> + 20: 0c 94 e7 00 jmp 0x1ce ; 0x1ce <__bad_interrupt> + 24: 0c 94 e7 00 jmp 0x1ce ; 0x1ce <__bad_interrupt> + 28: 0c 94 64 03 jmp 0x6c8 ; 0x6c8 <__vector_10> + 2c: 0c 94 d3 03 jmp 0x7a6 ; 0x7a6 <__vector_11> + 30: 0c 94 e7 00 jmp 0x1ce ; 0x1ce <__bad_interrupt> + 34: 0c 94 e7 00 jmp 0x1ce ; 0x1ce <__bad_interrupt> + 38: 0c 94 e7 00 jmp 0x1ce ; 0x1ce <__bad_interrupt> + 3c: 0c 94 e7 00 jmp 0x1ce ; 0x1ce <__bad_interrupt> + 40: 0c 94 e7 00 jmp 0x1ce ; 0x1ce <__bad_interrupt> + 44: 0c 94 e7 00 jmp 0x1ce ; 0x1ce <__bad_interrupt> + 48: 0c 94 e7 00 jmp 0x1ce ; 0x1ce <__bad_interrupt> + 4c: 0c 94 e7 00 jmp 0x1ce ; 0x1ce <__bad_interrupt> + 50: 0c 94 e7 00 jmp 0x1ce ; 0x1ce <__bad_interrupt> + 54: 0c 94 e7 00 jmp 0x1ce ; 0x1ce <__bad_interrupt> + 58: 0c 94 e7 00 jmp 0x1ce ; 0x1ce <__bad_interrupt> + 5c: 0c 94 05 06 jmp 0xc0a ; 0xc0a <__vector_23> + 60: 0c 94 e7 00 jmp 0x1ce ; 0x1ce <__bad_interrupt> + 64: 0c 94 e7 00 jmp 0x1ce ; 0x1ce <__bad_interrupt> + 68: 0c 94 e7 00 jmp 0x1ce ; 0x1ce <__bad_interrupt> + 6c: 0c 94 e7 00 jmp 0x1ce ; 0x1ce <__bad_interrupt> + 70: 0c 94 e7 00 jmp 0x1ce ; 0x1ce <__bad_interrupt> + 74: 0c 94 e7 00 jmp 0x1ce ; 0x1ce <__bad_interrupt> + 78: 0c 94 e7 00 jmp 0x1ce ; 0x1ce <__bad_interrupt> + 7c: 0c 94 e7 00 jmp 0x1ce ; 0x1ce <__bad_interrupt> + 80: 0c 94 e7 00 jmp 0x1ce ; 0x1ce <__bad_interrupt> + 84: 0c 94 e7 00 jmp 0x1ce ; 0x1ce <__bad_interrupt> + 88: 0c 94 e7 00 jmp 0x1ce ; 0x1ce <__bad_interrupt> + 8c: 0c 94 e7 00 jmp 0x1ce ; 0x1ce <__bad_interrupt> + 90: 0c 94 e7 00 jmp 0x1ce ; 0x1ce <__bad_interrupt> + 94: 0c 94 e7 00 jmp 0x1ce ; 0x1ce <__bad_interrupt> + 98: 0c 94 e7 00 jmp 0x1ce ; 0x1ce <__bad_interrupt> + 9c: 0c 94 e7 00 jmp 0x1ce ; 0x1ce <__bad_interrupt> + a0: 0c 94 e7 00 jmp 0x1ce ; 0x1ce <__bad_interrupt> + a4: 0c 94 e7 00 jmp 0x1ce ; 0x1ce <__bad_interrupt> + a8: 0c 94 e7 00 jmp 0x1ce ; 0x1ce <__bad_interrupt> + +000000ac <__trampolines_end>: + ac: 08 0b sbc r16, r24 + ae: 00 02 muls r16, r16 + b0: 02 02 muls r16, r18 + b2: 00 00 nop + b4: 09 04 cpc r0, r9 + b6: 00 00 nop + b8: 01 02 muls r16, r17 + ba: 02 00 .word 0x0002 ; ???? + bc: 00 05 cpc r16, r0 + be: 24 00 .word 0x0024 ; ???? + c0: 10 01 movw r2, r0 + c2: 05 24 eor r0, r5 + c4: 01 01 movw r0, r2 + c6: 01 04 cpc r0, r1 + c8: 24 02 muls r18, r20 + ca: 06 05 cpc r16, r6 + cc: 24 06 cpc r2, r20 + ce: 00 01 movw r0, r0 + d0: 07 05 cpc r16, r7 + d2: 81 03 fmuls r16, r17 + d4: 10 00 .word 0x0010 ; ???? + d6: 40 09 sbc r20, r0 + d8: 04 01 movw r0, r8 + da: 00 02 muls r16, r16 + dc: 0a 00 .word 0x000a ; ???? + de: 00 00 nop + e0: 07 05 cpc r16, r7 + e2: 02 02 muls r16, r18 + e4: 40 00 .word 0x0040 ; ???? + e6: 00 07 cpc r16, r16 + e8: 05 83 std Z+5, r16 ; 0x05 + ea: 02 40 sbci r16, 0x02 ; 2 + ... + +000000ee : + ee: 04 03 09 04 .... + +000000f2 : + f2: 12 01 00 02 ef 02 01 40 41 23 36 80 00 01 01 02 .......@A#6..... + 102: 03 01 .. + +00000104 : + 104: 41 72 64 75 69 6e 6f 20 4c 4c 43 00 Arduino LLC. + +00000110 : + 110: 41 72 64 75 69 6e 6f 20 4c 65 6f 6e 61 72 64 6f Arduino Leonardo + ... + +00000121 : + 121: 00 00 00 00 25 00 28 00 2b 00 2e 00 31 00 ....%.(.+...1. + +0000012f : + 12f: 00 00 00 00 24 00 27 00 2a 00 2d 00 30 00 ....$.'.*.-.0. + +0000013d : + 13d: 04 04 04 04 04 03 04 05 02 02 02 02 04 03 02 02 ................ + 14d: 02 02 06 06 06 06 06 06 04 04 02 02 02 04 04 ............... + +0000015c : + 15c: 04 08 02 01 10 40 80 40 10 20 40 80 40 80 08 02 .....@.@. @.@... + 16c: 04 01 80 40 20 10 02 01 10 80 10 20 40 40 20 00 ...@ ...... @@ . + +0000017c <__ctors_start>: + 17c: 75 06 cpc r7, r21 + +0000017e <__ctors_end>: + 17e: 11 24 eor r1, r1 + 180: 1f be out 0x3f, r1 ; 63 + 182: cf ef ldi r28, 0xFF ; 255 + 184: da e0 ldi r29, 0x0A ; 10 + 186: de bf out 0x3e, r29 ; 62 + 188: cd bf out 0x3d, r28 ; 61 + +0000018a <__do_copy_data>: + 18a: 11 e0 ldi r17, 0x01 ; 1 + 18c: a0 e0 ldi r26, 0x00 ; 0 + 18e: b1 e0 ldi r27, 0x01 ; 1 + 190: e6 e0 ldi r30, 0x06 ; 6 + 192: ff e0 ldi r31, 0x0F ; 15 + 194: 02 c0 rjmp .+4 ; 0x19a <__do_copy_data+0x10> + 196: 05 90 lpm r0, Z+ + 198: 0d 92 st X+, r0 + 19a: a6 32 cpi r26, 0x26 ; 38 + 19c: b1 07 cpc r27, r17 + 19e: d9 f7 brne .-10 ; 0x196 <__do_copy_data+0xc> + +000001a0 <__do_clear_bss>: + 1a0: 21 e0 ldi r18, 0x01 ; 1 + 1a2: a6 e2 ldi r26, 0x26 ; 38 + 1a4: b1 e0 ldi r27, 0x01 ; 1 + 1a6: 01 c0 rjmp .+2 ; 0x1aa <.do_clear_bss_start> + +000001a8 <.do_clear_bss_loop>: + 1a8: 1d 92 st X+, r1 + +000001aa <.do_clear_bss_start>: + 1aa: a5 39 cpi r26, 0x95 ; 149 + 1ac: b2 07 cpc r27, r18 + 1ae: e1 f7 brne .-8 ; 0x1a8 <.do_clear_bss_loop> + +000001b0 <__do_global_ctors>: + 1b0: 10 e0 ldi r17, 0x00 ; 0 + 1b2: cf eb ldi r28, 0xBF ; 191 + 1b4: d0 e0 ldi r29, 0x00 ; 0 + 1b6: 04 c0 rjmp .+8 ; 0x1c0 <__do_global_ctors+0x10> + 1b8: 21 97 sbiw r28, 0x01 ; 1 + 1ba: fe 01 movw r30, r28 + 1bc: 0e 94 7b 07 call 0xef6 ; 0xef6 <__tablejump2__> + 1c0: ce 3b cpi r28, 0xBE ; 190 + 1c2: d1 07 cpc r29, r17 + 1c4: c9 f7 brne .-14 ; 0x1b8 <__do_global_ctors+0x8> + 1c6: 0e 94 8a 06 call 0xd14 ; 0xd14
+ 1ca: 0c 94 81 07 jmp 0xf02 ; 0xf02 <_exit> + +000001ce <__bad_interrupt>: + 1ce: 0c 94 00 00 jmp 0 ; 0x0 <__vectors> + +000001d2 : + +#define ARDUINO_MAIN +#include "wiring_private.h" +#include "pins_arduino.h" + +void pinMode(uint8_t pin, uint8_t mode) + 1d2: cf 93 push r28 + 1d4: df 93 push r29 +{ + uint8_t bit = digitalPinToBitMask(pin); + 1d6: 90 e0 ldi r25, 0x00 ; 0 + 1d8: fc 01 movw r30, r24 + 1da: e4 5a subi r30, 0xA4 ; 164 + 1dc: fe 4f sbci r31, 0xFE ; 254 + 1de: 24 91 lpm r18, Z + uint8_t port = digitalPinToPort(pin); + 1e0: 83 5c subi r24, 0xC3 ; 195 + 1e2: 9e 4f sbci r25, 0xFE ; 254 + 1e4: fc 01 movw r30, r24 + 1e6: 84 91 lpm r24, Z + volatile uint8_t *reg, *out; + + if (port == NOT_A_PIN) return; + 1e8: 88 23 and r24, r24 + 1ea: c1 f0 breq .+48 ; 0x21c + + // JWS: can I let the optimizer do this? + reg = portModeRegister(port); + 1ec: 90 e0 ldi r25, 0x00 ; 0 + 1ee: 88 0f add r24, r24 + 1f0: 99 1f adc r25, r25 + 1f2: fc 01 movw r30, r24 + 1f4: e1 5d subi r30, 0xD1 ; 209 + 1f6: fe 4f sbci r31, 0xFE ; 254 + 1f8: c5 91 lpm r28, Z+ + 1fa: d4 91 lpm r29, Z + out = portOutputRegister(port); + 1fc: fc 01 movw r30, r24 + 1fe: ef 5d subi r30, 0xDF ; 223 + 200: fe 4f sbci r31, 0xFE ; 254 + 202: a5 91 lpm r26, Z+ + 204: b4 91 lpm r27, Z + cli(); + *reg &= ~bit; + *out &= ~bit; + SREG = oldSREG; + } else if (mode == INPUT_PULLUP) { + uint8_t oldSREG = SREG; + 206: 9f b7 in r25, 0x3f ; 63 + cli(); + 208: f8 94 cli + *reg &= ~bit; + 20a: 38 81 ld r19, Y + 20c: 82 2f mov r24, r18 + 20e: 80 95 com r24 + 210: 83 23 and r24, r19 + 212: 88 83 st Y, r24 + *out |= bit; + 214: ec 91 ld r30, X + 216: e2 2b or r30, r18 + 218: ec 93 st X, r30 + SREG = oldSREG; + 21a: 9f bf out 0x3f, r25 ; 63 + uint8_t oldSREG = SREG; + cli(); + *reg |= bit; + SREG = oldSREG; + } +} + 21c: df 91 pop r29 + 21e: cf 91 pop r28 + 220: 08 95 ret + +00000222 <_Z8USB_RecvhPvi.constprop.5>: + return FifoByteCount(); +} + +// Non Blocking receive +// Return number of bytes read +int USB_Recv(u8 ep, void* d, int len) + 222: fc 01 movw r30, r24 +{ + if (!_usbConfiguration || len < 0) + 224: 80 91 94 01 lds r24, 0x0194 ; 0x800194 <_usbConfiguration> + 228: 88 23 and r24, r24 + 22a: 11 f1 breq .+68 ; 0x270 <_Z8USB_RecvhPvi.constprop.5+0x4e> +#define USB_RECV_TIMEOUT +class LockEP +{ + u8 _sreg; +public: + LockEP(u8 ep) : _sreg(SREG) + 22c: 3f b7 in r19, 0x3f ; 63 + { + cli(); + 22e: f8 94 cli + UEDATX = d; +} + +static inline void SetEP(u8 ep) +{ + UENUM = ep; + 230: 82 e0 ldi r24, 0x02 ; 2 + 232: 80 93 e9 00 sts 0x00E9, r24 ; 0x8000e9 <__DATA_REGION_ORIGIN__+0x89> +} + +static inline u8 FifoByteCount() +{ + return UEBCLX; + 236: 20 91 f2 00 lds r18, 0x00F2 ; 0x8000f2 <__DATA_REGION_ORIGIN__+0x92> + if (!_usbConfiguration || len < 0) + return -1; + + LockEP lock(ep); + u8 n = FifoByteCount(); + len = min(n,len); + 23a: 82 2f mov r24, r18 + 23c: 90 e0 ldi r25, 0x00 ; 0 + 23e: 18 16 cp r1, r24 + 240: 19 06 cpc r1, r25 + 242: 14 f4 brge .+4 ; 0x248 <_Z8USB_RecvhPvi.constprop.5+0x26> + 244: 81 e0 ldi r24, 0x01 ; 1 + 246: 90 e0 ldi r25, 0x00 ; 0 + n = len; + u8* dst = (u8*)d; + while (n--) + 248: 88 23 and r24, r24 + 24a: 39 f0 breq .+14 ; 0x25a <_Z8USB_RecvhPvi.constprop.5+0x38> + RxLEDPulse = TX_RX_LED_PULSE_MS; +} + +static inline u8 Recv8() +{ + RXLED1; // light the RX LED + 24c: 28 98 cbi 0x05, 0 ; 5 + RxLEDPulse = TX_RX_LED_PULSE_MS; + 24e: 44 e6 ldi r20, 0x64 ; 100 + 250: 40 93 93 01 sts 0x0193, r20 ; 0x800193 + + return UEDATX; + 254: 40 91 f1 00 lds r20, 0x00F1 ; 0x8000f1 <__DATA_REGION_ORIGIN__+0x91> + u8 n = FifoByteCount(); + len = min(n,len); + n = len; + u8* dst = (u8*)d; + while (n--) + *dst++ = Recv8(); + 258: 40 83 st Z, r20 + if (len && !FifoByteCount()) // release empty buffer + 25a: 22 23 and r18, r18 + 25c: 39 f0 breq .+14 ; 0x26c <_Z8USB_RecvhPvi.constprop.5+0x4a> + UENUM = ep; +} + +static inline u8 FifoByteCount() +{ + return UEBCLX; + 25e: 20 91 f2 00 lds r18, 0x00F2 ; 0x8000f2 <__DATA_REGION_ORIGIN__+0x92> + len = min(n,len); + n = len; + u8* dst = (u8*)d; + while (n--) + *dst++ = Recv8(); + if (len && !FifoByteCount()) // release empty buffer + 262: 21 11 cpse r18, r1 + 264: 03 c0 rjmp .+6 ; 0x26c <_Z8USB_RecvhPvi.constprop.5+0x4a> + return UEINTX & (1< + cli(); + SetEP(ep & 7); + } + ~LockEP() + { + SREG = _sreg; + 26c: 3f bf out 0x3f, r19 ; 63 + 26e: 08 95 ret +// Non Blocking receive +// Return number of bytes read +int USB_Recv(u8 ep, void* d, int len) +{ + if (!_usbConfiguration || len < 0) + return -1; + 270: 8f ef ldi r24, 0xFF ; 255 + 272: 9f ef ldi r25, 0xFF ; 255 + *dst++ = Recv8(); + if (len && !FifoByteCount()) // release empty buffer + ReleaseRX(); + + return len; +} + 274: 08 95 ret + +00000276 <_Z13USB_SendSpaceh.constprop.3>: +#define USB_RECV_TIMEOUT +class LockEP +{ + u8 _sreg; +public: + LockEP(u8 ep) : _sreg(SREG) + 276: 2f b7 in r18, 0x3f ; 63 + { + cli(); + 278: f8 94 cli + UEDATX = d; +} + +static inline void SetEP(u8 ep) +{ + UENUM = ep; + 27a: 83 e0 ldi r24, 0x03 ; 3 + 27c: 80 93 e9 00 sts 0x00E9, r24 ; 0x8000e9 <__DATA_REGION_ORIGIN__+0x89> + UECONX = (1< + +// Space in send EP +u8 USB_SendSpace(u8 ep) +{ + LockEP lock(ep); + if (!ReadWriteAllowed()) + 284: 89 2f mov r24, r25 + 286: 80 72 andi r24, 0x20 ; 32 + 288: 95 ff sbrs r25, 5 + 28a: 04 c0 rjmp .+8 ; 0x294 <_Z13USB_SendSpaceh.constprop.3+0x1e> + UENUM = ep; +} + +static inline u8 FifoByteCount() +{ + return UEBCLX; + 28c: 90 91 f2 00 lds r25, 0x00F2 ; 0x8000f2 <__DATA_REGION_ORIGIN__+0x92> +u8 USB_SendSpace(u8 ep) +{ + LockEP lock(ep); + if (!ReadWriteAllowed()) + return 0; + return USB_EP_SIZE - FifoByteCount(); + 290: 80 e4 ldi r24, 0x40 ; 64 + 292: 89 1b sub r24, r25 + cli(); + SetEP(ep & 7); + } + ~LockEP() + { + SREG = _sreg; + 294: 2f bf out 0x3f, r18 ; 63 +{ + LockEP lock(ep); + if (!ReadWriteAllowed()) + return 0; + return USB_EP_SIZE - FifoByteCount(); +} + 296: 08 95 ret + +00000298 <_Z12PluggableUSBv>: + // restart USB layer??? +} + +PluggableUSB_& PluggableUSB() +{ + static PluggableUSB_ obj; + 298: 80 91 8b 01 lds r24, 0x018B ; 0x80018b <_ZGVZ12PluggableUSBvE3obj> + 29c: 81 11 cpse r24, r1 + 29e: 0d c0 rjmp .+26 ; 0x2ba <_Z12PluggableUSBv+0x22> + return obj; +} + +PluggableUSB_::PluggableUSB_() : lastIf(CDC_ACM_INTERFACE + CDC_INTERFACE_COUNT), + lastEp(CDC_FIRST_ENDPOINT + CDC_ENPOINT_COUNT), + rootNode(NULL) + 2a0: 82 e0 ldi r24, 0x02 ; 2 + 2a2: 80 93 87 01 sts 0x0187, r24 ; 0x800187 <_ZZ12PluggableUSBvE3obj> + 2a6: 84 e0 ldi r24, 0x04 ; 4 + 2a8: 80 93 88 01 sts 0x0188, r24 ; 0x800188 <_ZZ12PluggableUSBvE3obj+0x1> + 2ac: 10 92 8a 01 sts 0x018A, r1 ; 0x80018a <_ZZ12PluggableUSBvE3obj+0x3> + 2b0: 10 92 89 01 sts 0x0189, r1 ; 0x800189 <_ZZ12PluggableUSBvE3obj+0x2> + // restart USB layer??? +} + +PluggableUSB_& PluggableUSB() +{ + static PluggableUSB_ obj; + 2b4: 81 e0 ldi r24, 0x01 ; 1 + 2b6: 80 93 8b 01 sts 0x018B, r24 ; 0x80018b <_ZGVZ12PluggableUSBvE3obj> + return obj; +} + 2ba: 87 e8 ldi r24, 0x87 ; 135 + 2bc: 91 e0 ldi r25, 0x01 ; 1 + 2be: 08 95 ret + +000002c0 <_ZN7Serial_5writeEh>: +{ + USB_Flush(CDC_TX); +} + +size_t Serial_::write(uint8_t c) +{ + 2c0: cf 93 push r28 + 2c2: df 93 push r29 + 2c4: 1f 92 push r1 + 2c6: cd b7 in r28, 0x3d ; 61 + 2c8: de b7 in r29, 0x3e ; 62 + 2ca: 69 83 std Y+1, r22 ; 0x01 + return write(&c, 1); + 2cc: dc 01 movw r26, r24 + 2ce: ed 91 ld r30, X+ + 2d0: fc 91 ld r31, X + 2d2: 02 80 ldd r0, Z+2 ; 0x02 + 2d4: f3 81 ldd r31, Z+3 ; 0x03 + 2d6: e0 2d mov r30, r0 + 2d8: 41 e0 ldi r20, 0x01 ; 1 + 2da: 50 e0 ldi r21, 0x00 ; 0 + 2dc: be 01 movw r22, r28 + 2de: 6f 5f subi r22, 0xFF ; 255 + 2e0: 7f 4f sbci r23, 0xFF ; 255 + 2e2: 09 95 icall +} + 2e4: 0f 90 pop r0 + 2e6: df 91 pop r29 + 2e8: cf 91 pop r28 + 2ea: 08 95 ret + +000002ec <_ZN7Serial_5flushEv>: + UEDATX = d; +} + +static inline void SetEP(u8 ep) +{ + UENUM = ep; + 2ec: 83 e0 ldi r24, 0x03 ; 3 + 2ee: 80 93 e9 00 sts 0x00E9, r24 ; 0x8000e9 <__DATA_REGION_ORIGIN__+0x89> +} + +static inline u8 FifoByteCount() +{ + return UEBCLX; + 2f2: 80 91 f2 00 lds r24, 0x00F2 ; 0x8000f2 <__DATA_REGION_ORIGIN__+0x92> +} + +void USB_Flush(u8 ep) +{ + SetEP(ep); + if (FifoByteCount()) + 2f6: 88 23 and r24, r24 + 2f8: 19 f0 breq .+6 ; 0x300 <_ZN7Serial_5flushEv+0x14> + UEINTX = 0x6B; // FIFOCON=0 NAKINI=1 RWAL=1 NAKOUTI=0 RXSTPI=1 RXOUTI=0 STALLEDI=1 TXINI=1 +} + +static inline void ReleaseTX() +{ + UEINTX = 0x3A; // FIFOCON=0 NAKINI=0 RWAL=1 NAKOUTI=1 RXSTPI=1 RXOUTI=0 STALLEDI=1 TXINI=0 + 2fa: 8a e3 ldi r24, 0x3A ; 58 + 2fc: 80 93 e8 00 sts 0x00E8, r24 ; 0x8000e8 <__DATA_REGION_ORIGIN__+0x88> +} + +void Serial_::flush(void) +{ + USB_Flush(CDC_TX); +} + 300: 08 95 ret + +00000302 <_ZN7Serial_17availableForWriteEv>: + return USB_Recv(CDC_RX); +} + +int Serial_::availableForWrite(void) +{ + return USB_SendSpace(CDC_TX); + 302: 0e 94 3b 01 call 0x276 ; 0x276 <_Z13USB_SendSpaceh.constprop.3> +} + 306: 90 e0 ldi r25, 0x00 ; 0 + 308: 08 95 ret + +0000030a <_ZN7Serial_4readEv>: + peek_buffer = USB_Recv(CDC_RX); + return peek_buffer; +} + +int Serial_::read(void) +{ + 30a: cf 93 push r28 + 30c: df 93 push r29 + 30e: 1f 92 push r1 + 310: cd b7 in r28, 0x3d ; 61 + 312: de b7 in r29, 0x3e ; 62 + 314: fc 01 movw r30, r24 + if (peek_buffer >= 0) { + 316: 84 85 ldd r24, Z+12 ; 0x0c + 318: 95 85 ldd r25, Z+13 ; 0x0d + 31a: 97 fd sbrc r25, 7 + 31c: 08 c0 rjmp .+16 ; 0x32e <_ZN7Serial_4readEv+0x24> + int c = peek_buffer; + peek_buffer = -1; + 31e: 2f ef ldi r18, 0xFF ; 255 + 320: 3f ef ldi r19, 0xFF ; 255 + 322: 35 87 std Z+13, r19 ; 0x0d + 324: 24 87 std Z+12, r18 ; 0x0c + return c; + } + return USB_Recv(CDC_RX); +} + 326: 0f 90 pop r0 + 328: df 91 pop r29 + 32a: cf 91 pop r28 + 32c: 08 95 ret + +// Recv 1 byte if ready +int USB_Recv(u8 ep) +{ + u8 c; + if (USB_Recv(ep,&c,1) != 1) + 32e: ce 01 movw r24, r28 + 330: 01 96 adiw r24, 0x01 ; 1 + 332: 0e 94 11 01 call 0x222 ; 0x222 <_Z8USB_RecvhPvi.constprop.5> + 336: 01 97 sbiw r24, 0x01 ; 1 + 338: 19 f4 brne .+6 ; 0x340 <_ZN7Serial_4readEv+0x36> + return -1; + return c; + 33a: 89 81 ldd r24, Y+1 ; 0x01 + 33c: 90 e0 ldi r25, 0x00 ; 0 + 33e: f3 cf rjmp .-26 ; 0x326 <_ZN7Serial_4readEv+0x1c> +// Recv 1 byte if ready +int USB_Recv(u8 ep) +{ + u8 c; + if (USB_Recv(ep,&c,1) != 1) + return -1; + 340: 8f ef ldi r24, 0xFF ; 255 + 342: 9f ef ldi r25, 0xFF ; 255 + 344: f0 cf rjmp .-32 ; 0x326 <_ZN7Serial_4readEv+0x1c> + +00000346 <_ZN7Serial_4peekEv>: + } + return USB_Available(CDC_RX); +} + +int Serial_::peek(void) +{ + 346: 0f 93 push r16 + 348: 1f 93 push r17 + 34a: cf 93 push r28 + 34c: df 93 push r29 + 34e: 1f 92 push r1 + 350: cd b7 in r28, 0x3d ; 61 + 352: de b7 in r29, 0x3e ; 62 + 354: 8c 01 movw r16, r24 + if (peek_buffer < 0) + 356: fc 01 movw r30, r24 + 358: 84 85 ldd r24, Z+12 ; 0x0c + 35a: 95 85 ldd r25, Z+13 ; 0x0d + 35c: 97 ff sbrs r25, 7 + 35e: 0b c0 rjmp .+22 ; 0x376 <_ZN7Serial_4peekEv+0x30> + +// Recv 1 byte if ready +int USB_Recv(u8 ep) +{ + u8 c; + if (USB_Recv(ep,&c,1) != 1) + 360: ce 01 movw r24, r28 + 362: 01 96 adiw r24, 0x01 ; 1 + 364: 0e 94 11 01 call 0x222 ; 0x222 <_Z8USB_RecvhPvi.constprop.5> + 368: 01 97 sbiw r24, 0x01 ; 1 + 36a: 71 f4 brne .+28 ; 0x388 <_ZN7Serial_4peekEv+0x42> + return -1; + return c; + 36c: 89 81 ldd r24, Y+1 ; 0x01 + 36e: 90 e0 ldi r25, 0x00 ; 0 + peek_buffer = USB_Recv(CDC_RX); + 370: f8 01 movw r30, r16 + 372: 95 87 std Z+13, r25 ; 0x0d + 374: 84 87 std Z+12, r24 ; 0x0c + return peek_buffer; +} + 376: f8 01 movw r30, r16 + 378: 84 85 ldd r24, Z+12 ; 0x0c + 37a: 95 85 ldd r25, Z+13 ; 0x0d + 37c: 0f 90 pop r0 + 37e: df 91 pop r29 + 380: cf 91 pop r28 + 382: 1f 91 pop r17 + 384: 0f 91 pop r16 + 386: 08 95 ret +// Recv 1 byte if ready +int USB_Recv(u8 ep) +{ + u8 c; + if (USB_Recv(ep,&c,1) != 1) + return -1; + 388: 8f ef ldi r24, 0xFF ; 255 + 38a: 9f ef ldi r25, 0xFF ; 255 + 38c: f1 cf rjmp .-30 ; 0x370 <_ZN7Serial_4peekEv+0x2a> + +0000038e <_ZN7Serial_9availableEv>: +{ +} + +int Serial_::available(void) +{ + if (peek_buffer >= 0) { + 38e: fc 01 movw r30, r24 + 390: 84 85 ldd r24, Z+12 ; 0x0c + 392: 95 85 ldd r25, Z+13 ; 0x0d + 394: 97 fd sbrc r25, 7 + 396: 0b c0 rjmp .+22 ; 0x3ae <_ZN7Serial_9availableEv+0x20> +#define USB_RECV_TIMEOUT +class LockEP +{ + u8 _sreg; +public: + LockEP(u8 ep) : _sreg(SREG) + 398: 9f b7 in r25, 0x3f ; 63 + { + cli(); + 39a: f8 94 cli + UEDATX = d; +} + +static inline void SetEP(u8 ep) +{ + UENUM = ep; + 39c: 82 e0 ldi r24, 0x02 ; 2 + 39e: 80 93 e9 00 sts 0x00E9, r24 ; 0x8000e9 <__DATA_REGION_ORIGIN__+0x89> +} + +static inline u8 FifoByteCount() +{ + return UEBCLX; + 3a2: 80 91 f2 00 lds r24, 0x00F2 ; 0x8000f2 <__DATA_REGION_ORIGIN__+0x92> + cli(); + SetEP(ep & 7); + } + ~LockEP() + { + SREG = _sreg; + 3a6: 9f bf out 0x3f, r25 ; 63 + return 1 + USB_Available(CDC_RX); + 3a8: 90 e0 ldi r25, 0x00 ; 0 + 3aa: 01 96 adiw r24, 0x01 ; 1 + 3ac: 08 95 ret +#define USB_RECV_TIMEOUT +class LockEP +{ + u8 _sreg; +public: + LockEP(u8 ep) : _sreg(SREG) + 3ae: 9f b7 in r25, 0x3f ; 63 + { + cli(); + 3b0: f8 94 cli + UEDATX = d; +} + +static inline void SetEP(u8 ep) +{ + UENUM = ep; + 3b2: 82 e0 ldi r24, 0x02 ; 2 + 3b4: 80 93 e9 00 sts 0x00E9, r24 ; 0x8000e9 <__DATA_REGION_ORIGIN__+0x89> +} + +static inline u8 FifoByteCount() +{ + return UEBCLX; + 3b8: 80 91 f2 00 lds r24, 0x00F2 ; 0x8000f2 <__DATA_REGION_ORIGIN__+0x92> + cli(); + SetEP(ep & 7); + } + ~LockEP() + { + SREG = _sreg; + 3bc: 9f bf out 0x3f, r25 ; 63 + } + return USB_Available(CDC_RX); + 3be: 90 e0 ldi r25, 0x00 ; 0 +} + 3c0: 08 95 ret + +000003c2 <_ZL11SendControlh>: +} + +static +bool SendControl(u8 d) +{ + if (_cmark < _cend) + 3c2: 40 91 31 01 lds r20, 0x0131 ; 0x800131 <_ZL6_cmark> + 3c6: 50 91 32 01 lds r21, 0x0132 ; 0x800132 <_ZL6_cmark+0x1> + 3ca: 20 91 2f 01 lds r18, 0x012F ; 0x80012f <_ZL5_cend> + 3ce: 30 91 30 01 lds r19, 0x0130 ; 0x800130 <_ZL5_cend+0x1> + 3d2: 42 17 cp r20, r18 + 3d4: 53 07 cpc r21, r19 + 3d6: b4 f4 brge .+44 ; 0x404 <__LOCK_REGION_LENGTH__+0x4> + ; +} + +static inline u8 WaitForINOrOUT() +{ + while (!(UEINTX & ((1< + 3dc: 95 70 andi r25, 0x05 ; 5 + 3de: e1 f3 breq .-8 ; 0x3d8 <_ZL11SendControlh+0x16> + ; + return (UEINTX & (1< +static +bool SendControl(u8 d) +{ + if (_cmark < _cend) + { + if (!WaitForINOrOUT()) + 3e4: 92 fd sbrc r25, 2 + 3e6: 19 c0 rjmp .+50 ; 0x41a <__LOCK_REGION_LENGTH__+0x1a> + return UEDATX; +} + +static inline void Send8(u8 d) +{ + UEDATX = d; + 3e8: 80 93 f1 00 sts 0x00F1, r24 ; 0x8000f1 <__DATA_REGION_ORIGIN__+0x91> + if (_cmark < _cend) + { + if (!WaitForINOrOUT()) + return false; + Send8(d); + if (!((_cmark + 1) & 0x3F)) + 3ec: 80 91 31 01 lds r24, 0x0131 ; 0x800131 <_ZL6_cmark> + 3f0: 90 91 32 01 lds r25, 0x0132 ; 0x800132 <_ZL6_cmark+0x1> + 3f4: 01 96 adiw r24, 0x01 ; 1 + 3f6: 8f 73 andi r24, 0x3F ; 63 + 3f8: 99 27 eor r25, r25 + 3fa: 89 2b or r24, r25 + 3fc: 19 f4 brne .+6 ; 0x404 <__LOCK_REGION_LENGTH__+0x4> + ; +} + +static inline void ClearIN(void) +{ + UEINTX = ~(1< + return false; + Send8(d); + if (!((_cmark + 1) & 0x3F)) + ClearIN(); // Fifo is full, release this packet + } + _cmark++; + 404: 80 91 31 01 lds r24, 0x0131 ; 0x800131 <_ZL6_cmark> + 408: 90 91 32 01 lds r25, 0x0132 ; 0x800132 <_ZL6_cmark+0x1> + 40c: 01 96 adiw r24, 0x01 ; 1 + 40e: 90 93 32 01 sts 0x0132, r25 ; 0x800132 <_ZL6_cmark+0x1> + 412: 80 93 31 01 sts 0x0131, r24 ; 0x800131 <_ZL6_cmark> + return true; + 416: 81 e0 ldi r24, 0x01 ; 1 + 418: 08 95 ret +bool SendControl(u8 d) +{ + if (_cmark < _cend) + { + if (!WaitForINOrOUT()) + return false; + 41a: 80 e0 ldi r24, 0x00 ; 0 + if (!((_cmark + 1) & 0x3F)) + ClearIN(); // Fifo is full, release this packet + } + _cmark++; + return true; +} + 41c: 08 95 ret + +0000041e <_ZL24USB_SendStringDescriptorPKhhh>: +} + +// Send a USB descriptor string. The string is stored in PROGMEM as a +// plain ASCII string but is sent out as UTF-16 with the correct 2-byte +// prefix +static bool USB_SendStringDescriptor(const u8*string_P, u8 string_len, uint8_t flags) { + 41e: ef 92 push r14 + 420: ff 92 push r15 + 422: 0f 93 push r16 + 424: 1f 93 push r17 + 426: cf 93 push r28 + 428: df 93 push r29 + 42a: f8 2e mov r15, r24 + 42c: 19 2f mov r17, r25 + 42e: e6 2e mov r14, r22 + 430: 04 2f mov r16, r20 + SendControl(2 + string_len * 2); + 432: 81 e0 ldi r24, 0x01 ; 1 + 434: 86 0f add r24, r22 + 436: 88 0f add r24, r24 + 438: 0e 94 e1 01 call 0x3c2 ; 0x3c2 <_ZL11SendControlh> + SendControl(3); + 43c: 83 e0 ldi r24, 0x03 ; 3 + 43e: 0e 94 e1 01 call 0x3c2 ; 0x3c2 <_ZL11SendControlh> + 442: cf 2d mov r28, r15 + 444: d1 2f mov r29, r17 + 446: ec 0e add r14, r28 + 448: fd 2e mov r15, r29 + 44a: f1 1c adc r15, r1 + bool pgm = flags & TRANSFER_PGM; + for(u8 i = 0; i < string_len; i++) { + 44c: ce 15 cp r28, r14 + 44e: df 05 cpc r29, r15 + 450: b9 f0 breq .+46 ; 0x480 <_ZL24USB_SendStringDescriptorPKhhh+0x62> + bool r = SendControl(pgm ? pgm_read_byte(&string_P[i]) : string_P[i]); + 452: 07 ff sbrs r16, 7 + 454: 13 c0 rjmp .+38 ; 0x47c <_ZL24USB_SendStringDescriptorPKhhh+0x5e> + 456: fe 01 movw r30, r28 + 458: 84 91 lpm r24, Z + 45a: 0e 94 e1 01 call 0x3c2 ; 0x3c2 <_ZL11SendControlh> + 45e: 18 2f mov r17, r24 + r &= SendControl(0); // high byte + 460: 80 e0 ldi r24, 0x00 ; 0 + 462: 0e 94 e1 01 call 0x3c2 ; 0x3c2 <_ZL11SendControlh> + 466: 81 23 and r24, r17 + 468: 21 96 adiw r28, 0x01 ; 1 + if(!r) { + 46a: 81 11 cpse r24, r1 + 46c: ef cf rjmp .-34 ; 0x44c <_ZL24USB_SendStringDescriptorPKhhh+0x2e> + return false; + } + } + return true; +} + 46e: df 91 pop r29 + 470: cf 91 pop r28 + 472: 1f 91 pop r17 + 474: 0f 91 pop r16 + 476: ff 90 pop r15 + 478: ef 90 pop r14 + 47a: 08 95 ret +static bool USB_SendStringDescriptor(const u8*string_P, u8 string_len, uint8_t flags) { + SendControl(2 + string_len * 2); + SendControl(3); + bool pgm = flags & TRANSFER_PGM; + for(u8 i = 0; i < string_len; i++) { + bool r = SendControl(pgm ? pgm_read_byte(&string_P[i]) : string_P[i]); + 47c: 88 81 ld r24, Y + 47e: ed cf rjmp .-38 ; 0x45a <_ZL24USB_SendStringDescriptorPKhhh+0x3c> + r &= SendControl(0); // high byte + if(!r) { + return false; + } + } + return true; + 480: 81 e0 ldi r24, 0x01 ; 1 + 482: f5 cf rjmp .-22 ; 0x46e <_ZL24USB_SendStringDescriptorPKhhh+0x50> + +00000484 <_Z15USB_SendControlhPKvi>: + return true; +} + +// Clipped by _cmark/_cend +int USB_SendControl(u8 flags, const void* d, int len) +{ + 484: df 92 push r13 + 486: ef 92 push r14 + 488: ff 92 push r15 + 48a: 0f 93 push r16 + 48c: 1f 93 push r17 + 48e: cf 93 push r28 + 490: df 93 push r29 + 492: d8 2e mov r13, r24 + 494: 8a 01 movw r16, r20 + 496: eb 01 movw r28, r22 + 498: 7b 01 movw r14, r22 + 49a: e4 0e add r14, r20 + 49c: f5 1e adc r15, r21 + int sent = len; + const u8* data = (const u8*)d; + bool pgm = flags & TRANSFER_PGM; + while (len--) + 49e: ce 15 cp r28, r14 + 4a0: df 05 cpc r29, r15 + 4a2: 59 f0 breq .+22 ; 0x4ba <_Z15USB_SendControlhPKvi+0x36> + { + u8 c = pgm ? pgm_read_byte(data++) : *data++; + 4a4: d7 fe sbrs r13, 7 + 4a6: 12 c0 rjmp .+36 ; 0x4cc <_Z15USB_SendControlhPKvi+0x48> + 4a8: fe 01 movw r30, r28 + 4aa: 84 91 lpm r24, Z + if (!SendControl(c)) + 4ac: 0e 94 e1 01 call 0x3c2 ; 0x3c2 <_ZL11SendControlh> + 4b0: 21 96 adiw r28, 0x01 ; 1 + 4b2: 81 11 cpse r24, r1 + 4b4: f4 cf rjmp .-24 ; 0x49e <_Z15USB_SendControlhPKvi+0x1a> + return -1; + 4b6: 0f ef ldi r16, 0xFF ; 255 + 4b8: 1f ef ldi r17, 0xFF ; 255 + } + return sent; +} + 4ba: c8 01 movw r24, r16 + 4bc: df 91 pop r29 + 4be: cf 91 pop r28 + 4c0: 1f 91 pop r17 + 4c2: 0f 91 pop r16 + 4c4: ff 90 pop r15 + 4c6: ef 90 pop r14 + 4c8: df 90 pop r13 + 4ca: 08 95 ret + int sent = len; + const u8* data = (const u8*)d; + bool pgm = flags & TRANSFER_PGM; + while (len--) + { + u8 c = pgm ? pgm_read_byte(data++) : *data++; + 4cc: 88 81 ld r24, Y + 4ce: ee cf rjmp .-36 ; 0x4ac <_Z15USB_SendControlhPKvi+0x28> + +000004d0 <_ZL14SendInterfacesv>: + } + return len; +} + +static u8 SendInterfaces() +{ + 4d0: 0f 93 push r16 + 4d2: 1f 93 push r17 + 4d4: cf 93 push r28 + 4d6: df 93 push r29 + 4d8: 1f 92 push r1 + 4da: cd b7 in r28, 0x3d ; 61 + 4dc: de b7 in r29, 0x3e ; 62 + return pgm_read_word(FLASHEND - 1) == NEW_LUFA_SIGNATURE; +} + +int CDC_GetInterface(u8* interfaceNum) +{ + interfaceNum[0] += 2; // uses 2 + 4de: 82 e0 ldi r24, 0x02 ; 2 + 4e0: 89 83 std Y+1, r24 ; 0x01 + return USB_SendControl(TRANSFER_PGM,&_cdcInterface,sizeof(_cdcInterface)); + 4e2: 42 e4 ldi r20, 0x42 ; 66 + 4e4: 50 e0 ldi r21, 0x00 ; 0 + 4e6: 6c ea ldi r22, 0xAC ; 172 + 4e8: 70 e0 ldi r23, 0x00 ; 0 + 4ea: 80 e8 ldi r24, 0x80 ; 128 + 4ec: 0e 94 42 02 call 0x484 ; 0x484 <_Z15USB_SendControlhPKvi> +#ifdef CDC_ENABLED + CDC_GetInterface(&interfaces); +#endif + +#ifdef PLUGGABLE_USB_ENABLED + PluggableUSB().getInterface(&interfaces); + 4f0: 0e 94 4c 01 call 0x298 ; 0x298 <_Z12PluggableUSBv> + +int PluggableUSB_::getInterface(uint8_t* interfaceCount) +{ + int sent = 0; + PluggableUSBModule* node; + for (node = rootNode; node; node = node->next) { + 4f4: dc 01 movw r26, r24 + 4f6: 12 96 adiw r26, 0x02 ; 2 + 4f8: 0d 91 ld r16, X+ + 4fa: 1c 91 ld r17, X + 4fc: 01 15 cp r16, r1 + 4fe: 11 05 cpc r17, r1 + 500: 89 f0 breq .+34 ; 0x524 <_ZL14SendInterfacesv+0x54> + int res = node->getInterface(interfaceCount); + 502: d8 01 movw r26, r16 + 504: ed 91 ld r30, X+ + 506: fc 91 ld r31, X + 508: 02 80 ldd r0, Z+2 ; 0x02 + 50a: f3 81 ldd r31, Z+3 ; 0x03 + 50c: e0 2d mov r30, r0 + 50e: be 01 movw r22, r28 + 510: 6f 5f subi r22, 0xFF ; 255 + 512: 7f 4f sbci r23, 0xFF ; 255 + 514: c8 01 movw r24, r16 + 516: 09 95 icall + if (res < 0) + 518: 97 fd sbrc r25, 7 + 51a: 04 c0 rjmp .+8 ; 0x524 <_ZL14SendInterfacesv+0x54> + +int PluggableUSB_::getInterface(uint8_t* interfaceCount) +{ + int sent = 0; + PluggableUSBModule* node; + for (node = rootNode; node; node = node->next) { + 51c: f8 01 movw r30, r16 + 51e: 00 85 ldd r16, Z+8 ; 0x08 + 520: 11 85 ldd r17, Z+9 ; 0x09 + 522: ec cf rjmp .-40 ; 0x4fc <_ZL14SendInterfacesv+0x2c> +#endif + + return interfaces; +} + 524: 89 81 ldd r24, Y+1 ; 0x01 + 526: 0f 90 pop r0 + 528: df 91 pop r29 + 52a: cf 91 pop r28 + 52c: 1f 91 pop r17 + 52e: 0f 91 pop r16 + 530: 08 95 ret + +00000532 <_ZL4RecvPVhh>: + UEINTX = ~(1< + *data++ = UEDATX; + 536: 20 91 f1 00 lds r18, 0x00F1 ; 0x8000f1 <__DATA_REGION_ORIGIN__+0x91> + 53a: fc 01 movw r30, r24 + 53c: 20 83 st Z, r18 + 53e: 01 96 adiw r24, 0x01 ; 1 + 540: f8 cf rjmp .-16 ; 0x532 <_ZL4RecvPVhh> + + RXLED1; // light the RX LED + 542: 28 98 cbi 0x05, 0 ; 5 + RxLEDPulse = TX_RX_LED_PULSE_MS; + 544: 84 e6 ldi r24, 0x64 ; 100 + 546: 80 93 93 01 sts 0x0193, r24 ; 0x800193 +} + 54a: 08 95 ret + +0000054c : + return m; +} + +unsigned long micros() { + unsigned long m; + uint8_t oldSREG = SREG, t; + 54c: 3f b7 in r19, 0x3f ; 63 + + cli(); + 54e: f8 94 cli + m = timer0_overflow_count; + 550: 80 91 2b 01 lds r24, 0x012B ; 0x80012b + 554: 90 91 2c 01 lds r25, 0x012C ; 0x80012c + 558: a0 91 2d 01 lds r26, 0x012D ; 0x80012d + 55c: b0 91 2e 01 lds r27, 0x012E ; 0x80012e +#if defined(TCNT0) + t = TCNT0; + 560: 26 b5 in r18, 0x26 ; 38 +#else + #error TIMER 0 not defined +#endif + +#ifdef TIFR0 + if ((TIFR0 & _BV(TOV0)) && (t < 255)) + 562: a8 9b sbis 0x15, 0 ; 21 + 564: 05 c0 rjmp .+10 ; 0x570 + 566: 2f 3f cpi r18, 0xFF ; 255 + 568: 19 f0 breq .+6 ; 0x570 + m++; + 56a: 01 96 adiw r24, 0x01 ; 1 + 56c: a1 1d adc r26, r1 + 56e: b1 1d adc r27, r1 +#else + if ((TIFR & _BV(TOV0)) && (t < 255)) + m++; +#endif + + SREG = oldSREG; + 570: 3f bf out 0x3f, r19 ; 63 + + return ((m << 8) + t) * (64 / clockCyclesPerMicrosecond()); + 572: ba 2f mov r27, r26 + 574: a9 2f mov r26, r25 + 576: 98 2f mov r25, r24 + 578: 88 27 eor r24, r24 + 57a: bc 01 movw r22, r24 + 57c: cd 01 movw r24, r26 + 57e: 62 0f add r22, r18 + 580: 71 1d adc r23, r1 + 582: 81 1d adc r24, r1 + 584: 91 1d adc r25, r1 + 586: 42 e0 ldi r20, 0x02 ; 2 + 588: 66 0f add r22, r22 + 58a: 77 1f adc r23, r23 + 58c: 88 1f adc r24, r24 + 58e: 99 1f adc r25, r25 + 590: 4a 95 dec r20 + 592: d1 f7 brne .-12 ; 0x588 +} + 594: 08 95 ret + +00000596 : + +void delay(unsigned long ms) + 596: cf 92 push r12 + 598: df 92 push r13 + 59a: ef 92 push r14 + 59c: ff 92 push r15 +{ + uint32_t start = micros(); + 59e: 0e 94 a6 02 call 0x54c ; 0x54c + 5a2: 6b 01 movw r12, r22 + 5a4: 7c 01 movw r14, r24 + + while (ms > 0) { + yield(); + while ( ms > 0 && (micros() - start) >= 1000) { + 5a6: 0e 94 a6 02 call 0x54c ; 0x54c + 5aa: 6c 19 sub r22, r12 + 5ac: 7d 09 sbc r23, r13 + 5ae: 8e 09 sbc r24, r14 + 5b0: 9f 09 sbc r25, r15 + 5b2: 68 3e cpi r22, 0xE8 ; 232 + 5b4: 73 40 sbci r23, 0x03 ; 3 + 5b6: 81 05 cpc r24, r1 + 5b8: 91 05 cpc r25, r1 + 5ba: a8 f3 brcs .-22 ; 0x5a6 + ms--; + start += 1000; + } + } +} + 5bc: ff 90 pop r15 + 5be: ef 90 pop r14 + 5c0: df 90 pop r13 + 5c2: cf 90 pop r12 + 5c4: 08 95 ret + +000005c6 <_ZN7Serial_5writeEPKhj>: +{ + return write(&c, 1); +} + +size_t Serial_::write(const uint8_t *buffer, size_t size) +{ + 5c6: 8f 92 push r8 + 5c8: 9f 92 push r9 + 5ca: af 92 push r10 + 5cc: bf 92 push r11 + 5ce: cf 92 push r12 + 5d0: df 92 push r13 + 5d2: ef 92 push r14 + 5d4: ff 92 push r15 + 5d6: 0f 93 push r16 + 5d8: 1f 93 push r17 + 5da: cf 93 push r28 + 5dc: df 93 push r29 + 5de: 6c 01 movw r12, r24 + 5e0: 7b 01 movw r14, r22 + 5e2: 8a 01 movw r16, r20 + the connection is closed are lost - just like with a UART. */ + + // TODO - ZE - check behavior on different OSes and test what happens if an + // open connection isn't broken cleanly (cable is yanked out, host dies + // or locks up, or host virtual serial port hangs) + if (_usbLineInfo.lineState > 0) { + 5e4: 80 91 0b 01 lds r24, 0x010B ; 0x80010b <_ZL12_usbLineInfo+0x7> + 5e8: 88 23 and r24, r24 + 5ea: 09 f4 brne .+2 ; 0x5ee <_ZN7Serial_5writeEPKhj+0x28> + 5ec: 58 c0 rjmp .+176 ; 0x69e <_ZN7Serial_5writeEPKhj+0xd8> +} + +// Blocking Send of data to an endpoint +int USB_Send(u8 ep, const void* d, int len) +{ + if (!_usbConfiguration) + 5ee: 80 91 94 01 lds r24, 0x0194 ; 0x800194 <_usbConfiguration> + 5f2: 88 23 and r24, r24 + 5f4: 09 f4 brne .+2 ; 0x5f8 <_ZN7Serial_5writeEPKhj+0x32> + 5f6: 53 c0 rjmp .+166 ; 0x69e <_ZN7Serial_5writeEPKhj+0xd8> + return -1; + + if (_usbSuspendState & (1< + 5fc: 80 ff sbrs r24, 0 + 5fe: 05 c0 rjmp .+10 ; 0x60a <_ZN7Serial_5writeEPKhj+0x44> + //send a remote wakeup + UDCON |= (1 << RMWKUP); + 600: 80 91 e0 00 lds r24, 0x00E0 ; 0x8000e0 <__DATA_REGION_ORIGIN__+0x80> + 604: 82 60 ori r24, 0x02 ; 2 + 606: 80 93 e0 00 sts 0x00E0, r24 ; 0x8000e0 <__DATA_REGION_ORIGIN__+0x80> +{ + return write(&c, 1); +} + +size_t Serial_::write(const uint8_t *buffer, size_t size) +{ + 60a: e8 01 movw r28, r16 + 60c: b1 2c mov r11, r1 + 60e: 8a ef ldi r24, 0xFA ; 250 + 610: a8 2e mov r10, r24 + UEDATX = d; +} + +static inline void SetEP(u8 ep) +{ + UENUM = ep; + 612: 93 e0 ldi r25, 0x03 ; 3 + 614: 89 2e mov r8, r25 + UEINTX = 0x6B; // FIFOCON=0 NAKINI=1 RWAL=1 NAKOUTI=0 RXSTPI=1 RXOUTI=0 STALLEDI=1 TXINI=1 +} + +static inline void ReleaseTX() +{ + UEINTX = 0x3A; // FIFOCON=0 NAKINI=0 RWAL=1 NAKOUTI=1 RXSTPI=1 RXOUTI=0 STALLEDI=1 TXINI=0 + 616: 2a e3 ldi r18, 0x3A ; 58 + 618: 92 2e mov r9, r18 + int r = len; + const u8* data = (const u8*)d; + u8 timeout = 250; // 250ms timeout on send? TODO + bool sendZlp = false; + + while (len || sendZlp) + 61a: 20 97 sbiw r28, 0x00 ; 0 + 61c: 11 f4 brne .+4 ; 0x622 <_ZN7Serial_5writeEPKhj+0x5c> + 61e: bb 20 and r11, r11 + 620: b9 f1 breq .+110 ; 0x690 <_ZN7Serial_5writeEPKhj+0xca> + { + u8 n = USB_SendSpace(ep); + 622: 0e 94 3b 01 call 0x276 ; 0x276 <_Z13USB_SendSpaceh.constprop.3> + if (n == 0) + 626: 81 11 cpse r24, r1 + 628: 06 c0 rjmp .+12 ; 0x636 <_ZN7Serial_5writeEPKhj+0x70> + { + if (!(--timeout)) + 62a: aa 94 dec r10 + 62c: aa 20 and r10, r10 + 62e: b9 f1 breq .+110 ; 0x69e <_ZN7Serial_5writeEPKhj+0xd8> + return -1; + delay(1); + 630: 0e 94 cb 02 call 0x596 ; 0x596 + 634: f2 cf rjmp .-28 ; 0x61a <_ZN7Serial_5writeEPKhj+0x54> + continue; + } + + if (n > len) { + 636: 8c 17 cp r24, r28 + 638: 1d 06 cpc r1, r29 + 63a: 11 f0 breq .+4 ; 0x640 <_ZN7Serial_5writeEPKhj+0x7a> + 63c: 0c f0 brlt .+2 ; 0x640 <_ZN7Serial_5writeEPKhj+0x7a> + n = len; + 63e: 8c 2f mov r24, r28 +#define USB_RECV_TIMEOUT +class LockEP +{ + u8 _sreg; +public: + LockEP(u8 ep) : _sreg(SREG) + 640: 9f b7 in r25, 0x3f ; 63 + { + cli(); + 642: f8 94 cli + UEDATX = d; +} + +static inline void SetEP(u8 ep) +{ + UENUM = ep; + 644: 80 92 e9 00 sts 0x00E9, r8 ; 0x8000e9 <__DATA_REGION_ORIGIN__+0x89> + UECONX = (1< + } + + { + LockEP lock(ep); + // Frame may have been released by the SOF interrupt handler + if (!ReadWriteAllowed()) + 64c: 25 fd sbrc r18, 5 + 64e: 02 c0 rjmp .+4 ; 0x654 <_ZN7Serial_5writeEPKhj+0x8e> + cli(); + SetEP(ep & 7); + } + ~LockEP() + { + SREG = _sreg; + 650: 9f bf out 0x3f, r25 ; 63 + 652: e3 cf rjmp .-58 ; 0x61a <_ZN7Serial_5writeEPKhj+0x54> + LockEP lock(ep); + // Frame may have been released by the SOF interrupt handler + if (!ReadWriteAllowed()) + continue; + + len -= n; + 654: 28 2f mov r18, r24 + 656: 30 e0 ldi r19, 0x00 ; 0 + 658: c2 1b sub r28, r18 + 65a: d3 0b sbc r29, r19 + 65c: f7 01 movw r30, r14 + while (n--) + Send8(pgm_read_byte(data++)); + } + else + { + while (n--) + 65e: 81 50 subi r24, 0x01 ; 1 + 660: 20 f0 brcs .+8 ; 0x66a <_ZN7Serial_5writeEPKhj+0xa4> + Send8(*data++); + 662: 41 91 ld r20, Z+ + return UEDATX; +} + +static inline void Send8(u8 d) +{ + UEDATX = d; + 664: 40 93 f1 00 sts 0x00F1, r20 ; 0x8000f1 <__DATA_REGION_ORIGIN__+0x91> + 668: fa cf rjmp .-12 ; 0x65e <_ZN7Serial_5writeEPKhj+0x98> + 66a: e2 0e add r14, r18 + 66c: f3 1e adc r15, r19 + { + while (n--) + Send8(*data++); + } + + if (sendZlp) { + 66e: bb 20 and r11, r11 + 670: 21 f0 breq .+8 ; 0x67a <_ZN7Serial_5writeEPKhj+0xb4> + UEINTX = 0x6B; // FIFOCON=0 NAKINI=1 RWAL=1 NAKOUTI=0 RXSTPI=1 RXOUTI=0 STALLEDI=1 TXINI=1 +} + +static inline void ReleaseTX() +{ + UEINTX = 0x3A; // FIFOCON=0 NAKINI=0 RWAL=1 NAKOUTI=1 RXSTPI=1 RXOUTI=0 STALLEDI=1 TXINI=0 + 672: 90 92 e8 00 sts 0x00E8, r9 ; 0x8000e8 <__DATA_REGION_ORIGIN__+0x88> + if (sendZlp) { + ReleaseTX(); + sendZlp = false; + } else if (!ReadWriteAllowed()) { // ...release if buffer is full... + ReleaseTX(); + if (len == 0) sendZlp = true; + 676: b1 2c mov r11, r1 + 678: eb cf rjmp .-42 ; 0x650 <_ZN7Serial_5writeEPKhj+0x8a> + UECONX = (1< + } + + if (sendZlp) { + ReleaseTX(); + sendZlp = false; + } else if (!ReadWriteAllowed()) { // ...release if buffer is full... + 67e: 85 fd sbrc r24, 5 + 680: e7 cf rjmp .-50 ; 0x650 <_ZN7Serial_5writeEPKhj+0x8a> + UEINTX = 0x6B; // FIFOCON=0 NAKINI=1 RWAL=1 NAKOUTI=0 RXSTPI=1 RXOUTI=0 STALLEDI=1 TXINI=1 +} + +static inline void ReleaseTX() +{ + UEINTX = 0x3A; // FIFOCON=0 NAKINI=0 RWAL=1 NAKOUTI=1 RXSTPI=1 RXOUTI=0 STALLEDI=1 TXINI=0 + 682: 90 92 e8 00 sts 0x00E8, r9 ; 0x8000e8 <__DATA_REGION_ORIGIN__+0x88> + if (sendZlp) { + ReleaseTX(); + sendZlp = false; + } else if (!ReadWriteAllowed()) { // ...release if buffer is full... + ReleaseTX(); + if (len == 0) sendZlp = true; + 686: bb 24 eor r11, r11 + 688: b3 94 inc r11 + 68a: 20 97 sbiw r28, 0x00 ; 0 + 68c: 09 f3 breq .-62 ; 0x650 <_ZN7Serial_5writeEPKhj+0x8a> + 68e: f3 cf rjmp .-26 ; 0x676 <_ZN7Serial_5writeEPKhj+0xb0> + // XXX: TRANSFER_RELEASE is never used can be removed? + ReleaseTX(); + } + } + } + TXLED1; // light the TX LED + 690: 5d 98 cbi 0x0b, 5 ; 11 + TxLEDPulse = TX_RX_LED_PULSE_MS; + 692: 84 e6 ldi r24, 0x64 ; 100 + 694: 80 93 35 01 sts 0x0135, r24 ; 0x800135 + // TODO - ZE - check behavior on different OSes and test what happens if an + // open connection isn't broken cleanly (cable is yanked out, host dies + // or locks up, or host virtual serial port hangs) + if (_usbLineInfo.lineState > 0) { + int r = USB_Send(CDC_TX,buffer,size); + if (r > 0) { + 698: 10 16 cp r1, r16 + 69a: 11 06 cpc r1, r17 + 69c: 3c f0 brlt .+14 ; 0x6ac <_ZN7Serial_5writeEPKhj+0xe6> + private: + int write_error; + size_t printNumber(unsigned long, uint8_t); + size_t printFloat(double, uint8_t); + protected: + void setWriteError(int err = 1) { write_error = err; } + 69e: 81 e0 ldi r24, 0x01 ; 1 + 6a0: 90 e0 ldi r25, 0x00 ; 0 + 6a2: f6 01 movw r30, r12 + 6a4: 93 83 std Z+3, r25 ; 0x03 + 6a6: 82 83 std Z+2, r24 ; 0x02 + return r; + } else { + setWriteError(); + return 0; + 6a8: 10 e0 ldi r17, 0x00 ; 0 + 6aa: 00 e0 ldi r16, 0x00 ; 0 + } + } + setWriteError(); + return 0; +} + 6ac: c8 01 movw r24, r16 + 6ae: df 91 pop r29 + 6b0: cf 91 pop r28 + 6b2: 1f 91 pop r17 + 6b4: 0f 91 pop r16 + 6b6: ff 90 pop r15 + 6b8: ef 90 pop r14 + 6ba: df 90 pop r13 + 6bc: cf 90 pop r12 + 6be: bf 90 pop r11 + 6c0: af 90 pop r10 + 6c2: 9f 90 pop r9 + 6c4: 8f 90 pop r8 + 6c6: 08 95 ret + +000006c8 <__vector_10>: +#endif +} + +// General interrupt +ISR(USB_GEN_vect) +{ + 6c8: 1f 92 push r1 + 6ca: 0f 92 push r0 + 6cc: 0f b6 in r0, 0x3f ; 63 + 6ce: 0f 92 push r0 + 6d0: 11 24 eor r1, r1 + 6d2: 8f 93 push r24 + 6d4: 9f 93 push r25 + u8 udint = UDINT; + 6d6: 80 91 e1 00 lds r24, 0x00E1 ; 0x8000e1 <__DATA_REGION_ORIGIN__+0x81> + UDINT &= ~((1< + 6de: 93 7f andi r25, 0xF3 ; 243 + 6e0: 90 93 e1 00 sts 0x00E1, r25 ; 0x8000e1 <__DATA_REGION_ORIGIN__+0x81> + + // End of Reset + if (udint & (1< +#define EP_SINGLE_16 0x12 + +static +void InitEP(u8 index, u8 type, u8 size) +{ + UENUM = index; + 6e8: 10 92 e9 00 sts 0x00E9, r1 ; 0x8000e9 <__DATA_REGION_ORIGIN__+0x89> + UECONX = (1< + UECFG0X = type; + 6f2: 10 92 ec 00 sts 0x00EC, r1 ; 0x8000ec <__DATA_REGION_ORIGIN__+0x8c> + UECFG1X = size; + 6f6: 92 e3 ldi r25, 0x32 ; 50 + 6f8: 90 93 ed 00 sts 0x00ED, r25 ; 0x8000ed <__DATA_REGION_ORIGIN__+0x8d> + + // End of Reset + if (udint & (1< + UEIENX = 1 << RXSTPE; // Enable interrupts for ep0 + 700: 98 e0 ldi r25, 0x08 ; 8 + 702: 90 93 f0 00 sts 0x00F0, r25 ; 0x8000f0 <__DATA_REGION_ORIGIN__+0x90> + } + + // Start of Frame - happens every millisecond so we use it for TX and RX LED one-shot timing, too + if (udint & (1< + UEDATX = d; +} + +static inline void SetEP(u8 ep) +{ + UENUM = ep; + 70a: 93 e0 ldi r25, 0x03 ; 3 + 70c: 90 93 e9 00 sts 0x00E9, r25 ; 0x8000e9 <__DATA_REGION_ORIGIN__+0x89> +} + +static inline u8 FifoByteCount() +{ + return UEBCLX; + 710: 90 91 f2 00 lds r25, 0x00F2 ; 0x8000f2 <__DATA_REGION_ORIGIN__+0x92> +} + +void USB_Flush(u8 ep) +{ + SetEP(ep); + if (FifoByteCount()) + 714: 99 23 and r25, r25 + 716: 19 f0 breq .+6 ; 0x71e <__vector_10+0x56> + UEINTX = 0x6B; // FIFOCON=0 NAKINI=1 RWAL=1 NAKOUTI=0 RXSTPI=1 RXOUTI=0 STALLEDI=1 TXINI=1 +} + +static inline void ReleaseTX() +{ + UEINTX = 0x3A; // FIFOCON=0 NAKINI=0 RWAL=1 NAKOUTI=1 RXSTPI=1 RXOUTI=0 STALLEDI=1 TXINI=0 + 718: 9a e3 ldi r25, 0x3A ; 58 + 71a: 90 93 e8 00 sts 0x00E8, r25 ; 0x8000e8 <__DATA_REGION_ORIGIN__+0x88> + if (udint & (1< + 722: 99 23 and r25, r25 + 724: 41 f0 breq .+16 ; 0x736 <__vector_10+0x6e> + 726: 90 91 35 01 lds r25, 0x0135 ; 0x800135 + 72a: 91 50 subi r25, 0x01 ; 1 + 72c: 90 93 35 01 sts 0x0135, r25 ; 0x800135 + 730: 91 11 cpse r25, r1 + 732: 01 c0 rjmp .+2 ; 0x736 <__vector_10+0x6e> + TXLED0; + 734: 5d 9a sbi 0x0b, 5 ; 11 + if (RxLEDPulse && !(--RxLEDPulse)) + 736: 90 91 93 01 lds r25, 0x0193 ; 0x800193 + 73a: 99 23 and r25, r25 + 73c: 41 f0 breq .+16 ; 0x74e <__vector_10+0x86> + 73e: 90 91 93 01 lds r25, 0x0193 ; 0x800193 + 742: 91 50 subi r25, 0x01 ; 1 + 744: 90 93 93 01 sts 0x0193, r25 ; 0x800193 + 748: 91 11 cpse r25, r1 + 74a: 01 c0 rjmp .+2 ; 0x74e <__vector_10+0x86> + RXLED0; + 74c: 28 9a sbi 0x05, 0 ; 5 + } + + // the WAKEUPI interrupt is triggered as soon as there are non-idle patterns on the data + // lines. Thus, the WAKEUPI interrupt can occur even if the controller is not in the "suspend" mode. + // Therefore the we enable it only when USB is suspended + if (udint & (1< + { + UDIEN = (UDIEN & ~(1< + 756: 8e 7e andi r24, 0xEE ; 238 + 758: 81 60 ori r24, 0x01 ; 1 + 75a: 80 93 e2 00 sts 0x00E2, r24 ; 0x8000e2 <__DATA_REGION_ORIGIN__+0x82> + + //TODO + // WAKEUPI shall be cleared by software (USB clock inputs must be enabled before). + //USB_ClockEnable(); + UDINT &= ~(1< + 762: 8f 7e andi r24, 0xEF ; 239 + 764: 80 93 e1 00 sts 0x00E1, r24 ; 0x8000e1 <__DATA_REGION_ORIGIN__+0x81> + _usbSuspendState = (_usbSuspendState & ~(1< + 76c: 8e 7e andi r24, 0xEE ; 238 + 76e: 80 61 ori r24, 0x10 ; 16 + + //TODO + //USB_ClockDisable(); + + UDINT &= ~((1< + } +} + 774: 9f 91 pop r25 + 776: 8f 91 pop r24 + 778: 0f 90 pop r0 + 77a: 0f be out 0x3f, r0 ; 63 + 77c: 0f 90 pop r0 + 77e: 1f 90 pop r1 + 780: 18 95 reti + // WAKEUPI shall be cleared by software (USB clock inputs must be enabled before). + //USB_ClockEnable(); + UDINT &= ~(1< + { + UDIEN = (UDIEN & ~(1< + 78a: 8e 7e andi r24, 0xEE ; 238 + 78c: 80 61 ori r24, 0x10 ; 16 + 78e: 80 93 e2 00 sts 0x00E2, r24 ; 0x8000e2 <__DATA_REGION_ORIGIN__+0x82> + + //TODO + //USB_ClockDisable(); + + UDINT &= ~((1< + 796: 8e 7e andi r24, 0xEE ; 238 + 798: 80 93 e1 00 sts 0x00E1, r24 ; 0x8000e1 <__DATA_REGION_ORIGIN__+0x81> + _usbSuspendState = (_usbSuspendState & ~(1< + 7a0: 8e 7e andi r24, 0xEE ; 238 + 7a2: 81 60 ori r24, 0x01 ; 1 + 7a4: e5 cf rjmp .-54 ; 0x770 <__vector_10+0xa8> + +000007a6 <__vector_11>: + return true; +} + +// Endpoint 0 interrupt +ISR(USB_COM_vect) +{ + 7a6: 1f 92 push r1 + 7a8: 0f 92 push r0 + 7aa: 0f b6 in r0, 0x3f ; 63 + 7ac: 0f 92 push r0 + 7ae: 11 24 eor r1, r1 + 7b0: cf 92 push r12 + 7b2: df 92 push r13 + 7b4: ef 92 push r14 + 7b6: ff 92 push r15 + 7b8: 0f 93 push r16 + 7ba: 1f 93 push r17 + 7bc: 2f 93 push r18 + 7be: 3f 93 push r19 + 7c0: 4f 93 push r20 + 7c2: 5f 93 push r21 + 7c4: 6f 93 push r22 + 7c6: 7f 93 push r23 + 7c8: 8f 93 push r24 + 7ca: 9f 93 push r25 + 7cc: af 93 push r26 + 7ce: bf 93 push r27 + 7d0: ef 93 push r30 + 7d2: ff 93 push r31 + 7d4: cf 93 push r28 + 7d6: df 93 push r29 + 7d8: cd b7 in r28, 0x3d ; 61 + 7da: de b7 in r29, 0x3e ; 62 + 7dc: 6c 97 sbiw r28, 0x1c ; 28 + 7de: de bf out 0x3e, r29 ; 62 + 7e0: cd bf out 0x3d, r28 ; 61 + UEDATX = d; +} + +static inline void SetEP(u8 ep) +{ + UENUM = ep; + 7e2: 10 92 e9 00 sts 0x00E9, r1 ; 0x8000e9 <__DATA_REGION_ORIGIN__+0x89> + return UEBCLX; +} + +static inline u8 ReceivedSetupInt() +{ + return UEINTX & (1< + +// Endpoint 0 interrupt +ISR(USB_COM_vect) +{ + SetEP(0); + if (!ReceivedSetupInt()) + 7ea: 83 ff sbrs r24, 3 + 7ec: 25 c0 rjmp .+74 ; 0x838 <__vector_11+0x92> + return; + + USBSetup setup; + Recv((u8*)&setup,8); + 7ee: 68 e0 ldi r22, 0x08 ; 8 + 7f0: ce 01 movw r24, r28 + 7f2: 45 96 adiw r24, 0x15 ; 21 + 7f4: 0e 94 99 02 call 0x532 ; 0x532 <_ZL4RecvPVhh> + return UEINTX & (1< + + USBSetup setup; + Recv((u8*)&setup,8); + ClearSetupInt(); + + u8 requestType = setup.bmRequestType; + 7fe: 8d 89 ldd r24, Y+21 ; 0x15 + if (requestType & REQUEST_DEVICETOHOST) + 800: 87 ff sbrs r24, 7 + 802: 39 c0 rjmp .+114 ; 0x876 <__vector_11+0xd0> +volatile u8 _usbCurrentStatus = 0; // meaning of bits see usb_20.pdf, Figure 9-4. Information Returned by a GetStatus() Request to a Device +volatile u8 _usbSuspendState = 0; // copy of UDINT to check SUSPI and WAKEUPI bits + +static inline void WaitIN(void) +{ + while (!(UEINTX & (1< + 808: 90 ff sbrs r25, 0 + 80a: fc cf rjmp .-8 ; 0x804 <__vector_11+0x5e> + WaitIN(); + else + ClearIN(); + + bool ok = true; + if (REQUEST_STANDARD == (requestType & REQUEST_TYPE)) + 80c: 98 2f mov r25, r24 + 80e: 90 76 andi r25, 0x60 ; 96 + 810: 09 f0 breq .+2 ; 0x814 <__vector_11+0x6e> + 812: 34 c1 rjmp .+616 ; 0xa7c <__vector_11+0x2d6> + { + // Standard Requests + u8 r = setup.bRequest; + 814: 9e 89 ldd r25, Y+22 ; 0x16 + 816: 4f 89 ldd r20, Y+23 ; 0x17 + 818: 58 8d ldd r21, Y+24 ; 0x18 + u16 wValue = setup.wValueL | (setup.wValueH << 8); + 81a: 2f 89 ldd r18, Y+23 ; 0x17 + 81c: f8 8c ldd r15, Y+24 ; 0x18 + if (GET_STATUS == r) + 81e: 91 11 cpse r25, r1 + 820: 31 c0 rjmp .+98 ; 0x884 <__vector_11+0xde> + { + if (requestType == (REQUEST_DEVICETOHOST | REQUEST_STANDARD | REQUEST_DEVICE)) + 822: 80 38 cpi r24, 0x80 ; 128 + 824: 61 f5 brne .+88 ; 0x87e <__vector_11+0xd8> + { + Send8(_usbCurrentStatus); + 826: 80 91 34 01 lds r24, 0x0134 ; 0x800134 <_usbCurrentStatus> + return UEDATX; +} + +static inline void Send8(u8 d) +{ + UEDATX = d; + 82a: 80 93 f1 00 sts 0x00F1, r24 ; 0x8000f1 <__DATA_REGION_ORIGIN__+0x91> + 82e: 10 92 f1 00 sts 0x00F1, r1 ; 0x8000f1 <__DATA_REGION_ORIGIN__+0x91> + ; +} + +static inline void ClearIN(void) +{ + UEINTX = ~(1< + ClearIN(); + else + { + Stall(); + } +} + 838: 6c 96 adiw r28, 0x1c ; 28 + 83a: 0f b6 in r0, 0x3f ; 63 + 83c: f8 94 cli + 83e: de bf out 0x3e, r29 ; 62 + 840: 0f be out 0x3f, r0 ; 63 + 842: cd bf out 0x3d, r28 ; 61 + 844: df 91 pop r29 + 846: cf 91 pop r28 + 848: ff 91 pop r31 + 84a: ef 91 pop r30 + 84c: bf 91 pop r27 + 84e: af 91 pop r26 + 850: 9f 91 pop r25 + 852: 8f 91 pop r24 + 854: 7f 91 pop r23 + 856: 6f 91 pop r22 + 858: 5f 91 pop r21 + 85a: 4f 91 pop r20 + 85c: 3f 91 pop r19 + 85e: 2f 91 pop r18 + 860: 1f 91 pop r17 + 862: 0f 91 pop r16 + 864: ff 90 pop r15 + 866: ef 90 pop r14 + 868: df 90 pop r13 + 86a: cf 90 pop r12 + 86c: 0f 90 pop r0 + 86e: 0f be out 0x3f, r0 ; 63 + 870: 0f 90 pop r0 + 872: 1f 90 pop r1 + 874: 18 95 reti + ; +} + +static inline void ClearIN(void) +{ + UEINTX = ~(1< + 87c: c7 cf rjmp .-114 ; 0x80c <__vector_11+0x66> + return UEDATX; +} + +static inline void Send8(u8 d) +{ + UEDATX = d; + 87e: 10 92 f1 00 sts 0x00F1, r1 ; 0x8000f1 <__DATA_REGION_ORIGIN__+0x91> + 882: d5 cf rjmp .-86 ; 0x82e <__vector_11+0x88> + // see "Figure 9-6. Information Returned by a GetStatus() Request to an Endpoint" in usb_20.pdf for more information + Send8(0); + Send8(0); + } + } + else if (CLEAR_FEATURE == r) + 884: 91 30 cpi r25, 0x01 ; 1 + 886: 59 f4 brne .+22 ; 0x89e <__vector_11+0xf8> + { + if((requestType == (REQUEST_HOSTTODEVICE | REQUEST_STANDARD | REQUEST_DEVICE)) + 888: 81 11 cpse r24, r1 + 88a: d3 cf rjmp .-90 ; 0x832 <__vector_11+0x8c> + && (wValue == DEVICE_REMOTE_WAKEUP)) + 88c: 41 30 cpi r20, 0x01 ; 1 + 88e: 51 05 cpc r21, r1 + 890: 81 f6 brne .-96 ; 0x832 <__vector_11+0x8c> + { + _usbCurrentStatus &= ~FEATURE_REMOTE_WAKEUP_ENABLED; + 892: 80 91 34 01 lds r24, 0x0134 ; 0x800134 <_usbCurrentStatus> + 896: 8d 7f andi r24, 0xFD ; 253 + else if (SET_FEATURE == r) + { + if((requestType == (REQUEST_HOSTTODEVICE | REQUEST_STANDARD | REQUEST_DEVICE)) + && (wValue == DEVICE_REMOTE_WAKEUP)) + { + _usbCurrentStatus |= FEATURE_REMOTE_WAKEUP_ENABLED; + 898: 80 93 34 01 sts 0x0134, r24 ; 0x800134 <_usbCurrentStatus> + 89c: ca cf rjmp .-108 ; 0x832 <__vector_11+0x8c> + && (wValue == DEVICE_REMOTE_WAKEUP)) + { + _usbCurrentStatus &= ~FEATURE_REMOTE_WAKEUP_ENABLED; + } + } + else if (SET_FEATURE == r) + 89e: 93 30 cpi r25, 0x03 ; 3 + 8a0: 49 f4 brne .+18 ; 0x8b4 <__vector_11+0x10e> + { + if((requestType == (REQUEST_HOSTTODEVICE | REQUEST_STANDARD | REQUEST_DEVICE)) + 8a2: 81 11 cpse r24, r1 + 8a4: c6 cf rjmp .-116 ; 0x832 <__vector_11+0x8c> + && (wValue == DEVICE_REMOTE_WAKEUP)) + 8a6: 41 30 cpi r20, 0x01 ; 1 + 8a8: 51 05 cpc r21, r1 + 8aa: 19 f6 brne .-122 ; 0x832 <__vector_11+0x8c> + { + _usbCurrentStatus |= FEATURE_REMOTE_WAKEUP_ENABLED; + 8ac: 80 91 34 01 lds r24, 0x0134 ; 0x800134 <_usbCurrentStatus> + 8b0: 82 60 ori r24, 0x02 ; 2 + 8b2: f2 cf rjmp .-28 ; 0x898 <__vector_11+0xf2> + } + } + else if (SET_ADDRESS == r) + 8b4: 95 30 cpi r25, 0x05 ; 5 + 8b6: 41 f4 brne .+16 ; 0x8c8 <__vector_11+0x122> +volatile u8 _usbCurrentStatus = 0; // meaning of bits see usb_20.pdf, Figure 9-4. Information Returned by a GetStatus() Request to a Device +volatile u8 _usbSuspendState = 0; // copy of UDINT to check SUSPI and WAKEUPI bits + +static inline void WaitIN(void) +{ + while (!(UEINTX & (1< + 8bc: 80 ff sbrs r24, 0 + 8be: fc cf rjmp .-8 ; 0x8b8 <__vector_11+0x112> + } + } + else if (SET_ADDRESS == r) + { + WaitIN(); + UDADDR = setup.wValueL | (1< + 8c6: b5 cf rjmp .-150 ; 0x832 <__vector_11+0x8c> + } + else if (GET_DESCRIPTOR == r) + 8c8: 96 30 cpi r25, 0x06 ; 6 + 8ca: 09 f0 breq .+2 ; 0x8ce <__vector_11+0x128> + 8cc: a9 c0 rjmp .+338 ; 0xa20 <__vector_11+0x27a> + 8ce: 0b 8d ldd r16, Y+27 ; 0x1b + 8d0: 1c 8d ldd r17, Y+28 ; 0x1c + +static +bool SendDescriptor(USBSetup& setup) +{ + u8 t = setup.wValueH; + if (USB_CONFIGURATION_DESCRIPTOR_TYPE == t) + 8d2: 22 e0 ldi r18, 0x02 ; 2 + UEDATX = d; +} + +static inline void SetEP(u8 ep) +{ + UENUM = ep; + 8d4: 10 92 e9 00 sts 0x00E9, r1 ; 0x8000e9 <__DATA_REGION_ORIGIN__+0x89> +static int _cmark; +static int _cend; +void InitControl(int end) +{ + SetEP(0); + _cmark = 0; + 8d8: 10 92 32 01 sts 0x0132, r1 ; 0x800132 <_ZL6_cmark+0x1> + 8dc: 10 92 31 01 sts 0x0131, r1 ; 0x800131 <_ZL6_cmark> + +static +bool SendDescriptor(USBSetup& setup) +{ + u8 t = setup.wValueH; + if (USB_CONFIGURATION_DESCRIPTOR_TYPE == t) + 8e0: f2 12 cpse r15, r18 + 8e2: 2e c0 rjmp .+92 ; 0x940 <__vector_11+0x19a> +static int _cend; +void InitControl(int end) +{ + SetEP(0); + _cmark = 0; + _cend = end; + 8e4: 10 92 30 01 sts 0x0130, r1 ; 0x800130 <_ZL5_cend+0x1> + 8e8: 10 92 2f 01 sts 0x012F, r1 ; 0x80012f <_ZL5_cend> +static +bool SendConfiguration(int maxlen) +{ + // Count and measure interfaces + InitControl(0); + u8 interfaces = SendInterfaces(); + 8ec: 0e 94 68 02 call 0x4d0 ; 0x4d0 <_ZL14SendInterfacesv> + ConfigDescriptor config = D_CONFIG(_cmark + sizeof(ConfigDescriptor),interfaces); + 8f0: 1f 82 std Y+7, r1 ; 0x07 + 8f2: 99 e0 ldi r25, 0x09 ; 9 + 8f4: 99 83 std Y+1, r25 ; 0x01 + 8f6: fa 82 std Y+2, r15 ; 0x02 + 8f8: 91 e0 ldi r25, 0x01 ; 1 + 8fa: 9e 83 std Y+6, r25 ; 0x06 + 8fc: 90 ea ldi r25, 0xA0 ; 160 + 8fe: 98 87 std Y+8, r25 ; 0x08 + 900: 9a ef ldi r25, 0xFA ; 250 + 902: 99 87 std Y+9, r25 ; 0x09 + 904: 20 91 31 01 lds r18, 0x0131 ; 0x800131 <_ZL6_cmark> + 908: 30 91 32 01 lds r19, 0x0132 ; 0x800132 <_ZL6_cmark+0x1> + 90c: 27 5f subi r18, 0xF7 ; 247 + 90e: 3f 4f sbci r19, 0xFF ; 255 + 910: 3c 83 std Y+4, r19 ; 0x04 + 912: 2b 83 std Y+3, r18 ; 0x03 + 914: 8d 83 std Y+5, r24 ; 0x05 + UEDATX = d; +} + +static inline void SetEP(u8 ep) +{ + UENUM = ep; + 916: 10 92 e9 00 sts 0x00E9, r1 ; 0x8000e9 <__DATA_REGION_ORIGIN__+0x89> +static int _cmark; +static int _cend; +void InitControl(int end) +{ + SetEP(0); + _cmark = 0; + 91a: 10 92 32 01 sts 0x0132, r1 ; 0x800132 <_ZL6_cmark+0x1> + 91e: 10 92 31 01 sts 0x0131, r1 ; 0x800131 <_ZL6_cmark> + _cend = end; + 922: 10 93 30 01 sts 0x0130, r17 ; 0x800130 <_ZL5_cend+0x1> + 926: 00 93 2f 01 sts 0x012F, r16 ; 0x80012f <_ZL5_cend> + u8 interfaces = SendInterfaces(); + ConfigDescriptor config = D_CONFIG(_cmark + sizeof(ConfigDescriptor),interfaces); + + // Now send them + InitControl(maxlen); + USB_SendControl(0,&config,sizeof(ConfigDescriptor)); + 92a: 49 e0 ldi r20, 0x09 ; 9 + 92c: 50 e0 ldi r21, 0x00 ; 0 + 92e: be 01 movw r22, r28 + 930: 6f 5f subi r22, 0xFF ; 255 + 932: 7f 4f sbci r23, 0xFF ; 255 + 934: 80 e0 ldi r24, 0x00 ; 0 + 936: 0e 94 42 02 call 0x484 ; 0x484 <_Z15USB_SendControlhPKvi> + SendInterfaces(); + 93a: 0e 94 68 02 call 0x4d0 ; 0x4d0 <_ZL14SendInterfacesv> + 93e: 79 cf rjmp .-270 ; 0x832 <__vector_11+0x8c> +static int _cend; +void InitControl(int end) +{ + SetEP(0); + _cmark = 0; + _cend = end; + 940: 10 93 30 01 sts 0x0130, r17 ; 0x800130 <_ZL5_cend+0x1> + 944: 00 93 2f 01 sts 0x012F, r16 ; 0x80012f <_ZL5_cend> + if (USB_CONFIGURATION_DESCRIPTOR_TYPE == t) + return SendConfiguration(setup.wLength); + + InitControl(setup.wLength); +#ifdef PLUGGABLE_USB_ENABLED + int ret = PluggableUSB().getDescriptor(setup); + 948: 0e 94 4c 01 call 0x298 ; 0x298 <_Z12PluggableUSBv> +} + +int PluggableUSB_::getDescriptor(USBSetup& setup) +{ + PluggableUSBModule* node; + for (node = rootNode; node; node = node->next) { + 94c: dc 01 movw r26, r24 + 94e: 12 96 adiw r26, 0x02 ; 2 + 950: 0d 91 ld r16, X+ + 952: 1c 91 ld r17, X + 954: 01 15 cp r16, r1 + 956: 11 05 cpc r17, r1 + 958: 09 f4 brne .+2 ; 0x95c <__vector_11+0x1b6> + 95a: 51 c1 rjmp .+674 ; 0xbfe <__stack+0xff> + int ret = node->getDescriptor(setup); + 95c: d8 01 movw r26, r16 + 95e: ed 91 ld r30, X+ + 960: fc 91 ld r31, X + 962: 04 80 ldd r0, Z+4 ; 0x04 + 964: f5 81 ldd r31, Z+5 ; 0x05 + 966: e0 2d mov r30, r0 + 968: be 01 movw r22, r28 + 96a: 6b 5e subi r22, 0xEB ; 235 + 96c: 7f 4f sbci r23, 0xFF ; 255 + 96e: c8 01 movw r24, r16 + 970: 09 95 icall + // ret!=0 -> request has been processed + if (ret) + 972: 00 97 sbiw r24, 0x00 ; 0 + 974: 09 f0 breq .+2 ; 0x978 <__vector_11+0x1d2> + 976: 3e c1 rjmp .+636 ; 0xbf4 <__stack+0xf5> +} + +int PluggableUSB_::getDescriptor(USBSetup& setup) +{ + PluggableUSBModule* node; + for (node = rootNode; node; node = node->next) { + 978: f8 01 movw r30, r16 + 97a: 00 85 ldd r16, Z+8 ; 0x08 + 97c: 11 85 ldd r17, Z+9 ; 0x09 + 97e: ea cf rjmp .-44 ; 0x954 <__vector_11+0x1ae> + const u8* desc_addr = 0; + if (USB_DEVICE_DESCRIPTOR_TYPE == t) + { + desc_addr = (const u8*)&USB_DeviceDescriptorIAD; + } + else if (USB_STRING_DESCRIPTOR_TYPE == t) + 980: f3 e0 ldi r31, 0x03 ; 3 + 982: ff 12 cpse r15, r31 + 984: 0e c0 rjmp .+28 ; 0x9a2 <__vector_11+0x1fc> + { + if (setup.wValueL == 0) { + 986: 8f 89 ldd r24, Y+23 ; 0x17 + 988: 88 23 and r24, r24 + 98a: 09 f4 brne .+2 ; 0x98e <__vector_11+0x1e8> + 98c: 40 c0 rjmp .+128 ; 0xa0e <__vector_11+0x268> + desc_addr = (const u8*)&STRING_LANGUAGE; + } + else if (setup.wValueL == IPRODUCT) { + 98e: 82 30 cpi r24, 0x02 ; 2 + 990: 61 f4 brne .+24 ; 0x9aa <__vector_11+0x204> + return USB_SendStringDescriptor(STRING_PRODUCT, strlen(USB_PRODUCT), TRANSFER_PGM); + 992: 40 e8 ldi r20, 0x80 ; 128 + 994: 60 e1 ldi r22, 0x10 ; 16 + 996: 80 e1 ldi r24, 0x10 ; 16 + 998: 91 e0 ldi r25, 0x01 ; 1 + } + else if (setup.wValueL == ISERIAL) { +#ifdef PLUGGABLE_USB_ENABLED + char name[ISERIAL_MAX_LEN]; + PluggableUSB().getShortName(name); + return USB_SendStringDescriptor((uint8_t*)name, strlen(name), 0); + 99a: 0e 94 0f 02 call 0x41e ; 0x41e <_ZL24USB_SendStringDescriptorPKhhh> + { + InitControl(setup.wLength); // Max length of transfer + ok = ClassInterfaceRequest(setup); + } + + if (ok) + 99e: 81 11 cpse r24, r1 + 9a0: 48 cf rjmp .-368 ; 0x832 <__vector_11+0x8c> + UEINTX = ~((1< + 9a8: 47 cf rjmp .-370 ; 0x838 <__vector_11+0x92> + desc_addr = (const u8*)&STRING_LANGUAGE; + } + else if (setup.wValueL == IPRODUCT) { + return USB_SendStringDescriptor(STRING_PRODUCT, strlen(USB_PRODUCT), TRANSFER_PGM); + } + else if (setup.wValueL == IMANUFACTURER) { + 9aa: 81 30 cpi r24, 0x01 ; 1 + 9ac: 29 f4 brne .+10 ; 0x9b8 <__vector_11+0x212> + return USB_SendStringDescriptor(STRING_MANUFACTURER, strlen(USB_MANUFACTURER), TRANSFER_PGM); + 9ae: 40 e8 ldi r20, 0x80 ; 128 + 9b0: 6b e0 ldi r22, 0x0B ; 11 + 9b2: 84 e0 ldi r24, 0x04 ; 4 + 9b4: 91 e0 ldi r25, 0x01 ; 1 + 9b6: f1 cf rjmp .-30 ; 0x99a <__vector_11+0x1f4> + } + else if (setup.wValueL == ISERIAL) { + 9b8: 83 30 cpi r24, 0x03 ; 3 + 9ba: 99 f7 brne .-26 ; 0x9a2 <__vector_11+0x1fc> +#ifdef PLUGGABLE_USB_ENABLED + char name[ISERIAL_MAX_LEN]; + PluggableUSB().getShortName(name); + 9bc: 0e 94 4c 01 call 0x298 ; 0x298 <_Z12PluggableUSBv> +} + +void PluggableUSB_::getShortName(char *iSerialNum) +{ + PluggableUSBModule* node; + for (node = rootNode; node; node = node->next) { + 9c0: dc 01 movw r26, r24 + 9c2: 12 96 adiw r26, 0x02 ; 2 + 9c4: ed 90 ld r14, X+ + 9c6: fc 90 ld r15, X + 9c8: 8e 01 movw r16, r28 + 9ca: 0f 5f subi r16, 0xFF ; 255 + 9cc: 1f 4f sbci r17, 0xFF ; 255 + 9ce: 68 01 movw r12, r16 + 9d0: e1 14 cp r14, r1 + 9d2: f1 04 cpc r15, r1 + 9d4: 79 f0 breq .+30 ; 0x9f4 <__vector_11+0x24e> + iSerialNum += node->getShortName(iSerialNum); + 9d6: d7 01 movw r26, r14 + 9d8: ed 91 ld r30, X+ + 9da: fc 91 ld r31, X + 9dc: 06 80 ldd r0, Z+6 ; 0x06 + 9de: f7 81 ldd r31, Z+7 ; 0x07 + 9e0: e0 2d mov r30, r0 + 9e2: b8 01 movw r22, r16 + 9e4: c7 01 movw r24, r14 + 9e6: 09 95 icall + 9e8: 08 0f add r16, r24 + 9ea: 11 1d adc r17, r1 +} + +void PluggableUSB_::getShortName(char *iSerialNum) +{ + PluggableUSBModule* node; + for (node = rootNode; node; node = node->next) { + 9ec: f7 01 movw r30, r14 + 9ee: e0 84 ldd r14, Z+8 ; 0x08 + 9f0: f1 84 ldd r15, Z+9 ; 0x09 + 9f2: ee cf rjmp .-36 ; 0x9d0 <__vector_11+0x22a> + iSerialNum += node->getShortName(iSerialNum); + } + *iSerialNum = 0; + 9f4: d8 01 movw r26, r16 + 9f6: 1c 92 st X, r1 + return USB_SendStringDescriptor((uint8_t*)name, strlen(name), 0); + 9f8: f6 01 movw r30, r12 + 9fa: 01 90 ld r0, Z+ + 9fc: 00 20 and r0, r0 + 9fe: e9 f7 brne .-6 ; 0x9fa <__vector_11+0x254> + a00: 31 97 sbiw r30, 0x01 ; 1 + a02: bf 01 movw r22, r30 + a04: 6c 19 sub r22, r12 + a06: 7d 09 sbc r23, r13 + a08: 40 e0 ldi r20, 0x00 ; 0 + a0a: c6 01 movw r24, r12 + a0c: c6 cf rjmp .-116 ; 0x99a <__vector_11+0x1f4> + desc_addr = (const u8*)&USB_DeviceDescriptorIAD; + } + else if (USB_STRING_DESCRIPTOR_TYPE == t) + { + if (setup.wValueL == 0) { + desc_addr = (const u8*)&STRING_LANGUAGE; + a0e: 6e ee ldi r22, 0xEE ; 238 + a10: 70 e0 ldi r23, 0x00 ; 0 + return false; + } + + if (desc_addr == 0) + return false; + u8 desc_length = pgm_read_byte(desc_addr); + a12: fb 01 movw r30, r22 + a14: 44 91 lpm r20, Z + + USB_SendControl(TRANSFER_PGM,desc_addr,desc_length); + a16: 50 e0 ldi r21, 0x00 ; 0 + a18: 80 e8 ldi r24, 0x80 ; 128 + + if (REQUEST_DEVICETOHOST_CLASS_INTERFACE == requestType) + { + if (CDC_GET_LINE_CODING == r) + { + USB_SendControl(0,(void*)&_usbLineInfo,7); + a1a: 0e 94 42 02 call 0x484 ; 0x484 <_Z15USB_SendControlhPKvi> + a1e: 09 cf rjmp .-494 ; 0x832 <__vector_11+0x8c> + } + else if (GET_DESCRIPTOR == r) + { + ok = SendDescriptor(setup); + } + else if (SET_DESCRIPTOR == r) + a20: 97 30 cpi r25, 0x07 ; 7 + a22: 09 f4 brne .+2 ; 0xa26 <__vector_11+0x280> + a24: be cf rjmp .-132 ; 0x9a2 <__vector_11+0x1fc> + { + ok = false; + } + else if (GET_CONFIGURATION == r) + a26: 98 30 cpi r25, 0x08 ; 8 + a28: 21 f4 brne .+8 ; 0xa32 <__vector_11+0x28c> + return UEDATX; +} + +static inline void Send8(u8 d) +{ + UEDATX = d; + a2a: 81 e0 ldi r24, 0x01 ; 1 + a2c: 80 93 f1 00 sts 0x00F1, r24 ; 0x8000f1 <__DATA_REGION_ORIGIN__+0x91> + a30: 00 cf rjmp .-512 ; 0x832 <__vector_11+0x8c> + } + else if (GET_CONFIGURATION == r) + { + Send8(1); + } + else if (SET_CONFIGURATION == r) + a32: 99 30 cpi r25, 0x09 ; 9 + a34: 09 f0 breq .+2 ; 0xa38 <__vector_11+0x292> + a36: fd ce rjmp .-518 ; 0x832 <__vector_11+0x8c> + { + if (REQUEST_DEVICE == (requestType & REQUEST_RECIPIENT)) + a38: 83 70 andi r24, 0x03 ; 3 + a3a: 09 f0 breq .+2 ; 0xa3e <__vector_11+0x298> + a3c: b2 cf rjmp .-156 ; 0x9a2 <__vector_11+0x1fc> + a3e: ed e0 ldi r30, 0x0D ; 13 + a40: f1 e0 ldi r31, 0x01 ; 1 +} + +static +void InitEndpoints() +{ + for (u8 i = 1; i < sizeof(_initEndpoints) && _initEndpoints[i] != 0; i++) + a42: 81 e0 ldi r24, 0x01 ; 1 + { + UENUM = i; + UECONX = (1< + { + UENUM = i; + a4e: 80 93 e9 00 sts 0x00E9, r24 ; 0x8000e9 <__DATA_REGION_ORIGIN__+0x89> + UECONX = (1< + UECFG0X = _initEndpoints[i]; + a56: df 01 movw r26, r30 + a58: 11 97 sbiw r26, 0x01 ; 1 + a5a: 2c 91 ld r18, X + a5c: 20 93 ec 00 sts 0x00EC, r18 ; 0x8000ec <__DATA_REGION_ORIGIN__+0x8c> +#if USB_EP_SIZE == 16 + UECFG1X = EP_SINGLE_16; +#elif USB_EP_SIZE == 64 + UECFG1X = EP_DOUBLE_64; + a60: 90 93 ed 00 sts 0x00ED, r25 ; 0x8000ed <__DATA_REGION_ORIGIN__+0x8d> +} + +static +void InitEndpoints() +{ + for (u8 i = 1; i < sizeof(_initEndpoints) && _initEndpoints[i] != 0; i++) + a64: 8f 5f subi r24, 0xFF ; 255 + a66: 87 30 cpi r24, 0x07 ; 7 + a68: 79 f7 brne .-34 ; 0xa48 <__vector_11+0x2a2> + UECFG1X = EP_DOUBLE_64; +#else +#error Unsupported value for USB_EP_SIZE +#endif + } + UERST = 0x7E; // And reset them + a6a: 8e e7 ldi r24, 0x7E ; 126 + a6c: 80 93 ea 00 sts 0x00EA, r24 ; 0x8000ea <__DATA_REGION_ORIGIN__+0x8a> + UERST = 0; + a70: 10 92 ea 00 sts 0x00EA, r1 ; 0x8000ea <__DATA_REGION_ORIGIN__+0x8a> + else if (SET_CONFIGURATION == r) + { + if (REQUEST_DEVICE == (requestType & REQUEST_RECIPIENT)) + { + InitEndpoints(); + _usbConfiguration = setup.wValueL; + a74: 8f 89 ldd r24, Y+23 ; 0x17 + a76: 80 93 94 01 sts 0x0194, r24 ; 0x800194 <_usbConfiguration> + a7a: db ce rjmp .-586 ; 0x832 <__vector_11+0x8c> + { + } + } + else + { + InitControl(setup.wLength); // Max length of transfer + a7c: 8b 8d ldd r24, Y+27 ; 0x1b + a7e: 9c 8d ldd r25, Y+28 ; 0x1c + UEDATX = d; +} + +static inline void SetEP(u8 ep) +{ + UENUM = ep; + a80: 10 92 e9 00 sts 0x00E9, r1 ; 0x8000e9 <__DATA_REGION_ORIGIN__+0x89> +static int _cmark; +static int _cend; +void InitControl(int end) +{ + SetEP(0); + _cmark = 0; + a84: 10 92 32 01 sts 0x0132, r1 ; 0x800132 <_ZL6_cmark+0x1> + a88: 10 92 31 01 sts 0x0131, r1 ; 0x800131 <_ZL6_cmark> + _cend = end; + a8c: 90 93 30 01 sts 0x0130, r25 ; 0x800130 <_ZL5_cend+0x1> + a90: 80 93 2f 01 sts 0x012F, r24 ; 0x80012f <_ZL5_cend> +bool ClassInterfaceRequest(USBSetup& setup) +{ +#ifdef CDC_ENABLED + u8 i = setup.wIndex; + + if (CDC_ACM_INTERFACE == i) + a94: 89 8d ldd r24, Y+25 ; 0x19 + a96: 81 11 cpse r24, r1 + a98: 92 c0 rjmp .+292 ; 0xbbe <__stack+0xbf> + return USB_SendControl(TRANSFER_PGM,&_cdcInterface,sizeof(_cdcInterface)); +} + +bool CDC_Setup(USBSetup& setup) +{ + u8 r = setup.bRequest; + a9a: 8e 89 ldd r24, Y+22 ; 0x16 + u8 requestType = setup.bmRequestType; + a9c: 9d 89 ldd r25, Y+21 ; 0x15 + + if (REQUEST_DEVICETOHOST_CLASS_INTERFACE == requestType) + a9e: 91 3a cpi r25, 0xA1 ; 161 + aa0: 49 f4 brne .+18 ; 0xab4 <__vector_11+0x30e> + { + if (CDC_GET_LINE_CODING == r) + aa2: 81 32 cpi r24, 0x21 ; 33 + aa4: 09 f0 breq .+2 ; 0xaa8 <__vector_11+0x302> + aa6: 7d cf rjmp .-262 ; 0x9a2 <__vector_11+0x1fc> + { + USB_SendControl(0,(void*)&_usbLineInfo,7); + aa8: 47 e0 ldi r20, 0x07 ; 7 + aaa: 50 e0 ldi r21, 0x00 ; 0 + aac: 64 e0 ldi r22, 0x04 ; 4 + aae: 71 e0 ldi r23, 0x01 ; 1 + ab0: 80 e0 ldi r24, 0x00 ; 0 + ab2: b3 cf rjmp .-154 ; 0xa1a <__vector_11+0x274> + return true; + } + } + + if (REQUEST_HOSTTODEVICE_CLASS_INTERFACE == requestType) + ab4: 91 32 cpi r25, 0x21 ; 33 + ab6: 09 f0 breq .+2 ; 0xaba <__vector_11+0x314> + ab8: 74 cf rjmp .-280 ; 0x9a2 <__vector_11+0x1fc> + { + if (CDC_SEND_BREAK == r) + aba: 83 32 cpi r24, 0x23 ; 35 + abc: 69 f4 brne .+26 ; 0xad8 <__vector_11+0x332> + { + breakValue = ((uint16_t)setup.wValueH << 8) | setup.wValueL; + abe: 8f 89 ldd r24, Y+23 ; 0x17 + ac0: 98 8d ldd r25, Y+24 ; 0x18 + ac2: b0 e0 ldi r27, 0x00 ; 0 + ac4: a0 e0 ldi r26, 0x00 ; 0 + ac6: 80 93 00 01 sts 0x0100, r24 ; 0x800100 <__data_start> + aca: 90 93 01 01 sts 0x0101, r25 ; 0x800101 <__data_start+0x1> + ace: a0 93 02 01 sts 0x0102, r26 ; 0x800102 <__data_start+0x2> + ad2: b0 93 03 01 sts 0x0103, r27 ; 0x800103 <__data_start+0x3> + ad6: ad ce rjmp .-678 ; 0x832 <__vector_11+0x8c> + } + + if (CDC_SET_LINE_CODING == r) + ad8: 80 32 cpi r24, 0x20 ; 32 + ada: 69 f4 brne .+26 ; 0xaf6 <__vector_11+0x350> + UEINTX = ~(1< + ae0: 82 ff sbrs r24, 2 + ae2: fc cf rjmp .-8 ; 0xadc <__vector_11+0x336> + recvLength = 64; + } + + // Write data to fit to the end (not the beginning) of the array + WaitOUT(); + Recv((u8*)d + len - length, recvLength); + ae4: 67 e0 ldi r22, 0x07 ; 7 + ae6: 84 e0 ldi r24, 0x04 ; 4 + ae8: 91 e0 ldi r25, 0x01 ; 1 + aea: 0e 94 99 02 call 0x532 ; 0x532 <_ZL4RecvPVhh> + return (UEINTX & (1< + af4: 9e ce rjmp .-708 ; 0x832 <__vector_11+0x8c> + { + USB_RecvControl((void*)&_usbLineInfo,7); + } + + if (CDC_SET_CONTROL_LINE_STATE == r) + af6: 82 32 cpi r24, 0x22 ; 34 + af8: 09 f0 breq .+2 ; 0xafc <__vector_11+0x356> + afa: 9b ce rjmp .-714 ; 0x832 <__vector_11+0x8c> + { + _usbLineInfo.lineState = setup.wValueL; + afc: 8f 89 ldd r24, Y+23 ; 0x17 + afe: 80 93 0b 01 sts 0x010B, r24 ; 0x80010b <_ZL12_usbLineInfo+0x7> + D_ENDPOINT(USB_ENDPOINT_IN (CDC_ENDPOINT_IN ),USB_ENDPOINT_TYPE_BULK,USB_EP_SIZE,0) +}; + +bool isLUFAbootloader() +{ + return pgm_read_word(FLASHEND - 1) == NEW_LUFA_SIGNATURE; + b02: ee ef ldi r30, 0xFE ; 254 + b04: ff e7 ldi r31, 0x7F ; 127 + b06: 85 91 lpm r24, Z+ + b08: 94 91 lpm r25, Z +// This is used to keep compatible with the old leonardo bootloaders. +// You are still able to set the magic key position manually to RAMEND-1 to save a few bytes for this check. +#if MAGIC_KEY_POS != (RAMEND-1) + // For future boards save the key in the inproblematic RAMEND + // Which is reserved for the main() return value (which will never return) + if (isLUFAbootloader()) { + b0a: 8b 3f cpi r24, 0xFB ; 251 + b0c: 9c 4d sbci r25, 0xDC ; 220 + b0e: 51 f1 breq .+84 ; 0xb64 <__stack+0x65> + // auto-reset into the bootloader is triggered when the port, already + // open at 1200 bps, is closed. this is the signal to start the watchdog + // with a relatively long period so it can finish housekeeping tasks + // like servicing endpoints before the sketch ends + + uint16_t magic_key_pos = MAGIC_KEY_POS; + b10: e0 e0 ldi r30, 0x00 ; 0 + b12: f8 e0 ldi r31, 0x08 ; 8 + magic_key_pos = (RAMEND-1); + } +#endif + + // We check DTR state to determine if host port is open (bit 0 of lineState). + if (1200 == _usbLineInfo.dwDTERate && (_usbLineInfo.lineState & 0x01) == 0) + b14: 80 91 04 01 lds r24, 0x0104 ; 0x800104 <_ZL12_usbLineInfo> + b18: 90 91 05 01 lds r25, 0x0105 ; 0x800105 <_ZL12_usbLineInfo+0x1> + b1c: a0 91 06 01 lds r26, 0x0106 ; 0x800106 <_ZL12_usbLineInfo+0x2> + b20: b0 91 07 01 lds r27, 0x0107 ; 0x800107 <_ZL12_usbLineInfo+0x3> + b24: 80 3b cpi r24, 0xB0 ; 176 + b26: 94 40 sbci r25, 0x04 ; 4 + b28: a1 05 cpc r26, r1 + b2a: b1 05 cpc r27, r1 + b2c: f1 f4 brne .+60 ; 0xb6a <__stack+0x6b> + b2e: 80 91 0b 01 lds r24, 0x010B ; 0x80010b <_ZL12_usbLineInfo+0x7> + b32: 80 fd sbrc r24, 0 + b34: 1a c0 rjmp .+52 ; 0xb6a <__stack+0x6b> + { +#if MAGIC_KEY_POS != (RAMEND-1) + // Backup ram value if its not a newer bootloader and it hasn't already been saved. + // This should avoid memory corruption at least a bit, not fully + if (magic_key_pos != (RAMEND-1) && *(uint16_t *)magic_key_pos != MAGIC_KEY) { + b36: ee 3f cpi r30, 0xFE ; 254 + b38: 8a e0 ldi r24, 0x0A ; 10 + b3a: f8 07 cpc r31, r24 + b3c: 89 f5 brne .+98 ; 0xba0 <__stack+0xa1> + *(uint16_t *)(RAMEND-1) = *(uint16_t *)magic_key_pos; + } +#endif + // Store boot key + *(uint16_t *)magic_key_pos = MAGIC_KEY; + b3e: 87 e7 ldi r24, 0x77 ; 119 + b40: 97 e7 ldi r25, 0x77 ; 119 + b42: 91 83 std Z+1, r25 ; 0x01 + b44: 80 83 st Z, r24 + // Save the watchdog state in case the reset is aborted. + wdtcsr_save = WDTCSR; + b46: 80 91 60 00 lds r24, 0x0060 ; 0x800060 <__DATA_REGION_ORIGIN__> + b4a: 80 93 33 01 sts 0x0133, r24 ; 0x800133 <_ZL11wdtcsr_save> + : "n" (_SFR_MEM_ADDR(_WD_CONTROL_REG)), + "r" ((uint8_t)(_BV(_WD_CHANGE_BIT) | _BV(WDE))), + "r" ((uint8_t) ((value & 0x08 ? _WD_PS3_MASK : 0x00) | + _BV(WDE) | (value & 0x07)) ) + : "r0" + ); + b4e: 88 e1 ldi r24, 0x18 ; 24 + b50: 9b e0 ldi r25, 0x0B ; 11 + b52: 0f b6 in r0, 0x3f ; 63 + b54: f8 94 cli + b56: a8 95 wdr + b58: 80 93 60 00 sts 0x0060, r24 ; 0x800060 <__DATA_REGION_ORIGIN__> + b5c: 0f be out 0x3f, r0 ; 63 + b5e: 90 93 60 00 sts 0x0060, r25 ; 0x800060 <__DATA_REGION_ORIGIN__> + b62: 67 ce rjmp .-818 ; 0x832 <__vector_11+0x8c> +#if MAGIC_KEY_POS != (RAMEND-1) + // For future boards save the key in the inproblematic RAMEND + // Which is reserved for the main() return value (which will never return) + if (isLUFAbootloader()) { + // horray, we got a new bootloader! + magic_key_pos = (RAMEND-1); + b64: ee ef ldi r30, 0xFE ; 254 + b66: fa e0 ldi r31, 0x0A ; 10 + b68: d5 cf rjmp .-86 ; 0xb14 <__stack+0x15> + *(uint16_t *)magic_key_pos = MAGIC_KEY; + // Save the watchdog state in case the reset is aborted. + wdtcsr_save = WDTCSR; + wdt_enable(WDTO_120MS); + } + else if (*(uint16_t *)magic_key_pos == MAGIC_KEY) + b6a: 80 81 ld r24, Z + b6c: 91 81 ldd r25, Z+1 ; 0x01 + b6e: 87 37 cpi r24, 0x77 ; 119 + b70: 97 47 sbci r25, 0x77 ; 119 + b72: 09 f0 breq .+2 ; 0xb76 <__stack+0x77> + b74: 5e ce rjmp .-836 ; 0x832 <__vector_11+0x8c> + // To avoid spurious resets we set the watchdog to 120ms and eventually + // cancel if DTR goes back high. + // Cancellation is only done if an auto-reset was started, which is + // indicated by the magic key having been set. + + wdt_reset(); + b76: a8 95 wdr + // Restore the watchdog state in case the sketch was using it. + WDTCSR |= (1< + b7c: 88 61 ori r24, 0x18 ; 24 + b7e: 80 93 60 00 sts 0x0060, r24 ; 0x800060 <__DATA_REGION_ORIGIN__> + WDTCSR = wdtcsr_save; + b82: 80 91 33 01 lds r24, 0x0133 ; 0x800133 <_ZL11wdtcsr_save> + b86: 80 93 60 00 sts 0x0060, r24 ; 0x800060 <__DATA_REGION_ORIGIN__> +#if MAGIC_KEY_POS != (RAMEND-1) + // Restore backed up (old bootloader) magic key data + if (magic_key_pos != (RAMEND-1)) { + b8a: ee 3f cpi r30, 0xFE ; 254 + b8c: 2a e0 ldi r18, 0x0A ; 10 + b8e: f2 07 cpc r31, r18 + b90: 89 f0 breq .+34 ; 0xbb4 <__stack+0xb5> + *(uint16_t *)magic_key_pos = *(uint16_t *)(RAMEND-1); + b92: 80 91 fe 0a lds r24, 0x0AFE ; 0x800afe <__bss_end+0x969> + b96: 90 91 ff 0a lds r25, 0x0AFF ; 0x800aff <__bss_end+0x96a> + b9a: 91 83 std Z+1, r25 ; 0x01 + b9c: 80 83 st Z, r24 + b9e: 49 ce rjmp .-878 ; 0x832 <__vector_11+0x8c> + if (1200 == _usbLineInfo.dwDTERate && (_usbLineInfo.lineState & 0x01) == 0) + { +#if MAGIC_KEY_POS != (RAMEND-1) + // Backup ram value if its not a newer bootloader and it hasn't already been saved. + // This should avoid memory corruption at least a bit, not fully + if (magic_key_pos != (RAMEND-1) && *(uint16_t *)magic_key_pos != MAGIC_KEY) { + ba0: 80 81 ld r24, Z + ba2: 91 81 ldd r25, Z+1 ; 0x01 + ba4: 87 37 cpi r24, 0x77 ; 119 + ba6: 98 07 cpc r25, r24 + ba8: 51 f2 breq .-108 ; 0xb3e <__stack+0x3f> + *(uint16_t *)(RAMEND-1) = *(uint16_t *)magic_key_pos; + baa: 90 93 ff 0a sts 0x0AFF, r25 ; 0x800aff <__bss_end+0x96a> + bae: 80 93 fe 0a sts 0x0AFE, r24 ; 0x800afe <__bss_end+0x969> + bb2: c5 cf rjmp .-118 ; 0xb3e <__stack+0x3f> + *(uint16_t *)magic_key_pos = *(uint16_t *)(RAMEND-1); + } else +#endif + { + // Clean up RAMEND key + *(uint16_t *)magic_key_pos = 0x0000; + bb4: 10 92 ff 0a sts 0x0AFF, r1 ; 0x800aff <__bss_end+0x96a> + bb8: 10 92 fe 0a sts 0x0AFE, r1 ; 0x800afe <__bss_end+0x969> + bbc: 3a ce rjmp .-908 ; 0x832 <__vector_11+0x8c> + if (CDC_ACM_INTERFACE == i) + return CDC_Setup(setup); +#endif + +#ifdef PLUGGABLE_USB_ENABLED + return PluggableUSB().setup(setup); + bbe: 0e 94 4c 01 call 0x298 ; 0x298 <_Z12PluggableUSBv> +} + +bool PluggableUSB_::setup(USBSetup& setup) +{ + PluggableUSBModule* node; + for (node = rootNode; node; node = node->next) { + bc2: dc 01 movw r26, r24 + bc4: 12 96 adiw r26, 0x02 ; 2 + bc6: 0d 91 ld r16, X+ + bc8: 1c 91 ld r17, X + bca: 01 15 cp r16, r1 + bcc: 11 05 cpc r17, r1 + bce: 09 f4 brne .+2 ; 0xbd2 <__stack+0xd3> + bd0: e8 ce rjmp .-560 ; 0x9a2 <__vector_11+0x1fc> + if (node->setup(setup)) { + bd2: d8 01 movw r26, r16 + bd4: ed 91 ld r30, X+ + bd6: fc 91 ld r31, X + bd8: 01 90 ld r0, Z+ + bda: f0 81 ld r31, Z + bdc: e0 2d mov r30, r0 + bde: be 01 movw r22, r28 + be0: 6b 5e subi r22, 0xEB ; 235 + be2: 7f 4f sbci r23, 0xFF ; 255 + be4: c8 01 movw r24, r16 + be6: 09 95 icall + be8: 81 11 cpse r24, r1 + bea: 23 ce rjmp .-954 ; 0x832 <__vector_11+0x8c> +} + +bool PluggableUSB_::setup(USBSetup& setup) +{ + PluggableUSBModule* node; + for (node = rootNode; node; node = node->next) { + bec: f8 01 movw r30, r16 + bee: 00 85 ldd r16, Z+8 ; 0x08 + bf0: 11 85 ldd r17, Z+9 ; 0x09 + bf2: eb cf rjmp .-42 ; 0xbca <__stack+0xcb> + + InitControl(setup.wLength); +#ifdef PLUGGABLE_USB_ENABLED + int ret = PluggableUSB().getDescriptor(setup); + if (ret != 0) { + return (ret > 0 ? true : false); + bf4: 18 16 cp r1, r24 + bf6: 19 06 cpc r1, r25 + bf8: 0c f4 brge .+2 ; 0xbfc <__stack+0xfd> + bfa: 1b ce rjmp .-970 ; 0x832 <__vector_11+0x8c> + bfc: d2 ce rjmp .-604 ; 0x9a2 <__vector_11+0x1fc> + } +#endif + + const u8* desc_addr = 0; + if (USB_DEVICE_DESCRIPTOR_TYPE == t) + bfe: f1 e0 ldi r31, 0x01 ; 1 + c00: ff 12 cpse r15, r31 + c02: be ce rjmp .-644 ; 0x980 <__vector_11+0x1da> + { + desc_addr = (const u8*)&USB_DeviceDescriptorIAD; + c04: 62 ef ldi r22, 0xF2 ; 242 + c06: 70 e0 ldi r23, 0x00 ; 0 + c08: 04 cf rjmp .-504 ; 0xa12 <__vector_11+0x26c> + +00000c0a <__vector_23>: +#if defined(TIM0_OVF_vect) +ISR(TIM0_OVF_vect) +#else +ISR(TIMER0_OVF_vect) +#endif +{ + c0a: 1f 92 push r1 + c0c: 0f 92 push r0 + c0e: 0f b6 in r0, 0x3f ; 63 + c10: 0f 92 push r0 + c12: 11 24 eor r1, r1 + c14: 2f 93 push r18 + c16: 3f 93 push r19 + c18: 8f 93 push r24 + c1a: 9f 93 push r25 + c1c: af 93 push r26 + c1e: bf 93 push r27 + // copy these to local variables so they can be stored in registers + // (volatile variables must be read from memory on every access) + unsigned long m = timer0_millis; + c20: 80 91 27 01 lds r24, 0x0127 ; 0x800127 + c24: 90 91 28 01 lds r25, 0x0128 ; 0x800128 + c28: a0 91 29 01 lds r26, 0x0129 ; 0x800129 + c2c: b0 91 2a 01 lds r27, 0x012A ; 0x80012a + unsigned char f = timer0_fract; + c30: 30 91 26 01 lds r19, 0x0126 ; 0x800126 <__data_end> + + m += MILLIS_INC; + f += FRACT_INC; + c34: 23 e0 ldi r18, 0x03 ; 3 + c36: 23 0f add r18, r19 + if (f >= FRACT_MAX) { + c38: 2d 37 cpi r18, 0x7D ; 125 + c3a: 58 f5 brcc .+86 ; 0xc92 <__vector_23+0x88> + // copy these to local variables so they can be stored in registers + // (volatile variables must be read from memory on every access) + unsigned long m = timer0_millis; + unsigned char f = timer0_fract; + + m += MILLIS_INC; + c3c: 01 96 adiw r24, 0x01 ; 1 + c3e: a1 1d adc r26, r1 + c40: b1 1d adc r27, r1 + if (f >= FRACT_MAX) { + f -= FRACT_MAX; + m += 1; + } + + timer0_fract = f; + c42: 20 93 26 01 sts 0x0126, r18 ; 0x800126 <__data_end> + timer0_millis = m; + c46: 80 93 27 01 sts 0x0127, r24 ; 0x800127 + c4a: 90 93 28 01 sts 0x0128, r25 ; 0x800128 + c4e: a0 93 29 01 sts 0x0129, r26 ; 0x800129 + c52: b0 93 2a 01 sts 0x012A, r27 ; 0x80012a + timer0_overflow_count++; + c56: 80 91 2b 01 lds r24, 0x012B ; 0x80012b + c5a: 90 91 2c 01 lds r25, 0x012C ; 0x80012c + c5e: a0 91 2d 01 lds r26, 0x012D ; 0x80012d + c62: b0 91 2e 01 lds r27, 0x012E ; 0x80012e + c66: 01 96 adiw r24, 0x01 ; 1 + c68: a1 1d adc r26, r1 + c6a: b1 1d adc r27, r1 + c6c: 80 93 2b 01 sts 0x012B, r24 ; 0x80012b + c70: 90 93 2c 01 sts 0x012C, r25 ; 0x80012c + c74: a0 93 2d 01 sts 0x012D, r26 ; 0x80012d + c78: b0 93 2e 01 sts 0x012E, r27 ; 0x80012e +} + c7c: bf 91 pop r27 + c7e: af 91 pop r26 + c80: 9f 91 pop r25 + c82: 8f 91 pop r24 + c84: 3f 91 pop r19 + c86: 2f 91 pop r18 + c88: 0f 90 pop r0 + c8a: 0f be out 0x3f, r0 ; 63 + c8c: 0f 90 pop r0 + c8e: 1f 90 pop r1 + c90: 18 95 reti + unsigned char f = timer0_fract; + + m += MILLIS_INC; + f += FRACT_INC; + if (f >= FRACT_MAX) { + f -= FRACT_MAX; + c92: 26 e8 ldi r18, 0x86 ; 134 + c94: 23 0f add r18, r19 + m += 1; + c96: 02 96 adiw r24, 0x02 ; 2 + c98: a1 1d adc r26, r1 + c9a: b1 1d adc r27, r1 + c9c: d2 cf rjmp .-92 ; 0xc42 <__vector_23+0x38> + +00000c9e : + " rjmp INT3_vect_part_2 \n" // go to part 2 for required prologue and epilogue + :: [pin] "I" (_SFR_IO_ADDR(PORTB)), [gpio] "I" (_SFR_IO_ADDR(GPIOR1))); + //:: [pin] "I" (_SFR_IO_ADDR(PORTB)), [gpio] "M" (_SFR_MEM_ADDR(GPIOR1))); +} + +ISR(INT3_vect_part_2) { GPIOR2 = &GPIOR1; } + c9e: 1f 92 push r1 + ca0: 0f 92 push r0 + ca2: 0f b6 in r0, 0x3f ; 63 + ca4: 0f 92 push r0 + ca6: 11 24 eor r1, r1 + ca8: 8f 93 push r24 + caa: 8a e4 ldi r24, 0x4A ; 74 + cac: 8b bd out 0x2b, r24 ; 43 + cae: 8f 91 pop r24 + cb0: 0f 90 pop r0 + cb2: 0f be out 0x3f, r0 ; 63 + cb4: 0f 90 pop r0 + cb6: 1f 90 pop r1 + cb8: 18 95 reti + +00000cba <__vector_4>: +// " lds r0, %[gpio] \n" // GPIOR1 address is 42 + " in r0, %[gpio] \n" + " out %[pin], r0 \n" + " pop r0 \n" + " rjmp INT3_vect_part_2 \n" // go to part 2 for required prologue and epilogue + :: [pin] "I" (_SFR_IO_ADDR(PORTB)), [gpio] "I" (_SFR_IO_ADDR(GPIOR1))); + cba: 0f 92 push r0 + cbc: 0a b4 in r0, 0x2a ; 42 + cbe: 05 b8 out 0x05, r0 ; 5 + cc0: 0f 90 pop r0 + cc2: ed cf rjmp .-38 ; 0xc9e + +00000cc4 : + " pop r0 \n" + " rjmp INT2_vect_part_2 \n" // go to part 2 for required prologue and epilogue + :: [pin] "I" (_SFR_IO_ADDR(PORTB)), [gpio] "I" (_SFR_IO_ADDR(GPIOR0))); +} + +ISR(INT2_vect_part_2) { GPIOR2 = &GPIOR0; } + cc4: 1f 92 push r1 + cc6: 0f 92 push r0 + cc8: 0f b6 in r0, 0x3f ; 63 + cca: 0f 92 push r0 + ccc: 11 24 eor r1, r1 + cce: 8f 93 push r24 + cd0: 8e e3 ldi r24, 0x3E ; 62 + cd2: 8b bd out 0x2b, r24 ; 43 + cd4: 8f 91 pop r24 + cd6: 0f 90 pop r0 + cd8: 0f be out 0x3f, r0 ; 63 + cda: 0f 90 pop r0 + cdc: 1f 90 pop r1 + cde: 18 95 reti + +00000ce0 <__vector_3>: + " push r0 \n" + " in r0, %[gpio] \n" + " out %[pin], r0 \n" + " pop r0 \n" + " rjmp INT2_vect_part_2 \n" // go to part 2 for required prologue and epilogue + :: [pin] "I" (_SFR_IO_ADDR(PORTB)), [gpio] "I" (_SFR_IO_ADDR(GPIOR0))); + ce0: 0f 92 push r0 + ce2: 0e b2 in r0, 0x1e ; 30 + ce4: 05 b8 out 0x05, r0 ; 5 + ce6: 0f 90 pop r0 + ce8: ed cf rjmp .-38 ; 0xcc4 + +00000cea <_GLOBAL__sub_I__cdcInterface>: + public: + Print() : write_error(0) {} + cea: e7 e3 ldi r30, 0x37 ; 55 + cec: f1 e0 ldi r31, 0x01 ; 1 + cee: 13 82 std Z+3, r1 ; 0x03 + cf0: 12 82 std Z+2, r1 ; 0x02 + public: + virtual int available() = 0; + virtual int read() = 0; + virtual int peek() = 0; + + Stream() {_timeout=1000;} + cf2: 88 ee ldi r24, 0xE8 ; 232 + cf4: 93 e0 ldi r25, 0x03 ; 3 + cf6: a0 e0 ldi r26, 0x00 ; 0 + cf8: b0 e0 ldi r27, 0x00 ; 0 + cfa: 84 83 std Z+4, r24 ; 0x04 + cfc: 95 83 std Z+5, r25 ; 0x05 + cfe: a6 83 std Z+6, r26 ; 0x06 + d00: b7 83 std Z+7, r27 ; 0x07 +class Serial_ : public Stream +{ +private: + int peek_buffer; +public: + Serial_() { peek_buffer = -1; }; + d02: 87 e1 ldi r24, 0x17 ; 23 + d04: 91 e0 ldi r25, 0x01 ; 1 + d06: 91 83 std Z+1, r25 ; 0x01 + d08: 80 83 st Z, r24 + d0a: 8f ef ldi r24, 0xFF ; 255 + d0c: 9f ef ldi r25, 0xFF ; 255 + d0e: 95 87 std Z+13, r25 ; 0x0d + d10: 84 87 std Z+12, r24 ; 0x0c + breakValue = -1; + } + return ret; +} + +Serial_ Serial; + d12: 08 95 ret + +00000d14
: + +void init() +{ + // this needs to be called before setup() or some functions won't + // work there + sei(); + d14: 78 94 sei + + // on the ATmega168, timer 0 is also used for fast hardware pwm + // (using phase-correct PWM would mean that timer 0 overflowed half as often + // resulting in different millis() behavior on the ATmega8 and ATmega168) +#if defined(TCCR0A) && defined(WGM01) + sbi(TCCR0A, WGM01); + d16: 84 b5 in r24, 0x24 ; 36 + d18: 82 60 ori r24, 0x02 ; 2 + d1a: 84 bd out 0x24, r24 ; 36 + sbi(TCCR0A, WGM00); + d1c: 84 b5 in r24, 0x24 ; 36 + d1e: 81 60 ori r24, 0x01 ; 1 + d20: 84 bd out 0x24, r24 ; 36 + // this combination is for the standard atmega8 + sbi(TCCR0, CS01); + sbi(TCCR0, CS00); +#elif defined(TCCR0B) && defined(CS01) && defined(CS00) + // this combination is for the standard 168/328/1280/2560 + sbi(TCCR0B, CS01); + d22: 85 b5 in r24, 0x25 ; 37 + d24: 82 60 ori r24, 0x02 ; 2 + d26: 85 bd out 0x25, r24 ; 37 + sbi(TCCR0B, CS00); + d28: 85 b5 in r24, 0x25 ; 37 + d2a: 81 60 ori r24, 0x01 ; 1 + d2c: 85 bd out 0x25, r24 ; 37 + + // enable timer 0 overflow interrupt +#if defined(TIMSK) && defined(TOIE0) + sbi(TIMSK, TOIE0); +#elif defined(TIMSK0) && defined(TOIE0) + sbi(TIMSK0, TOIE0); + d2e: 80 91 6e 00 lds r24, 0x006E ; 0x80006e <__DATA_REGION_ORIGIN__+0xe> + d32: 81 60 ori r24, 0x01 ; 1 + d34: 80 93 6e 00 sts 0x006E, r24 ; 0x80006e <__DATA_REGION_ORIGIN__+0xe> + // this is better for motors as it ensures an even waveform + // note, however, that fast pwm mode can achieve a frequency of up + // 8 MHz (with a 16 MHz clock) at 50% duty cycle + +#if defined(TCCR1B) && defined(CS11) && defined(CS10) + TCCR1B = 0; + d38: 10 92 81 00 sts 0x0081, r1 ; 0x800081 <__DATA_REGION_ORIGIN__+0x21> + + // set timer 1 prescale factor to 64 + sbi(TCCR1B, CS11); + d3c: 80 91 81 00 lds r24, 0x0081 ; 0x800081 <__DATA_REGION_ORIGIN__+0x21> + d40: 82 60 ori r24, 0x02 ; 2 + d42: 80 93 81 00 sts 0x0081, r24 ; 0x800081 <__DATA_REGION_ORIGIN__+0x21> +#if F_CPU >= 8000000L + sbi(TCCR1B, CS10); + d46: 80 91 81 00 lds r24, 0x0081 ; 0x800081 <__DATA_REGION_ORIGIN__+0x21> + d4a: 81 60 ori r24, 0x01 ; 1 + d4c: 80 93 81 00 sts 0x0081, r24 ; 0x800081 <__DATA_REGION_ORIGIN__+0x21> + sbi(TCCR1, CS10); +#endif +#endif + // put timer 1 in 8-bit phase correct pwm mode +#if defined(TCCR1A) && defined(WGM10) + sbi(TCCR1A, WGM10); + d50: 80 91 80 00 lds r24, 0x0080 ; 0x800080 <__DATA_REGION_ORIGIN__+0x20> + d54: 81 60 ori r24, 0x01 ; 1 + d56: 80 93 80 00 sts 0x0080, r24 ; 0x800080 <__DATA_REGION_ORIGIN__+0x20> +//#else + // Timer 2 not finished (may not be present on this CPU) +#endif + +#if defined(TCCR3B) && defined(CS31) && defined(WGM30) + sbi(TCCR3B, CS31); // set timer 3 prescale factor to 64 + d5a: 80 91 91 00 lds r24, 0x0091 ; 0x800091 <__DATA_REGION_ORIGIN__+0x31> + d5e: 82 60 ori r24, 0x02 ; 2 + d60: 80 93 91 00 sts 0x0091, r24 ; 0x800091 <__DATA_REGION_ORIGIN__+0x31> + sbi(TCCR3B, CS30); + d64: 80 91 91 00 lds r24, 0x0091 ; 0x800091 <__DATA_REGION_ORIGIN__+0x31> + d68: 81 60 ori r24, 0x01 ; 1 + d6a: 80 93 91 00 sts 0x0091, r24 ; 0x800091 <__DATA_REGION_ORIGIN__+0x31> + sbi(TCCR3A, WGM30); // put timer 3 in 8-bit phase correct pwm mode + d6e: 80 91 90 00 lds r24, 0x0090 ; 0x800090 <__DATA_REGION_ORIGIN__+0x30> + d72: 81 60 ori r24, 0x01 ; 1 + d74: 80 93 90 00 sts 0x0090, r24 ; 0x800090 <__DATA_REGION_ORIGIN__+0x30> +#endif + +#if defined(TCCR4A) && defined(TCCR4B) && defined(TCCR4D) /* beginning of timer4 block for 32U4 and similar */ + sbi(TCCR4B, CS42); // set timer4 prescale factor to 64 + d78: 80 91 c1 00 lds r24, 0x00C1 ; 0x8000c1 <__DATA_REGION_ORIGIN__+0x61> + d7c: 84 60 ori r24, 0x04 ; 4 + d7e: 80 93 c1 00 sts 0x00C1, r24 ; 0x8000c1 <__DATA_REGION_ORIGIN__+0x61> + sbi(TCCR4B, CS41); + d82: 80 91 c1 00 lds r24, 0x00C1 ; 0x8000c1 <__DATA_REGION_ORIGIN__+0x61> + d86: 82 60 ori r24, 0x02 ; 2 + d88: 80 93 c1 00 sts 0x00C1, r24 ; 0x8000c1 <__DATA_REGION_ORIGIN__+0x61> + sbi(TCCR4B, CS40); + d8c: 80 91 c1 00 lds r24, 0x00C1 ; 0x8000c1 <__DATA_REGION_ORIGIN__+0x61> + d90: 81 60 ori r24, 0x01 ; 1 + d92: 80 93 c1 00 sts 0x00C1, r24 ; 0x8000c1 <__DATA_REGION_ORIGIN__+0x61> + sbi(TCCR4D, WGM40); // put timer 4 in phase- and frequency-correct PWM mode + d96: 80 91 c3 00 lds r24, 0x00C3 ; 0x8000c3 <__DATA_REGION_ORIGIN__+0x63> + d9a: 81 60 ori r24, 0x01 ; 1 + d9c: 80 93 c3 00 sts 0x00C3, r24 ; 0x8000c3 <__DATA_REGION_ORIGIN__+0x63> + sbi(TCCR4A, PWM4A); // enable PWM mode for comparator OCR4A + da0: 80 91 c0 00 lds r24, 0x00C0 ; 0x8000c0 <__DATA_REGION_ORIGIN__+0x60> + da4: 82 60 ori r24, 0x02 ; 2 + da6: 80 93 c0 00 sts 0x00C0, r24 ; 0x8000c0 <__DATA_REGION_ORIGIN__+0x60> + sbi(TCCR4C, PWM4D); // enable PWM mode for comparator OCR4D + daa: 80 91 c2 00 lds r24, 0x00C2 ; 0x8000c2 <__DATA_REGION_ORIGIN__+0x62> + dae: 81 60 ori r24, 0x01 ; 1 + db0: 80 93 c2 00 sts 0x00C2, r24 ; 0x8000c2 <__DATA_REGION_ORIGIN__+0x62> +#endif + +#if defined(ADCSRA) + // set a2d prescaler so we are inside the desired 50-200 KHz range. + #if F_CPU >= 16000000 // 16 MHz / 128 = 125 KHz + sbi(ADCSRA, ADPS2); + db4: 80 91 7a 00 lds r24, 0x007A ; 0x80007a <__DATA_REGION_ORIGIN__+0x1a> + db8: 84 60 ori r24, 0x04 ; 4 + dba: 80 93 7a 00 sts 0x007A, r24 ; 0x80007a <__DATA_REGION_ORIGIN__+0x1a> + sbi(ADCSRA, ADPS1); + dbe: 80 91 7a 00 lds r24, 0x007A ; 0x80007a <__DATA_REGION_ORIGIN__+0x1a> + dc2: 82 60 ori r24, 0x02 ; 2 + dc4: 80 93 7a 00 sts 0x007A, r24 ; 0x80007a <__DATA_REGION_ORIGIN__+0x1a> + sbi(ADCSRA, ADPS0); + dc8: 80 91 7a 00 lds r24, 0x007A ; 0x80007a <__DATA_REGION_ORIGIN__+0x1a> + dcc: 81 60 ori r24, 0x01 ; 1 + dce: 80 93 7a 00 sts 0x007A, r24 ; 0x80007a <__DATA_REGION_ORIGIN__+0x1a> + cbi(ADCSRA, ADPS2); + cbi(ADCSRA, ADPS1); + sbi(ADCSRA, ADPS0); + #endif + // enable a2d conversions + sbi(ADCSRA, ADEN); + dd2: 80 91 7a 00 lds r24, 0x007A ; 0x80007a <__DATA_REGION_ORIGIN__+0x1a> + dd6: 80 68 ori r24, 0x80 ; 128 + dd8: 80 93 7a 00 sts 0x007A, r24 ; 0x80007a <__DATA_REGION_ORIGIN__+0x1a> +{ +} + +void USBDevice_::attach() +{ + _usbConfiguration = 0; + ddc: 10 92 94 01 sts 0x0194, r1 ; 0x800194 <_usbConfiguration> + _usbCurrentStatus = 0; + de0: 10 92 34 01 sts 0x0134, r1 ; 0x800134 <_usbCurrentStatus> + _usbSuspendState = 0; + de4: 10 92 36 01 sts 0x0136, r1 ; 0x800136 <_usbSuspendState> +} + +static inline void USB_ClockEnable() +{ +#if defined(UHWCON) + UHWCON |= (1< + dec: 81 60 ori r24, 0x01 ; 1 + dee: 80 93 d7 00 sts 0x00D7, r24 ; 0x8000d7 <__DATA_REGION_ORIGIN__+0x77> +#endif + USBCON = (1< + +// ATmega32U4 +#if defined(PINDIV) +#if F_CPU == 16000000UL + PLLCSR |= (1< + } + + // Some tests on specific versions of macosx (10.7.3), reported some + // strange behaviors when the board is reset using the serial + // port touch at 1200 bps. This delay fixes this behavior. + delay(1); + e0a: 0e 94 cb 02 call 0x596 ; 0x596 +#if defined(OTGPADE) + USBCON = (USBCON & ~(1< + e12: 8f 7c andi r24, 0xCF ; 207 + e14: 80 61 ori r24, 0x10 ; 16 + e16: 80 93 d8 00 sts 0x00D8, r24 ; 0x8000d8 <__DATA_REGION_ORIGIN__+0x78> + USBCON &= ~(1 << FRZCLK); // start USB clock +#endif + +#if defined(RSTCPU) +#if defined(LSM) + UDCON &= ~((1< + e1e: 80 7f andi r24, 0xF0 ; 240 + e20: 80 93 e0 00 sts 0x00E0, r24 ; 0x8000e0 <__DATA_REGION_ORIGIN__+0x80> + _usbConfiguration = 0; + _usbCurrentStatus = 0; + _usbSuspendState = 0; + USB_ClockEnable(); + + UDINT &= ~((1< + e28: 8e 7e andi r24, 0xEE ; 238 + e2a: 80 93 e1 00 sts 0x00E1, r24 ; 0x8000e1 <__DATA_REGION_ORIGIN__+0x81> + UDIEN = (1< + + TX_RX_LED_INIT; + e34: 55 9a sbi 0x0a, 5 ; 10 + e36: 20 9a sbi 0x04, 0 ; 4 +} + +ISR(INT3_vect_part_2) { GPIOR2 = &GPIOR1; } + +void setup() { + DDRB = 0xff; PORTB = 0xff; //all PB-ports are outputs and high (0xff = zero state, because signals are inverted) + e38: 8f ef ldi r24, 0xFF ; 255 + e3a: 84 b9 out 0x04, r24 ; 4 + e3c: 85 b9 out 0x05, r24 ; 5 + DDRF = 0; PORTF = 0xff; // all PF-ports are inputs with pullups + e3e: 10 ba out 0x10, r1 ; 16 + e40: 81 bb out 0x11, r24 ; 17 + DDRD = B00100000; PORTD = B11110011; // all PD-ports are inputs (except PD5) with pullups (PD2,PD3 without pullup) + e42: 80 e2 ldi r24, 0x20 ; 32 + e44: 8a b9 out 0x0a, r24 ; 10 + e46: 83 ef ldi r24, 0xF3 ; 243 + e48: 8b b9 out 0x0b, r24 ; 11 + pinMode(5, INPUT_PULLUP); // pin5 (PC6) is input + e4a: 85 e0 ldi r24, 0x05 ; 5 + e4c: 0e 94 e9 00 call 0x1d2 ; 0x1d2 + pinMode(7, INPUT_PULLUP); // pin7 (PE6) is input + e50: 87 e0 ldi r24, 0x07 ; 7 + e52: 0e 94 e9 00 call 0x1d2 ; 0x1d2 + + if (selectC) GPIOR2 = &GPIOR0; else GPIOR2 = &GPIOR1; + e56: 4a 9b sbis 0x09, 2 ; 9 + e58: 4a c0 rjmp .+148 ; 0xeee + e5a: 8e e3 ldi r24, 0x3E ; 62 + e5c: 8b bd out 0x2b, r24 ; 43 + GPIOR0 = 0xff; GPIOR1 = 0xff; // start from zero state (signals are inverted) + e5e: 8f ef ldi r24, 0xFF ; 255 + e60: 8e bb out 0x1e, r24 ; 30 + e62: 8a bd out 0x2a, r24 ; 42 + + TIMSK0 = 0; // disable timer0 interrupts (Arduino Uno/Pro Micro millis()/micros() update ISR) + e64: 10 92 6e 00 sts 0x006E, r1 ; 0x80006e <__DATA_REGION_ORIGIN__+0xe> + + EICRA = B10110000; // INT2 ÔÇô rising edge on RXD (Bxx11xxxx), INT3 - falling edge on TXD (B10xxxxxx) + e68: 80 eb ldi r24, 0xB0 ; 176 + e6a: 80 93 69 00 sts 0x0069, r24 ; 0x800069 <__DATA_REGION_ORIGIN__+0x9> + EIMSK = B1100; // enable INT2 (Bx1xx) and INT3 (B1xxx) + e6e: 8c e0 ldi r24, 0x0C ; 12 + e70: 8d bb out 0x1d, r24 ; 29 + + setup(); + + for (;;) { + loop(); + if (serialEventRun) serialEventRun(); + e72: c0 e0 ldi r28, 0x00 ; 0 + e74: d0 e0 ldi r29, 0x00 ; 0 + TCNT1 = 0; // reset Timer1 counter*/ +} + +void loop() { + uint8_t PF, PD, PC, PE; + PF = PINF; PD = PIND; PC = PINC; PE = PINE; + e76: 3f b1 in r19, 0x0f ; 15 + e78: 29 b1 in r18, 0x09 ; 9 + e7a: 86 b1 in r24, 0x06 ; 6 + e7c: 4c b1 in r20, 0x0c ; 12 + uint8_t joy1 = 0xff; uint8_t joy2 = 0xff; // all signals are inverted + if (up1) bitClear(joy1,upC); + e7e: 9d ef ldi r25, 0xFD ; 253 + e80: 27 fd sbrc r18, 7 +} + +void loop() { + uint8_t PF, PD, PC, PE; + PF = PINF; PD = PIND; PC = PINC; PE = PINE; + uint8_t joy1 = 0xff; uint8_t joy2 = 0xff; // all signals are inverted + e82: 9f ef ldi r25, 0xFF ; 255 + if (up1) bitClear(joy1,upC); + if (down1) bitClear(joy1,downC); + e84: 86 ff sbrs r24, 6 + e86: 97 7f andi r25, 0xF7 ; 247 + if (left1) bitClear(joy1,leftC); + e88: 24 ff sbrs r18, 4 + e8a: 9b 7f andi r25, 0xFB ; 251 + if (right1) bitClear(joy1,rightC); + e8c: 20 ff sbrs r18, 0 + e8e: 9f 7b andi r25, 0xBF ; 191 + if (up2) bitClear(joy2,upC); + e90: 8d ef ldi r24, 0xFD ; 253 + e92: 37 fd sbrc r19, 7 +} + +void loop() { + uint8_t PF, PD, PC, PE; + PF = PINF; PD = PIND; PC = PINC; PE = PINE; + uint8_t joy1 = 0xff; uint8_t joy2 = 0xff; // all signals are inverted + e94: 8f ef ldi r24, 0xFF ; 255 + if (up1) bitClear(joy1,upC); + if (down1) bitClear(joy1,downC); + if (left1) bitClear(joy1,leftC); + if (right1) bitClear(joy1,rightC); + if (up2) bitClear(joy2,upC); + if (down2) bitClear(joy2,downC); + e96: 36 ff sbrs r19, 6 + e98: 87 7f andi r24, 0xF7 ; 247 + if (left2) bitClear(joy2,leftC); + e9a: 35 ff sbrs r19, 5 + e9c: 8b 7f andi r24, 0xFB ; 251 + if (right2) bitClear(joy2,rightC); + e9e: 34 ff sbrs r19, 4 + ea0: 8f 7b andi r24, 0xBF ; 191 + if (fire1) { bitClear(joy1,fire1C); bitClear(joy2,fire1C); } + ea2: 21 fd sbrc r18, 1 + ea4: 02 c0 rjmp .+4 ; 0xeaa + ea6: 9f 7e andi r25, 0xEF ; 239 + ea8: 8f 7e andi r24, 0xEF ; 239 + if (fire2) { bitClear(joy1,fire2C); bitClear(joy2,fire2C); } + eaa: 46 fd sbrc r20, 6 + eac: 02 c0 rjmp .+4 ; 0xeb2 + eae: 9f 7d andi r25, 0xDF ; 223 + eb0: 8f 7d andi r24, 0xDF ; 223 + + if (GPIOR2 == &GPIOR0) { PORTD &= ~_BV(5); } else { PORTD |= _BV(5); } //TX-LED on, if joystick 3 is activated + eb2: 2b b5 in r18, 0x2b ; 43 + eb4: 2e 33 cpi r18, 0x3E ; 62 + eb6: e9 f4 brne .+58 ; 0xef2 + eb8: 5d 98 cbi 0x0b, 5 ; 11 + if (GPIOR2 == &GPIOR1) { bitClear(joy2,0); } //RX-LED on, if joystick 4 is activated + eba: 2b b5 in r18, 0x2b ; 43 + ebc: 2a 34 cpi r18, 0x4A ; 74 + ebe: 09 f4 brne .+2 ; 0xec2 + ec0: 8e 7f andi r24, 0xFE ; 254 + + GPIOR0 = joy1; GPIOR1 = joy2; + ec2: 9e bb out 0x1e, r25 ; 30 + ec4: 8a bd out 0x2a, r24 ; 42 + + //PORTB = *ptr; // is this atomic? probably, because ptr is 6-bit pointer. nope... + noInterrupts(); + ec6: f8 94 cli + PORTB = *((unsigned int *)GPIOR2); + ec8: eb b5 in r30, 0x2b ; 43 + eca: f0 e0 ldi r31, 0x00 ; 0 + ecc: 80 81 ld r24, Z + ece: 85 b9 out 0x05, r24 ; 5 + //ec8: eb b5 in r30, 0x2b ; 43 + //eca: f0 e0 ldi r31, 0x00 ; 0 + //ecc: 80 81 ld r24, Z + //ece: 85 b9 out 0x05, r24 ; 5 + interrupts(); + ed0: 78 94 sei + " cli \n" + " lds r30, %[gpio] \n" + " ld __tmp_reg__, Z \n" + " sts %[pin], __tmp_reg__ \n" + " sei \n" + :: [pin] "M" (_SFR_MEM_ADDR(PORTB)), [gpio] "M" (_SFR_MEM_ADDR(GPIOR2)) : "r30", "r31"); + ed2: ff 27 eor r31, r31 + ed4: f8 94 cli + ed6: e0 91 4b 00 lds r30, 0x004B ; 0x80004b <__TEXT_REGION_LENGTH__+0x7e004b> + eda: 00 80 ld r0, Z + edc: 00 92 25 00 sts 0x0025, r0 ; 0x800025 <__TEXT_REGION_LENGTH__+0x7e0025> + ee0: 78 94 sei + ee2: 20 97 sbiw r28, 0x00 ; 0 + ee4: 09 f4 brne .+2 ; 0xee8 + ee6: c7 cf rjmp .-114 ; 0xe76 + ee8: 0e 94 00 00 call 0 ; 0x0 <__vectors> + eec: c4 cf rjmp .-120 ; 0xe76 + DDRF = 0; PORTF = 0xff; // all PF-ports are inputs with pullups + DDRD = B00100000; PORTD = B11110011; // all PD-ports are inputs (except PD5) with pullups (PD2,PD3 without pullup) + pinMode(5, INPUT_PULLUP); // pin5 (PC6) is input + pinMode(7, INPUT_PULLUP); // pin7 (PE6) is input + + if (selectC) GPIOR2 = &GPIOR0; else GPIOR2 = &GPIOR1; + eee: 8a e4 ldi r24, 0x4A ; 74 + ef0: b5 cf rjmp .-150 ; 0xe5c + if (left2) bitClear(joy2,leftC); + if (right2) bitClear(joy2,rightC); + if (fire1) { bitClear(joy1,fire1C); bitClear(joy2,fire1C); } + if (fire2) { bitClear(joy1,fire2C); bitClear(joy2,fire2C); } + + if (GPIOR2 == &GPIOR0) { PORTD &= ~_BV(5); } else { PORTD |= _BV(5); } //TX-LED on, if joystick 3 is activated + ef2: 5d 9a sbi 0x0b, 5 ; 11 + ef4: e2 cf rjmp .-60 ; 0xeba + +00000ef6 <__tablejump2__>: + ef6: ee 0f add r30, r30 + ef8: ff 1f adc r31, r31 + efa: 05 90 lpm r0, Z+ + efc: f4 91 lpm r31, Z + efe: e0 2d mov r30, r0 + f00: 09 94 ijmp + +00000f02 <_exit>: + f02: f8 94 cli + +00000f04 <__stop_program>: + f04: ff cf rjmp .-2 ; 0xf04 <__stop_program>