Skip to content

Instantly share code, notes, and snippets.

@kriegsman
Created March 13, 2017 20:25
Show Gist options
  • Save kriegsman/a0fe3dde20c5eb99610044b40bdabdbe to your computer and use it in GitHub Desktop.
Save kriegsman/a0fe3dde20c5eb99610044b40bdabdbe to your computer and use it in GitHub Desktop.
Teensy30
PaulTeensyLCPaletteBugTest.ino.elf: file format elf32-littlearm
Disassembly of section .text:
00000000 <_VectorsFlash>:
0: 00 20 00 20 f9 00 00 00 59 15 00 00 25 15 00 00 . . ....Y...%...
10: 25 15 00 00 25 15 00 00 25 15 00 00 25 15 00 00 %...%...%...%...
20: 25 15 00 00 25 15 00 00 25 15 00 00 59 15 00 00 %...%...%...Y...
30: 59 15 00 00 25 15 00 00 59 15 00 00 15 15 00 00 Y...%...Y.......
40: 59 15 00 00 59 15 00 00 59 15 00 00 59 15 00 00 Y...Y...Y...Y...
50: 59 15 00 00 59 15 00 00 59 15 00 00 59 15 00 00 Y...Y...Y...Y...
60: 59 15 00 00 59 15 00 00 59 15 00 00 59 15 00 00 Y...Y...Y...Y...
70: 59 15 00 00 59 15 00 00 59 15 00 00 59 15 00 00 Y...Y...Y...Y...
80: 61 1b 00 00 59 15 00 00 05 21 00 00 59 15 00 00 a...Y....!..Y...
90: a5 25 00 00 59 15 00 00 59 15 00 00 59 15 00 00 .%..Y...Y...Y...
a0: 59 15 00 00 59 15 00 00 59 15 00 00 59 15 00 00 Y...Y...Y...Y...
b0: 59 15 00 00 59 15 00 00 59 15 00 00 59 15 00 00 Y...Y...Y...Y...
c0: 59 15 00 00 59 15 00 00 59 15 00 00 0d 0a 00 00 Y...Y...Y.......
d0: 59 15 00 00 59 15 00 00 59 15 00 00 59 15 00 00 Y...Y...Y...Y...
e0: 59 15 00 00 59 15 00 00 59 15 00 00 59 15 00 00 Y...Y...Y...Y...
f0: 59 15 00 00 59 15 00 00 Y...Y...
000000f8 <ResetHandler>:
volatile int n;
#endif
//volatile int count;
#ifdef KINETISK
WDOG_UNLOCK = WDOG_UNLOCK_SEQ1;
f8: 4b54 ldr r3, [pc, #336] ; (24c <ResetHandler+0x154>)
fa: f24c 5220 movw r2, #50464 ; 0xc520
__attribute__ ((optimize("-Os")))
#else
__attribute__ ((section(".startup"),optimize("-Os")))
#endif
void ResetHandler(void)
{
fe: b510 push {r4, lr}
volatile int n;
#endif
//volatile int count;
#ifdef KINETISK
WDOG_UNLOCK = WDOG_UNLOCK_SEQ1;
100: 801a strh r2, [r3, #0]
WDOG_UNLOCK = WDOG_UNLOCK_SEQ2;
102: f64d 1228 movw r2, #55592 ; 0xd928
106: 801a strh r2, [r3, #0]
__asm__ volatile ("nop");
108: bf00 nop
__asm__ volatile ("nop");
10a: bf00 nop
#endif
// programs using the watchdog timer or needing to initialize hardware as
// early as possible can implement startup_early_hook()
startup_early_hook();
10c: f001 fa28 bl 1560 <startup_early_hook>
// enable clocks to always-used peripherals
#if defined(__MK20DX128__)
SIM_SCGC5 = 0x00043F82; // clocks active to all GPIO
110: 4b4f ldr r3, [pc, #316] ; (250 <ResetHandler+0x158>)
112: 4a50 ldr r2, [pc, #320] ; (254 <ResetHandler+0x15c>)
114: 601a str r2, [r3, #0]
SIM_SCGC6 = SIM_SCGC6_RTC | SIM_SCGC6_FTM0 | SIM_SCGC6_FTM1 | SIM_SCGC6_ADC0 | SIM_SCGC6_FTFL;
116: 4a50 ldr r2, [pc, #320] ; (258 <ResetHandler+0x160>)
118: 605a str r2, [r3, #4]
UART0_C2 = UART_C2_TE;
PORTB_PCR17 = PORT_PCR_MUX(3);
#endif
#ifdef KINETISK
// if the RTC oscillator isn't enabled, get it started early
if (!(RTC_CR & RTC_CR_OSCE)) {
11a: f5a3 4330 sub.w r3, r3, #45056 ; 0xb000
11e: 3b28 subs r3, #40 ; 0x28
120: 681a ldr r2, [r3, #0]
122: f412 7280 ands.w r2, r2, #256 ; 0x100
126: d104 bne.n 132 <ResetHandler+0x3a>
RTC_SR = 0;
128: 494c ldr r1, [pc, #304] ; (25c <ResetHandler+0x164>)
12a: 600a str r2, [r1, #0]
RTC_CR = RTC_CR_SC16P | RTC_CR_SC4P | RTC_CR_OSCE;
12c: f44f 52a8 mov.w r2, #5376 ; 0x1500
130: 601a str r2, [r3, #0]
}
#endif
// release I/O pins hold, if we woke up from VLLS mode
if (PMC_REGSC & PMC_REGSC_ACKISO) PMC_REGSC |= PMC_REGSC_ACKISO;
132: 4b4b ldr r3, [pc, #300] ; (260 <ResetHandler+0x168>)
134: 781a ldrb r2, [r3, #0]
136: 0711 lsls r1, r2, #28
138: d503 bpl.n 142 <ResetHandler+0x4a>
13a: 781a ldrb r2, [r3, #0]
13c: f042 0208 orr.w r2, r2, #8
140: 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;
142: 4b48 ldr r3, [pc, #288] ; (264 <ResetHandler+0x16c>)
144: 222a movs r2, #42 ; 0x2a
146: 701a strb r2, [r3, #0]
#endif
// TODO: do this while the PLL is waiting to lock....
while (dest < &_edata) *dest++ = *src++;
148: 2300 movs r3, #0
14a: 4a47 ldr r2, [pc, #284] ; (268 <ResetHandler+0x170>)
14c: 4947 ldr r1, [pc, #284] ; (26c <ResetHandler+0x174>)
14e: 1898 adds r0, r3, r2
150: 4288 cmp r0, r1
152: d204 bcs.n 15e <ResetHandler+0x66>
154: 4946 ldr r1, [pc, #280] ; (270 <ResetHandler+0x178>)
156: 5859 ldr r1, [r3, r1]
158: 5099 str r1, [r3, r2]
15a: 3304 adds r3, #4
15c: e7f5 b.n 14a <ResetHandler+0x52>
15e: 4a45 ldr r2, [pc, #276] ; (274 <ResetHandler+0x17c>)
dest = &_sbss;
while (dest < &_ebss) *dest++ = 0;
160: 4b45 ldr r3, [pc, #276] ; (278 <ResetHandler+0x180>)
162: 429a cmp r2, r3
164: f04f 0300 mov.w r3, #0
168: d202 bcs.n 170 <ResetHandler+0x78>
16a: f842 3b04 str.w r3, [r2], #4
16e: e7f7 b.n 160 <ResetHandler+0x68>
// default all interrupts to medium priority level
for (i=0; i < NVIC_NUM_INTERRUPTS + 16; i++) _VectorsRam[i] = _VectorsFlash[i];
170: 4942 ldr r1, [pc, #264] ; (27c <ResetHandler+0x184>)
172: 4a43 ldr r2, [pc, #268] ; (280 <ResetHandler+0x188>)
174: 5859 ldr r1, [r3, r1]
176: 5099 str r1, [r3, r2]
178: 3304 adds r3, #4
17a: 2bf8 cmp r3, #248 ; 0xf8
17c: d1f8 bne.n 170 <ResetHandler+0x78>
17e: 4b41 ldr r3, [pc, #260] ; (284 <ResetHandler+0x18c>)
for (i=0; i < NVIC_NUM_INTERRUPTS; i++) NVIC_SET_PRIORITY(i, 128);
180: 2180 movs r1, #128 ; 0x80
182: f803 1b01 strb.w r1, [r3], #1
186: 4940 ldr r1, [pc, #256] ; (288 <ResetHandler+0x190>)
188: 428b cmp r3, r1
18a: d1f9 bne.n 180 <ResetHandler+0x88>
SCB_VTOR = (uint32_t)_VectorsRam; // use vector table in RAM
18c: 4b3f ldr r3, [pc, #252] ; (28c <ResetHandler+0x194>)
18e: 601a str r2, [r3, #0]
// C6[PLLS] bit is written to 0
// C2[LP] bit is written to 1
#else
#if defined(KINETISK)
// enable capacitors for crystal
OSC0_CR = OSC_SC8P | OSC_SC2P;
190: 4b3f ldr r3, [pc, #252] ; (290 <ResetHandler+0x198>)
192: 220a movs r2, #10
194: 701a strb r2, [r3, #0]
#elif defined(KINETISL)
// enable capacitors for crystal
OSC0_CR = OSC_SC8P | OSC_SC2P | OSC_ERCLKEN;
#endif
// enable osc, 8-32 MHz range, low power mode
MCG_C2 = MCG_C2_RANGE0(2) | MCG_C2_EREFS;
196: f5a3 5380 sub.w r3, r3, #4096 ; 0x1000
19a: 2224 movs r2, #36 ; 0x24
19c: 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);
19e: 22a0 movs r2, #160 ; 0xa0
1a0: 701a strb r2, [r3, #0]
// wait for crystal oscillator to begin
while ((MCG_S & MCG_S_OSCINIT0) == 0) ;
1a2: 799a ldrb r2, [r3, #6]
1a4: 0792 lsls r2, r2, #30
1a6: d5fc bpl.n 1a2 <ResetHandler+0xaa>
// wait for FLL to use oscillator
while ((MCG_S & MCG_S_IREFST) != 0) ;
1a8: 799a ldrb r2, [r3, #6]
1aa: 06d4 lsls r4, r2, #27
1ac: d4fc bmi.n 1a8 <ResetHandler+0xb0>
// wait for MCGOUT to use oscillator
while ((MCG_S & MCG_S_CLKST_MASK) != MCG_S_CLKST(2)) ;
1ae: 4b39 ldr r3, [pc, #228] ; (294 <ResetHandler+0x19c>)
1b0: 799a ldrb r2, [r3, #6]
1b2: f002 020c and.w r2, r2, #12
1b6: 2a08 cmp r2, #8
1b8: d1f9 bne.n 1ae <ResetHandler+0xb6>
#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
1ba: 2203 movs r2, #3
1bc: 711a strb r2, [r3, #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
1be: 2240 movs r2, #64 ; 0x40
1c0: 715a strb r2, [r3, #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)) ;
1c2: 799a ldrb r2, [r3, #6]
1c4: 0690 lsls r0, r2, #26
1c6: d5fc bpl.n 1c2 <ResetHandler+0xca>
// wait for PLL to lock
while (!(MCG_S & MCG_S_LOCK0)) ;
1c8: 4b32 ldr r3, [pc, #200] ; (294 <ResetHandler+0x19c>)
1ca: 799a ldrb r2, [r3, #6]
1cc: 0651 lsls r1, r2, #25
1ce: d5fb bpl.n 1c8 <ResetHandler+0xd0>
#endif
SIM_CLKDIV2 = SIM_CLKDIV2_USBDIV(4) | SIM_CLKDIV2_USBFRAC;
#elif F_CPU == 96000000
// config divisors: 96 MHz core, 48 MHz bus, 24 MHz flash, USB = 96 / 2
#if F_BUS == 48000000
SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(0) | SIM_CLKDIV1_OUTDIV2(1) | SIM_CLKDIV1_OUTDIV4(3);
1d0: 4a31 ldr r2, [pc, #196] ; (298 <ResetHandler+0x1a0>)
1d2: 4932 ldr r1, [pc, #200] ; (29c <ResetHandler+0x1a4>)
1d4: 6011 str r1, [r2, #0]
#elif F_BUS == 96000000
SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(0) | SIM_CLKDIV1_OUTDIV2(0) | SIM_CLKDIV1_OUTDIV4(3);
#else
#error "This F_CPU & F_BUS combination is not supported"
#endif
SIM_CLKDIV2 = SIM_CLKDIV2_USBDIV(1);
1d6: 2102 movs r1, #2
1d8: 6051 str r1, [r2, #4]
#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);
1da: 2220 movs r2, #32
1dc: 701a strb r2, [r3, #0]
// wait for PLL clock to be used
while ((MCG_S & MCG_S_CLKST_MASK) != MCG_S_CLKST(3)) ;
1de: 4b2d ldr r3, [pc, #180] ; (294 <ResetHandler+0x19c>)
1e0: 799b ldrb r3, [r3, #6]
1e2: f003 030c and.w r3, r3, #12
1e6: 2b0c cmp r3, #12
1e8: d1f9 bne.n 1de <ResetHandler+0xe6>
// USB uses PLL clock, trace is CPU clock, CLKOUT=OSCERCLK0
#if defined(KINETISK)
#if F_CPU == 216000000 || F_CPU == 180000000
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);
1ea: 4b2d ldr r3, [pc, #180] ; (2a0 <ResetHandler+0x1a8>)
1ec: 4a2d ldr r2, [pc, #180] ; (2a4 <ResetHandler+0x1ac>)
1ee: 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;
1f0: 4b2d ldr r3, [pc, #180] ; (2a8 <ResetHandler+0x1b0>)
1f2: 4a2e ldr r2, [pc, #184] ; (2ac <ResetHandler+0x1b4>)
1f4: 601a str r2, [r3, #0]
SYST_CVR = 0;
1f6: 2200 movs r2, #0
1f8: 605a str r2, [r3, #4]
SYST_CSR = SYST_CSR_CLKSOURCE | SYST_CSR_TICKINT | SYST_CSR_ENABLE;
1fa: 2207 movs r2, #7
1fc: f843 2c04 str.w r2, [r3, #-4]
SCB_SHPR3 = 0x20200000; // Systick = priority 32
200: 4a2b ldr r2, [pc, #172] ; (2b0 <ResetHandler+0x1b8>)
202: f8c3 2d0c str.w r2, [r3, #3340] ; 0xd0c
//init_pins();
__enable_irq();
206: b662 cpsie i
_init_Teensyduino_internal_();
208: f000 faf0 bl 7ec <_init_Teensyduino_internal_>
#if defined(KINETISK)
// RTC initialization
if (RTC_SR & RTC_SR_TIF) {
20c: 4b13 ldr r3, [pc, #76] ; (25c <ResetHandler+0x164>)
20e: 681b ldr r3, [r3, #0]
210: 07da lsls r2, r3, #31
212: d505 bpl.n 220 <ResetHandler+0x128>
// compiled-in time will be stale. Write a special
// flag into the VBAT register file indicating the
// RTC is set with known-stale time and should be
// updated when fresh time is known.
#if ARDUINO >= 10600
rtc_set((uint32_t)&__rtc_localtime);
214: 4827 ldr r0, [pc, #156] ; (2b4 <ResetHandler+0x1bc>)
216: f000 fa47 bl 6a8 <rtc_set>
#else
rtc_set(TIME_T);
#endif
*(uint32_t *)0x4003E01C = 0x5A94C3A5;
21a: 4b27 ldr r3, [pc, #156] ; (2b8 <ResetHandler+0x1c0>)
21c: 4a27 ldr r2, [pc, #156] ; (2bc <ResetHandler+0x1c4>)
21e: 601a str r2, [r3, #0]
}
if ((RCM_SRS0 & RCM_SRS0_PIN) && (*(uint32_t *)0x4003E01C == 0x5A94C3A5)) {
220: 4b27 ldr r3, [pc, #156] ; (2c0 <ResetHandler+0x1c8>)
222: 781b ldrb r3, [r3, #0]
224: 065b lsls r3, r3, #25
226: d509 bpl.n 23c <ResetHandler+0x144>
228: 4c23 ldr r4, [pc, #140] ; (2b8 <ResetHandler+0x1c0>)
22a: 4a24 ldr r2, [pc, #144] ; (2bc <ResetHandler+0x1c4>)
22c: 6823 ldr r3, [r4, #0]
22e: 4293 cmp r3, r2
230: d104 bne.n 23c <ResetHandler+0x144>
// Our compiled-in time will be very fresh, so set
// the RTC with this, and clear the VBAT resister file
// data so we don't mess with the time after it's been
// set well.
#if ARDUINO >= 10600
rtc_set((uint32_t)&__rtc_localtime);
232: 4820 ldr r0, [pc, #128] ; (2b4 <ResetHandler+0x1bc>)
234: f000 fa38 bl 6a8 <rtc_set>
#else
rtc_set(TIME_T);
#endif
*(uint32_t *)0x4003E01C = 0;
238: 2300 movs r3, #0
23a: 6023 str r3, [r4, #0]
}
#endif
__libc_init_array();
23c: f002 fbea bl 2a14 <__libc_init_array>
startup_late_hook();
240: f001 f994 bl 156c <startup_late_hook>
main();
244: f001 f8d4 bl 13f0 <main>
248: e7fe b.n 248 <ResetHandler+0x150>
24a: bf00 nop
24c: 4005200e .word 0x4005200e
250: 40048038 .word 0x40048038
254: 00043f82 .word 0x00043f82
258: 2b000001 .word 0x2b000001
25c: 4003d014 .word 0x4003d014
260: 4007d002 .word 0x4007d002
264: 4007e000 .word 0x4007e000
268: 1fffe560 .word 0x1fffe560
26c: 1fffe608 .word 0x1fffe608
270: 00002d70 .word 0x00002d70
274: 1fffe608 .word 0x1fffe608
278: 1fffe938 .word 0x1fffe938
27c: 00000000 .word 0x00000000
280: 1fffe100 .word 0x1fffe100
284: e000e400 .word 0xe000e400
288: e000e42e .word 0xe000e42e
28c: e000ed08 .word 0xe000ed08
290: 40065000 .word 0x40065000
294: 40064000 .word 0x40064000
298: 40048044 .word 0x40048044
29c: 01030000 .word 0x01030000
2a0: 40048004 .word 0x40048004
2a4: 000510c0 .word 0x000510c0
2a8: e000e014 .word 0xe000e014
2ac: 000176ff .word 0x000176ff
2b0: 20200000 .word 0x20200000
2b4: 58c6c6a9 .word 0x58c6c6a9
2b8: 4003e01c .word 0x4003e01c
2bc: 5a94c3a5 .word 0x5a94c3a5
2c0: 4007f000 .word 0x4007f000
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: 4c05 ldr r4, [pc, #20] ; (428 <__do_global_dtors_aux+0x18>)
414: 7823 ldrb r3, [r4, #0]
416: b933 cbnz r3, 426 <__do_global_dtors_aux+0x16>
418: 4b04 ldr r3, [pc, #16] ; (42c <__do_global_dtors_aux+0x1c>)
41a: b113 cbz r3, 422 <__do_global_dtors_aux+0x12>
41c: 4804 ldr r0, [pc, #16] ; (430 <__do_global_dtors_aux+0x20>)
41e: f3af 8000 nop.w
422: 2301 movs r3, #1
424: 7023 strb r3, [r4, #0]
426: bd10 pop {r4, pc}
428: 1fffe608 .word 0x1fffe608
42c: 00000000 .word 0x00000000
430: 00002d70 .word 0x00002d70
00000434 <frame_dummy>:
434: b508 push {r3, lr}
436: 4b06 ldr r3, [pc, #24] ; (450 <frame_dummy+0x1c>)
438: b11b cbz r3, 442 <frame_dummy+0xe>
43a: 4806 ldr r0, [pc, #24] ; (454 <frame_dummy+0x20>)
43c: 4906 ldr r1, [pc, #24] ; (458 <frame_dummy+0x24>)
43e: f3af 8000 nop.w
442: 4806 ldr r0, [pc, #24] ; (45c <frame_dummy+0x28>)
444: 6803 ldr r3, [r0, #0]
446: b113 cbz r3, 44e <frame_dummy+0x1a>
448: 4b05 ldr r3, [pc, #20] ; (460 <frame_dummy+0x2c>)
44a: b103 cbz r3, 44e <frame_dummy+0x1a>
44c: 4798 blx r3
44e: bd08 pop {r3, pc}
450: 00000000 .word 0x00000000
454: 00002d70 .word 0x00002d70
458: 1fffe60c .word 0x1fffe60c
45c: 1fffe608 .word 0x1fffe608
460: 00000000 .word 0x00000000
00000464 <_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(); }
464: b538 push {r3, r4, r5, lr}
466: 4604 mov r4, r0
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)); }
468: 4608 mov r0, r1
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(); }
46a: 460d mov r5, r1
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)); }
46c: f002 faf8 bl 2a60 <strlen>
470: 6823 ldr r3, [r4, #0]
472: 4602 mov r2, r0
474: 4629 mov r1, r5
476: 685b ldr r3, [r3, #4]
478: 4620 mov r0, r4
47a: 4798 blx r3
47c: 4605 mov r5, r0
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(); }
47e: 4620 mov r0, r4
480: f000 ff6e bl 1360 <_ZN5Print7printlnEv>
484: 4428 add r0, r5
486: bd38 pop {r3, r4, r5, pc}
00000488 <_ZN13CRGBPalette16aSEPKh>:
// the exact stripe widths at the expense of dropping some colors.
CRGBPalette16( TProgmemRGBGradientPalette_bytes progpal )
{
*this = progpal;
}
CRGBPalette16& operator=( TProgmemRGBGradientPalette_bytes progpal )
488: e92d 4ff0 stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, fp, lr}
48c: 4607 mov r7, r0
48e: b089 sub sp, #36 ; 0x24
{
TRGBGradientPaletteEntryUnion* progent = (TRGBGradientPaletteEntryUnion*)(progpal);
TRGBGradientPaletteEntryUnion u;
// Count entries
uint16_t count = 0;
490: 2400 movs r4, #0
do {
u.dword = FL_PGM_READ_DWORD_NEAR(progent + count);
492: f851 3024 ldr.w r3, [r1, r4, lsl #2]
TRGBGradientPaletteEntryUnion* progent = (TRGBGradientPaletteEntryUnion*)(progpal);
TRGBGradientPaletteEntryUnion u;
// Count entries
uint16_t count = 0;
do {
496: b2de uxtb r6, r3
u.dword = FL_PGM_READ_DWORD_NEAR(progent + count);
count++;;
498: 3401 adds r4, #1
TRGBGradientPaletteEntryUnion* progent = (TRGBGradientPaletteEntryUnion*)(progpal);
TRGBGradientPaletteEntryUnion u;
// Count entries
uint16_t count = 0;
do {
49a: 2eff cmp r6, #255 ; 0xff
u.dword = FL_PGM_READ_DWORD_NEAR(progent + count);
count++;;
49c: b2a4 uxth r4, r4
TRGBGradientPaletteEntryUnion* progent = (TRGBGradientPaletteEntryUnion*)(progpal);
TRGBGradientPaletteEntryUnion u;
// Count entries
uint16_t count = 0;
do {
49e: d1f8 bne.n 492 <_ZN13CRGBPalette16aSEPKh+0xa>
count++;;
} while ( u.index != 255);
int8_t lastSlotUsed = -1;
u.dword = FL_PGM_READ_DWORD_NEAR( progent);
4a0: 680b ldr r3, [r1, #0]
4a2: 9102 str r1, [sp, #8]
CRGB rgbstart( u.r, u.g, u.b);
4a4: f3c3 2007 ubfx r0, r3, #8, #8
4a8: f3c3 4207 ubfx r2, r3, #16, #8
4ac: ea4f 6813 mov.w r8, r3, lsr #24
int indexstart = 0;
4b0: f04f 0b00 mov.w fp, #0
uint8_t istart8 = 0;
uint8_t iend8 = 0;
while( indexstart < 255) {
progent++;
u.dword = FL_PGM_READ_DWORD_NEAR( progent);
4b4: 9902 ldr r1, [sp, #8]
4b6: f851 3f04 ldr.w r3, [r1, #4]!
4ba: 9102 str r1, [sp, #8]
int indexend = u.index;
CRGB rgbend( u.r, u.g, u.b);
4bc: f3c3 2907 ubfx r9, r3, #8, #8
4c0: fa5f f189 uxtb.w r1, r9
4c4: f3c3 4c07 ubfx ip, r3, #16, #8
4c8: f3c3 6e07 ubfx lr, r3, #24, #8
uint8_t istart8 = 0;
uint8_t iend8 = 0;
while( indexstart < 255) {
progent++;
u.dword = FL_PGM_READ_DWORD_NEAR( progent);
int indexend = u.index;
4cc: b2dd uxtb r5, r3
CRGB rgbend( u.r, u.g, u.b);
4ce: 9103 str r1, [sp, #12]
4d0: fa5f f38e uxtb.w r3, lr
4d4: fa5f f18c uxtb.w r1, ip
istart8 = indexstart / 16;
4d8: ea4f 1b2b mov.w fp, fp, asr #4
iend8 = indexend / 16;
if( count < 16) {
4dc: 2c0f cmp r4, #15
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);
4de: 9105 str r1, [sp, #20]
4e0: 9304 str r3, [sp, #16]
istart8 = indexstart / 16;
4e2: fa5f f18b uxtb.w r1, fp
iend8 = indexend / 16;
4e6: ea4f 1315 mov.w r3, r5, lsr #4
if( count < 16) {
4ea: d80c bhi.n 506 <_ZN13CRGBPalette16aSEPKh+0x7e>
if( (istart8 <= lastSlotUsed) && (lastSlotUsed < 15)) {
4ec: fa4f fa86 sxtb.w sl, r6
4f0: 45d3 cmp fp, sl
4f2: dc07 bgt.n 504 <_ZN13CRGBPalette16aSEPKh+0x7c>
4f4: f1ba 0f0e cmp.w sl, #14
4f8: dc04 bgt.n 504 <_ZN13CRGBPalette16aSEPKh+0x7c>
istart8 = lastSlotUsed + 1;
4fa: 3601 adds r6, #1
4fc: b2f1 uxtb r1, r6
4fe: 4299 cmp r1, r3
500: bf28 it cs
502: 460b movcs r3, r1
if( iend8 < istart8) {
iend8 = istart8;
}
}
lastSlotUsed = iend8;
504: b2de uxtb r6, r3
/// allow copy construction
inline CRGB(const CRGB& rhs) __attribute__((always_inline))
{
r = rhs.r;
g = rhs.g;
506: f88d 2019 strb.w r2, [sp, #25]
}
fill_gradient_RGB( &(entries[0]), istart8, rgbstart, iend8, rgbend);
50a: aa07 add r2, sp, #28
}
/// allow copy construction
inline CRGB(const CRGB& rhs) __attribute__((always_inline))
{
r = rhs.r;
50c: f88d 0018 strb.w r0, [sp, #24]
510: 9200 str r2, [sp, #0]
512: 4638 mov r0, r7
514: aa06 add r2, sp, #24
g = rhs.g;
b = rhs.b;
516: f88d 801a strb.w r8, [sp, #26]
}
/// allow copy construction
inline CRGB(const CRGB& rhs) __attribute__((always_inline))
{
r = rhs.r;
51a: f88d 901c strb.w r9, [sp, #28]
g = rhs.g;
51e: f88d c01d strb.w ip, [sp, #29]
b = rhs.b;
522: f88d e01e strb.w lr, [sp, #30]
526: f000 f859 bl 5dc <_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) {
52a: 2dff cmp r5, #255 ; 0xff
52c: d005 beq.n 53a <_ZN13CRGBPalette16aSEPKh+0xb2>
}
/// allow assignment from one RGB struct to another
inline CRGB& operator= (const CRGB& rhs) __attribute__((always_inline))
{
r = rhs.r;
52e: 9803 ldr r0, [sp, #12]
g = rhs.g;
530: 9a05 ldr r2, [sp, #20]
b = rhs.b;
532: f8dd 8010 ldr.w r8, [sp, #16]
}
}
lastSlotUsed = iend8;
}
fill_gradient_RGB( &(entries[0]), istart8, rgbstart, iend8, rgbend);
indexstart = indexend;
536: 46ab mov fp, r5
538: e7bc b.n 4b4 <_ZN13CRGBPalette16aSEPKh+0x2c>
rgbstart = rgbend;
}
return *this;
}
53a: 4638 mov r0, r7
53c: b009 add sp, #36 ; 0x24
53e: e8bd 8ff0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, sl, fp, pc}
542: ffff b508 vabal.u<illegal width 64> <illegal reg q13.5>, d15, d8
00000544 <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() {
544: b508 push {r3, 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)) &&
546: 4b12 ldr r3, [pc, #72] ; (590 <setup+0x4c>)
548: 781b ldrb r3, [r3, #0]
54a: 2b00 cmp r3, #0
54c: d0fb beq.n 546 <setup+0x2>
54e: 4b11 ldr r3, [pc, #68] ; (594 <setup+0x50>)
550: 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 &&
552: 079b lsls r3, r3, #30
554: d0f7 beq.n 546 <setup+0x2>
(usb_cdc_line_rtsdtr & (USB_SERIAL_DTR | USB_SERIAL_RTS)) &&
((uint32_t)(systick_millis_count - usb_cdc_line_rtsdtr_millis) >= 25);
556: 4b10 ldr r3, [pc, #64] ; (598 <setup+0x54>)
558: 681a ldr r2, [r3, #0]
55a: 4b10 ldr r3, [pc, #64] ; (59c <setup+0x58>)
55c: 681b ldr r3, [r3, #0]
55e: 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)) &&
560: 2b18 cmp r3, #24
562: d9f0 bls.n 546 <setup+0x2>
while (!Serial) ; // wait for Arduino Serial Monitor
delay(10);
564: 200a movs r0, #10
566: f000 f92b bl 7c0 <delay>
Serial.println("setup begin");
56a: 490d ldr r1, [pc, #52] ; (5a0 <setup+0x5c>)
56c: 480d ldr r0, [pc, #52] ; (5a4 <setup+0x60>)
56e: f7ff ff79 bl 464 <_ZN5Print7printlnEPKc>
Serial.println("setup2"); // must print 2+ strings to reproduce problem
572: 490d ldr r1, [pc, #52] ; (5a8 <setup+0x64>)
574: 480b ldr r0, [pc, #44] ; (5a4 <setup+0x60>)
576: f7ff ff75 bl 464 <_ZN5Print7printlnEPKc>
size_t print(const char s[]) { return write(s); }
size_t print(const __FlashStringHelper *f) { return write((const char *)f); }
size_t print(uint8_t b) { return printNumber(b, 10, 0); }
size_t print(int n) { return print((long)n); }
size_t print(unsigned int n) { return printNumber(n, 10, 0); }
57a: 2300 movs r3, #0
57c: 4809 ldr r0, [pc, #36] ; (5a4 <setup+0x60>)
57e: 2130 movs r1, #48 ; 0x30
580: 220a movs r2, #10
582: f000 fefd bl 1380 <_ZN5Print11printNumberEmhh>
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(); }
586: 4807 ldr r0, [pc, #28] ; (5a4 <setup+0x60>)
Serial.println(sizeof(LedsMultitask));
}
588: e8bd 4008 ldmia.w sp!, {r3, lr}
58c: f000 bee8 b.w 1360 <_ZN5Print7printlnEv>
590: 1fffe747 .word 0x1fffe747
594: 1fffe758 .word 0x1fffe758
598: 1fffe664 .word 0x1fffe664
59c: 1fffe934 .word 0x1fffe934
5a0: 00002a70 .word 0x00002a70
5a4: 1fffe75c .word 0x1fffe75c
5a8: 00002a7c .word 0x00002a7c
000005ac <loop>:
void loop() {}
5ac: 4770 bx lr
5ae: ffff b508 vabal.u<illegal width 64> <illegal reg q13.5>, d15, d8
000005b0 <_GLOBAL__sub_I_heatmap_gp>:
5b0: 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;
5b2: 4902 ldr r1, [pc, #8] ; (5bc <_GLOBAL__sub_I_heatmap_gp+0xc>)
5b4: 4802 ldr r0, [pc, #8] ; (5c0 <_GLOBAL__sub_I_heatmap_gp+0x10>)
5b6: f7ff ff67 bl 488 <_ZN13CRGBPalette16aSEPKh>
5ba: bd08 pop {r3, pc}
5bc: 00002a83 .word 0x00002a83
5c0: 1fffe624 .word 0x1fffe624
000005c4 <_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;
5c4: 4b04 ldr r3, [pc, #16] ; (5d8 <_GLOBAL__sub_I_pSmartMatrix+0x14>)
5c6: 22ff movs r2, #255 ; 0xff
5c8: 701a strb r2, [r3, #0]
m_nFPS = 0;
5ca: 2200 movs r2, #0
5cc: 805a strh r2, [r3, #2]
m_pPowerFunc = NULL;
5ce: 60da str r2, [r3, #12]
m_nPowerData = 0xFFFFFFFF;
5d0: f04f 32ff mov.w r2, #4294967295 ; 0xffffffff
5d4: 609a str r2, [r3, #8]
5d6: 4770 bx lr
5d8: 1fffe654 .word 0x1fffe654
000005dc <_Z17fill_gradient_RGBP4CRGBtS_tS_>:
void fill_gradient_RGB( CRGB* leds,
uint16_t startpos, CRGB startcolor,
uint16_t endpos, CRGB endcolor )
{
5dc: e92d 47f0 stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, lr}
// if the points are in the wrong order, straighten them
if( endpos < startpos ) {
5e0: 428b cmp r3, r1
void fill_gradient_RGB( CRGB* leds,
uint16_t startpos, CRGB startcolor,
uint16_t endpos, CRGB endcolor )
{
5e2: 9c08 ldr r4, [sp, #32]
// if the points are in the wrong order, straighten them
if( endpos < startpos ) {
5e4: d214 bcs.n 610 <_Z17fill_gradient_RGBP4CRGBtS_tS_+0x34>
}
/// allow assignment from one RGB struct to another
inline CRGB& operator= (const CRGB& rhs) __attribute__((always_inline))
{
r = rhs.r;
5e6: f892 c000 ldrb.w ip, [r2]
/// allow copy construction
inline CRGB(const CRGB& rhs) __attribute__((always_inline))
{
r = rhs.r;
g = rhs.g;
b = rhs.b;
5ea: 78a5 ldrb r5, [r4, #2]
}
/// allow copy construction
inline CRGB(const CRGB& rhs) __attribute__((always_inline))
{
r = rhs.r;
5ec: 7827 ldrb r7, [r4, #0]
}
/// allow assignment from one RGB struct to another
inline CRGB& operator= (const CRGB& rhs) __attribute__((always_inline))
{
r = rhs.r;
5ee: f884 c000 strb.w ip, [r4]
g = rhs.g;
5f2: f892 c001 ldrb.w ip, [r2, #1]
/// allow copy construction
inline CRGB(const CRGB& rhs) __attribute__((always_inline))
{
r = rhs.r;
g = rhs.g;
5f6: 7866 ldrb r6, [r4, #1]
/// allow assignment from one RGB struct to another
inline CRGB& operator= (const CRGB& rhs) __attribute__((always_inline))
{
r = rhs.r;
g = rhs.g;
5f8: f884 c001 strb.w ip, [r4, #1]
b = rhs.b;
5fc: f892 c002 ldrb.w ip, [r2, #2]
600: 7095 strb r5, [r2, #2]
602: 460d mov r5, r1
604: f884 c002 strb.w ip, [r4, #2]
608: 4619 mov r1, r3
}
/// allow assignment from one RGB struct to another
inline CRGB& operator= (const CRGB& rhs) __attribute__((always_inline))
{
r = rhs.r;
60a: 7017 strb r7, [r2, #0]
g = rhs.g;
60c: 7056 strb r6, [r2, #1]
60e: 462b mov r3, r5
saccum87 rdistance87;
saccum87 gdistance87;
saccum87 bdistance87;
rdistance87 = (endcolor.r - startcolor.r) << 7;
610: f892 c000 ldrb.w ip, [r2]
gdistance87 = (endcolor.g - startcolor.g) << 7;
614: 7857 ldrb r7, [r2, #1]
bdistance87 = (endcolor.b - startcolor.b) << 7;
616: 7895 ldrb r5, [r2, #2]
saccum87 rdistance87;
saccum87 gdistance87;
saccum87 bdistance87;
rdistance87 = (endcolor.r - startcolor.r) << 7;
618: f894 8000 ldrb.w r8, [r4]
gdistance87 = (endcolor.g - startcolor.g) << 7;
61c: f894 9001 ldrb.w r9, [r4, #1]
bdistance87 = (endcolor.b - startcolor.b) << 7;
620: 78a2 ldrb r2, [r4, #2]
uint16_t pixeldistance = endpos - startpos;
622: 1a5e subs r6, r3, r1
saccum87 rdistance87;
saccum87 gdistance87;
saccum87 bdistance87;
rdistance87 = (endcolor.r - startcolor.r) << 7;
624: ebcc 0808 rsb r8, ip, r8
gdistance87 = (endcolor.g - startcolor.g) << 7;
628: ebc7 0909 rsb r9, r7, r9
bdistance87 = (endcolor.b - startcolor.b) << 7;
62c: 1b52 subs r2, r2, r5
uint16_t pixeldistance = endpos - startpos;
62e: b2b6 uxth r6, r6
saccum87 rdistance87;
saccum87 gdistance87;
saccum87 bdistance87;
rdistance87 = (endcolor.r - startcolor.r) << 7;
630: ea4f 18c8 mov.w r8, r8, lsl #7
gdistance87 = (endcolor.g - startcolor.g) << 7;
634: ea4f 19c9 mov.w r9, r9, lsl #7
bdistance87 = (endcolor.b - startcolor.b) << 7;
638: 01d2 lsls r2, r2, #7
uint16_t pixeldistance = endpos - startpos;
int16_t divisor = pixeldistance ? pixeldistance : 1;
63a: b10e cbz r6, 640 <_Z17fill_gradient_RGBP4CRGBtS_tS_+0x64>
63c: b2b6 uxth r6, r6
63e: e000 b.n 642 <_Z17fill_gradient_RGBP4CRGBtS_tS_+0x66>
640: 2601 movs r6, #1
saccum87 rdelta87 = rdistance87 / divisor;
642: b236 sxth r6, r6
644: fb98 f8f6 sdiv r8, r8, r6
saccum87 gdelta87 = gdistance87 / divisor;
648: fb99 f9f6 sdiv r9, r9, r6
saccum87 bdelta87 = bdistance87 / divisor;
64c: fb92 f6f6 sdiv r6, r2, r6
rdelta87 *= 2;
650: ea4f 0848 mov.w r8, r8, lsl #1
gdelta87 *= 2;
654: ea4f 0949 mov.w r9, r9, lsl #1
bdelta87 *= 2;
658: 0076 lsls r6, r6, #1
saccum87 rdelta87 = rdistance87 / divisor;
saccum87 gdelta87 = gdistance87 / divisor;
saccum87 bdelta87 = bdistance87 / divisor;
rdelta87 *= 2;
65a: fa1f f888 uxth.w r8, r8
gdelta87 *= 2;
65e: fa1f f989 uxth.w r9, r9
bdelta87 *= 2;
662: b2b6 uxth r6, r6
accum88 r88 = startcolor.r << 8;
664: ea4f 220c mov.w r2, ip, lsl #8
accum88 g88 = startcolor.g << 8;
668: 023c lsls r4, r7, #8
accum88 b88 = startcolor.b << 8;
66a: 022d lsls r5, r5, #8
for( uint16_t i = startpos; i <= endpos; i++) {
66c: 4299 cmp r1, r3
66e: d818 bhi.n 6a2 <_Z17fill_gradient_RGBP4CRGBtS_tS_+0xc6>
leds[i] = CRGB( r88 >> 8, g88 >> 8, b88 >> 8);
670: eb01 0c41 add.w ip, r1, r1, lsl #1
674: eb00 070c add.w r7, r0, ip
678: ea4f 2a22 mov.w sl, r2, asr #8
67c: f800 a00c strb.w sl, [r0, ip]
680: ea4f 2c24 mov.w ip, r4, asr #8
684: f887 c001 strb.w ip, [r7, #1]
r88 += rdelta87;
688: 4442 add r2, r8
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);
68a: ea4f 2c25 mov.w ip, r5, asr #8
r88 += rdelta87;
g88 += gdelta87;
68e: 444c add r4, r9
b88 += bdelta87;
690: 4435 add r5, r6
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++) {
692: 3101 adds r1, #1
leds[i] = CRGB( r88 >> 8, g88 >> 8, b88 >> 8);
694: f887 c002 strb.w ip, [r7, #2]
r88 += rdelta87;
698: b292 uxth r2, r2
g88 += gdelta87;
69a: b2a4 uxth r4, r4
b88 += bdelta87;
69c: b2ad uxth r5, r5
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: b289 uxth r1, r1
6a0: e7e4 b.n 66c <_Z17fill_gradient_RGBP4CRGBtS_tS_+0x90>
leds[i] = CRGB( r88 >> 8, g88 >> 8, b88 >> 8);
r88 += rdelta87;
g88 += gdelta87;
b88 += bdelta87;
}
}
6a2: e8bd 87f0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, sl, pc}
6a6: ffff 4b04 vtbl.8 d20, {d15-d18}, d4
000006a8 <rtc_set>:
return RTC_TSR;
}
void rtc_set(unsigned long t)
{
RTC_SR = 0;
6a8: 4b04 ldr r3, [pc, #16] ; (6bc <rtc_set+0x14>)
RTC_TPR = 0;
6aa: 4905 ldr r1, [pc, #20] ; (6c0 <rtc_set+0x18>)
return RTC_TSR;
}
void rtc_set(unsigned long t)
{
RTC_SR = 0;
6ac: 2200 movs r2, #0
6ae: 601a str r2, [r3, #0]
RTC_TPR = 0;
6b0: 600a str r2, [r1, #0]
RTC_TSR = t;
6b2: 4a04 ldr r2, [pc, #16] ; (6c4 <rtc_set+0x1c>)
6b4: 6010 str r0, [r2, #0]
RTC_SR = RTC_SR_TCE;
6b6: 2210 movs r2, #16
6b8: 601a str r2, [r3, #0]
6ba: 4770 bx lr
6bc: 4003d014 .word 0x4003d014
6c0: 4003d004 .word 0x4003d004
6c4: 4003d000 .word 0x4003d000
000006c8 <digitalWrite>:
// TODO: startup code needs to initialize all pins to GPIO mode, input by default
void digitalWrite(uint8_t pin, uint8_t val)
{
if (pin >= CORE_NUM_DIGITAL) return;
6c8: 2821 cmp r0, #33 ; 0x21
// TODO: startup code needs to initialize all pins to GPIO mode, input by default
void digitalWrite(uint8_t pin, uint8_t val)
{
6ca: b510 push {r4, lr}
if (pin >= CORE_NUM_DIGITAL) return;
6cc: d818 bhi.n 700 <digitalWrite+0x38>
#ifdef KINETISK
if (*portModeRegister(pin)) {
6ce: 4a0d ldr r2, [pc, #52] ; (704 <digitalWrite+0x3c>)
6d0: f852 3030 ldr.w r3, [r2, r0, lsl #3]
6d4: f893 4280 ldrb.w r4, [r3, #640] ; 0x280
6d8: b13c cbz r4, 6ea <digitalWrite+0x22>
6da: 2201 movs r2, #1
if (val) {
6dc: b111 cbz r1, 6e4 <digitalWrite+0x1c>
*portSetRegister(pin) = 1;
6de: f883 2080 strb.w r2, [r3, #128] ; 0x80
6e2: bd10 pop {r4, pc}
} else {
*portClearRegister(pin) = 1;
6e4: f883 2100 strb.w r2, [r3, #256] ; 0x100
6e8: bd10 pop {r4, pc}
} else {
*portClearRegister(pin) = digitalPinToBitMask(pin);
}
#endif
} else {
volatile uint32_t *config = portConfigRegister(pin);
6ea: eb02 00c0 add.w r0, r2, r0, lsl #3
6ee: 6843 ldr r3, [r0, #4]
if (val) {
// TODO use bitband for atomic read-mod-write
*config |= (PORT_PCR_PE | PORT_PCR_PS);
6f0: 681a ldr r2, [r3, #0]
*portClearRegister(pin) = digitalPinToBitMask(pin);
}
#endif
} else {
volatile uint32_t *config = portConfigRegister(pin);
if (val) {
6f2: b111 cbz r1, 6fa <digitalWrite+0x32>
// TODO use bitband for atomic read-mod-write
*config |= (PORT_PCR_PE | PORT_PCR_PS);
6f4: f042 0203 orr.w r2, r2, #3
6f8: e001 b.n 6fe <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);
6fa: f022 0202 bic.w r2, r2, #2
6fe: 601a str r2, [r3, #0]
700: bd10 pop {r4, pc}
702: bf00 nop
704: 00002a94 .word 0x00002a94
00000708 <pinMode>:
void pinMode(uint8_t pin, uint8_t mode)
{
volatile uint32_t *config;
if (pin >= CORE_NUM_DIGITAL) return;
708: 2821 cmp r0, #33 ; 0x21
}
void pinMode(uint8_t pin, uint8_t mode)
{
70a: b510 push {r4, lr}
volatile uint32_t *config;
if (pin >= CORE_NUM_DIGITAL) return;
70c: d837 bhi.n 77e <pinMode+0x76>
config = portConfigRegister(pin);
70e: 4a1c ldr r2, [pc, #112] ; (780 <pinMode+0x78>)
710: eb02 03c0 add.w r3, r2, r0, lsl #3
if (mode == OUTPUT || mode == OUTPUT_OPENDRAIN) {
714: 2901 cmp r1, #1
void pinMode(uint8_t pin, uint8_t mode)
{
volatile uint32_t *config;
if (pin >= CORE_NUM_DIGITAL) return;
config = portConfigRegister(pin);
716: 685b ldr r3, [r3, #4]
718: 4614 mov r4, r2
if (mode == OUTPUT || mode == OUTPUT_OPENDRAIN) {
71a: d001 beq.n 720 <pinMode+0x18>
71c: 2904 cmp r1, #4
71e: d10f bne.n 740 <pinMode+0x38>
#ifdef KINETISK
*portModeRegister(pin) = 1;
720: f854 2030 ldr.w r2, [r4, r0, lsl #3]
724: 2001 movs r0, #1
726: f882 0280 strb.w r0, [r2, #640] ; 0x280
#else
*portModeRegister(pin) |= digitalPinToBitMask(pin); // TODO: atomic
#endif
*config = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1);
72a: f44f 72a2 mov.w r2, #324 ; 0x144
72e: 601a str r2, [r3, #0]
if (mode == OUTPUT_OPENDRAIN) {
*config |= PORT_PCR_ODE;
730: 681a ldr r2, [r3, #0]
*portModeRegister(pin) = 1;
#else
*portModeRegister(pin) |= digitalPinToBitMask(pin); // TODO: atomic
#endif
*config = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1);
if (mode == OUTPUT_OPENDRAIN) {
732: 2904 cmp r1, #4
*config |= PORT_PCR_ODE;
734: bf0c ite eq
736: f042 0220 orreq.w r2, r2, #32
} else {
*config &= ~PORT_PCR_ODE;
73a: f022 0220 bicne.w r2, r2, #32
73e: e01d b.n 77c <pinMode+0x74>
}
} else {
#ifdef KINETISK
*portModeRegister(pin) = 0;
740: f852 2030 ldr.w r2, [r2, r0, lsl #3]
744: 2000 movs r0, #0
746: f882 0280 strb.w r0, [r2, #640] ; 0x280
#else
*portModeRegister(pin) &= ~digitalPinToBitMask(pin);
#endif
if (mode == INPUT || mode == INPUT_PULLUP || mode == INPUT_PULLDOWN) {
74a: b111 cbz r1, 752 <pinMode+0x4a>
74c: 1e8a subs r2, r1, #2
74e: 2a01 cmp r2, #1
750: d812 bhi.n 778 <pinMode+0x70>
*config = PORT_PCR_MUX(1);
752: f44f 7280 mov.w r2, #256 ; 0x100
if (mode == INPUT_PULLUP) {
756: 2902 cmp r1, #2
*portModeRegister(pin) = 0;
#else
*portModeRegister(pin) &= ~digitalPinToBitMask(pin);
#endif
if (mode == INPUT || mode == INPUT_PULLUP || mode == INPUT_PULLDOWN) {
*config = PORT_PCR_MUX(1);
758: 601a str r2, [r3, #0]
if (mode == INPUT_PULLUP) {
75a: d103 bne.n 764 <pinMode+0x5c>
*config |= (PORT_PCR_PE | PORT_PCR_PS); // pullup
75c: 681a ldr r2, [r3, #0]
75e: f042 0203 orr.w r2, r2, #3
762: e00b b.n 77c <pinMode+0x74>
} else if (mode == INPUT_PULLDOWN) {
764: 2903 cmp r1, #3
766: d10a bne.n 77e <pinMode+0x76>
*config |= (PORT_PCR_PE); // pulldown
768: 681a ldr r2, [r3, #0]
76a: f042 0202 orr.w r2, r2, #2
76e: 601a str r2, [r3, #0]
*config &= ~(PORT_PCR_PS);
770: 681a ldr r2, [r3, #0]
772: f022 0201 bic.w r2, r2, #1
776: e001 b.n 77c <pinMode+0x74>
}
} else {
*config = PORT_PCR_MUX(1) | PORT_PCR_PE | PORT_PCR_PS; // pullup
778: f240 1203 movw r2, #259 ; 0x103
77c: 601a str r2, [r3, #0]
77e: bd10 pop {r4, pc}
780: 00002a94 .word 0x00002a94
00000784 <micros>:
uint32_t micros(void)
{
uint32_t count, current, istatus;
__disable_irq();
784: b672 cpsid i
current = SYST_CVR;
786: 4b0b ldr r3, [pc, #44] ; (7b4 <micros+0x30>)
count = systick_millis_count;
istatus = SCB_ICSR; // bit 26 indicates if systick exception pending
788: 490b ldr r1, [pc, #44] ; (7b8 <micros+0x34>)
uint32_t micros(void)
{
uint32_t count, current, istatus;
__disable_irq();
current = SYST_CVR;
78a: 681a ldr r2, [r3, #0]
count = systick_millis_count;
78c: 4b0b ldr r3, [pc, #44] ; (7bc <micros+0x38>)
78e: 681b ldr r3, [r3, #0]
istatus = SCB_ICSR; // bit 26 indicates if systick exception pending
790: 6809 ldr r1, [r1, #0]
__enable_irq();
792: 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++;
794: 0149 lsls r1, r1, #5
796: d502 bpl.n 79e <micros+0x1a>
798: 2a32 cmp r2, #50 ; 0x32
79a: bf88 it hi
79c: 3301 addhi r3, #1
current = ((F_CPU / 1000) - 1) - current;
79e: f5c2 32bb rsb r2, r2, #95744 ; 0x17600
#if defined(KINETISL) && F_CPU == 48000000
return count * 1000 + ((current * (uint32_t)87381) >> 22);
#elif defined(KINETISL) && F_CPU == 24000000
return count * 1000 + ((current * (uint32_t)174763) >> 22);
#endif
return count * 1000 + current / (F_CPU / 1000000);
7a2: 2160 movs r1, #96 ; 0x60
__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;
7a4: 32ff adds r2, #255 ; 0xff
#if defined(KINETISL) && F_CPU == 48000000
return count * 1000 + ((current * (uint32_t)87381) >> 22);
#elif defined(KINETISL) && F_CPU == 24000000
return count * 1000 + ((current * (uint32_t)174763) >> 22);
#endif
return count * 1000 + current / (F_CPU / 1000000);
7a6: fbb2 f2f1 udiv r2, r2, r1
}
7aa: f44f 707a mov.w r0, #1000 ; 0x3e8
7ae: fb00 2003 mla r0, r0, r3, r2
7b2: 4770 bx lr
7b4: e000e018 .word 0xe000e018
7b8: e000ed04 .word 0xe000ed04
7bc: 1fffe664 .word 0x1fffe664
000007c0 <delay>:
void delay(uint32_t ms)
{
7c0: b538 push {r3, r4, r5, lr}
7c2: 4604 mov r4, r0
uint32_t start = micros();
7c4: f7ff ffde bl 784 <micros>
7c8: 4605 mov r5, r0
if (ms > 0) {
7ca: b924 cbnz r4, 7d6 <delay+0x16>
7cc: bd38 pop {r3, r4, r5, pc}
while (1) {
while ((micros() - start) >= 1000) {
ms--;
if (ms == 0) return;
7ce: 3c01 subs r4, #1
7d0: d00a beq.n 7e8 <delay+0x28>
start += 1000;
7d2: f505 757a add.w r5, r5, #1000 ; 0x3e8
{
uint32_t start = micros();
if (ms > 0) {
while (1) {
while ((micros() - start) >= 1000) {
7d6: f7ff ffd5 bl 784 <micros>
7da: 1b40 subs r0, r0, r5
7dc: f5b0 7f7a cmp.w r0, #1000 ; 0x3e8
7e0: d2f5 bcs.n 7ce <delay+0xe>
ms--;
if (ms == 0) return;
start += 1000;
}
yield();
7e2: f000 fe2d bl 1440 <yield>
}
7e6: e7f6 b.n 7d6 <delay+0x16>
7e8: bd38 pop {r3, r4, r5, pc}
7ea: ffff 4b1b ; <UNDEFINED> instruction: 0xffff4b1b
000007ec <_init_Teensyduino_internal_>:
//void init_pins(void)
void _init_Teensyduino_internal_(void)
{
#if defined(__MK20DX128__) || defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__)
NVIC_ENABLE_IRQ(IRQ_PORTA);
7ec: 4b1b ldr r3, [pc, #108] ; (85c <_init_Teensyduino_internal_+0x70>)
7ee: f44f 7280 mov.w r2, #256 ; 0x100
#define DEFAULT_FTM_PRESCALE 0
#endif
//void init_pins(void)
void _init_Teensyduino_internal_(void)
{
7f2: b510 push {r4, lr}
#if defined(__MK20DX128__) || defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__)
NVIC_ENABLE_IRQ(IRQ_PORTA);
7f4: 601a str r2, [r3, #0]
NVIC_ENABLE_IRQ(IRQ_PORTB);
7f6: f44f 7200 mov.w r2, #512 ; 0x200
7fa: 601a str r2, [r3, #0]
NVIC_ENABLE_IRQ(IRQ_PORTC);
7fc: f44f 6280 mov.w r2, #1024 ; 0x400
800: 601a str r2, [r3, #0]
NVIC_ENABLE_IRQ(IRQ_PORTD);
802: f44f 6200 mov.w r2, #2048 ; 0x800
806: 601a str r2, [r3, #0]
NVIC_ENABLE_IRQ(IRQ_PORTE);
808: f44f 5280 mov.w r2, #4096 ; 0x1000
80c: 601a str r2, [r3, #0]
NVIC_ENABLE_IRQ(IRQ_PORTA);
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;
80e: 4b14 ldr r3, [pc, #80] ; (860 <_init_Teensyduino_internal_+0x74>)
FTM0_MOD = DEFAULT_FTM_MOD;
FTM0_C0SC = 0x28; // MSnB:MSnA = 10, ELSnB:ELSnA = 10
810: 4a14 ldr r2, [pc, #80] ; (864 <_init_Teensyduino_internal_+0x78>)
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);
812: 4c15 ldr r4, [pc, #84] ; (868 <_init_Teensyduino_internal_+0x7c>)
NVIC_ENABLE_IRQ(IRQ_PORTA);
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;
814: 2000 movs r0, #0
FTM0_MOD = DEFAULT_FTM_MOD;
816: f64b 71ff movw r1, #49151 ; 0xbfff
NVIC_ENABLE_IRQ(IRQ_PORTA);
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;
81a: 6018 str r0, [r3, #0]
FTM0_MOD = DEFAULT_FTM_MOD;
81c: 6059 str r1, [r3, #4]
FTM0_C0SC = 0x28; // MSnB:MSnA = 10, ELSnB:ELSnA = 10
81e: 2328 movs r3, #40 ; 0x28
820: 6013 str r3, [r2, #0]
FTM0_C1SC = 0x28;
822: 6093 str r3, [r2, #8]
FTM0_C2SC = 0x28;
824: 6113 str r3, [r2, #16]
FTM0_C3SC = 0x28;
826: 6193 str r3, [r2, #24]
FTM0_C4SC = 0x28;
828: 6213 str r3, [r2, #32]
FTM0_C5SC = 0x28;
82a: 6293 str r3, [r2, #40] ; 0x28
#if defined(__MK20DX128__) || defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__)
FTM0_C6SC = 0x28;
82c: 6313 str r3, [r2, #48] ; 0x30
FTM0_C7SC = 0x28;
82e: 6393 str r3, [r2, #56] ; 0x38
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);
830: 2209 movs r2, #9
832: 6022 str r2, [r4, #0]
FTM1_CNT = 0;
834: f504 5480 add.w r4, r4, #4096 ; 0x1000
838: 3404 adds r4, #4
83a: 6020 str r0, [r4, #0]
FTM1_MOD = DEFAULT_FTM_MOD;
83c: 480b ldr r0, [pc, #44] ; (86c <_init_Teensyduino_internal_+0x80>)
83e: 6001 str r1, [r0, #0]
FTM1_C0SC = 0x28;
840: 490b ldr r1, [pc, #44] ; (870 <_init_Teensyduino_internal_+0x84>)
842: 600b str r3, [r1, #0]
FTM1_C1SC = 0x28;
844: 608b str r3, [r1, #8]
FTM1_SC = FTM_SC_CLKS(1) | FTM_SC_PS(DEFAULT_FTM_PRESCALE);
846: 4b0b ldr r3, [pc, #44] ; (874 <_init_Teensyduino_internal_+0x88>)
848: 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();
84a: f000 fe19 bl 1480 <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);
84e: 20fa movs r0, #250 ; 0xfa
850: f7ff ffb6 bl 7c0 <delay>
usb_init();
}
854: e8bd 4010 ldmia.w sp!, {r4, lr}
#endif
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);
usb_init();
858: f000 bbd6 b.w 1008 <usb_init>
85c: e000e104 .word 0xe000e104
860: 40038004 .word 0x40038004
864: 4003800c .word 0x4003800c
868: 40038000 .word 0x40038000
86c: 40039008 .word 0x40039008
870: 4003900c .word 0x4003900c
874: 40039000 .word 0x40039000
00000878 <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)
{
878: 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;
87a: 4b0c ldr r3, [pc, #48] ; (8ac <endpoint0_transmit+0x34>)
87c: 4c0c ldr r4, [pc, #48] ; (8b0 <endpoint0_transmit+0x38>)
87e: 781a ldrb r2, [r3, #0]
880: f042 0502 orr.w r5, r2, #2
884: eb04 06c5 add.w r6, r4, r5, lsl #3
table[index(0, TX, ep0_tx_bdt_bank)].desc = BDT_DESC(len, ep0_tx_data_toggle);
ep0_tx_data_toggle ^= 1;
ep0_tx_bdt_bank ^= 1;
888: f082 0201 eor.w r2, r2, #1
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;
88c: 6070 str r0, [r6, #4]
table[index(0, TX, ep0_tx_bdt_bank)].desc = BDT_DESC(len, ep0_tx_data_toggle);
88e: 4809 ldr r0, [pc, #36] ; (8b4 <endpoint0_transmit+0x3c>)
ep0_tx_data_toggle ^= 1;
ep0_tx_bdt_bank ^= 1;
890: 701a strb r2, [r3, #0]
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;
table[index(0, TX, ep0_tx_bdt_bank)].desc = BDT_DESC(len, ep0_tx_data_toggle);
892: 7806 ldrb r6, [r0, #0]
894: 2e00 cmp r6, #0
896: bf0c ite eq
898: 2788 moveq r7, #136 ; 0x88
89a: 27c8 movne r7, #200 ; 0xc8
ep0_tx_data_toggle ^= 1;
89c: f086 0601 eor.w r6, r6, #1
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;
table[index(0, TX, ep0_tx_bdt_bank)].desc = BDT_DESC(len, ep0_tx_data_toggle);
8a0: ea47 4101 orr.w r1, r7, r1, lsl #16
ep0_tx_data_toggle ^= 1;
8a4: 7006 strb r6, [r0, #0]
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;
table[index(0, TX, ep0_tx_bdt_bank)].desc = BDT_DESC(len, ep0_tx_data_toggle);
8a6: f844 1035 str.w r1, [r4, r5, lsl #3]
ep0_tx_data_toggle ^= 1;
ep0_tx_bdt_bank ^= 1;
8aa: bdf0 pop {r4, r5, r6, r7, pc}
8ac: 1fffe6d0 .word 0x1fffe6d0
8b0: 1fffe000 .word 0x1fffe000
8b4: 1fffe748 .word 0x1fffe748
000008b8 <usb_rx>:
usb_packet_t *usb_rx(uint32_t endpoint)
{
usb_packet_t *ret;
endpoint--;
8b8: 1e43 subs r3, r0, #1
if (endpoint >= NUM_ENDPOINTS) return NULL;
8ba: 2b03 cmp r3, #3
usb_packet_t *usb_rx(uint32_t endpoint)
{
8bc: b510 push {r4, lr}
usb_packet_t *ret;
endpoint--;
if (endpoint >= NUM_ENDPOINTS) return NULL;
8be: d810 bhi.n 8e2 <usb_rx+0x2a>
__disable_irq();
8c0: b672 cpsid i
ret = rx_first[endpoint];
8c2: 4a09 ldr r2, [pc, #36] ; (8e8 <usb_rx+0x30>)
8c4: f852 0023 ldr.w r0, [r2, r3, lsl #2]
if (ret) {
8c8: b148 cbz r0, 8de <usb_rx+0x26>
rx_first[endpoint] = ret->next;
8ca: 6841 ldr r1, [r0, #4]
8cc: f842 1023 str.w r1, [r2, r3, lsl #2]
usb_rx_byte_count_data[endpoint] -= ret->len;
8d0: 4a06 ldr r2, [pc, #24] ; (8ec <usb_rx+0x34>)
8d2: 8801 ldrh r1, [r0, #0]
8d4: f832 4013 ldrh.w r4, [r2, r3, lsl #1]
8d8: 1a61 subs r1, r4, r1
8da: f822 1013 strh.w r1, [r2, r3, lsl #1]
}
__enable_irq();
8de: b662 cpsie i
//serial_print("rx, epidx=");
//serial_phex(endpoint);
//serial_print(", packet=");
//serial_phex32(ret);
//serial_print("\n");
return ret;
8e0: bd10 pop {r4, pc}
usb_packet_t *usb_rx(uint32_t endpoint)
{
usb_packet_t *ret;
endpoint--;
if (endpoint >= NUM_ENDPOINTS) return NULL;
8e2: 2000 movs r0, #0
//serial_phex(endpoint);
//serial_print(", packet=");
//serial_phex32(ret);
//serial_print("\n");
return ret;
}
8e4: bd10 pop {r4, pc}
8e6: bf00 nop
8e8: 1fffe6c0 .word 0x1fffe6c0
8ec: 1fffe924 .word 0x1fffe924
000008f0 <usb_tx_packet_count>:
uint32_t usb_tx_packet_count(uint32_t endpoint)
{
const usb_packet_t *p;
uint32_t count=0;
endpoint--;
8f0: 3801 subs r0, #1
if (endpoint >= NUM_ENDPOINTS) return 0;
8f2: 2803 cmp r0, #3
8f4: d80a bhi.n 90c <usb_tx_packet_count+0x1c>
__disable_irq();
8f6: b672 cpsid i
for (p = tx_first[endpoint]; p; p = p->next) count++;
8f8: 4b05 ldr r3, [pc, #20] ; (910 <usb_tx_packet_count+0x20>)
8fa: f853 3020 ldr.w r3, [r3, r0, lsl #2]
}
uint32_t usb_tx_packet_count(uint32_t endpoint)
{
const usb_packet_t *p;
uint32_t count=0;
8fe: 2000 movs r0, #0
endpoint--;
if (endpoint >= NUM_ENDPOINTS) return 0;
__disable_irq();
for (p = tx_first[endpoint]; p; p = p->next) count++;
900: b113 cbz r3, 908 <usb_tx_packet_count+0x18>
902: 3001 adds r0, #1
904: 685b ldr r3, [r3, #4]
906: e7fb b.n 900 <usb_tx_packet_count+0x10>
__enable_irq();
908: b662 cpsie i
return count;
90a: 4770 bx lr
{
const usb_packet_t *p;
uint32_t count=0;
endpoint--;
if (endpoint >= NUM_ENDPOINTS) return 0;
90c: 2000 movs r0, #0
__disable_irq();
for (p = tx_first[endpoint]; p; p = p->next) count++;
__enable_irq();
return count;
}
90e: 4770 bx lr
910: 1fffe714 .word 0x1fffe714
00000914 <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)
{
914: b510 push {r4, lr}
unsigned int i;
const uint8_t *cfg;
cfg = usb_endpoint_config_table;
//serial_print("rx_mem:");
__disable_irq();
916: b672 cpsid i
for (i=1; i <= NUM_ENDPOINTS; i++) {
918: 2301 movs r3, #1
91a: 4a17 ldr r2, [pc, #92] ; (978 <usb_rx_memory+0x64>)
91c: 441a add r2, r3
#ifdef AUDIO_INTERFACE
if (i == AUDIO_RX_ENDPOINT) continue;
#endif
if (*cfg++ & USB_ENDPT_EPRXEN) {
91e: f812 2c01 ldrb.w r2, [r2, #-1]
922: 0712 lsls r2, r2, #28
924: d51c bpl.n 960 <usb_rx_memory+0x4c>
if (table[index(i, RX, EVEN)].desc == 0) {
926: 0099 lsls r1, r3, #2
928: 4a14 ldr r2, [pc, #80] ; (97c <usb_rx_memory+0x68>)
92a: f852 4031 ldr.w r4, [r2, r1, lsl #3]
92e: b92c cbnz r4, 93c <usb_rx_memory+0x28>
table[index(i, RX, EVEN)].addr = packet->buf;
930: eb02 1343 add.w r3, r2, r3, lsl #5
934: 3008 adds r0, #8
936: 6058 str r0, [r3, #4]
table[index(i, RX, EVEN)].desc = BDT_DESC(64, 0);
938: 4b11 ldr r3, [pc, #68] ; (980 <usb_rx_memory+0x6c>)
93a: e009 b.n 950 <usb_rx_memory+0x3c>
__enable_irq();
//serial_phex(i);
//serial_print(",even\n");
return;
}
if (table[index(i, RX, ODD)].desc == 0) {
93c: f041 0101 orr.w r1, r1, #1
940: f852 4031 ldr.w r4, [r2, r1, lsl #3]
944: b964 cbnz r4, 960 <usb_rx_memory+0x4c>
table[index(i, RX, ODD)].addr = packet->buf;
946: eb02 03c1 add.w r3, r2, r1, lsl #3
94a: 3008 adds r0, #8
94c: 6058 str r0, [r3, #4]
table[index(i, RX, ODD)].desc = BDT_DESC(64, 1);
94e: 4b0d ldr r3, [pc, #52] ; (984 <usb_rx_memory+0x70>)
950: f842 3031 str.w r3, [r2, r1, lsl #3]
usb_rx_memory_needed--;
954: 4b0c ldr r3, [pc, #48] ; (988 <usb_rx_memory+0x74>)
956: 781a ldrb r2, [r3, #0]
958: 3a01 subs r2, #1
95a: 701a strb r2, [r3, #0]
__enable_irq();
95c: b662 cpsie i
//serial_phex(i);
//serial_print(",odd\n");
return;
95e: bd10 pop {r4, pc}
const uint8_t *cfg;
cfg = usb_endpoint_config_table;
//serial_print("rx_mem:");
__disable_irq();
for (i=1; i <= NUM_ENDPOINTS; i++) {
960: 3301 adds r3, #1
962: 2b05 cmp r3, #5
964: d1d9 bne.n 91a <usb_rx_memory+0x6>
//serial_print(",odd\n");
return;
}
}
}
__enable_irq();
966: 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;
968: 4b07 ldr r3, [pc, #28] ; (988 <usb_rx_memory+0x74>)
96a: 2200 movs r2, #0
96c: 701a strb r2, [r3, #0]
usb_free(packet);
return;
}
96e: e8bd 4010 ldmia.w sp!, {r4, lr}
__enable_irq();
// 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;
usb_free(packet);
972: f000 bba5 b.w 10c0 <usb_free>
976: bf00 nop
978: 00002bd0 .word 0x00002bd0
97c: 1fffe000 .word 0x1fffe000
980: 00400088 .word 0x00400088
984: 004000c8 .word 0x004000c8
988: 1fffe73e .word 0x1fffe73e
0000098c <usb_tx>:
void usb_tx(uint32_t endpoint, usb_packet_t *packet)
{
bdt_t *b = &table[index(endpoint, TX, EVEN)];
uint8_t next;
endpoint--;
98c: 1e43 subs r3, r0, #1
if (endpoint >= NUM_ENDPOINTS) return;
98e: 2b03 cmp r3, #3
//#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)
{
990: b530 push {r4, r5, lr}
bdt_t *b = &table[index(endpoint, TX, EVEN)];
uint8_t next;
endpoint--;
if (endpoint >= NUM_ENDPOINTS) return;
992: d832 bhi.n 9fa <usb_tx+0x6e>
//#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)];
994: 4a19 ldr r2, [pc, #100] ; (9fc <usb_tx+0x70>)
996: 0140 lsls r0, r0, #5
998: f040 0010 orr.w r0, r0, #16
99c: 4410 add r0, r2
uint8_t next;
endpoint--;
if (endpoint >= NUM_ENDPOINTS) return;
__disable_irq();
99e: b672 cpsid i
//serial_print("txstate=");
//serial_phex(tx_state[endpoint]);
//serial_print("\n");
switch (tx_state[endpoint]) {
9a0: 4c17 ldr r4, [pc, #92] ; (a00 <usb_tx+0x74>)
9a2: 5ce2 ldrb r2, [r4, r3]
9a4: 2a03 cmp r2, #3
9a6: d809 bhi.n 9bc <usb_tx+0x30>
9a8: e8df f002 tbb [pc, r2]
9ac: 05180216 .word 0x05180216
case TX_STATE_BOTH_FREE_EVEN_FIRST:
next = TX_STATE_ODD_FREE;
break;
case TX_STATE_BOTH_FREE_ODD_FIRST:
b++;
9b0: 3008 adds r0, #8
next = TX_STATE_EVEN_FREE;
9b2: 2202 movs r2, #2
break;
9b4: e013 b.n 9de <usb_tx+0x52>
case TX_STATE_EVEN_FREE:
next = TX_STATE_NONE_FREE_ODD_FIRST;
break;
case TX_STATE_ODD_FREE:
b++;
9b6: 3008 adds r0, #8
next = TX_STATE_NONE_FREE_EVEN_FIRST;
9b8: 2204 movs r2, #4
break;
9ba: e010 b.n 9de <usb_tx+0x52>
default:
if (tx_first[endpoint] == NULL) {
9bc: 4811 ldr r0, [pc, #68] ; (a04 <usb_tx+0x78>)
9be: 4a12 ldr r2, [pc, #72] ; (a08 <usb_tx+0x7c>)
9c0: f850 4023 ldr.w r4, [r0, r3, lsl #2]
9c4: b914 cbnz r4, 9cc <usb_tx+0x40>
tx_first[endpoint] = packet;
9c6: f840 1023 str.w r1, [r0, r3, lsl #2]
9ca: e002 b.n 9d2 <usb_tx+0x46>
} else {
tx_last[endpoint]->next = packet;
9cc: f852 0023 ldr.w r0, [r2, r3, lsl #2]
9d0: 6041 str r1, [r0, #4]
}
tx_last[endpoint] = packet;
9d2: f842 1023 str.w r1, [r2, r3, lsl #2]
9d6: e00f b.n 9f8 <usb_tx+0x6c>
//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;
9d8: 2203 movs r2, #3
9da: e000 b.n 9de <usb_tx+0x52>
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;
9dc: 2205 movs r2, #5
}
tx_last[endpoint] = packet;
__enable_irq();
return;
}
tx_state[endpoint] = next;
9de: 54e2 strb r2, [r4, r3]
b->addr = packet->buf;
b->desc = BDT_DESC(packet->len, ((uint32_t)b & 8) ? DATA1 : DATA0);
9e0: f010 0f08 tst.w r0, #8
tx_last[endpoint] = packet;
__enable_irq();
return;
}
tx_state[endpoint] = next;
b->addr = packet->buf;
9e4: f101 0308 add.w r3, r1, #8
b->desc = BDT_DESC(packet->len, ((uint32_t)b & 8) ? DATA1 : DATA0);
9e8: 880a ldrh r2, [r1, #0]
tx_last[endpoint] = packet;
__enable_irq();
return;
}
tx_state[endpoint] = next;
b->addr = packet->buf;
9ea: 6043 str r3, [r0, #4]
b->desc = BDT_DESC(packet->len, ((uint32_t)b & 8) ? DATA1 : DATA0);
9ec: bf0c ite eq
9ee: 2388 moveq r3, #136 ; 0x88
9f0: 23c8 movne r3, #200 ; 0xc8
9f2: ea43 4302 orr.w r3, r3, r2, lsl #16
9f6: 6003 str r3, [r0, #0]
__enable_irq();
9f8: b662 cpsie i
9fa: bd30 pop {r4, r5, pc}
9fc: 1fffe000 .word 0x1fffe000
a00: 1fffe67c .word 0x1fffe67c
a04: 1fffe714 .word 0x1fffe714
a08: 1fffe724 .word 0x1fffe724
00000a0c <usb_isr>:
}
void usb_isr(void)
{
a0c: e92d 4ff8 stmdb sp!, {r3, r4, r5, r6, r7, r8, r9, sl, fp, lr}
//serial_print("isr");
//status = USB0_ISTAT;
//serial_phex(status);
//serial_print("\n");
restart:
status = USB0_ISTAT;
a10: 4fab ldr r7, [pc, #684] ; (cc0 <usb_isr+0x2b4>)
a12: 783c ldrb r4, [r7, #0]
a14: b2e4 uxtb r4, r4
if ((status & USB_ISTAT_SOFTOK /* 04 */ )) {
a16: f014 0f04 tst.w r4, #4
a1a: 463d mov r5, r7
a1c: d019 beq.n a52 <usb_isr+0x46>
if (usb_configuration) {
a1e: 4ba9 ldr r3, [pc, #676] ; (cc4 <usb_isr+0x2b8>)
a20: 781b ldrb r3, [r3, #0]
a22: b1a3 cbz r3, a4e <usb_isr+0x42>
t = usb_reboot_timer;
a24: 4aa8 ldr r2, [pc, #672] ; (cc8 <usb_isr+0x2bc>)
a26: 7811 ldrb r1, [r2, #0]
if (t) {
a28: f001 03ff and.w r3, r1, #255 ; 0xff
a2c: b121 cbz r1, a38 <usb_isr+0x2c>
usb_reboot_timer = --t;
a2e: 3b01 subs r3, #1
a30: b2db uxtb r3, r3
a32: 7013 strb r3, [r2, #0]
if (!t) _reboot_Teensyduino_();
a34: b903 cbnz r3, a38 <usb_isr+0x2c>
void _reboot_Teensyduino_(void)
{
// TODO: initialize R0 with a code....
__asm__ volatile("bkpt");
a36: be00 bkpt 0x0000
if (t) {
usb_reboot_timer = --t;
if (!t) _reboot_Teensyduino_();
}
#ifdef CDC_DATA_INTERFACE
t = usb_cdc_transmit_flush_timer;
a38: 4aa4 ldr r2, [pc, #656] ; (ccc <usb_isr+0x2c0>)
a3a: 7811 ldrb r1, [r2, #0]
if (t) {
a3c: f001 03ff and.w r3, r1, #255 ; 0xff
a40: b129 cbz r1, a4e <usb_isr+0x42>
usb_cdc_transmit_flush_timer = --t;
a42: 3b01 subs r3, #1
a44: b2db uxtb r3, r3
a46: 7013 strb r3, [r2, #0]
if (t == 0) usb_serial_flush_callback();
a48: b90b cbnz r3, a4e <usb_isr+0x42>
a4a: f000 fc65 bl 1318 <usb_serial_flush_callback>
#endif
#ifdef MULTITOUCH_INTERFACE
usb_touchscreen_update_callback();
#endif
}
USB0_ISTAT = USB_ISTAT_SOFTOK;
a4e: 2304 movs r3, #4
a50: 703b strb r3, [r7, #0]
}
if ((status & USB_ISTAT_TOKDNE /* 08 */ )) {
a52: f004 0308 and.w r3, r4, #8
a56: f003 02ff and.w r2, r3, #255 ; 0xff
a5a: 2b00 cmp r3, #0
a5c: f000 8267 beq.w f2e <usb_isr+0x522>
uint8_t endpoint;
stat = USB0_STAT;
a60: 4b9b ldr r3, [pc, #620] ; (cd0 <usb_isr+0x2c4>)
a62: 4c9c ldr r4, [pc, #624] ; (cd4 <usb_isr+0x2c8>)
a64: 781a ldrb r2, [r3, #0]
a66: b2d2 uxtb r2, r2
//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;
if (endpoint == 0) {
a68: 0915 lsrs r5, r2, #4
a6a: ea4f 0892 mov.w r8, r2, lsr #2
a6e: f040 81e4 bne.w e3a <usb_isr+0x42e>
bdt_t *b;
uint32_t pid, size;
uint8_t *buf;
const uint8_t *data;
b = stat2bufferdescriptor(stat);
a72: eb04 03c8 add.w r3, r4, r8, lsl #3
pid = BDT_PID(b->desc);
//count = b->desc >> 16;
buf = b->addr;
a76: 6859 ldr r1, [r3, #4]
uint32_t pid, size;
uint8_t *buf;
const uint8_t *data;
b = stat2bufferdescriptor(stat);
pid = BDT_PID(b->desc);
a78: f854 3038 ldr.w r3, [r4, r8, lsl #3]
a7c: f3c3 0383 ubfx r3, r3, #2, #4
//serial_phex(pid);
//serial_print(", count:");
//serial_phex(count);
//serial_print("\n");
switch (pid) {
a80: 3b01 subs r3, #1
a82: 2b0c cmp r3, #12
a84: f200 81d6 bhi.w e34 <usb_isr+0x428>
a88: e8df f013 tbh [pc, r3, lsl #1]
a8c: 01950195 .word 0x01950195
a90: 01d401d4 .word 0x01d401d4
a94: 01d401d4 .word 0x01d401d4
a98: 01d401d4 .word 0x01d401d4
a9c: 01d401b0 .word 0x01d401b0
aa0: 01d401d4 .word 0x01d401d4
aa4: 000d .short 0x000d
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);
aa6: 4d8c ldr r5, [pc, #560] ; (cd8 <usb_isr+0x2cc>)
aa8: 680a ldr r2, [r1, #0]
setup.word2 = *(uint32_t *)(buf + 4);
aaa: 684b ldr r3, [r1, #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;
aac: 488b ldr r0, [pc, #556] ; (cdc <usb_isr+0x2d0>)
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);
setup.word2 = *(uint32_t *)(buf + 4);
aae: 606b str r3, [r5, #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;
ab0: 2101 movs r1, #1
// 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);
ab2: 4b8b ldr r3, [pc, #556] ; (ce0 <usb_isr+0x2d4>)
ab4: f844 3038 str.w r3, [r4, r8, lsl #3]
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);
ab8: 602a str r2, [r5, #0]
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;
aba: f8df 8250 ldr.w r8, [pc, #592] ; d0c <usb_isr+0x300>
//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;
abe: 7001 strb r1, [r0, #0]
volatile uint8_t *reg;
uint8_t epconf;
const uint8_t *cfg;
int i;
switch (setup.wRequestAndType) {
ac0: b292 uxth r2, r2
ac2: f240 6081 movw r0, #1665 ; 0x681
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;
ac6: 2300 movs r3, #0
volatile uint8_t *reg;
uint8_t epconf;
const uint8_t *cfg;
int i;
switch (setup.wRequestAndType) {
ac8: 4282 cmp r2, r0
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;
aca: f8c8 3000 str.w r3, [r8]
//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;
ace: 6123 str r3, [r4, #16]
table[index(0, TX, ODD)].desc = 0;
ad0: 61a3 str r3, [r4, #24]
volatile uint8_t *reg;
uint8_t epconf;
const uint8_t *cfg;
int i;
switch (setup.wRequestAndType) {
ad2: d817 bhi.n b04 <usb_isr+0xf8>
ad4: f5b2 6fd0 cmp.w r2, #1664 ; 0x680
ad8: f080 811e bcs.w d18 <usb_isr+0x30c>
adc: f5b2 7f81 cmp.w r2, #258 ; 0x102
ae0: f000 80cf beq.w c82 <usb_isr+0x276>
ae4: d806 bhi.n af4 <usb_isr+0xe8>
ae6: 2a80 cmp r2, #128 ; 0x80
ae8: f000 80ba beq.w c60 <usb_isr+0x254>
aec: 2a82 cmp r2, #130 ; 0x82
aee: f000 80bb beq.w c68 <usb_isr+0x25c>
af2: e131 b.n d58 <usb_isr+0x34c>
af4: f240 3302 movw r3, #770 ; 0x302
af8: 429a cmp r2, r3
afa: f000 80d1 beq.w ca0 <usb_isr+0x294>
afe: f5b2 6fa0 cmp.w r2, #1280 ; 0x500
b02: e01c b.n b3e <usb_isr+0x132>
b04: f242 0021 movw r0, #8225 ; 0x2021
b08: 4282 cmp r2, r0
b0a: f000 8151 beq.w db0 <usb_isr+0x3a4>
b0e: d80e bhi.n b2e <usb_isr+0x122>
b10: f5b2 6f08 cmp.w r2, #2176 ; 0x880
b14: f000 809e beq.w c54 <usb_isr+0x248>
b18: f5b2 6f10 cmp.w r2, #2304 ; 0x900
b1c: f040 811c bne.w d58 <usb_isr+0x34c>
case 0x0500: // SET_ADDRESS
break;
case 0x0900: // SET_CONFIGURATION
//serial_print("configure\n");
usb_configuration = setup.wValue;
b20: 4b68 ldr r3, [pc, #416] ; (cc4 <usb_isr+0x2b8>)
b22: 4e6c ldr r6, [pc, #432] ; (cd4 <usb_isr+0x2c8>)
b24: 78aa ldrb r2, [r5, #2]
b26: 701a strb r2, [r3, #0]
b28: f106 0980 add.w r9, r6, #128 ; 0x80
b2c: e00a b.n b44 <usb_isr+0x138>
volatile uint8_t *reg;
uint8_t epconf;
const uint8_t *cfg;
int i;
switch (setup.wRequestAndType) {
b2e: f242 2121 movw r1, #8737 ; 0x2221
b32: 428a cmp r2, r1
b34: f000 8108 beq.w d48 <usb_isr+0x33c>
b38: f242 3321 movw r3, #8993 ; 0x2321
b3c: 429a cmp r2, r3
b3e: f000 810f beq.w d60 <usb_isr+0x354>
b42: e109 b.n d58 <usb_isr+0x34c>
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) {
b44: 6a33 ldr r3, [r6, #32]
b46: 061b lsls r3, r3, #24
b48: d503 bpl.n b52 <usb_isr+0x146>
usb_free((usb_packet_t *)((uint8_t *)(table[i].addr) - 8));
b4a: 6a70 ldr r0, [r6, #36] ; 0x24
b4c: 3808 subs r0, #8
b4e: f000 fab7 bl 10c0 <usb_free>
b52: 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++) {
b54: 454e cmp r6, r9
b56: d1f5 bne.n b44 <usb_isr+0x138>
b58: 2600 movs r6, #0
b5a: 46b1 mov r9, r6
}
}
// free all queued packets
for (i=0; i < NUM_ENDPOINTS; i++) {
usb_packet_t *p, *n;
p = rx_first[i];
b5c: f8df a1b0 ldr.w sl, [pc, #432] ; d10 <usb_isr+0x304>
b60: f856 000a ldr.w r0, [r6, sl]
while (p) {
b64: b128 cbz r0, b72 <usb_isr+0x166>
n = p->next;
b66: f8d0 b004 ldr.w fp, [r0, #4]
usb_free(p);
b6a: f000 faa9 bl 10c0 <usb_free>
p = n;
b6e: 4658 mov r0, fp
b70: e7f8 b.n b64 <usb_isr+0x158>
}
rx_first[i] = NULL;
b72: f84a 0006 str.w r0, [sl, r6]
rx_last[i] = NULL;
b76: 4b5b ldr r3, [pc, #364] ; (ce4 <usb_isr+0x2d8>)
p = tx_first[i];
b78: f8df a198 ldr.w sl, [pc, #408] ; d14 <usb_isr+0x308>
n = p->next;
usb_free(p);
p = n;
}
rx_first[i] = NULL;
rx_last[i] = NULL;
b7c: 50f0 str r0, [r6, r3]
p = tx_first[i];
b7e: f856 000a ldr.w r0, [r6, sl]
while (p) {
b82: b128 cbz r0, b90 <usb_isr+0x184>
n = p->next;
b84: f8d0 b004 ldr.w fp, [r0, #4]
usb_free(p);
b88: f000 fa9a bl 10c0 <usb_free>
p = n;
b8c: 4658 mov r0, fp
b8e: e7f8 b.n b82 <usb_isr+0x176>
}
tx_first[i] = NULL;
tx_last[i] = NULL;
b90: 4b55 ldr r3, [pc, #340] ; (ce8 <usb_isr+0x2dc>)
while (p) {
n = p->next;
usb_free(p);
p = n;
}
tx_first[i] = NULL;
b92: f84a 0006 str.w r0, [sl, r6]
tx_last[i] = NULL;
b96: 50f0 str r0, [r6, r3]
usb_rx_byte_count_data[i] = 0;
b98: 4b54 ldr r3, [pc, #336] ; (cec <usb_isr+0x2e0>)
b9a: f823 0019 strh.w r0, [r3, r9, lsl #1]
switch (tx_state[i]) {
b9e: 4b54 ldr r3, [pc, #336] ; (cf0 <usb_isr+0x2e4>)
ba0: f819 2003 ldrb.w r2, [r9, r3]
ba4: 3a02 subs r2, #2
ba6: 2a03 cmp r2, #3
ba8: d808 bhi.n bbc <usb_isr+0x1b0>
baa: e8df f002 tbb [pc, r2]
bae: 0402 .short 0x0402
bb0: 0402 .short 0x0402
case TX_STATE_EVEN_FREE:
case TX_STATE_NONE_FREE_EVEN_FIRST:
tx_state[i] = TX_STATE_BOTH_FREE_EVEN_FIRST;
bb2: 2200 movs r2, #0
bb4: e000 b.n bb8 <usb_isr+0x1ac>
break;
case TX_STATE_ODD_FREE:
case TX_STATE_NONE_FREE_ODD_FIRST:
tx_state[i] = TX_STATE_BOTH_FREE_ODD_FIRST;
bb6: 2201 movs r2, #1
bb8: f803 2009 strb.w r2, [r3, r9]
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++) {
bbc: f109 0901 add.w r9, r9, #1
bc0: f1b9 0f04 cmp.w r9, #4
bc4: f106 0604 add.w r6, r6, #4
bc8: d1c8 bne.n b5c <usb_isr+0x150>
break;
default:
break;
}
}
usb_rx_memory_needed = 0;
bca: 4b4a ldr r3, [pc, #296] ; (cf4 <usb_isr+0x2e8>)
bcc: 2200 movs r2, #0
bce: 701a strb r2, [r3, #0]
for (i=1; i <= NUM_ENDPOINTS; i++) {
bd0: 2601 movs r6, #1
bd2: 469a mov sl, r3
bd4: 4a48 ldr r2, [pc, #288] ; (cf8 <usb_isr+0x2ec>)
bd6: 4b49 ldr r3, [pc, #292] ; (cfc <usb_isr+0x2f0>)
bd8: 4432 add r2, r6
bda: 4433 add r3, r6
epconf = *cfg++;
bdc: f812 2c01 ldrb.w r2, [r2, #-1]
be0: 009b lsls r3, r3, #2
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) {
be2: f012 0f08 tst.w r2, #8
}
}
usb_rx_memory_needed = 0;
for (i=1; i <= NUM_ENDPOINTS; i++) {
epconf = *cfg++;
*reg = epconf;
be6: 701a strb r2, [r3, #0]
be8: ea4f 0986 mov.w r9, r6, lsl #2
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) {
bec: d025 beq.n c3a <usb_isr+0x22e>
usb_packet_t *p;
p = usb_malloc();
bee: f000 fa49 bl 1084 <usb_malloc>
if (p) {
bf2: b138 cbz r0, c04 <usb_isr+0x1f8>
table[index(i, RX, EVEN)].addr = p->buf;
bf4: eb04 1346 add.w r3, r4, r6, lsl #5
bf8: 3008 adds r0, #8
bfa: 6058 str r0, [r3, #4]
table[index(i, RX, EVEN)].desc = BDT_DESC(64, 0);
bfc: 4b40 ldr r3, [pc, #256] ; (d00 <usb_isr+0x2f4>)
bfe: f844 3039 str.w r3, [r4, r9, lsl #3]
c02: e006 b.n c12 <usb_isr+0x206>
} else {
table[index(i, RX, EVEN)].desc = 0;
usb_rx_memory_needed++;
c04: f89a 3000 ldrb.w r3, [sl]
p = usb_malloc();
if (p) {
table[index(i, RX, EVEN)].addr = p->buf;
table[index(i, RX, EVEN)].desc = BDT_DESC(64, 0);
} else {
table[index(i, RX, EVEN)].desc = 0;
c08: f844 0039 str.w r0, [r4, r9, lsl #3]
usb_rx_memory_needed++;
c0c: 3301 adds r3, #1
c0e: f88a 3000 strb.w r3, [sl]
}
p = usb_malloc();
c12: f000 fa37 bl 1084 <usb_malloc>
if (p) {
table[index(i, RX, ODD)].addr = p->buf;
c16: f049 0301 orr.w r3, r9, #1
} else {
table[index(i, RX, EVEN)].desc = 0;
usb_rx_memory_needed++;
}
p = usb_malloc();
if (p) {
c1a: b138 cbz r0, c2c <usb_isr+0x220>
table[index(i, RX, ODD)].addr = p->buf;
c1c: eb04 02c3 add.w r2, r4, r3, lsl #3
c20: 3008 adds r0, #8
c22: 6050 str r0, [r2, #4]
table[index(i, RX, ODD)].desc = BDT_DESC(64, 1);
c24: 4a2e ldr r2, [pc, #184] ; (ce0 <usb_isr+0x2d4>)
c26: f844 2033 str.w r2, [r4, r3, lsl #3]
c2a: e006 b.n c3a <usb_isr+0x22e>
} else {
table[index(i, RX, ODD)].desc = 0;
c2c: f844 0033 str.w r0, [r4, r3, lsl #3]
usb_rx_memory_needed++;
c30: f89a 3000 ldrb.w r3, [sl]
c34: 3301 adds r3, #1
c36: f88a 3000 strb.w r3, [sl]
}
}
table[index(i, TX, EVEN)].desc = 0;
c3a: f049 0202 orr.w r2, r9, #2
default:
break;
}
}
usb_rx_memory_needed = 0;
for (i=1; i <= NUM_ENDPOINTS; i++) {
c3e: 3601 adds r6, #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;
c40: f049 0903 orr.w r9, r9, #3
} else {
table[index(i, RX, ODD)].desc = 0;
usb_rx_memory_needed++;
}
}
table[index(i, TX, EVEN)].desc = 0;
c44: 2300 movs r3, #0
default:
break;
}
}
usb_rx_memory_needed = 0;
for (i=1; i <= NUM_ENDPOINTS; i++) {
c46: 2e05 cmp r6, #5
} else {
table[index(i, RX, ODD)].desc = 0;
usb_rx_memory_needed++;
}
}
table[index(i, TX, EVEN)].desc = 0;
c48: f844 3032 str.w r3, [r4, r2, lsl #3]
table[index(i, TX, ODD)].desc = 0;
c4c: f844 3039 str.w r3, [r4, r9, lsl #3]
default:
break;
}
}
usb_rx_memory_needed = 0;
for (i=1; i <= NUM_ENDPOINTS; i++) {
c50: d1c0 bne.n bd4 <usb_isr+0x1c8>
c52: e086 b.n d62 <usb_isr+0x356>
}
#endif
}
break;
case 0x0880: // GET_CONFIGURATION
reply_buffer[0] = usb_configuration;
c54: 4b1b ldr r3, [pc, #108] ; (cc4 <usb_isr+0x2b8>)
c56: 4c2b ldr r4, [pc, #172] ; (d04 <usb_isr+0x2f8>)
c58: 781b ldrb r3, [r3, #0]
c5a: 7023 strb r3, [r4, #0]
datalen = 1;
c5c: 460b mov r3, r1
c5e: e083 b.n d68 <usb_isr+0x35c>
data = reply_buffer;
break;
case 0x0080: // GET_STATUS (device)
reply_buffer[0] = 0;
c60: 4c28 ldr r4, [pc, #160] ; (d04 <usb_isr+0x2f8>)
c62: 7023 strb r3, [r4, #0]
reply_buffer[1] = 0;
c64: 7063 strb r3, [r4, #1]
c66: e07e b.n d66 <usb_isr+0x35a>
datalen = 2;
data = reply_buffer;
break;
case 0x0082: // GET_STATUS (endpoint)
if (setup.wIndex > NUM_ENDPOINTS) {
c68: 88aa ldrh r2, [r5, #4]
c6a: 2a04 cmp r2, #4
c6c: d874 bhi.n d58 <usb_isr+0x34c>
// TODO: do we need to handle IN vs OUT here?
endpoint0_stall();
return;
}
reply_buffer[0] = 0;
c6e: 4c25 ldr r4, [pc, #148] ; (d04 <usb_isr+0x2f8>)
reply_buffer[1] = 0;
if (*(uint8_t *)(&USB0_ENDPT0 + setup.wIndex * 4) & 0x02) reply_buffer[0] = 1;
c70: 0092 lsls r2, r2, #2
if (setup.wIndex > NUM_ENDPOINTS) {
// TODO: do we need to handle IN vs OUT here?
endpoint0_stall();
return;
}
reply_buffer[0] = 0;
c72: 7023 strb r3, [r4, #0]
reply_buffer[1] = 0;
c74: 7063 strb r3, [r4, #1]
if (*(uint8_t *)(&USB0_ENDPT0 + setup.wIndex * 4) & 0x02) reply_buffer[0] = 1;
c76: 4b24 ldr r3, [pc, #144] ; (d08 <usb_isr+0x2fc>)
c78: 5c9b ldrb r3, [r3, r2]
c7a: 079e lsls r6, r3, #30
c7c: d573 bpl.n d66 <usb_isr+0x35a>
c7e: 7021 strb r1, [r4, #0]
c80: e071 b.n d66 <usb_isr+0x35a>
data = reply_buffer;
datalen = 2;
break;
case 0x0102: // CLEAR_FEATURE (endpoint)
i = setup.wIndex & 0x7F;
c82: 88aa ldrh r2, [r5, #4]
c84: f002 027f and.w r2, r2, #127 ; 0x7f
if (i > NUM_ENDPOINTS || setup.wValue != 0) {
c88: 2a04 cmp r2, #4
c8a: dc65 bgt.n d58 <usb_isr+0x34c>
c8c: 886b ldrh r3, [r5, #2]
c8e: 2b00 cmp r3, #0
c90: d162 bne.n d58 <usb_isr+0x34c>
// TODO: do we need to handle IN vs OUT here?
endpoint0_stall();
return;
}
(*(uint8_t *)(&USB0_ENDPT0 + i * 4)) &= ~0x02;
c92: 0091 lsls r1, r2, #2
c94: 4a1c ldr r2, [pc, #112] ; (d08 <usb_isr+0x2fc>)
c96: 440a add r2, r1
c98: 7811 ldrb r1, [r2, #0]
c9a: f021 0102 bic.w r1, r1, #2
c9e: e059 b.n d54 <usb_isr+0x348>
// TODO: do we need to clear the data toggle here?
break;
case 0x0302: // SET_FEATURE (endpoint)
i = setup.wIndex & 0x7F;
ca0: 88aa ldrh r2, [r5, #4]
ca2: f002 027f and.w r2, r2, #127 ; 0x7f
if (i > NUM_ENDPOINTS || setup.wValue != 0) {
ca6: 2a04 cmp r2, #4
ca8: dc56 bgt.n d58 <usb_isr+0x34c>
caa: 886b ldrh r3, [r5, #2]
cac: 2b00 cmp r3, #0
cae: d153 bne.n d58 <usb_isr+0x34c>
// TODO: do we need to handle IN vs OUT here?
endpoint0_stall();
return;
}
(*(uint8_t *)(&USB0_ENDPT0 + i * 4)) |= 0x02;
cb0: 0091 lsls r1, r2, #2
cb2: 4a15 ldr r2, [pc, #84] ; (d08 <usb_isr+0x2fc>)
cb4: 440a add r2, r1
cb6: 7811 ldrb r1, [r2, #0]
cb8: f041 0102 orr.w r1, r1, #2
cbc: e04a b.n d54 <usb_isr+0x348>
cbe: bf00 nop
cc0: 40072080 .word 0x40072080
cc4: 1fffe747 .word 0x1fffe747
cc8: 1fffe6d1 .word 0x1fffe6d1
ccc: 1fffe749 .word 0x1fffe749
cd0: 40072090 .word 0x40072090
cd4: 1fffe000 .word 0x1fffe000
cd8: 1fffe734 .word 0x1fffe734
cdc: 1fffe748 .word 0x1fffe748
ce0: 004000c8 .word 0x004000c8
ce4: 1fffe66c .word 0x1fffe66c
ce8: 1fffe724 .word 0x1fffe724
cec: 1fffe924 .word 0x1fffe924
cf0: 1fffe67c .word 0x1fffe67c
cf4: 1fffe73e .word 0x1fffe73e
cf8: 00002bd0 .word 0x00002bd0
cfc: 1001c830 .word 0x1001c830
d00: 00400088 .word 0x00400088
d04: 1fffe73f .word 0x1fffe73f
d08: 400720c0 .word 0x400720c0
d0c: 1fffe668 .word 0x1fffe668
d10: 1fffe6c0 .word 0x1fffe6c0
d14: 1fffe714 .word 0x1fffe714
//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) {
d18: 886a ldrh r2, [r5, #2]
d1a: 88a9 ldrh r1, [r5, #4]
d1c: 4b9f ldr r3, [pc, #636] ; (f9c <usb_isr+0x590>)
case 0x0681:
//serial_print("desc:");
//serial_phex16(setup.wValue);
//serial_print("\n");
for (list = usb_descriptor_list; 1; list++) {
if (list->addr == NULL) break;
d1e: f853 4c08 ldr.w r4, [r3, #-8]
d22: f1a3 000c sub.w r0, r3, #12
d26: b1bc cbz r4, d58 <usb_isr+0x34c>
//if (setup.wValue == list->wValue &&
//(setup.wIndex == list->wIndex) || ((setup.wValue >> 8) == 3)) {
if (setup.wValue == list->wValue && setup.wIndex == list->wIndex) {
d28: f833 6c0c ldrh.w r6, [r3, #-12]
d2c: 4296 cmp r6, r2
d2e: d109 bne.n d44 <usb_isr+0x338>
d30: f833 6c0a ldrh.w r6, [r3, #-10]
d34: 428e cmp r6, r1
d36: d105 bne.n d44 <usb_isr+0x338>
data = list->addr;
if ((setup.wValue >> 8) == 3) {
d38: 0a12 lsrs r2, r2, #8
d3a: 2a03 cmp r2, #3
// for string descriptors, use the descriptor's
// length field, allowing runtime configured
// length.
datalen = *(list->addr);
d3c: bf0c ite eq
d3e: 7823 ldrbeq r3, [r4, #0]
} else {
datalen = list->length;
d40: 8903 ldrhne r3, [r0, #8]
d42: e011 b.n d68 <usb_isr+0x35c>
d44: 330c adds r3, #12
d46: e7ea b.n d1e <usb_isr+0x312>
//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;
d48: 4a95 ldr r2, [pc, #596] ; (fa0 <usb_isr+0x594>)
d4a: 6811 ldr r1, [r2, #0]
d4c: 4a95 ldr r2, [pc, #596] ; (fa4 <usb_isr+0x598>)
d4e: 6011 str r1, [r2, #0]
usb_cdc_line_rtsdtr = setup.wValue;
d50: 78a9 ldrb r1, [r5, #2]
d52: 4a95 ldr r2, [pc, #596] ; (fa8 <usb_isr+0x59c>)
d54: 7011 strb r1, [r2, #0]
d56: e004 b.n d62 <usb_isr+0x356>
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;
d58: 4b94 ldr r3, [pc, #592] ; (fac <usb_isr+0x5a0>)
d5a: 220f movs r2, #15
d5c: 701a strb r2, [r3, #0]
d5e: e027 b.n db0 <usb_isr+0x3a4>
static uint8_t reply_buffer[8];
static void usb_setup(void)
{
const uint8_t *data = NULL;
uint32_t datalen = 0;
d60: 2300 movs r3, #0
static uint8_t reply_buffer[8];
static void usb_setup(void)
{
const uint8_t *data = NULL;
d62: 461c mov r4, r3
d64: e000 b.n d68 <usb_isr+0x35c>
}
reply_buffer[0] = 0;
reply_buffer[1] = 0;
if (*(uint8_t *)(&USB0_ENDPT0 + setup.wIndex * 4) & 0x02) reply_buffer[0] = 1;
data = reply_buffer;
datalen = 2;
d66: 2302 movs r3, #2
//serial_phex32(data);
//serial_print(",");
//serial_phex16(datalen);
//serial_print("\n");
if (datalen > setup.wLength) datalen = setup.wLength;
d68: 88ee ldrh r6, [r5, #6]
d6a: 42b3 cmp r3, r6
d6c: bf38 it cc
d6e: 461e movcc r6, r3
d70: 2e40 cmp r6, #64 ; 0x40
d72: bf34 ite cc
d74: 4635 movcc r5, r6
d76: 2540 movcs r5, #64 ; 0x40
size = datalen;
if (size > EP0_SIZE) size = EP0_SIZE;
endpoint0_transmit(data, size);
d78: 4620 mov r0, r4
d7a: 4629 mov r1, r5
d7c: f7ff fd7c bl 878 <endpoint0_transmit>
data += size;
datalen -= size;
if (datalen == 0 && size < EP0_SIZE) return;
d80: 1b76 subs r6, r6, r5
if (datalen > setup.wLength) datalen = setup.wLength;
size = datalen;
if (size > EP0_SIZE) size = EP0_SIZE;
endpoint0_transmit(data, size);
data += size;
d82: 442c add r4, r5
datalen -= size;
if (datalen == 0 && size < EP0_SIZE) return;
d84: d103 bne.n d8e <usb_isr+0x382>
d86: 2d40 cmp r5, #64 ; 0x40
d88: d112 bne.n db0 <usb_isr+0x3a4>
d8a: 4635 mov r5, r6
d8c: e003 b.n d96 <usb_isr+0x38a>
d8e: 2e40 cmp r6, #64 ; 0x40
d90: bf34 ite cc
d92: 4635 movcc r5, r6
d94: 2540 movcs r5, #64 ; 0x40
size = datalen;
if (size > EP0_SIZE) size = EP0_SIZE;
endpoint0_transmit(data, size);
d96: 4620 mov r0, r4
d98: 4629 mov r1, r5
d9a: f7ff fd6d bl 878 <endpoint0_transmit>
data += size;
datalen -= size;
if (datalen == 0 && size < EP0_SIZE) return;
d9e: 1b76 subs r6, r6, r5
if (datalen == 0 && size < EP0_SIZE) return;
size = datalen;
if (size > EP0_SIZE) size = EP0_SIZE;
endpoint0_transmit(data, size);
data += size;
da0: 442c add r4, r5
datalen -= size;
if (datalen == 0 && size < EP0_SIZE) return;
da2: d101 bne.n da8 <usb_isr+0x39c>
da4: 2d40 cmp r5, #64 ; 0x40
da6: d103 bne.n db0 <usb_isr+0x3a4>
ep0_tx_ptr = data;
ep0_tx_len = datalen;
da8: 4a81 ldr r2, [pc, #516] ; (fb0 <usb_isr+0x5a4>)
endpoint0_transmit(data, size);
data += size;
datalen -= size;
if (datalen == 0 && size < EP0_SIZE) return;
ep0_tx_ptr = data;
daa: f8c8 4000 str.w r4, [r8]
ep0_tx_len = datalen;
dae: 8016 strh r6, [r2, #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
db0: 2201 movs r2, #1
db2: 4b80 ldr r3, [pc, #512] ; (fb4 <usb_isr+0x5a8>)
db4: e03d b.n e32 <usb_isr+0x426>
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*/) {
db6: 4b80 ldr r3, [pc, #512] ; (fb8 <usb_isr+0x5ac>)
db8: 881a ldrh r2, [r3, #0]
dba: f242 0321 movw r3, #8225 ; 0x2021
dbe: 429a cmp r2, r3
dc0: d110 bne.n de4 <usb_isr+0x3d8>
dc2: 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++;
dc4: 4a7d ldr r2, [pc, #500] ; (fbc <usb_isr+0x5b0>)
dc6: 5cc8 ldrb r0, [r1, r3]
dc8: 5498 strb r0, [r3, r2]
#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++) {
dca: 3301 adds r3, #1
dcc: 2b07 cmp r3, #7
dce: d1f9 bne.n dc4 <usb_isr+0x3b8>
//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;
dd0: 6813 ldr r3, [r2, #0]
dd2: 2b86 cmp r3, #134 ; 0x86
dd4: d102 bne.n ddc <usb_isr+0x3d0>
dd6: 4b7a ldr r3, [pc, #488] ; (fc0 <usb_isr+0x5b4>)
dd8: 220f movs r2, #15
dda: 701a strb r2, [r3, #0]
endpoint0_transmit(NULL, 0);
ddc: 2000 movs r0, #0
dde: 4601 mov r1, r0
de0: f7ff fd4a bl 878 <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);
de4: 4b77 ldr r3, [pc, #476] ; (fc4 <usb_isr+0x5b8>)
de6: f844 3038 str.w r3, [r4, r8, lsl #3]
dea: e023 b.n e34 <usb_isr+0x428>
//serial_print("PID=IN:");
//serial_phex(stat);
//serial_print("\n");
// send remaining data, if any...
data = ep0_tx_ptr;
dec: 4e76 ldr r6, [pc, #472] ; (fc8 <usb_isr+0x5bc>)
dee: 6835 ldr r5, [r6, #0]
if (data) {
df0: b1b5 cbz r5, e20 <usb_isr+0x414>
size = ep0_tx_len;
df2: f8df 81bc ldr.w r8, [pc, #444] ; fb0 <usb_isr+0x5a4>
df6: f8b8 9000 ldrh.w r9, [r8]
dfa: f1b9 0f40 cmp.w r9, #64 ; 0x40
dfe: bf34 ite cc
e00: 464c movcc r4, r9
e02: 2440 movcs r4, #64 ; 0x40
if (size > EP0_SIZE) size = EP0_SIZE;
endpoint0_transmit(data, size);
e04: 4628 mov r0, r5
e06: 4621 mov r1, r4
e08: f7ff fd36 bl 878 <endpoint0_transmit>
data += size;
ep0_tx_len -= size;
e0c: ebc4 0309 rsb r3, r4, r9
e10: b29b uxth r3, r3
e12: f8a8 3000 strh.w r3, [r8]
ep0_tx_ptr = (ep0_tx_len > 0 || size == EP0_SIZE) ? data : NULL;
e16: b90b cbnz r3, e1c <usb_isr+0x410>
e18: 2c40 cmp r4, #64 ; 0x40
e1a: d100 bne.n e1e <usb_isr+0x412>
data = ep0_tx_ptr;
if (data) {
size = ep0_tx_len;
if (size > EP0_SIZE) size = EP0_SIZE;
endpoint0_transmit(data, size);
data += size;
e1c: 192b adds r3, r5, r4
ep0_tx_len -= size;
ep0_tx_ptr = (ep0_tx_len > 0 || size == EP0_SIZE) ? data : NULL;
e1e: 6033 str r3, [r6, #0]
}
if (setup.bRequest == 5 && setup.bmRequestType == 0) {
e20: 4b65 ldr r3, [pc, #404] ; (fb8 <usb_isr+0x5ac>)
e22: 881a ldrh r2, [r3, #0]
e24: f5b2 6fa0 cmp.w r2, #1280 ; 0x500
e28: d104 bne.n e34 <usb_isr+0x428>
setup.bRequest = 0;
e2a: 2200 movs r2, #0
e2c: 705a strb r2, [r3, #1]
//serial_print("set address: ");
//serial_phex16(setup.wValue);
//serial_print("\n");
USB0_ADDR = setup.wValue;
e2e: 789a ldrb r2, [r3, #2]
e30: 4b66 ldr r3, [pc, #408] ; (fcc <usb_isr+0x5c0>)
e32: 701a strb r2, [r3, #0]
//default:
//serial_print("PID=unknown:");
//serial_phex(pid);
//serial_print("\n");
}
USB0_CTL = USB_CTL_USBENSOFEN; // clear TXSUSPENDTOKENBUSY bit
e34: 2201 movs r2, #1
e36: 4b5f ldr r3, [pc, #380] ; (fb4 <usb_isr+0x5a8>)
e38: e06c b.n f14 <usb_isr+0x508>
//serial_print(stat & 0x04 ? ",odd\n" : ",even\n");
endpoint = stat >> 4;
if (endpoint == 0) {
usb_control(stat);
} else {
bdt_t *b = stat2bufferdescriptor(stat);
e3a: eb04 06c8 add.w r6, r4, r8, lsl #3
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
e3e: 3d01 subs r5, #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);
e40: 6873 ldr r3, [r6, #4]
b->addr = &usb_audio_sync_feedback;
b->desc = (3 << 16) | BDT_OWN;
tx_state[endpoint] ^= 1;
} else
#endif
if (stat & 0x08) { // transmit
e42: f002 0208 and.w r2, r2, #8
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);
e46: f1a3 0008 sub.w r0, r3, #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
e4a: b2ed uxtb r5, r5
b->addr = &usb_audio_sync_feedback;
b->desc = (3 << 16) | BDT_OWN;
tx_state[endpoint] ^= 1;
} else
#endif
if (stat & 0x08) { // transmit
e4c: f002 01ff and.w r1, r2, #255 ; 0xff
e50: 2a00 cmp r2, #0
e52: d036 beq.n ec2 <usb_isr+0x4b6>
usb_free(packet);
e54: f000 f934 bl 10c0 <usb_free>
packet = tx_first[endpoint];
e58: 485d ldr r0, [pc, #372] ; (fd0 <usb_isr+0x5c4>)
e5a: 4b5e ldr r3, [pc, #376] ; (fd4 <usb_isr+0x5c8>)
e5c: f850 2025 ldr.w r2, [r0, r5, lsl #2]
if (packet) {
e60: b1ea cbz r2, e9e <usb_isr+0x492>
//serial_print("tx packet\n");
tx_first[endpoint] = packet->next;
e62: 6851 ldr r1, [r2, #4]
e64: f840 1025 str.w r1, [r0, r5, lsl #2]
b->addr = packet->buf;
e68: f102 0108 add.w r1, r2, #8
e6c: 6071 str r1, [r6, #4]
switch (tx_state[endpoint]) {
e6e: 5d59 ldrb r1, [r3, r5]
e70: 2903 cmp r1, #3
e72: d80b bhi.n e8c <usb_isr+0x480>
e74: e8df f001 tbb [pc, r1]
e78: 08060402 .word 0x08060402
case TX_STATE_BOTH_FREE_EVEN_FIRST:
tx_state[endpoint] = TX_STATE_ODD_FREE;
e7c: 2103 movs r1, #3
e7e: e004 b.n e8a <usb_isr+0x47e>
break;
case TX_STATE_BOTH_FREE_ODD_FIRST:
tx_state[endpoint] = TX_STATE_EVEN_FREE;
e80: 2102 movs r1, #2
e82: e002 b.n e8a <usb_isr+0x47e>
break;
case TX_STATE_EVEN_FREE:
tx_state[endpoint] = TX_STATE_NONE_FREE_ODD_FIRST;
e84: 2105 movs r1, #5
e86: e000 b.n e8a <usb_isr+0x47e>
break;
case TX_STATE_ODD_FREE:
tx_state[endpoint] = TX_STATE_NONE_FREE_EVEN_FIRST;
e88: 2104 movs r1, #4
e8a: 5559 strb r1, [r3, r5]
break;
default:
break;
}
b->desc = BDT_DESC(packet->len,
e8c: f016 0f08 tst.w r6, #8
e90: 8812 ldrh r2, [r2, #0]
e92: bf0c ite eq
e94: 2388 moveq r3, #136 ; 0x88
e96: 23c8 movne r3, #200 ; 0xc8
e98: ea43 4302 orr.w r3, r3, r2, lsl #16
e9c: e042 b.n f24 <usb_isr+0x518>
((uint32_t)b & 8) ? DATA1 : DATA0);
} else {
//serial_print("tx no packet\n");
switch (tx_state[endpoint]) {
e9e: 5d5a ldrb r2, [r3, r5]
ea0: 2a03 cmp r2, #3
ea2: d807 bhi.n eb4 <usb_isr+0x4a8>
ea4: e8df f002 tbb [pc, r2]
ea8: 04024040 .word 0x04024040
case TX_STATE_BOTH_FREE_EVEN_FIRST:
case TX_STATE_BOTH_FREE_ODD_FIRST:
break;
case TX_STATE_EVEN_FREE:
tx_state[endpoint] = TX_STATE_BOTH_FREE_EVEN_FIRST;
eac: 2200 movs r2, #0
eae: e006 b.n ebe <usb_isr+0x4b2>
break;
case TX_STATE_ODD_FREE:
tx_state[endpoint] = TX_STATE_BOTH_FREE_ODD_FIRST;
eb0: 2201 movs r2, #1
eb2: e004 b.n ebe <usb_isr+0x4b2>
break;
default:
tx_state[endpoint] = ((uint32_t)b & 8) ?
eb4: f016 0f08 tst.w r6, #8
eb8: bf0c ite eq
eba: 2202 moveq r2, #2
ebc: 2203 movne r2, #3
ebe: 555a strb r2, [r3, r5]
TX_STATE_ODD_FREE : TX_STATE_EVEN_FREE;
break;
ec0: e032 b.n f28 <usb_isr+0x51c>
}
}
} else { // receive
packet->len = b->desc >> 16;
ec2: f854 2038 ldr.w r2, [r4, r8, lsl #3]
ec6: 0c12 lsrs r2, r2, #16
ec8: f823 2c08 strh.w r2, [r3, #-8]
if (packet->len > 0) {
ecc: b322 cbz r2, f18 <usb_isr+0x50c>
packet->index = 0;
packet->next = NULL;
if (rx_first[endpoint] == NULL) {
ece: f8df e134 ldr.w lr, [pc, #308] ; 1004 <usb_isr+0x5f8>
}
}
} else { // receive
packet->len = b->desc >> 16;
if (packet->len > 0) {
packet->index = 0;
ed2: f823 1c06 strh.w r1, [r3, #-6]
packet->next = NULL;
ed6: f843 1c04 str.w r1, [r3, #-4]
if (rx_first[endpoint] == NULL) {
eda: f85e 3025 ldr.w r3, [lr, r5, lsl #2]
ede: 493e ldr r1, [pc, #248] ; (fd8 <usb_isr+0x5cc>)
ee0: b913 cbnz r3, ee8 <usb_isr+0x4dc>
//serial_print("rx 1st, epidx=");
//serial_phex(endpoint);
//serial_print(", packet=");
//serial_phex32((uint32_t)packet);
//serial_print("\n");
rx_first[endpoint] = packet;
ee2: f84e 0025 str.w r0, [lr, r5, lsl #2]
ee6: e002 b.n eee <usb_isr+0x4e2>
//serial_print("rx Nth, epidx=");
//serial_phex(endpoint);
//serial_print(", packet=");
//serial_phex32((uint32_t)packet);
//serial_print("\n");
rx_last[endpoint]->next = packet;
ee8: f851 3025 ldr.w r3, [r1, r5, lsl #2]
eec: 6058 str r0, [r3, #4]
}
rx_last[endpoint] = packet;
usb_rx_byte_count_data[endpoint] += packet->len;
eee: 4b3b ldr r3, [pc, #236] ; (fdc <usb_isr+0x5d0>)
//serial_print(", packet=");
//serial_phex32((uint32_t)packet);
//serial_print("\n");
rx_last[endpoint]->next = packet;
}
rx_last[endpoint] = packet;
ef0: f841 0025 str.w r0, [r1, r5, lsl #2]
usb_rx_byte_count_data[endpoint] += packet->len;
ef4: f833 1015 ldrh.w r1, [r3, r5, lsl #1]
ef8: 440a add r2, r1
efa: f823 2015 strh.w r2, [r3, r5, lsl #1]
// TODO: implement a per-endpoint maximum # of allocated
// packets, so a flood of incoming data on 1 endpoint
// doesn't starve the others if the user isn't reading
// it regularly
packet = usb_malloc();
efe: f000 f8c1 bl 1084 <usb_malloc>
if (packet) {
f02: b110 cbz r0, f0a <usb_isr+0x4fe>
b->addr = packet->buf;
f04: 3008 adds r0, #8
f06: 6070 str r0, [r6, #4]
f08: e006 b.n f18 <usb_isr+0x50c>
((uint32_t)b & 8) ? DATA1 : DATA0);
} else {
//serial_print("starving ");
//serial_phex(endpoint + 1);
b->desc = 0;
usb_rx_memory_needed++;
f0a: 4b35 ldr r3, [pc, #212] ; (fe0 <usb_isr+0x5d4>)
b->desc = BDT_DESC(64,
((uint32_t)b & 8) ? DATA1 : DATA0);
} else {
//serial_print("starving ");
//serial_phex(endpoint + 1);
b->desc = 0;
f0c: f844 0038 str.w r0, [r4, r8, lsl #3]
usb_rx_memory_needed++;
f10: 781a ldrb r2, [r3, #0]
f12: 3201 adds r2, #1
f14: 701a strb r2, [r3, #0]
f16: e007 b.n f28 <usb_isr+0x51c>
}
} else {
b->desc = BDT_DESC(64, ((uint32_t)b & 8) ? DATA1 : DATA0);
f18: 4b2a ldr r3, [pc, #168] ; (fc4 <usb_isr+0x5b8>)
f1a: 4a32 ldr r2, [pc, #200] ; (fe4 <usb_isr+0x5d8>)
f1c: f016 0f08 tst.w r6, #8
f20: bf08 it eq
f22: 4613 moveq r3, r2
f24: f844 3038 str.w r3, [r4, r8, lsl #3]
}
}
}
USB0_ISTAT = USB_ISTAT_TOKDNE;
f28: 2308 movs r3, #8
f2a: 703b strb r3, [r7, #0]
goto restart;
f2c: e570 b.n a10 <usb_isr+0x4>
}
if (status & USB_ISTAT_USBRST /* 01 */ ) {
f2e: 07e0 lsls r0, r4, #31
f30: d51f bpl.n f72 <usb_isr+0x566>
//serial_print("reset\n");
// initialize BDT toggle bits
USB0_CTL = USB_CTL_ODDRST;
f32: 4920 ldr r1, [pc, #128] ; (fb4 <usb_isr+0x5a8>)
ep0_tx_bdt_bank = 0;
// set up buffers to receive Setup and OUT packets
table[index(0, RX, EVEN)].desc = BDT_DESC(EP0_SIZE, 0);
f34: 482b ldr r0, [pc, #172] ; (fe4 <usb_isr+0x5d8>)
table[index(0, RX, EVEN)].addr = ep0_rx0_buf;
f36: 4c2c ldr r4, [pc, #176] ; (fe8 <usb_isr+0x5dc>)
if (status & USB_ISTAT_USBRST /* 01 */ ) {
//serial_print("reset\n");
// initialize BDT toggle bits
USB0_CTL = USB_CTL_ODDRST;
f38: 2302 movs r3, #2
f3a: 700b strb r3, [r1, #0]
ep0_tx_bdt_bank = 0;
f3c: 4b2b ldr r3, [pc, #172] ; (fec <usb_isr+0x5e0>)
f3e: 701a strb r2, [r3, #0]
// set up buffers to receive Setup and OUT packets
table[index(0, RX, EVEN)].desc = BDT_DESC(EP0_SIZE, 0);
f40: 4b2b ldr r3, [pc, #172] ; (ff0 <usb_isr+0x5e4>)
f42: 6018 str r0, [r3, #0]
table[index(0, RX, EVEN)].addr = ep0_rx0_buf;
table[index(0, RX, ODD)].desc = BDT_DESC(EP0_SIZE, 0);
f44: 6098 str r0, [r3, #8]
table[index(0, RX, ODD)].addr = ep0_rx1_buf;
f46: 482b ldr r0, [pc, #172] ; (ff4 <usb_isr+0x5e8>)
f48: 60d8 str r0, [r3, #12]
table[index(0, TX, EVEN)].desc = 0;
f4a: 611a str r2, [r3, #16]
table[index(0, TX, ODD)].desc = 0;
f4c: 619a str r2, [r3, #24]
USB0_CTL = USB_CTL_ODDRST;
ep0_tx_bdt_bank = 0;
// set up buffers to receive Setup and OUT packets
table[index(0, RX, EVEN)].desc = BDT_DESC(EP0_SIZE, 0);
table[index(0, RX, EVEN)].addr = ep0_rx0_buf;
f4e: 605c str r4, [r3, #4]
table[index(0, RX, ODD)].addr = ep0_rx1_buf;
table[index(0, TX, EVEN)].desc = 0;
table[index(0, TX, ODD)].desc = 0;
// activate endpoint 0
USB0_ENDPT0 = USB_ENDPT_EPRXEN | USB_ENDPT_EPTXEN | USB_ENDPT_EPHSHK;
f50: 4b16 ldr r3, [pc, #88] ; (fac <usb_isr+0x5a0>)
f52: 200d movs r0, #13
f54: 7018 strb r0, [r3, #0]
// clear all ending interrupts
USB0_ERRSTAT = 0xFF;
f56: 4828 ldr r0, [pc, #160] ; (ff8 <usb_isr+0x5ec>)
f58: 23ff movs r3, #255 ; 0xff
f5a: 7003 strb r3, [r0, #0]
USB0_ISTAT = 0xFF;
f5c: 702b strb r3, [r5, #0]
// set the address to zero during enumeration
USB0_ADDR = 0;
f5e: 7402 strb r2, [r0, #16]
// enable other interrupts
USB0_ERREN = 0xFF;
f60: 4a26 ldr r2, [pc, #152] ; (ffc <usb_isr+0x5f0>)
f62: 7013 strb r3, [r2, #0]
USB0_INTEN = USB_INTEN_TOKDNEEN |
f64: 4b26 ldr r3, [pc, #152] ; (1000 <usb_isr+0x5f4>)
f66: 229f movs r2, #159 ; 0x9f
f68: 701a strb r2, [r3, #0]
USB_INTEN_ERROREN |
USB_INTEN_USBRSTEN |
USB_INTEN_SLEEPEN;
// is this necessary?
USB0_CTL = USB_CTL_USBENSOFEN;
f6a: 2301 movs r3, #1
f6c: 700b strb r3, [r1, #0]
return;
f6e: e8bd 8ff8 ldmia.w sp!, {r3, r4, r5, r6, r7, r8, r9, sl, fp, pc}
}
if ((status & USB_ISTAT_STALL /* 80 */ )) {
f72: 0621 lsls r1, r4, #24
f74: d504 bpl.n f80 <usb_isr+0x574>
//serial_print("stall:\n");
USB0_ENDPT0 = USB_ENDPT_EPRXEN | USB_ENDPT_EPTXEN | USB_ENDPT_EPHSHK;
f76: 4b0d ldr r3, [pc, #52] ; (fac <usb_isr+0x5a0>)
f78: 220d movs r2, #13
f7a: 701a strb r2, [r3, #0]
USB0_ISTAT = USB_ISTAT_STALL;
f7c: 2380 movs r3, #128 ; 0x80
f7e: 702b strb r3, [r5, #0]
}
if ((status & USB_ISTAT_ERROR /* 02 */ )) {
f80: 07a2 lsls r2, r4, #30
f82: d505 bpl.n f90 <usb_isr+0x584>
uint8_t err = USB0_ERRSTAT;
f84: 4b1c ldr r3, [pc, #112] ; (ff8 <usb_isr+0x5ec>)
f86: 781a ldrb r2, [r3, #0]
f88: b2d2 uxtb r2, r2
USB0_ERRSTAT = err;
f8a: 701a strb r2, [r3, #0]
//serial_print("err:");
//serial_phex(err);
//serial_print("\n");
USB0_ISTAT = USB_ISTAT_ERROR;
f8c: 2302 movs r3, #2
f8e: 702b strb r3, [r5, #0]
}
if ((status & USB_ISTAT_SLEEP /* 10 */ )) {
f90: 06e3 lsls r3, r4, #27
//serial_print("sleep\n");
USB0_ISTAT = USB_ISTAT_SLEEP;
f92: bf44 itt mi
f94: 2310 movmi r3, #16
f96: 702b strbmi r3, [r5, #0]
f98: e8bd 8ff8 ldmia.w sp!, {r3, r4, r5, r6, r7, r8, r9, sl, fp, pc}
f9c: 00002be0 .word 0x00002be0
fa0: 1fffe664 .word 0x1fffe664
fa4: 1fffe934 .word 0x1fffe934
fa8: 1fffe758 .word 0x1fffe758
fac: 400720c0 .word 0x400720c0
fb0: 1fffe73c .word 0x1fffe73c
fb4: 40072094 .word 0x40072094
fb8: 1fffe734 .word 0x1fffe734
fbc: 1fffe92c .word 0x1fffe92c
fc0: 1fffe6d1 .word 0x1fffe6d1
fc4: 004000c8 .word 0x004000c8
fc8: 1fffe668 .word 0x1fffe668
fcc: 40072098 .word 0x40072098
fd0: 1fffe714 .word 0x1fffe714
fd4: 1fffe67c .word 0x1fffe67c
fd8: 1fffe66c .word 0x1fffe66c
fdc: 1fffe924 .word 0x1fffe924
fe0: 1fffe73e .word 0x1fffe73e
fe4: 00400088 .word 0x00400088
fe8: 1fffe680 .word 0x1fffe680
fec: 1fffe6d0 .word 0x1fffe6d0
ff0: 1fffe000 .word 0x1fffe000
ff4: 1fffe6d4 .word 0x1fffe6d4
ff8: 40072088 .word 0x40072088
ffc: 4007208c .word 0x4007208c
1000: 40072084 .word 0x40072084
1004: 1fffe6c0 .word 0x1fffe6c0
00001008 <usb_init>:
}
void usb_init(void)
{
1008: b508 push {r3, lr}
int i;
//serial_begin(BAUD2DIV(115200));
//serial_print("usb_init\n");
usb_init_serialnumber();
100a: f001 fb33 bl 2674 <usb_init_serialnumber>
100e: 2200 movs r2, #0
for (i=0; i <= NUM_ENDPOINTS*4; i++) {
table[i].desc = 0;
1010: 4b18 ldr r3, [pc, #96] ; (1074 <usb_init+0x6c>)
1012: 2100 movs r1, #0
1014: 50d1 str r1, [r2, r3]
1016: 1898 adds r0, r3, r2
1018: 3208 adds r2, #8
//serial_begin(BAUD2DIV(115200));
//serial_print("usb_init\n");
usb_init_serialnumber();
for (i=0; i <= NUM_ENDPOINTS*4; i++) {
101a: 2a88 cmp r2, #136 ; 0x88
table[i].desc = 0;
table[i].addr = 0;
101c: 6041 str r1, [r0, #4]
//serial_begin(BAUD2DIV(115200));
//serial_print("usb_init\n");
usb_init_serialnumber();
for (i=0; i <= NUM_ENDPOINTS*4; i++) {
101e: d1f7 bne.n 1010 <usb_init+0x8>
// this basically follows the flowchart in the Kinetis
// Quick Reference User Guide, Rev. 1, 03/2012, page 141
// assume 48 MHz clock already running
// SIM - enable clock
SIM_SCGC4 |= SIM_SCGC4_USBOTG;
1020: 4a15 ldr r2, [pc, #84] ; (1078 <usb_init+0x70>)
1022: 6810 ldr r0, [r2, #0]
1024: f440 2080 orr.w r0, r0, #262144 ; 0x40000
1028: 6010 str r0, [r2, #0]
// reset USB module
//USB0_USBTRC0 = USB_USBTRC_USBRESET;
//while ((USB0_USBTRC0 & USB_USBTRC_USBRESET) != 0) ; // wait for reset to end
// set desc table base addr
USB0_BDTPAGE1 = ((uint32_t)table) >> 8;
102a: f502 3228 add.w r2, r2, #172032 ; 0x2a000
102e: 3268 adds r2, #104 ; 0x68
1030: f3c3 2007 ubfx r0, r3, #8, #8
1034: 7010 strb r0, [r2, #0]
USB0_BDTPAGE2 = ((uint32_t)table) >> 16;
1036: f3c3 4007 ubfx r0, r3, #16, #8
USB0_BDTPAGE3 = ((uint32_t)table) >> 24;
103a: 0e1b lsrs r3, r3, #24
//USB0_USBTRC0 = USB_USBTRC_USBRESET;
//while ((USB0_USBTRC0 & USB_USBTRC_USBRESET) != 0) ; // wait for reset to end
// set desc table base addr
USB0_BDTPAGE1 = ((uint32_t)table) >> 8;
USB0_BDTPAGE2 = ((uint32_t)table) >> 16;
103c: 7510 strb r0, [r2, #20]
USB0_BDTPAGE3 = ((uint32_t)table) >>