Created
March 13, 2017 20:25
-
-
Save kriegsman/a0fe3dde20c5eb99610044b40bdabdbe to your computer and use it in GitHub Desktop.
Teensy30
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) >> |