Blame | Last modification | View Log | RSS feed
main.elf: file format elf32-avr
Sections:
Idx Name Size VMA LMA File off Algn
0 .text 00000976 00000000 00000000 000000b4 2**1
CONTENTS, ALLOC, LOAD, READONLY, CODE
1 .data 00000002 00800060 00000976 00000a2a 2**0
CONTENTS, ALLOC, LOAD, DATA
2 .bss 00000039 00800062 00800062 00000a2c 2**0
ALLOC
3 .fuse 00000003 00820000 00820000 00000a2c 2**0
CONTENTS, ALLOC, LOAD, DATA
4 .stab 000019c8 00000000 00000000 00000a30 2**2
CONTENTS, READONLY, DEBUGGING
5 .stabstr 00000145 00000000 00000000 000023f8 2**0
CONTENTS, READONLY, DEBUGGING
6 .debug_aranges 00000040 00000000 00000000 0000253d 2**0
CONTENTS, READONLY, DEBUGGING
7 .debug_pubnames 00000207 00000000 00000000 0000257d 2**0
CONTENTS, READONLY, DEBUGGING
8 .debug_info 000012e3 00000000 00000000 00002784 2**0
CONTENTS, READONLY, DEBUGGING
9 .debug_abbrev 00000549 00000000 00000000 00003a67 2**0
CONTENTS, READONLY, DEBUGGING
10 .debug_line 00000976 00000000 00000000 00003fb0 2**0
CONTENTS, READONLY, DEBUGGING
11 .debug_frame 00000080 00000000 00000000 00004928 2**2
CONTENTS, READONLY, DEBUGGING
12 .debug_str 0000050f 00000000 00000000 000049a8 2**0
CONTENTS, READONLY, DEBUGGING
13 .debug_loc 000008c0 00000000 00000000 00004eb7 2**0
CONTENTS, READONLY, DEBUGGING
14 .debug_pubtypes 0000013a 00000000 00000000 00005777 2**0
CONTENTS, READONLY, DEBUGGING
15 .debug_ranges 000002b0 00000000 00000000 000058b1 2**0
CONTENTS, READONLY, DEBUGGING
Disassembly of section .text:
00000000 <__vectors>:
0: 5e c0 rjmp .+188 ; 0xbe <__ctors_end>
2: 43 c3 rjmp .+1670 ; 0x68a <__vector_1>
4: 77 c0 rjmp .+238 ; 0xf4 <__bad_interrupt>
6: 76 c0 rjmp .+236 ; 0xf4 <__bad_interrupt>
8: 75 c0 rjmp .+234 ; 0xf4 <__bad_interrupt>
a: 74 c0 rjmp .+232 ; 0xf4 <__bad_interrupt>
c: 73 c0 rjmp .+230 ; 0xf4 <__bad_interrupt>
e: 72 c0 rjmp .+228 ; 0xf4 <__bad_interrupt>
10: 71 c0 rjmp .+226 ; 0xf4 <__bad_interrupt>
12: 70 c0 rjmp .+224 ; 0xf4 <__bad_interrupt>
14: 6f c0 rjmp .+222 ; 0xf4 <__bad_interrupt>
16: 6e c0 rjmp .+220 ; 0xf4 <__bad_interrupt>
18: 6d c0 rjmp .+218 ; 0xf4 <__bad_interrupt>
1a: 6c c0 rjmp .+216 ; 0xf4 <__bad_interrupt>
1c: 6b c0 rjmp .+214 ; 0xf4 <__bad_interrupt>
0000001e <usbDescriptorHidReport>:
1e: 05 01 09 05 a1 01 09 01 a1 00 09 30 09 31 15 00 ...........0.1..
2e: 25 02 75 02 95 02 81 02 c0 05 09 19 01 29 04 15 %.u..........)..
3e: 00 25 01 75 01 95 04 81 02 c0 .%.u......
00000048 <usbDescriptorString0>:
48: 04 03 09 04 ....
0000004c <usbDescriptorStringVendor>:
4c: 16 03 76 00 69 00 6b 00 69 00 74 00 73 00 2e 00 ..v.i.k.i.t.s...
5c: 63 00 6f 00 6d 00 c.o.m.
00000062 <usbDescriptorStringDevice>:
62: 28 03 55 00 53 00 42 00 20 00 4e 00 45 00 53 00 (.U.S.B. .N.E.S.
72: 20 00 50 00 61 00 64 00 20 00 61 00 64 00 61 00 .P.a.d. .a.d.a.
82: 70 00 74 00 65 00 72 00 p.t.e.r.
0000008a <usbDescriptorDevice>:
8a: 12 01 10 01 00 00 00 08 ea 1d 07 10 00 01 01 02 ................
9a: 00 01 ..
0000009c <usbDescriptorConfiguration>:
9c: 09 02 22 00 01 01 00 80 32 09 04 00 00 01 03 00 ..".....2.......
ac: 00 00 09 21 01 01 00 01 22 2a 00 07 05 81 03 08 ...!...."*......
bc: 00 0a ..
000000be <__ctors_end>:
be: 11 24 eor r1, r1
c0: 1f be out 0x3f, r1 ; 63
c2: cf e5 ldi r28, 0x5F ; 95
c4: d2 e0 ldi r29, 0x02 ; 2
c6: de bf out 0x3e, r29 ; 62
c8: cd bf out 0x3d, r28 ; 61
000000ca <__do_copy_data>:
ca: 10 e0 ldi r17, 0x00 ; 0
cc: a0 e6 ldi r26, 0x60 ; 96
ce: b0 e0 ldi r27, 0x00 ; 0
d0: e6 e7 ldi r30, 0x76 ; 118
d2: f9 e0 ldi r31, 0x09 ; 9
d4: 02 c0 rjmp .+4 ; 0xda <__do_copy_data+0x10>
d6: 05 90 lpm r0, Z+
d8: 0d 92 st X+, r0
da: a2 36 cpi r26, 0x62 ; 98
dc: b1 07 cpc r27, r17
de: d9 f7 brne .-10 ; 0xd6 <__do_copy_data+0xc>
000000e0 <__do_clear_bss>:
e0: 10 e0 ldi r17, 0x00 ; 0
e2: a2 e6 ldi r26, 0x62 ; 98
e4: b0 e0 ldi r27, 0x00 ; 0
e6: 01 c0 rjmp .+2 ; 0xea <.do_clear_bss_start>
000000e8 <.do_clear_bss_loop>:
e8: 1d 92 st X+, r1
000000ea <.do_clear_bss_start>:
ea: ab 39 cpi r26, 0x9B ; 155
ec: b1 07 cpc r27, r17
ee: e1 f7 brne .-8 ; 0xe8 <.do_clear_bss_loop>
f0: 56 d0 rcall .+172 ; 0x19e <main>
f2: 3f c4 rjmp .+2174 ; 0x972 <_exit>
000000f4 <__bad_interrupt>:
f4: 85 cf rjmp .-246 ; 0x0 <__vectors>
000000f6 <usbFunctionSetup>:
usbMsgLen_t usbFunctionSetup(uchar data[8]) {
usbRequest_t *req = (void *)data;
return 0; // Nothing implemented
}
f6: 80 e0 ldi r24, 0x00 ; 0
f8: 08 95 ret
000000fa <hadUsbReset>:
For version 5.x RC oscillators (those with a split range of 2x128 steps, e.g.
ATTiny25, ATTiny45, ATTiny85), it may be useful to search for the optimum in
both regions.
*/
void hadUsbReset(void) {
fa: af 92 push r10
fc: bf 92 push r11
fe: df 92 push r13
100: ef 92 push r14
102: ff 92 push r15
104: 0f 93 push r16
106: 1f 93 push r17
108: cf 93 push r28
10a: df 93 push r29
10c: 08 e0 ldi r16, 0x08 ; 8
10e: 10 e0 ldi r17, 0x00 ; 0
* experimental purposes only!
*/
static void calibrateOscillator(void)
{
uchar step = 128;
uchar trialValue = 0, optimumValue;
110: ee 24 eor r14, r14
* the 12 MHz clock! Use the RC oscillator calibrated to 12 MHz for
* experimental purposes only!
*/
static void calibrateOscillator(void)
{
uchar step = 128;
112: 80 e8 ldi r24, 0x80 ; 128
114: f8 2e mov r15, r24
uchar trialValue = 0, optimumValue;
int x, optimumDev, targetValue = (unsigned)(1499 * (double)F_CPU / 10.5e6 + 0.5);
/* do a binary search: */
do{
OSCCAL = trialValue + step;
116: df 2c mov r13, r15
118: de 0c add r13, r14
11a: d1 be out 0x31, r13 ; 49
x = usbMeasureFrameLength(); /* proportional to current real frequency */
11c: a3 d2 rcall .+1350 ; 0x664 <usbMeasureFrameLength>
11e: a8 2e mov r10, r24
120: e5 01 movw r28, r10
122: 5e 01 movw r10, r28
124: b9 2e mov r11, r25
126: e5 01 movw r28, r10
if(x < targetValue) /* frequency still too low */
128: 99 e0 ldi r25, 0x09 ; 9
12a: c4 33 cpi r28, 0x34 ; 52
12c: d9 07 cpc r29, r25
12e: 0c f4 brge .+2 ; 0x132 <hadUsbReset+0x38>
trialValue += step;
130: ed 2c mov r14, r13
step >>= 1;
132: f6 94 lsr r15
134: 01 50 subi r16, 0x01 ; 1
136: 10 40 sbci r17, 0x00 ; 0
}while(step > 0);
138: 71 f7 brne .-36 ; 0x116 <hadUsbReset+0x1c>
/* We have a precision of +/- 1 for optimum OSCCAL here */
/* now do a neighborhood search for optimum value */
optimumValue = trialValue;
optimumDev = x; /* this is certainly far away from optimum */
for(OSCCAL = trialValue - 1; OSCCAL <= trialValue + 1; OSCCAL++){
13a: 8e 2d mov r24, r14
13c: 81 50 subi r24, 0x01 ; 1
13e: 81 bf out 0x31, r24 ; 49
140: 81 b7 in r24, 0x31 ; 49
142: 0e 2d mov r16, r14
144: 10 e0 ldi r17, 0x00 ; 0
146: 0f 5f subi r16, 0xFF ; 255
148: 1f 4f sbci r17, 0xFF ; 255
14a: 90 e0 ldi r25, 0x00 ; 0
14c: 08 17 cp r16, r24
14e: 19 07 cpc r17, r25
150: 74 f4 brge .+28 ; 0x16e <hadUsbReset+0x74>
152: 16 c0 rjmp .+44 ; 0x180 <hadUsbReset+0x86>
x = usbMeasureFrameLength() - targetValue;
if(x < 0)
x = -x;
if(x < optimumDev){
154: 8c 17 cp r24, r28
156: 9d 07 cpc r25, r29
158: 14 f4 brge .+4 ; 0x15e <hadUsbReset+0x64>
optimumDev = x;
optimumValue = OSCCAL;
15a: e1 b6 in r14, 0x31 ; 49
15c: ec 01 movw r28, r24
}while(step > 0);
/* We have a precision of +/- 1 for optimum OSCCAL here */
/* now do a neighborhood search for optimum value */
optimumValue = trialValue;
optimumDev = x; /* this is certainly far away from optimum */
for(OSCCAL = trialValue - 1; OSCCAL <= trialValue + 1; OSCCAL++){
15e: 81 b7 in r24, 0x31 ; 49
160: 8f 5f subi r24, 0xFF ; 255
162: 81 bf out 0x31, r24 ; 49
164: 81 b7 in r24, 0x31 ; 49
166: 90 e0 ldi r25, 0x00 ; 0
168: 08 17 cp r16, r24
16a: 19 07 cpc r17, r25
16c: 4c f0 brlt .+18 ; 0x180 <hadUsbReset+0x86>
x = usbMeasureFrameLength() - targetValue;
16e: 7a d2 rcall .+1268 ; 0x664 <usbMeasureFrameLength>
170: 84 53 subi r24, 0x34 ; 52
172: 99 40 sbci r25, 0x09 ; 9
174: 97 ff sbrs r25, 7
176: ee cf rjmp .-36 ; 0x154 <hadUsbReset+0x5a>
178: 90 95 com r25
17a: 81 95 neg r24
17c: 9f 4f sbci r25, 0xFF ; 255
17e: ea cf rjmp .-44 ; 0x154 <hadUsbReset+0x5a>
if(x < optimumDev){
optimumDev = x;
optimumValue = OSCCAL;
}
}
OSCCAL = optimumValue;
180: e1 be out 0x31, r14 ; 49
both regions.
*/
void hadUsbReset(void) {
calibrateOscillator();
eeprom_write_byte(0, OSCCAL); /* store the calibrated value in EEPROM */
182: 61 b7 in r22, 0x31 ; 49
184: 80 e0 ldi r24, 0x00 ; 0
186: 90 e0 ldi r25, 0x00 ; 0
188: e6 d3 rcall .+1996 ; 0x956 <__eewr_byte_tn85>
}
18a: df 91 pop r29
18c: cf 91 pop r28
18e: 1f 91 pop r17
190: 0f 91 pop r16
192: ff 90 pop r15
194: ef 90 pop r14
196: df 90 pop r13
198: bf 90 pop r11
19a: af 90 pop r10
19c: 08 95 ret
0000019e <main>:
#define STROBE_CLK() sbi(NES_PORT, CLK); \
_delay_us(1); \
cbi(NES_PORT, CLK); \
_delay_us(1);
int main(void) {
19e: 0f 93 push r16
1a0: 1f 93 push r17
uchar calibrationValue;
while (!eeprom_is_ready());
1a2: e1 99 sbic 0x1c, 1 ; 28
1a4: fe cf rjmp .-4 ; 0x1a2 <main+0x4>
calibrationValue = eeprom_read_byte(0); /* calibration value from last time */
1a6: 80 e0 ldi r24, 0x00 ; 0
1a8: 90 e0 ldi r25, 0x00 ; 0
1aa: cd d3 rcall .+1946 ; 0x946 <__eerd_byte_tn85>
if(calibrationValue != 0xff) {
1ac: 8f 3f cpi r24, 0xFF ; 255
1ae: 09 f0 breq .+2 ; 0x1b2 <main+0x14>
OSCCAL = calibrationValue;
1b0: 81 bf out 0x31, r24 ; 49
#else
//round up by default
__ticks_dc = (uint32_t)(ceil(fabs(__tmp)));
#endif
__builtin_avr_delay_cycles(__ticks_dc);
1b2: 81 e2 ldi r24, 0x21 ; 33
1b4: 91 ea ldi r25, 0xA1 ; 161
1b6: 01 97 sbiw r24, 0x01 ; 1
1b8: f1 f7 brne .-4 ; 0x1b6 <main+0x18>
1ba: 00 c0 rjmp .+0 ; 0x1bc <main+0x1e>
1bc: 00 00 nop
}
_delay_ms(10);
ACSR |= (1<<ACD); // Disable analog comparator
1be: 47 9a sbi 0x08, 7 ; 8
usbDeviceDisconnect(); /* enforce re-enumeration, do this while interrupts are disabled! */
1c0: b8 9a sbi 0x17, 0 ; 23
1c2: 8f e4 ldi r24, 0x4F ; 79
1c4: 9d e2 ldi r25, 0x2D ; 45
1c6: a9 e1 ldi r26, 0x19 ; 25
1c8: 81 50 subi r24, 0x01 ; 1
1ca: 90 40 sbci r25, 0x00 ; 0
1cc: a0 40 sbci r26, 0x00 ; 0
1ce: e1 f7 brne .-8 ; 0x1c8 <main+0x2a>
1d0: 00 c0 rjmp .+0 ; 0x1d2 <main+0x34>
1d2: 00 00 nop
_delay_ms(500);
usbDeviceConnect();
1d4: b8 98 cbi 0x17, 0 ; 23
wdt_enable(WDTO_1S);
1d6: 2e e0 ldi r18, 0x0E ; 14
1d8: 88 e1 ldi r24, 0x18 ; 24
1da: 90 e0 ldi r25, 0x00 ; 0
1dc: 0f b6 in r0, 0x3f ; 63
1de: f8 94 cli
1e0: a8 95 wdr
1e2: 81 bd out 0x21, r24 ; 33
1e4: 0f be out 0x3f, r0 ; 63
1e6: 21 bd out 0x21, r18 ; 33
usbInit();
1e8: 17 d2 rcall .+1070 ; 0x618 <usbInit>
sei();
1ea: 78 94 sei
sbi(NES_DDR, CLK);
1ec: bb 9a sbi 0x17, 3 ; 23
cbi(NES_DDR, OUT);
1ee: b9 98 cbi 0x17, 1 ; 23
sbi(NES_DDR, LATCH);
1f0: bc 9a sbi 0x17, 4 ; 23
cbi(NES_PORT, CLK);
1f2: c3 98 cbi 0x18, 3 ; 24
cbi(NES_PORT, LATCH);
1f4: c4 98 cbi 0x18, 4 ; 24
for(;;) {
wdt_reset();
usbPoll();
if(usbInterruptIsReady()){
reportBuffer.data = 0x05; // Center pad, little endian
1f6: 15 e0 ldi r17, 0x05 ; 5
_delay_us(1); // Latch pulse width >= 500ns
cbi(NES_PORT, LATCH);
_delay_us(1); // Propagation time <= 1000ns
if(bit_is_clear(NES_PIN, OUT))
reportBuffer.A = 1;
1f8: 05 e2 ldi r16, 0x25 ; 37
cbi(NES_PORT, CLK);
cbi(NES_PORT, LATCH);
for(;;) {
wdt_reset();
1fa: a8 95 wdr
usbPoll();
1fc: cf d0 rcall .+414 ; 0x39c <usbPoll>
if(usbInterruptIsReady()){
1fe: 80 91 70 00 lds r24, 0x0070
202: 84 ff sbrs r24, 4
204: fa cf rjmp .-12 ; 0x1fa <main+0x5c>
reportBuffer.data = 0x05; // Center pad, little endian
206: 10 93 64 00 sts 0x0064, r17
sbi(NES_PORT, LATCH);
20a: c4 9a sbi 0x18, 4 ; 24
#else
//round up by default
__ticks_dc = (uint32_t)(ceil(fabs(__tmp)));
#endif
__builtin_avr_delay_cycles(__ticks_dc);
20c: 95 e0 ldi r25, 0x05 ; 5
20e: 9a 95 dec r25
210: f1 f7 brne .-4 ; 0x20e <main+0x70>
212: 00 c0 rjmp .+0 ; 0x214 <main+0x76>
_delay_us(1); // Latch pulse width >= 500ns
cbi(NES_PORT, LATCH);
214: c4 98 cbi 0x18, 4 ; 24
216: a5 e0 ldi r26, 0x05 ; 5
218: aa 95 dec r26
21a: f1 f7 brne .-4 ; 0x218 <main+0x7a>
21c: 00 c0 rjmp .+0 ; 0x21e <main+0x80>
_delay_us(1); // Propagation time <= 1000ns
if(bit_is_clear(NES_PIN, OUT))
21e: b1 99 sbic 0x16, 1 ; 22
220: 02 c0 rjmp .+4 ; 0x226 <main+0x88>
reportBuffer.A = 1;
222: 00 93 64 00 sts 0x0064, r16
STROBE_CLK();
226: c3 9a sbi 0x18, 3 ; 24
228: b5 e0 ldi r27, 0x05 ; 5
22a: ba 95 dec r27
22c: f1 f7 brne .-4 ; 0x22a <main+0x8c>
22e: 00 c0 rjmp .+0 ; 0x230 <main+0x92>
230: c3 98 cbi 0x18, 3 ; 24
232: 85 e0 ldi r24, 0x05 ; 5
234: 8a 95 dec r24
236: f1 f7 brne .-4 ; 0x234 <main+0x96>
238: 00 c0 rjmp .+0 ; 0x23a <main+0x9c>
if(bit_is_clear(NES_PIN, OUT))
23a: b1 99 sbic 0x16, 1 ; 22
23c: 05 c0 rjmp .+10 ; 0x248 <main+0xaa>
reportBuffer.B = 1;
23e: 80 91 64 00 lds r24, 0x0064
242: 80 61 ori r24, 0x10 ; 16
244: 80 93 64 00 sts 0x0064, r24
STROBE_CLK();
248: c3 9a sbi 0x18, 3 ; 24
24a: 95 e0 ldi r25, 0x05 ; 5
24c: 9a 95 dec r25
24e: f1 f7 brne .-4 ; 0x24c <main+0xae>
250: 00 c0 rjmp .+0 ; 0x252 <main+0xb4>
252: c3 98 cbi 0x18, 3 ; 24
254: a5 e0 ldi r26, 0x05 ; 5
256: aa 95 dec r26
258: f1 f7 brne .-4 ; 0x256 <main+0xb8>
25a: 00 c0 rjmp .+0 ; 0x25c <main+0xbe>
if(bit_is_clear(NES_PIN, OUT))
25c: b1 99 sbic 0x16, 1 ; 22
25e: 05 c0 rjmp .+10 ; 0x26a <__stack+0xb>
reportBuffer.SELECT = 1;
260: 80 91 64 00 lds r24, 0x0064
264: 80 64 ori r24, 0x40 ; 64
266: 80 93 64 00 sts 0x0064, r24
STROBE_CLK();
26a: c3 9a sbi 0x18, 3 ; 24
26c: b5 e0 ldi r27, 0x05 ; 5
26e: ba 95 dec r27
270: f1 f7 brne .-4 ; 0x26e <__stack+0xf>
272: 00 c0 rjmp .+0 ; 0x274 <__stack+0x15>
274: c3 98 cbi 0x18, 3 ; 24
276: 85 e0 ldi r24, 0x05 ; 5
278: 8a 95 dec r24
27a: f1 f7 brne .-4 ; 0x278 <__stack+0x19>
27c: 00 c0 rjmp .+0 ; 0x27e <__stack+0x1f>
if(bit_is_clear(NES_PIN, OUT))
27e: b1 99 sbic 0x16, 1 ; 22
280: 05 c0 rjmp .+10 ; 0x28c <__stack+0x2d>
reportBuffer.START = 1;
282: 80 91 64 00 lds r24, 0x0064
286: 80 68 ori r24, 0x80 ; 128
288: 80 93 64 00 sts 0x0064, r24
STROBE_CLK();
28c: c3 9a sbi 0x18, 3 ; 24
28e: 95 e0 ldi r25, 0x05 ; 5
290: 9a 95 dec r25
292: f1 f7 brne .-4 ; 0x290 <__stack+0x31>
294: 00 c0 rjmp .+0 ; 0x296 <__stack+0x37>
296: c3 98 cbi 0x18, 3 ; 24
298: a5 e0 ldi r26, 0x05 ; 5
29a: aa 95 dec r26
29c: f1 f7 brne .-4 ; 0x29a <__stack+0x3b>
29e: 00 c0 rjmp .+0 ; 0x2a0 <__stack+0x41>
if(bit_is_clear(NES_PIN, OUT))
2a0: b1 99 sbic 0x16, 1 ; 22
2a2: 0d c0 rjmp .+26 ; 0x2be <__stack+0x5f>
reportBuffer.Y--;
2a4: 90 91 64 00 lds r25, 0x0064
2a8: 89 2f mov r24, r25
2aa: 86 95 lsr r24
2ac: 86 95 lsr r24
2ae: 8d 5f subi r24, 0xFD ; 253
2b0: 83 70 andi r24, 0x03 ; 3
2b2: 88 0f add r24, r24
2b4: 88 0f add r24, r24
2b6: 93 7f andi r25, 0xF3 ; 243
2b8: 98 2b or r25, r24
2ba: 90 93 64 00 sts 0x0064, r25
STROBE_CLK();
2be: c3 9a sbi 0x18, 3 ; 24
2c0: b5 e0 ldi r27, 0x05 ; 5
2c2: ba 95 dec r27
2c4: f1 f7 brne .-4 ; 0x2c2 <__stack+0x63>
2c6: 00 c0 rjmp .+0 ; 0x2c8 <__stack+0x69>
2c8: c3 98 cbi 0x18, 3 ; 24
2ca: 85 e0 ldi r24, 0x05 ; 5
2cc: 8a 95 dec r24
2ce: f1 f7 brne .-4 ; 0x2cc <__stack+0x6d>
2d0: 00 c0 rjmp .+0 ; 0x2d2 <__stack+0x73>
if(bit_is_clear(NES_PIN, OUT))
2d2: b1 99 sbic 0x16, 1 ; 22
2d4: 0d c0 rjmp .+26 ; 0x2f0 <__stack+0x91>
reportBuffer.Y++;
2d6: 90 91 64 00 lds r25, 0x0064
2da: 89 2f mov r24, r25
2dc: 86 95 lsr r24
2de: 86 95 lsr r24
2e0: 8f 5f subi r24, 0xFF ; 255
2e2: 83 70 andi r24, 0x03 ; 3
2e4: 88 0f add r24, r24
2e6: 88 0f add r24, r24
2e8: 93 7f andi r25, 0xF3 ; 243
2ea: 98 2b or r25, r24
2ec: 90 93 64 00 sts 0x0064, r25
STROBE_CLK();
2f0: c3 9a sbi 0x18, 3 ; 24
2f2: 95 e0 ldi r25, 0x05 ; 5
2f4: 9a 95 dec r25
2f6: f1 f7 brne .-4 ; 0x2f4 <__stack+0x95>
2f8: 00 c0 rjmp .+0 ; 0x2fa <__stack+0x9b>
2fa: c3 98 cbi 0x18, 3 ; 24
2fc: a5 e0 ldi r26, 0x05 ; 5
2fe: aa 95 dec r26
300: f1 f7 brne .-4 ; 0x2fe <__stack+0x9f>
302: 00 c0 rjmp .+0 ; 0x304 <__stack+0xa5>
if(bit_is_clear(NES_PIN, OUT))
304: b1 99 sbic 0x16, 1 ; 22
306: 09 c0 rjmp .+18 ; 0x31a <__stack+0xbb>
reportBuffer.X--;
308: 80 91 64 00 lds r24, 0x0064
30c: 98 2f mov r25, r24
30e: 9d 5f subi r25, 0xFD ; 253
310: 93 70 andi r25, 0x03 ; 3
312: 8c 7f andi r24, 0xFC ; 252
314: 89 2b or r24, r25
316: 80 93 64 00 sts 0x0064, r24
STROBE_CLK();
31a: c3 9a sbi 0x18, 3 ; 24
31c: b5 e0 ldi r27, 0x05 ; 5
31e: ba 95 dec r27
320: f1 f7 brne .-4 ; 0x31e <__stack+0xbf>
322: 00 c0 rjmp .+0 ; 0x324 <__stack+0xc5>
324: c3 98 cbi 0x18, 3 ; 24
326: 85 e0 ldi r24, 0x05 ; 5
328: 8a 95 dec r24
32a: f1 f7 brne .-4 ; 0x328 <__stack+0xc9>
32c: 00 c0 rjmp .+0 ; 0x32e <__stack+0xcf>
if(bit_is_clear(NES_PIN, OUT))
32e: b1 99 sbic 0x16, 1 ; 22
330: 09 c0 rjmp .+18 ; 0x344 <__stack+0xe5>
reportBuffer.X++;
332: 80 91 64 00 lds r24, 0x0064
336: 98 2f mov r25, r24
338: 9f 5f subi r25, 0xFF ; 255
33a: 93 70 andi r25, 0x03 ; 3
33c: 8c 7f andi r24, 0xFC ; 252
33e: 89 2b or r24, r25
340: 80 93 64 00 sts 0x0064, r24
/* called after every poll of the interrupt endpoint */
usbSetInterrupt(&reportBuffer, sizeof(reportBuffer));
344: 84 e6 ldi r24, 0x64 ; 100
346: 90 e0 ldi r25, 0x00 ; 0
348: 61 e0 ldi r22, 0x01 ; 1
34a: 01 d0 rcall .+2 ; 0x34e <usbSetInterrupt>
34c: 56 cf rjmp .-340 ; 0x1fa <main+0x5c>
0000034e <usbSetInterrupt>:
txStatus->len = len + 4; /* len must be given including sync byte */
DBG2(0x21 + (((int)txStatus >> 3) & 3), txStatus->buffer, len + 3);
}
USB_PUBLIC void usbSetInterrupt(uchar *data, uchar len)
{
34e: 1f 93 push r17
350: 16 2f mov r17, r22
#if USB_CFG_IMPLEMENT_HALT
if(usbTxLen1 == USBPID_STALL)
return;
#endif
if(txStatus->len & 0x10){ /* packet buffer was empty */
352: 20 91 70 00 lds r18, 0x0070
356: 24 ff sbrs r18, 4
358: 1d c0 rjmp .+58 ; 0x394 <usbSetInterrupt+0x46>
txStatus->buffer[0] ^= USBPID_DATA0 ^ USBPID_DATA1; /* toggle token */
35a: 20 91 71 00 lds r18, 0x0071
35e: 38 e8 ldi r19, 0x88 ; 136
360: 23 27 eor r18, r19
362: 20 93 71 00 sts 0x0071, r18
}else{
txStatus->len = USBPID_NAK; /* avoid sending outdated (overwritten) interrupt data */
366: a8 2f mov r26, r24
368: b9 2f mov r27, r25
usbCrc16Append(&txStatus->buffer[1], len);
txStatus->len = len + 4; /* len must be given including sync byte */
DBG2(0x21 + (((int)txStatus >> 3) & 3), txStatus->buffer, len + 3);
}
USB_PUBLIC void usbSetInterrupt(uchar *data, uchar len)
36a: 81 2f mov r24, r17
36c: 81 50 subi r24, 0x01 ; 1
36e: 90 e0 ldi r25, 0x00 ; 0
370: 8d 58 subi r24, 0x8D ; 141
372: 9f 4f sbci r25, 0xFF ; 255
374: e2 e7 ldi r30, 0x72 ; 114
376: f0 e0 ldi r31, 0x00 ; 0
txStatus->len = USBPID_NAK; /* avoid sending outdated (overwritten) interrupt data */
}
p = txStatus->buffer + 1;
i = len;
do{ /* if len == 0, we still copy 1 byte, but that's no problem */
*p++ = *data++;
378: 2d 91 ld r18, X+
37a: 21 93 st Z+, r18
}while(--i > 0); /* loop control at the end is 2 bytes shorter than at beginning */
37c: e8 17 cp r30, r24
37e: f9 07 cpc r31, r25
380: d9 f7 brne .-10 ; 0x378 <usbSetInterrupt+0x2a>
usbCrc16Append(&txStatus->buffer[1], len);
382: 82 e7 ldi r24, 0x72 ; 114
384: 90 e0 ldi r25, 0x00 ; 0
386: 61 2f mov r22, r17
388: 69 d1 rcall .+722 ; 0x65c <usbCrc16Append>
txStatus->len = len + 4; /* len must be given including sync byte */
38a: 1c 5f subi r17, 0xFC ; 252
38c: 10 93 70 00 sts 0x0070, r17
}
USB_PUBLIC void usbSetInterrupt(uchar *data, uchar len)
{
usbGenericSetInterrupt(data, len, &usbTxStatus1);
}
390: 1f 91 pop r17
392: 08 95 ret
return;
#endif
if(txStatus->len & 0x10){ /* packet buffer was empty */
txStatus->buffer[0] ^= USBPID_DATA0 ^ USBPID_DATA1; /* toggle token */
}else{
txStatus->len = USBPID_NAK; /* avoid sending outdated (overwritten) interrupt data */
394: 2a e5 ldi r18, 0x5A ; 90
396: 20 93 70 00 sts 0x0070, r18
39a: e5 cf rjmp .-54 ; 0x366 <usbSetInterrupt+0x18>
0000039c <usbPoll>:
}
/* ------------------------------------------------------------------------- */
USB_PUBLIC void usbPoll(void)
{
39c: 1f 93 push r17
39e: cf 93 push r28
3a0: df 93 push r29
schar len;
uchar i;
len = usbRxLen - 3;
3a2: 80 91 81 00 lds r24, 0x0081
3a6: 83 50 subi r24, 0x03 ; 3
if(len >= 0){
3a8: 87 fd sbrc r24, 7
3aa: 09 c0 rjmp .+18 ; 0x3be <usbPoll+0x22>
* need data integrity checks with this driver, check the CRC in your app
* code and report errors back to the host. Since the ACK was already sent,
* retries must be handled on application level.
* unsigned crc = usbCrc16(buffer + 1, usbRxLen - 3);
*/
usbProcessRx(usbRxBuf + USB_BUFSIZE + 1 - usbInputBufOffset, len);
3ac: 20 91 7e 00 lds r18, 0x007E
if(usbRxToken < 0x10){ /* OUT to endpoint != 0: endpoint number in usbRxToken */
usbFunctionWriteOut(data, len);
return;
}
#endif
if(usbRxToken == (uchar)USBPID_SETUP){
3b0: 90 91 7d 00 lds r25, 0x007D
3b4: 9d 32 cpi r25, 0x2D ; 45
3b6: 09 f4 brne .+2 ; 0x3ba <usbPoll+0x1e>
3b8: 5d c0 rjmp .+186 ; 0x474 <usbPoll+0xd8>
usbProcessRx(usbRxBuf + USB_BUFSIZE + 1 - usbInputBufOffset, len);
#if USB_CFG_HAVE_FLOWCONTROL
if(usbRxLen > 0) /* only mark as available if not inactivated */
usbRxLen = 0;
#else
usbRxLen = 0; /* mark rx buffer as available */
3ba: 10 92 81 00 sts 0x0081, r1
#endif
}
if(usbTxLen & 0x10){ /* transmit system idle */
3be: 80 91 60 00 lds r24, 0x0060
3c2: 84 ff sbrs r24, 4
3c4: 39 c0 rjmp .+114 ; 0x438 <usbPoll+0x9c>
if(usbMsgLen != USB_NO_MSG){ /* transmit data pending? */
3c6: 60 91 61 00 lds r22, 0x0061
3ca: 6f 3f cpi r22, 0xFF ; 255
3cc: a9 f1 breq .+106 ; 0x438 <usbPoll+0x9c>
{
usbMsgLen_t wantLen;
uchar len;
wantLen = usbMsgLen;
if(wantLen > 8)
3ce: 69 30 cpi r22, 0x09 ; 9
3d0: 08 f4 brcc .+2 ; 0x3d4 <usbPoll+0x38>
3d2: 7d c0 rjmp .+250 ; 0x4ce <usbPoll+0x132>
wantLen = 8;
usbMsgLen -= wantLen;
3d4: 68 50 subi r22, 0x08 ; 8
3d6: 60 93 61 00 sts 0x0061, r22
usbTxBuf[0] ^= USBPID_DATA0 ^ USBPID_DATA1; /* DATA toggling */
3da: 80 91 65 00 lds r24, 0x0065
3de: 98 e8 ldi r25, 0x88 ; 136
3e0: 89 27 eor r24, r25
3e2: 80 93 65 00 sts 0x0065, r24
3e6: 1c e0 ldi r17, 0x0C ; 12
usbMsgLen_t wantLen;
uchar len;
wantLen = usbMsgLen;
if(wantLen > 8)
wantLen = 8;
3e8: 68 e0 ldi r22, 0x08 ; 8
if(usbMsgFlags & USB_FLG_USE_USER_RW){
len = usbFunctionRead(data, len);
}else
#endif
{
uchar i = len, *r = usbMsgPtr;
3ea: 20 91 7f 00 lds r18, 0x007F
3ee: 30 91 80 00 lds r19, 0x0080
if(usbMsgFlags & USB_FLG_MSGPTR_IS_ROM){ /* ROM data */
3f2: 80 91 62 00 lds r24, 0x0062
3f6: 86 ff sbrs r24, 6
3f8: 80 c0 rjmp .+256 ; 0x4fa <usbPoll+0x15e>
#endif
}
/* ------------------------------------------------------------------------- */
USB_PUBLIC void usbPoll(void)
3fa: 46 2f mov r20, r22
3fc: 41 50 subi r20, 0x01 ; 1
3fe: 50 e0 ldi r21, 0x00 ; 0
400: ca 01 movw r24, r20
402: 89 59 subi r24, 0x99 ; 153
404: 9f 4f sbci r25, 0xFF ; 255
406: f9 01 movw r30, r18
408: a6 e6 ldi r26, 0x66 ; 102
40a: b0 e0 ldi r27, 0x00 ; 0
#endif
{
uchar i = len, *r = usbMsgPtr;
if(usbMsgFlags & USB_FLG_MSGPTR_IS_ROM){ /* ROM data */
do{
uchar c = USB_READ_FLASH(r); /* assign to char size variable to enforce byte ops */
40c: 74 91 lpm r23, Z+
*data++ = c;
40e: 7d 93 st X+, r23
r++;
410: 31 96 adiw r30, 0x01 ; 1
}while(--i);
412: a8 17 cp r26, r24
414: b9 07 cpc r27, r25
416: d1 f7 brne .-12 ; 0x40c <usbPoll+0x70>
#endif
}
/* ------------------------------------------------------------------------- */
USB_PUBLIC void usbPoll(void)
418: 4f 5f subi r20, 0xFF ; 255
41a: 5f 4f sbci r21, 0xFF ; 255
r++;
}while(--i);
}else{ /* RAM data */
do{
*data++ = *r++;
}while(--i);
41c: 42 0f add r20, r18
41e: 53 1f adc r21, r19
}
usbMsgPtr = r;
420: 50 93 80 00 sts 0x0080, r21
424: 40 93 7f 00 sts 0x007F, r20
wantLen = 8;
usbMsgLen -= wantLen;
usbTxBuf[0] ^= USBPID_DATA0 ^ USBPID_DATA1; /* DATA toggling */
len = usbDeviceRead(usbTxBuf + 1, wantLen);
if(len <= 8){ /* valid data packet */
usbCrc16Append(&usbTxBuf[1], len);
428: 86 e6 ldi r24, 0x66 ; 102
42a: 90 e0 ldi r25, 0x00 ; 0
42c: 17 d1 rcall .+558 ; 0x65c <usbCrc16Append>
len += 4; /* length including sync byte */
if(len < 12) /* a partial package identifies end of message */
42e: 1c 30 cpi r17, 0x0C ; 12
430: 09 f0 breq .+2 ; 0x434 <usbPoll+0x98>
432: 5d c0 rjmp .+186 ; 0x4ee <usbPoll+0x152>
usbMsgLen = USB_NO_MSG;
}else{
len = USBPID_STALL; /* stall the endpoint */
usbMsgLen = USB_NO_MSG;
}
usbTxLen = len;
434: 10 93 60 00 sts 0x0060, r17
if(usbTxLen & 0x10){ /* transmit system idle */
if(usbMsgLen != USB_NO_MSG){ /* transmit data pending? */
usbBuildTxBlock();
}
}
for(i = 20; i > 0; i--){
438: 94 e1 ldi r25, 0x14 ; 20
uchar usbLineStatus = USBIN & USBMASK;
43a: 86 b3 in r24, 0x16 ; 22
43c: 85 70 andi r24, 0x05 ; 5
if(usbLineStatus != 0) /* SE0 has ended */
43e: 99 f4 brne .+38 ; 0x466 <usbPoll+0xca>
if(usbTxLen & 0x10){ /* transmit system idle */
if(usbMsgLen != USB_NO_MSG){ /* transmit data pending? */
usbBuildTxBlock();
}
}
for(i = 20; i > 0; i--){
440: 91 50 subi r25, 0x01 ; 1
442: d9 f7 brne .-10 ; 0x43a <usbPoll+0x9e>
uchar usbLineStatus = USBIN & USBMASK;
if(usbLineStatus != 0) /* SE0 has ended */
goto isNotReset;
}
/* RESET condition, called multiple times during reset */
usbNewDeviceAddr = 0;
444: 10 92 82 00 sts 0x0082, r1
usbDeviceAddr = 0;
448: 10 92 7c 00 sts 0x007C, r1
44c: 11 e0 ldi r17, 0x01 ; 1
{
#ifdef USB_RESET_HOOK
static uchar wasReset;
uchar isReset = !notResetState;
if(wasReset != isReset){
44e: 80 91 63 00 lds r24, 0x0063
452: 18 17 cp r17, r24
454: 21 f0 breq .+8 ; 0x45e <usbPoll+0xc2>
USB_RESET_HOOK(isReset);
456: 11 23 and r17, r17
458: 59 f0 breq .+22 ; 0x470 <usbPoll+0xd4>
wasReset = isReset;
45a: 10 93 63 00 sts 0x0063, r17
usbDeviceAddr = 0;
usbResetStall();
DBG1(0xff, 0, 0);
isNotReset:
usbHandleResetHook(i);
}
45e: df 91 pop r29
460: cf 91 pop r28
462: 1f 91 pop r17
464: 08 95 ret
usbBuildTxBlock();
}
}
for(i = 20; i > 0; i--){
uchar usbLineStatus = USBIN & USBMASK;
if(usbLineStatus != 0) /* SE0 has ended */
466: 11 e0 ldi r17, 0x01 ; 1
468: 99 23 and r25, r25
46a: 89 f3 breq .-30 ; 0x44e <usbPoll+0xb2>
46c: 10 e0 ldi r17, 0x00 ; 0
46e: ef cf rjmp .-34 ; 0x44e <usbPoll+0xb2>
#ifdef USB_RESET_HOOK
static uchar wasReset;
uchar isReset = !notResetState;
if(wasReset != isReset){
USB_RESET_HOOK(isReset);
470: 44 de rcall .-888 ; 0xfa <hadUsbReset>
472: f3 cf rjmp .-26 ; 0x45a <usbPoll+0xbe>
usbFunctionWriteOut(data, len);
return;
}
#endif
if(usbRxToken == (uchar)USBPID_SETUP){
if(len != 8) /* Setup size must be always 8 bytes. Ignore otherwise. */
474: 88 30 cpi r24, 0x08 ; 8
476: 09 f0 breq .+2 ; 0x47a <usbPoll+0xde>
478: a0 cf rjmp .-192 ; 0x3ba <usbPoll+0x1e>
* need data integrity checks with this driver, check the CRC in your app
* code and report errors back to the host. Since the ACK was already sent,
* retries must be handled on application level.
* unsigned crc = usbCrc16(buffer + 1, usbRxLen - 3);
*/
usbProcessRx(usbRxBuf + USB_BUFSIZE + 1 - usbInputBufOffset, len);
47a: cc e0 ldi r28, 0x0C ; 12
47c: d0 e0 ldi r29, 0x00 ; 0
47e: c2 1b sub r28, r18
480: d1 09 sbc r29, r1
482: cb 57 subi r28, 0x7B ; 123
484: df 4f sbci r29, 0xFF ; 255
#endif
if(usbRxToken == (uchar)USBPID_SETUP){
if(len != 8) /* Setup size must be always 8 bytes. Ignore otherwise. */
return;
usbMsgLen_t replyLen;
usbTxBuf[0] = USBPID_DATA0; /* initialize data toggling */
486: 83 ec ldi r24, 0xC3 ; 195
488: 80 93 65 00 sts 0x0065, r24
usbTxLen = USBPID_NAK; /* abort pending transmit */
48c: 8a e5 ldi r24, 0x5A ; 90
48e: 80 93 60 00 sts 0x0060, r24
usbMsgFlags = 0;
492: 10 92 62 00 sts 0x0062, r1
uchar type = rq->bmRequestType & USBRQ_TYPE_MASK;
496: 88 81 ld r24, Y
498: 80 76 andi r24, 0x60 ; 96
if(type != USBRQ_TYPE_STANDARD){ /* standard requests are handled by driver */
49a: f1 f5 brne .+124 ; 0x518 <usbPoll+0x17c>
*/
static inline usbMsgLen_t usbDriverSetup(usbRequest_t *rq)
{
usbMsgLen_t len = 0;
uchar *dataPtr = usbTxBuf + 9; /* there are 2 bytes free space at the end of the buffer */
uchar value = rq->wValue.bytes[0];
49c: 9a 81 ldd r25, Y+2 ; 0x02
#if USB_CFG_IMPLEMENT_HALT
uchar index = rq->wIndex.bytes[0];
#endif
dataPtr[0] = 0; /* default reply common to USBRQ_GET_STATUS and USBRQ_GET_INTERFACE */
49e: 10 92 6e 00 sts 0x006E, r1
SWITCH_START(rq->bRequest)
4a2: 89 81 ldd r24, Y+1 ; 0x01
SWITCH_CASE(USBRQ_GET_STATUS) /* 0 */
4a4: 88 23 and r24, r24
4a6: d9 f5 brne .+118 ; 0x51e <usbPoll+0x182>
dataPtr[0] = USB_CFG_IS_SELF_POWERED;
#if USB_CFG_IMPLEMENT_HALT
if(recipient == USBRQ_RCPT_ENDPOINT && index == 0x81) /* request status for endpoint 1 */
dataPtr[0] = usbTxLen1 == USBPID_STALL;
#endif
dataPtr[1] = 0;
4a8: 10 92 6f 00 sts 0x006F, r1
* standard requests instead of class and custom requests.
*/
static inline usbMsgLen_t usbDriverSetup(usbRequest_t *rq)
{
usbMsgLen_t len = 0;
uchar *dataPtr = usbTxBuf + 9; /* there are 2 bytes free space at the end of the buffer */
4ac: 2e e6 ldi r18, 0x6E ; 110
4ae: 30 e0 ldi r19, 0x00 ; 0
#if USB_CFG_IMPLEMENT_HALT
if(recipient == USBRQ_RCPT_ENDPOINT && index == 0x81) /* request status for endpoint 1 */
dataPtr[0] = usbTxLen1 == USBPID_STALL;
#endif
dataPtr[1] = 0;
len = 2;
4b0: 82 e0 ldi r24, 0x02 ; 2
usbResetStall();
#endif
SWITCH_DEFAULT /* 7=SET_DESCRIPTOR, 12=SYNC_FRAME */
/* Should we add an optional hook here? */
SWITCH_END
usbMsgPtr = dataPtr;
4b2: 30 93 80 00 sts 0x0080, r19
4b6: 20 93 7f 00 sts 0x007F, r18
}
usbMsgFlags = USB_FLG_USE_USER_RW;
}else /* The 'else' prevents that we limit a replyLen of USB_NO_MSG to the maximum transfer len. */
#endif
if(sizeof(replyLen) < sizeof(rq->wLength.word)){ /* help compiler with optimizing */
if(!rq->wLength.bytes[1] && replyLen > rq->wLength.bytes[0]) /* limit length to max */
4ba: 9f 81 ldd r25, Y+7 ; 0x07
4bc: 99 23 and r25, r25
4be: 21 f4 brne .+8 ; 0x4c8 <usbPoll+0x12c>
4c0: 9e 81 ldd r25, Y+6 ; 0x06
4c2: 98 17 cp r25, r24
4c4: 08 f4 brcc .+2 ; 0x4c8 <usbPoll+0x12c>
4c6: 89 2f mov r24, r25
replyLen = rq->wLength.bytes[0];
}else{
if(replyLen > rq->wLength.word) /* limit length to max */
replyLen = rq->wLength.word;
}
usbMsgLen = replyLen;
4c8: 80 93 61 00 sts 0x0061, r24
4cc: 76 cf rjmp .-276 ; 0x3ba <usbPoll+0x1e>
uchar len;
wantLen = usbMsgLen;
if(wantLen > 8)
wantLen = 8;
usbMsgLen -= wantLen;
4ce: 10 92 61 00 sts 0x0061, r1
usbTxBuf[0] ^= USBPID_DATA0 ^ USBPID_DATA1; /* DATA toggling */
4d2: 80 91 65 00 lds r24, 0x0065
4d6: 98 e8 ldi r25, 0x88 ; 136
4d8: 89 27 eor r24, r25
4da: 80 93 65 00 sts 0x0065, r24
/* This function is similar to usbFunctionRead(), but it's also called for
* data handled automatically by the driver (e.g. descriptor reads).
*/
static uchar usbDeviceRead(uchar *data, uchar len)
{
if(len > 0){ /* don't bother app with 0 sized reads */
4de: 66 23 and r22, r22
4e0: 09 f0 breq .+2 ; 0x4e4 <usbPoll+0x148>
4e2: 82 c0 rjmp .+260 ; 0x5e8 <usbPoll+0x24c>
wantLen = 8;
usbMsgLen -= wantLen;
usbTxBuf[0] ^= USBPID_DATA0 ^ USBPID_DATA1; /* DATA toggling */
len = usbDeviceRead(usbTxBuf + 1, wantLen);
if(len <= 8){ /* valid data packet */
usbCrc16Append(&usbTxBuf[1], len);
4e4: 86 e6 ldi r24, 0x66 ; 102
4e6: 90 e0 ldi r25, 0x00 ; 0
4e8: 60 e0 ldi r22, 0x00 ; 0
4ea: b8 d0 rcall .+368 ; 0x65c <usbCrc16Append>
len += 4; /* length including sync byte */
4ec: 14 e0 ldi r17, 0x04 ; 4
if(len < 12) /* a partial package identifies end of message */
usbMsgLen = USB_NO_MSG;
4ee: 8f ef ldi r24, 0xFF ; 255
4f0: 80 93 61 00 sts 0x0061, r24
}else{
len = USBPID_STALL; /* stall the endpoint */
usbMsgLen = USB_NO_MSG;
}
usbTxLen = len;
4f4: 10 93 60 00 sts 0x0060, r17
4f8: 9f cf rjmp .-194 ; 0x438 <usbPoll+0x9c>
if(usbMsgFlags & USB_FLG_MSGPTR_IS_ROM){ /* ROM data */
do{
uchar c = USB_READ_FLASH(r); /* assign to char size variable to enforce byte ops */
*data++ = c;
r++;
}while(--i);
4fa: d9 01 movw r26, r18
#endif
}
/* ------------------------------------------------------------------------- */
USB_PUBLIC void usbPoll(void)
4fc: 46 2f mov r20, r22
4fe: 41 50 subi r20, 0x01 ; 1
500: 50 e0 ldi r21, 0x00 ; 0
502: ca 01 movw r24, r20
504: 89 59 subi r24, 0x99 ; 153
506: 9f 4f sbci r25, 0xFF ; 255
508: e6 e6 ldi r30, 0x66 ; 102
50a: f0 e0 ldi r31, 0x00 ; 0
*data++ = c;
r++;
}while(--i);
}else{ /* RAM data */
do{
*data++ = *r++;
50c: 7d 91 ld r23, X+
50e: 71 93 st Z+, r23
}while(--i);
510: e8 17 cp r30, r24
512: f9 07 cpc r31, r25
514: d9 f7 brne .-10 ; 0x50c <usbPoll+0x170>
516: 80 cf rjmp .-256 ; 0x418 <usbPoll+0x7c>
usbTxBuf[0] = USBPID_DATA0; /* initialize data toggling */
usbTxLen = USBPID_NAK; /* abort pending transmit */
usbMsgFlags = 0;
uchar type = rq->bmRequestType & USBRQ_TYPE_MASK;
if(type != USBRQ_TYPE_STANDARD){ /* standard requests are handled by driver */
replyLen = usbFunctionSetup(data);
518: ce 01 movw r24, r28
51a: ed dd rcall .-1062 ; 0xf6 <usbFunctionSetup>
51c: ce cf rjmp .-100 ; 0x4ba <usbPoll+0x11e>
if(value == 0 && index == 0x81){ /* feature 0 == HALT for endpoint == 1 */
usbTxLen1 = rq->bRequest == USBRQ_CLEAR_FEATURE ? USBPID_NAK : USBPID_STALL;
usbResetDataToggling();
}
#endif
SWITCH_CASE(USBRQ_SET_ADDRESS) /* 5 */
51e: 85 30 cpi r24, 0x05 ; 5
520: 71 f0 breq .+28 ; 0x53e <usbPoll+0x1a2>
usbNewDeviceAddr = value;
USB_SET_ADDRESS_HOOK();
SWITCH_CASE(USBRQ_GET_DESCRIPTOR) /* 6 */
522: 86 30 cpi r24, 0x06 ; 6
524: 91 f0 breq .+36 ; 0x54a <usbPoll+0x1ae>
len = usbDriverDescriptor(rq);
goto skipMsgPtrAssignment;
SWITCH_CASE(USBRQ_GET_CONFIGURATION) /* 8 */
526: 88 30 cpi r24, 0x08 ; 8
528: 01 f1 breq .+64 ; 0x56a <usbPoll+0x1ce>
dataPtr = &usbConfiguration; /* send current configuration value */
len = 1;
SWITCH_CASE(USBRQ_SET_CONFIGURATION) /* 9 */
52a: 89 30 cpi r24, 0x09 ; 9
52c: 11 f1 breq .+68 ; 0x572 <usbPoll+0x1d6>
usbConfiguration = value;
usbResetStall();
SWITCH_CASE(USBRQ_GET_INTERFACE) /* 10 */
52e: 8a 30 cpi r24, 0x0A ; 10
530: 71 f1 breq .+92 ; 0x58e <usbPoll+0x1f2>
len = 1;
#if USB_CFG_HAVE_INTRIN_ENDPOINT && !USB_CFG_SUPPRESS_INTR_CODE
SWITCH_CASE(USBRQ_SET_INTERFACE) /* 11 */
532: 8b 30 cpi r24, 0x0B ; 11
534: 81 f1 breq .+96 ; 0x596 <usbPoll+0x1fa>
* standard requests instead of class and custom requests.
*/
static inline usbMsgLen_t usbDriverSetup(usbRequest_t *rq)
{
usbMsgLen_t len = 0;
uchar *dataPtr = usbTxBuf + 9; /* there are 2 bytes free space at the end of the buffer */
536: 2e e6 ldi r18, 0x6E ; 110
538: 30 e0 ldi r19, 0x00 ; 0
/* usbDriverSetup() is similar to usbFunctionSetup(), but it's used for
* standard requests instead of class and custom requests.
*/
static inline usbMsgLen_t usbDriverSetup(usbRequest_t *rq)
{
usbMsgLen_t len = 0;
53a: 80 e0 ldi r24, 0x00 ; 0
53c: ba cf rjmp .-140 ; 0x4b2 <usbPoll+0x116>
usbTxLen1 = rq->bRequest == USBRQ_CLEAR_FEATURE ? USBPID_NAK : USBPID_STALL;
usbResetDataToggling();
}
#endif
SWITCH_CASE(USBRQ_SET_ADDRESS) /* 5 */
usbNewDeviceAddr = value;
53e: 90 93 82 00 sts 0x0082, r25
* standard requests instead of class and custom requests.
*/
static inline usbMsgLen_t usbDriverSetup(usbRequest_t *rq)
{
usbMsgLen_t len = 0;
uchar *dataPtr = usbTxBuf + 9; /* there are 2 bytes free space at the end of the buffer */
542: 2e e6 ldi r18, 0x6E ; 110
544: 30 e0 ldi r19, 0x00 ; 0
/* usbDriverSetup() is similar to usbFunctionSetup(), but it's used for
* standard requests instead of class and custom requests.
*/
static inline usbMsgLen_t usbDriverSetup(usbRequest_t *rq)
{
usbMsgLen_t len = 0;
546: 80 e0 ldi r24, 0x00 ; 0
548: b4 cf rjmp .-152 ; 0x4b2 <usbPoll+0x116>
usbTxLen1 = USBPID_NAK;
#if USB_CFG_HAVE_INTRIN_ENDPOINT3
usbTxLen3 = USBPID_NAK;
#endif
#endif
}
54a: 8b 81 ldd r24, Y+3 ; 0x03
{
usbMsgLen_t len = 0;
uchar flags = USB_FLG_MSGPTR_IS_ROM;
SWITCH_START(rq->wValue.bytes[1])
SWITCH_CASE(USBDESCR_DEVICE) /* 1 */
54c: 81 30 cpi r24, 0x01 ; 1
54e: b9 f0 breq .+46 ; 0x57e <usbPoll+0x1e2>
GET_DESCRIPTOR(USB_CFG_DESCR_PROPS_DEVICE, usbDescriptorDevice)
SWITCH_CASE(USBDESCR_CONFIG) /* 2 */
550: 82 30 cpi r24, 0x02 ; 2
552: 91 f1 breq .+100 ; 0x5b8 <usbPoll+0x21c>
GET_DESCRIPTOR(USB_CFG_DESCR_PROPS_CONFIGURATION, usbDescriptorConfiguration)
SWITCH_CASE(USBDESCR_STRING) /* 3 */
554: 83 30 cpi r24, 0x03 ; 3
556: 31 f1 breq .+76 ; 0x5a4 <usbPoll+0x208>
len = usbFunctionDescriptor(rq);
}
SWITCH_END
#endif /* USB_CFG_DESCR_PROPS_STRINGS & USB_PROP_IS_DYNAMIC */
#if USB_CFG_DESCR_PROPS_HID_REPORT /* only support HID descriptors if enabled */
SWITCH_CASE(USBDESCR_HID) /* 0x21 */
558: 81 32 cpi r24, 0x21 ; 33
55a: f1 f1 breq .+124 ; 0x5d8 <usbPoll+0x23c>
GET_DESCRIPTOR(USB_CFG_DESCR_PROPS_HID, usbDescriptorConfiguration + 18)
SWITCH_CASE(USBDESCR_HID_REPORT)/* 0x22 */
55c: 82 32 cpi r24, 0x22 ; 34
55e: a1 f1 breq .+104 ; 0x5c8 <usbPoll+0x22c>
/* usbDriverDescriptor() is similar to usbFunctionDescriptor(), but used
* internally for all types of descriptors.
*/
static inline usbMsgLen_t usbDriverDescriptor(usbRequest_t *rq)
{
usbMsgLen_t len = 0;
560: 80 e0 ldi r24, 0x00 ; 0
SWITCH_DEFAULT
if(USB_CFG_DESCR_PROPS_UNKNOWN & USB_PROP_IS_DYNAMIC){
len = usbFunctionDescriptor(rq);
}
SWITCH_END
usbMsgFlags = flags;
562: 90 e4 ldi r25, 0x40 ; 64
564: 90 93 62 00 sts 0x0062, r25
568: a8 cf rjmp .-176 ; 0x4ba <usbPoll+0x11e>
USB_SET_ADDRESS_HOOK();
SWITCH_CASE(USBRQ_GET_DESCRIPTOR) /* 6 */
len = usbDriverDescriptor(rq);
goto skipMsgPtrAssignment;
SWITCH_CASE(USBRQ_GET_CONFIGURATION) /* 8 */
dataPtr = &usbConfiguration; /* send current configuration value */
56a: 24 e8 ldi r18, 0x84 ; 132
56c: 30 e0 ldi r19, 0x00 ; 0
len = 1;
56e: 81 e0 ldi r24, 0x01 ; 1
570: a0 cf rjmp .-192 ; 0x4b2 <usbPoll+0x116>
SWITCH_CASE(USBRQ_SET_CONFIGURATION) /* 9 */
usbConfiguration = value;
572: 90 93 84 00 sts 0x0084, r25
* standard requests instead of class and custom requests.
*/
static inline usbMsgLen_t usbDriverSetup(usbRequest_t *rq)
{
usbMsgLen_t len = 0;
uchar *dataPtr = usbTxBuf + 9; /* there are 2 bytes free space at the end of the buffer */
576: 2e e6 ldi r18, 0x6E ; 110
578: 30 e0 ldi r19, 0x00 ; 0
/* usbDriverSetup() is similar to usbFunctionSetup(), but it's used for
* standard requests instead of class and custom requests.
*/
static inline usbMsgLen_t usbDriverSetup(usbRequest_t *rq)
{
usbMsgLen_t len = 0;
57a: 80 e0 ldi r24, 0x00 ; 0
57c: 9a cf rjmp .-204 ; 0x4b2 <usbPoll+0x116>
usbMsgLen_t len = 0;
uchar flags = USB_FLG_MSGPTR_IS_ROM;
SWITCH_START(rq->wValue.bytes[1])
SWITCH_CASE(USBDESCR_DEVICE) /* 1 */
GET_DESCRIPTOR(USB_CFG_DESCR_PROPS_DEVICE, usbDescriptorDevice)
57e: 8a e8 ldi r24, 0x8A ; 138
580: 90 e0 ldi r25, 0x00 ; 0
582: 90 93 80 00 sts 0x0080, r25
586: 80 93 7f 00 sts 0x007F, r24
58a: 82 e1 ldi r24, 0x12 ; 18
58c: ea cf rjmp .-44 ; 0x562 <usbPoll+0x1c6>
* standard requests instead of class and custom requests.
*/
static inline usbMsgLen_t usbDriverSetup(usbRequest_t *rq)
{
usbMsgLen_t len = 0;
uchar *dataPtr = usbTxBuf + 9; /* there are 2 bytes free space at the end of the buffer */
58e: 2e e6 ldi r18, 0x6E ; 110
590: 30 e0 ldi r19, 0x00 ; 0
len = 1;
SWITCH_CASE(USBRQ_SET_CONFIGURATION) /* 9 */
usbConfiguration = value;
usbResetStall();
SWITCH_CASE(USBRQ_GET_INTERFACE) /* 10 */
len = 1;
592: 81 e0 ldi r24, 0x01 ; 1
594: 8e cf rjmp .-228 ; 0x4b2 <usbPoll+0x116>
/* ------------------------------------------------------------------------- */
static inline void usbResetDataToggling(void)
{
#if USB_CFG_HAVE_INTRIN_ENDPOINT && !USB_CFG_SUPPRESS_INTR_CODE
USB_SET_DATATOKEN1(USB_INITIAL_DATATOKEN); /* reset data toggling for interrupt endpoint */
596: 8b e4 ldi r24, 0x4B ; 75
598: 80 93 71 00 sts 0x0071, r24
* standard requests instead of class and custom requests.
*/
static inline usbMsgLen_t usbDriverSetup(usbRequest_t *rq)
{
usbMsgLen_t len = 0;
uchar *dataPtr = usbTxBuf + 9; /* there are 2 bytes free space at the end of the buffer */
59c: 2e e6 ldi r18, 0x6E ; 110
59e: 30 e0 ldi r19, 0x00 ; 0
/* usbDriverSetup() is similar to usbFunctionSetup(), but it's used for
* standard requests instead of class and custom requests.
*/
static inline usbMsgLen_t usbDriverSetup(usbRequest_t *rq)
{
usbMsgLen_t len = 0;
5a0: 80 e0 ldi r24, 0x00 ; 0
5a2: 87 cf rjmp .-242 ; 0x4b2 <usbPoll+0x116>
if(USB_CFG_DESCR_PROPS_STRINGS & USB_PROP_IS_RAM)
flags = 0;
len = usbFunctionDescriptor(rq);
#else /* USB_CFG_DESCR_PROPS_STRINGS & USB_PROP_IS_DYNAMIC */
SWITCH_START(rq->wValue.bytes[0])
SWITCH_CASE(0)
5a4: 99 23 and r25, r25
5a6: 19 f5 brne .+70 ; 0x5ee <usbPoll+0x252>
GET_DESCRIPTOR(USB_CFG_DESCR_PROPS_STRING_0, usbDescriptorString0)
5a8: 88 e4 ldi r24, 0x48 ; 72
5aa: 90 e0 ldi r25, 0x00 ; 0
5ac: 90 93 80 00 sts 0x0080, r25
5b0: 80 93 7f 00 sts 0x007F, r24
5b4: 84 e0 ldi r24, 0x04 ; 4
5b6: d5 cf rjmp .-86 ; 0x562 <usbPoll+0x1c6>
SWITCH_START(rq->wValue.bytes[1])
SWITCH_CASE(USBDESCR_DEVICE) /* 1 */
GET_DESCRIPTOR(USB_CFG_DESCR_PROPS_DEVICE, usbDescriptorDevice)
SWITCH_CASE(USBDESCR_CONFIG) /* 2 */
GET_DESCRIPTOR(USB_CFG_DESCR_PROPS_CONFIGURATION, usbDescriptorConfiguration)
5b8: 8c e9 ldi r24, 0x9C ; 156
5ba: 90 e0 ldi r25, 0x00 ; 0
5bc: 90 93 80 00 sts 0x0080, r25
5c0: 80 93 7f 00 sts 0x007F, r24
5c4: 82 e2 ldi r24, 0x22 ; 34
5c6: cd cf rjmp .-102 ; 0x562 <usbPoll+0x1c6>
#endif /* USB_CFG_DESCR_PROPS_STRINGS & USB_PROP_IS_DYNAMIC */
#if USB_CFG_DESCR_PROPS_HID_REPORT /* only support HID descriptors if enabled */
SWITCH_CASE(USBDESCR_HID) /* 0x21 */
GET_DESCRIPTOR(USB_CFG_DESCR_PROPS_HID, usbDescriptorConfiguration + 18)
SWITCH_CASE(USBDESCR_HID_REPORT)/* 0x22 */
GET_DESCRIPTOR(USB_CFG_DESCR_PROPS_HID_REPORT, usbDescriptorHidReport)
5c8: 8e e1 ldi r24, 0x1E ; 30
5ca: 90 e0 ldi r25, 0x00 ; 0
5cc: 90 93 80 00 sts 0x0080, r25
5d0: 80 93 7f 00 sts 0x007F, r24
5d4: 8a e2 ldi r24, 0x2A ; 42
5d6: c5 cf rjmp .-118 ; 0x562 <usbPoll+0x1c6>
}
SWITCH_END
#endif /* USB_CFG_DESCR_PROPS_STRINGS & USB_PROP_IS_DYNAMIC */
#if USB_CFG_DESCR_PROPS_HID_REPORT /* only support HID descriptors if enabled */
SWITCH_CASE(USBDESCR_HID) /* 0x21 */
GET_DESCRIPTOR(USB_CFG_DESCR_PROPS_HID, usbDescriptorConfiguration + 18)
5d8: 8e ea ldi r24, 0xAE ; 174
5da: 90 e0 ldi r25, 0x00 ; 0
5dc: 90 93 80 00 sts 0x0080, r25
5e0: 80 93 7f 00 sts 0x007F, r24
5e4: 89 e0 ldi r24, 0x09 ; 9
5e6: bd cf rjmp .-134 ; 0x562 <usbPoll+0x1c6>
/* This function is similar to usbFunctionRead(), but it's also called for
* data handled automatically by the driver (e.g. descriptor reads).
*/
static uchar usbDeviceRead(uchar *data, uchar len)
{
if(len > 0){ /* don't bother app with 0 sized reads */
5e8: 16 2f mov r17, r22
5ea: 1c 5f subi r17, 0xFC ; 252
5ec: fe ce rjmp .-516 ; 0x3ea <usbPoll+0x4e>
len = usbFunctionDescriptor(rq);
#else /* USB_CFG_DESCR_PROPS_STRINGS & USB_PROP_IS_DYNAMIC */
SWITCH_START(rq->wValue.bytes[0])
SWITCH_CASE(0)
GET_DESCRIPTOR(USB_CFG_DESCR_PROPS_STRING_0, usbDescriptorString0)
SWITCH_CASE(1)
5ee: 91 30 cpi r25, 0x01 ; 1
5f0: 59 f0 breq .+22 ; 0x608 <usbPoll+0x26c>
GET_DESCRIPTOR(USB_CFG_DESCR_PROPS_STRING_VENDOR, usbDescriptorStringVendor)
SWITCH_CASE(2)
5f2: 92 30 cpi r25, 0x02 ; 2
5f4: 09 f0 breq .+2 ; 0x5f8 <usbPoll+0x25c>
5f6: b4 cf rjmp .-152 ; 0x560 <usbPoll+0x1c4>
GET_DESCRIPTOR(USB_CFG_DESCR_PROPS_STRING_PRODUCT, usbDescriptorStringDevice)
5f8: 82 e6 ldi r24, 0x62 ; 98
5fa: 90 e0 ldi r25, 0x00 ; 0
5fc: 90 93 80 00 sts 0x0080, r25
600: 80 93 7f 00 sts 0x007F, r24
604: 88 e2 ldi r24, 0x28 ; 40
606: ad cf rjmp .-166 ; 0x562 <usbPoll+0x1c6>
#else /* USB_CFG_DESCR_PROPS_STRINGS & USB_PROP_IS_DYNAMIC */
SWITCH_START(rq->wValue.bytes[0])
SWITCH_CASE(0)
GET_DESCRIPTOR(USB_CFG_DESCR_PROPS_STRING_0, usbDescriptorString0)
SWITCH_CASE(1)
GET_DESCRIPTOR(USB_CFG_DESCR_PROPS_STRING_VENDOR, usbDescriptorStringVendor)
608: 8c e4 ldi r24, 0x4C ; 76
60a: 90 e0 ldi r25, 0x00 ; 0
60c: 90 93 80 00 sts 0x0080, r25
610: 80 93 7f 00 sts 0x007F, r24
614: 86 e1 ldi r24, 0x16 ; 22
616: a5 cf rjmp .-182 ; 0x562 <usbPoll+0x1c6>
00000618 <usbInit>:
/* ------------------------------------------------------------------------- */
USB_PUBLIC void usbInit(void)
{
#if USB_INTR_CFG_SET != 0
USB_INTR_CFG |= USB_INTR_CFG_SET;
618: 85 b7 in r24, 0x35 ; 53
61a: 83 60 ori r24, 0x03 ; 3
61c: 85 bf out 0x35, r24 ; 53
#endif
#if USB_INTR_CFG_CLR != 0
USB_INTR_CFG &= ~(USB_INTR_CFG_CLR);
#endif
USB_INTR_ENABLE |= (1 << USB_INTR_ENABLE_BIT);
61e: 8b b7 in r24, 0x3b ; 59
620: 80 64 ori r24, 0x40 ; 64
622: 8b bf out 0x3b, r24 ; 59
/* ------------------------------------------------------------------------- */
static inline void usbResetDataToggling(void)
{
#if USB_CFG_HAVE_INTRIN_ENDPOINT && !USB_CFG_SUPPRESS_INTR_CODE
USB_SET_DATATOKEN1(USB_INITIAL_DATATOKEN); /* reset data toggling for interrupt endpoint */
624: 8b e4 ldi r24, 0x4B ; 75
626: 80 93 71 00 sts 0x0071, r24
USB_INTR_CFG &= ~(USB_INTR_CFG_CLR);
#endif
USB_INTR_ENABLE |= (1 << USB_INTR_ENABLE_BIT);
usbResetDataToggling();
#if USB_CFG_HAVE_INTRIN_ENDPOINT && !USB_CFG_SUPPRESS_INTR_CODE
usbTxLen1 = USBPID_NAK;
62a: 8a e5 ldi r24, 0x5A ; 90
62c: 80 93 70 00 sts 0x0070, r24
#if USB_CFG_HAVE_INTRIN_ENDPOINT3
usbTxLen3 = USBPID_NAK;
#endif
#endif
}
630: 08 95 ret
00000632 <usbCrc16>:
632: a8 2f mov r26, r24
634: b9 2f mov r27, r25
636: 80 e0 ldi r24, 0x00 ; 0
638: 90 e0 ldi r25, 0x00 ; 0
63a: 41 e0 ldi r20, 0x01 ; 1
63c: 50 ea ldi r21, 0xA0 ; 160
63e: 60 95 com r22
640: 30 e0 ldi r19, 0x00 ; 0
642: 09 c0 rjmp .+18 ; 0x656 <usbCrcLoopEntry>
00000644 <usbCrcByteLoop>:
644: 2d 91 ld r18, X+
646: 82 27 eor r24, r18
00000648 <usbCrcBitLoop>:
648: 97 95 ror r25
64a: 87 95 ror r24
64c: 10 f0 brcs .+4 ; 0x652 <usbCrcNoXor>
64e: 84 27 eor r24, r20
650: 95 27 eor r25, r21
00000652 <usbCrcNoXor>:
652: 30 5e subi r19, 0xE0 ; 224
654: c8 f3 brcs .-14 ; 0x648 <usbCrcBitLoop>
00000656 <usbCrcLoopEntry>:
656: 6f 5f subi r22, 0xFF ; 255
658: a8 f3 brcs .-22 ; 0x644 <usbCrcByteLoop>
0000065a <usbCrcReady>:
65a: 08 95 ret
0000065c <usbCrc16Append>:
65c: ea df rcall .-44 ; 0x632 <usbCrc16>
65e: 8d 93 st X+, r24
660: 9d 93 st X+, r25
662: 08 95 ret
00000664 <usbMeasureFrameLength>:
664: a6 e0 ldi r26, 0x06 ; 6
666: 88 27 eor r24, r24
668: 99 27 eor r25, r25
0000066a <usbMFTime16>:
66a: aa 95 dec r26
66c: 69 f0 breq .+26 ; 0x688 <usbMFTimeout>
0000066e <usbMFWaitStrobe>:
66e: 01 97 sbiw r24, 0x01 ; 1
670: e1 f3 breq .-8 ; 0x66a <usbMFTime16>
672: b0 99 sbic 0x16, 0 ; 22
674: fc cf rjmp .-8 ; 0x66e <usbMFWaitStrobe>
00000676 <usbMFWaitIdle>:
676: b0 9b sbis 0x16, 0 ; 22
678: fe cf rjmp .-4 ; 0x676 <usbMFWaitIdle>
67a: 81 e0 ldi r24, 0x01 ; 1
67c: 99 27 eor r25, r25
0000067e <usbMFWaitLoop>:
67e: a6 b3 in r26, 0x16 ; 22
680: 01 96 adiw r24, 0x01 ; 1
682: 11 f0 breq .+4 ; 0x688 <usbMFTimeout>
684: a5 70 andi r26, 0x05 ; 5
686: d9 f7 brne .-10 ; 0x67e <usbMFWaitLoop>
00000688 <usbMFTimeout>:
688: 08 95 ret
0000068a <__vector_1>:
68a: cf 93 push r28
68c: cf b7 in r28, 0x3f ; 63
68e: cf 93 push r28
00000690 <waitForJ>:
690: c3 95 inc r28
692: b0 9b sbis 0x16, 0 ; 22
694: e9 f7 brne .-6 ; 0x690 <waitForJ>
00000696 <waitForK>:
696: b0 9b sbis 0x16, 0 ; 22
698: 0b c0 rjmp .+22 ; 0x6b0 <foundK>
69a: b0 9b sbis 0x16, 0 ; 22
69c: 09 c0 rjmp .+18 ; 0x6b0 <foundK>
69e: b0 9b sbis 0x16, 0 ; 22
6a0: 07 c0 rjmp .+14 ; 0x6b0 <foundK>
6a2: b0 9b sbis 0x16, 0 ; 22
6a4: 05 c0 rjmp .+10 ; 0x6b0 <foundK>
6a6: b0 9b sbis 0x16, 0 ; 22
6a8: 03 c0 rjmp .+6 ; 0x6b0 <foundK>
6aa: b0 9b sbis 0x16, 0 ; 22
6ac: 01 c0 rjmp .+2 ; 0x6b0 <foundK>
6ae: d5 c0 rjmp .+426 ; 0x85a <sofError>
000006b0 <foundK>:
6b0: 0f 92 push r0
6b2: df 93 push r29
6b4: c0 91 7e 00 lds r28, 0x007E
6b8: dd 27 eor r29, r29
6ba: cb 57 subi r28, 0x7B ; 123
6bc: df 4f sbci r29, 0xFF ; 255
6be: 01 2e mov r0, r17
6c0: b0 9b sbis 0x16, 0 ; 22
6c2: 03 c0 rjmp .+6 ; 0x6ca <haveTwoBitsK>
6c4: df 91 pop r29
6c6: 0f 90 pop r0
6c8: e6 cf rjmp .-52 ; 0x696 <waitForK>
000006ca <haveTwoBitsK>:
6ca: 2f 93 push r18
6cc: 0f 93 push r16
6ce: 1f 93 push r17
6d0: 4f 93 push r20
6d2: 2f ef ldi r18, 0xFF ; 255
6d4: 4f 6f ori r20, 0xFF ; 255
6d6: 06 b3 in r16, 0x16 ; 22
6d8: 00 fb bst r16, 0
6da: 20 f9 bld r18, 0
6dc: 5f 93 push r21
6de: 3f 93 push r19
6e0: 50 e0 ldi r21, 0x00 ; 0
6e2: 3b e0 ldi r19, 0x0B ; 11
6e4: 65 c0 rjmp .+202 ; 0x7b0 <rxbit1>
000006e6 <continueWithBit5>:
6e6: 16 b3 in r17, 0x16 ; 22
6e8: 01 26 eor r0, r17
6ea: 50 29 or r21, r0
6ec: 50 fd sbrc r21, 0
6ee: c8 95 lpm
6f0: 56 b3 in r21, 0x16 ; 22
6f2: 01 27 eor r16, r17
6f4: 00 fb bst r16, 0
6f6: 25 f9 bld r18, 5
6f8: 2f 73 andi r18, 0x3F ; 63
6fa: 06 b3 in r16, 0x16 ; 22
6fc: b1 f0 breq .+44 ; 0x72a <unstuff5>
6fe: 50 27 eor r21, r16
700: 10 27 eor r17, r16
702: 10 fb bst r17, 0
704: 26 f9 bld r18, 6
00000706 <didUnstuff6>:
706: 06 b2 in r0, 0x16 ; 22
708: 22 30 cpi r18, 0x02 ; 2
70a: f0 f0 brcs .+60 ; 0x748 <unstuff6>
0000070c <didUnstuff5>:
70c: 00 c0 rjmp .+0 ; 0x70e <didUnstuff5+0x2>
70e: 16 b3 in r17, 0x16 ; 22
710: 01 27 eor r16, r17
712: 00 fb bst r16, 0
714: 27 f9 bld r18, 7
00000716 <didUnstuff7>:
716: 01 26 eor r0, r17
718: 50 29 or r21, r0
71a: 06 b2 in r0, 0x16 ; 22
71c: 24 30 cpi r18, 0x04 ; 4
71e: e8 f5 brcc .+122 ; 0x79a <rxLoop>
00000720 <unstuff7>:
720: 4f 77 andi r20, 0x7F ; 127
722: 20 68 ori r18, 0x80 ; 128
724: 16 b3 in r17, 0x16 ; 22
726: 00 00 nop
728: f6 cf rjmp .-20 ; 0x716 <didUnstuff7>
0000072a <unstuff5>:
72a: 50 27 eor r21, r16
72c: 4f 7d andi r20, 0xDF ; 223
72e: 20 62 ori r18, 0x20 ; 32
730: 06 b2 in r0, 0x16 ; 22
732: 10 2f mov r17, r16
734: 00 00 nop
736: 00 c0 rjmp .+0 ; 0x738 <unstuff5+0xe>
738: 06 b3 in r16, 0x16 ; 22
73a: 00 26 eor r0, r16
73c: 50 29 or r21, r0
73e: 10 27 eor r17, r16
740: 10 fb bst r17, 0
742: 26 f9 bld r18, 6
744: 06 b2 in r0, 0x16 ; 22
746: e2 cf rjmp .-60 ; 0x70c <didUnstuff5>
00000748 <unstuff6>:
748: 4f 7b andi r20, 0xBF ; 191
74a: 06 b3 in r16, 0x16 ; 22
74c: 20 64 ori r18, 0x40 ; 64
74e: 00 c0 rjmp .+0 ; 0x750 <unstuff6+0x8>
750: da cf rjmp .-76 ; 0x706 <didUnstuff6>
00000752 <unstuff0>:
752: 01 26 eor r0, r17
754: 50 29 or r21, r0
756: 15 70 andi r17, 0x05 ; 5
758: 06 b2 in r0, 0x16 ; 22
75a: 69 f1 breq .+90 ; 0x7b6 <didUnstuff0>
75c: 4e 7f andi r20, 0xFE ; 254
75e: 21 60 ori r18, 0x01 ; 1
760: 01 2f mov r16, r17
762: 16 b3 in r17, 0x16 ; 22
764: 28 c0 rjmp .+80 ; 0x7b6 <didUnstuff0>
00000766 <unstuff1>:
766: 00 26 eor r0, r16
768: 50 29 or r21, r0
76a: 4d 7f andi r20, 0xFD ; 253
76c: 06 b2 in r0, 0x16 ; 22
76e: 22 60 ori r18, 0x02 ; 2
770: 10 2f mov r17, r16
772: 29 c0 rjmp .+82 ; 0x7c6 <didUnstuff1>
00000774 <unstuff2>:
774: 01 26 eor r0, r17
776: 50 29 or r21, r0
778: 4b 7f andi r20, 0xFB ; 251
77a: 06 b2 in r0, 0x16 ; 22
77c: 24 60 ori r18, 0x04 ; 4
77e: 01 2f mov r16, r17
780: 2d c0 rjmp .+90 ; 0x7dc <didUnstuff2>
00000782 <unstuff3>:
782: 16 b3 in r17, 0x16 ; 22
784: 01 26 eor r0, r17
786: 50 29 or r21, r0
788: 47 7f andi r20, 0xF7 ; 247
78a: 28 60 ori r18, 0x08 ; 8
78c: 00 00 nop
78e: 06 b2 in r0, 0x16 ; 22
790: 2e c0 rjmp .+92 ; 0x7ee <didUnstuff3>
00000792 <unstuff4>:
792: 4f 7e andi r20, 0xEF ; 239
794: 06 b3 in r16, 0x16 ; 22
796: 20 61 ori r18, 0x10 ; 16
798: 30 c0 rjmp .+96 ; 0x7fa <didUnstuff4>
0000079a <rxLoop>:
79a: 42 27 eor r20, r18
79c: 06 b3 in r16, 0x16 ; 22
79e: 49 93 st Y+, r20
7a0: 00 26 eor r0, r16
7a2: 50 29 or r21, r0
7a4: 10 27 eor r17, r16
7a6: 06 b2 in r0, 0x16 ; 22
7a8: 4f ef ldi r20, 0xFF ; 255
7aa: 10 fb bst r17, 0
7ac: 20 f9 bld r18, 0
7ae: 29 7f andi r18, 0xF9 ; 249
000007b0 <rxbit1>:
7b0: 16 b3 in r17, 0x16 ; 22
7b2: 79 f2 breq .-98 ; 0x752 <unstuff0>
7b4: 15 70 andi r17, 0x05 ; 5
000007b6 <didUnstuff0>:
7b6: 59 f1 breq .+86 ; 0x80e <se0>
7b8: 01 26 eor r0, r17
7ba: 50 29 or r21, r0
7bc: 06 b2 in r0, 0x16 ; 22
7be: 01 27 eor r16, r17
7c0: 00 fb bst r16, 0
7c2: 21 f9 bld r18, 1
7c4: 23 7f andi r18, 0xF3 ; 243
000007c6 <didUnstuff1>:
7c6: 06 b3 in r16, 0x16 ; 22
7c8: 71 f2 breq .-100 ; 0x766 <unstuff1>
7ca: 00 26 eor r0, r16
7cc: 50 29 or r21, r0
7ce: 31 50 subi r19, 0x01 ; 1
7d0: d0 f0 brcs .+52 ; 0x806 <overflow>
7d2: 06 b2 in r0, 0x16 ; 22
7d4: 10 27 eor r17, r16
7d6: 10 fb bst r17, 0
7d8: 22 f9 bld r18, 2
7da: 27 7e andi r18, 0xE7 ; 231
000007dc <didUnstuff2>:
7dc: 16 b3 in r17, 0x16 ; 22
7de: 51 f2 breq .-108 ; 0x774 <unstuff2>
7e0: 01 26 eor r0, r17
7e2: 50 29 or r21, r0
7e4: 01 27 eor r16, r17
7e6: 00 fb bst r16, 0
7e8: 06 b2 in r0, 0x16 ; 22
7ea: 23 f9 bld r18, 3
7ec: 2f 7c andi r18, 0xCF ; 207
000007ee <didUnstuff3>:
7ee: 49 f2 breq .-110 ; 0x782 <unstuff3>
7f0: 00 00 nop
7f2: 06 b3 in r16, 0x16 ; 22
7f4: 10 27 eor r17, r16
7f6: 10 fb bst r17, 0
7f8: 24 f9 bld r18, 4
000007fa <didUnstuff4>:
7fa: 00 26 eor r0, r16
7fc: 50 29 or r21, r0
7fe: 06 b2 in r0, 0x16 ; 22
800: 2f 79 andi r18, 0x9F ; 159
802: 39 f2 breq .-114 ; 0x792 <unstuff4>
804: 70 cf rjmp .-288 ; 0x6e6 <continueWithBit5>
00000806 <overflow>:
806: 10 e4 ldi r17, 0x40 ; 64
808: 1a bf out 0x3a, r17 ; 58
0000080a <ignorePacket>:
80a: 00 27 eor r16, r16
80c: 19 c0 rjmp .+50 ; 0x840 <handleSetupOrOut>
0000080e <se0>:
80e: 3b 50 subi r19, 0x0B ; 11
810: 31 95 neg r19
812: c3 1b sub r28, r19
814: d0 40 sbci r29, 0x00 ; 0
816: 10 e4 ldi r17, 0x40 ; 64
818: 1a bf out 0x3a, r17 ; 58
81a: 08 81 ld r16, Y
81c: 03 3c cpi r16, 0xC3 ; 195
81e: 09 f1 breq .+66 ; 0x862 <handleData>
820: 0b 34 cpi r16, 0x4B ; 75
822: f9 f0 breq .+62 ; 0x862 <handleData>
824: 20 91 7c 00 lds r18, 0x007C
828: 19 81 ldd r17, Y+1 ; 0x01
82a: 11 0f add r17, r17
82c: 12 13 cpse r17, r18
82e: ed cf rjmp .-38 ; 0x80a <ignorePacket>
830: 4a 81 ldd r20, Y+2 ; 0x02
832: 44 1f adc r20, r20
834: 09 36 cpi r16, 0x69 ; 105
836: 51 f1 breq .+84 ; 0x88c <handleIn>
838: 0d 32 cpi r16, 0x2D ; 45
83a: 11 f0 breq .+4 ; 0x840 <handleSetupOrOut>
83c: 01 3e cpi r16, 0xE1 ; 225
83e: 29 f7 brne .-54 ; 0x80a <ignorePacket>
00000840 <handleSetupOrOut>:
840: 00 93 83 00 sts 0x0083, r16
00000844 <doReturn>:
844: 3f 91 pop r19
846: 5f 91 pop r21
848: 4f 91 pop r20
84a: 1f 91 pop r17
84c: 0f 91 pop r16
84e: 2f 91 pop r18
850: df 91 pop r29
852: 0f 90 pop r0
854: ca b7 in r28, 0x3a ; 58
856: c6 fd sbrc r28, 6
858: 1b cf rjmp .-458 ; 0x690 <waitForJ>
0000085a <sofError>:
85a: cf 91 pop r28
85c: cf bf out 0x3f, r28 ; 63
85e: cf 91 pop r28
860: 18 95 reti
00000862 <handleData>:
862: 20 91 83 00 lds r18, 0x0083
866: 22 23 and r18, r18
868: 69 f3 breq .-38 ; 0x844 <doReturn>
86a: 10 91 81 00 lds r17, 0x0081
86e: 11 23 and r17, r17
870: 79 f5 brne .+94 ; 0x8d0 <sendNakAndReti>
872: 34 30 cpi r19, 0x04 ; 4
874: 7a f1 brmi .+94 ; 0x8d4 <sendAckAndReti>
876: 30 93 81 00 sts 0x0081, r19
87a: 20 93 7d 00 sts 0x007D, r18
87e: 10 91 7e 00 lds r17, 0x007E
882: 3b e0 ldi r19, 0x0B ; 11
884: 31 1b sub r19, r17
886: 30 93 7e 00 sts 0x007E, r19
88a: 24 c0 rjmp .+72 ; 0x8d4 <sendAckAndReti>
0000088c <handleIn>:
88c: 00 91 81 00 lds r16, 0x0081
890: 01 30 cpi r16, 0x01 ; 1
892: f4 f4 brge .+60 ; 0x8d0 <sendNakAndReti>
894: 0a e5 ldi r16, 0x5A ; 90
896: 4f 70 andi r20, 0x0F ; 15
898: 49 f4 brne .+18 ; 0x8ac <handleIn1>
89a: 30 91 60 00 lds r19, 0x0060
89e: 34 fd sbrc r19, 4
8a0: 1a c0 rjmp .+52 ; 0x8d6 <sendCntAndReti>
8a2: 00 93 60 00 sts 0x0060, r16
8a6: c5 e6 ldi r28, 0x65 ; 101
8a8: d0 e0 ldi r29, 0x00 ; 0
8aa: 19 c0 rjmp .+50 ; 0x8de <usbSendAndReti>
000008ac <handleIn1>:
8ac: 30 91 70 00 lds r19, 0x0070
8b0: 34 fd sbrc r19, 4
8b2: 11 c0 rjmp .+34 ; 0x8d6 <sendCntAndReti>
8b4: 00 93 70 00 sts 0x0070, r16
8b8: c1 e7 ldi r28, 0x71 ; 113
8ba: d0 e0 ldi r29, 0x00 ; 0
8bc: 10 c0 rjmp .+32 ; 0x8de <usbSendAndReti>
000008be <bitstuff7>:
8be: 05 27 eor r16, r21
8c0: 10 e0 ldi r17, 0x00 ; 0
8c2: 00 c0 rjmp .+0 ; 0x8c4 <bitstuff7+0x6>
8c4: 21 c0 rjmp .+66 ; 0x908 <didStuff7>
000008c6 <bitstuffN>:
8c6: 05 27 eor r16, r21
8c8: 10 e0 ldi r17, 0x00 ; 0
8ca: c8 95 lpm
8cc: 08 bb out 0x18, r16 ; 24
8ce: 14 c0 rjmp .+40 ; 0x8f8 <didStuffN>
000008d0 <sendNakAndReti>:
8d0: 3a e5 ldi r19, 0x5A ; 90
8d2: 01 c0 rjmp .+2 ; 0x8d6 <sendCntAndReti>
000008d4 <sendAckAndReti>:
8d4: 32 ed ldi r19, 0xD2 ; 210
000008d6 <sendCntAndReti>:
8d6: 03 2e mov r0, r19
8d8: c0 e0 ldi r28, 0x00 ; 0
8da: d0 e0 ldi r29, 0x00 ; 0
8dc: 32 e0 ldi r19, 0x02 ; 2
000008de <usbSendAndReti>:
8de: 17 b3 in r17, 0x17 ; 23
8e0: 15 60 ori r17, 0x05 ; 5
8e2: c0 9a sbi 0x18, 0 ; 24
8e4: 08 b3 in r16, 0x18 ; 24
8e6: 17 bb out 0x17, r17 ; 23
8e8: 55 e0 ldi r21, 0x05 ; 5
8ea: 20 e8 ldi r18, 0x80 ; 128
8ec: 4f ef ldi r20, 0xFF ; 255
000008ee <bitloop>:
8ee: 20 ff sbrs r18, 0
8f0: 05 27 eor r16, r21
8f2: 08 bb out 0x18, r16 ; 24
8f4: 27 95 ror r18
8f6: 17 95 ror r17
000008f8 <didStuffN>:
8f8: 1c 3f cpi r17, 0xFC ; 252
8fa: 28 f7 brcc .-54 ; 0x8c6 <bitstuffN>
8fc: 00 00 nop
8fe: 45 52 subi r20, 0x25 ; 37
900: b0 f7 brcc .-20 ; 0x8ee <bitloop>
902: 20 ff sbrs r18, 0
904: 05 27 eor r16, r21
906: 27 95 ror r18
00000908 <didStuff7>:
908: 08 bb out 0x18, r16 ; 24
90a: 17 95 ror r17
90c: 1c 3f cpi r17, 0xFC ; 252
90e: b8 f6 brcc .-82 ; 0x8be <bitstuff7>
910: 29 91 ld r18, Y+
912: 3a 95 dec r19
914: 61 f7 brne .-40 ; 0x8ee <bitloop>
916: 0a 7f andi r16, 0xFA ; 250
918: 10 91 82 00 lds r17, 0x0082
91c: 11 0f add r17, r17
91e: 08 bb out 0x18, r16 ; 24
920: c2 50 subi r28, 0x02 ; 2
922: d0 40 sbci r29, 0x00 ; 0
924: 11 f0 breq .+4 ; 0x92a <skipAddrAssign>
926: 10 93 7c 00 sts 0x007C, r17
0000092a <skipAddrAssign>:
92a: 10 e4 ldi r17, 0x40 ; 64
92c: 1a bf out 0x3a, r17 ; 58
92e: 01 60 ori r16, 0x01 ; 1
930: 17 b3 in r17, 0x17 ; 23
932: 1a 7f andi r17, 0xFA ; 250
934: 40 2f mov r20, r16
936: 4a 7f andi r20, 0xFA ; 250
938: 54 e0 ldi r21, 0x04 ; 4
0000093a <se0Delay>:
93a: 5a 95 dec r21
93c: f1 f7 brne .-4 ; 0x93a <se0Delay>
93e: 08 bb out 0x18, r16 ; 24
940: 17 bb out 0x17, r17 ; 23
942: 48 bb out 0x18, r20 ; 24
944: 7f cf rjmp .-258 ; 0x844 <doReturn>
00000946 <__eerd_byte_tn85>:
946: e1 99 sbic 0x1c, 1 ; 28
948: fe cf rjmp .-4 ; 0x946 <__eerd_byte_tn85>
94a: 9f bb out 0x1f, r25 ; 31
94c: 8e bb out 0x1e, r24 ; 30
94e: e0 9a sbi 0x1c, 0 ; 28
950: 99 27 eor r25, r25
952: 8d b3 in r24, 0x1d ; 29
954: 08 95 ret
00000956 <__eewr_byte_tn85>:
956: 26 2f mov r18, r22
00000958 <__eewr_r18_tn85>:
958: e1 99 sbic 0x1c, 1 ; 28
95a: fe cf rjmp .-4 ; 0x958 <__eewr_r18_tn85>
95c: 1c ba out 0x1c, r1 ; 28
95e: 9f bb out 0x1f, r25 ; 31
960: 8e bb out 0x1e, r24 ; 30
962: 2d bb out 0x1d, r18 ; 29
964: 0f b6 in r0, 0x3f ; 63
966: f8 94 cli
968: e2 9a sbi 0x1c, 2 ; 28
96a: e1 9a sbi 0x1c, 1 ; 28
96c: 0f be out 0x3f, r0 ; 63
96e: 01 96 adiw r24, 0x01 ; 1
970: 08 95 ret
00000972 <_exit>:
972: f8 94 cli
00000974 <__stop_program>:
974: ff cf rjmp .-2 ; 0x974 <__stop_program>