Skip to content

Instantly share code, notes, and snippets.

@kriegsman
Created March 13, 2017 20:24
Show Gist options
  • Save kriegsman/d3b59fce1aa34e1015224a907e23d1a1 to your computer and use it in GitHub Desktop.
Save kriegsman/d3b59fce1aa34e1015224a907e23d1a1 to your computer and use it in GitHub Desktop.
TeensyLC
PaulTeensyLCPaletteBugTest.ino.elf: file format elf32-littlearm
Disassembly of section .text:
00000000 <_VectorsFlash>:
0: 00 18 00 20 c1 00 00 00 c5 15 00 00 91 15 00 00 ... ............
10: 91 15 00 00 91 15 00 00 91 15 00 00 91 15 00 00 ................
20: 91 15 00 00 91 15 00 00 91 15 00 00 c5 15 00 00 ................
30: c5 15 00 00 91 15 00 00 c5 15 00 00 81 15 00 00 ................
40: c5 15 00 00 c5 15 00 00 c5 15 00 00 c5 15 00 00 ................
50: c5 15 00 00 c5 15 00 00 c5 15 00 00 c5 15 00 00 ................
60: c5 15 00 00 c5 15 00 00 c5 15 00 00 c5 15 00 00 ................
70: e1 1b 00 00 6d 20 00 00 f1 25 00 00 c5 15 00 00 ....m ...%......
80: c5 15 00 00 c5 15 00 00 c5 15 00 00 c5 15 00 00 ................
90: c5 15 00 00 c5 15 00 00 c5 15 00 00 c5 15 00 00 ................
a0: 39 0a 00 00 c5 15 00 00 c5 15 00 00 c5 15 00 00 9...............
b0: c5 15 00 00 c5 15 00 00 c5 15 00 00 c5 15 00 00 ................
000000c0 <ResetHandler>:
__attribute__ ((optimize("-Os")))
#else
__attribute__ ((section(".startup"),optimize("-Os")))
#endif
void ResetHandler(void)
{
c0: b538 push {r3, r4, r5, lr}
__asm__ volatile ("nop");
__asm__ volatile ("nop");
#endif
// programs using the watchdog timer or needing to initialize hardware as
// early as possible can implement startup_early_hook()
startup_early_hook();
c2: f001 fa83 bl 15cc <startup_early_hook>
//PORTC_PCR5 = PORT_PCR_MUX(1) | PORT_PCR_DSE | PORT_PCR_SRE;
//GPIOC_PDDR |= (1<<5);
//GPIOC_PSOR = (1<<5);
//while (1);
#elif defined(__MKL26Z64__)
SIM_SCGC4 = SIM_SCGC4_USBOTG | 0xF0000030;
c6: 4a45 ldr r2, [pc, #276] ; (1dc <ResetHandler+0x11c>)
c8: 4b45 ldr r3, [pc, #276] ; (1e0 <ResetHandler+0x120>)
ca: 601a str r2, [r3, #0]
SIM_SCGC5 = 0x00003F82; // clocks active to all GPIO
cc: 4a45 ldr r2, [pc, #276] ; (1e4 <ResetHandler+0x124>)
ce: 4b46 ldr r3, [pc, #280] ; (1e8 <ResetHandler+0x128>)
d0: 601a str r2, [r3, #0]
SIM_SCGC6 = SIM_SCGC6_ADC0 | SIM_SCGC6_TPM0 | SIM_SCGC6_TPM1 | SIM_SCGC6_TPM2 | SIM_SCGC6_FTFL;
d2: 4a46 ldr r2, [pc, #280] ; (1ec <ResetHandler+0x12c>)
d4: 4b46 ldr r3, [pc, #280] ; (1f0 <ResetHandler+0x130>)
d6: 601a str r2, [r3, #0]
RTC_SR = 0;
RTC_CR = RTC_CR_SC16P | RTC_CR_SC4P | RTC_CR_OSCE;
}
#endif
// release I/O pins hold, if we woke up from VLLS mode
if (PMC_REGSC & PMC_REGSC_ACKISO) PMC_REGSC |= PMC_REGSC_ACKISO;
d8: 4b46 ldr r3, [pc, #280] ; (1f4 <ResetHandler+0x134>)
da: 2208 movs r2, #8
dc: 7819 ldrb r1, [r3, #0]
de: 4211 tst r1, r2
e0: d002 beq.n e8 <ResetHandler+0x28>
e2: 7819 ldrb r1, [r3, #0]
e4: 430a orrs r2, r1
e6: 701a strb r2, [r3, #0]
// since this is a write once register, make it visible to all F_CPU's
// so we can into other sleep modes in the future at any speed
#if defined(__MK66FX1M0__)
SMC_PMPROT = SMC_PMPROT_AHSRUN | SMC_PMPROT_AVLP | SMC_PMPROT_ALLS | SMC_PMPROT_AVLLS;
#else
SMC_PMPROT = SMC_PMPROT_AVLP | SMC_PMPROT_ALLS | SMC_PMPROT_AVLLS;
e8: 4b43 ldr r3, [pc, #268] ; (1f8 <ResetHandler+0x138>)
ea: 222a movs r2, #42 ; 0x2a
ec: 701a strb r2, [r3, #0]
#endif
// TODO: do this while the PLL is waiting to lock....
while (dest < &_edata) *dest++ = *src++;
ee: 2300 movs r3, #0
f0: 4a42 ldr r2, [pc, #264] ; (1fc <ResetHandler+0x13c>)
f2: 4943 ldr r1, [pc, #268] ; (200 <ResetHandler+0x140>)
f4: 189a adds r2, r3, r2
f6: 428a cmp r2, r1
f8: d204 bcs.n 104 <ResetHandler+0x44>
fa: 4942 ldr r1, [pc, #264] ; (204 <ResetHandler+0x144>)
fc: 58c9 ldr r1, [r1, r3]
fe: 3304 adds r3, #4
100: 6011 str r1, [r2, #0]
102: e7f5 b.n f0 <ResetHandler+0x30>
104: 4b40 ldr r3, [pc, #256] ; (208 <ResetHandler+0x148>)
dest = &_sbss;
while (dest < &_ebss) *dest++ = 0;
106: 4941 ldr r1, [pc, #260] ; (20c <ResetHandler+0x14c>)
108: 1f1a subs r2, r3, #4
10a: 1d18 adds r0, r3, #4
10c: 2300 movs r3, #0
10e: 428a cmp r2, r1
110: d202 bcs.n 118 <ResetHandler+0x58>
112: 6013 str r3, [r2, #0]
114: 1c03 adds r3, r0, #0
116: e7f6 b.n 106 <ResetHandler+0x46>
// default all interrupts to medium priority level
for (i=0; i < NVIC_NUM_INTERRUPTS + 16; i++) _VectorsRam[i] = _VectorsFlash[i];
118: 493d ldr r1, [pc, #244] ; (210 <ResetHandler+0x150>)
11a: 4a3e ldr r2, [pc, #248] ; (214 <ResetHandler+0x154>)
11c: 5859 ldr r1, [r3, r1]
11e: 1c10 adds r0, r2, #0
120: 5099 str r1, [r3, r2]
122: 3304 adds r3, #4
124: 2bc0 cmp r3, #192 ; 0xc0
126: d1f7 bne.n 118 <ResetHandler+0x58>
128: 2300 movs r3, #0
for (i=0; i < NVIC_NUM_INTERRUPTS; i++) NVIC_SET_PRIORITY(i, 128);
12a: 089a lsrs r2, r3, #2
12c: 493a ldr r1, [pc, #232] ; (218 <ResetHandler+0x158>)
12e: 0092 lsls r2, r2, #2
130: 1852 adds r2, r2, r1
132: 2103 movs r1, #3
134: 4019 ands r1, r3
136: 00c9 lsls r1, r1, #3
138: 6815 ldr r5, [r2, #0]
13a: 24ff movs r4, #255 ; 0xff
13c: 408c lsls r4, r1
13e: 43a5 bics r5, r4
140: 1c2c adds r4, r5, #0
142: 2580 movs r5, #128 ; 0x80
144: 408d lsls r5, r1
146: 1c29 adds r1, r5, #0
148: 4321 orrs r1, r4
14a: 3301 adds r3, #1
14c: 6011 str r1, [r2, #0]
14e: 2b20 cmp r3, #32
150: d1eb bne.n 12a <ResetHandler+0x6a>
SCB_VTOR = (uint32_t)_VectorsRam; // use vector table in RAM
152: 4b32 ldr r3, [pc, #200] ; (21c <ResetHandler+0x15c>)
#if defined(KINETISK)
// enable capacitors for crystal
OSC0_CR = OSC_SC8P | OSC_SC2P;
#elif defined(KINETISL)
// enable capacitors for crystal
OSC0_CR = OSC_SC8P | OSC_SC2P | OSC_ERCLKEN;
154: 228a movs r2, #138 ; 0x8a
while (dest < &_ebss) *dest++ = 0;
// default all interrupts to medium priority level
for (i=0; i < NVIC_NUM_INTERRUPTS + 16; i++) _VectorsRam[i] = _VectorsFlash[i];
for (i=0; i < NVIC_NUM_INTERRUPTS; i++) NVIC_SET_PRIORITY(i, 128);
SCB_VTOR = (uint32_t)_VectorsRam; // use vector table in RAM
156: 6018 str r0, [r3, #0]
#if defined(KINETISK)
// enable capacitors for crystal
OSC0_CR = OSC_SC8P | OSC_SC2P;
#elif defined(KINETISL)
// enable capacitors for crystal
OSC0_CR = OSC_SC8P | OSC_SC2P | OSC_ERCLKEN;
158: 4b31 ldr r3, [pc, #196] ; (220 <ResetHandler+0x160>)
15a: 701a strb r2, [r3, #0]
#endif
// enable osc, 8-32 MHz range, low power mode
MCG_C2 = MCG_C2_RANGE0(2) | MCG_C2_EREFS;
15c: 4b31 ldr r3, [pc, #196] ; (224 <ResetHandler+0x164>)
15e: 2224 movs r2, #36 ; 0x24
160: 705a strb r2, [r3, #1]
// switch to crystal as clock source, FLL input = 16 MHz / 512
MCG_C1 = MCG_C1_CLKS(2) | MCG_C1_FRDIV(4);
162: 22a0 movs r2, #160 ; 0xa0
164: 701a strb r2, [r3, #0]
// wait for crystal oscillator to begin
while ((MCG_S & MCG_S_OSCINIT0) == 0) ;
166: 799a ldrb r2, [r3, #6]
168: 0791 lsls r1, r2, #30
16a: d5fc bpl.n 166 <ResetHandler+0xa6>
// wait for FLL to use oscillator
while ((MCG_S & MCG_S_IREFST) != 0) ;
16c: 799a ldrb r2, [r3, #6]
16e: 06d5 lsls r5, r2, #27
170: d4fc bmi.n 16c <ResetHandler+0xac>
// wait for MCGOUT to use oscillator
while ((MCG_S & MCG_S_CLKST_MASK) != MCG_S_CLKST(2)) ;
172: 7998 ldrb r0, [r3, #6]
174: 210c movs r1, #12
176: 4a2b ldr r2, [pc, #172] ; (224 <ResetHandler+0x164>)
178: 4001 ands r1, r0
17a: 2908 cmp r1, #8
17c: d1f9 bne.n 172 <ResetHandler+0xb2>
#endif
#else
#if F_CPU == 72000000
MCG_C5 = MCG_C5_PRDIV0(5); // config PLL input for 16 MHz Crystal / 6 = 2.667 Hz
#else
MCG_C5 = MCG_C5_PRDIV0(3); // config PLL input for 16 MHz Crystal / 4 = 4 MHz
17e: 2103 movs r1, #3
180: 7111 strb r1, [r2, #4]
#elif F_CPU == 120000000
MCG_C6 = MCG_C6_PLLS | MCG_C6_VDIV0(6); // config PLL for 120 MHz output
#elif F_CPU == 72000000
MCG_C6 = MCG_C6_PLLS | MCG_C6_VDIV0(3); // config PLL for 72 MHz output
#elif F_CPU == 96000000 || F_CPU == 48000000 || F_CPU == 24000000
MCG_C6 = MCG_C6_PLLS | MCG_C6_VDIV0(0); // config PLL for 96 MHz output
182: 2140 movs r1, #64 ; 0x40
184: 7151 strb r1, [r2, #5]
#error "This clock speed isn't supported..."
#endif
#endif
// wait for PLL to start using xtal as its input
while (!(MCG_S & MCG_S_PLLST)) ;
186: 799a ldrb r2, [r3, #6]
188: 0691 lsls r1, r2, #26
18a: d5fc bpl.n 186 <ResetHandler+0xc6>
// wait for PLL to lock
while (!(MCG_S & MCG_S_LOCK0)) ;
18c: 799a ldrb r2, [r3, #6]
18e: 0655 lsls r5, r2, #25
190: d5fc bpl.n 18c <ResetHandler+0xcc>
// config divisors: 48 MHz core, 48 MHz bus, 24 MHz flash, USB = 96 / 2
#if defined(KINETISK)
SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(1) | SIM_CLKDIV1_OUTDIV2(1) | SIM_CLKDIV1_OUTDIV3(1) | SIM_CLKDIV1_OUTDIV4(3);
SIM_CLKDIV2 = SIM_CLKDIV2_USBDIV(1);
#elif defined(KINETISL)
SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(1) | SIM_CLKDIV1_OUTDIV4(1);
192: 4925 ldr r1, [pc, #148] ; (228 <ResetHandler+0x168>)
194: 4a25 ldr r2, [pc, #148] ; (22c <ResetHandler+0x16c>)
196: 6011 str r1, [r2, #0]
#error "Error, F_CPU must be 192, 180, 168, 144, 120, 96, 72, 48, 24, 16, 8, 4, or 2 MHz"
#endif
#if F_CPU > 16000000
// switch to PLL as clock source, FLL input = 16 MHz / 512
MCG_C1 = MCG_C1_CLKS(0) | MCG_C1_FRDIV(4);
198: 4a22 ldr r2, [pc, #136] ; (224 <ResetHandler+0x164>)
19a: 2120 movs r1, #32
19c: 7011 strb r1, [r2, #0]
// wait for PLL clock to be used
while ((MCG_S & MCG_S_CLKST_MASK) != MCG_S_CLKST(3)) ;
19e: 7999 ldrb r1, [r3, #6]
1a0: 220c movs r2, #12
1a2: 400a ands r2, r1
1a4: 2a0c cmp r2, #12
1a6: d1fa bne.n 19e <ResetHandler+0xde>
SIM_SOPT2 = SIM_SOPT2_USBSRC | SIM_SOPT2_IRC48SEL | SIM_SOPT2_TRACECLKSEL | SIM_SOPT2_CLKOUTSEL(6);
#else
SIM_SOPT2 = SIM_SOPT2_USBSRC | SIM_SOPT2_PLLFLLSEL | SIM_SOPT2_TRACECLKSEL | SIM_SOPT2_CLKOUTSEL(6);
#endif
#elif defined(KINETISL)
SIM_SOPT2 = SIM_SOPT2_USBSRC | SIM_SOPT2_PLLFLLSEL | SIM_SOPT2_CLKOUTSEL(6)
1a8: 4a21 ldr r2, [pc, #132] ; (230 <ResetHandler+0x170>)
1aa: 4b22 ldr r3, [pc, #136] ; (234 <ResetHandler+0x174>)
1ac: 601a str r2, [r3, #0]
// since we are not going into "stop mode" i removed it
SMC_PMCTRL = SMC_PMCTRL_RUNM(2); // VLPR mode :-)
#endif
// initialize the SysTick counter
SYST_RVR = (F_CPU / 1000) - 1;
1ae: 4a22 ldr r2, [pc, #136] ; (238 <ResetHandler+0x178>)
1b0: 4b22 ldr r3, [pc, #136] ; (23c <ResetHandler+0x17c>)
1b2: 601a str r2, [r3, #0]
SYST_CVR = 0;
1b4: 4b22 ldr r3, [pc, #136] ; (240 <ResetHandler+0x180>)
1b6: 2200 movs r2, #0
1b8: 601a str r2, [r3, #0]
SYST_CSR = SYST_CSR_CLKSOURCE | SYST_CSR_TICKINT | SYST_CSR_ENABLE;
1ba: 4b22 ldr r3, [pc, #136] ; (244 <ResetHandler+0x184>)
1bc: 2207 movs r2, #7
1be: 601a str r2, [r3, #0]
SCB_SHPR3 = 0x20200000; // Systick = priority 32
1c0: 4a21 ldr r2, [pc, #132] ; (248 <ResetHandler+0x188>)
1c2: 4b22 ldr r3, [pc, #136] ; (24c <ResetHandler+0x18c>)
1c4: 601a str r2, [r3, #0]
//init_pins();
__enable_irq();
1c6: b662 cpsie i
_init_Teensyduino_internal_();
1c8: f000 fb10 bl 7ec <_init_Teensyduino_internal_>
#endif
*(uint32_t *)0x4003E01C = 0;
}
#endif
__libc_init_array();
1cc: f002 fd82 bl 2cd4 <__libc_init_array>
startup_late_hook();
1d0: f001 fa02 bl 15d8 <startup_late_hook>
main();
1d4: f001 f932 bl 143c <main>
1d8: e7fe b.n 1d8 <ResetHandler+0x118>
1da: 46c0 nop ; (mov r8, r8)
1dc: f0040030 .word 0xf0040030
1e0: 40048034 .word 0x40048034
1e4: 00003f82 .word 0x00003f82
1e8: 40048038 .word 0x40048038
1ec: 0f000001 .word 0x0f000001
1f0: 4004803c .word 0x4004803c
1f4: 4007d002 .word 0x4007d002
1f8: 4007e000 .word 0x4007e000
1fc: 1ffffd60 .word 0x1ffffd60
200: 1ffffe08 .word 0x1ffffe08
204: 00003078 .word 0x00003078
208: 1ffffe0c .word 0x1ffffe0c
20c: 20000140 .word 0x20000140
210: 00000000 .word 0x00000000
214: 1ffff900 .word 0x1ffff900
218: e000e400 .word 0xe000e400
21c: e000ed08 .word 0xe000ed08
220: 40065000 .word 0x40065000
224: 40064000 .word 0x40064000
228: 10010000 .word 0x10010000
22c: 40048044 .word 0x40048044
230: 050500c0 .word 0x050500c0
234: 40048004 .word 0x40048004
238: 0000bb7f .word 0x0000bb7f
23c: e000e014 .word 0xe000e014
240: e000e018 .word 0xe000e018
244: e000e010 .word 0xe000e010
248: 20200000 .word 0x20200000
24c: e000ed20 .word 0xe000ed20
250: ffffffff .word 0xffffffff
254: ffffffff .word 0xffffffff
258: ffffffff .word 0xffffffff
25c: ffffffff .word 0xffffffff
260: ffffffff .word 0xffffffff
264: ffffffff .word 0xffffffff
268: ffffffff .word 0xffffffff
26c: ffffffff .word 0xffffffff
270: ffffffff .word 0xffffffff
274: ffffffff .word 0xffffffff
278: ffffffff .word 0xffffffff
27c: ffffffff .word 0xffffffff
280: ffffffff .word 0xffffffff
284: ffffffff .word 0xffffffff
288: ffffffff .word 0xffffffff
28c: ffffffff .word 0xffffffff
290: ffffffff .word 0xffffffff
294: ffffffff .word 0xffffffff
298: ffffffff .word 0xffffffff
29c: ffffffff .word 0xffffffff
2a0: ffffffff .word 0xffffffff
2a4: ffffffff .word 0xffffffff
2a8: ffffffff .word 0xffffffff
2ac: ffffffff .word 0xffffffff
2b0: ffffffff .word 0xffffffff
2b4: ffffffff .word 0xffffffff
2b8: ffffffff .word 0xffffffff
2bc: ffffffff .word 0xffffffff
2c0: ffffffff .word 0xffffffff
2c4: ffffffff .word 0xffffffff
2c8: ffffffff .word 0xffffffff
2cc: ffffffff .word 0xffffffff
2d0: ffffffff .word 0xffffffff
2d4: ffffffff .word 0xffffffff
2d8: ffffffff .word 0xffffffff
2dc: ffffffff .word 0xffffffff
2e0: ffffffff .word 0xffffffff
2e4: ffffffff .word 0xffffffff
2e8: ffffffff .word 0xffffffff
2ec: ffffffff .word 0xffffffff
2f0: ffffffff .word 0xffffffff
2f4: ffffffff .word 0xffffffff
2f8: ffffffff .word 0xffffffff
2fc: ffffffff .word 0xffffffff
300: ffffffff .word 0xffffffff
304: ffffffff .word 0xffffffff
308: ffffffff .word 0xffffffff
30c: ffffffff .word 0xffffffff
310: ffffffff .word 0xffffffff
314: ffffffff .word 0xffffffff
318: ffffffff .word 0xffffffff
31c: ffffffff .word 0xffffffff
320: ffffffff .word 0xffffffff
324: ffffffff .word 0xffffffff
328: ffffffff .word 0xffffffff
32c: ffffffff .word 0xffffffff
330: ffffffff .word 0xffffffff
334: ffffffff .word 0xffffffff
338: ffffffff .word 0xffffffff
33c: ffffffff .word 0xffffffff
340: ffffffff .word 0xffffffff
344: ffffffff .word 0xffffffff
348: ffffffff .word 0xffffffff
34c: ffffffff .word 0xffffffff
350: ffffffff .word 0xffffffff
354: ffffffff .word 0xffffffff
358: ffffffff .word 0xffffffff
35c: ffffffff .word 0xffffffff
360: ffffffff .word 0xffffffff
364: ffffffff .word 0xffffffff
368: ffffffff .word 0xffffffff
36c: ffffffff .word 0xffffffff
370: ffffffff .word 0xffffffff
374: ffffffff .word 0xffffffff
378: ffffffff .word 0xffffffff
37c: ffffffff .word 0xffffffff
380: ffffffff .word 0xffffffff
384: ffffffff .word 0xffffffff
388: ffffffff .word 0xffffffff
38c: ffffffff .word 0xffffffff
390: ffffffff .word 0xffffffff
394: ffffffff .word 0xffffffff
398: ffffffff .word 0xffffffff
39c: ffffffff .word 0xffffffff
3a0: ffffffff .word 0xffffffff
3a4: ffffffff .word 0xffffffff
3a8: ffffffff .word 0xffffffff
3ac: ffffffff .word 0xffffffff
3b0: ffffffff .word 0xffffffff
3b4: ffffffff .word 0xffffffff
3b8: ffffffff .word 0xffffffff
3bc: ffffffff .word 0xffffffff
3c0: ffffffff .word 0xffffffff
3c4: ffffffff .word 0xffffffff
3c8: ffffffff .word 0xffffffff
3cc: ffffffff .word 0xffffffff
3d0: ffffffff .word 0xffffffff
3d4: ffffffff .word 0xffffffff
3d8: ffffffff .word 0xffffffff
3dc: ffffffff .word 0xffffffff
3e0: ffffffff .word 0xffffffff
3e4: ffffffff .word 0xffffffff
3e8: ffffffff .word 0xffffffff
3ec: ffffffff .word 0xffffffff
3f0: ffffffff .word 0xffffffff
3f4: ffffffff .word 0xffffffff
3f8: ffffffff .word 0xffffffff
3fc: ffffffff .word 0xffffffff
00000400 <flashconfigbytes>:
400: ffffffff ffffffff ffffffff fffffffe ................
00000410 <__do_global_dtors_aux>:
410: b510 push {r4, lr}
412: 4c06 ldr r4, [pc, #24] ; (42c <__do_global_dtors_aux+0x1c>)
414: 7823 ldrb r3, [r4, #0]
416: 2b00 cmp r3, #0
418: d107 bne.n 42a <__do_global_dtors_aux+0x1a>
41a: 4b05 ldr r3, [pc, #20] ; (430 <__do_global_dtors_aux+0x20>)
41c: 2b00 cmp r3, #0
41e: d002 beq.n 426 <__do_global_dtors_aux+0x16>
420: 4804 ldr r0, [pc, #16] ; (434 <__do_global_dtors_aux+0x24>)
422: e000 b.n 426 <__do_global_dtors_aux+0x16>
424: bf00 nop
426: 2301 movs r3, #1
428: 7023 strb r3, [r4, #0]
42a: bd10 pop {r4, pc}
42c: 1ffffe08 .word 0x1ffffe08
430: 00000000 .word 0x00000000
434: 00003078 .word 0x00003078
00000438 <frame_dummy>:
438: b508 push {r3, lr}
43a: 4b08 ldr r3, [pc, #32] ; (45c <frame_dummy+0x24>)
43c: 2b00 cmp r3, #0
43e: d003 beq.n 448 <frame_dummy+0x10>
440: 4807 ldr r0, [pc, #28] ; (460 <frame_dummy+0x28>)
442: 4908 ldr r1, [pc, #32] ; (464 <frame_dummy+0x2c>)
444: e000 b.n 448 <frame_dummy+0x10>
446: bf00 nop
448: 4807 ldr r0, [pc, #28] ; (468 <frame_dummy+0x30>)
44a: 6803 ldr r3, [r0, #0]
44c: 2b00 cmp r3, #0
44e: d003 beq.n 458 <frame_dummy+0x20>
450: 4b06 ldr r3, [pc, #24] ; (46c <frame_dummy+0x34>)
452: 2b00 cmp r3, #0
454: d000 beq.n 458 <frame_dummy+0x20>
456: 4798 blx r3
458: bd08 pop {r3, pc}
45a: 46c0 nop ; (mov r8, r8)
45c: 00000000 .word 0x00000000
460: 00003078 .word 0x00003078
464: 1ffffe0c .word 0x1ffffe0c
468: 1ffffe08 .word 0x1ffffe08
46c: 00000000 .word 0x00000000
00000470 <_ZN5Print7printlnEPKc>:
size_t print(double n, int digits = 2) { return printFloat(n, digits); }
size_t print(const Printable &obj) { return obj.printTo(*this); }
size_t println(void);
size_t println(const String &s) { return print(s) + println(); }
size_t println(char c) { return print(c) + println(); }
size_t println(const char s[]) { return print(s) + println(); }
470: b538 push {r3, r4, r5, lr}
472: 1c04 adds r4, r0, #0
class Print
{
public:
Print() : write_error(0) {}
virtual size_t write(uint8_t b) = 0;
size_t write(const char *str) { return write((const uint8_t *)str, strlen(str)); }
474: 1c08 adds r0, r1, #0
size_t print(double n, int digits = 2) { return printFloat(n, digits); }
size_t print(const Printable &obj) { return obj.printTo(*this); }
size_t println(void);
size_t println(const String &s) { return print(s) + println(); }
size_t println(char c) { return print(c) + println(); }
size_t println(const char s[]) { return print(s) + println(); }
476: 1c0d adds r5, r1, #0
class Print
{
public:
Print() : write_error(0) {}
virtual size_t write(uint8_t b) = 0;
size_t write(const char *str) { return write((const uint8_t *)str, strlen(str)); }
478: f002 fc5b bl 2d32 <strlen>
47c: 6823 ldr r3, [r4, #0]
47e: 1c02 adds r2, r0, #0
480: 1c29 adds r1, r5, #0
482: 685b ldr r3, [r3, #4]
484: 1c20 adds r0, r4, #0
486: 4798 blx r3
488: 1c05 adds r5, r0, #0
size_t print(double n, int digits = 2) { return printFloat(n, digits); }
size_t print(const Printable &obj) { return obj.printTo(*this); }
size_t println(void);
size_t println(const String &s) { return print(s) + println(); }
size_t println(char c) { return print(c) + println(); }
size_t println(const char s[]) { return print(s) + println(); }
48a: 1c20 adds r0, r4, #0
48c: f000 ff94 bl 13b8 <_ZN5Print7printlnEv>
490: 1828 adds r0, r5, r0
492: bd38 pop {r3, r4, r5, pc}
00000494 <_ZN13CRGBPalette16aSEPKh>:
// the exact stripe widths at the expense of dropping some colors.
CRGBPalette16( TProgmemRGBGradientPalette_bytes progpal )
{
*this = progpal;
}
CRGBPalette16& operator=( TProgmemRGBGradientPalette_bytes progpal )
494: b5f0 push {r4, r5, r6, r7, lr}
496: b091 sub sp, #68 ; 0x44
498: 900a str r0, [sp, #40] ; 0x28
49a: 1c0c adds r4, r1, #0
{
TRGBGradientPaletteEntryUnion* progent = (TRGBGradientPaletteEntryUnion*)(progpal);
TRGBGradientPaletteEntryUnion u;
// Count entries
uint16_t count = 0;
49c: 2500 movs r5, #0
do {
u.dword = FL_PGM_READ_DWORD_NEAR(progent + count);
49e: 00ab lsls r3, r5, #2
TRGBGradientPaletteEntryUnion* progent = (TRGBGradientPaletteEntryUnion*)(progpal);
TRGBGradientPaletteEntryUnion u;
// Count entries
uint16_t count = 0;
do {
4a0: 5ce6 ldrb r6, [r4, r3]
u.dword = FL_PGM_READ_DWORD_NEAR(progent + count);
count++;;
4a2: 3501 adds r5, #1
4a4: b2ad uxth r5, r5
TRGBGradientPaletteEntryUnion* progent = (TRGBGradientPaletteEntryUnion*)(progpal);
TRGBGradientPaletteEntryUnion u;
// Count entries
uint16_t count = 0;
do {
4a6: 2eff cmp r6, #255 ; 0xff
4a8: d1f9 bne.n 49e <_ZN13CRGBPalette16aSEPKh+0xa>
count++;;
} while ( u.index != 255);
int8_t lastSlotUsed = -1;
u.dword = FL_PGM_READ_DWORD_NEAR( progent);
4aa: 6823 ldr r3, [r4, #0]
CRGB rgbstart( u.r, u.g, u.b);
int indexstart = 0;
4ac: 2000 movs r0, #0
} while ( u.index != 255);
int8_t lastSlotUsed = -1;
u.dword = FL_PGM_READ_DWORD_NEAR( progent);
CRGB rgbstart( u.r, u.g, u.b);
4ae: 041a lsls r2, r3, #16
4b0: 0e12 lsrs r2, r2, #24
4b2: 9205 str r2, [sp, #20]
4b4: 021a lsls r2, r3, #8
4b6: 0e12 lsrs r2, r2, #24
4b8: 9204 str r2, [sp, #16]
4ba: 0e1f lsrs r7, r3, #24
int indexstart = 0;
uint8_t istart8 = 0;
uint8_t iend8 = 0;
while( indexstart < 255) {
progent++;
4bc: 3404 adds r4, #4
u.dword = FL_PGM_READ_DWORD_NEAR( progent);
4be: 6823 ldr r3, [r4, #0]
int indexend = u.index;
CRGB rgbend( u.r, u.g, u.b);
istart8 = indexstart / 16;
4c0: 1100 asrs r0, r0, #4
uint8_t istart8 = 0;
uint8_t iend8 = 0;
while( indexstart < 255) {
progent++;
u.dword = FL_PGM_READ_DWORD_NEAR( progent);
int indexend = u.index;
4c2: b2d9 uxtb r1, r3
CRGB rgbend( u.r, u.g, u.b);
4c4: 041a lsls r2, r3, #16
4c6: 0e12 lsrs r2, r2, #24
uint8_t istart8 = 0;
uint8_t iend8 = 0;
while( indexstart < 255) {
progent++;
u.dword = FL_PGM_READ_DWORD_NEAR( progent);
int indexend = u.index;
4c8: 9102 str r1, [sp, #8]
CRGB rgbend( u.r, u.g, u.b);
4ca: 4669 mov r1, sp
4cc: 760a strb r2, [r1, #24]
4ce: b2d1 uxtb r1, r2
4d0: 021a lsls r2, r3, #8
4d2: 0e12 lsrs r2, r2, #24
4d4: 0e1b lsrs r3, r3, #24
4d6: 910b str r1, [sp, #44] ; 0x2c
4d8: a908 add r1, sp, #32
4da: 700a strb r2, [r1, #0]
4dc: b2d1 uxtb r1, r2
4de: b2da uxtb r2, r3
4e0: 920d str r2, [sp, #52] ; 0x34
istart8 = indexstart / 16;
iend8 = indexend / 16;
4e2: 9a02 ldr r2, [sp, #8]
uint8_t iend8 = 0;
while( indexstart < 255) {
progent++;
u.dword = FL_PGM_READ_DWORD_NEAR( progent);
int indexend = u.index;
CRGB rgbend( u.r, u.g, u.b);
4e4: 910c str r1, [sp, #48] ; 0x30
4e6: 469c mov ip, r3
istart8 = indexstart / 16;
4e8: b2c1 uxtb r1, r0
iend8 = indexend / 16;
4ea: 0913 lsrs r3, r2, #4
if( count < 16) {
4ec: 2d0f cmp r5, #15
4ee: d80c bhi.n 50a <_ZN13CRGBPalette16aSEPKh+0x76>
if( (istart8 <= lastSlotUsed) && (lastSlotUsed < 15)) {
4f0: b272 sxtb r2, r6
4f2: 4290 cmp r0, r2
4f4: dc08 bgt.n 508 <_ZN13CRGBPalette16aSEPKh+0x74>
4f6: 2a0e cmp r2, #14
4f8: dc06 bgt.n 508 <_ZN13CRGBPalette16aSEPKh+0x74>
istart8 = lastSlotUsed + 1;
4fa: 3601 adds r6, #1
4fc: b2f1 uxtb r1, r6
4fe: 1c0a adds r2, r1, #0
500: 4299 cmp r1, r3
502: d200 bcs.n 506 <_ZN13CRGBPalette16aSEPKh+0x72>
504: 1c1a adds r2, r3, #0
506: b2d3 uxtb r3, r2
if( iend8 < istart8) {
iend8 = istart8;
}
}
lastSlotUsed = iend8;
508: b2de uxtb r6, r3
}
/// allow copy construction
inline CRGB(const CRGB& rhs) __attribute__((always_inline))
{
r = rhs.r;
50a: 9805 ldr r0, [sp, #20]
50c: aa0e add r2, sp, #56 ; 0x38
50e: 7010 strb r0, [r2, #0]
g = rhs.g;
b = rhs.b;
510: 7097 strb r7, [r2, #2]
/// allow copy construction
inline CRGB(const CRGB& rhs) __attribute__((always_inline))
{
r = rhs.r;
g = rhs.g;
512: 9804 ldr r0, [sp, #16]
}
/// allow copy construction
inline CRGB(const CRGB& rhs) __attribute__((always_inline))
{
r = rhs.r;
514: 466f mov r7, sp
516: 7e3f ldrb r7, [r7, #24]
g = rhs.g;
518: 7050 strb r0, [r2, #1]
}
/// allow copy construction
inline CRGB(const CRGB& rhs) __attribute__((always_inline))
{
r = rhs.r;
51a: a80f add r0, sp, #60 ; 0x3c
51c: 7007 strb r7, [r0, #0]
g = rhs.g;
51e: af08 add r7, sp, #32
520: 783f ldrb r7, [r7, #0]
522: 7047 strb r7, [r0, #1]
b = rhs.b;
524: 4667 mov r7, ip
526: 7087 strb r7, [r0, #2]
}
fill_gradient_RGB( &(entries[0]), istart8, rgbstart, iend8, rgbend);
528: 9000 str r0, [sp, #0]
52a: 980a ldr r0, [sp, #40] ; 0x28
52c: f000 f85a bl 5e4 <_Z17fill_gradient_RGBP4CRGBtS_tS_>
CRGB rgbstart( u.r, u.g, u.b);
int indexstart = 0;
uint8_t istart8 = 0;
uint8_t iend8 = 0;
while( indexstart < 255) {
530: 9f02 ldr r7, [sp, #8]
532: 2fff cmp r7, #255 ; 0xff
534: d006 beq.n 544 <_ZN13CRGBPalette16aSEPKh+0xb0>
}
/// allow assignment from one RGB struct to another
inline CRGB& operator= (const CRGB& rhs) __attribute__((always_inline))
{
r = rhs.r;
536: 9f0b ldr r7, [sp, #44] ; 0x2c
}
}
lastSlotUsed = iend8;
}
fill_gradient_RGB( &(entries[0]), istart8, rgbstart, iend8, rgbend);
indexstart = indexend;
538: 9802 ldr r0, [sp, #8]
53a: 9705 str r7, [sp, #20]
g = rhs.g;
53c: 9f0c ldr r7, [sp, #48] ; 0x30
53e: 9704 str r7, [sp, #16]
b = rhs.b;
540: 9f0d ldr r7, [sp, #52] ; 0x34
542: e7bb b.n 4bc <_ZN13CRGBPalette16aSEPKh+0x28>
rgbstart = rgbend;
}
return *this;
}
544: 980a ldr r0, [sp, #40] ; 0x28
546: b011 add sp, #68 ; 0x44
548: bdf0 pop {r4, r5, r6, r7, pc}
54a: ffff b510 vsli.32 d27, d0, #31
0000054c <setup>:
// merely having this object created causes the program to crash
// comment out this line to get see the 3 Serial.print() output
LedsMultitask Bordlys;
void setup() {
54c: b510 push {r4, lr}
uint8_t paritytype(void) { return usb_cdc_line_coding[1] >> 8; } // 0=none, 1=odd, 2=even
uint8_t numbits(void) { return usb_cdc_line_coding[1] >> 16; }
uint8_t dtr(void) { return (usb_cdc_line_rtsdtr & USB_SERIAL_DTR) ? 1 : 0; }
uint8_t rts(void) { return (usb_cdc_line_rtsdtr & USB_SERIAL_RTS) ? 1 : 0; }
operator bool() { return usb_configuration &&
(usb_cdc_line_rtsdtr & (USB_SERIAL_DTR | USB_SERIAL_RTS)) &&
54e: 4b12 ldr r3, [pc, #72] ; (598 <setup+0x4c>)
550: 781b ldrb r3, [r3, #0]
552: 2b00 cmp r3, #0
554: d0fb beq.n 54e <setup+0x2>
556: 4b11 ldr r3, [pc, #68] ; (59c <setup+0x50>)
558: 781b ldrb r3, [r3, #0]
uint8_t stopbits(void) { uint8_t b = usb_cdc_line_coding[1]; if (!b) b = 1; return b; }
uint8_t paritytype(void) { return usb_cdc_line_coding[1] >> 8; } // 0=none, 1=odd, 2=even
uint8_t numbits(void) { return usb_cdc_line_coding[1] >> 16; }
uint8_t dtr(void) { return (usb_cdc_line_rtsdtr & USB_SERIAL_DTR) ? 1 : 0; }
uint8_t rts(void) { return (usb_cdc_line_rtsdtr & USB_SERIAL_RTS) ? 1 : 0; }
operator bool() { return usb_configuration &&
55a: 079a lsls r2, r3, #30
55c: d0f7 beq.n 54e <setup+0x2>
(usb_cdc_line_rtsdtr & (USB_SERIAL_DTR | USB_SERIAL_RTS)) &&
((uint32_t)(systick_millis_count - usb_cdc_line_rtsdtr_millis) >= 25);
55e: 4b10 ldr r3, [pc, #64] ; (5a0 <setup+0x54>)
560: 681a ldr r2, [r3, #0]
562: 4b10 ldr r3, [pc, #64] ; (5a4 <setup+0x58>)
564: 681b ldr r3, [r3, #0]
566: 1ad3 subs r3, r2, r3
uint8_t paritytype(void) { return usb_cdc_line_coding[1] >> 8; } // 0=none, 1=odd, 2=even
uint8_t numbits(void) { return usb_cdc_line_coding[1] >> 16; }
uint8_t dtr(void) { return (usb_cdc_line_rtsdtr & USB_SERIAL_DTR) ? 1 : 0; }
uint8_t rts(void) { return (usb_cdc_line_rtsdtr & USB_SERIAL_RTS) ? 1 : 0; }
operator bool() { return usb_configuration &&
(usb_cdc_line_rtsdtr & (USB_SERIAL_DTR | USB_SERIAL_RTS)) &&
568: 2b18 cmp r3, #24
56a: d9f0 bls.n 54e <setup+0x2>
while (!Serial) ; // wait for Arduino Serial Monitor
delay(10);
56c: 200a movs r0, #10
56e: f000 f923 bl 7b8 <delay>
Serial.println("setup begin");
572: 4c0d ldr r4, [pc, #52] ; (5a8 <setup+0x5c>)
574: 490d ldr r1, [pc, #52] ; (5ac <setup+0x60>)
576: 1c20 adds r0, r4, #0
578: f7ff ff7a bl 470 <_ZN5Print7printlnEPKc>
Serial.println("setup2"); // must print 2+ strings to reproduce problem
57c: 1c20 adds r0, r4, #0
57e: 490c ldr r1, [pc, #48] ; (5b0 <setup+0x64>)
580: f7ff ff76 bl 470 <_ZN5Print7printlnEPKc>
size_t printNumberAny(unsigned long n, uint8_t base);
inline size_t printNumber(unsigned long n, uint8_t base, uint8_t sign) __attribute__((always_inline)) {
// when "base" is a constant (pretty much always), the
// compiler optimizes this to a single function call.
if (base == 0) return write((uint8_t)n);
if (base == 10 || base < 2) return printNumberDec(n, sign);
584: 2130 movs r1, #48 ; 0x30
586: 2200 movs r2, #0
588: 1c20 adds r0, r4, #0
58a: f000 ff27 bl 13dc <_ZN5Print14printNumberDecEmh>
size_t println(const char s[]) { return print(s) + println(); }
size_t println(const __FlashStringHelper *f) { return print(f) + println(); }
size_t println(uint8_t b) { return print(b) + println(); }
size_t println(int n) { return print(n) + println(); }
size_t println(unsigned int n) { return print(n) + println(); }
58e: 1c20 adds r0, r4, #0
590: f000 ff12 bl 13b8 <_ZN5Print7printlnEv>
Serial.println(sizeof(LedsMultitask));
}
594: bd10 pop {r4, pc}
596: 46c0 nop ; (mov r8, r8)
598: 1fffff47 .word 0x1fffff47
59c: 1fffff58 .word 0x1fffff58
5a0: 1ffffe64 .word 0x1ffffe64
5a4: 2000013c .word 0x2000013c
5a8: 1fffff5c .word 0x1fffff5c
5ac: 00002d40 .word 0x00002d40
5b0: 00002d4c .word 0x00002d4c
000005b4 <loop>:
void loop() {}
5b4: 4770 bx lr
5b6: ffff b508 vabal.u<illegal width 64> <illegal reg q13.5>, d15, d8
000005b8 <_GLOBAL__sub_I_heatmap_gp>:
5b8: b508 push {r3, lr}
// will be, by definition, different from the widths in the gradient
// palette. This code attempts to preserve "all the colors", rather than
// the exact stripe widths at the expense of dropping some colors.
CRGBPalette16( TProgmemRGBGradientPalette_bytes progpal )
{
*this = progpal;
5ba: 4802 ldr r0, [pc, #8] ; (5c4 <_GLOBAL__sub_I_heatmap_gp+0xc>)
5bc: 4902 ldr r1, [pc, #8] ; (5c8 <_GLOBAL__sub_I_heatmap_gp+0x10>)
5be: f7ff ff69 bl 494 <_ZN13CRGBPalette16aSEPKh>
5c2: bd08 pop {r3, pc}
5c4: 1ffffe24 .word 0x1ffffe24
5c8: 00002d53 .word 0x00002d53
000005cc <_GLOBAL__sub_I_pSmartMatrix>:
// uint32_t CRGB::Squant = ((uint32_t)((__TIME__[4]-'0') * 28))<<16 | ((__TIME__[6]-'0')*50)<<8 | ((__TIME__[7]-'0')*28);
CFastLED::CFastLED() {
// clear out the array of led controllers
// m_nControllers = 0;
m_Scale = 255;
5cc: 4b04 ldr r3, [pc, #16] ; (5e0 <_GLOBAL__sub_I_pSmartMatrix+0x14>)
5ce: 22ff movs r2, #255 ; 0xff
5d0: 701a strb r2, [r3, #0]
m_nFPS = 0;
5d2: 2200 movs r2, #0
5d4: 805a strh r2, [r3, #2]
m_pPowerFunc = NULL;
5d6: 60da str r2, [r3, #12]
m_nPowerData = 0xFFFFFFFF;
5d8: 2201 movs r2, #1
5da: 4252 negs r2, r2
5dc: 609a str r2, [r3, #8]
} else {
m_nMinMicros = 0;
}
}
extern "C" int atexit(void (* /*func*/ )()) { return 0; }
5de: 4770 bx lr
5e0: 1ffffe54 .word 0x1ffffe54
000005e4 <_Z17fill_gradient_RGBP4CRGBtS_tS_>:
void fill_gradient_RGB( CRGB* leds,
uint16_t startpos, CRGB startcolor,
uint16_t endpos, CRGB endcolor )
{
5e4: b5f0 push {r4, r5, r6, r7, lr}
5e6: b089 sub sp, #36 ; 0x24
5e8: 1c1d adds r5, r3, #0
5ea: 9007 str r0, [sp, #28]
5ec: 1c0c adds r4, r1, #0
5ee: 9b0e ldr r3, [sp, #56] ; 0x38
// if the points are in the wrong order, straighten them
if( endpos < startpos ) {
5f0: 428d cmp r5, r1
5f2: d20e bcs.n 612 <_Z17fill_gradient_RGBP4CRGBtS_tS_+0x2e>
}
/// allow assignment from one RGB struct to another
inline CRGB& operator= (const CRGB& rhs) __attribute__((always_inline))
{
r = rhs.r;
5f4: 7817 ldrb r7, [r2, #0]
}
/// allow copy construction
inline CRGB(const CRGB& rhs) __attribute__((always_inline))
{
r = rhs.r;
5f6: 781e ldrb r6, [r3, #0]
}
/// allow assignment from one RGB struct to another
inline CRGB& operator= (const CRGB& rhs) __attribute__((always_inline))
{
r = rhs.r;
5f8: 701f strb r7, [r3, #0]
g = rhs.g;
5fa: 7857 ldrb r7, [r2, #1]
/// allow copy construction
inline CRGB(const CRGB& rhs) __attribute__((always_inline))
{
r = rhs.r;
g = rhs.g;
b = rhs.b;
5fc: 7899 ldrb r1, [r3, #2]
/// allow copy construction
inline CRGB(const CRGB& rhs) __attribute__((always_inline))
{
r = rhs.r;
g = rhs.g;
5fe: 7858 ldrb r0, [r3, #1]
/// allow assignment from one RGB struct to another
inline CRGB& operator= (const CRGB& rhs) __attribute__((always_inline))
{
r = rhs.r;
g = rhs.g;
600: 705f strb r7, [r3, #1]
b = rhs.b;
602: 7897 ldrb r7, [r2, #2]
604: 7091 strb r1, [r2, #2]
606: 1c21 adds r1, r4, #0
608: 709f strb r7, [r3, #2]
60a: 1c2c adds r4, r5, #0
}
/// allow assignment from one RGB struct to another
inline CRGB& operator= (const CRGB& rhs) __attribute__((always_inline))
{
r = rhs.r;
60c: 7016 strb r6, [r2, #0]
g = rhs.g;
60e: 7050 strb r0, [r2, #1]
610: 1c0d adds r5, r1, #0
saccum87 rdistance87;
saccum87 gdistance87;
saccum87 bdistance87;
rdistance87 = (endcolor.r - startcolor.r) << 7;
612: 7816 ldrb r6, [r2, #0]
614: 7818 ldrb r0, [r3, #0]
616: 9602 str r6, [sp, #8]
gdistance87 = (endcolor.g - startcolor.g) << 7;
618: 7857 ldrb r7, [r2, #1]
saccum87 rdistance87;
saccum87 gdistance87;
saccum87 bdistance87;
rdistance87 = (endcolor.r - startcolor.r) << 7;
61a: 1b80 subs r0, r0, r6
gdistance87 = (endcolor.g - startcolor.g) << 7;
61c: 9703 str r7, [sp, #12]
bdistance87 = (endcolor.b - startcolor.b) << 7;
61e: 7892 ldrb r2, [r2, #2]
saccum87 rdistance87;
saccum87 gdistance87;
saccum87 bdistance87;
rdistance87 = (endcolor.r - startcolor.r) << 7;
gdistance87 = (endcolor.g - startcolor.g) << 7;
620: 785f ldrb r7, [r3, #1]
bdistance87 = (endcolor.b - startcolor.b) << 7;
622: 9204 str r2, [sp, #16]
624: 789b ldrb r3, [r3, #2]
saccum87 rdistance87;
saccum87 gdistance87;
saccum87 bdistance87;
rdistance87 = (endcolor.r - startcolor.r) << 7;
gdistance87 = (endcolor.g - startcolor.g) << 7;
626: 9e03 ldr r6, [sp, #12]
bdistance87 = (endcolor.b - startcolor.b) << 7;
628: 1a9b subs r3, r3, r2
62a: 01db lsls r3, r3, #7
62c: 9305 str r3, [sp, #20]
uint16_t pixeldistance = endpos - startpos;
62e: 1b2b subs r3, r5, r4
saccum87 rdistance87;
saccum87 gdistance87;
saccum87 bdistance87;
rdistance87 = (endcolor.r - startcolor.r) << 7;
gdistance87 = (endcolor.g - startcolor.g) << 7;
630: 1bbf subs r7, r7, r6
bdistance87 = (endcolor.b - startcolor.b) << 7;
uint16_t pixeldistance = endpos - startpos;
632: b29b uxth r3, r3
saccum87 rdistance87;
saccum87 gdistance87;
saccum87 bdistance87;
rdistance87 = (endcolor.r - startcolor.r) << 7;
634: 01c0 lsls r0, r0, #7
gdistance87 = (endcolor.g - startcolor.g) << 7;
636: 01ff lsls r7, r7, #7
bdistance87 = (endcolor.b - startcolor.b) << 7;
uint16_t pixeldistance = endpos - startpos;
int16_t divisor = pixeldistance ? pixeldistance : 1;
638: 2601 movs r6, #1
63a: 2b00 cmp r3, #0
63c: d000 beq.n 640 <_Z17fill_gradient_RGBP4CRGBtS_tS_+0x5c>
63e: b29e uxth r6, r3
saccum87 rdelta87 = rdistance87 / divisor;
640: b236 sxth r6, r6
642: 1c31 adds r1, r6, #0
644: f002 fac6 bl 2bd4 <__aeabi_idiv>
saccum87 gdelta87 = gdistance87 / divisor;
saccum87 bdelta87 = bdistance87 / divisor;
rdelta87 *= 2;
648: 0040 lsls r0, r0, #1
64a: b280 uxth r0, r0
uint16_t pixeldistance = endpos - startpos;
int16_t divisor = pixeldistance ? pixeldistance : 1;
saccum87 rdelta87 = rdistance87 / divisor;
saccum87 gdelta87 = gdistance87 / divisor;
64c: 1c31 adds r1, r6, #0
saccum87 bdelta87 = bdistance87 / divisor;
rdelta87 *= 2;
64e: 9006 str r0, [sp, #24]
uint16_t pixeldistance = endpos - startpos;
int16_t divisor = pixeldistance ? pixeldistance : 1;
saccum87 rdelta87 = rdistance87 / divisor;
saccum87 gdelta87 = gdistance87 / divisor;
650: 1c38 adds r0, r7, #0
652: f002 fabf bl 2bd4 <__aeabi_idiv>
saccum87 bdelta87 = bdistance87 / divisor;
rdelta87 *= 2;
gdelta87 *= 2;
656: 0047 lsls r7, r0, #1
uint16_t pixeldistance = endpos - startpos;
int16_t divisor = pixeldistance ? pixeldistance : 1;
saccum87 rdelta87 = rdistance87 / divisor;
saccum87 gdelta87 = gdistance87 / divisor;
saccum87 bdelta87 = bdistance87 / divisor;
658: 1c31 adds r1, r6, #0
rdelta87 *= 2;
gdelta87 *= 2;
65a: b2bf uxth r7, r7
uint16_t pixeldistance = endpos - startpos;
int16_t divisor = pixeldistance ? pixeldistance : 1;
saccum87 rdelta87 = rdistance87 / divisor;
saccum87 gdelta87 = gdistance87 / divisor;
saccum87 bdelta87 = bdistance87 / divisor;
65c: 9805 ldr r0, [sp, #20]
rdelta87 *= 2;
gdelta87 *= 2;
65e: 9701 str r7, [sp, #4]
uint16_t pixeldistance = endpos - startpos;
int16_t divisor = pixeldistance ? pixeldistance : 1;
saccum87 rdelta87 = rdistance87 / divisor;
saccum87 gdelta87 = gdistance87 / divisor;
saccum87 bdelta87 = bdistance87 / divisor;
660: f002 fab8 bl 2bd4 <__aeabi_idiv>
rdelta87 *= 2;
gdelta87 *= 2;
bdelta87 *= 2;
accum88 r88 = startcolor.r << 8;
664: 9f02 ldr r7, [sp, #8]
accum88 g88 = startcolor.g << 8;
666: 9e03 ldr r6, [sp, #12]
rdelta87 *= 2;
gdelta87 *= 2;
bdelta87 *= 2;
accum88 r88 = startcolor.r << 8;
668: 023b lsls r3, r7, #8
accum88 g88 = startcolor.g << 8;
accum88 b88 = startcolor.b << 8;
66a: 9f04 ldr r7, [sp, #16]
saccum87 gdelta87 = gdistance87 / divisor;
saccum87 bdelta87 = bdistance87 / divisor;
rdelta87 *= 2;
gdelta87 *= 2;
bdelta87 *= 2;
66c: 0040 lsls r0, r0, #1
66e: b280 uxth r0, r0
accum88 r88 = startcolor.r << 8;
accum88 g88 = startcolor.g << 8;
670: 0232 lsls r2, r6, #8
accum88 b88 = startcolor.b << 8;
672: 0239 lsls r1, r7, #8
for( uint16_t i = startpos; i <= endpos; i++) {
674: 42ac cmp r4, r5
676: d814 bhi.n 6a2 <_Z17fill_gradient_RGBP4CRGBtS_tS_+0xbe>
leds[i] = CRGB( r88 >> 8, g88 >> 8, b88 >> 8);
678: 2603 movs r6, #3
67a: 4366 muls r6, r4
67c: 9f07 ldr r7, [sp, #28]
bdelta87 *= 2;
accum88 r88 = startcolor.r << 8;
accum88 g88 = startcolor.g << 8;
accum88 b88 = startcolor.b << 8;
for( uint16_t i = startpos; i <= endpos; i++) {
67e: 3401 adds r4, #1
leds[i] = CRGB( r88 >> 8, g88 >> 8, b88 >> 8);
680: 19be adds r6, r7, r6
682: 121f asrs r7, r3, #8
}
/// allow assignment from one RGB struct to another
inline CRGB& operator= (const CRGB& rhs) __attribute__((always_inline))
{
r = rhs.r;
684: 7037 strb r7, [r6, #0]
686: 1217 asrs r7, r2, #8
g = rhs.g;
688: 7077 strb r7, [r6, #1]
68a: 120f asrs r7, r1, #8
b = rhs.b;
68c: 70b7 strb r7, [r6, #2]
r88 += rdelta87;
68e: 9e06 ldr r6, [sp, #24]
g88 += gdelta87;
690: 9f01 ldr r7, [sp, #4]
accum88 r88 = startcolor.r << 8;
accum88 g88 = startcolor.g << 8;
accum88 b88 = startcolor.b << 8;
for( uint16_t i = startpos; i <= endpos; i++) {
leds[i] = CRGB( r88 >> 8, g88 >> 8, b88 >> 8);
r88 += rdelta87;
692: 199b adds r3, r3, r6
g88 += gdelta87;
694: 19d2 adds r2, r2, r7
b88 += bdelta87;
696: 1809 adds r1, r1, r0
accum88 r88 = startcolor.r << 8;
accum88 g88 = startcolor.g << 8;
accum88 b88 = startcolor.b << 8;
for( uint16_t i = startpos; i <= endpos; i++) {
leds[i] = CRGB( r88 >> 8, g88 >> 8, b88 >> 8);
r88 += rdelta87;
698: b29b uxth r3, r3
g88 += gdelta87;
69a: b292 uxth r2, r2
b88 += bdelta87;
69c: b289 uxth r1, r1
bdelta87 *= 2;
accum88 r88 = startcolor.r << 8;
accum88 g88 = startcolor.g << 8;
accum88 b88 = startcolor.b << 8;
for( uint16_t i = startpos; i <= endpos; i++) {
69e: b2a4 uxth r4, r4
6a0: e7e8 b.n 674 <_Z17fill_gradient_RGBP4CRGBtS_tS_+0x90>
leds[i] = CRGB( r88 >> 8, g88 >> 8, b88 >> 8);
r88 += rdelta87;
g88 += gdelta87;
b88 += bdelta87;
}
}
6a2: b009 add sp, #36 ; 0x24
6a4: bdf0 pop {r4, r5, r6, r7, pc}
6a6: ffff b510 vsli.32 d27, d0, #31
000006a8 <digitalWrite>:
// TODO: startup code needs to initialize all pins to GPIO mode, input by default
void digitalWrite(uint8_t pin, uint8_t val)
{
6a8: b510 push {r4, lr}
if (pin >= CORE_NUM_DIGITAL) return;
6aa: 281a cmp r0, #26
6ac: d818 bhi.n 6e0 <digitalWrite+0x38>
*portSetRegister(pin) = 1;
} else {
*portClearRegister(pin) = 1;
}
#else
if (*portModeRegister(pin) & digitalPinToBitMask(pin)) {
6ae: 230c movs r3, #12
6b0: 4358 muls r0, r3
6b2: 4a0c ldr r2, [pc, #48] ; (6e4 <digitalWrite+0x3c>)
6b4: 5883 ldr r3, [r0, r2]
6b6: 1810 adds r0, r2, r0
6b8: 7d1c ldrb r4, [r3, #20]
6ba: 7a02 ldrb r2, [r0, #8]
6bc: 4222 tst r2, r4
6be: d005 beq.n 6cc <digitalWrite+0x24>
if (val) {
6c0: 2900 cmp r1, #0
6c2: d001 beq.n 6c8 <digitalWrite+0x20>
*portSetRegister(pin) = digitalPinToBitMask(pin);
6c4: 711a strb r2, [r3, #4]
6c6: e00b b.n 6e0 <digitalWrite+0x38>
} else {
*portClearRegister(pin) = digitalPinToBitMask(pin);
6c8: 721a strb r2, [r3, #8]
6ca: e009 b.n 6e0 <digitalWrite+0x38>
}
#endif
} else {
volatile uint32_t *config = portConfigRegister(pin);
6cc: 6843 ldr r3, [r0, #4]
if (val) {
// TODO use bitband for atomic read-mod-write
*config |= (PORT_PCR_PE | PORT_PCR_PS);
6ce: 681a ldr r2, [r3, #0]
*portClearRegister(pin) = digitalPinToBitMask(pin);
}
#endif
} else {
volatile uint32_t *config = portConfigRegister(pin);
if (val) {
6d0: 2900 cmp r1, #0
6d2: d002 beq.n 6da <digitalWrite+0x32>
// TODO use bitband for atomic read-mod-write
*config |= (PORT_PCR_PE | PORT_PCR_PS);
6d4: 2103 movs r1, #3
6d6: 430a orrs r2, r1
6d8: e001 b.n 6de <digitalWrite+0x36>
//*config = PORT_PCR_MUX(1) | PORT_PCR_PE | PORT_PCR_PS;
} else {
// TODO use bitband for atomic read-mod-write
*config &= ~(PORT_PCR_PE);
6da: 2102 movs r1, #2
6dc: 438a bics r2, r1
6de: 601a str r2, [r3, #0]
//*config = PORT_PCR_MUX(1);
}
}
}
6e0: bd10 pop {r4, pc}
6e2: 46c0 nop ; (mov r8, r8)
6e4: 00002d64 .word 0x00002d64
000006e8 <pinMode>:
}
void pinMode(uint8_t pin, uint8_t mode)
{
6e8: b5f0 push {r4, r5, r6, r7, lr}
volatile uint32_t *config;
if (pin >= CORE_NUM_DIGITAL) return;
6ea: 281a cmp r0, #26
6ec: d83d bhi.n 76a <pinMode+0x82>
config = portConfigRegister(pin);
6ee: 270c movs r7, #12
6f0: 1c3d adds r5, r7, #0
6f2: 4345 muls r5, r0
6f4: 4a1d ldr r2, [pc, #116] ; (76c <pinMode+0x84>)
6f6: 1954 adds r4, r2, r5
6f8: 6863 ldr r3, [r4, #4]
6fa: 1c16 adds r6, r2, #0
if (mode == OUTPUT || mode == OUTPUT_OPENDRAIN) {
6fc: 2901 cmp r1, #1
6fe: d001 beq.n 704 <pinMode+0x1c>
700: 2904 cmp r1, #4
702: d112 bne.n 72a <pinMode+0x42>
#ifdef KINETISK
*portModeRegister(pin) = 1;
#else
*portModeRegister(pin) |= digitalPinToBitMask(pin); // TODO: atomic
704: 4378 muls r0, r7
706: 5832 ldr r2, [r6, r0]
708: 1830 adds r0, r6, r0
70a: 7d14 ldrb r4, [r2, #20]
70c: 7a00 ldrb r0, [r0, #8]
70e: 4320 orrs r0, r4
710: 7510 strb r0, [r2, #20]
#endif
*config = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1);
712: 22a2 movs r2, #162 ; 0xa2
714: 0052 lsls r2, r2, #1
716: 601a str r2, [r3, #0]
718: 2220 movs r2, #32
if (mode == OUTPUT_OPENDRAIN) {
71a: 2904 cmp r1, #4
71c: d101 bne.n 722 <pinMode+0x3a>
*config |= PORT_PCR_ODE;
71e: 6819 ldr r1, [r3, #0]
720: e014 b.n 74c <pinMode+0x64>
} else {
*config &= ~PORT_PCR_ODE;
722: 6819 ldr r1, [r3, #0]
724: 4391 bics r1, r2
726: 1c0a adds r2, r1, #0
728: e01e b.n 768 <pinMode+0x80>
}
} else {
#ifdef KINETISK
*portModeRegister(pin) = 0;
#else
*portModeRegister(pin) &= ~digitalPinToBitMask(pin);
72a: 58aa ldr r2, [r5, r2]
72c: 7a24 ldrb r4, [r4, #8]
72e: 7d10 ldrb r0, [r2, #20]
730: 43a0 bics r0, r4
732: 7510 strb r0, [r2, #20]
#endif
if (mode == INPUT || mode == INPUT_PULLUP || mode == INPUT_PULLDOWN) {
734: 2900 cmp r1, #0
736: d002 beq.n 73e <pinMode+0x56>
738: 1e8a subs r2, r1, #2
73a: 2a01 cmp r2, #1
73c: d812 bhi.n 764 <pinMode+0x7c>
*config = PORT_PCR_MUX(1);
73e: 2280 movs r2, #128 ; 0x80
740: 0052 lsls r2, r2, #1
742: 601a str r2, [r3, #0]
if (mode == INPUT_PULLUP) {
744: 2902 cmp r1, #2
746: d103 bne.n 750 <pinMode+0x68>
*config |= (PORT_PCR_PE | PORT_PCR_PS); // pullup
748: 681a ldr r2, [r3, #0]
74a: 2103 movs r1, #3
74c: 430a orrs r2, r1
74e: e00b b.n 768 <pinMode+0x80>
} else if (mode == INPUT_PULLDOWN) {
750: 2903 cmp r1, #3
752: d10a bne.n 76a <pinMode+0x82>
*config |= (PORT_PCR_PE); // pulldown
754: 681a ldr r2, [r3, #0]
756: 2102 movs r1, #2
758: 430a orrs r2, r1
75a: 601a str r2, [r3, #0]
*config &= ~(PORT_PCR_PS);
75c: 681a ldr r2, [r3, #0]
75e: 2101 movs r1, #1
760: 438a bics r2, r1
762: e001 b.n 768 <pinMode+0x80>
}
} else {
*config = PORT_PCR_MUX(1) | PORT_PCR_PE | PORT_PCR_PS; // pullup
764: 2204 movs r2, #4
766: 32ff adds r2, #255 ; 0xff
768: 601a str r2, [r3, #0]
}
}
}
76a: bdf0 pop {r4, r5, r6, r7, pc}
76c: 00002d64 .word 0x00002d64
00000770 <micros>:
uint32_t micros(void)
{
uint32_t count, current, istatus;
__disable_irq();
770: b672 cpsid i
current = SYST_CVR;
772: 4b0c ldr r3, [pc, #48] ; (7a4 <micros+0x34>)
count = systick_millis_count;
istatus = SCB_ICSR; // bit 26 indicates if systick exception pending
774: 490c ldr r1, [pc, #48] ; (7a8 <micros+0x38>)
uint32_t micros(void)
{
uint32_t count, current, istatus;
__disable_irq();
current = SYST_CVR;
776: 681a ldr r2, [r3, #0]
count = systick_millis_count;
778: 4b0c ldr r3, [pc, #48] ; (7ac <micros+0x3c>)
77a: 681b ldr r3, [r3, #0]
istatus = SCB_ICSR; // bit 26 indicates if systick exception pending
77c: 6809 ldr r1, [r1, #0]
__enable_irq();
77e: b662 cpsie i
//systick_current = current;
//systick_count = count;
//systick_istatus = istatus & SCB_ICSR_PENDSTSET ? 1 : 0;
if ((istatus & SCB_ICSR_PENDSTSET) && current > 50) count++;
780: 0148 lsls r0, r1, #5
782: d504 bpl.n 78e <micros+0x1e>
784: 2132 movs r1, #50 ; 0x32
786: 4291 cmp r1, r2
788: 4189 sbcs r1, r1
78a: 4249 negs r1, r1
78c: 185b adds r3, r3, r1
current = ((F_CPU / 1000) - 1) - current;
#if defined(KINETISL) && F_CPU == 48000000
return count * 1000 + ((current * (uint32_t)87381) >> 22);
78e: 20fa movs r0, #250 ; 0xfa
790: 0080 lsls r0, r0, #2
792: 4343 muls r3, r0
__enable_irq();
//systick_current = current;
//systick_count = count;
//systick_istatus = istatus & SCB_ICSR_PENDSTSET ? 1 : 0;
if ((istatus & SCB_ICSR_PENDSTSET) && current > 50) count++;
current = ((F_CPU / 1000) - 1) - current;
794: 4806 ldr r0, [pc, #24] ; (7b0 <micros+0x40>)
796: 1a82 subs r2, r0, r2
#if defined(KINETISL) && F_CPU == 48000000
return count * 1000 + ((current * (uint32_t)87381) >> 22);
798: 4806 ldr r0, [pc, #24] ; (7b4 <micros+0x44>)
79a: 4342 muls r2, r0
79c: 0d92 lsrs r2, r2, #22
79e: 1898 adds r0, r3, r2
#elif defined(KINETISL) && F_CPU == 24000000
return count * 1000 + ((current * (uint32_t)174763) >> 22);
#endif
return count * 1000 + current / (F_CPU / 1000000);
}
7a0: 4770 bx lr
7a2: 46c0 nop ; (mov r8, r8)
7a4: e000e018 .word 0xe000e018
7a8: e000ed04 .word 0xe000ed04
7ac: 1ffffe64 .word 0x1ffffe64
7b0: 0000bb7f .word 0x0000bb7f
7b4: 00015555 .word 0x00015555
000007b8 <delay>:
void delay(uint32_t ms)
{
7b8: b538 push {r3, r4, r5, lr}
7ba: 1c04 adds r4, r0, #0
uint32_t start = micros();
7bc: f7ff ffd8 bl 770 <micros>
7c0: 1c05 adds r5, r0, #0
if (ms > 0) {
7c2: 2c00 cmp r4, #0
7c4: d00f beq.n 7e6 <delay+0x2e>
while (1) {
while ((micros() - start) >= 1000) {
7c6: f7ff ffd3 bl 770 <micros>
7ca: 4b07 ldr r3, [pc, #28] ; (7e8 <delay+0x30>)
7cc: 1b40 subs r0, r0, r5
7ce: 4298 cmp r0, r3
7d0: d906 bls.n 7e0 <delay+0x28>
ms--;
7d2: 3c01 subs r4, #1
if (ms == 0) return;
7d4: 2c00 cmp r4, #0
7d6: d006 beq.n 7e6 <delay+0x2e>
start += 1000;
7d8: 23fa movs r3, #250 ; 0xfa
7da: 009b lsls r3, r3, #2
7dc: 18ed adds r5, r5, r3
7de: e7f2 b.n 7c6 <delay+0xe>
}
yield();
7e0: f000 fe62 bl 14a8 <yield>
}
7e4: e7ef b.n 7c6 <delay+0xe>
}
}
7e6: bd38 pop {r3, r4, r5, pc}
7e8: 000003e7 .word 0x000003e7
000007ec <_init_Teensyduino_internal_>:
NVIC_ENABLE_IRQ(IRQ_PORTB);
NVIC_ENABLE_IRQ(IRQ_PORTC);
NVIC_ENABLE_IRQ(IRQ_PORTD);
NVIC_ENABLE_IRQ(IRQ_PORTE);
#elif defined(__MKL26Z64__)
NVIC_ENABLE_IRQ(IRQ_PORTA);
7ec: 4b1c ldr r3, [pc, #112] ; (860 <_init_Teensyduino_internal_+0x74>)
7ee: 2280 movs r2, #128 ; 0x80
7f0: 05d2 lsls r2, r2, #23
#define DEFAULT_FTM_PRESCALE 0
#endif
//void init_pins(void)
void _init_Teensyduino_internal_(void)
{
7f2: b510 push {r4, lr}
NVIC_ENABLE_IRQ(IRQ_PORTB);
NVIC_ENABLE_IRQ(IRQ_PORTC);
NVIC_ENABLE_IRQ(IRQ_PORTD);
NVIC_ENABLE_IRQ(IRQ_PORTE);
#elif defined(__MKL26Z64__)
NVIC_ENABLE_IRQ(IRQ_PORTA);
7f4: 601a str r2, [r3, #0]
NVIC_ENABLE_IRQ(IRQ_PORTCD);
7f6: 2280 movs r2, #128 ; 0x80
7f8: 0612 lsls r2, r2, #24
7fa: 601a str r2, [r3, #0]
#endif
//SIM_SCGC6 |= SIM_SCGC6_FTM0; // TODO: use bitband for atomic read-mod-write
//SIM_SCGC6 |= SIM_SCGC6_FTM1;
FTM0_CNT = 0;
7fc: 4b19 ldr r3, [pc, #100] ; (864 <_init_Teensyduino_internal_+0x78>)
7fe: 2000 movs r0, #0
800: 6018 str r0, [r3, #0]
FTM0_MOD = DEFAULT_FTM_MOD;
802: 4919 ldr r1, [pc, #100] ; (868 <_init_Teensyduino_internal_+0x7c>)
804: 4b19 ldr r3, [pc, #100] ; (86c <_init_Teensyduino_internal_+0x80>)
FTM0_C0SC = 0x28; // MSnB:MSnA = 10, ELSnB:ELSnA = 10
806: 4a1a ldr r2, [pc, #104] ; (870 <_init_Teensyduino_internal_+0x84>)
NVIC_ENABLE_IRQ(IRQ_PORTCD);
#endif
//SIM_SCGC6 |= SIM_SCGC6_FTM0; // TODO: use bitband for atomic read-mod-write
//SIM_SCGC6 |= SIM_SCGC6_FTM1;
FTM0_CNT = 0;
FTM0_MOD = DEFAULT_FTM_MOD;
808: 6019 str r1, [r3, #0]
FTM0_C0SC = 0x28; // MSnB:MSnA = 10, ELSnB:ELSnA = 10
80a: 2328 movs r3, #40 ; 0x28
80c: 6013 str r3, [r2, #0]
FTM0_C1SC = 0x28;
80e: 4a19 ldr r2, [pc, #100] ; (874 <_init_Teensyduino_internal_+0x88>)
FTM3_C4SC = 0x28;
FTM3_C5SC = 0x28;
FTM3_C6SC = 0x28;
FTM3_C7SC = 0x28;
#endif
FTM0_SC = FTM_SC_CLKS(1) | FTM_SC_PS(DEFAULT_FTM_PRESCALE);
810: 4c19 ldr r4, [pc, #100] ; (878 <_init_Teensyduino_internal_+0x8c>)
//SIM_SCGC6 |= SIM_SCGC6_FTM0; // TODO: use bitband for atomic read-mod-write
//SIM_SCGC6 |= SIM_SCGC6_FTM1;
FTM0_CNT = 0;
FTM0_MOD = DEFAULT_FTM_MOD;
FTM0_C0SC = 0x28; // MSnB:MSnA = 10, ELSnB:ELSnA = 10
FTM0_C1SC = 0x28;
812: 6013 str r3, [r2, #0]
FTM0_C2SC = 0x28;
814: 4a19 ldr r2, [pc, #100] ; (87c <_init_Teensyduino_internal_+0x90>)
816: 6013 str r3, [r2, #0]
FTM0_C3SC = 0x28;
818: 4a19 ldr r2, [pc, #100] ; (880 <_init_Teensyduino_internal_+0x94>)
81a: 6013 str r3, [r2, #0]
FTM0_C4SC = 0x28;
81c: 4a19 ldr r2, [pc, #100] ; (884 <_init_Teensyduino_internal_+0x98>)
81e: 6013 str r3, [r2, #0]
FTM0_C5SC = 0x28;
820: 4a19 ldr r2, [pc, #100] ; (888 <_init_Teensyduino_internal_+0x9c>)
822: 6013 str r3, [r2, #0]
FTM3_C4SC = 0x28;
FTM3_C5SC = 0x28;
FTM3_C6SC = 0x28;
FTM3_C7SC = 0x28;
#endif
FTM0_SC = FTM_SC_CLKS(1) | FTM_SC_PS(DEFAULT_FTM_PRESCALE);
824: 2209 movs r2, #9
826: 6022 str r2, [r4, #0]
FTM1_CNT = 0;
828: 4c18 ldr r4, [pc, #96] ; (88c <_init_Teensyduino_internal_+0xa0>)
82a: 6020 str r0, [r4, #0]
FTM1_MOD = DEFAULT_FTM_MOD;
82c: 4c18 ldr r4, [pc, #96] ; (890 <_init_Teensyduino_internal_+0xa4>)
82e: 6021 str r1, [r4, #0]
FTM1_C0SC = 0x28;
830: 4c18 ldr r4, [pc, #96] ; (894 <_init_Teensyduino_internal_+0xa8>)
832: 6023 str r3, [r4, #0]
FTM1_C1SC = 0x28;
834: 4c18 ldr r4, [pc, #96] ; (898 <_init_Teensyduino_internal_+0xac>)
836: 6023 str r3, [r4, #0]
FTM1_SC = FTM_SC_CLKS(1) | FTM_SC_PS(DEFAULT_FTM_PRESCALE);
838: 4c18 ldr r4, [pc, #96] ; (89c <_init_Teensyduino_internal_+0xb0>)
83a: 6022 str r2, [r4, #0]
#if defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__) || defined(__MKL26Z64__)
FTM2_CNT = 0;
83c: 4c18 ldr r4, [pc, #96] ; (8a0 <_init_Teensyduino_internal_+0xb4>)
83e: 6020 str r0, [r4, #0]
FTM2_MOD = DEFAULT_FTM_MOD;
840: 4818 ldr r0, [pc, #96] ; (8a4 <_init_Teensyduino_internal_+0xb8>)
842: 6001 str r1, [r0, #0]
FTM2_C0SC = 0x28;
844: 4918 ldr r1, [pc, #96] ; (8a8 <_init_Teensyduino_internal_+0xbc>)
846: 600b str r3, [r1, #0]
FTM2_C1SC = 0x28;
848: 4918 ldr r1, [pc, #96] ; (8ac <_init_Teensyduino_internal_+0xc0>)
84a: 600b str r3, [r1, #0]
FTM2_SC = FTM_SC_CLKS(1) | FTM_SC_PS(DEFAULT_FTM_PRESCALE);
84c: 4b18 ldr r3, [pc, #96] ; (8b0 <_init_Teensyduino_internal_+0xc4>)
84e: 601a str r2, [r3, #0]
FTM3_MOD = DEFAULT_FTM_MOD;
FTM3_C0SC = 0x28;
FTM3_C1SC = 0x28;
FTM3_SC = FTM_SC_CLKS(1) | FTM_SC_PS(DEFAULT_FTM_PRESCALE);
#endif
analog_init();
850: f000 fe4e bl 14f0 <analog_init>
// for background about this startup delay, please see this conversation
// https://forum.pjrc.com/threads/31290-Teensey-3-2-Teensey-Loader-1-24-Issues?p=87273&viewfull=1#post87273
delay(250);
854: 20fa movs r0, #250 ; 0xfa
856: f7ff ffaf bl 7b8 <delay>
usb_init();
85a: f000 fbd5 bl 1008 <usb_init>
}
85e: bd10 pop {r4, pc}
860: e000e100 .word 0xe000e100
864: 40038004 .word 0x40038004
868: 0000bfff .word 0x0000bfff
86c: 40038008 .word 0x40038008
870: 4003800c .word 0x4003800c
874: 40038014 .word 0x40038014
878: 40038000 .word 0x40038000
87c: 4003801c .word 0x4003801c
880: 40038024 .word 0x40038024
884: 4003802c .word 0x4003802c
888: 40038034 .word 0x40038034
88c: 40039004 .word 0x40039004
890: 40039008 .word 0x40039008
894: 4003900c .word 0x4003900c
898: 40039014 .word 0x40039014
89c: 40039000 .word 0x40039000
8a0: 4003a004 .word 0x4003a004
8a4: 4003a008 .word 0x4003a008
8a8: 4003a00c .word 0x4003a00c
8ac: 4003a014 .word 0x4003a014
8b0: 4003a000 .word 0x4003a000
000008b4 <endpoint0_transmit>:
USB0_ENDPT0 = USB_ENDPT_EPSTALL | USB_ENDPT_EPRXEN | USB_ENDPT_EPTXEN | USB_ENDPT_EPHSHK;
}
static void endpoint0_transmit(const void *data, uint32_t len)
{
8b4: b5f0 push {r4, r5, r6, r7, lr}
serial_print(",");
serial_phex16(len);
serial_print(ep0_tx_bdt_bank ? ", odd" : ", even");
serial_print(ep0_tx_data_toggle ? ", d1\n" : ", d0\n");
#endif
table[index(0, TX, ep0_tx_bdt_bank)].addr = (void *)data;
8b6: 4f0b ldr r7, [pc, #44] ; (8e4 <endpoint0_transmit+0x30>)
8b8: 2202 movs r2, #2
8ba: 783b ldrb r3, [r7, #0]
8bc: 4e0a ldr r6, [pc, #40] ; (8e8 <endpoint0_transmit+0x34>)
8be: 431a orrs r2, r3
8c0: 00d2 lsls r2, r2, #3
table[index(0, TX, ep0_tx_bdt_bank)].desc = BDT_DESC(len, ep0_tx_data_toggle);
8c2: 4d0a ldr r5, [pc, #40] ; (8ec <endpoint0_transmit+0x38>)
serial_print(",");
serial_phex16(len);
serial_print(ep0_tx_bdt_bank ? ", odd" : ", even");
serial_print(ep0_tx_data_toggle ? ", d1\n" : ", d0\n");
#endif
table[index(0, TX, ep0_tx_bdt_bank)].addr = (void *)data;
8c4: 18b4 adds r4, r6, r2
8c6: 6060 str r0, [r4, #4]
table[index(0, TX, ep0_tx_bdt_bank)].desc = BDT_DESC(len, ep0_tx_data_toggle);
8c8: 7828 ldrb r0, [r5, #0]
8ca: 2488 movs r4, #136 ; 0x88
8cc: 2800 cmp r0, #0
8ce: d000 beq.n 8d2 <endpoint0_transmit+0x1e>
8d0: 24c8 movs r4, #200 ; 0xc8
8d2: 0409 lsls r1, r1, #16
8d4: 430c orrs r4, r1
8d6: 50b4 str r4, [r6, r2]
ep0_tx_data_toggle ^= 1;
8d8: 2201 movs r2, #1
8da: 4050 eors r0, r2
ep0_tx_bdt_bank ^= 1;
8dc: 4053 eors r3, r2
serial_print(ep0_tx_bdt_bank ? ", odd" : ", even");
serial_print(ep0_tx_data_toggle ? ", d1\n" : ", d0\n");
#endif
table[index(0, TX, ep0_tx_bdt_bank)].addr = (void *)data;
table[index(0, TX, ep0_tx_bdt_bank)].desc = BDT_DESC(len, ep0_tx_data_toggle);
ep0_tx_data_toggle ^= 1;
8de: 7028 strb r0, [r5, #0]
ep0_tx_bdt_bank ^= 1;
8e0: 703b strb r3, [r7, #0]
}
8e2: bdf0 pop {r4, r5, r6, r7, pc}
8e4: 1ffffed0 .word 0x1ffffed0
8e8: 1ffff800 .word 0x1ffff800
8ec: 1fffff48 .word 0x1fffff48
000008f0 <usb_rx>:
usb_packet_t *usb_rx(uint32_t endpoint)
{
usb_packet_t *ret;
endpoint--;
8f0: 1e43 subs r3, r0, #1
usb_packet_t *usb_rx(uint32_t endpoint)
{
8f2: b510 push {r4, lr}
usb_packet_t *ret;
endpoint--;
if (endpoint >= NUM_ENDPOINTS) return NULL;
8f4: 2b03 cmp r3, #3
8f6: d80f bhi.n 918 <usb_rx+0x28>
__disable_irq();
8f8: b672 cpsid i
ret = rx_first[endpoint];
8fa: 4a08 ldr r2, [pc, #32] ; (91c <usb_rx+0x2c>)
8fc: 0099 lsls r1, r3, #2
8fe: 5888 ldr r0, [r1, r2]
if (ret) {
900: 2800 cmp r0, #0
902: d007 beq.n 914 <usb_rx+0x24>
rx_first[endpoint] = ret->next;
904: 6844 ldr r4, [r0, #4]
usb_rx_byte_count_data[endpoint] -= ret->len;
906: 005b lsls r3, r3, #1
endpoint--;
if (endpoint >= NUM_ENDPOINTS) return NULL;
__disable_irq();
ret = rx_first[endpoint];
if (ret) {
rx_first[endpoint] = ret->next;
908: 508c str r4, [r1, r2]
usb_rx_byte_count_data[endpoint] -= ret->len;
90a: 4a05 ldr r2, [pc, #20] ; (920 <usb_rx+0x30>)
90c: 8801 ldrh r1, [r0, #0]
90e: 5a9c ldrh r4, [r3, r2]
910: 1a61 subs r1, r4, r1
912: 5299 strh r1, [r3, r2]
}
__enable_irq();
914: b662 cpsie i
//serial_print("rx, epidx=");
//serial_phex(endpoint);
//serial_print(", packet=");
//serial_phex32(ret);
//serial_print("\n");
return ret;
916: e000 b.n 91a <usb_rx+0x2a>
usb_packet_t *usb_rx(uint32_t endpoint)
{
usb_packet_t *ret;
endpoint--;
if (endpoint >= NUM_ENDPOINTS) return NULL;
918: 2000 movs r0, #0
//serial_phex(endpoint);
//serial_print(", packet=");
//serial_phex32(ret);
//serial_print("\n");
return ret;
}
91a: bd10 pop {r4, pc}
91c: 1ffffec0 .word 0x1ffffec0
920: 2000012c .word 0x2000012c
00000924 <usb_tx_packet_count>:
uint32_t usb_tx_packet_count(uint32_t endpoint)
{
const usb_packet_t *p;
uint32_t count=0;
endpoint--;
924: 1e43 subs r3, r0, #1
if (endpoint >= NUM_ENDPOINTS) return 0;
926: 2000 movs r0, #0
928: 2b03 cmp r3, #3
92a: d809 bhi.n 940 <usb_tx_packet_count+0x1c>
__disable_irq();
92c: b672 cpsid i
for (p = tx_first[endpoint]; p; p = p->next) count++;
92e: 4a05 ldr r2, [pc, #20] ; (944 <usb_tx_packet_count+0x20>)
930: 009b lsls r3, r3, #2
932: 589b ldr r3, [r3, r2]
934: 2b00 cmp r3, #0
936: d002 beq.n 93e <usb_tx_packet_count+0x1a>
938: 3001 adds r0, #1
93a: 685b ldr r3, [r3, #4]
93c: e7fa b.n 934 <usb_tx_packet_count+0x10>
__enable_irq();
93e: b662 cpsie i
return count;
}
940: 4770 bx lr
942: 46c0 nop ; (mov r8, r8)
944: 1fffff14 .word 0x1fffff14
00000948 <usb_rx_memory>:
// user is creating data very quickly, their consumption could starve reception
// without this prioritization. The packet buffer (input) is assigned to the
// first endpoint needing memory.
//
void usb_rx_memory(usb_packet_t *packet)
{
948: b538 push {r3, r4, r5, lr}
unsigned int i;
const uint8_t *cfg;
cfg = usb_endpoint_config_table;
//serial_print("rx_mem:");
__disable_irq();
94a: b672 cpsid i
for (i=1; i <= NUM_ENDPOINTS; i++) {
94c: 2301 movs r3, #1
94e: 4a16 ldr r2, [pc, #88] ; (9a8 <usb_rx_memory+0x60>)
950: 189a adds r2, r3, r2
952: 3a01 subs r2, #1
#ifdef AUDIO_INTERFACE
if (i == AUDIO_RX_ENDPOINT) continue;
#endif
if (*cfg++ & USB_ENDPT_EPRXEN) {
954: 7812 ldrb r2, [r2, #0]
956: 0711 lsls r1, r2, #28
958: d51c bpl.n 994 <usb_rx_memory+0x4c>
if (table[index(i, RX, EVEN)].desc == 0) {
95a: 4a14 ldr r2, [pc, #80] ; (9ac <usb_rx_memory+0x64>)
95c: 015c lsls r4, r3, #5
95e: 58a5 ldr r5, [r4, r2]
960: 0099 lsls r1, r3, #2
962: 2d00 cmp r5, #0
964: d105 bne.n 972 <usb_rx_memory+0x2a>
table[index(i, RX, EVEN)].addr = packet->buf;
966: 1913 adds r3, r2, r4
968: 3008 adds r0, #8
96a: 6058 str r0, [r3, #4]
table[index(i, RX, EVEN)].desc = BDT_DESC(64, 0);
96c: 4b10 ldr r3, [pc, #64] ; (9b0 <usb_rx_memory+0x68>)
96e: 50a3 str r3, [r4, r2]
970: e00a b.n 988 <usb_rx_memory+0x40>
__enable_irq();
//serial_phex(i);
//serial_print(",even\n");
return;
}
if (table[index(i, RX, ODD)].desc == 0) {
972: 2401 movs r4, #1
974: 4321 orrs r1, r4
976: 00c9 lsls r1, r1, #3
978: 588c ldr r4, [r1, r2]
97a: 2c00 cmp r4, #0
97c: d10a bne.n 994 <usb_rx_memory+0x4c>
table[index(i, RX, ODD)].addr = packet->buf;
97e: 1853 adds r3, r2, r1
980: 3008 adds r0, #8
982: 6058 str r0, [r3, #4]
table[index(i, RX, ODD)].desc = BDT_DESC(64, 1);
984: 4b0b ldr r3, [pc, #44] ; (9b4 <usb_rx_memory+0x6c>)
986: 508b str r3, [r1, r2]
usb_rx_memory_needed--;
988: 4b0b ldr r3, [pc, #44] ; (9b8 <usb_rx_memory+0x70>)
98a: 781a ldrb r2, [r3, #0]
98c: 3a01 subs r2, #1
98e: 701a strb r2, [r3, #0]
__enable_irq();
990: b662 cpsie i
//serial_phex(i);
//serial_print(",odd\n");
return;
992: e008 b.n 9a6 <usb_rx_memory+0x5e>
const uint8_t *cfg;
cfg = usb_endpoint_config_table;
//serial_print("rx_mem:");
__disable_irq();
for (i=1; i <= NUM_ENDPOINTS; i++) {
994: 3301 adds r3, #1
996: 2b05 cmp r3, #5
998: d1d9 bne.n 94e <usb_rx_memory+0x6>
//serial_print(",odd\n");
return;
}
}
}
__enable_irq();
99a: b662 cpsie i
// we should never reach this point. If we get here, it means
// usb_rx_memory_needed was set greater than zero, but no memory
// was actually needed.
usb_rx_memory_needed = 0;
99c: 4b06 ldr r3, [pc, #24] ; (9b8 <usb_rx_memory+0x70>)
99e: 2200 movs r2, #0
9a0: 701a strb r2, [r3, #0]
usb_free(packet);
9a2: f000 fba5 bl 10f0 <usb_free>
return;
}
9a6: bd38 pop {r3, r4, r5, pc}
9a8: 00002ed8 .word 0x00002ed8
9ac: 1ffff800 .word 0x1ffff800
9b0: 00400088 .word 0x00400088
9b4: 004000c8 .word 0x004000c8
9b8: 1fffff3e .word 0x1fffff3e
000009bc <usb_tx>:
void usb_tx(uint32_t endpoint, usb_packet_t *packet)
{
bdt_t *b = &table[index(endpoint, TX, EVEN)];
uint8_t next;
endpoint--;
9bc: 1e42 subs r2, r0, #1
//#define index(endpoint, tx, odd) (((endpoint) << 2) | ((tx) << 1) | (odd))
//#define stat2bufferdescriptor(stat) (table + ((stat) >> 2))
void usb_tx(uint32_t endpoint, usb_packet_t *packet)
{
9be: b510 push {r4, lr}
bdt_t *b = &table[index(endpoint, TX, EVEN)];
uint8_t next;
endpoint--;
if (endpoint >= NUM_ENDPOINTS) return;
9c0: 2a03 cmp r2, #3
9c2: d830 bhi.n a26 <usb_tx+0x6a>
//#define index(endpoint, tx, odd) (((endpoint) << 2) | ((tx) << 1) | (odd))
//#define stat2bufferdescriptor(stat) (table + ((stat) >> 2))
void usb_tx(uint32_t endpoint, usb_packet_t *packet)
{
bdt_t *b = &table[index(endpoint, TX, EVEN)];
9c4: 2302 movs r3, #2
9c6: 0080 lsls r0, r0, #2
9c8: 4318 orrs r0, r3
9ca: 4b17 ldr r3, [pc, #92] ; (a28 <usb_tx+0x6c>)
9cc: 00c0 lsls r0, r0, #3
9ce: 181b adds r3, r3, r0
uint8_t next;
endpoint--;
if (endpoint >= NUM_ENDPOINTS) return;
__disable_irq();
9d0: b672 cpsid i
//serial_print("txstate=");
//serial_phex(tx_state[endpoint]);
//serial_print("\n");
switch (tx_state[endpoint]) {
9d2: 4c16 ldr r4, [pc, #88] ; (a2c <usb_tx+0x70>)
9d4: 5ca0 ldrb r0, [r4, r2]
9d6: 2803 cmp r0, #3
9d8: d809 bhi.n 9ee <usb_tx+0x32>
9da: f002 f899 bl 2b10 <__gnu_thumb1_case_uqi>
9de: 0214 .short 0x0214
9e0: 0516 .short 0x0516
case TX_STATE_BOTH_FREE_EVEN_FIRST:
next = TX_STATE_ODD_FREE;
break;
case TX_STATE_BOTH_FREE_ODD_FIRST:
b++;
9e2: 3308 adds r3, #8
next = TX_STATE_EVEN_FREE;
9e4: 2002 movs r0, #2
break;
9e6: e011 b.n a0c <usb_tx+0x50>
case TX_STATE_EVEN_FREE:
next = TX_STATE_NONE_FREE_ODD_FIRST;
break;
case TX_STATE_ODD_FREE:
b++;
9e8: 3308 adds r3, #8
next = TX_STATE_NONE_FREE_EVEN_FIRST;
9ea: 2004 movs r0, #4
break;
9ec: e00e b.n a0c <usb_tx+0x50>
default:
if (tx_first[endpoint] == NULL) {
9ee: 4810 ldr r0, [pc, #64] ; (a30 <usb_tx+0x74>)
9f0: 0092 lsls r2, r2, #2
9f2: 5814 ldr r4, [r2, r0]
9f4: 4b0f ldr r3, [pc, #60] ; (a34 <usb_tx+0x78>)
9f6: 2c00 cmp r4, #0
9f8: d101 bne.n 9fe <usb_tx+0x42>
tx_first[endpoint] = packet;
9fa: 5011 str r1, [r2, r0]
9fc: e001 b.n a02 <usb_tx+0x46>
} else {
tx_last[endpoint]->next = packet;
9fe: 5898 ldr r0, [r3, r2]
a00: 6041 str r1, [r0, #4]
}
tx_last[endpoint] = packet;
a02: 5099 str r1, [r3, r2]
a04: e00e b.n a24 <usb_tx+0x68>
//serial_print("txstate=");
//serial_phex(tx_state[endpoint]);
//serial_print("\n");
switch (tx_state[endpoint]) {
case TX_STATE_BOTH_FREE_EVEN_FIRST:
next = TX_STATE_ODD_FREE;
a06: 2003 movs r0, #3
a08: e000 b.n a0c <usb_tx+0x50>
case TX_STATE_BOTH_FREE_ODD_FIRST:
b++;
next = TX_STATE_EVEN_FREE;
break;
case TX_STATE_EVEN_FREE:
next = TX_STATE_NONE_FREE_ODD_FIRST;
a0a: 2005 movs r0, #5
}
tx_last[endpoint] = packet;
__enable_irq();
return;
}
tx_state[endpoint] = next;
a0c: 54a0 strb r0, [r4, r2]
b->addr = packet->buf;
a0e: 1c0a adds r2, r1, #0
a10: 3208 adds r2, #8
a12: 605a str r2, [r3, #4]
b->desc = BDT_DESC(packet->len, ((uint32_t)b & 8) ? DATA1 : DATA0);
a14: 2288 movs r2, #136 ; 0x88
a16: 0718 lsls r0, r3, #28
a18: d500 bpl.n a1c <usb_tx+0x60>
a1a: 22c8 movs r2, #200 ; 0xc8
a1c: 8809 ldrh r1, [r1, #0]
a1e: 0409 lsls r1, r1, #16
a20: 430a orrs r2, r1
a22: 601a str r2, [r3, #0]
__enable_irq();
a24: b662 cpsie i
}
a26: bd10 pop {r4, pc}
a28: 1ffff800 .word 0x1ffff800
a2c: 1ffffe7c .word 0x1ffffe7c
a30: 1fffff14 .word 0x1fffff14
a34: 1fffff24 .word 0x1fffff24
00000a38 <usb_isr>:
}
void usb_isr(void)
{
a38: b5f7 push {r0, r1, r2, r4, r5, r6, r7, lr}
//serial_print("isr");
//status = USB0_ISTAT;
//serial_phex(status);
//serial_print("\n");
restart:
status = USB0_ISTAT;
a3a: 49b5 ldr r1, [pc, #724] ; (d10 <usb_isr+0x2d8>)
a3c: 780c ldrb r4, [r1, #0]
a3e: 1c0e adds r6, r1, #0
a40: b2e4 uxtb r4, r4
if ((status & USB_ISTAT_SOFTOK /* 04 */ )) {
a42: 0762 lsls r2, r4, #29
a44: d51d bpl.n a82 <usb_isr+0x4a>
if (usb_configuration) {
a46: 4bb3 ldr r3, [pc, #716] ; (d14 <usb_isr+0x2dc>)
a48: 781b ldrb r3, [r3, #0]
a4a: 2b00 cmp r3, #0
a4c: d016 beq.n a7c <usb_isr+0x44>
t = usb_reboot_timer;
a4e: 4ab2 ldr r2, [pc, #712] ; (d18 <usb_isr+0x2e0>)
a50: 7813 ldrb r3, [r2, #0]
a52: b2db uxtb r3, r3
if (t) {
a54: 2b00 cmp r3, #0
a56: d005 beq.n a64 <usb_isr+0x2c>
usb_reboot_timer = --t;
a58: 3b01 subs r3, #1
a5a: b2db uxtb r3, r3
a5c: 7013 strb r3, [r2, #0]
if (!t) _reboot_Teensyduino_();
a5e: 2b00 cmp r3, #0
a60: d100 bne.n a64 <usb_isr+0x2c>
void _reboot_Teensyduino_(void)
{
// TODO: initialize R0 with a code....
__asm__ volatile("bkpt");
a62: be00 bkpt 0x0000
if (t) {
usb_reboot_timer = --t;
if (!t) _reboot_Teensyduino_();
}
#ifdef CDC_DATA_INTERFACE
t = usb_cdc_transmit_flush_timer;
a64: 4aad ldr r2, [pc, #692] ; (d1c <usb_isr+0x2e4>)
a66: 7813 ldrb r3, [r2, #0]
a68: b2db uxtb r3, r3
if (t) {
a6a: 2b00 cmp r3, #0
a6c: d006 beq.n a7c <usb_isr+0x44>
usb_cdc_transmit_flush_timer = --t;
a6e: 3b01 subs r3, #1
a70: b2db uxtb r3, r3
a72: 7013 strb r3, [r2, #0]
if (t == 0) usb_serial_flush_callback();
a74: 2b00 cmp r3, #0
a76: d101 bne.n a7c <usb_isr+0x44>
a78: f000 fc7a bl 1370 <usb_serial_flush_callback>
#endif
#ifdef MULTITOUCH_INTERFACE
usb_touchscreen_update_callback();
#endif
}
USB0_ISTAT = USB_ISTAT_SOFTOK;
a7c: 4da4 ldr r5, [pc, #656] ; (d10 <usb_isr+0x2d8>)
a7e: 2304 movs r3, #4
a80: 702b strb r3, [r5, #0]
}
if ((status & USB_ISTAT_TOKDNE /* 08 */ )) {
a82: 2508 movs r5, #8
a84: 1c22 adds r2, r4, #0
a86: 402a ands r2, r5
a88: d100 bne.n a8c <usb_isr+0x54>
a8a: e254 b.n f36 <usb_isr+0x4fe>
uint8_t endpoint;
stat = USB0_STAT;
a8c: 4ba4 ldr r3, [pc, #656] ; (d20 <usb_isr+0x2e8>)
a8e: 4ca5 ldr r4, [pc, #660] ; (d24 <usb_isr+0x2ec>)
a90: 781b ldrb r3, [r3, #0]
a92: b2db uxtb r3, r3
//serial_print("token: ep=");
//serial_phex(stat >> 4);
//serial_print(stat & 0x08 ? ",tx" : ",rx");
//serial_print(stat & 0x04 ? ",odd\n" : ",even\n");
endpoint = stat >> 4;
a94: 091e lsrs r6, r3, #4
a96: 089a lsrs r2, r3, #2
if (endpoint == 0) {
a98: 2e00 cmp r6, #0
a9a: d000 beq.n a9e <usb_isr+0x66>
a9c: e1dd b.n e5a <usb_isr+0x422>
bdt_t *b;
uint32_t pid, size;
uint8_t *buf;
const uint8_t *data;
b = stat2bufferdescriptor(stat);
a9e: 00d5 lsls r5, r2, #3
aa0: 1965 adds r5, r4, r5
pid = BDT_PID(b->desc);
aa2: 682f ldr r7, [r5, #0]
//count = b->desc >> 16;
buf = b->addr;
aa4: 686a ldr r2, [r5, #4]
uint32_t pid, size;
uint8_t *buf;
const uint8_t *data;
b = stat2bufferdescriptor(stat);
pid = BDT_PID(b->desc);
aa6: 06b8 lsls r0, r7, #26
aa8: 0f00 lsrs r0, r0, #28
//serial_phex(pid);
//serial_print(", count:");
//serial_phex(count);
//serial_print("\n");
switch (pid) {
aaa: 3801 subs r0, #1
aac: 280c cmp r0, #12
aae: d900 bls.n ab2 <usb_isr+0x7a>
ab0: e1d0 b.n e54 <usb_isr+0x41c>
ab2: f002 f837 bl 2b24 <__gnu_thumb1_case_uhi>
ab6: 0193 .short 0x0193
ab8: 01cf0193 .word 0x01cf0193
abc: 01cf01cf .word 0x01cf01cf
ac0: 01cf01cf .word 0x01cf01cf
ac4: 01ac01cf .word 0x01ac01cf
ac8: 01cf01cf .word 0x01cf01cf
acc: 000d01cf .word 0x000d01cf
// grab the 8 byte setup info
setup.word1 = *(uint32_t *)(buf);
setup.word2 = *(uint32_t *)(buf + 4);
// give the buffer back
b->desc = BDT_DESC(EP0_SIZE, DATA1);
ad0: 4995 ldr r1, [pc, #596] ; (d28 <usb_isr+0x2f0>)
switch (pid) {
case 0x0D: // Setup received from host
//serial_print("PID=Setup\n");
//if (count != 8) ; // panic?
// grab the 8 byte setup info
setup.word1 = *(uint32_t *)(buf);
ad2: 6813 ldr r3, [r2, #0]
ad4: 4f95 ldr r7, [pc, #596] ; (d2c <usb_isr+0x2f4>)
setup.word2 = *(uint32_t *)(buf + 4);
ad6: 6852 ldr r2, [r2, #4]
//serial_print("leftover tx odd\n");
//}
table[index(0, TX, EVEN)].desc = 0;
table[index(0, TX, ODD)].desc = 0;
// first IN after Setup is always DATA1
ep0_tx_data_toggle = 1;
ad8: 4895 ldr r0, [pc, #596] ; (d30 <usb_isr+0x2f8>)
// grab the 8 byte setup info
setup.word1 = *(uint32_t *)(buf);
setup.word2 = *(uint32_t *)(buf + 4);
// give the buffer back
b->desc = BDT_DESC(EP0_SIZE, DATA1);
ada: 6029 str r1, [r5, #0]
//table[index(0, RX, EVEN)].desc = BDT_DESC(EP0_SIZE, 1);
//table[index(0, RX, ODD)].desc = BDT_DESC(EP0_SIZE, 1);
// clear any leftover pending IN transactions
ep0_tx_ptr = NULL;
adc: 4d95 ldr r5, [pc, #596] ; (d34 <usb_isr+0x2fc>)
volatile uint8_t *reg;
uint8_t epconf;
const uint8_t *cfg;
int i;
switch (setup.wRequestAndType) {
ade: 4996 ldr r1, [pc, #600] ; (d38 <usb_isr+0x300>)
b->desc = BDT_DESC(EP0_SIZE, DATA1);
//table[index(0, RX, EVEN)].desc = BDT_DESC(EP0_SIZE, 1);
//table[index(0, RX, ODD)].desc = BDT_DESC(EP0_SIZE, 1);
// clear any leftover pending IN transactions
ep0_tx_ptr = NULL;
ae0: 2600 movs r6, #0
switch (pid) {
case 0x0D: // Setup received from host
//serial_print("PID=Setup\n");
//if (count != 8) ; // panic?
// grab the 8 byte setup info
setup.word1 = *(uint32_t *)(buf);
ae2: 603b str r3, [r7, #0]
setup.word2 = *(uint32_t *)(buf + 4);
ae4: 607a str r2, [r7, #4]
volatile uint8_t *reg;
uint8_t epconf;
const uint8_t *cfg;
int i;
switch (setup.wRequestAndType) {
ae6: b29b uxth r3, r3
//serial_print("leftover tx odd\n");
//}
table[index(0, TX, EVEN)].desc = 0;
table[index(0, TX, ODD)].desc = 0;
// first IN after Setup is always DATA1
ep0_tx_data_toggle = 1;
ae8: 2201 movs r2, #1
b->desc = BDT_DESC(EP0_SIZE, DATA1);
//table[index(0, RX, EVEN)].desc = BDT_DESC(EP0_SIZE, 1);
//table[index(0, RX, ODD)].desc = BDT_DESC(EP0_SIZE, 1);
// clear any leftover pending IN transactions
ep0_tx_ptr = NULL;
aea: 602e str r6, [r5, #0]
//serial_print("leftover tx even\n");
//}
//if (table[index(0, TX, ODD)].desc & 0x80) {
//serial_print("leftover tx odd\n");
//}
table[index(0, TX, EVEN)].desc = 0;
aec: 6126 str r6, [r4, #16]
table[index(0, TX, ODD)].desc = 0;
aee: 61a6 str r6, [r4, #24]
// first IN after Setup is always DATA1
ep0_tx_data_toggle = 1;
af0: 7002 strb r2, [r0, #0]
volatile uint8_t *reg;
uint8_t epconf;
const uint8_t *cfg;
int i;
switch (setup.wRequestAndType) {
af2: 428b cmp r3, r1
af4: d818 bhi.n b28 <usb_isr+0xf0>
af6: 21d0 movs r1, #208 ; 0xd0
af8: 00c9 lsls r1, r1, #3
afa: 428b cmp r3, r1
afc: d300 bcc.n b00 <usb_isr+0xc8>
afe: e0e5 b.n ccc <usb_isr+0x294>
b00: 2181 movs r1, #129 ; 0x81
b02: 4091 lsls r1, r2
b04: 428b cmp r3, r1
b06: d100 bne.n b0a <usb_isr+0xd2>
b08: e0c2 b.n c90 <usb_isr+0x258>
b0a: d806 bhi.n b1a <usb_isr+0xe2>
b0c: 2b80 cmp r3, #128 ; 0x80
b0e: d100 bne.n b12 <usb_isr+0xda>
b10: e0a9 b.n c66 <usb_isr+0x22e>
b12: 2b82 cmp r3, #130 ; 0x82
b14: d100 bne.n b18 <usb_isr+0xe0>
b16: e0ab b.n c70 <usb_isr+0x238>
b18: e0f5 b.n d06 <usb_isr+0x2ce>
b1a: 4a88 ldr r2, [pc, #544] ; (d3c <usb_isr+0x304>)
b1c: 4293 cmp r3, r2
b1e: d100 bne.n b22 <usb_isr+0xea>
b20: e0c5 b.n cae <usb_isr+0x276>
b22: 22a0 movs r2, #160 ; 0xa0
b24: 00d2 lsls r2, r2, #3
b26: e017 b.n b58 <usb_isr+0x120>
b28: 4985 ldr r1, [pc, #532] ; (d40 <usb_isr+0x308>)
b2a: 428b cmp r3, r1
b2c: d100 bne.n b30 <usb_isr+0xf8>
b2e: e152 b.n dd6 <usb_isr+0x39e>
b30: d80d bhi.n b4e <usb_isr+0x116>
b32: 2188 movs r1, #136 ; 0x88
b34: 0109 lsls r1, r1, #4
b36: 428b cmp r3, r1
b38: d100 bne.n b3c <usb_isr+0x104>
b3a: e08e b.n c5a <usb_isr+0x222>
b3c: 2290 movs r2, #144 ; 0x90
b3e: 0112 lsls r2, r2, #4
b40: 4293 cmp r3, r2
b42: d000 beq.n b46 <usb_isr+0x10e>
b44: e0df b.n d06 <usb_isr+0x2ce>
case 0x0500: // SET_ADDRESS
break;
case 0x0900: // SET_CONFIGURATION
//serial_print("configure\n");
usb_configuration = setup.wValue;
b46: 78ba ldrb r2, [r7, #2]
b48: 4b72 ldr r3, [pc, #456] ; (d14 <usb_isr+0x2dc>)
b4a: 701a strb r2, [r3, #0]
b4c: e009 b.n b62 <usb_isr+0x12a>
volatile uint8_t *reg;
uint8_t epconf;
const uint8_t *cfg;
int i;
switch (setup.wRequestAndType) {
b4e: 4a7d ldr r2, [pc, #500] ; (d44 <usb_isr+0x30c>)
b50: 4293 cmp r3, r2
b52: d100 bne.n b56 <usb_isr+0x11e>
b54: e0cf b.n cf6 <usb_isr+0x2be>
b56: 4a7c ldr r2, [pc, #496] ; (d48 <usb_isr+0x310>)
static uint8_t reply_buffer[8];
static void usb_setup(void)
{
const uint8_t *data = NULL;
uint32_t datalen = 0;
b58: 2600 movs r6, #0
volatile uint8_t *reg;
uint8_t epconf;
const uint8_t *cfg;
int i;
switch (setup.wRequestAndType) {
b5a: 4293 cmp r3, r2
b5c: d100 bne.n b60 <usb_isr+0x128>
b5e: e115 b.n d8c <usb_isr+0x354>
b60: e0d1 b.n d06 <usb_isr+0x2ce>
b62: 19a3 adds r3, r4, r6
usb_configuration = setup.wValue;
reg = &USB0_ENDPT1;
cfg = usb_endpoint_config_table;
// clear all BDT entries, free any allocated memory...
for (i=4; i < (NUM_ENDPOINTS+1)*4; i++) {
if (table[i].desc & BDT_OWN) {
b64: 6a19 ldr r1, [r3, #32]
b66: 0609 lsls r1, r1, #24
b68: d503 bpl.n b72 <usb_isr+0x13a>
usb_free((usb_packet_t *)((uint8_t *)(table[i].addr) - 8));
b6a: 6a58 ldr r0, [r3, #36] ; 0x24
b6c: 3808 subs r0, #8
b6e: f000 fabf bl 10f0 <usb_free>
b72: 3608 adds r6, #8
//serial_print("configure\n");
usb_configuration = setup.wValue;
reg = &USB0_ENDPT1;
cfg = usb_endpoint_config_table;
// clear all BDT entries, free any allocated memory...
for (i=4; i < (NUM_ENDPOINTS+1)*4; i++) {
b74: 2e80 cmp r6, #128 ; 0x80
b76: d1f4 bne.n b62 <usb_isr+0x12a>
b78: 2500 movs r5, #0
b7a: 1c2e adds r6, r5, #0
}
}
// free all queued packets
for (i=0; i < NUM_ENDPOINTS; i++) {
usb_packet_t *p, *n;
p = rx_first[i];
b7c: 4a73 ldr r2, [pc, #460] ; (d4c <usb_isr+0x314>)
b7e: 58a8 ldr r0, [r5, r2]
while (p) {
b80: 2800 cmp r0, #0
b82: d005 beq.n b90 <usb_isr+0x158>
n = p->next;
b84: 6843 ldr r3, [r0, #4]
b86: 9301 str r3, [sp, #4]
usb_free(p);
b88: f000 fab2 bl 10f0 <usb_free>
p = n;
b8c: 9801 ldr r0, [sp, #4]
b8e: e7f7 b.n b80 <usb_isr+0x148>
}
rx_first[i] = NULL;
b90: 496e ldr r1, [pc, #440] ; (d4c <usb_isr+0x314>)
rx_last[i] = NULL;
b92: 4b6f ldr r3, [pc, #444] ; (d50 <usb_isr+0x318>)
p = tx_first[i];
b94: 4a6f ldr r2, [pc, #444] ; (d54 <usb_isr+0x31c>)
while (p) {
n = p->next;
usb_free(p);
p = n;
}
rx_first[i] = NULL;
b96: 5148 str r0, [r1, r5]
rx_last[i] = NULL;
b98: 50e8 str r0, [r5, r3]
p = tx_first[i];
b9a: 58a8 ldr r0, [r5, r2]
while (p) {
b9c: 2800 cmp r0, #0
b9e: d005 beq.n bac <usb_isr+0x174>
n = p->next;
ba0: 6843 ldr r3, [r0, #4]
ba2: 9301 str r3, [sp, #4]
usb_free(p);
ba4: f000 faa4 bl 10f0 <usb_free>
p = n;
ba8: 9801 ldr r0, [sp, #4]
baa: e7f7 b.n b9c <usb_isr+0x164>
}
tx_first[i] = NULL;
tx_last[i] = NULL;
bac: 4b6a ldr r3, [pc, #424] ; (d58 <usb_isr+0x320>)
usb_rx_byte_count_data[i] = 0;
bae: 4a6b ldr r2, [pc, #428] ; (d5c <usb_isr+0x324>)
n = p->next;
usb_free(p);
p = n;
}
tx_first[i] = NULL;
tx_last[i] = NULL;
bb0: 50e8 str r0, [r5, r3]
bb2: 0073 lsls r3, r6, #1
usb_rx_byte_count_data[i] = 0;
bb4: 52d0 strh r0, [r2, r3]
while (p) {
n = p->next;
usb_free(p);
p = n;
}
tx_first[i] = NULL;
bb6: 4967 ldr r1, [pc, #412] ; (d54 <usb_isr+0x31c>)
tx_last[i] = NULL;
usb_rx_byte_count_data[i] = 0;
switch (tx_state[i]) {
bb8: 4b69 ldr r3, [pc, #420] ; (d60 <usb_isr+0x328>)
while (p) {
n = p->next;
usb_free(p);
p = n;
}
tx_first[i] = NULL;
bba: 5148 str r0, [r1, r5]
tx_last[i] = NULL;
usb_rx_byte_count_data[i] = 0;
switch (tx_state[i]) {
bbc: 5cf0 ldrb r0, [r6, r3]
bbe: 3802 subs r0, #2
bc0: 2803 cmp r0, #3
bc2: d807 bhi.n bd4 <usb_isr+0x19c>
bc4: f001 ffa4 bl 2b10 <__gnu_thumb1_case_uqi>
bc8: 04020402 .word 0x04020402
case TX_STATE_EVEN_FREE:
case TX_STATE_NONE_FREE_EVEN_FIRST:
tx_state[i] = TX_STATE_BOTH_FREE_EVEN_FIRST;
bcc: 2200 movs r2, #0
bce: e000 b.n bd2 <usb_isr+0x19a>
break;
case TX_STATE_ODD_FREE:
case TX_STATE_NONE_FREE_ODD_FIRST:
tx_state[i] = TX_STATE_BOTH_FREE_ODD_FIRST;
bd0: 2201 movs r2, #1
bd2: 559a strb r2, [r3, r6]
if (table[i].desc & BDT_OWN) {
usb_free((usb_packet_t *)((uint8_t *)(table[i].addr) - 8));
}
}
// free all queued packets
for (i=0; i < NUM_ENDPOINTS; i++) {
bd4: 3601 adds r6, #1
bd6: 3504 adds r5, #4
bd8: 2e04 cmp r6, #4
bda: d1cf bne.n b7c <usb_isr+0x144>
break;
default:
break;
}
}
usb_rx_memory_needed = 0;
bdc: 4a61 ldr r2, [pc, #388] ; (d64 <usb_isr+0x32c>)
bde: 2300 movs r3, #0
be0: 7013 strb r3, [r2, #0]
for (i=1; i <= NUM_ENDPOINTS; i++) {
be2: 2501 movs r5, #1
be4: 1c16 adds r6, r2, #0
be6: 4b60 ldr r3, [pc, #384] ; (d68 <usb_isr+0x330>)
be8: 18ea adds r2, r5, r3
bea: 4b60 ldr r3, [pc, #384] ; (d6c <usb_isr+0x334>)
bec: 0092 lsls r2, r2, #2
bee: 18eb adds r3, r5, r3
bf0: 3b01 subs r3, #1
epconf = *cfg++;
bf2: 781b ldrb r3, [r3, #0]
*reg = epconf;
bf4: 7013 strb r3, [r2, #0]
table[index(i, RX, EVEN)].desc = (AUDIO_RX_SIZE<<16) | BDT_OWN;
table[index(i, RX, ODD)].addr = usb_audio_receive_buffer;
table[index(i, RX, ODD)].desc = (AUDIO_RX_SIZE<<16) | BDT_OWN;
} else
#endif
if (epconf & USB_ENDPT_EPRXEN) {
bf6: 0719 lsls r1, r3, #28
bf8: d520 bpl.n c3c <usb_isr+0x204>
usb_packet_t *p;
p = usb_malloc();
bfa: f000 fa5b bl 10b4 <usb_malloc>
bfe: 016b lsls r3, r5, #5
if (p) {
c00: 2800 cmp r0, #0
c02: d005 beq.n c10 <usb_isr+0x1d8>
table[index(i, RX, EVEN)].addr = p->buf;
c04: 18e2 adds r2, r4, r3
c06: 3008 adds r0, #8
c08: 6050 str r0, [r2, #4]
table[index(i, RX, EVEN)].desc = BDT_DESC(64, 0);
c0a: 4a59 ldr r2, [pc, #356] ; (d70 <usb_isr+0x338>)
c0c: 50e2 str r2, [r4, r3]
c0e: e003 b.n c18 <usb_isr+0x1e0>
} else {
table[index(i, RX, EVEN)].desc = 0;
c10: 50e0 str r0, [r4, r3]
usb_rx_memory_needed++;
c12: 7833 ldrb r3, [r6, #0]
c14: 3301 adds r3, #1
c16: 7033 strb r3, [r6, #0]
}
p = usb_malloc();
c18: f000 fa4c bl 10b4 <usb_malloc>
c1c: 2201 movs r2, #1
c1e: 00ab lsls r3, r5, #2
if (p) {
table[index(i, RX, ODD)].addr = p->buf;
c20: 4313 orrs r3, r2
c22: 00db lsls r3, r3, #3
} else {
table[index(i, RX, EVEN)].desc = 0;
usb_rx_memory_needed++;
}
p = usb_malloc();
if (p) {
c24: 2800 cmp r0, #0
c26: d005 beq.n c34 <usb_isr+0x1fc>
table[index(i, RX, ODD)].addr = p->buf;
c28: 18e2 adds r2, r4, r3
c2a: 3008 adds r0, #8
c2c: 6050 str r0, [r2, #4]
table[index(i, RX, ODD)].desc = BDT_DESC(64, 1);
c2e: 4a3e ldr r2, [pc, #248] ; (d28 <usb_isr+0x2f0>)
c30: 50e2 str r2, [r4, r3]
c32: e003 b.n c3c <usb_isr+0x204>
} else {
table[index(i, RX, ODD)].desc = 0;
c34: 50e0 str r0, [r4, r3]
usb_rx_memory_needed++;
c36: 7833 ldrb r3, [r6, #0]
c38: 3301 adds r3, #1
c3a: 7033 strb r3, [r6, #0]
}
}
table[index(i, TX, EVEN)].desc = 0;
c3c: 00ab lsls r3, r5, #2
c3e: 2202 movs r2, #2
c40: 431a orrs r2, r3
c42: 00d2 lsls r2, r2, #3
c44: 2100 movs r1, #0
c46: 50a1 str r1, [r4, r2]
table[index(i, TX, ODD)].desc = 0;
c48: 2203 movs r2, #3
c4a: 4313 orrs r3, r2
c4c: 4093 lsls r3, r2
default:
break;
}
}
usb_rx_memory_needed = 0;
for (i=1; i <= NUM_ENDPOINTS; i++) {
c4e: 3501 adds r5, #1
table[index(i, RX, ODD)].desc = 0;
usb_rx_memory_needed++;
}
}
table[index(i, TX, EVEN)].desc = 0;
table[index(i, TX, ODD)].desc = 0;
c50: 50e1 str r1, [r4, r3]
default:
break;
}
}
usb_rx_memory_needed = 0;
for (i=1; i <= NUM_ENDPOINTS; i++) {
c52: 2d05 cmp r5, #5
c54: d1c7 bne.n be6 <usb_isr+0x1ae>
static uint8_t reply_buffer[8];
static void usb_setup(void)
{
const uint8_t *data = NULL;
uint32_t datalen = 0;
c56: 1c0e adds r6, r1, #0
c58: e098 b.n d8c <usb_isr+0x354>
}
#endif
}
break;
case 0x0880: // GET_CONFIGURATION
reply_buffer[0] = usb_configuration;
c5a: 4b2e ldr r3, [pc, #184] ; (d14 <usb_isr+0x2dc>)
c5c: 4c45 ldr r4, [pc, #276] ; (d74 <usb_isr+0x33c>)
c5e: 781b ldrb r3, [r3, #0]
datalen = 1;
c60: 1c16 adds r6, r2, #0
}
#endif
}
break;
case 0x0880: // GET_CONFIGURATION
reply_buffer[0] = usb_configuration;
c62: 7023 strb r3, [r4, #0]
c64: e093 b.n d8e <usb_isr+0x356>
datalen = 1;
data = reply_buffer;
break;
case 0x0080: // GET_STATUS (device)
reply_buffer[0] = 0;
c66: 4c43 ldr r4, [pc, #268] ; (d74 <usb_isr+0x33c>)
c68: 7026 strb r6, [r4, #0]
reply_buffer[1] = 0;
c6a: 7066 strb r6, [r4, #1]
datalen = 2;
c6c: 2602 movs r6, #2
c6e: e08e b.n d8e <usb_isr+0x356>
data = reply_buffer;
break;
case 0x0082: // GET_STATUS (endpoint)
if (setup.wIndex > NUM_ENDPOINTS) {
c70: 88bb ldrh r3, [r7, #4]
c72: 2b04 cmp r3, #4
c74: d847 bhi.n d06 <usb_isr+0x2ce>
// TODO: do we need to handle IN vs OUT here?
endpoint0_stall();
return;
}
reply_buffer[0] = 0;
c76: 4c3f ldr r4, [pc, #252] ; (d74 <usb_isr+0x33c>)
reply_buffer[1] = 0;
if (*(uint8_t *)(&USB0_ENDPT0 + setup.wIndex * 4) & 0x02) reply_buffer[0] = 1;
c78: 4d3f ldr r5, [pc, #252] ; (d78 <usb_isr+0x340>)
c7a: 009b lsls r3, r3, #2
if (setup.wIndex > NUM_ENDPOINTS) {
// TODO: do we need to handle IN vs OUT here?
endpoint0_stall();
return;
}
reply_buffer[0] = 0;
c7c: 7026 strb r6, [r4, #0]
reply_buffer[1] = 0;
c7e: 7066 strb r6, [r4, #1]
if (*(uint8_t *)(&USB0_ENDPT0 + setup.wIndex * 4) & 0x02) reply_buffer[0] = 1;
c80: 195b adds r3, r3, r5
c82: 781b ldrb r3, [r3, #0]
c84: 2602 movs r6, #2
c86: 4233 tst r3, r6
c88: d100 bne.n c8c <usb_isr+0x254>
c8a: e080 b.n d8e <usb_isr+0x356>
c8c: 7022 strb r2, [r4, #0]
c8e: e07e b.n d8e <usb_isr+0x356>
data = reply_buffer;
datalen = 2;
break;
case 0x0102: // CLEAR_FEATURE (endpoint)
i = setup.wIndex & 0x7F;
c90: 88ba ldrh r2, [r7, #4]
c92: 237f movs r3, #127 ; 0x7f
c94: 4013 ands r3, r2
if (i > NUM_ENDPOINTS || setup.wValue != 0) {
c96: 2b04 cmp r3, #4
c98: dc35 bgt.n d06 <usb_isr+0x2ce>
c9a: 887e ldrh r6, [r7, #2]
c9c: 2e00 cmp r6, #0
c9e: d132 bne.n d06 <usb_isr+0x2ce>
// TODO: do we need to handle IN vs OUT here?
endpoint0_stall();
return;
}
(*(uint8_t *)(&USB0_ENDPT0 + i * 4)) &= ~0x02;
ca0: 4935 ldr r1, [pc, #212] ; (d78 <usb_isr+0x340>)
ca2: 009b lsls r3, r3, #2
ca4: 185b adds r3, r3, r1
ca6: 781a ldrb r2, [r3, #0]
ca8: 2102 movs r1, #2
caa: 438a bics r2, r1
cac: e029 b.n d02 <usb_isr+0x2ca>
// TODO: do we need to clear the data toggle here?
break;
case 0x0302: // SET_FEATURE (endpoint)
i = setup.wIndex & 0x7F;
cae: 88ba ldrh r2, [r7, #4]
cb0: 237f movs r3, #127 ; 0x7f
cb2: 4013 ands r3, r2
if (i > NUM_ENDPOINTS || setup.wValue != 0) {
cb4: 2b04 cmp r3, #4
cb6: dc26 bgt.n d06 <usb_isr+0x2ce>
cb8: 887e ldrh r6, [r7, #2]
cba: 2e00 cmp r6, #0
cbc: d123 bne.n d06 <usb_isr+0x2ce>
// TODO: do we need to handle IN vs OUT here?
endpoint0_stall();
return;
}
(*(uint8_t *)(&USB0_ENDPT0 + i * 4)) |= 0x02;
cbe: 4a2e ldr r2, [pc, #184] ; (d78 <usb_isr+0x340>)
cc0: 009b lsls r3, r3, #2
cc2: 189b adds r3, r3, r2
cc4: 781a ldrb r2, [r3, #0]
cc6: 2102 movs r1, #2
cc8: 430a orrs r2, r1
cca: e01a b.n d02 <usb_isr+0x2ca>
//serial_print("\n");
for (list = usb_descriptor_list; 1; list++) {
if (list->addr == NULL) break;
//if (setup.wValue == list->wValue &&
//(setup.wIndex == list->wIndex) || ((setup.wValue >> 8) == 3)) {
if (setup.wValue == list->wValue && setup.wIndex == list->wIndex) {
ccc: 887a ldrh r2, [r7, #2]
cce: 88b9 ldrh r1, [r7, #4]
cd0: 4b2a ldr r3, [pc, #168] ; (d7c <usb_isr+0x344>)
case 0x0681:
//serial_print("desc:");
//serial_phex16(setup.wValue);
//serial_print("\n");
for (list = usb_descriptor_list; 1; list++) {
if (list->addr == NULL) break;
cd2: 685c ldr r4, [r3, #4]
cd4: 2c00 cmp r4, #0
cd6: d016 beq.n d06 <usb_isr+0x2ce>
//if (setup.wValue == list->wValue &&
//(setup.wIndex == list->wIndex) || ((setup.wValue >> 8) == 3)) {
if (setup.wValue == list->wValue && setup.wIndex == list->wIndex) {
cd8: 8818 ldrh r0, [r3, #0]
cda: 4290 cmp r0, r2
cdc: d109 bne.n cf2 <usb_isr+0x2ba>
cde: 8858 ldrh r0, [r3, #2]
ce0: 4288 cmp r0, r1
ce2: d106 bne.n cf2 <usb_isr+0x2ba>
data = list->addr;
if ((setup.wValue >> 8) == 3) {
ce4: 0a12 lsrs r2, r2, #8
ce6: 2a03 cmp r2, #3
ce8: d101 bne.n cee <usb_isr+0x2b6>
// for string descriptors, use the descriptor's
// length field, allowing runtime configured
// length.
datalen = *(list->addr);
cea: 7826 ldrb r6, [r4, #0]
cec: e04f b.n d8e <usb_isr+0x356>
} else {
datalen = list->length;
cee: 891e ldrh r6, [r3, #8]
cf0: e04d b.n d8e <usb_isr+0x356>
case 0x0680: // GET_DESCRIPTOR
case 0x0681:
//serial_print("desc:");
//serial_phex16(setup.wValue);
//serial_print("\n");
for (list = usb_descriptor_list; 1; list++) {
cf2: 330c adds r3, #12
cf4: e7ed b.n cd2 <usb_isr+0x29a>
//serial_print("desc: not found\n");
endpoint0_stall();
return;
#if defined(CDC_STATUS_INTERFACE)
case 0x2221: // CDC_SET_CONTROL_LINE_STATE
usb_cdc_line_rtsdtr_millis = systick_millis_count;
cf6: 4b22 ldr r3, [pc, #136] ; (d80 <usb_isr+0x348>)
cf8: 681a ldr r2, [r3, #0]
cfa: 4b22 ldr r3, [pc, #136] ; (d84 <usb_isr+0x34c>)
cfc: 601a str r2, [r3, #0]
usb_cdc_line_rtsdtr = setup.wValue;
cfe: 78ba ldrb r2, [r7, #2]
d00: 4b21 ldr r3, [pc, #132] ; (d88 <usb_isr+0x350>)
d02: 701a strb r2, [r3, #0]
d04: e042 b.n d8c <usb_isr+0x354>
volatile uint8_t usb_reboot_timer = 0;
static void endpoint0_stall(void)
{
USB0_ENDPT0 = USB_ENDPT_EPSTALL | USB_ENDPT_EPRXEN | USB_ENDPT_EPTXEN | USB_ENDPT_EPHSHK;
d06: 4b1c ldr r3, [pc, #112] ; (d78 <usb_isr+0x340>)
d08: 220f movs r2, #15
d0a: 701a strb r2, [r3, #0]
d0c: e063 b.n dd6 <usb_isr+0x39e>
d0e: 46c0 nop ; (mov r8, r8)
d10: 40072080 .word 0x40072080
d14: 1fffff47 .word 0x1fffff47
d18: 1ffffed1 .word 0x1ffffed1
d1c: 1fffff49 .word 0x1fffff49
d20: 40072090 .word 0x40072090
d24: 1ffff800 .word 0x1ffff800
d28: 004000c8 .word 0x004000c8
d2c: 1fffff34 .word 0x1fffff34
d30: 1fffff48 .word 0x1fffff48
d34: 1ffffe68 .word 0x1ffffe68
d38: 00000681 .word 0x00000681
d3c: 00000302 .word 0x00000302
d40: 00002021 .word 0x00002021
d44: 00002221 .word 0x00002221
d48: 00002321 .word 0x00002321
d4c: 1ffffec0 .word 0x1ffffec0
d50: 1ffffe6c .word 0x1ffffe6c
d54: 1fffff14 .word 0x1fffff14
d58: 1fffff24 .word 0x1fffff24
d5c: 2000012c .word 0x2000012c
d60: 1ffffe7c .word 0x1ffffe7c
d64: 1fffff3e .word 0x1fffff3e
d68: 1001c830 .word 0x1001c830
d6c: 00002ed8 .word 0x00002ed8
d70: 00400088 .word 0x00400088
d74: 1fffff3f .word 0x1fffff3f
d78: 400720c0 .word 0x400720c0
d7c: 00002edc .word 0x00002edc
d80: 1ffffe64 .word 0x1ffffe64
d84: 2000013c .word 0x2000013c
d88: 1fffff58 .word 0x1fffff58
static uint8_t reply_buffer[8];
static void usb_setup(void)
{
const uint8_t *data = NULL;
d8c: 1c34 adds r4, r6, #0
//serial_phex32(data);
//serial_print(",");
//serial_phex16(datalen);
//serial_print("\n");
if (datalen > setup.wLength) datalen = setup.wLength;
d8e: 88fb ldrh r3, [r7, #6]
d90: 429e cmp r6, r3
d92: d900 bls.n d96 <usb_isr+0x35e>
d94: 1c1e adds r6, r3, #0
d96: 1e37 subs r7, r6, #0
d98: 2f40 cmp r7, #64 ; 0x40
d9a: d900 bls.n d9e <usb_isr+0x366>
d9c: 2740 movs r7, #64 ; 0x40
size = datalen;
if (size > EP0_SIZE) size = EP0_SIZE;
endpoint0_transmit(data, size);
d9e: 1c20 adds r0, r4, #0
da0: 1c39 adds r1, r7, #0
da2: f7ff fd87 bl 8b4 <endpoint0_transmit>
data += size;
da6: 19e4 adds r4, r4, r7
datalen -= size;
da8: 1bf6 subs r6, r6, r7
if (datalen == 0 && size < EP0_SIZE) return;
daa: d103 bne.n db4 <usb_isr+0x37c>
dac: 1c35 adds r5, r6, #0
dae: 2f40 cmp r7, #64 ; 0x40
db0: d004 beq.n dbc <usb_isr+0x384>
db2: e010 b.n dd6 <usb_isr+0x39e>
db4: 2540 movs r5, #64 ; 0x40
db6: 42b5 cmp r5, r6
db8: d900 bls.n dbc <usb_isr+0x384>
dba: 1c35 adds r5, r6, #0
size = datalen;
if (size > EP0_SIZE) size = EP0_SIZE;
endpoint0_transmit(data, size);
dbc: 1c20 adds r0, r4, #0
dbe: 1c29 adds r1, r5, #0
dc0: f7ff fd78 bl 8b4 <endpoint0_transmit>
data += size;
dc4: 1964 adds r4, r4, r5
datalen -= size;
dc6: 1b76 subs r6, r6, r5
if (datalen == 0 && size < EP0_SIZE) return;
dc8: d101 bne.n dce <usb_isr+0x396>
dca: 2d40 cmp r5, #64 ; 0x40
dcc: d103 bne.n dd6 <usb_isr+0x39e>
ep0_tx_ptr = data;
dce: 4d75 ldr r5, [pc, #468] ; (fa4 <usb_isr+0x56c>)
ep0_tx_len = datalen;
dd0: 4b75 ldr r3, [pc, #468] ; (fa8 <usb_isr+0x570>)
endpoint0_transmit(data, size);
data += size;
datalen -= size;
if (datalen == 0 && size < EP0_SIZE) return;
ep0_tx_ptr = data;
dd2: 602c str r4, [r5, #0]
ep0_tx_len = datalen;
dd4: 801e strh r6, [r3, #0]
serial_print("\n");
#endif
// actually "do" the setup request
usb_setup();
// unfreeze the USB, now that we're ready
USB0_CTL = USB_CTL_USBENSOFEN; // clear TXSUSPENDTOKENBUSY bit
dd6: 2201 movs r2, #1
dd8: 4b74 ldr r3, [pc, #464] ; (fac <usb_isr+0x574>)
dda: e03a b.n e52 <usb_isr+0x41a>
break;
case 0x01: // OUT transaction received from host
case 0x02:
//serial_print("PID=OUT\n");
#ifdef CDC_STATUS_INTERFACE
if (setup.wRequestAndType == 0x2021 /*CDC_SET_LINE_CODING*/) {
ddc: 4b74 ldr r3, [pc, #464] ; (fb0 <usb_isr+0x578>)
dde: 8819 ldrh r1, [r3, #0]
de0: 4b74 ldr r3, [pc, #464] ; (fb4 <usb_isr+0x57c>)
de2: 4299 cmp r1, r3
de4: d110 bne.n e08 <usb_isr+0x3d0>
de6: 2300 movs r3, #0
int i;
uint8_t *dst = (uint8_t *)usb_cdc_line_coding;
//serial_print("set line coding ");
for (i=0; i<7; i++) {
//serial_phex(*buf);
*dst++ = *buf++;
de8: 5cd0 ldrb r0, [r2, r3]
dea: 4973 ldr r1, [pc, #460] ; (fb8 <usb_isr+0x580>)
dec: 54c8 strb r0, [r1, r3]
#ifdef CDC_STATUS_INTERFACE
if (setup.wRequestAndType == 0x2021 /*CDC_SET_LINE_CODING*/) {
int i;
uint8_t *dst = (uint8_t *)usb_cdc_line_coding;
//serial_print("set line coding ");
for (i=0; i<7; i++) {
dee: 3301 adds r3, #1
df0: 2b07 cmp r3, #7
df2: d1f9 bne.n de8 <usb_isr+0x3b0>
//serial_phex(*buf);
*dst++ = *buf++;
}
//serial_phex32(usb_cdc_line_coding[0]);
//serial_print("\n");
if (usb_cdc_line_coding[0] == 134) usb_reboot_timer = 15;
df4: 680b ldr r3, [r1, #0]
df6: 2b86 cmp r3, #134 ; 0x86
df8: d102 bne.n e00 <usb_isr+0x3c8>
dfa: 4b70 ldr r3, [pc, #448] ; (fbc <usb_isr+0x584>)
dfc: 220f movs r2, #15
dfe: 701a strb r2, [r3, #0]
endpoint0_transmit(NULL, 0);
e00: 2000 movs r0, #0
e02: 1c01 adds r1, r0, #0
e04: f7ff fd56 bl 8b4 <endpoint0_transmit>
if (usb_audio_set_feature(&setup, buf)) {
endpoint0_transmit(NULL, 0);
}
#endif
// give the buffer back
b->desc = BDT_DESC(EP0_SIZE, DATA1);
e08: 4b6d ldr r3, [pc, #436] ; (fc0 <usb_isr+0x588>)
e0a: 602b str r3, [r5, #0]
e0c: e022 b.n e54 <usb_isr+0x41c>
//serial_print("PID=IN:");
//serial_phex(stat);
//serial_print("\n");
// send remaining data, if any...
data = ep0_tx_ptr;
e0e: 4f65 ldr r7, [pc, #404] ; (fa4 <usb_isr+0x56c>)
e10: 683d ldr r5, [r7, #0]
if (data) {
e12: 2d00 cmp r5, #0
e14: d013 beq.n e3e <usb_isr+0x406>
size = ep0_tx_len;
e16: 4964 ldr r1, [pc, #400] ; (fa8 <usb_isr+0x570>)
e18: 880e ldrh r6, [r1, #0]
e1a: 1e34 subs r4, r6, #0
e1c: 2c40 cmp r4, #64 ; 0x40
e1e: d900 bls.n e22 <usb_isr+0x3ea>
e20: 2440 movs r4, #64 ; 0x40
if (size > EP0_SIZE) size = EP0_SIZE;
endpoint0_transmit(data, size);
e22: 1c28 adds r0, r5, #0
e24: 1c21 adds r1, r4, #0
e26: f7ff fd45 bl 8b4 <endpoint0_transmit>
data += size;
ep0_tx_len -= size;
e2a: 1b36 subs r6, r6, r4
e2c: 4a5e ldr r2, [pc, #376] ; (fa8 <usb_isr+0x570>)
e2e: b2b6 uxth r6, r6
e30: 8016 strh r6, [r2, #0]
ep0_tx_ptr = (ep0_tx_len > 0 || size == EP0_SIZE) ? data : NULL;
e32: 2e00 cmp r6, #0
e34: d101 bne.n e3a <usb_isr+0x402>
e36: 2c40 cmp r4, #64 ; 0x40
e38: d100 bne.n e3c <usb_isr+0x404>
data = ep0_tx_ptr;
if (data) {
size = ep0_tx_len;
if (size > EP0_SIZE) size = EP0_SIZE;
endpoint0_transmit(data, size);
data += size;
e3a: 192e adds r6, r5, r4
ep0_tx_len -= size;
ep0_tx_ptr = (ep0_tx_len > 0 || size == EP0_SIZE) ? data : NULL;
e3c: 603e str r6, [r7, #0]
}
if (setup.bRequest == 5 && setup.bmRequestType == 0) {
e3e: 4b5c ldr r3, [pc, #368] ; (fb0 <usb_isr+0x578>)
e40: 22a0 movs r2, #160 ; 0xa0
e42: 8819 ldrh r1, [r3, #0]
e44: 00d2 lsls r2, r2, #3
e46: 4291 cmp r1, r2
e48: d104 bne.n e54 <usb_isr+0x41c>
setup.bRequest = 0;
e4a: 2200 movs r2, #0
e4c: 705a strb r2, [r3, #1]
//serial_print("set address: ");
//serial_phex16(setup.wValue);
//serial_print("\n");
USB0_ADDR = setup.wValue;
e4e: 789a ldrb r2, [r3, #2]
e50: 4b5c ldr r3, [pc, #368] ; (fc4 <usb_isr+0x58c>)
e52: 701a strb r2, [r3, #0]
//default:
//serial_print("PID=unknown:");
//serial_phex(pid);
//serial_print("\n");
}
USB0_CTL = USB_CTL_USBENSOFEN; // clear TXSUSPENDTOKENBUSY bit
e54: 2201 movs r2, #1
e56: 4b55 ldr r3, [pc, #340] ; (fac <usb_isr+0x574>)
e58: e061 b.n f1e <usb_isr+0x4e6>
//serial_print(stat & 0x04 ? ",odd\n" : ",even\n");
endpoint = stat >> 4;
if (endpoint == 0) {
usb_control(stat);
} else {
bdt_t *b = stat2bufferdescriptor(stat);
e5a: 00d2 lsls r2, r2, #3
e5c: 18a4 adds r4, r4, r2
usb_packet_t *packet = (usb_packet_t *)((uint8_t *)(b->addr) - 8);
e5e: 6860 ldr r0, [r4, #4]
serial_print(((uint32_t)b & 8) ? ", odd" : ", even");
serial_print(", count:");
serial_phex(b->desc >> 16);
serial_print("\n");
#endif
endpoint--; // endpoint is index to zero-based arrays
e60: 3e01 subs r6, #1
endpoint = stat >> 4;
if (endpoint == 0) {
usb_control(stat);
} else {
bdt_t *b = stat2bufferdescriptor(stat);
usb_packet_t *packet = (usb_packet_t *)((uint8_t *)(b->addr) - 8);
e62: 3808 subs r0, #8
serial_print(((uint32_t)b & 8) ? ", odd" : ", even");
serial_print(", count:");
serial_phex(b->desc >> 16);
serial_print("\n");
#endif
endpoint--; // endpoint is index to zero-based arrays
e64: b2f6 uxtb r6, r6
b->addr = &usb_audio_sync_feedback;
b->desc = (3 << 16) | BDT_OWN;
tx_state[endpoint] ^= 1;
} else
#endif
if (stat & 0x08) { // transmit
e66: 402b ands r3, r5
e68: d036 beq.n ed8 <usb_isr+0x4a0>
usb_free(packet);
e6a: f000 f941 bl 10f0 <usb_free>
packet = tx_first[endpoint];
e6e: 4956 ldr r1, [pc, #344] ; (fc8 <usb_isr+0x590>)
e70: 00b0 lsls r0, r6, #2
e72: 5842 ldr r2, [r0, r1]
e74: 4b55 ldr r3, [pc, #340] ; (fcc <usb_isr+0x594>)
if (packet) {
e76: 2a00 cmp r2, #0
e78: d01b beq.n eb2 <usb_isr+0x47a>
//serial_print("tx packet\n");
tx_first[endpoint] = packet->next;
e7a: 6855 ldr r5, [r2, #4]
e7c: 5045 str r5, [r0, r1]
b->addr = packet->buf;
e7e: 1c11 adds r1, r2, #0
switch (tx_state[endpoint]) {
e80: 5d98 ldrb r0, [r3, r6]
usb_free(packet);
packet = tx_first[endpoint];
if (packet) {
//serial_print("tx packet\n");
tx_first[endpoint] = packet->next;
b->addr = packet->buf;
e82: 3108 adds r1, #8