Skip to content

Instantly share code, notes, and snippets.

@pingbird
Created October 20, 2016 06:19
Show Gist options
  • Select an option

  • Save pingbird/2730c75d2648a702fb44cfd147b4b5a2 to your computer and use it in GitHub Desktop.

Select an option

Save pingbird/2730c75d2648a702fb44cfd147b4b5a2 to your computer and use it in GitHub Desktop.
PROS dissasembly
This file has been truncated, but you can view the full file.
In archive libpros_sym.a:
API.o: file format elf32-littlearm
rw-r--r-- 1000/1000 25540 Oct 20 02:06 2016 API.o
architecture: arm, flags 0x00000011:
HAS_RELOC, HAS_SYMS
start address 0x00000000
private flags = 5000000: [Version5 EABI]
Sections:
Idx Name Size VMA LMA File off Algn
0 .text 00000000 00000000 00000000 00000034 2**1
CONTENTS, ALLOC, LOAD, READONLY, CODE
1 .data 00000000 00000000 00000000 00000034 2**0
CONTENTS, ALLOC, LOAD, DATA
2 .bss 00000000 00000000 00000000 00000034 2**0
ALLOC
3 .text._taskRunLoopHelper 00000038 00000000 00000000 00000034 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
4 .text.analogCalibrate 00000044 00000000 00000000 0000006c 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
5 .text.analogRead 00000014 00000000 00000000 000000b0 2**1
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
6 .text.analogReadCalibrated 0000002c 00000000 00000000 000000c4 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
7 .text.analogReadCalibratedHR 0000002c 00000000 00000000 000000f0 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
8 .text.delay 00000004 00000000 00000000 0000011c 2**1
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
9 .text.delayMicroseconds 0000003c 00000000 00000000 00000120 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
10 .text.digitalRead 0000002c 00000000 00000000 0000015c 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
11 .text.digitalWrite 0000002c 00000000 00000000 00000188 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
12 .text.isAutonomous 00000010 00000000 00000000 000001b4 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
13 .text.isEnabled 0000001c 00000000 00000000 000001c4 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
14 .text.isJoystickConnected 00000028 00000000 00000000 000001e0 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
15 .text.isOnline 00000010 00000000 00000000 00000208 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
16 .text.joystickGetAnalog 00000058 00000000 00000000 00000218 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
17 .text.joystickGetDigital 0000006c 00000000 00000000 00000270 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
18 .text.micros 00000004 00000000 00000000 000002dc 2**1
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
19 .text.millis 00000004 00000000 00000000 000002e0 2**1
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
20 .text.motorGet 0000000a 00000000 00000000 000002e4 2**1
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
21 .text.motorSet 0000002a 00000000 00000000 000002ee 2**1
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
22 .text.motorStop 00000006 00000000 00000000 00000318 2**1
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
23 .text.motorStopAll 00000004 00000000 00000000 0000031e 2**1
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
24 .text.pinMode 00000020 00000000 00000000 00000324 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
25 .text.powerLevelBackup 00000018 00000000 00000000 00000344 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
26 .text.powerLevelMain 00000018 00000000 00000000 0000035c 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
27 .text.setTeamName 0000002c 00000000 00000000 00000374 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
28 .text.taskRunLoop 00000028 00000000 00000000 000003a0 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
29 .text.wait 00000004 00000000 00000000 000003c8 2**1
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
30 .text.waitUntil 00000004 00000000 00000000 000003cc 2**1
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
31 .debug_info 00001086 00000000 00000000 000003d0 2**0
CONTENTS, RELOC, READONLY, DEBUGGING
32 .debug_abbrev 000003c6 00000000 00000000 00001456 2**0
CONTENTS, READONLY, DEBUGGING
33 .debug_loc 000007e3 00000000 00000000 0000181c 2**0
CONTENTS, RELOC, READONLY, DEBUGGING
34 .debug_aranges 000000f8 00000000 00000000 00001fff 2**0
CONTENTS, RELOC, READONLY, DEBUGGING
35 .debug_ranges 00000130 00000000 00000000 000020f7 2**0
CONTENTS, RELOC, READONLY, DEBUGGING
36 .debug_line 00000412 00000000 00000000 00002227 2**0
CONTENTS, RELOC, READONLY, DEBUGGING
37 .debug_str 00000748 00000000 00000000 00002639 2**0
CONTENTS, READONLY, DEBUGGING
38 .comment 00000039 00000000 00000000 00002d81 2**0
CONTENTS, READONLY
39 .debug_frame 00000260 00000000 00000000 00002dbc 2**2
CONTENTS, RELOC, READONLY, DEBUGGING
40 .ARM.attributes 00000033 00000000 00000000 0000301c 2**0
CONTENTS, READONLY
SYMBOL TABLE:
00000000 l df *ABS* 00000000 API.c
00000000 l d .text 00000000 .text
00000000 l d .data 00000000 .data
00000000 l d .bss 00000000 .bss
00000000 l d .text._taskRunLoopHelper 00000000 .text._taskRunLoopHelper
00000000 l F .text._taskRunLoopHelper 00000038 _taskRunLoopHelper
00000000 l d .text.analogCalibrate 00000000 .text.analogCalibrate
00000000 l d .text.analogRead 00000000 .text.analogRead
00000000 l d .text.analogReadCalibrated 00000000 .text.analogReadCalibrated
00000000 l d .text.analogReadCalibratedHR 00000000 .text.analogReadCalibratedHR
00000000 l d .text.delay 00000000 .text.delay
00000000 l d .text.delayMicroseconds 00000000 .text.delayMicroseconds
00000000 l d .text.digitalRead 00000000 .text.digitalRead
00000000 l d .text.digitalWrite 00000000 .text.digitalWrite
00000000 l d .text.isAutonomous 00000000 .text.isAutonomous
00000000 l d .text.isEnabled 00000000 .text.isEnabled
00000000 l d .text.isJoystickConnected 00000000 .text.isJoystickConnected
00000000 l d .text.isOnline 00000000 .text.isOnline
00000000 l d .text.joystickGetAnalog 00000000 .text.joystickGetAnalog
00000000 l d .text.joystickGetDigital 00000000 .text.joystickGetDigital
00000000 l d .text.micros 00000000 .text.micros
00000000 l d .text.millis 00000000 .text.millis
00000000 l d .text.motorGet 00000000 .text.motorGet
00000000 l d .text.motorSet 00000000 .text.motorSet
00000000 l d .text.motorStop 00000000 .text.motorStop
00000000 l d .text.motorStopAll 00000000 .text.motorStopAll
00000000 l d .text.pinMode 00000000 .text.pinMode
00000000 l d .text.powerLevelBackup 00000000 .text.powerLevelBackup
00000000 l d .text.powerLevelMain 00000000 .text.powerLevelMain
00000000 l d .text.setTeamName 00000000 .text.setTeamName
00000000 l d .text.taskRunLoop 00000000 .text.taskRunLoop
00000000 l d .text.wait 00000000 .text.wait
00000000 l d .text.waitUntil 00000000 .text.waitUntil
00000000 l d .debug_info 00000000 .debug_info
00000000 l d .debug_abbrev 00000000 .debug_abbrev
00000000 l d .debug_loc 00000000 .debug_loc
00000000 l d .debug_aranges 00000000 .debug_aranges
00000000 l d .debug_ranges 00000000 .debug_ranges
00000000 l d .debug_line 00000000 .debug_line
00000000 l d .debug_str 00000000 .debug_str
00000000 l d .debug_frame 00000000 .debug_frame
00000000 l d .comment 00000000 .comment
00000000 l d .ARM.attributes 00000000 .ARM.attributes
00000000 *UND* 00000000 free
00000000 *UND* 00000000 timeLowRes
00000000 *UND* 00000000 taskDelayUntil
00000000 *UND* 00000000 svFlags
00000000 g F .text.analogCalibrate 00000044 analogCalibrate
00000000 *UND* 00000000 adcRead
00000000 *UND* 00000000 taskDelay
00000000 *UND* 00000000 _analogState
00000000 g F .text.analogRead 00000014 analogRead
00000000 g F .text.analogReadCalibrated 0000002c analogReadCalibrated
00000000 g F .text.analogReadCalibratedHR 0000002c analogReadCalibratedHR
00000000 g F .text.delay 00000004 delay
00000000 g F .text.delayMicroseconds 0000003c delayMicroseconds
00000000 g F .text.digitalRead 0000002c digitalRead
00000000 *UND* 00000000 _pinLookupTable
00000000 *UND* 00000000 _pinIndexTable
00000000 g F .text.digitalWrite 0000002c digitalWrite
00000000 g F .text.isAutonomous 00000010 isAutonomous
00000000 g F .text.isEnabled 0000001c isEnabled
00000000 g F .text.isJoystickConnected 00000028 isJoystickConnected
00000000 *UND* 00000000 spiBufferRX
00000000 g F .text.isOnline 00000010 isOnline
00000000 g F .text.joystickGetAnalog 00000058 joystickGetAnalog
00000000 g F .text.joystickGetDigital 0000006c joystickGetDigital
00000000 g F .text.micros 00000004 micros
00000000 *UND* 00000000 timeHighRes
00000000 g F .text.millis 00000004 millis
00000000 g F .text.motorGet 0000000a motorGet
00000000 *UND* 00000000 motorControlGet
00000000 g F .text.motorSet 0000002a motorSet
00000000 *UND* 00000000 motorControlSet
00000000 g F .text.motorStop 00000006 motorStop
00000000 g F .text.motorStopAll 00000004 motorStopAll
00000000 *UND* 00000000 motorControlStop
00000000 g F .text.pinMode 00000020 pinMode
00000000 *UND* 00000000 ioSetDirection
00000000 g F .text.powerLevelBackup 00000018 powerLevelBackup
00000000 g F .text.powerLevelMain 00000018 powerLevelMain
00000000 g F .text.setTeamName 0000002c setTeamName
00000000 *UND* 00000000 svTeamName
00000000 g F .text.taskRunLoop 00000028 taskRunLoop
00000000 *UND* 00000000 malloc
00000000 *UND* 00000000 taskCreate
00000000 g F .text.wait 00000004 wait
00000000 g F .text.waitUntil 00000004 waitUntil
Disassembly of section .text._taskRunLoopHelper:
00000000 <_taskRunLoopHelper>:
void (*fn)(void);
clock_t period;
} LoopTask;
// Helper task for taskRunLoop()
static void _taskRunLoopHelper(void *data) {
0: b5f7 push {r0, r1, r2, r4, r5, r6, r7, lr}
// Extract information from pointer
LoopTask *info = (LoopTask*)data;
void (*fn)(void) = info->fn;
clock_t period = info->period;
2: e890 00c0 ldmia.w r0, {r6, r7}
// Avoid leaking data
free(data);
6: f7ff fffe bl 0 <free>
6: R_ARM_THM_CALL free
// Start counter
clock_t now = timeLowRes();
a: f7ff fffe bl 0 <timeLowRes>
a: R_ARM_THM_CALL timeLowRes
uint16_t sf = svFlags & (SV_AUTONOMOUS | SV_ENABLED | SV_FMS);
e: 4b09 ldr r3, [pc, #36] ; (34 <_taskRunLoopHelper+0x34>)
void (*fn)(void) = info->fn;
clock_t period = info->period;
// Avoid leaking data
free(data);
// Start counter
clock_t now = timeLowRes();
10: 9001 str r0, [sp, #4]
12: 461c mov r4, r3
uint16_t sf = svFlags & (SV_AUTONOMOUS | SV_ENABLED | SV_FMS);
14: 881d ldrh r5, [r3, #0]
16: f005 050e and.w r5, r5, #14
do {
fn();
1a: 47b0 blx r6
taskDelayUntil(&now, period);
1c: a801 add r0, sp, #4
1e: 4639 mov r1, r7
20: f7ff fffe bl 0 <taskDelayUntil>
20: R_ARM_THM_CALL taskDelayUntil
// Auto-terminate on mode switch, drop, or disable
} while ((svFlags & (SV_AUTONOMOUS | SV_ENABLED | SV_FMS)) == sf);
24: 8823 ldrh r3, [r4, #0]
26: f003 030e and.w r3, r3, #14
2a: 42ab cmp r3, r5
2c: d0f5 beq.n 1a <_taskRunLoopHelper+0x1a>
}
2e: b003 add sp, #12
30: bdf0 pop {r4, r5, r6, r7, pc}
32: bf00 nop
34: 00000000 andeq r0, r0, r0
34: R_ARM_ABS32 svFlags
Disassembly of section .text.analogCalibrate:
00000000 <analogCalibrate>:
void (*fn)(void);
clock_t period;
} LoopTask;
// Helper task for taskRunLoop()
static void _taskRunLoopHelper(void *data) {
0: 3801 subs r0, #1
// Extract information from pointer
LoopTask *info = (LoopTask*)data;
void (*fn)(void) = info->fn;
clock_t period = info->period;
2: b570 push {r4, r5, r6, lr}
4: b2c5 uxtb r5, r0
// Avoid leaking data
free(data);
6: 2d07 cmp r5, #7
8: d818 bhi.n 3c <analogCalibrate+0x3c>
// Start counter
clock_t now = timeLowRes();
a: f44f 7600 mov.w r6, #512 ; 0x200
uint16_t sf = svFlags & (SV_AUTONOMOUS | SV_ENABLED | SV_FMS);
e: 2400 movs r4, #0
void (*fn)(void) = info->fn;
clock_t period = info->period;
// Avoid leaking data
free(data);
// Start counter
clock_t now = timeLowRes();
10: 4628 mov r0, r5
12: f7ff fffe bl 0 <adcRead>
12: R_ARM_THM_CALL adcRead
uint16_t sf = svFlags & (SV_AUTONOMOUS | SV_ENABLED | SV_FMS);
16: 4404 add r4, r0
18: 2001 movs r0, #1
do {
fn();
1a: f7ff fffe bl 0 <taskDelay>
1a: R_ARM_THM_CALL taskDelay
taskDelayUntil(&now, period);
1e: 3e01 subs r6, #1
20: d1f6 bne.n 10 <analogCalibrate+0x10>
22: 4a07 ldr r2, [pc, #28] ; (40 <analogCalibrate+0x40>)
// Auto-terminate on mode switch, drop, or disable
} while ((svFlags & (SV_AUTONOMOUS | SV_ENABLED | SV_FMS)) == sf);
24: 200c movs r0, #12
26: fb00 2505 mla r5, r0, r5, r2
2a: f104 0310 add.w r3, r4, #16
}
2e: f3c3 134f ubfx r3, r3, #5, #16
32: f504 7080 add.w r0, r4, #256 ; 0x100
36: 80eb strh r3, [r5, #6]
// analogCalibrate - Calibrates the analog sensor on the specified channel, assuming that it is
// not actively changing. Approximately 512 samples are taken, 1 ms apart, for a 0.5 s period
// of calibration. The average value thus calculated is returned and stored for later calls
// to analogReadCalibrated()
int analogCalibrate(unsigned char channel) {
channel--;
38: 0a40 lsrs r0, r0, #9
// analogCalibrate - Calibrates the analog sensor on the specified channel, assuming that it is
// not actively changing. Approximately 512 samples are taken, 1 ms apart, for a 0.5 s period
// of calibration. The average value thus calculated is returned and stored for later calls
// to analogReadCalibrated()
int analogCalibrate(unsigned char channel) {
3a: bd70 pop {r4, r5, r6, pc}
channel--;
3c: 2000 movs r0, #0
if (channel < BOARD_NR_ADC_PINS) {
3e: bd70 pop {r4, r5, r6, pc}
40: 00000000 andeq r0, r0, r0
40: R_ARM_ABS32 _analogState
Disassembly of section .text.analogRead:
00000000 <analogRead>:
void (*fn)(void);
clock_t period;
} LoopTask;
// Helper task for taskRunLoop()
static void _taskRunLoopHelper(void *data) {
0: 3801 subs r0, #1
// Extract information from pointer
LoopTask *info = (LoopTask*)data;
void (*fn)(void) = info->fn;
clock_t period = info->period;
2: b2c0 uxtb r0, r0
4: 2807 cmp r0, #7
// Avoid leaking data
free(data);
6: b508 push {r3, lr}
8: d802 bhi.n 10 <analogRead+0x10>
// Start counter
clock_t now = timeLowRes();
a: f7ff fffe bl 0 <adcRead>
a: R_ARM_THM_CALL adcRead
uint16_t sf = svFlags & (SV_AUTONOMOUS | SV_ENABLED | SV_FMS);
e: bd08 pop {r3, pc}
void (*fn)(void) = info->fn;
clock_t period = info->period;
// Avoid leaking data
free(data);
// Start counter
clock_t now = timeLowRes();
10: 2000 movs r0, #0
12: bd08 pop {r3, pc}
Disassembly of section .text.analogReadCalibrated:
00000000 <analogReadCalibrated>:
void (*fn)(void);
clock_t period;
} LoopTask;
// Helper task for taskRunLoop()
static void _taskRunLoopHelper(void *data) {
0: 3801 subs r0, #1
// Extract information from pointer
LoopTask *info = (LoopTask*)data;
void (*fn)(void) = info->fn;
clock_t period = info->period;
2: b510 push {r4, lr}
4: b2c4 uxtb r4, r0
// Avoid leaking data
free(data);
6: 2c07 cmp r4, #7
8: d80b bhi.n 22 <analogReadCalibrated+0x22>
// Start counter
clock_t now = timeLowRes();
a: 4620 mov r0, r4
c: f7ff fffe bl 0 <adcRead>
c: R_ARM_THM_CALL adcRead
10: 4b05 ldr r3, [pc, #20] ; (28 <analogReadCalibrated+0x28>)
12: 220c movs r2, #12
uint16_t sf = svFlags & (SV_AUTONOMOUS | SV_ENABLED | SV_FMS);
14: fb02 3404 mla r4, r2, r4, r3
18: 88e3 ldrh r3, [r4, #6]
do {
fn();
1a: f3c3 130b ubfx r3, r3, #4, #12
taskDelayUntil(&now, period);
1e: 1ac0 subs r0, r0, r3
20: bd10 pop {r4, pc}
22: 2000 movs r0, #0
// Auto-terminate on mode switch, drop, or disable
} while ((svFlags & (SV_AUTONOMOUS | SV_ENABLED | SV_FMS)) == sf);
24: bd10 pop {r4, pc}
26: bf00 nop
28: 00000000 andeq r0, r0, r0
28: R_ARM_ABS32 _analogState
Disassembly of section .text.analogReadCalibratedHR:
00000000 <analogReadCalibratedHR>:
void (*fn)(void);
clock_t period;
} LoopTask;
// Helper task for taskRunLoop()
static void _taskRunLoopHelper(void *data) {
0: 3801 subs r0, #1
// Extract information from pointer
LoopTask *info = (LoopTask*)data;
void (*fn)(void) = info->fn;
clock_t period = info->period;
2: b510 push {r4, lr}
4: b2c4 uxtb r4, r0
// Avoid leaking data
free(data);
6: 2c07 cmp r4, #7
8: d80b bhi.n 22 <analogReadCalibratedHR+0x22>
// Start counter
clock_t now = timeLowRes();
a: 4620 mov r0, r4
c: f7ff fffe bl 0 <adcRead>
c: R_ARM_THM_CALL adcRead
10: 4b05 ldr r3, [pc, #20] ; (28 <analogReadCalibratedHR+0x28>)
12: 220c movs r2, #12
uint16_t sf = svFlags & (SV_AUTONOMOUS | SV_ENABLED | SV_FMS);
14: fb02 3404 mla r4, r2, r4, r3
18: 88e3 ldrh r3, [r4, #6]
do {
fn();
1a: b29b uxth r3, r3
taskDelayUntil(&now, period);
1c: ebc3 1000 rsb r0, r3, r0, lsl #4
20: bd10 pop {r4, pc}
22: 2000 movs r0, #0
// Auto-terminate on mode switch, drop, or disable
} while ((svFlags & (SV_AUTONOMOUS | SV_ENABLED | SV_FMS)) == sf);
24: bd10 pop {r4, pc}
26: bf00 nop
28: 00000000 andeq r0, r0, r0
28: R_ARM_ABS32 _analogState
Disassembly of section .text.delay:
00000000 <delay>:
void (*fn)(void);
clock_t period;
} LoopTask;
// Helper task for taskRunLoop()
static void _taskRunLoopHelper(void *data) {
0: f7ff bffe b.w 0 <taskDelay>
0: R_ARM_THM_JUMP24 taskDelay
Disassembly of section .text.delayMicroseconds:
00000000 <delayMicroseconds>:
0: b510 push {r4, lr}
// Extract information from pointer
LoopTask *info = (LoopTask*)data;
void (*fn)(void) = info->fn;
clock_t period = info->period;
2: 4603 mov r3, r0
4: b1b0 cbz r0, 34 <delayMicroseconds+0x34>
// Avoid leaking data
free(data);
6: f5b0 7f7a cmp.w r0, #1000 ; 0x3e8
// Start counter
clock_t now = timeLowRes();
a: d909 bls.n 20 <delayMicroseconds+0x20>
c: f44f 747a mov.w r4, #1000 ; 0x3e8
10: fbb0 f0f4 udiv r0, r0, r4
uint16_t sf = svFlags & (SV_AUTONOMOUS | SV_ENABLED | SV_FMS);
14: fb04 3410 mls r4, r4, r0, r3
18: f7ff fffe bl 0 <taskDelay>
18: R_ARM_THM_CALL taskDelay
do {
fn();
taskDelayUntil(&now, period);
1c: b154 cbz r4, 34 <delayMicroseconds+0x34>
1e: e000 b.n 22 <delayMicroseconds+0x22>
20: 4604 mov r4, r0
22: 4b05 ldr r3, [pc, #20] ; (38 <delayMicroseconds+0x38>)
// Auto-terminate on mode switch, drop, or disable
} while ((svFlags & (SV_AUTONOMOUS | SV_ENABLED | SV_FMS)) == sf);
24: 461a mov r2, r3
26: 8c99 ldrh r1, [r3, #36] ; 0x24
28: b289 uxth r1, r1
2a: 8c93 ldrh r3, [r2, #36] ; 0x24
2c: b29b uxth r3, r3
}
2e: 1a5b subs r3, r3, r1
30: 42a3 cmp r3, r4
32: d3fa bcc.n 2a <delayMicroseconds+0x2a>
34: bd10 pop {r4, pc}
36: bf00 nop
// analogCalibrate - Calibrates the analog sensor on the specified channel, assuming that it is
// not actively changing. Approximately 512 samples are taken, 1 ms apart, for a 0.5 s period
// of calibration. The average value thus calculated is returned and stored for later calls
// to analogReadCalibrated()
int analogCalibrate(unsigned char channel) {
channel--;
38: 40013400 andmi r3, r1, r0, lsl #8
Disassembly of section .text.digitalRead:
00000000 <digitalRead>:
void (*fn)(void);
clock_t period;
} LoopTask;
// Helper task for taskRunLoop()
static void _taskRunLoopHelper(void *data) {
0: 4603 mov r3, r0
// Extract information from pointer
LoopTask *info = (LoopTask*)data;
void (*fn)(void) = info->fn;
clock_t period = info->period;
2: 281a cmp r0, #26
4: bf9f itttt ls
// Avoid leaking data
free(data);
6: 4a07 ldrls r2, [pc, #28] ; (24 <digitalRead+0x24>)
8: f852 2020 ldrls.w r2, [r2, r0, lsl #2]
// Start counter
clock_t now = timeLowRes();
c: 6890 ldrls r0, [r2, #8]
uint16_t sf = svFlags & (SV_AUTONOMOUS | SV_ENABLED | SV_FMS);
e: 4a06 ldrls r2, [pc, #24] ; (28 <digitalRead+0x28>)
void (*fn)(void) = info->fn;
clock_t period = info->period;
// Avoid leaking data
free(data);
// Start counter
clock_t now = timeLowRes();
10: bf9f itttt ls
12: 5cd3 ldrbls r3, [r2, r3]
uint16_t sf = svFlags & (SV_AUTONOMOUS | SV_ENABLED | SV_FMS);
14: f003 030f andls.w r3, r3, #15
18: 40d8 lsrls r0, r3
do {
fn();
1a: f000 0001 andls.w r0, r0, #1
taskDelayUntil(&now, period);
1e: bf88 it hi
20: 2000 movhi r0, #0
22: 4770 bx lr
...
24: R_ARM_ABS32 _pinLookupTable
28: R_ARM_ABS32 _pinIndexTable
Disassembly of section .text.digitalWrite:
00000000 <digitalWrite>:
void (*fn)(void);
clock_t period;
} LoopTask;
// Helper task for taskRunLoop()
static void _taskRunLoopHelper(void *data) {
0: 281a cmp r0, #26
// Extract information from pointer
LoopTask *info = (LoopTask*)data;
void (*fn)(void) = info->fn;
clock_t period = info->period;
2: b510 push {r4, lr}
4: d80c bhi.n 20 <digitalWrite+0x20>
// Avoid leaking data
free(data);
6: 4b07 ldr r3, [pc, #28] ; (24 <digitalWrite+0x24>)
8: f853 4020 ldr.w r4, [r3, r0, lsl #2]
// Start counter
clock_t now = timeLowRes();
c: 4b06 ldr r3, [pc, #24] ; (28 <digitalWrite+0x28>)
uint16_t sf = svFlags & (SV_AUTONOMOUS | SV_ENABLED | SV_FMS);
e: 5c1a ldrb r2, [r3, r0]
void (*fn)(void) = info->fn;
clock_t period = info->period;
// Avoid leaking data
free(data);
// Start counter
clock_t now = timeLowRes();
10: 2301 movs r3, #1
12: f002 020f and.w r2, r2, #15
uint16_t sf = svFlags & (SV_AUTONOMOUS | SV_ENABLED | SV_FMS);
16: 4093 lsls r3, r2
18: b109 cbz r1, 1e <digitalWrite+0x1e>
do {
fn();
1a: 6123 str r3, [r4, #16]
taskDelayUntil(&now, period);
1c: bd10 pop {r4, pc}
1e: 6163 str r3, [r4, #20]
20: bd10 pop {r4, pc}
22: bf00 nop
...
24: R_ARM_ABS32 _pinLookupTable
28: R_ARM_ABS32 _pinIndexTable
Disassembly of section .text.isAutonomous:
00000000 <isAutonomous>:
void (*fn)(void);
clock_t period;
} LoopTask;
// Helper task for taskRunLoop()
static void _taskRunLoopHelper(void *data) {
0: 4b02 ldr r3, [pc, #8] ; (c <isAutonomous+0xc>)
// Extract information from pointer
LoopTask *info = (LoopTask*)data;
void (*fn)(void) = info->fn;
clock_t period = info->period;
2: 8818 ldrh r0, [r3, #0]
4: f3c0 0080 ubfx r0, r0, #2, #1
// Avoid leaking data
free(data);
8: 4770 bx lr
// Start counter
clock_t now = timeLowRes();
a: bf00 nop
c: 00000000 andeq r0, r0, r0
c: R_ARM_ABS32 svFlags
Disassembly of section .text.isEnabled:
00000000 <isEnabled>:
void (*fn)(void);
clock_t period;
} LoopTask;
// Helper task for taskRunLoop()
static void _taskRunLoopHelper(void *data) {
0: 4b05 ldr r3, [pc, #20] ; (18 <isEnabled+0x18>)
// Extract information from pointer
LoopTask *info = (LoopTask*)data;
void (*fn)(void) = info->fn;
clock_t period = info->period;
2: 8818 ldrh r0, [r3, #0]
4: b280 uxth r0, r0
// Avoid leaking data
free(data);
6: 0783 lsls r3, r0, #30
8: bf5a itte pl
// Start counter
clock_t now = timeLowRes();
a: f080 0008 eorpl.w r0, r0, #8
uint16_t sf = svFlags & (SV_AUTONOMOUS | SV_ENABLED | SV_FMS);
e: f3c0 00c0 ubfxpl r0, r0, #3, #1
void (*fn)(void) = info->fn;
clock_t period = info->period;
// Avoid leaking data
free(data);
// Start counter
clock_t now = timeLowRes();
12: 2001 movmi r0, #1
uint16_t sf = svFlags & (SV_AUTONOMOUS | SV_ENABLED | SV_FMS);
14: 4770 bx lr
16: bf00 nop
18: 00000000 andeq r0, r0, r0
18: R_ARM_ABS32 svFlags
Disassembly of section .text.isJoystickConnected:
00000000 <isJoystickConnected>:
void (*fn)(void);
clock_t period;
} LoopTask;
// Helper task for taskRunLoop()
static void _taskRunLoopHelper(void *data) {
0: 3801 subs r0, #1
// Extract information from pointer
LoopTask *info = (LoopTask*)data;
void (*fn)(void) = info->fn;
clock_t period = info->period;
2: 4a08 ldr r2, [pc, #32] ; (24 <isJoystickConnected+0x24>)
4: f000 0301 and.w r3, r0, #1
// Avoid leaking data
free(data);
8: 200c movs r0, #12
// Start counter
clock_t now = timeLowRes();
a: fb00 2003 mla r0, r0, r3, r2
uint16_t sf = svFlags & (SV_AUTONOMOUS | SV_ENABLED | SV_FMS);
e: 7a83 ldrb r3, [r0, #10]
void (*fn)(void) = info->fn;
clock_t period = info->period;
// Avoid leaking data
free(data);
// Start counter
clock_t now = timeLowRes();
10: 2b7f cmp r3, #127 ; 0x7f
12: d105 bne.n 20 <isJoystickConnected+0x20>
uint16_t sf = svFlags & (SV_AUTONOMOUS | SV_ENABLED | SV_FMS);
14: 3005 adds r0, #5
16: 7980 ldrb r0, [r0, #6]
18: 387f subs r0, #127 ; 0x7f
do {
fn();
1a: bf18 it ne
taskDelayUntil(&now, period);
1c: 2001 movne r0, #1
1e: 4770 bx lr
20: 2001 movs r0, #1
22: 4770 bx lr
// Auto-terminate on mode switch, drop, or disable
} while ((svFlags & (SV_AUTONOMOUS | SV_ENABLED | SV_FMS)) == sf);
24: 00000000 andeq r0, r0, r0
24: R_ARM_ABS32 spiBufferRX
Disassembly of section .text.isOnline:
00000000 <isOnline>:
void (*fn)(void);
clock_t period;
} LoopTask;
// Helper task for taskRunLoop()
static void _taskRunLoopHelper(void *data) {
0: 4b02 ldr r3, [pc, #8] ; (c <isOnline+0xc>)
// Extract information from pointer
LoopTask *info = (LoopTask*)data;
void (*fn)(void) = info->fn;
clock_t period = info->period;
2: 8818 ldrh r0, [r3, #0]
4: f3c0 00c0 ubfx r0, r0, #3, #1
// Avoid leaking data
free(data);
8: 4770 bx lr
// Start counter
clock_t now = timeLowRes();
a: bf00 nop
c: 00000000 andeq r0, r0, r0
c: R_ARM_ABS32 svFlags
Disassembly of section .text.joystickGetAnalog:
00000000 <joystickGetAnalog>:
void (*fn)(void);
clock_t period;
} LoopTask;
// Helper task for taskRunLoop()
static void _taskRunLoopHelper(void *data) {
0: b538 push {r3, r4, r5, lr}
// Extract information from pointer
LoopTask *info = (LoopTask*)data;
void (*fn)(void) = info->fn;
clock_t period = info->period;
2: 4604 mov r4, r0
4: 460d mov r5, r1
// Avoid leaking data
free(data);
6: f7ff fffe bl 0 <joystickGetAnalog>
6: R_ARM_THM_CALL isOnline
// Start counter
clock_t now = timeLowRes();
a: b9d8 cbnz r0, 44 <joystickGetAnalog+0x44>
c: 1e69 subs r1, r5, #1
uint16_t sf = svFlags & (SV_AUTONOMOUS | SV_ENABLED | SV_FMS);
e: 2206 movs r2, #6
void (*fn)(void) = info->fn;
clock_t period = info->period;
// Avoid leaking data
free(data);
// Start counter
clock_t now = timeLowRes();
10: fb91 f3f2 sdiv r3, r1, r2
uint16_t sf = svFlags & (SV_AUTONOMOUS | SV_ENABLED | SV_FMS);
14: fb02 1113 mls r1, r2, r3, r1
18: 3c01 subs r4, #1
do {
fn();
1a: b2c9 uxtb r1, r1
taskDelayUntil(&now, period);
1c: 230c movs r3, #12
1e: f004 0401 and.w r4, r4, #1
22: fb03 1404 mla r4, r3, r4, r1
// Auto-terminate on mode switch, drop, or disable
} while ((svFlags & (SV_AUTONOMOUS | SV_ENABLED | SV_FMS)) == sf);
26: 4b0b ldr r3, [pc, #44] ; (54 <joystickGetAnalog+0x54>)
28: 3901 subs r1, #1
2a: 441c add r4, r3
2c: 79a0 ldrb r0, [r4, #6]
}
2e: 28ff cmp r0, #255 ; 0xff
30: bf08 it eq
32: 20fe moveq r0, #254 ; 0xfe
34: 2901 cmp r1, #1
36: f1a0 007f sub.w r0, r0, #127 ; 0x7f
// analogCalibrate - Calibrates the analog sensor on the specified channel, assuming that it is
// not actively changing. Approximately 512 samples are taken, 1 ms apart, for a 0.5 s period
// of calibration. The average value thus calculated is returned and stored for later calls
// to analogReadCalibrated()
int analogCalibrate(unsigned char channel) {
3a: b2c0 uxtb r0, r0
channel--;
3c: d808 bhi.n 50 <joystickGetAnalog+0x50>
if (channel < BOARD_NR_ADC_PINS) {
3e: 4240 negs r0, r0
40: b2c0 uxtb r0, r0
42: e005 b.n 50 <joystickGetAnalog+0x50>
44: f7ff fffe bl 0 <joystickGetAnalog>
44: R_ARM_THM_CALL isAutonomous
// We have the true channel, do this in a loop
uint32_t total = 0, i;
for (i = 0; i < 512; i++) {
total += adcRead(channel);
48: 2800 cmp r0, #0
4a: d0df beq.n c <joystickGetAnalog+0xc>
4c: 2000 movs r0, #0
4e: bd38 pop {r3, r4, r5, pc}
taskDelay(1);
50: b240 sxtb r0, r0
52: bd38 pop {r3, r4, r5, pc}
54: 00000000 andeq r0, r0, r0
54: R_ARM_ABS32 spiBufferRX
Disassembly of section .text.joystickGetDigital:
00000000 <joystickGetDigital>:
void (*fn)(void);
clock_t period;
} LoopTask;
// Helper task for taskRunLoop()
static void _taskRunLoopHelper(void *data) {
0: b570 push {r4, r5, r6, lr}
// Extract information from pointer
LoopTask *info = (LoopTask*)data;
void (*fn)(void) = info->fn;
clock_t period = info->period;
2: 4605 mov r5, r0
4: 460e mov r6, r1
// Avoid leaking data
free(data);
6: 4614 mov r4, r2
8: f7ff fffe bl 0 <joystickGetDigital>
8: R_ARM_THM_CALL isOnline
// Start counter
clock_t now = timeLowRes();
c: b988 cbnz r0, 32 <joystickGetDigital+0x32>
uint16_t sf = svFlags & (SV_AUTONOMOUS | SV_ENABLED | SV_FMS);
e: 1f71 subs r1, r6, #5
void (*fn)(void) = info->fn;
clock_t period = info->period;
// Avoid leaking data
free(data);
// Start counter
clock_t now = timeLowRes();
10: 3d01 subs r5, #1
12: 4b15 ldr r3, [pc, #84] ; (68 <joystickGetDigital+0x68>)
uint16_t sf = svFlags & (SV_AUTONOMOUS | SV_ENABLED | SV_FMS);
14: f001 0103 and.w r1, r1, #3
18: f005 0501 and.w r5, r5, #1
do {
fn();
taskDelayUntil(&now, period);
1c: 200c movs r0, #12
1e: 2901 cmp r1, #1
20: fb00 3005 mla r0, r0, r5, r3
// Auto-terminate on mode switch, drop, or disable
} while ((svFlags & (SV_AUTONOMOUS | SV_ENABLED | SV_FMS)) == sf);
24: d00e beq.n 44 <joystickGetDigital+0x44>
26: d30a bcc.n 3e <joystickGetDigital+0x3e>
28: 2902 cmp r1, #2
2a: d114 bne.n 56 <joystickGetDigital+0x56>
2c: 7a03 ldrb r3, [r0, #8]
}
2e: 091b lsrs r3, r3, #4
30: e014 b.n 5c <joystickGetDigital+0x5c>
32: f7ff fffe bl 0 <joystickGetDigital>
32: R_ARM_THM_CALL isAutonomous
36: 2800 cmp r0, #0
// analogCalibrate - Calibrates the analog sensor on the specified channel, assuming that it is
// not actively changing. Approximately 512 samples are taken, 1 ms apart, for a 0.5 s period
// of calibration. The average value thus calculated is returned and stored for later calls
// to analogReadCalibrated()
int analogCalibrate(unsigned char channel) {
channel--;
38: d0e9 beq.n e <joystickGetDigital+0xe>
// analogCalibrate - Calibrates the analog sensor on the specified channel, assuming that it is
// not actively changing. Approximately 512 samples are taken, 1 ms apart, for a 0.5 s period
// of calibration. The average value thus calculated is returned and stored for later calls
// to analogReadCalibrated()
int analogCalibrate(unsigned char channel) {
3a: 2000 movs r0, #0
channel--;
3c: bd70 pop {r4, r5, r6, pc}
if (channel < BOARD_NR_ADC_PINS) {
3e: 79c2 ldrb r2, [r0, #7]
40: b2d2 uxtb r2, r2
42: e001 b.n 48 <joystickGetDigital+0x48>
44: 79c2 ldrb r2, [r0, #7]
46: 0892 lsrs r2, r2, #2
// We have the true channel, do this in a loop
uint32_t total = 0, i;
for (i = 0; i < 512; i++) {
total += adcRead(channel);
48: f002 0302 and.w r3, r2, #2
4c: f002 0201 and.w r2, r2, #1
taskDelay(1);
50: ea42 0343 orr.w r3, r2, r3, lsl #1
54: e002 b.n 5c <joystickGetDigital+0x5c>
int analogCalibrate(unsigned char channel) {
channel--;
if (channel < BOARD_NR_ADC_PINS) {
// We have the true channel, do this in a loop
uint32_t total = 0, i;
for (i = 0; i < 512; i++) {
56: 7a03 ldrb r3, [r0, #8]
58: f003 030f and.w r3, r3, #15
total += adcRead(channel);
taskDelay(1);
}
// Store value (fixed to correctly round to nearest to avoid positive bias)
_analogState[channel].calibValue = (total + 16) >> 5;
5c: 4223 tst r3, r4
5e: bf14 ite ne
60: 2001 movne r0, #1
62: 2000 moveq r0, #0
64: bd70 pop {r4, r5, r6, pc}
66: bf00 nop
68: 00000006 andeq r0, r0, r6
68: R_ARM_ABS32 spiBufferRX
Disassembly of section .text.micros:
00000000 <micros>:
void (*fn)(void);
clock_t period;
} LoopTask;
// Helper task for taskRunLoop()
static void _taskRunLoopHelper(void *data) {
0: f7ff bffe b.w 0 <timeHighRes>
0: R_ARM_THM_JUMP24 timeHighRes
Disassembly of section .text.millis:
00000000 <millis>:
0: f7ff bffe b.w 0 <timeLowRes>
0: R_ARM_THM_JUMP24 timeLowRes
Disassembly of section .text.motorGet:
00000000 <motorGet>:
0: b508 push {r3, lr}
// Extract information from pointer
LoopTask *info = (LoopTask*)data;
void (*fn)(void) = info->fn;
clock_t period = info->period;
2: f7ff fffe bl 0 <motorControlGet>
2: R_ARM_THM_CALL motorControlGet
// Avoid leaking data
free(data);
6: 387f subs r0, #127 ; 0x7f
8: bd08 pop {r3, pc}
Disassembly of section .text.motorSet:
00000000 <motorSet>:
void (*fn)(void);
clock_t period;
} LoopTask;
// Helper task for taskRunLoop()
static void _taskRunLoopHelper(void *data) {
0: b538 push {r3, r4, r5, lr}
// Extract information from pointer
LoopTask *info = (LoopTask*)data;
void (*fn)(void) = info->fn;
clock_t period = info->period;
2: 4605 mov r5, r0
4: 460c mov r4, r1
// Avoid leaking data
free(data);
6: f7ff fffe bl 0 <motorSet>
6: R_ARM_THM_CALL isEnabled
// Start counter
clock_t now = timeLowRes();
a: b168 cbz r0, 28 <motorSet+0x28>
c: f114 017f adds.w r1, r4, #127 ; 0x7f
10: d403 bmi.n 1a <motorSet+0x1a>
12: 29ff cmp r1, #255 ; 0xff
uint16_t sf = svFlags & (SV_AUTONOMOUS | SV_ENABLED | SV_FMS);
14: bfa8 it ge
16: 21ff movge r1, #255 ; 0xff
18: e000 b.n 1c <motorSet+0x1c>
do {
fn();
1a: 2100 movs r1, #0
taskDelayUntil(&now, period);
1c: 4628 mov r0, r5
1e: e8bd 4038 ldmia.w sp!, {r3, r4, r5, lr}
22: b2c9 uxtb r1, r1
// Auto-terminate on mode switch, drop, or disable
} while ((svFlags & (SV_AUTONOMOUS | SV_ENABLED | SV_FMS)) == sf);
24: f7ff bffe b.w 0 <motorControlSet>
24: R_ARM_THM_JUMP24 motorControlSet
28: bd38 pop {r3, r4, r5, pc}
Disassembly of section .text.motorStop:
00000000 <motorStop>:
void (*fn)(void);
clock_t period;
} LoopTask;
// Helper task for taskRunLoop()
static void _taskRunLoopHelper(void *data) {
0: 217f movs r1, #127 ; 0x7f
// Extract information from pointer
LoopTask *info = (LoopTask*)data;
void (*fn)(void) = info->fn;
clock_t period = info->period;
2: f7ff bffe b.w 0 <motorControlSet>
2: R_ARM_THM_JUMP24 motorControlSet
Disassembly of section .text.motorStopAll:
00000000 <motorStopAll>:
void (*fn)(void);
clock_t period;
} LoopTask;
// Helper task for taskRunLoop()
static void _taskRunLoopHelper(void *data) {
0: f7ff bffe b.w 0 <motorControlStop>
0: R_ARM_THM_JUMP24 motorControlStop
Disassembly of section .text.pinMode:
00000000 <pinMode>:
0: 281a cmp r0, #26
// Extract information from pointer
LoopTask *info = (LoopTask*)data;
void (*fn)(void) = info->fn;
clock_t period = info->period;
2: 4603 mov r3, r0
4: 460a mov r2, r1
// Avoid leaking data
free(data);
6: d806 bhi.n 16 <pinMode+0x16>
8: 4903 ldr r1, [pc, #12] ; (18 <pinMode+0x18>)
// Start counter
clock_t now = timeLowRes();
a: f851 0020 ldr.w r0, [r1, r0, lsl #2]
uint16_t sf = svFlags & (SV_AUTONOMOUS | SV_ENABLED | SV_FMS);
e: 4903 ldr r1, [pc, #12] ; (1c <pinMode+0x1c>)
void (*fn)(void) = info->fn;
clock_t period = info->period;
// Avoid leaking data
free(data);
// Start counter
clock_t now = timeLowRes();
10: 5cc9 ldrb r1, [r1, r3]
12: f7ff bffe b.w 0 <ioSetDirection>
12: R_ARM_THM_JUMP24 ioSetDirection
uint16_t sf = svFlags & (SV_AUTONOMOUS | SV_ENABLED | SV_FMS);
16: 4770 bx lr
...
18: R_ARM_ABS32 _pinLookupTable
1c: R_ARM_ABS32 _pinIndexTable
Disassembly of section .text.powerLevelBackup:
00000000 <powerLevelBackup>:
void (*fn)(void);
clock_t period;
} LoopTask;
// Helper task for taskRunLoop()
static void _taskRunLoopHelper(void *data) {
0: 4b04 ldr r3, [pc, #16] ; (14 <powerLevelBackup+0x14>)
// Extract information from pointer
LoopTask *info = (LoopTask*)data;
void (*fn)(void) = info->fn;
clock_t period = info->period;
2: 7958 ldrb r0, [r3, #5]
4: 233b movs r3, #59 ; 0x3b
// Avoid leaking data
free(data);
6: 4358 muls r0, r3
8: f5b0 7f7a cmp.w r0, #1000 ; 0x3e8
// Start counter
clock_t now = timeLowRes();
c: bf38 it cc
uint16_t sf = svFlags & (SV_AUTONOMOUS | SV_ENABLED | SV_FMS);
e: 2000 movcc r0, #0
void (*fn)(void) = info->fn;
clock_t period = info->period;
// Avoid leaking data
free(data);
// Start counter
clock_t now = timeLowRes();
10: 4770 bx lr
12: bf00 nop
uint16_t sf = svFlags & (SV_AUTONOMOUS | SV_ENABLED | SV_FMS);
14: 00000000 andeq r0, r0, r0
14: R_ARM_ABS32 spiBufferRX
Disassembly of section .text.powerLevelMain:
00000000 <powerLevelMain>:
void (*fn)(void);
clock_t period;
} LoopTask;
// Helper task for taskRunLoop()
static void _taskRunLoopHelper(void *data) {
0: 4b04 ldr r3, [pc, #16] ; (14 <powerLevelMain+0x14>)
// Extract information from pointer
LoopTask *info = (LoopTask*)data;
void (*fn)(void) = info->fn;
clock_t period = info->period;
2: 7918 ldrb r0, [r3, #4]
4: 233b movs r3, #59 ; 0x3b
// Avoid leaking data
free(data);
6: 4358 muls r0, r3
8: f5b0 7f7a cmp.w r0, #1000 ; 0x3e8
// Start counter
clock_t now = timeLowRes();
c: bf38 it cc
uint16_t sf = svFlags & (SV_AUTONOMOUS | SV_ENABLED | SV_FMS);
e: 2000 movcc r0, #0
void (*fn)(void) = info->fn;
clock_t period = info->period;
// Avoid leaking data
free(data);
// Start counter
clock_t now = timeLowRes();
10: 4770 bx lr
12: bf00 nop
uint16_t sf = svFlags & (SV_AUTONOMOUS | SV_ENABLED | SV_FMS);
14: 00000000 andeq r0, r0, r0
14: R_ARM_ABS32 spiBufferRX
Disassembly of section .text.setTeamName:
00000000 <setTeamName>:
void (*fn)(void);
clock_t period;
} LoopTask;
// Helper task for taskRunLoop()
static void _taskRunLoopHelper(void *data) {
0: 2200 movs r2, #0
// Extract information from pointer
LoopTask *info = (LoopTask*)data;
void (*fn)(void) = info->fn;
clock_t period = info->period;
2: 5c81 ldrb r1, [r0, r2]
4: b2d3 uxtb r3, r2
// Avoid leaking data
free(data);
6: b129 cbz r1, 14 <setTeamName+0x14>
8: 4b07 ldr r3, [pc, #28] ; (28 <setTeamName+0x28>)
// Start counter
clock_t now = timeLowRes();
a: 54d1 strb r1, [r2, r3]
c: 3201 adds r2, #1
uint16_t sf = svFlags & (SV_AUTONOMOUS | SV_ENABLED | SV_FMS);
e: 2a08 cmp r2, #8
void (*fn)(void) = info->fn;
clock_t period = info->period;
// Avoid leaking data
free(data);
// Start counter
clock_t now = timeLowRes();
10: d1f7 bne.n 2 <setTeamName+0x2>
12: 4613 mov r3, r2
uint16_t sf = svFlags & (SV_AUTONOMOUS | SV_ENABLED | SV_FMS);
14: 2b07 cmp r3, #7
16: d805 bhi.n 24 <setTeamName+0x24>
18: 4a03 ldr r2, [pc, #12] ; (28 <setTeamName+0x28>)
do {
fn();
1a: 2120 movs r1, #32
taskDelayUntil(&now, period);
1c: 54d1 strb r1, [r2, r3]
1e: 3301 adds r3, #1
20: b2db uxtb r3, r3
22: e7f7 b.n 14 <setTeamName+0x14>
// Auto-terminate on mode switch, drop, or disable
} while ((svFlags & (SV_AUTONOMOUS | SV_ENABLED | SV_FMS)) == sf);
24: 4770 bx lr
26: bf00 nop
28: 00000000 andeq r0, r0, r0
28: R_ARM_ABS32 svTeamName
Disassembly of section .text.taskRunLoop:
00000000 <taskRunLoop>:
void (*fn)(void);
clock_t period;
} LoopTask;
// Helper task for taskRunLoop()
static void _taskRunLoopHelper(void *data) {
0: b570 push {r4, r5, r6, lr}
// Extract information from pointer
LoopTask *info = (LoopTask*)data;
void (*fn)(void) = info->fn;
clock_t period = info->period;
2: 4605 mov r5, r0
4: 2008 movs r0, #8
// Avoid leaking data
free(data);
6: 460c mov r4, r1
8: f7ff fffe bl 0 <malloc>
8: R_ARM_THM_CALL malloc
// Start counter
clock_t now = timeLowRes();
c: f44f 7100 mov.w r1, #512 ; 0x200
10: 6005 str r5, [r0, #0]
12: 6044 str r4, [r0, #4]
uint16_t sf = svFlags & (SV_AUTONOMOUS | SV_ENABLED | SV_FMS);
14: 4602 mov r2, r0
16: e8bd 4070 ldmia.w sp!, {r4, r5, r6, lr}
do {
fn();
1a: 4802 ldr r0, [pc, #8] ; (24 <taskRunLoop+0x24>)
taskDelayUntil(&now, period);
1c: 2303 movs r3, #3
1e: f7ff bffe b.w 0 <taskCreate>
1e: R_ARM_THM_JUMP24 taskCreate
22: bf00 nop
// Auto-terminate on mode switch, drop, or disable
} while ((svFlags & (SV_AUTONOMOUS | SV_ENABLED | SV_FMS)) == sf);
24: 00000000 andeq r0, r0, r0
24: R_ARM_ABS32 _taskRunLoopHelper
Disassembly of section .text.wait:
00000000 <wait>:
void (*fn)(void);
clock_t period;
} LoopTask;
// Helper task for taskRunLoop()
static void _taskRunLoopHelper(void *data) {
0: f7ff bffe b.w 0 <taskDelay>
0: R_ARM_THM_JUMP24 taskDelay
Disassembly of section .text.waitUntil:
00000000 <waitUntil>:
0: f7ff bffe b.w 0 <taskDelayUntil>
0: R_ARM_THM_JUMP24 taskDelayUntil
Disassembly of section .debug_info:
00000000 <.debug_info>:
0: 00001082 andeq r1, r0, r2, lsl #1
// Extract information from pointer
LoopTask *info = (LoopTask*)data;
void (*fn)(void) = info->fn;
clock_t period = info->period;
4: 00000004 andeq r0, r0, r4
6: R_ARM_ABS32 .debug_abbrev
// Avoid leaking data
free(data);
8: 01040000 mrseq r0, (UNDEF: 4)
// Start counter
clock_t now = timeLowRes();
c: 0000056a andeq r0, r0, sl, ror #10
c: R_ARM_ABS32 .debug_str
10: 00037801 andeq r7, r3, r1, lsl #16
11: R_ARM_ABS32 .debug_str
uint16_t sf = svFlags & (SV_AUTONOMOUS | SV_ENABLED | SV_FMS);
14: 0002a900 andeq sl, r2, r0, lsl #18
15: R_ARM_ABS32 .debug_str
18: 00004800 andeq r4, r0, r0, lsl #16
19: R_ARM_ABS32 .debug_ranges
...
21: R_ARM_ABS32 .debug_line
do {
fn();
taskDelayUntil(&now, period);
// Auto-terminate on mode switch, drop, or disable
} while ((svFlags & (SV_AUTONOMOUS | SV_ENABLED | SV_FMS)) == sf);
24: 07040200 streq r0, [r4, -r0, lsl #4]
28: 0000007c andeq r0, r0, ip, ror r0
28: R_ARM_ABS32 .debug_str
2c: 0003bc03 andeq fp, r3, r3, lsl #24
2d: R_ARM_ABS32 .debug_str
}
30: 371b0400 ldrcc r0, [fp, -r0, lsl #8]
34: 02000000 andeq r0, r0, #0
// analogCalibrate - Calibrates the analog sensor on the specified channel, assuming that it is
// not actively changing. Approximately 512 samples are taken, 1 ms apart, for a 0.5 s period
// of calibration. The average value thus calculated is returned and stored for later calls
// to analogReadCalibrated()
int analogCalibrate(unsigned char channel) {
channel--;
38: 06c70601 strbeq r0, [r7], r1, lsl #12
3a: R_ARM_ABS32 .debug_str
3c: d5030000 strle r0, [r3, #-0]
3f: R_ARM_ABS32 .debug_str
if (channel < BOARD_NR_ADC_PINS) {
40: 04000004 streq r0, [r0], #-4
44: 0000491d andeq r4, r0, sp, lsl r9
// We have the true channel, do this in a loop
uint32_t total = 0, i;
for (i = 0; i < 512; i++) {
total += adcRead(channel);
48: 08010200 stmdaeq r1, {r9}
4c: 00000551 andeq r0, r0, r1, asr r5
4c: R_ARM_ABS32 .debug_str
taskDelay(1);
50: 54050202 strpl r0, [r5], #-514 ; 0xfffffdfe
53: R_ARM_ABS32 .debug_str
54: 03000004 movweq r0, #4
int analogCalibrate(unsigned char channel) {
channel--;
if (channel < BOARD_NR_ADC_PINS) {
// We have the true channel, do this in a loop
uint32_t total = 0, i;
for (i = 0; i < 512; i++) {
58: 000001cc andeq r0, r0, ip, asr #3
58: R_ARM_ABS32 .debug_str
total += adcRead(channel);
taskDelay(1);
}
// Store value (fixed to correctly round to nearest to avoid positive bias)
_analogState[channel].calibValue = (total + 16) >> 5;
5c: 00622b04 rsbeq r2, r2, r4, lsl #22
60: 02020000 andeq r0, r2, #0
64: 0006e307 andeq lr, r6, r7, lsl #6
65: R_ARM_ABS32 .debug_str
68: 00910300 addseq r0, r1, r0, lsl #6
6a: R_ARM_ABS32 .debug_str
return (int)((total + 256) >> 9);
6c: 3f040000 svccc 0x00040000
70: 00000074 andeq r0, r0, r4, ror r0
}
return 0;
74: 72050402 andvc r0, r5, #33554432 ; 0x2000000
77: R_ARM_ABS32 .debug_str
}
78: 03000004 movweq r0, #4
// analogRead - Reads an analog input channel 1-8 and returns the 12-bit value from 0 to 4095
int analogRead(unsigned char channel) {
channel--;
7c: 0000055f andeq r0, r0, pc, asr r5
7c: R_ARM_ABS32 .debug_str
if (channel < BOARD_NR_ADC_PINS)
80: 00864104 addeq r4, r6, r4, lsl #2
84: 04020000 streq r0, [r2], #-0
return (int)adcRead(channel);
88: 00050007 andeq r0, r5, r7
89: R_ARM_ABS32 .debug_str
return 0;
8c: 05080200 streq r0, [r8, #-512] ; 0xfffffe00
// analogReadCalibrated - Reads the calibrated value of an analog input channel 1-8;
// analogCalibrate() must be run first. This is inappropriate for integrated sensors as the
// round-off error can accumulate. Use analogReadCalibratedHR() instead.
int analogReadCalibrated(unsigned char channel) {
channel--;
90: 0000034f andeq r0, r0, pc, asr #6
90: R_ARM_ABS32 .debug_str
94: 94070802 strls r0, [r7], #-2050 ; 0xfffff7fe
97: R_ARM_ABS32 .debug_str
if (channel < BOARD_NR_ADC_PINS)
98: 04000001 streq r0, [r0], #-1
return (int)adcRead(channel) - (int)(_analogState[channel].calibValue >> 4);
9c: 6e690504 cdpvs 5, 6, cr0, cr9, cr4, {0}
a0: 3c030074 stccc 0, cr0, [r3], {116} ; 0x74
a3: R_ARM_ABS32 .debug_str
a4: 05000001 streq r0, [r0, #-1]
a8: 00002c13 andeq r2, r0, r3, lsl ip
ac: 03080300 movweq r0, #33536 ; 0x8300
ae: R_ARM_ABS32 .debug_str
b0: 14050000 strne r0, [r5], #-0
return 0;
}
b4: 0000003e andeq r0, r0, lr, lsr r0
b8: 0003dc03 andeq sp, r3, r3, lsl #24
b9: R_ARM_ABS32 .debug_str
// drift due to round-off.
int analogReadCalibratedHR(unsigned char channel) {
// The value returned actually has 16 bits of "precision", even though the ADC only reads
// 12 bits, so that errors induced by the average value being between two values come out
// in the wash when integrated over time. Think of the value as the true value << 4.
channel--;
bc: 571a0500 ldrpl r0, [sl, -r0, lsl #10]
c0: 03000000 movweq r0, #0
if (channel < BOARD_NR_ADC_PINS)
c4: 00000535 andeq r0, r0, r5, lsr r5
c4: R_ARM_ABS32 .debug_str
return (int)(adcRead(channel) << 4) - (int)(_analogState[channel].calibValue);
c8: 00691f05 rsbeq r1, r9, r5, lsl #30
cc: 33030000 movwcc r0, #12288 ; 0x3000
cf: R_ARM_ABS32 .debug_str
d0: 05000001 streq r0, [r0, #-1]
d4: 00007b20 andeq r7, r0, r0, lsr #22
d8: 02310300 eorseq r0, r1, #0, 6
da: R_ARM_ABS32 .debug_str
dc: d4060000 strle r0, [r6], #-0
return 0;
}
e0: 00000025 andeq r0, r0, r5, lsr #32
e4: f7070402 ; <UNDEFINED> instruction: 0xf7070402
e7: R_ARM_ABS32 .debug_str
// delay - taskDelay alias
void delay(const unsigned long time) {
taskDelay((clock_t)time);
e8: 05000004 streq r0, [r0, #-4]
}
// delayMicroseconds - Wait for approximately the given number of microseconds
void delayMicroseconds(const unsigned long time) {
ec: 01ef0304 mvneq r0, r4, lsl #6
ee: R_ARM_ABS32 .debug_str
clock_t us = (clock_t)time;
if (us) {
f0: 77070000 strvc r0, [r7, -r0]
/*us *= 12; us--;
asm volatile(" mov r0, %[us]\n\t"
"1: subs r0, #1\n\t"
" bhi 1b\n\t"
: : [us] "r" (us) : "r0");*/
if (us > 1000) {
f4: 00000086 andeq r0, r0, r6, lsl #1
// Wait off the milliseconds part first
clock_t millis = (clock_t)(us / 1000UL);
us %= 1000UL;
f8: f2060102 vrhadd.s8 d0, d6, d2
fb: R_ARM_ABS32 .debug_str
fc: 06000002 streq r0, [r0], -r2
100: 000000ce andeq r0, r0, lr, asr #1
taskDelay(millis);
104: 26081c07 strcs r1, [r8], -r7, lsl #24
}
if (us) {
108: 00016901 andeq r6, r1, r1, lsl #18
10c: 52430800 subpl r0, r3, #0, 16
// Spin on the highres timer value (next IRQ might be up to 1ms away!)
// Power consumption is bad, CPU usage possibly worse, but accuracy is acceptable
uint16_t start = TIM8->CNT;
110: 2808004c stmdacs r8, {r2, r3, r6}
114: 0000ff01 andeq pc, r0, r1, lsl #30
while (TIM8->CNT - start < us);
118: 43080000 movwmi r0, #32768 ; 0x8000
11c: 08004852 stmdaeq r0, {r1, r4, r6, fp, lr}
120: 00ff012a rscseq r0, pc, sl, lsr #2
124: 08040000 stmdaeq r4, {} ; <UNPREDICTABLE>
}
}
}
// digitalRead - Gets the digital value (1 or 0) of a pin configured as a digital input
bool digitalRead(unsigned char pin) {
128: 00524449 subseq r4, r2, r9, asr #8
if (pin >= BOARD_NR_GPIO_PINS)
return 0;
return ioGetInput((GPIO_TypeDef*)_pinLookupTable[pin], (uint8_t)_pinIndexTable[pin]);
12c: ff012c08 ; <UNDEFINED> instruction: 0xff012c08
130: 08000000 stmdaeq r0, {} ; <UNPREDICTABLE>
}
// ioGetInput - Gets the digital value (1 or 0) of a pin configured as a digital input
static INLINE bool ioGetInput(GPIO_TypeDef* port, uint32_t pin) {
// Shift right that many bits, then mask everything but the ones
return ((port->IDR >> (pin & 0x0F)) & 0x01) != 0;
134: 52444f08 subpl r4, r4, #8, 30
138: 012e0800 ; <UNDEFINED> instruction: 0x012e0800
13c: 000000ff strdeq r0, [r0], -pc ; <UNPREDICTABLE>
140: 0049090c subeq r0, r9, ip, lsl #18
142: R_ARM_ABS32 .debug_str
144: 30080000 andcc r0, r8, r0
}
// digitalRead - Gets the digital value (1 or 0) of a pin configured as a digital input
bool digitalRead(unsigned char pin) {
if (pin >= BOARD_NR_GPIO_PINS)
return 0;
148: 0000ff01 andeq pc, r0, r1, lsl #30
return ioGetInput((GPIO_TypeDef*)_pinLookupTable[pin], (uint8_t)_pinIndexTable[pin]);
}
14c: 42081000 andmi r1, r8, #0
150: 08005252 stmdaeq r0, {r1, r4, r6, r9, ip, lr}
// digitalWrite - Sets the digital value (1 or 0) of a pin configured as a digital output
void digitalWrite(unsigned char pin, bool value) {
// We will let this work when disabled, even though it might change a solenoid, since it
// is needed to set initial solenoid states in initializeIO() when enabled/disabled is
// undefined.
if (pin < BOARD_NR_GPIO_PINS)
154: 00ff0132 rscseq r0, pc, r2, lsr r1 ; <UNPREDICTABLE>
158: 09140000 ldmdbeq r4, {} ; <UNPREDICTABLE>
ioSetOutput((GPIO_TypeDef*)_pinLookupTable[pin], (uint8_t)_pinIndexTable[pin], value);
15c: 00000737 andeq r0, r0, r7, lsr r7
15c: R_ARM_ABS32 .debug_str
160: ff013408 ; <UNDEFINED> instruction: 0xff013408
164: 18000000 stmdane r0, {} ; <UNPREDICTABLE>
168: 04ea0a00 strbteq r0, [sl], #2560 ; 0xa00
16a: R_ARM_ABS32 .debug_str
return ((port->ODR >> (pin & 0x0F)) & 0x01) != 0;
}
// ioSetOutput - Sets the digital value (1 or 0) of a pin configured as a digital output
static INLINE void ioSetOutput(GPIO_TypeDef* port, uint32_t pin, bool value) {
if (value)
16c: 35080000 strcc r0, [r8, #-0]
// Atomic bit set
port->BSRR = ((uint32_t)0x00000001) << (pin & 0x0F);
170: 00010401 andeq r0, r1, r1, lsl #8
else
// Atomic bit reset
port->BRR = ((uint32_t)0x00000001) << (pin & 0x0F);
174: 00b80600 adcseq r0, r8, r0, lsl #12
178: 50070000 andpl r0, r7, r0
17c: 8b01f008 blhi 7c1a4 <_taskRunLoopHelper+0x7c1a4>
}
// isAutonomous - Checks to see if the system is in autonomous mode
bool isAutonomous() {
return (svFlags & SV_AUTONOMOUS) ? true : false;
180: 08000003 stmdaeq r0, {r0, r1}
}
184: 00315243 eorseq r5, r1, r3, asr #4
188: 7501f208 strvc pc, [r1, #-520] ; 0xfffffdf8
18c: 00000001 andeq r0, r0, r1
// isEnabled - Checks to see if the system is enabled
bool isEnabled() {
uint16_t flags = svFlags;
190: 00040e09 andeq r0, r4, r9, lsl #28
191: R_ARM_ABS32 .debug_str
194: 01f30800 mvnseq r0, r0, lsl #16
if (!(flags & SV_ENABLED)) {
if (flags & SV_FMS)
198: 000000b8 strheq r0, [r0], -r8
19c: 52430802 subpl r0, r3, #131072 ; 0x20000
1a0: f5080032 ; <UNDEFINED> instruction: 0xf5080032
return false;
}
return true;
}
1a4: 00017501 andeq r7, r1, r1, lsl #10
1a8: 18090400 stmdane r9, {sl}
1ab: R_ARM_ABS32 .debug_str
}
// svIsJoystickConnected - Checks to see if a joystick is connected
static INLINE uint8_t svIsJoystickConnected(uint8_t joystick) {
// Force in range from 0..1 (mapped from 1..2)
joystick = (joystick - 1) & (uint8_t)0x01;
1ac: 08000004 stmdaeq r0, {r2}
// If both accelerometer axes are zero, the joystick is likely not plugged in
// Obviously there is a chance for false positives but extremely unlikely due to the noise
// of the analog accelerometers
return SV_IN->joystick[joystick].axis[4] != (uint8_t)0x7F ||
1b0: 00b801f6 ldrshteq r0, [r8], r6
1b4: 09060000 stmdbeq r6, {} ; <UNPREDICTABLE>
1b8: 0000032c andeq r0, r0, ip, lsr #6
1b8: R_ARM_ABS32 .debug_str
1bc: 7501f808 strvc pc, [r1, #-2056] ; 0xfffff7f8
SV_IN->joystick[joystick].axis[5] != (uint8_t)0x7F;
1c0: 08000001 stmdaeq r0, {r0}
// Force in range from 0..1 (mapped from 1..2)
joystick = (joystick - 1) & (uint8_t)0x01;
// If both accelerometer axes are zero, the joystick is likely not plugged in
// Obviously there is a chance for false positives but extremely unlikely due to the noise
// of the analog accelerometers
return SV_IN->joystick[joystick].axis[4] != (uint8_t)0x7F ||
1c4: 00042209 andeq r2, r4, r9, lsl #4
1c5: R_ARM_ABS32 .debug_str
1c8: 01f90800 mvnseq r0, r0, lsl #16
1cc: 000000b8 strheq r0, [r0], -r8
// isJoystickConnected - Checks to see if the specified joystick is plugged in
bool isJoystickConnected(unsigned char joystick) {
return svIsJoystickConnected(joystick) ? true : false;
}
1d0: 0290090a addseq r0, r0, #163840 ; 0x28000
1d2: R_ARM_ABS32 .debug_str
// isOnline - Checks to see if the system is connected to a FMS/competition switch
bool isOnline() {
return (svFlags & SV_FMS) ? true : false;
1d4: fb080000 blx 2001de <_taskRunLoopHelper+0x2001de>
}
1d8: 00017501 andeq r7, r1, r1, lsl #10
1dc: 2c090c00 stccs 12, cr0, [r9], {-0}
1df: R_ARM_ABS32 .debug_str
1e0: 08000004 stmdaeq r0, {r2}
// joystickGetAnalog - Retrieve an analog axis of a joystick
int joystickGetAnalog(unsigned char joystick, unsigned char axis) {
1e4: 00b801fc ldrshteq r0, [r8], ip
1e8: 080e0000 stmdaeq lr, {} ; <UNPREDICTABLE>
// Safety first here
if (isOnline() && isAutonomous()) return 0;
1ec: 08005253 stmdaeq r0, {r0, r1, r4, r6, r9, ip, lr}
// svGetJoystickAnalog - Gets an analog joystick axis or accelerometer axis from the supervisor
// NO check on the mode when doing so
static INLINE int8_t svGetJoystickAnalog(uint8_t joystick, uint8_t axis) {
uint8_t value;
// Force in range from 0..5 (mapped from 1..6)
axis = (axis - 1) % 6;
1f0: 017501fe ldrsheq r0, [r5, #-30]! ; 0xffffffe2
1f4: 09100000 ldmdbeq r0, {} ; <UNPREDICTABLE>
1f8: 00000436 andeq r0, r0, r6, lsr r4
1f8: R_ARM_ABS32 .debug_str
// Force in range from 0..1 (mapped from 1..2)
joystick = (joystick - 1) & (uint8_t)0x01;
1fc: b801ff08 stmdalt r1, {r3, r8, r9, sl, fp, ip, sp, lr, pc}
value = SV_IN->joystick[joystick].axis[axis];
200: 12000000 andne r0, r0, #0
204: 52474508 subpl r4, r7, #8, 10 ; 0x2000000
208: 02010800 andeq r0, r1, #0, 16
// Prevent return of 128
if (value == 0xFF)
value = 0xFE;
value -= 127;
if (axis == 1 || axis == 2)
20c: 00000175 andeq r0, r0, r5, ror r1
uint8_t value;
// Force in range from 0..5 (mapped from 1..6)
axis = (axis - 1) % 6;
// Force in range from 0..1 (mapped from 1..2)
joystick = (joystick - 1) & (uint8_t)0x01;
value = SV_IN->joystick[joystick].axis[axis];
210: 04400914 strbeq r0, [r0], #-2324 ; 0xfffff6ec
212: R_ARM_ABS32 .debug_str
// Prevent return of 128
if (value == 0xFF)
value = 0xFE;
214: 02080000 andeq r0, r8, #0
value -= 127;
if (axis == 1 || axis == 2)
218: 0000b802 andeq fp, r0, r2, lsl #16
joystick = (joystick - 1) & (uint8_t)0x01;
value = SV_IN->joystick[joystick].axis[axis];
// Prevent return of 128
if (value == 0xFF)
value = 0xFE;
value -= 127;
21c: 63091600 movwvs r1, #38400 ; 0x9600
21f: R_ARM_ABS32 .debug_str
if (axis == 1 || axis == 2)
220: 08000001 stmdaeq r0, {r0}
value = -value;
224: 01750204 cmneq r5, r4, lsl #4
228: 09180000 ldmdbeq r8, {} ; <UNPREDICTABLE>
22c: 0000044a andeq r0, r0, sl, asr #8
22c: R_ARM_ABS32 .debug_str
230: b8020508 stmdalt r2, {r3, r8, sl}
return (int)svGetJoystickAnalog(joystick, axis);
234: 1a000000 bne 23c <.debug_info+0x23c>
238: 00016909 andeq r6, r1, r9, lsl #18
239: R_ARM_ABS32 .debug_str
}
// joystickGetDigital - Retrieve a digital button of a joystick
bool joystickGetDigital(unsigned char joystick, unsigned char buttonGroup,
unsigned char button) {
23c: 02070800 andeq r0, r7, #0, 16
240: 00000175 andeq r0, r0, r5, ror r1
// Safety first here
if (isOnline() && isAutonomous()) return false;
244: 072d091c ; <UNDEFINED> instruction: 0x072d091c
246: R_ARM_ABS32 .debug_str
248: 08080000 stmdaeq r8, {} ; <UNPREDICTABLE>
static INLINE uint8_t svGetJoystickDigital(uint8_t joystick, uint8_t button) {
uint8_t value; volatile Joystick_TypeDef *ref;
// Force in range from 0..3 (mapped from 5..8)
button = (button - 5) & (uint8_t)0x03;
// Force in range from 0..1 (mapped from 1..2)
joystick = (joystick - 1) & (uint8_t)0x01;
24c: 0000b802 andeq fp, r0, r2, lsl #16
ref = &SV_IN->joystick[joystick];
// 5 and 6 need some mangling to move the twos bit up to the fours
switch (button) {
250: dd091e00 stcle 14, cr1, [r9, #-0]
253: R_ARM_ABS32 .debug_str
uint8_t value; volatile Joystick_TypeDef *ref;
// Force in range from 0..3 (mapped from 5..8)
button = (button - 5) & (uint8_t)0x03;
// Force in range from 0..1 (mapped from 1..2)
joystick = (joystick - 1) & (uint8_t)0x01;
ref = &SV_IN->joystick[joystick];
254: 08000002 stmdaeq r0, {r1}
258: 0175020a cmneq r5, sl, lsl #4
25c: 09200000 stmdbeq r0!, {} ; <UNPREDICTABLE>
// 5 and 6 need some mangling to move the twos bit up to the fours
switch (button) {
260: 0000045e andeq r0, r0, lr, asr r4
260: R_ARM_ABS32 .debug_str
264: b8020b08 stmdalt r2, {r3, r8, r9, fp}
// 6
value = ref->button56 >> 2;
return ((value & 0x02) << 1) | (value & 0x01);
case 2:
// 7
return ref->button78 >> 4;
268: 22000000 andcs r0, r0, #0
26c: 544e4308 strbpl r4, [lr], #-776 ; 0xfffffcf8
270: 020d0800 andeq r0, sp, #0, 16
274: 00000175 andeq r0, r0, r5, ror r1
return (svGetJoystickDigital(joystick, buttonGroup) & button) ? true : false;
}
278: 04680924 strbteq r0, [r8], #-2340 ; 0xfffff6dc
27a: R_ARM_ABS32 .debug_str
ref = &SV_IN->joystick[joystick];
// 5 and 6 need some mangling to move the twos bit up to the fours
switch (button) {
case 0:
// 5
value = ref->button56;
27c: 0e080000 cdpeq 0, 0, cr0, cr8, cr0, {0}
return ((value & 0x02) << 1) | (value & 0x01);
case 1:
// 6
value = ref->button56 >> 2;
280: 0000b802 andeq fp, r0, r2, lsl #16
return ((value & 0x02) << 1) | (value & 0x01);
284: 50082600 andpl r2, r8, r0, lsl #12
288: 08004353 stmdaeq r0, {r0, r1, r4, r6, r8, r9, lr}
28c: 01750210 cmneq r5, r0, lsl r2
290: 09280000 stmdbeq r8!, {} ; <UNPREDICTABLE>
case 2:
// 7
return ref->button78 >> 4;
default:
// 8 (No other case is possible...)
return ref->button78 & 0x0F;
294: 00000619 andeq r0, r0, r9, lsl r6
294: R_ARM_ABS32 .debug_str
// joystickGetDigital - Retrieve a digital button of a joystick
bool joystickGetDigital(unsigned char joystick, unsigned char buttonGroup,
unsigned char button) {
// Safety first here
if (isOnline() && isAutonomous()) return false;
return (svGetJoystickDigital(joystick, buttonGroup) & button) ? true : false;
298: b8021108 stmdalt r2, {r3, r8, ip}
29c: 2a000000 bcs 2a4 <.debug_info+0x2a4>
2a0: 52524108 subspl r4, r2, #8, 2
2a4: 02130800 andseq r0, r3, #0, 16
}
// micros - Arduino-compatible alias for timeHighRes()
unsigned long micros() {
return (unsigned long)timeHighRes();
2a8: 00000175 andeq r0, r0, r5, ror r1
}
// millis - Arduino-compatible alias for timeLowRes()
unsigned long millis() {
return (unsigned long)timeLowRes();
2ac: 0624092c strteq r0, [r4], -ip, lsr #18
2ae: R_ARM_ABS32 .debug_str
}
// motorGet - Gets last commanded speed of the specified motor channel; this speed is reset
// to 0 if motors are stopped by the kernel for any reason
int motorGet(unsigned char channel) {
2b0: 14080000 strne r0, [r8], #-0
// Convert range
return (int)motorControlGet(channel) - 127;
2b4: 0000b802 andeq fp, r0, r2, lsl #16
}
2b8: 52082e00 andpl r2, r8, #0, 28
// motorSet - Sets the speed of the specified motor channel from 1 to 10, where -127 is full
// reverse and 127 is full forward, with 0 being off
void motorSet(unsigned char channel, int speed) {
2bc: 08005243 stmdaeq r0, {r0, r1, r6, r9, ip, lr}
if (isEnabled()) {
2c0: 01750216 cmneq r5, r6, lsl r2
2c4: 09300000 ldmdbeq r0!, {} ; <UNPREDICTABLE>
int ns = speed + 127;
// Equalize the bias
if (ns < 0) ns = 0;
2c8: 0000062f andeq r0, r0, pc, lsr #12
2c8: R_ARM_ABS32 .debug_str
if (ns > 255) ns = 255;
2cc: b8021708 stmdalt r2, {r3, r8, r9, sl, ip}
2d0: 32000000 andcc r0, r0, #0
// reverse and 127 is full forward, with 0 being off
void motorSet(unsigned char channel, int speed) {
if (isEnabled()) {
int ns = speed + 127;
// Equalize the bias
if (ns < 0) ns = 0;
2d4: 00014f09 andeq r4, r1, r9, lsl #30
2d5: R_ARM_ABS32 .debug_str
if (ns > 255) ns = 255;
motorControlSet(channel, (uint8_t)ns);
}
}
2d8: 02190800 andseq r0, r9, #0, 16
if (isEnabled()) {
int ns = speed + 127;
// Equalize the bias
if (ns < 0) ns = 0;
if (ns > 255) ns = 255;
motorControlSet(channel, (uint8_t)ns);
2dc: 00000175 andeq r0, r0, r5, ror r1
2e0: 063a0934 ; <UNDEFINED> instruction: 0x063a0934
2e2: R_ARM_ABS32 .debug_str
}
// motorStop - Stops the motor on the specified channel, equivalent to calling motorSet() with
// an argument of zero; this performs a coasting stop, not an active brake
void motorStop(unsigned char channel) {
motorControlSet(channel, 127);
2e4: 1a080000 bne 2002ec <_taskRunLoopHelper+0x2002ec>
2e8: 0000b802 andeq fp, r0, r2, lsl #16
// motorStopAll - Stops all motors; significantly faster than looping through all motor ports
// and calling motorSet(channel, 0) on each one
void motorStopAll() {
// It is safe to stop all motors when disabled, as that is their disabled state anyways.
motorControlStop();
2ec: 54093600 strpl r3, [r9], #-1536 ; 0xfffffa00
2ef: R_ARM_ABS32 .debug_str
}
// pinMode - Configures the pin as an input or output with a variety of settings
void pinMode(unsigned char pin, unsigned char mode) {
if (pin < BOARD_NR_GPIO_PINS)
2f0: 08000001 stmdaeq r0, {r0}
// It is safe to stop all motors when disabled, as that is their disabled state anyways.
motorControlStop();
}
// pinMode - Configures the pin as an input or output with a variety of settings
void pinMode(unsigned char pin, unsigned char mode) {
2f4: 0175021c cmneq r5, ip, lsl r2
if (pin < BOARD_NR_GPIO_PINS)
ioSetDirection((GPIO_TypeDef*)_pinLookupTable[pin], (uint8_t)_pinIndexTable[pin], mode);
2f8: 09380000 ldmdbeq r8!, {} ; <UNPREDICTABLE>
2fc: 00000645 andeq r0, r0, r5, asr #12
2fc: R_ARM_ABS32 .debug_str
300: b8021d08 stmdalt r2, {r3, r8, sl, fp, ip}
304: 3a000000 bcc 30c <.debug_info+0x30c>
308: 00015909 andeq r5, r1, r9, lsl #18
309: R_ARM_ABS32 .debug_str
30c: 021f0800 andseq r0, pc, #0, 16
return SV_OUT->data[index];
}
// svGetBackupBattery - Gets the backup battery voltage in millivolts, or 0 if not connected
static INLINE uint32_t svGetBackupBattery() {
uint32_t volts = ((uint32_t)SV_IN->backupBattery) * 59;
310: 00000175 andeq r0, r0, r5, ror r1
314: 0650093c ; <UNDEFINED> instruction: 0x0650093c
316: R_ARM_ABS32 .debug_str
if (volts < 1000)
318: 20080000 andcs r0, r8, r0
}
// powerLevelBackup - Get backup battery voltage in millivolts, or 0 if not connected
unsigned int powerLevelBackup() {
return svGetBackupBattery();
}
31c: 0000b802 andeq fp, r0, r2, lsl #16
320: 5e093e00 cdppl 14, 0, cr3, cr9, cr0, {0}
323: R_ARM_ABS32 .debug_str
324: 08000001 stmdaeq r0, {r0}
}
}
// svGetMainBattery - Gets the main battery voltage in millivolts, or 0 if not connected
static INLINE uint32_t svGetMainBattery() {
uint32_t volts = ((uint32_t)SV_IN->mainBattery) * 59;
328: 01750222 cmneq r5, r2, lsr #4
32c: 09400000 stmdbeq r0, {}^ ; <UNPREDICTABLE>
if (volts < 1000)
330: 0000065b andeq r0, r0, fp, asr r6
330: R_ARM_ABS32 .debug_str
// powerLevelMain - Get main battery voltage in millivolts, or 0 if not connected
unsigned int powerLevelMain() {
return svGetMainBattery();
}
334: b8022308 stmdalt r2, {r3, r8, r9, sp}
338: 42000000 andmi r0, r0, #0
33c: 00014309 andeq r4, r1, r9, lsl #6
33d: R_ARM_ABS32 .debug_str
// setTeamName - Sets the team name of the Cortex
void setTeamName(const char *name) {
340: 02250800 eoreq r0, r5, #0, 16
// svSetTeamName - Changes the team name reported to the supervisor
static INLINE void svSetTeamName(const char *name) {
char c; uint8_t i;
for (i = 0; i < 8; i++) {
// Copy up to 8 characters, respect zero terminator
c = (char)(*name++);
344: 00000175 andeq r0, r0, r5, ror r1
if (!c) break;
svTeamName[i] = c;
348: 06660944 strbteq r0, [r6], -r4, asr #18
34a: R_ARM_ABS32 .debug_str
34c: 26080000 strcs r0, [r8], -r0
}
// svSetTeamName - Changes the team name reported to the supervisor
static INLINE void svSetTeamName(const char *name) {
char c; uint8_t i;
for (i = 0; i < 8; i++) {
350: 0000b802 andeq fp, r0, r2, lsl #16
c = (char)(*name++);
if (!c) break;
svTeamName[i] = c;
}
// Space-pad
for (; i < 8; i++)
354: 44084600 strmi r4, [r8], #-1536 ; 0xfffffa00
svTeamName[i] = ' ';
358: 08005243 stmdaeq r0, {r0, r1, r6, r9, ip, lr}
35c: 01750228 cmneq r5, r8, lsr #4
c = (char)(*name++);
if (!c) break;
svTeamName[i] = c;
}
// Space-pad
for (; i < 8; i++)
360: 09480000 stmdbeq r8, {}^ ; <UNPREDICTABLE>
svSetTeamName(name);
}
364: 00000671 andeq r0, r0, r1, ror r6
364: R_ARM_ABS32 .debug_str
368: b8022908 stmdalt r2, {r3, r8, fp, sp}
// taskRunLoop - Starts a task at higher-than-normal priority to run the specified function
// in intervals as close to the specified period in milliseconds as possible
// For a stack size or priority different than the default, launch a custom task
TaskHandle taskRunLoop(void (*fn)(void), const unsigned long increment) {
36c: 4a000000 bmi 374 <.debug_info+0x374>
// Initialize data (will be later freed)
LoopTask *lt = malloc(sizeof(LoopTask));
370: 00047b09 andeq r7, r4, r9, lsl #22
371: R_ARM_ABS32 .debug_str
374: 022b0800 eoreq r0, fp, #0, 16
lt->fn = fn;
lt->period = (clock_t)increment;
// Create and start the task
return taskCreate(_taskRunLoopHelper, TASK_DEFAULT_STACK_SIZE, (void*)lt,
378: 00000175 andeq r0, r0, r5, ror r1
// in intervals as close to the specified period in milliseconds as possible
// For a stack size or priority different than the default, launch a custom task
TaskHandle taskRunLoop(void (*fn)(void), const unsigned long increment) {
// Initialize data (will be later freed)
LoopTask *lt = malloc(sizeof(LoopTask));
lt->fn = fn;
37c: 067c094c ldrbteq r0, [ip], -ip, asr #18
37e: R_ARM_ABS32 .debug_str
// taskRunLoop - Starts a task at higher-than-normal priority to run the specified function
// in intervals as close to the specified period in milliseconds as possible
// For a stack size or priority different than the default, launch a custom task
TaskHandle taskRunLoop(void (*fn)(void), const unsigned long increment) {
// Initialize data (will be later freed)
LoopTask *lt = malloc(sizeof(LoopTask));
380: 2c080000 stccs 0, cr0, [r8], {-0}
lt->fn = fn;
lt->period = (clock_t)increment;
// Create and start the task
return taskCreate(_taskRunLoopHelper, TASK_DEFAULT_STACK_SIZE, (void*)lt,
TASK_PRIORITY_DEFAULT + 1);
}
384: 0000b802 andeq fp, r0, r2, lsl #16
// Initialize data (will be later freed)
LoopTask *lt = malloc(sizeof(LoopTask));
lt->fn = fn;
lt->period = (clock_t)increment;
// Create and start the task
return taskCreate(_taskRunLoopHelper, TASK_DEFAULT_STACK_SIZE, (void*)lt,
388: 0a004e00 beq 13b90 <_taskRunLoopHelper+0x13b90>
38c: 00000127 andeq r0, r0, r7, lsr #2
38c: R_ARM_ABS32 .debug_str
390: 7a022d08 bvc 8b7b8 <_taskRunLoopHelper+0x8b7b8>
TASK_PRIORITY_DEFAULT + 1);
}
// wait - taskDelay alias
void wait(const unsigned long time) {
taskDelay((clock_t)time);
394: 06000001 streq r0, [r0], -r1
}
// waitUntil - taskDelayUntil alias
void waitUntil(unsigned long *previousWakeTime, unsigned long time) {
taskDelayUntil((clock_t*)previousWakeTime, (clock_t)time);
398: 000000c3 andeq r0, r0, r3, asr #1
39c: 0000ad06 andeq sl, r0, r6, lsl #26
3a0: 020c0b00 andeq r0, ip, #0, 22
3a4: 0003e686 andeq lr, r3, r6, lsl #13
3a8: 02250c00 eoreq r0, r5, #0, 24
3aa: R_ARM_ABS32 .debug_str
3ac: 88020000 stmdahi r2, {} ; <UNPREDICTABLE>
3b0: 00000397 muleq r0, r7, r3
3b4: 00760c00 rsbseq r0, r6, r0, lsl #24
3b6: R_ARM_ABS32 .debug_str
3b8: 89020000 stmdbhi r2, {} ; <UNPREDICTABLE>
3bc: 0000039c muleq r0, ip, r3
3c0: 00000c04 andeq r0, r0, r4, lsl #24
3c2: R_ARM_ABS32 .debug_str
3c4: 8a020000 bhi 803cc <_taskRunLoopHelper+0x803cc>
3c8: 0000039c muleq r0, ip, r3
3cc: 017a0c05 cmneq sl, r5, lsl #24
3ce: R_ARM_ABS32 .debug_str
3d0: 8c020000 stchi 0, cr0, [r2], {-0}
3d4: 00000175 andeq r0, r0, r5, ror r1
3d8: 01080c06 tsteq r8, r6, lsl #24
3da: R_ARM_ABS32 .debug_str
3dc: 8e020000 cdphi 0, 0, cr0, cr2, cr0, {0}
3e0: 000000ff strdeq r0, [r0], -pc ; <UNPREDICTABLE>
3e4: e3030008 movw r0, #12296 ; 0x3008
3e7: R_ARM_ABS32 .debug_str
3e8: 02000000 andeq r0, r0, #0
3ec: 0003a18f andeq sl, r3, pc, lsl #3
3f0: 030c0b00 movweq r0, #51968 ; 0xcb00
3f4: 0004361b andeq r3, r4, fp, lsl r6
3f8: 00d20c00 sbcseq r0, r2, r0, lsl #24
3fa: R_ARM_ABS32 .debug_str
3fc: 1d030000 stcne 0, cr0, [r3, #-0]
400: 00000446 andeq r0, r0, r6, asr #8
404: 040e0c00 streq r0, [lr], #-3072 ; 0xfffff400
406: R_ARM_ABS32 .debug_str
408: 1f030000 svcne 0x00030000
40c: 0000039c muleq r0, ip, r3
410: 01c30c06 biceq r0, r3, r6, lsl #24
412: R_ARM_ABS32 .debug_str
414: 21030000 mrscs r0, (UNDEF: 3)
418: 0000039c muleq r0, ip, r3
41c: 02a00c07 adceq r0, r0, #1792 ; 0x700
41e: R_ARM_ABS32 .debug_str
420: 23030000 movwcs r0, #12288 ; 0x3000
424: 0000039c muleq r0, ip, r3
428: 04180c08 ldreq r0, [r8], #-3080 ; 0xfffff3f8
42a: R_ARM_ABS32 .debug_str
42c: 25030000 strcs r0, [r3, #-0]
430: 0000045b andeq r0, r0, fp, asr r4
434: ad0d0009 stcge 0, cr0, [sp, #-36] ; 0xffffffdc
438: 46000000 strmi r0, [r0], -r0
43c: 0e000004 cdpeq 0, 0, cr0, cr0, cr4, {0}
440: 000000e4 andeq r0, r0, r4, ror #1
444: 36060005 strcc r0, [r6], -r5
448: 0d000004 stceq 0, cr0, [r0, #-16]
44c: 000000ad andeq r0, r0, sp, lsr #1
450: 0000045b andeq r0, r0, fp, asr r4
454: 0000e40e andeq lr, r0, lr, lsl #8
458: 06000200 streq r0, [r0], -r0, lsl #4
45c: 0000044b andeq r0, r0, fp, asr #8
460: 00069003 andeq r9, r6, r3
461: R_ARM_ABS32 .debug_str
464: f1260300 ; <UNDEFINED> instruction: 0xf1260300
468: 0b000003 bleq 47c <.debug_info+0x47c>
46c: d4290320 strtle r0, [r9], #-800 ; 0xfffffce0
470: 0f000004 svceq 0x00000004
474: 0079656b rsbseq r6, r9, fp, ror #10
478: 01752b03 cmneq r5, r3, lsl #22
47c: 0c000000 stceq 0, cr0, [r0], {-0}
480: 0000054a andeq r0, r0, sl, asr #10
480: R_ARM_ABS32 .debug_str
484: 039c2d03 orrseq r2, ip, #3, 26 ; 0xc0
488: 0c020000 stceq 0, cr0, [r2], {-0}
48c: 00000722 andeq r0, r0, r2, lsr #14
48c: R_ARM_ABS32 .debug_str
490: 039c2f03 orrseq r2, ip, #3, 30
494: 0c030000 stceq 0, cr0, [r3], {-0}
498: 000004bc ; <UNDEFINED> instruction: 0x000004bc
498: R_ARM_ABS32 .debug_str
49c: 039c3103 orrseq r3, ip, #-1073741824 ; 0xc0000000
4a0: 0c040000 stceq 0, cr0, [r4], {-0}
4a4: 0000038f andeq r0, r0, pc, lsl #7
4a4: R_ARM_ABS32 .debug_str
4a8: 039c3303 orrseq r3, ip, #201326592 ; 0xc000000
4ac: 0c050000 stceq 0, cr0, [r5], {-0}
4b0: 000001e6 andeq r0, r0, r6, ror #3
4b0: R_ARM_ABS32 .debug_str
4b4: 04e43503 strbteq r3, [r4], #1283 ; 0x503
4b8: 0c060000 stceq 0, cr0, [r6], {-0}
4bc: 00000089 andeq r0, r0, r9, lsl #1
4bc: R_ARM_ABS32 .debug_str
4c0: 039c3703 orrseq r3, ip, #786432 ; 0xc0000
4c4: 0c1e0000 ldceq 0, cr0, [lr], {-0}
4c8: 00000000 andeq r0, r0, r0
4c8: R_ARM_ABS32 .debug_str
4cc: 039c3803 orrseq r3, ip, #196608 ; 0x30000
4d0: 001f0000 andseq r0, pc, r0
4d4: 0004600d andeq r6, r4, sp
4d8: 0004e400 andeq lr, r4, r0, lsl #8
4dc: 00e40e00 rsceq r0, r4, r0, lsl #28
4e0: 00010000 andeq r0, r1, r0
4e4: 0004d406 andeq sp, r4, r6, lsl #8
4e8: 02630300 rsbeq r0, r3, #0, 6
4ea: R_ARM_ABS32 .debug_str
4ec: 39030000 stmdbcc r3, {} ; <UNPREDICTABLE>
4f0: 0000046b andeq r0, r0, fp, ror #8
4f4: 04fa0410 ldrbteq r0, [sl], #1040 ; 0x410
4f8: 10110000 andsne r0, r1, r0
4fc: 00050104 andeq r0, r5, r4, lsl #2
500: 00f81200 rscseq r1, r8, r0, lsl #4
504: f80d0000 ; <UNDEFINED> instruction: 0xf80d0000
508: 16000000 strne r0, [r0], -r0
50c: 0e000005 cdpeq 0, 0, cr0, cr0, cr5, {0}
510: 000000e4 andeq r0, r0, r4, ror #1
514: 6d030007 stcvs 0, cr0, [r3, #-28] ; 0xffffffe4
517: R_ARM_ABS32 .debug_str
518: 09000003 stmdbeq r0, {r0, r1}
51c: 0000eb42 andeq lr, r0, r2, asr #22
520: 04940300 ldreq r0, [r4], #768 ; 0x300
522: R_ARM_ABS32 .debug_str
524: 47090000 strmi r0, [r9, -r0]
528: 0000052c andeq r0, r0, ip, lsr #10
52c: 05320410 ldreq r0, [r2, #-1040]! ; 0xfffffbf0
530: 3d130000 ldccc 0, cr0, [r3, #-0]
534: 14000005 strne r0, [r0], #-5
538: 000000eb andeq r0, r0, fp, ror #1
53c: 01080b00 tsteq r8, r0, lsl #22
540: 00055d15 andeq r5, r5, r5, lsl sp
544: 6e660f00 cdpvs 15, 6, cr0, cr6, cr0, {0}
548: f4160100 ; <UNDEFINED> instruction: 0xf4160100
54c: 00000004 andeq r0, r0, r4
550: 0006d30c andeq sp, r6, ip, lsl #6
551: R_ARM_ABS32 .debug_str
554: ed170100 ldfs f0, [r7, #-0]
558: 04000000 streq r0, [r0], #-0
55c: 06da0300 ldrbeq r0, [sl], r0, lsl #6
55e: R_ARM_ABS32 .debug_str
560: 18010000 stmdane r1, {} ; <UNPREDICTABLE>
564: 0000053d andeq r0, r0, sp, lsr r5
568: 0003d115 andeq sp, r3, r5, lsl r1
569: R_ARM_ABS32 .debug_str
56c: 8fcb0200 svchi 0x00cb0200
570: 03000005 movweq r0, #5
574: 0000058f andeq r0, r0, pc, lsl #11
578: 00053d16 andeq r3, r5, r6, lsl sp
579: R_ARM_ABS32 .debug_str
57c: 96cb0200 strbls r0, [fp], r0, lsl #4
580: 17000005 strne r0, [r0, -r5]
584: 006e6970 rsbeq r6, lr, r0, ror r9
588: 00cecb02 sbceq ip, lr, r2, lsl #22
58c: 02000000 andeq r0, r0, #0
590: 03b60201 ; <UNDEFINED> instruction: 0x03b60201
592: R_ARM_ABS32 .debug_str
594: 04100000 ldreq r0, [r0], #-0
598: 00000169 andeq r0, r0, r9, ror #2
59c: 00025718 andeq r5, r2, r8, lsl r7
59d: R_ARM_ABS32 .debug_str
5a0: 03d70200 bicseq r0, r7, #0, 4
5a4: 000005ca andeq r0, r0, sl, asr #11
5a8: 00053d16 andeq r3, r5, r6, lsl sp
5a9: R_ARM_ABS32 .debug_str
5ac: 96d70200 ldrbls r0, [r7], r0, lsl #4
5b0: 17000005 strne r0, [r0, -r5]
5b4: 006e6970 rsbeq r6, lr, r0, ror r9
5b8: 00ced702 sbceq sp, lr, r2, lsl #14
5bc: 25160000 ldrcs r0, [r6, #-0]
5bf: R_ARM_ABS32 .debug_str
5c0: 02000002 andeq r0, r0, #2
5c4: 00058fd7 ldrdeq r8, [r5], -r7
5c8: 31150000 tstcc r5, r0
5cb: R_ARM_ABS32 .debug_str
5cc: 03000003 movweq r0, #3
5d0: 0000adb8 ; <UNDEFINED> instruction: 0x0000adb8
5d4: 05e60300 strbeq r0, [r6, #768]! ; 0x300
5d8: e6160000 ldr r0, [r6], -r0
5db: R_ARM_ABS32 .debug_str
5dc: 03000001 movweq r0, #1
5e0: 0000adb8 ; <UNDEFINED> instruction: 0x0000adb8
5e4: 0e150000 cdpeq 0, 1, cr0, cr5, cr0, {0}
5e7: R_ARM_ABS32 .debug_str
5e8: 03000007 movweq r0, #7
5ec: 0000a279 andeq sl, r0, r9, ror r2
5f0: 06180300 ldreq r0, [r8], -r0, lsl #6
5f4: e6160000 ldr r0, [r6], -r0
5f7: R_ARM_ABS32 .debug_str
5f8: 03000001 movweq r0, #1
5fc: 0000ad79 andeq sl, r0, r9, ror sp
600: 00d21600 sbcseq r1, r2, r0, lsl #12
602: R_ARM_ABS32 .debug_str
604: 79030000 stmdbvc r3, {} ; <UNPREDICTABLE>
608: 000000ad andeq r0, r0, sp, lsr #1
60c: 00022519 andeq r2, r2, r9, lsl r5
60d: R_ARM_ABS32 .debug_str
610: ad7a0300 ldclge 3, cr0, [sl, #-0]
614: 00000000 andeq r0, r0, r0
618: 00020315 andeq r0, r2, r5, lsl r3
619: R_ARM_ABS32 .debug_str
61c: ad8b0300 stcge 3, cr0, [fp]
620: 03000000 movweq r0, #0
624: 00000655 andeq r0, r0, r5, asr r6
628: 0001e616 andeq lr, r1, r6, lsl r6
629: R_ARM_ABS32 .debug_str
62c: ad8b0300 stcge 3, cr0, [fp]
630: 16000000 strne r0, [r0], -r0
634: 0000027a andeq r0, r0, sl, ror r2
634: R_ARM_ABS32 .debug_str
638: 00ad8b03 adceq r8, sp, r3, lsl #22
63c: 25190000 ldrcs r0, [r9, #-0]
63f: R_ARM_ABS32 .debug_str
640: 03000002 movweq r0, #2
644: 0000ad8c andeq sl, r0, ip, lsl #27
648: 65721a00 ldrbvs r1, [r2, #-2560]! ; 0xfffff600
64c: 8c030066 stchi 0, cr0, [r3], {102} ; 0x66
650: 00000655 andeq r0, r0, r5, asr r6
654: 5b041000 blpl 10465c <_taskRunLoopHelper+0x10465c>
658: 06000006 streq r0, [r0], -r6
65c: 00000460 andeq r0, r0, r0, ror #8
660: 0003191b andeq r1, r3, fp, lsl r9
661: R_ARM_ABS32 .debug_str
664: ce700300 cdpgt 3, 7, cr0, cr0, cr0, {0}
668: 03000000 movweq r0, #0
66c: 0000067c andeq r0, r0, ip, ror r6
670: 00022b19 andeq r2, r2, r9, lsl fp
671: R_ARM_ABS32 .debug_str
674: ce710300 cdpgt 3, 7, cr0, cr1, cr0, {0}
678: 00000000 andeq r0, r0, r0
67c: 0001b21b andeq fp, r1, fp, lsl r2
67d: R_ARM_ABS32 .debug_str
680: cea60300 cdpgt 3, 10, cr0, cr6, cr0, {0}
684: 03000000 movweq r0, #0
688: 00000698 muleq r0, r8, r6
68c: 00022b19 andeq r2, r2, r9, lsl fp
68d: R_ARM_ABS32 .debug_str
690: cea70300 cdpgt 3, 10, cr0, cr7, cr0, {0}
694: 00000000 andeq r0, r0, r0
698: 00048618 andeq r8, r4, r8, lsl r6
699: R_ARM_ABS32 .debug_str
69c: 03cd0300 biceq r0, sp, #0, 6
6a0: 000006c2 andeq r0, r0, r2, asr #13
6a4: 0004df16 andeq sp, r4, r6, lsl pc
6a5: R_ARM_ABS32 .debug_str
6a8: fbcd0300 blx ff3412b2 <_taskRunLoopHelper+0xff3412b2>
6ac: 1a000004 bne 6c4 <.debug_info+0x6c4>
6b0: ce030063 cdpgt 0, 0, cr0, cr3, cr3, {3}
6b4: 000000f8 strdeq r0, [r0], -r8
6b8: 0300691a movweq r6, #2330 ; 0x91a
6bc: 0000adce andeq sl, r0, lr, asr #27
6c0: 121c0000 andsne r0, ip, #0
6c3: R_ARM_ABS32 .debug_str
6c4: 01000005 tsteq r0, r5
6c8: 0000001b andeq r0, r0, fp, lsl r0
6c9: R_ARM_ABS32 .text._taskRunLoopHelper
6cc: 00003800 andeq r3, r0, r0, lsl #16
6d0: 619c0100 orrsvs r0, ip, r0, lsl #2
6d4: 1d000007 stcne 0, cr0, [r0, #-28] ; 0xffffffe4
6d8: 00000303 andeq r0, r0, r3, lsl #6
6d8: R_ARM_ABS32 .debug_str
6dc: 00eb1b01 rsceq r1, fp, r1, lsl #22
6e0: 00000000 andeq r0, r0, r0
6e2: R_ARM_ABS32 .debug_loc
6e4: ac1e0000 ldcge 0, cr0, [lr], {-0}
6e7: R_ARM_ABS32 .debug_str
6e8: 01000003 tsteq r0, r3
6ec: 0007611d andeq r6, r7, sp, lsl r1
6f0: 00000000 andeq r0, r0, r0
6f1: R_ARM_ABS32 .debug_loc
6f4: 6e661f00 cdpvs 15, 6, cr1, cr6, cr0, {0}
6f8: f41e0100 ; <UNDEFINED> instruction: 0xf41e0100
6fc: 01000004 tsteq r0, r4
700: 06d31e56 ; <UNDEFINED> instruction: 0x06d31e56
702: R_ARM_ABS32 .debug_str
704: 1f010000 svcne 0x00010000
708: 000000ed andeq r0, r0, sp, ror #1
70c: 00000021 andeq r0, r0, r1, lsr #32
70c: R_ARM_ABS32 .debug_loc
710: 776f6e1f ; <UNDEFINED> instruction: 0x776f6e1f
714: ed230100 stfs f0, [r3, #-0]
718: 02000000 andeq r0, r0, #0
71c: 73206491 ; <UNDEFINED> instruction: 0x73206491
720: 24010066 strcs r0, [r1], #-102 ; 0xffffff9a
724: 000000b8 strheq r0, [r0], -r8
728: 00000034 andeq r0, r0, r4, lsr r0
728: R_ARM_ABS32 .debug_loc
72c: 00000a21 andeq r0, r0, r1, lsr #20
72d: R_ARM_ABS32 .text._taskRunLoopHelper
730: 000f8100 andeq r8, pc, r0, lsl #2
734: 00074100 andeq r4, r7, r0, lsl #2
738: 50012200 andpl r2, r1, r0, lsl #4
73c: 5001f303 andpl pc, r1, r3, lsl #6
740: 000e2300 andeq r2, lr, r0, lsl #6
742: R_ARM_ABS32 .text._taskRunLoopHelper
744: 0f920000 svceq 0x00920000
748: 24240000 strtcs r0, [r4], #-0
74b: R_ARM_ABS32 .text._taskRunLoopHelper
74c: a3000000 movwge r0, #0
750: 2200000f andcs r0, r0, #15
754: 77025101 strvc r5, [r2, -r1, lsl #2]
758: 50012200 andpl r2, r1, r0, lsl #4
75c: 00649102 rsbeq r9, r4, r2, lsl #2
760: 5d041000 stcpl 0, cr1, [r4, #-0]
764: 25000005 strcs r0, [r0, #-5]
768: 000002e2 andeq r0, r0, r2, ror #5
768: R_ARM_ABS32 .debug_str
76c: 009b3001 addseq r3, fp, r1
770: 00000000 andeq r0, r0, r0
772: R_ARM_ABS32 .text.analogCalibrate
774: 00440000 subeq r0, r4, r0
778: 9c010000 stcls 0, cr0, [r1], {-0}
77c: 000007d9 ldrdeq r0, [r0], -r9
780: 0003ec1d andeq lr, r3, sp, lsl ip
781: R_ARM_ABS32 .debug_str
784: 49300100 ldmdbmi r0!, {r8}
788: 47000000 strmi r0, [r0, -r0]
78b: R_ARM_ABS32 .debug_loc
78c: 26000000 strcs r0, [r0], -r0
790: 00000010 andeq r0, r0, r0, lsl r0
790: R_ARM_ABS32 .text.analogCalibrate
794: 0000002c andeq r0, r0, ip, lsr #32
798: 0007081e andeq r0, r7, lr, lsl r8
799: R_ARM_ABS32 .debug_str
79c: ce340100 rsfgts f0, f4, f0
7a0: 7e000000 cdpvc 0, 0, cr0, cr0, cr0, {0}
7a3: R_ARM_ABS32 .debug_loc
7a4: 20000000 andcs r0, r0, r0
7a8: 34010069 strcc r0, [r1], #-105 ; 0xffffff97
7ac: 000000ce andeq r0, r0, lr, asr #1
7b0: 00000091 muleq r0, r1, r0
7b0: R_ARM_ABS32 .debug_loc
7b4: 00001621 andeq r1, r0, r1, lsr #12
7b5: R_ARM_ABS32 .text.analogCalibrate
7b8: 000fb900 andeq fp, pc, r0, lsl #18
7bc: 0007c800 andeq ip, r7, r0, lsl #16
7c0: 50012200 andpl r2, r1, r0, lsl #4
7c4: 00007502 andeq r7, r0, r2, lsl #10
7c8: 00001e24 andeq r1, r0, r4, lsr #28
7c9: R_ARM_ABS32 .text.analogCalibrate
7cc: 000fce00 andeq ip, pc, r0, lsl #28
7d0: 50012200 andpl r2, r1, r0, lsl #4
7d4: 00003101 andeq r3, r0, r1, lsl #2
7d8: 02952500 addseq r2, r5, #0, 10
7da: R_ARM_ABS32 .debug_str
7dc: 41010000 mrsmi r0, (UNDEF: 1)
7e0: 0000009b muleq r0, fp, r0
7e4: 00000000 andeq r0, r0, r0
7e4: R_ARM_ABS32 .text.analogRead
7e8: 00000014 andeq r0, r0, r4, lsl r0
7ec: 080b9c01 stmdaeq fp, {r0, sl, fp, ip, pc}
7f0: ec1d0000 ldc 0, cr0, [sp], {-0}
7f3: R_ARM_ABS32 .debug_str
7f4: 01000003 tsteq r0, r3
7f8: 00004941 andeq r4, r0, r1, asr #18
7fc: 0000cc00 andeq ip, r0, r0, lsl #24
7fd: R_ARM_ABS32 .debug_loc
800: 000e2300 andeq r2, lr, r0, lsl #6
802: R_ARM_ABS32 .text.analogRead
804: 0fb90000 svceq 0x00b90000
808: 25000000 strcs r0, [r0, #-0]
80c: 00000020 andeq r0, r0, r0, lsr #32
80c: R_ARM_ABS32 .debug_str
810: 009b4b01 addseq r4, fp, r1, lsl #22
814: 00000000 andeq r0, r0, r0
816: R_ARM_ABS32 .text.analogReadCalibrated
818: 002c0000 eoreq r0, ip, r0
81c: 9c010000 stcls 0, cr0, [r1], {-0}
820: 00000844 andeq r0, r0, r4, asr #16
824: 0003ec1d andeq lr, r3, sp, lsl ip
825: R_ARM_ABS32 .debug_str
828: 494b0100 stmdbmi fp, {r8}^
82c: 03000000 movweq r0, #0
82f: R_ARM_ABS32 .debug_loc
830: 24000001 strcs r0, [r0], #-1
834: 00000010 andeq r0, r0, r0, lsl r0
834: R_ARM_ABS32 .text.analogReadCalibrated
838: 00000fb9 ; <UNDEFINED> instruction: 0x00000fb9
83c: 02500122 subseq r0, r0, #-2147483640 ; 0x80000008
840: 00000074 andeq r0, r0, r4, ror r0
844: 00000925 andeq r0, r0, r5, lsr #18
845: R_ARM_ABS32 .debug_str
848: 9b550100 blls 1540c50 <_taskRunLoopHelper+0x1540c50>
84c: 00000000 andeq r0, r0, r0
84f: R_ARM_ABS32 .text.analogReadCalibratedHR
850: 2c000000 stccs 0, cr0, [r0], {-0}
854: 01000000 mrseq r0, (UNDEF: 0)
858: 00087d9c muleq r8, ip, sp
85c: 03ec1d00 mvneq r1, #0, 26
85e: R_ARM_ABS32 .debug_str
860: 55010000 strpl r0, [r1, #-0]
864: 00000049 andeq r0, r0, r9, asr #32
868: 0000013a andeq r0, r0, sl, lsr r1
868: R_ARM_ABS32 .debug_loc
86c: 00001024 andeq r1, r0, r4, lsr #32
86d: R_ARM_ABS32 .text.analogReadCalibratedHR
870: 000fb900 andeq fp, pc, r0, lsl #18
874: 50012200 andpl r2, r1, r0, lsl #4
878: 00007402 andeq r7, r0, r2, lsl #8
87c: 04802700 streq r2, [r0], #1792 ; 0x700
87e: R_ARM_ABS32 .debug_str
880: 60010000 andvs r0, r1, r0
884: 00000000 andeq r0, r0, r0
884: R_ARM_ABS32 .text.delay
888: 00000004 andeq r0, r0, r4
88c: 08b39c01 ldmeq r3!, {r0, sl, fp, ip, pc}
890: e11d0000 tst sp, r0
893: R_ARM_ABS32 .debug_str
894: 01000001 tsteq r0, r1
898: 0008b360 andeq fp, r8, r0, ror #6
89c: 00017100 andeq r7, r1, r0, lsl #2
89d: R_ARM_ABS32 .debug_loc
8a0: 00042800 andeq r2, r4, r0, lsl #16
8a2: R_ARM_ABS32 .text.delay
8a4: 0fce0000 svceq 0x00ce0000
8a8: 01220000 ; <UNDEFINED> instruction: 0x01220000
8ac: 01f30350 mvnseq r0, r0, asr r3
8b0: 12000050 andne r0, r0, #80 ; 0x50
8b4: 00000086 andeq r0, r0, r6, lsl #1
8b8: 0006f627 andeq pc, r6, r7, lsr #12
8b9: R_ARM_ABS32 .debug_str
8bc: 00650100 rsbeq r0, r5, r0, lsl #2
8bf: R_ARM_ABS32 .text.delayMicroseconds
8c0: 3c000000 stccc 0, cr0, [r0], {-0}
8c4: 01000000 mrseq r0, (UNDEF: 0)
8c8: 00093c9c muleq r9, ip, ip
8cc: 01e11d00 mvneq r1, r0, lsl #26
8ce: R_ARM_ABS32 .debug_str
8d0: 65010000 strvs r0, [r1, #-0]
8d4: 000008b3 ; <UNDEFINED> instruction: 0x000008b3
8d8: 00000192 muleq r0, r2, r1
8d8: R_ARM_ABS32 .debug_loc
8dc: 00737520 rsbseq r7, r3, r0, lsr #10
8e0: 00ed6601 rsceq r6, sp, r1, lsl #12
8e4: 01d70000 bicseq r0, r7, r0
8e6: R_ARM_ABS32 .debug_loc
8e8: 0c290000 stceq 0, cr0, [r9], #-0
8eb: R_ARM_ABS32 .text.delayMicroseconds
8ec: 10000000 andne r0, r0, r0
8f0: 22000000 andcs r0, r0, #0
8f4: 1e000009 cdpne 0, 0, cr0, cr0, cr9, {0}
8f8: 000001ab andeq r0, r0, fp, lsr #3
8f8: R_ARM_ABS32 .debug_str
8fc: 00ed7001 rsceq r7, sp, r1
900: 02160000 andseq r0, r6, #0
902: R_ARM_ABS32 .debug_loc
904: 1c240000 stcne 0, cr0, [r4], #-0
907: R_ARM_ABS32 .text.delayMicroseconds
908: ce000000 cdpgt 0, 0, cr0, cr0, cr0, {0}
90c: 2200000f andcs r0, r0, #15
910: f30d5001 vhadd.u8 d5, d13, d1
914: 25f75001 ldrbcs r5, [r7, #1]!
918: f703e80a ; <UNDEFINED> instruction: 0xf703e80a
91c: 00f71b25 rscseq r1, r7, r5, lsr #22
920: 22260000 eorcs r0, r6, #0
923: R_ARM_ABS32 .text.delayMicroseconds
924: 1a000000 bne 92c <.debug_info+0x92c>
928: 1e000000 cdpne 0, 0, cr0, cr0, cr0, {0}
92c: 000004e4 andeq r0, r0, r4, ror #9
92c: R_ARM_ABS32 .debug_str
930: 00b87701 adcseq r7, r8, r1, lsl #14
934: 02580000 subseq r0, r8, #0
936: R_ARM_ABS32 .debug_loc
938: 00000000 andeq r0, r0, r0
93c: 00049d25 andeq r9, r4, r5, lsr #26
93d: R_ARM_ABS32 .debug_str
940: 8f7e0100 svchi 0x007e0100
944: 00000005 andeq r0, r0, r5
947: R_ARM_ABS32 .text.digitalRead
948: 2c000000 stccs 0, cr0, [r0], {-0}
94c: 01000000 mrseq r0, (UNDEF: 0)
950: 0009839c muleq r9, ip, r3
954: 69702a00 ldmdbvs r0!, {r9, fp, sp}^
958: 7e01006e cdpvc 0, 0, cr0, cr1, cr14, {3}
95c: 00000049 andeq r0, r0, r9, asr #32
960: 0000026b andeq r0, r0, fp, ror #4
960: R_ARM_ABS32 .debug_loc
964: 0005682b andeq r6, r5, fp, lsr #16
968: 00000c00 andeq r0, r0, r0, lsl #24
969: R_ARM_ABS32 .text.digitalRead
96c: 00000000 andeq r0, r0, r0
96d: R_ARM_ABS32 .debug_ranges
970: 2c810100 stfcss f0, [r1], {0}
974: 00000583 andeq r0, r0, r3, lsl #11
978: 0005782d andeq r7, r5, sp, lsr #16
97c: 00028c00 andeq r8, r2, r0, lsl #24
97d: R_ARM_ABS32 .debug_loc
980: 27000000 strcs r0, [r0, -r0]
984: 00000069 andeq r0, r0, r9, rrx
984: R_ARM_ABS32 .debug_str
988: 00008501 andeq r8, r0, r1, lsl #10
98a: R_ARM_ABS32 .text.digitalWrite
98c: 002c0000 eoreq r0, ip, r0
990: 9c010000 stcls 0, cr0, [r1], {-0}
994: 000009de ldrdeq r0, [r0], -lr
998: 6e69702e cdpvs 0, 6, cr7, cr9, cr14, {1}
99c: 49850100 stmibmi r5, {r8}
9a0: 01000000 mrseq r0, (UNDEF: 0)
9a4: 02252f50 eoreq r2, r5, #80, 30 ; 0x140
9a6: R_ARM_ABS32 .debug_str
9a8: 85010000 strhi r0, [r1, #-0]
9ac: 0000058f andeq r0, r0, pc, lsl #11
9b0: 9c305101 ldflss f5, [r0], #-4
9b4: 16000005 strne r0, [r0], -r5
9b7: R_ARM_ABS32 .text.digitalWrite
9b8: 16000000 strne r0, [r0], -r0
9bc: 01000000 mrseq r0, (UNDEF: 0)
9c0: 05be2d8a ldreq r2, [lr, #3466]! ; 0xd8a
9c4: 029f0000 addseq r0, pc, #0
9c6: R_ARM_ABS32 .debug_loc
9c8: b32d0000 ; <UNDEFINED> instruction: 0xb32d0000
9cc: b2000005 andlt r0, r0, #5
9cf: R_ARM_ABS32 .debug_loc
9d0: 2d000002 stccs 0, cr0, [r0, #-8]
9d4: 000005a8 andeq r0, r0, r8, lsr #11
9d8: 000002ca andeq r0, r0, sl, asr #5
9d8: R_ARM_ABS32 .debug_loc
9dc: c8310000 ldmdagt r1!, {} ; <UNPREDICTABLE>
9df: R_ARM_ABS32 .debug_str
9e0: 01000004 tsteq r0, r4
9e4: 00058f8e andeq r8, r5, lr, lsl #31
9e8: 00000000 andeq r0, r0, r0
9e9: R_ARM_ABS32 .text.isAutonomous
9ec: 00001000 andeq r1, r0, r0
9f0: 329c0100 addscc r0, ip, #0, 2
9f4: 000001d7 ldrdeq r0, [r0], -r7
9f4: R_ARM_ABS32 .debug_str
9f8: 058f9301 streq r9, [pc, #769] ; d01 <.debug_info+0xd01>
9fc: 00000000 andeq r0, r0, r0
9fe: R_ARM_ABS32 .text.isEnabled
a00: 001c0000 andseq r0, ip, r0
a04: 9c010000 stcls 0, cr0, [r1], {-0}
a08: 00000a1c andeq r0, r0, ip, lsl sl
a0c: 0000761e andeq r7, r0, lr, lsl r6
a0d: R_ARM_ABS32 .debug_str
a10: b8940100 ldmlt r4, {r8}
a14: dd000000 stcle 0, cr0, [r0, #-0]
a17: R_ARM_ABS32 .debug_loc
a18: 00000002 andeq r0, r0, r2
a1c: 0006a125 andeq sl, r6, r5, lsr #2
a1d: R_ARM_ABS32 .debug_str
a20: 8f9d0100 svchi 0x009d0100
a24: 00000005 andeq r0, r0, r5
a27: R_ARM_ABS32 .text.isJoystickConnected
a28: 28000000 stmdacs r0, {} ; <UNPREDICTABLE>
a2c: 01000000 mrseq r0, (UNDEF: 0)
a30: 000a5e9c muleq sl, ip, lr
a34: 01e61d00 mvneq r1, r0, lsl #26
a36: R_ARM_ABS32 .debug_str
a38: 9d010000 stcls 0, cr0, [r1, #-0]
a3c: 00000049 andeq r0, r0, r9, asr #32
a40: 000002f0 strdeq r0, [r0], -r0 ; <UNPREDICTABLE>
a40: R_ARM_ABS32 .debug_loc
a44: 0005ca30 andeq ip, r5, r0, lsr sl
a48: 00000000 andeq r0, r0, r0
a49: R_ARM_ABS32 .text.isJoystickConnected
a4c: 00002200 andeq r2, r0, r0, lsl #4
a50: 2d9e0100 ldfcss f0, [lr]
a54: 000005da ldrdeq r0, [r0], -sl
a58: 00000311 andeq r0, r0, r1, lsl r3
a58: R_ARM_ABS32 .debug_loc
a5c: 10310000 eorsne r0, r1, r0
a5f: R_ARM_ABS32 .debug_str
a60: 01000003 tsteq r0, r3
a64: 00058fa2 andeq r8, r5, r2, lsr #31
a68: 00000000 andeq r0, r0, r0
a69: R_ARM_ABS32 .text.isOnline
a6c: 00001000 andeq r1, r0, r0
a70: 259c0100 ldrcs r0, [ip, #256] ; 0x100
a74: 000006b5 ; <UNDEFINED> instruction: 0x000006b5
a74: R_ARM_ABS32 .debug_str
a78: 009ba701 addseq sl, fp, r1, lsl #14
a7c: 00000000 andeq r0, r0, r0
a7e: R_ARM_ABS32 .text.joystickGetAnalog
a80: 00580000 subseq r0, r8, r0
a84: 9c010000 stcls 0, cr0, [r1], {-0}
a88: 00000af6 strdeq r0, [r0], -r6
a8c: 0001e61d andeq lr, r1, sp, lsl r6
a8d: R_ARM_ABS32 .debug_str
a90: 49a70100 stmibmi r7!, {r8}
a94: 3a000000 bcc 8 <.debug_info+0x8>
a97: R_ARM_ABS32 .debug_loc
a98: 1d000003 stcne 0, cr0, [r0, #-12]
a9c: 000000d2 ldrdeq r0, [r0], -r2
a9c: R_ARM_ABS32 .debug_str
aa0: 0049a701 subeq sl, r9, r1, lsl #14
aa4: 035b0000 cmpeq fp, #0
aa6: R_ARM_ABS32 .debug_loc
aa8: e6330000 ldrt r0, [r3], -r0
aac: 0c000005 stceq 0, cr0, [r0], {5}
aaf: R_ARM_ABS32 .text.joystickGetAnalog
ab0: 38000000 stmdacc r0, {} ; <UNPREDICTABLE>
ab4: 01000000 mrseq r0, (UNDEF: 0)
ab8: 000ae3aa andeq lr, sl, sl, lsr #7
abc: 06012d00 streq r2, [r1], -r0, lsl #26
ac0: 037c0000 cmneq ip, #0
ac2: R_ARM_ABS32 .debug_loc
ac4: f62d0000 ; <UNDEFINED> instruction: 0xf62d0000
ac8: b4000005 strlt r0, [r0], #-5
acb: R_ARM_ABS32 .debug_loc
acc: 26000003 strcs r0, [r0], -r3
ad0: 0000000c andeq r0, r0, ip
ad0: R_ARM_ABS32 .text.joystickGetAnalog
ad4: 00000038 andeq r0, r0, r8, lsr r0
ad8: 00060c34 andeq r0, r6, r4, lsr ip
adc: 0003c700 andeq ip, r3, r0, lsl #14
add: R_ARM_ABS32 .debug_loc
ae0: 23000000 movwcs r0, #0
ae4: 0000000a andeq r0, r0, sl
ae4: R_ARM_ABS32 .text.joystickGetAnalog
ae8: 00000a5e andeq r0, r0, lr, asr sl
aec: 00004823 andeq r4, r0, r3, lsr #16
aed: R_ARM_ABS32 .text.joystickGetAnalog
af0: 0009de00 andeq sp, r9, r0, lsl #28
af4: a9250000 stmdbge r5!, {} ; <UNPREDICTABLE>
af7: R_ARM_ABS32 .debug_str
af8: 01000004 tsteq r0, r4
afc: 00058fae andeq r8, r5, lr, lsr #31
b00: 00000000 andeq r0, r0, r0
b01: R_ARM_ABS32 .text.joystickGetDigital
b04: 00006c00 andeq r6, r0, r0, lsl #24
b08: 8d9c0100 ldfhis f0, [ip]
b0c: 1d00000b stcne 0, cr0, [r0, #-44] ; 0xffffffd4
b10: 000001e6 andeq r0, r0, r6, ror #3
b10: R_ARM_ABS32 .debug_str
b14: 0049ae01 subeq sl, r9, r1, lsl #28
b18: 04170000 ldreq r0, [r7], #-0
b1a: R_ARM_ABS32 .debug_loc
b1c: f71d0000 ; <UNDEFINED> instruction: 0xf71d0000
b1f: R_ARM_ABS32 .debug_str
b20: 01000001 tsteq r0, r1
b24: 000049ae andeq r4, r0, lr, lsr #19
b28: 00043800 andeq r3, r4, r0, lsl #16
b29: R_ARM_ABS32 .debug_loc
b2c: 027a1d00 rsbseq r1, sl, #0, 26
b2e: R_ARM_ABS32 .debug_str
b30: af010000 svcge 0x00010000
b34: 00000049 andeq r0, r0, r9, asr #32
b38: 00000459 andeq r0, r0, r9, asr r4
b38: R_ARM_ABS32 .debug_loc
b3c: 00061835 andeq r1, r6, r5, lsr r8
b40: 00000e00 andeq r0, r0, r0, lsl #28
b41: R_ARM_ABS32 .text.joystickGetDigital
b44: 00001800 andeq r1, r0, r0, lsl #16
b45: R_ARM_ABS32 .debug_ranges
b48: 7ab20100 bvc fec80f50 <_taskRunLoopHelper+0xfec80f50>
b4c: 2d00000b stccs 0, cr0, [r0, #-44] ; 0xffffffd4
b50: 00000633 andeq r0, r0, r3, lsr r6
b54: 0000047a andeq r0, r0, sl, ror r4
b54: R_ARM_ABS32 .debug_loc
b58: 0006282d andeq r2, r6, sp, lsr #16
b5c: 0004a000 andeq sl, r4, r0
b5d: R_ARM_ABS32 .debug_loc
b60: 00183600 andseq r3, r8, r0, lsl #12
b62: R_ARM_ABS32 .debug_ranges
b64: 3e340000 cdpcc 0, 3, cr0, cr4, cr0, {0}
b68: b7000006 strlt r0, [r0, -r6]
b6b: R_ARM_ABS32 .debug_loc
b6c: 34000004 strcc r0, [r0], #-4
b70: 00000649 andeq r0, r0, r9, asr #12
b74: 000004d5 ldrdeq r0, [r0], -r5
b74: R_ARM_ABS32 .debug_loc
b78: 0c230000 stceq 0, cr0, [r3], #-0
b7b: R_ARM_ABS32 .text.joystickGetDigital
b7c: 5e000000 cdppl 0, 0, cr0, cr0, cr0, {0}
b80: 2300000a movwcs r0, #10
b84: 00000036 andeq r0, r0, r6, lsr r0
b84: R_ARM_ABS32 .text.joystickGetDigital
b88: 000009de ldrdeq r0, [r0], -lr
b8c: 03e53200 mvneq r3, #0, 4
b8e: R_ARM_ABS32 .debug_str
b90: b6010000 strlt r0, [r1], -r0
b94: 00000086 andeq r0, r0, r6, lsl #1
b98: 00000000 andeq r0, r0, r0
b98: R_ARM_ABS32 .text.micros
b9c: 00000004 andeq r0, r0, r4
ba0: 0bb09c01 bleq fec27bac <_taskRunLoopHelper+0xfec27bac>
ba4: 04370000 ldrteq r0, [r7], #-0
ba7: R_ARM_ABS32 .text.micros
ba8: df000000 svcle 0x00000000
bac: 0000000f andeq r0, r0, pc
bb0: 0001ab32 andeq sl, r1, r2, lsr fp
bb1: R_ARM_ABS32 .debug_str
bb4: 86bb0100 ldrthi r0, [fp], r0, lsl #2
bb8: 00000000 andeq r0, r0, r0
bbb: R_ARM_ABS32 .text.millis
bbc: 04000000 streq r0, [r0], #-0
bc0: 01000000 mrseq r0, (UNDEF: 0)
bc4: 000bd39c muleq fp, ip, r3
bc8: 00043700 andeq r3, r4, r0, lsl #14
bca: R_ARM_ABS32 .text.millis
bcc: 0f920000 svceq 0x00920000
bd0: 25000000 strcs r0, [r0, #-0]
bd4: 000000b8 strheq r0, [r0], -r8
bd4: R_ARM_ABS32 .debug_str
bd8: 009bc101 addseq ip, fp, r1, lsl #2
bdc: 00000000 andeq r0, r0, r0
bde: R_ARM_ABS32 .text.motorGet
be0: 000a0000 andeq r0, sl, r0
be4: 9c010000 stcls 0, cr0, [r1], {-0}
be8: 00000c05 andeq r0, r0, r5, lsl #24
bec: 0003ec1d andeq lr, r3, sp, lsl ip
bed: R_ARM_ABS32 .debug_str
bf0: 49c10100 stmibmi r1, {r8}^
bf4: f3000000 vhadd.u8 d0, d0, d0
bf7: R_ARM_ABS32 .debug_loc
bf8: 23000004 movwcs r0, #4
bfc: 00000006 andeq r0, r0, r6
bfc: R_ARM_ABS32 .text.motorGet
c00: 00000ff0 strdeq r0, [r0], -r0 ; <UNPREDICTABLE>
c04: 06872700 streq r2, [r7], r0, lsl #14
c06: R_ARM_ABS32 .debug_str
c08: c8010000 stmdagt r1, {} ; <UNPREDICTABLE>
c0c: 00000000 andeq r0, r0, r0
c0c: R_ARM_ABS32 .text.motorSet
c10: 0000002a andeq r0, r0, sl, lsr #32
c14: 0c639c01 stcleq 12, cr9, [r3], #-4
c18: ec1d0000 ldc 0, cr0, [sp], {-0}
c1b: R_ARM_ABS32 .debug_str
c1c: 01000003 tsteq r0, r3
c20: 000049c8 andeq r4, r0, r8, asr #19
c24: 00051400 andeq r1, r5, r0, lsl #8
c25: R_ARM_ABS32 .debug_loc
c28: 01121d00 tsteq r2, r0, lsl #26
c2a: R_ARM_ABS32 .debug_str
c2c: c8010000 stmdagt r1, {} ; <UNPREDICTABLE>
c30: 0000009b muleq r0, fp, r0
c34: 00000535 andeq r0, r0, r5, lsr r5
c34: R_ARM_ABS32 .debug_loc
c38: 00003038 andeq r3, r0, r8, lsr r0
c39: R_ARM_ABS32 .debug_ranges
c3c: 000c5900 andeq r5, ip, r0, lsl #18
c40: 736e2000 cmnvc lr, #0
c44: 9bca0100 blls ff28104c <_taskRunLoopHelper+0xff28104c>
c48: 6c000000 stcvs 0, cr0, [r0], {-0}
c4b: R_ARM_ABS32 .debug_loc
c4c: 37000005 strcc r0, [r0, -r5]
c50: 00000028 andeq r0, r0, r8, lsr #32
c50: R_ARM_ABS32 .text.motorSet
c54: 00001006 andeq r1, r0, r6
c58: 000a2300 andeq r2, sl, r0, lsl #6
c5a: R_ARM_ABS32 .text.motorSet
c5c: 09f30000 ldmibeq r3!, {}^ ; <UNPREDICTABLE>
c60: 27000000 strcs r0, [r0, -r0]
c64: 00000035 andeq r0, r0, r5, lsr r0
c64: R_ARM_ABS32 .debug_str
c68: 0000d401 andeq sp, r0, r1, lsl #8
c6a: R_ARM_ABS32 .text.motorStop
c6c: 00060000 andeq r0, r6, r0
c70: 9c010000 stcls 0, cr0, [r1], {-0}
c74: 00000c98 muleq r0, r8, ip
c78: 0003ec1d andeq lr, r3, sp, lsl ip
c79: R_ARM_ABS32 .debug_str
c7c: 49d40100 ldmibmi r4, {r8}^
c80: a6000000 strge r0, [r0], -r0
c83: R_ARM_ABS32 .debug_loc
c84: 28000005 stmdacs r0, {r0, r2}
c88: 00000006 andeq r0, r0, r6
c88: R_ARM_ABS32 .text.motorStop
c8c: 00001006 andeq r1, r0, r6
c90: 02510122 subseq r0, r1, #-2147483640 ; 0x80000008
c94: 00007f08 andeq r7, r0, r8, lsl #30
c98: 00021839 andeq r1, r2, r9, lsr r8
c99: R_ARM_ABS32 .debug_str
c9c: 00da0100 sbcseq r0, sl, r0, lsl #2
c9f: R_ARM_ABS32 .text.motorStopAll
ca0: 04000000 streq r0, [r0], #-0
ca4: 01000000 mrseq r0, (UNDEF: 0)
ca8: 000cb79c muleq ip, ip, r7
cac: 00043700 andeq r3, r4, r0, lsl #14
cae: R_ARM_ABS32 .text.motorStopAll
cb0: 101d0000 andsne r0, sp, r0
cb4: 27000000 strcs r0, [r0, -r0]
cb8: 00000542 andeq r0, r0, r2, asr #10
cb8: R_ARM_ABS32 .debug_str
cbc: 0000e001 andeq lr, r0, r1
cbe: R_ARM_ABS32 .text.pinMode
cc0: 00200000 eoreq r0, r0, r0
cc4: 9c010000 stcls 0, cr0, [r1], {-0}
cc8: 00000cf4 strdeq r0, [r0], -r4
ccc: 6e69702a cdpvs 0, 6, cr7, cr9, cr10, {1}
cd0: 49e00100 stmibmi r0!, {r8}^
cd4: c7000000 strgt r0, [r0, -r0]
cd7: R_ARM_ABS32 .debug_loc
cd8: 1d000005 stcne 0, cr0, [r0, #-20] ; 0xffffffec
cdc: 000000f2 strdeq r0, [r0], -r2
cdc: R_ARM_ABS32 .debug_str
ce0: 0049e001 subeq lr, r9, r1
ce4: 05f30000 ldrbeq r0, [r3, #0]!
ce6: R_ARM_ABS32 .debug_loc
ce8: 16370000 ldrtne r0, [r7], -r0
ceb: R_ARM_ABS32 .text.pinMode
cec: 2b000000 blcs cf4 <.debug_info+0xcf4>
cf0: 00000010 andeq r0, r0, r0, lsl r0
cf4: 0000f732 andeq pc, r0, r2, lsr r7 ; <UNPREDICTABLE>
cf5: R_ARM_ABS32 .debug_str
cf8: 25e60100 strbcs r0, [r6, #256]! ; 0x100
cfc: 00000000 andeq r0, r0, r0
cff: R_ARM_ABS32 .text.powerLevelBackup
d00: 18000000 stmdane r0, {} ; <UNPREDICTABLE>
d04: 01000000 mrseq r0, (UNDEF: 0)
d08: 000d319c muleq sp, ip, r1
d0c: 06603000 strbteq r3, [r0], -r0
d10: 00000000 andeq r0, r0, r0
d12: R_ARM_ABS32 .text.powerLevelBackup
d14: 000c0000 andeq r0, ip, r0
d18: e7010000 str r0, [r1, -r0]
d1c: 00000026 andeq r0, r0, r6, lsr #32
d1d: R_ARM_ABS32 .text.powerLevelBackup
d20: 00000c00 andeq r0, r0, r0, lsl #24
d24: 06703400 ldrbteq r3, [r0], -r0, lsl #8
d28: 061f0000 ldreq r0, [pc], -r0
d2a: R_ARM_ABS32 .debug_loc
d2c: 00000000 andeq r0, r0, r0
d30: 01183200 tsteq r8, r0, lsl #4
d32: R_ARM_ABS32 .debug_str
d34: eb010000 bl 40d3c <_taskRunLoopHelper+0x40d3c>
d38: 00000025 andeq r0, r0, r5, lsr #32
d3c: 00000000 andeq r0, r0, r0
d3c: R_ARM_ABS32 .text.powerLevelMain
d40: 00000018 andeq r0, r0, r8, lsl r0
d44: 0d6e9c01 stcleq 12, cr9, [lr, #-4]!
d48: 7c300000 ldcvc 0, cr0, [r0], #-0
d4c: 00000006 andeq r0, r0, r6
d4f: R_ARM_ABS32 .text.powerLevelMain
d50: 0c000000 stceq 0, cr0, [r0], {-0}
d54: 01000000 mrseq r0, (UNDEF: 0)
d58: 000026ec andeq r2, r0, ip, ror #13
d5a: R_ARM_ABS32 .text.powerLevelMain
d5c: 000c0000 andeq r0, ip, r0
d60: 8c340000 ldchi 0, cr0, [r4], #-0
d64: 32000006 andcc r0, r0, #6
d67: R_ARM_ABS32 .debug_loc
d68: 00000006 andeq r0, r0, r6
d6c: f7270000 ; <UNDEFINED> instruction: 0xf7270000
d6f: R_ARM_ABS32 .debug_str
d70: 01000002 tsteq r0, r2
d74: 000000f0 strdeq r0, [r0], -r0 ; <UNPREDICTABLE>
d75: R_ARM_ABS32 .text.setTeamName
d78: 00002c00 andeq r2, r0, r0, lsl #24
d7c: c69c0100 ldrgt r0, [ip], r0, lsl #2
d80: 2f00000d svccs 0x0000000d
d84: 000004df ldrdeq r0, [r0], -pc ; <UNPREDICTABLE>
d84: R_ARM_ABS32 .debug_str
d88: 04fbf001 ldrbteq pc, [fp], #1 ; <UNPREDICTABLE>
d8c: 50010000 andpl r0, r1, r0
d90: 00069830 andeq r9, r6, r0, lsr r8
d94: 00000200 andeq r0, r0, r0, lsl #4
d95: R_ARM_ABS32 .text.setTeamName
d98: 00002200 andeq r2, r0, r0, lsl #4
d9c: 2df10100 ldfcse f0, [r1]
da0: 000006a4 andeq r0, r0, r4, lsr #13
da4: 00000645 andeq r0, r0, r5, asr #12
da4: R_ARM_ABS32 .debug_loc
da8: 00000226 andeq r0, r0, r6, lsr #4
da9: R_ARM_ABS32 .text.setTeamName
dac: 00002200 andeq r2, r0, r0, lsl #4
db0: 06af3400 strteq r3, [pc], r0, lsl #8
db4: 067a0000 ldrbteq r0, [sl], -r0
db6: R_ARM_ABS32 .debug_loc
db8: b8340000 ldmdalt r4!, {} ; <UNPREDICTABLE>
dbc: 8d000006 stchi 0, cr0, [r0, #-24] ; 0xffffffe8
dbf: R_ARM_ABS32 .debug_loc
dc0: 00000006 andeq r0, r0, r6
dc4: 9b250000 blls 940008 <_taskRunLoopHelper+0x940008>
dc7: R_ARM_ABS32 .debug_str
dc8: 01000000 mrseq r0, (UNDEF: 0)
dcc: 000516f7 strdeq r1, [r5], -r7
dd0: 00000000 andeq r0, r0, r0
dd1: R_ARM_ABS32 .text.taskRunLoop
dd4: 00002800 andeq r2, r0, r0, lsl #16
dd8: 3d9c0100 ldfccs f0, [ip]
ddc: 2a00000e bcs e1c <.debug_info+0xe1c>
de0: 01006e66 tsteq r0, r6, ror #28
de4: 0004f4f7 strdeq pc, [r4], -r7
de8: 0006da00 andeq sp, r6, r0, lsl #20
de9: R_ARM_ABS32 .debug_loc
dec: 02811d00 addeq r1, r1, #0, 26
dee: R_ARM_ABS32 .debug_str
df0: f7010000 ; <UNDEFINED> instruction: 0xf7010000
df4: 000008b3 ; <UNDEFINED> instruction: 0x000008b3
df8: 0000071e andeq r0, r0, lr, lsl r7
df8: R_ARM_ABS32 .debug_loc
dfc: 00746c20 rsbseq r6, r4, r0, lsr #24
e00: 0761f901 strbeq pc, [r1, -r1, lsl #18]! ; <UNPREDICTABLE>
e04: 07620000 strbeq r0, [r2, -r0]!
e06: R_ARM_ABS32 .debug_loc
e08: 0c210000 stceq 0, cr0, [r1], #-0
e0b: R_ARM_ABS32 .text.taskRunLoop
e0c: 47000000 strmi r0, [r0, -r0]
e10: 1d000010 stcne 0, cr0, [r0, #-64] ; 0xffffffc0
e14: 2200000e andcs r0, r0, #14
e18: 38015001 stmdacc r1, {r0, ip, lr}
e1c: 00222800 eoreq r2, r2, r0, lsl #16
e1e: R_ARM_ABS32 .text.taskRunLoop
e20: 105c0000 subsne r0, ip, r0
e24: 01220000 ; <UNDEFINED> instruction: 0x01220000
e28: 22330153 eorscs r0, r3, #-1073741804 ; 0xc0000014
e2c: 0a035101 beq d5238 <_taskRunLoopHelper+0xd5238>
e30: 01220200 ; <UNDEFINED> instruction: 0x01220200
e34: 00030550 andeq r0, r3, r0, asr r5
e37: R_ARM_ABS32 _taskRunLoopHelper
e38: 00000000 andeq r0, r0, r0
e3c: 03b13a00 ; <UNDEFINED> instruction: 0x03b13a00
e3e: R_ARM_ABS32 .debug_str
e40: 02010000 andeq r0, r1, #0
e44: 00000001 andeq r0, r0, r1
e45: R_ARM_ABS32 .text.wait
e48: 00000400 andeq r0, r0, r0, lsl #8
e4c: 759c0100 ldrvc r0, [ip, #256] ; 0x100
e50: 3b00000e blcc e90 <.debug_info+0xe90>
e54: 000001e1 andeq r0, r0, r1, ror #3
e54: R_ARM_ABS32 .debug_str
e58: b3010201 movwlt r0, #4609 ; 0x1201
e5c: 80000008 andhi r0, r0, r8
e5f: R_ARM_ABS32 .debug_loc
e60: 28000007 stmdacs r0, {r0, r1, r2}
e64: 00000004 andeq r0, r0, r4
e64: R_ARM_ABS32 .text.wait
e68: 00000fce andeq r0, r0, lr, asr #31
e6c: 03500122 cmpeq r0, #-2147483640 ; 0x80000008
e70: 005001f3 ldrsheq r0, [r0], #-19 ; 0xffffffed
e74: 003f3a00 eorseq r3, pc, r0, lsl #20
e76: R_ARM_ABS32 .debug_str
e78: 07010000 streq r0, [r1, -r0]
e7c: 00000001 andeq r0, r0, r1
e7d: R_ARM_ABS32 .text.waitUntil
e80: 00000400 andeq r0, r0, r0, lsl #8
e84: c49c0100 ldrgt r0, [ip], #256 ; 0x100
e88: 3b00000e blcc ec8 <.debug_info+0xec8>
e8c: 0000037e andeq r0, r0, lr, ror r3
e8c: R_ARM_ABS32 .debug_str
e90: c4010701 strgt r0, [r1], #-1793 ; 0xfffff8ff
e94: a100000e tstge r0, lr
e97: R_ARM_ABS32 .debug_loc
e98: 3b000007 blcc ebc <.debug_info+0xebc>
e9c: 000001e1 andeq r0, r0, r1, ror #3
e9c: R_ARM_ABS32 .debug_str
ea0: 86010701 strhi r0, [r1], -r1, lsl #14
ea4: c2000000 andgt r0, r0, #0
ea7: R_ARM_ABS32 .debug_loc
ea8: 28000007 stmdacs r0, {r0, r1, r2}
eac: 00000004 andeq r0, r0, r4
eac: R_ARM_ABS32 .text.waitUntil
eb0: 00000fa3 andeq r0, r0, r3, lsr #31
eb4: 03510122 cmpeq r1, #-2147483640 ; 0x80000008
eb8: 225101f3 subscs r0, r1, #-1073741764 ; 0xc000003c
ebc: f3035001 vhadd.u8 d5, d3, d1
ec0: 00005001 andeq r5, r0, r1
ec4: 00860410 addeq r0, r6, r0, lsl r4
ec8: da0d0000 ble 340ed0 <_taskRunLoopHelper+0x340ed0>
ecc: da00000e ble f0c <.debug_info+0xf0c>
ed0: 0e00000e cdpeq 0, 0, cr0, cr0, cr14, {0}
ed4: 000000e4 andeq r0, r0, r4, ror #1
ed8: 0410001a ldreq r0, [r0], #-26 ; 0xffffffe6
edc: 00000ee0 andeq r0, r0, r0, ror #29
ee0: 00016912 andeq r6, r1, r2, lsl r9
ee4: 035d3c00 cmpeq sp, #0, 24
ee6: R_ARM_ABS32 .debug_str
ee8: 9c020000 stcls 0, cr0, [r2], {-0}
eec: 00000ef0 strdeq r0, [r0], -r0 ; <UNPREDICTABLE>
ef0: 000eca12 andeq ip, lr, r2, lsl sl
ef4: 00ad0d00 adceq r0, sp, r0, lsl #26
ef8: 0f050000 svceq 0x00050000
efc: e40e0000 str r0, [lr], #-0
f00: 1a000000 bne f08 <.debug_info+0xf08>
f04: 03f43c00 mvnseq r3, #0, 24
f06: R_ARM_ABS32 .debug_str
f08: 9d020000 stcls 0, cr0, [r2, #-0]
f0c: 00000f10 andeq r0, r0, r0, lsl pc
f10: 000ef512 andeq pc, lr, r2, lsl r5 ; <UNPREDICTABLE>
f14: 03e60d00 mvneq r0, #0, 26
f18: 0f250000 svceq 0x00250000
f1c: e40e0000 str r0, [lr], #-0
f20: 07000000 streq r0, [r0, -r0]
f24: 024a3c00 subeq r3, sl, #0, 24
f26: R_ARM_ABS32 .debug_str
f28: a1020000 mrsge r0, (UNDEF: 2)
f2c: 00000f15 andeq r0, r0, r5, lsl pc
f30: 0002423c andeq r4, r2, ip, lsr r2
f31: R_ARM_ABS32 .debug_str
f34: 75500300 ldrbvc r0, [r0, #-768] ; 0xfffffd00
f38: 0d000001 stceq 0, cr0, [r0, #-4]
f3c: 000000b8 strheq r0, [r0], -r8
f40: 00000f4b andeq r0, r0, fp, asr #30
f44: 0000e40e andeq lr, r0, lr, lsl #8
f48: 3c000f00 stccc 15, cr0, [r0], {-0}
f4c: 0000073c andeq r0, r0, ip, lsr r7
f4c: R_ARM_ABS32 .debug_str
f50: 0f565203 svceq 0x00565203
f54: 3b060000 blcc 180f5c <_taskRunLoopHelper+0x180f5c>
f58: 3c00000f stccc 0, cr0, [r0], {15}
f5c: 000000d7 ldrdeq r0, [r0], -r7
f5c: R_ARM_ABS32 .debug_str
f60: 0f665203 svceq 0x00665203
f64: 3b060000 blcc 180f6c <_taskRunLoopHelper+0x180f6c>
f68: 3c00000f stccc 0, cr0, [r0], {15}
f6c: 00000403 andeq r0, r0, r3, lsl #8
f6c: R_ARM_ABS32 .debug_str
f70: 05065403 streq r5, [r6, #-1027] ; 0xfffffbfd
f74: c13c0000 teqgt ip, r0
f77: R_ARM_ABS32 .debug_str
f78: 0a000000 beq f80 <.debug_info+0xf80>
f7c: 0000ff47 andeq pc, r0, r7, asr #30
f80: 028b3d00 addeq r3, fp, #0, 26
f82: R_ARM_ABS32 .debug_str
f84: 560b0000 strpl r0, [fp], -r0
f88: 00000f92 muleq r0, r2, pc ; <UNPREDICTABLE>
f8c: 0000eb14 andeq lr, r0, r4, lsl fp
f90: 5e3e0000 cdppl 0, 3, cr0, cr14, cr0, {0}
f93: R_ARM_ABS32 .debug_str
f94: 0c000000 stceq 0, cr0, [r0], {-0}
f98: 0000ed3d andeq lr, r0, sp, lsr sp
f9c: 000fa300 andeq sl, pc, r0, lsl #6
fa0: 3d003f00 stccc 15, cr3, [r0, #-0]
fa4: 0000039d muleq r0, sp, r3
fa4: R_ARM_ABS32 .debug_str
fa8: 0fb9d209 svceq 0x00b9d209
fac: c4140000 ldrgt r0, [r4], #-0
fb0: 1400000e strne r0, [r0], #-14
fb4: 000008b3 ; <UNDEFINED> instruction: 0x000008b3
fb8: 03474000 movteq r4, #28672 ; 0x7000
fba: R_ARM_ABS32 .debug_str
fbc: e6020000 str r0, [r2], -r0
fc0: 000000b8 strheq r0, [r0], -r8
fc4: 00000fce andeq r0, r0, lr, asr #31
fc8: 0000ce14 andeq ip, r0, r4, lsl lr
fcc: 383d0000 ldmdacc sp!, {} ; <UNPREDICTABLE>
fcf: R_ARM_ABS32 .debug_str
fd0: 09000002 stmdbeq r0, {r1}
fd4: 000fdfbe ; <UNDEFINED> instruction: 0x000fdfbe
fd8: 08b31400 ldmeq r3!, {sl, ip}
fdc: 3e000000 cdpcc 0, 0, cr0, cr0, cr0, {0}
fe0: 000003c5 andeq r0, r0, r5, asr #7
fe0: R_ARM_ABS32 .debug_str
fe4: 00ed3b0c rsceq r3, sp, ip, lsl #22
fe8: 0ff00000 svceq 0x00f00000 ; IMB
fec: 003f0000 eorseq r0, pc, r0
ff0: 00004e41 andeq r4, r0, r1, asr #28
ff1: R_ARM_ABS32 .debug_str
ff4: 01240200 ; <UNDEFINED> instruction: 0x01240200
ff8: 000000ad andeq r0, r0, sp, lsr #1
ffc: 00001006 andeq r1, r0, r6
1000: 0000ce14 andeq ip, r0, r4, lsl lr
1004: 25420000 strbcs r0, [r2, #-0]
1007: R_ARM_ABS32 .debug_str
1008: 02000005 andeq r0, r0, #5
100c: 101d0126 andsne r0, sp, r6, lsr #2
1010: ce140000 cdpgt 0, 1, cr0, cr4, cr0, {0}
1014: 14000000 strne r0, [r0], #-0
1018: 000000ad andeq r0, r0, sp, lsr #1
101c: 00a74300 adceq r4, r7, r0, lsl #6
101e: R_ARM_ABS32 .debug_str
1020: 28020000 stmdacs r2, {} ; <UNPREDICTABLE>
1024: 00102b01 andseq r2, r0, r1, lsl #22
1028: 42003f00 andmi r3, r0, #0, 30
102c: 00000185 andeq r0, r0, r5, lsl #3
102c: R_ARM_ABS32 .debug_str
1030: 47011f02 strmi r1, [r1, -r2, lsl #30]
1034: 14000010 strne r0, [r0], #-16
1038: 00000596 muleq r0, r6, r5
103c: 0000ce14 andeq ip, r0, r4, lsl lr
1040: 00ce1400 sbceq r1, lr, r0, lsl #8
1044: 40000000 andmi r0, r0, r0
1048: 00000148 andeq r0, r0, r8, asr #2
1048: R_ARM_ABS32 .debug_str
104c: 00eb610b rsceq r6, fp, fp, lsl #2
1050: 105c0000 subsne r0, ip, r0
1054: d9140000 ldmdble r4, {} ; <UNPREDICTABLE>
1058: 00000000 andeq r0, r0, r0
105c: 00016f40 andeq r6, r1, r0, asr #30
105d: R_ARM_ABS32 .debug_str
1060: 16950900 ldrne r0, [r5], r0, lsl #18
1064: 80000005 andhi r0, r0, r5
1068: 14000010 strne r0, [r0], #-16
106c: 00000521 andeq r0, r0, r1, lsr #10
1070: 00108014 andseq r8, r0, r4, lsl r0
1074: 00eb1400 rsceq r1, fp, r0, lsl #8
1078: 80140000 andshi r0, r4, r0
107c: 00000010 andeq r0, r0, r0, lsl r0
1080: 00002512 andeq r2, r0, r2, lsl r5
...
Disassembly of section .debug_abbrev:
00000000 <.debug_abbrev>:
void (*fn)(void);
clock_t period;
} LoopTask;
// Helper task for taskRunLoop()
static void _taskRunLoopHelper(void *data) {
0: 25011101 strcs r1, [r1, #-257] ; 0xfffffeff
// Extract information from pointer
LoopTask *info = (LoopTask*)data;
void (*fn)(void) = info->fn;
clock_t period = info->period;
4: 030b130e movweq r1, #45838 ; 0xb30e
// Avoid leaking data
free(data);
8: 550e1b0e strpl r1, [lr, #-2830] ; 0xfffff4f2
// Start counter
clock_t now = timeLowRes();
c: 10011117 andne r1, r1, r7, lsl r1
10: 02000017 andeq r0, r0, #23
uint16_t sf = svFlags & (SV_AUTONOMOUS | SV_ENABLED | SV_FMS);
14: 0b0b0024 bleq 2c00ac <_taskRunLoopHelper+0x2c00ac>
18: 0e030b3e vmoveq.16 d3[0], r0
do {
fn();
taskDelayUntil(&now, period);
1c: 16030000 strne r0, [r3], -r0
20: 3a0e0300 bcc 380c28 <_taskRunLoopHelper+0x380c28>
// Auto-terminate on mode switch, drop, or disable
} while ((svFlags & (SV_AUTONOMOUS | SV_ENABLED | SV_FMS)) == sf);
24: 490b3b0b stmdbmi fp, {r0, r1, r3, r8, r9, fp, ip, sp}
28: 04000013 streq r0, [r0], #-19 ; 0xffffffed
2c: 0b0b0024 bleq 2c00c4 <_taskRunLoopHelper+0x2c00c4>
}
30: 08030b3e stmdaeq r3, {r1, r2, r3, r4, r5, r8, r9, fp}
34: 0f050000 svceq 0x00050000
// analogCalibrate - Calibrates the analog sensor on the specified channel, assuming that it is
// not actively changing. Approximately 512 samples are taken, 1 ms apart, for a 0.5 s period
// of calibration. The average value thus calculated is returned and stored for later calls
// to analogReadCalibrated()
int analogCalibrate(unsigned char channel) {
channel--;
38: 000b0b00 andeq r0, fp, r0, lsl #22
3c: 00350600 eorseq r0, r5, r0, lsl #12
if (channel < BOARD_NR_ADC_PINS) {
40: 00001349 andeq r1, r0, r9, asr #6
44: 0b011307 bleq 44c68 <_taskRunLoopHelper+0x44c68>
// We have the true channel, do this in a loop
uint32_t total = 0, i;
for (i = 0; i < 512; i++) {
total += adcRead(channel);
48: 3b0b3a0b blcc 2ce87c <_taskRunLoopHelper+0x2ce87c>
4c: 00130105 andseq r0, r3, r5, lsl #2
taskDelay(1);
50: 000d0800 andeq r0, sp, r0, lsl #16
54: 0b3a0803 bleq e82068 <_taskRunLoopHelper+0xe82068>
int analogCalibrate(unsigned char channel) {
channel--;
if (channel < BOARD_NR_ADC_PINS) {
// We have the true channel, do this in a loop
uint32_t total = 0, i;
for (i = 0; i < 512; i++) {
58: 1349053b movtne r0, #38203 ; 0x953b
total += adcRead(channel);
taskDelay(1);
}
// Store value (fixed to correctly round to nearest to avoid positive bias)
_analogState[channel].calibValue = (total + 16) >> 5;
5c: 00000b38 andeq r0, r0, r8, lsr fp
60: 03000d09 movweq r0, #3337 ; 0xd09
64: 3b0b3a0e blcc 2ce8a4 <_taskRunLoopHelper+0x2ce8a4>
68: 38134905 ldmdacc r3, {r0, r2, r8, fp, lr}
return (int)((total + 256) >> 9);
6c: 0a00000b beq a0 <.debug_abbrev+0xa0>
70: 0e030016 mcreq 0, 0, r0, cr3, cr6, {0}
}
return 0;
74: 053b0b3a ldreq r0, [fp, #-2874]! ; 0xfffff4c6
}
78: 00001349 andeq r1, r0, r9, asr #6
// analogRead - Reads an analog input channel 1-8 and returns the 12-bit value from 0 to 4095
int analogRead(unsigned char channel) {
channel--;
7c: 0b01130b bleq 44cb0 <_taskRunLoopHelper+0x44cb0>
if (channel < BOARD_NR_ADC_PINS)
80: 3b0b3a0b blcc 2ce8b4 <_taskRunLoopHelper+0x2ce8b4>
84: 0013010b andseq r0, r3, fp, lsl #2
return (int)adcRead(channel);
88: 000d0c00 andeq r0, sp, r0, lsl #24
return 0;
8c: 0b3a0e03 bleq e838a0 <_taskRunLoopHelper+0xe838a0>
// analogReadCalibrated - Reads the calibrated value of an analog input channel 1-8;
// analogCalibrate() must be run first. This is inappropriate for integrated sensors as the
// round-off error can accumulate. Use analogReadCalibratedHR() instead.
int analogReadCalibrated(unsigned char channel) {
channel--;
90: 13490b3b movtne r0, #39739 ; 0x9b3b
94: 00000b38 andeq r0, r0, r8, lsr fp
if (channel < BOARD_NR_ADC_PINS)
98: 4901010d stmdbmi r1, {r0, r2, r3, r8}
return (int)adcRead(channel) - (int)(_analogState[channel].calibValue >> 4);
9c: 00130113 andseq r0, r3, r3, lsl r1
a0: 00210e00 eoreq r0, r1, r0, lsl #28
a4: 0b2f1349 bleq bc4dd0 <_taskRunLoopHelper+0xbc4dd0>
a8: 0d0f0000 stceq 0, cr0, [pc, #-0] ; b0 <.debug_abbrev+0xb0>
ac: 3a080300 bcc 200cb4 <_taskRunLoopHelper+0x200cb4>
b0: 490b3b0b stmdbmi fp, {r0, r1, r3, r8, r9, fp, ip, sp}
return 0;
}
b4: 000b3813 andeq r3, fp, r3, lsl r8
b8: 000f1000 andeq r1, pc, r0
// drift due to round-off.
int analogReadCalibratedHR(unsigned char channel) {
// The value returned actually has 16 bits of "precision", even though the ADC only reads
// 12 bits, so that errors induced by the average value being between two values come out
// in the wash when integrated over time. Think of the value as the true value << 4.
channel--;
bc: 13490b0b movtne r0, #39691 ; 0x9b0b
c0: 15110000 ldrne r0, [r1, #-0]
if (channel < BOARD_NR_ADC_PINS)
c4: 00192700 andseq r2, r9, r0, lsl #14
return (int)(adcRead(channel) << 4) - (int)(_analogState[channel].calibValue);
c8: 00261200 eoreq r1, r6, r0, lsl #4
cc: 00001349 andeq r1, r0, r9, asr #6
d0: 27011513 smladcs r1, r3, r5, r1
d4: 00130119 andseq r0, r3, r9, lsl r1
d8: 00051400 andeq r1, r5, r0, lsl #8
dc: 00001349 andeq r1, r0, r9, asr #6
return 0;
}
e0: 03012e15 movweq r2, #7701 ; 0x1e15
e4: 3b0b3a0e blcc 2ce924 <_taskRunLoopHelper+0x2ce924>
// delay - taskDelay alias
void delay(const unsigned long time) {
taskDelay((clock_t)time);
e8: 4919270b ldmdbmi r9, {r0, r1, r3, r8, r9, sl, sp}
}
// delayMicroseconds - Wait for approximately the given number of microseconds
void delayMicroseconds(const unsigned long time) {
ec: 010b2013 tsteq fp, r3, lsl r0
clock_t us = (clock_t)time;
if (us) {
f0: 16000013 ; <UNDEFINED> instruction: 0x16000013
/*us *= 12; us--;
asm volatile(" mov r0, %[us]\n\t"
"1: subs r0, #1\n\t"
" bhi 1b\n\t"
: : [us] "r" (us) : "r0");*/
if (us > 1000) {
f4: 0e030005 cdpeq 0, 0, cr0, cr3, cr5, {0}
// Wait off the milliseconds part first
clock_t millis = (clock_t)(us / 1000UL);
us %= 1000UL;
f8: 0b3b0b3a bleq ec2de8 <_taskRunLoopHelper+0xec2de8>
fc: 00001349 andeq r1, r0, r9, asr #6
100: 03000517 movweq r0, #1303 ; 0x517
taskDelay(millis);
104: 3b0b3a08 blcc 2ce92c <_taskRunLoopHelper+0x2ce92c>
}
if (us) {
108: 0013490b andseq r4, r3, fp, lsl #18
10c: 012e1800 ; <UNDEFINED> instruction: 0x012e1800
// Spin on the highres timer value (next IRQ might be up to 1ms away!)
// Power consumption is bad, CPU usage possibly worse, but accuracy is acceptable
uint16_t start = TIM8->CNT;
110: 0b3a0e03 bleq e83924 <_taskRunLoopHelper+0xe83924>
114: 19270b3b stmdbne r7!, {r0, r1, r3, r4, r5, r8, r9, fp}
while (TIM8->CNT - start < us);
118: 13010b20 movwne r0, #6944 ; 0x1b20
11c: 34190000 ldrcc r0, [r9], #-0
120: 3a0e0300 bcc 380d28 <_taskRunLoopHelper+0x380d28>
124: 490b3b0b stmdbmi fp, {r0, r1, r3, r8, r9, fp, ip, sp}
}
}
}
// digitalRead - Gets the digital value (1 or 0) of a pin configured as a digital input
bool digitalRead(unsigned char pin) {
128: 1a000013 bne 17c <.debug_abbrev+0x17c>
if (pin >= BOARD_NR_GPIO_PINS)
return 0;
return ioGetInput((GPIO_TypeDef*)_pinLookupTable[pin], (uint8_t)_pinIndexTable[pin]);
12c: 08030034 stmdaeq r3, {r2, r4, r5}
130: 0b3b0b3a bleq ec2e20 <_taskRunLoopHelper+0xec2e20>
}
// ioGetInput - Gets the digital value (1 or 0) of a pin configured as a digital input
static INLINE bool ioGetInput(GPIO_TypeDef* port, uint32_t pin) {
// Shift right that many bits, then mask everything but the ones
return ((port->IDR >> (pin & 0x0F)) & 0x01) != 0;
134: 00001349 andeq r1, r0, r9, asr #6
138: 03012e1b movweq r2, #7707 ; 0x1e1b
13c: 3b0b3a0e blcc 2ce97c <_taskRunLoopHelper+0x2ce97c>
140: 2013490b andscs r4, r3, fp, lsl #18
144: 0013010b andseq r0, r3, fp, lsl #2
}
// digitalRead - Gets the digital value (1 or 0) of a pin configured as a digital input
bool digitalRead(unsigned char pin) {
if (pin >= BOARD_NR_GPIO_PINS)
return 0;
148: 012e1c00 ; <UNDEFINED> instruction: 0x012e1c00
return ioGetInput((GPIO_TypeDef*)_pinLookupTable[pin], (uint8_t)_pinIndexTable[pin]);
}
14c: 0b3a0e03 bleq e83960 <_taskRunLoopHelper+0xe83960>
150: 19270b3b stmdbne r7!, {r0, r1, r3, r4, r5, r8, r9, fp}
// digitalWrite - Sets the digital value (1 or 0) of a pin configured as a digital output
void digitalWrite(unsigned char pin, bool value) {
// We will let this work when disabled, even though it might change a solenoid, since it
// is needed to set initial solenoid states in initializeIO() when enabled/disabled is
// undefined.
if (pin < BOARD_NR_GPIO_PINS)
154: 06120111 ; <UNDEFINED> instruction: 0x06120111
158: 42961840 addsmi r1, r6, #64, 16 ; 0x400000
ioSetOutput((GPIO_TypeDef*)_pinLookupTable[pin], (uint8_t)_pinIndexTable[pin], value);
15c: 00130119 andseq r0, r3, r9, lsl r1
160: 00051d00 andeq r1, r5, r0, lsl #26
164: 0b3a0e03 bleq e83978 <_taskRunLoopHelper+0xe83978>
168: 13490b3b movtne r0, #39739 ; 0x9b3b
return ((port->ODR >> (pin & 0x0F)) & 0x01) != 0;
}
// ioSetOutput - Sets the digital value (1 or 0) of a pin configured as a digital output
static INLINE void ioSetOutput(GPIO_TypeDef* port, uint32_t pin, bool value) {
if (value)
16c: 00001702 andeq r1, r0, r2, lsl #14
// Atomic bit set
port->BSRR = ((uint32_t)0x00000001) << (pin & 0x0F);
170: 0300341e movweq r3, #1054 ; 0x41e
else
// Atomic bit reset
port->BRR = ((uint32_t)0x00000001) << (pin & 0x0F);
174: 3b0b3a0e blcc 2ce9b4 <_taskRunLoopHelper+0x2ce9b4>
178: 0213490b andseq r4, r3, #180224 ; 0x2c000
17c: 1f000017 svcne 0x00000017
}
// isAutonomous - Checks to see if the system is in autonomous mode
bool isAutonomous() {
return (svFlags & SV_AUTONOMOUS) ? true : false;
180: 08030034 stmdaeq r3, {r2, r4, r5}
}
184: 0b3b0b3a bleq ec2e74 <_taskRunLoopHelper+0xec2e74>
188: 18021349 stmdane r2, {r0, r3, r6, r8, r9, ip}
18c: 34200000 strtcc r0, [r0], #-0
// isEnabled - Checks to see if the system is enabled
bool isEnabled() {
uint16_t flags = svFlags;
190: 3a080300 bcc 200d98 <_taskRunLoopHelper+0x200d98>
194: 490b3b0b stmdbmi fp, {r0, r1, r3, r8, r9, fp, ip, sp}
if (!(flags & SV_ENABLED)) {
if (flags & SV_FMS)
198: 00170213 andseq r0, r7, r3, lsl r2
19c: 82892100 addhi r2, r9, #0, 2
1a0: 01110101 tsteq r1, r1, lsl #2
return false;
}
return true;
}
1a4: 13011331 movwne r1, #4913 ; 0x1331
1a8: 8a220000 bhi 8801b0 <_taskRunLoopHelper+0x8801b0>
}
// svIsJoystickConnected - Checks to see if a joystick is connected
static INLINE uint8_t svIsJoystickConnected(uint8_t joystick) {
// Force in range from 0..1 (mapped from 1..2)
joystick = (joystick - 1) & (uint8_t)0x01;
1ac: 02000182 andeq r0, r0, #-2147483616 ; 0x80000020
// If both accelerometer axes are zero, the joystick is likely not plugged in
// Obviously there is a chance for false positives but extremely unlikely due to the noise
// of the analog accelerometers
return SV_IN->joystick[joystick].axis[4] != (uint8_t)0x7F ||
1b0: 18429118 stmdane r2, {r3, r4, r8, ip, pc}^
1b4: 89230000 stmdbhi r3!, {} ; <UNPREDICTABLE>
1b8: 11000182 smlabbne r0, r2, r1, r0
1bc: 00133101 andseq r3, r3, r1, lsl #2
SV_IN->joystick[joystick].axis[5] != (uint8_t)0x7F;
1c0: 82892400 addhi r2, r9, #0, 8
// Force in range from 0..1 (mapped from 1..2)
joystick = (joystick - 1) & (uint8_t)0x01;
// If both accelerometer axes are zero, the joystick is likely not plugged in
// Obviously there is a chance for false positives but extremely unlikely due to the noise
// of the analog accelerometers
return SV_IN->joystick[joystick].axis[4] != (uint8_t)0x7F ||
1c4: 01110101 tsteq r1, r1, lsl #2
1c8: 00001331 andeq r1, r0, r1, lsr r3
1cc: 3f012e25 svccc 0x00012e25
// isJoystickConnected - Checks to see if the specified joystick is plugged in
bool isJoystickConnected(unsigned char joystick) {
return svIsJoystickConnected(joystick) ? true : false;
}
1d0: 3a0e0319 bcc 380e3c <_taskRunLoopHelper+0x380e3c>
// isOnline - Checks to see if the system is connected to a FMS/competition switch
bool isOnline() {
return (svFlags & SV_FMS) ? true : false;
1d4: 270b3b0b strcs r3, [fp, -fp, lsl #22]
}
1d8: 11134919 tstne r3, r9, lsl r9
1dc: 40061201 andmi r1, r6, r1, lsl #4
1e0: 19429718 stmdbne r2, {r3, r4, r8, r9, sl, ip, pc}^
// joystickGetAnalog - Retrieve an analog axis of a joystick
int joystickGetAnalog(unsigned char joystick, unsigned char axis) {
1e4: 00001301 andeq r1, r0, r1, lsl #6
1e8: 11010b26 tstne r1, r6, lsr #22
// Safety first here
if (isOnline() && isAutonomous()) return 0;
1ec: 00061201 andeq r1, r6, r1, lsl #4
// svGetJoystickAnalog - Gets an analog joystick axis or accelerometer axis from the supervisor
// NO check on the mode when doing so
static INLINE int8_t svGetJoystickAnalog(uint8_t joystick, uint8_t axis) {
uint8_t value;
// Force in range from 0..5 (mapped from 1..6)
axis = (axis - 1) % 6;
1f0: 012e2700 ; <UNDEFINED> instruction: 0x012e2700
1f4: 0e03193f mcreq 9, 0, r1, cr3, cr15, {1}
1f8: 0b3b0b3a bleq ec2ee8 <_taskRunLoopHelper+0xec2ee8>
// Force in range from 0..1 (mapped from 1..2)
joystick = (joystick - 1) & (uint8_t)0x01;
1fc: 01111927 tsteq r1, r7, lsr #18
value = SV_IN->joystick[joystick].axis[axis];
200: 18400612 stmdane r0, {r1, r4, r9, sl}^
204: 01194297 ; <UNDEFINED> instruction: 0x01194297
208: 28000013 stmdacs r0, {r0, r1, r4}
// Prevent return of 128
if (value == 0xFF)
value = 0xFE;
value -= 127;
if (axis == 1 || axis == 2)
20c: 01018289 smlabbeq r1, r9, r2, r8
uint8_t value;
// Force in range from 0..5 (mapped from 1..6)
axis = (axis - 1) % 6;
// Force in range from 0..1 (mapped from 1..2)
joystick = (joystick - 1) & (uint8_t)0x01;
value = SV_IN->joystick[joystick].axis[axis];
210: 42950111 addsmi r0, r5, #1073741828 ; 0x40000004
// Prevent return of 128
if (value == 0xFF)
value = 0xFE;
214: 00133119 andseq r3, r3, r9, lsl r1
value -= 127;
if (axis == 1 || axis == 2)
218: 010b2900 tsteq fp, r0, lsl #18
joystick = (joystick - 1) & (uint8_t)0x01;
value = SV_IN->joystick[joystick].axis[axis];
// Prevent return of 128
if (value == 0xFF)
value = 0xFE;
value -= 127;
21c: 06120111 ; <UNDEFINED> instruction: 0x06120111
if (axis == 1 || axis == 2)
220: 00001301 andeq r1, r0, r1, lsl #6
value = -value;
224: 0300052a movweq r0, #1322 ; 0x52a
228: 3b0b3a08 blcc 2cea50 <_taskRunLoopHelper+0x2cea50>
22c: 0213490b andseq r4, r3, #180224 ; 0x2c000
230: 2b000017 blcs 294 <.debug_abbrev+0x294>
return (int)svGetJoystickAnalog(joystick, axis);
234: 1331011d teqne r1, #1073741831 ; 0x40000007
238: 17550152 ; <UNDEFINED> instruction: 0x17550152
}
// joystickGetDigital - Retrieve a digital button of a joystick
bool joystickGetDigital(unsigned char joystick, unsigned char buttonGroup,
unsigned char button) {
23c: 0b590b58 bleq 1642fa4 <_taskRunLoopHelper+0x1642fa4>
240: 052c0000 streq r0, [ip, #-0]!
// Safety first here
if (isOnline() && isAutonomous()) return false;
244: 00133100 andseq r3, r3, r0, lsl #2
248: 00052d00 andeq r2, r5, r0, lsl #26
static INLINE uint8_t svGetJoystickDigital(uint8_t joystick, uint8_t button) {
uint8_t value; volatile Joystick_TypeDef *ref;
// Force in range from 0..3 (mapped from 5..8)
button = (button - 5) & (uint8_t)0x03;
// Force in range from 0..1 (mapped from 1..2)
joystick = (joystick - 1) & (uint8_t)0x01;
24c: 17021331 smladxne r2, r1, r3, r1
ref = &SV_IN->joystick[joystick];
// 5 and 6 need some mangling to move the twos bit up to the fours
switch (button) {
250: 052e0000 streq r0, [lr, #-0]!
uint8_t value; volatile Joystick_TypeDef *ref;
// Force in range from 0..3 (mapped from 5..8)
button = (button - 5) & (uint8_t)0x03;
// Force in range from 0..1 (mapped from 1..2)
joystick = (joystick - 1) & (uint8_t)0x01;
ref = &SV_IN->joystick[joystick];
254: 3a080300 bcc 200e5c <_taskRunLoopHelper+0x200e5c>
258: 490b3b0b stmdbmi fp, {r0, r1, r3, r8, r9, fp, ip, sp}
25c: 00180213 andseq r0, r8, r3, lsl r2
// 5 and 6 need some mangling to move the twos bit up to the fours
switch (button) {
260: 00052f00 andeq r2, r5, r0, lsl #30
264: 0b3a0e03 bleq e83a78 <_taskRunLoopHelper+0xe83a78>
// 6
value = ref->button56 >> 2;
return ((value & 0x02) << 1) | (value & 0x01);
case 2:
// 7
return ref->button78 >> 4;
268: 13490b3b movtne r0, #39739 ; 0x9b3b
26c: 00001802 andeq r1, r0, r2, lsl #16
270: 31011d30 tstcc r1, r0, lsr sp
274: 12011113 andne r1, r1, #-1073741820 ; 0xc0000004
return (svGetJoystickDigital(joystick, buttonGroup) & button) ? true : false;
}
278: 590b5806 stmdbpl fp, {r1, r2, fp, ip, lr}
ref = &SV_IN->joystick[joystick];
// 5 and 6 need some mangling to move the twos bit up to the fours
switch (button) {
case 0:
// 5
value = ref->button56;
27c: 3100000b tstcc r0, fp
return ((value & 0x02) << 1) | (value & 0x01);
case 1:
// 6
value = ref->button56 >> 2;
280: 193f002e ldmdbne pc!, {r1, r2, r3, r5} ; <UNPREDICTABLE>
return ((value & 0x02) << 1) | (value & 0x01);
284: 0b3a0e03 bleq e83a98 <_taskRunLoopHelper+0xe83a98>
288: 13490b3b movtne r0, #39739 ; 0x9b3b
28c: 06120111 ; <UNDEFINED> instruction: 0x06120111
290: 42971840 addsmi r1, r7, #64, 16 ; 0x400000
case 2:
// 7
return ref->button78 >> 4;
default:
// 8 (No other case is possible...)
return ref->button78 & 0x0F;
294: 32000019 andcc r0, r0, #25
// joystickGetDigital - Retrieve a digital button of a joystick
bool joystickGetDigital(unsigned char joystick, unsigned char buttonGroup,
unsigned char button) {
// Safety first here
if (isOnline() && isAutonomous()) return false;
return (svGetJoystickDigital(joystick, buttonGroup) & button) ? true : false;
298: 193f012e ldmdbne pc!, {r1, r2, r3, r5, r8} ; <UNPREDICTABLE>
29c: 0b3a0e03 bleq e83ab0 <_taskRunLoopHelper+0xe83ab0>
2a0: 13490b3b movtne r0, #39739 ; 0x9b3b
2a4: 06120111 ; <UNDEFINED> instruction: 0x06120111
}
// micros - Arduino-compatible alias for timeHighRes()
unsigned long micros() {
return (unsigned long)timeHighRes();
2a8: 42971840 addsmi r1, r7, #64, 16 ; 0x400000
}
// millis - Arduino-compatible alias for timeLowRes()
unsigned long millis() {
return (unsigned long)timeLowRes();
2ac: 00130119 andseq r0, r3, r9, lsl r1
}
// motorGet - Gets last commanded speed of the specified motor channel; this speed is reset
// to 0 if motors are stopped by the kernel for any reason
int motorGet(unsigned char channel) {
2b0: 011d3300 tsteq sp, r0, lsl #6
// Convert range
return (int)motorControlGet(channel) - 127;
2b4: 01111331 tsteq r1, r1, lsr r3
}
2b8: 0b580612 bleq 1601b08 <_taskRunLoopHelper+0x1601b08>
// motorSet - Sets the speed of the specified motor channel from 1 to 10, where -127 is full
// reverse and 127 is full forward, with 0 being off
void motorSet(unsigned char channel, int speed) {
2bc: 13010b59 movwne r0, #7001 ; 0x1b59
if (isEnabled()) {
2c0: 34340000 ldrtcc r0, [r4], #-0
2c4: 02133100 andseq r3, r3, #0, 2
int ns = speed + 127;
// Equalize the bias
if (ns < 0) ns = 0;
2c8: 35000017 strcc r0, [r0, #-23] ; 0xffffffe9
if (ns > 255) ns = 255;
2cc: 1331011d teqne r1, #1073741831 ; 0x40000007
2d0: 17550152 ; <UNDEFINED> instruction: 0x17550152
// reverse and 127 is full forward, with 0 being off
void motorSet(unsigned char channel, int speed) {
if (isEnabled()) {
int ns = speed + 127;
// Equalize the bias
if (ns < 0) ns = 0;
2d4: 0b590b58 bleq 164303c <_taskRunLoopHelper+0x164303c>
if (ns > 255) ns = 255;
motorControlSet(channel, (uint8_t)ns);
}
}
2d8: 00001301 andeq r1, r0, r1, lsl #6
if (isEnabled()) {
int ns = speed + 127;
// Equalize the bias
if (ns < 0) ns = 0;
if (ns > 255) ns = 255;
motorControlSet(channel, (uint8_t)ns);
2dc: 55010b36 strpl r0, [r1, #-2870] ; 0xfffff4ca
2e0: 37000017 smladcc r0, r7, r0, r0
}
// motorStop - Stops the motor on the specified channel, equivalent to calling motorSet() with
// an argument of zero; this performs a coasting stop, not an active brake
void motorStop(unsigned char channel) {
motorControlSet(channel, 127);
2e4: 00018289 andeq r8, r1, r9, lsl #5
2e8: 42950111 addsmi r0, r5, #1073741828 ; 0x40000004
// motorStopAll - Stops all motors; significantly faster than looping through all motor ports
// and calling motorSet(channel, 0) on each one
void motorStopAll() {
// It is safe to stop all motors when disabled, as that is their disabled state anyways.
motorControlStop();
2ec: 00133119 andseq r3, r3, r9, lsl r1
}
// pinMode - Configures the pin as an input or output with a variety of settings
void pinMode(unsigned char pin, unsigned char mode) {
if (pin < BOARD_NR_GPIO_PINS)
2f0: 010b3800 tsteq fp, r0, lsl #16
// It is safe to stop all motors when disabled, as that is their disabled state anyways.
motorControlStop();
}
// pinMode - Configures the pin as an input or output with a variety of settings
void pinMode(unsigned char pin, unsigned char mode) {
2f4: 13011755 movwne r1, #5973 ; 0x1755
if (pin < BOARD_NR_GPIO_PINS)
ioSetDirection((GPIO_TypeDef*)_pinLookupTable[pin], (uint8_t)_pinIndexTable[pin], mode);
2f8: 2e390000 cdpcs 0, 3, cr0, cr9, cr0, {0}
2fc: 03193f01 tsteq r9, #1, 30
300: 3b0b3a0e blcc 2ceb40 <_taskRunLoopHelper+0x2ceb40>
304: 1201110b andne r1, r1, #-1073741822 ; 0xc0000002
308: 97184006 ldrls r4, [r8, -r6]
30c: 13011942 movwne r1, #6466 ; 0x1942
return SV_OUT->data[index];
}
// svGetBackupBattery - Gets the backup battery voltage in millivolts, or 0 if not connected
static INLINE uint32_t svGetBackupBattery() {
uint32_t volts = ((uint32_t)SV_IN->backupBattery) * 59;
310: 2e3a0000 cdpcs 0, 3, cr0, cr10, cr0, {0}
314: 03193f01 tsteq r9, #1, 30
if (volts < 1000)
318: 3b0b3a0e blcc 2ceb58 <_taskRunLoopHelper+0x2ceb58>
}
// powerLevelBackup - Get backup battery voltage in millivolts, or 0 if not connected
unsigned int powerLevelBackup() {
return svGetBackupBattery();
}
31c: 11192705 tstne r9, r5, lsl #14
320: 40061201 andmi r1, r6, r1, lsl #4
324: 19429718 stmdbne r2, {r3, r4, r8, r9, sl, ip, pc}^
}
}
// svGetMainBattery - Gets the main battery voltage in millivolts, or 0 if not connected
static INLINE uint32_t svGetMainBattery() {
uint32_t volts = ((uint32_t)SV_IN->mainBattery) * 59;
328: 00001301 andeq r1, r0, r1, lsl #6
32c: 0300053b movweq r0, #1339 ; 0x53b
if (volts < 1000)
330: 3b0b3a0e blcc 2ceb70 <_taskRunLoopHelper+0x2ceb70>
// powerLevelMain - Get main battery voltage in millivolts, or 0 if not connected
unsigned int powerLevelMain() {
return svGetMainBattery();
}
334: 02134905 andseq r4, r3, #81920 ; 0x14000
338: 3c000017 stccc 0, cr0, [r0], {23}
33c: 0e030034 mcreq 0, 0, r0, cr3, cr4, {1}
// setTeamName - Sets the team name of the Cortex
void setTeamName(const char *name) {
340: 0b3b0b3a bleq ec3030 <_taskRunLoopHelper+0xec3030>
// svSetTeamName - Changes the team name reported to the supervisor
static INLINE void svSetTeamName(const char *name) {
char c; uint8_t i;
for (i = 0; i < 8; i++) {
// Copy up to 8 characters, respect zero terminator
c = (char)(*name++);
344: 193f1349 ldmdbne pc!, {r0, r3, r6, r8, r9, ip} ; <UNPREDICTABLE>
if (!c) break;
svTeamName[i] = c;
348: 0000193c andeq r1, r0, ip, lsr r9
34c: 3f012e3d svccc 0x00012e3d
}
// svSetTeamName - Changes the team name reported to the supervisor
static INLINE void svSetTeamName(const char *name) {
char c; uint8_t i;
for (i = 0; i < 8; i++) {
350: 3a0e0319 bcc 380fbc <_taskRunLoopHelper+0x380fbc>
c = (char)(*name++);
if (!c) break;
svTeamName[i] = c;
}
// Space-pad
for (; i < 8; i++)
354: 270b3b0b strcs r3, [fp, -fp, lsl #22]
svTeamName[i] = ' ';
358: 01193c19 tsteq r9, r9, lsl ip
35c: 3e000013 mcrcc 0, 0, r0, cr0, cr3, {0}
c = (char)(*name++);
if (!c) break;
svTeamName[i] = c;
}
// Space-pad
for (; i < 8; i++)
360: 193f012e ldmdbne pc!, {r1, r2, r3, r5, r8} ; <UNPREDICTABLE>
svSetTeamName(name);
}
364: 0b3a0e03 bleq e83b78 <_taskRunLoopHelper+0xe83b78>
368: 13490b3b movtne r0, #39739 ; 0x9b3b
// taskRunLoop - Starts a task at higher-than-normal priority to run the specified function
// in intervals as close to the specified period in milliseconds as possible
// For a stack size or priority different than the default, launch a custom task
TaskHandle taskRunLoop(void (*fn)(void), const unsigned long increment) {
36c: 1301193c movwne r1, #6460 ; 0x193c
// Initialize data (will be later freed)
LoopTask *lt = malloc(sizeof(LoopTask));
370: 183f0000 ldmdane pc!, {} ; <UNPREDICTABLE>
374: 40000000 andmi r0, r0, r0
lt->fn = fn;
lt->period = (clock_t)increment;
// Create and start the task
return taskCreate(_taskRunLoopHelper, TASK_DEFAULT_STACK_SIZE, (void*)lt,
378: 193f012e ldmdbne pc!, {r1, r2, r3, r5, r8} ; <UNPREDICTABLE>
// in intervals as close to the specified period in milliseconds as possible
// For a stack size or priority different than the default, launch a custom task
TaskHandle taskRunLoop(void (*fn)(void), const unsigned long increment) {
// Initialize data (will be later freed)
LoopTask *lt = malloc(sizeof(LoopTask));
lt->fn = fn;
37c: 0b3a0e03 bleq e83b90 <_taskRunLoopHelper+0xe83b90>
// taskRunLoop - Starts a task at higher-than-normal priority to run the specified function
// in intervals as close to the specified period in milliseconds as possible
// For a stack size or priority different than the default, launch a custom task
TaskHandle taskRunLoop(void (*fn)(void), const unsigned long increment) {
// Initialize data (will be later freed)
LoopTask *lt = malloc(sizeof(LoopTask));
380: 19270b3b stmdbne r7!, {r0, r1, r3, r4, r5, r8, r9, fp}
lt->fn = fn;
lt->period = (clock_t)increment;
// Create and start the task
return taskCreate(_taskRunLoopHelper, TASK_DEFAULT_STACK_SIZE, (void*)lt,
TASK_PRIORITY_DEFAULT + 1);
}
384: 193c1349 ldmdbne ip!, {r0, r3, r6, r8, r9, ip}
// Initialize data (will be later freed)
LoopTask *lt = malloc(sizeof(LoopTask));
lt->fn = fn;
lt->period = (clock_t)increment;
// Create and start the task
return taskCreate(_taskRunLoopHelper, TASK_DEFAULT_STACK_SIZE, (void*)lt,
388: 00001301 andeq r1, r0, r1, lsl #6
38c: 3f012e41 svccc 0x00012e41
390: 3a0e0319 bcc 380ffc <_taskRunLoopHelper+0x380ffc>
TASK_PRIORITY_DEFAULT + 1);
}
// wait - taskDelay alias
void wait(const unsigned long time) {
taskDelay((clock_t)time);
394: 27053b0b strcs r3, [r5, -fp, lsl #22]
}
// waitUntil - taskDelayUntil alias
void waitUntil(unsigned long *previousWakeTime, unsigned long time) {
taskDelayUntil((clock_t*)previousWakeTime, (clock_t)time);
398: 3c134919 ldccc 9, cr4, [r3], {25}
39c: 00130119 andseq r0, r3, r9, lsl r1
3a0: 012e4200 ; <UNDEFINED> instruction: 0x012e4200
3a4: 0e03193f mcreq 9, 0, r1, cr3, cr15, {1}
3a8: 053b0b3a ldreq r0, [fp, #-2874]! ; 0xfffff4c6
3ac: 193c1927 ldmdbne ip!, {r0, r1, r2, r5, r8, fp, ip}
3b0: 00001301 andeq r1, r0, r1, lsl #6
3b4: 3f012e43 svccc 0x00012e43
3b8: 3a0e0319 bcc 381024 <_taskRunLoopHelper+0x381024>
3bc: 3c053b0b stccc 11, cr3, [r5], {11}
3c0: 00130119 andseq r0, r3, r9, lsl r1
...
Disassembly of section .debug_loc:
00000000 <.debug_loc>:
void (*fn)(void);
clock_t period;
} LoopTask;
// Helper task for taskRunLoop()
static void _taskRunLoopHelper(void *data) {
0: 00000000 andeq r0, r0, r0
0: R_ARM_ABS32 .text._taskRunLoopHelper
// Extract information from pointer
LoopTask *info = (LoopTask*)data;
void (*fn)(void) = info->fn;
clock_t period = info->period;
4: 00000009 andeq r0, r0, r9
4: R_ARM_ABS32 .text._taskRunLoopHelper
// Avoid leaking data
free(data);
8: 09500001 ldmdbeq r0, {r0}^
b: R_ARM_ABS32 .text._taskRunLoopHelper
// Start counter
clock_t now = timeLowRes();
c: 38000000 stmdacc r0, {} ; <UNPREDICTABLE>
f: R_ARM_ABS32 .text._taskRunLoopHelper
10: 04000000 streq r0, [r0], #-0
uint16_t sf = svFlags & (SV_AUTONOMOUS | SV_ENABLED | SV_FMS);
14: 5001f300 andpl pc, r1, r0, lsl #6
18: 0000009f muleq r0, pc, r0 ; <UNPREDICTABLE>
do {
fn();
taskDelayUntil(&now, period);
1c: 00000000 andeq r0, r0, r0
20: 00000600 andeq r0, r0, r0, lsl #12
21: R_ARM_ABS32 .text._taskRunLoopHelper
// Auto-terminate on mode switch, drop, or disable
} while ((svFlags & (SV_AUTONOMOUS | SV_ENABLED | SV_FMS)) == sf);
24: 00003200 andeq r3, r0, r0, lsl #4
25: R_ARM_ABS32 .text._taskRunLoopHelper
28: 57000100 strpl r0, [r0, -r0, lsl #2]
...
}
34: 0000001a andeq r0, r0, sl, lsl r0
34: R_ARM_ABS32 .text._taskRunLoopHelper
// analogCalibrate - Calibrates the analog sensor on the specified channel, assuming that it is
// not actively changing. Approximately 512 samples are taken, 1 ms apart, for a 0.5 s period
// of calibration. The average value thus calculated is returned and stored for later calls
// to analogReadCalibrated()
int analogCalibrate(unsigned char channel) {
channel--;
38: 00000032 andeq r0, r0, r2, lsr r0
38: R_ARM_ABS32 .text._taskRunLoopHelper
3c: 00550001 subseq r0, r5, r1
...
47: R_ARM_ABS32 .text.analogCalibrate
if (channel < BOARD_NR_ADC_PINS) {
// We have the true channel, do this in a loop
uint32_t total = 0, i;
for (i = 0; i < 512; i++) {
total += adcRead(channel);
48: 02000000 andeq r0, r0, #0
4b: R_ARM_ABS32 .text.analogCalibrate
4c: 01000000 mrseq r0, (UNDEF: 0)
taskDelay(1);
50: 00025000 andeq r5, r2, r0
52: R_ARM_ABS32 .text.analogCalibrate
54: 00060000 andeq r0, r6, r0
56: R_ARM_ABS32 .text.analogCalibrate
int analogCalibrate(unsigned char channel) {
channel--;
if (channel < BOARD_NR_ADC_PINS) {
// We have the true channel, do this in a loop
uint32_t total = 0, i;
for (i = 0; i < 512; i++) {
58: 00040000 andeq r0, r4, r0
total += adcRead(channel);
taskDelay(1);
}
// Store value (fixed to correctly round to nearest to avoid positive bias)
_analogState[channel].calibValue = (total + 16) >> 5;
5c: 9f5001f3 svcls 0x005001f3
60: 00000006 andeq r0, r0, r6
60: R_ARM_ABS32 .text.analogCalibrate
64: 0000002a andeq r0, r0, sl, lsr #32
64: R_ARM_ABS32 .text.analogCalibrate
68: 3c550001 mrrccc 0, 0, r0, r5, cr1
6b: R_ARM_ABS32 .text.analogCalibrate
return (int)((total + 256) >> 9);
6c: 40000000 andmi r0, r0, r0
6f: R_ARM_ABS32 .text.analogCalibrate
70: 01000000 mrseq r0, (UNDEF: 0)
}
return 0;
74: 00005500 andeq r5, r0, r0, lsl #10
}
78: 00000000 andeq r0, r0, r0
// analogRead - Reads an analog input channel 1-8 and returns the 12-bit value from 0 to 4095
int analogRead(unsigned char channel) {
channel--;
7c: 00100000 andseq r0, r0, r0
7e: R_ARM_ABS32 .text.analogCalibrate
if (channel < BOARD_NR_ADC_PINS)
80: 003c0000 eorseq r0, ip, r0
82: R_ARM_ABS32 .text.analogCalibrate
84: 00010000 andeq r0, r1, r0
return (int)adcRead(channel);
88: 00000054 andeq r0, r0, r4, asr r0
return 0;
8c: 00000000 andeq r0, r0, r0
// analogReadCalibrated - Reads the calibrated value of an analog input channel 1-8;
// analogCalibrate() must be run first. This is inappropriate for integrated sensors as the
// round-off error can accumulate. Use analogReadCalibratedHR() instead.
int analogReadCalibrated(unsigned char channel) {
channel--;
90: 00001000 andeq r1, r0, r0
91: R_ARM_ABS32 .text.analogCalibrate
94: 00001e00 andeq r1, r0, r0, lsl #28
95: R_ARM_ABS32 .text.analogCalibrate
if (channel < BOARD_NR_ADC_PINS)
98: 0a000700 beq 1ca0 <_taskRunLoopHelper+0x1ca0>
return (int)adcRead(channel) - (int)(_analogState[channel].calibValue >> 4);
9c: 00760200 rsbseq r0, r6, r0, lsl #4
a0: 001e9f1c andseq r9, lr, ip, lsl pc
a2: R_ARM_ABS32 .text.analogCalibrate
a4: 00200000 eoreq r0, r0, r0
a6: R_ARM_ABS32 .text.analogCalibrate
a8: 00070000 andeq r0, r7, r0
ac: 7602010a strvc r0, [r2], -sl, lsl #2
b0: 209f1c00 addscs r1, pc, r0, lsl #24
b3: R_ARM_ABS32 .text.analogCalibrate
return 0;
}
b4: 3c000000 stccc 0, cr0, [r0], {-0}
b7: R_ARM_ABS32 .text.analogCalibrate
b8: 07000000 streq r0, [r0, -r0]
// drift due to round-off.
int analogReadCalibratedHR(unsigned char channel) {
// The value returned actually has 16 bits of "precision", even though the ADC only reads
// 12 bits, so that errors induced by the average value being between two values come out
// in the wash when integrated over time. Think of the value as the true value << 4.
channel--;
bc: 02000a00 andeq r0, r0, #0, 20
c0: 9f1c0076 svcls 0x001c0076
...
cc: R_ARM_ABS32 .text.analogRead
if (channel < BOARD_NR_ADC_PINS)
return (int)(adcRead(channel) << 4) - (int)(_analogState[channel].calibValue);
d0: 00000002 andeq r0, r0, r2
d0: R_ARM_ABS32 .text.analogRead
d4: 02500001 subseq r0, r0, #1
d7: R_ARM_ABS32 .text.analogRead
d8: 04000000 streq r0, [r0], #-0
db: R_ARM_ABS32 .text.analogRead
dc: 04000000 streq r0, [r0], #-0
return 0;
}
e0: 5001f300 andpl pc, r1, r0, lsl #6
e4: 0000049f muleq r0, pc, r4 ; <UNPREDICTABLE>
e5: R_ARM_ABS32 .text.analogRead
// delay - taskDelay alias
void delay(const unsigned long time) {
taskDelay((clock_t)time);
e8: 00000d00 andeq r0, r0, r0, lsl #26
e9: R_ARM_ABS32 .text.analogRead
}
// delayMicroseconds - Wait for approximately the given number of microseconds
void delayMicroseconds(const unsigned long time) {
ec: 50000100 andpl r0, r0, r0, lsl #2
clock_t us = (clock_t)time;
if (us) {
f0: 00000010 andeq r0, r0, r0, lsl r0
f0: R_ARM_ABS32 .text.analogRead
/*us *= 12; us--;
asm volatile(" mov r0, %[us]\n\t"
"1: subs r0, #1\n\t"
" bhi 1b\n\t"
: : [us] "r" (us) : "r0");*/
if (us > 1000) {
f4: 00000012 andeq r0, r0, r2, lsl r0
f4: R_ARM_ABS32 .text.analogRead
// Wait off the milliseconds part first
clock_t millis = (clock_t)(us / 1000UL);
us %= 1000UL;
f8: 00500001 subseq r0, r0, r1
...
103: R_ARM_ABS32 .text.analogReadCalibrated
taskDelay(millis);
104: 02000000 andeq r0, r0, #0
107: R_ARM_ABS32 .text.analogReadCalibrated
}
if (us) {
108: 01000000 mrseq r0, (UNDEF: 0)
10c: 00025000 andeq r5, r2, r0
10e: R_ARM_ABS32 .text.analogReadCalibrated
// Spin on the highres timer value (next IRQ might be up to 1ms away!)
// Power consumption is bad, CPU usage possibly worse, but accuracy is acceptable
uint16_t start = TIM8->CNT;
110: 00060000 andeq r0, r6, r0
112: R_ARM_ABS32 .text.analogReadCalibrated
114: 00040000 andeq r0, r4, r0
while (TIM8->CNT - start < us);
118: 9f5001f3 svcls 0x005001f3
11c: 00000006 andeq r0, r0, r6
11c: R_ARM_ABS32 .text.analogReadCalibrated
120: 00000018 andeq r0, r0, r8, lsl r0
120: R_ARM_ABS32 .text.analogReadCalibrated
124: 22540001 subscs r0, r4, #1
127: R_ARM_ABS32 .text.analogReadCalibrated
}
}
}
// digitalRead - Gets the digital value (1 or 0) of a pin configured as a digital input
bool digitalRead(unsigned char pin) {
128: 26000000 strcs r0, [r0], -r0
12b: R_ARM_ABS32 .text.analogReadCalibrated
if (pin >= BOARD_NR_GPIO_PINS)
return 0;
return ioGetInput((GPIO_TypeDef*)_pinLookupTable[pin], (uint8_t)_pinIndexTable[pin]);
12c: 01000000 mrseq r0, (UNDEF: 0)
130: 00005400 andeq r5, r0, r0, lsl #8
...
13a: R_ARM_ABS32 .text.analogReadCalibratedHR
}
// ioGetInput - Gets the digital value (1 or 0) of a pin configured as a digital input
static INLINE bool ioGetInput(GPIO_TypeDef* port, uint32_t pin) {
// Shift right that many bits, then mask everything but the ones
return ((port->IDR >> (pin & 0x0F)) & 0x01) != 0;
13c: 00020000 andeq r0, r2, r0
13e: R_ARM_ABS32 .text.analogReadCalibratedHR
140: 00010000 andeq r0, r1, r0
144: 00000250 andeq r0, r0, r0, asr r2
145: R_ARM_ABS32 .text.analogReadCalibratedHR
}
// digitalRead - Gets the digital value (1 or 0) of a pin configured as a digital input
bool digitalRead(unsigned char pin) {
if (pin >= BOARD_NR_GPIO_PINS)
return 0;
148: 00000600 andeq r0, r0, r0, lsl #12
149: R_ARM_ABS32 .text.analogReadCalibratedHR
return ioGetInput((GPIO_TypeDef*)_pinLookupTable[pin], (uint8_t)_pinIndexTable[pin]);
}
14c: f3000400 vshl.u8 d0, d0, d0
150: 069f5001 ldreq r5, [pc], r1
153: R_ARM_ABS32 .text.analogReadCalibratedHR
// digitalWrite - Sets the digital value (1 or 0) of a pin configured as a digital output
void digitalWrite(unsigned char pin, bool value) {
// We will let this work when disabled, even though it might change a solenoid, since it
// is needed to set initial solenoid states in initializeIO() when enabled/disabled is
// undefined.
if (pin < BOARD_NR_GPIO_PINS)
154: 18000000 stmdane r0, {} ; <UNPREDICTABLE>
157: R_ARM_ABS32 .text.analogReadCalibratedHR
158: 01000000 mrseq r0, (UNDEF: 0)
ioSetOutput((GPIO_TypeDef*)_pinLookupTable[pin], (uint8_t)_pinIndexTable[pin], value);
15c: 00225400 eoreq r5, r2, r0, lsl #8
15e: R_ARM_ABS32 .text.analogReadCalibratedHR
160: 00260000 eoreq r0, r6, r0
162: R_ARM_ABS32 .text.analogReadCalibratedHR
164: 00010000 andeq r0, r1, r0
168: 00000054 andeq r0, r0, r4, asr r0
...
171: R_ARM_ABS32 .text.delay
if (value)
// Atomic bit set
port->BSRR = ((uint32_t)0x00000001) << (pin & 0x0F);
else
// Atomic bit reset
port->BRR = ((uint32_t)0x00000001) << (pin & 0x0F);
174: 00000300 andeq r0, r0, r0, lsl #6
175: R_ARM_ABS32 .text.delay
178: 50000100 andpl r0, r0, r0, lsl #2
17c: 00000003 andeq r0, r0, r3
17c: R_ARM_ABS32 .text.delay
}
// isAutonomous - Checks to see if the system is in autonomous mode
bool isAutonomous() {
return (svFlags & SV_AUTONOMOUS) ? true : false;
180: 00000004 andeq r0, r0, r4
180: R_ARM_ABS32 .text.delay
}
184: 01f30004 mvnseq r0, r4
188: 00009f50 andeq r9, r0, r0, asr pc
...
192: R_ARM_ABS32 .text.delayMicroseconds
// isEnabled - Checks to see if the system is enabled
bool isEnabled() {
uint16_t flags = svFlags;
194: 00140000 andseq r0, r4, r0
196: R_ARM_ABS32 .text.delayMicroseconds
if (!(flags & SV_ENABLED)) {
if (flags & SV_FMS)
198: 00010000 andeq r0, r1, r0
19c: 00001450 andeq r1, r0, r0, asr r4
19d: R_ARM_ABS32 .text.delayMicroseconds
1a0: 00001b00 andeq r1, r0, r0, lsl #22
1a1: R_ARM_ABS32 .text.delayMicroseconds
return false;
}
return true;
}
1a4: 53000100 movwpl r0, #256 ; 0x100
1a8: 0000001b andeq r0, r0, fp, lsl r0
1a8: R_ARM_ABS32 .text.delayMicroseconds
}
// svIsJoystickConnected - Checks to see if a joystick is connected
static INLINE uint8_t svIsJoystickConnected(uint8_t joystick) {
// Force in range from 0..1 (mapped from 1..2)
joystick = (joystick - 1) & (uint8_t)0x01;
1ac: 00000020 andeq r0, r0, r0, lsr #32
1ac: R_ARM_ABS32 .text.delayMicroseconds
// If both accelerometer axes are zero, the joystick is likely not plugged in
// Obviously there is a chance for false positives but extremely unlikely due to the noise
// of the analog accelerometers
return SV_IN->joystick[joystick].axis[4] != (uint8_t)0x7F ||
1b0: 01f30004 mvnseq r0, r4
1b4: 00209f50 eoreq r9, r0, r0, asr pc
1b6: R_ARM_ABS32 .text.delayMicroseconds
1b8: 00220000 eoreq r0, r2, r0
1ba: R_ARM_ABS32 .text.delayMicroseconds
1bc: 00010000 andeq r0, r1, r0
SV_IN->joystick[joystick].axis[5] != (uint8_t)0x7F;
1c0: 00002250 andeq r2, r0, r0, asr r2
1c1: R_ARM_ABS32 .text.delayMicroseconds
// Force in range from 0..1 (mapped from 1..2)
joystick = (joystick - 1) & (uint8_t)0x01;
// If both accelerometer axes are zero, the joystick is likely not plugged in
// Obviously there is a chance for false positives but extremely unlikely due to the noise
// of the analog accelerometers
return SV_IN->joystick[joystick].axis[4] != (uint8_t)0x7F ||
1c4: 00003c00 andeq r3, r0, r0, lsl #24
1c5: R_ARM_ABS32 .text.delayMicroseconds
1c8: f3000400 vshl.u8 d0, d0, d0
1cc: 009f5001 addseq r5, pc, r1
...
1d7: R_ARM_ABS32 .text.delayMicroseconds
}
// isOnline - Checks to see if the system is connected to a FMS/competition switch
bool isOnline() {
return (svFlags & SV_FMS) ? true : false;
}
1d8: 14000000 strne r0, [r0], #-0
1db: R_ARM_ABS32 .text.delayMicroseconds
1dc: 01000000 mrseq r0, (UNDEF: 0)
1e0: 00145000 andseq r5, r4, r0
1e2: R_ARM_ABS32 .text.delayMicroseconds
// joystickGetAnalog - Retrieve an analog axis of a joystick
int joystickGetAnalog(unsigned char joystick, unsigned char axis) {
1e4: 00180000 andseq r0, r8, r0
1e6: R_ARM_ABS32 .text.delayMicroseconds
1e8: 00010000 andeq r0, r1, r0
// Safety first here
if (isOnline() && isAutonomous()) return 0;
1ec: 00001853 andeq r1, r0, r3, asr r8
1ed: R_ARM_ABS32 .text.delayMicroseconds
// svGetJoystickAnalog - Gets an analog joystick axis or accelerometer axis from the supervisor
// NO check on the mode when doing so
static INLINE int8_t svGetJoystickAnalog(uint8_t joystick, uint8_t axis) {
uint8_t value;
// Force in range from 0..5 (mapped from 1..6)
axis = (axis - 1) % 6;
1f0: 00002000 andeq r2, r0, r0
1f1: R_ARM_ABS32 .text.delayMicroseconds
1f4: 54000100 strpl r0, [r0], #-256 ; 0xffffff00
1f8: 00000020 andeq r0, r0, r0, lsr #32
1f8: R_ARM_ABS32 .text.delayMicroseconds
// Force in range from 0..1 (mapped from 1..2)
joystick = (joystick - 1) & (uint8_t)0x01;
1fc: 00000022 andeq r0, r0, r2, lsr #32
1fc: R_ARM_ABS32 .text.delayMicroseconds
value = SV_IN->joystick[joystick].axis[axis];
200: 22500001 subscs r0, r0, #1
203: R_ARM_ABS32 .text.delayMicroseconds
204: 34000000 strcc r0, [r0], #-0
207: R_ARM_ABS32 .text.delayMicroseconds
208: 01000000 mrseq r0, (UNDEF: 0)
// Prevent return of 128
if (value == 0xFF)
value = 0xFE;
value -= 127;
if (axis == 1 || axis == 2)
20c: 00005400 andeq r5, r0, r0, lsl #8
uint8_t value;
// Force in range from 0..5 (mapped from 1..6)
axis = (axis - 1) % 6;
// Force in range from 0..1 (mapped from 1..2)
joystick = (joystick - 1) & (uint8_t)0x01;
value = SV_IN->joystick[joystick].axis[axis];
210: 00000000 andeq r0, r0, r0
// Prevent return of 128
if (value == 0xFF)
value = 0xFE;
214: 000c0000 andeq r0, ip, r0
216: R_ARM_ABS32 .text.delayMicroseconds
value -= 127;
if (axis == 1 || axis == 2)
218: 00140000 andseq r0, r4, r0
21a: R_ARM_ABS32 .text.delayMicroseconds
joystick = (joystick - 1) & (uint8_t)0x01;
value = SV_IN->joystick[joystick].axis[axis];
// Prevent return of 128
if (value == 0xFF)
value = 0xFE;
value -= 127;
21c: 000d0000 andeq r0, sp, r0
if (axis == 1 || axis == 2)
220: 25f70070 ldrbcs r0, [r7, #112]! ; 0x70
value = -value;
224: f703e80a ; <UNDEFINED> instruction: 0xf703e80a
228: 00f71b25 rscseq r1, r7, r5, lsr #22
22c: 0000149f muleq r0, pc, r4 ; <UNPREDICTABLE>
22d: R_ARM_ABS32 .text.delayMicroseconds
230: 00001b00 andeq r1, r0, r0, lsl #22
231: R_ARM_ABS32 .text.delayMicroseconds
return (int)svGetJoystickAnalog(joystick, axis);
234: 50000100 andpl r0, r0, r0, lsl #2
238: 0000001b andeq r0, r0, fp, lsl r0
238: R_ARM_ABS32 .text.delayMicroseconds
}
// joystickGetDigital - Retrieve a digital button of a joystick
bool joystickGetDigital(unsigned char joystick, unsigned char buttonGroup,
unsigned char button) {
23c: 00000020 andeq r0, r0, r0, lsr #32
23c: R_ARM_ABS32 .text.delayMicroseconds
240: 01f3000e mvnseq r0, lr
// Safety first here
if (isOnline() && isAutonomous()) return false;
244: 0a25f750 beq 97df8c <_taskRunLoopHelper+0x97df8c>
248: 25f703e8 ldrbcs r0, [r7, #1000]! ; 0x3e8
static INLINE uint8_t svGetJoystickDigital(uint8_t joystick, uint8_t button) {
uint8_t value; volatile Joystick_TypeDef *ref;
// Force in range from 0..3 (mapped from 5..8)
button = (button - 5) & (uint8_t)0x03;
// Force in range from 0..1 (mapped from 1..2)
joystick = (joystick - 1) & (uint8_t)0x01;
24c: 9f00f71b svcls 0x0000f71b
...
ref = &SV_IN->joystick[joystick];
258: 0000002a andeq r0, r0, sl, lsr #32
258: R_ARM_ABS32 .text.delayMicroseconds
25c: 00000034 andeq r0, r0, r4, lsr r0
25c: R_ARM_ABS32 .text.delayMicroseconds
// 5 and 6 need some mangling to move the twos bit up to the fours
switch (button) {
260: 00510001 subseq r0, r1, r1
...
26b: R_ARM_ABS32 .text.digitalRead
// 6
value = ref->button56 >> 2;
return ((value & 0x02) << 1) | (value & 0x01);
case 2:
// 7
return ref->button78 >> 4;
26c: 0e000000 cdpeq 0, 0, cr0, cr0, cr0, {0}
26f: R_ARM_ABS32 .text.digitalRead
270: 01000000 mrseq r0, (UNDEF: 0)
274: 000e5000 andeq r5, lr, r0
276: R_ARM_ABS32 .text.digitalRead
return (svGetJoystickDigital(joystick, buttonGroup) & button) ? true : false;
}
278: 002c0000 eoreq r0, ip, r0
27a: R_ARM_ABS32 .text.digitalRead
ref = &SV_IN->joystick[joystick];
// 5 and 6 need some mangling to move the twos bit up to the fours
switch (button) {
case 0:
// 5
value = ref->button56;
27c: 00040000 andeq r0, r4, r0
return ((value & 0x02) << 1) | (value & 0x01);
case 1:
// 6
value = ref->button56 >> 2;
280: 9f5001f3 svcls 0x005001f3
...
return ((value & 0x02) << 1) | (value & 0x01);
28c: 0000000c andeq r0, r0, ip
28c: R_ARM_ABS32 .text.digitalRead
290: 00000010 andeq r0, r0, r0, lsl r0
290: R_ARM_ABS32 .text.digitalRead
case 2:
// 7
return ref->button78 >> 4;
default:
// 8 (No other case is possible...)
return ref->button78 & 0x0F;
294: 00520001 subseq r0, r2, r1
// joystickGetDigital - Retrieve a digital button of a joystick
bool joystickGetDigital(unsigned char joystick, unsigned char buttonGroup,
unsigned char button) {
// Safety first here
if (isOnline() && isAutonomous()) return false;
return (svGetJoystickDigital(joystick, buttonGroup) & button) ? true : false;
298: 00000000 andeq r0, r0, r0
29c: 10000000 andne r0, r0, r0
29f: R_ARM_ABS32 .text.digitalWrite
2a0: 20000000 andcs r0, r0, r0
2a3: R_ARM_ABS32 .text.digitalWrite
2a4: 01000000 mrseq r0, (UNDEF: 0)
}
// micros - Arduino-compatible alias for timeHighRes()
unsigned long micros() {
return (unsigned long)timeHighRes();
2a8: 00005100 andeq r5, r0, r0, lsl #2
}
// millis - Arduino-compatible alias for timeLowRes()
unsigned long millis() {
return (unsigned long)timeLowRes();
2ac: 00000000 andeq r0, r0, r0
}
// motorGet - Gets last commanded speed of the specified motor channel; this speed is reset
// to 0 if motors are stopped by the kernel for any reason
int motorGet(unsigned char channel) {
2b0: 00100000 andseq r0, r0, r0
2b2: R_ARM_ABS32 .text.digitalWrite
// Convert range
return (int)motorControlGet(channel) - 127;
2b4: 00160000 andseq r0, r6, r0
2b6: R_ARM_ABS32 .text.digitalWrite
}
2b8: 00060000 andeq r0, r6, r0
// motorSet - Sets the speed of the specified motor channel from 1 to 10, where -127 is full
// reverse and 127 is full forward, with 0 being off
void motorSet(unsigned char channel, int speed) {
2bc: ff080072 ; <UNDEFINED> instruction: 0xff080072
if (isEnabled()) {
2c0: 00009f1a andeq r9, r0, sl, lsl pc
2c4: 00000000 andeq r0, r0, r0
int ns = speed + 127;
// Equalize the bias
if (ns < 0) ns = 0;
2c8: 00100000 andseq r0, r0, r0
2ca: R_ARM_ABS32 .text.digitalWrite
if (ns > 255) ns = 255;
2cc: 00200000 eoreq r0, r0, r0
2ce: R_ARM_ABS32 .text.digitalWrite
2d0: 00010000 andeq r0, r1, r0
// reverse and 127 is full forward, with 0 being off
void motorSet(unsigned char channel, int speed) {
if (isEnabled()) {
int ns = speed + 127;
// Equalize the bias
if (ns < 0) ns = 0;
2d4: 00000054 andeq r0, r0, r4, asr r0
if (ns > 255) ns = 255;
motorControlSet(channel, (uint8_t)ns);
}
}
2d8: 00000000 andeq r0, r0, r0
if (isEnabled()) {
int ns = speed + 127;
// Equalize the bias
if (ns < 0) ns = 0;
if (ns > 255) ns = 255;
motorControlSet(channel, (uint8_t)ns);
2dc: 00000600 andeq r0, r0, r0, lsl #12
2dd: R_ARM_ABS32 .text.isEnabled
2e0: 00000e00 andeq r0, r0, r0, lsl #28
2e1: R_ARM_ABS32 .text.isEnabled
}
// motorStop - Stops the motor on the specified channel, equivalent to calling motorSet() with
// an argument of zero; this performs a coasting stop, not an active brake
void motorStop(unsigned char channel) {
motorControlSet(channel, 127);
2e4: 50000100 andpl r0, r0, r0, lsl #2
...
2f0: R_ARM_ABS32 .text.isJoystickConnected
// It is safe to stop all motors when disabled, as that is their disabled state anyways.
motorControlStop();
}
// pinMode - Configures the pin as an input or output with a variety of settings
void pinMode(unsigned char pin, unsigned char mode) {
2f4: 00000002 andeq r0, r0, r2
2f4: R_ARM_ABS32 .text.isJoystickConnected
if (pin < BOARD_NR_GPIO_PINS)
ioSetDirection((GPIO_TypeDef*)_pinLookupTable[pin], (uint8_t)_pinIndexTable[pin], mode);
2f8: 02500001 subseq r0, r0, #1
2fb: R_ARM_ABS32 .text.isJoystickConnected
2fc: 28000000 stmdacs r0, {} ; <UNPREDICTABLE>
2ff: R_ARM_ABS32 .text.isJoystickConnected
300: 04000000 streq r0, [r0], #-0
304: 5001f300 andpl pc, r1, r0, lsl #6
308: 0000009f muleq r0, pc, r0 ; <UNPREDICTABLE>
...
311: R_ARM_ABS32 .text.isJoystickConnected
return SV_OUT->data[index];
}
// svGetBackupBattery - Gets the backup battery voltage in millivolts, or 0 if not connected
static INLINE uint32_t svGetBackupBattery() {
uint32_t volts = ((uint32_t)SV_IN->backupBattery) * 59;
314: 00000200 andeq r0, r0, r0, lsl #4
315: R_ARM_ABS32 .text.isJoystickConnected
if (volts < 1000)
318: 70000500 andvc r0, r0, r0, lsl #10
}
// powerLevelBackup - Get backup battery voltage in millivolts, or 0 if not connected
unsigned int powerLevelBackup() {
return svGetBackupBattery();
}
31c: 9f1a317f svcls 0x001a317f
320: 00000002 andeq r0, r0, r2
320: R_ARM_ABS32 .text.isJoystickConnected
324: 00000028 andeq r0, r0, r8, lsr #32
324: R_ARM_ABS32 .text.isJoystickConnected
}
}
// svGetMainBattery - Gets the main battery voltage in millivolts, or 0 if not connected
static INLINE uint32_t svGetMainBattery() {
uint32_t volts = ((uint32_t)SV_IN->mainBattery) * 59;
328: 01f30008 mvnseq r0, r8
32c: 311c3150 tstcc ip, r0, asr r1
if (volts < 1000)
330: 00009f1a andeq r9, r0, sl, lsl pc
...
33a: R_ARM_ABS32 .text.joystickGetAnalog
// powerLevelMain - Get main battery voltage in millivolts, or 0 if not connected
unsigned int powerLevelMain() {
return svGetMainBattery();
}
33c: 00090000 andeq r0, r9, r0
33e: R_ARM_ABS32 .text.joystickGetAnalog
// setTeamName - Sets the team name of the Cortex
void setTeamName(const char *name) {
340: 00010000 andeq r0, r1, r0
// svSetTeamName - Changes the team name reported to the supervisor
static INLINE void svSetTeamName(const char *name) {
char c; uint8_t i;
for (i = 0; i < 8; i++) {
// Copy up to 8 characters, respect zero terminator
c = (char)(*name++);
344: 00000950 andeq r0, r0, r0, asr r9
345: R_ARM_ABS32 .text.joystickGetAnalog
if (!c) break;
svTeamName[i] = c;
348: 00005800 andeq r5, r0, r0, lsl #16
349: R_ARM_ABS32 .text.joystickGetAnalog
34c: f3000400 vshl.u8 d0, d0, d0
}
// svSetTeamName - Changes the team name reported to the supervisor
static INLINE void svSetTeamName(const char *name) {
char c; uint8_t i;
for (i = 0; i < 8; i++) {
350: 009f5001 addseq r5, pc, r1
...
35b: R_ARM_ABS32 .text.joystickGetAnalog
if (!c) break;
svTeamName[i] = c;
}
// Space-pad
for (; i < 8; i++)
svTeamName[i] = ' ';
35c: 09000000 stmdbeq r0, {} ; <UNPREDICTABLE>
35f: R_ARM_ABS32 .text.joystickGetAnalog
c = (char)(*name++);
if (!c) break;
svTeamName[i] = c;
}
// Space-pad
for (; i < 8; i++)
360: 01000000 mrseq r0, (UNDEF: 0)
svSetTeamName(name);
}
364: 00095100 andeq r5, r9, r0, lsl #2
366: R_ARM_ABS32 .text.joystickGetAnalog
368: 00580000 subseq r0, r8, r0
36a: R_ARM_ABS32 .text.joystickGetAnalog
// taskRunLoop - Starts a task at higher-than-normal priority to run the specified function
// in intervals as close to the specified period in milliseconds as possible
// For a stack size or priority different than the default, launch a custom task
TaskHandle taskRunLoop(void (*fn)(void), const unsigned long increment) {
36c: 00040000 andeq r0, r4, r0
// Initialize data (will be later freed)
LoopTask *lt = malloc(sizeof(LoopTask));
370: 9f5101f3 svcls 0x005101f3
...
lt->fn = fn;
37c: 0000000c andeq r0, r0, ip
37c: R_ARM_ABS32 .text.joystickGetAnalog
// taskRunLoop - Starts a task at higher-than-normal priority to run the specified function
// in intervals as close to the specified period in milliseconds as possible
// For a stack size or priority different than the default, launch a custom task
TaskHandle taskRunLoop(void (*fn)(void), const unsigned long increment) {
// Initialize data (will be later freed)
LoopTask *lt = malloc(sizeof(LoopTask));
380: 0000001c andeq r0, r0, ip, lsl r0
380: R_ARM_ABS32 .text.joystickGetAnalog
lt->fn = fn;
lt->period = (clock_t)increment;
// Create and start the task
return taskCreate(_taskRunLoopHelper, TASK_DEFAULT_STACK_SIZE, (void*)lt,
TASK_PRIORITY_DEFAULT + 1);
}
384: 1c550001 mrrcne 0, 0, r0, r5, cr1
387: R_ARM_ABS32 .text.joystickGetAnalog
// Initialize data (will be later freed)
LoopTask *lt = malloc(sizeof(LoopTask));
lt->fn = fn;
lt->period = (clock_t)increment;
// Create and start the task
return taskCreate(_taskRunLoopHelper, TASK_DEFAULT_STACK_SIZE, (void*)lt,
388: 2a000000 bcs 8 <.debug_loc+0x8>
38b: R_ARM_ABS32 .text.joystickGetAnalog
38c: 01000000 mrseq r0, (UNDEF: 0)
390: 002a5100 eoreq r5, sl, r0, lsl #2
392: R_ARM_ABS32 .text.joystickGetAnalog
TASK_PRIORITY_DEFAULT + 1);
}
// wait - taskDelay alias
void wait(const unsigned long time) {
taskDelay((clock_t)time);
394: 00440000 subeq r0, r4, r0
396: R_ARM_ABS32 .text.joystickGetAnalog
}
// waitUntil - taskDelayUntil alias
void waitUntil(unsigned long *previousWakeTime, unsigned long time) {
taskDelayUntil((clock_t*)previousWakeTime, (clock_t)time);
398: 00030000 andeq r0, r3, r0
39c: 509f0171 addspl r0, pc, r1, ror r1 ; <UNPREDICTABLE>
39f: R_ARM_ABS32 .text.joystickGetAnalog
3a0: 58000000 stmdapl r0, {} ; <UNPREDICTABLE>
3a3: R_ARM_ABS32 .text.joystickGetAnalog
3a4: 03000000 movweq r0, #0
3a8: 9f017100 svcls 0x00017100
...
3b4: 0000000c andeq r0, r0, ip
3b4: R_ARM_ABS32 .text.joystickGetAnalog
3b8: 0000001a andeq r0, r0, sl, lsl r0
3b8: R_ARM_ABS32 .text.joystickGetAnalog
3bc: 00540001 subseq r0, r4, r1
3c0: 00000000 andeq r0, r0, r0
3c4: 2e000000 cdpcs 0, 0, cr0, cr0, cr0, {0}
3c7: R_ARM_ABS32 .text.joystickGetAnalog
3c8: 3a000000 bcc 8 <.debug_loc+0x8>
3cb: R_ARM_ABS32 .text.joystickGetAnalog
3cc: 01000000 mrseq r0, (UNDEF: 0)
3d0: 003a5000 eorseq r5, sl, r0
3d2: R_ARM_ABS32 .text.joystickGetAnalog
3d4: 003c0000 eorseq r0, ip, r0
3d6: R_ARM_ABS32 .text.joystickGetAnalog
3d8: 00040000 andeq r0, r4, r0
3dc: 9f00ff70 svcls 0x0000ff70
3e0: 0000003c andeq r0, r0, ip, lsr r0
3e0: R_ARM_ABS32 .text.joystickGetAnalog
3e4: 00000040 andeq r0, r0, r0, asr #32
3e4: R_ARM_ABS32 .text.joystickGetAnalog
3e8: 40500001 subsmi r0, r0, r1
3eb: R_ARM_ABS32 .text.joystickGetAnalog
3ec: 42000000 andmi r0, r0, #0
3ef: R_ARM_ABS32 .text.joystickGetAnalog
3f0: 04000000 streq r0, [r0], #-0
3f4: 1f007000 svcne 0x00007000
3f8: 0000429f muleq r0, pc, r2 ; <UNPREDICTABLE>
3f9: R_ARM_ABS32 .text.joystickGetAnalog
3fc: 00004400 andeq r4, r0, r0, lsl #8
3fd: R_ARM_ABS32 .text.joystickGetAnalog
400: 50000100 andpl r0, r0, r0, lsl #2
404: 00000050 andeq r0, r0, r0, asr r0
404: R_ARM_ABS32 .text.joystickGetAnalog
408: 00000058 andeq r0, r0, r8, asr r0
408: R_ARM_ABS32 .text.joystickGetAnalog
40c: 00500001 subseq r0, r0, r1
...
417: R_ARM_ABS32 .text.joystickGetDigital
418: 0b000000 bleq 8 <.debug_loc+0x8>
41b: R_ARM_ABS32 .text.joystickGetDigital
41c: 01000000 mrseq r0, (UNDEF: 0)
420: 000b5000 andeq r5, fp, r0
422: R_ARM_ABS32 .text.joystickGetDigital
424: 006c0000 rsbeq r0, ip, r0
426: R_ARM_ABS32 .text.joystickGetDigital
428: 00040000 andeq r0, r4, r0
42c: 9f5001f3 svcls 0x005001f3
...
438: R_ARM_ABS32 .text.joystickGetDigital
43c: 0000000b andeq r0, r0, fp
43c: R_ARM_ABS32 .text.joystickGetDigital
440: 0b510001 bleq 144000c <_taskRunLoopHelper+0x144000c>
443: R_ARM_ABS32 .text.joystickGetDigital
444: 6c000000 stcvs 0, cr0, [r0], {-0}
447: R_ARM_ABS32 .text.joystickGetDigital
448: 04000000 streq r0, [r0], #-0
44c: 5101f300 mrspl pc, SP_irq ; <UNPREDICTABLE>
450: 0000009f muleq r0, pc, r0 ; <UNPREDICTABLE>
...
459: R_ARM_ABS32 .text.joystickGetDigital
45c: 00000b00 andeq r0, r0, r0, lsl #22
45d: R_ARM_ABS32 .text.joystickGetDigital
460: 52000100 andpl r0, r0, #0, 2
464: 0000000b andeq r0, r0, fp
464: R_ARM_ABS32 .text.joystickGetDigital
468: 0000006c andeq r0, r0, ip, rrx
468: R_ARM_ABS32 .text.joystickGetDigital
46c: 01f30004 mvnseq r0, r4
470: 00009f52 andeq r9, r0, r2, asr pc
474: 00000000 andeq r0, r0, r0
478: 000e0000 andeq r0, lr, r0
47a: R_ARM_ABS32 .text.joystickGetDigital
47c: 00320000 eorseq r0, r2, r0
47e: R_ARM_ABS32 .text.joystickGetDigital
480: 00050000 andeq r0, r5, r0
484: 1a337b76 bne cdf264 <_taskRunLoopHelper+0xcdf264>
488: 00003e9f muleq r0, pc, lr ; <UNPREDICTABLE>
489: R_ARM_ABS32 .text.joystickGetDigital
48c: 00006600 andeq r6, r0, r0, lsl #12
48d: R_ARM_ABS32 .text.joystickGetDigital
490: 76000500 strvc r0, [r0], -r0, lsl #10
494: 9f1a337b svcls 0x001a337b
...
4a0: 0000000e andeq r0, r0, lr
4a0: R_ARM_ABS32 .text.joystickGetDigital
4a4: 00000012 andeq r0, r0, r2, lsl r0
4a4: R_ARM_ABS32 .text.joystickGetDigital
4a8: 7f750005 svcvc 0x00750005
4ac: 009f1a31 addseq r1, pc, r1, lsr sl ; <UNPREDICTABLE>
4b0: 00000000 andeq r0, r0, r0
4b4: 42000000 andmi r0, r0, #0
4b7: R_ARM_ABS32 .text.joystickGetDigital
4b8: 44000000 strmi r0, [r0], #-0
4bb: R_ARM_ABS32 .text.joystickGetDigital
4bc: 01000000 mrseq r0, (UNDEF: 0)
4c0: 00485200 subeq r5, r8, r0, lsl #4
4c2: R_ARM_ABS32 .text.joystickGetDigital
4c4: 00500000 subseq r0, r0, r0
4c6: R_ARM_ABS32 .text.joystickGetDigital
4c8: 00010000 andeq r0, r1, r0
4cc: 00000052 andeq r0, r0, r2, asr r0
4d0: 00000000 andeq r0, r0, r0
4d4: 00002400 andeq r2, r0, r0, lsl #8
4d5: R_ARM_ABS32 .text.joystickGetDigital
4d8: 00003200 andeq r3, r0, r0, lsl #4
4d9: R_ARM_ABS32 .text.joystickGetDigital
4dc: 50000100 andpl r0, r0, r0, lsl #2
4e0: 0000003e andeq r0, r0, lr, lsr r0
4e0: R_ARM_ABS32 .text.joystickGetDigital
4e4: 00000062 andeq r0, r0, r2, rrx
4e4: R_ARM_ABS32 .text.joystickGetDigital
4e8: 00500001 subseq r0, r0, r1
...
4f3: R_ARM_ABS32 .text.motorGet
4f4: 05000000 streq r0, [r0, #-0]
4f7: R_ARM_ABS32 .text.motorGet
4f8: 01000000 mrseq r0, (UNDEF: 0)
4fc: 00055000 andeq r5, r5, r0
4fe: R_ARM_ABS32 .text.motorGet
500: 000a0000 andeq r0, sl, r0
502: R_ARM_ABS32 .text.motorGet
504: 00040000 andeq r0, r4, r0
508: 9f5001f3 svcls 0x005001f3
...
514: R_ARM_ABS32 .text.motorSet
518: 00000009 andeq r0, r0, r9
518: R_ARM_ABS32 .text.motorSet
51c: 09500001 ldmdbeq r0, {r0}^
51f: R_ARM_ABS32 .text.motorSet
520: 2a000000 bcs 8 <.debug_loc+0x8>
523: R_ARM_ABS32 .text.motorSet
524: 04000000 streq r0, [r0], #-0
528: 5001f300 andpl pc, r1, r0, lsl #6
52c: 0000009f muleq r0, pc, r0 ; <UNPREDICTABLE>
...
535: R_ARM_ABS32 .text.motorSet
538: 00000900 andeq r0, r0, r0, lsl #18
539: R_ARM_ABS32 .text.motorSet
53c: 51000100 mrspl r0, (UNDEF: 16)
540: 00000009 andeq r0, r0, r9
540: R_ARM_ABS32 .text.motorSet
544: 00000022 andeq r0, r0, r2, lsr #32
544: R_ARM_ABS32 .text.motorSet
548: 22540001 subscs r0, r4, #1
54b: R_ARM_ABS32 .text.motorSet
54c: 28000000 stmdacs r0, {} ; <UNPREDICTABLE>
54f: R_ARM_ABS32 .text.motorSet
550: 04000000 streq r0, [r0], #-0
554: 5101f300 mrspl pc, SP_irq ; <UNPREDICTABLE>
558: 0000289f muleq r0, pc, r8 ; <UNPREDICTABLE>
559: R_ARM_ABS32 .text.motorSet
55c: 00002a00 andeq r2, r0, r0, lsl #20
55d: R_ARM_ABS32 .text.motorSet
560: 54000100 strpl r0, [r0], #-256 ; 0xffffff00
...
56c: 0000000c andeq r0, r0, ip
56c: R_ARM_ABS32 .text.motorSet
570: 00000010 andeq r0, r0, r0, lsl r0
570: R_ARM_ABS32 .text.motorSet
574: ff740004 ; <UNDEFINED> instruction: 0xff740004
578: 00109f00 andseq r9, r0, r0, lsl #30
57a: R_ARM_ABS32 .text.motorSet
57c: 00180000 andseq r0, r8, r0
57e: R_ARM_ABS32 .text.motorSet
580: 00010000 andeq r0, r1, r0
584: 00001851 andeq r1, r0, r1, asr r8
585: R_ARM_ABS32 .text.motorSet
588: 00001a00 andeq r1, r0, r0, lsl #20
589: R_ARM_ABS32 .text.motorSet
58c: 74000400 strvc r0, [r0], #-1024 ; 0xfffffc00
590: 1a9f00ff bne fe7c0404 <_taskRunLoopHelper+0xfe7c0404>
593: R_ARM_ABS32 .text.motorSet
594: 24000000 strcs r0, [r0], #-0
597: R_ARM_ABS32 .text.motorSet
598: 01000000 mrseq r0, (UNDEF: 0)
59c: 00005100 andeq r5, r0, r0, lsl #2
...
5a6: R_ARM_ABS32 .text.motorStop
5a8: 00050000 andeq r0, r5, r0
5aa: R_ARM_ABS32 .text.motorStop
5ac: 00010000 andeq r0, r1, r0
5b0: 00000550 andeq r0, r0, r0, asr r5
5b1: R_ARM_ABS32 .text.motorStop
5b4: 00000600 andeq r0, r0, r0, lsl #12
5b5: R_ARM_ABS32 .text.motorStop
5b8: f3000400 vshl.u8 d0, d0, d0
5bc: 009f5001 addseq r5, pc, r1
...
5c7: R_ARM_ABS32 .text.pinMode
5c8: 0e000000 cdpeq 0, 0, cr0, cr0, cr0, {0}
5cb: R_ARM_ABS32 .text.pinMode
5cc: 01000000 mrseq r0, (UNDEF: 0)
5d0: 000e5000 andeq r5, lr, r0
5d2: R_ARM_ABS32 .text.pinMode
5d4: 00160000 andseq r0, r6, r0
5d6: R_ARM_ABS32 .text.pinMode
5d8: 00040000 andeq r0, r4, r0
5dc: 9f5001f3 svcls 0x005001f3
5e0: 00000016 andeq r0, r0, r6, lsl r0
5e0: R_ARM_ABS32 .text.pinMode
5e4: 00000020 andeq r0, r0, r0, lsr #32
5e4: R_ARM_ABS32 .text.pinMode
5e8: 00500001 subseq r0, r0, r1
...
5f3: R_ARM_ABS32 .text.pinMode
5f4: 0a000000 beq 8 <.debug_loc+0x8>
5f7: R_ARM_ABS32 .text.pinMode
5f8: 01000000 mrseq r0, (UNDEF: 0)
5fc: 000a5100 andeq r5, sl, r0, lsl #2
5fe: R_ARM_ABS32 .text.pinMode
600: 00160000 andseq r0, r6, r0
602: R_ARM_ABS32 .text.pinMode
604: 00040000 andeq r0, r4, r0
608: 9f5101f3 svcls 0x005101f3
60c: 00000016 andeq r0, r0, r6, lsl r0
60c: R_ARM_ABS32 .text.pinMode
610: 00000020 andeq r0, r0, r0, lsr #32
610: R_ARM_ABS32 .text.pinMode
614: 00510001 subseq r0, r1, r1
618: 00000000 andeq r0, r0, r0
61c: 08000000 stmdaeq r0, {} ; <UNPREDICTABLE>
61f: R_ARM_ABS32 .text.powerLevelBackup
620: 0c000000 stceq 0, cr0, [r0], {-0}
623: R_ARM_ABS32 .text.powerLevelBackup
624: 01000000 mrseq r0, (UNDEF: 0)
628: 00005000 andeq r5, r0, r0
62c: 00000000 andeq r0, r0, r0
630: 00080000 andeq r0, r8, r0
632: R_ARM_ABS32 .text.powerLevelMain
634: 000c0000 andeq r0, ip, r0
636: R_ARM_ABS32 .text.powerLevelMain
638: 00010000 andeq r0, r1, r0
63c: 00000050 andeq r0, r0, r0, asr r0
...
645: R_ARM_ABS32 .text.setTeamName
648: 00000200 andeq r0, r0, r0, lsl #4
649: R_ARM_ABS32 .text.setTeamName
64c: 50000100 andpl r0, r0, r0, lsl #2
650: 00000006 andeq r0, r0, r6
650: R_ARM_ABS32 .text.setTeamName
654: 0000000e andeq r0, r0, lr
654: R_ARM_ABS32 .text.setTeamName
658: 00700008 rsbseq r0, r0, r8
65c: 23220072 ; <UNDEFINED> instruction: 0x23220072
660: 000e9f01 andeq r9, lr, r1, lsl #30
662: R_ARM_ABS32 .text.setTeamName
664: 00140000 andseq r0, r4, r0
666: R_ARM_ABS32 .text.setTeamName
668: 00060000 andeq r0, r6, r0
66c: 00720070 rsbseq r0, r2, r0, ror r0
670: 00009f22 andeq r9, r0, r2, lsr #30
674: 00000000 andeq r0, r0, r0
678: 00060000 andeq r0, r6, r0
67a: R_ARM_ABS32 .text.setTeamName
67c: 00140000 andseq r0, r4, r0
67e: R_ARM_ABS32 .text.setTeamName
680: 00010000 andeq r0, r1, r0
684: 00000051 andeq r0, r0, r1, asr r0
...
68d: R_ARM_ABS32 .text.setTeamName
690: 00000200 andeq r0, r0, r0, lsl #4
691: R_ARM_ABS32 .text.setTeamName
694: 30000200 andcc r0, r0, r0, lsl #4
698: 0000069f muleq r0, pc, r6 ; <UNPREDICTABLE>
699: R_ARM_ABS32 .text.setTeamName
69c: 00000a00 andeq r0, r0, r0, lsl #20
69d: R_ARM_ABS32 .text.setTeamName
6a0: 53000100 movwpl r0, #256 ; 0x100
6a4: 0000000a andeq r0, r0, sl
6a4: R_ARM_ABS32 .text.setTeamName
6a8: 0000000c andeq r0, r0, ip
6a8: R_ARM_ABS32 .text.setTeamName
6ac: 0c520001 mrrceq 0, 0, r0, r2, cr1
6af: R_ARM_ABS32 .text.setTeamName
6b0: 0e000000 cdpeq 0, 0, cr0, cr0, cr0, {0}
6b3: R_ARM_ABS32 .text.setTeamName
6b4: 03000000 movweq r0, #0
6b8: 9f017200 svcls 0x00017200
6bc: 00000014 andeq r0, r0, r4, lsl r0
6bc: R_ARM_ABS32 .text.setTeamName
6c0: 00000020 andeq r0, r0, r0, lsr #32
6c0: R_ARM_ABS32 .text.setTeamName
6c4: 22530001 subscs r0, r3, #1
6c7: R_ARM_ABS32 .text.setTeamName
6c8: 2c000000 stccs 0, cr0, [r0], {-0}
6cb: R_ARM_ABS32 .text.setTeamName
6cc: 01000000 mrseq r0, (UNDEF: 0)
6d0: 00005300 andeq r5, r0, r0, lsl #6
...
6da: R_ARM_ABS32 .text.taskRunLoop
6dc: 00060000 andeq r0, r6, r0
6de: R_ARM_ABS32 .text.taskRunLoop
6e0: 00010000 andeq r0, r1, r0
6e4: 00000650 andeq r0, r0, r0, asr r6
6e5: R_ARM_ABS32 .text.taskRunLoop
6e8: 00001a00 andeq r1, r0, r0, lsl #20
6e9: R_ARM_ABS32 .text.taskRunLoop
6ec: 55000100 strpl r0, [r0, #-256] ; 0xffffff00
6f0: 0000001a andeq r0, r0, sl, lsl r0
6f0: R_ARM_ABS32 .text.taskRunLoop
6f4: 0000001c andeq r0, r0, ip, lsl r0
6f4: R_ARM_ABS32 .text.taskRunLoop
6f8: 00700002 rsbseq r0, r0, r2
6fc: 0000001c andeq r0, r0, ip, lsl r0
6fc: R_ARM_ABS32 .text.taskRunLoop
700: 00000021 andeq r0, r0, r1, lsr #32
700: R_ARM_ABS32 .text.taskRunLoop
704: 00720002 rsbseq r0, r2, r2
708: 00000021 andeq r0, r0, r1, lsr #32
708: R_ARM_ABS32 .text.taskRunLoop
70c: 00000028 andeq r0, r0, r8, lsr #32
70c: R_ARM_ABS32 .text.taskRunLoop
710: 01f30004 mvnseq r0, r4
714: 00009f50 andeq r9, r0, r0, asr pc
...
71e: R_ARM_ABS32 .text.taskRunLoop
720: 000b0000 andeq r0, fp, r0
722: R_ARM_ABS32 .text.taskRunLoop
724: 00010000 andeq r0, r1, r0
728: 00000b51 andeq r0, r0, r1, asr fp
729: R_ARM_ABS32 .text.taskRunLoop
72c: 00001a00 andeq r1, r0, r0, lsl #20
72d: R_ARM_ABS32 .text.taskRunLoop
730: 54000100 strpl r0, [r0], #-256 ; 0xffffff00
734: 0000001a andeq r0, r0, sl, lsl r0
734: R_ARM_ABS32 .text.taskRunLoop
738: 0000001c andeq r0, r0, ip, lsl r0
738: R_ARM_ABS32 .text.taskRunLoop
73c: 04700002 ldrbteq r0, [r0], #-2
740: 0000001c andeq r0, r0, ip, lsl r0
740: R_ARM_ABS32 .text.taskRunLoop
744: 00000021 andeq r0, r0, r1, lsr #32
744: R_ARM_ABS32 .text.taskRunLoop
748: 04720002 ldrbteq r0, [r2], #-2
74c: 00000021 andeq r0, r0, r1, lsr #32
74c: R_ARM_ABS32 .text.taskRunLoop
750: 00000028 andeq r0, r0, r8, lsr #32
750: R_ARM_ABS32 .text.taskRunLoop
754: 01f30004 mvnseq r0, r4
758: 00009f51 andeq r9, r0, r1, asr pc
75c: 00000000 andeq r0, r0, r0
760: 00160000 andseq r0, r6, r0
762: R_ARM_ABS32 .text.taskRunLoop
764: 001c0000 andseq r0, ip, r0
766: R_ARM_ABS32 .text.taskRunLoop
768: 00010000 andeq r0, r1, r0
76c: 00001c50 andeq r1, r0, r0, asr ip
76d: R_ARM_ABS32 .text.taskRunLoop
770: 00002100 andeq r2, r0, r0, lsl #2
771: R_ARM_ABS32 .text.taskRunLoop
774: 52000100 andpl r0, r0, #0, 2
...
780: R_ARM_ABS32 .text.wait
784: 00000003 andeq r0, r0, r3
784: R_ARM_ABS32 .text.wait
788: 03500001 cmpeq r0, #1
78b: R_ARM_ABS32 .text.wait
78c: 04000000 streq r0, [r0], #-0
78f: R_ARM_ABS32 .text.wait
790: 04000000 streq r0, [r0], #-0
794: 5001f300 andpl pc, r1, r0, lsl #6
798: 0000009f muleq r0, pc, r0 ; <UNPREDICTABLE>
...
7a1: R_ARM_ABS32 .text.waitUntil
7a4: 00000300 andeq r0, r0, r0, lsl #6
7a5: R_ARM_ABS32 .text.waitUntil
7a8: 50000100 andpl r0, r0, r0, lsl #2
7ac: 00000003 andeq r0, r0, r3
7ac: R_ARM_ABS32 .text.waitUntil
7b0: 00000004 andeq r0, r0, r4
7b0: R_ARM_ABS32 .text.waitUntil
7b4: 01f30004 mvnseq r0, r4
7b8: 00009f50 andeq r9, r0, r0, asr pc
...
7c2: R_ARM_ABS32 .text.waitUntil
7c4: 00030000 andeq r0, r3, r0
7c6: R_ARM_ABS32 .text.waitUntil
7c8: 00010000 andeq r0, r1, r0
7cc: 00000351 andeq r0, r0, r1, asr r3
7cd: R_ARM_ABS32 .text.waitUntil
7d0: 00000400 andeq r0, r0, r0, lsl #8
7d1: R_ARM_ABS32 .text.waitUntil
7d4: f3000400 vshl.u8 d0, d0, d0
7d8: 009f5101 addseq r5, pc, r1, lsl #2
7dc: 00000000 andeq r0, r0, r0
7e0: Address 0x00000000000007e0 is out of bounds.
Disassembly of section .debug_aranges:
00000000 <.debug_aranges>:
void (*fn)(void);
clock_t period;
} LoopTask;
// Helper task for taskRunLoop()
static void _taskRunLoopHelper(void *data) {
0: 000000f4 strdeq r0, [r0], -r4
// Extract information from pointer
LoopTask *info = (LoopTask*)data;
void (*fn)(void) = info->fn;
clock_t period = info->period;
4: 00000002 andeq r0, r0, r2
6: R_ARM_ABS32 .debug_info
// Avoid leaking data
free(data);
8: 00040000 andeq r0, r4, r0
...
10: R_ARM_ABS32 .text._taskRunLoopHelper
// Start counter
clock_t now = timeLowRes();
uint16_t sf = svFlags & (SV_AUTONOMOUS | SV_ENABLED | SV_FMS);
14: 00000038 andeq r0, r0, r8, lsr r0
18: 00000000 andeq r0, r0, r0
18: R_ARM_ABS32 .text.analogCalibrate
do {
fn();
taskDelayUntil(&now, period);
1c: 00000044 andeq r0, r0, r4, asr #32
20: 00000000 andeq r0, r0, r0
20: R_ARM_ABS32 .text.analogRead
// Auto-terminate on mode switch, drop, or disable
} while ((svFlags & (SV_AUTONOMOUS | SV_ENABLED | SV_FMS)) == sf);
24: 00000014 andeq r0, r0, r4, lsl r0
28: 00000000 andeq r0, r0, r0
28: R_ARM_ABS32 .text.analogReadCalibrated
2c: 0000002c andeq r0, r0, ip, lsr #32
}
30: 00000000 andeq r0, r0, r0
30: R_ARM_ABS32 .text.analogReadCalibratedHR
34: 0000002c andeq r0, r0, ip, lsr #32
// analogCalibrate - Calibrates the analog sensor on the specified channel, assuming that it is
// not actively changing. Approximately 512 samples are taken, 1 ms apart, for a 0.5 s period
// of calibration. The average value thus calculated is returned and stored for later calls
// to analogReadCalibrated()
int analogCalibrate(unsigned char channel) {
channel--;
38: 00000000 andeq r0, r0, r0
38: R_ARM_ABS32 .text.delay
3c: 00000004 andeq r0, r0, r4
if (channel < BOARD_NR_ADC_PINS) {
40: 00000000 andeq r0, r0, r0
40: R_ARM_ABS32 .text.delayMicroseconds
44: 0000003c andeq r0, r0, ip, lsr r0
// We have the true channel, do this in a loop
uint32_t total = 0, i;
for (i = 0; i < 512; i++) {
total += adcRead(channel);
48: 00000000 andeq r0, r0, r0
48: R_ARM_ABS32 .text.digitalRead
4c: 0000002c andeq r0, r0, ip, lsr #32
taskDelay(1);
50: 00000000 andeq r0, r0, r0
50: R_ARM_ABS32 .text.digitalWrite
54: 0000002c andeq r0, r0, ip, lsr #32
int analogCalibrate(unsigned char channel) {
channel--;
if (channel < BOARD_NR_ADC_PINS) {
// We have the true channel, do this in a loop
uint32_t total = 0, i;
for (i = 0; i < 512; i++) {
58: 00000000 andeq r0, r0, r0
58: R_ARM_ABS32 .text.isAutonomous
total += adcRead(channel);
taskDelay(1);
}
// Store value (fixed to correctly round to nearest to avoid positive bias)
_analogState[channel].calibValue = (total + 16) >> 5;
5c: 00000010 andeq r0, r0, r0, lsl r0
60: 00000000 andeq r0, r0, r0
60: R_ARM_ABS32 .text.isEnabled
64: 0000001c andeq r0, r0, ip, lsl r0
68: 00000000 andeq r0, r0, r0
68: R_ARM_ABS32 .text.isJoystickConnected
return (int)((total + 256) >> 9);
6c: 00000028 andeq r0, r0, r8, lsr #32
70: 00000000 andeq r0, r0, r0
70: R_ARM_ABS32 .text.isOnline
}
return 0;
74: 00000010 andeq r0, r0, r0, lsl r0
}
78: 00000000 andeq r0, r0, r0
78: R_ARM_ABS32 .text.joystickGetAnalog
// analogRead - Reads an analog input channel 1-8 and returns the 12-bit value from 0 to 4095
int analogRead(unsigned char channel) {
channel--;
7c: 00000058 andeq r0, r0, r8, asr r0
if (channel < BOARD_NR_ADC_PINS)
80: 00000000 andeq r0, r0, r0
80: R_ARM_ABS32 .text.joystickGetDigital
84: 0000006c andeq r0, r0, ip, rrx
return (int)adcRead(channel);
88: 00000000 andeq r0, r0, r0
88: R_ARM_ABS32 .text.micros
return 0;
8c: 00000004 andeq r0, r0, r4
// analogReadCalibrated - Reads the calibrated value of an analog input channel 1-8;
// analogCalibrate() must be run first. This is inappropriate for integrated sensors as the
// round-off error can accumulate. Use analogReadCalibratedHR() instead.
int analogReadCalibrated(unsigned char channel) {
channel--;
90: 00000000 andeq r0, r0, r0
90: R_ARM_ABS32 .text.millis
94: 00000004 andeq r0, r0, r4
if (channel < BOARD_NR_ADC_PINS)
98: 00000000 andeq r0, r0, r0
98: R_ARM_ABS32 .text.motorGet
return (int)adcRead(channel) - (int)(_analogState[channel].calibValue >> 4);
9c: 0000000a andeq r0, r0, sl
a0: 00000000 andeq r0, r0, r0
a0: R_ARM_ABS32 .text.motorSet
a4: 0000002a andeq r0, r0, sl, lsr #32
a8: 00000000 andeq r0, r0, r0
a8: R_ARM_ABS32 .text.motorStop
ac: 00000006 andeq r0, r0, r6
b0: 00000000 andeq r0, r0, r0
b0: R_ARM_ABS32 .text.motorStopAll
return 0;
}
b4: 00000004 andeq r0, r0, r4
b8: 00000000 andeq r0, r0, r0
b8: R_ARM_ABS32 .text.pinMode
// drift due to round-off.
int analogReadCalibratedHR(unsigned char channel) {
// The value returned actually has 16 bits of "precision", even though the ADC only reads
// 12 bits, so that errors induced by the average value being between two values come out
// in the wash when integrated over time. Think of the value as the true value << 4.
channel--;
bc: 00000020 andeq r0, r0, r0, lsr #32
c0: 00000000 andeq r0, r0, r0
c0: R_ARM_ABS32 .text.powerLevelBackup
if (channel < BOARD_NR_ADC_PINS)
c4: 00000018 andeq r0, r0, r8, lsl r0
return (int)(adcRead(channel) << 4) - (int)(_analogState[channel].calibValue);
c8: 00000000 andeq r0, r0, r0
c8: R_ARM_ABS32 .text.powerLevelMain
cc: 00000018 andeq r0, r0, r8, lsl r0
d0: 00000000 andeq r0, r0, r0
d0: R_ARM_ABS32 .text.setTeamName
d4: 0000002c andeq r0, r0, ip, lsr #32
d8: 00000000 andeq r0, r0, r0
d8: R_ARM_ABS32 .text.taskRunLoop
dc: 00000028 andeq r0, r0, r8, lsr #32
return 0;
}
e0: 00000000 andeq r0, r0, r0
e0: R_ARM_ABS32 .text.wait
e4: 00000004 andeq r0, r0, r4
// delay - taskDelay alias
void delay(const unsigned long time) {
taskDelay((clock_t)time);
e8: 00000000 andeq r0, r0, r0
e8: R_ARM_ABS32 .text.waitUntil
}
// delayMicroseconds - Wait for approximately the given number of microseconds
void delayMicroseconds(const unsigned long time) {
ec: 00000004 andeq r0, r0, r4
...
Disassembly of section .debug_ranges:
00000000 <.debug_ranges>:
void (*fn)(void);
clock_t period;
} LoopTask;
// Helper task for taskRunLoop()
static void _taskRunLoopHelper(void *data) {
0: 0000000c andeq r0, r0, ip
0: R_ARM_ABS32 .text.digitalRead
// Extract information from pointer
LoopTask *info = (LoopTask*)data;
void (*fn)(void) = info->fn;
clock_t period = info->period;
4: 0000000e andeq r0, r0, lr
4: R_ARM_ABS32 .text.digitalRead
// Avoid leaking data
free(data);
8: 00000010 andeq r0, r0, r0, lsl r0
8: R_ARM_ABS32 .text.digitalRead
// Start counter
clock_t now = timeLowRes();
c: 0000001e andeq r0, r0, lr, lsl r0
c: R_ARM_ABS32 .text.digitalRead
...
uint16_t sf = svFlags & (SV_AUTONOMOUS | SV_ENABLED | SV_FMS);
18: 0000000e andeq r0, r0, lr
18: R_ARM_ABS32 .text.joystickGetDigital
do {
fn();
taskDelayUntil(&now, period);
1c: 00000032 andeq r0, r0, r2, lsr r0
1c: R_ARM_ABS32 .text.joystickGetDigital
20: 0000003e andeq r0, r0, lr, lsr r0
20: R_ARM_ABS32 .text.joystickGetDigital
// Auto-terminate on mode switch, drop, or disable
} while ((svFlags & (SV_AUTONOMOUS | SV_ENABLED | SV_FMS)) == sf);
24: 0000005c andeq r0, r0, ip, asr r0
24: R_ARM_ABS32 .text.joystickGetDigital
...
}
30: 0000000c andeq r0, r0, ip
30: R_ARM_ABS32 .text.motorSet
34: 0000001e andeq r0, r0, lr, lsl r0
34: R_ARM_ABS32 .text.motorSet
// analogCalibrate - Calibrates the analog sensor on the specified channel, assuming that it is
// not actively changing. Approximately 512 samples are taken, 1 ms apart, for a 0.5 s period
// of calibration. The average value thus calculated is returned and stored for later calls
// to analogReadCalibrated()
int analogCalibrate(unsigned char channel) {
channel--;
38: 00000022 andeq r0, r0, r2, lsr #32
38: R_ARM_ABS32 .text.motorSet
3c: 0000002a andeq r0, r0, sl, lsr #32
3c: R_ARM_ABS32 .text.motorSet
...
48: R_ARM_ABS32 .text._taskRunLoopHelper
if (channel < BOARD_NR_ADC_PINS) {
// We have the true channel, do this in a loop
uint32_t total = 0, i;
for (i = 0; i < 512; i++) {
total += adcRead(channel);
4c: 00000038 andeq r0, r0, r8, lsr r0
4c: R_ARM_ABS32 .text._taskRunLoopHelper
taskDelay(1);
50: 00000000 andeq r0, r0, r0
50: R_ARM_ABS32 .text.analogCalibrate
54: 00000044 andeq r0, r0, r4, asr #32
54: R_ARM_ABS32 .text.analogCalibrate
int analogCalibrate(unsigned char channel) {
channel--;
if (channel < BOARD_NR_ADC_PINS) {
// We have the true channel, do this in a loop
uint32_t total = 0, i;
for (i = 0; i < 512; i++) {
58: 00000000 andeq r0, r0, r0
58: R_ARM_ABS32 .text.analogRead
total += adcRead(channel);
taskDelay(1);
}
// Store value (fixed to correctly round to nearest to avoid positive bias)
_analogState[channel].calibValue = (total + 16) >> 5;
5c: 00000014 andeq r0, r0, r4, lsl r0
5c: R_ARM_ABS32 .text.analogRead
60: 00000000 andeq r0, r0, r0
60: R_ARM_ABS32 .text.analogReadCalibrated
64: 0000002c andeq r0, r0, ip, lsr #32
64: R_ARM_ABS32 .text.analogReadCalibrated
68: 00000000 andeq r0, r0, r0
68: R_ARM_ABS32 .text.analogReadCalibratedHR
return (int)((total + 256) >> 9);
6c: 0000002c andeq r0, r0, ip, lsr #32
6c: R_ARM_ABS32 .text.analogReadCalibratedHR
70: 00000000 andeq r0, r0, r0
70: R_ARM_ABS32 .text.delay
}
return 0;
74: 00000004 andeq r0, r0, r4
74: R_ARM_ABS32 .text.delay
}
78: 00000000 andeq r0, r0, r0
78: R_ARM_ABS32 .text.delayMicroseconds
// analogRead - Reads an analog input channel 1-8 and returns the 12-bit value from 0 to 4095
int analogRead(unsigned char channel) {
channel--;
7c: 0000003c andeq r0, r0, ip, lsr r0
7c: R_ARM_ABS32 .text.delayMicroseconds
if (channel < BOARD_NR_ADC_PINS)
80: 00000000 andeq r0, r0, r0
80: R_ARM_ABS32 .text.digitalRead
84: 0000002c andeq r0, r0, ip, lsr #32
84: R_ARM_ABS32 .text.digitalRead
return (int)adcRead(channel);
88: 00000000 andeq r0, r0, r0
88: R_ARM_ABS32 .text.digitalWrite
return 0;
8c: 0000002c andeq r0, r0, ip, lsr #32
8c: R_ARM_ABS32 .text.digitalWrite
// analogReadCalibrated - Reads the calibrated value of an analog input channel 1-8;
// analogCalibrate() must be run first. This is inappropriate for integrated sensors as the
// round-off error can accumulate. Use analogReadCalibratedHR() instead.
int analogReadCalibrated(unsigned char channel) {
channel--;
90: 00000000 andeq r0, r0, r0
90: R_ARM_ABS32 .text.isAutonomous
94: 00000010 andeq r0, r0, r0, lsl r0
94: R_ARM_ABS32 .text.isAutonomous
if (channel < BOARD_NR_ADC_PINS)
98: 00000000 andeq r0, r0, r0
98: R_ARM_ABS32 .text.isEnabled
return (int)adcRead(channel) - (int)(_analogState[channel].calibValue >> 4);
9c: 0000001c andeq r0, r0, ip, lsl r0
9c: R_ARM_ABS32 .text.isEnabled
a0: 00000000 andeq r0, r0, r0
a0: R_ARM_ABS32 .text.isJoystickConnected
a4: 00000028 andeq r0, r0, r8, lsr #32
a4: R_ARM_ABS32 .text.isJoystickConnected
a8: 00000000 andeq r0, r0, r0
a8: R_ARM_ABS32 .text.isOnline
ac: 00000010 andeq r0, r0, r0, lsl r0
ac: R_ARM_ABS32 .text.isOnline
b0: 00000000 andeq r0, r0, r0
b0: R_ARM_ABS32 .text.joystickGetAnalog
return 0;
}
b4: 00000058 andeq r0, r0, r8, asr r0
b4: R_ARM_ABS32 .text.joystickGetAnalog
b8: 00000000 andeq r0, r0, r0
b8: R_ARM_ABS32 .text.joystickGetDigital
// drift due to round-off.
int analogReadCalibratedHR(unsigned char channel) {
// The value returned actually has 16 bits of "precision", even though the ADC only reads
// 12 bits, so that errors induced by the average value being between two values come out
// in the wash when integrated over time. Think of the value as the true value << 4.
channel--;
bc: 0000006c andeq r0, r0, ip, rrx
bc: R_ARM_ABS32 .text.joystickGetDigital
c0: 00000000 andeq r0, r0, r0
c0: R_ARM_ABS32 .text.micros
if (channel < BOARD_NR_ADC_PINS)
c4: 00000004 andeq r0, r0, r4
c4: R_ARM_ABS32 .text.micros
return (int)(adcRead(channel) << 4) - (int)(_analogState[channel].calibValue);
c8: 00000000 andeq r0, r0, r0
c8: R_ARM_ABS32 .text.millis
cc: 00000004 andeq r0, r0, r4
cc: R_ARM_ABS32 .text.millis
d0: 00000000 andeq r0, r0, r0
d0: R_ARM_ABS32 .text.motorGet
d4: 0000000a andeq r0, r0, sl
d4: R_ARM_ABS32 .text.motorGet
d8: 00000000 andeq r0, r0, r0
d8: R_ARM_ABS32 .text.motorSet
dc: 0000002a andeq r0, r0, sl, lsr #32
dc: R_ARM_ABS32 .text.motorSet
return 0;
}
e0: 00000000 andeq r0, r0, r0
e0: R_ARM_ABS32 .text.motorStop
e4: 00000006 andeq r0, r0, r6
e4: R_ARM_ABS32 .text.motorStop
// delay - taskDelay alias
void delay(const unsigned long time) {
taskDelay((clock_t)time);
e8: 00000000 andeq r0, r0, r0
e8: R_ARM_ABS32 .text.motorStopAll
}
// delayMicroseconds - Wait for approximately the given number of microseconds
void delayMicroseconds(const unsigned long time) {
ec: 00000004 andeq r0, r0, r4
ec: R_ARM_ABS32 .text.motorStopAll
clock_t us = (clock_t)time;
if (us) {
f0: 00000000 andeq r0, r0, r0
f0: R_ARM_ABS32 .text.pinMode
/*us *= 12; us--;
asm volatile(" mov r0, %[us]\n\t"
"1: subs r0, #1\n\t"
" bhi 1b\n\t"
: : [us] "r" (us) : "r0");*/
if (us > 1000) {
f4: 00000020 andeq r0, r0, r0, lsr #32
f4: R_ARM_ABS32 .text.pinMode
// Wait off the milliseconds part first
clock_t millis = (clock_t)(us / 1000UL);
us %= 1000UL;
f8: 00000000 andeq r0, r0, r0
f8: R_ARM_ABS32 .text.powerLevelBackup
fc: 00000018 andeq r0, r0, r8, lsl r0
fc: R_ARM_ABS32 .text.powerLevelBackup
100: 00000000 andeq r0, r0, r0
100: R_ARM_ABS32 .text.powerLevelMain
taskDelay(millis);
104: 00000018 andeq r0, r0, r8, lsl r0
104: R_ARM_ABS32 .text.powerLevelMain
}
if (us) {
108: 00000000 andeq r0, r0, r0
108: R_ARM_ABS32 .text.setTeamName
10c: 0000002c andeq r0, r0, ip, lsr #32
10c: R_ARM_ABS32 .text.setTeamName
// Spin on the highres timer value (next IRQ might be up to 1ms away!)
// Power consumption is bad, CPU usage possibly worse, but accuracy is acceptable
uint16_t start = TIM8->CNT;
110: 00000000 andeq r0, r0, r0
110: R_ARM_ABS32 .text.taskRunLoop
114: 00000028 andeq r0, r0, r8, lsr #32
114: R_ARM_ABS32 .text.taskRunLoop
while (TIM8->CNT - start < us);
118: 00000000 andeq r0, r0, r0
118: R_ARM_ABS32 .text.wait
11c: 00000004 andeq r0, r0, r4
11c: R_ARM_ABS32 .text.wait
120: 00000000 andeq r0, r0, r0
120: R_ARM_ABS32 .text.waitUntil
124: 00000004 andeq r0, r0, r4
124: R_ARM_ABS32 .text.waitUntil
...
Disassembly of section .debug_line:
00000000 <.debug_line>:
void (*fn)(void);
clock_t period;
} LoopTask;
// Helper task for taskRunLoop()
static void _taskRunLoopHelper(void *data) {
0: 0000040e andeq r0, r0, lr, lsl #8
// Extract information from pointer
LoopTask *info = (LoopTask*)data;
void (*fn)(void) = info->fn;
clock_t period = info->period;
4: 01280002 ; <UNDEFINED> instruction: 0x01280002
// Avoid leaking data
free(data);
8: 01020000 mrseq r0, (UNDEF: 2)
// Start counter
clock_t now = timeLowRes();
c: 000d0efb strdeq r0, [sp], -fp
10: 01010101 tsteq r1, r1, lsl #2
uint16_t sf = svFlags & (SV_AUTONOMOUS | SV_ENABLED | SV_FMS);
14: 01000000 mrseq r0, (UNDEF: 0)
18: 2e010000 cdpcs 0, 0, cr0, cr1, cr0, {0}
do {
fn();
taskDelayUntil(&now, period);
1c: 6e692f2e cdpvs 15, 6, cr2, cr9, cr14, {1}
20: 64756c63 ldrbtvs r6, [r5], #-3171 ; 0xfffff39d
// Auto-terminate on mode switch, drop, or disable
} while ((svFlags & (SV_AUTONOMOUS | SV_ENABLED | SV_FMS)) == sf);
24: 752f0065 strvc r0, [pc, #-101]! ; ffffffc7 <_taskRunLoopHelper+0xffffffc7>
28: 692f7273 stmdbvs pc!, {r0, r1, r4, r5, r6, r9, ip, sp, lr} ; <UNPREDICTABLE>
2c: 756c636e strbvc r6, [ip, #-878]! ; 0xfffffc92
}
30: 6e2f6564 cfsh64vs mvdx6, mvdx15, #52
34: 696c7765 stmdbvs ip!, {r0, r2, r5, r6, r8, r9, sl, ip, sp, lr}^
// analogCalibrate - Calibrates the analog sensor on the specified channel, assuming that it is
// not actively changing. Approximately 512 samples are taken, 1 ms apart, for a 0.5 s period
// of calibration. The average value thus calculated is returned and stored for later calls
// to analogReadCalibrated()
int analogCalibrate(unsigned char channel) {
channel--;
38: 616d2f62 cmnvs sp, r2, ror #30
3c: 6e696863 cdpvs 8, 6, cr6, cr9, cr3, {3}
if (channel < BOARD_NR_ADC_PINS) {
40: 752f0065 strvc r0, [pc, #-101]! ; ffffffe3 <_taskRunLoopHelper+0xffffffe3>
44: 692f7273 stmdbvs pc!, {r0, r1, r4, r5, r6, r9, ip, sp, lr} ; <UNPREDICTABLE>
// We have the true channel, do this in a loop
uint32_t total = 0, i;
for (i = 0; i < 512; i++) {
total += adcRead(channel);
48: 756c636e strbvc r6, [ip, #-878]! ; 0xfffffc92
4c: 6e2f6564 cfsh64vs mvdx6, mvdx15, #52
taskDelay(1);
50: 696c7765 stmdbvs ip!, {r0, r2, r5, r6, r8, r9, sl, ip, sp, lr}^
54: 79732f62 ldmdbvc r3!, {r1, r5, r6, r8, r9, sl, fp, sp}^
int analogCalibrate(unsigned char channel) {
channel--;
if (channel < BOARD_NR_ADC_PINS) {
// We have the true channel, do this in a loop
uint32_t total = 0, i;
for (i = 0; i < 512; i++) {
58: 752f0073 strvc r0, [pc, #-115]! ; ffffffed <_taskRunLoopHelper+0xffffffed>
total += adcRead(channel);
taskDelay(1);
}
// Store value (fixed to correctly round to nearest to avoid positive bias)
_analogState[channel].calibValue = (total + 16) >> 5;
5c: 6c2f7273 sfmvs f7, 4, [pc], #-460 ; fffffe98 <_taskRunLoopHelper+0xfffffe98>
60: 672f6269 strvs r6, [pc, -r9, ror #4]!
64: 612f6363 ; <UNDEFINED> instruction: 0x612f6363
68: 6e2d6d72 mcrvs 13, 1, r6, cr13, cr2, {3}
return (int)((total + 256) >> 9);
6c: 2d656e6f stclcs 14, cr6, [r5, #-444]! ; 0xfffffe44
70: 69626165 stmdbvs r2!, {r0, r2, r5, r6, r8, sp, lr}^
}
return 0;
74: 392e342f stmdbcc lr!, {r0, r1, r2, r3, r5, sl, ip, sp}
}
78: 692f332e stmdbvs pc!, {r1, r2, r3, r5, r8, r9, ip, sp} ; <UNPREDICTABLE>
// analogRead - Reads an analog input channel 1-8 and returns the 12-bit value from 0 to 4095
int analogRead(unsigned char channel) {
channel--;
7c: 756c636e strbvc r6, [ip, #-878]! ; 0xfffffc92
if (channel < BOARD_NR_ADC_PINS)
80: 2f006564 svccs 0x00006564
84: 2f727375 svccs 0x00727375
return (int)adcRead(channel);
88: 6c636e69 stclvs 14, cr6, [r3], #-420 ; 0xfffffe5c
return 0;
8c: 2f656475 svccs 0x00656475
// analogReadCalibrated - Reads the calibrated value of an analog input channel 1-8;
// analogCalibrate() must be run first. This is inappropriate for integrated sensors as the
// round-off error can accumulate. Use analogReadCalibratedHR() instead.
int analogReadCalibrated(unsigned char channel) {
channel--;
90: 6c77656e cfldr64vs mvdx6, [r7], #-440 ; 0xfffffe48
94: 00006269 andeq r6, r0, r9, ror #4
if (channel < BOARD_NR_ADC_PINS)
98: 2e495041 cdpcs 0, 4, cr5, cr9, cr1, {2}
return (int)adcRead(channel) - (int)(_analogState[channel].calibValue >> 4);
9c: 00000063 andeq r0, r0, r3, rrx
a0: 72657000 rsbvc r7, r5, #0
a4: 2e687069 cdpcs 0, 6, cr7, cr8, cr9, {3}
a8: 00010068 andeq r0, r1, r8, rrx
ac: 70757300 rsbsvc r7, r5, r0, lsl #6
b0: 69767265 ldmdbvs r6!, {r0, r2, r5, r6, r9, ip, sp, lr}^
return 0;
}
b4: 2e726f73 mrccs 15, 3, r6, cr2, cr3, {3}
b8: 00010068 andeq r0, r1, r8, rrx
// drift due to round-off.
int analogReadCalibratedHR(unsigned char channel) {
// The value returned actually has 16 bits of "precision", even though the ADC only reads
// 12 bits, so that errors induced by the average value being between two values come out
// in the wash when integrated over time. Think of the value as the true value << 4.
channel--;
bc: 65645f00 strbvs r5, [r4, #-3840]! ; 0xfffff100
c0: 6c756166 ldfvse f6, [r5], #-408 ; 0xfffffe68
if (channel < BOARD_NR_ADC_PINS)
c4: 79745f74 ldmdbvc r4!, {r2, r4, r5, r6, r8, r9, sl, fp, ip, lr}^
return (int)(adcRead(channel) << 4) - (int)(_analogState[channel].calibValue);
c8: 2e736570 mrccs 5, 3, r6, cr3, cr0, {3}
cc: 00020068 andeq r0, r2, r8, rrx
d0: 74735f00 ldrbtvc r5, [r3], #-3840 ; 0xfffff100
d4: 746e6964 strbtvc r6, [lr], #-2404 ; 0xfffff69c
d8: 0300682e movweq r6, #2094 ; 0x82e
dc: 74730000 ldrbtvc r0, [r3], #-0
return 0;
}
e0: 66656464 strbtvs r6, [r5], -r4, ror #8
e4: 0400682e streq r6, [r0], #-2094 ; 0xfffff7d2
// delay - taskDelay alias
void delay(const unsigned long time) {
taskDelay((clock_t)time);
e8: 79740000 ldmdbvc r4!, {}^ ; <UNPREDICTABLE>
}
// delayMicroseconds - Wait for approximately the given number of microseconds
void delayMicroseconds(const unsigned long time) {
ec: 2e736570 mrccs 5, 3, r6, cr3, cr0, {3}
clock_t us = (clock_t)time;
if (us) {
f0: 00030068 andeq r0, r3, r8, rrx
/*us *= 12; us--;
asm volatile(" mov r0, %[us]\n\t"
"1: subs r0, #1\n\t"
" bhi 1b\n\t"
: : [us] "r" (us) : "r0");*/
if (us > 1000) {
f4: 726f6300 rsbvc r6, pc, #0, 6
// Wait off the milliseconds part first
clock_t millis = (clock_t)(us / 1000UL);
us %= 1000UL;
f8: 2e786574 mrccs 5, 3, r6, cr8, cr4, {3}
fc: 00010068 andeq r0, r1, r8, rrx
100: 73617400 cmnvc r1, #0, 8
taskDelay(millis);
104: 00682e6b rsbeq r2, r8, fp, ror #28
}
if (us) {
108: 46000001 strmi r0, [r0], -r1
10c: 52656572 rsbpl r6, r5, #478150656 ; 0x1c800000
// Spin on the highres timer value (next IRQ might be up to 1ms away!)
// Power consumption is bad, CPU usage possibly worse, but accuracy is acceptable
uint16_t start = TIM8->CNT;
110: 2e534f54 mrccs 15, 2, r4, cr3, cr4, {2}
114: 00010068 andeq r0, r1, r8, rrx
while (TIM8->CNT - start < us);
118: 64747300 ldrbtvs r7, [r4], #-768 ; 0xfffffd00
11c: 2e62696c cdpcs 9, 6, cr6, cr2, cr12, {3}
120: 00050068 andeq r0, r5, r8, rrx
124: 72656b00 rsbvc r6, r5, #0, 22
}
}
}
// digitalRead - Gets the digital value (1 or 0) of a pin configured as a digital input
bool digitalRead(unsigned char pin) {
128: 2e6c656e cdpcs 5, 6, cr6, cr12, cr14, {3}
if (pin >= BOARD_NR_GPIO_PINS)
return 0;
return ioGetInput((GPIO_TypeDef*)_pinLookupTable[pin], (uint8_t)_pinIndexTable[pin]);
12c: 00010068 andeq r0, r1, r8, rrx
130: 05000000 streq r0, [r0, #-0]
}
// ioGetInput - Gets the digital value (1 or 0) of a pin configured as a digital input
static INLINE bool ioGetInput(GPIO_TypeDef* port, uint32_t pin) {
// Shift right that many bits, then mask everything but the ones
return ((port->IDR >> (pin & 0x0F)) & 0x01) != 0;
134: 00000002 andeq r0, r0, r2
135: R_ARM_ABS32 .text._taskRunLoopHelper
138: 011a0300 tsteq sl, r0, lsl #6
13c: 2f303024 svccs 0x00303024
140: 02002f1f andeq r2, r0, #31, 30 ; 0x7c
144: 003e0104 eorseq r0, lr, r4, lsl #2
}
// digitalRead - Gets the digital value (1 or 0) of a pin configured as a digital input
bool digitalRead(unsigned char pin) {
if (pin >= BOARD_NR_GPIO_PINS)
return 0;
148: 21010402 tstcs r1, r2, lsl #8
return ioGetInput((GPIO_TypeDef*)_pinLookupTable[pin], (uint8_t)_pinIndexTable[pin]);
}
14c: 01040200 mrseq r0, R12_usr
150: 0502594c streq r5, [r2, #-2380] ; 0xfffff6b4
// digitalWrite - Sets the digital value (1 or 0) of a pin configured as a digital output
void digitalWrite(unsigned char pin, bool value) {
// We will let this work when disabled, even though it might change a solenoid, since it
// is needed to set initial solenoid states in initializeIO() when enabled/disabled is
// undefined.
if (pin < BOARD_NR_GPIO_PINS)
154: 00010100 andeq r0, r1, r0, lsl #2
158: 00000205 andeq r0, r0, r5, lsl #4
15a: R_ARM_ABS32 .text.analogCalibrate
ioSetOutput((GPIO_TypeDef*)_pinLookupTable[pin], (uint8_t)_pinIndexTable[pin], value);
15c: 2f030000 svccs 0x00030000
160: 211f1301 tstcs pc, r1, lsl #6
164: 04020021 streq r0, [r2], #-33 ; 0xffffffdf
168: 02005c03 andeq r5, r0, #768 ; 0x300
return ((port->ODR >> (pin & 0x0F)) & 0x01) != 0;
}
// ioSetOutput - Sets the digital value (1 or 0) of a pin configured as a digital output
static INLINE void ioSetOutput(GPIO_TypeDef* port, uint32_t pin, bool value) {
if (value)
16c: 004b0304 subeq r0, fp, r4, lsl #6
// Atomic bit set
port->BSRR = ((uint32_t)0x00000001) << (pin & 0x0F);
170: 3a030402 bcc c1180 <_taskRunLoopHelper+0xc1180>
else
// Atomic bit reset
port->BRR = ((uint32_t)0x00000001) << (pin & 0x0F);
174: 212d8333 ; <UNDEFINED> instruction: 0x212d8333
178: 03022130 movweq r2, #8496 ; 0x2130
17c: 00010100 andeq r0, r1, r0, lsl #2
}
// isAutonomous - Checks to see if the system is in autonomous mode
bool isAutonomous() {
return (svFlags & SV_AUTONOMOUS) ? true : false;
180: 00000205 andeq r0, r0, r5, lsl #4
182: R_ARM_ABS32 .text.analogRead
}
184: c0030000 andgt r0, r3, r0
188: 2f130100 svccs 0x00130100
18c: 3d21221e sfmcc f2, 4, [r1, #-120]! ; 0xffffff88
// isEnabled - Checks to see if the system is enabled
bool isEnabled() {
uint16_t flags = svFlags;
190: 00010221 andeq r0, r1, r1, lsr #4
194: 05000101 streq r0, [r0, #-257] ; 0xfffffeff
if (!(flags & SV_ENABLED)) {
if (flags & SV_FMS)
198: 00000002 andeq r0, r0, r2
199: R_ARM_ABS32 .text.analogReadCalibrated
19c: 00ca0300 sbceq r0, sl, r0, lsl #6
1a0: 211f1301 tstcs pc, r1, lsl #6
return false;
}
return true;
}
1a4: 21bb2f21 ; <UNDEFINED> instruction: 0x21bb2f21
1a8: 01000402 tsteq r0, r2, lsl #8
}
// svIsJoystickConnected - Checks to see if a joystick is connected
static INLINE uint8_t svIsJoystickConnected(uint8_t joystick) {
// Force in range from 0..1 (mapped from 1..2)
joystick = (joystick - 1) & (uint8_t)0x01;
1ac: 02050001 andeq r0, r5, #1
// If both accelerometer axes are zero, the joystick is likely not plugged in
// Obviously there is a chance for false positives but extremely unlikely due to the noise
// of the analog accelerometers
return SV_IN->joystick[joystick].axis[4] != (uint8_t)0x7F ||
1b0: 00000000 andeq r0, r0, r0
1b0: R_ARM_ABS32 .text.analogReadCalibratedHR
1b4: 0100d403 tsteq r0, r3, lsl #8
1b8: 21241c16 ; <UNDEFINED> instruction: 0x21241c16
1bc: 0221bb2f eoreq fp, r1, #48128 ; 0xbc00
SV_IN->joystick[joystick].axis[5] != (uint8_t)0x7F;
1c0: 01010004 tsteq r1, r4
// Force in range from 0..1 (mapped from 1..2)
joystick = (joystick - 1) & (uint8_t)0x01;
// If both accelerometer axes are zero, the joystick is likely not plugged in
// Obviously there is a chance for false positives but extremely unlikely due to the noise
// of the analog accelerometers
return SV_IN->joystick[joystick].axis[4] != (uint8_t)0x7F ||
1c4: 00020500 andeq r0, r2, r0, lsl #10
1c7: R_ARM_ABS32 .text.delay
1c8: 03000000 movweq r0, #0
1cc: 130100df movwne r0, #4319 ; 0x10df
// isJoystickConnected - Checks to see if the specified joystick is plugged in
bool isJoystickConnected(unsigned char joystick) {
return svIsJoystickConnected(joystick) ? true : false;
}
1d0: 01000202 tsteq r0, r2, lsl #4
// isOnline - Checks to see if the system is connected to a FMS/competition switch
bool isOnline() {
return (svFlags & SV_FMS) ? true : false;
1d4: 02050001 andeq r0, r5, #1
}
1d8: 00000000 andeq r0, r0, r0
1d8: R_ARM_ABS32 .text.delayMicroseconds
1dc: 0100e403 tsteq r0, r3, lsl #8
1e0: 673f3522 ldrvs r3, [pc, -r2, lsr #10]!
// joystickGetAnalog - Retrieve an analog axis of a joystick
int joystickGetAnalog(unsigned char joystick, unsigned char axis) {
1e4: 02003f30 andeq r3, r0, #48, 30 ; 0xc0
1e8: 024b0104 subeq r0, fp, #4, 2
// Safety first here
if (isOnline() && isAutonomous()) return 0;
1ec: 01010009 tsteq r1, r9
// svGetJoystickAnalog - Gets an analog joystick axis or accelerometer axis from the supervisor
// NO check on the mode when doing so
static INLINE int8_t svGetJoystickAnalog(uint8_t joystick, uint8_t axis) {
uint8_t value;
// Force in range from 0..5 (mapped from 1..6)
axis = (axis - 1) % 6;
1f0: 00020500 andeq r0, r2, r0, lsl #10
1f3: R_ARM_ABS32 .text.digitalRead
1f4: 03000000 movweq r0, #0
1f8: 010100fd strdeq r0, [r1, -sp]
// Force in range from 0..1 (mapped from 1..2)
joystick = (joystick - 1) & (uint8_t)0x01;
1fc: 02042221 andeq r2, r4, #268435458 ; 0x10000002
value = SV_IN->joystick[joystick].axis[axis];
200: 4a00cc03 bmi 33214 <_taskRunLoopHelper+0x33214>
204: b4030104 strlt r0, [r3], #-260 ; 0xfffffefc
208: 0204207f andeq r2, r4, #127 ; 0x7f
// Prevent return of 128
if (value == 0xFF)
value = 0xFE;
value -= 127;
if (axis == 1 || axis == 2)
20c: 2000cc03 andcs ip, r0, r3, lsl #24
uint8_t value;
// Force in range from 0..5 (mapped from 1..6)
axis = (axis - 1) % 6;
// Force in range from 0..1 (mapped from 1..2)
joystick = (joystick - 1) & (uint8_t)0x01;
value = SV_IN->joystick[joystick].axis[axis];
210: b3030104 movwlt r0, #12548 ; 0x3104
// Prevent return of 128
if (value == 0xFF)
value = 0xFE;
214: 0230747f eorseq r7, r0, #2130706432 ; 0x7f000000
value -= 127;
if (axis == 1 || axis == 2)
218: 01010005 tsteq r1, r5
joystick = (joystick - 1) & (uint8_t)0x01;
value = SV_IN->joystick[joystick].axis[axis];
// Prevent return of 128
if (value == 0xFF)
value = 0xFE;
value -= 127;
21c: 00020500 andeq r0, r2, r0, lsl #10
21f: R_ARM_ABS32 .text.digitalWrite
if (axis == 1 || axis == 2)
220: 03000000 movweq r0, #0
value = -value;
224: 16010184 strne r0, [r1], -r4, lsl #3
228: 0421241c strteq r2, [r1], #-1052 ; 0xfffffbe4
22c: 00d00302 sbcseq r0, r0, r2, lsl #6
230: 31221e82 smlawbcc r2, r2, lr, r1
return (int)svGetJoystickAnalog(joystick, axis);
234: 01000702 tsteq r0, r2, lsl #14
238: 02050001 andeq r0, r5, #1
}
// joystickGetDigital - Retrieve a digital button of a joystick
bool joystickGetDigital(unsigned char joystick, unsigned char buttonGroup,
unsigned char button) {
23c: 00000000 andeq r0, r0, r0
23c: R_ARM_ABS32 .text.isAutonomous
240: 01018d03 tsteq r1, r3, lsl #26
// Safety first here
if (isOnline() && isAutonomous()) return false;
244: 06022f13 ; <UNDEFINED> instruction: 0x06022f13
248: 00010100 andeq r0, r1, r0, lsl #2
static INLINE uint8_t svGetJoystickDigital(uint8_t joystick, uint8_t button) {
uint8_t value; volatile Joystick_TypeDef *ref;
// Force in range from 0..3 (mapped from 5..8)
button = (button - 5) & (uint8_t)0x03;
// Force in range from 0..1 (mapped from 1..2)
joystick = (joystick - 1) & (uint8_t)0x01;
24c: 00000205 andeq r0, r0, r5, lsl #4
24e: R_ARM_ABS32 .text.isEnabled
ref = &SV_IN->joystick[joystick];
// 5 and 6 need some mangling to move the twos bit up to the fours
switch (button) {
250: 92030000 andls r0, r3, #0
uint8_t value; volatile Joystick_TypeDef *ref;
// Force in range from 0..3 (mapped from 5..8)
button = (button - 5) & (uint8_t)0x03;
// Force in range from 0..1 (mapped from 1..2)
joystick = (joystick - 1) & (uint8_t)0x01;
ref = &SV_IN->joystick[joystick];
254: 3d130101 ldfccs f0, [r3, #-4]
258: 02215b21 eoreq r5, r1, #33792 ; 0x8400
25c: 01010004 tsteq r1, r4
// 5 and 6 need some mangling to move the twos bit up to the fours
switch (button) {
260: 00020500 andeq r0, r2, r0, lsl #10
263: R_ARM_ABS32 .text.isJoystickConnected
264: 03000000 movweq r0, #0
// 6
value = ref->button56 >> 2;
return ((value & 0x02) << 1) | (value & 0x01);
case 2:
// 7
return ref->button78 >> 4;
268: 0401019c streq r0, [r1], #-412 ; 0xfffffe64
26c: 011d0303 tsteq sp, r3, lsl #6
270: 042d9124 strteq r9, [sp], #-292 ; 0xfffffedc
274: 58610301 stmdapl r1!, {r0, r8, r9}^
return (svGetJoystickDigital(joystick, buttonGroup) & button) ? true : false;
}
278: 01000302 tsteq r0, r2, lsl #6
ref = &SV_IN->joystick[joystick];
// 5 and 6 need some mangling to move the twos bit up to the fours
switch (button) {
case 0:
// 5
value = ref->button56;
27c: 02050001 andeq r0, r5, #1
return ((value & 0x02) << 1) | (value & 0x01);
case 1:
// 6
value = ref->button56 >> 2;
280: 00000000 andeq r0, r0, r0
280: R_ARM_ABS32 .text.isOnline
return ((value & 0x02) << 1) | (value & 0x01);
284: 0101a103 tsteq r1, r3, lsl #2
288: 06022f13 ; <UNDEFINED> instruction: 0x06022f13
28c: 00010100 andeq r0, r1, r0, lsl #2
290: 00000205 andeq r0, r0, r5, lsl #4
292: R_ARM_ABS32 .text.joystickGetAnalog
case 2:
// 7
return ref->button78 >> 4;
default:
// 8 (No other case is possible...)
return ref->button78 & 0x0F;
294: a6030000 strge r0, [r3], -r0
// joystickGetDigital - Retrieve a digital button of a joystick
bool joystickGetDigital(unsigned char joystick, unsigned char buttonGroup,
unsigned char button) {
// Safety first here
if (isOnline() && isAutonomous()) return false;
return (svGetJoystickDigital(joystick, buttonGroup) & button) ? true : false;
298: 30200101 eorcc r0, r0, r1, lsl #2
29c: 53030304 movwpl r0, #13060 ; 0x3304
2a0: 231e683c tstcs lr, #60, 16 ; 0x3c0000
2a4: 3e311b6b vsubcc.f64 d1, d1, d27
}
// micros - Arduino-compatible alias for timeHighRes()
unsigned long micros() {
return (unsigned long)timeHighRes();
2a8: 04213d1f strteq r3, [r1], #-3359 ; 0xfffff2e1
}
// millis - Arduino-compatible alias for timeLowRes()
unsigned long millis() {
return (unsigned long)timeLowRes();
2ac: 04020001 streq r0, [r2], #-1
}
// motorGet - Gets last commanded speed of the specified motor channel; this speed is reset
// to 0 if motors are stopped by the kernel for any reason
int motorGet(unsigned char channel) {
2b0: 3c240301 stccc 3, cr0, [r4], #-4
// Convert range
return (int)motorControlGet(channel) - 127;
2b4: 22064a06 andcs r4, r6, #24576 ; 0x6000
}
2b8: 0004021f andeq r0, r4, pc, lsl r2
// motorSet - Sets the speed of the specified motor channel from 1 to 10, where -127 is full
// reverse and 127 is full forward, with 0 being off
void motorSet(unsigned char channel, int speed) {
2bc: 05000101 streq r0, [r0, #-257] ; 0xfffffeff
if (isEnabled()) {
2c0: 00000002 andeq r0, r0, r2
2c1: R_ARM_ABS32 .text.joystickGetDigital
2c4: 01ae0300 ; <UNDEFINED> instruction: 0x01ae0300
int ns = speed + 127;
// Equalize the bias
if (ns < 0) ns = 0;
2c8: 043e2001 ldrteq r2, [lr], #-1
if (ns > 255) ns = 255;
2cc: 3c5d0303 mrrccc 3, 0, r0, sp, cr3
2d0: 2c222122 stfcss f2, [r2], #-136 ; 0xffffff78
// reverse and 127 is full forward, with 0 being off
void motorSet(unsigned char channel, int speed) {
if (isEnabled()) {
int ns = speed + 127;
// Equalize the bias
if (ns < 0) ns = 0;
2d4: 03301e3e teqeq r0, #992 ; 0x3e0
if (ns > 255) ns = 255;
motorControlSet(channel, (uint8_t)ns);
}
}
2d8: 01044a0b tsteq r4, fp, lsl #20
if (isEnabled()) {
int ns = speed + 127;
// Equalize the bias
if (ns < 0) ns = 0;
if (ns > 255) ns = 255;
motorControlSet(channel, (uint8_t)ns);
2dc: 01040200 mrseq r0, R12_usr
2e0: 063c1303 ldrteq r1, [ip], -r3, lsl #6
}
// motorStop - Stops the motor on the specified channel, equivalent to calling motorSet() with
// an argument of zero; this performs a coasting stop, not an active brake
void motorStop(unsigned char channel) {
motorControlSet(channel, 127);
2e4: 0422064a strteq r0, [r2], #-1610 ; 0xfffff9b6
2e8: 20630303 rsbcs r0, r3, r3, lsl #6
// motorStopAll - Stops all motors; significantly faster than looping through all motor ports
// and calling motorSet(channel, 0) on each one
void motorStopAll() {
// It is safe to stop all motors when disabled, as that is their disabled state anyways.
motorControlStop();
2ec: 047a2f40 ldrbteq r2, [sl], #-3904 ; 0xfffff0c0
}
// pinMode - Configures the pin as an input or output with a variety of settings
void pinMode(unsigned char pin, unsigned char mode) {
if (pin < BOARD_NR_GPIO_PINS)
2f0: 3c110301 ldccc 3, cr0, [r1], {1}
// It is safe to stop all motors when disabled, as that is their disabled state anyways.
motorControlStop();
}
// pinMode - Configures the pin as an input or output with a variety of settings
void pinMode(unsigned char pin, unsigned char mode) {
2f4: 01000802 tsteq r0, r2, lsl #16
if (pin < BOARD_NR_GPIO_PINS)
ioSetDirection((GPIO_TypeDef*)_pinLookupTable[pin], (uint8_t)_pinIndexTable[pin], mode);
2f8: 02050001 andeq r0, r5, #1
2fc: 00000000 andeq r0, r0, r0
2fc: R_ARM_ABS32 .text.micros
300: 0101b503 tsteq r1, r3, lsl #10
304: 00020213 andeq r0, r2, r3, lsl r2
308: 05000101 streq r0, [r0, #-257] ; 0xfffffeff
30c: 00000002 andeq r0, r0, r2
30d: R_ARM_ABS32 .text.millis
return SV_OUT->data[index];
}
// svGetBackupBattery - Gets the backup battery voltage in millivolts, or 0 if not connected
static INLINE uint32_t svGetBackupBattery() {
uint32_t volts = ((uint32_t)SV_IN->backupBattery) * 59;
310: 01ba0300 ; <UNDEFINED> instruction: 0x01ba0300
314: 02021301 andeq r1, r2, #67108864 ; 0x4000000
if (volts < 1000)
318: 00010100 andeq r0, r1, r0, lsl #2
}
// powerLevelBackup - Get backup battery voltage in millivolts, or 0 if not connected
unsigned int powerLevelBackup() {
return svGetBackupBattery();
}
31c: 00000205 andeq r0, r0, r5, lsl #4
31e: R_ARM_ABS32 .text.motorGet
320: c0030000 andgt r0, r3, r0
324: 2f220101 svccs 0x00220101
}
}
// svGetMainBattery - Gets the main battery voltage in millivolts, or 0 if not connected
static INLINE uint32_t svGetMainBattery() {
uint32_t volts = ((uint32_t)SV_IN->mainBattery) * 59;
328: 01000202 tsteq r0, r2, lsl #4
32c: 02050001 andeq r0, r5, #1
if (volts < 1000)
330: 00000000 andeq r0, r0, r0
330: R_ARM_ABS32 .text.motorSet
// powerLevelMain - Get main battery voltage in millivolts, or 0 if not connected
unsigned int powerLevelMain() {
return svGetMainBattery();
}
334: 0101c703 tsteq r1, r3, lsl #14
338: 3d3f2f20 ldccc 15, cr2, [pc, #-128]! ; 2c0 <.debug_line+0x2c0>
33c: 2c222249 sfmcs f2, 4, [r2], #-292 ; 0xfffffedc
// setTeamName - Sets the team name of the Cortex
void setTeamName(const char *name) {
340: 01000402 tsteq r0, r2, lsl #8
// svSetTeamName - Changes the team name reported to the supervisor
static INLINE void svSetTeamName(const char *name) {
char c; uint8_t i;
for (i = 0; i < 8; i++) {
// Copy up to 8 characters, respect zero terminator
c = (char)(*name++);
344: 02050001 andeq r0, r5, #1
if (!c) break;
svTeamName[i] = c;
348: 00000000 andeq r0, r0, r0
348: R_ARM_ABS32 .text.motorStop
34c: 0101d303 tsteq r1, r3, lsl #6
}
// svSetTeamName - Changes the team name reported to the supervisor
static INLINE void svSetTeamName(const char *name) {
char c; uint8_t i;
for (i = 0; i < 8; i++) {
350: 00030213 andeq r0, r3, r3, lsl r2
c = (char)(*name++);
if (!c) break;
svTeamName[i] = c;
}
// Space-pad
for (; i < 8; i++)
354: 05000101 streq r0, [r0, #-257] ; 0xfffffeff
svTeamName[i] = ' ';
358: 00000002 andeq r0, r0, r2
359: R_ARM_ABS32 .text.motorStopAll
35c: 01d90300 bicseq r0, r9, r0, lsl #6
c = (char)(*name++);
if (!c) break;
svTeamName[i] = c;
}
// Space-pad
for (; i < 8; i++)
360: 02021401 andeq r1, r2, #16777216 ; 0x1000000
svSetTeamName(name);
}
364: 00010100 andeq r0, r1, r0, lsl #2
368: 00000205 andeq r0, r0, r5, lsl #4
36a: R_ARM_ABS32 .text.pinMode
// taskRunLoop - Starts a task at higher-than-normal priority to run the specified function
// in intervals as close to the specified period in milliseconds as possible
// For a stack size or priority different than the default, launch a custom task
TaskHandle taskRunLoop(void (*fn)(void), const unsigned long increment) {
36c: df030000 svcle 0x00030000
// Initialize data (will be later freed)
LoopTask *lt = malloc(sizeof(LoopTask));
370: 1f130101 svcne 0x00130101
374: 0c02212f stfeqs f2, [r2], {47} ; 0x2f
lt->fn = fn;
lt->period = (clock_t)increment;
// Create and start the task
return taskCreate(_taskRunLoopHelper, TASK_DEFAULT_STACK_SIZE, (void*)lt,
378: 00010100 andeq r0, r1, r0, lsl #2
// in intervals as close to the specified period in milliseconds as possible
// For a stack size or priority different than the default, launch a custom task
TaskHandle taskRunLoop(void (*fn)(void), const unsigned long increment) {
// Initialize data (will be later freed)
LoopTask *lt = malloc(sizeof(LoopTask));
lt->fn = fn;
37c: 00000205 andeq r0, r0, r5, lsl #4
37e: R_ARM_ABS32 .text.powerLevelBackup
// taskRunLoop - Starts a task at higher-than-normal priority to run the specified function
// in intervals as close to the specified period in milliseconds as possible
// For a stack size or priority different than the default, launch a custom task
TaskHandle taskRunLoop(void (*fn)(void), const unsigned long increment) {
// Initialize data (will be later freed)
LoopTask *lt = malloc(sizeof(LoopTask));
380: e5030000 str r0, [r3, #-0]
lt->fn = fn;
lt->period = (clock_t)increment;
// Create and start the task
return taskCreate(_taskRunLoopHelper, TASK_DEFAULT_STACK_SIZE, (void*)lt,
TASK_PRIORITY_DEFAULT + 1);
}
384: 03040101 movweq r0, #16641 ; 0x4101
// Initialize data (will be later freed)
LoopTask *lt = malloc(sizeof(LoopTask));
lt->fn = fn;
lt->period = (clock_t)increment;
// Create and start the task
return taskCreate(_taskRunLoopHelper, TASK_DEFAULT_STACK_SIZE, (void*)lt,
388: 017f8b03 cmneq pc, r3, lsl #22
38c: 0301044b movweq r0, #5195 ; 0x144b
390: 022e00f6 eoreq r0, lr, #246 ; 0xf6
TASK_PRIORITY_DEFAULT + 1);
}
// wait - taskDelay alias
void wait(const unsigned long time) {
taskDelay((clock_t)time);
394: 01010006 tsteq r1, r6
}
// waitUntil - taskDelayUntil alias
void waitUntil(unsigned long *previousWakeTime, unsigned long time) {
taskDelayUntil((clock_t*)previousWakeTime, (clock_t)time);
398: 00020500 andeq r0, r2, r0, lsl #10
39b: R_ARM_ABS32 .text.powerLevelMain
39c: 03000000 movweq r0, #0
3a0: 040101ea streq r0, [r1], #-490 ; 0xfffffe16
3a4: 7fbc0303 svcvc 0x00bc0303
3a8: 01044b01 tsteq r4, r1, lsl #22
3ac: 2e00c503 cfsh32cs mvfx12, mvfx0, #3
3b0: 01000602 tsteq r0, r2, lsl #12
3b4: 02050001 andeq r0, r5, #1
3b8: 00000000 andeq r0, r0, r0
3b8: R_ARM_ABS32 .text.setTeamName
3bc: 0101ef03 tsteq r1, r3, lsl #30
3c0: 03030401 movweq r0, #13313 ; 0x3401
3c4: 212f2061 ; <UNDEFINED> instruction: 0x212f2061
3c8: 3b2f4338 blcc bd10b0 <_taskRunLoopHelper+0xbd10b0>
3cc: 1c030104 stfnes f0, [r3], {4}
3d0: 0004023c andeq r0, r4, ip, lsr r2
3d4: 05000101 streq r0, [r0, #-257] ; 0xfffffeff
3d8: 00000002 andeq r0, r0, r2
3d9: R_ARM_ABS32 .text.taskRunLoop
3dc: 01f60300 mvnseq r0, r0, lsl #6
3e0: 1e222001 cdpne 0, 2, cr2, cr2, cr1, {0}
3e4: 212b3222 ; <UNDEFINED> instruction: 0x212b3222
3e8: 022c261e eoreq r2, ip, #31457280 ; 0x1e00000
3ec: 01010007 tsteq r1, r7
3f0: 00020500 andeq r0, r2, r0, lsl #10
3f3: R_ARM_ABS32 .text.wait
3f4: 03000000 movweq r0, #0
3f8: 13010281 movwne r0, #4737 ; 0x1281
3fc: 01000202 tsteq r0, r2, lsl #4
400: 02050001 andeq r0, r5, #1
404: 00000000 andeq r0, r0, r0
404: R_ARM_ABS32 .text.waitUntil
408: 01028603 tsteq r2, r3, lsl #12
40c: 00020213 andeq r0, r2, r3, lsl r2
410: Address 0x0000000000000410 is out of bounds.
Disassembly of section .debug_str:
00000000 <.debug_str>:
void (*fn)(void);
clock_t period;
} LoopTask;
// Helper task for taskRunLoop()
static void _taskRunLoopHelper(void *data) {
0: 45534552 ldrbmi r4, [r3, #-1362] ; 0xfffffaae
// Extract information from pointer
LoopTask *info = (LoopTask*)data;
void (*fn)(void) = info->fn;
clock_t period = info->period;
4: 44455652 strbmi r5, [r5], #-1618 ; 0xfffff9ae
// Avoid leaking data
free(data);
8: 616e6100 cmnvs lr, r0, lsl #2
// Start counter
clock_t now = timeLowRes();
c: 52676f6c rsbpl r6, r7, #108, 30 ; 0x1b0
10: 43646165 cmnmi r4, #1073741849 ; 0x40000019
uint16_t sf = svFlags & (SV_AUTONOMOUS | SV_ENABLED | SV_FMS);
14: 62696c61 rsbvs r6, r9, #24832 ; 0x6100
18: 65746172 ldrbvs r6, [r4, #-370]! ; 0xfffffe8e
do {
fn();
taskDelayUntil(&now, period);
1c: 00524864 subseq r4, r2, r4, ror #16
20: 6c616e61 stclvs 14, cr6, [r1], #-388 ; 0xfffffe7c
// Auto-terminate on mode switch, drop, or disable
} while ((svFlags & (SV_AUTONOMOUS | SV_ENABLED | SV_FMS)) == sf);
24: 6552676f ldrbvs r6, [r2, #-1903] ; 0xfffff891
28: 61436461 cmpvs r3, r1, ror #8
2c: 7262696c rsbvc r6, r2, #108, 18 ; 0x1b0000
}
30: 64657461 strbtvs r7, [r5], #-1121 ; 0xfffffb9f
34: 746f6d00 strbtvc r6, [pc], #-3328 ; 3c <.debug_str+0x3c>
// analogCalibrate - Calibrates the analog sensor on the specified channel, assuming that it is
// not actively changing. Approximately 512 samples are taken, 1 ms apart, for a 0.5 s period
// of calibration. The average value thus calculated is returned and stored for later calls
// to analogReadCalibrated()
int analogCalibrate(unsigned char channel) {
channel--;
38: 7453726f ldrbvc r7, [r3], #-623 ; 0xfffffd91
3c: 7700706f strvc r7, [r0, -pc, rrx]
if (channel < BOARD_NR_ADC_PINS) {
40: 55746961 ldrbpl r6, [r4, #-2401]! ; 0xfffff69f
44: 6c69746e cfstrdvs mvd7, [r9], #-440 ; 0xfffffe48
// We have the true channel, do this in a loop
uint32_t total = 0, i;
for (i = 0; i < 512; i++) {
total += adcRead(channel);
48: 52534200 subspl r4, r3, #0, 4
4c: 6f6d0052 svcvs 0x006d0052
taskDelay(1);
50: 43726f74 cmnmi r2, #116, 30 ; 0x1d0
54: 72746e6f rsbsvc r6, r4, #1776 ; 0x6f0
int analogCalibrate(unsigned char channel) {
channel--;
if (channel < BOARD_NR_ADC_PINS) {
// We have the true channel, do this in a loop
uint32_t total = 0, i;
for (i = 0; i < 512; i++) {
58: 65476c6f strbvs r6, [r7, #-3183] ; 0xfffff391
total += adcRead(channel);
taskDelay(1);
}
// Store value (fixed to correctly round to nearest to avoid positive bias)
_analogState[channel].calibValue = (total + 16) >> 5;
5c: 69740074 ldmdbvs r4!, {r2, r4, r5, r6}^
60: 6f4c656d svcvs 0x004c656d
64: 73655277 cmnvc r5, #1879048199 ; 0x70000007
68: 67696400 strbvs r6, [r9, -r0, lsl #8]!
return (int)((total + 256) >> 9);
6c: 6c617469 cfstrdvs mvd7, [r1], #-420 ; 0xfffffe5c
70: 74697257 strbtvc r7, [r9], #-599 ; 0xfffffda9
}
return 0;
74: 6c660065 stclvs 0, cr0, [r6], #-404 ; 0xfffffe6c
}
78: 00736761 rsbseq r6, r3, r1, ror #14
// analogRead - Reads an analog input channel 1-8 and returns the 12-bit value from 0 to 4095
int analogRead(unsigned char channel) {
channel--;
7c: 69736e75 ldmdbvs r3!, {r0, r2, r4, r5, r6, r9, sl, fp, sp, lr}^
if (channel < BOARD_NR_ADC_PINS)
80: 64656e67 strbtvs r6, [r5], #-3687 ; 0xfffff199
84: 746e6920 strbtvc r6, [lr], #-2336 ; 0xfffff6e0
return (int)adcRead(channel);
88: 72657600 rsbvc r7, r5, #0, 12
return 0;
8c: 6e6f6973 mcrvs 9, 3, r6, cr15, cr3, {3}
// analogReadCalibrated - Reads the calibrated value of an analog input channel 1-8;
// analogCalibrate() must be run first. This is inappropriate for integrated sensors as the
// round-off error can accumulate. Use analogReadCalibratedHR() instead.
int analogReadCalibrated(unsigned char channel) {
channel--;
90: 695f5f00 ldmdbvs pc, {r8, r9, sl, fp, ip, lr}^ ; <UNPREDICTABLE>
94: 3233746e eorscc r7, r3, #1845493760 ; 0x6e000000
if (channel < BOARD_NR_ADC_PINS)
98: 7400745f strvc r7, [r0], #-1119 ; 0xfffffba1
return (int)adcRead(channel) - (int)(_analogState[channel].calibValue >> 4);
9c: 526b7361 rsbpl r7, fp, #-2080374783 ; 0x84000001
a0: 6f4c6e75 svcvs 0x004c6e75
a4: 6d00706f stcvs 0, cr7, [r0, #-444] ; 0xfffffe44
a8: 726f746f rsbvc r7, pc, #1862270976 ; 0x6f000000
ac: 746e6f43 strbtvc r6, [lr], #-3907 ; 0xfffff0bd
b0: 536c6f72 cmnpl ip, #456 ; 0x1c8
return 0;
}
b4: 00706f74 rsbseq r6, r0, r4, ror pc
b8: 6f746f6d svcvs 0x00746f6d
// drift due to round-off.
int analogReadCalibratedHR(unsigned char channel) {
// The value returned actually has 16 bits of "precision", even though the ADC only reads
// 12 bits, so that errors induced by the average value being between two values come out
// in the wash when integrated over time. Think of the value as the true value << 4.
channel--;
bc: 74654772 strbtvc r4, [r5], #-1906 ; 0xfffff88e
c0: 72635f00 rsbvc r5, r3, #0, 30
if (channel < BOARD_NR_ADC_PINS)
c4: 63697469 cmnvs r9, #1761607680 ; 0x69000000
return (int)(adcRead(channel) << 4) - (int)(_analogState[channel].calibValue);
c8: 654e6c61 strbvs r6, [lr, #-3169] ; 0xfffff39f
cc: 6e697473 mcrvs 4, 3, r7, cr9, cr3, {3}
d0: 78610067 stmdavc r1!, {r0, r1, r2, r5, r6}^
d4: 73007369 movwvc r7, #873 ; 0x369
d8: 75426970 strbvc r6, [r2, #-2416] ; 0xfffff690
dc: 72656666 rsbvc r6, r5, #106954752 ; 0x6600000
return 0;
}
e0: 41005854 tstmi r0, r4, asr r8
e4: 6f6c616e svcvs 0x006c616e
// delay - taskDelay alias
void delay(const unsigned long time) {
taskDelay((clock_t)time);
e8: 79545f67 ldmdbvc r4, {r0, r1, r2, r5, r6, r8, r9, sl, fp, ip, lr}^
}
// delayMicroseconds - Wait for approximately the given number of microseconds
void delayMicroseconds(const unsigned long time) {
ec: 65446570 strbvs r6, [r4, #-1392] ; 0xfffffa90
clock_t us = (clock_t)time;
if (us) {
f0: 6f6d0066 svcvs 0x006d0066
/*us *= 12; us--;
asm volatile(" mov r0, %[us]\n\t"
"1: subs r0, #1\n\t"
" bhi 1b\n\t"
: : [us] "r" (us) : "r0");*/
if (us > 1000) {
f4: 70006564 andvc r6, r0, r4, ror #10
// Wait off the milliseconds part first
clock_t millis = (clock_t)(us / 1000UL);
us %= 1000UL;
f8: 7265776f rsbvc r7, r5, #29097984 ; 0x1bc0000
fc: 6576654c ldrbvs r6, [r6, #-1356]! ; 0xfffffab4
100: 6361426c cmnvs r1, #108, 4 ; 0xc0000006
taskDelay(millis);
104: 0070756b rsbseq r7, r0, fp, ror #10
}
if (us) {
108: 7473616c ldrbtvc r6, [r3], #-364 ; 0xfffffe94
10c: 756c6156 strbvc r6, [ip, #-342]! ; 0xfffffeaa
// Spin on the highres timer value (next IRQ might be up to 1ms away!)
// Power consumption is bad, CPU usage possibly worse, but accuracy is acceptable
uint16_t start = TIM8->CNT;
110: 70730065 rsbsvc r0, r3, r5, rrx
114: 00646565 rsbeq r6, r4, r5, ror #10
while (TIM8->CNT - start < us);
118: 65776f70 ldrbvs r6, [r7, #-3952]! ; 0xfffff090
11c: 76654c72 ; <UNDEFINED> instruction: 0x76654c72
120: 614d6c65 cmpvs sp, r5, ror #24
124: 54006e69 strpl r6, [r0], #-3689 ; 0xfffff197
}
}
}
// digitalRead - Gets the digital value (1 or 0) of a pin configured as a digital input
bool digitalRead(unsigned char pin) {
128: 545f4d49 ldrbpl r4, [pc], #-3401 ; 130 <.debug_str+0x130>
if (pin >= BOARD_NR_GPIO_PINS)
return 0;
return ioGetInput((GPIO_TypeDef*)_pinLookupTable[pin], (uint8_t)_pinIndexTable[pin]);
12c: 44657079 strbtmi r7, [r5], #-121 ; 0xffffff87
130: 75006665 strvc r6, [r0, #-1637] ; 0xfffff99b
}
// ioGetInput - Gets the digital value (1 or 0) of a pin configured as a digital input
static INLINE bool ioGetInput(GPIO_TypeDef* port, uint32_t pin) {
// Shift right that many bits, then mask everything but the ones
return ((port->IDR >> (pin & 0x0F)) & 0x01) != 0;
134: 33746e69 cmncc r4, #1680 ; 0x690
138: 00745f32 rsbseq r5, r4, r2, lsr pc
13c: 38746e69 ldmdacc r4!, {r0, r3, r5, r6, r9, sl, fp, sp, lr}^
140: 4200745f andmi r7, r0, #1593835520 ; 0x5f000000
144: 00525444 subseq r5, r2, r4, asr #8
}
// digitalRead - Gets the digital value (1 or 0) of a pin configured as a digital input
bool digitalRead(unsigned char pin) {
if (pin >= BOARD_NR_GPIO_PINS)
return 0;
148: 6c6c616d stfvse f6, [ip], #-436 ; 0xfffffe4c
return ioGetInput((GPIO_TypeDef*)_pinLookupTable[pin], (uint8_t)_pinIndexTable[pin]);
}
14c: 4300636f movwmi r6, #879 ; 0x36f
150: 00315243 eorseq r5, r1, r3, asr #4
// digitalWrite - Sets the digital value (1 or 0) of a pin configured as a digital output
void digitalWrite(unsigned char pin, bool value) {
// We will let this work when disabled, even though it might change a solenoid, since it
// is needed to set initial solenoid states in initializeIO() when enabled/disabled is
// undefined.
if (pin < BOARD_NR_GPIO_PINS)
154: 32524343 subscc r4, r2, #201326593 ; 0xc000001
158: 52434300 subpl r4, r3, #0, 6
ioSetOutput((GPIO_TypeDef*)_pinLookupTable[pin], (uint8_t)_pinIndexTable[pin], value);
15c: 43430033 movtmi r0, #12339 ; 0x3033
160: 43003452 movwmi r3, #1106 ; 0x452
164: 31524d43 cmpcc r2, r3, asr #26
168: 4d434300 stclmi 3, cr4, [r3, #-0]
return ((port->ODR >> (pin & 0x0F)) & 0x01) != 0;
}
// ioSetOutput - Sets the digital value (1 or 0) of a pin configured as a digital output
static INLINE void ioSetOutput(GPIO_TypeDef* port, uint32_t pin, bool value) {
if (value)
16c: 74003252 strvc r3, [r0], #-594 ; 0xfffffdae
// Atomic bit set
port->BSRR = ((uint32_t)0x00000001) << (pin & 0x0F);
170: 436b7361 cmnmi fp, #-2080374783 ; 0x84000001
else
// Atomic bit reset
port->BRR = ((uint32_t)0x00000001) << (pin & 0x0F);
174: 74616572 strbtvc r6, [r1], #-1394 ; 0xfffffa8e
178: 61630065 cmnvs r3, r5, rrx
17c: 5662696c strbtpl r6, [r2], -ip, ror #18
}
// isAutonomous - Checks to see if the system is in autonomous mode
bool isAutonomous() {
return (svFlags & SV_AUTONOMOUS) ? true : false;
180: 65756c61 ldrbvs r6, [r5, #-3169]! ; 0xfffff39f
}
184: 536f6900 cmnpl pc, #0, 18
188: 69447465 stmdbvs r4, {r0, r2, r5, r6, sl, ip, sp, lr}^
18c: 74636572 strbtvc r6, [r3], #-1394 ; 0xfffffa8e
// isEnabled - Checks to see if the system is enabled
bool isEnabled() {
uint16_t flags = svFlags;
190: 006e6f69 rsbeq r6, lr, r9, ror #30
194: 676e6f6c strbvs r6, [lr, -ip, ror #30]!
if (!(flags & SV_ENABLED)) {
if (flags & SV_FMS)
198: 6e6f6c20 cdpvs 12, 6, cr6, cr15, cr0, {1}
19c: 6e752067 cdpvs 0, 7, cr2, cr5, cr7, {3}
1a0: 6e676973 mcrvs 9, 3, r6, cr7, cr3, {3}
return false;
}
return true;
}
1a4: 69206465 stmdbvs r0!, {r0, r2, r5, r6, sl, sp, lr}
1a8: 6d00746e cfstrsvs mvf7, [r0, #-440] ; 0xfffffe48
}
// svIsJoystickConnected - Checks to see if a joystick is connected
static INLINE uint8_t svIsJoystickConnected(uint8_t joystick) {
// Force in range from 0..1 (mapped from 1..2)
joystick = (joystick - 1) & (uint8_t)0x01;
1ac: 696c6c69 stmdbvs ip!, {r0, r3, r5, r6, sl, fp, sp, lr}^
// If both accelerometer axes are zero, the joystick is likely not plugged in
// Obviously there is a chance for false positives but extremely unlikely due to the noise
// of the analog accelerometers
return SV_IN->joystick[joystick].axis[4] != (uint8_t)0x7F ||
1b0: 76730073 ; <UNDEFINED> instruction: 0x76730073
1b4: 4d746547 cfldr64mi mvdx6, [r4, #-284]! ; 0xfffffee4
1b8: 426e6961 rsbmi r6, lr, #1589248 ; 0x184000
1bc: 65747461 ldrbvs r7, [r4, #-1121]! ; 0xfffffb9f
SV_IN->joystick[joystick].axis[5] != (uint8_t)0x7F;
1c0: 62007972 andvs r7, r0, #1867776 ; 0x1c8000
// Force in range from 0..1 (mapped from 1..2)
joystick = (joystick - 1) & (uint8_t)0x01;
// If both accelerometer axes are zero, the joystick is likely not plugged in
// Obviously there is a chance for false positives but extremely unlikely due to the noise
// of the analog accelerometers
return SV_IN->joystick[joystick].axis[4] != (uint8_t)0x7F ||
1c4: 6f747475 svcvs 0x00747475
1c8: 0036356e eorseq r3, r6, lr, ror #10
1cc: 69755f5f ldmdbvs r5!, {r0, r1, r2, r3, r4, r6, r8, r9, sl, fp, ip, lr}^
// isJoystickConnected - Checks to see if the specified joystick is plugged in
bool isJoystickConnected(unsigned char joystick) {
return svIsJoystickConnected(joystick) ? true : false;
}
1d0: 3631746e ldrtcc r7, [r1], -lr, ror #8
// isOnline - Checks to see if the system is connected to a FMS/competition switch
bool isOnline() {
return (svFlags & SV_FMS) ? true : false;
1d4: 6900745f stmdbvs r0, {r0, r1, r2, r3, r4, r6, sl, ip, sp, lr}
}
1d8: 616e4573 smcvs 58451 ; 0xe453
1dc: 64656c62 strbtvs r6, [r5], #-3170 ; 0xfffff39e
1e0: 6d697400 cfstrdvs mvd7, [r9, #-0]
// joystickGetAnalog - Retrieve an analog axis of a joystick
int joystickGetAnalog(unsigned char joystick, unsigned char axis) {
1e4: 6f6a0065 svcvs 0x006a0065
1e8: 69747379 ldmdbvs r4!, {r0, r3, r4, r5, r6, r8, r9, ip, sp, lr}^
// Safety first here
if (isOnline() && isAutonomous()) return 0;
1ec: 63006b63 movwvs r6, #2915 ; 0xb63
// svGetJoystickAnalog - Gets an analog joystick axis or accelerometer axis from the supervisor
// NO check on the mode when doing so
static INLINE int8_t svGetJoystickAnalog(uint8_t joystick, uint8_t axis) {
uint8_t value;
// Force in range from 0..5 (mapped from 1..6)
axis = (axis - 1) % 6;
1f0: 6b636f6c blvs 18dbfa8 <_taskRunLoopHelper+0x18dbfa8>
1f4: 6200745f andvs r7, r0, #1593835520 ; 0x5f000000
1f8: 6f747475 svcvs 0x00747475
// Force in range from 0..1 (mapped from 1..2)
joystick = (joystick - 1) & (uint8_t)0x01;
1fc: 6f72476e svcvs 0x0072476e
value = SV_IN->joystick[joystick].axis[axis];
200: 73007075 movwvc r7, #117 ; 0x75
204: 74654776 strbtvc r4, [r5], #-1910 ; 0xfffff88a
208: 73796f4a cmnvc r9, #296 ; 0x128
// Prevent return of 128
if (value == 0xFF)
value = 0xFE;
value -= 127;
if (axis == 1 || axis == 2)
20c: 6b636974 blvs 18da7e4 <_taskRunLoopHelper+0x18da7e4>
uint8_t value;
// Force in range from 0..5 (mapped from 1..6)
axis = (axis - 1) % 6;
// Force in range from 0..1 (mapped from 1..2)
joystick = (joystick - 1) & (uint8_t)0x01;
value = SV_IN->joystick[joystick].axis[axis];
210: 69676944 stmdbvs r7!, {r2, r6, r8, fp, sp, lr}^
// Prevent return of 128
if (value == 0xFF)
value = 0xFE;
214: 006c6174 rsbeq r6, ip, r4, ror r1
value -= 127;
if (axis == 1 || axis == 2)
218: 6f746f6d svcvs 0x00746f6d
joystick = (joystick - 1) & (uint8_t)0x01;
value = SV_IN->joystick[joystick].axis[axis];
// Prevent return of 128
if (value == 0xFF)
value = 0xFE;
value -= 127;
21c: 6f745372 svcvs 0x00745372
if (axis == 1 || axis == 2)
220: 6c6c4170 stfvse f4, [ip], #-448 ; 0xfffffe40
value = -value;
224: 6c617600 stclvs 6, cr7, [r1], #-0
228: 76006575 ; <UNDEFINED> instruction: 0x76006575
22c: 73746c6f cmnvc r4, #28416 ; 0x6f00
230: 7a697300 bvc 1a5ce38 <_taskRunLoopHelper+0x1a5ce38>
return (int)svGetJoystickAnalog(joystick, axis);
234: 00745f65 rsbseq r5, r4, r5, ror #30
238: 6b736174 blvs 1cd8810 <_taskRunLoopHelper+0x1cd8810>
}
// joystickGetDigital - Retrieve a digital button of a joystick
bool joystickGetDigital(unsigned char joystick, unsigned char buttonGroup,
unsigned char button) {
23c: 616c6544 cmnvs ip, r4, asr #10
240: 76730079 ; <UNDEFINED> instruction: 0x76730079
// Safety first here
if (isOnline() && isAutonomous()) return false;
244: 67616c46 strbvs r6, [r1, -r6, asr #24]!
248: 615f0073 cmpvs pc, r3, ror r0 ; <UNPREDICTABLE>
static INLINE uint8_t svGetJoystickDigital(uint8_t joystick, uint8_t button) {
uint8_t value; volatile Joystick_TypeDef *ref;
// Force in range from 0..3 (mapped from 5..8)
button = (button - 5) & (uint8_t)0x03;
// Force in range from 0..1 (mapped from 1..2)
joystick = (joystick - 1) & (uint8_t)0x01;
24c: 6f6c616e svcvs 0x006c616e
ref = &SV_IN->joystick[joystick];
// 5 and 6 need some mangling to move the twos bit up to the fours
switch (button) {
250: 61745367 cmnvs r4, r7, ror #6
uint8_t value; volatile Joystick_TypeDef *ref;
// Force in range from 0..3 (mapped from 5..8)
button = (button - 5) & (uint8_t)0x03;
// Force in range from 0..1 (mapped from 1..2)
joystick = (joystick - 1) & (uint8_t)0x01;
ref = &SV_IN->joystick[joystick];
254: 69006574 stmdbvs r0, {r2, r4, r5, r6, r8, sl, sp, lr}
258: 7465536f strbtvc r5, [r5], #-879 ; 0xfffffc91
25c: 7074754f rsbsvc r7, r4, pc, asr #10
// 5 and 6 need some mangling to move the twos bit up to the fours
switch (button) {
260: 53007475 movwpl r7, #1141 ; 0x475
264: 72657075 rsbvc r7, r5, #117 ; 0x75
// 6
value = ref->button56 >> 2;
return ((value & 0x02) << 1) | (value & 0x01);
case 2:
// 7
return ref->button78 >> 4;
268: 6f736976 svcvs 0x00736976
26c: 65525f72 ldrbvs r5, [r2, #-3954] ; 0xfffff08e
270: 79547663 ldmdbvc r4, {r0, r1, r5, r6, r9, sl, ip, sp, lr}^
274: 65446570 strbvs r6, [r4, #-1392] ; 0xfffffa90
return (svGetJoystickDigital(joystick, buttonGroup) & button) ? true : false;
}
278: 75620066 strbvc r0, [r2, #-102]! ; 0xffffff9a
ref = &SV_IN->joystick[joystick];
// 5 and 6 need some mangling to move the twos bit up to the fours
switch (button) {
case 0:
// 5
value = ref->button56;
27c: 6e6f7474 mcrvs 4, 3, r7, cr15, cr4, {3}
return ((value & 0x02) << 1) | (value & 0x01);
case 1:
// 6
value = ref->button56 >> 2;
280: 636e6900 cmnvs lr, #0, 18
return ((value & 0x02) << 1) | (value & 0x01);
284: 656d6572 strbvs r6, [sp, #-1394]! ; 0xfffffa8e
288: 6600746e strvs r7, [r0], -lr, ror #8
28c: 00656572 rsbeq r6, r5, r2, ror r5
290: 52454944 subpl r4, r5, #68, 18 ; 0x110000
case 2:
// 7
return ref->button78 >> 4;
default:
// 8 (No other case is possible...)
return ref->button78 & 0x0F;
294: 616e6100 cmnvs lr, r0, lsl #2
// joystickGetDigital - Retrieve a digital button of a joystick
bool joystickGetDigital(unsigned char joystick, unsigned char buttonGroup,
unsigned char button) {
// Safety first here
if (isOnline() && isAutonomous()) return false;
return (svGetJoystickDigital(joystick, buttonGroup) & button) ? true : false;
298: 52676f6c rsbpl r6, r7, #108, 30 ; 0x1b0
29c: 00646165 rsbeq r6, r4, r5, ror #2
2a0: 74747562 ldrbtvc r7, [r4], #-1378 ; 0xfffffa9e
2a4: 38376e6f ldmdacc r7!, {r0, r1, r2, r3, r5, r6, r9, sl, fp, sp, lr}
}
// micros - Arduino-compatible alias for timeHighRes()
unsigned long micros() {
return (unsigned long)timeHighRes();
2a8: 656d2f00 strbvs r2, [sp, #-3840]! ; 0xfffff100
}
// millis - Arduino-compatible alias for timeLowRes()
unsigned long millis() {
return (unsigned long)timeLowRes();
2ac: 2f616964 svccs 0x00616964
}
// motorGet - Gets last commanded speed of the specified motor channel; this speed is reset
// to 0 if motors are stopped by the kernel for any reason
int motorGet(unsigned char channel) {
2b0: 65786970 ldrbvs r6, [r8, #-2416]! ; 0xfffff690
// Convert range
return (int)motorControlGet(channel) - 127;
2b4: 494c2f6c stmdbmi ip, {r2, r3, r5, r6, r8, r9, sl, fp, sp}^
}
2b8: 682f554e stmdavs pc!, {r1, r2, r3, r6, r8, sl, ip, lr} ; <UNPREDICTABLE>
// motorSet - Sets the speed of the specified motor channel from 1 to 10, where -127 is full
// reverse and 127 is full forward, with 0 being off
void motorSet(unsigned char channel, int speed) {
2bc: 2f656d6f svccs 0x00656d6f
if (isEnabled()) {
2c0: 65786970 ldrbvs r6, [r8, #-2416]! ; 0xfffff690
2c4: 73732f6c cmnvc r3, #108, 30 ; 0x1b0
int ns = speed + 127;
// Equalize the bias
if (ns < 0) ns = 0;
2c8: 69702f64 ldmdbvs r0!, {r2, r5, r6, r8, r9, sl, fp, sp}^
if (ns > 255) ns = 255;
2cc: 2f6c6578 svccs 0x006c6578
2d0: 736f7270 cmnvc pc, #112, 4
// reverse and 127 is full forward, with 0 being off
void motorSet(unsigned char channel, int speed) {
if (isEnabled()) {
int ns = speed + 127;
// Equalize the bias
if (ns < 0) ns = 0;
2d4: 6b726f66 blvs 1c9c074 <_taskRunLoopHelper+0x1c9c074>
if (ns > 255) ns = 255;
motorControlSet(channel, (uint8_t)ns);
}
}
2d8: 6372732f cmnvs r2, #-1140850688 ; 0xbc000000
if (isEnabled()) {
int ns = speed + 127;
// Equalize the bias
if (ns < 0) ns = 0;
if (ns > 255) ns = 255;
motorControlSet(channel, (uint8_t)ns);
2dc: 45434300 strbmi r4, [r3, #-768] ; 0xfffffd00
2e0: 6e610052 mcrvs 0, 3, r0, cr1, cr2, {2}
}
// motorStop - Stops the motor on the specified channel, equivalent to calling motorSet() with
// an argument of zero; this performs a coasting stop, not an active brake
void motorStop(unsigned char channel) {
motorControlSet(channel, 127);
2e4: 676f6c61 strbvs r6, [pc, -r1, ror #24]!
2e8: 696c6143 stmdbvs ip!, {r0, r1, r6, r8, sp, lr}^
// motorStopAll - Stops all motors; significantly faster than looping through all motor ports
// and calling motorSet(channel, 0) on each one
void motorStopAll() {
// It is safe to stop all motors when disabled, as that is their disabled state anyways.
motorControlStop();
2ec: 74617262 strbtvc r7, [r1], #-610 ; 0xfffffd9e
}
// pinMode - Configures the pin as an input or output with a variety of settings
void pinMode(unsigned char pin, unsigned char mode) {
if (pin < BOARD_NR_GPIO_PINS)
2f0: 68630065 stmdavs r3!, {r0, r2, r5, r6}^
// It is safe to stop all motors when disabled, as that is their disabled state anyways.
motorControlStop();
}
// pinMode - Configures the pin as an input or output with a variety of settings
void pinMode(unsigned char pin, unsigned char mode) {
2f4: 73007261 movwvc r7, #609 ; 0x261
if (pin < BOARD_NR_GPIO_PINS)
ioSetDirection((GPIO_TypeDef*)_pinLookupTable[pin], (uint8_t)_pinIndexTable[pin], mode);
2f8: 65547465 ldrbvs r7, [r4, #-1125] ; 0xfffffb9b
2fc: 614e6d61 cmpvs lr, r1, ror #26
300: 6400656d strvs r6, [r0], #-1389 ; 0xfffffa93
304: 00617461 rsbeq r7, r1, r1, ror #8
308: 746e6975 strbtvc r6, [lr], #-2421 ; 0xfffff68b
30c: 00745f38 rsbseq r5, r4, r8, lsr pc
return SV_OUT->data[index];
}
// svGetBackupBattery - Gets the backup battery voltage in millivolts, or 0 if not connected
static INLINE uint32_t svGetBackupBattery() {
uint32_t volts = ((uint32_t)SV_IN->backupBattery) * 59;
310: 6e4f7369 cdpvs 3, 4, cr7, cr15, cr9, {3}
314: 656e696c strbvs r6, [lr, #-2412]! ; 0xfffff694
if (volts < 1000)
318: 47767300 ldrbmi r7, [r6, -r0, lsl #6]!
}
// powerLevelBackup - Get backup battery voltage in millivolts, or 0 if not connected
unsigned int powerLevelBackup() {
return svGetBackupBattery();
}
31c: 61427465 cmpvs r2, r5, ror #8
320: 70756b63 rsbsvc r6, r5, r3, ror #22
324: 74746142 ldrbtvc r6, [r4], #-322 ; 0xfffffebe
}
}
// svGetMainBattery - Gets the main battery voltage in millivolts, or 0 if not connected
static INLINE uint32_t svGetMainBattery() {
uint32_t volts = ((uint32_t)SV_IN->mainBattery) * 59;
328: 00797265 rsbseq r7, r9, r5, ror #4
32c: 52434d53 subpl r4, r3, #5312 ; 0x14c0
if (volts < 1000)
330: 49767300 ldmdbmi r6!, {r8, r9, ip, sp, lr}^
// powerLevelMain - Get main battery voltage in millivolts, or 0 if not connected
unsigned int powerLevelMain() {
return svGetMainBattery();
}
334: 796f4a73 stmdbvc pc!, {r0, r1, r4, r5, r6, r9, fp, lr}^ ; <UNPREDICTABLE>
338: 63697473 cmnvs r9, #1929379840 ; 0x73000000
33c: 6e6f436b cdpvs 3, 6, cr4, cr15, cr11, {3}
// setTeamName - Sets the team name of the Cortex
void setTeamName(const char *name) {
340: 7463656e strbtvc r6, [r3], #-1390 ; 0xfffffa92
// svSetTeamName - Changes the team name reported to the supervisor
static INLINE void svSetTeamName(const char *name) {
char c; uint8_t i;
for (i = 0; i < 8; i++) {
// Copy up to 8 characters, respect zero terminator
c = (char)(*name++);
344: 61006465 tstvs r0, r5, ror #8
if (!c) break;
svTeamName[i] = c;
348: 65526364 ldrbvs r6, [r2, #-868] ; 0xfffffc9c
34c: 6c006461 cfstrsvs mvf6, [r0], {97} ; 0x61
}
// svSetTeamName - Changes the team name reported to the supervisor
static INLINE void svSetTeamName(const char *name) {
char c; uint8_t i;
for (i = 0; i < 8; i++) {
350: 20676e6f rsbcs r6, r7, pc, ror #28
c = (char)(*name++);
if (!c) break;
svTeamName[i] = c;
}
// Space-pad
for (; i < 8; i++)
354: 676e6f6c strbvs r6, [lr, -ip, ror #30]!
svTeamName[i] = ' ';
358: 746e6920 strbtvc r6, [lr], #-2336 ; 0xfffff6e0
35c: 69705f00 ldmdbvs r0!, {r8, r9, sl, fp, ip, lr}^
c = (char)(*name++);
if (!c) break;
svTeamName[i] = c;
}
// Space-pad
for (; i < 8; i++)
360: 6f6f4c6e svcvs 0x006f4c6e
svSetTeamName(name);
}
364: 5470756b ldrbtpl r7, [r0], #-1387 ; 0xfffffa95
368: 656c6261 strbvs r6, [ip, #-609]! ; 0xfffffd9f
// taskRunLoop - Starts a task at higher-than-normal priority to run the specified function
// in intervals as close to the specified period in milliseconds as possible
// For a stack size or priority different than the default, launch a custom task
TaskHandle taskRunLoop(void (*fn)(void), const unsigned long increment) {
36c: 73615400 cmnvc r1, #0, 8
// Initialize data (will be later freed)
LoopTask *lt = malloc(sizeof(LoopTask));
370: 6e61486b cdpvs 8, 6, cr4, cr1, cr11, {3}
374: 00656c64 rsbeq r6, r5, r4, ror #24
lt->fn = fn;
lt->period = (clock_t)increment;
// Create and start the task
return taskCreate(_taskRunLoopHelper, TASK_DEFAULT_STACK_SIZE, (void*)lt,
378: 2e495041 cdpcs 0, 4, cr5, cr9, cr1, {2}
// in intervals as close to the specified period in milliseconds as possible
// For a stack size or priority different than the default, launch a custom task
TaskHandle taskRunLoop(void (*fn)(void), const unsigned long increment) {
// Initialize data (will be later freed)
LoopTask *lt = malloc(sizeof(LoopTask));
lt->fn = fn;
37c: 72700063 rsbsvc r0, r0, #99 ; 0x63
// taskRunLoop - Starts a task at higher-than-normal priority to run the specified function
// in intervals as close to the specified period in milliseconds as possible
// For a stack size or priority different than the default, launch a custom task
TaskHandle taskRunLoop(void (*fn)(void), const unsigned long increment) {
// Initialize data (will be later freed)
LoopTask *lt = malloc(sizeof(LoopTask));
380: 6f697665 svcvs 0x00697665
lt->fn = fn;
lt->period = (clock_t)increment;
// Create and start the task
return taskCreate(_taskRunLoopHelper, TASK_DEFAULT_STACK_SIZE, (void*)lt,
TASK_PRIORITY_DEFAULT + 1);
}
384: 61577375 cmpvs r7, r5, ror r3
// Initialize data (will be later freed)
LoopTask *lt = malloc(sizeof(LoopTask));
lt->fn = fn;
lt->period = (clock_t)increment;
// Create and start the task
return taskCreate(_taskRunLoopHelper, TASK_DEFAULT_STACK_SIZE, (void*)lt,
388: 6954656b ldmdbvs r4, {r0, r1, r3, r5, r6, r8, sl, sp, lr}^
38c: 6200656d andvs r6, r0, #457179136 ; 0x1b400000
390: 756b6361 strbvc r6, [fp, #-865]! ; 0xfffffc9f
TASK_PRIORITY_DEFAULT + 1);
}
// wait - taskDelay alias
void wait(const unsigned long time) {
taskDelay((clock_t)time);
394: 74614270 strbtvc r4, [r1], #-624 ; 0xfffffd90
}
// waitUntil - taskDelayUntil alias
void waitUntil(unsigned long *previousWakeTime, unsigned long time) {
taskDelayUntil((clock_t*)previousWakeTime, (clock_t)time);
398: 79726574 ldmdbvc r2!, {r2, r4, r5, r6, r8, sl, sp, lr}^
39c: 73617400 cmnvc r1, #0, 8
3a0: 6c65446b cfstrdvs mvd4, [r5], #-428 ; 0xfffffe54
3a4: 6e557961 cdpvs 9, 5, cr7, cr5, cr1, {3}
3a8: 006c6974 rsbeq r6, ip, r4, ror r9
3ac: 6f666e69 svcvs 0x00666e69
3b0: 69617700 stmdbvs r1!, {r8, r9, sl, ip, sp, lr}^
3b4: 425f0074 subsmi r0, pc, #116 ; 0x74
3b8: 006c6f6f rsbeq r6, ip, pc, ror #30
3bc: 6e695f5f mcrvs 15, 3, r5, cr9, cr15, {2}
3c0: 745f3874 ldrbvc r3, [pc], #-2164 ; 3c8 <.debug_str+0x3c8>
3c4: 6d697400 cfstrdvs mvd7, [r9, #-0]
3c8: 67694865 strbvs r4, [r9, -r5, ror #16]!
3cc: 73655268 cmnvc r5, #104, 4 ; 0x80000006
3d0: 476f6900 strbmi r6, [pc, -r0, lsl #18]!
3d4: 6e497465 cdpvs 4, 4, cr7, cr9, cr5, {3}
3d8: 00747570 rsbseq r7, r4, r0, ror r5
3dc: 746e6975 strbtvc r6, [lr], #-2421 ; 0xfffff68b
3e0: 745f3631 ldrbvc r3, [pc], #-1585 ; 3e8 <.debug_str+0x3e8>
3e4: 63696d00 cmnvs r9, #0, 26
3e8: 00736f72 rsbseq r6, r3, r2, ror pc
3ec: 6e616863 cdpvs 8, 6, cr6, cr1, cr3, {3}
3f0: 006c656e rsbeq r6, ip, lr, ror #10
3f4: 6e69705f mcrvs 0, 3, r7, cr9, cr15, {2}
3f8: 65646e49 strbvs r6, [r4, #-3657]! ; 0xfffff1b7
3fc: 62615478 rsbvs r5, r1, #120, 8 ; 0x78000000
400: 7300656c movwvc r6, #1388 ; 0x56c
404: 61655476 smcvs 21830 ; 0x5546
408: 6d614e6d stclvs 14, cr4, [r1, #-436]! ; 0xfffffe4c
40c: 45520065 ldrbmi r0, [r2, #-101] ; 0xffffff9b
410: 56524553 ; <UNDEFINED> instruction: 0x56524553
414: 00304445 eorseq r4, r0, r5, asr #8
418: 45534552 ldrbmi r4, [r3, #-1362] ; 0xfffffaae
41c: 44455652 strbmi r5, [r5], #-1618 ; 0xfffff9ae
420: 45520031 ldrbmi r0, [r2, #-49] ; 0xffffffcf
424: 56524553 ; <UNDEFINED> instruction: 0x56524553
428: 00324445 eorseq r4, r2, r5, asr #8
42c: 45534552 ldrbmi r4, [r3, #-1362] ; 0xfffffaae
430: 44455652 strbmi r5, [r5], #-1618 ; 0xfffff9ae
434: 45520033 ldrbmi r0, [r2, #-51] ; 0xffffffcd
438: 56524553 ; <UNDEFINED> instruction: 0x56524553
43c: 00344445 eorseq r4, r4, r5, asr #8
440: 45534552 ldrbmi r4, [r3, #-1362] ; 0xfffffaae
444: 44455652 strbmi r5, [r5], #-1618 ; 0xfffff9ae
448: 45520035 ldrbmi r0, [r2, #-53] ; 0xffffffcb
44c: 56524553 ; <UNDEFINED> instruction: 0x56524553
450: 00364445 eorseq r4, r6, r5, asr #8
454: 726f6873 rsbvc r6, pc, #7536640 ; 0x730000
458: 6e692074 mcrvs 0, 3, r2, cr9, cr4, {3}
45c: 45520074 ldrbmi r0, [r2, #-116] ; 0xffffff8c
460: 56524553 ; <UNDEFINED> instruction: 0x56524553
464: 00384445 eorseq r4, r8, r5, asr #8
468: 45534552 ldrbmi r4, [r3, #-1362] ; 0xfffffaae
46c: 44455652 strbmi r5, [r5], #-1618 ; 0xfffff9ae
470: 6f6c0039 svcvs 0x006c0039
474: 6920676e stmdbvs r0!, {r1, r2, r3, r5, r6, r8, r9, sl, sp, lr}
478: 4400746e strmi r7, [r0], #-1134 ; 0xfffffb92
47c: 0052414d subseq r4, r2, sp, asr #2
480: 616c6564 cmnvs ip, r4, ror #10
484: 76730079 ; <UNDEFINED> instruction: 0x76730079
488: 54746553 ldrbtpl r6, [r4], #-1363 ; 0xfffffaad
48c: 4e6d6165 powmiez f6, f5, f5
490: 00656d61 rsbeq r6, r5, r1, ror #26
494: 6b736154 blvs 1cd89ec <_taskRunLoopHelper+0x1cd89ec>
498: 65646f43 strbvs r6, [r4, #-3907]! ; 0xfffff0bd
49c: 67696400 strbvs r6, [r9, -r0, lsl #8]!
4a0: 6c617469 cfstrdvs mvd7, [r1], #-420 ; 0xfffffe5c
4a4: 64616552 strbtvs r6, [r1], #-1362 ; 0xfffffaae
4a8: 796f6a00 stmdbvc pc!, {r9, fp, sp, lr}^ ; <UNPREDICTABLE>
4ac: 63697473 cmnvs r9, #1929379840 ; 0x73000000
4b0: 7465476b strbtvc r4, [r5], #-1899 ; 0xfffff895
4b4: 69676944 stmdbvs r7!, {r2, r6, r8, fp, sp, lr}^
4b8: 006c6174 rsbeq r6, ip, r4, ror r1
4bc: 6e69616d powvsez f6, f1, #5.0
4c0: 74746142 ldrbtvc r6, [r4], #-322 ; 0xfffffebe
4c4: 00797265 rsbseq r7, r9, r5, ror #4
4c8: 75417369 strbvc r7, [r1, #-873] ; 0xfffffc97
4cc: 6f6e6f74 svcvs 0x006e6f74
4d0: 73756f6d cmnvc r5, #436 ; 0x1b4
4d4: 755f5f00 ldrbvc r5, [pc, #-3840] ; fffff5dc <_taskRunLoopHelper+0xfffff5dc>
4d8: 38746e69 ldmdacc r4!, {r0, r3, r5, r6, r9, sl, fp, sp, lr}^
4dc: 6e00745f cfmvsrvs mvf0, r7
4e0: 00656d61 rsbeq r6, r5, r1, ror #26
4e4: 72617473 rsbvc r7, r1, #1929379840 ; 0x73000000
4e8: 50470074 subpl r0, r7, r4, ror r0
4ec: 545f4f49 ldrbpl r4, [pc], #-3913 ; 4f4 <.debug_str+0x4f4>
4f0: 44657079 strbtmi r7, [r5], #-121 ; 0xffffff87
4f4: 73006665 movwvc r6, #1637 ; 0x665
4f8: 74657a69 strbtvc r7, [r5], #-2665 ; 0xfffff597
4fc: 00657079 rsbeq r7, r5, r9, ror r0
500: 676e6f6c strbvs r6, [lr, -ip, ror #30]!
504: 736e7520 cmnvc lr, #32, 10 ; 0x8000000
508: 656e6769 strbvs r6, [lr, #-1897]! ; 0xfffff897
50c: 6e692064 cdpvs 0, 6, cr2, cr9, cr4, {3}
510: 745f0074 ldrbvc r0, [pc], #-116 ; 518 <.debug_str+0x518>
514: 526b7361 rsbpl r7, fp, #-2080374783 ; 0x84000001
518: 6f4c6e75 svcvs 0x004c6e75
51c: 6548706f strbvs r7, [r8, #-111] ; 0xffffff91
520: 7265706c rsbvc r7, r5, #108 ; 0x6c
524: 746f6d00 strbtvc r6, [pc], #-3328 ; 52c <.debug_str+0x52c>
528: 6f43726f svcvs 0x0043726f
52c: 6f72746e svcvs 0x0072746e
530: 7465536c strbtvc r5, [r5], #-876 ; 0xfffffc94
534: 746e6900 strbtvc r6, [lr], #-2304 ; 0xfffff700
538: 745f3233 ldrbvc r3, [pc], #-563 ; 540 <.debug_str+0x540>
53c: 726f7000 rsbvc r7, pc, #0
540: 69700074 ldmdbvs r0!, {r2, r4, r5, r6}^
544: 646f4d6e strbtvs r4, [pc], #-3438 ; 54c <.debug_str+0x54c>
548: 6e690065 cdpvs 0, 6, cr0, cr9, cr5, {3}
54c: 65646f4d strbvs r6, [r4, #-3917]! ; 0xfffff0b3
550: 736e7500 cmnvc lr, #0, 10
554: 656e6769 strbvs r6, [lr, #-1897]! ; 0xfffff897
558: 68632064 stmdavs r3!, {r2, r5, r6, sp}^
55c: 5f007261 svcpl 0x00007261
560: 6e69755f mcrvs 5, 3, r7, cr9, cr15, {2}
564: 5f323374 svcpl 0x00323374
568: 4e470074 mcrmi 0, 2, r0, cr7, cr4, {3}
56c: 20432055 subcs r2, r3, r5, asr r0
570: 2e392e34 mrccs 14, 1, r2, cr9, cr4, {1}
574: 30322033 eorscc r2, r2, r3, lsr r0
578: 35303531 ldrcc r3, [r0, #-1329]! ; 0xfffffacf
57c: 28203932 stmdacs r0!, {r1, r4, r5, r8, fp, ip, sp}
580: 72657270 rsbvc r7, r5, #112, 4
584: 61656c65 cmnvs r5, r5, ror #24
588: 20296573 eorcs r6, r9, r3, ror r5
58c: 68746d2d ldmdavs r4!, {r0, r2, r3, r5, r8, sl, fp, sp, lr}^
590: 20626d75 rsbcs r6, r2, r5, ror sp
594: 70636d2d rsbvc r6, r3, sp, lsr #26
598: 6f633d75 svcvs 0x00633d75
59c: 78657472 stmdavc r5!, {r1, r4, r5, r6, sl, ip, sp, lr}^
5a0: 20336d2d eorscs r6, r3, sp, lsr #26
5a4: 696c6d2d stmdbvs ip!, {r0, r2, r3, r5, r8, sl, fp, sp, lr}^
5a8: 656c7474 strbvs r7, [ip, #-1140]! ; 0xfffffb8c
5ac: 646e652d strbtvs r6, [lr], #-1325 ; 0xfffffad3
5b0: 206e6169 rsbcs r6, lr, r9, ror #2
5b4: 2d20672d stccs 7, cr6, [r0, #-180]! ; 0xffffff4c
5b8: 2d20734f stccs 3, cr7, [r0, #-316]! ; 0xfffffec4
5bc: 3d647473 cfstrdcc mvd7, [r4, #-460]! ; 0xfffffe34
5c0: 39756e67 ldmdbcc r5!, {r0, r1, r2, r5, r6, r9, sl, fp, sp, lr}^
5c4: 662d2039 ; <UNDEFINED> instruction: 0x662d2039
5c8: 636e7566 cmnvs lr, #427819008 ; 0x19800000
5cc: 6e6f6974 mcrvs 9, 3, r6, cr15, cr4, {3}
5d0: 6365732d cmnvs r5, #-1275068416 ; 0xb4000000
5d4: 6e6f6974 mcrvs 9, 3, r6, cr15, cr4, {3}
5d8: 662d2073 ; <UNDEFINED> instruction: 0x662d2073
5dc: 6e676973 mcrvs 9, 3, r6, cr7, cr3, {3}
5e0: 632d6465 ; <UNDEFINED> instruction: 0x632d6465
5e4: 20726168 rsbscs r6, r2, r8, ror #2
5e8: 6d6f662d stclvs 6, cr6, [pc, #-180]! ; 53c <.debug_str+0x53c>
5ec: 662d7469 strtvs r7, [sp], -r9, ror #8
5f0: 656d6172 strbvs r6, [sp, #-370]! ; 0xfffffe8e
5f4: 696f702d stmdbvs pc!, {r0, r2, r3, r5, ip, sp, lr}^ ; <UNPREDICTABLE>
5f8: 7265746e rsbvc r7, r5, #1845493760 ; 0x6e000000
5fc: 73662d20 cmnvc r6, #32, 26 ; 0x800
600: 6c676e69 stclvs 14, cr6, [r7], #-420 ; 0xfffffe5c
604: 72702d65 rsbsvc r2, r0, #6464 ; 0x1940
608: 73696365 cmnvc r9, #-1811939327 ; 0x94000001
60c: 2d6e6f69 stclcs 15, cr6, [lr, #-420]! ; 0xfffffe5c
610: 736e6f63 cmnvc lr, #396 ; 0x18c
614: 746e6174 strbtvc r6, [lr], #-372 ; 0xfffffe8c
618: 53455200 movtpl r5, #20992 ; 0x5200
61c: 45565245 ldrbmi r5, [r6, #-581] ; 0xfffffdbb
620: 00303144 eorseq r3, r0, r4, asr #2
624: 45534552 ldrbmi r4, [r3, #-1362] ; 0xfffffaae
628: 44455652 strbmi r5, [r5], #-1618 ; 0xfffff9ae
62c: 52003131 andpl r3, r0, #1073741836 ; 0x4000000c
630: 52455345 subpl r5, r5, #335544321 ; 0x14000001
634: 31444556 cmpcc r4, r6, asr r5
638: 45520032 ldrbmi r0, [r2, #-50] ; 0xffffffce
63c: 56524553 ; <UNDEFINED> instruction: 0x56524553
640: 33314445 teqcc r1, #1157627904 ; 0x45000000
644: 53455200 movtpl r5, #20992 ; 0x5200
648: 45565245 ldrbmi r5, [r6, #-581] ; 0xfffffdbb
64c: 00343144 eorseq r3, r4, r4, asr #2
650: 45534552 ldrbmi r4, [r3, #-1362] ; 0xfffffaae
654: 44455652 strbmi r5, [r5], #-1618 ; 0xfffff9ae
658: 52003531 andpl r3, r0, #205520896 ; 0xc400000
65c: 52455345 subpl r5, r5, #335544321 ; 0x14000001
660: 31444556 cmpcc r4, r6, asr r5
664: 45520036 ldrbmi r0, [r2, #-54] ; 0xffffffca
668: 56524553 ; <UNDEFINED> instruction: 0x56524553
66c: 37314445 ldrcc r4, [r1, -r5, asr #8]!
670: 53455200 movtpl r5, #20992 ; 0x5200
674: 45565245 ldrbmi r5, [r6, #-581] ; 0xfffffdbb
678: 00383144 eorseq r3, r8, r4, asr #2
67c: 45534552 ldrbmi r4, [r3, #-1362] ; 0xfffffaae
680: 44455652 strbmi r5, [r5], #-1618 ; 0xfffff9ae
684: 6d003931 stcvs 9, cr3, [r0, #-196] ; 0xffffff3c
688: 726f746f rsbvc r7, pc, #1862270976 ; 0x6f000000
68c: 00746553 rsbseq r6, r4, r3, asr r5
690: 73796f4a cmnvc r9, #296 ; 0x128
694: 6b636974 blvs 18dac6c <_taskRunLoopHelper+0x18dac6c>
698: 7079545f rsbsvc r5, r9, pc, asr r4
69c: 66654465 strbtvs r4, [r5], -r5, ror #8
6a0: 4a736900 bmi 1cdaaa8 <_taskRunLoopHelper+0x1cdaaa8>
6a4: 7473796f ldrbtvc r7, [r3], #-2415 ; 0xfffff691
6a8: 436b6369 cmnmi fp, #-1543503871 ; 0xa4000001
6ac: 656e6e6f strbvs r6, [lr, #-3695]! ; 0xfffff191
6b0: 64657463 strbtvs r7, [r5], #-1123 ; 0xfffffb9d
6b4: 796f6a00 stmdbvc pc!, {r9, fp, sp, lr}^ ; <UNPREDICTABLE>
6b8: 63697473 cmnvs r9, #1929379840 ; 0x73000000
6bc: 7465476b strbtvc r4, [r5], #-1899 ; 0xfffff895
6c0: 6c616e41 stclvs 14, cr6, [r1], #-260 ; 0xfffffefc
6c4: 7300676f movwvc r6, #1903 ; 0x76f
6c8: 656e6769 strbvs r6, [lr, #-1897]! ; 0xfffff897
6cc: 68632064 stmdavs r3!, {r2, r5, r6, sp}^
6d0: 70007261 andvc r7, r0, r1, ror #4
6d4: 6f697265 svcvs 0x00697265
6d8: 6f4c0064 svcvs 0x004c0064
6dc: 6154706f cmpvs r4, pc, rrx
6e0: 73006b73 movwvc r6, #2931 ; 0xb73
6e4: 74726f68 ldrbtvc r6, [r2], #-3944 ; 0xfffff098
6e8: 736e7520 cmnvc lr, #32, 10 ; 0x8000000
6ec: 656e6769 strbvs r6, [lr, #-1897]! ; 0xfffff897
6f0: 6e692064 cdpvs 0, 6, cr2, cr9, cr4, {3}
6f4: 65640074 strbvs r0, [r4, #-116]! ; 0xffffff8c
6f8: 4d79616c ldfmie f6, [r9, #-432]! ; 0xfffffe50
6fc: 6f726369 svcvs 0x00726369
700: 6f636573 svcvs 0x00636573
704: 0073646e rsbseq r6, r3, lr, ror #8
708: 61746f74 cmnvs r4, r4, ror pc
70c: 7673006c ldrbtvc r0, [r3], -ip, rrx
710: 4a746547 bmi 1d19c34 <_taskRunLoopHelper+0x1d19c34>
714: 7473796f ldrbtvc r7, [r3], #-2415 ; 0xfffff691
718: 416b6369 cmnmi fp, r9, ror #6
71c: 6f6c616e svcvs 0x006c616e
720: 61670067 cmnvs r7, r7, rrx
724: 7453656d ldrbvc r6, [r3], #-1389 ; 0xfffffa93
728: 73757461 cmnvc r5, #1627389952 ; 0x61000000
72c: 53455200 movtpl r5, #20992 ; 0x5200
730: 45565245 ldrbmi r5, [r6, #-581] ; 0xfffffdbb
734: 4c003744 stcmi 7, cr3, [r0], {68} ; 0x44
738: 00524b43 subseq r4, r2, r3, asr #22
73c: 42697073 rsbmi r7, r9, #115 ; 0x73
740: 65666675 strbvs r6, [r6, #-1653]! ; 0xfffff98b
744: 00585272 subseq r5, r8, r2, ror r2
Disassembly of section .comment:
00000000 <.comment>:
void (*fn)(void);
clock_t period;
} LoopTask;
// Helper task for taskRunLoop()
static void _taskRunLoopHelper(void *data) {
0: 43434700 movtmi r4, #14080 ; 0x3700
// Extract information from pointer
LoopTask *info = (LoopTask*)data;
void (*fn)(void) = info->fn;
clock_t period = info->period;
4: 3128203a ; <UNDEFINED> instruction: 0x3128203a
// Avoid leaking data
free(data);
8: 2e343a35 mrccs 10, 1, r3, cr4, cr5, {1}
// Start counter
clock_t now = timeLowRes();
c: 2b332e39 blcs ccb8f8 <_taskRunLoopHelper+0xccb8f8>
10: 326e7673 rsbcc r7, lr, #120586240 ; 0x7300000
uint16_t sf = svFlags & (SV_AUTONOMOUS | SV_ENABLED | SV_FMS);
14: 37313133 ; <UNDEFINED> instruction: 0x37313133
18: 29312d37 ldmdbcs r1!, {r0, r1, r2, r4, r5, r8, sl, fp, sp}
do {
fn();
taskDelayUntil(&now, period);
1c: 392e3420 stmdbcc lr!, {r5, sl, ip, sp}
20: 3220332e eorcc r3, r0, #-1207959552 ; 0xb8000000
// Auto-terminate on mode switch, drop, or disable
} while ((svFlags & (SV_AUTONOMOUS | SV_ENABLED | SV_FMS)) == sf);
24: 30353130 eorscc r3, r5, r0, lsr r1
28: 20393235 eorscs r3, r9, r5, lsr r2
2c: 65727028 ldrbvs r7, [r2, #-40]! ; 0xffffffd8
}
30: 656c6572 strbvs r6, [ip, #-1394]! ; 0xfffffa8e
34: 29657361 stmdbcs r5!, {r0, r5, r6, r8, r9, ip, sp, lr}^
...
Disassembly of section .debug_frame:
00000000 <.debug_frame>:
void (*fn)(void);
clock_t period;
} LoopTask;
// Helper task for taskRunLoop()
static void _taskRunLoopHelper(void *data) {
0: 0000000c andeq r0, r0, ip
// Extract information from pointer
LoopTask *info = (LoopTask*)data;
void (*fn)(void) = info->fn;
clock_t period = info->period;
4: ffffffff ; <UNDEFINED> instruction: 0xffffffff
// Avoid leaking data
free(data);
8: 7c020001 stcvc 0, cr0, [r2], {1}
// Start counter
clock_t now = timeLowRes();
c: 000d0c0e andeq r0, sp, lr, lsl #24
10: 0000001c andeq r0, r0, ip, lsl r0
...
14: R_ARM_ABS32 .debug_frame
18: R_ARM_ABS32 .text._taskRunLoopHelper
uint16_t sf = svFlags & (SV_AUTONOMOUS | SV_ENABLED | SV_FMS);
do {
fn();
taskDelayUntil(&now, period);
1c: 00000038 andeq r0, r0, r8, lsr r0
20: 84200e41 strthi r0, [r0], #-3649 ; 0xfffff1bf
// Auto-terminate on mode switch, drop, or disable
} while ((svFlags & (SV_AUTONOMOUS | SV_ENABLED | SV_FMS)) == sf);
24: 86048505 strhi r8, [r4], -r5, lsl #10
28: 8e028703 cdphi 7, 0, cr8, cr2, cr3, {0}
2c: 140e5701 strne r5, [lr], #-1793 ; 0xfffff8ff
}
30: 00000018 andeq r0, r0, r8, lsl r0
...
34: R_ARM_ABS32 .debug_frame
38: R_ARM_ABS32 .text.analogCalibrate
// analogCalibrate - Calibrates the analog sensor on the specified channel, assuming that it is
// not actively changing. Approximately 512 samples are taken, 1 ms apart, for a 0.5 s period
// of calibration. The average value thus calculated is returned and stored for later calls
// to analogReadCalibrated()
int analogCalibrate(unsigned char channel) {
channel--;
3c: 00000044 andeq r0, r0, r4, asr #32
if (channel < BOARD_NR_ADC_PINS) {
40: 84100e42 ldrhi r0, [r0], #-3650 ; 0xfffff1be
44: 86038504 strhi r8, [r3], -r4, lsl #10
// We have the true channel, do this in a loop
uint32_t total = 0, i;
for (i = 0; i < 512; i++) {
total += adcRead(channel);
48: 00018e02 andeq r8, r1, r2, lsl #28
4c: 00000014 andeq r0, r0, r4, lsl r0
...
50: R_ARM_ABS32 .debug_frame
54: R_ARM_ABS32 .text.analogRead
int analogCalibrate(unsigned char channel) {
channel--;
if (channel < BOARD_NR_ADC_PINS) {
// We have the true channel, do this in a loop
uint32_t total = 0, i;
for (i = 0; i < 512; i++) {
58: 00000014 andeq r0, r0, r4, lsl r0
total += adcRead(channel);
taskDelay(1);
}
// Store value (fixed to correctly round to nearest to avoid positive bias)
_analogState[channel].calibValue = (total + 16) >> 5;
5c: 83080e44 movwhi r0, #36420 ; 0x8e44
60: 00018e02 andeq r8, r1, r2, lsl #28
64: 00000014 andeq r0, r0, r4, lsl r0
...
68: R_ARM_ABS32 .debug_frame
6c: R_ARM_ABS32 .text.analogReadCalibrated
return (int)((total + 256) >> 9);
70: 0000002c andeq r0, r0, ip, lsr #32
}
return 0;
74: 84080e42 strhi r0, [r8], #-3650 ; 0xfffff1be
}
78: 00018e02 andeq r8, r1, r2, lsl #28
// analogRead - Reads an analog input channel 1-8 and returns the 12-bit value from 0 to 4095
int analogRead(unsigned char channel) {
channel--;
7c: 00000014 andeq r0, r0, r4, lsl r0
...
80: R_ARM_ABS32 .debug_frame
84: R_ARM_ABS32 .text.analogReadCalibratedHR
if (channel < BOARD_NR_ADC_PINS)
return (int)adcRead(channel);
88: 0000002c andeq r0, r0, ip, lsr #32
return 0;
8c: 84080e42 strhi r0, [r8], #-3650 ; 0xfffff1be
// analogReadCalibrated - Reads the calibrated value of an analog input channel 1-8;
// analogCalibrate() must be run first. This is inappropriate for integrated sensors as the
// round-off error can accumulate. Use analogReadCalibratedHR() instead.
int analogReadCalibrated(unsigned char channel) {
channel--;
90: 00018e02 andeq r8, r1, r2, lsl #28
94: 0000000c andeq r0, r0, ip
...
98: R_ARM_ABS32 .debug_frame
9c: R_ARM_ABS32 .text.delay
if (channel < BOARD_NR_ADC_PINS)
return (int)adcRead(channel) - (int)(_analogState[channel].calibValue >> 4);
a0: 00000004 andeq r0, r0, r4
a4: 00000014 andeq r0, r0, r4, lsl r0
...
a8: R_ARM_ABS32 .debug_frame
ac: R_ARM_ABS32 .text.delayMicroseconds
b0: 0000003c andeq r0, r0, ip, lsr r0
return 0;
}
b4: 84080e41 strhi r0, [r8], #-3649 ; 0xfffff1bf
b8: 00018e02 andeq r8, r1, r2, lsl #28
// drift due to round-off.
int analogReadCalibratedHR(unsigned char channel) {
// The value returned actually has 16 bits of "precision", even though the ADC only reads
// 12 bits, so that errors induced by the average value being between two values come out
// in the wash when integrated over time. Think of the value as the true value << 4.
channel--;
bc: 0000000c andeq r0, r0, ip
...
c0: R_ARM_ABS32 .debug_frame
c4: R_ARM_ABS32 .text.digitalRead
if (channel < BOARD_NR_ADC_PINS)
return (int)(adcRead(channel) << 4) - (int)(_analogState[channel].calibValue);
c8: 0000002c andeq r0, r0, ip, lsr #32
cc: 00000014 andeq r0, r0, r4, lsl r0
...
d0: R_ARM_ABS32 .debug_frame
d4: R_ARM_ABS32 .text.digitalWrite
d8: 0000002c andeq r0, r0, ip, lsr #32
dc: 84080e42 strhi r0, [r8], #-3650 ; 0xfffff1be
return 0;
}
e0: 00018e02 andeq r8, r1, r2, lsl #28
e4: 0000000c andeq r0, r0, ip
...
e8: R_ARM_ABS32 .debug_frame
ec: R_ARM_ABS32 .text.isAutonomous
}
// delayMicroseconds - Wait for approximately the given number of microseconds
void delayMicroseconds(const unsigned long time) {
clock_t us = (clock_t)time;
if (us) {
f0: 00000010 andeq r0, r0, r0, lsl r0
/*us *= 12; us--;
asm volatile(" mov r0, %[us]\n\t"
"1: subs r0, #1\n\t"
" bhi 1b\n\t"
: : [us] "r" (us) : "r0");*/
if (us > 1000) {
f4: 0000000c andeq r0, r0, ip
...
f8: R_ARM_ABS32 .debug_frame
fc: R_ARM_ABS32 .text.isEnabled
// Wait off the milliseconds part first
clock_t millis = (clock_t)(us / 1000UL);
us %= 1000UL;
100: 0000001c andeq r0, r0, ip, lsl r0
taskDelay(millis);
104: 0000000c andeq r0, r0, ip
...
108: R_ARM_ABS32 .debug_frame
10c: R_ARM_ABS32 .text.isJoystickConnected
}
if (us) {
// Spin on the highres timer value (next IRQ might be up to 1ms away!)
// Power consumption is bad, CPU usage possibly worse, but accuracy is acceptable
uint16_t start = TIM8->CNT;
110: 00000028 andeq r0, r0, r8, lsr #32
114: 0000000c andeq r0, r0, ip
...
118: R_ARM_ABS32 .debug_frame
11c: R_ARM_ABS32 .text.isOnline
while (TIM8->CNT - start < us);
120: 00000010 andeq r0, r0, r0, lsl r0
124: 00000018 andeq r0, r0, r8, lsl r0
...
128: R_ARM_ABS32 .debug_frame
12c: R_ARM_ABS32 .text.joystickGetAnalog
// digitalRead - Gets the digital value (1 or 0) of a pin configured as a digital input
bool digitalRead(unsigned char pin) {
if (pin >= BOARD_NR_GPIO_PINS)
return 0;
return ioGetInput((GPIO_TypeDef*)_pinLookupTable[pin], (uint8_t)_pinIndexTable[pin]);
130: 00000058 andeq r0, r0, r8, asr r0
}
// ioGetInput - Gets the digital value (1 or 0) of a pin configured as a digital input
static INLINE bool ioGetInput(GPIO_TypeDef* port, uint32_t pin) {
// Shift right that many bits, then mask everything but the ones
return ((port->IDR >> (pin & 0x0F)) & 0x01) != 0;
134: 83100e41 tsthi r0, #1040 ; 0x410
138: 85038404 strhi r8, [r3, #-1028] ; 0xfffffbfc
13c: 00018e02 andeq r8, r1, r2, lsl #28
140: 00000018 andeq r0, r0, r8, lsl r0
...
144: R_ARM_ABS32 .debug_frame
148: R_ARM_ABS32 .text.joystickGetDigital
}
14c: 0000006c andeq r0, r0, ip, rrx
150: 84100e41 ldrhi r0, [r0], #-3649 ; 0xfffff1bf
// digitalWrite - Sets the digital value (1 or 0) of a pin configured as a digital output
void digitalWrite(unsigned char pin, bool value) {
// We will let this work when disabled, even though it might change a solenoid, since it
// is needed to set initial solenoid states in initializeIO() when enabled/disabled is
// undefined.
if (pin < BOARD_NR_GPIO_PINS)
154: 86038504 strhi r8, [r3], -r4, lsl #10
158: 00018e02 andeq r8, r1, r2, lsl #28
ioSetOutput((GPIO_TypeDef*)_pinLookupTable[pin], (uint8_t)_pinIndexTable[pin], value);
15c: 0000000c andeq r0, r0, ip
...
160: R_ARM_ABS32 .debug_frame
164: R_ARM_ABS32 .text.micros
168: 00000004 andeq r0, r0, r4
return ((port->ODR >> (pin & 0x0F)) & 0x01) != 0;
}
// ioSetOutput - Sets the digital value (1 or 0) of a pin configured as a digital output
static INLINE void ioSetOutput(GPIO_TypeDef* port, uint32_t pin, bool value) {
if (value)
16c: 0000000c andeq r0, r0, ip
...
170: R_ARM_ABS32 .debug_frame
174: R_ARM_ABS32 .text.millis
// Atomic bit set
port->BSRR = ((uint32_t)0x00000001) << (pin & 0x0F);
else
// Atomic bit reset
port->BRR = ((uint32_t)0x00000001) << (pin & 0x0F);
178: 00000004 andeq r0, r0, r4
17c: 00000014 andeq r0, r0, r4, lsl r0
...
180: R_ARM_ABS32 .debug_frame
184: R_ARM_ABS32 .text.motorGet
}
// isAutonomous - Checks to see if the system is in autonomous mode
bool isAutonomous() {
return (svFlags & SV_AUTONOMOUS) ? true : false;
}
188: 0000000a andeq r0, r0, sl
18c: 83080e41 movwhi r0, #36417 ; 0x8e41
// isEnabled - Checks to see if the system is enabled
bool isEnabled() {
uint16_t flags = svFlags;
190: 00018e02 andeq r8, r1, r2, lsl #28
194: 00000024 andeq r0, r0, r4, lsr #32
...
198: R_ARM_ABS32 .debug_frame
19c: R_ARM_ABS32 .text.motorSet
if (!(flags & SV_ENABLED)) {
if (flags & SV_FMS)
1a0: 0000002a andeq r0, r0, sl, lsr #32
return false;
}
return true;
}
1a4: 83100e41 tsthi r0, #1040 ; 0x410
1a8: 85038404 strhi r8, [r3, #-1028] ; 0xfffffbfc
}
// svIsJoystickConnected - Checks to see if a joystick is connected
static INLINE uint8_t svIsJoystickConnected(uint8_t joystick) {
// Force in range from 0..1 (mapped from 1..2)
joystick = (joystick - 1) & (uint8_t)0x01;
1ac: 50018e02 andpl r8, r1, r2, lsl #28
// If both accelerometer axes are zero, the joystick is likely not plugged in
// Obviously there is a chance for false positives but extremely unlikely due to the noise
// of the analog accelerometers
return SV_IN->joystick[joystick].axis[4] != (uint8_t)0x7F ||
1b0: c4c5ce0a strbgt ip, [r5], #3594 ; 0xe0a
1b4: 43000ec3 movwmi r0, #3779 ; 0xec3
1b8: 0000000b andeq r0, r0, fp
1bc: 0000000c andeq r0, r0, ip
...
1c0: R_ARM_ABS32 .debug_frame
1c4: R_ARM_ABS32 .text.motorStop
1c8: 00000006 andeq r0, r0, r6
1cc: 0000000c andeq r0, r0, ip
...
1d0: R_ARM_ABS32 .debug_frame
1d4: R_ARM_ABS32 .text.motorStopAll
}
// isOnline - Checks to see if the system is connected to a FMS/competition switch
bool isOnline() {
return (svFlags & SV_FMS) ? true : false;
}
1d8: 00000004 andeq r0, r0, r4
1dc: 0000000c andeq r0, r0, ip
...
1e0: R_ARM_ABS32 .debug_frame
1e4: R_ARM_ABS32 .text.pinMode
// joystickGetAnalog - Retrieve an analog axis of a joystick
int joystickGetAnalog(unsigned char joystick, unsigned char axis) {
1e8: 00000020 andeq r0, r0, r0, lsr #32
// Safety first here
if (isOnline() && isAutonomous()) return 0;
1ec: 0000000c andeq r0, r0, ip
...
1f0: R_ARM_ABS32 .debug_frame
1f4: R_ARM_ABS32 .text.powerLevelBackup
// svGetJoystickAnalog - Gets an analog joystick axis or accelerometer axis from the supervisor
// NO check on the mode when doing so
static INLINE int8_t svGetJoystickAnalog(uint8_t joystick, uint8_t axis) {
uint8_t value;
// Force in range from 0..5 (mapped from 1..6)
axis = (axis - 1) % 6;
1f8: 00000018 andeq r0, r0, r8, lsl r0
// Force in range from 0..1 (mapped from 1..2)
joystick = (joystick - 1) & (uint8_t)0x01;
1fc: 0000000c andeq r0, r0, ip
...
200: R_ARM_ABS32 .debug_frame
204: R_ARM_ABS32 .text.powerLevelMain
value = SV_IN->joystick[joystick].axis[axis];
208: 00000018 andeq r0, r0, r8, lsl r0
// Prevent return of 128
if (value == 0xFF)
value = 0xFE;
value -= 127;
if (axis == 1 || axis == 2)
20c: 0000000c andeq r0, r0, ip
...
210: R_ARM_ABS32 .debug_frame
214: R_ARM_ABS32 .text.setTeamName
218: 0000002c andeq r0, r0, ip, lsr #32
joystick = (joystick - 1) & (uint8_t)0x01;
value = SV_IN->joystick[joystick].axis[axis];
// Prevent return of 128
if (value == 0xFF)
value = 0xFE;
value -= 127;
21c: 00000020 andeq r0, r0, r0, lsr #32
...
220: R_ARM_ABS32 .debug_frame
224: R_ARM_ABS32 .text.taskRunLoop
228: 00000028 andeq r0, r0, r8, lsr #32
22c: 84100e41 ldrhi r0, [r0], #-3649 ; 0xfffff1bf
230: 86038504 strhi r8, [r3], -r4, lsl #10
return (int)svGetJoystickAnalog(joystick, axis);
234: 4c018e02 stcmi 14, cr8, [r1], {2}
238: c4c5c6ce strbgt ip, [r5], #1742 ; 0x6ce
}
// joystickGetDigital - Retrieve a digital button of a joystick
bool joystickGetDigital(unsigned char joystick, unsigned char buttonGroup,
unsigned char button) {
23c: 0000000e andeq r0, r0, lr
240: 0000000c andeq r0, r0, ip
...
244: R_ARM_ABS32 .debug_frame
248: R_ARM_ABS32 .text.wait
static INLINE uint8_t svGetJoystickDigital(uint8_t joystick, uint8_t button) {
uint8_t value; volatile Joystick_TypeDef *ref;
// Force in range from 0..3 (mapped from 5..8)
button = (button - 5) & (uint8_t)0x03;
// Force in range from 0..1 (mapped from 1..2)
joystick = (joystick - 1) & (uint8_t)0x01;
24c: 00000004 andeq r0, r0, r4
ref = &SV_IN->joystick[joystick];
// 5 and 6 need some mangling to move the twos bit up to the fours
switch (button) {
250: 0000000c andeq r0, r0, ip
...
254: R_ARM_ABS32 .debug_frame
258: R_ARM_ABS32 .text.waitUntil
uint8_t value; volatile Joystick_TypeDef *ref;
// Force in range from 0..3 (mapped from 5..8)
button = (button - 5) & (uint8_t)0x03;
// Force in range from 0..1 (mapped from 1..2)
joystick = (joystick - 1) & (uint8_t)0x01;
ref = &SV_IN->joystick[joystick];
25c: 00000004 andeq r0, r0, r4
Disassembly of section .ARM.attributes:
00000000 <.ARM.attributes>:
void (*fn)(void);
clock_t period;
} LoopTask;
// Helper task for taskRunLoop()
static void _taskRunLoopHelper(void *data) {
0: 00003241 andeq r3, r0, r1, asr #4
// Extract information from pointer
LoopTask *info = (LoopTask*)data;
void (*fn)(void) = info->fn;
clock_t period = info->period;
4: 61656100 cmnvs r5, r0, lsl #2
// Avoid leaking data
free(data);
8: 01006962 tsteq r0, r2, ror #18
// Start counter
clock_t now = timeLowRes();
c: 00000028 andeq r0, r0, r8, lsr #32
10: 726f4305 rsbvc r4, pc, #335544320 ; 0x14000000
uint16_t sf = svFlags & (SV_AUTONOMOUS | SV_ENABLED | SV_FMS);
14: 2d786574 cfldr64cs mvdx6, [r8, #-464]! ; 0xfffffe30
18: 0600334d streq r3, [r0], -sp, asr #6
do {
fn();
taskDelayUntil(&now, period);
1c: 094d070a stmdbeq sp, {r1, r3, r8, r9, sl}^
20: 14041202 strne r1, [r4], #-514 ; 0xfffffdfe
// Auto-terminate on mode switch, drop, or disable
} while ((svFlags & (SV_AUTONOMOUS | SV_ENABLED | SV_FMS)) == sf);
24: 17011501 strne r1, [r1, -r1, lsl #10]
28: 19011803 stmdbne r1, {r0, r1, fp, ip}
2c: 1e011a01 vmlane.f32 s2, s2, s2
}
30: Address 0x0000000000000030 is out of bounds.
comm.o: file format elf32-littlearm
rw-r--r-- 1000/1000 33096 Oct 20 02:06 2016 comm.o
architecture: arm, flags 0x00000011:
HAS_RELOC, HAS_SYMS
start address 0x00000000
private flags = 5000000: [Version5 EABI]
Sections:
Idx Name Size VMA LMA File off Algn
0 .text 00000000 00000000 00000000 00000034 2**1
CONTENTS, ALLOC, LOAD, READONLY, CODE
1 .data 00000000 00000000 00000000 00000034 2**0
CONTENTS, ALLOC, LOAD, DATA
2 .bss 000001e0 00000000 00000000 00000034 2**2
ALLOC
3 .text.lcdButtonProcess 0000005c 00000000 00000000 00000034 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
4 .text.fgetc 00000064 00000000 00000000 00000090 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
5 .text.fputc 00000084 00000000 00000000 000000f4 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
6 .text.fread 00000028 00000000 00000000 00000178 2**1
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
7 .text.fwrite 00000028 00000000 00000000 000001a0 2**1
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
8 .text.getchar 00000006 00000000 00000000 000001c8 2**1
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
9 .text.putchar 00000006 00000000 00000000 000001ce 2**1
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
10 .text.ISR_USART1 000000bc 00000000 00000000 000001d4 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
11 .text.ISR_USART2 000000cc 00000000 00000000 00000290 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
12 .text.ISR_USART3 000000cc 00000000 00000000 0000035c 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
13 .text.lcdReadButtons 0000002c 00000000 00000000 00000428 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
14 .text.lcdSetBacklight 00000028 00000000 00000000 00000454 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
15 .text._lcdDump 000000a8 00000000 00000000 0000047c 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
16 .text.lcdSetText 0000003c 00000000 00000000 00000524 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
17 .text.lcdClear 00000020 00000000 00000000 00000560 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
18 .text.lcdPrint 00000034 00000000 00000000 00000580 2**1
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
19 .text.usartBufferCount 00000030 00000000 00000000 000005b4 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
20 .text.fcount 0000001c 00000000 00000000 000005e4 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
21 .text.feof 00000028 00000000 00000000 00000600 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
22 .text.fgets 0000003a 00000000 00000000 00000628 2**1
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
23 .text.usartBufferInit 00000054 00000000 00000000 00000664 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
24 .text.usartFlushBuffers 0000002c 00000000 00000000 000006b8 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
25 .text.usartInit 000000b4 00000000 00000000 000006e4 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
26 .text.lcdInit 00000030 00000000 00000000 00000798 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
27 .text.usartShutdown 00000020 00000000 00000000 000007c8 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
28 .text.lcdShutdown 00000020 00000000 00000000 000007e8 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
29 .rodata.str1.1 00000001 00000000 00000000 00000808 2**0
CONTENTS, ALLOC, LOAD, READONLY, DATA
30 .debug_info 00001584 00000000 00000000 00000809 2**0
CONTENTS, RELOC, READONLY, DEBUGGING
31 .debug_abbrev 00000483 00000000 00000000 00001d8d 2**0
CONTENTS, READONLY, DEBUGGING
32 .debug_loc 00000f99 00000000 00000000 00002210 2**0
CONTENTS, RELOC, READONLY, DEBUGGING
33 .debug_aranges 000000e8 00000000 00000000 000031a9 2**0
CONTENTS, RELOC, READONLY, DEBUGGING
34 .debug_ranges 00000238 00000000 00000000 00003291 2**0
CONTENTS, RELOC, READONLY, DEBUGGING
35 .debug_line 0000055f 00000000 00000000 000034c9 2**0
CONTENTS, RELOC, READONLY, DEBUGGING
36 .debug_str 000005c6 00000000 00000000 00003a28 2**0
CONTENTS, READONLY, DEBUGGING
37 .comment 00000039 00000000 00000000 00003fee 2**0
CONTENTS, READONLY
38 .debug_frame 000002f0 00000000 00000000 00004028 2**2
CONTENTS, RELOC, READONLY, DEBUGGING
39 .ARM.attributes 00000033 00000000 00000000 00004318 2**0
CONTENTS, READONLY
SYMBOL TABLE:
00000000 l df *ABS* 00000000 comm.c
00000000 l d .text 00000000 .text
00000000 l d .data 00000000 .data
00000000 l d .bss 00000000 .bss
00000000 l d .text.lcdButtonProcess 00000000 .text.lcdButtonProcess
00000000 l F .text.lcdButtonProcess 0000005c lcdButtonProcess
00000000 l d .text.fgetc 00000000 .text.fgetc
00000000 l d .text.fputc 00000000 .text.fputc
00000000 l d .text.fread 00000000 .text.fread
00000000 l d .text.fwrite 00000000 .text.fwrite
00000000 l d .text.getchar 00000000 .text.getchar
00000000 l d .text.putchar 00000000 .text.putchar
00000000 l d .text.ISR_USART1 00000000 .text.ISR_USART1
00000000 l d .text.ISR_USART2 00000000 .text.ISR_USART2
00000000 l d .text.ISR_USART3 00000000 .text.ISR_USART3
00000000 l d .text.lcdReadButtons 00000000 .text.lcdReadButtons
00000000 l d .text.lcdSetBacklight 00000000 .text.lcdSetBacklight
00000000 l d .text._lcdDump 00000000 .text._lcdDump
00000000 l d .text.lcdSetText 00000000 .text.lcdSetText
00000000 l d .text.lcdClear 00000000 .text.lcdClear
00000000 l d .text.lcdPrint 00000000 .text.lcdPrint
00000000 l d .text.usartBufferCount 00000000 .text.usartBufferCount
00000000 l d .text.fcount 00000000 .text.fcount
00000000 l d .text.feof 00000000 .text.feof
00000000 l d .text.fgets 00000000 .text.fgets
00000000 l d .text.usartBufferInit 00000000 .text.usartBufferInit
00000000 l d .text.usartFlushBuffers 00000000 .text.usartFlushBuffers
00000000 l d .text.usartInit 00000000 .text.usartInit
00000000 l d .text.lcdInit 00000000 .text.lcdInit
00000000 l d .text.usartShutdown 00000000 .text.usartShutdown
00000000 l d .text.lcdShutdown 00000000 .text.lcdShutdown
00000000 l d .rodata.str1.1 00000000 .rodata.str1.1
00000000 l O .bss 00000048 lcd
00000048 l O .bss 00000198 usart
00000000 l d .debug_info 00000000 .debug_info
00000000 l d .debug_abbrev 00000000 .debug_abbrev
00000000 l d .debug_loc 00000000 .debug_loc
00000000 l d .debug_aranges 00000000 .debug_aranges
00000000 l d .debug_ranges 00000000 .debug_ranges
00000000 l d .debug_line 00000000 .debug_line
00000000 l d .debug_str 00000000 .debug_str
00000000 l d .debug_frame 00000000 .debug_frame
00000000 l d .comment 00000000 .comment
00000000 l d .ARM.attributes 00000000 .ARM.attributes
00000000 g F .text.fgetc 00000064 fgetc
00000000 *UND* 00000000 semaphoreTake
00000000 *UND* 00000000 fsRead
00000000 g F .text.fputc 00000084 fputc
00000000 *UND* 00000000 _yield
00000000 *UND* 00000000 fsWrite
00000000 g F .text.fread 00000028 fread
00000000 g F .text.fwrite 00000028 fwrite
00000000 g F .text.getchar 00000006 getchar
00000000 g F .text.putchar 00000006 putchar
00000000 g F .text.ISR_USART1 000000bc ISR_USART1
00000000 *UND* 00000000 semaphoreGiveISR
00000000 g F .text.ISR_USART2 000000cc ISR_USART2
00000000 g F .text.ISR_USART3 000000cc ISR_USART3
00000000 g F .text.lcdReadButtons 0000002c lcdReadButtons
00000000 g F .text.lcdSetBacklight 00000028 lcdSetBacklight
00000000 g F .text._lcdDump 000000a8 _lcdDump
00000000 g F .text.lcdSetText 0000003c lcdSetText
00000000 g F .text.lcdClear 00000020 lcdClear
00000000 g F .text.lcdPrint 00000034 lcdPrint
00000000 *UND* 00000000 vsnprintf
00000000 g F .text.usartBufferCount 00000030 usartBufferCount
00000000 *UND* 00000000 _criticalNesting
00000000 g F .text.fcount 0000001c fcount
00000000 *UND* 00000000 fsLeft
00000000 g F .text.feof 00000028 feof
00000000 *UND* 00000000 fsEof
00000000 g F .text.fgets 0000003a fgets
00000000 g F .text.usartBufferInit 00000054 usartBufferInit
00000000 *UND* 00000000 semaphoreCreate
00000000 g F .text.usartFlushBuffers 0000002c usartFlushBuffers
00000000 g F .text.usartInit 000000b4 usartInit
00000000 g F .text.lcdInit 00000030 lcdInit
00000000 g F .text.usartShutdown 00000020 usartShutdown
00000000 g F .text.lcdShutdown 00000020 lcdShutdown
Disassembly of section .bss:
00000000 <lcd>:
...
00000048 <usart>:
...
Disassembly of section .text.lcdButtonProcess:
00000000 <lcdButtonProcess>:
_taskYield();
}
// lcdButtonProcess - Processes the VEX LCD buttons
static void lcdButtonProcess(char value, uint32_t index) {
uint16_t count = lcd[index].state;
0: 4a15 ldr r2, [pc, #84] ; (58 <lcdButtonProcess+0x58>)
2: 2324 movs r3, #36 ; 0x24
4: fb03 2301 mla r3, r3, r1, r2
8: f110 0f56 cmn.w r0, #86 ; 0x56
c: 8c5b ldrh r3, [r3, #34] ; 0x22
e: d015 beq.n 3c <lcdButtonProcess+0x3c>
10: 2855 cmp r0, #85 ; 0x55
12: d102 bne.n 1a <lcdButtonProcess+0x1a>
14: 2b01 cmp r3, #1
16: d109 bne.n 2c <lcdButtonProcess+0x2c>
18: e012 b.n 40 <lcdButtonProcess+0x40>
1a: 2816 cmp r0, #22
1c: d102 bne.n 24 <lcdButtonProcess+0x24>
1e: 2b02 cmp r3, #2
20: d104 bne.n 2c <lcdButtonProcess+0x2c>
22: e00f b.n 44 <lcdButtonProcess+0x44>
24: 2802 cmp r0, #2
26: d101 bne.n 2c <lcdButtonProcess+0x2c>
28: 2b03 cmp r3, #3
2a: d00d beq.n 48 <lcdButtonProcess+0x48>
2c: 2b04 cmp r3, #4
2e: d10d bne.n 4c <lcdButtonProcess+0x4c>
30: 2324 movs r3, #36 ; 0x24
32: fb03 2301 mla r3, r3, r1, r2
36: f883 0021 strb.w r0, [r3, #33] ; 0x21
3a: e007 b.n 4c <lcdButtonProcess+0x4c>
3c: 2301 movs r3, #1
3e: e006 b.n 4e <lcdButtonProcess+0x4e>
40: 2302 movs r3, #2
42: e004 b.n 4e <lcdButtonProcess+0x4e>
44: 2303 movs r3, #3
46: e002 b.n 4e <lcdButtonProcess+0x4e>
48: 2304 movs r3, #4
4a: e000 b.n 4e <lcdButtonProcess+0x4e>
4c: 2300 movs r3, #0
4e: 2024 movs r0, #36 ; 0x24
50: fb00 2101 mla r1, r0, r1, r2
54: 844b strh r3, [r1, #34] ; 0x22
56: 4770 bx lr
58: 00000000 andeq r0, r0, r0
58: R_ARM_ABS32 .bss
Disassembly of section .text.fgetc:
00000000 <fgetc>:
0: b538 push {r3, r4, r5, lr}
2: 1e44 subs r4, r0, #1
4: 2c02 cmp r4, #2
6: d815 bhi.n 34 <fgetc+0x34>
8: 4d14 ldr r5, [pc, #80] ; (5c <fgetc+0x5c>)
a: 2388 movs r3, #136 ; 0x88
c: fb03 5504 mla r5, r3, r4, r5
10: f895 2042 ldrb.w r2, [r5, #66] ; 0x42
14: f895 3043 ldrb.w r3, [r5, #67] ; 0x43
18: 429a cmp r2, r3
1a: f04f 0388 mov.w r3, #136 ; 0x88
1e: 4a10 ldr r2, [pc, #64] ; (60 <fgetc+0x60>)
20: d10c bne.n 3c <fgetc+0x3c>
22: fb03 2304 mla r3, r3, r4, r2
26: f04f 31ff mov.w r1, #4294967295 ; 0xffffffff
2a: f8d3 00cc ldr.w r0, [r3, #204] ; 0xcc
2e: f7ff fffe bl 0 <semaphoreTake>
2e: R_ARM_THM_CALL semaphoreTake
32: e7ed b.n 10 <fgetc+0x10>
34: e8bd 4038 ldmia.w sp!, {r3, r4, r5, lr}
38: f7ff bffe b.w 0 <fsRead>
38: R_ARM_THM_JUMP24 fsRead
3c: fb03 2404 mla r4, r3, r4, r2
40: f894 308a ldrb.w r3, [r4, #138] ; 0x8a
44: f104 0288 add.w r2, r4, #136 ; 0x88
48: b2db uxtb r3, r3
4a: 441c add r4, r3
4c: 3301 adds r3, #1
4e: f003 033f and.w r3, r3, #63 ; 0x3f
52: f894 008c ldrb.w r0, [r4, #140] ; 0x8c
56: 7093 strb r3, [r2, #2]
58: bd38 pop {r3, r4, r5, pc}
5a: bf00 nop
5c: 00000048 andeq r0, r0, r8, asr #32
5c: R_ARM_ABS32 .bss
60: 00000000 andeq r0, r0, r0
60: R_ARM_ABS32 .bss
Disassembly of section .text.fputc:
00000000 <fputc>:
0: b570 push {r4, r5, r6, lr}
2: 1e4d subs r5, r1, #1
4: 2d02 cmp r5, #2
6: 4604 mov r4, r0
8: d82c bhi.n 64 <fputc+0x64>
a: 4e19 ldr r6, [pc, #100] ; (70 <fputc+0x70>)
c: 2388 movs r3, #136 ; 0x88
e: fb03 6605 mla r6, r3, r5, r6
12: 7873 ldrb r3, [r6, #1]
14: 7832 ldrb r2, [r6, #0]
16: 3301 adds r3, #1
18: f003 033f and.w r3, r3, #63 ; 0x3f
1c: 4293 cmp r3, r2
1e: d102 bne.n 26 <fputc+0x26>
20: f7ff fffe bl 0 <_yield>
20: R_ARM_THM_CALL _yield
24: e7f5 b.n 12 <fputc+0x12>
26: 4a13 ldr r2, [pc, #76] ; (74 <fputc+0x74>)
28: 2388 movs r3, #136 ; 0x88
2a: fb03 2205 mla r2, r3, r5, r2
2e: f892 3049 ldrb.w r3, [r2, #73] ; 0x49
32: f102 0048 add.w r0, r2, #72 ; 0x48
36: b2db uxtb r3, r3
38: 441a add r2, r3
3a: 3301 adds r3, #1
3c: b2e1 uxtb r1, r4
3e: f003 033f and.w r3, r3, #63 ; 0x3f
42: f882 104a strb.w r1, [r2, #74] ; 0x4a
46: 7043 strb r3, [r0, #1]
48: b90d cbnz r5, 4e <fputc+0x4e>
4a: 4a0b ldr r2, [pc, #44] ; (78 <fputc+0x78>)
4c: e003 b.n 56 <fputc+0x56>
4e: 2d01 cmp r5, #1
50: bf0c ite eq
52: 4a0a ldreq r2, [pc, #40] ; (7c <fputc+0x7c>)
54: 4a0a ldrne r2, [pc, #40] ; (80 <fputc+0x80>)
56: 8993 ldrh r3, [r2, #12]
58: 4620 mov r0, r4
5a: b29b uxth r3, r3
5c: f043 0380 orr.w r3, r3, #128 ; 0x80
60: 8193 strh r3, [r2, #12]
62: bd70 pop {r4, r5, r6, pc}
64: 4608 mov r0, r1
66: 4621 mov r1, r4
68: e8bd 4070 ldmia.w sp!, {r4, r5, r6, lr}
6c: f7ff bffe b.w 0 <fsWrite>
6c: R_ARM_THM_JUMP24 fsWrite
70: 00000048 andeq r0, r0, r8, asr #32
70: R_ARM_ABS32 .bss
74: 00000000 andeq r0, r0, r0
74: R_ARM_ABS32 .bss
78: 40004400 andmi r4, r0, r0, lsl #8
7c: 40004800 andmi r4, r0, r0, lsl #16
80: 40013800 andmi r3, r1, r0, lsl #16
Disassembly of section .text.fread:
00000000 <fread>:
0: b5f8 push {r3, r4, r5, r6, r7, lr}
2: 4606 mov r6, r0
4: 461f mov r7, r3
6: fb02 f501 mul.w r5, r2, r1
a: 2400 movs r4, #0
c: 42ac cmp r4, r5
e: d009 beq.n 24 <fread+0x24>
10: 4638 mov r0, r7
12: f7ff fffe bl 0 <fread>
12: R_ARM_THM_CALL fgetc
16: 1c43 adds r3, r0, #1
18: d101 bne.n 1e <fread+0x1e>
1a: 4625 mov r5, r4
1c: e002 b.n 24 <fread+0x24>
1e: 5530 strb r0, [r6, r4]
20: 3401 adds r4, #1
22: e7f3 b.n c <fread+0xc>
24: 4628 mov r0, r5
26: bdf8 pop {r3, r4, r5, r6, r7, pc}
Disassembly of section .text.fwrite:
00000000 <fwrite>:
0: b5f8 push {r3, r4, r5, r6, r7, lr}
2: 4606 mov r6, r0
4: 461f mov r7, r3
6: fb02 f501 mul.w r5, r2, r1
a: 2400 movs r4, #0
c: 42ac cmp r4, r5
e: d009 beq.n 24 <fwrite+0x24>
10: 5730 ldrsb r0, [r6, r4]
12: 4639 mov r1, r7
14: f7ff fffe bl 0 <fwrite>
14: R_ARM_THM_CALL fputc
18: 3001 adds r0, #1
1a: d101 bne.n 20 <fwrite+0x20>
1c: 4625 mov r5, r4
1e: e001 b.n 24 <fwrite+0x24>
20: 3401 adds r4, #1
22: e7f3 b.n c <fwrite+0xc>
24: 4628 mov r0, r5
26: bdf8 pop {r3, r4, r5, r6, r7, pc}
Disassembly of section .text.getchar:
00000000 <getchar>:
0: 2003 movs r0, #3
2: f7ff bffe b.w 0 <getchar>
2: R_ARM_THM_JUMP24 fgetc
Disassembly of section .text.putchar:
00000000 <putchar>:
0: 2103 movs r1, #3
2: f7ff bffe b.w 0 <putchar>
2: R_ARM_THM_JUMP24 fputc
Disassembly of section .text.ISR_USART1:
00000000 <ISR_USART1>:
0: 4668 mov r0, sp
2: f020 0107 bic.w r1, r0, #7
6: 468d mov sp, r1
8: b501 push {r0, lr}
a: 2300 movs r3, #0
c: b082 sub sp, #8
e: f88d 3007 strb.w r3, [sp, #7]
12: 4b27 ldr r3, [pc, #156] ; (b0 <ISR_USART1+0xb0>)
14: 881a ldrh r2, [r3, #0]
16: 0692 lsls r2, r2, #26
18: d51d bpl.n 56 <ISR_USART1+0x56>
1a: 8899 ldrh r1, [r3, #4]
1c: 4b25 ldr r3, [pc, #148] ; (b4 <ISR_USART1+0xb4>)
1e: b289 uxth r1, r1
20: f893 219b ldrb.w r2, [r3, #411] ; 0x19b
24: f893 019a ldrb.w r0, [r3, #410] ; 0x19a
28: 3201 adds r2, #1
2a: f002 023f and.w r2, r2, #63 ; 0x3f
2e: 4282 cmp r2, r0
30: d00b beq.n 4a <ISR_USART1+0x4a>
32: f893 219b ldrb.w r2, [r3, #411] ; 0x19b
36: b2c9 uxtb r1, r1
38: b2d2 uxtb r2, r2
3a: 1898 adds r0, r3, r2
3c: 3201 adds r2, #1
3e: f002 023f and.w r2, r2, #63 ; 0x3f
42: f880 119c strb.w r1, [r0, #412] ; 0x19c
46: f883 219b strb.w r2, [r3, #411] ; 0x19b
4a: f8d3 01dc ldr.w r0, [r3, #476] ; 0x1dc
4e: f10d 0107 add.w r1, sp, #7
52: f7ff fffe bl 0 <semaphoreGiveISR>
52: R_ARM_THM_CALL semaphoreGiveISR
56: 4816 ldr r0, [pc, #88] ; (b0 <ISR_USART1+0xb0>)
58: 8803 ldrh r3, [r0, #0]
5a: 061b lsls r3, r3, #24
5c: d51b bpl.n 96 <ISR_USART1+0x96>
5e: 4915 ldr r1, [pc, #84] ; (b4 <ISR_USART1+0xb4>)
60: f891 2158 ldrb.w r2, [r1, #344] ; 0x158
64: f891 3159 ldrb.w r3, [r1, #345] ; 0x159
68: 429a cmp r2, r3
6a: d106 bne.n 7a <ISR_USART1+0x7a>
6c: 8983 ldrh r3, [r0, #12]
6e: f023 0380 bic.w r3, r3, #128 ; 0x80
72: 041b lsls r3, r3, #16
74: 0c1b lsrs r3, r3, #16
76: 8183 strh r3, [r0, #12]
78: e00d b.n 96 <ISR_USART1+0x96>
7a: f891 3158 ldrb.w r3, [r1, #344] ; 0x158
7e: b2db uxtb r3, r3
80: 18ca adds r2, r1, r3
82: f892 215a ldrb.w r2, [r2, #346] ; 0x15a
86: 3301 adds r3, #1
88: f003 033f and.w r3, r3, #63 ; 0x3f
8c: f881 3158 strb.w r3, [r1, #344] ; 0x158
90: b253 sxtb r3, r2
92: b29b uxth r3, r3
94: 8083 strh r3, [r0, #4]
96: f89d 3007 ldrb.w r3, [sp, #7]
9a: b123 cbz r3, a6 <ISR_USART1+0xa6>
9c: 4a06 ldr r2, [pc, #24] ; (b8 <ISR_USART1+0xb8>)
9e: 6853 ldr r3, [r2, #4]
a0: f043 5380 orr.w r3, r3, #268435456 ; 0x10000000
a4: 6053 str r3, [r2, #4]
a6: b002 add sp, #8
a8: e8bd 4001 ldmia.w sp!, {r0, lr}
ac: 4685 mov sp, r0
ae: 4770 bx lr
b0: 40013800 andmi r3, r1, r0, lsl #16
b4: 00000000 andeq r0, r0, r0
b4: R_ARM_ABS32 .bss
b8: e000ed00 and lr, r0, r0, lsl #26
Disassembly of section .text.ISR_USART2:
00000000 <ISR_USART2>:
0: 4668 mov r0, sp
2: f020 0107 bic.w r1, r0, #7
6: 468d mov sp, r1
8: b501 push {r0, lr}
a: 4b2d ldr r3, [pc, #180] ; (c0 <ISR_USART2+0xc0>)
c: b082 sub sp, #8
e: 881a ldrh r2, [r3, #0]
10: 2100 movs r1, #0
12: 0690 lsls r0, r2, #26
14: f88d 1007 strb.w r1, [sp, #7]
18: d524 bpl.n 64 <ISR_USART2+0x64>
1a: 8898 ldrh r0, [r3, #4]
1c: 4b29 ldr r3, [pc, #164] ; (c4 <ISR_USART2+0xc4>)
1e: b2c0 uxtb r0, r0
20: f893 2020 ldrb.w r2, [r3, #32]
24: 0752 lsls r2, r2, #29
26: d503 bpl.n 30 <ISR_USART2+0x30>
28: b240 sxtb r0, r0
2a: f7ff fffe bl 0 <ISR_USART2>
2a: R_ARM_THM_CALL lcdButtonProcess
2e: e019 b.n 64 <ISR_USART2+0x64>
30: f893 208b ldrb.w r2, [r3, #139] ; 0x8b
34: f893 108a ldrb.w r1, [r3, #138] ; 0x8a
38: 3201 adds r2, #1
3a: f002 023f and.w r2, r2, #63 ; 0x3f
3e: 428a cmp r2, r1
40: d00a beq.n 58 <ISR_USART2+0x58>
42: f893 208b ldrb.w r2, [r3, #139] ; 0x8b
46: b2d2 uxtb r2, r2
48: 1899 adds r1, r3, r2
4a: 3201 adds r2, #1
4c: f002 023f and.w r2, r2, #63 ; 0x3f
50: f881 008c strb.w r0, [r1, #140] ; 0x8c
54: f883 208b strb.w r2, [r3, #139] ; 0x8b
58: f8d3 00cc ldr.w r0, [r3, #204] ; 0xcc
5c: f10d 0107 add.w r1, sp, #7
60: f7ff fffe bl 0 <semaphoreGiveISR>
60: R_ARM_THM_CALL semaphoreGiveISR
64: 4816 ldr r0, [pc, #88] ; (c0 <ISR_USART2+0xc0>)
66: 8803 ldrh r3, [r0, #0]
68: 061b lsls r3, r3, #24
6a: d51b bpl.n a4 <ISR_USART2+0xa4>
6c: 4915 ldr r1, [pc, #84] ; (c4 <ISR_USART2+0xc4>)
6e: f891 2048 ldrb.w r2, [r1, #72] ; 0x48
72: f891 3049 ldrb.w r3, [r1, #73] ; 0x49
76: 429a cmp r2, r3
78: d106 bne.n 88 <ISR_USART2+0x88>
7a: 8983 ldrh r3, [r0, #12]
7c: f023 0380 bic.w r3, r3, #128 ; 0x80
80: 041b lsls r3, r3, #16
82: 0c1b lsrs r3, r3, #16
84: 8183 strh r3, [r0, #12]
86: e00d b.n a4 <ISR_USART2+0xa4>
88: f891 3048 ldrb.w r3, [r1, #72] ; 0x48
8c: b2db uxtb r3, r3
8e: 18ca adds r2, r1, r3
90: f892 204a ldrb.w r2, [r2, #74] ; 0x4a
94: 3301 adds r3, #1
96: f003 033f and.w r3, r3, #63 ; 0x3f
9a: f881 3048 strb.w r3, [r1, #72] ; 0x48
9e: b253 sxtb r3, r2
a0: b29b uxth r3, r3
a2: 8083 strh r3, [r0, #4]
a4: f89d 3007 ldrb.w r3, [sp, #7]
a8: b123 cbz r3, b4 <ISR_USART2+0xb4>
aa: 4a07 ldr r2, [pc, #28] ; (c8 <ISR_USART2+0xc8>)
ac: 6853 ldr r3, [r2, #4]
ae: f043 5380 orr.w r3, r3, #268435456 ; 0x10000000
b2: 6053 str r3, [r2, #4]
b4: b002 add sp, #8
b6: e8bd 4001 ldmia.w sp!, {r0, lr}
ba: 4685 mov sp, r0
bc: 4770 bx lr
be: bf00 nop
c0: 40004400 andmi r4, r0, r0, lsl #8
c4: 00000000 andeq r0, r0, r0
c4: R_ARM_ABS32 .bss
c8: e000ed00 and lr, r0, r0, lsl #26
Disassembly of section .text.ISR_USART3:
00000000 <ISR_USART3>:
0: 4668 mov r0, sp
2: f020 0107 bic.w r1, r0, #7
6: 468d mov sp, r1
8: b501 push {r0, lr}
a: 2300 movs r3, #0
c: b082 sub sp, #8
e: f88d 3007 strb.w r3, [sp, #7]
12: 4b2b ldr r3, [pc, #172] ; (c0 <ISR_USART3+0xc0>)
14: 881a ldrh r2, [r3, #0]
16: 0691 lsls r1, r2, #26
18: d525 bpl.n 66 <ISR_USART3+0x66>
1a: 8898 ldrh r0, [r3, #4]
1c: 4b29 ldr r3, [pc, #164] ; (c4 <ISR_USART3+0xc4>)
1e: b2c0 uxtb r0, r0
20: f893 2044 ldrb.w r2, [r3, #68] ; 0x44
24: 0752 lsls r2, r2, #29
26: d504 bpl.n 32 <ISR_USART3+0x32>
28: b240 sxtb r0, r0
2a: 2101 movs r1, #1
2c: f7ff fffe bl 0 <ISR_USART3>
2c: R_ARM_THM_CALL lcdButtonProcess
30: e019 b.n 66 <ISR_USART3+0x66>
32: f893 2113 ldrb.w r2, [r3, #275] ; 0x113
36: f893 1112 ldrb.w r1, [r3, #274] ; 0x112
3a: 3201 adds r2, #1
3c: f002 023f and.w r2, r2, #63 ; 0x3f
40: 428a cmp r2, r1
42: d00a beq.n 5a <ISR_USART3+0x5a>
44: f893 2113 ldrb.w r2, [r3, #275] ; 0x113
48: b2d2 uxtb r2, r2
4a: 1899 adds r1, r3, r2
4c: 3201 adds r2, #1
4e: f002 023f and.w r2, r2, #63 ; 0x3f
52: f881 0114 strb.w r0, [r1, #276] ; 0x114
56: f883 2113 strb.w r2, [r3, #275] ; 0x113
5a: f8d3 0154 ldr.w r0, [r3, #340] ; 0x154
5e: f10d 0107 add.w r1, sp, #7
62: f7ff fffe bl 0 <semaphoreGiveISR>
62: R_ARM_THM_CALL semaphoreGiveISR
66: 4816 ldr r0, [pc, #88] ; (c0 <ISR_USART3+0xc0>)
68: 8803 ldrh r3, [r0, #0]
6a: 061b lsls r3, r3, #24
6c: d51b bpl.n a6 <ISR_USART3+0xa6>
6e: 4915 ldr r1, [pc, #84] ; (c4 <ISR_USART3+0xc4>)
70: f891 20d0 ldrb.w r2, [r1, #208] ; 0xd0
74: f891 30d1 ldrb.w r3, [r1, #209] ; 0xd1
78: 429a cmp r2, r3
7a: d106 bne.n 8a <ISR_USART3+0x8a>
7c: 8983 ldrh r3, [r0, #12]
7e: f023 0380 bic.w r3, r3, #128 ; 0x80
82: 041b lsls r3, r3, #16
84: 0c1b lsrs r3, r3, #16
86: 8183 strh r3, [r0, #12]
88: e00d b.n a6 <ISR_USART3+0xa6>
8a: f891 30d0 ldrb.w r3, [r1, #208] ; 0xd0
8e: b2db uxtb r3, r3
90: 18ca adds r2, r1, r3
92: f892 20d2 ldrb.w r2, [r2, #210] ; 0xd2
96: 3301 adds r3, #1
98: f003 033f and.w r3, r3, #63 ; 0x3f
9c: f881 30d0 strb.w r3, [r1, #208] ; 0xd0
a0: b253 sxtb r3, r2
a2: b29b uxth r3, r3
a4: 8083 strh r3, [r0, #4]
a6: f89d 3007 ldrb.w r3, [sp, #7]
aa: b123 cbz r3, b6 <ISR_USART3+0xb6>
ac: 4a06 ldr r2, [pc, #24] ; (c8 <ISR_USART3+0xc8>)
ae: 6853 ldr r3, [r2, #4]
b0: f043 5380 orr.w r3, r3, #268435456 ; 0x10000000
b4: 6053 str r3, [r2, #4]
b6: b002 add sp, #8
b8: e8bd 4001 ldmia.w sp!, {r0, lr}
bc: 4685 mov sp, r0
be: 4770 bx lr
c0: 40004800 andmi r4, r0, r0, lsl #16
c4: 00000000 andeq r0, r0, r0
c4: R_ARM_ABS32 .bss
c8: e000ed00 and lr, r0, r0, lsl #26
Disassembly of section .text.lcdReadButtons:
00000000 <lcdReadButtons>:
0: 1e43 subs r3, r0, #1
2: 2b01 cmp r3, #1
4: d80e bhi.n 24 <lcdReadButtons+0x24>
6: 4a08 ldr r2, [pc, #32] ; (28 <lcdReadButtons+0x28>)
8: 2024 movs r0, #36 ; 0x24
a: fb00 2003 mla r0, r0, r3, r2
e: f890 3020 ldrb.w r3, [r0, #32]
12: f100 0220 add.w r2, r0, #32
16: f003 0304 and.w r3, r3, #4
1a: f003 00ff and.w r0, r3, #255 ; 0xff
1e: b113 cbz r3, 26 <lcdReadButtons+0x26>
20: 7850 ldrb r0, [r2, #1]
22: 4770 bx lr
24: 2000 movs r0, #0
26: 4770 bx lr
28: 00000000 andeq r0, r0, r0
28: R_ARM_ABS32 .bss
Disassembly of section .text.lcdSetBacklight:
00000000 <lcdSetBacklight>:
0: 3801 subs r0, #1
2: 2801 cmp r0, #1
4: d80d bhi.n 22 <lcdSetBacklight+0x22>
6: 4b07 ldr r3, [pc, #28] ; (24 <lcdSetBacklight+0x24>)
8: 2224 movs r2, #36 ; 0x24
a: fb02 3000 mla r0, r2, r0, r3
e: f890 3020 ldrb.w r3, [r0, #32]
12: b111 cbz r1, 1a <lcdSetBacklight+0x1a>
14: f043 0302 orr.w r3, r3, #2
18: e001 b.n 1e <lcdSetBacklight+0x1e>
1a: f023 0302 bic.w r3, r3, #2
1e: f880 3020 strb.w r3, [r0, #32]
22: 4770 bx lr
24: 00000000 andeq r0, r0, r0
24: R_ARM_ABS32 .bss
Disassembly of section .text._lcdDump:
00000000 <_lcdDump>:
0: 4a28 ldr r2, [pc, #160] ; (a4 <_lcdDump+0xa4>)
2: e92d 41f0 stmdb sp!, {r4, r5, r6, r7, r8, lr}
6: 2324 movs r3, #36 ; 0x24
8: fb03 2300 mla r3, r3, r0, r2
c: f893 4020 ldrb.w r4, [r3, #32]
10: 0761 lsls r1, r4, #29
12: d544 bpl.n 9e <_lcdDump+0x9e>
14: 461e mov r6, r3
16: 07e2 lsls r2, r4, #31
18: bf4c ite mi
1a: f024 0201 bicmi.w r2, r4, #1
1e: f044 0301 orrpl.w r3, r4, #1
22: f100 0501 add.w r5, r0, #1
26: bf4c ite mi
28: f883 2020 strbmi.w r2, [r3, #32]
2c: f886 3020 strbpl.w r3, [r6, #32]
30: 4629 mov r1, r5
32: f04f 00aa mov.w r0, #170 ; 0xaa
36: bf48 it mi
38: 3610 addmi r6, #16
3a: f7ff fffe bl 0 <_lcdDump>
3a: R_ARM_THM_CALL fputc
3e: 4629 mov r1, r5
40: 2055 movs r0, #85 ; 0x55
42: f7ff fffe bl 0 <_lcdDump>
42: R_ARM_THM_CALL fputc
46: 4629 mov r1, r5
48: 201e movs r0, #30
4a: f7ff fffe bl 0 <_lcdDump>
4a: R_ARM_THM_CALL fputc
4e: f004 0403 and.w r4, r4, #3
52: 4629 mov r1, r5
54: 2012 movs r0, #18
56: f7ff fffe bl 0 <_lcdDump>
56: R_ARM_THM_CALL fputc
5a: 4620 mov r0, r4
5c: 4629 mov r1, r5
5e: f7ff fffe bl 0 <_lcdDump>
5e: R_ARM_THM_CALL fputc
62: 2710 movs r7, #16
64: f896 8000 ldrb.w r8, [r6]
68: f1b8 0f00 cmp.w r8, #0
6c: d008 beq.n 80 <_lcdDump+0x80>
6e: fa4f f088 sxtb.w r0, r8
72: 4629 mov r1, r5
74: 4444 add r4, r8
76: f7ff fffe bl 0 <_lcdDump>
76: R_ARM_THM_CALL fputc
7a: b2e4 uxtb r4, r4
7c: 3601 adds r6, #1
7e: e005 b.n 8c <_lcdDump+0x8c>
80: 2020 movs r0, #32
82: 4629 mov r1, r5
84: f7ff fffe bl 0 <_lcdDump>
84: R_ARM_THM_CALL fputc
88: 3420 adds r4, #32
8a: b2e4 uxtb r4, r4
8c: 3f01 subs r7, #1
8e: d1e9 bne.n 64 <_lcdDump+0x64>
90: 4260 negs r0, r4
92: 4629 mov r1, r5
94: e8bd 41f0 ldmia.w sp!, {r4, r5, r6, r7, r8, lr}
98: b240 sxtb r0, r0
9a: f7ff bffe b.w 0 <_lcdDump>
9a: R_ARM_THM_JUMP24 fputc
9e: e8bd 81f0 ldmia.w sp!, {r4, r5, r6, r7, r8, pc}
a2: bf00 nop
a4: 00000000 andeq r0, r0, r0
a4: R_ARM_ABS32 .bss
Disassembly of section .text.lcdSetText:
00000000 <lcdSetText>:
0: 1e43 subs r3, r0, #1
2: 2b01 cmp r3, #1
4: b510 push {r4, lr}
6: d815 bhi.n 34 <lcdSetText+0x34>
8: 3901 subs r1, #1
a: b2c9 uxtb r1, r1
c: 2901 cmp r1, #1
e: d811 bhi.n 34 <lcdSetText+0x34>
10: 4809 ldr r0, [pc, #36] ; (38 <lcdSetText+0x38>)
12: 2424 movs r4, #36 ; 0x24
14: fb04 0003 mla r0, r4, r3, r0
18: b101 cbz r1, 1c <lcdSetText+0x1c>
1a: 3010 adds r0, #16
1c: 1c43 adds r3, r0, #1
1e: 3011 adds r0, #17
20: 7811 ldrb r1, [r2, #0]
22: b109 cbz r1, 28 <lcdSetText+0x28>
24: 3201 adds r2, #1
26: e000 b.n 2a <lcdSetText+0x2a>
28: 2120 movs r1, #32
2a: f803 1c01 strb.w r1, [r3, #-1]
2e: 3301 adds r3, #1
30: 4283 cmp r3, r0
32: d1f5 bne.n 20 <lcdSetText+0x20>
34: bd10 pop {r4, pc}
36: bf00 nop
38: 00000000 andeq r0, r0, r0
38: R_ARM_ABS32 .bss
Disassembly of section .text.lcdClear:
00000000 <lcdClear>:
0: b538 push {r3, r4, r5, lr}
2: 4605 mov r5, r0
4: 4c05 ldr r4, [pc, #20] ; (1c <lcdClear+0x1c>)
6: 2101 movs r1, #1
8: 4622 mov r2, r4
a: f7ff fffe bl 0 <lcdClear>
a: R_ARM_THM_CALL lcdSetText
e: 4628 mov r0, r5
10: 4622 mov r2, r4
12: e8bd 4038 ldmia.w sp!, {r3, r4, r5, lr}
16: 2102 movs r1, #2
18: f7ff bffe b.w 0 <lcdClear>
18: R_ARM_THM_JUMP24 lcdSetText
1c: 00000000 andeq r0, r0, r0
1c: R_ARM_ABS32 .rodata.str1.1
Disassembly of section .text.lcdPrint:
00000000 <lcdPrint>:
0: b40c push {r2, r3}
2: b530 push {r4, r5, lr}
4: 4605 mov r5, r0
6: 460c mov r4, r1
8: b087 sub sp, #28
a: ab0a add r3, sp, #40 ; 0x28
c: f853 2b04 ldr.w r2, [r3], #4
10: a801 add r0, sp, #4
12: 2111 movs r1, #17
14: 9300 str r3, [sp, #0]
16: f7ff fffe bl 0 <vsnprintf>
16: R_ARM_THM_CALL vsnprintf
1a: 2300 movs r3, #0
1c: 4628 mov r0, r5
1e: 4621 mov r1, r4
20: aa01 add r2, sp, #4
22: f88d 3014 strb.w r3, [sp, #20]
26: f7ff fffe bl 0 <lcdPrint>
26: R_ARM_THM_CALL lcdSetText
2a: b007 add sp, #28
2c: e8bd 4030 ldmia.w sp!, {r4, r5, lr}
30: b002 add sp, #8
32: 4770 bx lr
Disassembly of section .text.usartBufferCount:
00000000 <usartBufferCount>:
0: b510 push {r4, lr}
2: b672 cpsid i
4: 4909 ldr r1, [pc, #36] ; (2c <usartBufferCount+0x2c>)
6: 680b ldr r3, [r1, #0]
8: 3301 adds r3, #1
a: 600b str r3, [r1, #0]
c: f890 4042 ldrb.w r4, [r0, #66] ; 0x42
10: f890 3043 ldrb.w r3, [r0, #67] ; 0x43
14: 680a ldr r2, [r1, #0]
16: b2e4 uxtb r4, r4
18: 3a01 subs r2, #1
1a: b2db uxtb r3, r3
1c: 600a str r2, [r1, #0]
1e: b902 cbnz r2, 22 <usartBufferCount+0x22>
20: b662 cpsie i
22: 1b18 subs r0, r3, r4
24: f000 003f and.w r0, r0, #63 ; 0x3f
28: bd10 pop {r4, pc}
2a: bf00 nop
2c: 00000000 andeq r0, r0, r0
2c: R_ARM_ABS32 _criticalNesting
Disassembly of section .text.fcount:
00000000 <fcount>:
0: 1e43 subs r3, r0, #1
2: 2b02 cmp r3, #2
4: d805 bhi.n 12 <fcount+0x12>
6: 4a04 ldr r2, [pc, #16] ; (18 <fcount+0x18>)
8: 2088 movs r0, #136 ; 0x88
a: fb00 2003 mla r0, r0, r3, r2
e: f7ff bffe b.w 0 <fcount>
e: R_ARM_THM_JUMP24 usartBufferCount
12: f7ff bffe b.w 0 <fsLeft>
12: R_ARM_THM_JUMP24 fsLeft
16: bf00 nop
18: 00000048 andeq r0, r0, r8, asr #32
18: R_ARM_ABS32 .bss
Disassembly of section .text.feof:
00000000 <feof>:
0: b508 push {r3, lr}
2: 1e43 subs r3, r0, #1
4: 2b02 cmp r3, #2
6: d903 bls.n 10 <feof+0x10>
8: e8bd 4008 ldmia.w sp!, {r3, lr}
c: f7ff bffe b.w 0 <fsEof>
c: R_ARM_THM_JUMP24 fsEof
10: 4a04 ldr r2, [pc, #16] ; (24 <feof+0x24>)
12: 2088 movs r0, #136 ; 0x88
14: fb00 2003 mla r0, r0, r3, r2
18: f7ff fffe bl 0 <feof>
18: R_ARM_THM_CALL usartBufferCount
1c: fab0 f080 clz r0, r0
20: 0940 lsrs r0, r0, #5
22: bd08 pop {r3, pc}
24: 00000048 andeq r0, r0, r8, asr #32
24: R_ARM_ABS32 .bss
Disassembly of section .text.fgets:
00000000 <fgets>:
0: b5f8 push {r3, r4, r5, r6, r7, lr}
2: 4604 mov r4, r0
4: 4610 mov r0, r2
6: 460f mov r7, r1
8: 4616 mov r6, r2
a: f7ff fffe bl 0 <fgets>
a: R_ARM_THM_CALL feof
e: b990 cbnz r0, 36 <fgets+0x36>
10: 4625 mov r5, r4
12: 1b7b subs r3, r7, r5
14: 4423 add r3, r4
16: 2b01 cmp r3, #1
18: dd09 ble.n 2e <fgets+0x2e>
1a: 4630 mov r0, r6
1c: f7ff fffe bl 0 <fgets>
1c: R_ARM_THM_CALL fgetc
20: 1c43 adds r3, r0, #1
22: d004 beq.n 2e <fgets+0x2e>
24: f805 0b01 strb.w r0, [r5], #1
28: b240 sxtb r0, r0
2a: 280a cmp r0, #10
2c: d1f1 bne.n 12 <fgets+0x12>
2e: 2300 movs r3, #0
30: 702b strb r3, [r5, #0]
32: 4620 mov r0, r4
34: bdf8 pop {r3, r4, r5, r6, r7, pc}
36: 2000 movs r0, #0
38: bdf8 pop {r3, r4, r5, r6, r7, pc}
Disassembly of section .text.usartBufferInit:
00000000 <usartBufferInit>:
0: b538 push {r3, r4, r5, lr}
2: 4c13 ldr r4, [pc, #76] ; (50 <usartBufferInit+0x50>)
4: 2500 movs r5, #0
6: f884 519a strb.w r5, [r4, #410] ; 0x19a
a: f884 519b strb.w r5, [r4, #411] ; 0x19b
e: f884 5158 strb.w r5, [r4, #344] ; 0x158
12: f884 519b strb.w r5, [r4, #411] ; 0x19b
16: f7ff fffe bl 0 <semaphoreCreate>
16: R_ARM_THM_CALL semaphoreCreate
1a: f884 508a strb.w r5, [r4, #138] ; 0x8a
1e: f8c4 01dc str.w r0, [r4, #476] ; 0x1dc
22: f884 508b strb.w r5, [r4, #139] ; 0x8b
26: f884 5048 strb.w r5, [r4, #72] ; 0x48
2a: f884 508b strb.w r5, [r4, #139] ; 0x8b
2e: f7ff fffe bl 0 <semaphoreCreate>
2e: R_ARM_THM_CALL semaphoreCreate
32: f884 5112 strb.w r5, [r4, #274] ; 0x112
36: f8c4 00cc str.w r0, [r4, #204] ; 0xcc
3a: f884 5113 strb.w r5, [r4, #275] ; 0x113
3e: f884 50d0 strb.w r5, [r4, #208] ; 0xd0
42: f884 5113 strb.w r5, [r4, #275] ; 0x113
46: f7ff fffe bl 0 <semaphoreCreate>
46: R_ARM_THM_CALL semaphoreCreate
4a: f8c4 0154 str.w r0, [r4, #340] ; 0x154
4e: bd38 pop {r3, r4, r5, pc}
50: 00000000 andeq r0, r0, r0
50: R_ARM_ABS32 .bss
Disassembly of section .text.usartFlushBuffers:
00000000 <usartFlushBuffers>:
0: b672 cpsid i
2: 4b09 ldr r3, [pc, #36] ; (28 <usartFlushBuffers+0x28>)
4: f893 2048 ldrb.w r2, [r3, #72] ; 0x48
8: b2d2 uxtb r2, r2
a: f883 2049 strb.w r2, [r3, #73] ; 0x49
e: f893 20d0 ldrb.w r2, [r3, #208] ; 0xd0
12: b2d2 uxtb r2, r2
14: f883 20d1 strb.w r2, [r3, #209] ; 0xd1
18: f893 2158 ldrb.w r2, [r3, #344] ; 0x158
1c: b2d2 uxtb r2, r2
1e: f883 2159 strb.w r2, [r3, #345] ; 0x159
22: b662 cpsie i
24: 4770 bx lr
26: bf00 nop
28: 00000000 andeq r0, r0, r0
28: R_ARM_ABS32 .bss
Disassembly of section .text.usartInit:
00000000 <usartInit>:
0: 2801 cmp r0, #1
2: b530 push {r4, r5, lr}
4: d003 beq.n e <usartInit+0xe>
6: 2802 cmp r0, #2
8: d149 bne.n 9e <usartInit+0x9e>
a: 4c25 ldr r4, [pc, #148] ; (a0 <usartInit+0xa0>)
c: e000 b.n 10 <usartInit+0x10>
e: 4c25 ldr r4, [pc, #148] ; (a4 <usartInit+0xa4>)
10: b672 cpsid i
12: 4b25 ldr r3, [pc, #148] ; (a8 <usartInit+0xa8>)
14: 2801 cmp r0, #1
16: 681d ldr r5, [r3, #0]
18: 4618 mov r0, r3
1a: f105 0501 add.w r5, r5, #1
1e: 601d str r5, [r3, #0]
20: f04f 0500 mov.w r5, #0
24: 4b21 ldr r3, [pc, #132] ; (ac <usartInit+0xac>)
26: 81a5 strh r5, [r4, #12]
28: bf0b itete eq
2a: f893 5048 ldrbeq.w r5, [r3, #72] ; 0x48
2e: f893 50d0 ldrbne.w r5, [r3, #208] ; 0xd0
32: b2ed uxtbeq r5, r5
34: b2ed uxtbne r5, r5
36: bf0b itete eq
38: f883 5049 strbeq.w r5, [r3, #73] ; 0x49
3c: f883 50d1 strbne.w r5, [r3, #209] ; 0xd1
40: f893 508a ldrbeq.w r5, [r3, #138] ; 0x8a
44: f893 5112 ldrbne.w r5, [r3, #274] ; 0x112
48: b292 uxth r2, r2
4a: bf0b itete eq
4c: b2ed uxtbeq r5, r5
4e: b2ed uxtbne r5, r5
50: f883 508b strbeq.w r5, [r3, #139] ; 0x8b
54: f883 5113 strbne.w r5, [r3, #275] ; 0x113
58: f402 5340 and.w r3, r2, #12288 ; 0x3000
5c: f402 52b0 and.w r2, r2, #5632 ; 0x1600
60: f442 5200 orr.w r2, r2, #8192 ; 0x2000
64: 8223 strh r3, [r4, #16]
66: f042 022c orr.w r2, r2, #44 ; 0x2c
6a: 2300 movs r3, #0
6c: 81a2 strh r2, [r4, #12]
6e: 82a3 strh r3, [r4, #20]
70: 4b0f ldr r3, [pc, #60] ; (b0 <usartInit+0xb0>)
72: fbb3 f1f1 udiv r1, r3, r1
76: 2364 movs r3, #100 ; 0x64
78: fbb1 f2f3 udiv r2, r1, r3
7c: fb03 1112 mls r1, r3, r2, r1
80: 0109 lsls r1, r1, #4
82: 3132 adds r1, #50 ; 0x32
84: fbb1 f3f3 udiv r3, r1, r3
88: f003 030f and.w r3, r3, #15
8c: ea43 1302 orr.w r3, r3, r2, lsl #4
90: b29b uxth r3, r3
92: 8123 strh r3, [r4, #8]
94: 6803 ldr r3, [r0, #0]
96: 3b01 subs r3, #1
98: 6003 str r3, [r0, #0]
9a: b903 cbnz r3, 9e <usartInit+0x9e>
9c: b662 cpsie i
9e: bd30 pop {r4, r5, pc}
a0: 40004800 andmi r4, r0, r0, lsl #16
a4: 40004400 andmi r4, r0, r0, lsl #8
...
a8: R_ARM_ABS32 _criticalNesting
ac: R_ARM_ABS32 .bss
b0: 0d693a40 vstmdbeq r9!, {s7-s70}
Disassembly of section .text.lcdInit:
00000000 <lcdInit>:
0: b510 push {r4, lr}
2: 1e44 subs r4, r0, #1
4: 2c01 cmp r4, #1
6: d810 bhi.n 2a <lcdInit+0x2a>
8: f44f 4196 mov.w r1, #19200 ; 0x4b00
c: 2200 movs r2, #0
e: f7ff fffe bl 0 <lcdInit>
e: R_ARM_THM_CALL usartInit
12: 4b06 ldr r3, [pc, #24] ; (2c <lcdInit+0x2c>)
14: 2224 movs r2, #36 ; 0x24
16: fb04 3302 mla r3, r4, r2, r3
1a: 2104 movs r1, #4
1c: f103 0220 add.w r2, r3, #32
20: f883 1020 strb.w r1, [r3, #32]
24: 2300 movs r3, #0
26: 8053 strh r3, [r2, #2]
28: 7053 strb r3, [r2, #1]
2a: bd10 pop {r4, pc}
2c: 00000000 andeq r0, r0, r0
2c: R_ARM_ABS32 .bss
Disassembly of section .text.usartShutdown:
00000000 <usartShutdown>:
0: 2801 cmp r0, #1
2: d102 bne.n a <usartShutdown+0xa>
4: 2200 movs r2, #0
6: 4b04 ldr r3, [pc, #16] ; (18 <usartShutdown+0x18>)
8: e003 b.n 12 <usartShutdown+0x12>
a: 2802 cmp r0, #2
c: d102 bne.n 14 <usartShutdown+0x14>
e: 4b03 ldr r3, [pc, #12] ; (1c <usartShutdown+0x1c>)
10: 2200 movs r2, #0
12: 819a strh r2, [r3, #12]
14: 4770 bx lr
16: bf00 nop
18: 40004400 andmi r4, r0, r0, lsl #8
1c: 40004800 andmi r4, r0, r0, lsl #16
Disassembly of section .text.lcdShutdown:
00000000 <lcdShutdown>:
0: b510 push {r4, lr}
2: 1e44 subs r4, r0, #1
4: 2c01 cmp r4, #1
6: d808 bhi.n 1a <lcdShutdown+0x1a>
8: f7ff fffe bl 0 <lcdShutdown>
8: R_ARM_THM_CALL usartShutdown
c: 4b03 ldr r3, [pc, #12] ; (1c <lcdShutdown+0x1c>)
e: 2224 movs r2, #36 ; 0x24
10: fb04 3302 mla r3, r4, r2, r3
14: 2200 movs r2, #0
16: f883 2020 strb.w r2, [r3, #32]
1a: bd10 pop {r4, pc}
1c: 00000000 andeq r0, r0, r0
1c: R_ARM_ABS32 .bss
Disassembly of section .rodata.str1.1:
00000000 <.rodata.str1.1>:
...
Disassembly of section .debug_info:
00000000 <.debug_info>:
0: 00001580 andeq r1, r0, r0, lsl #11
4: 00000004 andeq r0, r0, r4
6: R_ARM_ABS32 .debug_abbrev
8: 01040000 mrseq r0, (UNDEF: 4)
c: 00000432 andeq r0, r0, r2, lsr r4
c: R_ARM_ABS32 .debug_str
10: 00059601 andeq r9, r5, r1, lsl #12
11: R_ARM_ABS32 .debug_str
14: 0001d500 andeq sp, r1, r0, lsl #10
15: R_ARM_ABS32 .debug_str
18: 00016000 andeq r6, r1, r0
19: R_ARM_ABS32 .debug_ranges
...
21: R_ARM_ABS32 .debug_line
24: 07040200 streq r0, [r4, -r0, lsl #4]
28: 0000003c andeq r0, r0, ip, lsr r0
28: R_ARM_ABS32 .debug_str
2c: 69050403 stmdbvs r5, {r0, r1, sl}
30: 0400746e streq r7, [r0], #-1134 ; 0xfffffb92
34: 00000189 andeq r0, r0, r9, lsl #3
34: R_ARM_ABS32 .debug_str
38: 0025d404 eoreq sp, r5, r4, lsl #8
3c: 01020000 mrseq r0, (UNDEF: 2)
40: 00053706 andeq r3, r5, r6, lsl #14
41: R_ARM_ABS32 .debug_str
44: 03790400 cmneq r9, #0, 8
46: R_ARM_ABS32 .debug_str
48: 1d050000 stcne 0, cr0, [r5, #-0]
4c: 00000050 andeq r0, r0, r0, asr r0
50: ef080102 svc 0x00080102
53: R_ARM_ABS32 .debug_str
54: 02000003 andeq r0, r0, #3
58: 03490502 movteq r0, #38146 ; 0x9502
5a: R_ARM_ABS32 .debug_str
5c: 17040000 strne r0, [r4, -r0]
5f: R_ARM_ABS32 .debug_str
60: 05000001 streq r0, [r0, #-1]
64: 0000692b andeq r6, r0, fp, lsr #18
68: 07020200 streq r0, [r2, -r0, lsl #4]
6c: 0000054b andeq r0, r0, fp, asr #10
6c: R_ARM_ABS32 .debug_str
70: 53050402 movwpl r0, #21506 ; 0x5402
73: R_ARM_ABS32 .debug_str
74: 04000003 streq r0, [r0], #-3
78: 00000405 andeq r0, r0, r5, lsl #8
78: R_ARM_ABS32 .debug_str
7c: 00824105 addeq r4, r2, r5, lsl #2
80: 04020000 streq r0, [r2], #-0
84: 0003bd07 andeq fp, r3, r7, lsl #26
85: R_ARM_ABS32 .debug_str
88: 05080200 streq r0, [r8, #-512] ; 0xfffffe00
8c: 0000026f andeq r0, r0, pc, ror #4
8c: R_ARM_ABS32 .debug_str
90: ef070802 svc 0x00070802
93: R_ARM_ABS32 .debug_str
94: 04000000 streq r0, [r0], #-0
98: 0000022f andeq r0, r0, pc, lsr #4
98: R_ARM_ABS32 .debug_str
9c: 00451406 subeq r1, r5, r6, lsl #8
a0: f1040000 cps #0
a3: R_ARM_ABS32 .debug_str
a4: 06000002 streq r0, [r0], -r2
a8: 00005e1a andeq r5, r0, sl, lsl lr
ac: 00cb0400 sbceq r0, fp, r0, lsl #8
ae: R_ARM_ABS32 .debug_str
b0: 20060000 andcs r0, r6, r0
b4: 00000077 andeq r0, r0, r7, ror r0
b8: 00017a04 andeq r7, r1, r4, lsl #20
b9: R_ARM_ABS32 .debug_str
bc: c3280700 ; <UNDEFINED> instruction: 0xc3280700
c0: 05000000 streq r0, [r0, #-0]
c4: 0000039b muleq r0, fp, r3
c4: R_ARM_ABS32 .debug_str
c8: da000d04 ble 34e0 <usart+0x3498>
cc: 06000000 streq r0, [r0], -r0
d0: 000002a3 andeq r0, r0, r3, lsr #5
d0: R_ARM_ABS32 .debug_str
d4: 000000da ldrdeq r0, [r0], -sl
d8: 04070000 streq r0, [r7], #-0
dc: 00025204 andeq r5, r2, r4, lsl #4
dd: R_ARM_ABS32 .debug_str
e0: b8620700 stmdalt r2!, {r8, r9, sl}^
e4: 04000000 streq r0, [r0], #-0
e8: 00000591 muleq r0, r1, r5
e8: R_ARM_ABS32 .debug_str
ec: 002c2508 eoreq r2, ip, r8, lsl #10
f0: 04020000 streq r0, [r2], #-0
f4: 0003af07 andeq sl, r3, r7, lsl #30
f5: R_ARM_ABS32 .debug_str
f8: ff040800 ; <UNDEFINED> instruction: 0xff040800
fc: 02000000 andeq r0, r0, #0
100: 02090601 andeq r0, r9, #1048576 ; 0x100000
102: R_ARM_ABS32 .debug_str
104: 04080000 streq r0, [r8], #-0
108: 0000010c andeq r0, r0, ip, lsl #2
10c: 0000ff09 andeq pc, r0, r9, lsl #30
110: 17040800 strne r0, [r4, -r0, lsl #16]
114: 0a000001 beq 120 <.debug_info+0x120>
118: 00013b04 andeq r3, r1, r4, lsl #22
119: R_ARM_ABS32 .debug_str
11c: 82770900 rsbshi r0, r7, #0, 18
120: 0b000000 bleq 128 <.debug_info+0x128>
124: 000000ad andeq r0, r0, sp, lsr #1
128: 0000ad0c andeq sl, r0, ip, lsl #26
12c: 00013800 andeq r3, r1, r0, lsl #16
130: 00f20d00 rscseq r0, r2, r0, lsl #26
134: 00030000 andeq r0, r3, r0
138: 0000a20b andeq sl, r0, fp, lsl #4
13c: 03740e00 cmneq r4, #0, 28
140: 023e019b eorseq r0, lr, #-1073741786 ; 0xc0000026
144: 9e0f0000 cdpls 0, 0, cr0, cr15, cr0, {0}
147: R_ARM_ABS32 .debug_str
148: 03000001 movweq r0, #1
14c: 0123019d ; <UNDEFINED> instruction: 0x0123019d
150: 0f000000 svceq 0x00000000
154: 000003b8 ; <UNDEFINED> instruction: 0x000003b8
154: R_ARM_ABS32 .debug_str
158: 23019f03 movwcs r9, #7939 ; 0x1f03
15c: 04000001 streq r0, [r0], #-1
160: 0003960f andeq r9, r3, pc, lsl #12
161: R_ARM_ABS32 .debug_str
164: 01a10300 ; <UNDEFINED> instruction: 0x01a10300
168: 00000123 andeq r0, r0, r3, lsr #2
16c: 02290f08 eoreq r0, r9, #8, 30
16e: R_ARM_ABS32 .debug_str
170: a3030000 movwge r0, #12288 ; 0x3000
174: 00012301 andeq r2, r1, r1, lsl #6
178: 53100c00 tstpl r0, #0, 24
17c: 03005243 movweq r5, #579 ; 0x243
180: 012301a5 smulwbeq r3, r5, r1
184: 10100000 andsne r0, r0, r0
188: 00524343 subseq r4, r2, r3, asr #6
18c: 2301a703 movwcs sl, #5891 ; 0x1703
190: 14000001 strne r0, [r0], #-1
194: 50485310 subpl r5, r8, r0, lsl r3
198: 01a90300 ; <UNDEFINED> instruction: 0x01a90300
19c: 0000024e andeq r0, r0, lr, asr #4
1a0: 031b0f18 tsteq fp, #24, 30 ; 0x60
1a2: R_ARM_ABS32 .debug_str
1a4: ab030000 blge c01ac <usart+0xc0164>
1a8: 00012301 andeq r2, r1, r1, lsl #6
1ac: 890f2400 stmdbhi pc, {sl, sp} ; <UNPREDICTABLE>
1af: R_ARM_ABS32 .debug_str
1b0: 03000002 movweq r0, #2
1b4: 012301ad smulwbeq r3, sp, r1
1b8: 0f280000 svceq 0x00280000
1bc: 000001d0 ldrdeq r0, [r0], -r0 ; <UNPREDICTABLE>
1bc: R_ARM_ABS32 .debug_str
1c0: 2301af03 movwcs sl, #7939 ; 0x1f03
1c4: 2c000001 stccs 0, cr0, [r0], {1}
1c8: 0000490f andeq r4, r0, pc, lsl #18
1c9: R_ARM_ABS32 .debug_str
1cc: 01b10300 ; <UNDEFINED> instruction: 0x01b10300
1d0: 00000123 andeq r0, r0, r3, lsr #2
1d4: 03010f30 movweq r0, #7984 ; 0x1f30
1d6: R_ARM_ABS32 .debug_str
1d8: b3030000 movwlt r0, #12288 ; 0x3000
1dc: 00012301 andeq r2, r1, r1, lsl #6
1e0: 910f3400 tstls pc, r0, lsl #8
1e3: R_ARM_ABS32 .debug_str
1e4: 03000003 movweq r0, #3
// If 0xAA, set count to 1
// If 0x55, set count to 2 if count == 1
// If 0x16, set count to 3 if count == 2
if (value == (char)0xAA)
1e8: 012301b5 ; <UNDEFINED> instruction: 0x012301b5
_taskYield();
}
// lcdButtonProcess - Processes the VEX LCD buttons
static void lcdButtonProcess(char value, uint32_t index) {
uint16_t count = lcd[index].state;
1ec: 0f380000 svceq 0x00380000
// If 0xAA, set count to 1
// If 0x55, set count to 2 if count == 1
// If 0x16, set count to 3 if count == 2
if (value == (char)0xAA)
count = 1;
else if (value == (char)0x55 && count == 1)
1f0: 000001af andeq r0, r0, pc, lsr #3
1f0: R_ARM_ABS32 .debug_str
1f4: 2301b703 movwcs fp, #5891 ; 0x1703
1f8: 3c000001 stccc 0, cr0, [r0], {1}
count = 2;
else if (value == (char)0x16 && count == 2)
1fc: 52465010 subpl r5, r6, #16
200: 01b90300 ; <UNDEFINED> instruction: 0x01b90300
count = 3;
else if (value == (char)0x02 && count == 3)
204: 00000263 andeq r0, r0, r3, ror #4
208: 46441040 strbmi r1, [r4], -r0, asr #32
// Size must be 2
count = 4;
else if (count == 4) {
20c: bb030052 bllt c035c <usart+0xc0314>
lcd[index].buttons = (uint8_t)value;
210: 00012301 andeq r2, r1, r1, lsl #6
214: 41104800 tstmi r0, r0, lsl #16
218: 03005244 movweq r5, #580 ; 0x244
uint16_t count = lcd[index].state;
// If 0xAA, set count to 1
// If 0x55, set count to 2 if count == 1
// If 0x16, set count to 3 if count == 2
if (value == (char)0xAA)
count = 1;
21c: 012301bd ; <UNDEFINED> instruction: 0x012301bd
else if (value == (char)0x55 && count == 1)
count = 2;
220: 0f4c0000 svceq 0x004c0000
else if (value == (char)0x16 && count == 2)
count = 3;
224: 000000d4 ldrdeq r0, [r0], -r4
224: R_ARM_ABS32 .debug_str
else if (value == (char)0x02 && count == 3)
// Size must be 2
count = 4;
228: 6801bf03 stmdavs r1, {r0, r1, r8, r9, sl, fp, ip, sp, pc}
else if (count == 4) {
lcd[index].buttons = (uint8_t)value;
count = 0;
} else
// Ignore the checksum and any noise we pick up
count = 0;
22c: 50000002 andpl r0, r0, r2
lcd[index].state = count;
230: 0005820f andeq r8, r5, pc, lsl #4
231: R_ARM_ABS32 .debug_str
234: 01c10300 biceq r0, r1, r0, lsl #6
238: 0000027d andeq r0, r0, sp, ror r2
return 1;
#endif
}
// fgetc - Read a character from the specified stream
int fgetc(FILE *stream) {
23c: 970c0060 strls r0, [ip, -r0, rrx]
uint32_t snew = (uint32_t)stream - 1;
if (snew < 3) {
240: 4e000000 cdpmi 0, 0, cr0, cr0, cr0, {0}
SerialPort_TypeDef *ser = &usart[snew];
244: 0d000002 stceq 0, cr0, [r0, #-8]
248: 000000f2 strdeq r0, [r0], -r2
// Prototype this
uint32_t usartBufferCount(SerialPort_TypeDef* port);
// Checks to see if the ring buffer is empty (head = tail)
static INLINE uint8_t _isBufferEmpty(volatile RingBuffer_TypeDef* buffer) {
return buffer->head == buffer->tail;
24c: 3e0b000b cdpcc 0, 0, cr0, cr11, cr11, {0}
250: 0c000002 stceq 0, cr0, [r0], {2}
}
// Waits for a byte in the given port's RX buffer
// This does not happen during init, so it is OK to use scheduler functions
static void _waitForByte(SerialPort_TypeDef* port) {
while (_isBufferEmpty(&(port->rx)))
254: 000000ad andeq r0, r0, sp, lsr #1
258: 00000263 andeq r0, r0, r3, ror #4
25c: 0000f20d andeq pc, r0, sp, lsl #4
semaphoreTake(port->readLock, MAX_DELAY);
260: 0b000100 bleq 668 <.debug_info+0x668>
264: 00000253 andeq r0, r0, r3, asr r2
268: 0001280b andeq r2, r1, fp, lsl #16
26c: 00ad0c00 adceq r0, sp, r0, lsl #24
// File system check
return fsRead(stream);
#else
return EOF;
#endif
}
270: 027d0000 rsbseq r0, sp, #0
// Take byte off the tail
return (int)_pullByte(&(ser->rx)) & 0xFF;
}
#ifndef NO_FILESYSTEM
// File system check
return fsRead(stream);
274: f20d0000 vhadd.s8 d0, d13, d0
return ((buffer->tail + 1) & _USART_MAX) == buffer->head;
}
// Removes a byte from the head of the given buffer
static char _pullByte(volatile RingBuffer_TypeDef* buffer) {
uint8_t head = buffer->head; char value;
278: 04000000 streq r0, [r0], #-0
27c: 026d0b00 rsbeq r0, sp, #0, 22
280: dc110000 ldcle 0, cr0, [r1], {-0}
283: R_ARM_ABS32 .debug_str
284: 03000003 movweq r0, #3
value = buffer->buffer[head];
buffer->head = (head + 1) & _USART_MAX;
288: 013d01c2 teqeq sp, r2, asr #3
28c: 1c0e0000 stcne 0, cr0, [lr], {-0}
}
// Removes a byte from the head of the given buffer
static char _pullByte(volatile RingBuffer_TypeDef* buffer) {
uint8_t head = buffer->head; char value;
value = buffer->buffer[head];
290: 4c023003 stcmi 0, cr3, [r2], {3}
// File system check
return fsRead(stream);
#else
return EOF;
#endif
}
294: 10000003 andne r0, r0, r3
298: 03005253 movweq r5, #595 ; 0x253
29c: 01380232 teqeq r8, r2, lsr r2
*ptr = '\0';
return str;
}
// fputc - Write a character to the specified stream
int fputc(int value, FILE *stream) {
2a0: 0f000000 svceq 0x00000000
uint32_t snew = (uint32_t)stream - 1;
if (snew < 3) {
2a4: 00000307 andeq r0, r0, r7, lsl #6
2a4: R_ARM_ABS32 .debug_str
2a8: a2023303 andge r3, r2, #201326592 ; 0xc000000
SerialPort_TypeDef *ser = &usart[snew];
2ac: 02000000 andeq r0, r0, #0
2b0: 00524410 subseq r4, r2, r0, lsl r4
return buffer->head == buffer->tail;
}
// Checks to see if the ring buffer is full (tail + 1 = head)
static INLINE uint8_t _isBufferFull(volatile RingBuffer_TypeDef* buffer) {
return ((buffer->tail + 1) & _USART_MAX) == buffer->head;
2b4: 38023503 stmdacc r2, {r0, r1, r8, sl, ip, sp}
2b8: 04000001 streq r0, [r0], #-1
}
// Waits for space in the given port's TX buffer
// This happens infrequently, so simply sleep-waiting is acceptable
static void _waitForSpace(SerialPort_TypeDef* port) {
while (_isBufferFull(&(port->tx)))
2bc: 0003110f andeq r1, r3, pc, lsl #2
2bd: R_ARM_ABS32 .debug_str
_yield();
2c0: 02360300 eorseq r0, r6, #0, 6
2c4: 000000a2 andeq r0, r0, r2, lsr #1
return value;
}
// Queues a byte onto the tail of the given buffer
static void _queueByte(volatile RingBuffer_TypeDef* buffer, char value) {
uint8_t tail = buffer->tail;
2c8: 52421006 subpl r1, r2, #6
2cc: 38030052 stmdacc r3, {r1, r4, r6}
2d0: 00013802 andeq r3, r1, r2, lsl #16
2d4: 870f0800 strhi r0, [pc, -r0, lsl #16]
2d7: R_ARM_ABS32 .debug_str
buffer->buffer[tail] = value;
2d8: 03000005 movweq r0, #5
uint32_t snew = (uint32_t)stream - 1;
if (snew < 3) {
SerialPort_TypeDef *ser = &usart[snew];
_waitForSpace(ser);
// Jam a byte onto the head
_queueByte(&(ser->tx), (char)value);
2dc: 00a20239 adceq r0, r2, r9, lsr r2
// Queues a byte onto the tail of the given buffer
static void _queueByte(volatile RingBuffer_TypeDef* buffer, char value) {
uint8_t tail = buffer->tail;
buffer->buffer[tail] = value;
buffer->tail = (tail + 1) & _USART_MAX;
2e0: 100a0000 andne r0, sl, r0
}
// Queues a byte onto the tail of the given buffer
static void _queueByte(volatile RingBuffer_TypeDef* buffer, char value) {
uint8_t tail = buffer->tail;
buffer->buffer[tail] = value;
2e4: 00315243 eorseq r5, r1, r3, asr #4
if (snew < 3) {
SerialPort_TypeDef *ser = &usart[snew];
_waitForSpace(ser);
// Jam a byte onto the head
_queueByte(&(ser->tx), (char)value);
if (snew == 0)
2e8: 38023b03 stmdacc r2, {r0, r1, r8, r9, fp, ip, sp}
// Enable USART2 TXE interrupts
USART2->CR1 |= USART_CR1_TXEIE;
2ec: 0c000001 stceq 0, cr0, [r0], {1}
else if (snew == 1)
// Enable USART3 TXE interrupts
USART3->CR1 |= USART_CR1_TXEIE;
2f0: 0003210f andeq r2, r3, pc, lsl #2
2f1: R_ARM_ABS32 .debug_str
else if (snew == 2)
// Enable USART1 TXE interrupts
USART1->CR1 |= USART_CR1_TXEIE;
2f4: 023c0300 eorseq r0, ip, #0, 6
else
// File system check
return fsWrite(stream, value);
#endif
return value;
}
2f8: 000000a2 andeq r0, r0, r2, lsr #1
else if (snew == 1)
// Enable USART3 TXE interrupts
USART3->CR1 |= USART_CR1_TXEIE;
else if (snew == 2)
// Enable USART1 TXE interrupts
USART1->CR1 |= USART_CR1_TXEIE;
2fc: 5243100e subpl r1, r3, #14
300: 3e030032 mcrcc 0, 0, r0, cr3, cr2, {1}
}
#ifndef NO_FILESYSTEM
else
// File system check
return fsWrite(stream, value);
304: 00013802 andeq r3, r1, r2, lsl #16
#endif
return value;
}
308: 2b0f1000 blcs 3c4008 <usart+0x3c3fc0>
30b: R_ARM_ABS32 .debug_str
USART1->CR1 |= USART_CR1_TXEIE;
}
#ifndef NO_FILESYSTEM
else
// File system check
return fsWrite(stream, value);
30c: 03000003 movweq r0, #3
310: 00a2023f adceq r0, r2, pc, lsr r2
314: 10120000 andsne r0, r2, r0
318: 00335243 eorseq r5, r3, r3, asr #4
31c: 38024103 stmdacc r2, {r0, r1, r8, lr}
320: 14000001 strne r0, [r0], #-1
#endif
return value;
}
// fread - Read data from stream
size_t fread(void *ptr, size_t size, size_t count, FILE *stream) {
324: 0003350f andeq r3, r3, pc, lsl #10
325: R_ARM_ABS32 .debug_str
328: 02420300 subeq r0, r2, #0, 6
char *memory = (char *)ptr;
size_t write = 0; int read;
for (uint32_t i = 0; i < (size * count); i++)
32c: 000000a2 andeq r0, r0, r2, lsr #1
330: 00ae0f16 adceq r0, lr, r6, lsl pc
332: R_ARM_ABS32 .debug_str
// Write as many as we can, break if we fail
if ((read = fgetc(stream)) != EOF) {
334: 44030000 strmi r0, [r3], #-0
338: 00013802 andeq r3, r1, r2, lsl #16
33c: 3f0f1800 svccc 0x000f1800
33f: R_ARM_ABS32 .debug_str
340: 03000003 movweq r0, #3
*memory++ = (char)read;
write++;
344: 00a20245 adceq r0, r2, r5, asr #4
} else
break;
return write;
}
348: 001a0000 andseq r0, sl, r0
// fwrite - Write data to stream
size_t fwrite(const void *ptr, size_t size, size_t count, FILE *stream) {
34c: 0001b411 andeq fp, r1, r1, lsl r4
34d: R_ARM_ABS32 .debug_str
350: 02460300 subeq r0, r6, #0, 6
const char *memory = (const char *)ptr;
size_t write = 0;
for (uint32_t i = 0; i < (size * count); i++)
354: 0000028e andeq r0, r0, lr, lsl #5
358: 00057504 andeq r7, r5, r4, lsl #10
359: R_ARM_ABS32 .debug_str
// Write as many as we can, break if we fail
if (fputc((int)(*memory++), stream) != EOF)
35c: da3b0a00 ble ec2b64 <usart+0xec2b1c>
360: 04000000 streq r0, [r0], #-0
364: 000002c3 andeq r0, r0, r3, asr #5
364: R_ARM_ABS32 .debug_str
368: 0358360b cmpeq r8, #11534336 ; 0xb00000
write++;
36c: 42120000 andsmi r0, r2, #0
else
break;
return write;
}
370: 039b2401 orrseq r2, fp, #16777216 ; 0x1000000
// getchar - Gets a character from the serial PC communication buffer; blocks until read
int getchar() {
return fgetc(stdin);
374: 4e130000 cdpmi 0, 1, cr0, cr3, cr0, {0}
377: R_ARM_ABS32 .debug_str
378: 01000000 mrseq r0, (UNDEF: 0)
}
// putchar - Write a character to the serial PC communication buffer
int putchar(int value) {
return fputc(value, stdout);
37c: 00009725 andeq r9, r0, r5, lsr #14
}
// ISR_USART1 - Buffered character I/O handler for debug communications
void ISR_USART1() {
380: f0130000 ; <UNDEFINED> instruction: 0xf0130000
383: R_ARM_ABS32 .debug_str
384: 01000004 tsteq r0, r4
388: 00009726 andeq r9, r0, r6, lsr #14
38c: 2b130100 blcs 4c0408 <usart+0x4c03c0>
38f: R_ARM_ABS32 .debug_str
char value;
bool cs = false;
390: 01000000 mrseq r0, (UNDEF: 0)
SerialPort_TypeDef *ser = &usart[2];
if (USART1->SR & USART_SR_RXNE) {
394: 00039b27 andeq r9, r3, r7, lsr #22
398: 0c000200 sfmeq f0, 4, [r0], {-0}
return buffer->head == buffer->tail;
}
// Checks to see if the ring buffer is full (tail + 1 = head)
static INLINE uint8_t _isBufferFull(volatile RingBuffer_TypeDef* buffer) {
return ((buffer->tail + 1) & _USART_MAX) == buffer->head;
39c: 000000ff strdeq r0, [r0], -pc ; <UNPREDICTABLE>
3a0: 000003ab andeq r0, r0, fp, lsr #7
3a4: 0000f20d andeq pc, r0, sp, lsl #4
3a8: 04003f00 streq r3, [r0], #-3840 ; 0xfffff100
3ac: 00000072 andeq r0, r0, r2, ror r0
3ac: R_ARM_ABS32 .debug_str
SerialPort_TypeDef *ser = &usart[2];
if (USART1->SR & USART_SR_RXNE) {
// Read to clear the flag
value = (char)USART1->DR;
// Buffer it up, if it's not full to the brim
if (!_isBufferFull(&(ser->rx)))
3b0: 036e2801 cmneq lr, #65536 ; 0x10000
return value;
}
// Queues a byte onto the tail of the given buffer
static void _queueByte(volatile RingBuffer_TypeDef* buffer, char value) {
uint8_t tail = buffer->tail;
3b4: 88120000 ldmdahi r2, {} ; <UNPREDICTABLE>
3b8: 03e12a01 mvneq r2, #4096 ; 0x1000
buffer->buffer[tail] = value;
buffer->tail = (tail + 1) & _USART_MAX;
3bc: 74140000 ldrvc r0, [r4], #-0
3c0: 2b010078 blcs 405a8 <usart+0x40560>
}
// Queues a byte onto the tail of the given buffer
static void _queueByte(volatile RingBuffer_TypeDef* buffer, char value) {
uint8_t tail = buffer->tail;
buffer->buffer[tail] = value;
3c4: 000003e1 andeq r0, r0, r1, ror #7
buffer->tail = (tail + 1) & _USART_MAX;
3c8: 78721400 ldmdavc r2!, {sl, ip}^
value = (char)USART1->DR;
// Buffer it up, if it's not full to the brim
if (!_isBufferFull(&(ser->rx)))
_queueByte(&(ser->rx), value);
// Notify any receivers
semaphoreGiveISR(ser->readLock, &cs);
3cc: e12c0100 ; <UNDEFINED> instruction: 0xe12c0100
3d0: 42000003 andmi r0, r0, #3
3d4: 00026613 andeq r6, r2, r3, lsl r6
3d5: R_ARM_ABS32 .debug_str
}
if (USART1->SR & USART_SR_TXE) {
3d8: 632d0100 ; <UNDEFINED> instruction: 0x632d0100
3dc: 84000003 strhi r0, [r0], #-3
// Prototype this
uint32_t usartBufferCount(SerialPort_TypeDef* port);
// Checks to see if the ring buffer is empty (head = tail)
static INLINE uint8_t _isBufferEmpty(volatile RingBuffer_TypeDef* buffer) {
return buffer->head == buffer->tail;
3e0: 03ab0b00 ; <UNDEFINED> instruction: 0x03ab0b00
3e4: 9b040000 blls 100008 <usart+0xfffc0>
3e7: R_ARM_ABS32 .debug_str
_queueByte(&(ser->rx), value);
// Notify any receivers
semaphoreGiveISR(ser->readLock, &cs);
}
if (USART1->SR & USART_SR_TXE) {
if (_isBufferEmpty(&(ser->tx)))
3e8: 01000000 mrseq r0, (UNDEF: 0)
// Nothing to send, disable interrupt
USART1->CR1 &= ~USART_CR1_TXEIE;
3ec: 0003b62e andeq fp, r3, lr, lsr #12
3f0: 01241200 ; <UNDEFINED> instruction: 0x01241200
3f4: 00042a30 andeq r2, r4, r0, lsr sl
3f8: 00b81300 adcseq r1, r8, r0, lsl #6
3fa: R_ARM_ABS32 .debug_str
return ((buffer->tail + 1) & _USART_MAX) == buffer->head;
}
// Removes a byte from the head of the given buffer
static char _pullByte(volatile RingBuffer_TypeDef* buffer) {
uint8_t head = buffer->head; char value;
3fc: 32010000 andcc r0, r1, #0
value = buffer->buffer[head];
400: 0000042a andeq r0, r0, sl, lsr #8
404: 00251300 eoreq r1, r5, r0, lsl #6
406: R_ARM_ABS32 .debug_str
buffer->head = (head + 1) & _USART_MAX;
408: 34010000 strcc r0, [r1], #-0
40c: 00000097 muleq r0, r7, r0
if (_isBufferEmpty(&(ser->tx)))
// Nothing to send, disable interrupt
USART1->CR1 &= ~USART_CR1_TXEIE;
else {
value = _pullByte(&(ser->tx));
USART1->DR = value;
410: 03cf1320 biceq r1, pc, #32, 6 ; 0x80000000
412: R_ARM_ABS32 .debug_str
414: 36010000 strcc r0, [r1], -r0
}
}
if (cs)
418: 00000097 muleq r0, r7, r0
*/
bool _taskClearEvent(OSList *eventList);
static INLINE void _taskYield() {
/* Set a PendSV to request a context switch. */
SCB->ICSR |= SCB_ICSR_PENDSV;
41c: 04fa1321 ldrbteq r1, [sl], #801 ; 0x321
41e: R_ARM_ABS32 .debug_str
420: 38010000 stmdacc r1, {} ; <UNPREDICTABLE>
424: 000000a2 andeq r0, r0, r2, lsr #1
_taskYield();
}
428: ff0c0022 ; <UNDEFINED> instruction: 0xff0c0022
42c: 3a000000 bcc 434 <.debug_info+0x434>
430: 0d000004 stceq 0, cr0, [r0, #-16]
434: 000000f2 strdeq r0, [r0], -r2
438: cd04001f stcgt 0, cr0, [r4, #-124] ; 0xffffff84
43b: R_ARM_ABS32 .debug_str
count = 0;
lcd[index].state = count;
}
// ISR_USART2 - Buffered character I/O handler for UART port 1
void ISR_USART2() {
43c: 01000002 tsteq r0, r2
440: 0003f139 andeq pc, r3, r9, lsr r1 ; <UNPREDICTABLE>
444: 04e11500 strbteq r1, [r1], #1280 ; 0x500
446: R_ARM_ABS32 .debug_str
448: 46010000 strmi r0, [r1], -r0
char value;
bool cs = false;
44c: 00000097 muleq r0, r7, r0
450: 00046103 andeq r6, r4, r3, lsl #2
SerialPort_TypeDef *ser = &usart[0];
if (USART2->SR & USART_SR_RXNE) {
454: 002b1600 eoreq r1, fp, r0, lsl #12
456: R_ARM_ABS32 .debug_str
// Read to clear the flag
value = (char)USART2->DR;
if (lcd[0].flags & LCD_ACTIVE)
458: 46010000 strmi r0, [r1], -r0
45c: 00000461 andeq r0, r0, r1, ror #8
460: e1040800 tst r4, r0, lsl #16
lcdButtonProcess(value, 0);
464: 15000003 strne r0, [r0, #-3]
468: 00000383 andeq r0, r0, r3, lsl #7
468: R_ARM_ABS32 .debug_str
return buffer->head == buffer->tail;
}
// Checks to see if the ring buffer is full (tail + 1 = head)
static INLINE uint8_t _isBufferFull(volatile RingBuffer_TypeDef* buffer) {
return ((buffer->tail + 1) & _USART_MAX) == buffer->head;
46c: 00974b01 addseq r4, r7, r1, lsl #22
470: 83030000 movwhi r0, #12288 ; 0x3000
474: 16000004 strne r0, [r0], -r4
478: 0000002b andeq r0, r0, fp, lsr #32
478: R_ARM_ABS32 .debug_str
value = (char)USART2->DR;
if (lcd[0].flags & LCD_ACTIVE)
lcdButtonProcess(value, 0);
else {
// Buffer it up, if it's not full to the brim
if (!_isBufferFull(&(ser->rx)))
47c: 04614b01 strbteq r4, [r1], #-2817 ; 0xfffff4ff
return value;
}
// Queues a byte onto the tail of the given buffer
static void _queueByte(volatile RingBuffer_TypeDef* buffer, char value) {
uint8_t tail = buffer->tail;
480: 17000000 strne r0, [r0, -r0]
buffer->buffer[tail] = value;
484: 0000000f andeq r0, r0, pc
484: R_ARM_ABS32 .debug_str
buffer->tail = (tail + 1) & _USART_MAX;
488: 17037c02 strne r7, [r3, -r2, lsl #24]
}
// Queues a byte onto the tail of the given buffer
static void _queueByte(volatile RingBuffer_TypeDef* buffer, char value) {
uint8_t tail = buffer->tail;
buffer->buffer[tail] = value;
48c: 00000000 andeq r0, r0, r0
48c: R_ARM_ABS32 .debug_str
buffer->tail = (tail + 1) & _USART_MAX;
490: 18034a02 stmdane r3, {r1, r9, fp, lr}
else {
// Buffer it up, if it's not full to the brim
if (!_isBufferFull(&(ser->rx)))
_queueByte(&(ser->rx), value);
// Notify any receivers
semaphoreGiveISR(ser->readLock, &cs);
494: 000002b0 ; <UNDEFINED> instruction: 0x000002b0
494: R_ARM_ABS32 .debug_str
498: ab035002 blge d44a8 <usart+0xd4460>
49c: 19000004 stmdbne r0, {r2}
}
}
if (USART2->SR & USART_SR_TXE) {
4a0: 000000bf strheq r0, [r0], -pc ; <UNPREDICTABLE>
4a0: R_ARM_ABS32 .debug_str
4a4: 04ab5102 strteq r5, [fp], #258 ; 0x102
// Prototype this
uint32_t usartBufferCount(SerialPort_TypeDef* port);
// Checks to see if the ring buffer is empty (head = tail)
static INLINE uint8_t _isBufferEmpty(volatile RingBuffer_TypeDef* buffer) {
return buffer->head == buffer->tail;
4a8: 09000000 stmdbeq r0, {} ; <UNPREDICTABLE>
4ac: 000000ad andeq r0, r0, sp, lsr #1
4b0: 0005161a andeq r1, r5, sl, lsl r6
4b1: R_ARM_ABS32 .debug_str
// Notify any receivers
semaphoreGiveISR(ser->readLock, &cs);
}
}
if (USART2->SR & USART_SR_TXE) {
if (_isBufferEmpty(&(ser->tx)))
4b4: 01da0100 bicseq r0, sl, r0, lsl #2
// Nothing to send, disable interrupt
USART2->CR1 &= ~USART_CR1_TXEIE;
4b8: 0004ca03 andeq ip, r4, r3, lsl #20
4bc: 03d71b00 bicseq r1, r7, #0, 22
4be: R_ARM_ABS32 .debug_str
4c0: da010000 ble 404c8 <usart+0x40480>
return ((buffer->tail + 1) & _USART_MAX) == buffer->head;
}
// Removes a byte from the head of the given buffer
static char _pullByte(volatile RingBuffer_TypeDef* buffer) {
uint8_t head = buffer->head; char value;
4c4: 0004ca01 andeq ip, r4, r1, lsl #20
4c8: 04080000 streq r0, [r8], #-0
value = buffer->buffer[head];
4cc: 000003e6 andeq r0, r0, r6, ror #7
buffer->head = (head + 1) & _USART_MAX;
4d0: 0001901c andeq r9, r1, ip, lsl r0
4d1: R_ARM_ABS32 .debug_str
4d4: 055d0300 ldrbeq r0, [sp, #-768] ; 0xfffffd00
4d8: 03621c03 cmneq r2, #768 ; 0x300
4da: R_ARM_ABS32 .debug_str
if (_isBufferEmpty(&(ser->tx)))
// Nothing to send, disable interrupt
USART2->CR1 &= ~USART_CR1_TXEIE;
else {
value = _pullByte(&(ser->tx));
USART2->DR = value;
4dc: 65030000 strvs r0, [r3, #-0]
}
}
if (cs)
4e0: 191d0305 ldmdbne sp, {r0, r2, r8, r9}
4e3: R_ARM_ABS32 .debug_str
4e4: 01000004 tsteq r0, r4
4e8: 00000103 andeq r0, r0, r3, lsl #2
4ea: R_ARM_ABS32 .text.lcdButtonProcess
4ec: 005c0000 subseq r0, ip, r0
_taskYield();
}
4f0: 9c010000 stcls 0, cr0, [r1], {-0}
4f4: 00000529 andeq r0, r0, r9, lsr #10
4f8: 0001531e andeq r5, r1, lr, lsl r3
4f9: R_ARM_ABS32 .debug_str
4fc: 01030100 mrseq r0, (UNDEF: 19)
500: 000000ff strdeq r0, [r0], -pc ; <UNPREDICTABLE>
504: 00000000 andeq r0, r0, r0
504: R_ARM_ABS32 .debug_loc
// ISR_USART3 - Buffered character I/O handler for UART port 2
void ISR_USART3() {
508: 0000e91e andeq lr, r0, lr, lsl r9
509: R_ARM_ABS32 .debug_str
50c: 01030100 mrseq r0, (UNDEF: 19)
510: 000000ad andeq r0, r0, sp, lsr #1
514: 00000021 andeq r0, r0, r1, lsr #32
514: R_ARM_ABS32 .debug_loc
char value;
bool cs = false;
518: 0000e31f andeq lr, r0, pc, lsl r3
519: R_ARM_ABS32 .debug_str
SerialPort_TypeDef *ser = &usart[1];
if (USART3->SR & USART_SR_RXNE) {
51c: 01040100 mrseq r0, (UNDEF: 20)
520: 000000a2 andeq r0, r0, r2, lsr #1
// Read to clear the flag
value = (char)USART3->DR;
if (lcd[1].flags & LCD_ACTIVE)
524: 00000042 andeq r0, r0, r2, asr #32
524: R_ARM_ABS32 .debug_loc
528: 02372000 eorseq r2, r7, #0
52a: R_ARM_ABS32 .debug_str
52c: 60010000 andvs r0, r1, r0
lcdButtonProcess(value, 1);
530: 00054101 andeq r4, r5, r1, lsl #2
534: 03d71600 bicseq r1, r7, #0, 12
536: R_ARM_ABS32 .debug_str
538: 60010000 andvs r0, r1, r0
return buffer->head == buffer->tail;
}
// Checks to see if the ring buffer is full (tail + 1 = head)
static INLINE uint8_t _isBufferFull(volatile RingBuffer_TypeDef* buffer) {
return ((buffer->tail + 1) & _USART_MAX) == buffer->head;
53c: 000004ca andeq r0, r0, sl, asr #9
540: 036f1500 cmneq pc, #0, 10
542: R_ARM_ABS32 .debug_str
544: 50010000 andpl r0, r1, r0
value = (char)USART3->DR;
if (lcd[1].flags & LCD_ACTIVE)
lcdButtonProcess(value, 1);
else {
// Buffer it up, if it's not full to the brim
if (!_isBufferFull(&(ser->rx)))
548: 000000ff strdeq r0, [r0], -pc ; <UNPREDICTABLE>
return value;
}
// Queues a byte onto the tail of the given buffer
static void _queueByte(volatile RingBuffer_TypeDef* buffer, char value) {
uint8_t tail = buffer->tail;
54c: 00057301 andeq r7, r5, r1, lsl #6
550: 002b1600 eoreq r1, fp, r0, lsl #12
552: R_ARM_ABS32 .debug_str
buffer->buffer[tail] = value;
buffer->tail = (tail + 1) & _USART_MAX;
554: 50010000 andpl r0, r1, r0
558: 00000461 andeq r0, r0, r1, ror #8
}
// Queues a byte onto the tail of the given buffer
static void _queueByte(volatile RingBuffer_TypeDef* buffer, char value) {
uint8_t tail = buffer->tail;
buffer->buffer[tail] = value;
55c: 00004e19 andeq r4, r0, r9, lsl lr
55d: R_ARM_ABS32 .debug_str
buffer->tail = (tail + 1) & _USART_MAX;
560: 97510100 ldrbls r0, [r1, -r0, lsl #2]
else {
// Buffer it up, if it's not full to the brim
if (!_isBufferFull(&(ser->rx)))
_queueByte(&(ser->rx), value);
// Notify any receivers
semaphoreGiveISR(ser->readLock, &cs);
564: 19000000 stmdbne r0, {} ; <UNPREDICTABLE>
568: 00000153 andeq r0, r0, r3, asr r1
568: R_ARM_ABS32 .debug_str
56c: 00ff5101 rscseq r5, pc, r1, lsl #2
}
}
if (USART3->SR & USART_SR_TXE) {
570: 21000000 mrscs r0, (UNDEF: 0)
574: 000002e0 andeq r0, r0, r0, ror #5
574: R_ARM_ABS32 .debug_str
// Prototype this
uint32_t usartBufferCount(SerialPort_TypeDef* port);
// Checks to see if the ring buffer is empty (head = tail)
static INLINE uint8_t _isBufferEmpty(volatile RingBuffer_TypeDef* buffer) {
return buffer->head == buffer->tail;
578: 002c8601 eoreq r8, ip, r1, lsl #12
57c: 00000000 andeq r0, r0, r0
57e: R_ARM_ABS32 .text.fgetc
// Notify any receivers
semaphoreGiveISR(ser->readLock, &cs);
}
}
if (USART3->SR & USART_SR_TXE) {
if (_isBufferEmpty(&(ser->tx)))
580: 00640000 rsbeq r0, r4, r0
// Nothing to send, disable interrupt
USART3->CR1 &= ~USART_CR1_TXEIE;
584: 9c010000 stcls 0, cr0, [r1], {-0}
588: 0000064a andeq r0, r0, sl, asr #12
58c: 0005a722 andeq sl, r5, r2, lsr #14
58d: R_ARM_ABS32 .debug_str
590: 4a860100 bmi fe180998 <usart+0xfe180950>
return ((buffer->tail + 1) & _USART_MAX) == buffer->head;
}
// Removes a byte from the head of the given buffer
static char _pullByte(volatile RingBuffer_TypeDef* buffer) {
uint8_t head = buffer->head; char value;
594: 10000006 andne r0, r0, r6
597: R_ARM_ABS32 .debug_loc
value = buffer->buffer[head];
598: 23000001 movwcs r0, #1
59c: 000000b3 strheq r0, [r0], -r3
59c: R_ARM_ABS32 .debug_str
buffer->head = (head + 1) & _USART_MAX;
5a0: 00ad8701 adceq r8, sp, r1, lsl #14
5a4: 01490000 mrseq r0, (UNDEF: 73)
5a6: R_ARM_ABS32 .debug_loc
if (_isBufferEmpty(&(ser->tx)))
// Nothing to send, disable interrupt
USART3->CR1 &= ~USART_CR1_TXEIE;
else {
value = _pullByte(&(ser->tx));
USART3->DR = value;
5a8: 00240000 eoreq r0, r4, r0
5ab: R_ARM_ABS32 .debug_ranges
5ac: 40000000 andmi r0, r0, r0
}
}
if (cs)
5b0: 25000006 strcs r0, [r0, #-6]
5b4: 00726573 rsbseq r6, r2, r3, ror r5
5b8: 04ca8901 strbeq r8, [sl], #2305 ; 0x901
5bc: 01940000 orrseq r0, r4, r0
5be: R_ARM_ABS32 .debug_loc
_taskYield();
}
5c0: 29260000 stmdbcs r6!, {} ; <UNPREDICTABLE>
5c4: 10000005 andne r0, r0, r5
5c7: R_ARM_ABS32 .text.fgetc
5c8: 24000000 strcs r0, [r0], #-0
5cc: 01000000 mrseq r0, (UNDEF: 0)
5d0: 00060c8b andeq r0, r6, fp, lsl #25
}
// lcdReadButtons - Reads the button status from the LCD display and returns the buttons
// pressed as a bit mask. Does not block, always returns the last button status
unsigned int lcdReadButtons(FILE *lcdPort) {
uint32_t port = (uint32_t)lcdPort - 1;
5d4: 05352700 ldreq r2, [r5, #-1792]! ; 0xfffff900
if (port < 2) {
5d8: 01940000 orrseq r0, r4, r0
5da: R_ARM_ABS32 .debug_loc
if (lcd[port].flags & LCD_ACTIVE)
5dc: 45260000 strmi r0, [r6, #-0]!
5e0: 10000004 andne r0, r0, r4
5e3: R_ARM_ABS32 .text.fgetc
5e4: 08000000 stmdaeq r0, {} ; <UNPREDICTABLE>
5e8: 01000000 mrseq r0, (UNDEF: 0)
5ec: 0005fb61 andeq pc, r5, r1, ror #22
5f0: 04552700 ldrbeq r2, [r5], #-1792 ; 0xfffff900
return (uint32_t)(lcd[port].buttons);
5f4: 01cb0000 biceq r0, fp, r0
5f6: R_ARM_ABS32 .debug_loc
}
return 0;
5f8: 28000000 stmdacs r0, {} ; <UNPREDICTABLE>
}
5fc: 00000032 andeq r0, r0, r2, lsr r0
5fc: R_ARM_ABS32 .text.fgetc
// lcdSetBacklight - Turns the specified LCD backlight on or off
// The backlight will not update until the next line is sent (maybe 15ms latency)
void lcdSetBacklight(FILE *lcdPort, bool backlight) {
uint32_t port = (uint32_t)lcdPort - 1;
600: 000014ad andeq r1, r0, sp, lsr #9
if (port < 2) {
604: 02510129 subseq r0, r1, #1073741834 ; 0x4000000a
608: 0000ff09 andeq pc, r0, r9, lsl #30
if (backlight)
lcd[port].flags |= LCD_BACKLIGHT;
60c: 0005412a andeq r4, r5, sl, lsr #2
610: 00003c00 andeq r3, r0, r0, lsl #24
611: R_ARM_ABS32 .text.fgetc
614: 00001c00 andeq r1, r0, r0, lsl #24
618: 278d0100 strcs r0, [sp, r0, lsl #2]
else
lcd[port].flags &= ~LCD_BACKLIGHT;
61c: 00000551 andeq r0, r0, r1, asr r5
620: 00000208 andeq r0, r0, r8, lsl #4
620: R_ARM_ABS32 .debug_loc
624: 00003c2b andeq r3, r0, fp, lsr #24
625: R_ARM_ABS32 .text.fgetc
// _lcdDump - Dumps characters from the buffers to active LCDs (run from the IDLE TASK)
// lcdIndex == 0 for port #1 or 1 for port #2
void _lcdDump(uint32_t lcdIndex) {
// 22 byte packets
uint8_t flags = lcd[lcdIndex].flags, total;
628: 00001c00 andeq r1, r0, r0, lsl #24
}
}
// _lcdDump - Dumps characters from the buffers to active LCDs (run from the IDLE TASK)
// lcdIndex == 0 for port #1 or 1 for port #2
void _lcdDump(uint32_t lcdIndex) {
62c: 055c2c00 ldrbeq r2, [ip, #-3072] ; 0xfffff400
// 22 byte packets
uint8_t flags = lcd[lcdIndex].flags, total;
630: 023f0000 eorseq r0, pc, #0
632: R_ARM_ABS32 .debug_loc
634: 672d0000 strvs r0, [sp, -r0]!
if (flags & LCD_ACTIVE) {
638: 01000005 tsteq r0, r5
// Concoct the port
FILE *lcdPort = (FILE*)(lcdIndex + 1);
char value, *ptr = &(lcd[lcdIndex].screen[0]);
63c: 00000050 andeq r0, r0, r0, asr r0
// Set line (alternating order)
if (flags & LCD_ROW_2) {
ptr += 16;
lcd[lcdIndex].flags = flags & ~LCD_ROW_2;
640: 00003c2e andeq r3, r0, lr, lsr #24
641: R_ARM_ABS32 .text.fgetc
644: 0014cc00 andseq ip, r4, r0, lsl #24
} else
lcd[lcdIndex].flags = flags | LCD_ROW_2;
648: 04080000 streq r0, [r8], #-0
void _lcdDump(uint32_t lcdIndex) {
// 22 byte packets
uint8_t flags = lcd[lcdIndex].flags, total;
if (flags & LCD_ACTIVE) {
// Concoct the port
FILE *lcdPort = (FILE*)(lcdIndex + 1);
64c: 000000e7 andeq r0, r0, r7, ror #1
char value, *ptr = &(lcd[lcdIndex].screen[0]);
// Set line (alternating order)
if (flags & LCD_ROW_2) {
ptr += 16;
lcd[lcdIndex].flags = flags & ~LCD_ROW_2;
650: 00029520 andeq r9, r2, r0, lsr #10
651: R_ARM_ABS32 .debug_str
} else
lcd[lcdIndex].flags = flags | LCD_ROW_2;
654: 01670100 cmneq r7, r0, lsl #2
flags &= (LCD_ROW_2 | LCD_BACKLIGHT);
// Sync bytes
fputc(0xAA, lcdPort);
658: 00000668 andeq r0, r0, r8, ror #12
65c: 0003d716 andeq sp, r3, r6, lsl r7
65d: R_ARM_ABS32 .debug_str
// Concoct the port
FILE *lcdPort = (FILE*)(lcdIndex + 1);
char value, *ptr = &(lcd[lcdIndex].screen[0]);
// Set line (alternating order)
if (flags & LCD_ROW_2) {
ptr += 16;
660: ca670100 bgt 19c0a68 <usart+0x19c0a20>
lcd[lcdIndex].flags = flags & ~LCD_ROW_2;
} else
lcd[lcdIndex].flags = flags | LCD_ROW_2;
flags &= (LCD_ROW_2 | LCD_BACKLIGHT);
// Sync bytes
fputc(0xAA, lcdPort);
664: 00000004 andeq r0, r0, r4
fputc(0x55, lcdPort);
668: 00020e20 andeq r0, r2, r0, lsr #28
669: R_ARM_ABS32 .debug_str
66c: 01580100 cmpeq r8, r0, lsl #2
// Packet type 1E
fputc(0x1E, lcdPort);
670: 00000696 muleq r0, r6, r6
674: 00002b16 andeq r2, r0, r6, lsl fp
675: R_ARM_ABS32 .debug_str
if (flags & LCD_ROW_2) {
ptr += 16;
lcd[lcdIndex].flags = flags & ~LCD_ROW_2;
} else
lcd[lcdIndex].flags = flags | LCD_ROW_2;
flags &= (LCD_ROW_2 | LCD_BACKLIGHT);
678: 61580100 cmpvs r8, r0, lsl #2
fputc(0xAA, lcdPort);
fputc(0x55, lcdPort);
// Packet type 1E
fputc(0x1E, lcdPort);
// 18 bytes to follow
fputc(0x12, lcdPort);
67c: 16000004 strne r0, [r0], -r4
680: 00000153 andeq r0, r0, r3, asr r1
680: R_ARM_ABS32 .debug_str
// LCD flags
fputc((char)flags, lcdPort);
684: 00ff5801 rscseq r5, pc, r1, lsl #16
688: f0190000 ; <UNDEFINED> instruction: 0xf0190000
68b: R_ARM_ABS32 .debug_str
total = flags;
// Run until out of space or end of buffer
for (uint32_t i = 0; i < 16; i++) {
value = *ptr;
68c: 01000004 tsteq r0, r4
if (value) {
690: 00009759 andeq r9, r0, r9, asr r7
694: c0210000 eorgt r0, r1, r0
697: R_ARM_ABS32 .debug_str
// Output text
fputc(value, lcdPort);
698: 01000005 tsteq r0, r5
total += (uint8_t)(value);
69c: 00002ca9 andeq r2, r0, r9, lsr #25
// Run until out of space or end of buffer
for (uint32_t i = 0; i < 16; i++) {
value = *ptr;
if (value) {
// Output text
fputc(value, lcdPort);
6a0: 00000000 andeq r0, r0, r0
6a1: R_ARM_ABS32 .text.fputc
total += (uint8_t)(value);
ptr++;
6a4: 00008400 andeq r8, r0, r0, lsl #8
} else {
// Pad with spaces
fputc(' ', lcdPort);
6a8: 7c9c0100 ldfvcs f0, [ip], {0}
6ac: 22000007 andcs r0, r0, #7
total += (uint8_t)' ';
6b0: 00000153 andeq r0, r0, r3, asr r1
6b0: R_ARM_ABS32 .debug_str
fputc(0x12, lcdPort);
// LCD flags
fputc((char)flags, lcdPort);
total = flags;
// Run until out of space or end of buffer
for (uint32_t i = 0; i < 16; i++) {
6b4: 002ca901 eoreq sl, ip, r1, lsl #18
fputc(' ', lcdPort);
total += (uint8_t)' ';
}
}
// Checksum
fputc((char)((uint8_t)(-total)), lcdPort);
6b8: 025f0000 subseq r0, pc, #0
6ba: R_ARM_ABS32 .debug_loc
}
}
6bc: a7220000 strge r0, [r2, -r0]!
6bf: R_ARM_ABS32 .debug_str
fputc(' ', lcdPort);
total += (uint8_t)' ';
}
}
// Checksum
fputc((char)((uint8_t)(-total)), lcdPort);
6c0: 01000005 tsteq r0, r5
6c4: 00064aa9 andeq r4, r6, r9, lsr #21
6c8: 0002ac00 andeq sl, r2, r0, lsl #24
6c9: R_ARM_ABS32 .debug_loc
6cc: 00b32300 adcseq r2, r3, r0, lsl #6
6ce: R_ARM_ABS32 .debug_str
// lcdSetText - Sets a line (1 or 2) of text on the LCD to the specified null-terminated string
// Up to 16 characters will actually be transmitted; this function is thread safe, but
// concurrent access to the same line of the same LCD will cause garbage text to be displayed
void lcdSetText(FILE *lcdPort, unsigned char line, const char *buffer) {
// Blit to the buffer, automatically dumped on the idle task
uint32_t port = (uint32_t)lcdPort - 1, i;
6d0: aa010000 bge 406d8 <usart+0x40690>
}
// lcdSetText - Sets a line (1 or 2) of text on the LCD to the specified null-terminated string
// Up to 16 characters will actually be transmitted; this function is thread safe, but
// concurrent access to the same line of the same LCD will cause garbage text to be displayed
void lcdSetText(FILE *lcdPort, unsigned char line, const char *buffer) {
6d4: 000000ad andeq r0, r0, sp, lsr #1
// Blit to the buffer, automatically dumped on the idle task
uint32_t port = (uint32_t)lcdPort - 1, i;
line--;
6d8: 000002f0 strdeq r0, [r0], -r0 ; <UNPREDICTABLE>
6d8: R_ARM_ABS32 .debug_loc
if (port < 2 && line < 2) {
6dc: 00001824 andeq r1, r0, r4, lsr #16
6dd: R_ARM_ABS32 .debug_ranges
// Find pointer to location
char *scr = &(lcd[port].screen[0]);
6e0: 00076300 andeq r6, r7, r0, lsl #6
6e4: 65732500 ldrbvs r2, [r3, #-1280]! ; 0xfffffb00
if (line) scr += 16;
6e8: ac010072 stcge 0, cr0, [r1], {114} ; 0x72
6ec: 000004ca andeq r0, r0, sl, asr #9
for (i = 0; i < 16; i++) {
// Space pad to 16 characters
if (*buffer)
6f0: 00000320 andeq r0, r0, r0, lsr #6
6f0: R_ARM_ABS32 .debug_loc
*scr++ = *buffer++;
6f4: 00065026 andeq r5, r6, r6, lsr #32
else
*scr++ = ' ';
6f8: 00001200 andeq r1, r0, r0, lsl #4
6f9: R_ARM_ABS32 .text.fputc
6fc: 00001400 andeq r1, r0, r0, lsl #8
line--;
if (port < 2 && line < 2) {
// Find pointer to location
char *scr = &(lcd[port].screen[0]);
if (line) scr += 16;
for (i = 0; i < 16; i++) {
700: 37ad0100 strcc r0, [sp, r0, lsl #2]!
704: 27000007 strcs r0, [r0, -r7]
708: 0000065c andeq r0, r0, ip, asr r6
if (cs)
_taskYield();
}
// lcdClear - Clears the screen
void lcdClear(FILE *lcdPort) {
70c: 00000320 andeq r0, r0, r0, lsr #6
70c: R_ARM_ABS32 .debug_loc
lcdSetText(lcdPort, 1, "");
710: 00046726 andeq r6, r4, r6, lsr #14
714: 00001200 andeq r1, r0, r0, lsl #4
715: R_ARM_ABS32 .text.fputc
718: 00000a00 andeq r0, r0, r0, lsl #20
lcdSetText(lcdPort, 2, "");
71c: 2d680100 stfcse f0, [r8, #-0]
}
720: 27000007 strcs r0, [r0, -r7]
}
// lcdClear - Clears the screen
void lcdClear(FILE *lcdPort) {
lcdSetText(lcdPort, 1, "");
lcdSetText(lcdPort, 2, "");
724: 00000477 andeq r0, r0, r7, ror r4
728: 00000320 andeq r0, r0, r0, lsr #6
728: R_ARM_ABS32 .debug_loc
lcd[idx].buttons = 0;
}
}
// lcdPrint - Convenience method that performs snprintf() and then lcdSetText()
void lcdPrint(FILE *lcdPort, unsigned char line, const char *fmt, ...) {
72c: 00242f00 eoreq r2, r4, r0, lsl #30
72e: R_ARM_ABS32 .text.fputc
730: 14e10000 strbtne r0, [r1], #0
734: 30000000 andcc r0, r0, r0
738: 00000668 andeq r0, r0, r8, ror #12
char buffer[17];
// Pass to vsnprintf
va_list args;
va_start(args, fmt);
vsnprintf(buffer, 17, fmt, args);
73c: 00000026 andeq r0, r0, r6, lsr #32
73c: R_ARM_ABS32 .text.fputc
// lcdPrint - Convenience method that performs snprintf() and then lcdSetText()
void lcdPrint(FILE *lcdPort, unsigned char line, const char *fmt, ...) {
char buffer[17];
// Pass to vsnprintf
va_list args;
va_start(args, fmt);
740: 00000030 andeq r0, r0, r0, lsr r0
740: R_ARM_ABS32 .debug_ranges
vsnprintf(buffer, 17, fmt, args);
744: 7f31af01 svcvc 0x0031af01
va_end(args);
// Ensure that there are no null-terminator issues
buffer[16] = 0;
lcdSetText(lcdPort, line, buffer);
748: 27000006 strcs r0, [r0, -r6]
74c: 00000674 andeq r0, r0, r4, ror r6
va_list args;
va_start(args, fmt);
vsnprintf(buffer, 17, fmt, args);
va_end(args);
// Ensure that there are no null-terminator issues
buffer[16] = 0;
750: 00000333 andeq r0, r0, r3, lsr r3
750: R_ARM_ABS32 .debug_loc
lcdSetText(lcdPort, line, buffer);
754: 00003032 andeq r3, r0, r2, lsr r0
755: R_ARM_ABS32 .debug_ranges
}
758: 068a2d00 streq r2, [sl], r0, lsl #26
75c: 53010000 movwpl r0, #4096 ; 0x1000
port->rx.tail = 0;
port->readLock = semaphoreCreate();
}
// usartBufferCount - Determine the number of available characters on the specified USART
uint32_t usartBufferCount(SerialPort_TypeDef* port) {
760: 33000000 movwcc r0, #0
extern volatile uint32_t _criticalNesting;
/* Enter a critical section. */
static INLINE void _enterCritical() {
__disable_irq();
_criticalNesting++;
764: 00000070 andeq r0, r0, r0, ror r0
764: R_ARM_ABS32 .text.fputc
768: 000014ee andeq r1, r0, lr, ror #9
uint32_t head, tail;
_enterCritical();
head = (uint32_t)port->rx.head;
76c: 03510129 cmpeq r1, #1073741834 ; 0x4000000a
tail = (uint32_t)port->rx.tail;
770: 295001f3 ldmdbcs r0, {r0, r1, r4, r5, r6, r7, r8}^
}
/* Exit a critical section. */
static INLINE void _exitCritical() {
const uint32_t newCritical = _criticalNesting - 1;
774: f3035001 vhadd.u8 d5, d3, d1
778: 00005101 andeq r5, r0, r1, lsl #2
_criticalNesting = newCritical;
77c: 00035c21 andeq r5, r3, r1, lsr #24
77d: R_ARM_ABS32 .debug_str
// Waits for memory accesses to complete before continuing (Data Synchronization Barrier)
static inline void __dsb() { asm volatile ("dsb"); }
// Enables FAULT interrupts
static inline void __enable_fault_irq() { asm volatile ("cpsie f"); }
// Enables interrupts
static inline void __enable_irq() { asm volatile ("cpsie i"); }
780: 33c30100 biccc r0, r3, #0, 2
_exitCritical();
return (tail - head) & (uint32_t)_USART_MAX;
}
784: 00000000 andeq r0, r0, r0
787: R_ARM_ABS32 .text.fread
788: 28000000 stmdacs r0, {} ; <UNPREDICTABLE>
78c: 01000000 mrseq r0, (UNDEF: 0)
_yield();
}
// fcount - Non-standard function to return estimated number of characters waiting on stream
int fcount(FILE *stream) {
uint32_t snew = (uint32_t)stream - 1;
790: 0008229c muleq r8, ip, r2
if (snew < 3)
794: 74703400 ldrbtvc r3, [r0], #-1024 ; 0xfffffc00
return (int)usartBufferCount(&usart[snew]);
798: c3010072 movwgt r0, #4210 ; 0x1072
79c: 000000da ldrdeq r0, [r0], -sl
7a0: 00000351 andeq r0, r0, r1, asr r3
7a0: R_ARM_ABS32 .debug_loc
#ifndef NO_FILESYSTEM
// File system check
return fsLeft(stream);
7a4: 0002be22 andeq fp, r2, r2, lsr #28
7a5: R_ARM_ABS32 .debug_str
7a8: 33c30100 biccc r0, r3, #0, 2
return 0;
#endif
}
// feof - Return 1 if the stream is at EOF, or 0 otherwise
int feof(FILE *stream) {
7ac: 6f000000 svcvs 0x00000000
7af: R_ARM_ABS32 .debug_loc
uint32_t snew = (uint32_t)stream - 1;
if (snew < 3)
7b0: 22000003 andcs r0, r0, #3
#ifndef NO_FILESYSTEM
return fsEof(stream);
#else
return 1;
#endif
}
7b4: 000000e3 andeq r0, r0, r3, ror #1
7b4: R_ARM_ABS32 .debug_str
int feof(FILE *stream) {
uint32_t snew = (uint32_t)stream - 1;
if (snew < 3)
return (usartBufferCount(&usart[snew]) == 0) ? 1 : 0;
#ifndef NO_FILESYSTEM
return fsEof(stream);
7b8: 0033c301 eorseq ip, r3, r1, lsl #6
// feof - Return 1 if the stream is at EOF, or 0 otherwise
int feof(FILE *stream) {
uint32_t snew = (uint32_t)stream - 1;
if (snew < 3)
return (usartBufferCount(&usart[snew]) == 0) ? 1 : 0;
7bc: 03900000 orrseq r0, r0, #0
7be: R_ARM_ABS32 .debug_loc
7c0: a7220000 strge r0, [r2, -r0]!
7c3: R_ARM_ABS32 .debug_str
7c4: 01000005 tsteq r0, r5
7c8: 00064ac3 andeq r4, r6, r3, asr #21
7cc: 0003b100 andeq fp, r3, r0, lsl #2
7cd: R_ARM_ABS32 .debug_loc
#ifndef NO_FILESYSTEM
return fsEof(stream);
#else
return 1;
#endif
}
7d0: 03e82300 mvneq r2, #0, 6
7d2: R_ARM_ABS32 .debug_str
return EOF;
#endif
}
// fgets - Read a string from the specified stream
char* fgets(char *str, int num, FILE *stream) {
7d4: c4010000 strgt r0, [r1], #-0
// Required by standard
char *ptr = str;
int value;
if (feof(stream)) return NULL;
7d8: 000000f9 strdeq r0, [r0], -r9
return EOF;
#endif
}
// fgets - Read a string from the specified stream
char* fgets(char *str, int num, FILE *stream) {
7dc: 000003cf andeq r0, r0, pc, asr #7
7dc: R_ARM_ABS32 .debug_loc
// Required by standard
char *ptr = str;
int value;
if (feof(stream)) return NULL;
7e0: 00027d23 andeq r7, r2, r3, lsr #26
7e1: R_ARM_ABS32 .debug_str
7e4: 33c50100 biccc r0, r5, #0, 2
7e8: 04000000 streq r0, [r0], #-0
7eb: R_ARM_ABS32 .debug_loc
// Read at most num-1 characters
for (; num > 1 && (value = fgetc(stream)) != EOF; num--) {
7ec: 23000004 movwcs r0, #4
7f0: 000000d9 ldrdeq r0, [r0], -r9
7f0: R_ARM_ABS32 .debug_str
7f4: 002cc501 eoreq ip, ip, r1, lsl #10
*ptr++ = (char)value;
7f8: 04230000 strteq r0, [r3], #-0
7fa: R_ARM_ABS32 .debug_loc
// Exit loop (including new line) when a new line is found
if ((char)value == '\n') break;
7fc: 48320000 ldmdami r2!, {} ; <UNPREDICTABLE>
7ff: R_ARM_ABS32 .debug_ranges
800: 25000000 strcs r0, [r0, #-0]
}
// Add null terminator
*ptr = '\0';
804: c6010069 strgt r0, [r1], -r9, rrx
return str;
808: 000000ad andeq r0, r0, sp, lsr #1
}
80c: 00000404 andeq r0, r0, r4, lsl #8
80c: R_ARM_ABS32 .debug_loc
_exitCritical();
return (tail - head) & (uint32_t)_USART_MAX;
}
// usartBufferInit - Initializes (empty) the USART buffers
void usartBufferInit() {
810: 00001628 andeq r1, r0, r8, lsr #12
811: R_ARM_ABS32 .text.fread
}
}
// _usartBufferInit - Clears one particular buffer and sets up its semaphore
static INLINE void _usartBufferInit(SerialPort_TypeDef* port) {
port->rx.head = 0;
814: 00057300 andeq r7, r5, r0, lsl #6
818: 50012900 andpl r2, r1, r0, lsl #18
port->rx.tail = 0;
81c: 00007702 andeq r7, r0, r2, lsl #14
port->tx.head = 0;
820: 27210000 strcs r0, [r1, -r0]!
823: R_ARM_ABS32 .debug_str
port->rx.tail = 0;
824: 01000005 tsteq r0, r5
port->readLock = semaphoreCreate();
828: 000033d1 ldrdeq r3, [r0], -r1
}
}
// _usartBufferInit - Clears one particular buffer and sets up its semaphore
static INLINE void _usartBufferInit(SerialPort_TypeDef* port) {
port->rx.head = 0;
82c: 00000000 andeq r0, r0, r0
82d: R_ARM_ABS32 .text.fwrite
port->rx.tail = 0;
port->tx.head = 0;
port->rx.tail = 0;
port->readLock = semaphoreCreate();
830: 00002800 andeq r2, r0, r0, lsl #16
}
// _usartBufferInit - Clears one particular buffer and sets up its semaphore
static INLINE void _usartBufferInit(SerialPort_TypeDef* port) {
port->rx.head = 0;
port->rx.tail = 0;
834: b99c0100 ldmiblt ip, {r8}
port->tx.head = 0;
838: 34000008 strcc r0, [r0], #-8
port->rx.tail = 0;
83c: 00727470 rsbseq r7, r2, r0, ror r4
port->readLock = semaphoreCreate();
840: 0111d101 tsteq r1, r1, lsl #2
}
}
// _usartBufferInit - Clears one particular buffer and sets up its semaphore
static INLINE void _usartBufferInit(SerialPort_TypeDef* port) {
port->rx.head = 0;
844: 04360000 ldrteq r0, [r6], #-0
846: R_ARM_ABS32 .debug_loc
port->rx.tail = 0;
port->tx.head = 0;
port->rx.tail = 0;
port->readLock = semaphoreCreate();
848: be220000 cdplt 0, 2, cr0, cr2, cr0, {0}
84b: R_ARM_ABS32 .debug_str
}
// _usartBufferInit - Clears one particular buffer and sets up its semaphore
static INLINE void _usartBufferInit(SerialPort_TypeDef* port) {
port->rx.head = 0;
port->rx.tail = 0;
84c: 01000002 tsteq r0, r2
port->tx.head = 0;
850: 000033d1 ldrdeq r3, [r0], -r1
port->rx.tail = 0;
854: 00045400 andeq r5, r4, r0, lsl #8
855: R_ARM_ABS32 .debug_loc
port->readLock = semaphoreCreate();
858: 00e32200 rsceq r2, r3, r0, lsl #4
85a: R_ARM_ABS32 .debug_str
85c: d1010000 mrsle r0, (UNDEF: 1)
860: 00000033 andeq r0, r0, r3, lsr r0
#define USART_CR3_CTSE ((uint16_t)0x0200)
// Disables FAULT interrupts
static inline void __disable_fault_irq() { asm volatile ("cpsid f"); }
// Disables interrupts
static inline void __disable_irq() { asm volatile ("cpsid i"); }
864: 00000475 andeq r0, r0, r5, ror r4
864: R_ARM_ABS32 .debug_loc
}
// usartFlushBuffers - Clears the USART output buffers (Trashes data! From ALL USARTS!)
void usartFlushBuffers() {
__disable_irq();
usart[0].tx.tail = usart[0].tx.head;
868: 0005a722 andeq sl, r5, r2, lsr #14
869: R_ARM_ABS32 .debug_str
86c: 4ad10100 bmi ff440c74 <usart+0xff440c2c>
870: 96000006 strls r0, [r0], -r6
873: R_ARM_ABS32 .debug_loc
usart[1].tx.tail = usart[1].tx.head;
874: 23000004 movwcs r0, #4
878: 000003e8 andeq r0, r0, r8, ror #7
878: R_ARM_ABS32 .debug_str
usart[2].tx.tail = usart[2].tx.head;
87c: 0106d201 tsteq r6, r1, lsl #4
880: 04b40000 ldrteq r0, [r4], #0
882: R_ARM_ABS32 .debug_loc
884: 7d230000 stcvc 0, cr0, [r3, #-0]
887: R_ARM_ABS32 .debug_str
// Waits for memory accesses to complete before continuing (Data Synchronization Barrier)
static inline void __dsb() { asm volatile ("dsb"); }
// Enables FAULT interrupts
static inline void __enable_fault_irq() { asm volatile ("cpsie f"); }
// Enables interrupts
static inline void __enable_irq() { asm volatile ("cpsie i"); }
888: 01000002 tsteq r0, r2
88c: 000033d3 ldrdeq r3, [r0], -r3 ; <UNPREDICTABLE>
// usartInit - Initialize the specified USART interface with the given connection parameters
// The interface argument can be 1 or 2 to specify UART1 and UART2 respectively
void usartInit(FILE *port, unsigned int baud, unsigned int flags) {
// Determine correct USART
USART_TypeDef *base;
if (port == uart1)
890: 0004e900 andeq lr, r4, r0, lsl #18
891: R_ARM_ABS32 .debug_loc
894: 00603200 rsbeq r3, r0, r0, lsl #4
896: R_ARM_ABS32 .debug_ranges
base = USART2;
else if (port == uart2)
898: 69250000 stmdbvs r5!, {} ; <UNPREDICTABLE>
base = USART3;
89c: add40100 ldfgee f0, [r4]
#define USART_CR3_CTSE ((uint16_t)0x0200)
// Disables FAULT interrupts
static inline void __disable_fault_irq() { asm volatile ("cpsid f"); }
// Disables interrupts
static inline void __disable_irq() { asm volatile ("cpsid i"); }
8a0: e9000000 stmdb r0, {} ; <UNPREDICTABLE>
8a3: R_ARM_ABS32 .debug_loc
return;
_enterCritical();
{
base->CR1 = 0;
// Flush buffers
if (port == uart1) {
8a4: 28000004 stmdacs r0, {r2}
extern volatile uint32_t _criticalNesting;
/* Enter a critical section. */
static INLINE void _enterCritical() {
__disable_irq();
_criticalNesting++;
8a8: 00000018 andeq r0, r0, r8, lsl r0
8a8: R_ARM_ABS32 .text.fwrite
8ac: 00000696 muleq r0, r6, r6
else
// Invalid interface
return;
_enterCritical();
{
base->CR1 = 0;
8b0: 02510129 subseq r0, r1, #1073741834 ; 0x4000000a
8b4: 00000077 andeq r0, r0, r7, ror r0
// Flush buffers
if (port == uart1) {
usart[0].tx.tail = usart[0].tx.head;
8b8: 042a3500 strteq r3, [sl], #-1280 ; 0xfffffb00
8ba: R_ARM_ABS32 .debug_str
8bc: de010000 cdple 0, 0, cr0, cr1, cr0, {0}
usart[0].rx.tail = usart[0].rx.head;
} else {
usart[1].tx.tail = usart[1].tx.head;
8c0: 0000002c andeq r0, r0, ip, lsr #32
8c4: 00000000 andeq r0, r0, r0
8c4: R_ARM_ABS32 .text.getchar
_enterCritical();
{
base->CR1 = 0;
// Flush buffers
if (port == uart1) {
usart[0].tx.tail = usart[0].tx.head;
8c8: 00000006 andeq r0, r0, r6
usart[0].rx.tail = usart[0].rx.head;
} else {
usart[1].tx.tail = usart[1].tx.head;
8cc: 08e29c01 stmiaeq r2!, {r0, sl, fp, ip, pc}^
{
base->CR1 = 0;
// Flush buffers
if (port == uart1) {
usart[0].tx.tail = usart[0].tx.head;
usart[0].rx.tail = usart[0].rx.head;
8d0: 06330000 ldrteq r0, [r3], -r0
8d3: R_ARM_ABS32 .text.getchar
} else {
usart[1].tx.tail = usart[1].tx.head;
usart[1].rx.tail = usart[1].rx.head;
8d4: 73000000 movwvc r0, #0
}
// Configure base registers
base->CR2 = flags & (USART_CR2_STOP0 | USART_CR2_STOP1);
8d8: 29000005 stmdbcs r0, {r0, r2}
{
base->CR1 = 0;
// Flush buffers
if (port == uart1) {
usart[0].tx.tail = usart[0].tx.head;
usart[0].rx.tail = usart[0].rx.head;
8dc: 33015001 movwcc r5, #4097 ; 0x1001
8e0: 93210000 ; <UNDEFINED> instruction: 0x93210000
8e3: R_ARM_ABS32 .debug_str
} else {
usart[1].tx.tail = usart[1].tx.head;
usart[1].rx.tail = usart[1].rx.head;
8e4: 01000000 mrseq r0, (UNDEF: 0)
}
// Configure base registers
base->CR2 = flags & (USART_CR2_STOP0 | USART_CR2_STOP1);
8e8: 00002ce3 andeq r2, r0, r3, ror #25
// Turn on USART
base->CR1 = USART_CR1_RXNEIE | USART_CR1_RE | USART_CR1_TE | USART_CR1_UE |
8ec: 00000000 andeq r0, r0, r0
8ed: R_ARM_ABS32 .text.putchar
8f0: 00000600 andeq r0, r0, r0, lsl #12
} else {
usart[1].tx.tail = usart[1].tx.head;
usart[1].rx.tail = usart[1].rx.head;
}
// Configure base registers
base->CR2 = flags & (USART_CR2_STOP0 | USART_CR2_STOP1);
8f4: 219c0100 orrscs r0, ip, r0, lsl #2
// Turn on USART
base->CR1 = USART_CR1_RXNEIE | USART_CR1_RE | USART_CR1_TE | USART_CR1_UE |
8f8: 22000009 andcs r0, r0, #9
8fc: 00000153 andeq r0, r0, r3, asr r1
8fc: R_ARM_ABS32 .debug_str
(flags & (USART_CR1_PCE | USART_CR1_PS | USART_CR1_M));
base->CR3 = (uint16_t)0;
// Set baud rate
uint32_t brr = 225000000 / baud, mod = brr / 100, fracDiv = brr - (100 * mod);
900: 002ce301 eoreq lr, ip, r1, lsl #6
904: 05080000 streq r0, [r8, #-0]
906: R_ARM_ABS32 .debug_loc
908: 06330000 ldrteq r0, [r3], -r0
90b: R_ARM_ABS32 .text.putchar
90c: 96000000 strls r0, [r0], -r0
base->BRR = (uint16_t)(mod << 4) | (uint16_t)((((fracDiv << 4) + 50) / 100) & 0xF);
910: 29000006 stmdbcs r0, {r1, r2}
914: 33015101 movwcc r5, #4353 ; 0x1101
918: 03500129 cmpeq r0, #1073741834 ; 0x4000000a
91c: 005001f3 ldrsheq r0, [r0], #-19 ; 0xffffffed
920: 01593600 cmpeq r9, r0, lsl #12
922: R_ARM_ABS32 .debug_str
}
/* Exit a critical section. */
static INLINE void _exitCritical() {
const uint32_t newCritical = _criticalNesting - 1;
924: e8010000 stmda r1, {} ; <UNPREDICTABLE>
_criticalNesting = newCritical;
928: 00000000 andeq r0, r0, r0
928: R_ARM_ABS32 .text.ISR_USART1
// Waits for memory accesses to complete before continuing (Data Synchronization Barrier)
static inline void __dsb() { asm volatile ("dsb"); }
// Enables FAULT interrupts
static inline void __enable_fault_irq() { asm volatile ("cpsie f"); }
// Enables interrupts
static inline void __enable_irq() { asm volatile ("cpsie i"); }
92c: 000000bc strheq r0, [r0], -ip
930: 0a2c9c01 beq b2793c <usart+0xb278f4>
934: 53230000 ; <UNDEFINED> instruction: 0x53230000
937: R_ARM_ABS32 .debug_str
938: 01000001 tsteq r0, r1
93c: 0000ffe9 andeq pc, r0, r9, ror #31
940: 00052900 andeq r2, r5, r0, lsl #18
941: R_ARM_ABS32 .debug_loc
lcdSetText(lcdPort, 1, "");
lcdSetText(lcdPort, 2, "");
}
// lcdInit - Enables the LCD on the specified port
void lcdInit(FILE *lcdPort) {
944: 73633700 cmnvc r3, #0, 14
// No flags = 8 N 1
if (lcdPort == uart1 || lcdPort == uart2) {
948: 2cea0100 stfcse f0, [sl]
uint32_t idx = (uint32_t)lcdPort - 1;
usartInit(lcdPort, 19200, 0);
94c: 0200000a andeq r0, r0, #10
950: 73377791 teqvc r7, #38010880 ; 0x2440000
954: 01007265 tsteq r0, r5, ror #4
// Clear LCD state, turn on
lcd[idx].flags = LCD_ACTIVE;
958: 0004caeb andeq ip, r4, fp, ror #21
95c: 58030600 stmdapl r3, {r9, sl}
95f: R_ARM_ABS32 .bss
960: 9f000001 svcls 0x00000001
964: 00046738 andeq r6, r4, r8, lsr r7
lcd[idx].state = 0;
968: 00001c00 andeq r1, r0, r0, lsl #24
969: R_ARM_ABS32 .text.ISR_USART1
lcd[idx].buttons = 0;
96c: 00007800 andeq r7, r0, r0, lsl #16
96d: R_ARM_ABS32 .debug_ranges
970: 81f00100 mvnshi r0, r0, lsl #2
}
// usartShutdown - Disable the specified USART interface
void usartShutdown(FILE *usart) {
// Disable transmitter, receiver, clock, and interrupts
if (usart == uart1)
974: 27000009 strcs r0, [r0, -r9]
USART2->CR1 = (uint16_t)0;
978: 00000477 andeq r0, r0, r7, ror r4
97c: 0000053c andeq r0, r0, ip, lsr r5
97c: R_ARM_ABS32 .debug_loc
else if (usart == uart2)
980: 06683800 strbteq r3, [r8], -r0, lsl #16
USART3->CR1 = (uint16_t)0;
984: 00320000 eorseq r0, r2, r0
986: R_ARM_ABS32 .text.ISR_USART1
988: 00900000 addseq r0, r0, r0
98a: R_ARM_ABS32 .debug_ranges
98c: f1010000 setend le
990: 000009b6 ; <UNDEFINED> instruction: 0x000009b6
}
}
}
// lcdShutdown - Disable the LCD on the specified port
void lcdShutdown(FILE *lcdPort) {
994: 00067f27 andeq r7, r6, r7, lsr #30
if (lcdPort == uart1 || lcdPort == uart2) {
998: 00055400 andeq r5, r5, r0, lsl #8
999: R_ARM_ABS32 .debug_loc
usartShutdown(lcdPort);
99c: 06742700 ldrbteq r2, [r4], -r0, lsl #14
lcd[(uint32_t)lcdPort - 1].flags = 0;
9a0: 05670000 strbeq r0, [r7, #-0]!
9a2: R_ARM_ABS32 .debug_loc
9a4: 90320000 eorsls r0, r2, r0
9a7: R_ARM_ABS32 .debug_ranges
9a8: 2c000000 stccs 0, cr0, [r0], {-0}
9ac: 0000068a andeq r0, r0, sl, lsl #13
9b0: 0000057f andeq r0, r0, pc, ror r5
9b0: R_ARM_ABS32 .debug_loc
9b4: 45260000 strmi r0, [r6, #-0]!
9b8: 5e000004 cdppl 0, 0, cr0, cr0, cr4, {0}
9bb: R_ARM_ABS32 .text.ISR_USART1
9bc: 0a000000 beq 9c4 <.debug_info+0x9c4>
9c0: 01000000 mrseq r0, (UNDEF: 0)
9c4: 0009d3f6 strdeq sp, [r9], -r6
9c8: 04552700 ldrbeq r2, [r5], #-1792 ; 0xfffff900
9cc: 05ae0000 streq r0, [lr, #0]!
9ce: R_ARM_ABS32 .debug_loc
9d0: 26000000 strcs r0, [r0], -r0
9d4: 00000541 andeq r0, r0, r1, asr #10
9d8: 0000007a andeq r0, r0, sl, ror r0
9d8: R_ARM_ABS32 .text.ISR_USART1
9dc: 00000016 andeq r0, r0, r6, lsl r0
9e0: 0a0cfa01 beq 33f1ec <usart+0x33f1a4>
9e4: 51270000 ; <UNDEFINED> instruction: 0x51270000
9e8: c6000005 strgt r0, [r0], -r5
9eb: R_ARM_ABS32 .debug_loc
9ec: 2b000005 blcs a08 <.debug_info+0xa08>
9f0: 0000007a andeq r0, r0, sl, ror r0
9f0: R_ARM_ABS32 .text.ISR_USART1
9f4: 00000016 andeq r0, r0, r6, lsl r0
9f8: 00055c2c andeq r5, r5, ip, lsr #24
9fc: 0005de00 andeq sp, r5, r0, lsl #28
9fd: R_ARM_ABS32 .debug_loc
a00: 05672c00 strbeq r2, [r7, #-3072]! ; 0xfffff400
a04: 060d0000 streq r0, [sp], -r0
a06: R_ARM_ABS32 .debug_loc
a08: 00000000 andeq r0, r0, r0
a0c: 00048339 andeq r8, r4, r9, lsr r3
a10: 00009c00 andeq r9, r0, r0, lsl #24
a11: R_ARM_ABS32 .text.ISR_USART1
a14: 00000a00 andeq r0, r0, r0, lsl #20
a18: 28ff0100 ldmcs pc!, {r8}^ ; <UNPREDICTABLE>
a1c: 00000056 andeq r0, r0, r6, asr r0
a1c: R_ARM_ABS32 .text.ISR_USART1
a20: 00001508 andeq r1, r0, r8, lsl #10
a24: 02510129 subseq r0, r1, #1073741834 ; 0x4000000a
a28: 00007791 muleq r0, r1, r7
a2c: a4020102 strge r0, [r2], #-258 ; 0xfffffefe
a2f: R_ARM_ABS32 .debug_str
a30: 3a000001 bcc a3c <.debug_info+0xa3c>
a34: 00000164 andeq r0, r0, r4, ror #2
a34: R_ARM_ABS32 .debug_str
a38: 00011b01 andeq r1, r1, r1, lsl #22
a3b: R_ARM_ABS32 .text.ISR_USART2
a3c: cc000000 stcgt 0, cr0, [r0], {-0}
a40: 01000000 mrseq r0, (UNDEF: 0)
a44: 000b5e9c muleq fp, ip, lr
a48: 01531f00 cmpeq r3, r0, lsl #30
a4a: R_ARM_ABS32 .debug_str
a4c: 1c010000 stcne 0, cr0, [r1], {-0}
a50: 0000ff01 andeq pc, r0, r1, lsl #30
a54: 00062000 andeq r2, r6, r0
a55: R_ARM_ABS32 .debug_loc
a58: 73633b00 cmnvc r3, #0, 22
a5c: 011d0100 tsteq sp, r0, lsl #2
a60: 00000a2c andeq r0, r0, ip, lsr #20
a64: 3b779102 blcc 1de4e74 <usart+0x1de4e2c>
a68: 00726573 rsbseq r6, r2, r3, ror r5
a6c: ca011e01 bgt 48278 <usart+0x48230>
a70: 06000004 streq r0, [r0], -r4
a74: 00004803 andeq r4, r0, r3, lsl #16
a75: R_ARM_ABS32 .bss
a78: 673c9f00 ldrvs r9, [ip, -r0, lsl #30]!
a7c: 30000004 andcc r0, r0, r4
a7f: R_ARM_ABS32 .text.ISR_USART2
a80: 0e000000 cdpeq 0, 0, cr0, cr0, cr0, {0}
a84: 01000000 mrseq r0, (UNDEF: 0)
a88: 0a980126 beq fe600f28 <usart+0xfe600ee0>
a8c: 77270000 strvc r0, [r7, -r0]!
a90: 3e000004 cdpcc 0, 0, cr0, cr0, cr4, {0}
a93: R_ARM_ABS32 .debug_loc
a94: 00000006 andeq r0, r0, r6
a98: 0006683c andeq r6, r6, ip, lsr r8
a9c: 00004200 andeq r4, r0, r0, lsl #4
a9d: R_ARM_ABS32 .text.ISR_USART2
aa0: 00001600 andeq r1, r0, r0, lsl #12
aa4: 01270100 ; <UNDEFINED> instruction: 0x01270100
aa8: 00000ad2 ldrdeq r0, [r0], -r2
aac: 00067f27 andeq r7, r6, r7, lsr #30
ab0: 00065600 andeq r5, r6, r0, lsl #12
ab1: R_ARM_ABS32 .debug_loc
ab4: 06742700 ldrbteq r2, [r4], -r0, lsl #14
ab8: 06690000 strbteq r0, [r9], -r0
aba: R_ARM_ABS32 .debug_loc
abc: 422b0000 eormi r0, fp, #0
abf: R_ARM_ABS32 .text.ISR_USART2
ac0: 16000000 strne r0, [r0], -r0
ac4: 2c000000 stccs 0, cr0, [r0], {-0}
ac8: 0000068a andeq r0, r0, sl, lsl #13
acc: 00000681 andeq r0, r0, r1, lsl #13
acc: R_ARM_ABS32 .debug_loc
ad0: 453c0000 ldrmi r0, [ip, #-0]!
ad4: 6c000004 stcvs 0, cr0, [r0], {4}
ad7: R_ARM_ABS32 .text.ISR_USART2
ad8: 0a000000 beq ae0 <.debug_info+0xae0>
adc: 01000000 mrseq r0, (UNDEF: 0)
ae0: 0af0012d beq ffc00f9c <usart+0xffc00f54>
ae4: 55270000 strpl r0, [r7, #-0]!
ae8: b0000004 andlt r0, r0, r4
aeb: R_ARM_ABS32 .debug_loc
aec: 00000006 andeq r0, r0, r6
af0: 0005413c andeq r4, r5, ip, lsr r1
af4: 00008800 andeq r8, r0, r0, lsl #16
af5: R_ARM_ABS32 .text.ISR_USART2
af8: 00001600 andeq r1, r0, r0, lsl #12
afc: 01310100 teqeq r1, r0, lsl #2
b00: 00000b2a andeq r0, r0, sl, lsr #22
b04: 00055127 andeq r5, r5, r7, lsr #2
b08: 0006c800 andeq ip, r6, r0, lsl #16
b09: R_ARM_ABS32 .debug_loc
b0c: 00882b00 addeq r2, r8, r0, lsl #22
b0e: R_ARM_ABS32 .text.ISR_USART2
b10: 00160000 andseq r0, r6, r0
b14: 5c2c0000 stcpl 0, cr0, [ip], #-0
b18: e0000005 and r0, r0, r5
b1b: R_ARM_ABS32 .debug_loc
b1c: 2c000006 stccs 0, cr0, [r0], {6}
b20: 00000567 andeq r0, r0, r7, ror #10
b24: 0000070f andeq r0, r0, pc, lsl #14
b24: R_ARM_ABS32 .debug_loc
b28: 833d0000 teqhi sp, #0
b2c: aa000004 bge 18 <.debug_info+0x18>
b2f: R_ARM_ABS32 .text.ISR_USART2
b30: 0a000000 beq b38 <.debug_info+0xb38>
b34: 01000000 mrseq r0, (UNDEF: 0)
b38: 2e3e0136 mrccs 1, 1, r0, cr14, cr6, {1}
b3b: R_ARM_ABS32 .text.ISR_USART2
b3c: e2000000 and r0, r0, #0
b40: 4d000004 stcmi 0, cr0, [r0, #-16]
b44: 2900000b stmdbcs r0, {r0, r1, r3}
b48: 30015101 andcc r5, r1, r1, lsl #2
b4c: 00642800 rsbeq r2, r4, r0, lsl #16
b4e: R_ARM_ABS32 .text.ISR_USART2
b50: 15080000 strne r0, [r8, #-0]
b54: 01290000 ; <UNDEFINED> instruction: 0x01290000
b58: 77910251 ; <UNDEFINED> instruction: 0x77910251
b5c: 6f3a0000 svcvs 0x003a0000
b5f: R_ARM_ABS32 .debug_str
b60: 01000001 tsteq r0, r1
b64: 0000013a andeq r0, r0, sl, lsr r1
b66: R_ARM_ABS32 .text.ISR_USART3
b68: 00cc0000 sbceq r0, ip, r0
b6c: 9c010000 stcls 0, cr0, [r1], {-0}
b70: 00000c89 andeq r0, r0, r9, lsl #25
b74: 0001531f andeq r5, r1, pc, lsl r3
b75: R_ARM_ABS32 .debug_str
b78: 013b0100 teqeq fp, r0, lsl #2
b7c: 000000ff strdeq r0, [r0], -pc ; <UNPREDICTABLE>
b80: 00000722 andeq r0, r0, r2, lsr #14
b80: R_ARM_ABS32 .debug_loc
b84: 0073633b rsbseq r6, r3, fp, lsr r3
b88: 2c013c01 stccs 12, cr3, [r1], {1}
b8c: 0200000a andeq r0, r0, #10
b90: 733b7791 teqvc fp, #38010880 ; 0x2440000
b94: 01007265 tsteq r0, r5, ror #4
b98: 04ca013d strbeq r0, [sl], #317 ; 0x13d
b9c: 03060000 movweq r0, #24576 ; 0x6000
ba0: 000000d0 ldrdeq r0, [r0], -r0 ; <UNPREDICTABLE>
ba0: R_ARM_ABS32 .bss
ba4: 04673c9f strbteq r3, [r7], #-3231 ; 0xfffff361
ba8: 00320000 eorseq r0, r2, r0
baa: R_ARM_ABS32 .text.ISR_USART3
bac: 000e0000 andeq r0, lr, r0
bb0: 45010000 strmi r0, [r1, #-0]
bb4: 000bc301 andeq ip, fp, r1, lsl #6
bb8: 04772700 ldrbteq r2, [r7], #-1792 ; 0xfffff900
bbc: 07400000 strbeq r0, [r0, -r0]
bbe: R_ARM_ABS32 .debug_loc
bc0: 3c000000 stccc 0, cr0, [r0], {-0}
bc4: 00000668 andeq r0, r0, r8, ror #12
bc8: 00000044 andeq r0, r0, r4, asr #32
bc8: R_ARM_ABS32 .text.ISR_USART3
bcc: 00000016 andeq r0, r0, r6, lsl r0
bd0: fd014601 stc2 6, cr4, [r1, #-4]
bd4: 2700000b strcs r0, [r0, -fp]
bd8: 0000067f andeq r0, r0, pc, ror r6
bdc: 00000758 andeq r0, r0, r8, asr r7
bdc: R_ARM_ABS32 .debug_loc
be0: 00067427 andeq r7, r6, r7, lsr #8
be4: 00076b00 andeq r6, r7, r0, lsl #22
be5: R_ARM_ABS32 .debug_loc
be8: 00442b00 subeq r2, r4, r0, lsl #22
bea: R_ARM_ABS32 .text.ISR_USART3
bec: 00160000 andseq r0, r6, r0
bf0: 8a2c0000 bhi b00bf8 <usart+0xb00bb0>
bf4: 83000006 movwhi r0, #6
bf7: R_ARM_ABS32 .debug_loc
bf8: 00000007 andeq r0, r0, r7
bfc: 04453c00 strbeq r3, [r5], #-3072 ; 0xfffff400
c00: 006e0000 rsbeq r0, lr, r0
c02: R_ARM_ABS32 .text.ISR_USART3
c04: 000a0000 andeq r0, sl, r0
c08: 4c010000 stcmi 0, cr0, [r1], {-0}
c0c: 000c1b01 andeq r1, ip, r1, lsl #22
c10: 04552700 ldrbeq r2, [r5], #-1792 ; 0xfffff900
c14: 07b20000 ldreq r0, [r2, r0]!
c16: R_ARM_ABS32 .debug_loc
c18: 3c000000 stccc 0, cr0, [r0], {-0}
c1c: 00000541 andeq r0, r0, r1, asr #10
c20: 0000008a andeq r0, r0, sl, lsl #1
c20: R_ARM_ABS32 .text.ISR_USART3
c24: 00000016 andeq r0, r0, r6, lsl r0
c28: 55015001 strpl r5, [r1, #-1]
c2c: 2700000c strcs r0, [r0, -ip]
c30: 00000551 andeq r0, r0, r1, asr r5
c34: 000007ca andeq r0, r0, sl, asr #15
c34: R_ARM_ABS32 .debug_loc
c38: 00008a2b andeq r8, r0, fp, lsr #20
c39: R_ARM_ABS32 .text.ISR_USART3
c3c: 00001600 andeq r1, r0, r0, lsl #12
c40: 055c2c00 ldrbeq r2, [ip, #-3072] ; 0xfffff400
c44: 07e20000 strbeq r0, [r2, r0]!
c46: R_ARM_ABS32 .debug_loc
c48: 672c0000 strvs r0, [ip, -r0]!
c4c: 11000005 tstne r0, r5
c4f: R_ARM_ABS32 .debug_loc
c50: 00000008 andeq r0, r0, r8
c54: 04833d00 streq r3, [r3], #3328 ; 0xd00
c58: 00ac0000 adceq r0, ip, r0
c5a: R_ARM_ABS32 .text.ISR_USART3
c5c: 000a0000 andeq r0, sl, r0
c60: 55010000 strpl r0, [r1, #-0]
c64: 00303e01 eorseq r3, r0, r1, lsl #28
c66: R_ARM_ABS32 .text.ISR_USART3
c68: 04e20000 strbteq r0, [r2], #0
c6c: 0c780000 ldcleq 0, cr0, [r8], #-0
c70: 01290000 ; <UNDEFINED> instruction: 0x01290000
c74: 00310151 eorseq r0, r1, r1, asr r1
c78: 00006628 andeq r6, r0, r8, lsr #12
c79: R_ARM_ABS32 .text.ISR_USART3
c7c: 00150800 andseq r0, r5, r0, lsl #16
c80: 51012900 tstpl r1, r0, lsl #18
c84: 00779102 rsbseq r9, r7, r2, lsl #2
c88: 05073f00 streq r3, [r7, #-3840] ; 0xfffff100
c8a: R_ARM_ABS32 .debug_str
c8c: 7a010000 bvc 40c94 <usart+0x40c4c>
c90: 00002501 andeq r2, r0, r1, lsl #10
c94: 00000000 andeq r0, r0, r0
c95: R_ARM_ABS32 .text.lcdReadButtons
c98: 00002c00 andeq r2, r0, r0, lsl #24
c9c: c49c0100 ldrgt r0, [ip], #256 ; 0x100
ca0: 1e00000c cdpne 0, 0, cr0, cr0, cr12, {0}
ca4: 000002a8 andeq r0, r0, r8, lsr #5
ca4: R_ARM_ABS32 .debug_str
ca8: 4a017a01 bmi 5f4b4 <usart+0x5f46c>
cac: 24000006 strcs r0, [r0], #-6
caf: R_ARM_ABS32 .debug_loc
cb0: 1f000008 svcne 0x00000008
cb4: 000003d7 ldrdeq r0, [r0], -r7
cb4: R_ARM_ABS32 .debug_str
cb8: ad017b01 vstrge d7, [r1, #-4]
cbc: 6b000000 blvs 8 <.debug_info+0x8>
cbf: R_ARM_ABS32 .debug_loc
cc0: 00000008 andeq r0, r0, r8
cc4: 00014340 andeq r4, r1, r0, asr #6
cc5: R_ARM_ABS32 .debug_str
cc8: 01850100 orreq r0, r5, r0, lsl #2
ccc: 00000000 andeq r0, r0, r0
ccc: R_ARM_ABS32 .text.lcdSetBacklight
cd0: 00000028 andeq r0, r0, r8, lsr #32
cd4: 0d099c01 stceq 12, cr9, [r9, #-4]
cd8: a81e0000 ldmdage lr, {} ; <UNPREDICTABLE>
cdb: R_ARM_ABS32 .debug_str
cdc: 01000002 tsteq r0, r2
ce0: 064a0185 strbeq r0, [sl], -r5, lsl #3
ce4: 08a90000 stmiaeq r9!, {} ; <UNPREDICTABLE>
ce6: R_ARM_ABS32 .debug_loc
ce8: 32410000 subcc r0, r1, #0
ceb: R_ARM_ABS32 .debug_str
cec: 01000000 mrseq r0, (UNDEF: 0)
cf0: 0a2c0185 beq b0130c <usart+0xb012c4>
cf4: 51010000 mrspl r0, (UNDEF: 1)
cf8: 0003d71f andeq sp, r3, pc, lsl r7
cf9: R_ARM_ABS32 .debug_str
cfc: 01860100 orreq r0, r6, r0, lsl #2
d00: 000000ad andeq r0, r0, sp, lsr #1
d04: 000008d7 ldrdeq r0, [r0], -r7
d04: R_ARM_ABS32 .debug_loc
d08: 00584000 subseq r4, r8, r0
d0a: R_ARM_ABS32 .debug_str
d0c: 91010000 mrsls r0, (UNDEF: 1)
d10: 00000001 andeq r0, r0, r1
d11: R_ARM_ABS32 .text._lcdDump
d14: 0000a800 andeq sl, r0, r0, lsl #16
d18: 699c0100 ldmibvs ip, {r8}
d1c: 1e00000e cdpne 0, 0, cr0, cr0, cr14, {0}
d20: 00000410 andeq r0, r0, r0, lsl r4
d20: R_ARM_ABS32 .debug_str
d24: ad019101 stfged f1, [r1, #-4]
d28: fa000000 blx 8 <.debug_info+0x8>
d2b: R_ARM_ABS32 .debug_loc
d2c: 1f000008 svcne 0x00000008
d30: 00000025 andeq r0, r0, r5, lsr #32
d30: R_ARM_ABS32 .debug_str
d34: 97019301 strls r9, [r1, -r1, lsl #6]
d38: 40000000 andmi r0, r0, r0
d3b: R_ARM_ABS32 .debug_loc
d3c: 1f000009 svcne 0x00000009
d40: 0000056f andeq r0, r0, pc, ror #10
d40: R_ARM_ABS32 .debug_str
d44: 97019301 strls r9, [r1, -r1, lsl #6]
d48: 6a000000 bvs 8 <.debug_info+0x8>
d4b: R_ARM_ABS32 .debug_loc
d4c: 32000009 andcc r0, r0, #9
d50: 000000a8 andeq r0, r0, r8, lsr #1
d50: R_ARM_ABS32 .debug_ranges
d54: 0002a81f andeq sl, r2, pc, lsl r8
d55: R_ARM_ABS32 .debug_str
d58: 01960100 orrseq r0, r6, r0, lsl #2
d5c: 0000064a andeq r0, r0, sl, asr #12
d60: 00000993 muleq r0, r3, r9
d60: R_ARM_ABS32 .debug_loc
d64: 0001531f andeq r5, r1, pc, lsl r3
d65: R_ARM_ABS32 .debug_str
d68: 01970100 orrseq r0, r7, r0, lsl #2
d6c: 000000ff strdeq r0, [r0], -pc ; <UNPREDICTABLE>
d70: 000009c1 andeq r0, r0, r1, asr #19
d70: R_ARM_ABS32 .debug_loc
d74: 72747042 rsbsvc r7, r4, #66 ; 0x42
d78: 01970100 orrseq r0, r7, r0, lsl #2
d7c: 000000f9 strdeq r0, [r0], -r9
d80: 000009d4 ldrdeq r0, [r0], -r4
d80: R_ARM_ABS32 .debug_loc
d84: 00006443 andeq r6, r0, r3, asr #8
d85: R_ARM_ABS32 .text._lcdDump
d88: 00002c00 andeq r2, r0, r0, lsl #24
d8c: 000dd400 andeq sp, sp, r0, lsl #8
d90: 00694200 rsbeq r4, r9, r0, lsl #4
d94: ad01aa01 vstrge s20, [r1, #-4]
d98: e7000000 str r0, [r0, -r0]
d9b: R_ARM_ABS32 .debug_loc
d9c: 3e000009 cdpcc 0, 0, cr0, cr0, cr9, {0}
da0: 0000007a andeq r0, r0, sl, ror r0
da0: R_ARM_ABS32 .text._lcdDump
da4: 00000696 muleq r0, r6, r6
da8: 00000dbd ; <UNDEFINED> instruction: 0x00000dbd
dac: 02510129 subseq r0, r1, #1073741834 ; 0x4000000a
db0: 01290075 ; <UNDEFINED> instruction: 0x01290075
db4: 00780650 rsbseq r0, r8, r0, asr r6
db8: 26482448 strbcs r2, [r8], -r8, asr #8
dbc: 00882800 addeq r2, r8, r0, lsl #16
dbe: R_ARM_ABS32 .text._lcdDump
dc0: 06960000 ldreq r0, [r6], r0
dc4: 01290000 ; <UNDEFINED> instruction: 0x01290000
dc8: 00750251 rsbseq r0, r5, r1, asr r2
dcc: 02500129 subseq r0, r0, #1073741834 ; 0x4000000a
dd0: 00002008 andeq r2, r0, r8
dd4: 00003e3e andeq r3, r0, lr, lsr lr
dd5: R_ARM_ABS32 .text._lcdDump
dd8: 00069600 andeq r9, r6, r0, lsl #12
ddc: 000dee00 andeq lr, sp, r0, lsl #28
de0: 51012900 tstpl r1, r0, lsl #18
de4: 29007502 stmdbcs r0, {r1, r8, sl, ip, sp, lr}
de8: 08025001 stmdaeq r2, {r0, ip, lr}
dec: 463e00aa ldrtmi r0, [lr], -sl, lsr #1
def: R_ARM_ABS32 .text._lcdDump
df0: 96000000 strls r0, [r0], -r0
df4: 08000006 stmdaeq r0, {r1, r2}
df8: 2900000e stmdbcs r0, {r1, r2, r3}
dfc: 75025101 strvc r5, [r2, #-257] ; 0xfffffeff
e00: 50012900 andpl r2, r1, r0, lsl #18
e04: 00550802 subseq r0, r5, r2, lsl #16
e08: 00004e3e andeq r4, r0, lr, lsr lr
e09: R_ARM_ABS32 .text._lcdDump
e0c: 00069600 andeq r9, r6, r0, lsl #12
e10: 000e2100 andeq r2, lr, r0, lsl #2
e14: 51012900 tstpl r1, r0, lsl #18
e18: 29007502 stmdbcs r0, {r1, r8, sl, ip, sp, lr}
e1c: 4e015001 cdpmi 0, 0, cr5, cr1, cr1, {0}
e20: 005a3e00 subseq r3, sl, r0, lsl #28
e22: R_ARM_ABS32 .text._lcdDump
e24: 06960000 ldreq r0, [r6], r0
e28: 0e3a0000 cdpeq 0, 3, cr0, cr10, cr0, {0}
e2c: 01290000 ; <UNDEFINED> instruction: 0x01290000
e30: 00750251 rsbseq r0, r5, r1, asr r2
e34: 01500129 cmpeq r0, r9, lsr #2
e38: 623e0042 eorsvs r0, lr, #66 ; 0x42
e3b: R_ARM_ABS32 .text._lcdDump
e3c: 96000000 strls r0, [r0], -r0
e40: 54000006 strpl r0, [r0], #-6
e44: 2900000e stmdbcs r0, {r1, r2, r3}
e48: 75025101 strvc r5, [r2, #-257] ; 0xfffffeff
e4c: 50012900 andpl r2, r1, r0, lsl #18
e50: 00007402 andeq r7, r0, r2, lsl #8
e54: 00009e33 andeq r9, r0, r3, lsr lr
e55: R_ARM_ABS32 .text._lcdDump
e58: 00069600 andeq r9, r6, r0, lsl #12
e5c: 51012900 tstpl r1, r0, lsl #18
e60: 5001f305 andpl pc, r1, r5, lsl #6
e64: 00000123 andeq r0, r0, r3, lsr #2
e68: 001a4000 andseq r4, sl, r0
e6a: R_ARM_ABS32 .debug_str
e6c: bf010000 svclt 0x00010000
e70: 00000001 andeq r0, r0, r1
e71: R_ARM_ABS32 .text.lcdSetText
e74: 00003c00 andeq r3, r0, r0, lsl #24
e78: e89c0100 ldm ip, {r8}
e7c: 1e00000e cdpne 0, 0, cr0, cr0, cr14, {0}
e80: 000002a8 andeq r0, r0, r8, lsr #5
e80: R_ARM_ABS32 .debug_str
e84: 4a01bf01 bmi 70a90 <usart+0x70a48>
e88: 28000006 stmdacs r0, {r1, r2}
e8b: R_ARM_ABS32 .debug_loc
e8c: 1e00000a cdpne 0, 0, cr0, cr0, cr10, {0}
e90: 00000053 andeq r0, r0, r3, asr r0
e90: R_ARM_ABS32 .debug_str
e94: 5001bf01 andpl fp, r1, r1, lsl #30
e98: 56000000 strpl r0, [r0], -r0
e9b: R_ARM_ABS32 .debug_loc
e9c: 1e00000a cdpne 0, 0, cr0, cr0, cr10, {0}
ea0: 0000002b andeq r0, r0, fp, lsr #32
ea0: R_ARM_ABS32 .debug_str
ea4: 0601bf01 streq fp, [r1], -r1, lsl #30
ea8: 86000001 strhi r0, [r0], -r1
eab: R_ARM_ABS32 .debug_loc
eac: 1f00000a svcne 0x0000000a
eb0: 000003d7 ldrdeq r0, [r0], -r7
eb0: R_ARM_ABS32 .debug_str
eb4: ad01c101 stfged f4, [r1, #-4]
eb8: a4000000 strge r0, [r0], #-0
ebb: R_ARM_ABS32 .debug_loc
ebc: 4200000a andmi r0, r0, #10
ec0: c1010069 tstgt r1, r9, rrx
ec4: 0000ad01 andeq sl, r0, r1, lsl #26
ec8: 000ac700 andeq ip, sl, r0, lsl #14
ec9: R_ARM_ABS32 .debug_loc
ecc: 00102b00 andseq r2, r0, r0, lsl #22
ece: R_ARM_ABS32 .text.lcdSetText
ed0: 002c0000 eoreq r0, ip, r0
ed4: 73420000 movtvc r0, #8192 ; 0x2000
ed8: 01007263 tsteq r0, r3, ror #4
edc: 00f901c5 rscseq r0, r9, r5, asr #3
ee0: 0b100000 bleq 400008 <usart+0x3fffc0>
ee2: R_ARM_ABS32 .debug_loc
ee4: 00000000 andeq r0, r0, r0
ee8: 00052e40 andeq r2, r5, r0, asr #28
ee9: R_ARM_ABS32 .debug_str
eec: 01590100 cmpeq r9, r0, lsl #2
ef0: 00000000 andeq r0, r0, r0
ef0: R_ARM_ABS32 .text.lcdClear
ef4: 00000020 andeq r0, r0, r0, lsr #32
ef8: 0f4d9c01 svceq 0x004d9c01
efc: a81e0000 ldmdage lr, {} ; <UNPREDICTABLE>
eff: R_ARM_ABS32 .debug_str
f00: 01000002 tsteq r0, r2
f04: 064a0159 ; <UNDEFINED> instruction: 0x064a0159
f08: 0b530000 bleq 14c0008 <usart+0x14bffc0>
f0a: R_ARM_ABS32 .debug_loc
f0c: 0e3e0000 cdpeq 0, 3, cr0, cr14, cr0, {0}
f0f: R_ARM_ABS32 .text.lcdClear
f10: 69000000 stmdbvs r0, {} ; <UNPREDICTABLE>
f14: 2d00000e stccs 0, cr0, [r0, #-56] ; 0xffffffc8
f18: 2900000f stmdbcs r0, {r0, r1, r2, r3}
f1c: 74025201 strvc r5, [r2], #-513 ; 0xfffffdff
f20: 51012900 tstpl r1, r0, lsl #18
f24: 01293101 ; <UNDEFINED> instruction: 0x01293101
f28: 00750250 rsbseq r0, r5, r0, asr r2
f2c: 001c3300 andseq r3, ip, r0, lsl #6
f2e: R_ARM_ABS32 .text.lcdClear
f30: 0e690000 cdpeq 0, 6, cr0, cr9, cr0, {0}
f34: 01290000 ; <UNDEFINED> instruction: 0x01290000
f38: 00030552 andeq r0, r3, r2, asr r5
f3b: R_ARM_ABS32 .rodata.str1.1
f3c: 29000000 stmdbcs r0, {} ; <UNPREDICTABLE>
f40: 32015101 andcc r5, r1, #1073741824 ; 0x40000000
f44: 03500129 cmpeq r0, #1073741834 ; 0x4000000a
f48: 005001f3 ldrsheq r0, [r0], #-19 ; 0xffffffed
f4c: 01324000 teqeq r2, r0
f4e: R_ARM_ABS32 .debug_str
f50: 6c010000 stcvs 0, cr0, [r1], {-0}
f54: 00000001 andeq r0, r0, r1
f55: R_ARM_ABS32 .text.lcdPrint
f58: 00003400 andeq r3, r0, r0, lsl #8
f5c: f49c0100 ; <UNDEFINED> instruction: 0xf49c0100
f60: 1e00000f cdpne 0, 0, cr0, cr0, cr15, {0}
f64: 000002a8 andeq r0, r0, r8, lsr #5
f64: R_ARM_ABS32 .debug_str
f68: 4a016c01 bmi 5bf74 <usart+0x5bf2c>
f6c: 8a000006 bhi 20 <.debug_info+0x20>
f6f: R_ARM_ABS32 .debug_loc
f70: 1e00000b cdpne 0, 0, cr0, cr0, cr11, {0}
f74: 00000053 andeq r0, r0, r3, asr r0
f74: R_ARM_ABS32 .debug_str
f78: 50016c01 andpl r6, r1, r1, lsl #24
f7c: b6000000 strlt r0, [r0], -r0
f7f: R_ARM_ABS32 .debug_loc
f80: 4400000b strmi r0, [r0], #-11
f84: 00746d66 rsbseq r6, r4, r6, ror #26
f88: 06016c01 streq r6, [r1], -r1, lsl #24
f8c: 02000001 andeq r0, r0, #1
f90: 46457891 ; <UNDEFINED> instruction: 0x46457891
f94: 0000002b andeq r0, r0, fp, lsr #32
f94: R_ARM_ABS32 .debug_str
f98: f4016d01 ; <UNDEFINED> instruction: 0xf4016d01
f9c: 0200000f andeq r0, r0, #15
fa0: ec465491 cfstrd mvd5, [r6], {145} ; 0x91
fa3: R_ARM_ABS32 .debug_str
fa4: 01000002 tsteq r0, r2
fa8: 00dc016f sbcseq r0, ip, pc, ror #2
fac: 91020000 mrsls r0, (UNDEF: 2)
fb0: 001a3e50 andseq r3, sl, r0, asr lr
fb2: R_ARM_ABS32 .text.lcdPrint
fb4: 15280000 strne r0, [r8, #-0]!
fb8: 0fd70000 svceq 0x00d70000
fbc: 01290000 ; <UNDEFINED> instruction: 0x01290000
fc0: 6c910253 lfmvs f0, 4, [r1], {83} ; 0x53
fc4: 03520129 cmpeq r2, #1073741834 ; 0x4000000a
fc8: 29066891 stmdbcs r6, {r0, r4, r7, fp, sp, lr}
fcc: 41015101 tstmi r1, r1, lsl #2
fd0: 02500129 subseq r0, r0, #1073741834 ; 0x4000000a
fd4: 28004491 stmdacs r0, {r0, r4, r7, sl, lr}
fd8: 0000002a andeq r0, r0, sl, lsr #32
fd8: R_ARM_ABS32 .text.lcdPrint
fdc: 00000e69 andeq r0, r0, r9, ror #28
fe0: 02520129 subseq r0, r2, #1073741834 ; 0x4000000a
fe4: 01294491 ; <UNDEFINED> instruction: 0x01294491
fe8: 00740251 rsbseq r0, r4, r1, asr r2
fec: 02500129 subseq r0, r0, #1073741834 ; 0x4000000a
ff0: 00000075 andeq r0, r0, r5, ror r0
ff4: 0000ff0c andeq pc, r0, ip, lsl #30
ff8: 00100400 andseq r0, r0, r0, lsl #8
ffc: 00f20d00 rscseq r0, r2, r0, lsl #26
1000: 00100000 andseq r0, r0, r0
1004: 00055e3f andeq r5, r5, pc, lsr lr
1005: R_ARM_ABS32 .debug_str
1008: 01e30100 mvneq r0, r0, lsl #2
100c: 000000ad andeq r0, r0, sp, lsr #1
1010: 00000000 andeq r0, r0, r0
1010: R_ARM_ABS32 .text.usartBufferCount
1014: 00000030 andeq r0, r0, r0, lsr r0
1018: 109e9c01 addsne r9, lr, r1, lsl #24
101c: d71e0000 ldrle r0, [lr, -r0]
101f: R_ARM_ABS32 .debug_str
1020: 01000003 tsteq r0, r3
1024: 04ca01e3 strbeq r0, [sl], #483 ; 0x1e3
1028: 0bd70000 bleq ff5c0008 <usart+0xff5bffc0>
102a: R_ARM_ABS32 .debug_loc
102c: 4e1f0000 cdpmi 0, 1, cr0, cr15, cr0, {0}
102f: R_ARM_ABS32 .debug_str
1030: 01000000 mrseq r0, (UNDEF: 0)
1034: 00ad01e4 adceq r0, sp, r4, ror #3
1038: 0bf80000 bleq ffe00008 <usart+0xffdfffc0>
103a: R_ARM_ABS32 .debug_loc
103c: f0460000 ; <UNDEFINED> instruction: 0xf0460000
103f: R_ARM_ABS32 .debug_str
1040: 01000004 tsteq r0, r4
1044: 00ad01e4 adceq r0, sp, r4, ror #3
1048: 53010000 movwpl r0, #4096 ; 0x1000
104c: 00048b3c andeq r8, r4, ip, lsr fp
1050: 00000200 andeq r0, r0, r0, lsl #4
1051: R_ARM_ABS32 .text.usartBufferCount
1054: 00000a00 andeq r0, r0, r0, lsl #20
1058: 01e50100 mvneq r0, r0, lsl #2
105c: 00001070 andeq r1, r0, r0, ror r0
1060: 0004d039 andeq sp, r4, r9, lsr r0
1064: 00000200 andeq r0, r0, r0, lsl #4
1065: R_ARM_ABS32 .text.usartBufferCount
1068: 00000200 andeq r0, r0, r0, lsl #4
106c: 004b0200 subeq r0, fp, r0, lsl #4
1070: 00049347 andeq r9, r4, r7, asr #6
1074: 00001400 andeq r1, r0, r0, lsl #8
1075: R_ARM_ABS32 .text.usartBufferCount
1078: 0000c000 andeq ip, r0, r0
1079: R_ARM_ABS32 .debug_ranges
107c: 01e80100 mvneq r0, r0, lsl #2
1080: 0000c032 andeq ip, r0, r2, lsr r0
1081: R_ARM_ABS32 .debug_ranges
1084: 049f2d00 ldreq r2, [pc], #3328 ; 108c <.debug_info+0x108c>
1088: 52010000 andpl r0, r1, #0
108c: 0004d939 andeq sp, r4, r9, lsr r9
1090: 00002000 andeq r2, r0, r0
1091: R_ARM_ABS32 .text.usartBufferCount
1094: 00000200 andeq r0, r0, r0, lsl #4
1098: 00540200 subseq r0, r4, r0, lsl #4
109c: 8e210000 cdphi 0, 2, cr0, cr1, cr0, {0}
109f: R_ARM_ABS32 .debug_str
10a0: 01000002 tsteq r0, r2
10a4: 00002c6d andeq r2, r0, sp, ror #24
10a8: 00000000 andeq r0, r0, r0
10a9: R_ARM_ABS32 .text.fcount
10ac: 00001c00 andeq r1, r0, r0, lsl #24
10b0: ff9c0100 ; <UNDEFINED> instruction: 0xff9c0100
10b4: 22000010 andcs r0, r0, #16
10b8: 000005a7 andeq r0, r0, r7, lsr #11
10b8: R_ARM_ABS32 .debug_str
10bc: 064a6d01 strbeq r6, [sl], -r1, lsl #26
10c0: 0c0b0000 stceq 0, cr0, [fp], {-0}
10c2: R_ARM_ABS32 .debug_loc
10c4: b3230000 ; <UNDEFINED> instruction: 0xb3230000
10c7: R_ARM_ABS32 .debug_str
10c8: 01000000 mrseq r0, (UNDEF: 0)
10cc: 0000ad6e andeq sl, r0, lr, ror #26
10d0: 000c5200 andeq r5, ip, r0, lsl #4
10d1: R_ARM_ABS32 .debug_loc
10d4: 00124800 andseq r4, r2, r0, lsl #16
10d6: R_ARM_ABS32 .text.fcount
10d8: 10040000 andne r0, r4, r0
10dc: 10f50000 rscsne r0, r5, r0
10e0: 01290000 ; <UNDEFINED> instruction: 0x01290000
10e4: 01f30e50 mvnseq r0, r0, asr lr
10e8: 081c3150 ldmdaeq ip, {r4, r6, r8, ip, sp}
10ec: 48031e88 stmdami r3, {r3, r7, r9, sl, fp, ip}
10ef: R_ARM_ABS32 .bss
10f0: 22000000 andcs r0, r0, #0
10f4: 00162e00 andseq r2, r6, r0, lsl #28
10f6: R_ARM_ABS32 .text.fcount
10f8: 154c0000 strbne r0, [ip, #-0]
10fc: 21000000 mrscs r0, (UNDEF: 0)
1100: 000004f5 strdeq r0, [r0], -r5
1100: R_ARM_ABS32 .debug_str
1104: 002c7a01 eoreq r7, ip, r1, lsl #20
1108: 00000000 andeq r0, r0, r0
110a: R_ARM_ABS32 .text.feof
110c: 00280000 eoreq r0, r8, r0
1110: 9c010000 stcls 0, cr0, [r1], {-0}
1114: 00001168 andeq r1, r0, r8, ror #2
1118: 0005a722 andeq sl, r5, r2, lsr #14
1119: R_ARM_ABS32 .debug_str
111c: 4a7a0100 bmi 1e81524 <usart+0x1e814dc>
1120: 90000006 andls r0, r0, r6
1123: R_ARM_ABS32 .debug_loc
1124: 2300000c movwcs r0, #12
1128: 000000b3 strheq r0, [r0], -r3
1128: R_ARM_ABS32 .debug_str
112c: 00ad7b01 adceq r7, sp, r1, lsl #22
1130: 0cd70000 ldcleq 0, cr0, [r7], {0}
1132: R_ARM_ABS32 .debug_loc
1134: 10480000 subne r0, r8, r0
1137: R_ARM_ABS32 .text.feof
1138: 61000000 mrsvs r0, (UNDEF: 0)
113c: 4b000015 blmi 1198 <.debug_info+0x1198>
1140: 29000011 stmdbcs r0, {r0, r4}
1144: f3035001 vhadd.u8 d5, d3, d1
1148: 28005001 stmdacs r0, {r0, ip, lr}
114c: 0000001c andeq r0, r0, ip, lsl r0
114c: R_ARM_ABS32 .text.feof
1150: 00001004 andeq r1, r0, r4
1154: 0e500129 rdfeqsp f0, f0, #1.0
1158: 315001f3 ldrshcc r0, [r0, #-19] ; 0xffffffed
115c: 1e88081c mcrne 8, 4, r0, cr8, cr12, {0}
1160: 00004803 andeq r4, r0, r3, lsl #16
1161: R_ARM_ABS32 .bss
1164: 00002200 andeq r2, r0, r0, lsl #4
1168: 0002e621 andeq lr, r2, r1, lsr #12
1169: R_ARM_ABS32 .debug_str
116c: f9980100 ; <UNDEFINED> instruction: 0xf9980100
1170: 00000000 andeq r0, r0, r0
1173: R_ARM_ABS32 .text.fgets
1174: 3a000000 bcc 117c <.debug_info+0x117c>
1178: 01000000 mrseq r0, (UNDEF: 0)
117c: 0011f19c mulseq r1, ip, r1
1180: 74733400 ldrbtvc r3, [r3], #-1024 ; 0xfffffc00
1184: 98010072 stmdals r1, {r1, r4, r5, r6}
1188: 000000f9 strdeq r0, [r0], -r9
118c: 00000d22 andeq r0, r0, r2, lsr #26
118c: R_ARM_ABS32 .debug_loc
1190: 6d756e34 ldclvs 14, cr6, [r5, #-208]! ; 0xffffff30
1194: 2c980100 ldfcss f0, [r8], {0}
1198: 40000000 andmi r0, r0, r0
119b: R_ARM_ABS32 .debug_loc
119c: 2200000d andcs r0, r0, #13
11a0: 000005a7 andeq r0, r0, r7, lsr #11
11a0: R_ARM_ABS32 .debug_str
11a4: 064a9801 strbeq r9, [sl], -r1, lsl #16
11a8: 0d910000 ldceq 0, cr0, [r1]
11aa: R_ARM_ABS32 .debug_loc
11ac: 70250000 eorvc r0, r5, r0
11b0: 01007274 tsteq r0, r4, ror r2
11b4: 0000f99a muleq r0, sl, r9
11b8: 000daf00 andeq sl, sp, r0, lsl #30
11b9: R_ARM_ABS32 .debug_loc
11bc: 01532300 cmpeq r3, r0, lsl #6
11be: R_ARM_ABS32 .debug_str
11c0: 9b010000 blls 411c8 <usart+0x41180>
11c4: 0000002c andeq r0, r0, ip, lsr #32
11c8: 00000dfb strdeq r0, [r0], -fp
11c8: R_ARM_ABS32 .debug_loc
11cc: 00000e3e andeq r0, r0, lr, lsr lr
11cd: R_ARM_ABS32 .text.fgets
11d0: 0010ff00 andseq pc, r0, r0, lsl #30
11d4: 0011e000 andseq lr, r1, r0
11d8: 50012900 andpl r2, r1, r0, lsl #18
11dc: 00007602 andeq r7, r0, r2, lsl #12
11e0: 00002028 andeq r2, r0, r8, lsr #32
11e1: R_ARM_ABS32 .text.fgets
11e4: 00057300 andeq r7, r5, r0, lsl #6
11e8: 50012900 andpl r2, r1, r0, lsl #18
11ec: 00007602 andeq r7, r0, r2, lsl #12
11f0: 01223a00 ; <UNDEFINED> instruction: 0x01223a00
11f2: R_ARM_ABS32 .debug_str
11f4: ed010000 stc 0, cr0, [r1, #-0]
11f8: 00000001 andeq r0, r0, r1
11f9: R_ARM_ABS32 .text.usartBufferInit
11fc: 00005400 andeq r5, r0, r0, lsl #8
1200: 829c0100 addshi r0, ip, #0, 2
1204: 49000012 stmdbmi r0, {r1, r4}
1208: 000004b0 ; <UNDEFINED> instruction: 0x000004b0
120c: 00000002 andeq r0, r0, r2
120c: R_ARM_ABS32 .text.usartBufferInit
1210: 000000e0 andeq r0, r0, r0, ror #1
1210: R_ARM_ABS32 .debug_ranges
1214: 3101ef01 tstcc r1, r1, lsl #30
1218: 4a000012 bmi 1268 <.debug_info+0x1268>
121c: 000004bd ; <UNDEFINED> instruction: 0x000004bd
1220: 01580306 cmpeq r8, r6, lsl #6
1222: R_ARM_ABS32 .bss
1224: 2f9f0000 svccs 0x009f0000
1228: 0000001a andeq r0, r0, sl, lsl r0
1228: R_ARM_ABS32 .text.usartBufferInit
122c: 00001576 andeq r1, r0, r6, ror r5
1230: 04b04900 ldrteq r4, [r0], #2304 ; 0x900
1234: 001a0000 andseq r0, sl, r0
1236: R_ARM_ABS32 .text.usartBufferInit
1238: 00f80000 rscseq r0, r8, r0
123a: R_ARM_ABS32 .debug_ranges
123c: f1010000 setend le
1240: 00125b01 andseq r5, r2, r1, lsl #22
1244: 04bd4a00 ldrteq r4, [sp], #2560 ; 0xa00
1248: 03060000 movweq r0, #24576 ; 0x6000
124c: 00000048 andeq r0, r0, r8, asr #32
124c: R_ARM_ABS32 .bss
1250: 00322f9f mlaseq r2, pc, pc, r2 ; <UNPREDICTABLE>
1252: R_ARM_ABS32 .text.usartBufferInit
1254: 15760000 ldrbne r0, [r6, #-0]!
1258: 47000000 strmi r0, [r0, -r0]
125c: 000004b0 ; <UNDEFINED> instruction: 0x000004b0
1260: 00000032 andeq r0, r0, r2, lsr r0
1260: R_ARM_ABS32 .text.usartBufferInit
1264: 00000118 andeq r0, r0, r8, lsl r1
1264: R_ARM_ABS32 .debug_ranges
1268: 4a01f301 bmi 7de74 <usart+0x7de2c>
126c: 000004bd ; <UNDEFINED> instruction: 0x000004bd
1270: 00d00306 sbcseq r0, r0, r6, lsl #6
1272: R_ARM_ABS32 .bss
1274: 2f9f0000 svccs 0x009f0000
1278: 0000004a andeq r0, r0, sl, asr #32
1278: R_ARM_ABS32 .text.usartBufferInit
127c: 00001576 andeq r1, r0, r6, ror r5
1280: ae3a0000 cdpge 0, 3, cr0, cr10, cr0, {0}
1283: R_ARM_ABS32 .debug_str
1284: 01000005 tsteq r0, r5
1288: 000001f7 strdeq r0, [r0], -r7
128a: R_ARM_ABS32 .text.usartFlushBuffers
128c: 002c0000 eoreq r0, ip, r0
1290: 9c010000 stcls 0, cr0, [r1], {-0}
1294: 000012b9 ; <UNDEFINED> instruction: 0x000012b9
1298: 0004d03d andeq sp, r4, sp, lsr r0
129c: 00000000 andeq r0, r0, r0
129d: R_ARM_ABS32 .text.usartFlushBuffers
12a0: 00000200 andeq r0, r0, r0, lsl #4
12a4: 01f80100 mvnseq r0, r0, lsl #2
12a8: 0004d93d andeq sp, r4, sp, lsr r9
12ac: 00002200 andeq r2, r0, r0, lsl #4
12ad: R_ARM_ABS32 .text.usartFlushBuffers
12b0: 00000a00 andeq r0, r0, r0, lsl #20
12b4: 01fc0100 mvnseq r0, r0, lsl #2
12b8: 03a54000 ; <UNDEFINED> instruction: 0x03a54000
12ba: R_ARM_ABS32 .debug_str
12bc: 01010000 mrseq r0, (UNDEF: 1)
12c0: 00000002 andeq r0, r0, r2
12c1: R_ARM_ABS32 .text.usartInit
12c4: 0000b400 andeq fp, r0, r0, lsl #8
12c8: a19c0100 orrsge r0, ip, r0, lsl #2
12cc: 1e000013 mcrne 0, 0, r0, cr0, cr3, {0}
12d0: 000003d7 ldrdeq r0, [r0], -r7
12d0: R_ARM_ABS32 .debug_str
12d4: 4a020101 bmi 816e0 <usart+0x81698>
12d8: 1b000006 blne 20 <.debug_info+0x20>
12db: R_ARM_ABS32 .debug_loc
12dc: 1e00000e cdpne 0, 0, cr0, cr0, cr14, {0}
12e0: 000001aa andeq r0, r0, sl, lsr #3
12e0: R_ARM_ABS32 .debug_str
12e4: 25020101 strcs r0, [r2, #-257] ; 0xfffffeff
12e8: 3c000000 stccc 0, cr0, [r0], {-0}
12eb: R_ARM_ABS32 .debug_loc
12ec: 1e00000e cdpne 0, 0, cr0, cr0, cr14, {0}
12f0: 00000025 andeq r0, r0, r5, lsr #32
12f0: R_ARM_ABS32 .debug_str
12f4: 25020101 strcs r0, [r2, #-257] ; 0xfffffeff
12f8: 5d000000 stcpl 0, cr0, [r0, #-0]
12fb: R_ARM_ABS32 .debug_loc
12fc: 1f00000e svcne 0x0000000e
1300: 000000de ldrdeq r0, [r0], -lr
1300: R_ARM_ABS32 .debug_str
1304: a1020301 tstge r2, r1, lsl #6
1308: 7e000013 mcrvc 0, 0, r0, cr0, cr3, {0}
130b: R_ARM_ABS32 .debug_loc
130c: 4900000e stmdbmi r0, {r1, r2, r3}
1310: 0000048b andeq r0, r0, fp, lsl #9
1314: 00000010 andeq r0, r0, r0, lsl r0
1314: R_ARM_ABS32 .text.usartInit
1318: 00000130 andeq r0, r0, r0, lsr r1
1318: R_ARM_ABS32 .debug_ranges
131c: 33020b01 movwcc r0, #11009 ; 0x2b01
1320: 39000013 stmdbcc r0, {r0, r1, r4}
1324: 000004d0 ldrdeq r0, [r0], -r0 ; <UNPREDICTABLE>
1328: 00000010 andeq r0, r0, r0, lsl r0
1328: R_ARM_ABS32 .text.usartInit
132c: 00000002 andeq r0, r0, r2
1330: 24004b02 strcs r4, [r0], #-2818 ; 0xfffff4fe
1334: 00000148 andeq r0, r0, r8, asr #2
1334: R_ARM_ABS32 .debug_ranges
1338: 0000136d andeq r1, r0, sp, ror #6
133c: 72726242 rsbsvc r6, r2, #536870916 ; 0x20000004
1340: 021d0100 andseq r0, sp, #0, 2
1344: 000000ad andeq r0, r0, sp, lsr #1
1348: 00000e91 muleq r0, r1, lr
1348: R_ARM_ABS32 .debug_loc
134c: 646f6d42 strbtvs r6, [pc], #-3394 ; 1354 <.debug_info+0x1354>
1350: 021d0100 andseq r0, sp, #0, 2
1354: 000000ad andeq r0, r0, sp, lsr #1
1358: 00000ebe ; <UNDEFINED> instruction: 0x00000ebe
1358: R_ARM_ABS32 .debug_loc
135c: 0005431f andeq r4, r5, pc, lsl r3
135d: R_ARM_ABS32 .debug_str
1360: 021d0100 andseq r0, sp, #0, 2
1364: 000000ad andeq r0, r0, sp, lsr #1
1368: 00000ed1 ldrdeq r0, [r0], -r1
1368: R_ARM_ABS32 .debug_loc
136c: 04934b00 ldreq r4, [r3], #2816 ; 0xb00
1370: 00940000 addseq r0, r4, r0
1372: R_ARM_ABS32 .text.usartInit
1374: 00200000 eoreq r0, r0, r0
1378: 20010000 andcs r0, r1, r0
137c: 00942b02 addseq r2, r4, r2, lsl #22
137e: R_ARM_ABS32 .text.usartInit
1380: 00200000 eoreq r0, r0, r0
1384: 9f2c0000 svcls 0x002c0000
1388: 17000004 strne r0, [r0, -r4]
138b: R_ARM_ABS32 .debug_loc
138c: 3900000f stmdbcc r0, {r0, r1, r2, r3}
1390: 000004d9 ldrdeq r0, [r0], -r9
1394: 0000009c muleq r0, ip, r0
1394: R_ARM_ABS32 .text.usartInit
1398: 00000018 andeq r0, r0, r8, lsl r0
139c: 00005402 andeq r5, r0, r2, lsl #8
13a0: 4c040800 stcmi 8, cr0, [r4], {-0}
13a4: 40000003 andmi r0, r0, r3
13a8: 00000244 andeq r0, r0, r4, asr #4
13a8: R_ARM_ABS32 .debug_str
13ac: 00015f01 andeq r5, r1, r1, lsl #30
13af: R_ARM_ABS32 .text.lcdInit
13b0: 30000000 andcc r0, r0, r0
13b4: 01000000 mrseq r0, (UNDEF: 0)
13b8: 0014049c mulseq r4, ip, r4
13bc: 02a81e00 adceq r1, r8, #0, 28
13be: R_ARM_ABS32 .debug_str
13c0: 5f010000 svcpl 0x00010000
13c4: 00064a01 andeq r4, r6, r1, lsl #20
13c8: 000f2a00 andeq r2, pc, r0, lsl #20
13c9: R_ARM_ABS32 .debug_loc
13cc: 00082b00 andeq r2, r8, r0, lsl #22
13ce: R_ARM_ABS32 .text.lcdInit
13d0: 00280000 eoreq r0, r8, r0
13d4: 69420000 stmdbvs r2, {}^ ; <UNPREDICTABLE>
13d8: 01007864 tsteq r0, r4, ror #16
13dc: 00ad0162 adceq r0, sp, r2, ror #2
13e0: 0f580000 svceq 0x00580000
13e2: R_ARM_ABS32 .debug_loc
13e4: 12280000 eorne r0, r8, #0
13e7: R_ARM_ABS32 .text.lcdInit
13e8: b9000000 stmdblt r0, {} ; <UNPREDICTABLE>
13ec: 29000012 stmdbcs r0, {r1, r4}
13f0: 30015201 andcc r5, r1, r1, lsl #4
13f4: 03510129 cmpeq r1, #1073741834 ; 0x4000000a
13f8: 294b000a stmdbcs fp, {r1, r3}^
13fc: 74025001 strvc r5, [r2], #-1
1400: 00000001 andeq r0, r0, r1
1404: 00008540 andeq r8, r0, r0, asr #10
1405: R_ARM_ABS32 .debug_str
1408: 02240100 eoreq r0, r4, #0, 2
140c: 00000000 andeq r0, r0, r0
140c: R_ARM_ABS32 .text.usartShutdown
1410: 00000020 andeq r0, r0, r0, lsr #32
1414: 14299c01 strtne r9, [r9], #-3073 ; 0xfffff3ff
1418: 4c410000 marmi acc0, r0, r1
141b: R_ARM_ABS32 .debug_str
141c: 01000002 tsteq r0, r2
1420: 064a0224 strbeq r0, [sl], -r4, lsr #4
1424: 50010000 andpl r0, r1, r0
1428: 025a4000 subseq r4, sl, #0
142a: R_ARM_ABS32 .debug_str
142c: d2010000 andle r0, r1, #0
1430: 00000001 andeq r0, r0, r1
1431: R_ARM_ABS32 .text.lcdShutdown
1434: 00002000 andeq r2, r0, r0
1438: 609c0100 addsvs r0, ip, r0, lsl #2
143c: 1e000014 mcrne 0, 0, r0, cr0, cr4, {0}
1440: 000002a8 andeq r0, r0, r8, lsr #5
1440: R_ARM_ABS32 .debug_str
1444: 4a01d201 bmi 75c50 <usart+0x75c08>
1448: 6b000006 blvs 20 <.debug_info+0x20>
144b: R_ARM_ABS32 .debug_loc
144c: 2800000f stmdacs r0, {r0, r1, r2, r3}
1450: 0000000c andeq r0, r0, ip
1450: R_ARM_ABS32 .text.lcdShutdown
1454: 00001404 andeq r1, r0, r4, lsl #8
1458: 02500129 subseq r0, r0, #1073741834 ; 0x4000000a
145c: 00000174 andeq r0, r0, r4, ror r1
1460: 0003e60c andeq lr, r3, ip, lsl #12
1464: 00147000 andseq r7, r4, r0
1468: 00f20d00 rscseq r0, r2, r0, lsl #26
146c: 00020000 andeq r0, r2, r0
1470: 00024c4c andeq r4, r2, ip, asr #24
1471: R_ARM_ABS32 .debug_str
1474: 603d0100 eorsvs r0, sp, r0, lsl #2
1478: 05000014 streq r0, [r0, #-20] ; 0xffffffec
147c: 00004803 andeq r4, r0, r3, lsl #16
147d: R_ARM_ABS32 .bss
1480: 043a0c00 ldrteq r0, [sl], #-3072 ; 0xfffff400
1484: 14910000 ldrne r0, [r1], #0
1488: f20d0000 vhadd.s8 d0, d13, d0
148c: 01000000 mrseq r0, (UNDEF: 0)
1490: 636c3700 cmnvs ip, #0, 14
1494: 40010064 andmi r0, r1, r4, rrx
1498: 00001481 andeq r1, r0, r1, lsl #9
149c: 00000305 andeq r0, r0, r5, lsl #6
149e: R_ARM_ABS32 .bss
14a0: 614d0000 mrsvs r0, (UNDEF: 77)
14a3: R_ARM_ABS32 .debug_str
14a4: 02000000 andeq r0, r0, #0
14a8: 00012347 andeq r2, r1, r7, asr #6
14ac: 01c24e00 biceq r4, r2, r0, lsl #28
14ae: R_ARM_ABS32 .debug_str
14b0: 430b0000 movwmi r0, #45056 ; 0xb000
14b4: 00000a2c andeq r0, r0, ip, lsr #20
14b8: 000014c7 andeq r1, r0, r7, asr #9
14bc: 0003634f andeq r6, r3, pc, asr #6
14c0: 14c74f00 strbne r4, [r7], #3840 ; 0xf00
14c4: 09000000 stmdbeq r0, {} ; <UNPREDICTABLE>
14c8: 00000082 andeq r0, r0, r2, lsl #1
14cc: 0002d94e andeq sp, r2, lr, asr #18
14cd: R_ARM_ABS32 .debug_str
14d0: 2c680c00 stclcs 12, cr0, [r8], #-0
14d4: e1000000 mrs r0, (UNDEF: 0)
14d8: 4f000014 svcmi 0x00000014
14dc: 0000064a andeq r0, r0, sl, asr #12
14e0: 02fa5000 rscseq r5, sl, #0
14e2: R_ARM_ABS32 .debug_str
14e4: 82020000 andhi r0, r2, #0
14e8: 000014ee andeq r1, r0, lr, ror #9
14ec: fd4e0045 stc2l 0, cr0, [lr, #-276] ; 0xfffffeec
14ef: R_ARM_ABS32 .debug_str
14f0: 0c000003 stceq 0, cr0, [r0], {3}
14f4: 00002c87 andeq r2, r0, r7, lsl #25
14f8: 00150800 andseq r0, r5, r0, lsl #16
14fc: 064a4f00 strbeq r4, [sl], -r0, lsl #30
1500: 2c4f0000 marcs acc0, r0, pc
1504: 00000000 andeq r0, r0, r0
1508: 0001064e andeq r0, r1, lr, asr #12
1509: R_ARM_ABS32 .debug_str
150c: 2c410b00 mcrrcs 11, 0, r0, r1, cr0
1510: 2200000a andcs r0, r0, #10
1514: 4f000015 svcmi 0x00000015
1518: 00000363 andeq r0, r0, r3, ror #6
151c: 0015224f andseq r2, r5, pc, asr #4
1520: 04080000 streq r0, [r8], #-0
1524: 00000a2c andeq r0, r0, ip, lsr #20
1528: 00059d4e andeq r9, r5, lr, asr #26
1529: R_ARM_ABS32 .debug_str
152c: 2c610800 stclcs 8, cr0, [r1], #-0
1530: 4c000000 stcmi 0, cr0, [r0], {-0}
1534: 4f000015 svcmi 0x00000015
1538: 000000f9 strdeq r0, [r0], -r9
153c: 0000334f andeq r3, r0, pc, asr #6
1540: 01064f00 tsteq r6, r0, lsl #30
1544: dc4f0000 marle acc0, r0, pc
1548: 00000000 andeq r0, r0, r0
154c: 0005004e andeq r0, r5, lr, asr #32
154d: R_ARM_ABS32 .debug_str
1550: ad580c00 ldclge 12, cr0, [r8, #-0]
1554: 61000000 mrsvs r0, (UNDEF: 0)
1558: 4f000015 svcmi 0x00000015
155c: 0000064a andeq r0, r0, sl, asr #12
1560: 02834e00 addeq r4, r3, #0, 28
1562: R_ARM_ABS32 .debug_str
1564: 480c0000 stmdami ip, {} ; <UNPREDICTABLE>
1568: 0000002c andeq r0, r0, ip, lsr #32
156c: 00001576 andeq r1, r0, r6, ror r5
1570: 00064a4f andeq r4, r6, pc, asr #20
1574: 19510000 ldmdbne r1, {}^ ; <UNPREDICTABLE>
1577: R_ARM_ABS32 .debug_str
1578: 0b000002 bleq 1588 <usart+0x1540>
157c: 0003633b andeq r6, r3, fp, lsr r3
1580: 00004500 andeq r4, r0, r0, lsl #10
Disassembly of section .debug_abbrev:
00000000 <.debug_abbrev>:
0: 25011101 strcs r1, [r1, #-257] ; 0xfffffeff
4: 030b130e movweq r1, #45838 ; 0xb30e
8: 550e1b0e strpl r1, [lr, #-2830] ; 0xfffff4f2
c: 10011117 andne r1, r1, r7, lsl r1
10: 02000017 andeq r0, r0, #23
14: 0b0b0024 bleq 2c00ac <usart+0x2c0064>
18: 0e030b3e vmoveq.16 d3[0], r0
1c: 24030000 strcs r0, [r3], #-0
20: 3e0b0b00 vmlacc.f64 d0, d11, d0
24: 0008030b andeq r0, r8, fp, lsl #6
28: 00160400 andseq r0, r6, r0, lsl #8
2c: 0b3a0e03 bleq e83840 <usart+0xe837f8>
30: 13490b3b movtne r0, #39739 ; 0x9b3b
34: 13050000 movwne r0, #20480 ; 0x5000
38: 0b0e0301 bleq 380c44 <usart+0x380bfc>
3c: 3b0b3a0b blcc 2ce870 <usart+0x2ce828>
40: 0013010b andseq r0, r3, fp, lsl #2
44: 000d0600 andeq r0, sp, r0, lsl #12
48: 13490e03 movtne r0, #40451 ; 0x9e03
4c: 19340b38 ldmdbne r4!, {r3, r4, r5, r8, r9, fp}
50: 0f070000 svceq 0x00070000
54: 000b0b00 andeq r0, fp, r0, lsl #22
58: 000f0800 andeq r0, pc, r0, lsl #16
5c: 13490b0b movtne r0, #39691 ; 0x9b0b
60: 26090000 strcs r0, [r9], -r0
64: 00134900 andseq r4, r3, r0, lsl #18
68: 00260a00 eoreq r0, r6, r0, lsl #20
6c: 350b0000 strcc r0, [fp, #-0]
70: 00134900 andseq r4, r3, r0, lsl #18
74: 01010c00 tsteq r1, r0, lsl #24
78: 13011349 movwne r1, #4937 ; 0x1349
7c: 210d0000 mrscs r0, (UNDEF: 13)
80: 2f134900 svccs 0x00134900
84: 0e00000b cdpeq 0, 0, cr0, cr0, cr11, {0}
88: 0b0b0113 bleq 2c04dc <usart+0x2c0494>
8c: 053b0b3a ldreq r0, [fp, #-2874]! ; 0xfffff4c6
90: 00001301 andeq r1, r0, r1, lsl #6
94: 03000d0f movweq r0, #3343 ; 0xd0f
98: 3b0b3a0e blcc 2ce8d8 <usart+0x2ce890>
9c: 38134905 ldmdacc r3, {r0, r2, r8, fp, lr}
a0: 1000000b andne r0, r0, fp
a4: 0803000d stmdaeq r3, {r0, r2, r3}
a8: 053b0b3a ldreq r0, [fp, #-2874]! ; 0xfffff4c6
ac: 0b381349 bleq e04dd8 <usart+0xe04d90>
b0: 16110000 ldrne r0, [r1], -r0
b4: 3a0e0300 bcc 380cbc <usart+0x380c74>
b8: 49053b0b stmdbmi r5, {r0, r1, r3, r8, r9, fp, ip, sp}
bc: 12000013 andne r0, r0, #19
c0: 0b0b0113 bleq 2c0514 <usart+0x2c04cc>
c4: 0b3b0b3a bleq ec2db4 <usart+0xec2d6c>
c8: 00001301 andeq r1, r0, r1, lsl #6
cc: 03000d13 movweq r0, #3347 ; 0xd13
d0: 3b0b3a0e blcc 2ce910 <usart+0x2ce8c8>
d4: 3813490b ldmdacc r3, {r0, r1, r3, r8, fp, lr}
d8: 1400000b strne r0, [r0], #-11
dc: 0803000d stmdaeq r3, {r0, r2, r3}
e0: 0b3b0b3a bleq ec2dd0 <usart+0xec2d88>
e4: 0b381349 bleq e04e10 <usart+0xe04dc8>
e8: 2e150000 cdpcs 0, 1, cr0, cr5, cr0, {0}
ec: 3a0e0301 bcc 380cf8 <usart+0x380cb0>
f0: 270b3b0b strcs r3, [fp, -fp, lsl #22]
f4: 20134919 andscs r4, r3, r9, lsl r9
f8: 0013010b andseq r0, r3, fp, lsl #2
fc: 00051600 andeq r1, r5, r0, lsl #12
100: 0b3a0e03 bleq e83914 <usart+0xe838cc>
104: 13490b3b movtne r0, #39739 ; 0x9b3b
108: 2e170000 cdpcs 0, 1, cr0, cr7, cr0, {0}
10c: 3a0e0300 bcc 380d14 <usart+0x380ccc>
110: 200b3b0b andcs r3, fp, fp, lsl #22
114: 1800000b stmdane r0, {r0, r1, r3}
118: 0e03012e adfeqsp f0, f3, #0.5
11c: 0b3b0b3a bleq ec2e0c <usart+0xec2dc4>
120: 13010b20 movwne r0, #6944 ; 0x1b20
124: 34190000 ldrcc r0, [r9], #-0
128: 3a0e0300 bcc 380d30 <usart+0x380ce8>
12c: 490b3b0b stmdbmi fp, {r0, r1, r3, r8, r9, fp, ip, sp}
130: 1a000013 bne 184 <.debug_abbrev+0x184>
134: 0e03012e adfeqsp f0, f3, #0.5
138: 053b0b3a ldreq r0, [fp, #-2874]! ; 0xfffff4c6
13c: 0b201927 bleq 8065e0 <usart+0x806598>
140: 00001301 andeq r1, r0, r1, lsl #6
144: 0300051b movweq r0, #1307 ; 0x51b
148: 3b0b3a0e blcc 2ce988 <usart+0x2ce940>
14c: 00134905 andseq r4, r3, r5, lsl #18
150: 002e1c00 eoreq r1, lr, r0, lsl #24
154: 0b3a0e03 bleq e83968 <usart+0xe83920>
158: 0b20053b bleq 80164c <usart+0x801604>
15c: 2e1d0000 cdpcs 0, 1, cr0, cr13, cr0, {0}
160: 3a0e0301 bcc 380d6c <usart+0x380d24>
164: 27053b0b strcs r3, [r5, -fp, lsl #22]
168: 12011119 andne r1, r1, #1073741830 ; 0x40000006
16c: 97184006 ldrls r4, [r8, -r6]
170: 13011942 movwne r1, #6466 ; 0x1942
174: 051e0000 ldreq r0, [lr, #-0]
178: 3a0e0300 bcc 380d80 <usart+0x380d38>
17c: 49053b0b stmdbmi r5, {r0, r1, r3, r8, r9, fp, ip, sp}
180: 00170213 andseq r0, r7, r3, lsl r2
184: 00341f00 eorseq r1, r4, r0, lsl #30
188: 0b3a0e03 bleq e8399c <usart+0xe83954>
18c: 1349053b movtne r0, #38203 ; 0x953b
190: 00001702 andeq r1, r0, r2, lsl #14
194: 03012e20 movweq r2, #7712 ; 0x1e20
198: 3b0b3a0e blcc 2ce9d8 <usart+0x2ce990>
19c: 2019270b andscs r2, r9, fp, lsl #14
1a0: 0013010b andseq r0, r3, fp, lsl #2
1a4: 012e2100 ; <UNDEFINED> instruction: 0x012e2100
1a8: 0e03193f mcreq 9, 0, r1, cr3, cr15, {1}
1ac: 0b3b0b3a bleq ec2e9c <usart+0xec2e54>
1b0: 13491927 movtne r1, #39207 ; 0x9927
1b4: 06120111 ; <UNDEFINED> instruction: 0x06120111
1b8: 42971840 addsmi r1, r7, #64, 16 ; 0x400000
1bc: 00130119 andseq r0, r3, r9, lsl r1
1c0: 00052200 andeq r2, r5, r0, lsl #4
1c4: 0b3a0e03 bleq e839d8 <usart+0xe83990>
1c8: 13490b3b movtne r0, #39739 ; 0x9b3b
1cc: 00001702 andeq r1, r0, r2, lsl #14
1d0: 03003423 movweq r3, #1059 ; 0x423
1d4: 3b0b3a0e blcc 2cea14 <usart+0x2ce9cc>
1d8: 0213490b andseq r4, r3, #180224 ; 0x2c000
1dc: 24000017 strcs r0, [r0], #-23 ; 0xffffffe9
_taskYield();
}
// lcdButtonProcess - Processes the VEX LCD buttons
static void lcdButtonProcess(char value, uint32_t index) {
uint16_t count = lcd[index].state;
1e0: 1755010b ldrbne r0, [r5, -fp, lsl #2]
1e4: 00001301 andeq r1, r0, r1, lsl #6
// If 0xAA, set count to 1
// If 0x55, set count to 2 if count == 1
// If 0x16, set count to 3 if count == 2
if (value == (char)0xAA)
1e8: 03003425 movweq r3, #1061 ; 0x425
_taskYield();
}
// lcdButtonProcess - Processes the VEX LCD buttons
static void lcdButtonProcess(char value, uint32_t index) {
uint16_t count = lcd[index].state;
1ec: 3b0b3a08 blcc 2cea14 <usart+0x2ce9cc>
// If 0xAA, set count to 1
// If 0x55, set count to 2 if count == 1
// If 0x16, set count to 3 if count == 2
if (value == (char)0xAA)
count = 1;
else if (value == (char)0x55 && count == 1)
1f0: 0213490b andseq r4, r3, #180224 ; 0x2c000
1f4: 26000017 ; <UNDEFINED> instruction: 0x26000017
1f8: 1331011d teqne r1, #1073741831 ; 0x40000007
count = 2;
else if (value == (char)0x16 && count == 2)
1fc: 06120111 ; <UNDEFINED> instruction: 0x06120111
200: 0b590b58 bleq 1642f68 <usart+0x1642f20>
count = 3;
else if (value == (char)0x02 && count == 3)
204: 00001301 andeq r1, r0, r1, lsl #6
208: 31000527 tstcc r0, r7, lsr #10
// Size must be 2
count = 4;
else if (count == 4) {
20c: 00170213 andseq r0, r7, r3, lsl r2
lcd[index].buttons = (uint8_t)value;
210: 82892800 addhi r2, r9, #0, 16
214: 01110101 tsteq r1, r1, lsl #2
218: 00001331 andeq r1, r0, r1, lsr r3
uint16_t count = lcd[index].state;
// If 0xAA, set count to 1
// If 0x55, set count to 2 if count == 1
// If 0x16, set count to 3 if count == 2
if (value == (char)0xAA)
count = 1;
21c: 01828a29 orreq r8, r2, r9, lsr #20
else if (value == (char)0x55 && count == 1)
count = 2;
220: 91180200 tstls r8, r0, lsl #4
else if (value == (char)0x16 && count == 2)
count = 3;
224: 00001842 andeq r1, r0, r2, asr #16
else if (value == (char)0x02 && count == 3)
// Size must be 2
count = 4;
228: 31011d2a tstcc r1, sl, lsr #26
else if (count == 4) {
lcd[index].buttons = (uint8_t)value;
count = 0;
} else
// Ignore the checksum and any noise we pick up
count = 0;
22c: 12011113 andne r1, r1, #-1073741820 ; 0xc0000004
lcd[index].state = count;
230: 590b5806 stmdbpl fp, {r1, r2, fp, ip, lr}
234: 2b00000b blcs 268 <.debug_abbrev+0x268>
238: 0111010b tsteq r1, fp, lsl #2
return 1;
#endif
}
// fgetc - Read a character from the specified stream
int fgetc(FILE *stream) {
23c: 00000612 andeq r0, r0, r2, lsl r6
uint32_t snew = (uint32_t)stream - 1;
if (snew < 3) {
240: 3100342c tstcc r0, ip, lsr #8
SerialPort_TypeDef *ser = &usart[snew];
244: 00170213 andseq r0, r7, r3, lsl r2
248: 00342d00 eorseq r2, r4, r0, lsl #26
// Prototype this
uint32_t usartBufferCount(SerialPort_TypeDef* port);
// Checks to see if the ring buffer is empty (head = tail)
static INLINE uint8_t _isBufferEmpty(volatile RingBuffer_TypeDef* buffer) {
return buffer->head == buffer->tail;
24c: 18021331 stmdane r2, {r0, r4, r5, r8, r9, ip}
250: 892e0000 stmdbhi lr!, {} ; <UNPREDICTABLE>
}
// Waits for a byte in the given port's RX buffer
// This does not happen during init, so it is OK to use scheduler functions
static void _waitForByte(SerialPort_TypeDef* port) {
while (_isBufferEmpty(&(port->rx)))
254: 11000182 smlabbne r0, r2, r1, r0
258: 19429501 stmdbne r2, {r0, r8, sl, ip, pc}^
25c: 00001331 andeq r1, r0, r1, lsr r3
semaphoreTake(port->readLock, MAX_DELAY);
260: 0182892f orreq r8, r2, pc, lsr #18
264: 31011100 mrscc r1, (UNDEF: 17)
268: 30000013 andcc r0, r0, r3, lsl r0
26c: 1331011d teqne r1, #1073741831 ; 0x40000007
// File system check
return fsRead(stream);
#else
return EOF;
#endif
}
270: 17550152 ; <UNDEFINED> instruction: 0x17550152
// Take byte off the tail
return (int)_pullByte(&(ser->rx)) & 0xFF;
}
#ifndef NO_FILESYSTEM
// File system check
return fsRead(stream);
274: 0b590b58 bleq 1642fdc <usart+0x1642f94>
return ((buffer->tail + 1) & _USART_MAX) == buffer->head;
}
// Removes a byte from the head of the given buffer
static char _pullByte(volatile RingBuffer_TypeDef* buffer) {
uint8_t head = buffer->head; char value;
278: 05310000 ldreq r0, [r1, #-0]!
27c: 00133100 andseq r3, r3, r0, lsl #2
280: 010b3200 mrseq r3, R11_fiq
284: 00001755 andeq r1, r0, r5, asr r7
value = buffer->buffer[head];
buffer->head = (head + 1) & _USART_MAX;
288: 01828933 orreq r8, r2, r3, lsr r9
28c: 95011101 strls r1, [r1, #-257] ; 0xfffffeff
}
// Removes a byte from the head of the given buffer
static char _pullByte(volatile RingBuffer_TypeDef* buffer) {
uint8_t head = buffer->head; char value;
value = buffer->buffer[head];
290: 13311942 teqne r1, #1081344 ; 0x108000
// File system check
return fsRead(stream);
#else
return EOF;
#endif
}
294: 05340000 ldreq r0, [r4, #-0]!
298: 3a080300 bcc 200ea0 <usart+0x200e58>
29c: 490b3b0b stmdbmi fp, {r0, r1, r3, r8, r9, fp, ip, sp}
*ptr = '\0';
return str;
}
// fputc - Write a character to the specified stream
int fputc(int value, FILE *stream) {
2a0: 00170213 andseq r0, r7, r3, lsl r2
uint32_t snew = (uint32_t)stream - 1;
if (snew < 3) {
2a4: 012e3500 ; <UNDEFINED> instruction: 0x012e3500
2a8: 0e03193f mcreq 9, 0, r1, cr3, cr15, {1}
SerialPort_TypeDef *ser = &usart[snew];
2ac: 0b3b0b3a bleq ec2f9c <usart+0xec2f54>
2b0: 01111349 tsteq r1, r9, asr #6
return buffer->head == buffer->tail;
}
// Checks to see if the ring buffer is full (tail + 1 = head)
static INLINE uint8_t _isBufferFull(volatile RingBuffer_TypeDef* buffer) {
return ((buffer->tail + 1) & _USART_MAX) == buffer->head;
2b4: 18400612 stmdane r0, {r1, r4, r9, sl}^
2b8: 01194297 ; <UNDEFINED> instruction: 0x01194297
}
// Waits for space in the given port's TX buffer
// This happens infrequently, so simply sleep-waiting is acceptable
static void _waitForSpace(SerialPort_TypeDef* port) {
while (_isBufferFull(&(port->tx)))
2bc: 36000013 ; <UNDEFINED> instruction: 0x36000013
_yield();
2c0: 193f012e ldmdbne pc!, {r1, r2, r3, r5, r8} ; <UNPREDICTABLE>
2c4: 0b3a0e03 bleq e83ad8 <usart+0xe83a90>
return value;
}
// Queues a byte onto the tail of the given buffer
static void _queueByte(volatile RingBuffer_TypeDef* buffer, char value) {
uint8_t tail = buffer->tail;
2c8: 01110b3b tsteq r1, fp, lsr fp
2cc: 18400612 stmdane r0, {r1, r4, r9, sl}^
2d0: 01194297 ; <UNDEFINED> instruction: 0x01194297
2d4: 37000013 smladcc r0, r3, r0, r0
buffer->buffer[tail] = value;
2d8: 08030034 stmdaeq r3, {r2, r4, r5}
uint32_t snew = (uint32_t)stream - 1;
if (snew < 3) {
SerialPort_TypeDef *ser = &usart[snew];
_waitForSpace(ser);
// Jam a byte onto the head
_queueByte(&(ser->tx), (char)value);
2dc: 0b3b0b3a bleq ec2fcc <usart+0xec2f84>
// Queues a byte onto the tail of the given buffer
static void _queueByte(volatile RingBuffer_TypeDef* buffer, char value) {
uint8_t tail = buffer->tail;
buffer->buffer[tail] = value;
buffer->tail = (tail + 1) & _USART_MAX;
2e0: 18021349 stmdane r2, {r0, r3, r6, r8, r9, ip}
}
// Queues a byte onto the tail of the given buffer
static void _queueByte(volatile RingBuffer_TypeDef* buffer, char value) {
uint8_t tail = buffer->tail;
buffer->buffer[tail] = value;
2e4: 1d380000 ldcne 0, cr0, [r8, #-0]
if (snew < 3) {
SerialPort_TypeDef *ser = &usart[snew];
_waitForSpace(ser);
// Jam a byte onto the head
_queueByte(&(ser->tx), (char)value);
if (snew == 0)
2e8: 52133101 andspl r3, r3, #1073741824 ; 0x40000000
// Enable USART2 TXE interrupts
USART2->CR1 |= USART_CR1_TXEIE;
2ec: 58175501 ldmdapl r7, {r0, r8, sl, ip, lr}
else if (snew == 1)
// Enable USART3 TXE interrupts
USART3->CR1 |= USART_CR1_TXEIE;
2f0: 010b590b tsteq fp, fp, lsl #18
else if (snew == 2)
// Enable USART1 TXE interrupts
USART1->CR1 |= USART_CR1_TXEIE;
2f4: 39000013 stmdbcc r0, {r0, r1, r4}
else
// File system check
return fsWrite(stream, value);
#endif
return value;
}
2f8: 1331001d teqne r1, #29
else if (snew == 1)
// Enable USART3 TXE interrupts
USART3->CR1 |= USART_CR1_TXEIE;
else if (snew == 2)
// Enable USART1 TXE interrupts
USART1->CR1 |= USART_CR1_TXEIE;
2fc: 06120111 ; <UNDEFINED> instruction: 0x06120111
300: 0b590b58 bleq 1643068 <usart+0x1643020>
}
#ifndef NO_FILESYSTEM
else
// File system check
return fsWrite(stream, value);
304: 2e3a0000 cdpcs 0, 3, cr0, cr10, cr0, {0}
#endif
return value;
}
308: 03193f01 tsteq r9, #1, 30
USART1->CR1 |= USART_CR1_TXEIE;
}
#ifndef NO_FILESYSTEM
else
// File system check
return fsWrite(stream, value);
30c: 3b0b3a0e blcc 2ceb4c <usart+0x2ceb04>
310: 12011105 andne r1, r1, #1073741825 ; 0x40000001
314: 97184006 ldrls r4, [r8, -r6]
318: 13011942 movwne r1, #6466 ; 0x1942
31c: 343b0000 ldrtcc r0, [fp], #-0
320: 3a080300 bcc 200f28 <usart+0x200ee0>
#endif
return value;
}
// fread - Read data from stream
size_t fread(void *ptr, size_t size, size_t count, FILE *stream) {
324: 49053b0b stmdbmi r5, {r0, r1, r3, r8, r9, fp, ip, sp}
328: 00180213 andseq r0, r8, r3, lsl r2
char *memory = (char *)ptr;
size_t write = 0; int read;
for (uint32_t i = 0; i < (size * count); i++)
32c: 011d3c00 tsteq sp, r0, lsl #24
330: 01111331 tsteq r1, r1, lsr r3
// Write as many as we can, break if we fail
if ((read = fgetc(stream)) != EOF) {
334: 0b580612 bleq 1601b84 <usart+0x1601b3c>
338: 13010559 movwne r0, #5465 ; 0x1559
33c: 1d3d0000 ldcne 0, cr0, [sp, #-0]
340: 11133100 tstne r3, r0, lsl #2
*memory++ = (char)read;
write++;
344: 58061201 stmdapl r6, {r0, r9, ip}
} else
break;
return write;
}
348: 0005590b andeq r5, r5, fp, lsl #18
// fwrite - Write data to stream
size_t fwrite(const void *ptr, size_t size, size_t count, FILE *stream) {
34c: 82893e00 addhi r3, r9, #0, 28
350: 01110101 tsteq r1, r1, lsl #2
const char *memory = (const char *)ptr;
size_t write = 0;
for (uint32_t i = 0; i < (size * count); i++)
354: 13011331 movwne r1, #4913 ; 0x1331
358: 2e3f0000 cdpcs 0, 3, cr0, cr15, cr0, {0}
// Write as many as we can, break if we fail
if (fputc((int)(*memory++), stream) != EOF)
35c: 03193f01 tsteq r9, #1, 30
360: 3b0b3a0e blcc 2ceba0 <usart+0x2ceb58>
364: 49192705 ldmdbmi r9, {r0, r2, r8, r9, sl, sp}
368: 12011113 andne r1, r1, #-1073741820 ; 0xc0000004
write++;
36c: 97184006 ldrls r4, [r8, -r6]
else
break;
return write;
}
370: 13011942 movwne r1, #6466 ; 0x1942
// getchar - Gets a character from the serial PC communication buffer; blocks until read
int getchar() {
return fgetc(stdin);
374: 2e400000 cdpcs 0, 4, cr0, cr0, cr0, {0}
378: 03193f01 tsteq r9, #1, 30
}
// putchar - Write a character to the serial PC communication buffer
int putchar(int value) {
return fputc(value, stdout);
37c: 3b0b3a0e blcc 2cebbc <usart+0x2ceb74>
}
// ISR_USART1 - Buffered character I/O handler for debug communications
void ISR_USART1() {
380: 11192705 tstne r9, r5, lsl #14
384: 40061201 andmi r1, r6, r1, lsl #4
388: 19429718 stmdbne r2, {r3, r4, r8, r9, sl, ip, pc}^
38c: 00001301 andeq r1, r0, r1, lsl #6
char value;
bool cs = false;
390: 03000541 movweq r0, #1345 ; 0x541
SerialPort_TypeDef *ser = &usart[2];
if (USART1->SR & USART_SR_RXNE) {
394: 3b0b3a0e blcc 2cebd4 <usart+0x2ceb8c>
398: 02134905 andseq r4, r3, #81920 ; 0x14000
return buffer->head == buffer->tail;
}
// Checks to see if the ring buffer is full (tail + 1 = head)
static INLINE uint8_t _isBufferFull(volatile RingBuffer_TypeDef* buffer) {
return ((buffer->tail + 1) & _USART_MAX) == buffer->head;
39c: 42000018 andmi r0, r0, #24
3a0: 08030034 stmdaeq r3, {r2, r4, r5}
3a4: 053b0b3a ldreq r0, [fp, #-2874]! ; 0xfffff4c6
3a8: 17021349 strne r1, [r2, -r9, asr #6]
3ac: 0b430000 bleq 10c03b4 <usart+0x10c036c>
SerialPort_TypeDef *ser = &usart[2];
if (USART1->SR & USART_SR_RXNE) {
// Read to clear the flag
value = (char)USART1->DR;
// Buffer it up, if it's not full to the brim
if (!_isBufferFull(&(ser->rx)))
3b0: 12011101 andne r1, r1, #1073741824 ; 0x40000000
return value;
}
// Queues a byte onto the tail of the given buffer
static void _queueByte(volatile RingBuffer_TypeDef* buffer, char value) {
uint8_t tail = buffer->tail;
3b4: 00130106 andseq r0, r3, r6, lsl #2
3b8: 00054400 andeq r4, r5, r0, lsl #8
buffer->buffer[tail] = value;
buffer->tail = (tail + 1) & _USART_MAX;
3bc: 0b3a0803 bleq e823d0 <usart+0xe82388>
3c0: 1349053b movtne r0, #38203 ; 0x953b
}
// Queues a byte onto the tail of the given buffer
static void _queueByte(volatile RingBuffer_TypeDef* buffer, char value) {
uint8_t tail = buffer->tail;
buffer->buffer[tail] = value;
3c4: 00001802 andeq r1, r0, r2, lsl #16
buffer->tail = (tail + 1) & _USART_MAX;
3c8: 00001845 andeq r1, r0, r5, asr #16
value = (char)USART1->DR;
// Buffer it up, if it's not full to the brim
if (!_isBufferFull(&(ser->rx)))
_queueByte(&(ser->rx), value);
// Notify any receivers
semaphoreGiveISR(ser->readLock, &cs);
3cc: 00344600 eorseq r4, r4, r0, lsl #12
3d0: 0b3a0e03 bleq e83be4 <usart+0xe83b9c>
3d4: 1349053b movtne r0, #38203 ; 0x953b
}
if (USART1->SR & USART_SR_TXE) {
3d8: 00001802 andeq r1, r0, r2, lsl #16
3dc: 31011d47 tstcc r1, r7, asr #26
// Prototype this
uint32_t usartBufferCount(SerialPort_TypeDef* port);
// Checks to see if the ring buffer is empty (head = tail)
static INLINE uint8_t _isBufferEmpty(volatile RingBuffer_TypeDef* buffer) {
return buffer->head == buffer->tail;
3e0: 55015213 strpl r5, [r1, #-531] ; 0xfffffded
3e4: 590b5817 stmdbpl fp, {r0, r1, r2, r4, fp, ip, lr}
_queueByte(&(ser->rx), value);
// Notify any receivers
semaphoreGiveISR(ser->readLock, &cs);
}
if (USART1->SR & USART_SR_TXE) {
if (_isBufferEmpty(&(ser->tx)))
3e8: 48000005 stmdami r0, {r0, r2}
// Nothing to send, disable interrupt
USART1->CR1 &= ~USART_CR1_TXEIE;
3ec: 01018289 smlabbeq r1, r9, r2, r8
3f0: 42950111 addsmi r0, r5, #1073741828 ; 0x40000004
3f4: 01133119 tsteq r3, r9, lsl r1
3f8: 49000013 stmdbmi r0, {r0, r1, r4}
return ((buffer->tail + 1) & _USART_MAX) == buffer->head;
}
// Removes a byte from the head of the given buffer
static char _pullByte(volatile RingBuffer_TypeDef* buffer) {
uint8_t head = buffer->head; char value;
3fc: 1331011d teqne r1, #1073741831 ; 0x40000007
value = buffer->buffer[head];
400: 17550152 ; <UNDEFINED> instruction: 0x17550152
404: 05590b58 ldrbeq r0, [r9, #-2904] ; 0xfffff4a8
buffer->head = (head + 1) & _USART_MAX;
408: 00001301 andeq r1, r0, r1, lsl #6
40c: 3100054a tstcc r0, sl, asr #10
if (_isBufferEmpty(&(ser->tx)))
// Nothing to send, disable interrupt
USART1->CR1 &= ~USART_CR1_TXEIE;
else {
value = _pullByte(&(ser->tx));
USART1->DR = value;
410: 00180213 andseq r0, r8, r3, lsl r2
414: 011d4b00 tsteq sp, r0, lsl #22
}
}
if (cs)
418: 01111331 tsteq r1, r1, lsr r3
*/
bool _taskClearEvent(OSList *eventList);
static INLINE void _taskYield() {
/* Set a PendSV to request a context switch. */
SCB->ICSR |= SCB_ICSR_PENDSV;
41c: 0b580612 bleq 1601c6c <usart+0x1601c24>
420: 00000559 andeq r0, r0, r9, asr r5
424: 0300344c movweq r3, #1100 ; 0x44c
_taskYield();
}
428: 3b0b3a0e blcc 2cec68 <usart+0x2cec20>
42c: 0213490b andseq r4, r3, #180224 ; 0x2c000
430: 4d000018 stcmi 0, cr0, [r0, #-96] ; 0xffffffa0
434: 0e030034 mcreq 0, 0, r0, cr3, cr4, {1}
438: 0b3b0b3a bleq ec3128 <usart+0xec30e0>
count = 0;
lcd[index].state = count;
}
// ISR_USART2 - Buffered character I/O handler for UART port 1
void ISR_USART2() {
43c: 193f1349 ldmdbne pc!, {r0, r3, r6, r8, r9, ip} ; <UNPREDICTABLE>
440: 0000193c andeq r1, r0, ip, lsr r9
444: 3f012e4e svccc 0x00012e4e
448: 3a0e0319 bcc 3810b4 <usart+0x38106c>
char value;
bool cs = false;
44c: 270b3b0b strcs r3, [fp, -fp, lsl #22]
450: 3c134919 ldccc 9, cr4, [r3], {25}
SerialPort_TypeDef *ser = &usart[0];
if (USART2->SR & USART_SR_RXNE) {
454: 00130119 andseq r0, r3, r9, lsl r1
// Read to clear the flag
value = (char)USART2->DR;
if (lcd[0].flags & LCD_ACTIVE)
458: 00054f00 andeq r4, r5, r0, lsl #30
45c: 00001349 andeq r1, r0, r9, asr #6
460: 3f012e50 svccc 0x00012e50
lcdButtonProcess(value, 0);
464: 3a0e0319 bcc 3810d0 <usart+0x381088>
468: 3c0b3b0b stccc 11, cr3, [fp], {11}
return buffer->head == buffer->tail;
}
// Checks to see if the ring buffer is full (tail + 1 = head)
static INLINE uint8_t _isBufferFull(volatile RingBuffer_TypeDef* buffer) {
return ((buffer->tail + 1) & _USART_MAX) == buffer->head;
46c: 00130119 andseq r0, r3, r9, lsl r1
470: 012e5100 ; <UNDEFINED> instruction: 0x012e5100
474: 0e03193f mcreq 9, 0, r1, cr3, cr15, {1}
478: 0b3b0b3a bleq ec3168 <usart+0xec3120>
value = (char)USART2->DR;
if (lcd[0].flags & LCD_ACTIVE)
lcdButtonProcess(value, 0);
else {
// Buffer it up, if it's not full to the brim
if (!_isBufferFull(&(ser->rx)))
47c: 193c1349 ldmdbne ip!, {r0, r3, r6, r8, r9, ip}
return value;
}
// Queues a byte onto the tail of the given buffer
static void _queueByte(volatile RingBuffer_TypeDef* buffer, char value) {
uint8_t tail = buffer->tail;
480: Address 0x0000000000000480 is out of bounds.
Disassembly of section .debug_loc:
00000000 <.debug_loc>:
0: 00000000 andeq r0, r0, r0
0: R_ARM_ABS32 .text.lcdButtonProcess
4: 00000050 andeq r0, r0, r0, asr r0
4: R_ARM_ABS32 .text.lcdButtonProcess
8: 50500001 subspl r0, r0, r1
b: R_ARM_ABS32 .text.lcdButtonProcess
c: 5c000000 stcpl 0, cr0, [r0], {-0}
f: R_ARM_ABS32 .text.lcdButtonProcess
10: 04000000 streq r0, [r0], #-0
14: 5001f300 andpl pc, r1, r0, lsl #6
18: 0000009f muleq r0, pc, r0 ; <UNPREDICTABLE>
...
21: R_ARM_ABS32 .text.lcdButtonProcess
24: 00005400 andeq r5, r0, r0, lsl #8
25: R_ARM_ABS32 .text.lcdButtonProcess
28: 51000100 mrspl r0, (UNDEF: 16)
2c: 00000054 andeq r0, r0, r4, asr r0
2c: R_ARM_ABS32 .text.lcdButtonProcess
30: 0000005c andeq r0, r0, ip, asr r0
30: R_ARM_ABS32 .text.lcdButtonProcess
34: 01f30004 mvnseq r0, r4
38: 00009f51 andeq r9, r0, r1, asr pc
3c: 00000000 andeq r0, r0, r0
40: 000e0000 andeq r0, lr, r0
42: R_ARM_ABS32 .text.lcdButtonProcess
44: 00320000 eorseq r0, r2, r0
46: R_ARM_ABS32 .text.lcdButtonProcess
48: 00010000 andeq r0, r1, r0
4c: 00003253 andeq r3, r0, r3, asr r2
4d: R_ARM_ABS32 .text.lcdButtonProcess
50: 00003600 andeq r3, r0, r0, lsl #12
51: R_ARM_ABS32 .text.lcdButtonProcess
54: 73000a00 movwvc r0, #2560 ; 0xa00
58: 1e007100 adfnes f7, f0, f0
5c: 23220072 ; <UNDEFINED> instruction: 0x23220072
60: 00003622 andeq r3, r0, r2, lsr #12
61: R_ARM_ABS32 .text.lcdButtonProcess
64: 00003a00 andeq r3, r0, r0, lsl #20
65: R_ARM_ABS32 .text.lcdButtonProcess
68: 71000a00 tstvc r0, r0, lsl #20
6c: 1e240800 cdpne 8, 2, cr0, cr4, cr0, {0}
70: 23220072 ; <UNDEFINED> instruction: 0x23220072
74: 00003a22 andeq r3, r0, r2, lsr #20
75: R_ARM_ABS32 .text.lcdButtonProcess
78: 00003c00 andeq r3, r0, r0, lsl #24
79: R_ARM_ABS32 .text.lcdButtonProcess
7c: 30000200 andcc r0, r0, r0, lsl #4
80: 00003c9f muleq r0, pc, ip ; <UNPREDICTABLE>
81: R_ARM_ABS32 .text.lcdButtonProcess
84: 00003e00 andeq r3, r0, r0, lsl #28
85: R_ARM_ABS32 .text.lcdButtonProcess
88: 53000100 movwpl r0, #256 ; 0x100
8c: 0000003e andeq r0, r0, lr, lsr r0
8c: R_ARM_ABS32 .text.lcdButtonProcess
90: 00000040 andeq r0, r0, r0, asr #32
90: R_ARM_ABS32 .text.lcdButtonProcess
94: 0071000a rsbseq r0, r1, sl
98: 721e2408 andsvc r2, lr, #8, 8 ; 0x8000000
9c: 22232200 eorcs r2, r3, #0, 4
a0: 00000040 andeq r0, r0, r0, asr #32
a0: R_ARM_ABS32 .text.lcdButtonProcess
a4: 00000042 andeq r0, r0, r2, asr #32
a4: R_ARM_ABS32 .text.lcdButtonProcess
a8: 42530001 subsmi r0, r3, #1
ab: R_ARM_ABS32 .text.lcdButtonProcess
ac: 44000000 strmi r0, [r0], #-0
af: R_ARM_ABS32 .text.lcdButtonProcess
b0: 0a000000 beq b8 <.debug_loc+0xb8>
b4: 08007100 stmdaeq r0, {r8, ip, sp, lr}
b8: 00721e24 rsbseq r1, r2, r4, lsr #28
bc: 44222322 strtmi r2, [r2], #-802 ; 0xfffffcde
bf: R_ARM_ABS32 .text.lcdButtonProcess
c0: 46000000 strmi r0, [r0], -r0
c3: R_ARM_ABS32 .text.lcdButtonProcess
c4: 01000000 mrseq r0, (UNDEF: 0)
c8: 00465300 subeq r5, r6, r0, lsl #6
ca: R_ARM_ABS32 .text.lcdButtonProcess
cc: 00480000 subeq r0, r8, r0
ce: R_ARM_ABS32 .text.lcdButtonProcess
d0: 000a0000 andeq r0, sl, r0
d4: 24080071 strcs r0, [r8], #-113 ; 0xffffff8f
d8: 2200721e andcs r7, r0, #-536870911 ; 0xe0000001
dc: 00482223 subeq r2, r8, r3, lsr #4
de: R_ARM_ABS32 .text.lcdButtonProcess
e0: 004a0000 subeq r0, sl, r0
e2: R_ARM_ABS32 .text.lcdButtonProcess
e4: 00010000 andeq r0, r1, r0
e8: 00004a53 andeq r4, r0, r3, asr sl
e9: R_ARM_ABS32 .text.lcdButtonProcess
ec: 00004c00 andeq r4, r0, r0, lsl #24
ed: R_ARM_ABS32 .text.lcdButtonProcess
f0: 71000a00 tstvc r0, r0, lsl #20
f4: 1e240800 cdpne 8, 2, cr0, cr4, cr0, {0}
f8: 23220072 ; <UNDEFINED> instruction: 0x23220072
fc: 00004e22 andeq r4, r0, r2, lsr #28
fd: R_ARM_ABS32 .text.lcdButtonProcess
100: 00005c00 andeq r5, r0, r0, lsl #24
101: R_ARM_ABS32 .text.lcdButtonProcess
104: 53000100 movwpl r0, #256 ; 0x100
...
110: R_ARM_ABS32 .text.fgetc
114: 00000010 andeq r0, r0, r0, lsl r0
114: R_ARM_ABS32 .text.fgetc
118: 10500001 subsne r0, r0, r1
11b: R_ARM_ABS32 .text.fgetc
11c: 34000000 strcc r0, [r0], #-0
11f: R_ARM_ABS32 .text.fgetc
120: 03000000 movweq r0, #0
124: 9f017400 svcls 0x00017400
128: 00000034 andeq r0, r0, r4, lsr r0
128: R_ARM_ABS32 .text.fgetc
12c: 0000003b andeq r0, r0, fp, lsr r0
12c: R_ARM_ABS32 .text.fgetc
130: 3b500001 blcc 140000c <usart+0x13fffc4>
133: R_ARM_ABS32 .text.fgetc
134: 64000000 strvs r0, [r0], #-0
137: R_ARM_ABS32 .text.fgetc
138: 04000000 streq r0, [r0], #-0
13c: 5001f300 andpl pc, r1, r0, lsl #6
140: 0000009f muleq r0, pc, r0 ; <UNPREDICTABLE>
144: 00000000 andeq r0, r0, r0
148: 00000400 andeq r0, r0, r0, lsl #8
149: R_ARM_ABS32 .text.fgetc
14c: 00003800 andeq r3, r0, r0, lsl #16
14d: R_ARM_ABS32 .text.fgetc
150: 54000100 strpl r0, [r0], #-256 ; 0xffffff00
154: 00000038 andeq r0, r0, r8, lsr r0
154: R_ARM_ABS32 .text.fgetc
158: 0000003b andeq r0, r0, fp, lsr r0
158: R_ARM_ABS32 .text.fgetc
15c: 7f700003 svcvc 0x00700003
160: 00003b9f muleq r0, pc, fp ; <UNPREDICTABLE>
161: R_ARM_ABS32 .text.fgetc
164: 00003c00 andeq r3, r0, r0, lsl #24
165: R_ARM_ABS32 .text.fgetc
168: f3000600 vmax.u8 d0, d0, d0
16c: 1c315001 ldcne 0, cr5, [r1], #-4
170: 00003c9f muleq r0, pc, ip ; <UNPREDICTABLE>
171: R_ARM_ABS32 .text.fgetc
174: 00004000 andeq r4, r0, r0
175: R_ARM_ABS32 .text.fgetc
178: 54000100 strpl r0, [r0], #-256 ; 0xffffff00
17c: 00000040 andeq r0, r0, r0, asr #32
17c: R_ARM_ABS32 .text.fgetc
180: 00000064 andeq r0, r0, r4, rrx
180: R_ARM_ABS32 .text.fgetc
184: 01f30006 mvnseq r0, r6
188: 9f1c3150 svcls 0x001c3150
...
194: 00000010 andeq r0, r0, r0, lsl r0
194: R_ARM_ABS32 .text.fgetc
198: 00000034 andeq r0, r0, r4, lsr r0
198: R_ARM_ABS32 .text.fgetc
19c: 3c550001 mrrccc 0, 0, r0, r5, cr1
19f: R_ARM_ABS32 .text.fgetc
1a0: 5a000000 bpl 8 <.debug_loc+0x8>
1a3: R_ARM_ABS32 .text.fgetc
1a4: 01000000 mrseq r0, (UNDEF: 0)
1a8: 005a5500 subseq r5, sl, r0, lsl #10
1aa: R_ARM_ABS32 .text.fgetc
1ac: 00640000 rsbeq r0, r4, r0
1ae: R_ARM_ABS32 .text.fgetc
1b0: 000f0000 andeq r0, pc, r0
1b4: 315001f3 ldrshcc r0, [r0, #-19] ; 0xffffffed
1b8: 1e88081c mcrne 8, 4, r0, cr8, cr12, {0}
1bc: 00004803 andeq r4, r0, r3, lsl #16
1bd: R_ARM_ABS32 .bss
1c0: 009f2200 addseq r2, pc, r0, lsl #4
1c4: 00000000 andeq r0, r0, r0
1c8: 10000000 andne r0, r0, r0
1cb: R_ARM_ABS32 .text.fgetc
1cc: 34000000 strcc r0, [r0], #-0
1cf: R_ARM_ABS32 .text.fgetc
1d0: 04000000 streq r0, [r0], #-0
1d4: 00c27500 sbceq r7, r2, r0, lsl #10
1d8: 00003c9f muleq r0, pc, ip ; <UNPREDICTABLE>
1d9: R_ARM_ABS32 .text.fgetc
1dc: 00005a00 andeq r5, r0, r0, lsl #20
1dd: R_ARM_ABS32 .text.fgetc
_taskYield();
}
// lcdButtonProcess - Processes the VEX LCD buttons
static void lcdButtonProcess(char value, uint32_t index) {
uint16_t count = lcd[index].state;
1e0: 75000400 strvc r0, [r0, #-1024] ; 0xfffffc00
1e4: 5a9f00c2 bpl fe7c0310 <usart+0xfe7c02c8>
1e7: R_ARM_ABS32 .text.fgetc
// If 0xAA, set count to 1
// If 0x55, set count to 2 if count == 1
// If 0x16, set count to 3 if count == 2
if (value == (char)0xAA)
1e8: 64000000 strvs r0, [r0], #-0
1eb: R_ARM_ABS32 .text.fgetc
_taskYield();
}
// lcdButtonProcess - Processes the VEX LCD buttons
static void lcdButtonProcess(char value, uint32_t index) {
uint16_t count = lcd[index].state;
1ec: 0f000000 svceq 0x00000000
// If 0xAA, set count to 1
// If 0x55, set count to 2 if count == 1
// If 0x16, set count to 3 if count == 2
if (value == (char)0xAA)
count = 1;
else if (value == (char)0x55 && count == 1)
1f0: 5001f300 andpl pc, r1, r0, lsl #6
1f4: 88081c31 stmdahi r8, {r0, r4, r5, sl, fp, ip}
1f8: 008a031e addeq r0, sl, lr, lsl r3
1fa: R_ARM_ABS32 .bss
count = 2;
else if (value == (char)0x16 && count == 2)
1fc: 9f220000 svcls 0x00220000
...
count = 3;
else if (value == (char)0x02 && count == 3)
208: 0000003c andeq r0, r0, ip, lsr r0
208: R_ARM_ABS32 .text.fgetc
// Size must be 2
count = 4;
else if (count == 4) {
20c: 00000040 andeq r0, r0, r0, asr #32
20c: R_ARM_ABS32 .text.fgetc
lcd[index].buttons = (uint8_t)value;
210: 0074000c rsbseq r0, r4, ip
214: 031e8808 tsteq lr, #8, 16 ; 0x80000
218: 0000008a andeq r0, r0, sl, lsl #1
218: R_ARM_ABS32 .bss
uint16_t count = lcd[index].state;
// If 0xAA, set count to 1
// If 0x55, set count to 2 if count == 1
// If 0x16, set count to 3 if count == 2
if (value == (char)0xAA)
count = 1;
21c: 00409f22 subeq r9, r0, r2, lsr #30
21e: R_ARM_ABS32 .text.fgetc
else if (value == (char)0x55 && count == 1)
count = 2;
220: 00640000 rsbeq r0, r4, r0
222: R_ARM_ABS32 .text.fgetc
else if (value == (char)0x16 && count == 2)
count = 3;
224: 000f0000 andeq r0, pc, r0
else if (value == (char)0x02 && count == 3)
// Size must be 2
count = 4;
228: 315001f3 ldrshcc r0, [r0, #-19] ; 0xffffffed
else if (count == 4) {
lcd[index].buttons = (uint8_t)value;
count = 0;
} else
// Ignore the checksum and any noise we pick up
count = 0;
22c: 1e88081c mcrne 8, 4, r0, cr8, cr12, {0}
lcd[index].state = count;
230: 00008a03 andeq r8, r0, r3, lsl #20
231: R_ARM_ABS32 .bss
234: 009f2200 addseq r2, pc, r0, lsl #4
238: 00000000 andeq r0, r0, r0
return 1;
#endif
}
// fgetc - Read a character from the specified stream
int fgetc(FILE *stream) {
23c: 4a000000 bmi 8 <.debug_loc+0x8>
23f: R_ARM_ABS32 .text.fgetc
uint32_t snew = (uint32_t)stream - 1;
if (snew < 3) {
240: 4e000000 cdpmi 0, 0, cr0, cr0, cr0, {0}
243: R_ARM_ABS32 .text.fgetc
SerialPort_TypeDef *ser = &usart[snew];
244: 01000000 mrseq r0, (UNDEF: 0)
248: 004e5300 subeq r5, lr, r0, lsl #6
24a: R_ARM_ABS32 .text.fgetc
// Prototype this
uint32_t usartBufferCount(SerialPort_TypeDef* port);
// Checks to see if the ring buffer is empty (head = tail)
static INLINE uint8_t _isBufferEmpty(volatile RingBuffer_TypeDef* buffer) {
return buffer->head == buffer->tail;
24c: 00520000 subseq r0, r2, r0
24e: R_ARM_ABS32 .text.fgetc
250: 00030000 andeq r0, r3, r0
}
// Waits for a byte in the given port's RX buffer
// This does not happen during init, so it is OK to use scheduler functions
static void _waitForByte(SerialPort_TypeDef* port) {
while (_isBufferEmpty(&(port->rx)))
254: 009f7f73 addseq r7, pc, r3, ror pc ; <UNPREDICTABLE>
...
25f: R_ARM_ABS32 .text.fputc
semaphoreTake(port->readLock, MAX_DELAY);
260: 12000000 andne r0, r0, #0
263: R_ARM_ABS32 .text.fputc
264: 01000000 mrseq r0, (UNDEF: 0)
268: 00125000 andseq r5, r2, r0
26a: R_ARM_ABS32 .text.fputc
26c: 00640000 rsbeq r0, r4, r0
26e: R_ARM_ABS32 .text.fputc
// File system check
return fsRead(stream);
#else
return EOF;
#endif
}
270: 00010000 andeq r0, r1, r0
// Take byte off the tail
return (int)_pullByte(&(ser->rx)) & 0xFF;
}
#ifndef NO_FILESYSTEM
// File system check
return fsRead(stream);
274: 00006454 andeq r6, r0, r4, asr r4
275: R_ARM_ABS32 .text.fputc
return ((buffer->tail + 1) & _USART_MAX) == buffer->head;
}
// Removes a byte from the head of the given buffer
static char _pullByte(volatile RingBuffer_TypeDef* buffer) {
uint8_t head = buffer->head; char value;
278: 00006600 andeq r6, r0, r0, lsl #12
279: R_ARM_ABS32 .text.fputc
27c: 50000100 andpl r0, r0, r0, lsl #2
280: 00000066 andeq r0, r0, r6, rrx
280: R_ARM_ABS32 .text.fputc
284: 0000006c andeq r0, r0, ip, rrx
284: R_ARM_ABS32 .text.fputc
value = buffer->buffer[head];
buffer->head = (head + 1) & _USART_MAX;
288: 6c540001 mrrcvs 0, 0, r0, r4, cr1
28b: R_ARM_ABS32 .text.fputc
28c: 6f000000 svcvs 0x00000000
28f: R_ARM_ABS32 .text.fputc
}
// Removes a byte from the head of the given buffer
static char _pullByte(volatile RingBuffer_TypeDef* buffer) {
uint8_t head = buffer->head; char value;
value = buffer->buffer[head];
290: 01000000 mrseq r0, (UNDEF: 0)
// File system check
return fsRead(stream);
#else
return EOF;
#endif
}
294: 006f5100 rsbeq r5, pc, r0, lsl #2
296: R_ARM_ABS32 .text.fputc
298: 00840000 addeq r0, r4, r0
29a: R_ARM_ABS32 .text.fputc
29c: 00040000 andeq r0, r4, r0
*ptr = '\0';
return str;
}
// fputc - Write a character to the specified stream
int fputc(int value, FILE *stream) {
2a0: 9f5001f3 svcls 0x005001f3
...
2ac: R_ARM_ABS32 .text.fputc
uint32_t snew = (uint32_t)stream - 1;
if (snew < 3) {
SerialPort_TypeDef *ser = &usart[snew];
2b0: 00000012 andeq r0, r0, r2, lsl r0
2b0: R_ARM_ABS32 .text.fputc
return buffer->head == buffer->tail;
}
// Checks to see if the ring buffer is full (tail + 1 = head)
static INLINE uint8_t _isBufferFull(volatile RingBuffer_TypeDef* buffer) {
return ((buffer->tail + 1) & _USART_MAX) == buffer->head;
2b4: 12510001 subsne r0, r1, #1
2b7: R_ARM_ABS32 .text.fputc
2b8: 64000000 strvs r0, [r0], #-0
2bb: R_ARM_ABS32 .text.fputc
}
// Waits for space in the given port's TX buffer
// This happens infrequently, so simply sleep-waiting is acceptable
static void _waitForSpace(SerialPort_TypeDef* port) {
while (_isBufferFull(&(port->tx)))
2bc: 03000000 movweq r0, #0
_yield();
2c0: 9f017500 svcls 0x00017500
2c4: 00000064 andeq r0, r0, r4, rrx
2c4: R_ARM_ABS32 .text.fputc
return value;
}
// Queues a byte onto the tail of the given buffer
static void _queueByte(volatile RingBuffer_TypeDef* buffer, char value) {
uint8_t tail = buffer->tail;
2c8: 00000068 andeq r0, r0, r8, rrx
2c8: R_ARM_ABS32 .text.fputc
2cc: 68510001 ldmdavs r1, {r0}^
2cf: R_ARM_ABS32 .text.fputc
2d0: 6f000000 svcvs 0x00000000
2d3: R_ARM_ABS32 .text.fputc
2d4: 01000000 mrseq r0, (UNDEF: 0)
buffer->buffer[tail] = value;
2d8: 006f5000 rsbeq r5, pc, r0
2da: R_ARM_ABS32 .text.fputc
uint32_t snew = (uint32_t)stream - 1;
if (snew < 3) {
SerialPort_TypeDef *ser = &usart[snew];
_waitForSpace(ser);
// Jam a byte onto the head
_queueByte(&(ser->tx), (char)value);
2dc: 00840000 addeq r0, r4, r0
2de: R_ARM_ABS32 .text.fputc
// Queues a byte onto the tail of the given buffer
static void _queueByte(volatile RingBuffer_TypeDef* buffer, char value) {
uint8_t tail = buffer->tail;
buffer->buffer[tail] = value;
buffer->tail = (tail + 1) & _USART_MAX;
2e0: 00040000 andeq r0, r4, r0
}
// Queues a byte onto the tail of the given buffer
static void _queueByte(volatile RingBuffer_TypeDef* buffer, char value) {
uint8_t tail = buffer->tail;
buffer->buffer[tail] = value;
2e4: 9f5101f3 svcls 0x005101f3
...
if (snew == 0)
// Enable USART2 TXE interrupts
USART2->CR1 |= USART_CR1_TXEIE;
else if (snew == 1)
// Enable USART3 TXE interrupts
USART3->CR1 |= USART_CR1_TXEIE;
2f0: 00000004 andeq r0, r0, r4
2f0: R_ARM_ABS32 .text.fputc
else if (snew == 2)
// Enable USART1 TXE interrupts
USART1->CR1 |= USART_CR1_TXEIE;
2f4: 0000006c andeq r0, r0, ip, rrx
2f4: R_ARM_ABS32 .text.fputc
else
// File system check
return fsWrite(stream, value);
#endif
return value;
}
2f8: 6c550001 mrrcvs 0, 0, r0, r5, cr1
2fb: R_ARM_ABS32 .text.fputc
else if (snew == 1)
// Enable USART3 TXE interrupts
USART3->CR1 |= USART_CR1_TXEIE;
else if (snew == 2)
// Enable USART1 TXE interrupts
USART1->CR1 |= USART_CR1_TXEIE;
2fc: 6f000000 svcvs 0x00000000
2ff: R_ARM_ABS32 .text.fputc
300: 03000000 movweq r0, #0
}
#ifndef NO_FILESYSTEM
else
// File system check
return fsWrite(stream, value);
304: 9f7f7000 svcls 0x007f7000
#endif
return value;
}
308: 0000006f andeq r0, r0, pc, rrx
308: R_ARM_ABS32 .text.fputc
USART1->CR1 |= USART_CR1_TXEIE;
}
#ifndef NO_FILESYSTEM
else
// File system check
return fsWrite(stream, value);
30c: 00000084 andeq r0, r0, r4, lsl #1
30c: R_ARM_ABS32 .text.fputc
310: 01f30006 mvnseq r0, r6
314: 9f1c3151 svcls 0x001c3151
...
320: 00000012 andeq r0, r0, r2, lsl r0
320: R_ARM_ABS32 .text.fputc
#endif
return value;
}
// fread - Read data from stream
size_t fread(void *ptr, size_t size, size_t count, FILE *stream) {
324: 00000064 andeq r0, r0, r4, rrx
324: R_ARM_ABS32 .text.fputc
328: 00560001 subseq r0, r6, r1
char *memory = (char *)ptr;
size_t write = 0; int read;
for (uint32_t i = 0; i < (size * count); i++)
32c: 00000000 andeq r0, r0, r0
330: 3e000000 cdpcc 0, 0, cr0, cr0, cr0, {0}
333: R_ARM_ABS32 .text.fputc
// Write as many as we can, break if we fail
if ((read = fgetc(stream)) != EOF) {
334: 64000000 strvs r0, [r0], #-0
337: R_ARM_ABS32 .text.fputc
338: 0c000000 stceq 0, cr0, [r0], {-0}
33c: 08007500 stmdaeq r0, {r8, sl, ip, sp, lr}
340: 48031e88 stmdami r3, {r3, r7, r9, sl, fp, ip}
343: R_ARM_ABS32 .bss
*memory++ = (char)read;
write++;
344: 22000000 andcs r0, r0, #0
} else
break;
return write;
}
348: 0000009f muleq r0, pc, r0 ; <UNPREDICTABLE>
...
351: R_ARM_ABS32 .text.fread
// fwrite - Write data to stream
size_t fwrite(const void *ptr, size_t size, size_t count, FILE *stream) {
const char *memory = (const char *)ptr;
size_t write = 0;
for (uint32_t i = 0; i < (size * count); i++)
354: 00000c00 andeq r0, r0, r0, lsl #24
355: R_ARM_ABS32 .text.fread
358: 50000100 andpl r0, r0, r0, lsl #2
// Write as many as we can, break if we fail
if (fputc((int)(*memory++), stream) != EOF)
35c: 0000000c andeq r0, r0, ip
35c: R_ARM_ABS32 .text.fread
360: 00000028 andeq r0, r0, r8, lsr #32
360: R_ARM_ABS32 .text.fread
364: 00560001 subseq r0, r6, r1
...
36f: R_ARM_ABS32 .text.fread
write++;
else
break;
return write;
}
370: 0c000000 stceq 0, cr0, [r0], {-0}
373: R_ARM_ABS32 .text.fread
// getchar - Gets a character from the serial PC communication buffer; blocks until read
int getchar() {
return fgetc(stdin);
374: 01000000 mrseq r0, (UNDEF: 0)
378: 000c5100 andeq r5, ip, r0, lsl #2
37a: R_ARM_ABS32 .text.fread
}
// putchar - Write a character to the serial PC communication buffer
int putchar(int value) {
return fputc(value, stdout);
37c: 00280000 eoreq r0, r8, r0
37e: R_ARM_ABS32 .text.fread
}
// ISR_USART1 - Buffered character I/O handler for debug communications
void ISR_USART1() {
380: 00040000 andeq r0, r4, r0
384: 9f5101f3 svcls 0x005101f3
...
390: R_ARM_ABS32 .text.fread
char value;
bool cs = false;
SerialPort_TypeDef *ser = &usart[2];
if (USART1->SR & USART_SR_RXNE) {
394: 0000000c andeq r0, r0, ip
394: R_ARM_ABS32 .text.fread
398: 0c520001 mrrceq 0, 0, r0, r2, cr1
39b: R_ARM_ABS32 .text.fread
return buffer->head == buffer->tail;
}
// Checks to see if the ring buffer is full (tail + 1 = head)
static INLINE uint8_t _isBufferFull(volatile RingBuffer_TypeDef* buffer) {
return ((buffer->tail + 1) & _USART_MAX) == buffer->head;
39c: 28000000 stmdacs r0, {} ; <UNPREDICTABLE>
39f: R_ARM_ABS32 .text.fread
3a0: 04000000 streq r0, [r0], #-0
3a4: 5201f300 andpl pc, r1, #0, 6
3a8: 0000009f muleq r0, pc, r0 ; <UNPREDICTABLE>
...
3b1: R_ARM_ABS32 .text.fread
return value;
}
// Queues a byte onto the tail of the given buffer
static void _queueByte(volatile RingBuffer_TypeDef* buffer, char value) {
uint8_t tail = buffer->tail;
3b4: 00000c00 andeq r0, r0, r0, lsl #24
3b5: R_ARM_ABS32 .text.fread
3b8: 53000100 movwpl r0, #256 ; 0x100
buffer->buffer[tail] = value;
buffer->tail = (tail + 1) & _USART_MAX;
3bc: 0000000c andeq r0, r0, ip
3bc: R_ARM_ABS32 .text.fread
3c0: 00000028 andeq r0, r0, r8, lsr #32
3c0: R_ARM_ABS32 .text.fread
}
// Queues a byte onto the tail of the given buffer
static void _queueByte(volatile RingBuffer_TypeDef* buffer, char value) {
uint8_t tail = buffer->tail;
buffer->buffer[tail] = value;
3c4: 00570001 subseq r0, r7, r1
buffer->tail = (tail + 1) & _USART_MAX;
3c8: 00000000 andeq r0, r0, r0
value = (char)USART1->DR;
// Buffer it up, if it's not full to the brim
if (!_isBufferFull(&(ser->rx)))
_queueByte(&(ser->rx), value);
// Notify any receivers
semaphoreGiveISR(ser->readLock, &cs);
3cc: 04000000 streq r0, [r0], #-0
3cf: R_ARM_ABS32 .text.fread
3d0: 0c000000 stceq 0, cr0, [r0], {-0}
3d3: R_ARM_ABS32 .text.fread
3d4: 01000000 mrseq r0, (UNDEF: 0)
}
if (USART1->SR & USART_SR_TXE) {
3d8: 001e5000 andseq r5, lr, r0
3da: R_ARM_ABS32 .text.fread
3dc: 00220000 eoreq r0, r2, r0
3de: R_ARM_ABS32 .text.fread
// Prototype this
uint32_t usartBufferCount(SerialPort_TypeDef* port);
// Checks to see if the ring buffer is empty (head = tail)
static INLINE uint8_t _isBufferEmpty(volatile RingBuffer_TypeDef* buffer) {
return buffer->head == buffer->tail;
3e0: 00080000 andeq r0, r8, r0
3e4: 00740076 rsbseq r0, r4, r6, ror r0
_queueByte(&(ser->rx), value);
// Notify any receivers
semaphoreGiveISR(ser->readLock, &cs);
}
if (USART1->SR & USART_SR_TXE) {
if (_isBufferEmpty(&(ser->tx)))
3e8: 9f012322 svcls 0x00012322
// Nothing to send, disable interrupt
USART1->CR1 &= ~USART_CR1_TXEIE;
3ec: 00000022 andeq r0, r0, r2, lsr #32
3ec: R_ARM_ABS32 .text.fread
3f0: 00000024 andeq r0, r0, r4, lsr #32
3f0: R_ARM_ABS32 .text.fread
3f4: 00760006 rsbseq r0, r6, r6
3f8: 9f220074 svcls 0x00220074
...
}
// Removes a byte from the head of the given buffer
static char _pullByte(volatile RingBuffer_TypeDef* buffer) {
uint8_t head = buffer->head; char value;
value = buffer->buffer[head];
404: 00000004 andeq r0, r0, r4
404: R_ARM_ABS32 .text.fread
buffer->head = (head + 1) & _USART_MAX;
408: 0000000c andeq r0, r0, ip
408: R_ARM_ABS32 .text.fread
40c: 9f300002 svcls 0x00300002
if (_isBufferEmpty(&(ser->tx)))
// Nothing to send, disable interrupt
USART1->CR1 &= ~USART_CR1_TXEIE;
else {
value = _pullByte(&(ser->tx));
USART1->DR = value;
410: 0000000c andeq r0, r0, ip
410: R_ARM_ABS32 .text.fread
414: 00000028 andeq r0, r0, r8, lsr #32
414: R_ARM_ABS32 .text.fread
}
}
if (cs)
418: 00540001 subseq r0, r4, r1
41c: 00000000 andeq r0, r0, r0
420: 16000000 strne r0, [r0], -r0
423: R_ARM_ABS32 .text.fread
424: 24000000 strcs r0, [r0], #-0
427: R_ARM_ABS32 .text.fread
_taskYield();
}
428: 01000000 mrseq r0, (UNDEF: 0)
42c: 00005000 andeq r5, r0, r0
...
436: R_ARM_ABS32 .text.fwrite
438: 000c0000 andeq r0, ip, r0
43a: R_ARM_ABS32 .text.fwrite
count = 0;
lcd[index].state = count;
}
// ISR_USART2 - Buffered character I/O handler for UART port 1
void ISR_USART2() {
43c: 00010000 andeq r0, r1, r0
440: 00000c50 andeq r0, r0, r0, asr ip
441: R_ARM_ABS32 .text.fwrite
444: 00002800 andeq r2, r0, r0, lsl #16
445: R_ARM_ABS32 .text.fwrite
448: 56000100 strpl r0, [r0], -r0, lsl #2
...
454: R_ARM_ABS32 .text.fwrite
bool cs = false;
SerialPort_TypeDef *ser = &usart[0];
if (USART2->SR & USART_SR_RXNE) {
// Read to clear the flag
value = (char)USART2->DR;
if (lcd[0].flags & LCD_ACTIVE)
458: 0000000c andeq r0, r0, ip
458: R_ARM_ABS32 .text.fwrite
45c: 0c510001 mrrceq 0, 0, r0, r1, cr1
45f: R_ARM_ABS32 .text.fwrite
460: 28000000 stmdacs r0, {} ; <UNPREDICTABLE>
463: R_ARM_ABS32 .text.fwrite
lcdButtonProcess(value, 0);
464: 04000000 streq r0, [r0], #-0
468: 5101f300 mrspl pc, SP_irq ; <UNPREDICTABLE>
return buffer->head == buffer->tail;
}
// Checks to see if the ring buffer is full (tail + 1 = head)
static INLINE uint8_t _isBufferFull(volatile RingBuffer_TypeDef* buffer) {
return ((buffer->tail + 1) & _USART_MAX) == buffer->head;
46c: 0000009f muleq r0, pc, r0 ; <UNPREDICTABLE>
...
475: R_ARM_ABS32 .text.fwrite
478: 00000c00 andeq r0, r0, r0, lsl #24
479: R_ARM_ABS32 .text.fwrite
value = (char)USART2->DR;
if (lcd[0].flags & LCD_ACTIVE)
lcdButtonProcess(value, 0);
else {
// Buffer it up, if it's not full to the brim
if (!_isBufferFull(&(ser->rx)))
47c: 52000100 andpl r0, r0, #0, 2
return value;
}
// Queues a byte onto the tail of the given buffer
static void _queueByte(volatile RingBuffer_TypeDef* buffer, char value) {
uint8_t tail = buffer->tail;
480: 0000000c andeq r0, r0, ip
480: R_ARM_ABS32 .text.fwrite
buffer->buffer[tail] = value;
484: 00000028 andeq r0, r0, r8, lsr #32
484: R_ARM_ABS32 .text.fwrite
buffer->tail = (tail + 1) & _USART_MAX;
488: 01f30004 mvnseq r0, r4
}
// Queues a byte onto the tail of the given buffer
static void _queueByte(volatile RingBuffer_TypeDef* buffer, char value) {
uint8_t tail = buffer->tail;
buffer->buffer[tail] = value;
48c: 00009f52 andeq r9, r0, r2, asr pc
...
496: R_ARM_ABS32 .text.fwrite
else {
// Buffer it up, if it's not full to the brim
if (!_isBufferFull(&(ser->rx)))
_queueByte(&(ser->rx), value);
// Notify any receivers
semaphoreGiveISR(ser->readLock, &cs);
498: 000c0000 andeq r0, ip, r0
49a: R_ARM_ABS32 .text.fwrite
49c: 00010000 andeq r0, r1, r0
}
}
if (USART2->SR & USART_SR_TXE) {
4a0: 00000c53 andeq r0, r0, r3, asr ip
4a1: R_ARM_ABS32 .text.fwrite
4a4: 00002800 andeq r2, r0, r0, lsl #16
4a5: R_ARM_ABS32 .text.fwrite
// Prototype this
uint32_t usartBufferCount(SerialPort_TypeDef* port);
// Checks to see if the ring buffer is empty (head = tail)
static INLINE uint8_t _isBufferEmpty(volatile RingBuffer_TypeDef* buffer) {
return buffer->head == buffer->tail;
4a8: 57000100 strpl r0, [r0, -r0, lsl #2]
...
// Notify any receivers
semaphoreGiveISR(ser->readLock, &cs);
}
}
if (USART2->SR & USART_SR_TXE) {
if (_isBufferEmpty(&(ser->tx)))
4b4: 00000004 andeq r0, r0, r4
4b4: R_ARM_ABS32 .text.fwrite
// Nothing to send, disable interrupt
USART2->CR1 &= ~USART_CR1_TXEIE;
4b8: 0000000c andeq r0, r0, ip
4b8: R_ARM_ABS32 .text.fwrite
4bc: 10500001 subsne r0, r0, r1
4bf: R_ARM_ABS32 .text.fwrite
4c0: 22000000 andcs r0, r0, #0
4c3: R_ARM_ABS32 .text.fwrite
return ((buffer->tail + 1) & _USART_MAX) == buffer->head;
}
// Removes a byte from the head of the given buffer
static char _pullByte(volatile RingBuffer_TypeDef* buffer) {
uint8_t head = buffer->head; char value;
4c4: 08000000 stmdaeq r0, {} ; <UNPREDICTABLE>
4c8: 74007600 strvc r7, [r0], #-1536 ; 0xfffffa00
value = buffer->buffer[head];
4cc: 01232200 ; <UNDEFINED> instruction: 0x01232200
buffer->head = (head + 1) & _USART_MAX;
4d0: 0000229f muleq r0, pc, r2 ; <UNPREDICTABLE>
4d1: R_ARM_ABS32 .text.fwrite
4d4: 00002400 andeq r2, r0, r0, lsl #8
4d5: R_ARM_ABS32 .text.fwrite
4d8: 76000600 strvc r0, [r0], -r0, lsl #12
if (_isBufferEmpty(&(ser->tx)))
// Nothing to send, disable interrupt
USART2->CR1 &= ~USART_CR1_TXEIE;
else {
value = _pullByte(&(ser->tx));
USART2->DR = value;
4dc: 22007400 andcs r7, r0, #0, 8
}
}
if (cs)
4e0: 0000009f muleq r0, pc, r0 ; <UNPREDICTABLE>
4e4: 00000000 andeq r0, r0, r0
4e8: 00000400 andeq r0, r0, r0, lsl #8
4e9: R_ARM_ABS32 .text.fwrite
4ec: 00000c00 andeq r0, r0, r0, lsl #24
4ed: R_ARM_ABS32 .text.fwrite
_taskYield();
}
4f0: 30000200 andcc r0, r0, r0, lsl #4
4f4: 00000c9f muleq r0, pc, ip ; <UNPREDICTABLE>
4f5: R_ARM_ABS32 .text.fwrite
4f8: 00002800 andeq r2, r0, r0, lsl #16
4f9: R_ARM_ABS32 .text.fwrite
4fc: 54000100 strpl r0, [r0], #-256 ; 0xffffff00
...
508: R_ARM_ABS32 .text.putchar
// ISR_USART3 - Buffered character I/O handler for UART port 2
void ISR_USART3() {
50c: 00000005 andeq r0, r0, r5
50c: R_ARM_ABS32 .text.putchar
510: 05500001 ldrbeq r0, [r0, #-1]
513: R_ARM_ABS32 .text.putchar
514: 06000000 streq r0, [r0], -r0
517: R_ARM_ABS32 .text.putchar
char value;
bool cs = false;
518: 04000000 streq r0, [r0], #-0
SerialPort_TypeDef *ser = &usart[1];
if (USART3->SR & USART_SR_RXNE) {
51c: 5001f300 andpl pc, r1, r0, lsl #6
520: 0000009f muleq r0, pc, r0 ; <UNPREDICTABLE>
// Read to clear the flag
value = (char)USART3->DR;
if (lcd[1].flags & LCD_ACTIVE)
524: 00000000 andeq r0, r0, r0
528: 00002000 andeq r2, r0, r0
529: R_ARM_ABS32 .text.ISR_USART1
52c: 00004a00 andeq r4, r0, r0, lsl #20
52d: R_ARM_ABS32 .text.ISR_USART1
lcdButtonProcess(value, 1);
530: 51000100 mrspl r0, (UNDEF: 16)
...
return buffer->head == buffer->tail;
}
// Checks to see if the ring buffer is full (tail + 1 = head)
static INLINE uint8_t _isBufferFull(volatile RingBuffer_TypeDef* buffer) {
return ((buffer->tail + 1) & _USART_MAX) == buffer->head;
53c: 00000020 andeq r0, r0, r0, lsr #32
53c: R_ARM_ABS32 .text.ISR_USART1
540: 00000056 andeq r0, r0, r6, asr r0
540: R_ARM_ABS32 .text.ISR_USART1
544: 9a030006 bls c0020 <usart+0xbffd8>
547: R_ARM_ABS32 .bss
value = (char)USART3->DR;
if (lcd[1].flags & LCD_ACTIVE)
lcdButtonProcess(value, 1);
else {
// Buffer it up, if it's not full to the brim
if (!_isBufferFull(&(ser->rx)))
548: 9f000001 svcls 0x00000001
...
// Queues a byte onto the tail of the given buffer
static void _queueByte(volatile RingBuffer_TypeDef* buffer, char value) {
uint8_t tail = buffer->tail;
buffer->buffer[tail] = value;
buffer->tail = (tail + 1) & _USART_MAX;
554: 00000032 andeq r0, r0, r2, lsr r0
554: R_ARM_ABS32 .text.ISR_USART1
558: 0000004a andeq r0, r0, sl, asr #32
558: R_ARM_ABS32 .text.ISR_USART1
}
// Queues a byte onto the tail of the given buffer
static void _queueByte(volatile RingBuffer_TypeDef* buffer, char value) {
uint8_t tail = buffer->tail;
buffer->buffer[tail] = value;
55c: 00510001 subseq r0, r1, r1
buffer->tail = (tail + 1) & _USART_MAX;
560: 00000000 andeq r0, r0, r0
else {
// Buffer it up, if it's not full to the brim
if (!_isBufferFull(&(ser->rx)))
_queueByte(&(ser->rx), value);
// Notify any receivers
semaphoreGiveISR(ser->readLock, &cs);
564: 32000000 andcc r0, r0, #0
567: R_ARM_ABS32 .text.ISR_USART1
568: 4a000000 bmi 8 <.debug_loc+0x8>
56b: R_ARM_ABS32 .text.ISR_USART1
56c: 06000000 streq r0, [r0], -r0
}
}
if (USART3->SR & USART_SR_TXE) {
570: 019a0300 orrseq r0, sl, r0, lsl #6
572: R_ARM_ABS32 .bss
574: 009f0000 addseq r0, pc, r0
// Prototype this
uint32_t usartBufferCount(SerialPort_TypeDef* port);
// Checks to see if the ring buffer is empty (head = tail)
static INLINE uint8_t _isBufferEmpty(volatile RingBuffer_TypeDef* buffer) {
return buffer->head == buffer->tail;
578: 00000000 andeq r0, r0, r0
57c: 3a000000 bcc 8 <.debug_loc+0x8>
57f: R_ARM_ABS32 .text.ISR_USART1
// Notify any receivers
semaphoreGiveISR(ser->readLock, &cs);
}
}
if (USART3->SR & USART_SR_TXE) {
if (_isBufferEmpty(&(ser->tx)))
580: 3e000000 cdpcc 0, 0, cr0, cr0, cr0, {0}
583: R_ARM_ABS32 .text.ISR_USART1
// Nothing to send, disable interrupt
USART3->CR1 &= ~USART_CR1_TXEIE;
584: 01000000 mrseq r0, (UNDEF: 0)
588: 003e5200 eorseq r5, lr, r0, lsl #4
58a: R_ARM_ABS32 .text.ISR_USART1
58c: 00420000 subeq r0, r2, r0
58e: R_ARM_ABS32 .text.ISR_USART1
590: 00030000 andeq r0, r3, r0
return ((buffer->tail + 1) & _USART_MAX) == buffer->head;
}
// Removes a byte from the head of the given buffer
static char _pullByte(volatile RingBuffer_TypeDef* buffer) {
uint8_t head = buffer->head; char value;
594: 429f7f72 addsmi r7, pc, #456 ; 0x1c8
597: R_ARM_ABS32 .text.ISR_USART1
value = buffer->buffer[head];
598: 4a000000 bmi 8 <.debug_loc+0x8>
59b: R_ARM_ABS32 .text.ISR_USART1
59c: 05000000 streq r0, [r0, #-0]
buffer->head = (head + 1) & _USART_MAX;
5a0: 019b0300 orrseq r0, fp, r0, lsl #6
5a2: R_ARM_ABS32 .bss
...
if (_isBufferEmpty(&(ser->tx)))
// Nothing to send, disable interrupt
USART3->CR1 &= ~USART_CR1_TXEIE;
else {
value = _pullByte(&(ser->tx));
USART3->DR = value;
5ac: 005e0000 subseq r0, lr, r0
5ae: R_ARM_ABS32 .text.ISR_USART1
}
}
if (cs)
5b0: 00960000 addseq r0, r6, r0
5b2: R_ARM_ABS32 .text.ISR_USART1
5b4: 00060000 andeq r0, r6, r0
5b8: 00015803 andeq r5, r1, r3, lsl #16
5b9: R_ARM_ABS32 .bss
5bc: 00009f00 andeq r9, r0, r0, lsl #30
_taskYield();
}
5c0: 00000000 andeq r0, r0, r0
5c4: 007a0000 rsbseq r0, sl, r0
5c6: R_ARM_ABS32 .text.ISR_USART1
5c8: 00960000 addseq r0, r6, r0
5ca: R_ARM_ABS32 .text.ISR_USART1
5cc: 00060000 andeq r0, r6, r0
5d0: 00015803 andeq r5, r1, r3, lsl #16
5d1: R_ARM_ABS32 .bss
}
// lcdReadButtons - Reads the button status from the LCD display and returns the buttons
// pressed as a bit mask. Does not block, always returns the last button status
unsigned int lcdReadButtons(FILE *lcdPort) {
uint32_t port = (uint32_t)lcdPort - 1;
5d4: 00009f00 andeq r9, r0, r0, lsl #30
if (port < 2) {
5d8: 00000000 andeq r0, r0, r0
if (lcd[port].flags & LCD_ACTIVE)
5dc: 00800000 addeq r0, r0, r0
5de: R_ARM_ABS32 .text.ISR_USART1
5e0: 00880000 addeq r0, r8, r0
5e2: R_ARM_ABS32 .text.ISR_USART1
5e4: 00010000 andeq r0, r1, r0
5e8: 00008853 andeq r8, r0, r3, asr r8
5e9: R_ARM_ABS32 .text.ISR_USART1
5ec: 00008c00 andeq r8, r0, r0, lsl #24
5ed: R_ARM_ABS32 .text.ISR_USART1
5f0: 73000300 movwvc r0, #768 ; 0x300
return (uint32_t)(lcd[port].buttons);
5f4: 008c9f7f addeq r9, ip, pc, ror pc
5f6: R_ARM_ABS32 .text.ISR_USART1
}
return 0;
5f8: 00960000 addseq r0, r6, r0
5fa: R_ARM_ABS32 .text.ISR_USART1
}
5fc: 00050000 andeq r0, r5, r0
// lcdSetBacklight - Turns the specified LCD backlight on or off
// The backlight will not update until the next line is sent (maybe 15ms latency)
void lcdSetBacklight(FILE *lcdPort, bool backlight) {
uint32_t port = (uint32_t)lcdPort - 1;
600: 00015803 andeq r5, r1, r3, lsl #16
601: R_ARM_ABS32 .bss
...
if (port < 2) {
if (backlight)
lcd[port].flags |= LCD_BACKLIGHT;
60c: 00008600 andeq r8, r0, r0, lsl #12
60d: R_ARM_ABS32 .text.ISR_USART1
610: 00009600 andeq r9, r0, r0, lsl #12
611: R_ARM_ABS32 .text.ISR_USART1
614: 52000100 andpl r0, r0, #0, 2
...
else
lcd[port].flags &= ~LCD_BACKLIGHT;
620: 00000020 andeq r0, r0, r0, lsr #32
620: R_ARM_ABS32 .text.ISR_USART2
624: 0000002d andeq r0, r0, sp, lsr #32
624: R_ARM_ABS32 .text.ISR_USART2
// _lcdDump - Dumps characters from the buffers to active LCDs (run from the IDLE TASK)
// lcdIndex == 0 for port #1 or 1 for port #2
void _lcdDump(uint32_t lcdIndex) {
// 22 byte packets
uint8_t flags = lcd[lcdIndex].flags, total;
628: 30500001 subscc r0, r0, r1
62b: R_ARM_ABS32 .text.ISR_USART2
}
}
// _lcdDump - Dumps characters from the buffers to active LCDs (run from the IDLE TASK)
// lcdIndex == 0 for port #1 or 1 for port #2
void _lcdDump(uint32_t lcdIndex) {
62c: 5c000000 stcpl 0, cr0, [r0], {-0}
62f: R_ARM_ABS32 .text.ISR_USART2
// 22 byte packets
uint8_t flags = lcd[lcdIndex].flags, total;
630: 01000000 mrseq r0, (UNDEF: 0)
634: 00005000 andeq r5, r0, r0
if (flags & LCD_ACTIVE) {
638: 00000000 andeq r0, r0, r0
// Concoct the port
FILE *lcdPort = (FILE*)(lcdIndex + 1);
char value, *ptr = &(lcd[lcdIndex].screen[0]);
63c: 00300000 eorseq r0, r0, r0
63e: R_ARM_ABS32 .text.ISR_USART2
// Set line (alternating order)
if (flags & LCD_ROW_2) {
ptr += 16;
lcd[lcdIndex].flags = flags & ~LCD_ROW_2;
640: 00640000 rsbeq r0, r4, r0
642: R_ARM_ABS32 .text.ISR_USART2
644: 00060000 andeq r0, r6, r0
} else
lcd[lcdIndex].flags = flags | LCD_ROW_2;
648: 00008a03 andeq r8, r0, r3, lsl #20
649: R_ARM_ABS32 .bss
void _lcdDump(uint32_t lcdIndex) {
// 22 byte packets
uint8_t flags = lcd[lcdIndex].flags, total;
if (flags & LCD_ACTIVE) {
// Concoct the port
FILE *lcdPort = (FILE*)(lcdIndex + 1);
64c: 00009f00 andeq r9, r0, r0, lsl #30
char value, *ptr = &(lcd[lcdIndex].screen[0]);
// Set line (alternating order)
if (flags & LCD_ROW_2) {
ptr += 16;
lcd[lcdIndex].flags = flags & ~LCD_ROW_2;
650: 00000000 andeq r0, r0, r0
} else
lcd[lcdIndex].flags = flags | LCD_ROW_2;
654: 00420000 subeq r0, r2, r0
656: R_ARM_ABS32 .text.ISR_USART2
flags &= (LCD_ROW_2 | LCD_BACKLIGHT);
// Sync bytes
fputc(0xAA, lcdPort);
658: 00580000 subseq r0, r8, r0
65a: R_ARM_ABS32 .text.ISR_USART2
65c: 00010000 andeq r0, r1, r0
// Concoct the port
FILE *lcdPort = (FILE*)(lcdIndex + 1);
char value, *ptr = &(lcd[lcdIndex].screen[0]);
// Set line (alternating order)
if (flags & LCD_ROW_2) {
ptr += 16;
660: 00000050 andeq r0, r0, r0, asr r0
lcd[lcdIndex].flags = flags & ~LCD_ROW_2;
} else
lcd[lcdIndex].flags = flags | LCD_ROW_2;
flags &= (LCD_ROW_2 | LCD_BACKLIGHT);
// Sync bytes
fputc(0xAA, lcdPort);
664: 00000000 andeq r0, r0, r0
fputc(0x55, lcdPort);
668: 00004200 andeq r4, r0, r0, lsl #4
669: R_ARM_ABS32 .text.ISR_USART2
66c: 00005800 andeq r5, r0, r0, lsl #16
66d: R_ARM_ABS32 .text.ISR_USART2
// Packet type 1E
fputc(0x1E, lcdPort);
670: 03000600 movweq r0, #1536 ; 0x600
674: 0000008a andeq r0, r0, sl, lsl #1
674: R_ARM_ABS32 .bss
if (flags & LCD_ROW_2) {
ptr += 16;
lcd[lcdIndex].flags = flags & ~LCD_ROW_2;
} else
lcd[lcdIndex].flags = flags | LCD_ROW_2;
flags &= (LCD_ROW_2 | LCD_BACKLIGHT);
678: 0000009f muleq r0, pc, r0 ; <UNPREDICTABLE>
fputc(0xAA, lcdPort);
fputc(0x55, lcdPort);
// Packet type 1E
fputc(0x1E, lcdPort);
// 18 bytes to follow
fputc(0x12, lcdPort);
67c: 00000000 andeq r0, r0, r0
680: 00004800 andeq r4, r0, r0, lsl #16
681: R_ARM_ABS32 .text.ISR_USART2
// LCD flags
fputc((char)flags, lcdPort);
684: 00004c00 andeq r4, r0, r0, lsl #24
685: R_ARM_ABS32 .text.ISR_USART2
688: 52000100 andpl r0, r0, #0, 2
total = flags;
// Run until out of space or end of buffer
for (uint32_t i = 0; i < 16; i++) {
value = *ptr;
68c: 0000004c andeq r0, r0, ip, asr #32
68c: R_ARM_ABS32 .text.ISR_USART2
if (value) {
690: 00000050 andeq r0, r0, r0, asr r0
690: R_ARM_ABS32 .text.ISR_USART2
694: 7f720003 svcvc 0x00720003
// Output text
fputc(value, lcdPort);
698: 0000509f muleq r0, pc, r0 ; <UNPREDICTABLE>
699: R_ARM_ABS32 .text.ISR_USART2
total += (uint8_t)(value);
69c: 00005400 andeq r5, r0, r0, lsl #8
69d: R_ARM_ABS32 .text.ISR_USART2
// Run until out of space or end of buffer
for (uint32_t i = 0; i < 16; i++) {
value = *ptr;
if (value) {
// Output text
fputc(value, lcdPort);
6a0: 03000500 movweq r0, #1280 ; 0x500
total += (uint8_t)(value);
ptr++;
6a4: 0000008b andeq r0, r0, fp, lsl #1
6a4: R_ARM_ABS32 .bss
...
} else {
// Pad with spaces
fputc(' ', lcdPort);
total += (uint8_t)' ';
6b0: 0000006c andeq r0, r0, ip, rrx
6b0: R_ARM_ABS32 .text.ISR_USART2
fputc(0x12, lcdPort);
// LCD flags
fputc((char)flags, lcdPort);
total = flags;
// Run until out of space or end of buffer
for (uint32_t i = 0; i < 16; i++) {
6b4: 000000a4 andeq r0, r0, r4, lsr #1
6b4: R_ARM_ABS32 .text.ISR_USART2
fputc(' ', lcdPort);
total += (uint8_t)' ';
}
}
// Checksum
fputc((char)((uint8_t)(-total)), lcdPort);
6b8: 48030006 stmdami r3, {r1, r2}
6bb: R_ARM_ABS32 .bss
}
}
6bc: 9f000000 svcls 0x00000000
...
fputc(' ', lcdPort);
total += (uint8_t)' ';
}
}
// Checksum
fputc((char)((uint8_t)(-total)), lcdPort);
6c8: 00000088 andeq r0, r0, r8, lsl #1
6c8: R_ARM_ABS32 .text.ISR_USART2
6cc: 000000a4 andeq r0, r0, r4, lsr #1
6cc: R_ARM_ABS32 .text.ISR_USART2
// lcdSetText - Sets a line (1 or 2) of text on the LCD to the specified null-terminated string
// Up to 16 characters will actually be transmitted; this function is thread safe, but
// concurrent access to the same line of the same LCD will cause garbage text to be displayed
void lcdSetText(FILE *lcdPort, unsigned char line, const char *buffer) {
// Blit to the buffer, automatically dumped on the idle task
uint32_t port = (uint32_t)lcdPort - 1, i;
6d0: 48030006 stmdami r3, {r1, r2}
6d3: R_ARM_ABS32 .bss
}
// lcdSetText - Sets a line (1 or 2) of text on the LCD to the specified null-terminated string
// Up to 16 characters will actually be transmitted; this function is thread safe, but
// concurrent access to the same line of the same LCD will cause garbage text to be displayed
void lcdSetText(FILE *lcdPort, unsigned char line, const char *buffer) {
6d4: 9f000000 svcls 0x00000000
...
// Blit to the buffer, automatically dumped on the idle task
uint32_t port = (uint32_t)lcdPort - 1, i;
line--;
if (port < 2 && line < 2) {
// Find pointer to location
char *scr = &(lcd[port].screen[0]);
6e0: 0000008e andeq r0, r0, lr, lsl #1
6e0: R_ARM_ABS32 .text.ISR_USART2
6e4: 00000096 muleq r0, r6, r0
6e4: R_ARM_ABS32 .text.ISR_USART2
if (line) scr += 16;
6e8: 96530001 ldrbls r0, [r3], -r1
6eb: R_ARM_ABS32 .text.ISR_USART2
6ec: 9a000000 bls 8 <.debug_loc+0x8>
6ef: R_ARM_ABS32 .text.ISR_USART2
for (i = 0; i < 16; i++) {
// Space pad to 16 characters
if (*buffer)
6f0: 03000000 movweq r0, #0
*scr++ = *buffer++;
6f4: 9f7f7300 svcls 0x007f7300
else
*scr++ = ' ';
6f8: 0000009a muleq r0, sl, r0
6f8: R_ARM_ABS32 .text.ISR_USART2
6fc: 000000a4 andeq r0, r0, r4, lsr #1
6fc: R_ARM_ABS32 .text.ISR_USART2
line--;
if (port < 2 && line < 2) {
// Find pointer to location
char *scr = &(lcd[port].screen[0]);
if (line) scr += 16;
for (i = 0; i < 16; i++) {
700: 48030005 stmdami r3, {r0, r2}
703: R_ARM_ABS32 .bss
...
if (cs)
_taskYield();
}
// lcdClear - Clears the screen
void lcdClear(FILE *lcdPort) {
70c: 94000000 strls r0, [r0], #-0
70f: R_ARM_ABS32 .text.ISR_USART2
lcdSetText(lcdPort, 1, "");
710: a4000000 strge r0, [r0], #-0
713: R_ARM_ABS32 .text.ISR_USART2
714: 01000000 mrseq r0, (UNDEF: 0)
718: 00005200 andeq r5, r0, r0, lsl #4
lcdSetText(lcdPort, 2, "");
71c: 00000000 andeq r0, r0, r0
}
720: 00200000 eoreq r0, r0, r0
722: R_ARM_ABS32 .text.ISR_USART3
}
// lcdClear - Clears the screen
void lcdClear(FILE *lcdPort) {
lcdSetText(lcdPort, 1, "");
lcdSetText(lcdPort, 2, "");
724: 002f0000 eoreq r0, pc, r0
726: R_ARM_ABS32 .text.ISR_USART3
728: 00010000 andeq r0, r1, r0
lcd[idx].buttons = 0;
}
}
// lcdPrint - Convenience method that performs snprintf() and then lcdSetText()
void lcdPrint(FILE *lcdPort, unsigned char line, const char *fmt, ...) {
72c: 00003250 andeq r3, r0, r0, asr r2
72d: R_ARM_ABS32 .text.ISR_USART3
730: 00005e00 andeq r5, r0, r0, lsl #28
731: R_ARM_ABS32 .text.ISR_USART3
734: 50000100 andpl r0, r0, r0, lsl #2
...
char buffer[17];
// Pass to vsnprintf
va_list args;
va_start(args, fmt);
740: 00000032 andeq r0, r0, r2, lsr r0
740: R_ARM_ABS32 .text.ISR_USART3
vsnprintf(buffer, 17, fmt, args);
744: 00000066 andeq r0, r0, r6, rrx
744: R_ARM_ABS32 .text.ISR_USART3
va_end(args);
// Ensure that there are no null-terminator issues
buffer[16] = 0;
lcdSetText(lcdPort, line, buffer);
748: 12030006 andne r0, r3, #6
74b: R_ARM_ABS32 .bss
74c: 9f000001 svcls 0x00000001
...
}
758: 00000044 andeq r0, r0, r4, asr #32
758: R_ARM_ABS32 .text.ISR_USART3
75c: 0000005a andeq r0, r0, sl, asr r0
75c: R_ARM_ABS32 .text.ISR_USART3
port->rx.tail = 0;
port->readLock = semaphoreCreate();
}
// usartBufferCount - Determine the number of available characters on the specified USART
uint32_t usartBufferCount(SerialPort_TypeDef* port) {
760: 00500001 subseq r0, r0, r1
extern volatile uint32_t _criticalNesting;
/* Enter a critical section. */
static INLINE void _enterCritical() {
__disable_irq();
_criticalNesting++;
764: 00000000 andeq r0, r0, r0
768: 44000000 strmi r0, [r0], #-0
76b: R_ARM_ABS32 .text.ISR_USART3
uint32_t head, tail;
_enterCritical();
head = (uint32_t)port->rx.head;
76c: 5a000000 bpl 8 <.debug_loc+0x8>
76f: R_ARM_ABS32 .text.ISR_USART3
tail = (uint32_t)port->rx.tail;
770: 06000000 streq r0, [r0], -r0
}
/* Exit a critical section. */
static INLINE void _exitCritical() {
const uint32_t newCritical = _criticalNesting - 1;
774: 01120300 tsteq r2, r0, lsl #6
776: R_ARM_ABS32 .bss
778: 009f0000 addseq r0, pc, r0
_criticalNesting = newCritical;
77c: 00000000 andeq r0, r0, r0
780: 4a000000 bmi 8 <.debug_loc+0x8>
783: R_ARM_ABS32 .text.ISR_USART3
_exitCritical();
return (tail - head) & (uint32_t)_USART_MAX;
}
784: 4e000000 cdpmi 0, 0, cr0, cr0, cr0, {0}
787: R_ARM_ABS32 .text.ISR_USART3
788: 01000000 mrseq r0, (UNDEF: 0)
78c: 004e5200 subeq r5, lr, r0, lsl #4
78e: R_ARM_ABS32 .text.ISR_USART3
_yield();
}
// fcount - Non-standard function to return estimated number of characters waiting on stream
int fcount(FILE *stream) {
uint32_t snew = (uint32_t)stream - 1;
790: 00520000 subseq r0, r2, r0
792: R_ARM_ABS32 .text.ISR_USART3
if (snew < 3)
794: 00030000 andeq r0, r3, r0
return (int)usartBufferCount(&usart[snew]);
798: 529f7f72 addspl r7, pc, #456 ; 0x1c8
79b: R_ARM_ABS32 .text.ISR_USART3
79c: 56000000 strpl r0, [r0], -r0
79f: R_ARM_ABS32 .text.ISR_USART3
7a0: 05000000 streq r0, [r0, #-0]
#ifndef NO_FILESYSTEM
// File system check
return fsLeft(stream);
7a4: 01130300 tsteq r3, r0, lsl #6
7a6: R_ARM_ABS32 .bss
...
}
// feof - Return 1 if the stream is at EOF, or 0 otherwise
int feof(FILE *stream) {
uint32_t snew = (uint32_t)stream - 1;
if (snew < 3)
7b0: 006e0000 rsbeq r0, lr, r0
7b2: R_ARM_ABS32 .text.ISR_USART3
#ifndef NO_FILESYSTEM
return fsEof(stream);
#else
return 1;
#endif
}
7b4: 00a60000 adceq r0, r6, r0
7b6: R_ARM_ABS32 .text.ISR_USART3
int feof(FILE *stream) {
uint32_t snew = (uint32_t)stream - 1;
if (snew < 3)
return (usartBufferCount(&usart[snew]) == 0) ? 1 : 0;
#ifndef NO_FILESYSTEM
return fsEof(stream);
7b8: 00060000 andeq r0, r6, r0
// feof - Return 1 if the stream is at EOF, or 0 otherwise
int feof(FILE *stream) {
uint32_t snew = (uint32_t)stream - 1;
if (snew < 3)
return (usartBufferCount(&usart[snew]) == 0) ? 1 : 0;
7bc: 0000d003 andeq sp, r0, r3
7bd: R_ARM_ABS32 .bss
7c0: 00009f00 andeq r9, r0, r0, lsl #30
7c4: 00000000 andeq r0, r0, r0
7c8: 008a0000 addeq r0, sl, r0
7ca: R_ARM_ABS32 .text.ISR_USART3
7cc: 00a60000 adceq r0, r6, r0
7ce: R_ARM_ABS32 .text.ISR_USART3
#ifndef NO_FILESYSTEM
return fsEof(stream);
#else
return 1;
#endif
}
7d0: 00060000 andeq r0, r6, r0
return EOF;
#endif
}
// fgets - Read a string from the specified stream
char* fgets(char *str, int num, FILE *stream) {
7d4: 0000d003 andeq sp, r0, r3
7d5: R_ARM_ABS32 .bss
// Required by standard
char *ptr = str;
int value;
if (feof(stream)) return NULL;
7d8: 00009f00 andeq r9, r0, r0, lsl #30
return EOF;
#endif
}
// fgets - Read a string from the specified stream
char* fgets(char *str, int num, FILE *stream) {
7dc: 00000000 andeq r0, r0, r0
// Required by standard
char *ptr = str;
int value;
if (feof(stream)) return NULL;
7e0: 00900000 addseq r0, r0, r0
7e2: R_ARM_ABS32 .text.ISR_USART3
7e4: 00980000 addseq r0, r8, r0
7e6: R_ARM_ABS32 .text.ISR_USART3
7e8: 00010000 andeq r0, r1, r0
// Read at most num-1 characters
for (; num > 1 && (value = fgetc(stream)) != EOF; num--) {
7ec: 00009853 andeq r9, r0, r3, asr r8
7ed: R_ARM_ABS32 .text.ISR_USART3
7f0: 00009c00 andeq r9, r0, r0, lsl #24
7f1: R_ARM_ABS32 .text.ISR_USART3
7f4: 73000300 movwvc r0, #768 ; 0x300
*ptr++ = (char)value;
7f8: 009c9f7f addseq r9, ip, pc, ror pc
7fa: R_ARM_ABS32 .text.ISR_USART3
// Exit loop (including new line) when a new line is found
if ((char)value == '\n') break;
7fc: 00a60000 adceq r0, r6, r0
7fe: R_ARM_ABS32 .text.ISR_USART3
800: 00050000 andeq r0, r5, r0
}
// Add null terminator
*ptr = '\0';
804: 0000d003 andeq sp, r0, r3
805: R_ARM_ABS32 .bss
...
_exitCritical();
return (tail - head) & (uint32_t)_USART_MAX;
}
// usartBufferInit - Initializes (empty) the USART buffers
void usartBufferInit() {
810: 00009600 andeq r9, r0, r0, lsl #12
811: R_ARM_ABS32 .text.ISR_USART3
}
}
// _usartBufferInit - Clears one particular buffer and sets up its semaphore
static INLINE void _usartBufferInit(SerialPort_TypeDef* port) {
port->rx.head = 0;
814: 0000a600 andeq sl, r0, r0, lsl #12
815: R_ARM_ABS32 .text.ISR_USART3
818: 52000100 andpl r0, r0, #0, 2
...
824: R_ARM_ABS32 .text.lcdReadButtons
port->rx.tail = 0;
port->tx.head = 0;
port->rx.tail = 0;
port->readLock = semaphoreCreate();
828: 0000000a andeq r0, r0, sl
828: R_ARM_ABS32 .text.lcdReadButtons
}
}
// _usartBufferInit - Clears one particular buffer and sets up its semaphore
static INLINE void _usartBufferInit(SerialPort_TypeDef* port) {
port->rx.head = 0;
82c: 0a500001 beq 140000c <usart+0x13fffc4>
82f: R_ARM_ABS32 .text.lcdReadButtons
port->rx.tail = 0;
port->tx.head = 0;
port->rx.tail = 0;
port->readLock = semaphoreCreate();
830: 12000000 andne r0, r0, #0
833: R_ARM_ABS32 .text.lcdReadButtons
}
// _usartBufferInit - Clears one particular buffer and sets up its semaphore
static INLINE void _usartBufferInit(SerialPort_TypeDef* port) {
port->rx.head = 0;
port->rx.tail = 0;
834: 03000000 movweq r0, #0
port->tx.head = 0;
838: 9f017300 svcls 0x00017300
port->rx.tail = 0;
83c: 00000012 andeq r0, r0, r2, lsl r0
83c: R_ARM_ABS32 .text.lcdReadButtons
port->readLock = semaphoreCreate();
840: 00000024 andeq r0, r0, r4, lsr #32
840: R_ARM_ABS32 .text.lcdReadButtons
}
}
// _usartBufferInit - Clears one particular buffer and sets up its semaphore
static INLINE void _usartBufferInit(SerialPort_TypeDef* port) {
port->rx.head = 0;
844: 01f30004 mvnseq r0, r4
port->rx.tail = 0;
port->tx.head = 0;
port->rx.tail = 0;
port->readLock = semaphoreCreate();
848: 00249f50 eoreq r9, r4, r0, asr pc
84a: R_ARM_ABS32 .text.lcdReadButtons
}
// _usartBufferInit - Clears one particular buffer and sets up its semaphore
static INLINE void _usartBufferInit(SerialPort_TypeDef* port) {
port->rx.head = 0;
port->rx.tail = 0;
84c: 00260000 eoreq r0, r6, r0
84e: R_ARM_ABS32 .text.lcdReadButtons
port->tx.head = 0;
850: 00010000 andeq r0, r1, r0
port->rx.tail = 0;
854: 00002650 andeq r2, r0, r0, asr r6
855: R_ARM_ABS32 .text.lcdReadButtons
port->readLock = semaphoreCreate();
858: 00002c00 andeq r2, r0, r0, lsl #24
859: R_ARM_ABS32 .text.lcdReadButtons
85c: f3000400 vshl.u8 d0, d0, d0
860: 009f5001 addseq r5, pc, r1
#define USART_CR3_CTSE ((uint16_t)0x0200)
// Disables FAULT interrupts
static inline void __disable_fault_irq() { asm volatile ("cpsid f"); }
// Disables interrupts
static inline void __disable_irq() { asm volatile ("cpsid i"); }
864: 00000000 andeq r0, r0, r0
}
// usartFlushBuffers - Clears the USART output buffers (Trashes data! From ALL USARTS!)
void usartFlushBuffers() {
__disable_irq();
usart[0].tx.tail = usart[0].tx.head;
868: 02000000 andeq r0, r0, #0
86b: R_ARM_ABS32 .text.lcdReadButtons
86c: 12000000 andne r0, r0, #0
86f: R_ARM_ABS32 .text.lcdReadButtons
870: 01000000 mrseq r0, (UNDEF: 0)
usart[1].tx.tail = usart[1].tx.head;
874: 00125300 andseq r5, r2, r0, lsl #6
876: R_ARM_ABS32 .text.lcdReadButtons
878: 00240000 eoreq r0, r4, r0
87a: R_ARM_ABS32 .text.lcdReadButtons
usart[2].tx.tail = usart[2].tx.head;
87c: 00060000 andeq r0, r6, r0
880: 315001f3 ldrshcc r0, [r0, #-19] ; 0xffffffed
884: 00249f1c eoreq r9, r4, ip, lsl pc
886: R_ARM_ABS32 .text.lcdReadButtons
// Waits for memory accesses to complete before continuing (Data Synchronization Barrier)
static inline void __dsb() { asm volatile ("dsb"); }
// Enables FAULT interrupts
static inline void __enable_fault_irq() { asm volatile ("cpsie f"); }
// Enables interrupts
static inline void __enable_irq() { asm volatile ("cpsie i"); }
888: 00260000 eoreq r0, r6, r0
88a: R_ARM_ABS32 .text.lcdReadButtons
88c: 00010000 andeq r0, r1, r0
// usartInit - Initialize the specified USART interface with the given connection parameters
// The interface argument can be 1 or 2 to specify UART1 and UART2 respectively
void usartInit(FILE *port, unsigned int baud, unsigned int flags) {
// Determine correct USART
USART_TypeDef *base;
if (port == uart1)
890: 00002653 andeq r2, r0, r3, asr r6
891: R_ARM_ABS32 .text.lcdReadButtons
894: 00002c00 andeq r2, r0, r0, lsl #24
895: R_ARM_ABS32 .text.lcdReadButtons
base = USART2;
else if (port == uart2)
898: f3000600 vmax.u8 d0, d0, d0
base = USART3;
89c: 1c315001 ldcne 0, cr5, [r1], #-4
#define USART_CR3_CTSE ((uint16_t)0x0200)
// Disables FAULT interrupts
static inline void __disable_fault_irq() { asm volatile ("cpsid f"); }
// Disables interrupts
static inline void __disable_irq() { asm volatile ("cpsid i"); }
8a0: 0000009f muleq r0, pc, r0 ; <UNPREDICTABLE>
...
8a9: R_ARM_ABS32 .text.lcdSetBacklight
extern volatile uint32_t _criticalNesting;
/* Enter a critical section. */
static INLINE void _enterCritical() {
__disable_irq();
_criticalNesting++;
8ac: 00000200 andeq r0, r0, r0, lsl #4
8ad: R_ARM_ABS32 .text.lcdSetBacklight
else
// Invalid interface
return;
_enterCritical();
{
base->CR1 = 0;
8b0: 50000100 andpl r0, r0, r0, lsl #2
8b4: 00000002 andeq r0, r0, r2
8b4: R_ARM_ABS32 .text.lcdSetBacklight
// Flush buffers
if (port == uart1) {
usart[0].tx.tail = usart[0].tx.head;
8b8: 0000000e andeq r0, r0, lr
8b8: R_ARM_ABS32 .text.lcdSetBacklight
8bc: 01700003 cmneq r0, r3
usart[0].rx.tail = usart[0].rx.head;
} else {
usart[1].tx.tail = usart[1].tx.head;
8c0: 00000e9f muleq r0, pc, lr ; <UNPREDICTABLE>
8c1: R_ARM_ABS32 .text.lcdSetBacklight
8c4: 00002800 andeq r2, r0, r0, lsl #16
8c5: R_ARM_ABS32 .text.lcdSetBacklight
_enterCritical();
{
base->CR1 = 0;
// Flush buffers
if (port == uart1) {
usart[0].tx.tail = usart[0].tx.head;
8c8: f3000400 vshl.u8 d0, d0, d0
usart[0].rx.tail = usart[0].rx.head;
} else {
usart[1].tx.tail = usart[1].tx.head;
8cc: 009f5001 addseq r5, pc, r1
{
base->CR1 = 0;
// Flush buffers
if (port == uart1) {
usart[0].tx.tail = usart[0].tx.head;
usart[0].rx.tail = usart[0].rx.head;
8d0: 00000000 andeq r0, r0, r0
} else {
usart[1].tx.tail = usart[1].tx.head;
usart[1].rx.tail = usart[1].rx.head;
8d4: 02000000 andeq r0, r0, #0
8d7: R_ARM_ABS32 .text.lcdSetBacklight
}
// Configure base registers
base->CR2 = flags & (USART_CR2_STOP0 | USART_CR2_STOP1);
8d8: 0e000000 cdpeq 0, 0, cr0, cr0, cr0, {0}
8db: R_ARM_ABS32 .text.lcdSetBacklight
{
base->CR1 = 0;
// Flush buffers
if (port == uart1) {
usart[0].tx.tail = usart[0].tx.head;
usart[0].rx.tail = usart[0].rx.head;
8dc: 01000000 mrseq r0, (UNDEF: 0)
8e0: 000e5000 andeq r5, lr, r0
8e2: R_ARM_ABS32 .text.lcdSetBacklight
} else {
usart[1].tx.tail = usart[1].tx.head;
usart[1].rx.tail = usart[1].rx.head;
8e4: 00280000 eoreq r0, r8, r0
8e6: R_ARM_ABS32 .text.lcdSetBacklight
}
// Configure base registers
base->CR2 = flags & (USART_CR2_STOP0 | USART_CR2_STOP1);
8e8: 00060000 andeq r0, r6, r0
// Turn on USART
base->CR1 = USART_CR1_RXNEIE | USART_CR1_RE | USART_CR1_TE | USART_CR1_UE |
8ec: 315001f3 ldrshcc r0, [r0, #-19] ; 0xffffffed
8f0: 00009f1c andeq r9, r0, ip, lsl pc
...
8fa: R_ARM_ABS32 .text._lcdDump
8fc: 00360000 eorseq r0, r6, r0
8fe: R_ARM_ABS32 .text._lcdDump
(flags & (USART_CR1_PCE | USART_CR1_PS | USART_CR1_M));
base->CR3 = (uint16_t)0;
// Set baud rate
uint32_t brr = 225000000 / baud, mod = brr / 100, fracDiv = brr - (100 * mod);
900: 00010000 andeq r0, r1, r0
904: 00003650 andeq r3, r0, r0, asr r6
905: R_ARM_ABS32 .text._lcdDump
908: 00009800 andeq r9, r0, r0, lsl #16
909: R_ARM_ABS32 .text._lcdDump
90c: 75000300 strvc r0, [r0, #-768] ; 0xfffffd00
base->BRR = (uint16_t)(mod << 4) | (uint16_t)((((fracDiv << 4) + 50) / 100) & 0xF);
910: 00989f7f addseq r9, r8, pc, ror pc
912: R_ARM_ABS32 .text._lcdDump
914: 009d0000 addseq r0, sp, r0
916: R_ARM_ABS32 .text._lcdDump
918: 00030000 andeq r0, r3, r0
91c: 9d9f7f71 ldcls 15, cr7, [pc, #452] ; 1cc <.debug_loc+0x1cc>
91f: R_ARM_ABS32 .text._lcdDump
920: 9e000000 cdpls 0, 0, cr0, cr0, cr0, {0}
923: R_ARM_ABS32 .text._lcdDump
}
/* Exit a critical section. */
static INLINE void _exitCritical() {
const uint32_t newCritical = _criticalNesting - 1;
924: 04000000 streq r0, [r0], #-0
_criticalNesting = newCritical;
928: 5001f300 andpl pc, r1, r0, lsl #6
// Waits for memory accesses to complete before continuing (Data Synchronization Barrier)
static inline void __dsb() { asm volatile ("dsb"); }
// Enables FAULT interrupts
static inline void __enable_fault_irq() { asm volatile ("cpsie f"); }
// Enables interrupts
static inline void __enable_irq() { asm volatile ("cpsie i"); }
92c: 00009e9f muleq r0, pc, lr ; <UNPREDICTABLE>
92d: R_ARM_ABS32 .text._lcdDump
930: 0000a800 andeq sl, r0, r0, lsl #16
931: R_ARM_ABS32 .text._lcdDump
934: 50000100 andpl r0, r0, r0, lsl #2
...
940: 00000010 andeq r0, r0, r0, lsl r0
940: R_ARM_ABS32 .text._lcdDump
lcdSetText(lcdPort, 1, "");
lcdSetText(lcdPort, 2, "");
}
// lcdInit - Enables the LCD on the specified port
void lcdInit(FILE *lcdPort) {
944: 00000064 andeq r0, r0, r4, rrx
944: R_ARM_ABS32 .text._lcdDump
// No flags = 8 N 1
if (lcdPort == uart1 || lcdPort == uart2) {
948: 9e540001 cdpls 0, 5, cr0, cr4, cr1, {0}
94b: R_ARM_ABS32 .text._lcdDump
uint32_t idx = (uint32_t)lcdPort - 1;
usartInit(lcdPort, 19200, 0);
94c: a2000000 andge r0, r0, #0
94f: R_ARM_ABS32 .text._lcdDump
950: 01000000 mrseq r0, (UNDEF: 0)
954: 00a25400 adceq r5, r2, r0, lsl #8
956: R_ARM_ABS32 .text._lcdDump
// Clear LCD state, turn on
lcd[idx].flags = LCD_ACTIVE;
958: 00a80000 adceq r0, r8, r0
95a: R_ARM_ABS32 .text._lcdDump
95c: 00020000 andeq r0, r2, r0
960: 00002073 andeq r2, r0, r3, ror r0
964: 00000000 andeq r0, r0, r0
lcd[idx].state = 0;
968: 00620000 rsbeq r0, r2, r0
96a: R_ARM_ABS32 .text._lcdDump
lcd[idx].buttons = 0;
96c: 00760000 rsbseq r0, r6, r0
96e: R_ARM_ABS32 .text._lcdDump
970: 00010000 andeq r0, r1, r0
}
// usartShutdown - Disable the specified USART interface
void usartShutdown(FILE *usart) {
// Disable transmitter, receiver, clock, and interrupts
if (usart == uart1)
974: 00007c54 andeq r7, r0, r4, asr ip
975: R_ARM_ABS32 .text._lcdDump
USART2->CR1 = (uint16_t)0;
978: 00008a00 andeq r8, r0, r0, lsl #20
979: R_ARM_ABS32 .text._lcdDump
97c: 54000100 strpl r0, [r0], #-256 ; 0xffffff00
else if (usart == uart2)
980: 0000008c andeq r0, r0, ip, lsl #1
980: R_ARM_ABS32 .text._lcdDump
USART3->CR1 = (uint16_t)0;
984: 00000098 muleq r0, r8, r0
984: R_ARM_ABS32 .text._lcdDump
988: 00540001 subseq r0, r4, r1
98c: 00000000 andeq r0, r0, r0
990: 26000000 strcs r0, [r0], -r0
993: R_ARM_ABS32 .text._lcdDump
}
}
}
// lcdShutdown - Disable the LCD on the specified port
void lcdShutdown(FILE *lcdPort) {
994: 98000000 stmdals r0, {} ; <UNPREDICTABLE>
997: R_ARM_ABS32 .text._lcdDump
if (lcdPort == uart1 || lcdPort == uart2) {
998: 01000000 mrseq r0, (UNDEF: 0)
usartShutdown(lcdPort);
99c: 00985500 addseq r5, r8, r0, lsl #10
99e: R_ARM_ABS32 .text._lcdDump
lcd[(uint32_t)lcdPort - 1].flags = 0;
9a0: 009d0000 addseq r0, sp, r0
9a2: R_ARM_ABS32 .text._lcdDump
9a4: 00010000 andeq r0, r1, r0
9a8: 00009d51 andeq r9, r0, r1, asr sp
9a9: R_ARM_ABS32 .text._lcdDump
9ac: 00009e00 andeq r9, r0, r0, lsl #28
9ad: R_ARM_ABS32 .text._lcdDump
9b0: f3000600 vmax.u8 d0, d0, d0
9b4: 01235001 ; <UNDEFINED> instruction: 0x01235001
9b8: 0000009f muleq r0, pc, r0 ; <UNPREDICTABLE>
9bc: 00000000 andeq r0, r0, r0
9c0: 00006800 andeq r6, r0, r0, lsl #16
9c1: R_ARM_ABS32 .text._lcdDump
9c4: 00009800 andeq r9, r0, r0, lsl #16
9c5: R_ARM_ABS32 .text._lcdDump
9c8: 58000100 stmdapl r0, {r8}
...
9d4: 0000003a andeq r0, r0, sl, lsr r0
9d4: R_ARM_ABS32 .text._lcdDump
9d8: 00000098 muleq r0, r8, r0
9d8: R_ARM_ABS32 .text._lcdDump
9dc: 00560001 subseq r0, r6, r1
9e0: 00000000 andeq r0, r0, r0
9e4: 62000000 andvs r0, r0, #0
9e7: R_ARM_ABS32 .text._lcdDump
9e8: 64000000 strvs r0, [r0], #-0
9eb: R_ARM_ABS32 .text._lcdDump
9ec: 02000000 andeq r0, r0, #0
9f0: 649f3000 ldrvs r3, [pc], #0 ; 8 <.debug_loc+0x8>
9f3: R_ARM_ABS32 .text._lcdDump
9f4: 8c000000 stchi 0, cr0, [r0], {-0}
9f7: R_ARM_ABS32 .text._lcdDump
9f8: 05000000 streq r0, [r0, #-0]
9fc: 00774000 rsbseq r4, r7, r0
a00: 008c9f1c addeq r9, ip, ip, lsl pc
a02: R_ARM_ABS32 .text._lcdDump
a04: 008e0000 addeq r0, lr, r0
a06: R_ARM_ABS32 .text._lcdDump
a08: 00050000 andeq r0, r5, r0
a0c: 1c007741 stcne 7, cr7, [r0], {65} ; 0x41
a10: 00008e9f muleq r0, pc, lr ; <UNPREDICTABLE>
a11: R_ARM_ABS32 .text._lcdDump
a14: 00009800 andeq r9, r0, r0, lsl #16
a15: R_ARM_ABS32 .text._lcdDump
a18: 40000500 andmi r0, r0, r0, lsl #10
a1c: 9f1c0077 svcls 0x001c0077
...
a28: R_ARM_ABS32 .text.lcdSetText
a2c: 00000012 andeq r0, r0, r2, lsl r0
a2c: R_ARM_ABS32 .text.lcdSetText
a30: 12500001 subsne r0, r0, #1
a33: R_ARM_ABS32 .text.lcdSetText
a34: 1e000000 cdpne 0, 0, cr0, cr0, cr0, {0}
a37: R_ARM_ABS32 .text.lcdSetText
a38: 03000000 movweq r0, #0
a3c: 9f017300 svcls 0x00017300
a40: 0000001e andeq r0, r0, lr, lsl r0
a40: R_ARM_ABS32 .text.lcdSetText
a44: 0000003c andeq r0, r0, ip, lsr r0
a44: R_ARM_ABS32 .text.lcdSetText
a48: 01f30004 mvnseq r0, r4
a4c: 00009f50 andeq r9, r0, r0, asr pc
...
a56: R_ARM_ABS32 .text.lcdSetText
a58: 00020000 andeq r0, r2, r0
a5a: R_ARM_ABS32 .text.lcdSetText
a5c: 00010000 andeq r0, r1, r0
a60: 00000251 andeq r0, r0, r1, asr r2
a61: R_ARM_ABS32 .text.lcdSetText
a64: 00000a00 andeq r0, r0, r0, lsl #20
a65: R_ARM_ABS32 .text.lcdSetText
a68: 71000300 mrsvc r0, LR_irq
a6c: 000a9f7f andeq r9, sl, pc, ror pc
a6e: R_ARM_ABS32 .text.lcdSetText
a70: 003c0000 eorseq r0, ip, r0
a72: R_ARM_ABS32 .text.lcdSetText
a74: 00060000 andeq r0, r6, r0
a78: 315101f3 ldrshcc r0, [r1, #-19] ; 0xffffffed
a7c: 00009f1c andeq r9, r0, ip, lsl pc
...
a86: R_ARM_ABS32 .text.lcdSetText
a88: 00260000 eoreq r0, r6, r0
a8a: R_ARM_ABS32 .text.lcdSetText
a8c: 00010000 andeq r0, r1, r0
a90: 00002652 andeq r2, r0, r2, asr r6
a91: R_ARM_ABS32 .text.lcdSetText
a94: 00003c00 andeq r3, r0, r0, lsl #24
a95: R_ARM_ABS32 .text.lcdSetText
a98: 52000100 andpl r0, r0, #0, 2
...
aa4: 00000002 andeq r0, r0, r2
aa4: R_ARM_ABS32 .text.lcdSetText
aa8: 0000001e andeq r0, r0, lr, lsl r0
aa8: R_ARM_ABS32 .text.lcdSetText
aac: 1e530001 cdpne 0, 5, cr0, cr3, cr1, {0}
aaf: R_ARM_ABS32 .text.lcdSetText
ab0: 3c000000 stccc 0, cr0, [r0], {-0}
ab3: R_ARM_ABS32 .text.lcdSetText
ab4: 06000000 streq r0, [r0], -r0
ab8: 5001f300 andpl pc, r1, r0, lsl #6
abc: 009f1c31 addseq r1, pc, r1, lsr ip ; <UNPREDICTABLE>
ac0: 00000000 andeq r0, r0, r0
ac4: 1c000000 stcne 0, cr0, [r0], {-0}
ac7: R_ARM_ABS32 .text.lcdSetText
ac8: 20000000 andcs r0, r0, r0
acb: R_ARM_ABS32 .text.lcdSetText
acc: 02000000 andeq r0, r0, #0
ad0: 209f3000 addscs r3, pc, r0
ad3: R_ARM_ABS32 .text.lcdSetText
ad4: 2e000000 cdpcs 0, 0, cr0, cr0, cr0, {0}
ad7: R_ARM_ABS32 .text.lcdSetText
ad8: 07000000 streq r0, [r0, -r0]
adc: 206f7000 rsbcs r7, pc, r0
ae0: 9f220073 svcls 0x00220073
ae4: 0000002e andeq r0, r0, lr, lsr #32
ae4: R_ARM_ABS32 .text.lcdSetText
ae8: 00000030 andeq r0, r0, r0, lsr r0
ae8: R_ARM_ABS32 .text.lcdSetText
aec: 00730008 rsbseq r0, r3, r8
af0: 231c0070 tstcs ip, #112 ; 0x70
af4: 00309f11 eorseq r9, r0, r1, lsl pc
af6: R_ARM_ABS32 .text.lcdSetText
af8: 00340000 eorseq r0, r4, r0
afa: R_ARM_ABS32 .text.lcdSetText
afc: 00080000 andeq r0, r8, r0
b00: 00700073 rsbseq r0, r0, r3, ror r0
b04: 9f10231c svcls 0x0010231c
...
b10: 00000018 andeq r0, r0, r8, lsl r0
b10: R_ARM_ABS32 .text.lcdSetText
b14: 0000001a andeq r0, r0, sl, lsl r0
b14: R_ARM_ABS32 .text.lcdSetText
b18: 1a500001 bne 140000c <usart+0x13fffc4>
b1b: R_ARM_ABS32 .text.lcdSetText
b1c: 1c000000 stcne 0, cr0, [r0], {-0}
b1f: R_ARM_ABS32 .text.lcdSetText
b20: 03000000 movweq r0, #0
b24: 9f107000 svcls 0x00107000
b28: 0000001c andeq r0, r0, ip, lsl r0
b28: R_ARM_ABS32 .text.lcdSetText
b2c: 00000020 andeq r0, r0, r0, lsr #32
b2c: R_ARM_ABS32 .text.lcdSetText
b30: 20500001 subscs r0, r0, r1
b33: R_ARM_ABS32 .text.lcdSetText
b34: 24000000 strcs r0, [r0], #-0
b37: R_ARM_ABS32 .text.lcdSetText
b38: 03000000 movweq r0, #0
b3c: 9f7f7300 svcls 0x007f7300
b40: 00000024 andeq r0, r0, r4, lsr #32
b40: R_ARM_ABS32 .text.lcdSetText
b44: 0000002e andeq r0, r0, lr, lsr #32
b44: R_ARM_ABS32 .text.lcdSetText
b48: 00530001 subseq r0, r3, r1
...
b53: R_ARM_ABS32 .text.lcdClear
b54: 0d000000 stceq 0, cr0, [r0, #-0]
b57: R_ARM_ABS32 .text.lcdClear
b58: 01000000 mrseq r0, (UNDEF: 0)
b5c: 000d5000 andeq r5, sp, r0
b5e: R_ARM_ABS32 .text.lcdClear
b60: 00160000 andseq r0, r6, r0
b62: R_ARM_ABS32 .text.lcdClear
b64: 00010000 andeq r0, r1, r0
b68: 00001655 andeq r1, r0, r5, asr r6
b69: R_ARM_ABS32 .text.lcdClear
b6c: 00001b00 andeq r1, r0, r0, lsl #22
b6d: R_ARM_ABS32 .text.lcdClear
b70: 50000100 andpl r0, r0, r0, lsl #2
b74: 0000001b andeq r0, r0, fp, lsl r0
b74: R_ARM_ABS32 .text.lcdClear
b78: 00000020 andeq r0, r0, r0, lsr #32
b78: R_ARM_ABS32 .text.lcdClear
b7c: 01f30004 mvnseq r0, r4
b80: 00009f50 andeq r9, r0, r0, asr pc
...
b8a: R_ARM_ABS32 .text.lcdPrint
b8c: 00120000 andseq r0, r2, r0
b8e: R_ARM_ABS32 .text.lcdPrint
b90: 00010000 andeq r0, r1, r0
b94: 00001250 andeq r1, r0, r0, asr r2
b95: R_ARM_ABS32 .text.lcdPrint
b98: 00003000 andeq r3, r0, r0
b99: R_ARM_ABS32 .text.lcdPrint
b9c: 55000100 strpl r0, [r0, #-256] ; 0xffffff00
ba0: 00000030 andeq r0, r0, r0, lsr r0
ba0: R_ARM_ABS32 .text.lcdPrint
ba4: 00000034 andeq r0, r0, r4, lsr r0
ba4: R_ARM_ABS32 .text.lcdPrint
ba8: 01f30004 mvnseq r0, r4
bac: 00009f50 andeq r9, r0, r0, asr pc
...
bb6: R_ARM_ABS32 .text.lcdPrint
bb8: 00140000 andseq r0, r4, r0
bba: R_ARM_ABS32 .text.lcdPrint
bbc: 00010000 andeq r0, r1, r0
bc0: 00001451 andeq r1, r0, r1, asr r4
bc1: R_ARM_ABS32 .text.lcdPrint
bc4: 00003400 andeq r3, r0, r0, lsl #8
bc5: R_ARM_ABS32 .text.lcdPrint
bc8: f3000400 vshl.u8 d0, d0, d0
bcc: 009f5101 addseq r5, pc, r1, lsl #2
...
bd7: R_ARM_ABS32 .text.usartBufferCount
bd8: 24000000 strcs r0, [r0], #-0
bdb: R_ARM_ABS32 .text.usartBufferCount
bdc: 01000000 mrseq r0, (UNDEF: 0)
be0: 00245000 eoreq r5, r4, r0
be2: R_ARM_ABS32 .text.usartBufferCount
be4: 00300000 eorseq r0, r0, r0
be6: R_ARM_ABS32 .text.usartBufferCount
be8: 00040000 andeq r0, r4, r0
bec: 9f5001f3 svcls 0x005001f3
...
bf8: 00000018 andeq r0, r0, r8, lsl r0
bf8: R_ARM_ABS32 .text.usartBufferCount
bfc: 0000002a andeq r0, r0, sl, lsr #32
bfc: R_ARM_ABS32 .text.usartBufferCount
c00: 00540001 subseq r0, r4, r1
...
c0b: R_ARM_ABS32 .text.fcount
c0c: 0a000000 beq 8 <.debug_loc+0x8>
c0f: R_ARM_ABS32 .text.fcount
c10: 01000000 mrseq r0, (UNDEF: 0)
c14: 000a5000 andeq r5, sl, r0
c16: R_ARM_ABS32 .text.fcount
c18: 00110000 andseq r0, r1, r0
c1a: R_ARM_ABS32 .text.fcount
c1c: 00030000 andeq r0, r3, r0
c20: 119f0173 orrsne r0, pc, r3, ror r1 ; <UNPREDICTABLE>
c23: R_ARM_ABS32 .text.fcount
c24: 12000000 andne r0, r0, #0
c27: R_ARM_ABS32 .text.fcount
c28: 04000000 streq r0, [r0], #-0
c2c: 5001f300 andpl pc, r1, r0, lsl #6
c30: 0000129f muleq r0, pc, r2 ; <UNPREDICTABLE>
c31: R_ARM_ABS32 .text.fcount
c34: 00001500 andeq r1, r0, r0, lsl #10
c35: R_ARM_ABS32 .text.fcount
c38: 50000100 andpl r0, r0, r0, lsl #2
c3c: 00000015 andeq r0, r0, r5, lsl r0
c3c: R_ARM_ABS32 .text.fcount
c40: 0000001c andeq r0, r0, ip, lsl r0
c40: R_ARM_ABS32 .text.fcount
c44: 01f30004 mvnseq r0, r4
c48: 00009f50 andeq r9, r0, r0, asr pc
c4c: 00000000 andeq r0, r0, r0
c50: 00020000 andeq r0, r2, r0
c52: R_ARM_ABS32 .text.fcount
c54: 00110000 andseq r0, r1, r0
c56: R_ARM_ABS32 .text.fcount
c58: 00010000 andeq r0, r1, r0
c5c: 00001153 andeq r1, r0, r3, asr r1
c5d: R_ARM_ABS32 .text.fcount
c60: 00001200 andeq r1, r0, r0, lsl #4
c61: R_ARM_ABS32 .text.fcount
c64: f3000600 vmax.u8 d0, d0, d0
c68: 1c315001 ldcne 0, cr5, [r1], #-4
c6c: 0000129f muleq r0, pc, r2 ; <UNPREDICTABLE>
c6d: R_ARM_ABS32 .text.fcount
c70: 00001500 andeq r1, r0, r0, lsl #10
c71: R_ARM_ABS32 .text.fcount
c74: 53000100 movwpl r0, #256 ; 0x100
c78: 00000015 andeq r0, r0, r5, lsl r0
c78: R_ARM_ABS32 .text.fcount
c7c: 0000001c andeq r0, r0, ip, lsl r0
c7c: R_ARM_ABS32 .text.fcount
c80: 01f30006 mvnseq r0, r6
c84: 9f1c3150 svcls 0x001c3150
...
c90: R_ARM_ABS32 .text.feof
c94: 0000000f andeq r0, r0, pc
c94: R_ARM_ABS32 .text.feof
c98: 0f500001 svceq 0x00500001
c9b: R_ARM_ABS32 .text.feof
c9c: 10000000 andne r0, r0, r0
c9f: R_ARM_ABS32 .text.feof
ca0: 04000000 streq r0, [r0], #-0
ca4: 5001f300 andpl pc, r1, r0, lsl #6
ca8: 0000109f muleq r0, pc, r0 ; <UNPREDICTABLE>
ca9: R_ARM_ABS32 .text.feof
cac: 00001400 andeq r1, r0, r0, lsl #8
cad: R_ARM_ABS32 .text.feof
cb0: 50000100 andpl r0, r0, r0, lsl #2
cb4: 00000014 andeq r0, r0, r4, lsl r0
cb4: R_ARM_ABS32 .text.feof
cb8: 0000001b andeq r0, r0, fp, lsl r0
cb8: R_ARM_ABS32 .text.feof
cbc: 01730003 cmneq r3, r3
cc0: 00001b9f muleq r0, pc, fp ; <UNPREDICTABLE>
cc1: R_ARM_ABS32 .text.feof
cc4: 00002800 andeq r2, r0, r0, lsl #16
cc5: R_ARM_ABS32 .text.feof
cc8: f3000400 vshl.u8 d0, d0, d0
ccc: 009f5001 addseq r5, pc, r1
cd0: 00000000 andeq r0, r0, r0
cd4: 04000000 streq r0, [r0], #-0
cd7: R_ARM_ABS32 .text.feof
cd8: 0c000000 stceq 0, cr0, [r0], {-0}
cdb: R_ARM_ABS32 .text.feof
cdc: 01000000 mrseq r0, (UNDEF: 0)
ce0: 000c5300 andeq r5, ip, r0, lsl #6
ce2: R_ARM_ABS32 .text.feof
ce4: 000f0000 andeq r0, pc, r0
ce6: R_ARM_ABS32 .text.feof
ce8: 00030000 andeq r0, r3, r0
cec: 0f9f7f70 svceq 0x009f7f70
cef: R_ARM_ABS32 .text.feof
cf0: 10000000 andne r0, r0, r0
cf3: R_ARM_ABS32 .text.feof
cf4: 06000000 streq r0, [r0], -r0
cf8: 5001f300 andpl pc, r1, r0, lsl #6
cfc: 109f1c31 addsne r1, pc, r1, lsr ip ; <UNPREDICTABLE>
cff: R_ARM_ABS32 .text.feof
d00: 1b000000 blne 8 <.debug_loc+0x8>
d03: R_ARM_ABS32 .text.feof
d04: 01000000 mrseq r0, (UNDEF: 0)
d08: 001b5300 andseq r5, fp, r0, lsl #6
d0a: R_ARM_ABS32 .text.feof
d0c: 00280000 eoreq r0, r8, r0
d0e: R_ARM_ABS32 .text.feof
d10: 00060000 andeq r0, r6, r0
d14: 315001f3 ldrshcc r0, [r0, #-19] ; 0xffffffed
d18: 00009f1c andeq r9, r0, ip, lsl pc
...
d22: R_ARM_ABS32 .text.fgets
d24: 00060000 andeq r0, r6, r0
d26: R_ARM_ABS32 .text.fgets
d28: 00010000 andeq r0, r1, r0
d2c: 00000650 andeq r0, r0, r0, asr r6
d2d: R_ARM_ABS32 .text.fgets
d30: 00003a00 andeq r3, r0, r0, lsl #20
d31: R_ARM_ABS32 .text.fgets
d34: 54000100 strpl r0, [r0], #-256 ; 0xffffff00
...
d40: R_ARM_ABS32 .text.fgets
d44: 0000000d andeq r0, r0, sp
d44: R_ARM_ABS32 .text.fgets
d48: 0d510001 ldcleq 0, cr0, [r1, #-4]
d4b: R_ARM_ABS32 .text.fgets
d4c: 12000000 andne r0, r0, #0
d4f: R_ARM_ABS32 .text.fgets
d50: 01000000 mrseq r0, (UNDEF: 0)
d54: 00125700 andseq r5, r2, r0, lsl #14
d56: R_ARM_ABS32 .text.fgets
d58: 00280000 eoreq r0, r8, r0
d5a: R_ARM_ABS32 .text.fgets
d5c: 00090000 andeq r0, r9, r0
d60: 00750074 rsbseq r0, r5, r4, ror r0
d64: 2200771c andcs r7, r0, #28, 14 ; 0x700000
d68: 0000289f muleq r0, pc, r8 ; <UNPREDICTABLE>
d69: R_ARM_ABS32 .text.fgets
d6c: 00002e00 andeq r2, r0, r0, lsl #28
d6d: R_ARM_ABS32 .text.fgets
d70: 74000b00 strvc r0, [r0], #-2816 ; 0xfffff500
d74: 1c007500 cfstr32ne mvfx7, [r0], {-0}
d78: 23220077 ; <UNDEFINED> instruction: 0x23220077
d7c: 00369f01 eorseq r9, r6, r1, lsl #30
d7e: R_ARM_ABS32 .text.fgets
d80: 003a0000 eorseq r0, sl, r0
d82: R_ARM_ABS32 .text.fgets
d84: 00010000 andeq r0, r1, r0
d88: 00000057 andeq r0, r0, r7, asr r0
...
d91: R_ARM_ABS32 .text.fgets
d94: 00000d00 andeq r0, r0, r0, lsl #26
d95: R_ARM_ABS32 .text.fgets
d98: 52000100 andpl r0, r0, #0, 2
d9c: 0000000d andeq r0, r0, sp
d9c: R_ARM_ABS32 .text.fgets
da0: 0000003a andeq r0, r0, sl, lsr r0
da0: R_ARM_ABS32 .text.fgets
da4: 00560001 subseq r0, r6, r1
da8: 00000000 andeq r0, r0, r0
dac: 04000000 streq r0, [r0], #-0
daf: R_ARM_ABS32 .text.fgets
db0: 06000000 streq r0, [r0], -r0
db3: R_ARM_ABS32 .text.fgets
db4: 01000000 mrseq r0, (UNDEF: 0)
db8: 00065000 andeq r5, r6, r0
dba: R_ARM_ABS32 .text.fgets
dbc: 00120000 andseq r0, r2, r0
dbe: R_ARM_ABS32 .text.fgets
dc0: 00010000 andeq r0, r1, r0
dc4: 00001254 andeq r1, r0, r4, asr r2
dc5: R_ARM_ABS32 .text.fgets
dc8: 00002800 andeq r2, r0, r0, lsl #16
dc9: R_ARM_ABS32 .text.fgets
dcc: 55000100 strpl r0, [r0, #-256] ; 0xffffff00
dd0: 00000028 andeq r0, r0, r8, lsr #32
dd0: R_ARM_ABS32 .text.fgets
dd4: 0000002e andeq r0, r0, lr, lsr #32
dd4: R_ARM_ABS32 .text.fgets
dd8: 7f750003 svcvc 0x00750003
ddc: 00002e9f muleq r0, pc, lr ; <UNPREDICTABLE>
ddd: R_ARM_ABS32 .text.fgets
de0: 00003600 andeq r3, r0, r0, lsl #12
de1: R_ARM_ABS32 .text.fgets
de4: 55000100 strpl r0, [r0, #-256] ; 0xffffff00
de8: 00000036 andeq r0, r0, r6, lsr r0
de8: R_ARM_ABS32 .text.fgets
dec: 0000003a andeq r0, r0, sl, lsr r0
dec: R_ARM_ABS32 .text.fgets
df0: 00540001 subseq r0, r4, r1
df4: 00000000 andeq r0, r0, r0
df8: 20000000 andcs r0, r0, r0
dfb: R_ARM_ABS32 .text.fgets
dfc: 2a000000 bcs 8 <.debug_loc+0x8>
dff: R_ARM_ABS32 .text.fgets
e00: 01000000 mrseq r0, (UNDEF: 0)
e04: 002a5000 eoreq r5, sl, r0
e06: R_ARM_ABS32 .text.fgets
e08: 002e0000 eoreq r0, lr, r0
e0a: R_ARM_ABS32 .text.fgets
e0c: 00030000 andeq r0, r3, r0
e10: 009f7f73 addseq r7, pc, r3, ror pc ; <UNPREDICTABLE>
...
e1b: R_ARM_ABS32 .text.usartInit
e1c: 1a000000 bne 8 <.debug_loc+0x8>
e1f: R_ARM_ABS32 .text.usartInit
e20: 01000000 mrseq r0, (UNDEF: 0)
e24: 001a5000 andseq r5, sl, r0
e26: R_ARM_ABS32 .text.usartInit
e28: 00b40000 adcseq r0, r4, r0
e2a: R_ARM_ABS32 .text.usartInit
e2c: 00040000 andeq r0, r4, r0
e30: 9f5001f3 svcls 0x005001f3
...
e3c: R_ARM_ABS32 .text.usartInit
e40: 00000076 andeq r0, r0, r6, ror r0
e40: R_ARM_ABS32 .text.usartInit
e44: 76510001 ldrbvc r0, [r1], -r1
e47: R_ARM_ABS32 .text.usartInit
e48: b4000000 strlt r0, [r0], #-0
e4b: R_ARM_ABS32 .text.usartInit
e4c: 04000000 streq r0, [r0], #-0
e50: 5101f300 mrspl pc, SP_irq ; <UNPREDICTABLE>
e54: 0000009f muleq r0, pc, r0 ; <UNPREDICTABLE>
...
e5d: R_ARM_ABS32 .text.usartInit
e60: 00004a00 andeq r4, r0, r0, lsl #20
e61: R_ARM_ABS32 .text.usartInit
e64: 52000100 andpl r0, r0, #0, 2
e68: 0000004a andeq r0, r0, sl, asr #32
e68: R_ARM_ABS32 .text.usartInit
e6c: 000000b4 strheq r0, [r0], -r4
e6c: R_ARM_ABS32 .text.usartInit
e70: 01f30004 mvnseq r0, r4
e74: 00009f52 andeq r9, r0, r2, asr pc
e78: 00000000 andeq r0, r0, r0
e7c: 00100000 andseq r0, r0, r0
e7e: R_ARM_ABS32 .text.usartInit
e80: 009e0000 addseq r0, lr, r0
e82: R_ARM_ABS32 .text.usartInit
e84: 00010000 andeq r0, r1, r0
e88: 00000054 andeq r0, r0, r4, asr r0
e8c: 00000000 andeq r0, r0, r0
e90: 00007600 andeq r7, r0, r0, lsl #12
e91: R_ARM_ABS32 .text.usartInit
e94: 00008000 andeq r8, r0, r0
e95: R_ARM_ABS32 .text.usartInit
e98: 51000100 mrspl r0, (UNDEF: 16)
e9c: 00000080 andeq r0, r0, r0, lsl #1
e9c: R_ARM_ABS32 .text.usartInit
ea0: 0000009e muleq r0, lr, r0
ea0: R_ARM_ABS32 .text.usartInit
ea4: 400c0010 andmi r0, ip, r0, lsl r0
ea8: f70d693a ; <UNDEFINED> instruction: 0xf70d693a
eac: 5101f325 tstpl r1, r5, lsr #6 ; <UNPREDICTABLE>
eb0: f71b25f7 ; <UNDEFINED> instruction: 0xf71b25f7
eb4: 00009f00 andeq r9, r0, r0, lsl #30
eb8: 00000000 andeq r0, r0, r0
ebc: 007c0000 rsbseq r0, ip, r0
ebe: R_ARM_ABS32 .text.usartInit
ec0: 009e0000 addseq r0, lr, r0
ec2: R_ARM_ABS32 .text.usartInit
ec4: 00010000 andeq r0, r1, r0
ec8: 00000052 andeq r0, r0, r2, asr r0
ecc: 00000000 andeq r0, r0, r0
ed0: 00007c00 andeq r7, r0, r0, lsl #24
ed1: R_ARM_ABS32 .text.usartInit
ed4: 00008000 andeq r8, r0, r0
ed5: R_ARM_ABS32 .text.usartInit
ed8: 71000900 tstvc r0, r0, lsl #18
edc: 08007200 stmdaeq r0, {r9, ip, sp, lr}
ee0: 9f1c1e64 svcls 0x001c1e64
ee4: 00000080 andeq r0, r0, r0, lsl #1
ee4: R_ARM_ABS32 .text.usartInit
ee8: 00000082 andeq r0, r0, r2, lsl #1
ee8: R_ARM_ABS32 .text.usartInit
eec: 82510001 subshi r0, r1, #1
eef: R_ARM_ABS32 .text.usartInit
ef0: 9e000000 cdpls 0, 0, cr0, cr0, cr0, {0}
ef3: R_ARM_ABS32 .text.usartInit
ef4: 16000000 strne r0, [r0], -r0
ef8: 3a400c00 bcc 1003f00 <usart+0x1003eb8>
efc: 25f70d69 ldrbcs r0, [r7, #3433]! ; 0xd69
f00: f75101f3 ; <UNDEFINED> instruction: 0xf75101f3
f04: 00f71b25 rscseq r1, r7, r5, lsr #22
f08: 64080072 strvs r0, [r8], #-114 ; 0xffffff8e
f0c: 009f1c1e addseq r1, pc, lr, lsl ip ; <UNPREDICTABLE>
f10: 00000000 andeq r0, r0, r0
f14: 98000000 stmdals r0, {} ; <UNPREDICTABLE>
f17: R_ARM_ABS32 .text.usartInit
f18: 9e000000 cdpls 0, 0, cr0, cr0, cr0, {0}
f1b: R_ARM_ABS32 .text.usartInit
f1c: 01000000 mrseq r0, (UNDEF: 0)
f20: 00005300 andeq r5, r0, r0, lsl #6
...
f2a: R_ARM_ABS32 .text.lcdInit
f2c: 00110000 andseq r0, r1, r0
f2e: R_ARM_ABS32 .text.lcdInit
f30: 00010000 andeq r0, r1, r0
f34: 00001150 andeq r1, r0, r0, asr r1
f35: R_ARM_ABS32 .text.lcdInit
f38: 00002c00 andeq r2, r0, r0, lsl #24
f39: R_ARM_ABS32 .text.lcdInit
f3c: 74000300 strvc r0, [r0], #-768 ; 0xfffffd00
f40: 002c9f01 eoreq r9, ip, r1, lsl #30
f42: R_ARM_ABS32 .text.lcdInit
f44: 00300000 eorseq r0, r0, r0
f46: R_ARM_ABS32 .text.lcdInit
f48: 00040000 andeq r0, r4, r0
f4c: 9f5001f3 svcls 0x005001f3
...
f58: 00000008 andeq r0, r0, r8
f58: R_ARM_ABS32 .text.lcdInit
f5c: 0000002a andeq r0, r0, sl, lsr #32
f5c: R_ARM_ABS32 .text.lcdInit
f60: 00540001 subseq r0, r4, r1
...
f6b: R_ARM_ABS32 .text.lcdShutdown
f6c: 0b000000 bleq 8 <.debug_loc+0x8>
f6f: R_ARM_ABS32 .text.lcdShutdown
f70: 01000000 mrseq r0, (UNDEF: 0)
f74: 000b5000 andeq r5, fp, r0
f76: R_ARM_ABS32 .text.lcdShutdown
f78: 001c0000 andseq r0, ip, r0
f7a: R_ARM_ABS32 .text.lcdShutdown
f7c: 00030000 andeq r0, r3, r0
f80: 1c9f0174 ldfnes f0, [pc], {116} ; 0x74
f83: R_ARM_ABS32 .text.lcdShutdown
f84: 20000000 andcs r0, r0, r0
f87: R_ARM_ABS32 .text.lcdShutdown
f88: 04000000 streq r0, [r0], #-0
f8c: 5001f300 andpl pc, r1, r0, lsl #6
f90: 0000009f muleq r0, pc, r0 ; <UNPREDICTABLE>
f94: 00000000 andeq r0, r0, r0
...
Disassembly of section .debug_aranges:
00000000 <.debug_aranges>:
0: 000000e4 andeq r0, r0, r4, ror #1
4: 00000002 andeq r0, r0, r2
6: R_ARM_ABS32 .debug_info
8: 00040000 andeq r0, r4, r0
...
10: R_ARM_ABS32 .text.lcdButtonProcess
14: 0000005c andeq r0, r0, ip, asr r0
18: 00000000 andeq r0, r0, r0
18: R_ARM_ABS32 .text.fgetc
1c: 00000064 andeq r0, r0, r4, rrx
20: 00000000 andeq r0, r0, r0
20: R_ARM_ABS32 .text.fputc
24: 00000084 andeq r0, r0, r4, lsl #1
28: 00000000 andeq r0, r0, r0
28: R_ARM_ABS32 .text.fread
2c: 00000028 andeq r0, r0, r8, lsr #32
30: 00000000 andeq r0, r0, r0
30: R_ARM_ABS32 .text.fwrite
34: 00000028 andeq r0, r0, r8, lsr #32
38: 00000000 andeq r0, r0, r0
38: R_ARM_ABS32 .text.getchar
3c: 00000006 andeq r0, r0, r6
40: 00000000 andeq r0, r0, r0
40: R_ARM_ABS32 .text.putchar
44: 00000006 andeq r0, r0, r6
48: 00000000 andeq r0, r0, r0
48: R_ARM_ABS32 .text.ISR_USART1
4c: 000000bc strheq r0, [r0], -ip
50: 00000000 andeq r0, r0, r0
50: R_ARM_ABS32 .text.ISR_USART2
54: 000000cc andeq r0, r0, ip, asr #1
58: 00000000 andeq r0, r0, r0
58: R_ARM_ABS32 .text.ISR_USART3
5c: 000000cc andeq r0, r0, ip, asr #1
60: 00000000 andeq r0, r0, r0
60: R_ARM_ABS32 .text.lcdReadButtons
64: 0000002c andeq r0, r0, ip, lsr #32
68: 00000000 andeq r0, r0, r0
68: R_ARM_ABS32 .text.lcdSetBacklight
6c: 00000028 andeq r0, r0, r8, lsr #32
70: 00000000 andeq r0, r0, r0
70: R_ARM_ABS32 .text._lcdDump
74: 000000a8 andeq r0, r0, r8, lsr #1
78: 00000000 andeq r0, r0, r0
78: R_ARM_ABS32 .text.lcdSetText
7c: 0000003c andeq r0, r0, ip, lsr r0
80: 00000000 andeq r0, r0, r0
80: R_ARM_ABS32 .text.lcdClear
84: 00000020 andeq r0, r0, r0, lsr #32
88: 00000000 andeq r0, r0, r0
88: R_ARM_ABS32 .text.lcdPrint
8c: 00000034 andeq r0, r0, r4, lsr r0
90: 00000000 andeq r0, r0, r0
90: R_ARM_ABS32 .text.usartBufferCount
94: 00000030 andeq r0, r0, r0, lsr r0
98: 00000000 andeq r0, r0, r0
98: R_ARM_ABS32 .text.fcount
9c: 0000001c andeq r0, r0, ip, lsl r0
a0: 00000000 andeq r0, r0, r0
a0: R_ARM_ABS32 .text.feof
a4: 00000028 andeq r0, r0, r8, lsr #32
a8: 00000000 andeq r0, r0, r0
a8: R_ARM_ABS32 .text.fgets
ac: 0000003a andeq r0, r0, sl, lsr r0
b0: 00000000 andeq r0, r0, r0
b0: R_ARM_ABS32 .text.usartBufferInit
b4: 00000054 andeq r0, r0, r4, asr r0
b8: 00000000 andeq r0, r0, r0
b8: R_ARM_ABS32 .text.usartFlushBuffers
bc: 0000002c andeq r0, r0, ip, lsr #32
c0: 00000000 andeq r0, r0, r0
c0: R_ARM_ABS32 .text.usartInit
c4: 000000b4 strheq r0, [r0], -r4
c8: 00000000 andeq r0, r0, r0
c8: R_ARM_ABS32 .text.lcdInit
cc: 00000030 andeq r0, r0, r0, lsr r0
d0: 00000000 andeq r0, r0, r0
d0: R_ARM_ABS32 .text.usartShutdown
d4: 00000020 andeq r0, r0, r0, lsr #32
d8: 00000000 andeq r0, r0, r0
d8: R_ARM_ABS32 .text.lcdShutdown
dc: 00000020 andeq r0, r0, r0, lsr #32
...
Disassembly of section .debug_ranges:
00000000 <.debug_ranges>:
0: 00000008 andeq r0, r0, r8
0: R_ARM_ABS32 .text.fgetc
4: 00000034 andeq r0, r0, r4, lsr r0
4: R_ARM_ABS32 .text.fgetc
8: 0000003c andeq r0, r0, ip, lsr r0
8: R_ARM_ABS32 .text.fgetc
c: 00000058 andeq r0, r0, r8, asr r0
c: R_ARM_ABS32 .text.fgetc
...
18: 0000000a andeq r0, r0, sl
18: R_ARM_ABS32 .text.fputc
1c: 00000058 andeq r0, r0, r8, asr r0
1c: R_ARM_ABS32 .text.fputc
20: 0000005a andeq r0, r0, sl, asr r0
20: R_ARM_ABS32 .text.fputc
24: 00000062 andeq r0, r0, r2, rrx
24: R_ARM_ABS32 .text.fputc
...
30: 00000026 andeq r0, r0, r6, lsr #32
30: R_ARM_ABS32 .text.fputc
34: 0000003c andeq r0, r0, ip, lsr r0
34: R_ARM_ABS32 .text.fputc
38: 0000003e andeq r0, r0, lr, lsr r0
38: R_ARM_ABS32 .text.fputc
3c: 00000048 andeq r0, r0, r8, asr #32
3c: R_ARM_ABS32 .text.fputc
...
48: 00000006 andeq r0, r0, r6
48: R_ARM_ABS32 .text.fread
4c: 0000000a andeq r0, r0, sl
4c: R_ARM_ABS32 .text.fread
50: 0000000c andeq r0, r0, ip
50: R_ARM_ABS32 .text.fread
54: 00000024 andeq r0, r0, r4, lsr #32
54: R_ARM_ABS32 .text.fread
...
60: 00000006 andeq r0, r0, r6
60: R_ARM_ABS32 .text.fwrite
64: 0000000a andeq r0, r0, sl
64: R_ARM_ABS32 .text.fwrite
68: 0000000c andeq r0, r0, ip
68: R_ARM_ABS32 .text.fwrite
6c: 00000024 andeq r0, r0, r4, lsr #32
6c: R_ARM_ABS32 .text.fwrite
...
78: 0000001c andeq r0, r0, ip, lsl r0
78: R_ARM_ABS32 .text.ISR_USART1
7c: 0000001e andeq r0, r0, lr, lsl r0
7c: R_ARM_ABS32 .text.ISR_USART1
80: 00000020 andeq r0, r0, r0, lsr #32
80: R_ARM_ABS32 .text.ISR_USART1
84: 0000002e andeq r0, r0, lr, lsr #32
84: R_ARM_ABS32 .text.ISR_USART1
...
90: 00000032 andeq r0, r0, r2, lsr r0
90: R_ARM_ABS32 .text.ISR_USART1
94: 00000036 andeq r0, r0, r6, lsr r0
94: R_ARM_ABS32 .text.ISR_USART1
98: 00000038 andeq r0, r0, r8, lsr r0
98: R_ARM_ABS32 .text.ISR_USART1
9c: 0000004a andeq r0, r0, sl, asr #32
9c: R_ARM_ABS32 .text.ISR_USART1
...
a8: 00000014 andeq r0, r0, r4, lsl r0
a8: R_ARM_ABS32 .text._lcdDump
ac: 00000094 muleq r0, r4, r0
ac: R_ARM_ABS32 .text._lcdDump
b0: 00000098 muleq r0, r8, r0
b0: R_ARM_ABS32 .text._lcdDump
b4: 000000a8 andeq r0, r0, r8, lsr #1
b4: R_ARM_ABS32 .text._lcdDump
...
c0: 00000014 andeq r0, r0, r4, lsl r0
c0: R_ARM_ABS32 .text.usartBufferCount
c4: 00000016 andeq r0, r0, r6, lsl r0
c4: R_ARM_ABS32 .text.usartBufferCount
c8: 00000018 andeq r0, r0, r8, lsl r0
c8: R_ARM_ABS32 .text.usartBufferCount
cc: 0000001a andeq r0, r0, sl, lsl r0
cc: R_ARM_ABS32 .text.usartBufferCount
d0: 0000001c andeq r0, r0, ip, lsl r0
d0: R_ARM_ABS32 .text.usartBufferCount
d4: 00000022 andeq r0, r0, r2, lsr #32
d4: R_ARM_ABS32 .text.usartBufferCount
...
e0: 00000002 andeq r0, r0, r2
e0: R_ARM_ABS32 .text.usartBufferInit
e4: 0000001a andeq r0, r0, sl, lsl r0
e4: R_ARM_ABS32 .text.usartBufferInit
e8: 0000001e andeq r0, r0, lr, lsl r0
e8: R_ARM_ABS32 .text.usartBufferInit
ec: 00000022 andeq r0, r0, r2, lsr #32
ec: R_ARM_ABS32 .text.usartBufferInit
...
f8: 0000001a andeq r0, r0, sl, lsl r0
f8: R_ARM_ABS32 .text.usartBufferInit
fc: 0000001e andeq r0, r0, lr, lsl r0
fc: R_ARM_ABS32 .text.usartBufferInit
100: 00000022 andeq r0, r0, r2, lsr #32
100: R_ARM_ABS32 .text.usartBufferInit
104: 00000032 andeq r0, r0, r2, lsr r0
104: R_ARM_ABS32 .text.usartBufferInit
108: 00000036 andeq r0, r0, r6, lsr r0
108: R_ARM_ABS32 .text.usartBufferInit
10c: 0000003a andeq r0, r0, sl, lsr r0
10c: R_ARM_ABS32 .text.usartBufferInit
...
118: 00000032 andeq r0, r0, r2, lsr r0
118: R_ARM_ABS32 .text.usartBufferInit
11c: 00000036 andeq r0, r0, r6, lsr r0
11c: R_ARM_ABS32 .text.usartBufferInit
120: 0000003a andeq r0, r0, sl, lsr r0
120: R_ARM_ABS32 .text.usartBufferInit
124: 00000054 andeq r0, r0, r4, asr r0
124: R_ARM_ABS32 .text.usartBufferInit
...
130: 00000010 andeq r0, r0, r0, lsl r0
130: R_ARM_ABS32 .text.usartInit
134: 00000014 andeq r0, r0, r4, lsl r0
134: R_ARM_ABS32 .text.usartInit
138: 00000016 andeq r0, r0, r6, lsl r0
138: R_ARM_ABS32 .text.usartInit
13c: 00000020 andeq r0, r0, r0, lsr #32
13c: R_ARM_ABS32 .text.usartInit
...
148: 00000014 andeq r0, r0, r4, lsl r0
148: R_ARM_ABS32 .text.usartInit
14c: 00000016 andeq r0, r0, r6, lsl r0
14c: R_ARM_ABS32 .text.usartInit
150: 00000020 andeq r0, r0, r0, lsr #32
150: R_ARM_ABS32 .text.usartInit
154: 00000094 muleq r0, r4, r0
154: R_ARM_ABS32 .text.usartInit
...
160: R_ARM_ABS32 .text.lcdButtonProcess
164: 0000005c andeq r0, r0, ip, asr r0
164: R_ARM_ABS32 .text.lcdButtonProcess
168: 00000000 andeq r0, r0, r0
168: R_ARM_ABS32 .text.fgetc
16c: 00000064 andeq r0, r0, r4, rrx
16c: R_ARM_ABS32 .text.fgetc
170: 00000000 andeq r0, r0, r0
170: R_ARM_ABS32 .text.fputc
174: 00000084 andeq r0, r0, r4, lsl #1
174: R_ARM_ABS32 .text.fputc
178: 00000000 andeq r0, r0, r0
178: R_ARM_ABS32 .text.fread
17c: 00000028 andeq r0, r0, r8, lsr #32
17c: R_ARM_ABS32 .text.fread
180: 00000000 andeq r0, r0, r0
180: R_ARM_ABS32 .text.fwrite
184: 00000028 andeq r0, r0, r8, lsr #32
184: R_ARM_ABS32 .text.fwrite
188: 00000000 andeq r0, r0, r0
188: R_ARM_ABS32 .text.getchar
18c: 00000006 andeq r0, r0, r6
18c: R_ARM_ABS32 .text.getchar
190: 00000000 andeq r0, r0, r0
190: R_ARM_ABS32 .text.putchar
194: 00000006 andeq r0, r0, r6
194: R_ARM_ABS32 .text.putchar
198: 00000000 andeq r0, r0, r0
198: R_ARM_ABS32 .text.ISR_USART1
19c: 000000bc strheq r0, [r0], -ip
19c: R_ARM_ABS32 .text.ISR_USART1
1a0: 00000000 andeq r0, r0, r0
1a0: R_ARM_ABS32 .text.ISR_USART2
1a4: 000000cc andeq r0, r0, ip, asr #1
1a4: R_ARM_ABS32 .text.ISR_USART2
1a8: 00000000 andeq r0, r0, r0
1a8: R_ARM_ABS32 .text.ISR_USART3
1ac: 000000cc andeq r0, r0, ip, asr #1
1ac: R_ARM_ABS32 .text.ISR_USART3
1b0: 00000000 andeq r0, r0, r0
1b0: R_ARM_ABS32 .text.lcdReadButtons
1b4: 0000002c andeq r0, r0, ip, lsr #32
1b4: R_ARM_ABS32 .text.lcdReadButtons
1b8: 00000000 andeq r0, r0, r0
1b8: R_ARM_ABS32 .text.lcdSetBacklight
1bc: 00000028 andeq r0, r0, r8, lsr #32
1bc: R_ARM_ABS32 .text.lcdSetBacklight
1c0: 00000000 andeq r0, r0, r0
1c0: R_ARM_ABS32 .text._lcdDump
1c4: 000000a8 andeq r0, r0, r8, lsr #1
1c4: R_ARM_ABS32 .text._lcdDump
1c8: 00000000 andeq r0, r0, r0
1c8: R_ARM_ABS32 .text.lcdSetText
1cc: 0000003c andeq r0, r0, ip, lsr r0
1cc: R_ARM_ABS32 .text.lcdSetText
1d0: 00000000 andeq r0, r0, r0
1d0: R_ARM_ABS32 .text.lcdClear
1d4: 00000020 andeq r0, r0, r0, lsr #32
1d4: R_ARM_ABS32 .text.lcdClear
1d8: 00000000 andeq r0, r0, r0
1d8: R_ARM_ABS32 .text.lcdPrint
1dc: 00000034 andeq r0, r0, r4, lsr r0
1dc: R_ARM_ABS32 .text.lcdPrint
_taskYield();
}
// lcdButtonProcess - Processes the VEX LCD buttons
static void lcdButtonProcess(char value, uint32_t index) {
uint16_t count = lcd[index].state;
1e0: 00000000 andeq r0, r0, r0
1e0: R_ARM_ABS32 .text.usartBufferCount
1e4: 00000030 andeq r0, r0, r0, lsr r0
1e4: R_ARM_ABS32 .text.usartBufferCount
// If 0xAA, set count to 1
// If 0x55, set count to 2 if count == 1
// If 0x16, set count to 3 if count == 2
if (value == (char)0xAA)
1e8: 00000000 andeq r0, r0, r0
1e8: R_ARM_ABS32 .text.fcount
_taskYield();
}
// lcdButtonProcess - Processes the VEX LCD buttons
static void lcdButtonProcess(char value, uint32_t index) {
uint16_t count = lcd[index].state;
1ec: 0000001c andeq r0, r0, ip, lsl r0
1ec: R_ARM_ABS32 .text.fcount
// If 0xAA, set count to 1
// If 0x55, set count to 2 if count == 1
// If 0x16, set count to 3 if count == 2
if (value == (char)0xAA)
count = 1;
else if (value == (char)0x55 && count == 1)
1f0: 00000000 andeq r0, r0, r0
1f0: R_ARM_ABS32 .text.feof
1f4: 00000028 andeq r0, r0, r8, lsr #32
1f4: R_ARM_ABS32 .text.feof
1f8: 00000000 andeq r0, r0, r0
1f8: R_ARM_ABS32 .text.fgets
count = 2;
else if (value == (char)0x16 && count == 2)
1fc: 0000003a andeq r0, r0, sl, lsr r0
1fc: R_ARM_ABS32 .text.fgets
200: 00000000 andeq r0, r0, r0
200: R_ARM_ABS32 .text.usartBufferInit
count = 3;
else if (value == (char)0x02 && count == 3)
204: 00000054 andeq r0, r0, r4, asr r0
204: R_ARM_ABS32 .text.usartBufferInit
208: 00000000 andeq r0, r0, r0
208: R_ARM_ABS32 .text.usartFlushBuffers
// Size must be 2
count = 4;
else if (count == 4) {
20c: 0000002c andeq r0, r0, ip, lsr #32
20c: R_ARM_ABS32 .text.usartFlushBuffers
lcd[index].buttons = (uint8_t)value;
210: 00000000 andeq r0, r0, r0
210: R_ARM_ABS32 .text.usartInit
214: 000000b4 strheq r0, [r0], -r4
214: R_ARM_ABS32 .text.usartInit
218: 00000000 andeq r0, r0, r0
218: R_ARM_ABS32 .text.lcdInit
uint16_t count = lcd[index].state;
// If 0xAA, set count to 1
// If 0x55, set count to 2 if count == 1
// If 0x16, set count to 3 if count == 2
if (value == (char)0xAA)
count = 1;
21c: 00000030 andeq r0, r0, r0, lsr r0
21c: R_ARM_ABS32 .text.lcdInit
else if (value == (char)0x55 && count == 1)
count = 2;
220: 00000000 andeq r0, r0, r0
220: R_ARM_ABS32 .text.usartShutdown
else if (value == (char)0x16 && count == 2)
count = 3;
224: 00000020 andeq r0, r0, r0, lsr #32
224: R_ARM_ABS32 .text.usartShutdown
else if (value == (char)0x02 && count == 3)
// Size must be 2
count = 4;
228: 00000000 andeq r0, r0, r0
228: R_ARM_ABS32 .text.lcdShutdown
else if (count == 4) {
lcd[index].buttons = (uint8_t)value;
count = 0;
} else
// Ignore the checksum and any noise we pick up
count = 0;
22c: 00000020 andeq r0, r0, r0, lsr #32
22c: R_ARM_ABS32 .text.lcdShutdown
...
Disassembly of section .debug_line:
00000000 <.debug_line>:
0: 0000055b andeq r0, r0, fp, asr r5
4: 011a0002 tsteq sl, r2
8: 01020000 mrseq r0, (UNDEF: 2)
c: 000d0efb strdeq r0, [sp], -fp
10: 01010101 tsteq r1, r1, lsl #2
14: 01000000 mrseq r0, (UNDEF: 0)
18: 2e010000 cdpcs 0, 0, cr0, cr1, cr0, {0}
1c: 6e692f2e cdpvs 15, 6, cr2, cr9, cr14, {1}
20: 64756c63 ldrbtvs r6, [r5], #-3171 ; 0xfffff39d
24: 752f0065 strvc r0, [pc, #-101]! ; ffffffc7 <usart+0xffffff7f>
28: 6c2f7273 sfmvs f7, 4, [pc], #-460 ; fffffe64 <usart+0xfffffe1c>
2c: 672f6269 strvs r6, [pc, -r9, ror #4]!
30: 612f6363 ; <UNDEFINED> instruction: 0x612f6363
34: 6e2d6d72 mcrvs 13, 1, r6, cr13, cr2, {3}
38: 2d656e6f stclcs 14, cr6, [r5, #-444]! ; 0xfffffe44
3c: 69626165 stmdbvs r2!, {r0, r2, r5, r6, r8, sp, lr}^
40: 392e342f stmdbcc lr!, {r0, r1, r2, r3, r5, sl, ip, sp}
44: 692f332e stmdbvs pc!, {r1, r2, r3, r5, r8, r9, ip, sp} ; <UNPREDICTABLE>
48: 756c636e strbvc r6, [ip, #-878]! ; 0xfffffc92
4c: 2f006564 svccs 0x00006564
50: 2f727375 svccs 0x00727375
54: 6c636e69 stclvs 14, cr6, [r3], #-420 ; 0xfffffe5c
58: 2f656475 svccs 0x00656475
5c: 6c77656e cfldr64vs mvdx6, [r7], #-440 ; 0xfffffe48
60: 6d2f6269 sfmvs f6, 4, [pc, #-420]! ; fffffec4 <usart+0xfffffe7c>
64: 69686361 stmdbvs r8!, {r0, r5, r6, r8, r9, sp, lr}^
68: 2f00656e svccs 0x0000656e
6c: 2f727375 svccs 0x00727375
70: 6c636e69 stclvs 14, cr6, [r3], #-420 ; 0xfffffe5c
74: 2f656475 svccs 0x00656475
78: 6c77656e cfldr64vs mvdx6, [r7], #-440 ; 0xfffffe48
7c: 732f6269 ; <UNDEFINED> instruction: 0x732f6269
80: 00007379 andeq r7, r0, r9, ror r3
84: 6d6d6f63 stclvs 15, cr6, [sp, #-396]! ; 0xfffffe74
88: 0000632e andeq r6, r0, lr, lsr #6
8c: 72460000 subvc r0, r6, #0
90: 54526565 ldrbpl r6, [r2], #-1381 ; 0xfffffa9b
94: 682e534f stmdavs lr!, {r0, r1, r2, r3, r6, r8, r9, ip, lr}
98: 00000100 andeq r0, r0, r0, lsl #2
9c: 74726f63 ldrbtvc r6, [r2], #-3939 ; 0xfffff09d
a0: 682e7865 stmdavs lr!, {r0, r2, r5, r6, fp, ip, sp, lr}
a4: 00000100 andeq r0, r0, r0, lsl #2
a8: 64647473 strbtvs r7, [r4], #-1139 ; 0xfffffb8d
ac: 682e6665 stmdavs lr!, {r0, r2, r5, r6, r9, sl, sp, lr}
b0: 00000200 andeq r0, r0, r0, lsl #4
b4: 6665645f ; <UNDEFINED> instruction: 0x6665645f
b8: 746c7561 strbtvc r7, [ip], #-1377 ; 0xfffffa9f
bc: 7079745f rsbsvc r7, r9, pc, asr r4
c0: 682e7365 stmdavs lr!, {r0, r2, r5, r6, r8, r9, ip, sp, lr}
c4: 00000300 andeq r0, r0, r0, lsl #6
c8: 6474735f ldrbtvs r7, [r4], #-863 ; 0xfffffca1
cc: 2e746e69 cdpcs 14, 7, cr6, cr4, cr9, {3}
d0: 00040068 andeq r0, r4, r8, rrx
d4: 64747300 ldrbtvs r7, [r4], #-768 ; 0xfffffd00
d8: 2e677261 cdpcs 2, 6, cr7, cr7, cr1, {3}
dc: 00020068 andeq r0, r2, r8, rrx
e0: 6d6f6300 stclvs 3, cr6, [pc, #-0] ; e8 <.debug_line+0xe8>
e4: 00682e6d rsbeq r2, r8, sp, ror #28
e8: 74000001 strvc r0, [r0], #-1
ec: 73657079 cmnvc r5, #121 ; 0x79
f0: 0400682e streq r6, [r0], #-2094 ; 0xfffff7d2
f4: 75710000 ldrbvc r0, [r1, #-0]!
f8: 2e657565 cdpcs 5, 6, cr7, cr5, cr5, {3}
fc: 00010068 andeq r0, r1, r8, rrx
100: 6d657300 stclvs 3, cr7, [r5, #-0]
104: 2e726870 mrccs 8, 3, r6, cr2, cr0, {3}
108: 00010068 andeq r0, r1, r8, rrx
10c: 2e736600 cdpcs 6, 7, cr6, cr3, cr0, {0}
110: 00010068 andeq r0, r1, r8, rrx
114: 75623c00 strbvc r3, [r2, #-3072]! ; 0xfffff400
118: 2d746c69 ldclcs 12, cr6, [r4, #-420]! ; 0xfffffe5c
11c: 003e6e69 eorseq r6, lr, r9, ror #28
120: 00000000 andeq r0, r0, r0
124: 00020500 andeq r0, r2, r0, lsl #10
127: R_ARM_ABS32 .text.lcdButtonProcess
128: 03000000 movweq r0, #0
12c: 13010282 movwne r0, #4738 ; 0x1282
130: 22242a4e eorcs r2, r4, #319488 ; 0x4e000
134: 01040200 mrseq r0, R12_usr
138: 3e062e06 cdpcc 14, 0, cr2, cr6, cr6, {0}
13c: 01040200 mrseq r0, R12_usr
140: 3e062e06 cdpcc 14, 0, cr2, cr6, cr6, {0}
144: 01040200 mrseq r0, R12_usr
148: 31062e06 tstcc r6, r6, lsl #28
14c: 6677032f ldrbtvs r0, [r7], -pc, lsr #6
150: 34313030 ldrtcc r3, [r1], #-48 ; 0xffffffd0
154: 00070221 andeq r0, r7, r1, lsr #4
158: 05000101 streq r0, [r0, #-257] ; 0xfffffeff
15c: 00000002 andeq r0, r0, r2
15d: R_ARM_ABS32 .text.fgetc
160: 01850300 orreq r0, r5, r0, lsl #6
164: 2f212101 svccs 0x00212101
168: 4a7fbe03 bmi 1fef97c <usart+0x1fef934>
16c: 594a1a03 stmdbpl sl, {r0, r1, r9, fp, ip}^
170: 2a903303 bcs fe40cd84 <usart+0xfe40cd3c>
174: 752e4003 strvc r4, [lr, #-3]!
178: 032f3b21 ; <UNDEFINED> instruction: 0x032f3b21
17c: 022000c2 eoreq r0, r0, #194 ; 0xc2
180: 01010006 tsteq r1, r6
184: 00020500 andeq r0, r2, r0, lsl #10
187: R_ARM_ABS32 .text.fputc
188: 03000000 movweq r0, #0
18c: 210101a8 smlatbcs r1, r8, r1, r0
190: 21221e21 ; <UNDEFINED> instruction: 0x21221e21
194: 4a7fa003 bmi 1fe81a8 <usart+0x1fe8160>
198: 2f581c03 svccs 0x00581c03
19c: 913c7003 teqls ip, r3
1a0: 00d40321 sbcseq r0, r4, r1, lsr #6
1a4: 7fac0320 svcvc 0x00ac0320
1a8: 032f2d20 ; <UNDEFINED> instruction: 0x032f2d20
1ac: 222000d5 eorcs r0, r0, #213 ; 0xd5
1b0: 3631222f ldrtcc r2, [r1], -pc, lsr #4
1b4: 52207803 eorpl r7, r0, #196608 ; 0x30000
1b8: 022b311d eoreq r3, fp, #1073741831 ; 0x40000007
1bc: 0101000c tsteq r1, ip
1c0: 00020500 andeq r0, r2, r0, lsl #10
1c3: R_ARM_ABS32 .text.fread
1c4: 03000000 movweq r0, #0
1c8: 200101c2 andcs r0, r1, r2, asr #3
1cc: 02002d31 andeq r2, r0, #3136 ; 0xc40
1d0: 30210104 eorcc r0, r1, r4, lsl #2
1d4: 02040200 andeq r0, r4, #0, 4
1d8: 04020075 streq r0, [r2], #-117 ; 0xffffff8b
1dc: 02322102 eorseq r2, r2, #-2147483648 ; 0x80000000
_taskYield();
}
// lcdButtonProcess - Processes the VEX LCD buttons
static void lcdButtonProcess(char value, uint32_t index) {
uint16_t count = lcd[index].state;
1e0: 01010002 tsteq r1, r2
1e4: 00020500 andeq r0, r2, r0, lsl #10
1e7: R_ARM_ABS32 .text.fwrite
// If 0xAA, set count to 1
// If 0x55, set count to 2 if count == 1
// If 0x16, set count to 3 if count == 2
if (value == (char)0xAA)
1e8: 03000000 movweq r0, #0
_taskYield();
}
// lcdButtonProcess - Processes the VEX LCD buttons
static void lcdButtonProcess(char value, uint32_t index) {
uint16_t count = lcd[index].state;
1ec: 200101d0 ldrdcs r0, [r1], -r0 ; <UNPREDICTABLE>
// If 0xAA, set count to 1
// If 0x55, set count to 2 if count == 1
// If 0x16, set count to 3 if count == 2
if (value == (char)0xAA)
count = 1;
else if (value == (char)0x55 && count == 1)
1f0: 02002d31 andeq r2, r0, #3136 ; 0xc40
1f4: 30210104 eorcc r0, r1, r4, lsl #2
1f8: 02040200 andeq r0, r4, #0, 4
count = 2;
else if (value == (char)0x16 && count == 2)
1fc: 02023283 andeq r3, r2, #805306376 ; 0x30000008
200: 00010100 andeq r0, r1, r0, lsl #2
count = 3;
else if (value == (char)0x02 && count == 3)
204: 00000205 andeq r0, r0, r5, lsl #4
206: R_ARM_ABS32 .text.getchar
208: dd030000 stcle 0, cr0, [r3, #-0]
// Size must be 2
count = 4;
else if (count == 4) {
20c: 02130101 andseq r0, r3, #1073741824 ; 0x40000000
lcd[index].buttons = (uint8_t)value;
210: 01010003 tsteq r1, r3
214: 00020500 andeq r0, r2, r0, lsl #10
217: R_ARM_ABS32 .text.putchar
218: 03000000 movweq r0, #0
uint16_t count = lcd[index].state;
// If 0xAA, set count to 1
// If 0x55, set count to 2 if count == 1
// If 0x16, set count to 3 if count == 2
if (value == (char)0xAA)
count = 1;
21c: 130101e2 movwne r0, #4578 ; 0x11e2
else if (value == (char)0x55 && count == 1)
count = 2;
220: 01000302 tsteq r0, r2, lsl #6
else if (value == (char)0x16 && count == 2)
count = 3;
224: 02050001 andeq r0, r5, #1
else if (value == (char)0x02 && count == 3)
// Size must be 2
count = 4;
228: 00000000 andeq r0, r0, r0
228: R_ARM_ABS32 .text.ISR_USART1
else if (count == 4) {
lcd[index].buttons = (uint8_t)value;
count = 0;
} else
// Ignore the checksum and any noise we pick up
count = 0;
22c: 0101e703 tsteq r1, r3, lsl #14
lcd[index].state = count;
230: 30221e5a eorcc r1, r2, sl, asr lr
234: 7ede034c cdpvc 3, 13, cr0, cr14, cr12, {2}
238: 01a20320 ; <UNDEFINED> instruction: 0x01a20320
return 1;
#endif
}
// fgetc - Read a character from the specified stream
int fgetc(FILE *stream) {
23c: 7ede0320 cdpvc 3, 13, cr0, cr14, cr0, {1}
uint32_t snew = (uint32_t)stream - 1;
if (snew < 3) {
240: 01a40320 ; <UNDEFINED> instruction: 0x01a40320
SerialPort_TypeDef *ser = &usart[snew];
244: 7ee90374 mcrvc 3, 7, r0, cr9, cr4, {3}
248: 0195032e orrseq r0, r5, lr, lsr #6
// Prototype this
uint32_t usartBufferCount(SerialPort_TypeDef* port);
// Checks to see if the ring buffer is empty (head = tail)
static INLINE uint8_t _isBufferEmpty(volatile RingBuffer_TypeDef* buffer) {
return buffer->head == buffer->tail;
24c: 7eeb032e cdpvc 3, 14, cr0, cr11, cr14, {1}
250: 3b212120 blcc 8486d8 <usart+0x848690>
}
// Waits for a byte in the given port's RX buffer
// This does not happen during init, so it is OK to use scheduler functions
static void _waitForByte(SerialPort_TypeDef* port) {
while (_isBufferEmpty(&(port->rx)))
254: 0198032f orrseq r0, r8, pc, lsr #6
258: d203682e andle r6, r3, #3014656 ; 0x2e0000
25c: af034a7e svcge 0x00034a7e
semaphoreTake(port->readLock, MAX_DELAY);
260: 03305801 teqeq r0, #65536 ; 0x10000
264: 3d747ed9 ldclcc 14, cr7, [r4, #-868]! ; 0xfffffc9c
268: 01a8033d ; <UNDEFINED> instruction: 0x01a8033d
26c: 02043f58 andeq r3, r4, #88, 30 ; 0x160
// File system check
return fsRead(stream);
#else
return EOF;
#endif
}
270: 3c7f8003 ldclcc 0, cr8, [pc], #-12 ; 26c <.debug_line+0x26c>
// Take byte off the tail
return (int)_pullByte(&(ser->rx)) & 0xFF;
}
#ifndef NO_FILESYSTEM
// File system check
return fsRead(stream);
274: 82030104 andhi r0, r3, #4, 2
return ((buffer->tail + 1) & _USART_MAX) == buffer->head;
}
// Removes a byte from the head of the given buffer
static char _pullByte(volatile RingBuffer_TypeDef* buffer) {
uint8_t head = buffer->head; char value;
278: 0b025801 bleq 96284 <usart+0x9623c>
27c: 00010100 andeq r0, r1, r0, lsl #2
280: 00000205 andeq r0, r0, r5, lsl #4
282: R_ARM_ABS32 .text.ISR_USART2
284: 9a030000 bls c028c <usart+0xc0244>
value = buffer->buffer[head];
buffer->head = (head + 1) & _USART_MAX;
288: 1c5c0102 ldfnee f0, [ip], {2}
28c: 1e221e24 cdpne 14, 2, cr1, cr2, cr4, {1}
}
// Removes a byte from the head of the given buffer
static char _pullByte(volatile RingBuffer_TypeDef* buffer) {
uint8_t head = buffer->head; char value;
value = buffer->buffer[head];
290: 1f212230 svcne 0x00212230
// File system check
return fsRead(stream);
#else
return EOF;
#endif
}
294: a9034b21 stmdbge r3, {r0, r5, r8, r9, fp, lr}
298: da034a7e ble d2c98 <usart+0xd2c50>
29c: b3037401 movwlt r7, #13313 ; 0x3401
*ptr = '\0';
return str;
}
// fputc - Write a character to the specified stream
int fputc(int value, FILE *stream) {
2a0: 213d2e7e teqcs sp, lr, ror lr
uint32_t snew = (uint32_t)stream - 1;
if (snew < 3) {
2a4: ce032f3b mcrgt 15, 0, r2, cr3, cr11, {1}
2a8: 03692e01 cmneq r9, #1, 28
SerialPort_TypeDef *ser = &usart[snew];
2ac: 034a7e9b movteq r7, #44699 ; 0xae9b
2b0: 305801e6 subscc r0, r8, r6, ror #3
return buffer->head == buffer->tail;
}
// Checks to see if the ring buffer is full (tail + 1 = head)
static INLINE uint8_t _isBufferFull(volatile RingBuffer_TypeDef* buffer) {
return ((buffer->tail + 1) & _USART_MAX) == buffer->head;
2b4: 747ea203 ldrbtvc sl, [lr], #-515 ; 0xfffffdfd
2b8: df033d3d svcle 0x00033d3d
}
// Waits for space in the given port's TX buffer
// This happens infrequently, so simply sleep-waiting is acceptable
static void _waitForSpace(SerialPort_TypeDef* port) {
while (_isBufferFull(&(port->tx)))
2bc: 043f5801 ldrteq r5, [pc], #-2049 ; 2c4 <.debug_line+0x2c4>
_yield();
2c0: 7ec90302 cdpvc 3, 12, cr0, cr9, cr2, {0}
2c4: 0301043c movweq r0, #5180 ; 0x143c
return value;
}
// Queues a byte onto the tail of the given buffer
static void _queueByte(volatile RingBuffer_TypeDef* buffer, char value) {
uint8_t tail = buffer->tail;
2c8: 025801b9 subseq r0, r8, #1073741870 ; 0x4000002e
2cc: 0101000c tsteq r1, ip
2d0: 00020500 andeq r0, r2, r0, lsl #10
2d3: R_ARM_ABS32 .text.ISR_USART3
2d4: 03000000 movweq r0, #0
buffer->buffer[tail] = value;
2d8: 5a0102b9 bpl 40dc4 <usart+0x40d7c>
uint32_t snew = (uint32_t)stream - 1;
if (snew < 3) {
SerialPort_TypeDef *ser = &usart[snew];
_waitForSpace(ser);
// Jam a byte onto the head
_queueByte(&(ser->tx), (char)value);
2dc: 4c30221e lfmmi f2, 4, [r0], #-120 ; 0xffffff88
// Queues a byte onto the tail of the given buffer
static void _queueByte(volatile RingBuffer_TypeDef* buffer, char value) {
uint8_t tail = buffer->tail;
buffer->buffer[tail] = value;
buffer->tail = (tail + 1) & _USART_MAX;
2e0: 4b211f21 blmi 847f6c <usart+0x847f24>
}
// Queues a byte onto the tail of the given buffer
static void _queueByte(volatile RingBuffer_TypeDef* buffer, char value) {
uint8_t tail = buffer->tail;
buffer->buffer[tail] = value;
2e4: 587e8a03 ldmdapl lr!, {r0, r1, r9, fp, pc}^
if (snew < 3) {
SerialPort_TypeDef *ser = &usart[snew];
_waitForSpace(ser);
// Jam a byte onto the head
_queueByte(&(ser->tx), (char)value);
if (snew == 0)
2e8: 7401f903 strvc pc, [r1], #-2307 ; 0xfffff6fd
// Enable USART2 TXE interrupts
USART2->CR1 |= USART_CR1_TXEIE;
2ec: 2e7e9403 cdpcs 4, 7, cr9, cr14, cr3, {0}
else if (snew == 1)
// Enable USART3 TXE interrupts
USART3->CR1 |= USART_CR1_TXEIE;
2f0: 2f3b213d svccs 0x003b213d
else if (snew == 2)
// Enable USART1 TXE interrupts
USART1->CR1 |= USART_CR1_TXEIE;
2f4: 2e01ed03 cdpcs 13, 0, cr14, cr1, cr3, {0}
else
// File system check
return fsWrite(stream, value);
#endif
return value;
}
2f8: 7dfc0369 ldclvc 3, cr0, [ip, #420]! ; 0x1a4
else if (snew == 1)
// Enable USART3 TXE interrupts
USART3->CR1 |= USART_CR1_TXEIE;
else if (snew == 2)
// Enable USART1 TXE interrupts
USART1->CR1 |= USART_CR1_TXEIE;
2fc: 0285034a addeq r0, r5, #671088641 ; 0x28000001
300: 83033058 movwhi r3, #12376 ; 0x3058
}
#ifndef NO_FILESYSTEM
else
// File system check
return fsWrite(stream, value);
304: 3d3d747e cfldrscc mvf7, [sp, #-504]! ; 0xfffffe08
#endif
return value;
}
308: 5801fe03 stmdapl r1, {r0, r1, r9, sl, fp, ip, sp, lr, pc}
USART1->CR1 |= USART_CR1_TXEIE;
}
#ifndef NO_FILESYSTEM
else
// File system check
return fsWrite(stream, value);
30c: 0302043f movweq r0, #9279 ; 0x243f
310: 043c7eaa ldrteq r7, [ip], #-3754 ; 0xfffff156
314: 01d80301 bicseq r0, r8, r1, lsl #6
318: 000b0258 andeq r0, fp, r8, asr r2
31c: 05000101 streq r0, [r0, #-257] ; 0xfffffeff
320: 00000002 andeq r0, r0, r2
321: R_ARM_ABS32 .text.lcdReadButtons
#endif
return value;
}
// fread - Read data from stream
size_t fread(void *ptr, size_t size, size_t count, FILE *stream) {
324: 02f90300 rscseq r0, r9, #0, 6
328: 2f211301 svccs 0x00211301
char *memory = (char *)ptr;
size_t write = 0; int read;
for (uint32_t i = 0; i < (size * count); i++)
32c: 022130c9 eoreq r3, r1, #201 ; 0xc9
330: 01010003 tsteq r1, r3
// Write as many as we can, break if we fail
if ((read = fgetc(stream)) != EOF) {
334: 00020500 andeq r0, r2, r0, lsl #10
337: R_ARM_ABS32 .text.lcdSetBacklight
338: 03000000 movweq r0, #0
33c: 13010384 movwne r0, #4996 ; 0x1384
340: 21494c21 cmpcs r9, r1, lsr #24
*memory++ = (char)read;
write++;
344: 0007023e andeq r0, r7, lr, lsr r2
} else
break;
return write;
}
348: 05000101 streq r0, [r0, #-257] ; 0xfffffeff
// fwrite - Write data to stream
size_t fwrite(const void *ptr, size_t size, size_t count, FILE *stream) {
34c: 00000002 andeq r0, r0, r2
34d: R_ARM_ABS32 .text._lcdDump
350: 03900300 orrseq r0, r0, #0, 6
const char *memory = (const char *)ptr;
size_t write = 0;
for (uint32_t i = 0; i < (size * count); i++)
354: 301e1401 andscc r1, lr, r1, lsl #8
358: 22223159 eorcs r3, r2, #1073741846 ; 0x40000016
// Write as many as we can, break if we fail
if (fputc((int)(*memory++), stream) != EOF)
35c: 2e79033e mrccs 3, 3, r0, cr9, cr14, {1}
360: 03313e33 teqeq r1, #816 ; 0x330
364: 2f343c7a svccs 0x00343c7a
368: 4c35454c cfldr32mi mvfx4, [r5], #-304 ; 0xfffffed0
write++;
36c: 3d3e2f5c ldccc 15, cr2, [lr, #-368]! ; 0xfffffe90
else
break;
return write;
}
370: 31212f1f ; <UNDEFINED> instruction: 0x31212f1f
// getchar - Gets a character from the serial PC communication buffer; blocks until read
int getchar() {
return fgetc(stdin);
374: 0402004b streq r0, [r2], #-75 ; 0xffffffb5
378: 2e760302 cdpcs 3, 7, cr0, cr6, cr2, {0}
}
// putchar - Write a character to the serial PC communication buffer
int putchar(int value) {
return fputc(value, stdout);
37c: 302e0e03 eorcc r0, lr, r3, lsl #28
}
// ISR_USART1 - Buffered character I/O handler for debug communications
void ISR_USART1() {
380: 0008022c andeq r0, r8, ip, lsr #4
384: 05000101 streq r0, [r0, #-257] ; 0xfffffeff
388: 00000002 andeq r0, r0, r2
389: R_ARM_ABS32 .text.lcdSetText
38c: 03be0300 ; <UNDEFINED> instruction: 0x03be0300
char value;
bool cs = false;
390: 1c221401 cfstrsne mvf1, [r2], #-4
SerialPort_TypeDef *ser = &usart[2];
if (USART1->SR & USART_SR_RXNE) {
394: 04020024 streq r0, [r2], #-36 ; 0xffffffdc
398: 02001f01 andeq r1, r0, #1, 30
return buffer->head == buffer->tail;
}
// Checks to see if the ring buffer is full (tail + 1 = head)
static INLINE uint8_t _isBufferFull(volatile RingBuffer_TypeDef* buffer) {
return ((buffer->tail + 1) & _USART_MAX) == buffer->head;
39c: 302f0104 eorcc r0, pc, r4, lsl #2
3a0: 0402004b streq r0, [r2], #-75 ; 0xffffffb5
3a4: 06200601 strteq r0, [r0], -r1, lsl #12
3a8: 45302f3f ldrmi r2, [r0, #-3903]! ; 0xfffff0c1
3ac: 01000602 tsteq r0, r2, lsl #12
SerialPort_TypeDef *ser = &usart[2];
if (USART1->SR & USART_SR_RXNE) {
// Read to clear the flag
value = (char)USART1->DR;
// Buffer it up, if it's not full to the brim
if (!_isBufferFull(&(ser->rx)))
3b0: 02050001 andeq r0, r5, #1
return value;
}
// Queues a byte onto the tail of the given buffer
static void _queueByte(volatile RingBuffer_TypeDef* buffer, char value) {
uint8_t tail = buffer->tail;
3b4: 00000000 andeq r0, r0, r0
3b4: R_ARM_ABS32 .text.lcdClear
3b8: 0102d803 tsteq r2, r3, lsl #16
buffer->buffer[tail] = value;
buffer->tail = (tail + 1) & _USART_MAX;
3bc: 2f592120 svccs 0x00592120
3c0: 0005022d andeq r0, r5, sp, lsr #4
}
// Queues a byte onto the tail of the given buffer
static void _queueByte(volatile RingBuffer_TypeDef* buffer, char value) {
uint8_t tail = buffer->tail;
buffer->buffer[tail] = value;
3c4: 05000101 streq r0, [r0, #-257] ; 0xfffffeff
buffer->tail = (tail + 1) & _USART_MAX;
3c8: 00000002 andeq r0, r0, r2
3c9: R_ARM_ABS32 .text.lcdPrint
value = (char)USART1->DR;
// Buffer it up, if it's not full to the brim
if (!_isBufferFull(&(ser->rx)))
_queueByte(&(ser->rx), value);
// Notify any receivers
semaphoreGiveISR(ser->readLock, &cs);
3cc: 02eb0300 rsceq r0, fp, #0, 6
3d0: 2d415801 stclcs 8, cr5, [r1, #-4]
3d4: 3b213121 blcc 84c860 <usart+0x84c818>
}
if (USART1->SR & USART_SR_TXE) {
3d8: 05022f2f streq r2, [r2, #-3887] ; 0xfffff0d1
3dc: 00010100 andeq r0, r1, r0, lsl #2
// Prototype this
uint32_t usartBufferCount(SerialPort_TypeDef* port);
// Checks to see if the ring buffer is empty (head = tail)
static INLINE uint8_t _isBufferEmpty(volatile RingBuffer_TypeDef* buffer) {
return buffer->head == buffer->tail;
3e0: 00000205 andeq r0, r0, r5, lsl #4
3e2: R_ARM_ABS32 .text.usartBufferCount
3e4: e2030000 and r0, r3, #0
_queueByte(&(ser->rx), value);
// Notify any receivers
semaphoreGiveISR(ser->readLock, &cs);
}
if (USART1->SR & USART_SR_TXE) {
if (_isBufferEmpty(&(ser->tx)))
3e8: 03040103 movweq r0, #16643 ; 0x4103
// Nothing to send, disable interrupt
USART1->CR1 &= ~USART_CR1_TXEIE;
3ec: 2006fa03 andcs pc, r6, r3, lsl #20
3f0: ef030204 svc 0x00030204
3f4: 01042075 tsteq r4, r5, ror r0
3f8: 4a039a03 bmi e6c0c <usart+0xe6bc4>
return ((buffer->tail + 1) & _USART_MAX) == buffer->head;
}
// Removes a byte from the head of the given buffer
static char _pullByte(volatile RingBuffer_TypeDef* buffer) {
uint8_t head = buffer->head; char value;
3fc: 0302042f movweq r0, #9263 ; 0x242f
value = buffer->buffer[head];
400: 042e7cea strteq r7, [lr], #-3306 ; 0xfffff316
404: 03950301 orrseq r0, r5, #67108864 ; 0x4000000
buffer->head = (head + 1) & _USART_MAX;
408: 03020420 movweq r0, #9248 ; 0x2420
40c: 04207ceb strteq r7, [r0], #-3307 ; 0xfffff315
if (_isBufferEmpty(&(ser->tx)))
// Nothing to send, disable interrupt
USART1->CR1 &= ~USART_CR1_TXEIE;
else {
value = _pullByte(&(ser->tx));
USART1->DR = value;
410: 03960301 orrseq r0, r6, #67108864 ; 0x4000000
414: 03020420 movweq r0, #9248 ; 0x2420
}
}
if (cs)
418: 21207ceb ; <UNDEFINED> instruction: 0x21207ceb
*/
bool _taskClearEvent(OSList *eventList);
static INLINE void _taskYield() {
/* Set a PendSV to request a context switch. */
SCB->ICSR |= SCB_ICSR_PENDSV;
41c: 92030304 andls r0, r3, #4, 6 ; 0x10000000
420: 0104200a tsteq r4, sl
424: 20798403 rsbscs r8, r9, r3, lsl #8
_taskYield();
}
428: 00060221 andeq r0, r6, r1, lsr #4
42c: 05000101 streq r0, [r0, #-257] ; 0xfffffeff
430: 00000002 andeq r0, r0, r2
431: R_ARM_ABS32 .text.fcount
434: 00ec0300 rsceq r0, ip, r0, lsl #6
438: 2f211301 svccs 0x00211301
count = 0;
lcd[index].state = count;
}
// ISR_USART2 - Buffered character I/O handler for UART port 1
void ISR_USART2() {
43c: 00050269 andeq r0, r5, r9, ror #4
440: 05000101 streq r0, [r0, #-257] ; 0xfffffeff
444: 00000002 andeq r0, r0, r2
445: R_ARM_ABS32 .text.feof
448: 00f90300 rscseq r0, r9, r0, lsl #6
char value;
bool cs = false;
44c: 35212101 strcc r2, [r1, #-257]! ; 0xfffffeff
450: 02962c2a addseq r2, r6, #10752 ; 0x2a00
SerialPort_TypeDef *ser = &usart[0];
if (USART2->SR & USART_SR_RXNE) {
454: 01010003 tsteq r1, r3
// Read to clear the flag
value = (char)USART2->DR;
if (lcd[0].flags & LCD_ACTIVE)
458: 00020500 andeq r0, r2, r0, lsl #10
45b: R_ARM_ABS32 .text.fgets
45c: 03000000 movweq r0, #0
460: 20010197 mulcs r1, r7, r1
lcdButtonProcess(value, 0);
464: 00321c24 eorseq r1, r2, r4, lsr #24
468: 68010402 stmdavs r1, {r1, sl}
return buffer->head == buffer->tail;
}
// Checks to see if the ring buffer is full (tail + 1 = head)
static INLINE uint8_t _isBufferFull(volatile RingBuffer_TypeDef* buffer) {
return ((buffer->tail + 1) & _USART_MAX) == buffer->head;
46c: 02040200 andeq r0, r4, #0, 4
470: 59062e06 stmdbpl r6, {r1, r2, r9, sl, fp, sp}
474: 032f3f30 ; <UNDEFINED> instruction: 0x032f3f30
478: 0a032e77 beq cbe5c <usart+0xcbe14>
value = (char)USART2->DR;
if (lcd[0].flags & LCD_ACTIVE)
lcdButtonProcess(value, 0);
else {
// Buffer it up, if it's not full to the brim
if (!_isBufferFull(&(ser->rx)))
47c: 00010220 andeq r0, r1, r0, lsr #4
return value;
}
// Queues a byte onto the tail of the given buffer
static void _queueByte(volatile RingBuffer_TypeDef* buffer, char value) {
uint8_t tail = buffer->tail;
480: 05000101 streq r0, [r0, #-257] ; 0xfffffeff
buffer->buffer[tail] = value;
484: 00000002 andeq r0, r0, r2
485: R_ARM_ABS32 .text.usartBufferInit
buffer->tail = (tail + 1) & _USART_MAX;
488: 03ec0300 mvneq r0, #0, 6
}
// Queues a byte onto the tail of the given buffer
static void _queueByte(volatile RingBuffer_TypeDef* buffer, char value) {
uint8_t tail = buffer->tail;
buffer->buffer[tail] = value;
48c: 206e0301 rsbcs r0, lr, r1, lsl #6
buffer->tail = (tail + 1) & _USART_MAX;
490: 2f2f2f4b svccs 0x002f2f4b
else {
// Buffer it up, if it's not full to the brim
if (!_isBufferFull(&(ser->rx)))
_queueByte(&(ser->rx), value);
// Notify any receivers
semaphoreGiveISR(ser->readLock, &cs);
494: 2f2b322a svccs 0x002b322a
498: 322a2f2f eorcc r2, sl, #47, 30 ; 0xbc
49c: 2f2f2f2b svccs 0x002f2f2b
}
}
if (USART2->SR & USART_SR_TXE) {
4a0: 01000702 tsteq r0, r2, lsl #14
4a4: 02050001 andeq r0, r5, #1
// Prototype this
uint32_t usartBufferCount(SerialPort_TypeDef* port);
// Checks to see if the ring buffer is empty (head = tail)
static INLINE uint8_t _isBufferEmpty(volatile RingBuffer_TypeDef* buffer) {
return buffer->head == buffer->tail;
4a8: 00000000 andeq r0, r0, r0
4a8: R_ARM_ABS32 .text.usartFlushBuffers
4ac: 0103f603 tsteq r3, r3, lsl #12 ; <UNPREDICTABLE>
4b0: e6030304 str r0, [r3], -r4, lsl #6
// Notify any receivers
semaphoreGiveISR(ser->readLock, &cs);
}
}
if (USART2->SR & USART_SR_TXE) {
if (_isBufferEmpty(&(ser->tx)))
4b4: 01040106 tsteq r4, r6, lsl #2
// Nothing to send, disable interrupt
USART2->CR1 &= ~USART_CR1_TXEIE;
4b8: 20799c03 rsbscs r9, r9, r3, lsl #24
4bc: 03045967 movweq r5, #18791 ; 0x4967
4c0: 5806ea03 stmdapl r6, {r0, r1, r9, fp, sp, lr, pc}
return ((buffer->tail + 1) & _USART_MAX) == buffer->head;
}
// Removes a byte from the head of the given buffer
static char _pullByte(volatile RingBuffer_TypeDef* buffer) {
uint8_t head = buffer->head; char value;
4c4: 01000502 tsteq r0, r2, lsl #10
4c8: 02050001 andeq r0, r5, #1
value = buffer->buffer[head];
4cc: 00000000 andeq r0, r0, r0
4cc: R_ARM_ABS32 .text.usartInit
buffer->head = (head + 1) & _USART_MAX;
4d0: 01048003 tsteq r4, r3
4d4: 22231d15 eorcs r1, r3, #1344 ; 0x540
4d8: 03042c2f movweq r2, #19503 ; 0x4c2f
if (_isBufferEmpty(&(ser->tx)))
// Nothing to send, disable interrupt
USART2->CR1 &= ~USART_CR1_TXEIE;
else {
value = _pullByte(&(ser->tx));
USART2->DR = value;
4dc: 2006d803 andcs sp, r6, r3, lsl #16
}
}
if (cs)
4e0: ef030204 svc 0x00030204
4e4: 01042075 tsteq r4, r5, ror r0
4e8: 2003c303 andcs ip, r3, r3, lsl #6
4ec: bd030204 sfmlt f0, 4, [r3, #-16]
_taskYield();
}
4f0: 0104207c tsteq r4, ip, ror r0
4f4: 5803c103 stmdapl r3, {r0, r1, r8, lr, pc}
4f8: 232b3f4d ; <UNDEFINED> instruction: 0x232b3f4d
4fc: 312c3f1d ; <UNDEFINED> instruction: 0x312c3f1d
500: 207a0331 rsbscs r0, sl, r1, lsr r3
504: 31311d31 teqcc r1, r1, lsr sp
// ISR_USART3 - Buffered character I/O handler for UART port 2
void ISR_USART3() {
508: 30224830 eorcc r4, r2, r0, lsr r8
50c: 8322221e ; <UNDEFINED> instruction: 0x8322221e
510: b3030204 movwlt r0, #12804 ; 0x3204
514: 212f9e7c ; <UNDEFINED> instruction: 0x212f9e7c
char value;
bool cs = false;
518: 92030304 andls r0, r3, #4, 6 ; 0x10000000
SerialPort_TypeDef *ser = &usart[1];
if (USART3->SR & USART_SR_RXNE) {
51c: 0c02200a stceq 0, cr2, [r2], {10}
520: 00010100 andeq r0, r1, r0, lsl #2
// Read to clear the flag
value = (char)USART3->DR;
if (lcd[1].flags & LCD_ACTIVE)
524: 00000205 andeq r0, r0, r5, lsl #4
526: R_ARM_ABS32 .text.lcdInit
528: de030000 cdple 0, 0, cr0, cr3, cr0, {0}
52c: 3e220102 sufccs f0, f2, f2
lcdButtonProcess(value, 1);
530: 022f915a eoreq r9, pc, #-2147483626 ; 0x80000016
534: 01010004 tsteq r1, r4
538: 00020500 andeq r0, r2, r0, lsl #10
53b: R_ARM_ABS32 .text.usartShutdown
return buffer->head == buffer->tail;
}
// Checks to see if the ring buffer is full (tail + 1 = head)
static INLINE uint8_t _isBufferFull(volatile RingBuffer_TypeDef* buffer) {
return ((buffer->tail + 1) & _USART_MAX) == buffer->head;
53c: 03000000 movweq r0, #0
540: 140104a3 strne r0, [r1], #-1187 ; 0xfffffb5d
544: 022f3d2f eoreq r3, pc, #3008 ; 0xbc0
value = (char)USART3->DR;
if (lcd[1].flags & LCD_ACTIVE)
lcdButtonProcess(value, 1);
else {
// Buffer it up, if it's not full to the brim
if (!_isBufferFull(&(ser->rx)))
548: 01010009 tsteq r1, r9
return value;
}
// Queues a byte onto the tail of the given buffer
static void _queueByte(volatile RingBuffer_TypeDef* buffer, char value) {
uint8_t tail = buffer->tail;
54c: 00020500 andeq r0, r2, r0, lsl #10
54f: R_ARM_ABS32 .text.lcdShutdown
550: 03000000 movweq r0, #0
buffer->buffer[tail] = value;
buffer->tail = (tail + 1) & _USART_MAX;
554: 210103d1 ldrdcs r0, [r1, -r1]
558: 0a022f3d beq 8c254 <usart+0x8c20c>
}
// Queues a byte onto the tail of the given buffer
static void _queueByte(volatile RingBuffer_TypeDef* buffer, char value) {
uint8_t tail = buffer->tail;
buffer->buffer[tail] = value;
55c: Address 0x000000000000055c is out of bounds.
Disassembly of section .debug_str:
00000000 <.debug_str>:
0: 746e655f strbtvc r6, [lr], #-1375 ; 0xfffffaa1
4: 72437265 subvc r7, r3, #1342177286 ; 0x50000006
8: 63697469 cmnvs r9, #1761607680 ; 0x69000000
c: 5f006c61 svcpl 0x00006c61
10: 6b736174 blvs 1cd85e8 <usart+0x1cd85a0>
14: 6c656959 stclvs 9, cr6, [r5], #-356 ; 0xfffffe9c
18: 636c0064 cmnvs ip, #100 ; 0x64
1c: 74655364 strbtvc r5, [r5], #-868 ; 0xfffffc9c
20: 74786554 ldrbtvc r6, [r8], #-1364 ; 0xfffffaac
24: 616c6600 cmnvs ip, r0, lsl #12
28: 62007367 andvs r7, r0, #-1677721599 ; 0x9c000001
2c: 65666675 strbvs r6, [r6, #-1653]! ; 0xfffff98b
30: 61620072 smcvs 8194 ; 0x2002
34: 696c6b63 stmdbvs ip!, {r0, r1, r5, r6, r8, r9, fp, sp, lr}^
38: 00746867 rsbseq r6, r4, r7, ror #16
3c: 69736e75 ldmdbvs r3!, {r0, r2, r4, r5, r6, r9, sl, fp, sp, lr}^
40: 64656e67 strbtvs r6, [r5], #-3687 ; 0xfffff199
44: 746e6920 strbtvc r6, [lr], #-2336 ; 0xfffff6e0
48: 53464400 movtpl r4, #25600 ; 0x6400
4c: 65680052 strbvs r0, [r8, #-82]! ; 0xffffffae
50: 6c006461 cfstrsvs mvf6, [r0], {97} ; 0x61
54: 00656e69 rsbeq r6, r5, r9, ror #28
58: 64636c5f strbtvs r6, [r3], #-3167 ; 0xfffff3a1
5c: 706d7544 rsbvc r7, sp, r4, asr #10
60: 72635f00 rsbvc r5, r3, #0, 30
64: 63697469 cmnvs r9, #1761607680 ; 0x69000000
68: 654e6c61 strbvs r6, [lr, #-3169] ; 0xfffff39f
6c: 6e697473 mcrvs 4, 3, r7, cr9, cr3, {3}
70: 69520067 ldmdbvs r2, {r0, r1, r2, r5, r6}^
74: 7542676e strbvc r6, [r2, #-1902] ; 0xfffff892
78: 72656666 rsbvc r6, r5, #106954752 ; 0x6600000
7c: 7079545f rsbsvc r5, r9, pc, asr r4
80: 66654465 strbtvs r4, [r5], -r5, ror #8
84: 61737500 cmnvs r3, r0, lsl #10
88: 68537472 ldmdavs r3, {r1, r4, r5, r6, sl, ip, sp, lr}^
8c: 6f647475 svcvs 0x00647475
90: 70006e77 andvc r6, r0, r7, ror lr
94: 68637475 stmdavs r3!, {r0, r2, r4, r5, r6, sl, ip, sp, lr}^
98: 53007261 movwpl r7, #609 ; 0x261
9c: 61697265 cmnvs r9, r5, ror #4
a0: 726f506c rsbvc r5, pc, #108 ; 0x6c
a4: 79545f74 ldmdbvc r4, {r2, r4, r5, r6, r8, r9, sl, fp, ip, lr}^
a8: 65446570 strbvs r6, [r4, #-1392] ; 0xfffffa90
ac: 54470066 strbpl r0, [r7], #-102 ; 0xffffff9a
b0: 73005250 movwvc r5, #592 ; 0x250
b4: 0077656e rsbseq r6, r7, lr, ror #10
b8: 65726373 ldrbvs r6, [r2, #-883]! ; 0xfffffc8d
bc: 6e006e65 cdpvs 14, 0, cr6, cr0, cr5, {3}
c0: 72437765 subvc r7, r3, #26476544 ; 0x1940000
c4: 63697469 cmnvs r9, #1761607680 ; 0x69000000
c8: 75006c61 strvc r6, [r0, #-3169] ; 0xfffff39f
cc: 33746e69 cmncc r4, #1680 ; 0x690
d0: 00745f32 rsbseq r5, r4, r2, lsr pc
d4: 52464d4d subpl r4, r6, #4928 ; 0x1340
d8: 61657200 cmnvs r5, r0, lsl #4
dc: 61620064 cmnvs r2, r4, rrx
e0: 63006573 movwvs r6, #1395 ; 0x573
e4: 746e756f strbtvc r7, [lr], #-1391 ; 0xfffffa91
e8: 646e6900 strbtvs r6, [lr], #-2304 ; 0xfffff700
ec: 6c007865 stcvs 8, cr7, [r0], {101} ; 0x65
f0: 20676e6f rsbcs r6, r7, pc, ror #28
f4: 676e6f6c strbvs r6, [lr, -ip, ror #30]!
f8: 736e7520 cmnvc lr, #32, 10 ; 0x8000000
fc: 656e6769 strbvs r6, [lr, #-1897]! ; 0xfffff897
100: 6e692064 cdpvs 0, 6, cr2, cr9, cr4, {3}
104: 65730074 ldrbvs r0, [r3, #-116]! ; 0xffffff8c
108: 6870616d ldmdavs r0!, {r0, r2, r3, r5, r6, r8, sp, lr}^
10c: 4765726f strbmi r7, [r5, -pc, ror #4]!
110: 49657669 stmdbmi r5!, {r0, r3, r5, r6, r9, sl, ip, sp, lr}^
114: 5f005253 svcpl 0x00005253
118: 6e69755f mcrvs 5, 3, r7, cr9, cr15, {2}
11c: 5f363174 svcpl 0x00363174
120: 73750074 cmnvc r5, #116 ; 0x74
124: 42747261 rsbsmi r7, r4, #268435462 ; 0x10000006
128: 65666675 strbvs r6, [r6, #-1653]! ; 0xfffff98b
12c: 696e4972 stmdbvs lr!, {r1, r4, r5, r6, r8, fp, lr}^
130: 636c0074 cmnvs ip, #116 ; 0x74
134: 69725064 ldmdbvs r2!, {r2, r5, r6, ip, lr}^
138: 6300746e movwvs r7, #1134 ; 0x46e
13c: 6b636f6c blvs 18dbef4 <usart+0x18dbeac>
140: 6c00745f cfstrsvs mvf7, [r0], {95} ; 0x5f
144: 65536463 ldrbvs r6, [r3, #-1123] ; 0xfffffb9d
148: 63614274 cmnvs r1, #116, 4 ; 0x40000007
14c: 67696c6b strbvs r6, [r9, -fp, ror #24]!
150: 76007468 strvc r7, [r0], -r8, ror #8
154: 65756c61 ldrbvs r6, [r5, #-3169]! ; 0xfffff39f
158: 52534900 subspl r4, r3, #0, 18
15c: 4153555f cmpmi r3, pc, asr r5
160: 00315452 eorseq r5, r1, r2, asr r4
164: 5f525349 svcpl 0x00525349
168: 52415355 subpl r5, r1, #1409286145 ; 0x54000001
16c: 49003254 stmdbmi r0, {r2, r4, r6, r9, ip, sp}
170: 555f5253 ldrbpl r5, [pc, #-595] ; ffffff25 <usart+0xfffffedd>
174: 54524153 ldrbpl r4, [r2], #-339 ; 0xfffffead
178: 5f5f0033 svcpl 0x005f0033
17c: 63756e67 cmnvs r5, #1648 ; 0x670
180: 5f61765f svcpl 0x0061765f
184: 7473696c ldrbtvc r6, [r3], #-2412 ; 0xfffff694
188: 7a697300 bvc 1a5cd90 <usart+0x1a5cd48>
18c: 00745f65 rsbseq r5, r4, r5, ror #30
190: 69645f5f stmdbvs r4!, {r0, r1, r2, r3, r4, r6, r8, r9, sl, fp, ip, lr}^
194: 6c626173 stfvse f6, [r2], #-460 ; 0xfffffe34
198: 72695f65 rsbvc r5, r9, #404 ; 0x194
19c: 50430071 subpl r0, r3, r1, ror r0
1a0: 00444955 subeq r4, r4, r5, asr r9
1a4: 6f6f425f svcvs 0x006f425f
1a8: 6162006c cmnvs r2, ip, rrx
1ac: 41006475 tstmi r0, r5, ror r4
1b0: 00525346 subseq r5, r2, r6, asr #6
1b4: 52415355 subpl r5, r1, #1409286145 ; 0x54000001
1b8: 79545f54 ldmdbvc r4, {r2, r4, r6, r8, r9, sl, fp, ip, lr}^
1bc: 65446570 strbvs r6, [r4, #-1392] ; 0xfffffa90
1c0: 65730066 ldrbvs r0, [r3, #-102]! ; 0xffffff9a
1c4: 6870616d ldmdavs r0!, {r0, r2, r3, r5, r6, r8, sp, lr}^
1c8: 5465726f strbtpl r7, [r5], #-623 ; 0xfffffd91
1cc: 00656b61 rsbeq r6, r5, r1, ror #22
1d0: 52534648 subspl r4, r3, #72, 12 ; 0x4800000
1d4: 656d2f00 strbvs r2, [sp, #-3840]! ; 0xfffff100
1d8: 2f616964 svccs 0x00616964
1dc: 65786970 ldrbvs r6, [r8, #-2416]! ; 0xfffff690
_taskYield();
}
// lcdButtonProcess - Processes the VEX LCD buttons
static void lcdButtonProcess(char value, uint32_t index) {
uint16_t count = lcd[index].state;
1e0: 494c2f6c stmdbmi ip, {r2, r3, r5, r6, r8, r9, sl, fp, sp}^
1e4: 682f554e stmdavs pc!, {r1, r2, r3, r6, r8, sl, ip, lr} ; <UNPREDICTABLE>
// If 0xAA, set count to 1
// If 0x55, set count to 2 if count == 1
// If 0x16, set count to 3 if count == 2
if (value == (char)0xAA)
1e8: 2f656d6f svccs 0x00656d6f
_taskYield();
}
// lcdButtonProcess - Processes the VEX LCD buttons
static void lcdButtonProcess(char value, uint32_t index) {
uint16_t count = lcd[index].state;
1ec: 65786970 ldrbvs r6, [r8, #-2416]! ; 0xfffff690
// If 0xAA, set count to 1
// If 0x55, set count to 2 if count == 1
// If 0x16, set count to 3 if count == 2
if (value == (char)0xAA)
count = 1;
else if (value == (char)0x55 && count == 1)
1f0: 73732f6c cmnvc r3, #108, 30 ; 0x1b0
1f4: 69702f64 ldmdbvs r0!, {r2, r5, r6, r8, r9, sl, fp, sp}^
1f8: 2f6c6578 svccs 0x006c6578
count = 2;
else if (value == (char)0x16 && count == 2)
1fc: 736f7270 cmnvc pc, #112, 4
200: 6b726f66 blvs 1c9bfa0 <usart+0x1c9bf58>
count = 3;
else if (value == (char)0x02 && count == 3)
204: 6372732f cmnvs r2, #-1140850688 ; 0xbc000000
208: 61686300 cmnvs r8, r0, lsl #6
// Size must be 2
count = 4;
else if (count == 4) {
20c: 715f0072 cmpvc pc, r2, ror r0 ; <UNPREDICTABLE>
lcd[index].buttons = (uint8_t)value;
210: 65756575 ldrbvs r6, [r5, #-1397]! ; 0xfffffa8b
214: 65747942 ldrbvs r7, [r4, #-2370]! ; 0xfffff6be
218: 6d657300 stclvs 3, cr7, [r5, #-0]
uint16_t count = lcd[index].state;
// If 0xAA, set count to 1
// If 0x55, set count to 2 if count == 1
// If 0x16, set count to 3 if count == 2
if (value == (char)0xAA)
count = 1;
21c: 6f687061 svcvs 0x00687061
else if (value == (char)0x55 && count == 1)
count = 2;
220: 72436572 subvc r6, r3, #478150656 ; 0x1c800000
else if (value == (char)0x16 && count == 2)
count = 3;
224: 65746165 ldrbvs r6, [r4, #-357]! ; 0xfffffe9b
else if (value == (char)0x02 && count == 3)
// Size must be 2
count = 4;
228: 52494100 subpl r4, r9, #0, 2
else if (count == 4) {
lcd[index].buttons = (uint8_t)value;
count = 0;
} else
// Ignore the checksum and any noise we pick up
count = 0;
22c: 75005243 strvc r5, [r0, #-579] ; 0xfffffdbd
lcd[index].state = count;
230: 38746e69 ldmdacc r4!, {r0, r3, r5, r6, r9, sl, fp, sp, lr}^
234: 5f00745f svcpl 0x0000745f
238: 74696177 strbtvc r6, [r9], #-375 ; 0xfffffe89
return 1;
#endif
}
// fgetc - Read a character from the specified stream
int fgetc(FILE *stream) {
23c: 42726f46 rsbsmi r6, r2, #280 ; 0x118
uint32_t snew = (uint32_t)stream - 1;
if (snew < 3) {
240: 00657479 rsbeq r7, r5, r9, ror r4
SerialPort_TypeDef *ser = &usart[snew];
244: 4964636c stmdbmi r4!, {r2, r3, r5, r6, r8, r9, sp, lr}^
248: 0074696e rsbseq r6, r4, lr, ror #18
// Prototype this
uint32_t usartBufferCount(SerialPort_TypeDef* port);
// Checks to see if the ring buffer is empty (head = tail)
static INLINE uint8_t _isBufferEmpty(volatile RingBuffer_TypeDef* buffer) {
return buffer->head == buffer->tail;
24c: 72617375 rsbvc r7, r1, #-738197503 ; 0xd4000001
250: 61760074 cmnvs r6, r4, ror r0
}
// Waits for a byte in the given port's RX buffer
// This does not happen during init, so it is OK to use scheduler functions
static void _waitForByte(SerialPort_TypeDef* port) {
while (_isBufferEmpty(&(port->rx)))
254: 73696c5f cmnvc r9, #24320 ; 0x5f00
258: 636c0074 cmnvs ip, #116 ; 0x74
25c: 75685364 strbvc r5, [r8, #-868]! ; 0xfffffc9c
semaphoreTake(port->readLock, MAX_DELAY);
260: 776f6474 ; <UNDEFINED> instruction: 0x776f6474
264: 6572006e ldrbvs r0, [r2, #-110]! ; 0xffffff92
268: 6f4c6461 svcvs 0x004c6461
26c: 6c006b63 stcvs 11, cr6, [r0], {99} ; 0x63
// File system check
return fsRead(stream);
#else
return EOF;
#endif
}
270: 20676e6f rsbcs r6, r7, pc, ror #28
// Take byte off the tail
return (int)_pullByte(&(ser->rx)) & 0xFF;
}
#ifndef NO_FILESYSTEM
// File system check
return fsRead(stream);
274: 676e6f6c strbvs r6, [lr, -ip, ror #30]!
return ((buffer->tail + 1) & _USART_MAX) == buffer->head;
}
// Removes a byte from the head of the given buffer
static char _pullByte(volatile RingBuffer_TypeDef* buffer) {
uint8_t head = buffer->head; char value;
278: 746e6920 strbtvc r6, [lr], #-2336 ; 0xfffff6e0
27c: 69727700 ldmdbvs r2!, {r8, r9, sl, ip, sp, lr}^
280: 66006574 ; <UNDEFINED> instruction: 0x66006574
284: 666f4573 ; <UNDEFINED> instruction: 0x666f4573
value = buffer->buffer[head];
buffer->head = (head + 1) & _USART_MAX;
288: 53464300 movtpl r4, #25344 ; 0x6300
28c: 63660052 cmnvs r6, #82 ; 0x52
}
// Removes a byte from the head of the given buffer
static char _pullByte(volatile RingBuffer_TypeDef* buffer) {
uint8_t head = buffer->head; char value;
value = buffer->buffer[head];
290: 746e756f strbtvc r7, [lr], #-1391 ; 0xfffffa91
// File system check
return fsRead(stream);
#else
return EOF;
#endif
}
294: 61775f00 cmnvs r7, r0, lsl #30
298: 6f467469 svcvs 0x00467469
29c: 61705372 cmnvs r0, r2, ror r3
*ptr = '\0';
return str;
}
// fputc - Write a character to the specified stream
int fputc(int value, FILE *stream) {
2a0: 5f006563 svcpl 0x00006563
uint32_t snew = (uint32_t)stream - 1;
if (snew < 3) {
2a4: 0070615f rsbseq r6, r0, pc, asr r1
2a8: 5064636c rsbpl r6, r4, ip, ror #6
SerialPort_TypeDef *ser = &usart[snew];
2ac: 0074726f rsbseq r7, r4, pc, ror #4
2b0: 6978655f ldmdbvs r8!, {r0, r1, r2, r3, r4, r6, r8, sl, sp, lr}^
return buffer->head == buffer->tail;
}
// Checks to see if the ring buffer is full (tail + 1 = head)
static INLINE uint8_t _isBufferFull(volatile RingBuffer_TypeDef* buffer) {
return ((buffer->tail + 1) & _USART_MAX) == buffer->head;
2b4: 69724374 ldmdbvs r2!, {r2, r4, r5, r6, r8, r9, lr}^
2b8: 61636974 smcvs 13972 ; 0x3694
}
// Waits for space in the given port's TX buffer
// This happens infrequently, so simply sleep-waiting is acceptable
static void _waitForSpace(SerialPort_TypeDef* port) {
while (_isBufferFull(&(port->tx)))
2bc: 6973006c ldmdbvs r3!, {r2, r3, r5, r6}^
_yield();
2c0: 5300657a movwpl r6, #1402 ; 0x57a
2c4: 70616d65 rsbvc r6, r1, r5, ror #26
return value;
}
// Queues a byte onto the tail of the given buffer
static void _queueByte(volatile RingBuffer_TypeDef* buffer, char value) {
uint8_t tail = buffer->tail;
2c8: 65726f68 ldrbvs r6, [r2, #-3944]! ; 0xfffff098
2cc: 44434c00 strbmi r4, [r3], #-3072 ; 0xfffff400
2d0: 7079545f rsbsvc r5, r9, pc, asr r4
2d4: 66654465 strbtvs r4, [r5], -r5, ror #8
buffer->buffer[tail] = value;
2d8: 52736600 rsbspl r6, r3, #0, 12
uint32_t snew = (uint32_t)stream - 1;
if (snew < 3) {
SerialPort_TypeDef *ser = &usart[snew];
_waitForSpace(ser);
// Jam a byte onto the head
_queueByte(&(ser->tx), (char)value);
2dc: 00646165 rsbeq r6, r4, r5, ror #2
// Queues a byte onto the tail of the given buffer
static void _queueByte(volatile RingBuffer_TypeDef* buffer, char value) {
uint8_t tail = buffer->tail;
buffer->buffer[tail] = value;
buffer->tail = (tail + 1) & _USART_MAX;
2e0: 74656766 strbtvc r6, [r5], #-1894 ; 0xfffff89a
}
// Queues a byte onto the tail of the given buffer
static void _queueByte(volatile RingBuffer_TypeDef* buffer, char value) {
uint8_t tail = buffer->tail;
buffer->buffer[tail] = value;
2e4: 67660063 strbvs r0, [r6, -r3, rrx]!
if (snew < 3) {
SerialPort_TypeDef *ser = &usart[snew];
_waitForSpace(ser);
// Jam a byte onto the head
_queueByte(&(ser->tx), (char)value);
if (snew == 0)
2e8: 00737465 rsbseq r7, r3, r5, ror #8
// Enable USART2 TXE interrupts
USART2->CR1 |= USART_CR1_TXEIE;
2ec: 73677261 cmnvc r7, #268435462 ; 0x10000006
else if (snew == 1)
// Enable USART3 TXE interrupts
USART3->CR1 |= USART_CR1_TXEIE;
2f0: 6e697500 cdpvs 5, 6, cr7, cr9, cr0, {0}
else if (snew == 2)
// Enable USART1 TXE interrupts
USART1->CR1 |= USART_CR1_TXEIE;
2f4: 5f363174 svcpl 0x00363174
else
// File system check
return fsWrite(stream, value);
#endif
return value;
}
2f8: 795f0074 ldmdbvc pc, {r2, r4, r5, r6}^ ; <UNPREDICTABLE>
else if (snew == 1)
// Enable USART3 TXE interrupts
USART3->CR1 |= USART_CR1_TXEIE;
else if (snew == 2)
// Enable USART1 TXE interrupts
USART1->CR1 |= USART_CR1_TXEIE;
2fc: 646c6569 strbtvs r6, [ip], #-1385 ; 0xfffffa97
300: 464d4d00 strbmi r4, [sp], -r0, lsl #26
}
#ifndef NO_FILESYSTEM
else
// File system check
return fsWrite(stream, value);
304: 52005241 andpl r5, r0, #268435460 ; 0x10000004
#endif
return value;
}
308: 52455345 subpl r5, r5, #335544321 ; 0x14000001
USART1->CR1 |= USART_CR1_TXEIE;
}
#ifndef NO_FILESYSTEM
else
// File system check
return fsWrite(stream, value);
30c: 30444556 subcc r4, r4, r6, asr r5
310: 53455200 movtpl r5, #20992 ; 0x5200
314: 45565245 ldrbmi r5, [r6, #-581] ; 0xfffffdbb
318: 53003144 movwpl r3, #324 ; 0x144
31c: 52534348 subspl r4, r3, #72, 6 ; 0x20000001
320: 53455200 movtpl r5, #20992 ; 0x5200
#endif
return value;
}
// fread - Read data from stream
size_t fread(void *ptr, size_t size, size_t count, FILE *stream) {
324: 45565245 ldrbmi r5, [r6, #-581] ; 0xfffffdbb
328: 52003344 andpl r3, r0, #68, 6 ; 0x10000001
char *memory = (char *)ptr;
size_t write = 0; int read;
for (uint32_t i = 0; i < (size * count); i++)
32c: 52455345 subpl r5, r5, #335544321 ; 0x14000001
330: 34444556 strbcc r4, [r4], #-1366 ; 0xfffffaaa
// Write as many as we can, break if we fail
if ((read = fgetc(stream)) != EOF) {
334: 53455200 movtpl r5, #20992 ; 0x5200
338: 45565245 ldrbmi r5, [r6, #-581] ; 0xfffffdbb
33c: 52003544 andpl r3, r0, #68, 10 ; 0x11000000
340: 52455345 subpl r5, r5, #335544321 ; 0x14000001
*memory++ = (char)read;
write++;
344: 36444556 ; <UNDEFINED> instruction: 0x36444556
} else
break;
return write;
}
348: 6f687300 svcvs 0x00687300
// fwrite - Write data to stream
size_t fwrite(const void *ptr, size_t size, size_t count, FILE *stream) {
34c: 69207472 stmdbvs r0!, {r1, r4, r5, r6, sl, ip, sp, lr}
350: 6c00746e cfstrsvs mvf7, [r0], {110} ; 0x6e
const char *memory = (const char *)ptr;
size_t write = 0;
for (uint32_t i = 0; i < (size * count); i++)
354: 20676e6f rsbcs r6, r7, pc, ror #28
358: 00746e69 rsbseq r6, r4, r9, ror #28
// Write as many as we can, break if we fail
if (fputc((int)(*memory++), stream) != EOF)
35c: 61657266 cmnvs r5, r6, ror #4
360: 5f5f0064 svcpl 0x005f0064
364: 62616e65 rsbvs r6, r1, #1616 ; 0x650
368: 695f656c ldmdbvs pc, {r2, r3, r5, r6, r8, sl, sp, lr}^ ; <UNPREDICTABLE>
write++;
36c: 5f007172 svcpl 0x00007172
else
break;
return write;
}
370: 6c6c7570 cfstr64vs mvdx7, [ip], #-448 ; 0xfffffe40
// getchar - Gets a character from the serial PC communication buffer; blocks until read
int getchar() {
return fgetc(stdin);
374: 65747942 ldrbvs r7, [r4, #-2370]! ; 0xfffff6be
378: 755f5f00 ldrbvc r5, [pc, #-3840] ; fffff480 <usart+0xfffff438>
}
// putchar - Write a character to the serial PC communication buffer
int putchar(int value) {
return fputc(value, stdout);
37c: 38746e69 ldmdacc r4!, {r0, r3, r5, r6, r9, sl, fp, sp, lr}^
}
// ISR_USART1 - Buffered character I/O handler for debug communications
void ISR_USART1() {
380: 5f00745f svcpl 0x0000745f
384: 75427369 strbvc r7, [r2, #-873] ; 0xfffffc97
388: 72656666 rsbvc r6, r5, #106954752 ; 0x6600000
38c: 6c6c7546 cfstr64vs mvdx7, [ip], #-280 ; 0xfffffee8
char value;
bool cs = false;
390: 41464200 mrsmi r4, (UNDEF: 102)
SerialPort_TypeDef *ser = &usart[2];
if (USART1->SR & USART_SR_RXNE) {
394: 54560052 ldrbpl r0, [r6], #-82 ; 0xffffffae
398: 5f00524f svcpl 0x0000524f
return buffer->head == buffer->tail;
}
// Checks to see if the ring buffer is full (tail + 1 = head)
static INLINE uint8_t _isBufferFull(volatile RingBuffer_TypeDef* buffer) {
return ((buffer->tail + 1) & _USART_MAX) == buffer->head;
39c: 5f61765f svcpl 0x0061765f
3a0: 7473696c ldrbtvc r6, [r3], #-2412 ; 0xfffff694
3a4: 61737500 cmnvs r3, r0, lsl #10
3a8: 6e497472 mcrvs 4, 2, r7, cr9, cr2, {3}
3ac: 73007469 movwvc r7, #1129 ; 0x469
SerialPort_TypeDef *ser = &usart[2];
if (USART1->SR & USART_SR_RXNE) {
// Read to clear the flag
value = (char)USART1->DR;
// Buffer it up, if it's not full to the brim
if (!_isBufferFull(&(ser->rx)))
3b0: 74657a69 strbtvc r7, [r5], #-2665 ; 0xfffff597
return value;
}
// Queues a byte onto the tail of the given buffer
static void _queueByte(volatile RingBuffer_TypeDef* buffer, char value) {
uint8_t tail = buffer->tail;
3b4: 00657079 rsbeq r7, r5, r9, ror r0
3b8: 52534349 subspl r4, r3, #603979777 ; 0x24000001
buffer->buffer[tail] = value;
buffer->tail = (tail + 1) & _USART_MAX;
3bc: 6e6f6c00 cdpvs 12, 6, cr6, cr15, cr0, {0}
3c0: 6e752067 cdpvs 0, 7, cr2, cr5, cr7, {3}
}
// Queues a byte onto the tail of the given buffer
static void _queueByte(volatile RingBuffer_TypeDef* buffer, char value) {
uint8_t tail = buffer->tail;
buffer->buffer[tail] = value;
3c4: 6e676973 mcrvs 9, 3, r6, cr7, cr3, {3}
buffer->tail = (tail + 1) & _USART_MAX;
3c8: 69206465 stmdbvs r0!, {r0, r2, r5, r6, sl, sp, lr}
value = (char)USART1->DR;
// Buffer it up, if it's not full to the brim
if (!_isBufferFull(&(ser->rx)))
_queueByte(&(ser->rx), value);
// Notify any receivers
semaphoreGiveISR(ser->readLock, &cs);
3cc: 6200746e andvs r7, r0, #1845493760 ; 0x6e000000
3d0: 6f747475 svcvs 0x00747475
3d4: 7000736e andvc r7, r0, lr, ror #6
}
if (USART1->SR & USART_SR_TXE) {
3d8: 0074726f rsbseq r7, r4, pc, ror #4
3dc: 5f424353 svcpl 0x00424353
// Prototype this
uint32_t usartBufferCount(SerialPort_TypeDef* port);
// Checks to see if the ring buffer is empty (head = tail)
static INLINE uint8_t _isBufferEmpty(volatile RingBuffer_TypeDef* buffer) {
return buffer->head == buffer->tail;
3e0: 65707954 ldrbvs r7, [r0, #-2388]! ; 0xfffff6ac
3e4: 00666544 rsbeq r6, r6, r4, asr #10
_queueByte(&(ser->rx), value);
// Notify any receivers
semaphoreGiveISR(ser->readLock, &cs);
}
if (USART1->SR & USART_SR_TXE) {
if (_isBufferEmpty(&(ser->tx)))
3e8: 6f6d656d svcvs 0x006d656d
// Nothing to send, disable interrupt
USART1->CR1 &= ~USART_CR1_TXEIE;
3ec: 75007972 strvc r7, [r0, #-2418] ; 0xfffff68e
3f0: 6769736e strbvs r7, [r9, -lr, ror #6]!
3f4: 2064656e rsbcs r6, r4, lr, ror #10
3f8: 72616863 rsbvc r6, r1, #6488064 ; 0x630000
return ((buffer->tail + 1) & _USART_MAX) == buffer->head;
}
// Removes a byte from the head of the given buffer
static char _pullByte(volatile RingBuffer_TypeDef* buffer) {
uint8_t head = buffer->head; char value;
3fc: 57736600 ldrbpl r6, [r3, -r0, lsl #12]!
value = buffer->buffer[head];
400: 65746972 ldrbvs r6, [r4, #-2418]! ; 0xfffff68e
404: 755f5f00 ldrbvc r5, [pc, #-3840] ; fffff50c <usart+0xfffff4c4>
buffer->head = (head + 1) & _USART_MAX;
408: 33746e69 cmncc r4, #1680 ; 0x690
40c: 00745f32 rsbseq r5, r4, r2, lsr pc
if (_isBufferEmpty(&(ser->tx)))
// Nothing to send, disable interrupt
USART1->CR1 &= ~USART_CR1_TXEIE;
else {
value = _pullByte(&(ser->tx));
USART1->DR = value;
410: 4964636c stmdbmi r4!, {r2, r3, r5, r6, r8, r9, sp, lr}^
414: 7865646e stmdavc r5!, {r1, r2, r3, r5, r6, sl, sp, lr}^
}
}
if (cs)
418: 64636c00 strbtvs r6, [r3], #-3072 ; 0xfffff400
41c: 74747542 ldrbtvc r7, [r4], #-1346 ; 0xfffffabe
420: 72506e6f subsvc r6, r0, #1776 ; 0x6f0
424: 7365636f cmnvc r5, #-1140850687 ; 0xbc000001
_taskYield();
}
428: 65670073 strbvs r0, [r7, #-115]! ; 0xffffff8d
42c: 61686374 smcvs 34356 ; 0x8634
430: 4e470072 mcrmi 0, 2, r0, cr7, cr2, {3}
434: 20432055 subcs r2, r3, r5, asr r0
438: 2e392e34 mrccs 14, 1, r2, cr9, cr4, {1}
count = 0;
lcd[index].state = count;
}
// ISR_USART2 - Buffered character I/O handler for UART port 1
void ISR_USART2() {
43c: 30322033 eorscc r2, r2, r3, lsr r0
440: 35303531 ldrcc r3, [r0, #-1329]! ; 0xfffffacf
444: 28203932 stmdacs r0!, {r1, r4, r5, r8, fp, ip, sp}
448: 72657270 rsbvc r7, r5, #112, 4
char value;
bool cs = false;
44c: 61656c65 cmnvs r5, r5, ror #24
450: 20296573 eorcs r6, r9, r3, ror r5
SerialPort_TypeDef *ser = &usart[0];
if (USART2->SR & USART_SR_RXNE) {
454: 68746d2d ldmdavs r4!, {r0, r2, r3, r5, r8, sl, fp, sp, lr}^
// Read to clear the flag
value = (char)USART2->DR;
if (lcd[0].flags & LCD_ACTIVE)
458: 20626d75 rsbcs r6, r2, r5, ror sp
45c: 70636d2d rsbvc r6, r3, sp, lsr #26
460: 6f633d75 svcvs 0x00633d75
lcdButtonProcess(value, 0);
464: 78657472 stmdavc r5!, {r1, r4, r5, r6, sl, ip, sp, lr}^
468: 20336d2d eorscs r6, r3, sp, lsr #26
return buffer->head == buffer->tail;
}
// Checks to see if the ring buffer is full (tail + 1 = head)
static INLINE uint8_t _isBufferFull(volatile RingBuffer_TypeDef* buffer) {
return ((buffer->tail + 1) & _USART_MAX) == buffer->head;
46c: 696c6d2d stmdbvs ip!, {r0, r2, r3, r5, r8, sl, fp, sp, lr}^
470: 656c7474 strbvs r7, [ip, #-1140]! ; 0xfffffb8c
474: 646e652d strbtvs r6, [lr], #-1325 ; 0xfffffad3
478: 206e6169 rsbcs r6, lr, r9, ror #2
value = (char)USART2->DR;
if (lcd[0].flags & LCD_ACTIVE)
lcdButtonProcess(value, 0);
else {
// Buffer it up, if it's not full to the brim
if (!_isBufferFull(&(ser->rx)))
47c: 2d20672d stccs 7, cr6, [r0, #-180]! ; 0xffffff4c
return value;
}
// Queues a byte onto the tail of the given buffer
static void _queueByte(volatile RingBuffer_TypeDef* buffer, char value) {
uint8_t tail = buffer->tail;
480: 2d20734f stccs 3, cr7, [r0, #-316]! ; 0xfffffec4
buffer->buffer[tail] = value;
484: 3d647473 cfstrdcc mvd7, [r4, #-460]! ; 0xfffffe34
buffer->tail = (tail + 1) & _USART_MAX;
488: 39756e67 ldmdbcc r5!, {r0, r1, r2, r5, r6, r9, sl, fp, sp, lr}^
}
// Queues a byte onto the tail of the given buffer
static void _queueByte(volatile RingBuffer_TypeDef* buffer, char value) {
uint8_t tail = buffer->tail;
buffer->buffer[tail] = value;
48c: 662d2039 ; <UNDEFINED> instruction: 0x662d2039
buffer->tail = (tail + 1) & _USART_MAX;
490: 636e7566 cmnvs lr, #427819008 ; 0x19800000
else {
// Buffer it up, if it's not full to the brim
if (!_isBufferFull(&(ser->rx)))
_queueByte(&(ser->rx), value);
// Notify any receivers
semaphoreGiveISR(ser->readLock, &cs);
494: 6e6f6974 mcrvs 9, 3, r6, cr15, cr4, {3}
498: 6365732d cmnvs r5, #-1275068416 ; 0xb4000000
49c: 6e6f6974 mcrvs 9, 3, r6, cr15, cr4, {3}
}
}
if (USART2->SR & USART_SR_TXE) {
4a0: 662d2073 ; <UNDEFINED> instruction: 0x662d2073
4a4: 6e676973 mcrvs 9, 3, r6, cr7, cr3, {3}
// Prototype this
uint32_t usartBufferCount(SerialPort_TypeDef* port);
// Checks to see if the ring buffer is empty (head = tail)
static INLINE uint8_t _isBufferEmpty(volatile RingBuffer_TypeDef* buffer) {
return buffer->head == buffer->tail;
4a8: 632d6465 ; <UNDEFINED> instruction: 0x632d6465
4ac: 20726168 rsbscs r6, r2, r8, ror #2
4b0: 6d6f662d stclvs 6, cr6, [pc, #-180]! ; 404 <.debug_str+0x404>
// Notify any receivers
semaphoreGiveISR(ser->readLock, &cs);
}
}
if (USART2->SR & USART_SR_TXE) {
if (_isBufferEmpty(&(ser->tx)))
4b4: 662d7469 strtvs r7, [sp], -r9, ror #8
// Nothing to send, disable interrupt
USART2->CR1 &= ~USART_CR1_TXEIE;
4b8: 656d6172 strbvs r6, [sp, #-370]! ; 0xfffffe8e
4bc: 696f702d stmdbvs pc!, {r0, r2, r3, r5, ip, sp, lr}^ ; <UNPREDICTABLE>
4c0: 7265746e rsbvc r7, r5, #1845493760 ; 0x6e000000
return ((buffer->tail + 1) & _USART_MAX) == buffer->head;
}
// Removes a byte from the head of the given buffer
static char _pullByte(volatile RingBuffer_TypeDef* buffer) {
uint8_t head = buffer->head; char value;
4c4: 73662d20 cmnvc r6, #32, 26 ; 0x800
4c8: 6c676e69 stclvs 14, cr6, [r7], #-420 ; 0xfffffe5c
value = buffer->buffer[head];
4cc: 72702d65 rsbsvc r2, r0, #6464 ; 0x1940
buffer->head = (head + 1) & _USART_MAX;
4d0: 73696365 cmnvc r9, #-1811939327 ; 0x94000001
4d4: 2d6e6f69 stclcs 15, cr6, [lr, #-420]! ; 0xfffffe5c
4d8: 736e6f63 cmnvc lr, #396 ; 0x18c
if (_isBufferEmpty(&(ser->tx)))
// Nothing to send, disable interrupt
USART2->CR1 &= ~USART_CR1_TXEIE;
else {
value = _pullByte(&(ser->tx));
USART2->DR = value;
4dc: 746e6174 strbtvc r6, [lr], #-372 ; 0xfffffe8c
}
}
if (cs)
4e0: 73695f00 cmnvc r9, #0, 30
4e4: 66667542 strbtvs r7, [r6], -r2, asr #10
4e8: 6d457265 sfmvs f7, 2, [r5, #-404] ; 0xfffffe6c
4ec: 00797470 rsbseq r7, r9, r0, ror r4
_taskYield();
}
4f0: 6c696174 stfvse f6, [r9], #-464 ; 0xfffffe30
4f4: 6f656600 svcvs 0x00656600
4f8: 74730066 ldrbtvc r0, [r3], #-102 ; 0xffffff9a
4fc: 00657461 rsbeq r7, r5, r1, ror #8
500: 654c7366 strbvs r7, [ip, #-870] ; 0xfffffc9a
504: 6c007466 cfstrsvs mvf7, [r0], {102} ; 0x66
// ISR_USART3 - Buffered character I/O handler for UART port 2
void ISR_USART3() {
508: 65526463 ldrbvs r6, [r2, #-1123] ; 0xfffffb9d
50c: 75426461 strbvc r6, [r2, #-1121] ; 0xfffffb9f
510: 6e6f7474 mcrvs 4, 3, r7, cr15, cr4, {3}
514: 755f0073 ldrbvc r0, [pc, #-115] ; 4a9 <.debug_str+0x4a9>
char value;
bool cs = false;
518: 74726173 ldrbtvc r6, [r2], #-371 ; 0xfffffe8d
SerialPort_TypeDef *ser = &usart[1];
if (USART3->SR & USART_SR_RXNE) {
51c: 66667542 strbtvs r7, [r6], -r2, asr #10
520: 6e497265 cdpvs 2, 4, cr7, cr9, cr5, {3}
// Read to clear the flag
value = (char)USART3->DR;
if (lcd[1].flags & LCD_ACTIVE)
524: 66007469 strvs r7, [r0], -r9, ror #8
528: 74697277 strbtvc r7, [r9], #-631 ; 0xfffffd89
52c: 636c0065 cmnvs ip, #101 ; 0x65
lcdButtonProcess(value, 1);
530: 656c4364 strbvs r4, [ip, #-868]! ; 0xfffffc9c
534: 73007261 movwvc r7, #609 ; 0x261
538: 656e6769 strbvs r6, [lr, #-1897]! ; 0xfffff897
return buffer->head == buffer->tail;
}
// Checks to see if the ring buffer is full (tail + 1 = head)
static INLINE uint8_t _isBufferFull(volatile RingBuffer_TypeDef* buffer) {
return ((buffer->tail + 1) & _USART_MAX) == buffer->head;
53c: 68632064 stmdavs r3!, {r2, r5, r6, sp}^
540: 66007261 strvs r7, [r0], -r1, ror #4
544: 44636172 strbtmi r6, [r3], #-370 ; 0xfffffe8e
value = (char)USART3->DR;
if (lcd[1].flags & LCD_ACTIVE)
lcdButtonProcess(value, 1);
else {
// Buffer it up, if it's not full to the brim
if (!_isBufferFull(&(ser->rx)))
548: 73007669 movwvc r7, #1641 ; 0x669
return value;
}
// Queues a byte onto the tail of the given buffer
static void _queueByte(volatile RingBuffer_TypeDef* buffer, char value) {
uint8_t tail = buffer->tail;
54c: 74726f68 ldrbtvc r6, [r2], #-3944 ; 0xfffff098
550: 736e7520 cmnvc lr, #32, 10 ; 0x8000000
buffer->buffer[tail] = value;
buffer->tail = (tail + 1) & _USART_MAX;
554: 656e6769 strbvs r6, [lr, #-1897]! ; 0xfffff897
558: 6e692064 cdpvs 0, 6, cr2, cr9, cr4, {3}
}
// Queues a byte onto the tail of the given buffer
static void _queueByte(volatile RingBuffer_TypeDef* buffer, char value) {
uint8_t tail = buffer->tail;
buffer->buffer[tail] = value;
55c: 73750074 cmnvc r5, #116 ; 0x74
buffer->tail = (tail + 1) & _USART_MAX;
560: 42747261 rsbsmi r7, r4, #268435462 ; 0x10000006
else {
// Buffer it up, if it's not full to the brim
if (!_isBufferFull(&(ser->rx)))
_queueByte(&(ser->rx), value);
// Notify any receivers
semaphoreGiveISR(ser->readLock, &cs);
564: 65666675 strbvs r6, [r6, #-1653]! ; 0xfffff98b
568: 756f4372 strbvc r4, [pc, #-882]! ; 1fe <.debug_str+0x1fe>
56c: 7400746e strvc r7, [r0], #-1134 ; 0xfffffb92
}
}
if (USART3->SR & USART_SR_TXE) {
570: 6c61746f cfstrdvs mvd7, [r1], #-444 ; 0xfffffe44
574: 73654d00 cmnvc r5, #0, 26
// Prototype this
uint32_t usartBufferCount(SerialPort_TypeDef* port);
// Checks to see if the ring buffer is empty (head = tail)
static INLINE uint8_t _isBufferEmpty(volatile RingBuffer_TypeDef* buffer) {
return buffer->head == buffer->tail;
578: 65676173 strbvs r6, [r7, #-371]! ; 0xfffffe8d
57c: 75657551 strbvc r7, [r5, #-1361]! ; 0xfffffaaf
// Notify any receivers
semaphoreGiveISR(ser->readLock, &cs);
}
}
if (USART3->SR & USART_SR_TXE) {
if (_isBufferEmpty(&(ser->tx)))
580: 53490065 movtpl r0, #36965 ; 0x9065
// Nothing to send, disable interrupt
USART3->CR1 &= ~USART_CR1_TXEIE;
584: 52005241 andpl r5, r0, #268435460 ; 0x10000004
588: 52455345 subpl r5, r5, #335544321 ; 0x14000001
58c: 32444556 subcc r4, r4, #360710144 ; 0x15800000
590: 4c494600 mcrrmi 6, 0, r4, r9, cr0
return ((buffer->tail + 1) & _USART_MAX) == buffer->head;
}
// Removes a byte from the head of the given buffer
static char _pullByte(volatile RingBuffer_TypeDef* buffer) {
uint8_t head = buffer->head; char value;
594: 6f630045 svcvs 0x00630045
value = buffer->buffer[head];
598: 632e6d6d ; <UNDEFINED> instruction: 0x632e6d6d
59c: 6e737600 cdpvs 6, 7, cr7, cr3, cr0, {0}
buffer->head = (head + 1) & _USART_MAX;
5a0: 6e697270 mcrvs 2, 3, r7, cr9, cr0, {3}
5a4: 73006674 movwvc r6, #1652 ; 0x674
if (_isBufferEmpty(&(ser->tx)))
// Nothing to send, disable interrupt
USART3->CR1 &= ~USART_CR1_TXEIE;
else {
value = _pullByte(&(ser->tx));
USART3->DR = value;
5a8: 61657274 smcvs 22308 ; 0x5724
5ac: 7375006d cmnvc r5, #109 ; 0x6d
}
}
if (cs)
5b0: 46747261 ldrbtmi r7, [r4], -r1, ror #4
5b4: 6873756c ldmdavs r3!, {r2, r3, r5, r6, r8, sl, ip, sp, lr}^
5b8: 66667542 strbtvs r7, [r6], -r2, asr #10
5bc: 00737265 rsbseq r7, r3, r5, ror #4
_taskYield();
}
5c0: 74757066 ldrbtvc r7, [r5], #-102 ; 0xffffff9a
5c4: Address 0x00000000000005c4 is out of bounds.
Disassembly of section .comment:
00000000 <.comment>:
0: 43434700 movtmi r4, #14080 ; 0x3700
4: 3128203a ; <UNDEFINED> instruction: 0x3128203a
8: 2e343a35 mrccs 10, 1, r3, cr4, cr5, {1}
c: 2b332e39 blcs ccb8f8 <usart+0xccb8b0>
10: 326e7673 rsbcc r7, lr, #120586240 ; 0x7300000
14: 37313133 ; <UNDEFINED> instruction: 0x37313133
18: 29312d37 ldmdbcs r1!, {r0, r1, r2, r4, r5, r8, sl, fp, sp}
1c: 392e3420 stmdbcc lr!, {r5, sl, ip, sp}
20: 3220332e eorcc r3, r0, #-1207959552 ; 0xb8000000
24: 30353130 eorscc r3, r5, r0, lsr r1
28: 20393235 eorscs r3, r9, r5, lsr r2
2c: 65727028 ldrbvs r7, [r2, #-40]! ; 0xffffffd8
30: 656c6572 strbvs r6, [ip, #-1394]! ; 0xfffffa8e
34: 29657361 stmdbcs r5!, {r0, r5, r6, r8, r9, ip, sp, lr}^
...
Disassembly of section .debug_frame:
00000000 <.debug_frame>:
0: 0000000c andeq r0, r0, ip
4: ffffffff ; <UNDEFINED> instruction: 0xffffffff
8: 7c020001 stcvc 0, cr0, [r2], {1}
c: 000d0c0e andeq r0, sp, lr, lsl #24
10: 0000000c andeq r0, r0, ip
...
14: R_ARM_ABS32 .debug_frame
18: R_ARM_ABS32 .text.lcdButtonProcess
1c: 0000005c andeq r0, r0, ip, asr r0
20: 00000024 andeq r0, r0, r4, lsr #32
...
24: R_ARM_ABS32 .debug_frame
28: R_ARM_ABS32 .text.fgetc
2c: 00000064 andeq r0, r0, r4, rrx
30: 83100e41 tsthi r0, #1040 ; 0x410
34: 85038404 strhi r8, [r3, #-1028] ; 0xfffffbfc
38: 5b018e02 blpl 63848 <usart+0x63800>
3c: c4c5ce0a strbgt ip, [r5], #3594 ; 0xe0a
40: 42000ec3 andmi r0, r0, #3120 ; 0xc30
44: 0000000b andeq r0, r0, fp
48: 00000020 andeq r0, r0, r0, lsr #32
...
4c: R_ARM_ABS32 .debug_frame
50: R_ARM_ABS32 .text.fputc
54: 00000084 andeq r0, r0, r4, lsl #1
58: 84100e41 ldrhi r0, [r0], #-3649 ; 0xfffff1bf
5c: 86038504 strhi r8, [r3], -r4, lsl #10
60: 75018e02 strvc r8, [r1, #-3586] ; 0xfffff1fe
64: c4c5c6ce strbgt ip, [r5], #1742 ; 0x6ce
68: 0000000e andeq r0, r0, lr
6c: 0000001c andeq r0, r0, ip, lsl r0
...
70: R_ARM_ABS32 .debug_frame
74: R_ARM_ABS32 .text.fread
78: 00000028 andeq r0, r0, r8, lsr #32
7c: 83180e41 tsthi r8, #1040 ; 0x410
80: 85058406 strhi r8, [r5, #-1030] ; 0xfffffbfa
84: 87038604 strhi r8, [r3, -r4, lsl #12]
88: 00018e02 andeq r8, r1, r2, lsl #28
8c: 0000001c andeq r0, r0, ip, lsl r0
...
90: R_ARM_ABS32 .debug_frame
94: R_ARM_ABS32 .text.fwrite
98: 00000028 andeq r0, r0, r8, lsr #32
9c: 83180e41 tsthi r8, #1040 ; 0x410
a0: 85058406 strhi r8, [r5, #-1030] ; 0xfffffbfa
a4: 87038604 strhi r8, [r3, -r4, lsl #12]
a8: 00018e02 andeq r8, r1, r2, lsl #28
ac: 0000000c andeq r0, r0, ip
...
b0: R_ARM_ABS32 .debug_frame
b4: R_ARM_ABS32 .text.getchar
b8: 00000006 andeq r0, r0, r6
bc: 0000000c andeq r0, r0, ip
...
c0: R_ARM_ABS32 .debug_frame
c4: R_ARM_ABS32 .text.putchar
c8: 00000006 andeq r0, r0, r6
cc: 00000024 andeq r0, r0, r4, lsr #32
...
d0: R_ARM_ABS32 .debug_frame
d4: R_ARM_ABS32 .text.ISR_USART1
d8: 000000bc strheq r0, [r0], -ip
dc: 000d0941 andeq r0, sp, r1, asr #18
e0: 8d080e44 stchi 14, cr0, [r8, #-272] ; 0xfffffef0
e4: 42018e02 andmi r8, r1, #2, 28
e8: 4d02100e stcmi 0, cr1, [r2, #-56] ; 0xffffffc8
ec: ce42080e cdpgt 8, 4, cr0, cr2, cr14, {0}
f0: 00000ec0 andeq r0, r0, r0, asr #29
f4: 00000024 andeq r0, r0, r4, lsr #32
...
f8: R_ARM_ABS32 .debug_frame
fc: R_ARM_ABS32 .text.ISR_USART2
100: 000000cc andeq r0, r0, ip, asr #1
104: 000d0941 andeq r0, sp, r1, asr #18
108: 8d080e44 stchi 14, cr0, [r8, #-272] ; 0xfffffef0
10c: 42018e02 andmi r8, r1, #2, 28
110: 5402100e strpl r1, [r2], #-14
114: ce42080e cdpgt 8, 4, cr0, cr2, cr14, {0}
118: 00000ec0 andeq r0, r0, r0, asr #29
11c: 00000024 andeq r0, r0, r4, lsr #32
...
120: R_ARM_ABS32 .debug_frame
124: R_ARM_ABS32 .text.ISR_USART3
128: 000000cc andeq r0, r0, ip, asr #1
12c: 000d0941 andeq r0, sp, r1, asr #18
130: 8d080e44 stchi 14, cr0, [r8, #-272] ; 0xfffffef0
134: 42018e02 andmi r8, r1, #2, 28
138: 5502100e strpl r1, [r2, #-14]
13c: ce42080e cdpgt 8, 4, cr0, cr2, cr14, {0}
140: 00000ec0 andeq r0, r0, r0, asr #29
144: 0000000c andeq r0, r0, ip
...
148: R_ARM_ABS32 .debug_frame
14c: R_ARM_ABS32 .text.lcdReadButtons
150: 0000002c andeq r0, r0, ip, lsr #32
154: 0000000c andeq r0, r0, ip
...
158: R_ARM_ABS32 .debug_frame
15c: R_ARM_ABS32 .text.lcdSetBacklight
160: 00000028 andeq r0, r0, r8, lsr #32
164: 00000028 andeq r0, r0, r8, lsr #32
...
168: R_ARM_ABS32 .debug_frame
16c: R_ARM_ABS32 .text._lcdDump
170: 000000a8 andeq r0, r0, r8, lsr #1
174: 84180e43 ldrhi r0, [r8], #-3651 ; 0xfffff1bd
178: 86058506 strhi r8, [r5], -r6, lsl #10
17c: 88038704 stmdahi r3, {r2, r8, r9, sl, pc}
180: 02018e02 andeq r8, r1, #2, 28
184: c8ce0a49 stmiagt lr, {r0, r3, r6, r9, fp}^
188: c4c5c6c7 strbgt ip, [r5], #1735 ; 0x6c7
18c: 0b43000e bleq 10c01cc <usart+0x10c0184>
190: 00000014 andeq r0, r0, r4, lsl r0
...
194: R_ARM_ABS32 .debug_frame
198: R_ARM_ABS32 .text.lcdSetText
19c: 0000003c andeq r0, r0, ip, lsr r0
1a0: 84080e43 strhi r0, [r8], #-3651 ; 0xfffff1bd
1a4: 00018e02 andeq r8, r1, r2, lsl #28
1a8: 00000020 andeq r0, r0, r0, lsr #32
...
1ac: R_ARM_ABS32 .debug_frame
1b0: R_ARM_ABS32 .text.lcdClear
1b4: 00000020 andeq r0, r0, r0, lsr #32
1b8: 83100e41 tsthi r0, #1040 ; 0x410
1bc: 85038404 strhi r8, [r3, #-1028] ; 0xfffffbfc
1c0: 4a018e02 bmi 639d0 <usart+0x63988>
1c4: c3c4c5ce bicgt ip, r4, #864026624 ; 0x33800000
1c8: 0000000e andeq r0, r0, lr
1cc: 00000030 andeq r0, r0, r0, lsr r0
...
1d0: R_ARM_ABS32 .debug_frame
1d4: R_ARM_ABS32 .text.lcdPrint
1d8: 00000034 andeq r0, r0, r4, lsr r0
1dc: 82080e41 andhi r0, r8, #1040 ; 0x410
_taskYield();
}
// lcdButtonProcess - Processes the VEX LCD buttons
static void lcdButtonProcess(char value, uint32_t index) {
uint16_t count = lcd[index].state;
1e0: 41018302 tstmi r1, r2, lsl #6
1e4: 0584140e streq r1, [r4, #1038] ; 0x40e
// If 0xAA, set count to 1
// If 0x55, set count to 2 if count == 1
// If 0x16, set count to 3 if count == 2
if (value == (char)0xAA)
1e8: 038e0485 orreq r0, lr, #-2063597568 ; 0x85000000
_taskYield();
}
// lcdButtonProcess - Processes the VEX LCD buttons
static void lcdButtonProcess(char value, uint32_t index) {
uint16_t count = lcd[index].state;
1ec: 51300e43 teqpl r0, r3, asr #28
// If 0xAA, set count to 1
// If 0x55, set count to 2 if count == 1
// If 0x16, set count to 3 if count == 2
if (value == (char)0xAA)
count = 1;
else if (value == (char)0x55 && count == 1)
1f0: ce42140e cdpgt 4, 4, cr1, cr2, cr14, {0}
1f4: 080ec4c5 stmdaeq lr, {r0, r2, r6, r7, sl, lr, pc}
1f8: 0ec2c341 cdpeq 3, 12, cr12, cr2, cr1, {2}
count = 2;
else if (value == (char)0x16 && count == 2)
1fc: 00000000 andeq r0, r0, r0
200: 00000014 andeq r0, r0, r4, lsl r0
...
204: R_ARM_ABS32 .debug_frame
208: R_ARM_ABS32 .text.usartBufferCount
count = 3;
else if (value == (char)0x02 && count == 3)
// Size must be 2
count = 4;
else if (count == 4) {
20c: 00000030 andeq r0, r0, r0, lsr r0
lcd[index].buttons = (uint8_t)value;
210: 84080e41 strhi r0, [r8], #-3649 ; 0xfffff1bf
214: 00018e02 andeq r8, r1, r2, lsl #28
218: 0000000c andeq r0, r0, ip
...
21c: R_ARM_ABS32 .debug_frame
220: R_ARM_ABS32 .text.fcount
if (value == (char)0xAA)
count = 1;
else if (value == (char)0x55 && count == 1)
count = 2;
else if (value == (char)0x16 && count == 2)
count = 3;
224: 0000001c andeq r0, r0, ip, lsl r0
else if (value == (char)0x02 && count == 3)
// Size must be 2
count = 4;
228: 0000001c andeq r0, r0, ip, lsl r0
...
22c: R_ARM_ABS32 .debug_frame
230: R_ARM_ABS32 .text.feof
lcd[index].buttons = (uint8_t)value;
count = 0;
} else
// Ignore the checksum and any noise we pick up
count = 0;
lcd[index].state = count;
234: 00000028 andeq r0, r0, r8, lsr #32
238: 83080e41 movwhi r0, #36417 ; 0x8e41
return 1;
#endif
}
// fgetc - Read a character from the specified stream
int fgetc(FILE *stream) {
23c: 45018e02 strmi r8, [r1, #-3586] ; 0xfffff1fe
uint32_t snew = (uint32_t)stream - 1;
if (snew < 3) {
240: 0ec3ce0a cdpeq 14, 12, cr12, cr3, cr10, {0}
SerialPort_TypeDef *ser = &usart[snew];
244: 000b4200 andeq r4, fp, r0, lsl #4
248: 0000001c andeq r0, r0, ip, lsl r0
...
24c: R_ARM_ABS32 .debug_frame
250: R_ARM_ABS32 .text.fgets
}
// Waits for a byte in the given port's RX buffer
// This does not happen during init, so it is OK to use scheduler functions
static void _waitForByte(SerialPort_TypeDef* port) {
while (_isBufferEmpty(&(port->rx)))
254: 0000003a andeq r0, r0, sl, lsr r0
258: 83180e41 tsthi r8, #1040 ; 0x410
25c: 85058406 strhi r8, [r5, #-1030] ; 0xfffffbfa
semaphoreTake(port->readLock, MAX_DELAY);
260: 87038604 strhi r8, [r3, -r4, lsl #12]
264: 00018e02 andeq r8, r1, r2, lsl #28
268: 00000018 andeq r0, r0, r8, lsl r0
...
26c: R_ARM_ABS32 .debug_frame
270: R_ARM_ABS32 .text.usartBufferInit
// Take byte off the tail
return (int)_pullByte(&(ser->rx)) & 0xFF;
}
#ifndef NO_FILESYSTEM
// File system check
return fsRead(stream);
274: 00000054 andeq r0, r0, r4, asr r0
return ((buffer->tail + 1) & _USART_MAX) == buffer->head;
}
// Removes a byte from the head of the given buffer
static char _pullByte(volatile RingBuffer_TypeDef* buffer) {
uint8_t head = buffer->head; char value;
278: 83100e41 tsthi r0, #1040 ; 0x410
27c: 85038404 strhi r8, [r3, #-1028] ; 0xfffffbfc
280: 00018e02 andeq r8, r1, r2, lsl #28
284: 0000000c andeq r0, r0, ip
...
288: R_ARM_ABS32 .debug_frame
28c: R_ARM_ABS32 .text.usartFlushBuffers
value = buffer->buffer[head];
290: 0000002c andeq r0, r0, ip, lsr #32
// File system check
return fsRead(stream);
#else
return EOF;
#endif
}
294: 00000018 andeq r0, r0, r8, lsl r0
...
298: R_ARM_ABS32 .debug_frame
29c: R_ARM_ABS32 .text.usartInit
*ptr = '\0';
return str;
}
// fputc - Write a character to the specified stream
int fputc(int value, FILE *stream) {
2a0: 000000b4 strheq r0, [r0], -r4
uint32_t snew = (uint32_t)stream - 1;
if (snew < 3) {
2a4: 840c0e42 strhi r0, [ip], #-3650 ; 0xfffff1be
2a8: 8e028503 cfsh32hi mvfx8, mvfx2, #3
SerialPort_TypeDef *ser = &usart[snew];
2ac: 00000001 andeq r0, r0, r1
2b0: 00000014 andeq r0, r0, r4, lsl r0
...
2b4: R_ARM_ABS32 .debug_frame
2b8: R_ARM_ABS32 .text.lcdInit
}
// Waits for space in the given port's TX buffer
// This happens infrequently, so simply sleep-waiting is acceptable
static void _waitForSpace(SerialPort_TypeDef* port) {
while (_isBufferFull(&(port->tx)))
2bc: 00000030 andeq r0, r0, r0, lsr r0
_yield();
2c0: 84080e41 strhi r0, [r8], #-3649 ; 0xfffff1bf
2c4: 00018e02 andeq r8, r1, r2, lsl #28
return value;
}
// Queues a byte onto the tail of the given buffer
static void _queueByte(volatile RingBuffer_TypeDef* buffer, char value) {
uint8_t tail = buffer->tail;
2c8: 0000000c andeq r0, r0, ip
...
2cc: R_ARM_ABS32 .debug_frame
2d0: R_ARM_ABS32 .text.usartShutdown
2d4: 00000020 andeq r0, r0, r0, lsr #32
buffer->buffer[tail] = value;
2d8: 00000014 andeq r0, r0, r4, lsl r0
...
2dc: R_ARM_ABS32 .debug_frame
2e0: R_ARM_ABS32 .text.lcdShutdown
2e4: 00000020 andeq r0, r0, r0, lsr #32
if (snew < 3) {
SerialPort_TypeDef *ser = &usart[snew];
_waitForSpace(ser);
// Jam a byte onto the head
_queueByte(&(ser->tx), (char)value);
if (snew == 0)
2e8: 84080e41 strhi r0, [r8], #-3649 ; 0xfffff1bf
// Enable USART2 TXE interrupts
USART2->CR1 |= USART_CR1_TXEIE;
2ec: 00018e02 andeq r8, r1, r2, lsl #28
Disassembly of section .ARM.attributes:
00000000 <.ARM.attributes>:
0: 00003241 andeq r3, r0, r1, asr #4
4: 61656100 cmnvs r5, r0, lsl #2
8: 01006962 tsteq r0, r2, ror #18
c: 00000028 andeq r0, r0, r8, lsr #32
10: 726f4305 rsbvc r4, pc, #335544320 ; 0x14000000
14: 2d786574 cfldr64cs mvdx6, [r8, #-464]! ; 0xfffffe30
18: 0600334d streq r3, [r0], -sp, asr #6
1c: 094d070a stmdbeq sp, {r1, r3, r8, r9, sl}^
20: 14041202 strne r1, [r4], #-514 ; 0xfffffdfe
24: 17011501 strne r1, [r1, -r1, lsl #10]
28: 19011803 stmdbne r1, {r0, r1, fp, ip}
2c: 1e011a01 vmlane.f32 s2, s2, s2
30: Address 0x0000000000000030 is out of bounds.
encoder.o: file format elf32-littlearm
rw-r--r-- 1000/1000 15432 Oct 20 02:06 2016 encoder.o
architecture: arm, flags 0x00000011:
HAS_RELOC, HAS_SYMS
start address 0x00000000
private flags = 5000000: [Version5 EABI]
Sections:
Idx Name Size VMA LMA File off Algn
0 .text 00000000 00000000 00000000 00000034 2**1
CONTENTS, ALLOC, LOAD, READONLY, CODE
1 .data 00000000 00000000 00000000 00000034 2**0
CONTENTS, ALLOC, LOAD, DATA
2 .bss 00000000 00000000 00000000 00000034 2**0
ALLOC
3 .text.encoderGet 00000006 00000000 00000000 00000034 2**1
CONTENTS, ALLOC, LOAD, READONLY, CODE
4 .text.encoderReset 00000024 00000000 00000000 0000003c 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
5 .text.ioClearInterrupt 00000048 00000000 00000000 00000060 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
6 .text.encoderShutdown 00000040 00000000 00000000 000000a8 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
7 .text.ioSetInterrupt 00000084 00000000 00000000 000000e8 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
8 .text.encoderInit 000000cc 00000000 00000000 0000016c 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
9 .text.ISR_EXTI0 0000002c 00000000 00000000 00000238 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
10 .text.ISR_EXTI1 0000002c 00000000 00000000 00000264 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
11 .text.ISR_EXTI9_5 0000006c 00000000 00000000 00000290 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
12 .text.ISR_EXTI15_10 00000080 00000000 00000000 000002fc 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
13 .debug_info 000009a4 00000000 00000000 0000037c 2**0
CONTENTS, RELOC, READONLY, DEBUGGING
14 .debug_abbrev 000002e4 00000000 00000000 00000d20 2**0
CONTENTS, READONLY, DEBUGGING
15 .debug_loc 00000568 00000000 00000000 00001004 2**0
CONTENTS, RELOC, READONLY, DEBUGGING
16 .debug_aranges 00000068 00000000 00000000 0000156c 2**0
CONTENTS, RELOC, READONLY, DEBUGGING
17 .debug_ranges 00000150 00000000 00000000 000015d4 2**0
CONTENTS, RELOC, READONLY, DEBUGGING
18 .debug_line 0000030e 00000000 00000000 00001724 2**0
CONTENTS, RELOC, READONLY, DEBUGGING
19 .debug_str 00000395 00000000 00000000 00001a32 2**0
CONTENTS, READONLY, DEBUGGING
20 .comment 00000039 00000000 00000000 00001dc7 2**0
CONTENTS, READONLY
21 .debug_frame 00000140 00000000 00000000 00001e00 2**2
CONTENTS, RELOC, READONLY, DEBUGGING
22 .ARM.attributes 00000033 00000000 00000000 00001f40 2**0
CONTENTS, READONLY
SYMBOL TABLE:
00000000 l df *ABS* 00000000 encoder.c
00000000 l d .text 00000000 .text
00000000 l d .data 00000000 .data
00000000 l d .bss 00000000 .bss
00000000 l d .text.encoderGet 00000000 .text.encoderGet
00000000 l d .text.encoderReset 00000000 .text.encoderReset
00000000 l d .text.ioClearInterrupt 00000000 .text.ioClearInterrupt
00000000 l d .text.encoderShutdown 00000000 .text.encoderShutdown
00000000 l d .text.ioSetInterrupt 00000000 .text.ioSetInterrupt
00000000 l d .text.encoderInit 00000000 .text.encoderInit
00000000 l d .text.ISR_EXTI0 00000000 .text.ISR_EXTI0
00000000 l d .text.ISR_EXTI1 00000000 .text.ISR_EXTI1
00000000 l d .text.ISR_EXTI9_5 00000000 .text.ISR_EXTI9_5
00000000 l d .text.ISR_EXTI15_10 00000000 .text.ISR_EXTI15_10
00000000 l d .debug_info 00000000 .debug_info
00000000 l d .debug_abbrev 00000000 .debug_abbrev
00000000 l d .debug_loc 00000000 .debug_loc
00000000 l d .debug_aranges 00000000 .debug_aranges
00000000 l d .debug_ranges 00000000 .debug_ranges
00000000 l d .debug_line 00000000 .debug_line
00000000 l d .debug_str 00000000 .debug_str
00000000 l d .debug_frame 00000000 .debug_frame
00000000 l d .comment 00000000 .comment
00000000 l d .ARM.attributes 00000000 .ARM.attributes
00000000 g F .text.encoderGet 00000006 encoderGet
00000000 g F .text.encoderReset 00000024 encoderReset
00000000 *UND* 00000000 _criticalNesting
00000000 g F .text.ioClearInterrupt 00000048 ioClearInterrupt
00000000 *UND* 00000000 _pinIndexTable
00000000 g F .text.encoderShutdown 00000040 encoderShutdown
000000c0 O *COM* 00000004 _sensorState
00000000 g F .text.ioSetInterrupt 00000084 ioSetInterrupt
00000000 g F .text.encoderInit 000000cc encoderInit
00000000 *UND* 00000000 pinMode
00000000 *UND* 00000000 _encoderISRTop
00000000 *UND* 00000000 _encoderISRBottom
00000000 g F .text.ISR_EXTI0 0000002c ISR_EXTI0
00000000 g F .text.ISR_EXTI1 0000002c ISR_EXTI1
00000000 g F .text.ISR_EXTI9_5 0000006c ISR_EXTI9_5
00000000 g F .text.ISR_EXTI15_10 00000080 ISR_EXTI15_10
Disassembly of section .text.encoderGet:
00000000 <encoderGet>:
#endif
// encoderGet - Gets the value of the encoder
int encoderGet(Encoder enc) {
Sensor_TypeDef *encoder = (Sensor_TypeDef*)enc;
if (encoder)
0: b100 cbz r0, 4 <encoderGet+0x4>
return (int)encoder->value;
2: 6800 ldr r0, [r0, #0]
return 0;
}
4: 4770 bx lr
Disassembly of section .text.encoderReset:
00000000 <encoderReset>:
#endif
// encoderGet - Gets the value of the encoder
int encoderGet(Encoder enc) {
Sensor_TypeDef *encoder = (Sensor_TypeDef*)enc;
if (encoder)
0: b160 cbz r0, 1c <encoderReset+0x1c>
return (int)encoder->value;
2: b672 cpsid i
return 0;
}
4: 4a06 ldr r2, [pc, #24] ; (20 <encoderReset+0x20>)
6: 6813 ldr r3, [r2, #0]
}
// encoderReset - Resets the encoder to zero
void encoderReset(Encoder enc) {
Sensor_TypeDef *encoder = (Sensor_TypeDef*)enc;
if (encoder) {
8: 3301 adds r3, #1
#define USART_CR3_CTSE ((uint16_t)0x0200)
// Disables FAULT interrupts
static inline void __disable_fault_irq() { asm volatile ("cpsid f"); }
// Disables interrupts
static inline void __disable_irq() { asm volatile ("cpsid i"); }
a: 6013 str r3, [r2, #0]
extern volatile uint32_t _criticalNesting;
/* Enter a critical section. */
static INLINE void _enterCritical() {
__disable_irq();
_criticalNesting++;
c: 2300 movs r3, #0
e: 6003 str r3, [r0, #0]
10: 60c3 str r3, [r0, #12]
12: 6813 ldr r3, [r2, #0]
_enterCritical();
{
encoder->value = 0;
14: 3b01 subs r3, #1
16: 6013 str r3, [r2, #0]
encoder->lastValue = 0;
18: b903 cbnz r3, 1c <encoderReset+0x1c>
}
/* Exit a critical section. */
static INLINE void _exitCritical() {
const uint32_t newCritical = _criticalNesting - 1;
1a: b662 cpsie i
1c: 4770 bx lr
_criticalNesting = newCritical;
1e: bf00 nop
if (newCritical == 0)
20: 00000000 andeq r0, r0, r0
20: R_ARM_ABS32 _criticalNesting
Disassembly of section .text.ioClearInterrupt:
00000000 <ioClearInterrupt>:
#endif
// encoderGet - Gets the value of the encoder
int encoderGet(Encoder enc) {
Sensor_TypeDef *encoder = (Sensor_TypeDef*)enc;
if (encoder)
0: 3801 subs r0, #1
return (int)encoder->value;
2: b2c0 uxtb r0, r0
return 0;
}
4: 280b cmp r0, #11
6: d818 bhi.n 3a <ioClearInterrupt+0x3a>
}
// encoderReset - Resets the encoder to zero
void encoderReset(Encoder enc) {
Sensor_TypeDef *encoder = (Sensor_TypeDef*)enc;
if (encoder) {
8: 2809 cmp r0, #9
a: d016 beq.n 3a <ioClearInterrupt+0x3a>
extern volatile uint32_t _criticalNesting;
/* Enter a critical section. */
static INLINE void _enterCritical() {
__disable_irq();
_criticalNesting++;
c: b672 cpsid i
e: 4a0b ldr r2, [pc, #44] ; (3c <ioClearInterrupt+0x3c>)
10: 2101 movs r1, #1
12: 6813 ldr r3, [r2, #0]
_enterCritical();
{
encoder->value = 0;
14: 3301 adds r3, #1
16: 6013 str r3, [r2, #0]
encoder->lastValue = 0;
18: 4b09 ldr r3, [pc, #36] ; (40 <ioClearInterrupt+0x40>)
}
/* Exit a critical section. */
static INLINE void _exitCritical() {
const uint32_t newCritical = _criticalNesting - 1;
1a: 4418 add r0, r3
1c: 7843 ldrb r3, [r0, #1]
_criticalNesting = newCritical;
1e: 4099 lsls r1, r3
if (newCritical == 0)
20: 4b08 ldr r3, [pc, #32] ; (44 <ioClearInterrupt+0x44>)
// Waits for memory accesses to complete before continuing (Data Synchronization Barrier)
static inline void __dsb() { asm volatile ("dsb"); }
// Enables FAULT interrupts
static inline void __enable_fault_irq() { asm volatile ("cpsie f"); }
// Enables interrupts
static inline void __enable_irq() { asm volatile ("cpsie i"); }
22: 6958 ldr r0, [r3, #20]
24: 4308 orrs r0, r1
26: 6158 str r0, [r3, #20]
28: 6818 ldr r0, [r3, #0]
2a: ea20 0101 bic.w r1, r0, r1
}
}
// ioClearInterrupt - Disables interrupts on the specified pin
void ioClearInterrupt(unsigned char pin) {
pin--;
2e: 6019 str r1, [r3, #0]
if (pin < 12 && pin != 9) {
30: 6813 ldr r3, [r2, #0]
32: 3b01 subs r3, #1
34: 6013 str r3, [r2, #0]
36: b903 cbnz r3, 3a <ioClearInterrupt+0x3a>
#define USART_CR3_CTSE ((uint16_t)0x0200)
// Disables FAULT interrupts
static inline void __disable_fault_irq() { asm volatile ("cpsid f"); }
// Disables interrupts
static inline void __disable_irq() { asm volatile ("cpsid i"); }
38: b662 cpsie i
extern volatile uint32_t _criticalNesting;
/* Enter a critical section. */
static INLINE void _enterCritical() {
__disable_irq();
_criticalNesting++;
3a: 4770 bx lr
...
3c: R_ARM_ABS32 _criticalNesting
40: R_ARM_ABS32 _pinIndexTable
// Avoid having the OS swap this out
_enterCritical();
{
uint32_t mask = (uint32_t)1 << _pinIndexTable[pin + 1];
44: 40010400 andmi r0, r1, r0, lsl #8
Disassembly of section .text.encoderShutdown:
00000000 <encoderShutdown>:
#endif
// encoderGet - Gets the value of the encoder
int encoderGet(Encoder enc) {
Sensor_TypeDef *encoder = (Sensor_TypeDef*)enc;
if (encoder)
0: b538 push {r3, r4, r5, lr}
return (int)encoder->value;
2: 4604 mov r4, r0
return 0;
}
4: b1b0 cbz r0, 34 <encoderShutdown+0x34>
6: b672 cpsid i
}
// encoderReset - Resets the encoder to zero
void encoderReset(Encoder enc) {
Sensor_TypeDef *encoder = (Sensor_TypeDef*)enc;
if (encoder) {
8: 4d0b ldr r5, [pc, #44] ; (38 <encoderShutdown+0x38>)
a: 2200 movs r2, #0
c: 682b ldr r3, [r5, #0]
e: 3301 adds r3, #1
10: 602b str r3, [r5, #0]
12: 8082 strh r2, [r0, #4]
_enterCritical();
{
encoder->value = 0;
14: 79c1 ldrb r1, [r0, #7]
16: 4b09 ldr r3, [pc, #36] ; (3c <encoderShutdown+0x3c>)
encoder->lastValue = 0;
18: eb03 1301 add.w r3, r3, r1, lsl #4
}
/* Exit a critical section. */
static INLINE void _exitCritical() {
const uint32_t newCritical = _criticalNesting - 1;
1c: 809a strh r2, [r3, #4]
_criticalNesting = newCritical;
1e: 7980 ldrb r0, [r0, #6]
if (newCritical == 0)
20: f7ff fffe bl 0 <encoderShutdown>
20: R_ARM_THM_CALL ioClearInterrupt
// Waits for memory accesses to complete before continuing (Data Synchronization Barrier)
static inline void __dsb() { asm volatile ("dsb"); }
// Enables FAULT interrupts
static inline void __enable_fault_irq() { asm volatile ("cpsie f"); }
// Enables interrupts
static inline void __enable_irq() { asm volatile ("cpsie i"); }
24: 79e0 ldrb r0, [r4, #7]
26: f7ff fffe bl 0 <encoderShutdown>
26: R_ARM_THM_CALL ioClearInterrupt
2a: 682b ldr r3, [r5, #0]
}
}
// ioClearInterrupt - Disables interrupts on the specified pin
void ioClearInterrupt(unsigned char pin) {
pin--;
2c: 3b01 subs r3, #1
2e: 602b str r3, [r5, #0]
if (pin < 12 && pin != 9) {
30: b903 cbnz r3, 34 <encoderShutdown+0x34>
32: b662 cpsie i
34: bd38 pop {r3, r4, r5, pc}
36: bf00 nop
...
38: R_ARM_ABS32 _criticalNesting
3c: R_ARM_ABS32 _sensorState
Disassembly of section .text.ioSetInterrupt:
00000000 <ioSetInterrupt>:
#endif
// encoderGet - Gets the value of the encoder
int encoderGet(Encoder enc) {
Sensor_TypeDef *encoder = (Sensor_TypeDef*)enc;
if (encoder)
0: 3801 subs r0, #1
return (int)encoder->value;
2: b2c0 uxtb r0, r0
return 0;
}
4: 280b cmp r0, #11
6: b5f0 push {r4, r5, r6, r7, lr}
}
// encoderReset - Resets the encoder to zero
void encoderReset(Encoder enc) {
Sensor_TypeDef *encoder = (Sensor_TypeDef*)enc;
if (encoder) {
8: d832 bhi.n 70 <ioSetInterrupt+0x70>
#define USART_CR3_CTSE ((uint16_t)0x0200)
// Disables FAULT interrupts
static inline void __disable_fault_irq() { asm volatile ("cpsid f"); }
// Disables interrupts
static inline void __disable_irq() { asm volatile ("cpsid i"); }
a: 2809 cmp r0, #9
extern volatile uint32_t _criticalNesting;
/* Enter a critical section. */
static INLINE void _enterCritical() {
__disable_irq();
_criticalNesting++;
c: d030 beq.n 70 <ioSetInterrupt+0x70>
e: b672 cpsid i
10: 4e18 ldr r6, [pc, #96] ; (74 <ioSetInterrupt+0x74>)
12: 2401 movs r4, #1
_enterCritical();
{
encoder->value = 0;
14: 6833 ldr r3, [r6, #0]
16: f011 0f02 tst.w r1, #2
}
/* Exit a critical section. */
static INLINE void _exitCritical() {
const uint32_t newCritical = _criticalNesting - 1;
1a: f103 0301 add.w r3, r3, #1
_criticalNesting = newCritical;
1e: 6033 str r3, [r6, #0]
if (newCritical == 0)
20: 4b15 ldr r3, [pc, #84] ; (78 <ioSetInterrupt+0x78>)
// Waits for memory accesses to complete before continuing (Data Synchronization Barrier)
static inline void __dsb() { asm volatile ("dsb"); }
// Enables FAULT interrupts
static inline void __enable_fault_irq() { asm volatile ("cpsie f"); }
// Enables interrupts
static inline void __enable_irq() { asm volatile ("cpsie i"); }
22: 4403 add r3, r0
24: 785b ldrb r3, [r3, #1]
26: fa04 f403 lsl.w r4, r4, r3
2a: ea6f 0504 mvn.w r5, r4
}
}
// ioClearInterrupt - Disables interrupts on the specified pin
void ioClearInterrupt(unsigned char pin) {
pin--;
2e: 4b13 ldr r3, [pc, #76] ; (7c <ioSetInterrupt+0x7c>)
if (pin < 12 && pin != 9) {
30: 681f ldr r7, [r3, #0]
32: ea07 0705 and.w r7, r7, r5
36: 601f str r7, [r3, #0]
#define USART_CR3_CTSE ((uint16_t)0x0200)
// Disables FAULT interrupts
static inline void __disable_fault_irq() { asm volatile ("cpsid f"); }
// Disables interrupts
static inline void __disable_irq() { asm volatile ("cpsid i"); }
38: 4f11 ldr r7, [pc, #68] ; (80 <ioSetInterrupt+0x80>)
extern volatile uint32_t _criticalNesting;
/* Enter a critical section. */
static INLINE void _enterCritical() {
__disable_irq();
_criticalNesting++;
3a: eb07 1000 add.w r0, r7, r0, lsl #4
3e: 6082 str r2, [r0, #8]
40: 68d8 ldr r0, [r3, #12]
42: bf14 ite ne
// Avoid having the OS swap this out
_enterCritical();
{
uint32_t mask = (uint32_t)1 << _pinIndexTable[pin + 1];
44: 4320 orrne r0, r4
46: 4028 andeq r0, r5
48: 60d8 str r0, [r3, #12]
4a: 6898 ldr r0, [r3, #8]
// Clear pending interrupt
EXTI->PR |= mask;
4c: 07c9 lsls r1, r1, #31
4e: bf4c ite mi
50: ea44 0100 orrmi.w r1, r4, r0
// Mask interrupt
EXTI->IMR &= ~mask;
54: ea05 0100 andpl.w r1, r5, r0
58: 6099 str r1, [r3, #8]
5a: 6959 ldr r1, [r3, #20]
}
/* Exit a critical section. */
static INLINE void _exitCritical() {
const uint32_t newCritical = _criticalNesting - 1;
5c: 4321 orrs r1, r4
5e: 6159 str r1, [r3, #20]
_criticalNesting = newCritical;
60: 6819 ldr r1, [r3, #0]
if (newCritical == 0)
62: 430c orrs r4, r1
// Waits for memory accesses to complete before continuing (Data Synchronization Barrier)
static inline void __dsb() { asm volatile ("dsb"); }
// Enables FAULT interrupts
static inline void __enable_fault_irq() { asm volatile ("cpsie f"); }
// Enables interrupts
static inline void __enable_irq() { asm volatile ("cpsie i"); }
64: 601c str r4, [r3, #0]
66: 6833 ldr r3, [r6, #0]
68: 3b01 subs r3, #1
6a: 6033 str r3, [r6, #0]
6c: b903 cbnz r3, 70 <ioSetInterrupt+0x70>
6e: b662 cpsie i
70: bdf0 pop {r4, r5, r6, r7, pc}
72: bf00 nop
...
74: R_ARM_ABS32 _criticalNesting
78: R_ARM_ABS32 _pinIndexTable
extern volatile uint32_t _criticalNesting;
/* Enter a critical section. */
static INLINE void _enterCritical() {
__disable_irq();
_criticalNesting++;
7c: 40010400 andmi r0, r1, r0, lsl #8
80: 00000000 andeq r0, r0, r0
80: R_ARM_ABS32 _sensorState
Disassembly of section .text.encoderInit:
00000000 <encoderInit>:
#endif
// encoderGet - Gets the value of the encoder
int encoderGet(Encoder enc) {
Sensor_TypeDef *encoder = (Sensor_TypeDef*)enc;
if (encoder)
0: e92d 4ff7 stmdb sp!, {r0, r1, r2, r4, r5, r6, r7, r8, r9, sl, fp, lr}
return (int)encoder->value;
return 0;
}
4: 1e46 subs r6, r0, #1
6: 2e0b cmp r6, #11
}
// encoderReset - Resets the encoder to zero
void encoderReset(Encoder enc) {
Sensor_TypeDef *encoder = (Sensor_TypeDef*)enc;
if (encoder) {
8: 4682 mov sl, r0
#define USART_CR3_CTSE ((uint16_t)0x0200)
// Disables FAULT interrupts
static inline void __disable_fault_irq() { asm volatile ("cpsid f"); }
// Disables interrupts
static inline void __disable_irq() { asm volatile ("cpsid i"); }
a: 460f mov r7, r1
c: f101 35ff add.w r5, r1, #4294967295 ; 0xffffffff
10: d84c bhi.n ac <encoderInit+0xac>
12: 2e09 cmp r6, #9
_enterCritical();
{
encoder->value = 0;
14: d04a beq.n ac <encoderInit+0xac>
16: f8df c0ac ldr.w ip, [pc, #172] ; c4 <encoderInit+0xc4>
}
/* Exit a critical section. */
static INLINE void _exitCritical() {
const uint32_t newCritical = _criticalNesting - 1;
1a: 0136 lsls r6, r6, #4
1c: eb0c 0406 add.w r4, ip, r6
_criticalNesting = newCritical;
if (newCritical == 0)
20: 88a3 ldrh r3, [r4, #4]
// Waits for memory accesses to complete before continuing (Data Synchronization Barrier)
static inline void __dsb() { asm volatile ("dsb"); }
// Enables FAULT interrupts
static inline void __enable_fault_irq() { asm volatile ("cpsie f"); }
// Enables interrupts
static inline void __enable_irq() { asm volatile ("cpsie i"); }
22: b29b uxth r3, r3
24: 2b00 cmp r3, #0
26: d141 bne.n ac <encoderInit+0xac>
28: 2d0b cmp r5, #11
2a: d841 bhi.n b0 <encoderInit+0xb0>
}
}
// ioClearInterrupt - Disables interrupts on the specified pin
void ioClearInterrupt(unsigned char pin) {
pin--;
2c: 2d09 cmp r5, #9
2e: d03f beq.n b0 <encoderInit+0xb0>
if (pin < 12 && pin != 9) {
30: eb0c 1505 add.w r5, ip, r5, lsl #4
34: f8b5 8004 ldrh.w r8, [r5, #4]
#define USART_CR3_CTSE ((uint16_t)0x0200)
// Disables FAULT interrupts
static inline void __disable_fault_irq() { asm volatile ("cpsid f"); }
// Disables interrupts
static inline void __disable_irq() { asm volatile ("cpsid i"); }
38: f8cd c004 str.w ip, [sp, #4]
// Avoid having the OS swap this out
_enterCritical();
{
uint32_t mask = (uint32_t)1 << _pinIndexTable[pin + 1];
3c: fa1f f888 uxth.w r8, r8
extern volatile uint32_t _criticalNesting;
/* Enter a critical section. */
static INLINE void _enterCritical() {
__disable_irq();
_criticalNesting++;
40: f1b8 0f00 cmp.w r8, #0
44: d134 bne.n b0 <encoderInit+0xb0>
46: b672 cpsid i
48: f8df 907c ldr.w r9, [pc, #124] ; c8 <encoderInit+0xc8>
// Clear pending interrupt
EXTI->PR |= mask;
4c: 210a movs r1, #10
4e: f8d9 3000 ldr.w r3, [r9]
52: f042 0b02 orr.w fp, r2, #2
// Mask interrupt
EXTI->IMR &= ~mask;
56: 3301 adds r3, #1
58: f8c9 3000 str.w r3, [r9]
}
/* Exit a critical section. */
static INLINE void _exitCritical() {
const uint32_t newCritical = _criticalNesting - 1;
5c: f7ff fffe bl 0 <pinMode>
5c: R_ARM_THM_CALL pinMode
_criticalNesting = newCritical;
60: 4638 mov r0, r7
if (newCritical == 0)
62: 210a movs r1, #10
// Waits for memory accesses to complete before continuing (Data Synchronization Barrier)
static inline void __dsb() { asm volatile ("dsb"); }
// Enables FAULT interrupts
static inline void __enable_fault_irq() { asm volatile ("cpsie f"); }
// Enables interrupts
static inline void __enable_irq() { asm volatile ("cpsie i"); }
64: f7ff fffe bl 0 <pinMode>
64: R_ARM_THM_CALL pinMode
68: f8dd c004 ldr.w ip, [sp, #4]
6c: f8a4 b004 strh.w fp, [r4, #4]
70: 4650 mov r0, sl
72: f884 a006 strb.w sl, [r4, #6]
}
// encoderShutdown - Stops and disables the encoder
void encoderShutdown(Encoder enc) {
Sensor_TypeDef *encoder = (Sensor_TypeDef*)enc;
if (encoder) {
76: 2103 movs r1, #3
78: 71e7 strb r7, [r4, #7]
#define USART_CR3_CTSE ((uint16_t)0x0200)
// Disables FAULT interrupts
static inline void __disable_fault_irq() { asm volatile ("cpsid f"); }
// Disables interrupts
static inline void __disable_irq() { asm volatile ("cpsid i"); }
7a: 4a10 ldr r2, [pc, #64] ; (bc <encoderInit+0xbc>)
extern volatile uint32_t _criticalNesting;
/* Enter a critical section. */
static INLINE void _enterCritical() {
__disable_irq();
_criticalNesting++;
7c: f84c 8006 str.w r8, [ip, r6]
80: f8c4 800c str.w r8, [r4, #12]
84: f8a5 b004 strh.w fp, [r5, #4]
_enterCritical();
{
// Stop
encoder->flags = 0;
_sensorState[encoder->portBottom].flags = 0;
88: f885 a006 strb.w sl, [r5, #6]
8c: 71ef strb r7, [r5, #7]
8e: f7ff fffe bl 0 <encoderInit>
8e: R_ARM_THM_CALL ioSetInterrupt
// Clear interrupts
ioClearInterrupt(encoder->portTop);
92: 4638 mov r0, r7
94: 2103 movs r1, #3
96: 4a0a ldr r2, [pc, #40] ; (c0 <encoderInit+0xc0>)
ioClearInterrupt(encoder->portBottom);
98: f7ff fffe bl 0 <encoderInit>
98: R_ARM_THM_CALL ioSetInterrupt
9c: f8d9 3000 ldr.w r3, [r9]
}
/* Exit a critical section. */
static INLINE void _exitCritical() {
const uint32_t newCritical = _criticalNesting - 1;
a0: 3b01 subs r3, #1
_criticalNesting = newCritical;
a2: f8c9 3000 str.w r3, [r9]
// Waits for memory accesses to complete before continuing (Data Synchronization Barrier)
static inline void __dsb() { asm volatile ("dsb"); }
// Enables FAULT interrupts
static inline void __enable_fault_irq() { asm volatile ("cpsie f"); }
// Enables interrupts
static inline void __enable_irq() { asm volatile ("cpsie i"); }
a6: b92b cbnz r3, b4 <encoderInit+0xb4>
a8: b662 cpsie i
aa: e003 b.n b4 <encoderInit+0xb4>
ac: 2000 movs r0, #0
ae: e002 b.n b6 <encoderInit+0xb6>
b0: 4618 mov r0, r3
b2: e000 b.n b6 <encoderInit+0xb6>
}
// ioSetInterrupt - Sets up an interrupt to occur on the specified pin, and resets count & time
// Provide NULL for handler for standard interrupts, or pass function pointer for custom
void ioSetInterrupt(unsigned char pin, unsigned char edges, InterruptHandler handler) {
pin--;
b4: 4620 mov r0, r4
b6: b003 add sp, #12
if (pin < BOARD_NR_DIGITAL_IO && pin != 9) {
b8: e8bd 8ff0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, sl, fp, pc}
...
bc: R_ARM_ABS32 _encoderISRTop
c0: R_ARM_ABS32 _encoderISRBottom
c4: R_ARM_ABS32 _sensorState
c8: R_ARM_ABS32 _criticalNesting
Disassembly of section .text.ISR_EXTI0:
00000000 <ISR_EXTI0>:
#endif
// encoderGet - Gets the value of the encoder
int encoderGet(Encoder enc) {
Sensor_TypeDef *encoder = (Sensor_TypeDef*)enc;
if (encoder)
0: 4668 mov r0, sp
return (int)encoder->value;
2: f020 0107 bic.w r1, r0, #7
6: 468d mov sp, r1
}
// encoderReset - Resets the encoder to zero
void encoderReset(Encoder enc) {
Sensor_TypeDef *encoder = (Sensor_TypeDef*)enc;
if (encoder) {
8: 4b06 ldr r3, [pc, #24] ; (24 <ISR_EXTI0+0x24>)
#define USART_CR3_CTSE ((uint16_t)0x0200)
// Disables FAULT interrupts
static inline void __disable_fault_irq() { asm volatile ("cpsid f"); }
// Disables interrupts
static inline void __disable_irq() { asm volatile ("cpsid i"); }
a: b501 push {r0, lr}
extern volatile uint32_t _criticalNesting;
/* Enter a critical section. */
static INLINE void _enterCritical() {
__disable_irq();
_criticalNesting++;
c: f8d3 30a8 ldr.w r3, [r3, #168] ; 0xa8
10: b10b cbz r3, 16 <ISR_EXTI0+0x16>
12: 200b movs r0, #11
_enterCritical();
{
encoder->value = 0;
14: 4798 blx r3
16: e8bd 4001 ldmia.w sp!, {r0, lr}
}
/* Exit a critical section. */
static INLINE void _exitCritical() {
const uint32_t newCritical = _criticalNesting - 1;
1a: 4b03 ldr r3, [pc, #12] ; (28 <ISR_EXTI0+0x28>)
1c: 2201 movs r2, #1
_criticalNesting = newCritical;
1e: 615a str r2, [r3, #20]
if (newCritical == 0)
20: 4685 mov sp, r0
// Waits for memory accesses to complete before continuing (Data Synchronization Barrier)
static inline void __dsb() { asm volatile ("dsb"); }
// Enables FAULT interrupts
static inline void __enable_fault_irq() { asm volatile ("cpsie f"); }
// Enables interrupts
static inline void __enable_irq() { asm volatile ("cpsie i"); }
22: 4770 bx lr
24: 00000000 andeq r0, r0, r0
24: R_ARM_ABS32 _sensorState
28: 40010400 andmi r0, r1, r0, lsl #8
Disassembly of section .text.ISR_EXTI1:
00000000 <ISR_EXTI1>:
#endif
// encoderGet - Gets the value of the encoder
int encoderGet(Encoder enc) {
Sensor_TypeDef *encoder = (Sensor_TypeDef*)enc;
if (encoder)
0: 4668 mov r0, sp
return (int)encoder->value;
2: f020 0107 bic.w r1, r0, #7
6: 468d mov sp, r1
}
// encoderReset - Resets the encoder to zero
void encoderReset(Encoder enc) {
Sensor_TypeDef *encoder = (Sensor_TypeDef*)enc;
if (encoder) {
8: 4b06 ldr r3, [pc, #24] ; (24 <ISR_EXTI1+0x24>)
#define USART_CR3_CTSE ((uint16_t)0x0200)
// Disables FAULT interrupts
static inline void __disable_fault_irq() { asm volatile ("cpsid f"); }
// Disables interrupts
static inline void __disable_irq() { asm volatile ("cpsid i"); }
a: b501 push {r0, lr}
extern volatile uint32_t _criticalNesting;
/* Enter a critical section. */
static INLINE void _enterCritical() {
__disable_irq();
_criticalNesting++;
c: f8d3 30b8 ldr.w r3, [r3, #184] ; 0xb8
10: b10b cbz r3, 16 <ISR_EXTI1+0x16>
12: 200c movs r0, #12
_enterCritical();
{
encoder->value = 0;
14: 4798 blx r3
16: e8bd 4001 ldmia.w sp!, {r0, lr}
}
/* Exit a critical section. */
static INLINE void _exitCritical() {
const uint32_t newCritical = _criticalNesting - 1;
1a: 4b03 ldr r3, [pc, #12] ; (28 <ISR_EXTI1+0x28>)
1c: 2202 movs r2, #2
_criticalNesting = newCritical;
1e: 615a str r2, [r3, #20]
if (newCritical == 0)
20: 4685 mov sp, r0
// Waits for memory accesses to complete before continuing (Data Synchronization Barrier)
static inline void __dsb() { asm volatile ("dsb"); }
// Enables FAULT interrupts
static inline void __enable_fault_irq() { asm volatile ("cpsie f"); }
// Enables interrupts
static inline void __enable_irq() { asm volatile ("cpsie i"); }
22: 4770 bx lr
24: 00000000 andeq r0, r0, r0
24: R_ARM_ABS32 _sensorState
28: 40010400 andmi r0, r1, r0, lsl #8
Disassembly of section .text.ISR_EXTI9_5:
00000000 <ISR_EXTI9_5>:
#endif
// encoderGet - Gets the value of the encoder
int encoderGet(Encoder enc) {
Sensor_TypeDef *encoder = (Sensor_TypeDef*)enc;
if (encoder)
0: 4668 mov r0, sp
return (int)encoder->value;
2: f020 0107 bic.w r1, r0, #7
6: 468d mov sp, r1
}
// encoderReset - Resets the encoder to zero
void encoderReset(Encoder enc) {
Sensor_TypeDef *encoder = (Sensor_TypeDef*)enc;
if (encoder) {
8: b579 push {r0, r3, r4, r5, r6, lr}
#define USART_CR3_CTSE ((uint16_t)0x0200)
// Disables FAULT interrupts
static inline void __disable_fault_irq() { asm volatile ("cpsid f"); }
// Disables interrupts
static inline void __disable_irq() { asm volatile ("cpsid i"); }
a: 4b16 ldr r3, [pc, #88] ; (64 <ISR_EXTI9_5+0x64>)
extern volatile uint32_t _criticalNesting;
/* Enter a critical section. */
static INLINE void _enterCritical() {
__disable_irq();
_criticalNesting++;
c: 695d ldr r5, [r3, #20]
e: 461e mov r6, r3
10: f015 0440 ands.w r4, r5, #64 ; 0x40
_enterCritical();
{
encoder->value = 0;
14: d005 beq.n 22 <ISR_EXTI9_5+0x22>
16: 4b14 ldr r3, [pc, #80] ; (68 <ISR_EXTI9_5+0x68>)
encoder->lastValue = 0;
18: 6a9b ldr r3, [r3, #40] ; 0x28
}
/* Exit a critical section. */
static INLINE void _exitCritical() {
const uint32_t newCritical = _criticalNesting - 1;
1a: b10b cbz r3, 20 <ISR_EXTI9_5+0x20>
1c: 2003 movs r0, #3
_criticalNesting = newCritical;
1e: 4798 blx r3
if (newCritical == 0)
20: 2440 movs r4, #64 ; 0x40
// Waits for memory accesses to complete before continuing (Data Synchronization Barrier)
static inline void __dsb() { asm volatile ("dsb"); }
// Enables FAULT interrupts
static inline void __enable_fault_irq() { asm volatile ("cpsie f"); }
// Enables interrupts
static inline void __enable_irq() { asm volatile ("cpsie i"); }
22: 0629 lsls r1, r5, #24
24: d506 bpl.n 34 <ISR_EXTI9_5+0x34>
26: 4b10 ldr r3, [pc, #64] ; (68 <ISR_EXTI9_5+0x68>)
28: 6b9b ldr r3, [r3, #56] ; 0x38
2a: b10b cbz r3, 30 <ISR_EXTI9_5+0x30>
}
}
// ioClearInterrupt - Disables interrupts on the specified pin
void ioClearInterrupt(unsigned char pin) {
pin--;
2c: 2004 movs r0, #4
2e: 4798 blx r3
if (pin < 12 && pin != 9) {
30: f044 0480 orr.w r4, r4, #128 ; 0x80
34: 05ea lsls r2, r5, #23
36: d506 bpl.n 46 <ISR_EXTI9_5+0x46>
#define USART_CR3_CTSE ((uint16_t)0x0200)
// Disables FAULT interrupts
static inline void __disable_fault_irq() { asm volatile ("cpsid f"); }
// Disables interrupts
static inline void __disable_irq() { asm volatile ("cpsid i"); }
38: 4b0b ldr r3, [pc, #44] ; (68 <ISR_EXTI9_5+0x68>)
extern volatile uint32_t _criticalNesting;
/* Enter a critical section. */
static INLINE void _enterCritical() {
__disable_irq();
_criticalNesting++;
3a: 6e9b ldr r3, [r3, #104] ; 0x68
// Avoid having the OS swap this out
_enterCritical();
{
uint32_t mask = (uint32_t)1 << _pinIndexTable[pin + 1];
3c: b10b cbz r3, 42 <ISR_EXTI9_5+0x42>
3e: 2007 movs r0, #7
40: 4798 blx r3
42: f444 7480 orr.w r4, r4, #256 ; 0x100
46: 05ab lsls r3, r5, #22
48: d506 bpl.n 58 <ISR_EXTI9_5+0x58>
4a: 4b07 ldr r3, [pc, #28] ; (68 <ISR_EXTI9_5+0x68>)
// Clear pending interrupt
EXTI->PR |= mask;
4c: 689b ldr r3, [r3, #8]
4e: b10b cbz r3, 54 <ISR_EXTI9_5+0x54>
50: 2001 movs r0, #1
52: 4798 blx r3
// Mask interrupt
EXTI->IMR &= ~mask;
54: f444 7400 orr.w r4, r4, #512 ; 0x200
58: 6174 str r4, [r6, #20]
5a: e8bd 4079 ldmia.w sp!, {r0, r3, r4, r5, r6, lr}
}
/* Exit a critical section. */
static INLINE void _exitCritical() {
const uint32_t newCritical = _criticalNesting - 1;
5e: 4685 mov sp, r0
_criticalNesting = newCritical;
60: 4770 bx lr
if (newCritical == 0)
62: bf00 nop
// Waits for memory accesses to complete before continuing (Data Synchronization Barrier)
static inline void __dsb() { asm volatile ("dsb"); }
// Enables FAULT interrupts
static inline void __enable_fault_irq() { asm volatile ("cpsie f"); }
// Enables interrupts
static inline void __enable_irq() { asm volatile ("cpsie i"); }
64: 40010400 andmi r0, r1, r0, lsl #8
68: 00000000 andeq r0, r0, r0
68: R_ARM_ABS32 _sensorState
Disassembly of section .text.ISR_EXTI15_10:
00000000 <ISR_EXTI15_10>:
#endif
// encoderGet - Gets the value of the encoder
int encoderGet(Encoder enc) {
Sensor_TypeDef *encoder = (Sensor_TypeDef*)enc;
if (encoder)
0: 4668 mov r0, sp
return (int)encoder->value;
2: f020 0107 bic.w r1, r0, #7
6: 468d mov sp, r1
}
// encoderReset - Resets the encoder to zero
void encoderReset(Encoder enc) {
Sensor_TypeDef *encoder = (Sensor_TypeDef*)enc;
if (encoder) {
8: b579 push {r0, r3, r4, r5, r6, lr}
#define USART_CR3_CTSE ((uint16_t)0x0200)
// Disables FAULT interrupts
static inline void __disable_fault_irq() { asm volatile ("cpsid f"); }
// Disables interrupts
static inline void __disable_irq() { asm volatile ("cpsid i"); }
a: 4e1b ldr r6, [pc, #108] ; (78 <ISR_EXTI15_10+0x78>)
extern volatile uint32_t _criticalNesting;
/* Enter a critical section. */
static INLINE void _enterCritical() {
__disable_irq();
_criticalNesting++;
c: 6975 ldr r5, [r6, #20]
e: f415 6480 ands.w r4, r5, #1024 ; 0x400
12: d006 beq.n 22 <ISR_EXTI15_10+0x22>
_enterCritical();
{
encoder->value = 0;
14: 4b19 ldr r3, [pc, #100] ; (7c <ISR_EXTI15_10+0x7c>)
16: 6f9b ldr r3, [r3, #120] ; 0x78
encoder->lastValue = 0;
18: b10b cbz r3, 1e <ISR_EXTI15_10+0x1e>
}
/* Exit a critical section. */
static INLINE void _exitCritical() {
const uint32_t newCritical = _criticalNesting - 1;
1a: 2008 movs r0, #8
1c: 4798 blx r3
_criticalNesting = newCritical;
1e: f44f 6480 mov.w r4, #1024 ; 0x400
// Waits for memory accesses to complete before continuing (Data Synchronization Barrier)
static inline void __dsb() { asm volatile ("dsb"); }
// Enables FAULT interrupts
static inline void __enable_fault_irq() { asm volatile ("cpsie f"); }
// Enables interrupts
static inline void __enable_irq() { asm volatile ("cpsie i"); }
22: 0528 lsls r0, r5, #20
24: d506 bpl.n 34 <ISR_EXTI15_10+0x34>
26: 4b15 ldr r3, [pc, #84] ; (7c <ISR_EXTI15_10+0x7c>)
28: 699b ldr r3, [r3, #24]
2a: b10b cbz r3, 30 <ISR_EXTI15_10+0x30>
}
}
// ioClearInterrupt - Disables interrupts on the specified pin
void ioClearInterrupt(unsigned char pin) {
pin--;
2c: 2002 movs r0, #2
2e: 4798 blx r3
if (pin < 12 && pin != 9) {
30: f444 6400 orr.w r4, r4, #2048 ; 0x800
34: 04e9 lsls r1, r5, #19
36: d507 bpl.n 48 <ISR_EXTI15_10+0x48>
#define USART_CR3_CTSE ((uint16_t)0x0200)
// Disables FAULT interrupts
static inline void __disable_fault_irq() { asm volatile ("cpsid f"); }
// Disables interrupts
static inline void __disable_irq() { asm volatile ("cpsid i"); }
38: 4b10 ldr r3, [pc, #64] ; (7c <ISR_EXTI15_10+0x7c>)
extern volatile uint32_t _criticalNesting;
/* Enter a critical section. */
static INLINE void _enterCritical() {
__disable_irq();
_criticalNesting++;
3a: f8d3 3088 ldr.w r3, [r3, #136] ; 0x88
3e: b10b cbz r3, 44 <ISR_EXTI15_10+0x44>
40: 2009 movs r0, #9
42: 4798 blx r3
// Avoid having the OS swap this out
_enterCritical();
{
uint32_t mask = (uint32_t)1 << _pinIndexTable[pin + 1];
44: f444 5480 orr.w r4, r4, #4096 ; 0x1000
48: 04aa lsls r2, r5, #18
4a: d506 bpl.n 5a <ISR_EXTI15_10+0x5a>
// Clear pending interrupt
EXTI->PR |= mask;
4c: 4b0b ldr r3, [pc, #44] ; (7c <ISR_EXTI15_10+0x7c>)
4e: 6c9b ldr r3, [r3, #72] ; 0x48
50: b10b cbz r3, 56 <ISR_EXTI15_10+0x56>
52: 2005 movs r0, #5
// Mask interrupt
EXTI->IMR &= ~mask;
54: 4798 blx r3
56: f444 5400 orr.w r4, r4, #8192 ; 0x2000
5a: 046b lsls r3, r5, #17
}
/* Exit a critical section. */
static INLINE void _exitCritical() {
const uint32_t newCritical = _criticalNesting - 1;
5c: d506 bpl.n 6c <ISR_EXTI15_10+0x6c>
5e: 4b07 ldr r3, [pc, #28] ; (7c <ISR_EXTI15_10+0x7c>)
_criticalNesting = newCritical;
60: 6d9b ldr r3, [r3, #88] ; 0x58
if (newCritical == 0)
62: b10b cbz r3, 68 <ISR_EXTI15_10+0x68>
// Waits for memory accesses to complete before continuing (Data Synchronization Barrier)
static inline void __dsb() { asm volatile ("dsb"); }
// Enables FAULT interrupts
static inline void __enable_fault_irq() { asm volatile ("cpsie f"); }
// Enables interrupts
static inline void __enable_irq() { asm volatile ("cpsie i"); }
64: 2006 movs r0, #6
66: 4798 blx r3
68: f444 4480 orr.w r4, r4, #16384 ; 0x4000
6c: 6174 str r4, [r6, #20]
6e: e8bd 4079 ldmia.w sp!, {r0, r3, r4, r5, r6, lr}
72: 4685 mov sp, r0
_exitCritical();
}
}
// encoderShutdown - Stops and disables the encoder
void encoderShutdown(Encoder enc) {
74: 4770 bx lr
Sensor_TypeDef *encoder = (Sensor_TypeDef*)enc;
if (encoder) {
76: bf00 nop
78: 40010400 andmi r0, r1, r0, lsl #8
extern volatile uint32_t _criticalNesting;
/* Enter a critical section. */
static INLINE void _enterCritical() {
__disable_irq();
_criticalNesting++;
7c: 00000000 andeq r0, r0, r0
7c: R_ARM_ABS32 _sensorState
Disassembly of section .debug_info:
00000000 <.debug_info>:
#endif
// encoderGet - Gets the value of the encoder
int encoderGet(Encoder enc) {
Sensor_TypeDef *encoder = (Sensor_TypeDef*)enc;
if (encoder)
0: 000009a0 andeq r0, r0, r0, lsr #19
return (int)encoder->value;
return 0;
}
4: 00000004 andeq r0, r0, r4
6: R_ARM_ABS32 .debug_abbrev
}
// encoderReset - Resets the encoder to zero
void encoderReset(Encoder enc) {
Sensor_TypeDef *encoder = (Sensor_TypeDef*)enc;
if (encoder) {
8: 01040000 mrseq r0, (UNDEF: 4)
c: 000002d0 ldrdeq r0, [r0], -r0 ; <UNPREDICTABLE>
c: R_ARM_ABS32 .debug_str
10: 0000b601 andeq fp, r0, r1, lsl #12
11: R_ARM_ABS32 .debug_str
_enterCritical();
{
encoder->value = 0;
14: 00025900 andeq r5, r2, r0, lsl #18
15: R_ARM_ABS32 .debug_str
encoder->lastValue = 0;
18: 0000f800 andeq pc, r0, r0, lsl #16
19: R_ARM_ABS32 .debug_ranges
...
21: R_ARM_ABS32 .debug_line
24: 06010200 streq r0, [r1], -r0, lsl #4
28: 0000016a andeq r0, r0, sl, ror #2
28: R_ARM_ABS32 .debug_str
}
}
// ioClearInterrupt - Disables interrupts on the specified pin
void ioClearInterrupt(unsigned char pin) {
pin--;
2c: 00011f03 andeq r1, r1, r3, lsl #30
2d: R_ARM_ABS32 .debug_str
if (pin < 12 && pin != 9) {
30: 371d0400 ldrcc r0, [sp, -r0, lsl #8]
34: 02000000 andeq r0, r0, #0
#define USART_CR3_CTSE ((uint16_t)0x0200)
// Disables FAULT interrupts
static inline void __disable_fault_irq() { asm volatile ("cpsid f"); }
// Disables interrupts
static inline void __disable_irq() { asm volatile ("cpsid i"); }
38: 01440801 cmpeq r4, r1, lsl #16
3a: R_ARM_ABS32 .debug_str
// Avoid having the OS swap this out
_enterCritical();
{
uint32_t mask = (uint32_t)1 << _pinIndexTable[pin + 1];
3c: 02020000 andeq r0, r2, #0
40: 00008105 andeq r8, r0, r5, lsl #2
41: R_ARM_ABS32 .debug_str
44: 006e0300 rsbeq r0, lr, r0, lsl #6
46: R_ARM_ABS32 .debug_str
48: 2b040000 blcs 100050 <encoderGet+0x100050>
// Clear pending interrupt
EXTI->PR |= mask;
4c: 00000050 andeq r0, r0, r0, asr r0
50: bc070202 sfmlt f0, 4, [r7], {2}
53: R_ARM_ABS32 .debug_str
// Mask interrupt
EXTI->IMR &= ~mask;
54: 03000001 movweq r0, #1
58: 00000298 muleq r0, r8, r2
58: R_ARM_ABS32 .debug_str
}
/* Exit a critical section. */
static INLINE void _exitCritical() {
const uint32_t newCritical = _criticalNesting - 1;
5c: 00623f04 rsbeq r3, r2, r4, lsl #30
_criticalNesting = newCritical;
60: 04020000 streq r0, [r2], #-0
// Waits for memory accesses to complete before continuing (Data Synchronization Barrier)
static inline void __dsb() { asm volatile ("dsb"); }
// Enables FAULT interrupts
static inline void __enable_fault_irq() { asm volatile ("cpsie f"); }
// Enables interrupts
static inline void __enable_irq() { asm volatile ("cpsie i"); }
64: 0001ef05 andeq lr, r1, r5, lsl #30
65: R_ARM_ABS32 .debug_str
68: 00630300 rsbeq r0, r3, r0, lsl #6
6a: R_ARM_ABS32 .debug_str
6c: 41040000 mrsmi r0, (UNDEF: 4)
70: 00000074 andeq r0, r0, r4, ror r0
_exitCritical();
}
}
// encoderShutdown - Stops and disables the encoder
void encoderShutdown(Encoder enc) {
74: 2a070402 bcs 1c1010 <encoderGet+0x1c1010>
77: R_ARM_ABS32 .debug_str
Sensor_TypeDef *encoder = (Sensor_TypeDef*)enc;
if (encoder) {
78: 02000002 andeq r0, r0, #2
extern volatile uint32_t _criticalNesting;
/* Enter a critical section. */
static INLINE void _enterCritical() {
__disable_irq();
_criticalNesting++;
7c: 00cd0508 sbceq r0, sp, r8, lsl #10
7e: R_ARM_ABS32 .debug_str
80: 08020000 stmdaeq r2, {} ; <UNPREDICTABLE>
84: 00017c07 andeq r7, r1, r7, lsl #24
85: R_ARM_ABS32 .debug_str
_enterCritical();
{
// Stop
encoder->flags = 0;
_sensorState[encoder->portBottom].flags = 0;
88: 05040400 streq r0, [r4, #-1024] ; 0xfffffc00
8c: 00746e69 rsbseq r6, r4, r9, ror #28
90: a2070402 andge r0, r7, #33554432 ; 0x2000000
93: R_ARM_ABS32 .debug_str
// Clear interrupts
ioClearInterrupt(encoder->portTop);
94: 03000001 movweq r0, #1
ioClearInterrupt(encoder->portBottom);
98: 000002b2 ; <UNDEFINED> instruction: 0x000002b2
98: R_ARM_ABS32 .debug_str
9c: 002c1405 eoreq r1, ip, r5, lsl #8
}
/* Exit a critical section. */
static INLINE void _exitCritical() {
const uint32_t newCritical = _criticalNesting - 1;
a0: e6030000 str r0, [r3], -r0
a3: R_ARM_ABS32 .debug_str
_criticalNesting = newCritical;
if (newCritical == 0)
a4: 05000001 streq r0, [r0, #-1]
a8: 0000451a andeq r4, r0, sl, lsl r5
ac: 01f80300 mvnseq r0, r0, lsl #6
ae: R_ARM_ABS32 .debug_str
b0: 1f050000 svcne 0x00050000
}
// ioSetInterrupt - Sets up an interrupt to occur on the specified pin, and resets count & time
// Provide NULL for handler for standard interrupts, or pass function pointer for custom
void ioSetInterrupt(unsigned char pin, unsigned char edges, InterruptHandler handler) {
pin--;
b4: 00000057 andeq r0, r0, r7, asr r0
if (pin < BOARD_NR_DIGITAL_IO && pin != 9) {
b8: 00019303 andeq r9, r1, r3, lsl #6
b9: R_ARM_ABS32 .debug_str
bc: 69200500 stmdbvs r0!, {r8, sl}
c0: 02000000 andeq r0, r0, #0
extern volatile uint32_t _criticalNesting;
/* Enter a critical section. */
static INLINE void _enterCritical() {
__disable_irq();
_criticalNesting++;
c4: 003a0704 eorseq r0, sl, r4, lsl #14
c6: R_ARM_ABS32 .debug_str
c8: 04050000 streq r0, [r5], #-0
// Configure freely, we won't have an issue here since interrupt is masked
Sensor_TypeDef *state = &_sensorState[pin];
state->eventTrigger = handler;
// Falling edge configuration
temp = EXTI->FTSR;
if (edges & INTERRUPT_EDGE_FALLING)
cc: f2060102 vrhadd.s8 d0, d6, d2
cf: R_ARM_ABS32 .debug_str
d0: 06000000 streq r0, [r0], -r0
if (pin < BOARD_NR_DIGITAL_IO && pin != 9) {
// Avoid having the OS swap this out during init
_enterCritical();
{
// In range, start by masking interrupt if enabled
uint32_t mask = (uint32_t)1 << _pinIndexTable[pin + 1], temp;
d4: 000000b8 strheq r0, [r0], -r8
d8: 04021807 streq r1, [r2], #-2055 ; 0xfffff7f9
dc: 00012f01 andeq r2, r1, r1, lsl #30
EXTI->IMR &= ~mask;
e0: 4d490800 stclmi 8, cr0, [r9, #-0]
e4: 06020052 ; <UNDEFINED> instruction: 0x06020052
e8: 0000d301 andeq sp, r0, r1, lsl #6
// Configure freely, we won't have an issue here since interrupt is masked
Sensor_TypeDef *state = &_sensorState[pin];
state->eventTrigger = handler;
ec: 45080000 strmi r0, [r8, #-0]
f0: 0200524d andeq r5, r0, #-805306364 ; 0xd0000004
// Falling edge configuration
temp = EXTI->FTSR;
f4: 00d30108 sbcseq r0, r3, r8, lsl #2
if (edges & INTERRUPT_EDGE_FALLING)
temp |= mask;
f8: 09040000 stmdbeq r4, {} ; <UNPREDICTABLE>
else
temp &= ~mask;
EXTI->FTSR = temp;
fc: 00000206 andeq r0, r0, r6, lsl #4
fc: R_ARM_ABS32 .debug_str
// Rising edge configuration
temp = EXTI->RTSR;
if (edges & INTERRUPT_EDGE_RISING)
100: d3010a02 movwle r0, #6658 ; 0x1a02
temp |= mask;
104: 08000000 stmdaeq r0, {} ; <UNPREDICTABLE>
else
temp &= ~mask;
108: 0001af09 andeq sl, r1, r9, lsl #30
109: R_ARM_ABS32 .debug_str
EXTI->RTSR = temp;
10c: 010c0200 mrseq r0, R12_fiq
// Clear pending interrupt
EXTI->PR |= mask;
110: 000000d3 ldrdeq r0, [r0], -r3
// Unmask interrupt to start monitoring
EXTI->IMR |= mask;
114: 0200090c andeq r0, r0, #12, 18 ; 0x30000
116: R_ARM_ABS32 .debug_str
118: 0e020000 cdpeq 0, 0, cr0, cr2, cr0, {0}
}
/* Exit a critical section. */
static INLINE void _exitCritical() {
const uint32_t newCritical = _criticalNesting - 1;
11c: 0000d301 andeq sp, r0, r1, lsl #6
_criticalNesting = newCritical;
if (newCritical == 0)
120: 50081000 andpl r1, r8, r0
124: 10020052 andne r0, r2, r2, asr r0
128: 0000d301 andeq sp, r0, r1, lsl #6
12c: 0a001400 beq 5134 <encoderGet+0x5134>
130: 00000108 andeq r0, r0, r8, lsl #2
130: R_ARM_ABS32 .debug_str
134: d8011102 stmdale r1, {r1, r8, ip}
return (int)encoder->value;
return 0;
}
// encoderInit - Initializes and enables a quadrature encoder on two digital ports
Encoder encoderInit(unsigned char portTop, unsigned char portBottom, bool reverse) {
138: 06000000 streq r0, [r0], -r0
Sensor_TypeDef *encoder, *slave;
// Change to 0..11 range
uint32_t it = portTop - 1, ib = portBottom - 1;
13c: 000000a2 andeq r0, r0, r2, lsr #1
return (int)encoder->value;
return 0;
}
// encoderInit - Initializes and enables a quadrature encoder on two digital ports
Encoder encoderInit(unsigned char portTop, unsigned char portBottom, bool reverse) {
140: 0000f703 andeq pc, r0, r3, lsl #14
141: R_ARM_ABS32 .debug_str
Sensor_TypeDef *encoder, *slave;
// Change to 0..11 range
uint32_t it = portTop - 1, ib = portBottom - 1;
144: 4b740600 blmi 1d0194c <encoderGet+0x1d0194c>
// Check range
if (it < BOARD_NR_DIGITAL_IO && it != 9 && _sensorState[it].flags == 0 &&
148: 0b000001 bleq 154 <.debug_info+0x154>
14c: 00015104 andeq r5, r1, r4, lsl #2
150: 015c0c00 cmpeq ip, r0, lsl #24
154: 370d0000 strcc r0, [sp, -r0]
158: 00000000 andeq r0, r0, r0
15c: 7906100e stmdbvc r6, {r1, r2, r3, ip}
160: 000001ad andeq r0, r0, sp, lsr #3
ib < BOARD_NR_DIGITAL_IO && ib != 9 && _sensorState[ib].flags == 0) {
164: 0000930f andeq r9, r0, pc, lsl #6
165: R_ARM_ABS32 .debug_str
168: ad7b0600 ldclge 6, cr0, [fp, #-0]
16c: 00000001 andeq r0, r0, r1
170: 0001760f andeq r7, r1, pc, lsl #12
171: R_ARM_ABS32 .debug_str
174: 3b7c0600 blcc 1f0197c <encoderGet+0x1f0197c>
178: 04000001 streq r0, [r0], #-1
17c: 0002c80f andeq ip, r2, pc, lsl #16
17d: R_ARM_ABS32 .debug_str
extern volatile uint32_t _criticalNesting;
/* Enter a critical section. */
static INLINE void _enterCritical() {
__disable_irq();
_criticalNesting++;
180: b27e0600 rsbslt r0, lr, #0, 12
{
uint16_t flags = (uint16_t)0x0002 | (uint16_t)(reverse ? 0x01 : 0x00);
encoder = &_sensorState[it];
slave = &_sensorState[ib];
// Set pins to input pull-up
pinMode(portTop, DDR_INPUT_PULLUP);
184: 06000001 streq r0, [r0], -r1
188: 00038a0f andeq r8, r3, pc, lsl #20
189: R_ARM_ABS32 .debug_str
// Check range
if (it < BOARD_NR_DIGITAL_IO && it != 9 && _sensorState[it].flags == 0 &&
ib < BOARD_NR_DIGITAL_IO && ib != 9 && _sensorState[ib].flags == 0) {
_enterCritical();
{
uint16_t flags = (uint16_t)0x0002 | (uint16_t)(reverse ? 0x01 : 0x00);
18c: b27f0600 rsbslt r0, pc, #0, 12
190: 07000001 streq r0, [r0, -r1]
encoder = &_sensorState[it];
slave = &_sensorState[ib];
// Set pins to input pull-up
pinMode(portTop, DDR_INPUT_PULLUP);
194: 0000000f andeq r0, r0, pc
195: R_ARM_ABS32 .debug_str
pinMode(portBottom, DDR_INPUT_PULLUP);
198: b7810600 strlt r0, [r1, r0, lsl #12]
19c: 08000001 stmdaeq r0, {r0}
// Set state of master pin (top)
encoder->flags = flags;
encoder->portTop = (uint8_t)portTop;
encoder->portBottom = (uint8_t)portBottom;
encoder->value = 0;
1a0: 0001150f andeq r1, r1, pc, lsl #10
1a1: R_ARM_ABS32 .debug_str
slave = &_sensorState[ib];
// Set pins to input pull-up
pinMode(portTop, DDR_INPUT_PULLUP);
pinMode(portBottom, DDR_INPUT_PULLUP);
// Set state of master pin (top)
encoder->flags = flags;
1a4: d3830600 orrle r0, r3, #0, 12
// Set slaved state
slave->flags = flags;
slave->portTop = (uint8_t)portTop;
slave->portBottom = (uint8_t)portBottom;
// Interrupt per-port on either rising or falling edge
ioSetInterrupt(portTop, INTERRUPT_EDGE_BOTH, _encoderISRTop);
1a8: 0c000000 stceq 0, cr0, [r0], {-0}
// Set pins to input pull-up
pinMode(portTop, DDR_INPUT_PULLUP);
pinMode(portBottom, DDR_INPUT_PULLUP);
// Set state of master pin (top)
encoder->flags = flags;
encoder->portTop = (uint8_t)portTop;
1ac: 00ad0600 adceq r0, sp, r0, lsl #12
encoder->portBottom = (uint8_t)portBottom;
1b0: 97060000 strls r0, [r6, -r0]
encoder->value = 0;
1b4: 06000000 streq r0, [r0], -r0
encoder->lastValue = 0;
1b8: 00000140 andeq r0, r0, r0, asr #2
// Set slaved state
slave->flags = flags;
1bc: 00004303 andeq r4, r0, r3, lsl #6
1bd: R_ARM_ABS32 .debug_str
slave->portTop = (uint8_t)portTop;
1c0: 5c840600 stcpl 6, cr0, [r4], {0}
slave->portBottom = (uint8_t)portBottom;
1c4: 03000001 movweq r0, #1
// Interrupt per-port on either rising or falling edge
ioSetInterrupt(portTop, INTERRUPT_EDGE_BOTH, _encoderISRTop);
1c8: 000001b4 ; <UNDEFINED> instruction: 0x000001b4
1c8: R_ARM_ABS32 .debug_str
ioSetInterrupt(portBottom, INTERRUPT_EDGE_BOTH, _encoderISRBottom);
1cc: 00ca9206 sbceq r9, sl, r6, lsl #4
1d0: db100000 blle 400008 <encoderGet+0x400008>
1d3: R_ARM_ABS32 .debug_str
}
/* Exit a critical section. */
static INLINE void _exitCritical() {
const uint32_t newCritical = _criticalNesting - 1;
1d4: 03000000 movweq r0, #0
1d8: 2c11034a ldccs 3, cr0, [r1], {74} ; 0x4a
1db: R_ARM_ABS32 .debug_str
_criticalNesting = newCritical;
1dc: 03000000 movweq r0, #0
1e0: 01f20350 mvnseq r0, r0, asr r3
}
_exitCritical();
return (Encoder)encoder;
}
return NULL;
1e4: 3c120000 ldccc 0, cr0, [r2], {-0}
1e7: R_ARM_ABS32 .debug_str
1e8: 03000002 movweq r0, #2
// Interrupt per-port on either rising or falling edge
ioSetInterrupt(portTop, INTERRUPT_EDGE_BOTH, _encoderISRTop);
ioSetInterrupt(portBottom, INTERRUPT_EDGE_BOTH, _encoderISRBottom);
}
_exitCritical();
return (Encoder)encoder;
1ec: 0001f251 andeq pc, r1, r1, asr r2 ; <UNPREDICTABLE>
}
return NULL;
}
1f0: b8130000 ldmdalt r3, {} ; <UNPREDICTABLE>
1f4: 14000000 strne r0, [r0], #-0
1f8: 00000152 andeq r0, r0, r2, asr r1
1f8: R_ARM_ABS32 .debug_str
1fc: 1a03cc01 bne f3208 <encoderGet+0xf3208>
200: 15000002 strne r0, [r0, #-2]
if (handler != NULL)
handler(pin + 1);
}
// External interrupts all Px0 pins (PD0/Digital 11)
IRQ ISR_EXTI0() {
204: 006e6970 rsbeq r6, lr, r0, ror r9
208: 00b8cc01 adcseq ip, r8, r1, lsl #24
}
}
// Fires off the external interrupt logic for a given pin
static INLINE void triggerEXTI(uint32_t pin) {
InterruptHandler handler = _sensorState[pin].eventTrigger;
20c: 79120000 ldmdbvc r2, {} ; <UNPREDICTABLE>
20f: R_ARM_ABS32 .debug_str
210: 01000000 mrseq r0, (UNDEF: 0)
if (handler != NULL)
214: 000140cd andeq r4, r1, sp, asr #1
handler(pin + 1);
218: 7f160000 svcvc 0x00160000
21b: R_ARM_ABS32 .debug_str
// External interrupts all Px0 pins (PD0/Digital 11)
IRQ ISR_EXTI0() {
// We assume that this can only fire if unmasked (therefore, wanted)
triggerEXTI(10);
EXTI->PR = (uint32_t)0x0001;
}
21c: 01000003 tsteq r0, r3
// External interrupts all Px0 pins (PD0/Digital 11)
IRQ ISR_EXTI0() {
// We assume that this can only fire if unmasked (therefore, wanted)
triggerEXTI(10);
EXTI->PR = (uint32_t)0x0001;
220: 0000894c andeq r8, r0, ip, asr #18
}
224: 00000000 andeq r0, r0, r0
225: R_ARM_ABS32 .text.encoderGet
228: 00000600 andeq r0, r0, r0, lsl #12
22c: 529c0100 addspl r0, ip, #0, 2
// External interrupts all Px1 pins (PD1/Digital 12)
IRQ ISR_EXTI1() {
230: 17000002 strne r0, [r0, -r2]
234: 00636e65 rsbeq r6, r3, r5, ror #28
}
}
// Fires off the external interrupt logic for a given pin
static INLINE void triggerEXTI(uint32_t pin) {
InterruptHandler handler = _sensorState[pin].eventTrigger;
238: 01c74c01 biceq r4, r7, r1, lsl #24
23c: 00000000 andeq r0, r0, r0
23e: R_ARM_ABS32 .debug_loc
if (handler != NULL)
240: c0180000 andsgt r0, r8, r0
243: R_ARM_ABS32 .debug_str
handler(pin + 1);
244: 01000002 tsteq r0, r2
// External interrupts all Px1 pins (PD1/Digital 12)
IRQ ISR_EXTI1() {
// We assume that this can only fire if unmasked (therefore, wanted)
triggerEXTI(11);
EXTI->PR = (uint32_t)0x0002;
}
248: 0002524d andeq r5, r2, sp, asr #4
// External interrupts all Px1 pins (PD1/Digital 12)
IRQ ISR_EXTI1() {
// We assume that this can only fire if unmasked (therefore, wanted)
triggerEXTI(11);
EXTI->PR = (uint32_t)0x0002;
24c: 00000000 andeq r0, r0, r0
24d: R_ARM_ABS32 .debug_loc
}
250: 040b0000 streq r0, [fp], #-0
254: 000001bc ; <UNDEFINED> instruction: 0x000001bc
258: 00013619 andeq r3, r1, r9, lsl r6
259: R_ARM_ABS32 .debug_str
// External interrupts all Px5-Px9 pins
// (PC6/Digital 3, PC7/Digital 4, PE8/Digital 7, PE9/Digital 1)
IRQ ISR_EXTI9_5() {
25c: 055d0200 ldrbeq r0, [sp, #-512] ; 0xfffffe00
260: 01291903 ; <UNDEFINED> instruction: 0x01291903
262: R_ARM_ABS32 .debug_str
264: 65020000 strvs r0, [r2, #-0]
uint32_t pending = EXTI->PR, reset = 0;
268: c01a0305 andsgt r0, sl, r5, lsl #6
26b: R_ARM_ABS32 .debug_str
if (pending & (uint32_t)0x0040) {
26c: 01000000 mrseq r0, (UNDEF: 0)
270: 00000078 andeq r0, r0, r8, ror r0
271: R_ARM_ABS32 .text.encoderReset
}
}
// Fires off the external interrupt logic for a given pin
static INLINE void triggerEXTI(uint32_t pin) {
InterruptHandler handler = _sensorState[pin].eventTrigger;
274: 00002400 andeq r2, r0, r0, lsl #8
if (handler != NULL)
handler(pin + 1);
278: ef9c0100 svc 0x009c0100
IRQ ISR_EXTI9_5() {
uint32_t pending = EXTI->PR, reset = 0;
if (pending & (uint32_t)0x0040) {
// PC6 fired
triggerEXTI(2);
reset |= (uint32_t)0x0040;
27c: 1b000002 blne 28c <.debug_info+0x28c>
}
if (pending & (uint32_t)0x0080) {
280: 00636e65 rsbeq r6, r3, r5, ror #28
}
}
// Fires off the external interrupt logic for a given pin
static INLINE void triggerEXTI(uint32_t pin) {
InterruptHandler handler = _sensorState[pin].eventTrigger;
284: 01c77801 biceq r7, r7, r1, lsl #16
if (handler != NULL)
handler(pin + 1);
288: 50010000 andpl r0, r1, r0
reset |= (uint32_t)0x0040;
}
if (pending & (uint32_t)0x0080) {
// PC7 fired
triggerEXTI(3);
reset |= (uint32_t)0x0080;
28c: 0002c01c andeq ip, r2, ip, lsl r0
28d: R_ARM_ABS32 .debug_str
}
if (pending & (uint32_t)0x0100) {
290: 52790100 rsbspl r0, r9, #0, 2
}
}
// Fires off the external interrupt logic for a given pin
static INLINE void triggerEXTI(uint32_t pin) {
InterruptHandler handler = _sensorState[pin].eventTrigger;
294: 01000002 tsteq r0, r2
if (handler != NULL)
298: 01d21d50 bicseq r1, r2, r0, asr sp
handler(pin + 1);
29c: 00020000 andeq r0, r2, r0
29e: R_ARM_ABS32 .text.encoderReset
reset |= (uint32_t)0x0080;
}
if (pending & (uint32_t)0x0100) {
// PE8 fired
triggerEXTI(6);
reset |= (uint32_t)0x0100;
2a0: 000a0000 andeq r0, sl, r0
}
if (pending & (uint32_t)0x0200) {
2a4: 7b010000 blvc 402ac <encoderGet+0x402ac>
}
}
// Fires off the external interrupt logic for a given pin
static INLINE void triggerEXTI(uint32_t pin) {
InterruptHandler handler = _sensorState[pin].eventTrigger;
2a8: 000002bc ; <UNDEFINED> instruction: 0x000002bc
if (handler != NULL)
handler(pin + 1);
2ac: 0002581e andeq r5, r2, lr, lsl r8
reset |= (uint32_t)0x0100;
}
if (pending & (uint32_t)0x0200) {
// PE9 fired
triggerEXTI(0);
reset |= (uint32_t)0x0200;
2b0: 00000200 andeq r0, r0, r0, lsl #4
2b1: R_ARM_ABS32 .text.encoderReset
}
EXTI->PR = reset;
2b4: 00000200 andeq r0, r0, r0, lsl #4
}
2b8: 004b0300 subeq r0, fp, r0, lsl #6
2bc: 0001da1f andeq sp, r1, pc, lsl sl
2c0: 00001200 andeq r1, r0, r0, lsl #4
2c1: R_ARM_ABS32 .text.encoderReset
2c4: 00001200 andeq r1, r0, r0, lsl #4
// External interrupts all Px10-Px15 pins
// (PE10/Digital 8, PE11/Digital 2, PE12/Digital 9, PE13/Digital 5, PE14/Digital 6)
IRQ ISR_EXTI15_10() {
2c8: 20800100 addcs r0, r0, r0, lsl #2
2cc: 00000012 andeq r0, r0, r2, lsl r0
2cc: R_ARM_ABS32 .text.encoderReset
2d0: 00000012 andeq r0, r0, r2, lsl r0
uint32_t pending = EXTI->PR, reset = 0;
2d4: 0001e621 andeq lr, r1, r1, lsr #12
if (pending & (uint32_t)0x0400) {
2d8: 00002100 andeq r2, r0, r0, lsl #2
2d9: R_ARM_ABS32 .debug_loc
}
}
// Fires off the external interrupt logic for a given pin
static INLINE void triggerEXTI(uint32_t pin) {
InterruptHandler handler = _sensorState[pin].eventTrigger;
2dc: 02611e00 rsbeq r1, r1, #0, 28
if (handler != NULL)
2e0: 001a0000 andseq r0, sl, r0
2e2: R_ARM_ABS32 .text.encoderReset
handler(pin + 1);
2e4: 000a0000 andeq r0, sl, r0
IRQ ISR_EXTI15_10() {
uint32_t pending = EXTI->PR, reset = 0;
if (pending & (uint32_t)0x0400) {
// PE10 fired
triggerEXTI(7);
reset |= (uint32_t)0x0400;
2e8: 54030000 strpl r0, [r3], #-0
}
if (pending & (uint32_t)0x0800) {
2ec: 1a000000 bne 2f4 <.debug_info+0x2f4>
}
}
// Fires off the external interrupt logic for a given pin
static INLINE void triggerEXTI(uint32_t pin) {
InterruptHandler handler = _sensorState[pin].eventTrigger;
2f0: 00000248 andeq r0, r0, r8, asr #4
2f0: R_ARM_ABS32 .debug_str
if (handler != NULL)
handler(pin + 1);
2f4: 00009601 andeq r9, r0, r1, lsl #12
2f6: R_ARM_ABS32 .text.ioClearInterrupt
reset |= (uint32_t)0x0400;
}
if (pending & (uint32_t)0x0800) {
// PE11 fired
triggerEXTI(1);
reset |= (uint32_t)0x0800;
2f8: 00480000 subeq r0, r8, r0
}
if (pending & (uint32_t)0x1000) {
2fc: 9c010000 stcls 0, cr0, [r1], {-0}
}
}
// Fires off the external interrupt logic for a given pin
static INLINE void triggerEXTI(uint32_t pin) {
InterruptHandler handler = _sensorState[pin].eventTrigger;
300: 00000382 andeq r0, r0, r2, lsl #7
304: 6e697017 mcrvs 0, 3, r7, cr9, cr7, {0}
if (handler != NULL)
handler(pin + 1);
308: 37960100 ldrcc r0, [r6, r0, lsl #2]
reset |= (uint32_t)0x0800;
}
if (pending & (uint32_t)0x1000) {
// PE12 fired
triggerEXTI(8);
reset |= (uint32_t)0x1000;
30c: 34000000 strcc r0, [r0], #-0
30f: R_ARM_ABS32 .debug_loc
}
if (pending & (uint32_t)0x2000) {
310: 22000000 andcs r0, r0, #0
}
}
// Fires off the external interrupt logic for a given pin
static INLINE void triggerEXTI(uint32_t pin) {
InterruptHandler handler = _sensorState[pin].eventTrigger;
314: 000001d2 ldrdeq r0, [r0], -r2
if (handler != NULL)
318: 0000000c andeq r0, r0, ip
318: R_ARM_ABS32 .text.ioClearInterrupt
handler(pin + 1);
31c: 00000000 andeq r0, r0, r0
31c: R_ARM_ABS32 .debug_ranges
reset |= (uint32_t)0x1000;
}
if (pending & (uint32_t)0x2000) {
// PE13 fired
triggerEXTI(4);
reset |= (uint32_t)0x2000;
320: 03369a01 teqeq r6, #4096 ; 0x1000
}
if (pending & (uint32_t)0x4000) {
324: 581e0000 ldmdapl lr, {} ; <UNPREDICTABLE>
}
}
// Fires off the external interrupt logic for a given pin
static INLINE void triggerEXTI(uint32_t pin) {
InterruptHandler handler = _sensorState[pin].eventTrigger;
328: 0c000002 stceq 0, cr0, [r0], {2}
32b: R_ARM_ABS32 .text.ioClearInterrupt
if (handler != NULL)
handler(pin + 1);
32c: 02000000 andeq r0, r0, #0
reset |= (uint32_t)0x2000;
}
if (pending & (uint32_t)0x4000) {
// PE14 fired
triggerEXTI(5);
reset |= (uint32_t)0x4000;
330: 03000000 movweq r0, #0
}
EXTI->PR = reset;
334: 1823004b stmdane r3!, {r0, r1, r3, r6}
337: R_ARM_ABS32 .debug_ranges
}
338: 4f000000 svcmi 0x00000000
33c: 18000003 stmdane r0, {r0, r1}
340: 0000028d andeq r0, r0, sp, lsl #5
340: R_ARM_ABS32 .debug_str
344: 00b89c01 adcseq r9, r8, r1, lsl #24
348: 00600000 rsbeq r0, r0, r0
34a: R_ARM_ABS32 .debug_loc
34c: 1f000000 svcne 0x00000000
350: 000001da ldrdeq r0, [r0], -sl
354: 00000030 andeq r0, r0, r0, lsr r0
354: R_ARM_ABS32 .text.ioClearInterrupt
358: 00000018 andeq r0, r0, r8, lsl r0
35c: 3020a201 eorcc sl, r0, r1, lsl #4
35f: R_ARM_ABS32 .text.ioClearInterrupt
360: 18000000 stmdane r0, {} ; <UNPREDICTABLE>
364: 21000000 mrscs r0, (UNDEF: 0)
368: 000001e6 andeq r0, r0, r6, ror #3
36c: 00000073 andeq r0, r0, r3, ror r0
36c: R_ARM_ABS32 .debug_loc
370: 0002611e andeq r6, r2, lr, lsl r1
374: 00003800 andeq r3, r0, r0, lsl #16
375: R_ARM_ABS32 .text.ioClearInterrupt
378: 00001000 andeq r1, r0, r0
37c: 00540300 subseq r0, r4, r0, lsl #6
380: a21a0000 andsge r0, sl, #0
383: R_ARM_ABS32 .debug_str
384: 01000002 tsteq r0, r2
388: 00000085 andeq r0, r0, r5, lsl #1
389: R_ARM_ABS32 .text.encoderShutdown
38c: 00004000 andeq r4, r0, r0
390: 219c0100 orrscs r0, ip, r0, lsl #2
394: 17000004 strne r0, [r0, -r4]
398: 00636e65 rsbeq r6, r3, r5, ror #28
39c: 01c78501 biceq r8, r7, r1, lsl #10
3a0: 00860000 addeq r0, r6, r0
3a2: R_ARM_ABS32 .debug_loc
3a4: c0180000 andsgt r0, r8, r0
3a7: R_ARM_ABS32 .debug_str
3a8: 01000002 tsteq r0, r2
3ac: 00025286 andeq r5, r2, r6, lsl #5
3b0: 00008600 andeq r8, r0, r0, lsl #12
3b1: R_ARM_ABS32 .debug_loc
3b4: 01d22200 bicseq r2, r2, r0, lsl #4
3b8: 00060000 andeq r0, r6, r0
3ba: R_ARM_ABS32 .text.encoderShutdown
3bc: 00300000 eorseq r0, r0, r0
3be: R_ARM_ABS32 .debug_ranges
3c0: 88010000 stmdahi r1, {} ; <UNPREDICTABLE>
3c4: 000003d8 ldrdeq r0, [r0], -r8
3c8: 0002581e andeq r5, r2, lr, lsl r8
3cc: 00000600 andeq r0, r0, r0, lsl #12
3cd: R_ARM_ABS32 .text.encoderShutdown
3d0: 00000200 andeq r0, r0, r0, lsl #4
3d4: 004b0300 subeq r0, fp, r0, lsl #6
3d8: 0001da1d andeq sp, r1, sp, lsl sl
3dc: 00002a00 andeq r2, r0, r0, lsl #20
3dd: R_ARM_ABS32 .text.encoderShutdown
3e0: 00001600 andeq r1, r0, r0, lsl #12
3e4: 0e910100 fmleqs f0, f1, f0
3e8: 20000004 andcs r0, r0, r4
3ec: 0000002a andeq r0, r0, sl, lsr #32
3ec: R_ARM_ABS32 .text.encoderShutdown
3f0: 00000016 andeq r0, r0, r6, lsl r0
3f4: 0001e621 andeq lr, r1, r1, lsr #12
3f8: 0000b200 andeq fp, r0, r0, lsl #4
3f9: R_ARM_ABS32 .debug_loc
3fc: 02611e00 rsbeq r1, r1, #0, 28
400: 00320000 eorseq r0, r2, r0
402: R_ARM_ABS32 .text.encoderShutdown
404: 000e0000 andeq r0, lr, r0
408: 54030000 strpl r0, [r3], #-0
40c: 24240000 strtcs r0, [r4], #-0
40f: R_ARM_ABS32 .text.encoderShutdown
410: ef000000 svc 0x00000000
414: 24000002 strcs r0, [r0], #-2
418: 0000002a andeq r0, r0, sl, lsr #32
418: R_ARM_ABS32 .text.encoderShutdown
41c: 000002ef andeq r0, r0, pc, ror #5
420: 01cf1a00 biceq r1, pc, r0, lsl #20
422: R_ARM_ABS32 .debug_str
424: a8010000 stmdage r1, {} ; <UNPREDICTABLE>
428: 00000000 andeq r0, r0, r0
428: R_ARM_ABS32 .text.ioSetInterrupt
42c: 00000084 andeq r0, r0, r4, lsl #1
430: 04ee9c01 strbteq r9, [lr], #3073 ; 0xc01
434: 70170000 andsvc r0, r7, r0
438: 01006e69 tsteq r0, r9, ror #28
43c: 000037a8 andeq r3, r0, r8, lsr #15
440: 0000c500 andeq ip, r0, r0, lsl #10
441: R_ARM_ABS32 .debug_loc
444: 02ba2500 adcseq r2, sl, #0, 10
446: R_ARM_ABS32 .debug_str
448: a8010000 stmdage r1, {} ; <UNPREDICTABLE>
44c: 00000037 andeq r0, r0, r7, lsr r0
450: 000000f1 strdeq r0, [r0], -r1
450: R_ARM_ABS32 .debug_loc
454: 00007926 andeq r7, r0, r6, lsr #18
455: R_ARM_ABS32 .debug_str
458: 40a80100 adcmi r0, r8, r0, lsl #2
45c: 01000001 tsteq r0, r1
460: 01d22252 bicseq r2, r2, r2, asr r2
464: 000e0000 andeq r0, lr, r0
466: R_ARM_ABS32 .text.ioSetInterrupt
468: 00480000 subeq r0, r8, r0
46a: R_ARM_ABS32 .debug_ranges
46c: ac010000 stcge 0, cr0, [r1], {-0}
470: 00000484 andeq r0, r0, r4, lsl #9
474: 0002581e andeq r5, r2, lr, lsl r8
478: 00000e00 andeq r0, r0, r0, lsl #28
479: R_ARM_ABS32 .text.ioSetInterrupt
47c: 00000200 andeq r0, r0, r0, lsl #4
480: 004b0300 subeq r0, fp, r0, lsl #6
484: 00006823 andeq r6, r0, r3, lsr #16
485: R_ARM_ABS32 .debug_ranges
488: 0004bb00 andeq fp, r4, r0, lsl #22
48c: 028d1800 addeq r1, sp, #0, 16
48e: R_ARM_ABS32 .debug_str
490: af010000 svcge 0x00010000
494: 000000b8 strheq r0, [r0], -r8
498: 00000112 andeq r0, r0, r2, lsl r1
498: R_ARM_ABS32 .debug_loc
49c: 00002718 andeq r2, r0, r8, lsl r7
49d: R_ARM_ABS32 .debug_str
4a0: b8af0100 stmialt pc!, {r8} ; <UNPREDICTABLE>
4a4: 33000000 movwcc r0, #0
4a7: R_ARM_ABS32 .debug_loc
4a8: 18000001 stmdane r0, {r0}
4ac: 00000021 andeq r0, r0, r1, lsr #32
4ac: R_ARM_ABS32 .debug_str
4b0: 0252b201 subseq fp, r2, #268435456 ; 0x10000000
4b4: 015d0000 cmpeq sp, r0
4b6: R_ARM_ABS32 .debug_loc
4b8: 1f000000 svcne 0x00000000
4bc: 000001da ldrdeq r0, [r0], -sl
4c0: 00000066 andeq r0, r0, r6, rrx
4c0: R_ARM_ABS32 .text.ioSetInterrupt
4c4: 0000001e andeq r0, r0, lr, lsl r0
4c8: 6620c701 strtvs ip, [r0], -r1, lsl #14
4cb: R_ARM_ABS32 .text.ioSetInterrupt
4cc: 1e000000 cdpne 0, 0, cr0, cr0, cr0, {0}
4d0: 21000000 mrscs r0, (UNDEF: 0)
4d4: 000001e6 andeq r0, r0, r6, ror #3
4d8: 0000017a andeq r0, r0, sl, ror r1
4d8: R_ARM_ABS32 .debug_loc
4dc: 0002611e andeq r6, r2, lr, lsl r1
4e0: 00006e00 andeq r6, r0, r0, lsl #28
4e1: R_ARM_ABS32 .text.ioSetInterrupt
4e4: 00001600 andeq r1, r0, r0, lsl #12
4e8: 00540300 subseq r0, r4, r0, lsl #6
4ec: 5e160000 cdppl 0, 1, cr0, cr6, cr0, {0}
4ef: R_ARM_ABS32 .debug_str
4f0: 01000001 tsteq r0, r1
4f4: 0001c754 andeq ip, r1, r4, asr r7
4f8: 00000000 andeq r0, r0, r0
4f9: R_ARM_ABS32 .text.encoderInit
4fc: 0000cc00 andeq ip, r0, r0, lsl #24
500: 399c0100 ldmibcc ip, {r8}
504: 25000006 strcs r0, [r0, #-6]
508: 000002c8 andeq r0, r0, r8, asr #5
508: R_ARM_ABS32 .debug_str
50c: 00375401 eorseq r5, r7, r1, lsl #8
510: 018d0000 orreq r0, sp, r0
512: R_ARM_ABS32 .debug_loc
514: 8a250000 bhi 940008 <encoderGet+0x940008>
517: R_ARM_ABS32 .debug_str
518: 01000003 tsteq r0, r3
51c: 00003754 andeq r3, r0, r4, asr r7
520: 0001e000 andeq lr, r1, r0
521: R_ARM_ABS32 .debug_loc
524: 01de2500 bicseq r2, lr, r0, lsl #10
526: R_ARM_ABS32 .debug_str
528: 54010000 strpl r0, [r1], #-0
52c: 00000639 andeq r0, r0, r9, lsr r6
530: 0000021a andeq r0, r0, sl, lsl r2
530: R_ARM_ABS32 .debug_loc
534: 0002c018 andeq ip, r2, r8, lsl r0
535: R_ARM_ABS32 .debug_str
538: 52550100 subspl r0, r5, #0, 2
53c: 54000002 strpl r0, [r0], #-2
53f: R_ARM_ABS32 .debug_loc
540: 12000002 andne r0, r0, #2
544: 0000019c muleq r0, ip, r1
544: R_ARM_ABS32 .debug_str
548: 02525501 subseq r5, r2, #4194304 ; 0x400000
54c: 69270000 stmdbvs r7!, {} ; <UNPREDICTABLE>
550: 57010074 smlsdxpl r1, r4, r0, r0
554: 000000b8 strheq r0, [r0], -r8
558: 00000272 andeq r0, r0, r2, ror r2
558: R_ARM_ABS32 .debug_loc
55c: 00626927 rsbeq r6, r2, r7, lsr #18
560: 00b85701 adcseq r5, r8, r1, lsl #14
564: 02d30000 sbcseq r0, r3, #0
566: R_ARM_ABS32 .debug_loc
568: d2220000 eorle r0, r2, #0
56c: 46000001 strmi r0, [r0], -r1
56f: R_ARM_ABS32 .text.encoderInit
570: 88000000 stmdahi r0, {} ; <UNPREDICTABLE>
573: R_ARM_ABS32 .debug_ranges
574: 01000000 mrseq r0, (UNDEF: 0)
578: 00058d5b andeq r8, r5, fp, asr sp
57c: 02581e00 subseq r1, r8, #0, 28
580: 00460000 subeq r0, r6, r0
582: R_ARM_ABS32 .text.encoderInit
584: 00020000 andeq r0, r2, r0
588: 4b030000 blmi c0590 <encoderGet+0xc0590>
58c: 00a82300 adceq r2, r8, r0, lsl #6
58e: R_ARM_ABS32 .debug_ranges
590: 06060000 streq r0, [r6], -r0
594: 76180000 ldrvc r0, [r8], -r0
597: R_ARM_ABS32 .debug_str
598: 01000001 tsteq r0, r1
59c: 0000a25d andeq sl, r0, sp, asr r2
5a0: 00032500 andeq r2, r3, r0, lsl #10
5a1: R_ARM_ABS32 .debug_loc
5a4: 00602800 rsbeq r2, r0, r0, lsl #16
5a6: R_ARM_ABS32 .text.encoderInit
5a8: 09900000 ldmibeq r0, {} ; <UNPREDICTABLE>
5ac: 05be0000 ldreq r0, [lr, #0]!
5b0: 01290000 ; <UNDEFINED> instruction: 0x01290000
5b4: 293a0151 ldmdbcs sl!, {r0, r4, r6, r8}
5b8: 7a025001 bvc 945c4 <encoderGet+0x945c4>
5bc: 68280000 stmdavs r8!, {} ; <UNPREDICTABLE>
5bf: R_ARM_ABS32 .text.encoderInit
5c0: 90000000 andls r0, r0, r0
5c4: d7000009 strle r0, [r0, -r9]
5c8: 29000005 stmdbcs r0, {r0, r2}
5cc: 3a015101 bcc 549d8 <encoderGet+0x549d8>
5d0: 02500129 subseq r0, r0, #1073741834 ; 0x4000000a
5d4: 28000077 stmdacs r0, {r0, r1, r2, r4, r5, r6}
5d8: 00000092 muleq r0, r2, r0
5d8: R_ARM_ABS32 .text.encoderInit
5dc: 00000421 andeq r0, r0, r1, lsr #8
5e0: 000005f0 strdeq r0, [r0], -r0 ; <UNPREDICTABLE>
5e4: 01510129 cmpeq r1, r9, lsr #2
5e8: 50012933 andpl r2, r1, r3, lsr r9
5ec: 00007a02 andeq r7, r0, r2, lsl #20
5f0: 00009c2a andeq r9, r0, sl, lsr #24
5f1: R_ARM_ABS32 .text.encoderInit
5f4: 00042100 andeq r2, r4, r0, lsl #2
5f8: 51012900 tstpl r1, r0, lsl #18
5fc: 01293301 ; <UNDEFINED> instruction: 0x01293301
600: 00770250 rsbseq r0, r7, r0, asr r2
604: da1f0000 ble 7c060c <encoderGet+0x7c060c>
608: 9c000001 stcls 0, cr0, [r0], {1}
60b: R_ARM_ABS32 .text.encoderInit
60c: 10000000 andne r0, r0, r0
610: 01000000 mrseq r0, (UNDEF: 0)
614: 009c2071 addseq r2, ip, r1, ror r0
616: R_ARM_ABS32 .text.encoderInit
618: 00100000 andseq r0, r0, r0
61c: e6210000 strt r0, [r1], -r0
620: 43000001 movwmi r0, #1
623: R_ARM_ABS32 .debug_loc
624: 1e000003 cdpne 0, 0, cr0, cr0, cr3, {0}
628: 00000261 andeq r0, r0, r1, ror #4
62c: 000000a8 andeq r0, r0, r8, lsr #1
62c: R_ARM_ABS32 .text.encoderInit
630: 00000004 andeq r0, r0, r4
634: 00005403 andeq r5, r0, r3, lsl #8
638: 02010200 andeq r0, r1, #0, 4
63c: 0000020b andeq r0, r0, fp, lsl #4
63c: R_ARM_ABS32 .debug_str
640: 00000d2b andeq r0, r0, fp, lsr #26
641: R_ARM_ABS32 .debug_str
644: 00d30100 sbcseq r0, r3, r0, lsl #2
647: R_ARM_ABS32 .text.ISR_EXTI0
648: 2c000000 stccs 0, cr0, [r0], {-0}
64c: 01000000 mrseq r0, (UNDEF: 0)
650: 0006869c muleq r6, ip, r6
654: 01f72c00 mvnseq r2, r0, lsl #24
658: 00080000 andeq r0, r8, r0
65a: R_ARM_ABS32 .text.ISR_EXTI0
65c: 00c80000 sbceq r0, r8, r0
65e: R_ARM_ABS32 .debug_ranges
660: d5010000 strle r0, [r1, #-0]
664: 0002032d andeq r0, r2, sp, lsr #6
668: c82e0a00 stmdagt lr!, {r9, fp}
66b: R_ARM_ABS32 .debug_ranges
66c: 21000000 mrscs r0, (UNDEF: 0)
670: 0000020e andeq r0, r0, lr, lsl #4
674: 00000361 andeq r0, r0, r1, ror #6
674: R_ARM_ABS32 .debug_loc
678: 0000162f andeq r1, r0, pc, lsr #12
679: R_ARM_ABS32 .text.ISR_EXTI0
67c: 50012900 andpl r2, r1, r0, lsl #18
680: 00003b01 andeq r3, r0, r1, lsl #22
684: 172b0000 strne r0, [fp, -r0]!
687: R_ARM_ABS32 .debug_str
688: 01000000 mrseq r0, (UNDEF: 0)
68c: 000000da ldrdeq r0, [r0], -sl
68d: R_ARM_ABS32 .text.ISR_EXTI1
690: 00002c00 andeq r2, r0, r0, lsl #24
694: cc9c0100 ldfgts f0, [ip], {0}
698: 2c000006 stccs 0, cr0, [r0], {6}
69c: 000001f7 strdeq r0, [r0], -r7
6a0: 00000008 andeq r0, r0, r8
6a0: R_ARM_ABS32 .text.ISR_EXTI1
6a4: 000000e0 andeq r0, r0, r0, ror #1
6a4: R_ARM_ABS32 .debug_ranges
6a8: 032ddc01 ; <UNDEFINED> instruction: 0x032ddc01
6ac: 0b000002 bleq 6bc <.debug_info+0x6bc>
6b0: 0000e02e andeq lr, r0, lr, lsr #32
6b1: R_ARM_ABS32 .debug_ranges
6b4: 020e2100 andeq r2, lr, #0, 2
6b8: 03740000 cmneq r4, #0
6ba: R_ARM_ABS32 .debug_loc
6bc: 162f0000 strtne r0, [pc], -r0
6bf: R_ARM_ABS32 .text.ISR_EXTI1
6c0: 29000000 stmdbcs r0, {} ; <UNPREDICTABLE>
6c4: 3c015001 stccc 0, cr5, [r1], {1}
6c8: 00000000 andeq r0, r0, r0
6cc: 0002112b andeq r1, r2, fp, lsr #2
6cd: R_ARM_ABS32 .debug_str
6d0: 00e20100 rsceq r0, r2, r0, lsl #2
6d3: R_ARM_ABS32 .text.ISR_EXTI9_5
6d4: 6c000000 stcvs 0, cr0, [r0], {-0}
6d8: 01000000 mrseq r0, (UNDEF: 0)
6dc: 0007e89c muleq r7, ip, r8
6e0: 008b1800 addeq r1, fp, r0, lsl #16
6e2: R_ARM_ABS32 .debug_str
6e4: e3010000 movw r0, #4096 ; 0x1000
6e8: 000000b8 strheq r0, [r0], -r8
6ec: 00000387 andeq r0, r0, r7, lsl #7
6ec: R_ARM_ABS32 .debug_loc
6f0: 00029218 andeq r9, r2, r8, lsl r2
6f1: R_ARM_ABS32 .debug_str
6f4: b8e30100 stmialt r3!, {r8}^
6f8: 9a000000 bls 8 <.debug_info+0x8>
6fb: R_ARM_ABS32 .debug_loc
6fc: 1d000003 stcne 0, cr0, [r0, #-12]
700: 000001f7 strdeq r0, [r0], -r7
704: 00000016 andeq r0, r0, r6, lsl r0
704: R_ARM_ABS32 .text.ISR_EXTI9_5
708: 0000000a andeq r0, r0, sl
70c: 073ae601 ldreq lr, [sl, -r1, lsl #12]!
710: 03300000 teqeq r0, #0
714: c8000002 stmdagt r0, {r1}
717: R_ARM_ABS32 .debug_loc
718: 20000003 andcs r0, r0, r3
71c: 00000016 andeq r0, r0, r6, lsl r0
71c: R_ARM_ABS32 .text.ISR_EXTI9_5
720: 0000000a andeq r0, r0, sl
724: 00020e21 andeq r0, r2, r1, lsr #28
728: 0003dc00 andeq sp, r3, r0, lsl #24
729: R_ARM_ABS32 .debug_loc
72c: 00202f00 eoreq r2, r0, r0, lsl #30
72e: R_ARM_ABS32 .text.ISR_EXTI9_5
730: 01290000 ; <UNDEFINED> instruction: 0x01290000
734: 00330150 eorseq r0, r3, r0, asr r1
738: f71d0000 ; <UNDEFINED> instruction: 0xf71d0000
73c: 26000001 strcs r0, [r0], -r1
73f: R_ARM_ABS32 .text.ISR_EXTI9_5
740: 0a000000 beq 748 <.debug_info+0x748>
744: 01000000 mrseq r0, (UNDEF: 0)
748: 000775eb andeq r7, r7, fp, ror #11
74c: 02033000 andeq r3, r3, #0
750: 03ef0000 mvneq r0, #0
752: R_ARM_ABS32 .debug_loc
754: 26200000 strtcs r0, [r0], -r0
757: R_ARM_ABS32 .text.ISR_EXTI9_5
758: 0a000000 beq 760 <.debug_info+0x760>
75c: 21000000 mrscs r0, (UNDEF: 0)
760: 0000020e andeq r0, r0, lr, lsl #4
764: 00000403 andeq r0, r0, r3, lsl #8
764: R_ARM_ABS32 .debug_loc
768: 0000302f andeq r3, r0, pc, lsr #32
769: R_ARM_ABS32 .text.ISR_EXTI9_5
76c: 50012900 andpl r2, r1, r0, lsl #18
770: 00003401 andeq r3, r0, r1, lsl #8
774: 01f71d00 mvnseq r1, r0, lsl #26
778: 00380000 eorseq r0, r8, r0
77a: R_ARM_ABS32 .text.ISR_EXTI9_5
77c: 000a0000 andeq r0, sl, r0
780: f0010000 ; <UNDEFINED> instruction: 0xf0010000
784: 000007b0 ; <UNDEFINED> instruction: 0x000007b0
788: 00020330 andeq r0, r2, r0, lsr r3
78c: 00041600 andeq r1, r4, r0, lsl #12
78d: R_ARM_ABS32 .debug_loc
790: 00382000 eorseq r2, r8, r0
792: R_ARM_ABS32 .text.ISR_EXTI9_5
794: 000a0000 andeq r0, sl, r0
798: 0e210000 cdpeq 0, 2, cr0, cr1, cr0, {0}
79c: 2a000002 bcs 10 <.debug_info+0x10>
79f: R_ARM_ABS32 .debug_loc
7a0: 2f000004 svccs 0x00000004
7a4: 00000042 andeq r0, r0, r2, asr #32
7a4: R_ARM_ABS32 .text.ISR_EXTI9_5
7a8: 01500129 cmpeq r0, r9, lsr #2
7ac: 00000037 andeq r0, r0, r7, lsr r0
7b0: 0001f71f andeq pc, r1, pc, lsl r7 ; <UNPREDICTABLE>
7b4: 00004a00 andeq r4, r0, r0, lsl #20
7b5: R_ARM_ABS32 .text.ISR_EXTI9_5
7b8: 00000a00 andeq r0, r0, r0, lsl #20
7bc: 30f50100 rscscc r0, r5, r0, lsl #2
7c0: 00000203 andeq r0, r0, r3, lsl #4
7c4: 0000043d andeq r0, r0, sp, lsr r4
7c4: R_ARM_ABS32 .debug_loc
7c8: 00004a20 andeq r4, r0, r0, lsr #20
7c9: R_ARM_ABS32 .text.ISR_EXTI9_5
7cc: 00000a00 andeq r0, r0, r0, lsl #20
7d0: 020e2100 andeq r2, lr, #0, 2
7d4: 04510000 ldrbeq r0, [r1], #-0
7d6: R_ARM_ABS32 .debug_loc
7d8: 542f0000 strtpl r0, [pc], #-0 ; 8 <.debug_info+0x8>
7db: R_ARM_ABS32 .text.ISR_EXTI9_5
7dc: 29000000 stmdbcs r0, {} ; <UNPREDICTABLE>
7e0: 31015001 tstcc r1, r1
7e4: 00000000 andeq r0, r0, r0
7e8: 0000a82b andeq sl, r0, fp, lsr #16
7e9: R_ARM_ABS32 .debug_str
7ec: 00fd0100 rscseq r0, sp, r0, lsl #2
7ef: R_ARM_ABS32 .text.ISR_EXTI15_10
7f0: 80000000 andhi r0, r0, r0
7f4: 01000000 mrseq r0, (UNDEF: 0)
7f8: 0009449c muleq r9, ip, r4
7fc: 008b1800 addeq r1, fp, r0, lsl #16
7fe: R_ARM_ABS32 .debug_str
800: fe010000 cdp2 0, 0, cr0, cr1, cr0, {0}
804: 000000b8 strheq r0, [r0], -r8
808: 00000464 andeq r0, r0, r4, ror #8
808: R_ARM_ABS32 .debug_loc
80c: 00029218 andeq r9, r2, r8, lsl r2
80d: R_ARM_ABS32 .debug_str
810: b8fe0100 ldmlt lr!, {r8}^
814: 77000000 strvc r0, [r0, -r0]
817: R_ARM_ABS32 .debug_loc
818: 31000004 tstcc r0, r4
81c: 000001f7 strdeq r0, [r0], -r7
820: 00000014 andeq r0, r0, r4, lsl r0
820: R_ARM_ABS32 .text.ISR_EXTI15_10
824: 0000000a andeq r0, r0, sl
828: 57010101 strpl r0, [r1, -r1, lsl #2]
82c: 30000008 andcc r0, r0, r8
830: 00000203 andeq r0, r0, r3, lsl #4
834: 000004a5 andeq r0, r0, r5, lsr #9
834: R_ARM_ABS32 .debug_loc
838: 00001420 andeq r1, r0, r0, lsr #8
839: R_ARM_ABS32 .text.ISR_EXTI15_10
83c: 00000a00 andeq r0, r0, r0, lsl #20
840: 020e2100 andeq r2, lr, #0, 2
844: 04b90000 ldrteq r0, [r9], #0
846: R_ARM_ABS32 .debug_loc
848: 1e2f0000 cdpne 0, 2, cr0, cr15, cr0, {0}
84b: R_ARM_ABS32 .text.ISR_EXTI15_10
84c: 29000000 stmdbcs r0, {} ; <UNPREDICTABLE>
850: 38015001 stmdacc r1, {r0, ip, lr}
854: 31000000 mrscc r0, (UNDEF: 0)
858: 000001f7 strdeq r0, [r0], -r7
85c: 00000026 andeq r0, r0, r6, lsr #32
85c: R_ARM_ABS32 .text.ISR_EXTI15_10
860: 0000000a andeq r0, r0, sl
864: 93010601 movwls r0, #5633 ; 0x1601
868: 30000008 andcc r0, r0, r8
86c: 00000203 andeq r0, r0, r3, lsl #4
870: 000004cc andeq r0, r0, ip, asr #9
870: R_ARM_ABS32 .debug_loc
874: 00002620 andeq r2, r0, r0, lsr #12
875: R_ARM_ABS32 .text.ISR_EXTI15_10
878: 00000a00 andeq r0, r0, r0, lsl #20
87c: 020e2100 andeq r2, lr, #0, 2
880: 04e00000 strbteq r0, [r0], #0
882: R_ARM_ABS32 .debug_loc
884: 302f0000 eorcc r0, pc, r0
887: R_ARM_ABS32 .text.ISR_EXTI15_10
888: 29000000 stmdbcs r0, {} ; <UNPREDICTABLE>
88c: 32015001 andcc r5, r1, #1
890: 31000000 mrscc r0, (UNDEF: 0)
894: 000001f7 strdeq r0, [r0], -r7
898: 00000038 andeq r0, r0, r8, lsr r0
898: R_ARM_ABS32 .text.ISR_EXTI15_10
89c: 0000000c andeq r0, r0, ip
8a0: cf010b01 svcgt 0x00010b01
8a4: 30000008 andcc r0, r0, r8
8a8: 00000203 andeq r0, r0, r3, lsl #4
8ac: 000004f3 strdeq r0, [r0], -r3
8ac: R_ARM_ABS32 .debug_loc
8b0: 00003820 andeq r3, r0, r0, lsr #16
8b1: R_ARM_ABS32 .text.ISR_EXTI15_10
8b4: 00000c00 andeq r0, r0, r0, lsl #24
8b8: 020e2100 andeq r2, lr, #0, 2
8bc: 05070000 streq r0, [r7, #-0]
8be: R_ARM_ABS32 .debug_loc
8c0: 442f0000 strtmi r0, [pc], #-0 ; 8 <.debug_info+0x8>
8c3: R_ARM_ABS32 .text.ISR_EXTI15_10
8c4: 29000000 stmdbcs r0, {} ; <UNPREDICTABLE>
8c8: 39015001 stmdbcc r1, {r0, ip, lr}
8cc: 31000000 mrscc r0, (UNDEF: 0)
8d0: 000001f7 strdeq r0, [r0], -r7
8d4: 0000004c andeq r0, r0, ip, asr #32
8d4: R_ARM_ABS32 .text.ISR_EXTI15_10
8d8: 0000000a andeq r0, r0, sl
8dc: 0b011001 bleq 448e8 <encoderGet+0x448e8>
8e0: 30000009 andcc r0, r0, r9
8e4: 00000203 andeq r0, r0, r3, lsl #4
8e8: 0000051a andeq r0, r0, sl, lsl r5
8e8: R_ARM_ABS32 .debug_loc
8ec: 00004c20 andeq r4, r0, r0, lsr #24
8ed: R_ARM_ABS32 .text.ISR_EXTI15_10
8f0: 00000a00 andeq r0, r0, r0, lsl #20
8f4: 020e2100 andeq r2, lr, #0, 2
8f8: 052e0000 streq r0, [lr, #-0]!
8fa: R_ARM_ABS32 .debug_loc
8fc: 562f0000 strtpl r0, [pc], -r0
8ff: R_ARM_ABS32 .text.ISR_EXTI15_10
900: 29000000 stmdbcs r0, {} ; <UNPREDICTABLE>
904: 35015001 strcc r5, [r1, #-1]
908: 32000000 andcc r0, r0, #0
90c: 000001f7 strdeq r0, [r0], -r7
910: 0000005e andeq r0, r0, lr, asr r0
910: R_ARM_ABS32 .text.ISR_EXTI15_10
914: 0000000a andeq r0, r0, sl
918: 30011501 andcc r1, r1, r1, lsl #10
91c: 00000203 andeq r0, r0, r3, lsl #4
920: 00000541 andeq r0, r0, r1, asr #10
920: R_ARM_ABS32 .debug_loc
924: 00005e20 andeq r5, r0, r0, lsr #28
925: R_ARM_ABS32 .text.ISR_EXTI15_10
928: 00000a00 andeq r0, r0, r0, lsl #20
92c: 020e2100 andeq r2, lr, #0, 2
930: 05550000 ldrbeq r0, [r5, #-0]
932: R_ARM_ABS32 .debug_loc
934: 682f0000 stmdavs pc!, {} ; <UNPREDICTABLE>
937: R_ARM_ABS32 .text.ISR_EXTI15_10
938: 29000000 stmdbcs r0, {} ; <UNPREDICTABLE>
93c: 36015001 strcc r5, [r1], -r1
940: 00000000 andeq r0, r0, r0
944: 00005233 andeq r5, r0, r3, lsr r2
945: R_ARM_ABS32 .debug_str
948: d3470300 movtle r0, #29440 ; 0x7300
94c: 34000000 strcc r0, [r0], #-0
950: 00000097 muleq r0, r7, r0
954: 0000095f andeq r0, r0, pc, asr r9
958: 0000c335 andeq ip, r0, r5, lsr r3
95c: 33001a00 movwcc r1, #2560 ; 0xa00
960: 00000099 muleq r0, r9, r0
960: R_ARM_ABS32 .debug_str
964: 096a9d06 stmdbeq sl!, {r1, r2, r8, sl, fp, ip, pc}^
968: 4f130000 svcmi 0x00130000
96c: 34000009 strcc r0, [r0], #-9
970: 000001bc ; <UNDEFINED> instruction: 0x000001bc
974: 0000097f andeq r0, r0, pc, ror r9
978: 0000c335 andeq ip, r0, r5, lsr r3
97c: 36000b00 strcc r0, [r0], -r0, lsl #22
980: 0000021d andeq r0, r0, sp, lsl r2
980: R_ARM_ABS32 .debug_str
984: 096f1401 stmdbeq pc!, {r0, sl, ip}^ ; <UNPREDICTABLE>
988: 03050000 movweq r0, #20480 ; 0x5000
98c: 00000000 andeq r0, r0, r0
98c: R_ARM_ABS32 _sensorState
990: 0000ea37 andeq lr, r0, r7, lsr sl
991: R_ARM_ABS32 .debug_str
994: 01300600 teqeq r0, r0, lsl #12
998: 0000370d andeq r3, r0, sp, lsl #14
99c: 00370d00 eorseq r0, r7, r0, lsl #26
9a0: 00000000 andeq r0, r0, r0
Disassembly of section .debug_abbrev:
00000000 <.debug_abbrev>:
#endif
// encoderGet - Gets the value of the encoder
int encoderGet(Encoder enc) {
Sensor_TypeDef *encoder = (Sensor_TypeDef*)enc;
if (encoder)
0: 25011101 strcs r1, [r1, #-257] ; 0xfffffeff
return (int)encoder->value;
return 0;
}
4: 030b130e movweq r1, #45838 ; 0xb30e
}
// encoderReset - Resets the encoder to zero
void encoderReset(Encoder enc) {
Sensor_TypeDef *encoder = (Sensor_TypeDef*)enc;
if (encoder) {
8: 550e1b0e strpl r1, [lr, #-2830] ; 0xfffff4f2
extern volatile uint32_t _criticalNesting;
/* Enter a critical section. */
static INLINE void _enterCritical() {
__disable_irq();
_criticalNesting++;
c: 10011117 andne r1, r1, r7, lsl r1
10: 02000017 andeq r0, r0, #23
_enterCritical();
{
encoder->value = 0;
14: 0b0b0024 bleq 2c00ac <encoderGet+0x2c00ac>
encoder->lastValue = 0;
18: 0e030b3e vmoveq.16 d3[0], r0
}
/* Exit a critical section. */
static INLINE void _exitCritical() {
const uint32_t newCritical = _criticalNesting - 1;
1c: 16030000 strne r0, [r3], -r0
_criticalNesting = newCritical;
if (newCritical == 0)
20: 3a0e0300 bcc 380c28 <encoderGet+0x380c28>
24: 490b3b0b stmdbmi fp, {r0, r1, r3, r8, r9, fp, ip, sp}
28: 04000013 streq r0, [r0], #-19 ; 0xffffffed
}
}
// ioClearInterrupt - Disables interrupts on the specified pin
void ioClearInterrupt(unsigned char pin) {
pin--;
2c: 0b0b0024 bleq 2c00c4 <encoderGet+0x2c00c4>
if (pin < 12 && pin != 9) {
30: 08030b3e stmdaeq r3, {r1, r2, r3, r4, r5, r8, r9, fp}
34: 0f050000 svceq 0x00050000
#define USART_CR3_CTSE ((uint16_t)0x0200)
// Disables FAULT interrupts
static inline void __disable_fault_irq() { asm volatile ("cpsid f"); }
// Disables interrupts
static inline void __disable_irq() { asm volatile ("cpsid i"); }
38: 000b0b00 andeq r0, fp, r0, lsl #22
// Avoid having the OS swap this out
_enterCritical();
{
uint32_t mask = (uint32_t)1 << _pinIndexTable[pin + 1];
3c: 00350600 eorseq r0, r5, r0, lsl #12
extern volatile uint32_t _criticalNesting;
/* Enter a critical section. */
static INLINE void _enterCritical() {
__disable_irq();
_criticalNesting++;
40: 00001349 andeq r1, r0, r9, asr #6
44: 0b011307 bleq 44c68 <encoderGet+0x44c68>
48: 3b0b3a0b blcc 2ce87c <encoderGet+0x2ce87c>
// Clear pending interrupt
EXTI->PR |= mask;
4c: 00130105 andseq r0, r3, r5, lsl #2
50: 000d0800 andeq r0, sp, r0, lsl #16
// Mask interrupt
EXTI->IMR &= ~mask;
54: 0b3a0803 bleq e82068 <encoderGet+0xe82068>
58: 1349053b movtne r0, #38203 ; 0x953b
}
/* Exit a critical section. */
static INLINE void _exitCritical() {
const uint32_t newCritical = _criticalNesting - 1;
5c: 00000b38 andeq r0, r0, r8, lsr fp
_criticalNesting = newCritical;
60: 03000d09 movweq r0, #3337 ; 0xd09
// Waits for memory accesses to complete before continuing (Data Synchronization Barrier)
static inline void __dsb() { asm volatile ("dsb"); }
// Enables FAULT interrupts
static inline void __enable_fault_irq() { asm volatile ("cpsie f"); }
// Enables interrupts
static inline void __enable_irq() { asm volatile ("cpsie i"); }
64: 3b0b3a0e blcc 2ce8a4 <encoderGet+0x2ce8a4>
68: 38134905 ldmdacc r3, {r0, r2, r8, fp, lr}
6c: 0a00000b beq a0 <.debug_abbrev+0xa0>
70: 0e030016 mcreq 0, 0, r0, cr3, cr6, {0}
_exitCritical();
}
}
// encoderShutdown - Stops and disables the encoder
void encoderShutdown(Encoder enc) {
74: 053b0b3a ldreq r0, [fp, #-2874]! ; 0xfffff4c6
Sensor_TypeDef *encoder = (Sensor_TypeDef*)enc;
if (encoder) {
78: 00001349 andeq r1, r0, r9, asr #6
extern volatile uint32_t _criticalNesting;
/* Enter a critical section. */
static INLINE void _enterCritical() {
__disable_irq();
_criticalNesting++;
7c: 0b000f0b bleq 3cb0 <encoderGet+0x3cb0>
80: 0013490b andseq r4, r3, fp, lsl #18
84: 01150c00 tsteq r5, r0, lsl #24
_enterCritical();
{
// Stop
encoder->flags = 0;
_sensorState[encoder->portBottom].flags = 0;
88: 13011927 movwne r1, #6439 ; 0x1927
8c: 050d0000 streq r0, [sp, #-0]
90: 00134900 andseq r4, r3, r0, lsl #18
// Clear interrupts
ioClearInterrupt(encoder->portTop);
94: 01130e00 tsteq r3, r0, lsl #28
ioClearInterrupt(encoder->portBottom);
98: 0b3a0b0b bleq e82ccc <encoderGet+0xe82ccc>
9c: 13010b3b movwne r0, #6971 ; 0x1b3b
}
/* Exit a critical section. */
static INLINE void _exitCritical() {
const uint32_t newCritical = _criticalNesting - 1;
a0: 0d0f0000 stceq 0, cr0, [pc, #-0] ; a8 <.debug_abbrev+0xa8>
_criticalNesting = newCritical;
if (newCritical == 0)
a4: 3a0e0300 bcc 380cac <encoderGet+0x380cac>
a8: 490b3b0b stmdbmi fp, {r0, r1, r3, r8, r9, fp, ip, sp}
ac: 000b3813 andeq r3, fp, r3, lsl r8
b0: 002e1000 eoreq r1, lr, r0
}
// ioSetInterrupt - Sets up an interrupt to occur on the specified pin, and resets count & time
// Provide NULL for handler for standard interrupts, or pass function pointer for custom
void ioSetInterrupt(unsigned char pin, unsigned char edges, InterruptHandler handler) {
pin--;
b4: 0b3a0e03 bleq e838c8 <encoderGet+0xe838c8>
if (pin < BOARD_NR_DIGITAL_IO && pin != 9) {
b8: 0b200b3b bleq 802dac <encoderGet+0x802dac>
bc: 2e110000 cdpcs 0, 1, cr0, cr1, cr0, {0}
c0: 3a0e0301 bcc 380ccc <encoderGet+0x380ccc>
extern volatile uint32_t _criticalNesting;
/* Enter a critical section. */
static INLINE void _enterCritical() {
__disable_irq();
_criticalNesting++;
c4: 200b3b0b andcs r3, fp, fp, lsl #22
c8: 0013010b andseq r0, r3, fp, lsl #2
// Configure freely, we won't have an issue here since interrupt is masked
Sensor_TypeDef *state = &_sensorState[pin];
state->eventTrigger = handler;
// Falling edge configuration
temp = EXTI->FTSR;
if (edges & INTERRUPT_EDGE_FALLING)
cc: 00341200 eorseq r1, r4, r0, lsl #4
d0: 0b3a0e03 bleq e838e4 <encoderGet+0xe838e4>
if (pin < BOARD_NR_DIGITAL_IO && pin != 9) {
// Avoid having the OS swap this out during init
_enterCritical();
{
// In range, start by masking interrupt if enabled
uint32_t mask = (uint32_t)1 << _pinIndexTable[pin + 1], temp;
d4: 13490b3b movtne r0, #39739 ; 0x9b3b
d8: 26130000 ldrcs r0, [r3], -r0
dc: 00134900 andseq r4, r3, r0, lsl #18
EXTI->IMR &= ~mask;
e0: 012e1400 ; <UNDEFINED> instruction: 0x012e1400
e4: 0b3a0e03 bleq e838f8 <encoderGet+0xe838f8>
e8: 19270b3b stmdbne r7!, {r0, r1, r3, r4, r5, r8, r9, fp}
// Configure freely, we won't have an issue here since interrupt is masked
Sensor_TypeDef *state = &_sensorState[pin];
state->eventTrigger = handler;
ec: 13010b20 movwne r0, #6944 ; 0x1b20
f0: 05150000 ldreq r0, [r5, #-0]
// Falling edge configuration
temp = EXTI->FTSR;
f4: 3a080300 bcc 200cfc <encoderGet+0x200cfc>
if (edges & INTERRUPT_EDGE_FALLING)
temp |= mask;
f8: 490b3b0b stmdbmi fp, {r0, r1, r3, r8, r9, fp, ip, sp}
else
temp &= ~mask;
EXTI->FTSR = temp;
fc: 16000013 ; <UNDEFINED> instruction: 0x16000013
// Rising edge configuration
temp = EXTI->RTSR;
if (edges & INTERRUPT_EDGE_RISING)
100: 193f012e ldmdbne pc!, {r1, r2, r3, r5, r8} ; <UNPREDICTABLE>
temp |= mask;
104: 0b3a0e03 bleq e83918 <encoderGet+0xe83918>
else
temp &= ~mask;
108: 19270b3b stmdbne r7!, {r0, r1, r3, r4, r5, r8, r9, fp}
EXTI->RTSR = temp;
10c: 01111349 tsteq r1, r9, asr #6
// Clear pending interrupt
EXTI->PR |= mask;
110: 18400612 stmdane r0, {r1, r4, r9, sl}^
// Unmask interrupt to start monitoring
EXTI->IMR |= mask;
114: 01194297 ; <UNDEFINED> instruction: 0x01194297
118: 17000013 smladne r0, r3, r0, r0
}
/* Exit a critical section. */
static INLINE void _exitCritical() {
const uint32_t newCritical = _criticalNesting - 1;
11c: 08030005 stmdaeq r3, {r0, r2}
_criticalNesting = newCritical;
if (newCritical == 0)
120: 0b3b0b3a bleq ec2e10 <encoderGet+0xec2e10>
124: 17021349 strne r1, [r2, -r9, asr #6]
128: 34180000 ldrcc r0, [r8], #-0
12c: 3a0e0300 bcc 380d34 <encoderGet+0x380d34>
130: 490b3b0b stmdbmi fp, {r0, r1, r3, r8, r9, fp, ip, sp}
134: 00170213 andseq r0, r7, r3, lsl r2
return (int)encoder->value;
return 0;
}
// encoderInit - Initializes and enables a quadrature encoder on two digital ports
Encoder encoderInit(unsigned char portTop, unsigned char portBottom, bool reverse) {
138: 002e1900 eoreq r1, lr, r0, lsl #18
Sensor_TypeDef *encoder, *slave;
// Change to 0..11 range
uint32_t it = portTop - 1, ib = portBottom - 1;
13c: 0b3a0e03 bleq e83950 <encoderGet+0xe83950>
return (int)encoder->value;
return 0;
}
// encoderInit - Initializes and enables a quadrature encoder on two digital ports
Encoder encoderInit(unsigned char portTop, unsigned char portBottom, bool reverse) {
140: 0b20053b bleq 801634 <encoderGet+0x801634>
Sensor_TypeDef *encoder, *slave;
// Change to 0..11 range
uint32_t it = portTop - 1, ib = portBottom - 1;
144: 2e1a0000 cdpcs 0, 1, cr0, cr10, cr0, {0}
// Check range
if (it < BOARD_NR_DIGITAL_IO && it != 9 && _sensorState[it].flags == 0 &&
148: 03193f01 tsteq r9, #1, 30
14c: 3b0b3a0e blcc 2ce98c <encoderGet+0x2ce98c>
150: 1119270b tstne r9, fp, lsl #14
154: 40061201 andmi r1, r6, r1, lsl #4
158: 19429718 stmdbne r2, {r3, r4, r8, r9, sl, ip, pc}^
15c: 00001301 andeq r1, r0, r1, lsl #6
160: 0300051b movweq r0, #1307 ; 0x51b
ib < BOARD_NR_DIGITAL_IO && ib != 9 && _sensorState[ib].flags == 0) {
164: 3b0b3a08 blcc 2ce98c <encoderGet+0x2ce98c>
168: 0213490b andseq r4, r3, #180224 ; 0x2c000
16c: 1c000018 stcne 0, cr0, [r0], {24}
170: 0e030034 mcreq 0, 0, r0, cr3, cr4, {1}
174: 0b3b0b3a bleq ec2e64 <encoderGet+0xec2e64>
178: 18021349 stmdane r2, {r0, r3, r6, r8, r9, ip}
17c: 1d1d0000 ldcne 0, cr0, [sp, #-0]
extern volatile uint32_t _criticalNesting;
/* Enter a critical section. */
static INLINE void _enterCritical() {
__disable_irq();
_criticalNesting++;
180: 11133101 tstne r3, r1, lsl #2
{
uint16_t flags = (uint16_t)0x0002 | (uint16_t)(reverse ? 0x01 : 0x00);
encoder = &_sensorState[it];
slave = &_sensorState[ib];
// Set pins to input pull-up
pinMode(portTop, DDR_INPUT_PULLUP);
184: 58061201 stmdapl r6, {r0, r9, ip}
188: 010b590b tsteq fp, fp, lsl #18
// Check range
if (it < BOARD_NR_DIGITAL_IO && it != 9 && _sensorState[it].flags == 0 &&
ib < BOARD_NR_DIGITAL_IO && ib != 9 && _sensorState[ib].flags == 0) {
_enterCritical();
{
uint16_t flags = (uint16_t)0x0002 | (uint16_t)(reverse ? 0x01 : 0x00);
18c: 1e000013 mcrne 0, 0, r0, cr0, cr3, {0}
190: 1331001d teqne r1, #29
encoder = &_sensorState[it];
slave = &_sensorState[ib];
// Set pins to input pull-up
pinMode(portTop, DDR_INPUT_PULLUP);
194: 06120111 ; <UNDEFINED> instruction: 0x06120111
pinMode(portBottom, DDR_INPUT_PULLUP);
198: 0b590b58 bleq 1642f00 <encoderGet+0x1642f00>
19c: 1d1f0000 ldcne 0, cr0, [pc, #-0] ; 1a4 <.debug_abbrev+0x1a4>
// Set state of master pin (top)
encoder->flags = flags;
encoder->portTop = (uint8_t)portTop;
encoder->portBottom = (uint8_t)portBottom;
encoder->value = 0;
1a0: 11133101 tstne r3, r1, lsl #2
slave = &_sensorState[ib];
// Set pins to input pull-up
pinMode(portTop, DDR_INPUT_PULLUP);
pinMode(portBottom, DDR_INPUT_PULLUP);
// Set state of master pin (top)
encoder->flags = flags;
1a4: 58061201 stmdapl r6, {r0, r9, ip}
// Set slaved state
slave->flags = flags;
slave->portTop = (uint8_t)portTop;
slave->portBottom = (uint8_t)portBottom;
// Interrupt per-port on either rising or falling edge
ioSetInterrupt(portTop, INTERRUPT_EDGE_BOTH, _encoderISRTop);
1a8: 000b590b andeq r5, fp, fp, lsl #18
// Set pins to input pull-up
pinMode(portTop, DDR_INPUT_PULLUP);
pinMode(portBottom, DDR_INPUT_PULLUP);
// Set state of master pin (top)
encoder->flags = flags;
encoder->portTop = (uint8_t)portTop;
1ac: 010b2000 mrseq r2, (UNDEF: 11)
encoder->portBottom = (uint8_t)portBottom;
1b0: 06120111 ; <UNDEFINED> instruction: 0x06120111
encoder->value = 0;
1b4: 34210000 strtcc r0, [r1], #-0
encoder->lastValue = 0;
1b8: 02133100 andseq r3, r3, #0, 2
// Set slaved state
slave->flags = flags;
1bc: 22000017 andcs r0, r0, #23
slave->portTop = (uint8_t)portTop;
1c0: 1331011d teqne r1, #1073741831 ; 0x40000007
slave->portBottom = (uint8_t)portBottom;
1c4: 17550152 ; <UNDEFINED> instruction: 0x17550152
// Interrupt per-port on either rising or falling edge
ioSetInterrupt(portTop, INTERRUPT_EDGE_BOTH, _encoderISRTop);
1c8: 0b590b58 bleq 1642f30 <encoderGet+0x1642f30>
ioSetInterrupt(portBottom, INTERRUPT_EDGE_BOTH, _encoderISRBottom);
1cc: 00001301 andeq r1, r0, r1, lsl #6
1d0: 55010b23 strpl r0, [r1, #-2851] ; 0xfffff4dd
}
/* Exit a critical section. */
static INLINE void _exitCritical() {
const uint32_t newCritical = _criticalNesting - 1;
1d4: 00130117 andseq r0, r3, r7, lsl r1
1d8: 82892400 addhi r2, r9, #0, 8
_criticalNesting = newCritical;
1dc: 01110001 tsteq r1, r1
1e0: 00001331 andeq r1, r0, r1, lsr r3
}
_exitCritical();
return (Encoder)encoder;
}
return NULL;
1e4: 03000525 movweq r0, #1317 ; 0x525
1e8: 3b0b3a0e blcc 2cea28 <encoderGet+0x2cea28>
// Interrupt per-port on either rising or falling edge
ioSetInterrupt(portTop, INTERRUPT_EDGE_BOTH, _encoderISRTop);
ioSetInterrupt(portBottom, INTERRUPT_EDGE_BOTH, _encoderISRBottom);
}
_exitCritical();
return (Encoder)encoder;
1ec: 0213490b andseq r4, r3, #180224 ; 0x2c000
}
return NULL;
}
1f0: 26000017 ; <UNDEFINED> instruction: 0x26000017
1f4: 0e030005 cdpeq 0, 0, cr0, cr3, cr5, {0}
1f8: 0b3b0b3a bleq ec2ee8 <encoderGet+0xec2ee8>
1fc: 18021349 stmdane r2, {r0, r3, r6, r8, r9, ip}
200: 34270000 strtcc r0, [r7], #-0
if (handler != NULL)
handler(pin + 1);
}
// External interrupts all Px0 pins (PD0/Digital 11)
IRQ ISR_EXTI0() {
204: 3a080300 bcc 200e0c <encoderGet+0x200e0c>
208: 490b3b0b stmdbmi fp, {r0, r1, r3, r8, r9, fp, ip, sp}
}
}
// Fires off the external interrupt logic for a given pin
static INLINE void triggerEXTI(uint32_t pin) {
InterruptHandler handler = _sensorState[pin].eventTrigger;
20c: 00170213 andseq r0, r7, r3, lsl r2
210: 82892800 addhi r2, r9, #0, 16
if (handler != NULL)
214: 01110101 tsteq r1, r1, lsl #2
handler(pin + 1);
218: 13011331 movwne r1, #4913 ; 0x1331
// External interrupts all Px0 pins (PD0/Digital 11)
IRQ ISR_EXTI0() {
// We assume that this can only fire if unmasked (therefore, wanted)
triggerEXTI(10);
EXTI->PR = (uint32_t)0x0001;
}
21c: 8a290000 bhi a40224 <encoderGet+0xa40224>
// External interrupts all Px0 pins (PD0/Digital 11)
IRQ ISR_EXTI0() {
// We assume that this can only fire if unmasked (therefore, wanted)
triggerEXTI(10);
EXTI->PR = (uint32_t)0x0001;
220: 02000182 andeq r0, r0, #-2147483616 ; 0x80000020
}
224: 18429118 stmdane r2, {r3, r4, r8, ip, pc}^
228: 892a0000 stmdbhi sl!, {} ; <UNPREDICTABLE>
22c: 11010182 smlabbne r1, r2, r1, r0
// External interrupts all Px1 pins (PD1/Digital 12)
IRQ ISR_EXTI1() {
230: 00133101 andseq r3, r3, r1, lsl #2
234: 012e2b00 ; <UNDEFINED> instruction: 0x012e2b00
}
}
// Fires off the external interrupt logic for a given pin
static INLINE void triggerEXTI(uint32_t pin) {
InterruptHandler handler = _sensorState[pin].eventTrigger;
238: 0e03193f mcreq 9, 0, r1, cr3, cr15, {1}
23c: 0b3b0b3a bleq ec2f2c <encoderGet+0xec2f2c>
if (handler != NULL)
240: 06120111 ; <UNDEFINED> instruction: 0x06120111
handler(pin + 1);
244: 42971840 addsmi r1, r7, #64, 16 ; 0x400000
// External interrupts all Px1 pins (PD1/Digital 12)
IRQ ISR_EXTI1() {
// We assume that this can only fire if unmasked (therefore, wanted)
triggerEXTI(11);
EXTI->PR = (uint32_t)0x0002;
}
248: 00130119 andseq r0, r3, r9, lsl r1
// External interrupts all Px1 pins (PD1/Digital 12)
IRQ ISR_EXTI1() {
// We assume that this can only fire if unmasked (therefore, wanted)
triggerEXTI(11);
EXTI->PR = (uint32_t)0x0002;
24c: 011d2c00 tsteq sp, r0, lsl #24
}
250: 01521331 cmpeq r2, r1, lsr r3
254: 0b581755 bleq 1605fb0 <encoderGet+0x1605fb0>
258: 00000b59 andeq r0, r0, r9, asr fp
// External interrupts all Px5-Px9 pins
// (PC6/Digital 3, PC7/Digital 4, PE8/Digital 7, PE9/Digital 1)
IRQ ISR_EXTI9_5() {
25c: 3100052d tstcc r0, sp, lsr #10
260: 000b1c13 andeq r1, fp, r3, lsl ip
264: 010b2e00 tsteq fp, r0, lsl #28
uint32_t pending = EXTI->PR, reset = 0;
268: 00001755 andeq r1, r0, r5, asr r7
if (pending & (uint32_t)0x0040) {
26c: 0182892f orreq r8, r2, pc, lsr #18
270: 00011101 andeq r1, r1, r1, lsl #2
}
}
// Fires off the external interrupt logic for a given pin
static INLINE void triggerEXTI(uint32_t pin) {
InterruptHandler handler = _sensorState[pin].eventTrigger;
274: 00053000 andeq r3, r5, r0
if (handler != NULL)
handler(pin + 1);
278: 17021331 smladxne r2, r1, r3, r1
IRQ ISR_EXTI9_5() {
uint32_t pending = EXTI->PR, reset = 0;
if (pending & (uint32_t)0x0040) {
// PC6 fired
triggerEXTI(2);
reset |= (uint32_t)0x0040;
27c: 1d310000 ldcne 0, cr0, [r1, #-0]
}
if (pending & (uint32_t)0x0080) {
280: 11133101 tstne r3, r1, lsl #2
}
}
// Fires off the external interrupt logic for a given pin
static INLINE void triggerEXTI(uint32_t pin) {
InterruptHandler handler = _sensorState[pin].eventTrigger;
284: 58061201 stmdapl r6, {r0, r9, ip}
if (handler != NULL)
handler(pin + 1);
288: 0105590b tsteq r5, fp, lsl #18
reset |= (uint32_t)0x0040;
}
if (pending & (uint32_t)0x0080) {
// PC7 fired
triggerEXTI(3);
reset |= (uint32_t)0x0080;
28c: 32000013 andcc r0, r0, #19
}
if (pending & (uint32_t)0x0100) {
290: 1331011d teqne r1, #1073741831 ; 0x40000007
}
}
// Fires off the external interrupt logic for a given pin
static INLINE void triggerEXTI(uint32_t pin) {
InterruptHandler handler = _sensorState[pin].eventTrigger;
294: 06120111 ; <UNDEFINED> instruction: 0x06120111
if (handler != NULL)
298: 05590b58 ldrbeq r0, [r9, #-2904] ; 0xfffff4a8
handler(pin + 1);
29c: 34330000 ldrtcc r0, [r3], #-0
reset |= (uint32_t)0x0080;
}
if (pending & (uint32_t)0x0100) {
// PE8 fired
triggerEXTI(6);
reset |= (uint32_t)0x0100;
2a0: 3a0e0300 bcc 380ea8 <encoderGet+0x380ea8>
}
if (pending & (uint32_t)0x0200) {
2a4: 490b3b0b stmdbmi fp, {r0, r1, r3, r8, r9, fp, ip, sp}
}
}
// Fires off the external interrupt logic for a given pin
static INLINE void triggerEXTI(uint32_t pin) {
InterruptHandler handler = _sensorState[pin].eventTrigger;
2a8: 3c193f13 ldccc 15, cr3, [r9], {19}
if (handler != NULL)
handler(pin + 1);
2ac: 34000019 strcc r0, [r0], #-25 ; 0xffffffe7
reset |= (uint32_t)0x0100;
}
if (pending & (uint32_t)0x0200) {
// PE9 fired
triggerEXTI(0);
reset |= (uint32_t)0x0200;
2b0: 13490101 movtne r0, #37121 ; 0x9101
}
EXTI->PR = reset;
2b4: 00001301 andeq r1, r0, r1, lsl #6
}
2b8: 49002135 stmdbmi r0, {r0, r2, r4, r5, r8, sp}
2bc: 000b2f13 andeq r2, fp, r3, lsl pc
2c0: 00343600 eorseq r3, r4, r0, lsl #12
2c4: 0b3a0e03 bleq e83ad8 <encoderGet+0xe83ad8>
// External interrupts all Px10-Px15 pins
// (PE10/Digital 8, PE11/Digital 2, PE12/Digital 9, PE13/Digital 5, PE14/Digital 6)
IRQ ISR_EXTI15_10() {
2c8: 13490b3b movtne r0, #39739 ; 0x9b3b
2cc: 1802193f stmdane r2, {r0, r1, r2, r3, r4, r5, r8, fp, ip}
2d0: 2e370000 cdpcs 0, 3, cr0, cr7, cr0, {0}
uint32_t pending = EXTI->PR, reset = 0;
2d4: 03193f01 tsteq r9, #1, 30
if (pending & (uint32_t)0x0400) {
2d8: 3b0b3a0e blcc 2ceb18 <encoderGet+0x2ceb18>
}
}
// Fires off the external interrupt logic for a given pin
static INLINE void triggerEXTI(uint32_t pin) {
InterruptHandler handler = _sensorState[pin].eventTrigger;
2dc: 3c192705 ldccc 7, cr2, [r9], {5}
if (handler != NULL)
2e0: 00000019 andeq r0, r0, r9, lsl r0
Disassembly of section .debug_loc:
00000000 <.debug_loc>:
#endif
// encoderGet - Gets the value of the encoder
int encoderGet(Encoder enc) {
Sensor_TypeDef *encoder = (Sensor_TypeDef*)enc;
if (encoder)
0: 00000000 andeq r0, r0, r0
0: R_ARM_ABS32 .text.encoderGet
return (int)encoder->value;
return 0;
}
4: 00000004 andeq r0, r0, r4
4: R_ARM_ABS32 .text.encoderGet
}
// encoderReset - Resets the encoder to zero
void encoderReset(Encoder enc) {
Sensor_TypeDef *encoder = (Sensor_TypeDef*)enc;
if (encoder) {
8: 04500001 ldrbeq r0, [r0], #-1
b: R_ARM_ABS32 .text.encoderGet
extern volatile uint32_t _criticalNesting;
/* Enter a critical section. */
static INLINE void _enterCritical() {
__disable_irq();
_criticalNesting++;
c: 06000000 streq r0, [r0], -r0
f: R_ARM_ABS32 .text.encoderGet
10: 04000000 streq r0, [r0], #-0
_enterCritical();
{
encoder->value = 0;
14: 5001f300 andpl pc, r1, r0, lsl #6
encoder->lastValue = 0;
18: 0000009f muleq r0, pc, r0 ; <UNPREDICTABLE>
}
/* Exit a critical section. */
static INLINE void _exitCritical() {
const uint32_t newCritical = _criticalNesting - 1;
1c: 00000000 andeq r0, r0, r0
_criticalNesting = newCritical;
if (newCritical == 0)
20: 00001600 andeq r1, r0, r0, lsl #12
21: R_ARM_ABS32 .text.encoderReset
24: 00001c00 andeq r1, r0, r0, lsl #24
25: R_ARM_ABS32 .text.encoderReset
28: 53000100 movwpl r0, #256 ; 0x100
...
34: R_ARM_ABS32 .text.ioClearInterrupt
#define USART_CR3_CTSE ((uint16_t)0x0200)
// Disables FAULT interrupts
static inline void __disable_fault_irq() { asm volatile ("cpsid f"); }
// Disables interrupts
static inline void __disable_irq() { asm volatile ("cpsid i"); }
38: 00000002 andeq r0, r0, r2
38: R_ARM_ABS32 .text.ioClearInterrupt
pin--;
if (pin < 12 && pin != 9) {
// Avoid having the OS swap this out
_enterCritical();
{
uint32_t mask = (uint32_t)1 << _pinIndexTable[pin + 1];
3c: 02500001 subseq r0, r0, #1
3f: R_ARM_ABS32 .text.ioClearInterrupt
extern volatile uint32_t _criticalNesting;
/* Enter a critical section. */
static INLINE void _enterCritical() {
__disable_irq();
_criticalNesting++;
40: 04000000 streq r0, [r0], #-0
43: R_ARM_ABS32 .text.ioClearInterrupt
44: 04000000 streq r0, [r0], #-0
48: 5001f300 andpl pc, r1, r0, lsl #6
// Clear pending interrupt
EXTI->PR |= mask;
4c: 0000049f muleq r0, pc, r4 ; <UNPREDICTABLE>
4d: R_ARM_ABS32 .text.ioClearInterrupt
50: 00001c00 andeq r1, r0, r0, lsl #24
51: R_ARM_ABS32 .text.ioClearInterrupt
// Mask interrupt
EXTI->IMR &= ~mask;
54: 50000100 andpl r0, r0, r0, lsl #2
...
}
/* Exit a critical section. */
static INLINE void _exitCritical() {
const uint32_t newCritical = _criticalNesting - 1;
_criticalNesting = newCritical;
60: 00000020 andeq r0, r0, r0, lsr #32
60: R_ARM_ABS32 .text.ioClearInterrupt
// Waits for memory accesses to complete before continuing (Data Synchronization Barrier)
static inline void __dsb() { asm volatile ("dsb"); }
// Enables FAULT interrupts
static inline void __enable_fault_irq() { asm volatile ("cpsie f"); }
// Enables interrupts
static inline void __enable_irq() { asm volatile ("cpsie i"); }
64: 0000002e andeq r0, r0, lr, lsr #32
64: R_ARM_ABS32 .text.ioClearInterrupt
68: 00510001 subseq r0, r1, r1
6c: 00000000 andeq r0, r0, r0
70: 34000000 strcc r0, [r0], #-0
73: R_ARM_ABS32 .text.ioClearInterrupt
_exitCritical();
}
}
// encoderShutdown - Stops and disables the encoder
void encoderShutdown(Encoder enc) {
74: 3a000000 bcc 8 <.debug_loc+0x8>
77: R_ARM_ABS32 .text.ioClearInterrupt
Sensor_TypeDef *encoder = (Sensor_TypeDef*)enc;
if (encoder) {
78: 01000000 mrseq r0, (UNDEF: 0)
extern volatile uint32_t _criticalNesting;
/* Enter a critical section. */
static INLINE void _enterCritical() {
__disable_irq();
_criticalNesting++;
7c: 00005300 andeq r5, r0, r0, lsl #6
...
86: R_ARM_ABS32 .text.encoderShutdown
_enterCritical();
{
// Stop
encoder->flags = 0;
_sensorState[encoder->portBottom].flags = 0;
88: 00200000 eoreq r0, r0, r0
8a: R_ARM_ABS32 .text.encoderShutdown
8c: 00010000 andeq r0, r1, r0
90: 00002050 andeq r2, r0, r0, asr r0
91: R_ARM_ABS32 .text.encoderShutdown
// Clear interrupts
ioClearInterrupt(encoder->portTop);
94: 00003600 andeq r3, r0, r0, lsl #12
95: R_ARM_ABS32 .text.encoderShutdown
ioClearInterrupt(encoder->portBottom);
98: 54000100 strpl r0, [r0], #-256 ; 0xffffff00
9c: 00000036 andeq r0, r0, r6, lsr r0
9c: R_ARM_ABS32 .text.encoderShutdown
}
/* Exit a critical section. */
static INLINE void _exitCritical() {
const uint32_t newCritical = _criticalNesting - 1;
a0: 00000040 andeq r0, r0, r0, asr #32
a0: R_ARM_ABS32 .text.encoderShutdown
_criticalNesting = newCritical;
if (newCritical == 0)
a4: 01f30004 mvnseq r0, r4
a8: 00009f50 andeq r9, r0, r0, asr pc
ac: 00000000 andeq r0, r0, r0
b0: 002e0000 eoreq r0, lr, r0
b2: R_ARM_ABS32 .text.encoderShutdown
}
// ioSetInterrupt - Sets up an interrupt to occur on the specified pin, and resets count & time
// Provide NULL for handler for standard interrupts, or pass function pointer for custom
void ioSetInterrupt(unsigned char pin, unsigned char edges, InterruptHandler handler) {
pin--;
b4: 00340000 eorseq r0, r4, r0
b6: R_ARM_ABS32 .text.encoderShutdown
if (pin < BOARD_NR_DIGITAL_IO && pin != 9) {
b8: 00010000 andeq r0, r1, r0
bc: 00000053 andeq r0, r0, r3, asr r0
...
c5: R_ARM_ABS32 .text.ioSetInterrupt
extern volatile uint32_t _criticalNesting;
/* Enter a critical section. */
static INLINE void _enterCritical() {
__disable_irq();
_criticalNesting++;
c8: 00000200 andeq r0, r0, r0, lsl #4
c9: R_ARM_ABS32 .text.ioSetInterrupt
// Configure freely, we won't have an issue here since interrupt is masked
Sensor_TypeDef *state = &_sensorState[pin];
state->eventTrigger = handler;
// Falling edge configuration
temp = EXTI->FTSR;
if (edges & INTERRUPT_EDGE_FALLING)
cc: 50000100 andpl r0, r0, r0, lsl #2
d0: 00000002 andeq r0, r0, r2
d0: R_ARM_ABS32 .text.ioSetInterrupt
if (pin < BOARD_NR_DIGITAL_IO && pin != 9) {
// Avoid having the OS swap this out during init
_enterCritical();
{
// In range, start by masking interrupt if enabled
uint32_t mask = (uint32_t)1 << _pinIndexTable[pin + 1], temp;
d4: 00000004 andeq r0, r0, r4
d4: R_ARM_ABS32 .text.ioSetInterrupt
d8: 01f30004 mvnseq r0, r4
dc: 00049f50 andeq r9, r4, r0, asr pc
de: R_ARM_ABS32 .text.ioSetInterrupt
EXTI->IMR &= ~mask;
e0: 003e0000 eorseq r0, lr, r0
e2: R_ARM_ABS32 .text.ioSetInterrupt
e4: 00010000 andeq r0, r1, r0
e8: 00000050 andeq r0, r0, r0, asr r0
...
f1: R_ARM_ABS32 .text.ioSetInterrupt
// Configure freely, we won't have an issue here since interrupt is masked
Sensor_TypeDef *state = &_sensorState[pin];
state->eventTrigger = handler;
// Falling edge configuration
temp = EXTI->FTSR;
f4: 00004e00 andeq r4, r0, r0, lsl #28
f5: R_ARM_ABS32 .text.ioSetInterrupt
if (edges & INTERRUPT_EDGE_FALLING)
temp |= mask;
f8: 51000100 mrspl r0, (UNDEF: 16)
else
temp &= ~mask;
EXTI->FTSR = temp;
fc: 0000004e andeq r0, r0, lr, asr #32
fc: R_ARM_ABS32 .text.ioSetInterrupt
// Rising edge configuration
temp = EXTI->RTSR;
if (edges & INTERRUPT_EDGE_RISING)
100: 00000084 andeq r0, r0, r4, lsl #1
100: R_ARM_ABS32 .text.ioSetInterrupt
temp |= mask;
104: 01f30004 mvnseq r0, r4
else
temp &= ~mask;
108: 00009f51 andeq r9, r0, r1, asr pc
EXTI->RTSR = temp;
10c: 00000000 andeq r0, r0, r0
// Clear pending interrupt
EXTI->PR |= mask;
110: 002a0000 eoreq r0, sl, r0
112: R_ARM_ABS32 .text.ioSetInterrupt
// Unmask interrupt to start monitoring
EXTI->IMR |= mask;
114: 00640000 rsbeq r0, r4, r0
116: R_ARM_ABS32 .text.ioSetInterrupt
118: 00010000 andeq r0, r1, r0
}
/* Exit a critical section. */
static INLINE void _exitCritical() {
const uint32_t newCritical = _criticalNesting - 1;
11c: 00006454 andeq r6, r0, r4, asr r4
11d: R_ARM_ABS32 .text.ioSetInterrupt
_criticalNesting = newCritical;
if (newCritical == 0)
120: 00007000 andeq r7, r0, r0
121: R_ARM_ABS32 .text.ioSetInterrupt
124: 75000400 strvc r0, [r0, #-1024] ; 0xfffffc00
128: 009f2000 addseq r2, pc, r0
12c: 00000000 andeq r0, r0, r0
130: 42000000 andmi r0, r0, #0
133: R_ARM_ABS32 .text.ioSetInterrupt
134: 54000000 strpl r0, [r0], #-0
137: R_ARM_ABS32 .text.ioSetInterrupt
return (int)encoder->value;
return 0;
}
// encoderInit - Initializes and enables a quadrature encoder on two digital ports
Encoder encoderInit(unsigned char portTop, unsigned char portBottom, bool reverse) {
138: 01000000 mrseq r0, (UNDEF: 0)
Sensor_TypeDef *encoder, *slave;
// Change to 0..11 range
uint32_t it = portTop - 1, ib = portBottom - 1;
13c: 00545000 subseq r5, r4, r0
13e: R_ARM_ABS32 .text.ioSetInterrupt
return (int)encoder->value;
return 0;
}
// encoderInit - Initializes and enables a quadrature encoder on two digital ports
Encoder encoderInit(unsigned char portTop, unsigned char portBottom, bool reverse) {
140: 005c0000 subseq r0, ip, r0
142: R_ARM_ABS32 .text.ioSetInterrupt
Sensor_TypeDef *encoder, *slave;
// Change to 0..11 range
uint32_t it = portTop - 1, ib = portBottom - 1;
144: 00010000 andeq r0, r1, r0
// Check range
if (it < BOARD_NR_DIGITAL_IO && it != 9 && _sensorState[it].flags == 0 &&
148: 00005c51 andeq r5, r0, r1, asr ip
149: R_ARM_ABS32 .text.ioSetInterrupt
14c: 00006000 andeq r6, r0, r0
14d: R_ARM_ABS32 .text.ioSetInterrupt
150: 73000200 movwvc r0, #512 ; 0x200
154: 00000008 andeq r0, r0, r8
158: 00000000 andeq r0, r0, r0
15c: 00003800 andeq r3, r0, r0, lsl #16
15d: R_ARM_ABS32 .text.ioSetInterrupt
160: 00003e00 andeq r3, r0, r0, lsl #28
161: R_ARM_ABS32 .text.ioSetInterrupt
ib < BOARD_NR_DIGITAL_IO && ib != 9 && _sensorState[ib].flags == 0) {
164: 70000b00 andvc r0, r0, r0, lsl #22
168: 03243400 ; <UNDEFINED> instruction: 0x03243400
16c: 00000000 andeq r0, r0, r0
16c: R_ARM_ABS32 _sensorState
170: 00009f22 andeq r9, r0, r2, lsr #30
174: 00000000 andeq r0, r0, r0
178: 006a0000 rsbeq r0, sl, r0
17a: R_ARM_ABS32 .text.ioSetInterrupt
17c: 00700000 rsbseq r0, r0, r0
17e: R_ARM_ABS32 .text.ioSetInterrupt
extern volatile uint32_t _criticalNesting;
/* Enter a critical section. */
static INLINE void _enterCritical() {
__disable_irq();
_criticalNesting++;
180: 00010000 andeq r0, r1, r0
{
uint16_t flags = (uint16_t)0x0002 | (uint16_t)(reverse ? 0x01 : 0x00);
encoder = &_sensorState[it];
slave = &_sensorState[ib];
// Set pins to input pull-up
pinMode(portTop, DDR_INPUT_PULLUP);
184: 00000053 andeq r0, r0, r3, asr r0
...
18d: R_ARM_ABS32 .text.encoderInit
190: 00005f00 andeq r5, r0, r0, lsl #30
191: R_ARM_ABS32 .text.encoderInit
194: 50000100 andpl r0, r0, r0, lsl #2
pinMode(portBottom, DDR_INPUT_PULLUP);
198: 0000005f andeq r0, r0, pc, asr r0
198: R_ARM_ABS32 .text.encoderInit
19c: 000000ac andeq r0, r0, ip, lsr #1
19c: R_ARM_ABS32 .text.encoderInit
// Set state of master pin (top)
encoder->flags = flags;
encoder->portTop = (uint8_t)portTop;
encoder->portBottom = (uint8_t)portBottom;
encoder->value = 0;
1a0: 01f30004 mvnseq r0, r4
slave = &_sensorState[ib];
// Set pins to input pull-up
pinMode(portTop, DDR_INPUT_PULLUP);
pinMode(portBottom, DDR_INPUT_PULLUP);
// Set state of master pin (top)
encoder->flags = flags;
1a4: 00ac9f50 adceq r9, ip, r0, asr pc
1a6: R_ARM_ABS32 .text.encoderInit
// Set slaved state
slave->flags = flags;
slave->portTop = (uint8_t)portTop;
slave->portBottom = (uint8_t)portBottom;
// Interrupt per-port on either rising or falling edge
ioSetInterrupt(portTop, INTERRUPT_EDGE_BOTH, _encoderISRTop);
1a8: 00ae0000 adceq r0, lr, r0
1aa: R_ARM_ABS32 .text.encoderInit
// Set pins to input pull-up
pinMode(portTop, DDR_INPUT_PULLUP);
pinMode(portBottom, DDR_INPUT_PULLUP);
// Set state of master pin (top)
encoder->flags = flags;
encoder->portTop = (uint8_t)portTop;
1ac: 00010000 andeq r0, r1, r0
encoder->portBottom = (uint8_t)portBottom;
1b0: 0000ae50 andeq sl, r0, r0, asr lr
1b1: R_ARM_ABS32 .text.encoderInit
encoder->value = 0;
1b4: 0000b000 andeq fp, r0, r0
1b5: R_ARM_ABS32 .text.encoderInit
encoder->lastValue = 0;
1b8: f3000400 vshl.u8 d0, d0, d0
// Set slaved state
slave->flags = flags;
1bc: b09f5001 addslt r5, pc, r1
1bf: R_ARM_ABS32 .text.encoderInit
slave->portTop = (uint8_t)portTop;
1c0: b2000000 andlt r0, r0, #0
1c3: R_ARM_ABS32 .text.encoderInit
slave->portBottom = (uint8_t)portBottom;
1c4: 01000000 mrseq r0, (UNDEF: 0)
// Interrupt per-port on either rising or falling edge
ioSetInterrupt(portTop, INTERRUPT_EDGE_BOTH, _encoderISRTop);
1c8: 00b25000 adcseq r5, r2, r0
1ca: R_ARM_ABS32 .text.encoderInit
ioSetInterrupt(portBottom, INTERRUPT_EDGE_BOTH, _encoderISRBottom);
1cc: 00cc0000 sbceq r0, ip, r0
1ce: R_ARM_ABS32 .text.encoderInit
1d0: 00040000 andeq r0, r4, r0
}
/* Exit a critical section. */
static INLINE void _exitCritical() {
const uint32_t newCritical = _criticalNesting - 1;
1d4: 9f5001f3 svcls 0x005001f3
...
1e0: R_ARM_ABS32 .text.encoderInit
}
_exitCritical();
return (Encoder)encoder;
}
return NULL;
1e4: 0000004e andeq r0, r0, lr, asr #32
1e4: R_ARM_ABS32 .text.encoderInit
1e8: 4e510001 cdpmi 0, 5, cr0, cr1, cr1, {0}
1eb: R_ARM_ABS32 .text.encoderInit
// Interrupt per-port on either rising or falling edge
ioSetInterrupt(portTop, INTERRUPT_EDGE_BOTH, _encoderISRTop);
ioSetInterrupt(portBottom, INTERRUPT_EDGE_BOTH, _encoderISRBottom);
}
_exitCritical();
return (Encoder)encoder;
1ec: ac000000 stcge 0, cr0, [r0], {-0}
1ef: R_ARM_ABS32 .text.encoderInit
}
return NULL;
}
1f0: 04000000 streq r0, [r0], #-0
1f4: 5101f300 mrspl pc, SP_irq ; <UNPREDICTABLE>
1f8: 0000ac9f muleq r0, pc, ip ; <UNPREDICTABLE>
1f9: R_ARM_ABS32 .text.encoderInit
1fc: 0000b400 andeq fp, r0, r0, lsl #8
1fd: R_ARM_ABS32 .text.encoderInit
200: 51000100 mrspl r0, (UNDEF: 16)
if (handler != NULL)
handler(pin + 1);
}
// External interrupts all Px0 pins (PD0/Digital 11)
IRQ ISR_EXTI0() {
204: 000000b4 strheq r0, [r0], -r4
204: R_ARM_ABS32 .text.encoderInit
208: 000000cc andeq r0, r0, ip, asr #1
208: R_ARM_ABS32 .text.encoderInit
}
}
// Fires off the external interrupt logic for a given pin
static INLINE void triggerEXTI(uint32_t pin) {
InterruptHandler handler = _sensorState[pin].eventTrigger;
20c: 01f30004 mvnseq r0, r4
210: 00009f51 andeq r9, r0, r1, asr pc
...
21a: R_ARM_ABS32 .text.encoderInit
// External interrupts all Px0 pins (PD0/Digital 11)
IRQ ISR_EXTI0() {
// We assume that this can only fire if unmasked (therefore, wanted)
triggerEXTI(10);
EXTI->PR = (uint32_t)0x0001;
}
21c: 005f0000 subseq r0, pc, r0
21e: R_ARM_ABS32 .text.encoderInit
// External interrupts all Px0 pins (PD0/Digital 11)
IRQ ISR_EXTI0() {
// We assume that this can only fire if unmasked (therefore, wanted)
triggerEXTI(10);
EXTI->PR = (uint32_t)0x0001;
220: 00010000 andeq r0, r1, r0
}
224: 00005f52 andeq r5, r0, r2, asr pc
225: R_ARM_ABS32 .text.encoderInit
228: 0000ac00 andeq sl, r0, r0, lsl #24
229: R_ARM_ABS32 .text.encoderInit
22c: f3000400 vshl.u8 d0, d0, d0
// External interrupts all Px1 pins (PD1/Digital 12)
IRQ ISR_EXTI1() {
230: ac9f5201 lfmge f5, 4, [pc], {1}
233: R_ARM_ABS32 .text.encoderInit
234: b4000000 strlt r0, [r0], #-0
237: R_ARM_ABS32 .text.encoderInit
}
}
// Fires off the external interrupt logic for a given pin
static INLINE void triggerEXTI(uint32_t pin) {
InterruptHandler handler = _sensorState[pin].eventTrigger;
238: 01000000 mrseq r0, (UNDEF: 0)
23c: 00b45200 adcseq r5, r4, r0, lsl #4
23e: R_ARM_ABS32 .text.encoderInit
if (handler != NULL)
240: 00cc0000 sbceq r0, ip, r0
242: R_ARM_ABS32 .text.encoderInit
handler(pin + 1);
244: 00040000 andeq r0, r4, r0
// External interrupts all Px1 pins (PD1/Digital 12)
IRQ ISR_EXTI1() {
// We assume that this can only fire if unmasked (therefore, wanted)
triggerEXTI(11);
EXTI->PR = (uint32_t)0x0002;
}
248: 9f5201f3 svcls 0x005201f3
...
254: 00000056 andeq r0, r0, r6, asr r0
254: R_ARM_ABS32 .text.encoderInit
258: 000000ac andeq r0, r0, ip, lsr #1
258: R_ARM_ABS32 .text.encoderInit
// External interrupts all Px5-Px9 pins
// (PC6/Digital 3, PC7/Digital 4, PE8/Digital 7, PE9/Digital 1)
IRQ ISR_EXTI9_5() {
25c: b4540001 ldrblt r0, [r4], #-1
25f: R_ARM_ABS32 .text.encoderInit
260: b6000000 strlt r0, [r0], -r0
263: R_ARM_ABS32 .text.encoderInit
264: 01000000 mrseq r0, (UNDEF: 0)
uint32_t pending = EXTI->PR, reset = 0;
268: 00005400 andeq r5, r0, r0, lsl #8
if (pending & (uint32_t)0x0040) {
26c: 00000000 andeq r0, r0, r0
270: 00060000 andeq r0, r6, r0
272: R_ARM_ABS32 .text.encoderInit
}
}
// Fires off the external interrupt logic for a given pin
static INLINE void triggerEXTI(uint32_t pin) {
InterruptHandler handler = _sensorState[pin].eventTrigger;
274: 001c0000 andseq r0, ip, r0
276: R_ARM_ABS32 .text.encoderInit
if (handler != NULL)
handler(pin + 1);
278: 00010000 andeq r0, r1, r0
IRQ ISR_EXTI9_5() {
uint32_t pending = EXTI->PR, reset = 0;
if (pending & (uint32_t)0x0040) {
// PC6 fired
triggerEXTI(2);
reset |= (uint32_t)0x0040;
27c: 00001c56 andeq r1, r0, r6, asr ip
27d: R_ARM_ABS32 .text.encoderInit
}
if (pending & (uint32_t)0x0080) {
280: 00005f00 andeq r5, r0, r0, lsl #30
281: R_ARM_ABS32 .text.encoderInit
}
}
// Fires off the external interrupt logic for a given pin
static INLINE void triggerEXTI(uint32_t pin) {
InterruptHandler handler = _sensorState[pin].eventTrigger;
284: 70000300 andvc r0, r0, r0, lsl #6
if (handler != NULL)
handler(pin + 1);
288: 005f9f7f subseq r9, pc, pc, ror pc ; <UNPREDICTABLE>
28a: R_ARM_ABS32 .text.encoderInit
reset |= (uint32_t)0x0040;
}
if (pending & (uint32_t)0x0080) {
// PC7 fired
triggerEXTI(3);
reset |= (uint32_t)0x0080;
28c: 00ac0000 adceq r0, ip, r0
28e: R_ARM_ABS32 .text.encoderInit
}
if (pending & (uint32_t)0x0100) {
290: 00030000 andeq r0, r3, r0
}
}
// Fires off the external interrupt logic for a given pin
static INLINE void triggerEXTI(uint32_t pin) {
InterruptHandler handler = _sensorState[pin].eventTrigger;
294: ac9f7f7a ldcge 15, cr7, [pc], {122} ; 0x7a
297: R_ARM_ABS32 .text.encoderInit
if (handler != NULL)
298: ae000000 cdpge 0, 0, cr0, cr0, cr0, {0}
29b: R_ARM_ABS32 .text.encoderInit
handler(pin + 1);
29c: 03000000 movweq r0, #0
reset |= (uint32_t)0x0080;
}
if (pending & (uint32_t)0x0100) {
// PE8 fired
triggerEXTI(6);
reset |= (uint32_t)0x0100;
2a0: 9f7f7000 svcls 0x007f7000
}
if (pending & (uint32_t)0x0200) {
2a4: 000000ae andeq r0, r0, lr, lsr #1
2a4: R_ARM_ABS32 .text.encoderInit
}
}
// Fires off the external interrupt logic for a given pin
static INLINE void triggerEXTI(uint32_t pin) {
InterruptHandler handler = _sensorState[pin].eventTrigger;
2a8: 000000b0 strheq r0, [r0], -r0 ; <UNPREDICTABLE>
2a8: R_ARM_ABS32 .text.encoderInit
if (handler != NULL)
handler(pin + 1);
2ac: 7f7a0003 svcvc 0x007a0003
reset |= (uint32_t)0x0100;
}
if (pending & (uint32_t)0x0200) {
// PE9 fired
triggerEXTI(0);
reset |= (uint32_t)0x0200;
2b0: 0000b09f muleq r0, pc, r0 ; <UNPREDICTABLE>
2b1: R_ARM_ABS32 .text.encoderInit
}
EXTI->PR = reset;
2b4: 0000b200 andeq fp, r0, r0, lsl #4
2b5: R_ARM_ABS32 .text.encoderInit
}
2b8: 70000300 andvc r0, r0, r0, lsl #6
2bc: 00b29f7f adcseq r9, r2, pc, ror pc
2be: R_ARM_ABS32 .text.encoderInit
2c0: 00bc0000 adcseq r0, ip, r0
2c2: R_ARM_ABS32 .text.encoderInit
2c4: 00030000 andeq r0, r3, r0
// External interrupts all Px10-Px15 pins
// (PE10/Digital 8, PE11/Digital 2, PE12/Digital 9, PE13/Digital 5, PE14/Digital 6)
IRQ ISR_EXTI15_10() {
2c8: 009f7f7a addseq r7, pc, sl, ror pc ; <UNPREDICTABLE>
2cc: 00000000 andeq r0, r0, r0
2d0: 10000000 andne r0, r0, r0
2d3: R_ARM_ABS32 .text.encoderInit
uint32_t pending = EXTI->PR, reset = 0;
2d4: 34000000 strcc r0, [r0], #-0
2d7: R_ARM_ABS32 .text.encoderInit
if (pending & (uint32_t)0x0400) {
2d8: 01000000 mrseq r0, (UNDEF: 0)
}
}
// Fires off the external interrupt logic for a given pin
static INLINE void triggerEXTI(uint32_t pin) {
InterruptHandler handler = _sensorState[pin].eventTrigger;
2dc: 00345500 eorseq r5, r4, r0, lsl #10
2de: R_ARM_ABS32 .text.encoderInit
if (handler != NULL)
2e0: 004e0000 subeq r0, lr, r0
2e2: R_ARM_ABS32 .text.encoderInit
handler(pin + 1);
2e4: 00030000 andeq r0, r3, r0
IRQ ISR_EXTI15_10() {
uint32_t pending = EXTI->PR, reset = 0;
if (pending & (uint32_t)0x0400) {
// PE10 fired
triggerEXTI(7);
reset |= (uint32_t)0x0400;
2e8: 4e9f7f71 mrcmi 15, 4, r7, cr15, cr1, {3}
2eb: R_ARM_ABS32 .text.encoderInit
}
if (pending & (uint32_t)0x0800) {
2ec: ac000000 stcge 0, cr0, [r0], {-0}
2ef: R_ARM_ABS32 .text.encoderInit
}
}
// Fires off the external interrupt logic for a given pin
static INLINE void triggerEXTI(uint32_t pin) {
InterruptHandler handler = _sensorState[pin].eventTrigger;
2f0: 03000000 movweq r0, #0
if (handler != NULL)
handler(pin + 1);
2f4: 9f7f7700 svcls 0x007f7700
reset |= (uint32_t)0x0400;
}
if (pending & (uint32_t)0x0800) {
// PE11 fired
triggerEXTI(1);
reset |= (uint32_t)0x0800;
2f8: 000000ac andeq r0, r0, ip, lsr #1
2f8: R_ARM_ABS32 .text.encoderInit
}
if (pending & (uint32_t)0x1000) {
2fc: 000000b0 strheq r0, [r0], -r0 ; <UNPREDICTABLE>
2fc: R_ARM_ABS32 .text.encoderInit
}
}
// Fires off the external interrupt logic for a given pin
static INLINE void triggerEXTI(uint32_t pin) {
InterruptHandler handler = _sensorState[pin].eventTrigger;
300: b0550001 subslt r0, r5, r1
303: R_ARM_ABS32 .text.encoderInit
304: b4000000 strlt r0, [r0], #-0
307: R_ARM_ABS32 .text.encoderInit
if (handler != NULL)
handler(pin + 1);
308: 03000000 movweq r0, #0
reset |= (uint32_t)0x0800;
}
if (pending & (uint32_t)0x1000) {
// PE12 fired
triggerEXTI(8);
reset |= (uint32_t)0x1000;
30c: 9f7f7100 svcls 0x007f7100
}
if (pending & (uint32_t)0x2000) {
310: 000000b4 strheq r0, [r0], -r4
310: R_ARM_ABS32 .text.encoderInit
}
}
// Fires off the external interrupt logic for a given pin
static INLINE void triggerEXTI(uint32_t pin) {
InterruptHandler handler = _sensorState[pin].eventTrigger;
314: 000000bc strheq r0, [r0], -ip
314: R_ARM_ABS32 .text.encoderInit
if (handler != NULL)
318: 7f770003 svcvc 0x00770003
handler(pin + 1);
31c: 0000009f muleq r0, pc, r0 ; <UNPREDICTABLE>
reset |= (uint32_t)0x1000;
}
if (pending & (uint32_t)0x2000) {
// PE13 fired
triggerEXTI(4);
reset |= (uint32_t)0x2000;
320: 00000000 andeq r0, r0, r0
}
if (pending & (uint32_t)0x4000) {
324: 00005600 andeq r5, r0, r0, lsl #12
325: R_ARM_ABS32 .text.encoderInit
}
}
// Fires off the external interrupt logic for a given pin
static INLINE void triggerEXTI(uint32_t pin) {
InterruptHandler handler = _sensorState[pin].eventTrigger;
328: 0000ac00 andeq sl, r0, r0, lsl #24
329: R_ARM_ABS32 .text.encoderInit
if (handler != NULL)
handler(pin + 1);
32c: 5b000100 blpl 734 <encoderGet+0x734>
reset |= (uint32_t)0x2000;
}
if (pending & (uint32_t)0x4000) {
// PE14 fired
triggerEXTI(5);
reset |= (uint32_t)0x4000;
330: 000000b4 strheq r0, [r0], -r4
330: R_ARM_ABS32 .text.encoderInit
}
EXTI->PR = reset;
334: 000000b6 strheq r0, [r0], -r6
334: R_ARM_ABS32 .text.encoderInit
}
338: 005b0001 subseq r0, fp, r1
33c: 00000000 andeq r0, r0, r0
340: a2000000 andge r0, r0, #0
343: R_ARM_ABS32 .text.encoderInit
344: ac000000 stcge 0, cr0, [r0], {-0}
347: R_ARM_ABS32 .text.encoderInit
348: 01000000 mrseq r0, (UNDEF: 0)
34c: 00b45300 adcseq r5, r4, r0, lsl #6
34e: R_ARM_ABS32 .text.encoderInit
350: 00b60000 adcseq r0, r6, r0
352: R_ARM_ABS32 .text.encoderInit
354: 00010000 andeq r0, r1, r0
358: 00000053 andeq r0, r0, r3, asr r0
35c: 00000000 andeq r0, r0, r0
360: 00001000 andeq r1, r0, r0
361: R_ARM_ABS32 .text.ISR_EXTI0
364: 00001500 andeq r1, r0, r0, lsl #10
365: R_ARM_ABS32 .text.ISR_EXTI0
368: 53000100 movwpl r0, #256 ; 0x100
...
374: 00000010 andeq r0, r0, r0, lsl r0
374: R_ARM_ABS32 .text.ISR_EXTI1
378: 00000015 andeq r0, r0, r5, lsl r0
378: R_ARM_ABS32 .text.ISR_EXTI1
37c: 00530001 subseq r0, r3, r1
380: 00000000 andeq r0, r0, r0
384: 0e000000 cdpeq 0, 0, cr0, cr0, cr0, {0}
387: R_ARM_ABS32 .text.ISR_EXTI9_5
388: 5e000000 cdppl 0, 0, cr0, cr0, cr0, {0}
38b: R_ARM_ABS32 .text.ISR_EXTI9_5
38c: 01000000 mrseq r0, (UNDEF: 0)
390: 00005500 andeq r5, r0, r0, lsl #10
394: 00000000 andeq r0, r0, r0
398: 000e0000 andeq r0, lr, r0
39a: R_ARM_ABS32 .text.ISR_EXTI9_5
39c: 00220000 eoreq r0, r2, r0
39e: R_ARM_ABS32 .text.ISR_EXTI9_5
3a0: 00020000 andeq r0, r2, r0
3a4: 00229f30 eoreq r9, r2, r0, lsr pc
3a6: R_ARM_ABS32 .text.ISR_EXTI9_5
3a8: 005e0000 subseq r0, lr, r0
3aa: R_ARM_ABS32 .text.ISR_EXTI9_5
3ac: 00010000 andeq r0, r1, r0
3b0: 00005e54 andeq r5, r0, r4, asr lr
3b1: R_ARM_ABS32 .text.ISR_EXTI9_5
3b4: 00006c00 andeq r6, r0, r0, lsl #24
3b5: R_ARM_ABS32 .text.ISR_EXTI9_5
3b8: 0c000500 cfstr32eq mvfx0, [r0], {-0}
3bc: 40010414 andmi r0, r1, r4, lsl r4
...
3c8: 00000016 andeq r0, r0, r6, lsl r0
3c8: R_ARM_ABS32 .text.ISR_EXTI9_5
3cc: 00000022 andeq r0, r0, r2, lsr #32
3cc: R_ARM_ABS32 .text.ISR_EXTI9_5
3d0: 9f320002 svcls 0x00320002
...
3dc: 0000001a andeq r0, r0, sl, lsl r0
3dc: R_ARM_ABS32 .text.ISR_EXTI9_5
3e0: 0000001f andeq r0, r0, pc, lsl r0
3e0: R_ARM_ABS32 .text.ISR_EXTI9_5
3e4: 00530001 subseq r0, r3, r1
3e8: 00000000 andeq r0, r0, r0
3ec: 26000000 strcs r0, [r0], -r0
3ef: R_ARM_ABS32 .text.ISR_EXTI9_5
3f0: 34000000 strcc r0, [r0], #-0
3f3: R_ARM_ABS32 .text.ISR_EXTI9_5
3f4: 02000000 andeq r0, r0, #0
3f8: 009f3300 addseq r3, pc, r0, lsl #6
3fc: 00000000 andeq r0, r0, r0
400: 2a000000 bcs 8 <.debug_loc+0x8>
403: R_ARM_ABS32 .text.ISR_EXTI9_5
404: 2f000000 svccs 0x00000000
407: R_ARM_ABS32 .text.ISR_EXTI9_5
408: 01000000 mrseq r0, (UNDEF: 0)
40c: 00005300 andeq r5, r0, r0, lsl #6
410: 00000000 andeq r0, r0, r0
414: 00380000 eorseq r0, r8, r0
416: R_ARM_ABS32 .text.ISR_EXTI9_5
418: 00460000 subeq r0, r6, r0
41a: R_ARM_ABS32 .text.ISR_EXTI9_5
41c: 00020000 andeq r0, r2, r0
420: 00009f36 andeq r9, r0, r6, lsr pc
424: 00000000 andeq r0, r0, r0
428: 003c0000 eorseq r0, ip, r0
42a: R_ARM_ABS32 .text.ISR_EXTI9_5
42c: 00410000 subeq r0, r1, r0
42e: R_ARM_ABS32 .text.ISR_EXTI9_5
430: 00010000 andeq r0, r1, r0
434: 00000053 andeq r0, r0, r3, asr r0
438: 00000000 andeq r0, r0, r0
43c: 00004a00 andeq r4, r0, r0, lsl #20
43d: R_ARM_ABS32 .text.ISR_EXTI9_5
440: 00005800 andeq r5, r0, r0, lsl #16
441: R_ARM_ABS32 .text.ISR_EXTI9_5
444: 30000200 andcc r0, r0, r0, lsl #4
448: 0000009f muleq r0, pc, r0 ; <UNPREDICTABLE>
44c: 00000000 andeq r0, r0, r0
450: 00004e00 andeq r4, r0, r0, lsl #28
451: R_ARM_ABS32 .text.ISR_EXTI9_5
454: 00005300 andeq r5, r0, r0, lsl #6
455: R_ARM_ABS32 .text.ISR_EXTI9_5
458: 53000100 movwpl r0, #256 ; 0x100
...
464: 0000000e andeq r0, r0, lr
464: R_ARM_ABS32 .text.ISR_EXTI15_10
468: 00000072 andeq r0, r0, r2, ror r0
468: R_ARM_ABS32 .text.ISR_EXTI15_10
46c: 00550001 subseq r0, r5, r1
470: 00000000 andeq r0, r0, r0
474: 0e000000 cdpeq 0, 0, cr0, cr0, cr0, {0}
477: R_ARM_ABS32 .text.ISR_EXTI15_10
478: 22000000 andcs r0, r0, #0
47b: R_ARM_ABS32 .text.ISR_EXTI15_10
47c: 02000000 andeq r0, r0, #0
480: 229f3000 addscs r3, pc, #0
483: R_ARM_ABS32 .text.ISR_EXTI15_10
484: 72000000 andvc r0, r0, #0
487: R_ARM_ABS32 .text.ISR_EXTI15_10
488: 01000000 mrseq r0, (UNDEF: 0)
48c: 00725400 rsbseq r5, r2, r0, lsl #8
48e: R_ARM_ABS32 .text.ISR_EXTI15_10
490: 00800000 addeq r0, r0, r0
492: R_ARM_ABS32 .text.ISR_EXTI15_10
494: 00050000 andeq r0, r5, r0
498: 0104140c tsteq r4, ip, lsl #8
49c: 00000040 andeq r0, r0, r0, asr #32
4a0: 00000000 andeq r0, r0, r0
4a4: 00001400 andeq r1, r0, r0, lsl #8
4a5: R_ARM_ABS32 .text.ISR_EXTI15_10
4a8: 00002200 andeq r2, r0, r0, lsl #4
4a9: R_ARM_ABS32 .text.ISR_EXTI15_10
4ac: 37000200 strcc r0, [r0, -r0, lsl #4]
4b0: 0000009f muleq r0, pc, r0 ; <UNPREDICTABLE>
4b4: 00000000 andeq r0, r0, r0
4b8: 00001800 andeq r1, r0, r0, lsl #16
4b9: R_ARM_ABS32 .text.ISR_EXTI15_10
4bc: 00001d00 andeq r1, r0, r0, lsl #26
4bd: R_ARM_ABS32 .text.ISR_EXTI15_10
4c0: 53000100 movwpl r0, #256 ; 0x100
...
4cc: 00000026 andeq r0, r0, r6, lsr #32
4cc: R_ARM_ABS32 .text.ISR_EXTI15_10
4d0: 00000034 andeq r0, r0, r4, lsr r0
4d0: R_ARM_ABS32 .text.ISR_EXTI15_10
4d4: 9f310002 svcls 0x00310002
...
4e0: 0000002a andeq r0, r0, sl, lsr #32
4e0: R_ARM_ABS32 .text.ISR_EXTI15_10
4e4: 0000002f andeq r0, r0, pc, lsr #32
4e4: R_ARM_ABS32 .text.ISR_EXTI15_10
4e8: 00530001 subseq r0, r3, r1
4ec: 00000000 andeq r0, r0, r0
4f0: 38000000 stmdacc r0, {} ; <UNPREDICTABLE>
4f3: R_ARM_ABS32 .text.ISR_EXTI15_10
4f4: 48000000 stmdami r0, {} ; <UNPREDICTABLE>
4f7: R_ARM_ABS32 .text.ISR_EXTI15_10
4f8: 02000000 andeq r0, r0, #0
4fc: 009f3800 addseq r3, pc, r0, lsl #16
500: 00000000 andeq r0, r0, r0
504: 3e000000 cdpcc 0, 0, cr0, cr0, cr0, {0}
507: R_ARM_ABS32 .text.ISR_EXTI15_10
508: 43000000 movwmi r0, #0
50b: R_ARM_ABS32 .text.ISR_EXTI15_10
50c: 01000000 mrseq r0, (UNDEF: 0)
510: 00005300 andeq r5, r0, r0, lsl #6
514: 00000000 andeq r0, r0, r0
518: 004c0000 subeq r0, ip, r0
51a: R_ARM_ABS32 .text.ISR_EXTI15_10
51c: 005a0000 subseq r0, sl, r0
51e: R_ARM_ABS32 .text.ISR_EXTI15_10
520: 00020000 andeq r0, r2, r0
524: 00009f34 andeq r9, r0, r4, lsr pc
528: 00000000 andeq r0, r0, r0
52c: 00500000 subseq r0, r0, r0
52e: R_ARM_ABS32 .text.ISR_EXTI15_10
530: 00550000 subseq r0, r5, r0
532: R_ARM_ABS32 .text.ISR_EXTI15_10
534: 00010000 andeq r0, r1, r0
538: 00000053 andeq r0, r0, r3, asr r0
53c: 00000000 andeq r0, r0, r0
540: 00005e00 andeq r5, r0, r0, lsl #28
541: R_ARM_ABS32 .text.ISR_EXTI15_10
544: 00006c00 andeq r6, r0, r0, lsl #24
545: R_ARM_ABS32 .text.ISR_EXTI15_10
548: 35000200 strcc r0, [r0, #-512] ; 0xfffffe00
54c: 0000009f muleq r0, pc, r0 ; <UNPREDICTABLE>
550: 00000000 andeq r0, r0, r0
554: 00006200 andeq r6, r0, r0, lsl #4
555: R_ARM_ABS32 .text.ISR_EXTI15_10
558: 00006700 andeq r6, r0, r0, lsl #14
559: R_ARM_ABS32 .text.ISR_EXTI15_10
55c: 53000100 movwpl r0, #256 ; 0x100
...
Disassembly of section .debug_aranges:
00000000 <.debug_aranges>:
#endif
// encoderGet - Gets the value of the encoder
int encoderGet(Encoder enc) {
Sensor_TypeDef *encoder = (Sensor_TypeDef*)enc;
if (encoder)
0: 00000064 andeq r0, r0, r4, rrx
return (int)encoder->value;
return 0;
}
4: 00000002 andeq r0, r0, r2
6: R_ARM_ABS32 .debug_info
}
// encoderReset - Resets the encoder to zero
void encoderReset(Encoder enc) {
Sensor_TypeDef *encoder = (Sensor_TypeDef*)enc;
if (encoder) {
8: 00040000 andeq r0, r4, r0
...
10: R_ARM_ABS32 .text.encoderGet
_enterCritical();
{
encoder->value = 0;
14: 00000006 andeq r0, r0, r6
encoder->lastValue = 0;
18: 00000000 andeq r0, r0, r0
18: R_ARM_ABS32 .text.encoderReset
1c: 00000024 andeq r0, r0, r4, lsr #32
_criticalNesting = newCritical;
if (newCritical == 0)
20: 00000000 andeq r0, r0, r0
20: R_ARM_ABS32 .text.ioClearInterrupt
24: 00000048 andeq r0, r0, r8, asr #32
28: 00000000 andeq r0, r0, r0
28: R_ARM_ABS32 .text.encoderShutdown
}
}
// ioClearInterrupt - Disables interrupts on the specified pin
void ioClearInterrupt(unsigned char pin) {
pin--;
2c: 00000040 andeq r0, r0, r0, asr #32
if (pin < 12 && pin != 9) {
30: 00000000 andeq r0, r0, r0
30: R_ARM_ABS32 .text.ioSetInterrupt
34: 00000084 andeq r0, r0, r4, lsl #1
#define USART_CR3_CTSE ((uint16_t)0x0200)
// Disables FAULT interrupts
static inline void __disable_fault_irq() { asm volatile ("cpsid f"); }
// Disables interrupts
static inline void __disable_irq() { asm volatile ("cpsid i"); }
38: 00000000 andeq r0, r0, r0
38: R_ARM_ABS32 .text.encoderInit
// Avoid having the OS swap this out
_enterCritical();
{
uint32_t mask = (uint32_t)1 << _pinIndexTable[pin + 1];
3c: 000000cc andeq r0, r0, ip, asr #1
extern volatile uint32_t _criticalNesting;
/* Enter a critical section. */
static INLINE void _enterCritical() {
__disable_irq();
_criticalNesting++;
40: 00000000 andeq r0, r0, r0
40: R_ARM_ABS32 .text.ISR_EXTI0
44: 0000002c andeq r0, r0, ip, lsr #32
48: 00000000 andeq r0, r0, r0
48: R_ARM_ABS32 .text.ISR_EXTI1
// Clear pending interrupt
EXTI->PR |= mask;
4c: 0000002c andeq r0, r0, ip, lsr #32
50: 00000000 andeq r0, r0, r0
50: R_ARM_ABS32 .text.ISR_EXTI9_5
// Mask interrupt
EXTI->IMR &= ~mask;
54: 0000006c andeq r0, r0, ip, rrx
58: 00000000 andeq r0, r0, r0
58: R_ARM_ABS32 .text.ISR_EXTI15_10
}
/* Exit a critical section. */
static INLINE void _exitCritical() {
const uint32_t newCritical = _criticalNesting - 1;
5c: 00000080 andeq r0, r0, r0, lsl #1
...
Disassembly of section .debug_ranges:
00000000 <.debug_ranges>:
#endif
// encoderGet - Gets the value of the encoder
int encoderGet(Encoder enc) {
Sensor_TypeDef *encoder = (Sensor_TypeDef*)enc;
if (encoder)
0: 0000000c andeq r0, r0, ip
0: R_ARM_ABS32 .text.ioClearInterrupt
return (int)encoder->value;
return 0;
}
4: 00000010 andeq r0, r0, r0, lsl r0
4: R_ARM_ABS32 .text.ioClearInterrupt
}
// encoderReset - Resets the encoder to zero
void encoderReset(Encoder enc) {
Sensor_TypeDef *encoder = (Sensor_TypeDef*)enc;
if (encoder) {
8: 00000012 andeq r0, r0, r2, lsl r0
8: R_ARM_ABS32 .text.ioClearInterrupt
extern volatile uint32_t _criticalNesting;
/* Enter a critical section. */
static INLINE void _enterCritical() {
__disable_irq();
_criticalNesting++;
c: 00000018 andeq r0, r0, r8, lsl r0
c: R_ARM_ABS32 .text.ioClearInterrupt
...
_enterCritical();
{
encoder->value = 0;
encoder->lastValue = 0;
18: 00000010 andeq r0, r0, r0, lsl r0
18: R_ARM_ABS32 .text.ioClearInterrupt
}
/* Exit a critical section. */
static INLINE void _exitCritical() {
const uint32_t newCritical = _criticalNesting - 1;
1c: 00000012 andeq r0, r0, r2, lsl r0
1c: R_ARM_ABS32 .text.ioClearInterrupt
_criticalNesting = newCritical;
if (newCritical == 0)
20: 00000018 andeq r0, r0, r8, lsl r0
20: R_ARM_ABS32 .text.ioClearInterrupt
// Waits for memory accesses to complete before continuing (Data Synchronization Barrier)
static inline void __dsb() { asm volatile ("dsb"); }
// Enables FAULT interrupts
static inline void __enable_fault_irq() { asm volatile ("cpsie f"); }
// Enables interrupts
static inline void __enable_irq() { asm volatile ("cpsie i"); }
24: 00000030 andeq r0, r0, r0, lsr r0
24: R_ARM_ABS32 .text.ioClearInterrupt
...
}
// ioClearInterrupt - Disables interrupts on the specified pin
void ioClearInterrupt(unsigned char pin) {
pin--;
if (pin < 12 && pin != 9) {
30: 00000006 andeq r0, r0, r6
30: R_ARM_ABS32 .text.encoderShutdown
34: 0000000a andeq r0, r0, sl
34: R_ARM_ABS32 .text.encoderShutdown
#define USART_CR3_CTSE ((uint16_t)0x0200)
// Disables FAULT interrupts
static inline void __disable_fault_irq() { asm volatile ("cpsid f"); }
// Disables interrupts
static inline void __disable_irq() { asm volatile ("cpsid i"); }
38: 0000000c andeq r0, r0, ip
38: R_ARM_ABS32 .text.encoderShutdown
// Avoid having the OS swap this out
_enterCritical();
{
uint32_t mask = (uint32_t)1 << _pinIndexTable[pin + 1];
3c: 00000012 andeq r0, r0, r2, lsl r0
3c: R_ARM_ABS32 .text.encoderShutdown
...
48: 0000000e andeq r0, r0, lr
48: R_ARM_ABS32 .text.ioSetInterrupt
// Clear pending interrupt
EXTI->PR |= mask;
4c: 00000012 andeq r0, r0, r2, lsl r0
4c: R_ARM_ABS32 .text.ioSetInterrupt
50: 00000014 andeq r0, r0, r4, lsl r0
50: R_ARM_ABS32 .text.ioSetInterrupt
// Mask interrupt
EXTI->IMR &= ~mask;
54: 00000016 andeq r0, r0, r6, lsl r0
54: R_ARM_ABS32 .text.ioSetInterrupt
58: 0000001a andeq r0, r0, sl, lsl r0
58: R_ARM_ABS32 .text.ioSetInterrupt
_criticalNesting++;
}
/* Exit a critical section. */
static INLINE void _exitCritical() {
const uint32_t newCritical = _criticalNesting - 1;
5c: 00000020 andeq r0, r0, r0, lsr #32
5c: R_ARM_ABS32 .text.ioSetInterrupt
...
// Waits for memory accesses to complete before continuing (Data Synchronization Barrier)
static inline void __dsb() { asm volatile ("dsb"); }
// Enables FAULT interrupts
static inline void __enable_fault_irq() { asm volatile ("cpsie f"); }
// Enables interrupts
static inline void __enable_irq() { asm volatile ("cpsie i"); }
68: 00000012 andeq r0, r0, r2, lsl r0
68: R_ARM_ABS32 .text.ioSetInterrupt
6c: 00000014 andeq r0, r0, r4, lsl r0
6c: R_ARM_ABS32 .text.ioSetInterrupt
70: 00000016 andeq r0, r0, r6, lsl r0
70: R_ARM_ABS32 .text.ioSetInterrupt
_exitCritical();
}
}
// encoderShutdown - Stops and disables the encoder
void encoderShutdown(Encoder enc) {
74: 0000001a andeq r0, r0, sl, lsl r0
74: R_ARM_ABS32 .text.ioSetInterrupt
Sensor_TypeDef *encoder = (Sensor_TypeDef*)enc;
if (encoder) {
78: 00000020 andeq r0, r0, r0, lsr #32
78: R_ARM_ABS32 .text.ioSetInterrupt
extern volatile uint32_t _criticalNesting;
/* Enter a critical section. */
static INLINE void _enterCritical() {
__disable_irq();
_criticalNesting++;
7c: 00000066 andeq r0, r0, r6, rrx
7c: R_ARM_ABS32 .text.ioSetInterrupt
...
_enterCritical();
{
// Stop
encoder->flags = 0;
_sensorState[encoder->portBottom].flags = 0;
88: 00000046 andeq r0, r0, r6, asr #32
88: R_ARM_ABS32 .text.encoderInit
8c: 0000004c andeq r0, r0, ip, asr #32
8c: R_ARM_ABS32 .text.encoderInit
90: 0000004e andeq r0, r0, lr, asr #32
90: R_ARM_ABS32 .text.encoderInit
// Clear interrupts
ioClearInterrupt(encoder->portTop);
94: 00000052 andeq r0, r0, r2, asr r0
94: R_ARM_ABS32 .text.encoderInit
ioClearInterrupt(encoder->portBottom);
98: 00000056 andeq r0, r0, r6, asr r0
98: R_ARM_ABS32 .text.encoderInit
9c: 0000005c andeq r0, r0, ip, asr r0
9c: R_ARM_ABS32 .text.encoderInit
...
a8: 0000004c andeq r0, r0, ip, asr #32
a8: R_ARM_ABS32 .text.encoderInit
ac: 0000004e andeq r0, r0, lr, asr #32
ac: R_ARM_ABS32 .text.encoderInit
b0: 00000052 andeq r0, r0, r2, asr r0
b0: R_ARM_ABS32 .text.encoderInit
}
// ioSetInterrupt - Sets up an interrupt to occur on the specified pin, and resets count & time
// Provide NULL for handler for standard interrupts, or pass function pointer for custom
void ioSetInterrupt(unsigned char pin, unsigned char edges, InterruptHandler handler) {
pin--;
b4: 00000056 andeq r0, r0, r6, asr r0
b4: R_ARM_ABS32 .text.encoderInit
if (pin < BOARD_NR_DIGITAL_IO && pin != 9) {
b8: 0000005c andeq r0, r0, ip, asr r0
b8: R_ARM_ABS32 .text.encoderInit
bc: 0000009c muleq r0, ip, r0
bc: R_ARM_ABS32 .text.encoderInit
...
c8: 00000008 andeq r0, r0, r8
c8: R_ARM_ABS32 .text.ISR_EXTI0
// Configure freely, we won't have an issue here since interrupt is masked
Sensor_TypeDef *state = &_sensorState[pin];
state->eventTrigger = handler;
// Falling edge configuration
temp = EXTI->FTSR;
if (edges & INTERRUPT_EDGE_FALLING)
cc: 0000000a andeq r0, r0, sl
cc: R_ARM_ABS32 .text.ISR_EXTI0
d0: 0000000c andeq r0, r0, ip
d0: R_ARM_ABS32 .text.ISR_EXTI0
if (pin < BOARD_NR_DIGITAL_IO && pin != 9) {
// Avoid having the OS swap this out during init
_enterCritical();
{
// In range, start by masking interrupt if enabled
uint32_t mask = (uint32_t)1 << _pinIndexTable[pin + 1], temp;
d4: 00000016 andeq r0, r0, r6, lsl r0
d4: R_ARM_ABS32 .text.ISR_EXTI0
...
EXTI->IMR &= ~mask;
e0: 00000008 andeq r0, r0, r8
e0: R_ARM_ABS32 .text.ISR_EXTI1
e4: 0000000a andeq r0, r0, sl
e4: R_ARM_ABS32 .text.ISR_EXTI1
e8: 0000000c andeq r0, r0, ip
e8: R_ARM_ABS32 .text.ISR_EXTI1
// Configure freely, we won't have an issue here since interrupt is masked
Sensor_TypeDef *state = &_sensorState[pin];
state->eventTrigger = handler;
ec: 00000016 andeq r0, r0, r6, lsl r0
ec: R_ARM_ABS32 .text.ISR_EXTI1
...
f8: R_ARM_ABS32 .text.encoderGet
temp = EXTI->FTSR;
if (edges & INTERRUPT_EDGE_FALLING)
temp |= mask;
else
temp &= ~mask;
EXTI->FTSR = temp;
fc: 00000006 andeq r0, r0, r6
fc: R_ARM_ABS32 .text.encoderGet
// Rising edge configuration
temp = EXTI->RTSR;
if (edges & INTERRUPT_EDGE_RISING)
100: 00000000 andeq r0, r0, r0
100: R_ARM_ABS32 .text.encoderReset
temp |= mask;
104: 00000024 andeq r0, r0, r4, lsr #32
104: R_ARM_ABS32 .text.encoderReset
else
temp &= ~mask;
108: 00000000 andeq r0, r0, r0
108: R_ARM_ABS32 .text.ioClearInterrupt
EXTI->RTSR = temp;
10c: 00000048 andeq r0, r0, r8, asr #32
10c: R_ARM_ABS32 .text.ioClearInterrupt
// Clear pending interrupt
EXTI->PR |= mask;
110: 00000000 andeq r0, r0, r0
110: R_ARM_ABS32 .text.encoderShutdown
// Unmask interrupt to start monitoring
EXTI->IMR |= mask;
114: 00000040 andeq r0, r0, r0, asr #32
114: R_ARM_ABS32 .text.encoderShutdown
118: 00000000 andeq r0, r0, r0
118: R_ARM_ABS32 .text.ioSetInterrupt
}
/* Exit a critical section. */
static INLINE void _exitCritical() {
const uint32_t newCritical = _criticalNesting - 1;
11c: 00000084 andeq r0, r0, r4, lsl #1
11c: R_ARM_ABS32 .text.ioSetInterrupt
_criticalNesting = newCritical;
if (newCritical == 0)
120: 00000000 andeq r0, r0, r0
120: R_ARM_ABS32 .text.encoderInit
124: 000000cc andeq r0, r0, ip, asr #1
124: R_ARM_ABS32 .text.encoderInit
128: 00000000 andeq r0, r0, r0
128: R_ARM_ABS32 .text.ISR_EXTI0
12c: 0000002c andeq r0, r0, ip, lsr #32
12c: R_ARM_ABS32 .text.ISR_EXTI0
130: 00000000 andeq r0, r0, r0
130: R_ARM_ABS32 .text.ISR_EXTI1
134: 0000002c andeq r0, r0, ip, lsr #32
134: R_ARM_ABS32 .text.ISR_EXTI1
return (int)encoder->value;
return 0;
}
// encoderInit - Initializes and enables a quadrature encoder on two digital ports
Encoder encoderInit(unsigned char portTop, unsigned char portBottom, bool reverse) {
138: 00000000 andeq r0, r0, r0
138: R_ARM_ABS32 .text.ISR_EXTI9_5
Sensor_TypeDef *encoder, *slave;
// Change to 0..11 range
uint32_t it = portTop - 1, ib = portBottom - 1;
13c: 0000006c andeq r0, r0, ip, rrx
13c: R_ARM_ABS32 .text.ISR_EXTI9_5
return (int)encoder->value;
return 0;
}
// encoderInit - Initializes and enables a quadrature encoder on two digital ports
Encoder encoderInit(unsigned char portTop, unsigned char portBottom, bool reverse) {
140: 00000000 andeq r0, r0, r0
140: R_ARM_ABS32 .text.ISR_EXTI15_10
Sensor_TypeDef *encoder, *slave;
// Change to 0..11 range
uint32_t it = portTop - 1, ib = portBottom - 1;
144: 00000080 andeq r0, r0, r0, lsl #1
144: R_ARM_ABS32 .text.ISR_EXTI15_10
...
Disassembly of section .debug_line:
00000000 <.debug_line>:
#endif
// encoderGet - Gets the value of the encoder
int encoderGet(Encoder enc) {
Sensor_TypeDef *encoder = (Sensor_TypeDef*)enc;
if (encoder)
0: 0000030a andeq r0, r0, sl, lsl #6
return (int)encoder->value;
return 0;
}
4: 00a60002 adceq r0, r6, r2
}
// encoderReset - Resets the encoder to zero
void encoderReset(Encoder enc) {
Sensor_TypeDef *encoder = (Sensor_TypeDef*)enc;
if (encoder) {
8: 01020000 mrseq r0, (UNDEF: 2)
extern volatile uint32_t _criticalNesting;
/* Enter a critical section. */
static INLINE void _enterCritical() {
__disable_irq();
_criticalNesting++;
c: 000d0efb strdeq r0, [sp], -fp
10: 01010101 tsteq r1, r1, lsl #2
_enterCritical();
{
encoder->value = 0;
14: 01000000 mrseq r0, (UNDEF: 0)
encoder->lastValue = 0;
18: 2e010000 cdpcs 0, 0, cr0, cr1, cr0, {0}
}
/* Exit a critical section. */
static INLINE void _exitCritical() {
const uint32_t newCritical = _criticalNesting - 1;
1c: 6e692f2e cdpvs 15, 6, cr2, cr9, cr14, {1}
_criticalNesting = newCritical;
if (newCritical == 0)
20: 64756c63 ldrbtvs r6, [r5], #-3171 ; 0xfffff39d
24: 752f0065 strvc r0, [pc, #-101]! ; ffffffc7 <encoderGet+0xffffffc7>
28: 692f7273 stmdbvs pc!, {r0, r1, r4, r5, r6, r9, ip, sp, lr} ; <UNPREDICTABLE>
}
}
// ioClearInterrupt - Disables interrupts on the specified pin
void ioClearInterrupt(unsigned char pin) {
pin--;
2c: 756c636e strbvc r6, [ip, #-878]! ; 0xfffffc92
if (pin < 12 && pin != 9) {
30: 6e2f6564 cfsh64vs mvdx6, mvdx15, #52
34: 696c7765 stmdbvs ip!, {r0, r2, r5, r6, r8, r9, sl, ip, sp, lr}^
#define USART_CR3_CTSE ((uint16_t)0x0200)
// Disables FAULT interrupts
static inline void __disable_fault_irq() { asm volatile ("cpsid f"); }
// Disables interrupts
static inline void __disable_irq() { asm volatile ("cpsid i"); }
38: 616d2f62 cmnvs sp, r2, ror #30
// Avoid having the OS swap this out
_enterCritical();
{
uint32_t mask = (uint32_t)1 << _pinIndexTable[pin + 1];
3c: 6e696863 cdpvs 8, 6, cr6, cr9, cr3, {3}
extern volatile uint32_t _criticalNesting;
/* Enter a critical section. */
static INLINE void _enterCritical() {
__disable_irq();
_criticalNesting++;
40: 752f0065 strvc r0, [pc, #-101]! ; ffffffe3 <encoderGet+0xffffffe3>
44: 692f7273 stmdbvs pc!, {r0, r1, r4, r5, r6, r9, ip, sp, lr} ; <UNPREDICTABLE>
48: 756c636e strbvc r6, [ip, #-878]! ; 0xfffffc92
// Clear pending interrupt
EXTI->PR |= mask;
4c: 6e2f6564 cfsh64vs mvdx6, mvdx15, #52
50: 696c7765 stmdbvs ip!, {r0, r2, r5, r6, r8, r9, sl, ip, sp, lr}^
// Mask interrupt
EXTI->IMR &= ~mask;
54: 79732f62 ldmdbvc r3!, {r1, r5, r6, r8, r9, sl, fp, sp}^
58: 65000073 strvs r0, [r0, #-115] ; 0xffffff8d
}
/* Exit a critical section. */
static INLINE void _exitCritical() {
const uint32_t newCritical = _criticalNesting - 1;
5c: 646f636e strbtvs r6, [pc], #-878 ; 64 <.debug_line+0x64>
_criticalNesting = newCritical;
60: 632e7265 ; <UNDEFINED> instruction: 0x632e7265
// Waits for memory accesses to complete before continuing (Data Synchronization Barrier)
static inline void __dsb() { asm volatile ("dsb"); }
// Enables FAULT interrupts
static inline void __enable_fault_irq() { asm volatile ("cpsie f"); }
// Enables interrupts
static inline void __enable_irq() { asm volatile ("cpsie i"); }
64: 00000000 andeq r0, r0, r0
68: 74726f63 ldrbtvc r6, [r2], #-3939 ; 0xfffff09d
6c: 682e7865 stmdavs lr!, {r0, r2, r5, r6, fp, ip, sp, lr}
70: 00000100 andeq r0, r0, r0, lsl #2
_exitCritical();
}
}
// encoderShutdown - Stops and disables the encoder
void encoderShutdown(Encoder enc) {
74: 65657246 strbvs r7, [r5, #-582]! ; 0xfffffdba
Sensor_TypeDef *encoder = (Sensor_TypeDef*)enc;
if (encoder) {
78: 534f5452 movtpl r5, #62546 ; 0xf452
extern volatile uint32_t _criticalNesting;
/* Enter a critical section. */
static INLINE void _enterCritical() {
__disable_irq();
_criticalNesting++;
7c: 0100682e tsteq r0, lr, lsr #16
80: 645f0000 ldrbvs r0, [pc], #-0 ; 88 <.debug_line+0x88>
84: 75616665 strbvc r6, [r1, #-1637]! ; 0xfffff99b
_enterCritical();
{
// Stop
encoder->flags = 0;
_sensorState[encoder->portBottom].flags = 0;
88: 745f746c ldrbvc r7, [pc], #-1132 ; 90 <.debug_line+0x90>
8c: 73657079 cmnvc r5, #121 ; 0x79
90: 0200682e andeq r6, r0, #3014656 ; 0x2e0000
// Clear interrupts
ioClearInterrupt(encoder->portTop);
94: 735f0000 cmpvc pc, #0
ioClearInterrupt(encoder->portBottom);
98: 6e696474 mcrvs 4, 3, r6, cr9, cr4, {3}
9c: 00682e74 rsbeq r2, r8, r4, ror lr
}
/* Exit a critical section. */
static INLINE void _exitCritical() {
const uint32_t newCritical = _criticalNesting - 1;
a0: 70000003 andvc r0, r0, r3
_criticalNesting = newCritical;
if (newCritical == 0)
a4: 70697265 rsbvc r7, r9, r5, ror #4
a8: 00682e68 rsbeq r2, r8, r8, ror #28
ac: 00000001 andeq r0, r0, r1
b0: 00020500 andeq r0, r2, r0, lsl #10
b3: R_ARM_ABS32 .text.encoderGet
}
// ioSetInterrupt - Sets up an interrupt to occur on the specified pin, and resets count & time
// Provide NULL for handler for standard interrupts, or pass function pointer for custom
void ioSetInterrupt(unsigned char pin, unsigned char edges, InterruptHandler handler) {
pin--;
b4: 03000000 movweq r0, #0
if (pin < BOARD_NR_DIGITAL_IO && pin != 9) {
b8: 140100cb strne r0, [r1], #-203 ; 0xffffff35
bc: 01022221 tsteq r2, r1, lsr #4
c0: 00010100 andeq r0, r1, r0, lsl #2
extern volatile uint32_t _criticalNesting;
/* Enter a critical section. */
static INLINE void _enterCritical() {
__disable_irq();
_criticalNesting++;
c4: 00000205 andeq r0, r0, r5, lsl #4
c6: R_ARM_ABS32 .text.encoderReset
c8: f7030000 ; <UNDEFINED> instruction: 0xf7030000
// Configure freely, we won't have an issue here since interrupt is masked
Sensor_TypeDef *state = &_sensorState[pin];
state->eventTrigger = handler;
// Falling edge configuration
temp = EXTI->FTSR;
if (edges & INTERRUPT_EDGE_FALLING)
cc: 04140100 ldreq r0, [r4], #-256 ; 0xffffff00
d0: 09e30302 stmibeq r3!, {r1, r8, r9}^
if (pin < BOARD_NR_DIGITAL_IO && pin != 9) {
// Avoid having the OS swap this out during init
_enterCritical();
{
// In range, start by masking interrupt if enabled
uint32_t mask = (uint32_t)1 << _pinIndexTable[pin + 1], temp;
d4: 03030420 movweq r0, #13344 ; 0x3420
d8: 042075ef strteq r7, [r0], #-1519 ; 0xfffffa11
dc: 4a310301 bmi c40ce8 <encoderGet+0xc40ce8>
EXTI->IMR &= ~mask;
e0: 0303042f movweq r0, #13359 ; 0x342f
e4: 212f2053 qsubcs r2, r3, pc ; <UNPREDICTABLE>
e8: 92030204 andls r0, r3, #4, 4 ; 0x40000000
// Configure freely, we won't have an issue here since interrupt is masked
Sensor_TypeDef *state = &_sensorState[pin];
state->eventTrigger = handler;
ec: 0502200a streq r2, [r2, #-10]
f0: 00010100 andeq r0, r1, r0, lsl #2
// Falling edge configuration
temp = EXTI->FTSR;
f4: 00000205 andeq r0, r0, r5, lsl #4
f6: R_ARM_ABS32 .text.ioClearInterrupt
if (edges & INTERRUPT_EDGE_FALLING)
temp |= mask;
f8: 95030000 strls r0, [r3, #-0]
else
temp &= ~mask;
EXTI->FTSR = temp;
fc: 2f130101 svccs 0x00130101
// Rising edge configuration
temp = EXTI->RTSR;
if (edges & INTERRUPT_EDGE_RISING)
100: 01040200 mrseq r0, R12_usr
temp |= mask;
104: 02042e06 andeq r2, r4, #6, 28 ; 0x60
else
temp &= ~mask;
108: 09c50306 stmibeq r5, {r1, r2, r8, r9}^
EXTI->RTSR = temp;
10c: 0303042e movweq r0, #13358 ; 0x342e
// Clear pending interrupt
EXTI->PR |= mask;
110: 042075ef strteq r7, [r0], #-1519 ; 0xfffffa11
// Unmask interrupt to start monitoring
EXTI->IMR |= mask;
114: 00d00301 sbcseq r0, r0, r1, lsl #6
118: 03030420 movweq r0, #13344 ; 0x3420
}
/* Exit a critical section. */
static INLINE void _exitCritical() {
const uint32_t newCritical = _criticalNesting - 1;
11c: 04207fb0 strteq r7, [r0], #-4016 ; 0xfffff050
_criticalNesting = newCritical;
if (newCritical == 0)
120: 00d00301 sbcseq r0, r0, r1, lsl #6
124: 044c4c3c strbeq r4, [ip], #-3132 ; 0xfffff3c4
128: 7fb10303 svcvc 0x00b10303
12c: 04212f4a strteq r2, [r1], #-3914 ; 0xfffff0b6
130: 0a920302 beq fe480d40 <encoderGet+0xfe480d40>
134: 00080220 andeq r0, r8, r0, lsr #4
return (int)encoder->value;
return 0;
}
// encoderInit - Initializes and enables a quadrature encoder on two digital ports
Encoder encoderInit(unsigned char portTop, unsigned char portBottom, bool reverse) {
138: 05000101 streq r0, [r0, #-257] ; 0xfffffeff
Sensor_TypeDef *encoder, *slave;
// Change to 0..11 range
uint32_t it = portTop - 1, ib = portBottom - 1;
13c: 00000002 andeq r0, r0, r2
13d: R_ARM_ABS32 .text.encoderShutdown
return (int)encoder->value;
return 0;
}
// encoderInit - Initializes and enables a quadrature encoder on two digital ports
Encoder encoderInit(unsigned char portTop, unsigned char portBottom, bool reverse) {
140: 01840300 orreq r0, r4, r0, lsl #6
Sensor_TypeDef *encoder, *slave;
// Change to 0..11 range
uint32_t it = portTop - 1, ib = portBottom - 1;
144: 02042201 andeq r2, r4, #268435456 ; 0x10000000
// Check range
if (it < BOARD_NR_DIGITAL_IO && it != 9 && _sensorState[it].flags == 0 &&
148: 2e09d603 cfmadd32cs mvax0, mvfx13, mvfx9, mvfx3
14c: ef030304 svc 0x00030304
150: 01042075 tsteq r4, r5, ror r0
154: 04203f03 strteq r3, [r0], #-3843 ; 0xfffff0fd
158: 20410303 subcs r0, r1, r3, lsl #6
15c: 3f030104 svccc 0x00030104
160: 3d5a213c ldfcce f2, [sl, #-240] ; 0xffffff10
ib < BOARD_NR_DIGITAL_IO && ib != 9 && _sensorState[ib].flags == 0) {
164: 42030304 andmi r0, r3, #4, 6 ; 0x10000000
168: 04212f3c strteq r2, [r1], #-3900 ; 0xfffff0c4
16c: 0a920302 beq fe480d7c <encoderGet+0xfe480d7c>
170: 00070220 andeq r0, r7, r0, lsr #4
174: 05000101 streq r0, [r0, #-257] ; 0xfffffeff
178: 00000002 andeq r0, r0, r2
179: R_ARM_ABS32 .text.ioSetInterrupt
17c: 01a70300 ; <UNDEFINED> instruction: 0x01a70300
extern volatile uint32_t _criticalNesting;
/* Enter a critical section. */
static INLINE void _enterCritical() {
__disable_irq();
_criticalNesting++;
180: 1e2f1301 cdpne 3, 2, cr1, cr15, cr1, {0}
{
uint16_t flags = (uint16_t)0x0002 | (uint16_t)(reverse ? 0x01 : 0x00);
encoder = &_sensorState[it];
slave = &_sensorState[ib];
// Set pins to input pull-up
pinMode(portTop, DDR_INPUT_PULLUP);
184: 04020022 streq r0, [r2], #-34 ; 0xffffffde
188: 04200601 strteq r0, [r0], #-1537 ; 0xfffff9ff
// Check range
if (it < BOARD_NR_DIGITAL_IO && it != 9 && _sensorState[it].flags == 0 &&
ib < BOARD_NR_DIGITAL_IO && ib != 9 && _sensorState[ib].flags == 0) {
_enterCritical();
{
uint16_t flags = (uint16_t)0x0002 | (uint16_t)(reverse ? 0x01 : 0x00);
18c: b3030602 movwlt r0, #13826 ; 0x3602
190: 03042e09 movweq r2, #19977 ; 0x4e09
encoder = &_sensorState[it];
slave = &_sensorState[ib];
// Set pins to input pull-up
pinMode(portTop, DDR_INPUT_PULLUP);
194: 2075ef03 rsbscs lr, r5, r3, lsl #30
pinMode(portBottom, DDR_INPUT_PULLUP);
198: e3030104 movw r0, #12548 ; 0x3104
19c: 03042000 movweq r2, #16384 ; 0x4000
// Set state of master pin (top)
encoder->flags = flags;
encoder->portTop = (uint8_t)portTop;
encoder->portBottom = (uint8_t)portBottom;
encoder->value = 0;
1a0: 207f9d03 rsbscs r9, pc, r3, lsl #26
slave = &_sensorState[ib];
// Set pins to input pull-up
pinMode(portTop, DDR_INPUT_PULLUP);
pinMode(portBottom, DDR_INPUT_PULLUP);
// Set state of master pin (top)
encoder->flags = flags;
1a4: ea030104 b c05bc <encoderGet+0xc05bc>
// Set slaved state
slave->flags = flags;
slave->portTop = (uint8_t)portTop;
slave->portBottom = (uint8_t)portBottom;
// Interrupt per-port on either rising or falling edge
ioSetInterrupt(portTop, INTERRUPT_EDGE_BOTH, _encoderISRTop);
1a8: 03042000 movweq r2, #16384 ; 0x4000
// Set pins to input pull-up
pinMode(portTop, DDR_INPUT_PULLUP);
pinMode(portBottom, DDR_INPUT_PULLUP);
// Set state of master pin (top)
encoder->flags = flags;
encoder->portTop = (uint8_t)portTop;
1ac: 2e7f9603 cdpcs 6, 7, cr9, cr15, cr3, {0}
encoder->portBottom = (uint8_t)portBottom;
1b0: e3030104 movw r0, #12548 ; 0x3104
encoder->value = 0;
1b4: 77593c00 ldrbvc r3, [r9, -r0, lsl #24]
encoder->lastValue = 0;
1b8: 2130224c teqcs r0, ip, asr #4
// Set slaved state
slave->flags = flags;
1bc: 3e212122 sufccsp f2, f1, f2
slave->portTop = (uint8_t)portTop;
1c0: 043e222f ldrteq r2, [lr], #-559 ; 0xfffffdd1
slave->portBottom = (uint8_t)portBottom;
1c4: 7f8c0303 svcvc 0x008c0303
// Interrupt per-port on either rising or falling edge
ioSetInterrupt(portTop, INTERRUPT_EDGE_BOTH, _encoderISRTop);
1c8: 04212f3c strteq r2, [r1], #-3900 ; 0xfffff0c4
ioSetInterrupt(portBottom, INTERRUPT_EDGE_BOTH, _encoderISRBottom);
1cc: 0a920302 beq fe480ddc <encoderGet+0xfe480ddc>
1d0: 000b0220 andeq r0, fp, r0, lsr #4
}
/* Exit a critical section. */
static INLINE void _exitCritical() {
const uint32_t newCritical = _criticalNesting - 1;
1d4: 05000101 streq r0, [r0, #-257] ; 0xfffffeff
1d8: 00000002 andeq r0, r0, r2
1d9: R_ARM_ABS32 .text.encoderInit
_criticalNesting = newCritical;
1dc: 00d30300 sbcseq r0, r3, r0, lsl #6
1e0: 1b223101 blne 88c5ec <encoderGet+0x88c5ec>
}
_exitCritical();
return (Encoder)encoder;
}
return NULL;
1e4: 02003031 andeq r3, r0, #49 ; 0x31
1e8: 20060104 andcs r0, r6, r4, lsl #2
// Interrupt per-port on either rising or falling edge
ioSetInterrupt(portTop, INTERRUPT_EDGE_BOTH, _encoderISRTop);
ioSetInterrupt(portBottom, INTERRUPT_EDGE_BOTH, _encoderISRBottom);
}
_exitCritical();
return (Encoder)encoder;
1ec: 02040200 andeq r0, r4, #0, 4
}
return NULL;
}
1f0: 0402002e streq r0, [r2], #-46 ; 0xffffffd2
1f4: 2f069003 svccs 0x00069003
1f8: 01040200 mrseq r0, R12_usr
1fc: 02042e06 andeq r2, r4, #6, 28 ; 0x60
200: 0a830306 beq fe0c0e20 <encoderGet+0xfe0c0e20>
if (handler != NULL)
handler(pin + 1);
}
// External interrupts all Px0 pins (PD0/Digital 11)
IRQ ISR_EXTI0() {
204: 030304ac movweq r0, #13484 ; 0x34ac
208: 042075ef strteq r7, [r0], #-1519 ; 0xfffffa11
}
}
// Fires off the external interrupt logic for a given pin
static INLINE void triggerEXTI(uint32_t pin) {
InterruptHandler handler = _sensorState[pin].eventTrigger;
20c: 2e150301 cdpcs 3, 1, cr0, cr5, cr1, {0}
210: 6b030304 blvs c0e28 <encoderGet+0xc0e28>
if (handler != NULL)
214: 03010420 movweq r0, #5152 ; 0x1420
handler(pin + 1);
218: 03042e11 movweq r2, #19985 ; 0x4e11
// External interrupts all Px0 pins (PD0/Digital 11)
IRQ ISR_EXTI0() {
// We assume that this can only fire if unmasked (therefore, wanted)
triggerEXTI(10);
EXTI->PR = (uint32_t)0x0001;
}
21c: 042e6f03 strteq r6, [lr], #-3843 ; 0xfffff0fd
// External interrupts all Px0 pins (PD0/Digital 11)
IRQ ISR_EXTI0() {
// We assume that this can only fire if unmasked (therefore, wanted)
triggerEXTI(10);
EXTI->PR = (uint32_t)0x0001;
220: 3c150301 ldccc 3, cr0, [r5], {1}
}
224: 032b4f2f ; <UNDEFINED> instruction: 0x032b4f2f
228: 77032e0a strvc r2, [r3, -sl, lsl #28]
22c: 2e090320 cdpcs 3, 0, cr0, cr9, cr0, {1}
// External interrupts all Px1 pins (PD1/Digital 12)
IRQ ISR_EXTI1() {
230: 28207803 stmdacs r0!, {r0, r1, fp, ip, sp, lr}
234: 2f207903 svccs 0x00207903
}
}
// Fires off the external interrupt logic for a given pin
static INLINE void triggerEXTI(uint32_t pin) {
InterruptHandler handler = _sensorState[pin].eventTrigger;
238: 222f2f30 eorcs r2, pc, #48, 30 ; 0xc0
23c: 0303042f movweq r0, #13359 ; 0x342f
if (handler != NULL)
240: 2f3d5862 svccs 0x003d5862
handler(pin + 1);
244: 92030204 andls r0, r3, #4, 4 ; 0x40000000
// External interrupts all Px1 pins (PD1/Digital 12)
IRQ ISR_EXTI1() {
// We assume that this can only fire if unmasked (therefore, wanted)
triggerEXTI(11);
EXTI->PR = (uint32_t)0x0002;
}
248: 0104200a tsteq r4, sl
// External interrupts all Px1 pins (PD1/Digital 12)
IRQ ISR_EXTI1() {
// We assume that this can only fire if unmasked (therefore, wanted)
triggerEXTI(11);
EXTI->PR = (uint32_t)0x0002;
24c: 2e768f03 cdpcs 15, 7, cr8, cr6, cr3, {0}
}
250: 0b022348 bleq 88f78 <encoderGet+0x88f78>
254: 00010100 andeq r0, r1, r0, lsl #2
258: 00000205 andeq r0, r0, r5, lsl #4
25a: R_ARM_ABS32 .text.ISR_EXTI0
// External interrupts all Px5-Px9 pins
// (PC6/Digital 3, PC7/Digital 4, PE8/Digital 7, PE9/Digital 1)
IRQ ISR_EXTI9_5() {
25c: d2030000 andle r0, r3, #0
260: 7a030101 bvc c066c <encoderGet+0xc066c>
264: 7a03264a bvc c9b94 <encoderGet+0xc9b94>
uint32_t pending = EXTI->PR, reset = 0;
268: 36212f20 strtcc r2, [r1], -r0, lsr #30
if (pending & (uint32_t)0x0040) {
26c: 06023d2d streq r3, [r2], -sp, lsr #26
270: 00010100 andeq r0, r1, r0, lsl #2
}
}
// Fires off the external interrupt logic for a given pin
static INLINE void triggerEXTI(uint32_t pin) {
InterruptHandler handler = _sensorState[pin].eventTrigger;
274: 00000205 andeq r0, r0, r5, lsl #4
276: R_ARM_ABS32 .text.ISR_EXTI1
if (handler != NULL)
handler(pin + 1);
278: d9030000 stmdble r3, {} ; <UNPREDICTABLE>
IRQ ISR_EXTI9_5() {
uint32_t pending = EXTI->PR, reset = 0;
if (pending & (uint32_t)0x0040) {
// PC6 fired
triggerEXTI(2);
reset |= (uint32_t)0x0040;
27c: 73030101 movwvc r0, #12545 ; 0x3101
}
if (pending & (uint32_t)0x0080) {
280: 200d034a andcs r0, sp, sl, asr #6
}
}
// Fires off the external interrupt logic for a given pin
static INLINE void triggerEXTI(uint32_t pin) {
InterruptHandler handler = _sensorState[pin].eventTrigger;
284: 2f207303 svccs 0x00207303
if (handler != NULL)
handler(pin + 1);
288: 2e0f0321 cdpcs 3, 0, cr0, cr15, cr1, {1}
reset |= (uint32_t)0x0040;
}
if (pending & (uint32_t)0x0080) {
// PC7 fired
triggerEXTI(3);
reset |= (uint32_t)0x0080;
28c: 06023d2d streq r3, [r2], -sp, lsr #26
}
if (pending & (uint32_t)0x0100) {
290: 00010100 andeq r0, r1, r0, lsl #2
}
}
// Fires off the external interrupt logic for a given pin
static INLINE void triggerEXTI(uint32_t pin) {
InterruptHandler handler = _sensorState[pin].eventTrigger;
294: 00000205 andeq r0, r0, r5, lsl #4
296: R_ARM_ABS32 .text.ISR_EXTI9_5
if (handler != NULL)
298: e1030000 mrs r0, (UNDEF: 3)
handler(pin + 1);
29c: 3d590101 ldfcce f0, [r9, #-4]
reset |= (uint32_t)0x0080;
}
if (pending & (uint32_t)0x0100) {
// PE8 fired
triggerEXTI(6);
reset |= (uint32_t)0x0100;
2a0: 2f3c6903 svccs 0x003c6903
}
if (pending & (uint32_t)0x0200) {
2a4: 2e180321 cdpcs 3, 1, cr0, cr8, cr1, {1}
}
}
// Fires off the external interrupt logic for a given pin
static INLINE void triggerEXTI(uint32_t pin) {
InterruptHandler handler = _sensorState[pin].eventTrigger;
2a8: 2e640322 cdpcs 3, 6, cr0, cr4, cr2, {1}
if (handler != NULL)
handler(pin + 1);
2ac: 1d03212f stfnes f2, [r3, #-188] ; 0xffffff44
reset |= (uint32_t)0x0100;
}
if (pending & (uint32_t)0x0200) {
// PE9 fired
triggerEXTI(0);
reset |= (uint32_t)0x0200;
2b0: 5f03302e svcpl 0x0003302e
}
EXTI->PR = reset;
2b4: 03212f2e ; <UNDEFINED> instruction: 0x03212f2e
}
2b8: 03302e22 teqeq r0, #544 ; 0x220
2bc: 212f2e5a ; <UNDEFINED> instruction: 0x212f2e5a
2c0: 302e2703 eorcc r2, lr, r3, lsl #14
2c4: 00090221 andeq r0, r9, r1, lsr #4
// External interrupts all Px10-Px15 pins
// (PE10/Digital 8, PE11/Digital 2, PE12/Digital 9, PE13/Digital 5, PE14/Digital 6)
IRQ ISR_EXTI15_10() {
2c8: 05000101 streq r0, [r0, #-257] ; 0xfffffeff
2cc: 00000002 andeq r0, r0, r2
2cd: R_ARM_ABS32 .text.ISR_EXTI15_10
2d0: 01fc0300 mvnseq r0, r0, lsl #6
uint32_t pending = EXTI->PR, reset = 0;
2d4: 032f5901 ; <UNDEFINED> instruction: 0x032f5901
if (pending & (uint32_t)0x0400) {
2d8: 212f3c4e ; <UNDEFINED> instruction: 0x212f3c4e
}
}
// Fires off the external interrupt logic for a given pin
static INLINE void triggerEXTI(uint32_t pin) {
InterruptHandler handler = _sensorState[pin].eventTrigger;
2dc: 302e3303 eorcc r3, lr, r3, lsl #6
if (handler != NULL)
2e0: 2f2e4903 svccs 0x002e4903
handler(pin + 1);
2e4: 2e380321 cdpcs 3, 3, cr0, cr8, cr1, {1}
IRQ ISR_EXTI15_10() {
uint32_t pending = EXTI->PR, reset = 0;
if (pending & (uint32_t)0x0400) {
// PE10 fired
triggerEXTI(7);
reset |= (uint32_t)0x0400;
2e8: 2e440330 mcrcs 3, 2, r0, cr4, cr0, {1}
}
if (pending & (uint32_t)0x0800) {
2ec: 3d03213d stfccs f2, [r3, #-244] ; 0xffffff0c
}
}
// Fires off the external interrupt logic for a given pin
static INLINE void triggerEXTI(uint32_t pin) {
InterruptHandler handler = _sensorState[pin].eventTrigger;
2f0: bf03302e svclt 0x0003302e
if (handler != NULL)
handler(pin + 1);
2f4: 212f2e7f ; <UNDEFINED> instruction: 0x212f2e7f
reset |= (uint32_t)0x0400;
}
if (pending & (uint32_t)0x0800) {
// PE11 fired
triggerEXTI(1);
reset |= (uint32_t)0x0800;
2f8: 2e00c203 cdpcs 2, 0, cr12, cr0, cr3, {0}
}
if (pending & (uint32_t)0x1000) {
2fc: 7fba0330 svcvc 0x00ba0330
}
}
// Fires off the external interrupt logic for a given pin
static INLINE void triggerEXTI(uint32_t pin) {
InterruptHandler handler = _sensorState[pin].eventTrigger;
300: 03212f2e ; <UNDEFINED> instruction: 0x03212f2e
304: 302e00c7 eorcc r0, lr, r7, asr #1
if (handler != NULL)
handler(pin + 1);
308: 00090221 andeq r0, r9, r1, lsr #4
reset |= (uint32_t)0x0800;
}
if (pending & (uint32_t)0x1000) {
// PE12 fired
triggerEXTI(8);
reset |= (uint32_t)0x1000;
30c: Address 0x000000000000030c is out of bounds.
Disassembly of section .debug_str:
00000000 <.debug_str>:
#endif
// encoderGet - Gets the value of the encoder
int encoderGet(Encoder enc) {
Sensor_TypeDef *encoder = (Sensor_TypeDef*)enc;
if (encoder)
0: 6e657665 cdpvs 6, 6, cr7, cr5, cr5, {3}
return (int)encoder->value;
return 0;
}
4: 69725474 ldmdbvs r2!, {r2, r4, r5, r6, sl, ip, lr}^
}
// encoderReset - Resets the encoder to zero
void encoderReset(Encoder enc) {
Sensor_TypeDef *encoder = (Sensor_TypeDef*)enc;
if (encoder) {
8: 72656767 rsbvc r6, r5, #27000832 ; 0x19c0000
extern volatile uint32_t _criticalNesting;
/* Enter a critical section. */
static INLINE void _enterCritical() {
__disable_irq();
_criticalNesting++;
c: 52534900 subspl r4, r3, #0, 18
10: 5458455f ldrbpl r4, [r8], #-1375 ; 0xfffffaa1
_enterCritical();
{
encoder->value = 0;
14: 49003049 stmdbmi r0, {r0, r3, r6, ip, sp}
encoder->lastValue = 0;
18: 455f5253 ldrbmi r5, [pc, #-595] ; fffffdcd <encoderGet+0xfffffdcd>
}
/* Exit a critical section. */
static INLINE void _exitCritical() {
const uint32_t newCritical = _criticalNesting - 1;
1c: 31495458 cmpcc r9, r8, asr r4
_criticalNesting = newCritical;
if (newCritical == 0)
20: 61747300 cmnvs r4, r0, lsl #6
24: 74006574 strvc r6, [r0], #-1396 ; 0xfffffa8c
28: 00706d65 rsbseq r6, r0, r5, ror #26
}
}
// ioClearInterrupt - Disables interrupts on the specified pin
void ioClearInterrupt(unsigned char pin) {
pin--;
2c: 6978655f ldmdbvs r8!, {r0, r1, r2, r3, r4, r6, r8, sl, sp, lr}^
if (pin < 12 && pin != 9) {
30: 69724374 ldmdbvs r2!, {r2, r4, r5, r6, r8, r9, lr}^
34: 61636974 smcvs 13972 ; 0x3694
#define USART_CR3_CTSE ((uint16_t)0x0200)
// Disables FAULT interrupts
static inline void __disable_fault_irq() { asm volatile ("cpsid f"); }
// Disables interrupts
static inline void __disable_irq() { asm volatile ("cpsid i"); }
38: 6973006c ldmdbvs r3!, {r2, r3, r5, r6}^
// Avoid having the OS swap this out
_enterCritical();
{
uint32_t mask = (uint32_t)1 << _pinIndexTable[pin + 1];
3c: 7974657a ldmdbvc r4!, {r1, r3, r4, r5, r6, r8, sl, sp, lr}^
extern volatile uint32_t _criticalNesting;
/* Enter a critical section. */
static INLINE void _enterCritical() {
__disable_irq();
_criticalNesting++;
40: 53006570 movwpl r6, #1392 ; 0x570
44: 6f736e65 svcvs 0x00736e65
48: 79545f72 ldmdbvc r4, {r1, r4, r5, r6, r8, r9, sl, fp, ip, lr}^
// Clear pending interrupt
EXTI->PR |= mask;
4c: 65446570 strbvs r6, [r4, #-1392] ; 0xfffffa90
50: 635f0066 cmpvs pc, #102 ; 0x66
// Mask interrupt
EXTI->IMR &= ~mask;
54: 69746972 ldmdbvs r4!, {r1, r4, r5, r6, r8, fp, sp, lr}^
58: 4e6c6163 powmiez f6, f4, f3
}
/* Exit a critical section. */
static INLINE void _exitCritical() {
const uint32_t newCritical = _criticalNesting - 1;
5c: 69747365 ldmdbvs r4!, {r0, r2, r5, r6, r8, r9, ip, sp, lr}^
_criticalNesting = newCritical;
60: 5f00676e svcpl 0x0000676e
// Waits for memory accesses to complete before continuing (Data Synchronization Barrier)
static inline void __dsb() { asm volatile ("dsb"); }
// Enables FAULT interrupts
static inline void __enable_fault_irq() { asm volatile ("cpsie f"); }
// Enables interrupts
static inline void __enable_irq() { asm volatile ("cpsie i"); }
64: 6e69755f mcrvs 5, 3, r7, cr9, cr15, {2}
68: 5f323374 svcpl 0x00323374
6c: 5f5f0074 svcpl 0x005f0074
70: 746e6975 strbtvc r6, [lr], #-2421 ; 0xfffff68b
_exitCritical();
}
}
// encoderShutdown - Stops and disables the encoder
void encoderShutdown(Encoder enc) {
74: 745f3631 ldrbvc r3, [pc], #-1585 ; 7c <.debug_str+0x7c>
Sensor_TypeDef *encoder = (Sensor_TypeDef*)enc;
if (encoder) {
78: 6e616800 cdpvs 8, 6, cr6, cr1, cr0, {0}
extern volatile uint32_t _criticalNesting;
/* Enter a critical section. */
static INLINE void _enterCritical() {
__disable_irq();
_criticalNesting++;
7c: 72656c64 rsbvc r6, r5, #100, 24 ; 0x6400
80: 6f687300 svcvs 0x00687300
84: 69207472 stmdbvs r0!, {r1, r4, r5, r6, sl, ip, sp, lr}
_enterCritical();
{
// Stop
encoder->flags = 0;
_sensorState[encoder->portBottom].flags = 0;
88: 7000746e andvc r7, r0, lr, ror #8
8c: 69646e65 stmdbvs r4!, {r0, r2, r5, r6, r9, sl, fp, sp, lr}^
90: 7600676e strvc r6, [r0], -lr, ror #14
// Clear interrupts
ioClearInterrupt(encoder->portTop);
94: 65756c61 ldrbvs r6, [r5, #-3169]! ; 0xfffff39f
ioClearInterrupt(encoder->portBottom);
98: 69705f00 ldmdbvs r0!, {r8, r9, sl, fp, ip, lr}^
9c: 646e496e strbtvs r4, [lr], #-2414 ; 0xfffff692
}
/* Exit a critical section. */
static INLINE void _exitCritical() {
const uint32_t newCritical = _criticalNesting - 1;
a0: 61547865 cmpvs r4, r5, ror #16
_criticalNesting = newCritical;
if (newCritical == 0)
a4: 00656c62 rsbeq r6, r5, r2, ror #24
a8: 5f525349 svcpl 0x00525349
ac: 49545845 ldmdbmi r4, {r0, r2, r6, fp, ip, lr}^
b0: 315f3531 cmpcc pc, r1, lsr r5 ; <UNPREDICTABLE>
}
// ioSetInterrupt - Sets up an interrupt to occur on the specified pin, and resets count & time
// Provide NULL for handler for standard interrupts, or pass function pointer for custom
void ioSetInterrupt(unsigned char pin, unsigned char edges, InterruptHandler handler) {
pin--;
b4: 6e650030 mcrvs 0, 3, r0, cr5, cr0, {1}
if (pin < BOARD_NR_DIGITAL_IO && pin != 9) {
b8: 65646f63 strbvs r6, [r4, #-3939]! ; 0xfffff09d
bc: 00632e72 rsbeq r2, r3, r2, ror lr
c0: 6f636e65 svcvs 0x00636e65
extern volatile uint32_t _criticalNesting;
/* Enter a critical section. */
static INLINE void _enterCritical() {
__disable_irq();
_criticalNesting++;
c4: 52726564 rsbspl r6, r2, #100, 10 ; 0x19000000
c8: 74657365 strbtvc r7, [r5], #-869 ; 0xfffffc9b
// Configure freely, we won't have an issue here since interrupt is masked
Sensor_TypeDef *state = &_sensorState[pin];
state->eventTrigger = handler;
// Falling edge configuration
temp = EXTI->FTSR;
if (edges & INTERRUPT_EDGE_FALLING)
cc: 6e6f6c00 cdpvs 12, 6, cr6, cr15, cr0, {0}
d0: 6f6c2067 svcvs 0x006c2067
if (pin < BOARD_NR_DIGITAL_IO && pin != 9) {
// Avoid having the OS swap this out during init
_enterCritical();
{
// In range, start by masking interrupt if enabled
uint32_t mask = (uint32_t)1 << _pinIndexTable[pin + 1], temp;
d4: 6920676e stmdbvs r0!, {r1, r2, r3, r5, r6, r8, r9, sl, sp, lr}
d8: 5f00746e svcpl 0x0000746e
dc: 65746e65 ldrbvs r6, [r4, #-3685]! ; 0xfffff19b
EXTI->IMR &= ~mask;
e0: 69724372 ldmdbvs r2!, {r1, r4, r5, r6, r8, r9, lr}^
e4: 61636974 smcvs 13972 ; 0x3694
e8: 6970006c ldmdbvs r0!, {r2, r3, r5, r6}^
// Configure freely, we won't have an issue here since interrupt is masked
Sensor_TypeDef *state = &_sensorState[pin];
state->eventTrigger = handler;
ec: 646f4d6e strbtvs r4, [pc], #-3438 ; f4 <.debug_str+0xf4>
f0: 68630065 stmdavs r3!, {r0, r2, r5, r6}^
// Falling edge configuration
temp = EXTI->FTSR;
f4: 49007261 stmdbmi r0, {r0, r5, r6, r9, ip, sp, lr}
if (edges & INTERRUPT_EDGE_FALLING)
temp |= mask;
f8: 7265746e rsbvc r7, r5, #1845493760 ; 0x6e000000
else
temp &= ~mask;
EXTI->FTSR = temp;
fc: 74707572 ldrbtvc r7, [r0], #-1394 ; 0xfffffa8e
// Rising edge configuration
temp = EXTI->RTSR;
if (edges & INTERRUPT_EDGE_RISING)
100: 646e6148 strbtvs r6, [lr], #-328 ; 0xfffffeb8
temp |= mask;
104: 0072656c rsbseq r6, r2, ip, ror #10
else
temp &= ~mask;
108: 49545845 ldmdbmi r4, {r0, r2, r6, fp, ip, lr}^
EXTI->RTSR = temp;
10c: 7079545f rsbsvc r5, r9, pc, asr r4
// Clear pending interrupt
EXTI->PR |= mask;
110: 66654465 strbtvs r4, [r5], -r5, ror #8
// Unmask interrupt to start monitoring
EXTI->IMR |= mask;
114: 73616c00 cmnvc r1, #0, 24
118: 6c615674 stclvs 6, cr5, [r1], #-464 ; 0xfffffe30
}
/* Exit a critical section. */
static INLINE void _exitCritical() {
const uint32_t newCritical = _criticalNesting - 1;
11c: 5f006575 svcpl 0x00006575
_criticalNesting = newCritical;
if (newCritical == 0)
120: 6e69755f mcrvs 5, 3, r7, cr9, cr15, {2}
124: 745f3874 ldrbvc r3, [pc], #-2164 ; 12c <.debug_str+0x12c>
128: 655f5f00 ldrbvs r5, [pc, #-3840] ; fffff230 <encoderGet+0xfffff230>
12c: 6c62616e stfvse f6, [r2], #-440 ; 0xfffffe48
130: 72695f65 rsbvc r5, r9, #404 ; 0x194
134: 5f5f0071 svcpl 0x005f0071
return (int)encoder->value;
return 0;
}
// encoderInit - Initializes and enables a quadrature encoder on two digital ports
Encoder encoderInit(unsigned char portTop, unsigned char portBottom, bool reverse) {
138: 61736964 cmnvs r3, r4, ror #18
Sensor_TypeDef *encoder, *slave;
// Change to 0..11 range
uint32_t it = portTop - 1, ib = portBottom - 1;
13c: 5f656c62 svcpl 0x00656c62
return (int)encoder->value;
return 0;
}
// encoderInit - Initializes and enables a quadrature encoder on two digital ports
Encoder encoderInit(unsigned char portTop, unsigned char portBottom, bool reverse) {
140: 00717269 rsbseq r7, r1, r9, ror #4
Sensor_TypeDef *encoder, *slave;
// Change to 0..11 range
uint32_t it = portTop - 1, ib = portBottom - 1;
144: 69736e75 ldmdbvs r3!, {r0, r2, r4, r5, r6, r9, sl, fp, sp, lr}^
// Check range
if (it < BOARD_NR_DIGITAL_IO && it != 9 && _sensorState[it].flags == 0 &&
148: 64656e67 strbtvs r6, [r5], #-3687 ; 0xfffff199
14c: 61686320 cmnvs r8, r0, lsr #6
150: 72740072 rsbsvc r0, r4, #114 ; 0x72
154: 65676769 strbvs r6, [r7, #-1897]! ; 0xfffff897
158: 54584572 ldrbpl r4, [r8], #-1394 ; 0xfffffa8e
15c: 6e650049 cdpvs 0, 6, cr0, cr5, cr9, {2}
160: 65646f63 strbvs r6, [r4, #-3939]! ; 0xfffff09d
ib < BOARD_NR_DIGITAL_IO && ib != 9 && _sensorState[ib].flags == 0) {
164: 696e4972 stmdbvs lr!, {r1, r4, r5, r6, r8, fp, lr}^
168: 69730074 ldmdbvs r3!, {r2, r4, r5, r6}^
16c: 64656e67 strbtvs r6, [r5], #-3687 ; 0xfffff199
170: 61686320 cmnvs r8, r0, lsr #6
174: 6c660072 stclvs 0, cr0, [r6], #-456 ; 0xfffffe38
178: 00736761 rsbseq r6, r3, r1, ror #14
17c: 676e6f6c strbvs r6, [lr, -ip, ror #30]!
extern volatile uint32_t _criticalNesting;
/* Enter a critical section. */
static INLINE void _enterCritical() {
__disable_irq();
_criticalNesting++;
180: 6e6f6c20 cdpvs 12, 6, cr6, cr15, cr0, {1}
{
uint16_t flags = (uint16_t)0x0002 | (uint16_t)(reverse ? 0x01 : 0x00);
encoder = &_sensorState[it];
slave = &_sensorState[ib];
// Set pins to input pull-up
pinMode(portTop, DDR_INPUT_PULLUP);
184: 6e752067 cdpvs 0, 7, cr2, cr5, cr7, {3}
188: 6e676973 mcrvs 9, 3, r6, cr7, cr3, {3}
// Check range
if (it < BOARD_NR_DIGITAL_IO && it != 9 && _sensorState[it].flags == 0 &&
ib < BOARD_NR_DIGITAL_IO && ib != 9 && _sensorState[ib].flags == 0) {
_enterCritical();
{
uint16_t flags = (uint16_t)0x0002 | (uint16_t)(reverse ? 0x01 : 0x00);
18c: 69206465 stmdbvs r0!, {r0, r2, r5, r6, sl, sp, lr}
190: 7500746e strvc r7, [r0, #-1134] ; 0xfffffb92
encoder = &_sensorState[it];
slave = &_sensorState[ib];
// Set pins to input pull-up
pinMode(portTop, DDR_INPUT_PULLUP);
194: 33746e69 cmncc r4, #1680 ; 0x690
pinMode(portBottom, DDR_INPUT_PULLUP);
198: 00745f32 rsbseq r5, r4, r2, lsr pc
19c: 76616c73 ; <UNDEFINED> instruction: 0x76616c73
// Set state of master pin (top)
encoder->flags = flags;
encoder->portTop = (uint8_t)portTop;
encoder->portBottom = (uint8_t)portBottom;
encoder->value = 0;
1a0: 6e750065 cdpvs 0, 7, cr0, cr5, cr5, {3}
slave = &_sensorState[ib];
// Set pins to input pull-up
pinMode(portTop, DDR_INPUT_PULLUP);
pinMode(portBottom, DDR_INPUT_PULLUP);
// Set state of master pin (top)
encoder->flags = flags;
1a4: 6e676973 mcrvs 9, 3, r6, cr7, cr3, {3}
// Set slaved state
slave->flags = flags;
slave->portTop = (uint8_t)portTop;
slave->portBottom = (uint8_t)portBottom;
// Interrupt per-port on either rising or falling edge
ioSetInterrupt(portTop, INTERRUPT_EDGE_BOTH, _encoderISRTop);
1a8: 69206465 stmdbvs r0!, {r0, r2, r5, r6, sl, sp, lr}
// Set pins to input pull-up
pinMode(portTop, DDR_INPUT_PULLUP);
pinMode(portBottom, DDR_INPUT_PULLUP);
// Set state of master pin (top)
encoder->flags = flags;
encoder->portTop = (uint8_t)portTop;
1ac: 4600746e strmi r7, [r0], -lr, ror #8
encoder->portBottom = (uint8_t)portBottom;
1b0: 00525354 subseq r5, r2, r4, asr r3
encoder->value = 0;
1b4: 6f636e45 svcvs 0x00636e45
encoder->lastValue = 0;
1b8: 00726564 rsbseq r6, r2, r4, ror #10
// Set slaved state
slave->flags = flags;
1bc: 726f6873 rsbvc r6, pc, #7536640 ; 0x730000
slave->portTop = (uint8_t)portTop;
1c0: 6e752074 mrcvs 0, 3, r2, cr5, cr4, {3}
slave->portBottom = (uint8_t)portBottom;
1c4: 6e676973 mcrvs 9, 3, r6, cr7, cr3, {3}
// Interrupt per-port on either rising or falling edge
ioSetInterrupt(portTop, INTERRUPT_EDGE_BOTH, _encoderISRTop);
1c8: 69206465 stmdbvs r0!, {r0, r2, r5, r6, sl, sp, lr}
ioSetInterrupt(portBottom, INTERRUPT_EDGE_BOTH, _encoderISRBottom);
1cc: 6900746e stmdbvs r0, {r1, r2, r3, r5, r6, sl, ip, sp, lr}
1d0: 7465536f strbtvc r5, [r5], #-879 ; 0xfffffc91
}
/* Exit a critical section. */
static INLINE void _exitCritical() {
const uint32_t newCritical = _criticalNesting - 1;
1d4: 65746e49 ldrbvs r6, [r4, #-3657]! ; 0xfffff1b7
1d8: 70757272 rsbsvc r7, r5, r2, ror r2
_criticalNesting = newCritical;
1dc: 65720074 ldrbvs r0, [r2, #-116]! ; 0xffffff8c
1e0: 73726576 cmnvc r2, #494927872 ; 0x1d800000
}
_exitCritical();
return (Encoder)encoder;
}
return NULL;
1e4: 69750065 ldmdbvs r5!, {r0, r2, r5, r6}^
1e8: 3631746e ldrtcc r7, [r1], -lr, ror #8
// Interrupt per-port on either rising or falling edge
ioSetInterrupt(portTop, INTERRUPT_EDGE_BOTH, _encoderISRTop);
ioSetInterrupt(portBottom, INTERRUPT_EDGE_BOTH, _encoderISRBottom);
}
_exitCritical();
return (Encoder)encoder;
1ec: 6c00745f cfstrsvs mvf7, [r0], {95} ; 0x5f
}
return NULL;
}
1f0: 20676e6f rsbcs r6, r7, pc, ror #28
1f4: 00746e69 rsbseq r6, r4, r9, ror #28
1f8: 33746e69 cmncc r4, #1680 ; 0x690
1fc: 00745f32 rsbseq r5, r4, r2, lsr pc
200: 45495753 strbmi r5, [r9, #-1875] ; 0xfffff8ad
if (handler != NULL)
handler(pin + 1);
}
// External interrupts all Px0 pins (PD0/Digital 11)
IRQ ISR_EXTI0() {
204: 54520052 ldrbpl r0, [r2], #-82 ; 0xffffffae
208: 5f005253 svcpl 0x00005253
}
}
// Fires off the external interrupt logic for a given pin
static INLINE void triggerEXTI(uint32_t pin) {
InterruptHandler handler = _sensorState[pin].eventTrigger;
20c: 6c6f6f42 stclvs 15, cr6, [pc], #-264 ; 10c <.debug_str+0x10c>
210: 52534900 subspl r4, r3, #0, 18
if (handler != NULL)
214: 5458455f ldrbpl r4, [r8], #-1375 ; 0xfffffaa1
handler(pin + 1);
218: 355f3949 ldrbcc r3, [pc, #-2377] ; fffff8d7 <encoderGet+0xfffff8d7>
// External interrupts all Px0 pins (PD0/Digital 11)
IRQ ISR_EXTI0() {
// We assume that this can only fire if unmasked (therefore, wanted)
triggerEXTI(10);
EXTI->PR = (uint32_t)0x0001;
}
21c: 65735f00 ldrbvs r5, [r3, #-3840]! ; 0xfffff100
// External interrupts all Px0 pins (PD0/Digital 11)
IRQ ISR_EXTI0() {
// We assume that this can only fire if unmasked (therefore, wanted)
triggerEXTI(10);
EXTI->PR = (uint32_t)0x0001;
220: 726f736e rsbvc r7, pc, #-1207959551 ; 0xb8000001
}
224: 74617453 strbtvc r7, [r1], #-1107 ; 0xfffffbad
228: 6f6c0065 svcvs 0x006c0065
22c: 7520676e strvc r6, [r0, #-1902]! ; 0xfffff892
// External interrupts all Px1 pins (PD1/Digital 12)
IRQ ISR_EXTI1() {
230: 6769736e strbvs r7, [r9, -lr, ror #6]!
234: 2064656e rsbcs r6, r4, lr, ror #10
}
}
// Fires off the external interrupt logic for a given pin
static INLINE void triggerEXTI(uint32_t pin) {
InterruptHandler handler = _sensorState[pin].eventTrigger;
238: 00746e69 rsbseq r6, r4, r9, ror #28
23c: 4377656e cmnmi r7, #461373440 ; 0x1b800000
if (handler != NULL)
240: 69746972 ldmdbvs r4!, {r1, r4, r5, r6, r8, fp, sp, lr}^
handler(pin + 1);
244: 006c6163 rsbeq r6, ip, r3, ror #2
// External interrupts all Px1 pins (PD1/Digital 12)
IRQ ISR_EXTI1() {
// We assume that this can only fire if unmasked (therefore, wanted)
triggerEXTI(11);
EXTI->PR = (uint32_t)0x0002;
}
248: 6c436f69 mcrrvs 15, 6, r6, r3, cr9
// External interrupts all Px1 pins (PD1/Digital 12)
IRQ ISR_EXTI1() {
// We assume that this can only fire if unmasked (therefore, wanted)
triggerEXTI(11);
EXTI->PR = (uint32_t)0x0002;
24c: 49726165 ldmdbmi r2!, {r0, r2, r5, r6, r8, sp, lr}^
}
250: 7265746e rsbvc r7, r5, #1845493760 ; 0x6e000000
254: 74707572 ldrbtvc r7, [r0], #-1394 ; 0xfffffa8e
258: 656d2f00 strbvs r2, [sp, #-3840]! ; 0xfffff100
// External interrupts all Px5-Px9 pins
// (PC6/Digital 3, PC7/Digital 4, PE8/Digital 7, PE9/Digital 1)
IRQ ISR_EXTI9_5() {
25c: 2f616964 svccs 0x00616964
260: 65786970 ldrbvs r6, [r8, #-2416]! ; 0xfffff690
264: 494c2f6c stmdbmi ip, {r2, r3, r5, r6, r8, r9, sl, fp, sp}^
uint32_t pending = EXTI->PR, reset = 0;
268: 682f554e stmdavs pc!, {r1, r2, r3, r6, r8, sl, ip, lr} ; <UNPREDICTABLE>
if (pending & (uint32_t)0x0040) {
26c: 2f656d6f svccs 0x00656d6f
270: 65786970 ldrbvs r6, [r8, #-2416]! ; 0xfffff690
}
}
// Fires off the external interrupt logic for a given pin
static INLINE void triggerEXTI(uint32_t pin) {
InterruptHandler handler = _sensorState[pin].eventTrigger;
274: 73732f6c cmnvc r3, #108, 30 ; 0x1b0
if (handler != NULL)
handler(pin + 1);
278: 69702f64 ldmdbvs r0!, {r2, r5, r6, r8, r9, sl, fp, sp}^
IRQ ISR_EXTI9_5() {
uint32_t pending = EXTI->PR, reset = 0;
if (pending & (uint32_t)0x0040) {
// PC6 fired
triggerEXTI(2);
reset |= (uint32_t)0x0040;
27c: 2f6c6578 svccs 0x006c6578
}
if (pending & (uint32_t)0x0080) {
280: 736f7270 cmnvc pc, #112, 4
}
}
// Fires off the external interrupt logic for a given pin
static INLINE void triggerEXTI(uint32_t pin) {
InterruptHandler handler = _sensorState[pin].eventTrigger;
284: 6b726f66 blvs 1c9c024 <encoderGet+0x1c9c024>
if (handler != NULL)
handler(pin + 1);
288: 6372732f cmnvs r2, #-1140850688 ; 0xbc000000
reset |= (uint32_t)0x0040;
}
if (pending & (uint32_t)0x0080) {
// PC7 fired
triggerEXTI(3);
reset |= (uint32_t)0x0080;
28c: 73616d00 cmnvc r1, #0, 26
}
if (pending & (uint32_t)0x0100) {
290: 6572006b ldrbvs r0, [r2, #-107]! ; 0xffffff95
}
}
// Fires off the external interrupt logic for a given pin
static INLINE void triggerEXTI(uint32_t pin) {
InterruptHandler handler = _sensorState[pin].eventTrigger;
294: 00746573 rsbseq r6, r4, r3, ror r5
if (handler != NULL)
298: 6e695f5f mcrvs 15, 3, r5, cr9, cr15, {2}
handler(pin + 1);
29c: 5f323374 svcpl 0x00323374
reset |= (uint32_t)0x0080;
}
if (pending & (uint32_t)0x0100) {
// PE8 fired
triggerEXTI(6);
reset |= (uint32_t)0x0100;
2a0: 6e650074 mcrvs 0, 3, r0, cr5, cr4, {3}
}
if (pending & (uint32_t)0x0200) {
2a4: 65646f63 strbvs r6, [r4, #-3939]! ; 0xfffff09d
}
}
// Fires off the external interrupt logic for a given pin
static INLINE void triggerEXTI(uint32_t pin) {
InterruptHandler handler = _sensorState[pin].eventTrigger;
2a8: 75685372 strbvc r5, [r8, #-882]! ; 0xfffffc8e
if (handler != NULL)
handler(pin + 1);
2ac: 776f6474 ; <UNDEFINED> instruction: 0x776f6474
reset |= (uint32_t)0x0100;
}
if (pending & (uint32_t)0x0200) {
// PE9 fired
triggerEXTI(0);
reset |= (uint32_t)0x0200;
2b0: 6975006e ldmdbvs r5!, {r1, r2, r3, r5, r6}^
}
EXTI->PR = reset;
2b4: 5f38746e svcpl 0x0038746e
}
2b8: 64650074 strbtvs r0, [r5], #-116 ; 0xffffff8c
2bc: 00736567 rsbseq r6, r3, r7, ror #10
2c0: 6f636e65 svcvs 0x00636e65
2c4: 00726564 rsbseq r6, r2, r4, ror #10
// External interrupts all Px10-Px15 pins
// (PE10/Digital 8, PE11/Digital 2, PE12/Digital 9, PE13/Digital 5, PE14/Digital 6)
IRQ ISR_EXTI15_10() {
2c8: 74726f70 ldrbtvc r6, [r2], #-3952 ; 0xfffff090
2cc: 00706f54 rsbseq r6, r0, r4, asr pc
2d0: 20554e47 subscs r4, r5, r7, asr #28
uint32_t pending = EXTI->PR, reset = 0;
2d4: 2e342043 cdpcs 0, 3, cr2, cr4, cr3, {2}
if (pending & (uint32_t)0x0400) {
2d8: 20332e39 eorscs r2, r3, r9, lsr lr
}
}
// Fires off the external interrupt logic for a given pin
static INLINE void triggerEXTI(uint32_t pin) {
InterruptHandler handler = _sensorState[pin].eventTrigger;
2dc: 35313032 ldrcc r3, [r1, #-50]! ; 0xffffffce
if (handler != NULL)
2e0: 39323530 ldmdbcc r2!, {r4, r5, r8, sl, ip, sp}
handler(pin + 1);
2e4: 72702820 rsbsvc r2, r0, #32, 16 ; 0x200000
IRQ ISR_EXTI15_10() {
uint32_t pending = EXTI->PR, reset = 0;
if (pending & (uint32_t)0x0400) {
// PE10 fired
triggerEXTI(7);
reset |= (uint32_t)0x0400;
2e8: 6c657265 sfmvs f7, 2, [r5], #-404 ; 0xfffffe6c
}
if (pending & (uint32_t)0x0800) {
2ec: 65736165 ldrbvs r6, [r3, #-357]! ; 0xfffffe9b
}
}
// Fires off the external interrupt logic for a given pin
static INLINE void triggerEXTI(uint32_t pin) {
InterruptHandler handler = _sensorState[pin].eventTrigger;
2f0: 6d2d2029 stcvs 0, cr2, [sp, #-164]! ; 0xffffff5c
if (handler != NULL)
handler(pin + 1);
2f4: 6d756874 ldclvs 8, cr6, [r5, #-464]! ; 0xfffffe30
reset |= (uint32_t)0x0400;
}
if (pending & (uint32_t)0x0800) {
// PE11 fired
triggerEXTI(1);
reset |= (uint32_t)0x0800;
2f8: 6d2d2062 stcvs 0, cr2, [sp, #-392]! ; 0xfffffe78
}
if (pending & (uint32_t)0x1000) {
2fc: 3d757063 ldclcc 0, cr7, [r5, #-396]! ; 0xfffffe74
}
}
// Fires off the external interrupt logic for a given pin
static INLINE void triggerEXTI(uint32_t pin) {
InterruptHandler handler = _sensorState[pin].eventTrigger;
300: 74726f63 ldrbtvc r6, [r2], #-3939 ; 0xfffff09d
304: 6d2d7865 stcvs 8, cr7, [sp, #-404]! ; 0xfffffe6c
if (handler != NULL)
handler(pin + 1);
308: 6d2d2033 stcvs 0, cr2, [sp, #-204]! ; 0xffffff34
reset |= (uint32_t)0x0800;
}
if (pending & (uint32_t)0x1000) {
// PE12 fired
triggerEXTI(8);
reset |= (uint32_t)0x1000;
30c: 7474696c ldrbtvc r6, [r4], #-2412 ; 0xfffff694
}
if (pending & (uint32_t)0x2000) {
310: 652d656c strvs r6, [sp, #-1388]! ; 0xfffffa94
}
}
// Fires off the external interrupt logic for a given pin
static INLINE void triggerEXTI(uint32_t pin) {
InterruptHandler handler = _sensorState[pin].eventTrigger;
314: 6169646e cmnvs r9, lr, ror #8
if (handler != NULL)
318: 672d206e strvs r2, [sp, -lr, rrx]!
handler(pin + 1);
31c: 734f2d20 movtvc r2, #64800 ; 0xfd20
reset |= (uint32_t)0x1000;
}
if (pending & (uint32_t)0x2000) {
// PE13 fired
triggerEXTI(4);
reset |= (uint32_t)0x2000;
320: 74732d20 ldrbtvc r2, [r3], #-3360 ; 0xfffff2e0
}
if (pending & (uint32_t)0x4000) {
324: 6e673d64 cdpvs 13, 6, cr3, cr7, cr4, {3}
}
}
// Fires off the external interrupt logic for a given pin
static INLINE void triggerEXTI(uint32_t pin) {
InterruptHandler handler = _sensorState[pin].eventTrigger;
328: 20393975 eorscs r3, r9, r5, ror r9
if (handler != NULL)
handler(pin + 1);
32c: 7566662d strbvc r6, [r6, #-1581]! ; 0xfffff9d3
reset |= (uint32_t)0x2000;
}
if (pending & (uint32_t)0x4000) {
// PE14 fired
triggerEXTI(5);
reset |= (uint32_t)0x4000;
330: 6974636e ldmdbvs r4!, {r1, r2, r3, r5, r6, r8, r9, sp, lr}^
}
EXTI->PR = reset;
334: 732d6e6f ; <UNDEFINED> instruction: 0x732d6e6f
}
338: 69746365 ldmdbvs r4!, {r0, r2, r5, r6, r8, r9, sp, lr}^
33c: 20736e6f rsbscs r6, r3, pc, ror #28
340: 6973662d ldmdbvs r3!, {r0, r2, r3, r5, r9, sl, sp, lr}^
344: 64656e67 strbtvs r6, [r5], #-3687 ; 0xfffff199
348: 6168632d cmnvs r8, sp, lsr #6
34c: 662d2072 ; <UNDEFINED> instruction: 0x662d2072
350: 74696d6f strbtvc r6, [r9], #-3439 ; 0xfffff291
354: 6172662d cmnvs r2, sp, lsr #12
358: 702d656d eorvc r6, sp, sp, ror #10
35c: 746e696f strbtvc r6, [lr], #-2415 ; 0xfffff691
360: 2d207265 sfmcs f7, 4, [r0, #-404]! ; 0xfffffe6c
364: 6e697366 cdpvs 3, 6, cr7, cr9, cr6, {3}
368: 2d656c67 stclcs 12, cr6, [r5, #-412]! ; 0xfffffe64
36c: 63657270 cmnvs r5, #112, 4
370: 6f697369 svcvs 0x00697369
374: 6f632d6e svcvs 0x00632d6e
378: 6174736e cmnvs r4, lr, ror #6
37c: 6500746e strvs r7, [r0, #-1134] ; 0xfffffb92
380: 646f636e strbtvs r6, [pc], #-878 ; 388 <.debug_str+0x388>
384: 65477265 strbvs r7, [r7, #-613] ; 0xfffffd9b
388: 6f700074 svcvs 0x00700074
38c: 6f427472 svcvs 0x00427472
390: 6d6f7474 cfstrdvs mvd7, [pc, #-464]! ; 1c8 <.debug_str+0x1c8>
...
Disassembly of section .comment:
00000000 <.comment>:
#endif
// encoderGet - Gets the value of the encoder
int encoderGet(Encoder enc) {
Sensor_TypeDef *encoder = (Sensor_TypeDef*)enc;
if (encoder)
0: 43434700 movtmi r4, #14080 ; 0x3700
return (int)encoder->value;
return 0;
}
4: 3128203a ; <UNDEFINED> instruction: 0x3128203a
}
// encoderReset - Resets the encoder to zero
void encoderReset(Encoder enc) {
Sensor_TypeDef *encoder = (Sensor_TypeDef*)enc;
if (encoder) {
8: 2e343a35 mrccs 10, 1, r3, cr4, cr5, {1}
extern volatile uint32_t _criticalNesting;
/* Enter a critical section. */
static INLINE void _enterCritical() {
__disable_irq();
_criticalNesting++;
c: 2b332e39 blcs ccb8f8 <encoderGet+0xccb8f8>
10: 326e7673 rsbcc r7, lr, #120586240 ; 0x7300000
_enterCritical();
{
encoder->value = 0;
14: 37313133 ; <UNDEFINED> instruction: 0x37313133
encoder->lastValue = 0;
18: 29312d37 ldmdbcs r1!, {r0, r1, r2, r4, r5, r8, sl, fp, sp}
}
/* Exit a critical section. */
static INLINE void _exitCritical() {
const uint32_t newCritical = _criticalNesting - 1;
1c: 392e3420 stmdbcc lr!, {r5, sl, ip, sp}
_criticalNesting = newCritical;
if (newCritical == 0)
20: 3220332e eorcc r3, r0, #-1207959552 ; 0xb8000000
24: 30353130 eorscc r3, r5, r0, lsr r1
28: 20393235 eorscs r3, r9, r5, lsr r2
}
}
// ioClearInterrupt - Disables interrupts on the specified pin
void ioClearInterrupt(unsigned char pin) {
pin--;
2c: 65727028 ldrbvs r7, [r2, #-40]! ; 0xffffffd8
if (pin < 12 && pin != 9) {
30: 656c6572 strbvs r6, [ip, #-1394]! ; 0xfffffa8e
34: 29657361 stmdbcs r5!, {r0, r5, r6, r8, r9, ip, sp, lr}^
...
Disassembly of section .debug_frame:
00000000 <.debug_frame>:
#endif
// encoderGet - Gets the value of the encoder
int encoderGet(Encoder enc) {
Sensor_TypeDef *encoder = (Sensor_TypeDef*)enc;
if (encoder)
0: 0000000c andeq r0, r0, ip
return (int)encoder->value;
return 0;
}
4: ffffffff ; <UNDEFINED> instruction: 0xffffffff
}
// encoderReset - Resets the encoder to zero
void encoderReset(Encoder enc) {
Sensor_TypeDef *encoder = (Sensor_TypeDef*)enc;
if (encoder) {
8: 7c020001 stcvc 0, cr0, [r2], {1}
extern volatile uint32_t _criticalNesting;
/* Enter a critical section. */
static INLINE void _enterCritical() {
__disable_irq();
_criticalNesting++;
c: 000d0c0e andeq r0, sp, lr, lsl #24
10: 0000000c andeq r0, r0, ip
...
14: R_ARM_ABS32 .debug_frame
18: R_ARM_ABS32 .text.encoderGet
}
/* Exit a critical section. */
static INLINE void _exitCritical() {
const uint32_t newCritical = _criticalNesting - 1;
1c: 00000006 andeq r0, r0, r6
_criticalNesting = newCritical;
if (newCritical == 0)
20: 0000000c andeq r0, r0, ip
...
24: R_ARM_ABS32 .debug_frame
28: R_ARM_ABS32 .text.encoderReset
}
}
// ioClearInterrupt - Disables interrupts on the specified pin
void ioClearInterrupt(unsigned char pin) {
pin--;
2c: 00000024 andeq r0, r0, r4, lsr #32
if (pin < 12 && pin != 9) {
30: 0000000c andeq r0, r0, ip
...
34: R_ARM_ABS32 .debug_frame
38: R_ARM_ABS32 .text.ioClearInterrupt
// Avoid having the OS swap this out
_enterCritical();
{
uint32_t mask = (uint32_t)1 << _pinIndexTable[pin + 1];
3c: 00000048 andeq r0, r0, r8, asr #32
extern volatile uint32_t _criticalNesting;
/* Enter a critical section. */
static INLINE void _enterCritical() {
__disable_irq();
_criticalNesting++;
40: 00000018 andeq r0, r0, r8, lsl r0
...
44: R_ARM_ABS32 .debug_frame
48: R_ARM_ABS32 .text.encoderShutdown
// Clear pending interrupt
EXTI->PR |= mask;
4c: 00000040 andeq r0, r0, r0, asr #32
50: 83100e41 tsthi r0, #1040 ; 0x410
// Mask interrupt
EXTI->IMR &= ~mask;
54: 85038404 strhi r8, [r3, #-1028] ; 0xfffffbfc
58: 00018e02 andeq r8, r1, r2, lsl #28
}
/* Exit a critical section. */
static INLINE void _exitCritical() {
const uint32_t newCritical = _criticalNesting - 1;
5c: 0000001c andeq r0, r0, ip, lsl r0
...
60: R_ARM_ABS32 .debug_frame
64: R_ARM_ABS32 .text.ioSetInterrupt
68: 00000084 andeq r0, r0, r4, lsl #1
6c: 84140e44 ldrhi r0, [r4], #-3652 ; 0xfffff1bc
70: 86048505 strhi r8, [r4], -r5, lsl #10
_exitCritical();
}
}
// encoderShutdown - Stops and disables the encoder
void encoderShutdown(Encoder enc) {
74: 8e028703 cdphi 7, 0, cr8, cr2, cr3, {0}
Sensor_TypeDef *encoder = (Sensor_TypeDef*)enc;
if (encoder) {
78: 00000001 andeq r0, r0, r1
extern volatile uint32_t _criticalNesting;
/* Enter a critical section. */
static INLINE void _enterCritical() {
__disable_irq();
_criticalNesting++;
7c: 00000028 andeq r0, r0, r8, lsr #32
...
80: R_ARM_ABS32 .debug_frame
84: R_ARM_ABS32 .text.encoderInit
_enterCritical();
{
// Stop
encoder->flags = 0;
_sensorState[encoder->portBottom].flags = 0;
88: 000000cc andeq r0, r0, ip, asr #1
8c: 84300e42 ldrthi r0, [r0], #-3650 ; 0xfffff1be
90: 86088509 strhi r8, [r8], -r9, lsl #10
// Clear interrupts
ioClearInterrupt(encoder->portTop);
94: 88068707 stmdahi r6, {r0, r1, r2, r8, r9, sl, pc}
ioClearInterrupt(encoder->portBottom);
98: 8a048905 bhi 1224b4 <encoderGet+0x1224b4>
9c: 8e028b03 vmlahi.f64 d8, d2, d3
}
/* Exit a critical section. */
static INLINE void _exitCritical() {
const uint32_t newCritical = _criticalNesting - 1;
a0: 0e5a0201 cdpeq 2, 5, cr0, cr10, cr1, {0}
_criticalNesting = newCritical;
if (newCritical == 0)
a4: 00000024 andeq r0, r0, r4, lsr #32
a8: 0000001c andeq r0, r0, ip, lsl r0
...
ac: R_ARM_ABS32 .debug_frame
b0: R_ARM_ABS32 .text.ISR_EXTI0
}
// ioSetInterrupt - Sets up an interrupt to occur on the specified pin, and resets count & time
// Provide NULL for handler for standard interrupts, or pass function pointer for custom
void ioSetInterrupt(unsigned char pin, unsigned char edges, InterruptHandler handler) {
pin--;
b4: 0000002c andeq r0, r0, ip, lsr #32
if (pin < BOARD_NR_DIGITAL_IO && pin != 9) {
b8: 000d0941 andeq r0, sp, r1, asr #18
bc: 8d080e45 stchi 14, cr0, [r8, #-276] ; 0xfffffeec
c0: 47018e02 strmi r8, [r1, -r2, lsl #28]
extern volatile uint32_t _criticalNesting;
/* Enter a critical section. */
static INLINE void _enterCritical() {
__disable_irq();
_criticalNesting++;
c4: 000ec0ce andeq ip, lr, lr, asr #1
c8: 0000001c andeq r0, r0, ip, lsl r0
...
cc: R_ARM_ABS32 .debug_frame
d0: R_ARM_ABS32 .text.ISR_EXTI1
// Avoid having the OS swap this out during init
_enterCritical();
{
// In range, start by masking interrupt if enabled
uint32_t mask = (uint32_t)1 << _pinIndexTable[pin + 1], temp;
d4: 0000002c andeq r0, r0, ip, lsr #32
d8: 000d0941 andeq r0, sp, r1, asr #18
dc: 8d080e45 stchi 14, cr0, [r8, #-276] ; 0xfffffeec
EXTI->IMR &= ~mask;
e0: 47018e02 strmi r8, [r1, -r2, lsl #28]
e4: 000ec0ce andeq ip, lr, lr, asr #1
e8: 00000028 andeq r0, r0, r8, lsr #32
...
ec: R_ARM_ABS32 .debug_frame
f0: R_ARM_ABS32 .text.ISR_EXTI9_5
// Configure freely, we won't have an issue here since interrupt is masked
Sensor_TypeDef *state = &_sensorState[pin];
state->eventTrigger = handler;
// Falling edge configuration
temp = EXTI->FTSR;
f4: 0000006c andeq r0, r0, ip, rrx
if (edges & INTERRUPT_EDGE_FALLING)
temp |= mask;
f8: 000d0941 andeq r0, sp, r1, asr #18
else
temp &= ~mask;
EXTI->FTSR = temp;
fc: 8d180e44 ldchi 14, cr0, [r8, #-272] ; 0xfffffef0
// Rising edge configuration
temp = EXTI->RTSR;
if (edges & INTERRUPT_EDGE_RISING)
100: 84058306 strhi r8, [r5], #-774 ; 0xfffffcfa
temp |= mask;
104: 86038504 strhi r8, [r3], -r4, lsl #10
else
temp &= ~mask;
108: 6a018e02 bvs 63918 <encoderGet+0x63918>
EXTI->RTSR = temp;
10c: c4c5c6ce strbgt ip, [r5], #1742 ; 0x6ce
// Clear pending interrupt
EXTI->PR |= mask;
110: 000ec0c3 andeq ip, lr, r3, asr #1
// Unmask interrupt to start monitoring
EXTI->IMR |= mask;
114: 00000028 andeq r0, r0, r8, lsr #32
...
118: R_ARM_ABS32 .debug_frame
11c: R_ARM_ABS32 .text.ISR_EXTI15_10
/* Exit a critical section. */
static INLINE void _exitCritical() {
const uint32_t newCritical = _criticalNesting - 1;
_criticalNesting = newCritical;
if (newCritical == 0)
120: 00000080 andeq r0, r0, r0, lsl #1
124: 000d0941 andeq r0, sp, r1, asr #18
128: 8d180e44 ldchi 14, cr0, [r8, #-272] ; 0xfffffef0
12c: 84058306 strhi r8, [r5], #-774 ; 0xfffffcfa
130: 86038504 strhi r8, [r3], -r4, lsl #10
134: 74018e02 strvc r8, [r1], #-3586 ; 0xfffff1fe
return (int)encoder->value;
return 0;
}
// encoderInit - Initializes and enables a quadrature encoder on two digital ports
Encoder encoderInit(unsigned char portTop, unsigned char portBottom, bool reverse) {
138: c4c5c6ce strbgt ip, [r5], #1742 ; 0x6ce
Sensor_TypeDef *encoder, *slave;
// Change to 0..11 range
uint32_t it = portTop - 1, ib = portBottom - 1;
13c: 000ec0c3 andeq ip, lr, r3, asr #1
Disassembly of section .ARM.attributes:
00000000 <.ARM.attributes>:
#endif
// encoderGet - Gets the value of the encoder
int encoderGet(Encoder enc) {
Sensor_TypeDef *encoder = (Sensor_TypeDef*)enc;
if (encoder)
0: 00003241 andeq r3, r0, r1, asr #4
return (int)encoder->value;
return 0;
}
4: 61656100 cmnvs r5, r0, lsl #2
}
// encoderReset - Resets the encoder to zero
void encoderReset(Encoder enc) {
Sensor_TypeDef *encoder = (Sensor_TypeDef*)enc;
if (encoder) {
8: 01006962 tsteq r0, r2, ror #18
extern volatile uint32_t _criticalNesting;
/* Enter a critical section. */
static INLINE void _enterCritical() {
__disable_irq();
_criticalNesting++;
c: 00000028 andeq r0, r0, r8, lsr #32
10: 726f4305 rsbvc r4, pc, #335544320 ; 0x14000000
_enterCritical();
{
encoder->value = 0;
14: 2d786574 cfldr64cs mvdx6, [r8, #-464]! ; 0xfffffe30
encoder->lastValue = 0;
18: 0600334d streq r3, [r0], -sp, asr #6
}
/* Exit a critical section. */
static INLINE void _exitCritical() {
const uint32_t newCritical = _criticalNesting - 1;
1c: 094d070a stmdbeq sp, {r1, r3, r8, r9, sl}^
_criticalNesting = newCritical;
if (newCritical == 0)
20: 14041202 strne r1, [r4], #-514 ; 0xfffffdfe
24: 17011501 strne r1, [r1, -r1, lsl #10]
28: 19011803 stmdbne r1, {r0, r1, fp, ip}
}
}
// ioClearInterrupt - Disables interrupts on the specified pin
void ioClearInterrupt(unsigned char pin) {
pin--;
2c: 1e011a01 vmlane.f32 s2, s2, s2
if (pin < 12 && pin != 9) {
30: Address 0x0000000000000030 is out of bounds.
encoder_isr.o: file format elf32-littlearm
rw-r--r-- 1000/1000 1208 Oct 20 02:06 2016 encoder_isr.o
architecture: arm, flags 0x00000011:
HAS_RELOC, HAS_SYMS
start address 0x00000000
private flags = 5000000: [Version5 EABI]
Sections:
Idx Name Size VMA LMA File off Algn
0 .text 00000000 00000000 00000000 00000034 2**0
CONTENTS, ALLOC, LOAD, READONLY, CODE
1 .data 00000000 00000000 00000000 00000034 2**0
CONTENTS, ALLOC, LOAD, DATA
2 .bss 00000000 00000000 00000000 00000034 2**0
ALLOC
3 .text._encoderISRBottom 00000048 00000000 00000000 00000034 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
4 .text._encoderISRTop 00000040 00000000 00000000 0000007c 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
5 .ARM.attributes 00000021 00000000 00000000 000000bc 2**0
CONTENTS, READONLY
SYMBOL TABLE:
00000000 l d .text 00000000 .text
00000000 l d .data 00000000 .data
00000000 l d .bss 00000000 .bss
00000000 l d .text._encoderISRBottom 00000000 .text._encoderISRBottom
00000000 l d .text._encoderISRTop 00000000 .text._encoderISRTop
00000000 l d .ARM.attributes 00000000 .ARM.attributes
00000000 g F .text._encoderISRBottom 00000000 _encoderISRBottom
00000000 *UND* 00000000 digitalRead
00000000 *UND* 00000000 _sensorState
00000000 g F .text._encoderISRTop 00000000 _encoderISRTop
Disassembly of section .text._encoderISRBottom:
00000000 <_encoderISRBottom>:
0: b530 push {r4, r5, lr}
2: 4604 mov r4, r0
4: f7ff fffe bl 0 <digitalRead>
4: R_ARM_THM_CALL digitalRead
8: 4605 mov r5, r0
a: 4b0e ldr r3, [pc, #56] ; (44 <_encoderISRBottom+0x44>)
c: eb03 1404 add.w r4, r3, r4, lsl #4
10: 88a1 ldrh r1, [r4, #4]
12: f011 0f02 tst.w r1, #2
16: d013 beq.n 40 <_encoderISRBottom+0x40>
18: 79a0 ldrb r0, [r4, #6]
1a: f7ff fffe bl 0 <digitalRead>
1a: R_ARM_THM_CALL digitalRead
1e: 88a1 ldrh r1, [r4, #4]
20: f001 0101 and.w r1, r1, #1
24: 4281 cmp r1, r0
26: bf14 ite ne
28: f04f 32ff movne.w r2, #4294967295 ; 0xffffffff
2c: 2201 moveq r2, #1
2e: b905 cbnz r5, 32 <_encoderISRBottom+0x32>
30: 4252 negs r2, r2
32: 79a0 ldrb r0, [r4, #6]
34: 4b03 ldr r3, [pc, #12] ; (44 <_encoderISRBottom+0x44>)
36: eb03 1300 add.w r3, r3, r0, lsl #4
3a: 6818 ldr r0, [r3, #0]
3c: 1880 adds r0, r0, r2
3e: 6018 str r0, [r3, #0]
40: bd30 pop {r4, r5, pc}
42: fff00000 ; <UNDEFINED> instruction: 0xfff00000 ; IMB
44: R_ARM_ABS32 _sensorState
46: Address 0x0000000000000046 is out of bounds.
Disassembly of section .text._encoderISRTop:
00000000 <_encoderISRTop>:
0: b530 push {r4, r5, lr}
2: 4604 mov r4, r0
4: f7ff fffe bl 0 <digitalRead>
4: R_ARM_THM_CALL digitalRead
8: 4605 mov r5, r0
a: 4b0c ldr r3, [pc, #48] ; (3c <_encoderISRTop+0x3c>)
c: eb03 1404 add.w r4, r3, r4, lsl #4
10: 88a1 ldrh r1, [r4, #4]
12: f011 0f02 tst.w r1, #2
16: d00f beq.n 38 <_encoderISRTop+0x38>
18: 79e0 ldrb r0, [r4, #7]
1a: f7ff fffe bl 0 <digitalRead>
1a: R_ARM_THM_CALL digitalRead
1e: 88a1 ldrh r1, [r4, #4]
20: f001 0101 and.w r1, r1, #1
24: 42a9 cmp r1, r5
26: bf14 ite ne
28: f04f 32ff movne.w r2, #4294967295 ; 0xffffffff
2c: 2201 moveq r2, #1
2e: b100 cbz r0, 32 <_encoderISRTop+0x32>
30: 4252 negs r2, r2
32: 6820 ldr r0, [r4, #0]
34: 1880 adds r0, r0, r2
36: 6020 str r0, [r4, #0]
38: bd30 pop {r4, r5, pc}
3a: fff00000 ; <UNDEFINED> instruction: 0xfff00000 ; IMB
3c: R_ARM_ABS32 _sensorState
3e: Address 0x000000000000003e is out of bounds.
Disassembly of section .ARM.attributes:
00000000 <.ARM.attributes>:
0: 00002041 andeq r2, r0, r1, asr #32
4: 61656100 cmnvs r5, r0, lsl #2
8: 01006962 tsteq r0, r2, ror #18
c: 00000016 andeq r0, r0, r6, lsl r0
10: 726f4305 rsbvc r4, pc, #335544320 ; 0x14000000
14: 2d786574 cfldr64cs mvdx6, [r8, #-464]! ; 0xfffffe30
18: 0600334d streq r3, [r0], -sp, asr #6
1c: 094d070a stmdbeq sp, {r1, r3, r8, r9, sl}^
20: Address 0x0000000000000020 is out of bounds.
fs.o: file format elf32-littlearm
rw-r--r-- 1000/1000 22828 Oct 20 02:06 2016 fs.o
architecture: arm, flags 0x00000011:
HAS_RELOC, HAS_SYMS
start address 0x00000000
private flags = 5000000: [Version5 EABI]
Sections:
Idx Name Size VMA LMA File off Algn
0 .text 00000000 00000000 00000000 00000034 2**1
CONTENTS, ALLOC, LOAD, READONLY, CODE
1 .data 00000000 00000000 00000000 00000034 2**0
CONTENTS, ALLOC, LOAD, DATA
2 .bss 00000000 00000000 00000000 00000034 2**0
ALLOC
3 .text._fs_erase_page 00000020 00000000 00000000 00000034 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
4 .text._fs_prgm_word 00000020 00000000 00000000 00000054 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
5 .text.lookForFile 00000038 00000000 00000000 00000074 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
6 .text.fdelete 00000084 00000000 00000000 000000ac 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
7 .text.fsEof 00000030 00000000 00000000 00000130 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
8 .text.fflush 000000d8 00000000 00000000 00000160 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
9 .text.fsLeft 0000002c 00000000 00000000 00000238 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
10 .text.fopen 00000134 00000000 00000000 00000264 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
11 .text.fsRead 00000050 00000000 00000000 00000398 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
12 .text.fsScan 000000cc 00000000 00000000 000003e8 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
13 .text.fseek 00000050 00000000 00000000 000004b4 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
14 .text.ftell 00000024 00000000 00000000 00000504 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
15 .text.fsWrite 00000064 00000000 00000000 00000528 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
16 .text.fclose 00000094 00000000 00000000 0000058c 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
17 .rodata.str1.1 00000004 00000000 00000000 00000620 2**0
CONTENTS, ALLOC, LOAD, READONLY, DATA
18 .debug_info 00000cd5 00000000 00000000 00000624 2**0
CONTENTS, RELOC, READONLY, DEBUGGING
19 .debug_abbrev 0000039f 00000000 00000000 000012f9 2**0
CONTENTS, READONLY, DEBUGGING
20 .debug_loc 00000d77 00000000 00000000 00001698 2**0
CONTENTS, RELOC, READONLY, DEBUGGING
21 .debug_aranges 00000088 00000000 00000000 0000240f 2**0
CONTENTS, RELOC, READONLY, DEBUGGING
22 .debug_ranges 00000180 00000000 00000000 00002497 2**0
CONTENTS, RELOC, READONLY, DEBUGGING
23 .debug_line 000003e0 00000000 00000000 00002617 2**0
CONTENTS, RELOC, READONLY, DEBUGGING
24 .debug_str 00000342 00000000 00000000 000029f7 2**0
CONTENTS, READONLY, DEBUGGING
25 .comment 00000039 00000000 00000000 00002d39 2**0
CONTENTS, READONLY
26 .debug_frame 00000174 00000000 00000000 00002d74 2**2
CONTENTS, RELOC, READONLY, DEBUGGING
27 .ARM.attributes 00000033 00000000 00000000 00002ee8 2**0
CONTENTS, READONLY
SYMBOL TABLE:
00000000 l df *ABS* 00000000 fs.c
00000000 l d .text 00000000 .text
00000000 l d .data 00000000 .data
00000000 l d .bss 00000000 .bss
00000000 l d .text._fs_erase_page 00000000 .text._fs_erase_page
00000000 l F .text._fs_erase_page 00000020 _fs_erase_page
00000000 l d .text._fs_prgm_word 00000000 .text._fs_prgm_word
00000000 l F .text._fs_prgm_word 00000020 _fs_prgm_word
00000000 l d .text.lookForFile 00000000 .text.lookForFile
00000000 l F .text.lookForFile 00000038 lookForFile
00000000 l d .text.fdelete 00000000 .text.fdelete
00000000 l d .text.fsEof 00000000 .text.fsEof
00000000 l d .text.fflush 00000000 .text.fflush
00000000 l d .text.fsLeft 00000000 .text.fsLeft
00000000 l d .text.fopen 00000000 .text.fopen
00000000 l d .text.fsRead 00000000 .text.fsRead
00000000 l d .text.fsScan 00000000 .text.fsScan
00000000 l d .text.fseek 00000000 .text.fseek
00000000 l d .text.ftell 00000000 .text.ftell
00000000 l d .text.fsWrite 00000000 .text.fsWrite
00000000 l d .text.fclose 00000000 .text.fclose
00000000 l d .rodata.str1.1 00000000 .rodata.str1.1
00000000 l d .debug_info 00000000 .debug_info
00000000 l d .debug_abbrev 00000000 .debug_abbrev
00000000 l d .debug_loc 00000000 .debug_loc
00000000 l d .debug_aranges 00000000 .debug_aranges
00000000 l d .debug_ranges 00000000 .debug_ranges
00000000 l d .debug_line 00000000 .debug_line
00000000 l d .debug_str 00000000 .debug_str
00000000 l d .debug_frame 00000000 .debug_frame
00000000 l d .comment 00000000 .comment
00000000 l d .ARM.attributes 00000000 .ARM.attributes
00000000 *UND* 00000000 strncmp
000008b0 O *COM* 00000004 fs
00000000 g F .text.fdelete 00000084 fdelete
00000000 g F .text.fsEof 00000030 fsEof
00000000 g F .text.fflush 000000d8 fflush
00000000 g F .text.fsLeft 0000002c fsLeft
00000000 g F .text.fopen 00000134 fopen
00000000 *UND* 00000000 strcmp
00000000 g F .text.fsRead 00000050 fsRead
00000000 g F .text.fsScan 000000cc fsScan
00000000 g F .text.fseek 00000050 fseek
00000000 g F .text.ftell 00000024 ftell
00000000 g F .text.fsWrite 00000064 fsWrite
00000000 g F .text.fclose 00000094 fclose
Disassembly of section .text._fs_erase_page:
00000000 <_fs_erase_page>:
/**
* Erase a page of memory.
*/
static void _fs_erase_page(uint32_t page) {
FLASH->CR = FLASH_CR_PER;
0: 4b06 ldr r3, [pc, #24] ; (1c <_fs_erase_page+0x1c>)
/**
* Return pointer to given memory page. Skips the first 128 K (64 pages).
* Assumes memory can be mapped into linear address space (not AVR!)
*/
static INLINE void * _fs_pointer(const uint32_t page) {
return (void *)((FLASH_BASE + PAGE_SIZE * 64U) + page * PAGE_SIZE);
2: f500 3080 add.w r0, r0, #65536 ; 0x10000
/**
* Erase a page of memory.
*/
static void _fs_erase_page(uint32_t page) {
FLASH->CR = FLASH_CR_PER;
6: 2202 movs r2, #2
/**
* Return pointer to given memory page. Skips the first 128 K (64 pages).
* Assumes memory can be mapped into linear address space (not AVR!)
*/
static INLINE void * _fs_pointer(const uint32_t page) {
return (void *)((FLASH_BASE + PAGE_SIZE * 64U) + page * PAGE_SIZE);
8: 3040 adds r0, #64 ; 0x40
/**
* Erase a page of memory.
*/
static void _fs_erase_page(uint32_t page) {
FLASH->CR = FLASH_CR_PER;
a: 611a str r2, [r3, #16]
/**
* Return pointer to given memory page. Skips the first 128 K (64 pages).
* Assumes memory can be mapped into linear address space (not AVR!)
*/
static INLINE void * _fs_pointer(const uint32_t page) {
return (void *)((FLASH_BASE + PAGE_SIZE * 64U) + page * PAGE_SIZE);
c: 02c0 lsls r0, r0, #11
static void _fs_erase_page(uint32_t page) {
FLASH->CR = FLASH_CR_PER;
// Select page
FLASH->AR = (uint32_t)_fs_pointer(page);
// Start operation
FLASH->CR = FLASH_CR_PER | FLASH_CR_STRT;
e: 2242 movs r2, #66 ; 0x42
* Erase a page of memory.
*/
static void _fs_erase_page(uint32_t page) {
FLASH->CR = FLASH_CR_PER;
// Select page
FLASH->AR = (uint32_t)_fs_pointer(page);
10: 6158 str r0, [r3, #20]
// Start operation
FLASH->CR = FLASH_CR_PER | FLASH_CR_STRT;
12: 611a str r2, [r3, #16]
// Stall until BSY is reset (there is no sense sleeping here as IRQs cannot run while
// the erase is in progress)
while (FLASH->SR & FLASH_SR_BSY);
14: 68da ldr r2, [r3, #12]
16: 07d2 lsls r2, r2, #31
18: d4fc bmi.n 14 <_fs_erase_page+0x14>
// Verify erasure?
}
1a: 4770 bx lr
1c: 40022000 andmi r2, r2, r0
Disassembly of section .text._fs_prgm_word:
00000000 <_fs_prgm_word>:
/**
* Erase a page of memory.
*/
static void _fs_erase_page(uint32_t page) {
FLASH->CR = FLASH_CR_PER;
0: f500 3080 add.w r0, r0, #65536 ; 0x10000
/**
* Return pointer to given memory page. Skips the first 128 K (64 pages).
* Assumes memory can be mapped into linear address space (not AVR!)
*/
static INLINE void * _fs_pointer(const uint32_t page) {
return (void *)((FLASH_BASE + PAGE_SIZE * 64U) + page * PAGE_SIZE);
4: 4b05 ldr r3, [pc, #20] ; (1c <_fs_prgm_word+0x1c>)
/**
* Erase a page of memory.
*/
static void _fs_erase_page(uint32_t page) {
FLASH->CR = FLASH_CR_PER;
6: 3040 adds r0, #64 ; 0x40
/**
* Return pointer to given memory page. Skips the first 128 K (64 pages).
* Assumes memory can be mapped into linear address space (not AVR!)
*/
static INLINE void * _fs_pointer(const uint32_t page) {
return (void *)((FLASH_BASE + PAGE_SIZE * 64U) + page * PAGE_SIZE);
8: b510 push {r4, lr}
/**
* Erase a page of memory.
*/
static void _fs_erase_page(uint32_t page) {
FLASH->CR = FLASH_CR_PER;
a: 02c0 lsls r0, r0, #11
/**
* Return pointer to given memory page. Skips the first 128 K (64 pages).
* Assumes memory can be mapped into linear address space (not AVR!)
*/
static INLINE void * _fs_pointer(const uint32_t page) {
return (void *)((FLASH_BASE + PAGE_SIZE * 64U) + page * PAGE_SIZE);
c: 2401 movs r4, #1
static void _fs_erase_page(uint32_t page) {
FLASH->CR = FLASH_CR_PER;
// Select page
FLASH->AR = (uint32_t)_fs_pointer(page);
// Start operation
FLASH->CR = FLASH_CR_PER | FLASH_CR_STRT;
e: 611c str r4, [r3, #16]
* Erase a page of memory.
*/
static void _fs_erase_page(uint32_t page) {
FLASH->CR = FLASH_CR_PER;
// Select page
FLASH->AR = (uint32_t)_fs_pointer(page);
10: 5242 strh r2, [r0, r1]
// Start operation
FLASH->CR = FLASH_CR_PER | FLASH_CR_STRT;
12: 68da ldr r2, [r3, #12]
// Stall until BSY is reset (there is no sense sleeping here as IRQs cannot run while
// the erase is in progress)
while (FLASH->SR & FLASH_SR_BSY);
14: 07d2 lsls r2, r2, #31
16: d4fc bmi.n 12 <_fs_prgm_word+0x12>
18: bd10 pop {r4, pc}
// Verify erasure?
}
1a: bf00 nop
1c: 40022000 andmi r2, r2, r0
Disassembly of section .text.lookForFile:
00000000 <lookForFile>:
/**
* Erase a page of memory.
*/
static void _fs_erase_page(uint32_t page) {
FLASH->CR = FLASH_CR_PER;
0: b538 push {r3, r4, r5, lr}
/**
* Return pointer to given memory page. Skips the first 128 K (64 pages).
* Assumes memory can be mapped into linear address space (not AVR!)
*/
static INLINE void * _fs_pointer(const uint32_t page) {
return (void *)((FLASH_BASE + PAGE_SIZE * 64U) + page * PAGE_SIZE);
2: 4605 mov r5, r0
4: 2400 movs r4, #0
/**
* Erase a page of memory.
*/
static void _fs_erase_page(uint32_t page) {
FLASH->CR = FLASH_CR_PER;
6: 4b0a ldr r3, [pc, #40] ; (30 <lookForFile+0x30>)
/**
* Return pointer to given memory page. Skips the first 128 K (64 pages).
* Assumes memory can be mapped into linear address space (not AVR!)
*/
static INLINE void * _fs_pointer(const uint32_t page) {
return (void *)((FLASH_BASE + PAGE_SIZE * 64U) + page * PAGE_SIZE);
8: 5ce3 ldrb r3, [r4, r3]
/**
* Erase a page of memory.
*/
static void _fs_erase_page(uint32_t page) {
FLASH->CR = FLASH_CR_PER;
a: 2b01 cmp r3, #1
/**
* Return pointer to given memory page. Skips the first 128 K (64 pages).
* Assumes memory can be mapped into linear address space (not AVR!)
*/
static INLINE void * _fs_pointer(const uint32_t page) {
return (void *)((FLASH_BASE + PAGE_SIZE * 64U) + page * PAGE_SIZE);
c: d107 bne.n 1e <lookForFile+0x1e>
static void _fs_erase_page(uint32_t page) {
FLASH->CR = FLASH_CR_PER;
// Select page
FLASH->AR = (uint32_t)_fs_pointer(page);
// Start operation
FLASH->CR = FLASH_CR_PER | FLASH_CR_STRT;
e: 4909 ldr r1, [pc, #36] ; (34 <lookForFile+0x34>)
* Erase a page of memory.
*/
static void _fs_erase_page(uint32_t page) {
FLASH->CR = FLASH_CR_PER;
// Select page
FLASH->AR = (uint32_t)_fs_pointer(page);
10: 02e3 lsls r3, r4, #11
// Start operation
FLASH->CR = FLASH_CR_PER | FLASH_CR_STRT;
12: 4628 mov r0, r5
// Stall until BSY is reset (there is no sense sleeping here as IRQs cannot run while
// the erase is in progress)
while (FLASH->SR & FLASH_SR_BSY);
14: 4419 add r1, r3
16: 2208 movs r2, #8
18: f7ff fffe bl 0 <strncmp>
18: R_ARM_THM_CALL strncmp
// Verify erasure?
}
1c: b128 cbz r0, 2a <lookForFile+0x2a>
1e: 3401 adds r4, #1
/**
* Return pointer to given memory page. Skips the first 128 K (64 pages).
* Assumes memory can be mapped into linear address space (not AVR!)
*/
static INLINE void * _fs_pointer(const uint32_t page) {
return (void *)((FLASH_BASE + PAGE_SIZE * 64U) + page * PAGE_SIZE);
20: 2c80 cmp r4, #128 ; 0x80
22: d1f0 bne.n 6 <lookForFile+0x6>
/**
* Program a (half)word to memory.
*/
static void _fs_prgm_word(uint32_t page, uint32_t offs, uint16_t value) {
FLASH->CR = FLASH_CR_PG;
24: f04f 30ff mov.w r0, #4294967295 ; 0xffffffff
}
/**
* Program a (half)word to memory.
*/
static void _fs_prgm_word(uint32_t page, uint32_t offs, uint16_t value) {
28: bd38 pop {r3, r4, r5, pc}
FLASH->CR = FLASH_CR_PG;
// Ensure offs is even
//offs &= ~0x01;
// Select address by computing an offset from the desired page
uint8_t *addr = (uint8_t*)_fs_pointer(page) + offs;
*((uint16_t *)addr) = value;
2a: 4620 mov r0, r4
/**
* Program a (half)word to memory.
*/
static void _fs_prgm_word(uint32_t page, uint32_t offs, uint16_t value) {
FLASH->CR = FLASH_CR_PG;
2c: bd38 pop {r3, r4, r5, pc}
2e: bf00 nop
// Ensure offs is even
//offs &= ~0x01;
// Select address by computing an offset from the desired page
uint8_t *addr = (uint8_t*)_fs_pointer(page) + offs;
*((uint16_t *)addr) = value;
30: 00000000 andeq r0, r0, r0
30: R_ARM_ABS32 fs
// Stall until BSY is reset
while (FLASH->SR & FLASH_SR_BSY);
34: 08020008 stmdaeq r2, {r3}
Disassembly of section .text.fdelete:
00000000 <fdelete>:
/**
* Erase a page of memory.
*/
static void _fs_erase_page(uint32_t page) {
FLASH->CR = FLASH_CR_PER;
0: b5f8 push {r3, r4, r5, r6, r7, lr}
/**
* Return pointer to given memory page. Skips the first 128 K (64 pages).
* Assumes memory can be mapped into linear address space (not AVR!)
*/
static INLINE void * _fs_pointer(const uint32_t page) {
return (void *)((FLASH_BASE + PAGE_SIZE * 64U) + page * PAGE_SIZE);
2: f7ff fffe bl 0 <fdelete>
2: R_ARM_THM_CALL lookForFile
/**
* Erase a page of memory.
*/
static void _fs_erase_page(uint32_t page) {
FLASH->CR = FLASH_CR_PER;
6: b285 uxth r5, r0
/**
* Return pointer to given memory page. Skips the first 128 K (64 pages).
* Assumes memory can be mapped into linear address space (not AVR!)
*/
static INLINE void * _fs_pointer(const uint32_t page) {
return (void *)((FLASH_BASE + PAGE_SIZE * 64U) + page * PAGE_SIZE);
8: 2d7f cmp r5, #127 ; 0x7f
/**
* Erase a page of memory.
*/
static void _fs_erase_page(uint32_t page) {
FLASH->CR = FLASH_CR_PER;
a: d831 bhi.n 70 <fdelete+0x70>
/**
* Return pointer to given memory page. Skips the first 128 K (64 pages).
* Assumes memory can be mapped into linear address space (not AVR!)
*/
static INLINE void * _fs_pointer(const uint32_t page) {
return (void *)((FLASH_BASE + PAGE_SIZE * 64U) + page * PAGE_SIZE);
c: 2300 movs r3, #0
static void _fs_erase_page(uint32_t page) {
FLASH->CR = FLASH_CR_PER;
// Select page
FLASH->AR = (uint32_t)_fs_pointer(page);
// Start operation
FLASH->CR = FLASH_CR_PER | FLASH_CR_STRT;
e: 4e1a ldr r6, [pc, #104] ; (78 <fdelete+0x78>)
* Erase a page of memory.
*/
static void _fs_erase_page(uint32_t page) {
FLASH->CR = FLASH_CR_PER;
// Select page
FLASH->AR = (uint32_t)_fs_pointer(page);
10: 199a adds r2, r3, r6
// Start operation
FLASH->CR = FLASH_CR_PER | FLASH_CR_STRT;
12: f8b2 108a ldrh.w r1, [r2, #138] ; 0x8a
// Stall until BSY is reset (there is no sense sleeping here as IRQs cannot run while
// the erase is in progress)
while (FLASH->SR & FLASH_SR_BSY);
16: b119 cbz r1, 20 <fdelete+0x20>
18: f8b2 2088 ldrh.w r2, [r2, #136] ; 0x88
// Verify erasure?
}
1c: 42aa cmp r2, r5
1e: d027 beq.n 70 <fdelete+0x70>
/**
* Return pointer to given memory page. Skips the first 128 K (64 pages).
* Assumes memory can be mapped into linear address space (not AVR!)
*/
static INLINE void * _fs_pointer(const uint32_t page) {
return (void *)((FLASH_BASE + PAGE_SIZE * 64U) + page * PAGE_SIZE);
20: 330c adds r3, #12
22: 2b30 cmp r3, #48 ; 0x30
/**
* Program a (half)word to memory.
*/
static void _fs_prgm_word(uint32_t page, uint32_t offs, uint16_t value) {
FLASH->CR = FLASH_CR_PG;
24: d1f3 bne.n e <fdelete+0xe>
/**
* Return pointer to given memory page. Skips the first 128 K (64 pages).
* Assumes memory can be mapped into linear address space (not AVR!)
*/
static INLINE void * _fs_pointer(const uint32_t page) {
return (void *)((FLASH_BASE + PAGE_SIZE * 64U) + page * PAGE_SIZE);
26: f505 3380 add.w r3, r5, #65536 ; 0x10000
FLASH->CR = FLASH_CR_PG;
// Ensure offs is even
//offs &= ~0x01;
// Select address by computing an offset from the desired page
uint8_t *addr = (uint8_t*)_fs_pointer(page) + offs;
*((uint16_t *)addr) = value;
2a: 3340 adds r3, #64 ; 0x40
/**
* Program a (half)word to memory.
*/
static void _fs_prgm_word(uint32_t page, uint32_t offs, uint16_t value) {
FLASH->CR = FLASH_CR_PG;
2c: 02db lsls r3, r3, #11
2e: 889c ldrh r4, [r3, #4]
// Ensure offs is even
//offs &= ~0x01;
// Select address by computing an offset from the desired page
uint8_t *addr = (uint8_t*)_fs_pointer(page) + offs;
*((uint16_t *)addr) = value;
30: 4f12 ldr r7, [pc, #72] ; (7c <fdelete+0x7c>)
// Stall until BSY is reset
while (FLASH->SR & FLASH_SR_BSY);
32: 4b13 ldr r3, [pc, #76] ; (80 <fdelete+0x80>)
34: f24a 520a movw r2, #42250 ; 0xa50a
}
38: 607b str r3, [r7, #4]
3a: f103 3388 add.w r3, r3, #2290649224 ; 0x88888888
3e: 607b str r3, [r7, #4]
/*
* Looks for a file in the file system with the given name.
*
* @return the matching page number if a match is found, or UINT_MAX otherwise
*/
static uint32_t lookForFile(const char *name) {
40: 4628 mov r0, r5
42: 2102 movs r1, #2
uint32_t i;
for (i = 0; i < NUM_PAGES; i++) {
44: f7ff fffe bl 0 <fdelete>
44: R_ARM_THM_CALL _fs_prgm_word
uint8_t *page = (uint8_t *)_fs_pointer(i);
if (fs.page[i] == FLAG_FILE_PRESENT) {
48: 2380 movs r3, #128 ; 0x80
4a: 613b str r3, [r7, #16]
4c: 340f adds r4, #15
// The page has a file, not deleted, not a continuation
char *str = (char *)(&page[FILE_OFFSET_NAME]);
if (strncmp(name, str, MAX_LEN) == 0)
4e: 1c6b adds r3, r5, #1
50: f3c4 24cf ubfx r4, r4, #11, #16
54: b29b uxth r3, r3
56: 2204 movs r2, #4
58: 441c add r4, r3
5a: 5572 strb r2, [r6, r5]
5c: b2a4 uxth r4, r4
*
* @return the matching page number if a match is found, or UINT_MAX otherwise
*/
static uint32_t lookForFile(const char *name) {
uint32_t i;
for (i = 0; i < NUM_PAGES; i++) {
5e: 42a3 cmp r3, r4
60: d008 beq.n 74 <fdelete+0x74>
62: 2b80 cmp r3, #128 ; 0x80
// The file names match
return i;
}
}
// Return error code
return UINT_MAX;
64: d006 beq.n 74 <fdelete+0x74>
66: 1c5a adds r2, r3, #1
68: 2106 movs r1, #6
if (fs.page[i] == FLAG_FILE_PRESENT) {
// The page has a file, not deleted, not a continuation
char *str = (char *)(&page[FILE_OFFSET_NAME]);
if (strncmp(name, str, MAX_LEN) == 0)
// The file names match
return i;
6a: 54f1 strb r1, [r6, r3]
}
}
// Return error code
return UINT_MAX;
}
6c: b293 uxth r3, r2
6e: e7f6 b.n 5e <fdelete+0x5e>
70: 2001 movs r0, #1
72: bdf8 pop {r3, r4, r5, r6, r7, pc}
74: 2000 movs r0, #0
76: bdf8 pop {r3, r4, r5, r6, r7, pc}
* The file will actually be erased from memory on the next re-boot.
*
* @param file the file name to erase
* @return 0 if the file was deleted, or 1 if the file could not be found
*/
int fdelete(const char *file) {
78: 00000000 andeq r0, r0, r0
78: R_ARM_ABS32 fs
uint16_t len, page = lookForFile(file);
7c: 40022000 andmi r2, r2, r0
uint32_t i;
uint8_t *flash;
if (page < NUM_PAGES) {
80: 45670123 strbmi r0, [r7, #-291]! ; 0xfffffedd
Disassembly of section .text.fsEof:
00000000 <fsEof>:
/**
* Erase a page of memory.
*/
static void _fs_erase_page(uint32_t page) {
FLASH->CR = FLASH_CR_PER;
0: 3805 subs r0, #5
/**
* Return pointer to given memory page. Skips the first 128 K (64 pages).
* Assumes memory can be mapped into linear address space (not AVR!)
*/
static INLINE void * _fs_pointer(const uint32_t page) {
return (void *)((FLASH_BASE + PAGE_SIZE * 64U) + page * PAGE_SIZE);
2: 2803 cmp r0, #3
4: d810 bhi.n 28 <fsEof+0x28>
/**
* Erase a page of memory.
*/
static void _fs_erase_page(uint32_t page) {
FLASH->CR = FLASH_CR_PER;
6: 4b09 ldr r3, [pc, #36] ; (2c <fsEof+0x2c>)
/**
* Return pointer to given memory page. Skips the first 128 K (64 pages).
* Assumes memory can be mapped into linear address space (not AVR!)
*/
static INLINE void * _fs_pointer(const uint32_t page) {
return (void *)((FLASH_BASE + PAGE_SIZE * 64U) + page * PAGE_SIZE);
8: 220c movs r2, #12
/**
* Erase a page of memory.
*/
static void _fs_erase_page(uint32_t page) {
FLASH->CR = FLASH_CR_PER;
a: fb02 3300 mla r3, r2, r0, r3
// Select page
FLASH->AR = (uint32_t)_fs_pointer(page);
// Start operation
FLASH->CR = FLASH_CR_PER | FLASH_CR_STRT;
e: f8b3 208a ldrh.w r2, [r3, #138] ; 0x8a
12: 07d2 lsls r2, r2, #31
// Stall until BSY is reset (there is no sense sleeping here as IRQs cannot run while
// the erase is in progress)
while (FLASH->SR & FLASH_SR_BSY);
14: d508 bpl.n 28 <fsEof+0x28>
16: f8d3 0084 ldr.w r0, [r3, #132] ; 0x84
// Verify erasure?
}
1a: f8d3 2080 ldr.w r2, [r3, #128] ; 0x80
1e: 4282 cmp r2, r0
/**
* Return pointer to given memory page. Skips the first 128 K (64 pages).
* Assumes memory can be mapped into linear address space (not AVR!)
*/
static INLINE void * _fs_pointer(const uint32_t page) {
return (void *)((FLASH_BASE + PAGE_SIZE * 64U) + page * PAGE_SIZE);
20: bf34 ite cc
22: 2000 movcc r0, #0
/**
* Program a (half)word to memory.
*/
static void _fs_prgm_word(uint32_t page, uint32_t offs, uint16_t value) {
FLASH->CR = FLASH_CR_PG;
24: 2001 movcs r0, #1
/**
* Return pointer to given memory page. Skips the first 128 K (64 pages).
* Assumes memory can be mapped into linear address space (not AVR!)
*/
static INLINE void * _fs_pointer(const uint32_t page) {
return (void *)((FLASH_BASE + PAGE_SIZE * 64U) + page * PAGE_SIZE);
26: 4770 bx lr
}
/**
* Program a (half)word to memory.
*/
static void _fs_prgm_word(uint32_t page, uint32_t offs, uint16_t value) {
28: 2001 movs r0, #1
FLASH->CR = FLASH_CR_PG;
// Ensure offs is even
//offs &= ~0x01;
// Select address by computing an offset from the desired page
uint8_t *addr = (uint8_t*)_fs_pointer(page) + offs;
*((uint16_t *)addr) = value;
2a: 4770 bx lr
/**
* Program a (half)word to memory.
*/
static void _fs_prgm_word(uint32_t page, uint32_t offs, uint16_t value) {
FLASH->CR = FLASH_CR_PG;
2c: 00000000 andeq r0, r0, r0
2c: R_ARM_ABS32 fs
Disassembly of section .text.fflush:
00000000 <fflush>:
/**
* Erase a page of memory.
*/
static void _fs_erase_page(uint32_t page) {
FLASH->CR = FLASH_CR_PER;
0: e92d 47f0 stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, lr}
/**
* Return pointer to given memory page. Skips the first 128 K (64 pages).
* Assumes memory can be mapped into linear address space (not AVR!)
*/
static INLINE void * _fs_pointer(const uint32_t page) {
return (void *)((FLASH_BASE + PAGE_SIZE * 64U) + page * PAGE_SIZE);
4: f1a0 0805 sub.w r8, r0, #5
8: f1b8 0f03 cmp.w r8, #3
c: d859 bhi.n c2 <fflush+0xc2>
static void _fs_erase_page(uint32_t page) {
FLASH->CR = FLASH_CR_PER;
// Select page
FLASH->AR = (uint32_t)_fs_pointer(page);
// Start operation
FLASH->CR = FLASH_CR_PER | FLASH_CR_STRT;
e: 4b2f ldr r3, [pc, #188] ; (cc <fflush+0xcc>)
* Erase a page of memory.
*/
static void _fs_erase_page(uint32_t page) {
FLASH->CR = FLASH_CR_PER;
// Select page
FLASH->AR = (uint32_t)_fs_pointer(page);
10: 220c movs r2, #12
// Start operation
FLASH->CR = FLASH_CR_PER | FLASH_CR_STRT;
12: fb02 3208 mla r2, r2, r8, r3
// Stall until BSY is reset (there is no sense sleeping here as IRQs cannot run while
// the erase is in progress)
while (FLASH->SR & FLASH_SR_BSY);
16: f8b2 008a ldrh.w r0, [r2, #138] ; 0x8a
// Verify erasure?
}
1a: 461f mov r7, r3
1c: f010 0f02 tst.w r0, #2
/**
* Return pointer to given memory page. Skips the first 128 K (64 pages).
* Assumes memory can be mapped into linear address space (not AVR!)
*/
static INLINE void * _fs_pointer(const uint32_t page) {
return (void *)((FLASH_BASE + PAGE_SIZE * 64U) + page * PAGE_SIZE);
20: d049 beq.n b6 <fflush+0xb6>
22: f8d2 0080 ldr.w r0, [r2, #128] ; 0x80
26: f8b2 6088 ldrh.w r6, [r2, #136] ; 0x88
FLASH->CR = FLASH_CR_PG;
// Ensure offs is even
//offs &= ~0x01;
// Select address by computing an offset from the desired page
uint8_t *addr = (uint8_t*)_fs_pointer(page) + offs;
*((uint16_t *)addr) = value;
2a: f100 0510 add.w r5, r0, #16
/**
* Program a (half)word to memory.
*/
static void _fs_prgm_word(uint32_t page, uint32_t offs, uint16_t value) {
FLASH->CR = FLASH_CR_PG;
2e: 0aeb lsrs r3, r5, #11
// Ensure offs is even
//offs &= ~0x01;
// Select address by computing an offset from the desired page
uint8_t *addr = (uint8_t*)_fs_pointer(page) + offs;
*((uint16_t *)addr) = value;
30: f8d2 9084 ldr.w r9, [r2, #132] ; 0x84
// Stall until BSY is reset
while (FLASH->SR & FLASH_SR_BSY);
34: eba5 25c3 sub.w r5, r5, r3, lsl #11
}
38: 4a25 ldr r2, [pc, #148] ; (d0 <fflush+0xd0>)
3a: 441e add r6, r3
3c: 4b25 ldr r3, [pc, #148] ; (d4 <fflush+0xd4>)
3e: ebc0 0009 rsb r0, r0, r9
/*
* Looks for a file in the file system with the given name.
*
* @return the matching page number if a match is found, or UINT_MAX otherwise
*/
static uint32_t lookForFile(const char *name) {
42: 605a str r2, [r3, #4]
uint32_t i;
for (i = 0; i < NUM_PAGES; i++) {
44: f102 3288 add.w r2, r2, #2290649224 ; 0x88888888
uint8_t *page = (uint8_t *)_fs_pointer(i);
if (fs.page[i] == FLAG_FILE_PRESENT) {
48: f020 0401 bic.w r4, r0, #1
4c: 605a str r2, [r3, #4]
// The page has a file, not deleted, not a continuation
char *str = (char *)(&page[FILE_OFFSET_NAME]);
if (strncmp(name, str, MAX_LEN) == 0)
4e: f107 0ab0 add.w sl, r7, #176 ; 0xb0
52: b31c cbz r4, 9c <fflush+0x9c>
54: b9a5 cbnz r5, 80 <fflush+0x80>
56: 2e7f cmp r6, #127 ; 0x7f
58: d90c bls.n 74 <fflush+0x74>
5a: 230c movs r3, #12
5c: fb03 7308 mla r3, r3, r8, r7
*
* @return the matching page number if a match is found, or UINT_MAX otherwise
*/
static uint32_t lookForFile(const char *name) {
uint32_t i;
for (i = 0; i < NUM_PAGES; i++) {
60: ebc4 0009 rsb r0, r4, r9
// The file names match
return i;
}
}
// Return error code
return UINT_MAX;
64: f020 0001 bic.w r0, r0, #1
68: f8c3 0080 str.w r0, [r3, #128] ; 0x80
}
6c: 4b19 ldr r3, [pc, #100] ; (d4 <fflush+0xd4>)
6e: 2280 movs r2, #128 ; 0x80
70: 611a str r2, [r3, #16]
72: e026 b.n c2 <fflush+0xc2>
74: 5dbb ldrb r3, [r7, r6]
76: 2b00 cmp r3, #0
* The file will actually be erased from memory on the next re-boot.
*
* @param file the file name to erase
* @return 0 if the file was deleted, or 1 if the file could not be found
*/
int fdelete(const char *file) {
78: d1ef bne.n 5a <fflush+0x5a>
uint16_t len, page = lookForFile(file);
7a: 4b14 ldr r3, [pc, #80] ; (cc <fflush+0xcc>)
7c: 2203 movs r2, #3
7e: 559a strb r2, [r3, r6]
uint32_t i;
uint8_t *flash;
if (page < NUM_PAGES) {
80: 4630 mov r0, r6
82: 4629 mov r1, r5
84: f83a 2b02 ldrh.w r2, [sl], #2
88: 3502 adds r5, #2
// Already open?
for (i = 0; i < MAX_FILES; i++)
if (fs.files[i].flags != 0U && fs.files[i].page == page)
8a: f7ff fffe bl 0 <fflush>
8a: R_ARM_THM_CALL _fs_prgm_word
8e: f5b5 6f00 cmp.w r5, #2048 ; 0x800
92: bf24 itt cs
94: 3601 addcs r6, #1
96: 2500 movcs r5, #0
98: 3c02 subs r4, #2
uint16_t len, page = lookForFile(file);
uint32_t i;
uint8_t *flash;
if (page < NUM_PAGES) {
// Already open?
for (i = 0; i < MAX_FILES; i++)
9a: e7da b.n 52 <fflush+0x52>
9c: 4b0d ldr r3, [pc, #52] ; (d4 <fflush+0xd4>)
/**
* Return pointer to given memory page. Skips the first 128 K (64 pages).
* Assumes memory can be mapped into linear address space (not AVR!)
*/
static INLINE void * _fs_pointer(const uint32_t page) {
return (void *)((FLASH_BASE + PAGE_SIZE * 64U) + page * PAGE_SIZE);
9e: 2280 movs r2, #128 ; 0x80
a0: 611a str r2, [r3, #16]
a2: 230c movs r3, #12
for (i = 0; i < MAX_FILES; i++)
if (fs.files[i].flags != 0U && fs.files[i].page == page)
return 1;
// Found index, jump on it
flash = (uint8_t *)_fs_pointer(page);
len = (GET_UINT16(flash, FILE_OFFSET_LEN) + 15) / PAGE_SIZE;
a4: fb03 7308 mla r3, r3, r8, r7
/**
* Enable programming mode for the file system.
*/
static void _fs_prgm_on() {
FLASH->KEYR = 0x45670123;
a8: f029 0001 bic.w r0, r9, #1
// Found index, jump on it
flash = (uint8_t *)_fs_pointer(page);
len = (GET_UINT16(flash, FILE_OFFSET_LEN) + 15) / PAGE_SIZE;
_fs_prgm_on();
// Mark the pages as needing TRIM
_fs_prgm_word(page, FILE_OFFSET_STATUS, 0xA50A);
ac: f8c3 0080 str.w r0, [r3, #128] ; 0x80
/**
* Enable programming mode for the file system.
*/
static void _fs_prgm_on() {
FLASH->KEYR = 0x45670123;
b0: 4620 mov r0, r4
FLASH->KEYR = 0xCDEF89AB;
b2: e8bd 87f0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, sl, pc}
b6: f080 0001 eor.w r0, r0, #1
// Found index, jump on it
flash = (uint8_t *)_fs_pointer(page);
len = (GET_UINT16(flash, FILE_OFFSET_LEN) + 15) / PAGE_SIZE;
_fs_prgm_on();
// Mark the pages as needing TRIM
_fs_prgm_word(page, FILE_OFFSET_STATUS, 0xA50A);
ba: f340 0000 sbfx r0, r0, #0, #1
be: e8bd 87f0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, sl, pc}
/**
* Disable programming mode for the file system.
*/
static void _fs_prgm_off() {
FLASH->CR = FLASH_CR_LOCK;
c2: f04f 30ff mov.w r0, #4294967295 ; 0xffffffff
len = (GET_UINT16(flash, FILE_OFFSET_LEN) + 15) / PAGE_SIZE;
_fs_prgm_on();
// Mark the pages as needing TRIM
_fs_prgm_word(page, FILE_OFFSET_STATUS, 0xA50A);
_fs_prgm_off();
fs.page[page++] = FLAG_FILE_DELETED;
c6: e8bd 87f0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, sl, pc}
for (i = 0; i < MAX_FILES; i++)
if (fs.files[i].flags != 0U && fs.files[i].page == page)
return 1;
// Found index, jump on it
flash = (uint8_t *)_fs_pointer(page);
len = (GET_UINT16(flash, FILE_OFFSET_LEN) + 15) / PAGE_SIZE;
ca: bf00 nop
_fs_prgm_on();
// Mark the pages as needing TRIM
_fs_prgm_word(page, FILE_OFFSET_STATUS, 0xA50A);
_fs_prgm_off();
fs.page[page++] = FLAG_FILE_DELETED;
cc: 00000000 andeq r0, r0, r0
cc: R_ARM_ABS32 fs
d0: 45670123 strbmi r0, [r7, #-291]! ; 0xfffffedd
d4: 40022000 andmi r2, r2, r0
Disassembly of section .text.fsLeft:
00000000 <fsLeft>:
/**
* Erase a page of memory.
*/
static void _fs_erase_page(uint32_t page) {
FLASH->CR = FLASH_CR_PER;
0: 3805 subs r0, #5
/**
* Return pointer to given memory page. Skips the first 128 K (64 pages).
* Assumes memory can be mapped into linear address space (not AVR!)
*/
static INLINE void * _fs_pointer(const uint32_t page) {
return (void *)((FLASH_BASE + PAGE_SIZE * 64U) + page * PAGE_SIZE);
2: 2803 cmp r0, #3
4: d80e bhi.n 24 <fsLeft+0x24>
/**
* Erase a page of memory.
*/
static void _fs_erase_page(uint32_t page) {
FLASH->CR = FLASH_CR_PER;
6: 4b08 ldr r3, [pc, #32] ; (28 <fsLeft+0x28>)
/**
* Return pointer to given memory page. Skips the first 128 K (64 pages).
* Assumes memory can be mapped into linear address space (not AVR!)
*/
static INLINE void * _fs_pointer(const uint32_t page) {
return (void *)((FLASH_BASE + PAGE_SIZE * 64U) + page * PAGE_SIZE);
8: 220c movs r2, #12
/**
* Erase a page of memory.
*/
static void _fs_erase_page(uint32_t page) {
FLASH->CR = FLASH_CR_PER;
a: fb02 3200 mla r2, r2, r0, r3
// Select page
FLASH->AR = (uint32_t)_fs_pointer(page);
// Start operation
FLASH->CR = FLASH_CR_PER | FLASH_CR_STRT;
e: f8b2 008a ldrh.w r0, [r2, #138] ; 0x8a
12: f010 0001 ands.w r0, r0, #1
// Stall until BSY is reset (there is no sense sleeping here as IRQs cannot run while
// the erase is in progress)
while (FLASH->SR & FLASH_SR_BSY);
16: d006 beq.n 26 <fsLeft+0x26>
18: f8d2 3084 ldr.w r3, [r2, #132] ; 0x84
// Verify erasure?
}
1c: f8d2 0080 ldr.w r0, [r2, #128] ; 0x80
/**
* Return pointer to given memory page. Skips the first 128 K (64 pages).
* Assumes memory can be mapped into linear address space (not AVR!)
*/
static INLINE void * _fs_pointer(const uint32_t page) {
return (void *)((FLASH_BASE + PAGE_SIZE * 64U) + page * PAGE_SIZE);
20: 1a18 subs r0, r3, r0
22: 4770 bx lr
/**
* Program a (half)word to memory.
*/
static void _fs_prgm_word(uint32_t page, uint32_t offs, uint16_t value) {
FLASH->CR = FLASH_CR_PG;
24: 2000 movs r0, #0
/**
* Return pointer to given memory page. Skips the first 128 K (64 pages).
* Assumes memory can be mapped into linear address space (not AVR!)
*/
static INLINE void * _fs_pointer(const uint32_t page) {
return (void *)((FLASH_BASE + PAGE_SIZE * 64U) + page * PAGE_SIZE);
26: 4770 bx lr
}
/**
* Program a (half)word to memory.
*/
static void _fs_prgm_word(uint32_t page, uint32_t offs, uint16_t value) {
28: 00000000 andeq r0, r0, r0
28: R_ARM_ABS32 fs
Disassembly of section .text.fopen:
00000000 <fopen>:
/**
* Erase a page of memory.
*/
static void _fs_erase_page(uint32_t page) {
FLASH->CR = FLASH_CR_PER;
0: b573 push {r0, r1, r4, r5, r6, lr}
/**
* Return pointer to given memory page. Skips the first 128 K (64 pages).
* Assumes memory can be mapped into linear address space (not AVR!)
*/
static INLINE void * _fs_pointer(const uint32_t page) {
return (void *)((FLASH_BASE + PAGE_SIZE * 64U) + page * PAGE_SIZE);
2: 4606 mov r6, r0
4: 460d mov r5, r1
/**
* Erase a page of memory.
*/
static void _fs_erase_page(uint32_t page) {
FLASH->CR = FLASH_CR_PER;
6: 4608 mov r0, r1
/**
* Return pointer to given memory page. Skips the first 128 K (64 pages).
* Assumes memory can be mapped into linear address space (not AVR!)
*/
static INLINE void * _fs_pointer(const uint32_t page) {
return (void *)((FLASH_BASE + PAGE_SIZE * 64U) + page * PAGE_SIZE);
8: 4945 ldr r1, [pc, #276] ; (120 <fopen+0x120>)
/**
* Erase a page of memory.
*/
static void _fs_erase_page(uint32_t page) {
FLASH->CR = FLASH_CR_PER;
a: f7ff fffe bl 0 <strcmp>
a: R_ARM_THM_CALL strcmp
// Select page
FLASH->AR = (uint32_t)_fs_pointer(page);
// Start operation
FLASH->CR = FLASH_CR_PER | FLASH_CR_STRT;
e: 4604 mov r4, r0
* Erase a page of memory.
*/
static void _fs_erase_page(uint32_t page) {
FLASH->CR = FLASH_CR_PER;
// Select page
FLASH->AR = (uint32_t)_fs_pointer(page);
10: bb00 cbnz r0, 54 <fopen+0x54>
// Start operation
FLASH->CR = FLASH_CR_PER | FLASH_CR_STRT;
12: 4630 mov r0, r6
// Stall until BSY is reset (there is no sense sleeping here as IRQs cannot run while
// the erase is in progress)
while (FLASH->SR & FLASH_SR_BSY);
14: f7ff fffe bl 0 <fopen>
14: R_ARM_THM_CALL lookForFile
18: 287f cmp r0, #127 ; 0x7f
// Verify erasure?
}
1a: d901 bls.n 20 <fopen+0x20>
1c: 2000 movs r0, #0
1e: e07c b.n 11a <fopen+0x11a>
/**
* Return pointer to given memory page. Skips the first 128 K (64 pages).
* Assumes memory can be mapped into linear address space (not AVR!)
*/
static INLINE void * _fs_pointer(const uint32_t page) {
return (void *)((FLASH_BASE + PAGE_SIZE * 64U) + page * PAGE_SIZE);
20: f500 3380 add.w r3, r0, #65536 ; 0x10000
/**
* Program a (half)word to memory.
*/
static void _fs_prgm_word(uint32_t page, uint32_t offs, uint16_t value) {
FLASH->CR = FLASH_CR_PG;
24: 3340 adds r3, #64 ; 0x40
/**
* Return pointer to given memory page. Skips the first 128 K (64 pages).
* Assumes memory can be mapped into linear address space (not AVR!)
*/
static INLINE void * _fs_pointer(const uint32_t page) {
return (void *)((FLASH_BASE + PAGE_SIZE * 64U) + page * PAGE_SIZE);
26: 02db lsls r3, r3, #11
}
/**
* Program a (half)word to memory.
*/
static void _fs_prgm_word(uint32_t page, uint32_t offs, uint16_t value) {
28: 6859 ldr r1, [r3, #4]
FLASH->CR = FLASH_CR_PG;
// Ensure offs is even
//offs &= ~0x01;
// Select address by computing an offset from the desired page
uint8_t *addr = (uint8_t*)_fs_pointer(page) + offs;
*((uint16_t *)addr) = value;
2a: 4a3e ldr r2, [pc, #248] ; (124 <fopen+0x124>)
/**
* Program a (half)word to memory.
*/
static void _fs_prgm_word(uint32_t page, uint32_t offs, uint16_t value) {
FLASH->CR = FLASH_CR_PG;
2c: 230c movs r3, #12
2e: fb03 2304 mla r3, r3, r4, r2
//offs &= ~0x01;
// Select address by computing an offset from the desired page
uint8_t *addr = (uint8_t*)_fs_pointer(page) + offs;
*((uint16_t *)addr) = value;
// Stall until BSY is reset
while (FLASH->SR & FLASH_SR_BSY);
32: f8b3 208a ldrh.w r2, [r3, #138] ; 0x8a
36: b94a cbnz r2, 4c <fopen+0x4c>
}
38: 2501 movs r5, #1
3a: f8a3 508a strh.w r5, [r3, #138] ; 0x8a
3e: f8c3 1084 str.w r1, [r3, #132] ; 0x84
/*
* Looks for a file in the file system with the given name.
*
* @return the matching page number if a match is found, or UINT_MAX otherwise
*/
static uint32_t lookForFile(const char *name) {
42: f8c3 2080 str.w r2, [r3, #128] ; 0x80
uint32_t i;
for (i = 0; i < NUM_PAGES; i++) {
uint8_t *page = (uint8_t *)_fs_pointer(i);
if (fs.page[i] == FLAG_FILE_PRESENT) {
46: f8a3 0088 strh.w r0, [r3, #136] ; 0x88
4a: e05e b.n 10a <fopen+0x10a>
4c: 3401 adds r4, #1
// The page has a file, not deleted, not a continuation
char *str = (char *)(&page[FILE_OFFSET_NAME]);
if (strncmp(name, str, MAX_LEN) == 0)
4e: 2c04 cmp r4, #4
50: d1eb bne.n 2a <fopen+0x2a>
52: e7e3 b.n 1c <fopen+0x1c>
54: 4628 mov r0, r5
56: 4934 ldr r1, [pc, #208] ; (128 <fopen+0x128>)
58: f7ff fffe bl 0 <strcmp>
58: R_ARM_THM_CALL strcmp
5c: 4605 mov r5, r0
*
* @return the matching page number if a match is found, or UINT_MAX otherwise
*/
static uint32_t lookForFile(const char *name) {
uint32_t i;
for (i = 0; i < NUM_PAGES; i++) {
5e: 2800 cmp r0, #0
60: d1dc bne.n 1c <fopen+0x1c>
62: 4630 mov r0, r6
// The file names match
return i;
}
}
// Return error code
return UINT_MAX;
64: f7ff fffe bl 0 <fopen>
64: R_ARM_THM_CALL fdelete
68: 462c mov r4, r5
if (fs.page[i] == FLAG_FILE_PRESENT) {
// The page has a file, not deleted, not a continuation
char *str = (char *)(&page[FILE_OFFSET_NAME]);
if (strncmp(name, str, MAX_LEN) == 0)
// The file names match
return i;
6a: 462a mov r2, r5
}
}
// Return error code
return UINT_MAX;
}
6c: 462b mov r3, r5
6e: 492d ldr r1, [pc, #180] ; (124 <fopen+0x124>)
70: 5c58 ldrb r0, [r3, r1]
72: b948 cbnz r0, 88 <fopen+0x88>
74: 2b7f cmp r3, #127 ; 0x7f
76: f102 0001 add.w r0, r2, #1
*
* @param file the file name to erase
* @return 0 if the file was deleted, or 1 if the file could not be found
*/
int fdelete(const char *file) {
uint16_t len, page = lookForFile(file);
7a: d10a bne.n 92 <fopen+0x92>
7c: 42a0 cmp r0, r4
7e: d908 bls.n 92 <fopen+0x92>
uint32_t i;
uint8_t *flash;
if (page < NUM_PAGES) {
80: f1c2 057f rsb r5, r2, #127 ; 0x7f
84: 4604 mov r4, r0
86: e004 b.n 92 <fopen+0x92>
88: 42a2 cmp r2, r4
// Already open?
for (i = 0; i < MAX_FILES; i++)
if (fs.files[i].flags != 0U && fs.files[i].page == page)
8a: bf84 itt hi
8c: 4614 movhi r4, r2
8e: 1a9d subhi r5, r3, r2
90: 2000 movs r0, #0
92: 3301 adds r3, #1
94: 2b80 cmp r3, #128 ; 0x80
96: d001 beq.n 9c <fopen+0x9c>
98: 4602 mov r2, r0
uint16_t len, page = lookForFile(file);
uint32_t i;
uint8_t *flash;
if (page < NUM_PAGES) {
// Already open?
for (i = 0; i < MAX_FILES; i++)
9a: e7e8 b.n 6e <fopen+0x6e>
9c: 5d4c ldrb r4, [r1, r5]
/**
* Return pointer to given memory page. Skips the first 128 K (64 pages).
* Assumes memory can be mapped into linear address space (not AVR!)
*/
static INLINE void * _fs_pointer(const uint32_t page) {
return (void *)((FLASH_BASE + PAGE_SIZE * 64U) + page * PAGE_SIZE);
9e: 2c00 cmp r4, #0
a0: d1bc bne.n 1c <fopen+0x1c>
a2: 220c movs r2, #12
for (i = 0; i < MAX_FILES; i++)
if (fs.files[i].flags != 0U && fs.files[i].page == page)
return 1;
// Found index, jump on it
flash = (uint8_t *)_fs_pointer(page);
len = (GET_UINT16(flash, FILE_OFFSET_LEN) + 15) / PAGE_SIZE;
a4: fb02 1204 mla r2, r2, r4, r1
/**
* Enable programming mode for the file system.
*/
static void _fs_prgm_on() {
FLASH->KEYR = 0x45670123;
a8: f8b2 308a ldrh.w r3, [r2, #138] ; 0x8a
// Found index, jump on it
flash = (uint8_t *)_fs_pointer(page);
len = (GET_UINT16(flash, FILE_OFFSET_LEN) + 15) / PAGE_SIZE;
_fs_prgm_on();
// Mark the pages as needing TRIM
_fs_prgm_word(page, FILE_OFFSET_STATUS, 0xA50A);
ac: bb7b cbnz r3, 10e <fopen+0x10e>
ae: 2102 movs r1, #2
/**
* Enable programming mode for the file system.
*/
static void _fs_prgm_on() {
FLASH->KEYR = 0x45670123;
b0: f8a2 108a strh.w r1, [r2, #138] ; 0x8a
FLASH->KEYR = 0xCDEF89AB;
b4: f8c2 3084 str.w r3, [r2, #132] ; 0x84
// Found index, jump on it
flash = (uint8_t *)_fs_pointer(page);
len = (GET_UINT16(flash, FILE_OFFSET_LEN) + 15) / PAGE_SIZE;
_fs_prgm_on();
// Mark the pages as needing TRIM
_fs_prgm_word(page, FILE_OFFSET_STATUS, 0xA50A);
b8: f8c2 3080 str.w r3, [r2, #128] ; 0x80
bc: f8a2 5088 strh.w r5, [r2, #136] ; 0x88
/**
* Disable programming mode for the file system.
*/
static void _fs_prgm_off() {
FLASH->CR = FLASH_CR_LOCK;
c0: 4a18 ldr r2, [pc, #96] ; (124 <fopen+0x124>)
c2: 2101 movs r1, #1
for (i = 0; i < MAX_FILES; i++)
if (fs.files[i].flags != 0U && fs.files[i].page == page)
return 1;
// Found index, jump on it
flash = (uint8_t *)_fs_pointer(page);
len = (GET_UINT16(flash, FILE_OFFSET_LEN) + 15) / PAGE_SIZE;
c4: 5551 strb r1, [r2, r5]
_fs_prgm_on();
// Mark the pages as needing TRIM
_fs_prgm_word(page, FILE_OFFSET_STATUS, 0xA50A);
_fs_prgm_off();
fs.page[page++] = FLAG_FILE_DELETED;
c6: 7832 ldrb r2, [r6, #0]
for (i = 0; i < MAX_FILES; i++)
if (fs.files[i].flags != 0U && fs.files[i].page == page)
return 1;
// Found index, jump on it
flash = (uint8_t *)_fs_pointer(page);
len = (GET_UINT16(flash, FILE_OFFSET_LEN) + 15) / PAGE_SIZE;
c8: f80d 2003 strb.w r2, [sp, r3]
_fs_prgm_on();
// Mark the pages as needing TRIM
_fs_prgm_word(page, FILE_OFFSET_STATUS, 0xA50A);
_fs_prgm_off();
fs.page[page++] = FLAG_FILE_DELETED;
cc: b102 cbz r2, d0 <fopen+0xd0>
ce: 3601 adds r6, #1
d0: 3301 adds r3, #1
d2: 2b08 cmp r3, #8
d4: d1f7 bne.n c6 <fopen+0xc6>
for (; len && page < NUM_PAGES; len--) {
d6: 4b15 ldr r3, [pc, #84] ; (12c <fopen+0x12c>)
d8: 4a15 ldr r2, [pc, #84] ; (130 <fopen+0x130>)
da: 4628 mov r0, r5
dc: 605a str r2, [r3, #4]
// Mark the rest of the file invalid for this run
fs.page[page++] = FLAG_FILE_DELETED | FLAG_FILE_CONTINUE;
de: f102 3288 add.w r2, r2, #2290649224 ; 0x88888888
e2: 605a str r2, [r3, #4]
e4: 2100 movs r1, #0
e6: f64d 62de movw r2, #57054 ; 0xdede
}
return 0;
}
return 1;
ea: f7ff fffe bl 0 <fopen>
ea: R_ARM_THM_CALL _fs_prgm_word
}
ee: 2600 movs r6, #0
f0: 0071 lsls r1, r6, #1
f2: f83d 2016 ldrh.w r2, [sp, r6, lsl #1]
f6: 4628 mov r0, r5
f8: 3108 adds r1, #8
fa: 3601 adds r6, #1
*
* @param fd the channel to check
* @return 0 if the file is not at EOF, or 1 otherwise.
*/
int fsEof(FILE *fd) {
uint32_t idx = (uint32_t)fd - FILE_CHANNEL_1;
fc: f7ff fffe bl 0 <fopen>
fc: R_ARM_THM_CALL _fs_prgm_word
if (idx < MAX_FILES) {
100: 2e04 cmp r6, #4
// Index in bounds
uint16_t flags = fs.files[idx].flags;
102: d1f5 bne.n f0 <fopen+0xf0>
104: 4b09 ldr r3, [pc, #36] ; (12c <fopen+0x12c>)
106: 2280 movs r2, #128 ; 0x80
108: 611a str r2, [r3, #16]
if (flags & FILE_FLAG_RD)
10a: 1d60 adds r0, r4, #5
10c: e005 b.n 11a <fopen+0x11a>
10e: 079b lsls r3, r3, #30
110: d484 bmi.n 1c <fopen+0x1c>
return (fs.files[idx].offset >= fs.files[idx].len) ? 1 : 0;
112: 3401 adds r4, #1
114: 2c04 cmp r4, #4
116: d1c4 bne.n a2 <fopen+0xa2>
118: e780 b.n 1c <fopen+0x1c>
11a: b002 add sp, #8
11c: bd70 pop {r4, r5, r6, pc}
11e: bf00 nop
...
120: R_ARM_ABS32 .rodata.str1.1
124: R_ARM_ABS32 fs
// Else, can't determine
}
return 1;
}
128: 00000002 andeq r0, r0, r2
128: R_ARM_ABS32 .rodata.str1.1
*
* @param fd the channel to flush
* @return 0 if the data was successfully written out to Flash, EOF otherwise
* The file data is still invalid until properly closed!
*/
int fflush(FILE *fd) {
12c: 40022000 andmi r2, r2, r0
uint32_t idx = (uint32_t)fd - FILE_CHANNEL_1;
130: 45670123 strbmi r0, [r7, #-291]! ; 0xfffffedd
Disassembly of section .text.fsRead:
00000000 <fsRead>:
/**
* Erase a page of memory.
*/
static void _fs_erase_page(uint32_t page) {
FLASH->CR = FLASH_CR_PER;
0: 1f43 subs r3, r0, #5
/**
* Return pointer to given memory page. Skips the first 128 K (64 pages).
* Assumes memory can be mapped into linear address space (not AVR!)
*/
static INLINE void * _fs_pointer(const uint32_t page) {
return (void *)((FLASH_BASE + PAGE_SIZE * 64U) + page * PAGE_SIZE);
2: 2b03 cmp r3, #3
4: d81e bhi.n 44 <fsRead+0x44>
/**
* Erase a page of memory.
*/
static void _fs_erase_page(uint32_t page) {
FLASH->CR = FLASH_CR_PER;
6: 4a11 ldr r2, [pc, #68] ; (4c <fsRead+0x4c>)
/**
* Return pointer to given memory page. Skips the first 128 K (64 pages).
* Assumes memory can be mapped into linear address space (not AVR!)
*/
static INLINE void * _fs_pointer(const uint32_t page) {
return (void *)((FLASH_BASE + PAGE_SIZE * 64U) + page * PAGE_SIZE);
8: 200c movs r0, #12
/**
* Erase a page of memory.
*/
static void _fs_erase_page(uint32_t page) {
FLASH->CR = FLASH_CR_PER;
a: fb00 2003 mla r0, r0, r3, r2
// Select page
FLASH->AR = (uint32_t)_fs_pointer(page);
// Start operation
FLASH->CR = FLASH_CR_PER | FLASH_CR_STRT;
e: f8b0 308a ldrh.w r3, [r0, #138] ; 0x8a
12: 07db lsls r3, r3, #31
// Stall until BSY is reset (there is no sense sleeping here as IRQs cannot run while
// the erase is in progress)
while (FLASH->SR & FLASH_SR_BSY);
14: d516 bpl.n 44 <fsRead+0x44>
16: f8d0 3080 ldr.w r3, [r0, #128] ; 0x80
// Verify erasure?
}
1a: f8d0 2084 ldr.w r2, [r0, #132] ; 0x84
1e: 4293 cmp r3, r2
/**
* Return pointer to given memory page. Skips the first 128 K (64 pages).
* Assumes memory can be mapped into linear address space (not AVR!)
*/
static INLINE void * _fs_pointer(const uint32_t page) {
return (void *)((FLASH_BASE + PAGE_SIZE * 64U) + page * PAGE_SIZE);
20: d210 bcs.n 44 <fsRead+0x44>
22: f103 0210 add.w r2, r3, #16
26: 3301 adds r3, #1
}
/**
* Program a (half)word to memory.
*/
static void _fs_prgm_word(uint32_t page, uint32_t offs, uint16_t value) {
28: f8c0 3080 str.w r3, [r0, #128] ; 0x80
FLASH->CR = FLASH_CR_PG;
2c: f8b0 3088 ldrh.w r3, [r0, #136] ; 0x88
// Ensure offs is even
//offs &= ~0x01;
// Select address by computing an offset from the desired page
uint8_t *addr = (uint8_t*)_fs_pointer(page) + offs;
*((uint16_t *)addr) = value;
30: 0ad1 lsrs r1, r2, #11
// Stall until BSY is reset
while (FLASH->SR & FLASH_SR_BSY);
32: 440b add r3, r1
34: f503 3380 add.w r3, r3, #65536 ; 0x10000
}
38: 3340 adds r3, #64 ; 0x40
3a: eba2 22c1 sub.w r2, r2, r1, lsl #11
3e: 02db lsls r3, r3, #11
/*
* Looks for a file in the file system with the given name.
*
* @return the matching page number if a match is found, or UINT_MAX otherwise
*/
static uint32_t lookForFile(const char *name) {
40: 5c98 ldrb r0, [r3, r2]
42: 4770 bx lr
uint32_t i;
for (i = 0; i < NUM_PAGES; i++) {
44: f04f 30ff mov.w r0, #4294967295 ; 0xffffffff
uint8_t *page = (uint8_t *)_fs_pointer(i);
if (fs.page[i] == FLAG_FILE_PRESENT) {
48: 4770 bx lr
4a: bf00 nop
4c: 00000000 andeq r0, r0, r0
4c: R_ARM_ABS32 fs
Disassembly of section .text.fsScan:
00000000 <fsScan>:
/**
* Erase a page of memory.
*/
static void _fs_erase_page(uint32_t page) {
FLASH->CR = FLASH_CR_PER;
0: e92d 41f0 stmdb sp!, {r4, r5, r6, r7, r8, lr}
/**
* Return pointer to given memory page. Skips the first 128 K (64 pages).
* Assumes memory can be mapped into linear address space (not AVR!)
*/
static INLINE void * _fs_pointer(const uint32_t page) {
return (void *)((FLASH_BASE + PAGE_SIZE * 64U) + page * PAGE_SIZE);
4: 4607 mov r7, r0
/**
* Erase a page of memory.
*/
static void _fs_erase_page(uint32_t page) {
FLASH->CR = FLASH_CR_PER;
6: 2400 movs r4, #0
/**
* Return pointer to given memory page. Skips the first 128 K (64 pages).
* Assumes memory can be mapped into linear address space (not AVR!)
*/
static INLINE void * _fs_pointer(const uint32_t page) {
return (void *)((FLASH_BASE + PAGE_SIZE * 64U) + page * PAGE_SIZE);
8: f64d 61de movw r1, #57054 ; 0xdede
c: f504 3380 add.w r3, r4, #65536 ; 0x10000
* Erase a page of memory.
*/
static void _fs_erase_page(uint32_t page) {
FLASH->CR = FLASH_CR_PER;
// Select page
FLASH->AR = (uint32_t)_fs_pointer(page);
10: 3340 adds r3, #64 ; 0x40
// Start operation
FLASH->CR = FLASH_CR_PER | FLASH_CR_STRT;
12: 02db lsls r3, r3, #11
// Stall until BSY is reset (there is no sense sleeping here as IRQs cannot run while
// the erase is in progress)
while (FLASH->SR & FLASH_SR_BSY);
14: 881a ldrh r2, [r3, #0]
16: 685e ldr r6, [r3, #4]
18: 428a cmp r2, r1
// Verify erasure?
}
1a: f8df 80ac ldr.w r8, [pc, #172] ; c8 <fsScan+0xc8>
1e: d132 bne.n 86 <fsScan+0x86>
/**
* Return pointer to given memory page. Skips the first 128 K (64 pages).
* Assumes memory can be mapped into linear address space (not AVR!)
*/
static INLINE void * _fs_pointer(const uint32_t page) {
return (void *)((FLASH_BASE + PAGE_SIZE * 64U) + page * PAGE_SIZE);
20: f5b6 2f80 cmp.w r6, #262144 ; 0x40000
/**
* Program a (half)word to memory.
*/
static void _fs_prgm_word(uint32_t page, uint32_t offs, uint16_t value) {
FLASH->CR = FLASH_CR_PG;
24: 885a ldrh r2, [r3, #2]
/**
* Return pointer to given memory page. Skips the first 128 K (64 pages).
* Assumes memory can be mapped into linear address space (not AVR!)
*/
static INLINE void * _fs_pointer(const uint32_t page) {
return (void *)((FLASH_BASE + PAGE_SIZE * 64U) + page * PAGE_SIZE);
26: d208 bcs.n 3a <fsScan+0x3a>
}
/**
* Program a (half)word to memory.
*/
static void _fs_prgm_word(uint32_t page, uint32_t offs, uint16_t value) {
28: f64f 73ff movw r3, #65535 ; 0xffff
FLASH->CR = FLASH_CR_PG;
2c: 429a cmp r2, r3
2e: d105 bne.n 3c <fsScan+0x3c>
// Ensure offs is even
//offs &= ~0x01;
// Select address by computing an offset from the desired page
uint8_t *addr = (uint8_t*)_fs_pointer(page) + offs;
*((uint16_t *)addr) = value;
30: 2301 movs r3, #1
// Stall until BSY is reset
while (FLASH->SR & FLASH_SR_BSY);
32: f808 3004 strb.w r3, [r8, r4]
36: 2503 movs r5, #3
}
38: e011 b.n 5e <fsScan+0x5e>
3a: 2601 movs r6, #1
3c: b91f cbnz r7, 46 <fsScan+0x46>
3e: 2508 movs r5, #8
/*
* Looks for a file in the file system with the given name.
*
* @return the matching page number if a match is found, or UINT_MAX otherwise
*/
static uint32_t lookForFile(const char *name) {
40: f808 5004 strb.w r5, [r8, r4]
uint32_t i;
for (i = 0; i < NUM_PAGES; i++) {
44: e00b b.n 5e <fsScan+0x5e>
uint8_t *page = (uint8_t *)_fs_pointer(i);
if (fs.page[i] == FLAG_FILE_PRESENT) {
46: 4b1e ldr r3, [pc, #120] ; (c0 <fsScan+0xc0>)
48: 4a1e ldr r2, [pc, #120] ; (c4 <fsScan+0xc4>)
4a: 2500 movs r5, #0
4c: f808 5004 strb.w r5, [r8, r4]
// The page has a file, not deleted, not a continuation
char *str = (char *)(&page[FILE_OFFSET_NAME]);
if (strncmp(name, str, MAX_LEN) == 0)
50: 605a str r2, [r3, #4]
52: f102 3288 add.w r2, r2, #2290649224 ; 0x88888888
56: 605a str r2, [r3, #4]
58: 4620 mov r0, r4
5a: f7ff fffe bl 0 <fsScan>
5a: R_ARM_THM_CALL _fs_erase_page
*
* @return the matching page number if a match is found, or UINT_MAX otherwise
*/
static uint32_t lookForFile(const char *name) {
uint32_t i;
for (i = 0; i < NUM_PAGES; i++) {
5e: 360f adds r6, #15
60: eb04 26d6 add.w r6, r4, r6, lsr #11
// The file names match
return i;
}
}
// Return error code
return UINT_MAX;
64: 42b4 cmp r4, r6
66: d009 beq.n 7c <fsScan+0x7c>
68: 3401 adds r4, #1
if (fs.page[i] == FLAG_FILE_PRESENT) {
// The page has a file, not deleted, not a continuation
char *str = (char *)(&page[FILE_OFFSET_NAME]);
if (strncmp(name, str, MAX_LEN) == 0)
// The file names match
return i;
6a: b915 cbnz r5, 72 <fsScan+0x72>
}
}
// Return error code
return UINT_MAX;
}
6c: 4620 mov r0, r4
6e: f7ff fffe bl 0 <fsScan>
6e: R_ARM_THM_CALL _fs_erase_page
72: 2c80 cmp r4, #128 ; 0x80
74: f808 5004 strb.w r5, [r8, r4]
* The file will actually be erased from memory on the next re-boot.
*
* @param file the file name to erase
* @return 0 if the file was deleted, or 1 if the file could not be found
*/
int fdelete(const char *file) {
78: d1f4 bne.n 64 <fsScan+0x64>
uint16_t len, page = lookForFile(file);
7a: e01e b.n ba <fsScan+0xba>
7c: b97d cbnz r5, 9e <fsScan+0x9e>
7e: 4b10 ldr r3, [pc, #64] ; (c0 <fsScan+0xc0>)
uint32_t i;
uint8_t *flash;
if (page < NUM_PAGES) {
80: 2280 movs r2, #128 ; 0x80
82: 611a str r2, [r3, #16]
84: e00a b.n 9c <fsScan+0x9c>
86: f64f 73ff movw r3, #65535 ; 0xffff
// Already open?
for (i = 0; i < MAX_FILES; i++)
if (fs.files[i].flags != 0U && fs.files[i].page == page)
8a: 429a cmp r2, r3
8c: d103 bne.n 96 <fsScan+0x96>
8e: 3601 adds r6, #1
90: d101 bne.n 96 <fsScan+0x96>
92: 2300 movs r3, #0
94: e000 b.n 98 <fsScan+0x98>
96: 2308 movs r3, #8
98: f808 3004 strb.w r3, [r8, r4]
uint16_t len, page = lookForFile(file);
uint32_t i;
uint8_t *flash;
if (page < NUM_PAGES) {
// Already open?
for (i = 0; i < MAX_FILES; i++)
9c: 4626 mov r6, r4
/**
* Return pointer to given memory page. Skips the first 128 K (64 pages).
* Assumes memory can be mapped into linear address space (not AVR!)
*/
static INLINE void * _fs_pointer(const uint32_t page) {
return (void *)((FLASH_BASE + PAGE_SIZE * 64U) + page * PAGE_SIZE);
9e: 1c74 adds r4, r6, #1
a0: 2c7f cmp r4, #127 ; 0x7f
a2: d9b1 bls.n 8 <fsScan+0x8>
for (i = 0; i < MAX_FILES; i++)
if (fs.files[i].flags != 0U && fs.files[i].page == page)
return 1;
// Found index, jump on it
flash = (uint8_t *)_fs_pointer(page);
len = (GET_UINT16(flash, FILE_OFFSET_LEN) + 15) / PAGE_SIZE;
a4: 2300 movs r3, #0
a6: f8a8 308a strh.w r3, [r8, #138] ; 0x8a
/**
* Enable programming mode for the file system.
*/
static void _fs_prgm_on() {
FLASH->KEYR = 0x45670123;
aa: f8a8 3096 strh.w r3, [r8, #150] ; 0x96
// Found index, jump on it
flash = (uint8_t *)_fs_pointer(page);
len = (GET_UINT16(flash, FILE_OFFSET_LEN) + 15) / PAGE_SIZE;
_fs_prgm_on();
// Mark the pages as needing TRIM
_fs_prgm_word(page, FILE_OFFSET_STATUS, 0xA50A);
ae: f8a8 30a2 strh.w r3, [r8, #162] ; 0xa2
/**
* Enable programming mode for the file system.
*/
static void _fs_prgm_on() {
FLASH->KEYR = 0x45670123;
FLASH->KEYR = 0xCDEF89AB;
b2: f8a8 30ae strh.w r3, [r8, #174] ; 0xae
b6: e8bd 81f0 ldmia.w sp!, {r4, r5, r6, r7, r8, pc}
// Found index, jump on it
flash = (uint8_t *)_fs_pointer(page);
len = (GET_UINT16(flash, FILE_OFFSET_LEN) + 15) / PAGE_SIZE;
_fs_prgm_on();
// Mark the pages as needing TRIM
_fs_prgm_word(page, FILE_OFFSET_STATUS, 0xA50A);
ba: 2d00 cmp r5, #0
bc: d0df beq.n 7e <fsScan+0x7e>
be: e7f1 b.n a4 <fsScan+0xa4>
/**
* Disable programming mode for the file system.
*/
static void _fs_prgm_off() {
FLASH->CR = FLASH_CR_LOCK;
c0: 40022000 andmi r2, r2, r0
for (i = 0; i < MAX_FILES; i++)
if (fs.files[i].flags != 0U && fs.files[i].page == page)
return 1;
// Found index, jump on it
flash = (uint8_t *)_fs_pointer(page);
len = (GET_UINT16(flash, FILE_OFFSET_LEN) + 15) / PAGE_SIZE;
c4: 45670123 strbmi r0, [r7, #-291]! ; 0xfffffedd
c8: 00000000 andeq r0, r0, r0
c8: R_ARM_ABS32 fs
Disassembly of section .text.fseek:
00000000 <fseek>:
/**
* Erase a page of memory.
*/
static void _fs_erase_page(uint32_t page) {
FLASH->CR = FLASH_CR_PER;
0: 3805 subs r0, #5
/**
* Return pointer to given memory page. Skips the first 128 K (64 pages).
* Assumes memory can be mapped into linear address space (not AVR!)
*/
static INLINE void * _fs_pointer(const uint32_t page) {
return (void *)((FLASH_BASE + PAGE_SIZE * 64U) + page * PAGE_SIZE);
2: 2803 cmp r0, #3
4: b530 push {r4, r5, lr}
/**
* Erase a page of memory.
*/
static void _fs_erase_page(uint32_t page) {
FLASH->CR = FLASH_CR_PER;
6: d81e bhi.n 46 <fseek+0x46>
/**
* Return pointer to given memory page. Skips the first 128 K (64 pages).
* Assumes memory can be mapped into linear address space (not AVR!)
*/
static INLINE void * _fs_pointer(const uint32_t page) {
return (void *)((FLASH_BASE + PAGE_SIZE * 64U) + page * PAGE_SIZE);
8: 4c10 ldr r4, [pc, #64] ; (4c <fseek+0x4c>)
/**
* Erase a page of memory.
*/
static void _fs_erase_page(uint32_t page) {
FLASH->CR = FLASH_CR_PER;
a: 230c movs r3, #12
/**
* Return pointer to given memory page. Skips the first 128 K (64 pages).
* Assumes memory can be mapped into linear address space (not AVR!)
*/
static INLINE void * _fs_pointer(const uint32_t page) {
return (void *)((FLASH_BASE + PAGE_SIZE * 64U) + page * PAGE_SIZE);
c: fb03 4300 mla r3, r3, r0, r4
* Erase a page of memory.
*/
static void _fs_erase_page(uint32_t page) {
FLASH->CR = FLASH_CR_PER;
// Select page
FLASH->AR = (uint32_t)_fs_pointer(page);
10: f8b3 508a ldrh.w r5, [r3, #138] ; 0x8a
// Start operation
FLASH->CR = FLASH_CR_PER | FLASH_CR_STRT;
// Stall until BSY is reset (there is no sense sleeping here as IRQs cannot run while
// the erase is in progress)
while (FLASH->SR & FLASH_SR_BSY);
14: 07ed lsls r5, r5, #31
16: d516 bpl.n 46 <fseek+0x46>
18: f8d3 5084 ldr.w r5, [r3, #132] ; 0x84
// Verify erasure?
}
1c: b90a cbnz r2, 22 <fseek+0x22>
1e: 460b mov r3, r1
/**
* Return pointer to given memory page. Skips the first 128 K (64 pages).
* Assumes memory can be mapped into linear address space (not AVR!)
*/
static INLINE void * _fs_pointer(const uint32_t page) {
return (void *)((FLASH_BASE + PAGE_SIZE * 64U) + page * PAGE_SIZE);
20: e008 b.n 34 <fseek+0x34>
22: 2a01 cmp r2, #1
/**
* Program a (half)word to memory.
*/
static void _fs_prgm_word(uint32_t page, uint32_t offs, uint16_t value) {
FLASH->CR = FLASH_CR_PG;
24: d103 bne.n 2e <fseek+0x2e>
/**
* Return pointer to given memory page. Skips the first 128 K (64 pages).
* Assumes memory can be mapped into linear address space (not AVR!)
*/
static INLINE void * _fs_pointer(const uint32_t page) {
return (void *)((FLASH_BASE + PAGE_SIZE * 64U) + page * PAGE_SIZE);
26: f8d3 3080 ldr.w r3, [r3, #128] ; 0x80
FLASH->CR = FLASH_CR_PG;
// Ensure offs is even
//offs &= ~0x01;
// Select address by computing an offset from the desired page
uint8_t *addr = (uint8_t*)_fs_pointer(page) + offs;
*((uint16_t *)addr) = value;
2a: 440b add r3, r1
/**
* Program a (half)word to memory.
*/
static void _fs_prgm_word(uint32_t page, uint32_t offs, uint16_t value) {
FLASH->CR = FLASH_CR_PG;
2c: e002 b.n 34 <fseek+0x34>
2e: 2a02 cmp r2, #2
// Ensure offs is even
//offs &= ~0x01;
// Select address by computing an offset from the desired page
uint8_t *addr = (uint8_t*)_fs_pointer(page) + offs;
*((uint16_t *)addr) = value;
30: d109 bne.n 46 <fseek+0x46>
// Stall until BSY is reset
while (FLASH->SR & FLASH_SR_BSY);
32: 186b adds r3, r5, r1
34: 42ab cmp r3, r5
36: d206 bcs.n 46 <fseek+0x46>
}
38: 230c movs r3, #12
3a: fb03 4000 mla r0, r3, r0, r4
3e: f8c0 1080 str.w r1, [r0, #128] ; 0x80
/*
* Looks for a file in the file system with the given name.
*
* @return the matching page number if a match is found, or UINT_MAX otherwise
*/
static uint32_t lookForFile(const char *name) {
42: 2000 movs r0, #0
uint32_t i;
for (i = 0; i < NUM_PAGES; i++) {
44: bd30 pop {r4, r5, pc}
uint8_t *page = (uint8_t *)_fs_pointer(i);
if (fs.page[i] == FLAG_FILE_PRESENT) {
46: 2001 movs r0, #1
48: bd30 pop {r4, r5, pc}
4a: bf00 nop
4c: 00000000 andeq r0, r0, r0
4c: R_ARM_ABS32 fs
Disassembly of section .text.ftell:
00000000 <ftell>:
/**
* Erase a page of memory.
*/
static void _fs_erase_page(uint32_t page) {
FLASH->CR = FLASH_CR_PER;
0: 1f43 subs r3, r0, #5
/**
* Return pointer to given memory page. Skips the first 128 K (64 pages).
* Assumes memory can be mapped into linear address space (not AVR!)
*/
static INLINE void * _fs_pointer(const uint32_t page) {
return (void *)((FLASH_BASE + PAGE_SIZE * 64U) + page * PAGE_SIZE);
2: 2b03 cmp r3, #3
4: d809 bhi.n 1a <ftell+0x1a>
/**
* Erase a page of memory.
*/
static void _fs_erase_page(uint32_t page) {
FLASH->CR = FLASH_CR_PER;
6: 4a06 ldr r2, [pc, #24] ; (20 <ftell+0x20>)
/**
* Return pointer to given memory page. Skips the first 128 K (64 pages).
* Assumes memory can be mapped into linear address space (not AVR!)
*/
static INLINE void * _fs_pointer(const uint32_t page) {
return (void *)((FLASH_BASE + PAGE_SIZE * 64U) + page * PAGE_SIZE);
8: 200c movs r0, #12
/**
* Erase a page of memory.
*/
static void _fs_erase_page(uint32_t page) {
FLASH->CR = FLASH_CR_PER;
a: fb00 2003 mla r0, r0, r3, r2
// Select page
FLASH->AR = (uint32_t)_fs_pointer(page);
// Start operation
FLASH->CR = FLASH_CR_PER | FLASH_CR_STRT;
e: f8b0 308a ldrh.w r3, [r0, #138] ; 0x8a
12: b113 cbz r3, 1a <ftell+0x1a>
// Stall until BSY is reset (there is no sense sleeping here as IRQs cannot run while
// the erase is in progress)
while (FLASH->SR & FLASH_SR_BSY);
14: f8d0 0080 ldr.w r0, [r0, #128] ; 0x80
18: 4770 bx lr
// Verify erasure?
}
1a: f04f 30ff mov.w r0, #4294967295 ; 0xffffffff
1e: 4770 bx lr
/**
* Return pointer to given memory page. Skips the first 128 K (64 pages).
* Assumes memory can be mapped into linear address space (not AVR!)
*/
static INLINE void * _fs_pointer(const uint32_t page) {
return (void *)((FLASH_BASE + PAGE_SIZE * 64U) + page * PAGE_SIZE);
20: 00000000 andeq r0, r0, r0
20: R_ARM_ABS32 fs
Disassembly of section .text.fsWrite:
00000000 <fsWrite>:
/**
* Erase a page of memory.
*/
static void _fs_erase_page(uint32_t page) {
FLASH->CR = FLASH_CR_PER;
0: e92d 41f0 stmdb sp!, {r4, r5, r6, r7, r8, lr}
/**
* Return pointer to given memory page. Skips the first 128 K (64 pages).
* Assumes memory can be mapped into linear address space (not AVR!)
*/
static INLINE void * _fs_pointer(const uint32_t page) {
return (void *)((FLASH_BASE + PAGE_SIZE * 64U) + page * PAGE_SIZE);
4: 1f46 subs r6, r0, #5
/**
* Erase a page of memory.
*/
static void _fs_erase_page(uint32_t page) {
FLASH->CR = FLASH_CR_PER;
6: 2e03 cmp r6, #3
/**
* Return pointer to given memory page. Skips the first 128 K (64 pages).
* Assumes memory can be mapped into linear address space (not AVR!)
*/
static INLINE void * _fs_pointer(const uint32_t page) {
return (void *)((FLASH_BASE + PAGE_SIZE * 64U) + page * PAGE_SIZE);
8: 460d mov r5, r1
/**
* Erase a page of memory.
*/
static void _fs_erase_page(uint32_t page) {
FLASH->CR = FLASH_CR_PER;
a: d903 bls.n 14 <fsWrite+0x14>
/**
* Return pointer to given memory page. Skips the first 128 K (64 pages).
* Assumes memory can be mapped into linear address space (not AVR!)
*/
static INLINE void * _fs_pointer(const uint32_t page) {
return (void *)((FLASH_BASE + PAGE_SIZE * 64U) + page * PAGE_SIZE);
c: f04f 30ff mov.w r0, #4294967295 ; 0xffffffff
* Erase a page of memory.
*/
static void _fs_erase_page(uint32_t page) {
FLASH->CR = FLASH_CR_PER;
// Select page
FLASH->AR = (uint32_t)_fs_pointer(page);
10: e8bd 81f0 ldmia.w sp!, {r4, r5, r6, r7, r8, pc}
// Start operation
FLASH->CR = FLASH_CR_PER | FLASH_CR_STRT;
// Stall until BSY is reset (there is no sense sleeping here as IRQs cannot run while
// the erase is in progress)
while (FLASH->SR & FLASH_SR_BSY);
14: 4b12 ldr r3, [pc, #72] ; (60 <fsWrite+0x60>)
16: 240c movs r4, #12
18: fb04 3406 mla r4, r4, r6, r3
// Verify erasure?
}
1c: f8b4 208a ldrh.w r2, [r4, #138] ; 0x8a
/**
* Return pointer to given memory page. Skips the first 128 K (64 pages).
* Assumes memory can be mapped into linear address space (not AVR!)
*/
static INLINE void * _fs_pointer(const uint32_t page) {
return (void *)((FLASH_BASE + PAGE_SIZE * 64U) + page * PAGE_SIZE);
20: 4698 mov r8, r3
22: f012 0f02 tst.w r2, #2
26: d0f1 beq.n c <fsWrite+0xc>
}
/**
* Program a (half)word to memory.
*/
static void _fs_prgm_word(uint32_t page, uint32_t offs, uint16_t value) {
28: f8d4 3080 ldr.w r3, [r4, #128] ; 0x80
FLASH->CR = FLASH_CR_PG;
2c: f8d4 7084 ldr.w r7, [r4, #132] ; 0x84
// Ensure offs is even
//offs &= ~0x01;
// Select address by computing an offset from the desired page
uint8_t *addr = (uint8_t*)_fs_pointer(page) + offs;
*((uint16_t *)addr) = value;
30: f503 6200 add.w r2, r3, #2048 ; 0x800
// Stall until BSY is reset
while (FLASH->SR & FLASH_SR_BSY);
34: 4297 cmp r7, r2
36: d305 bcc.n 44 <fsWrite+0x44>
}
38: f7ff fffe bl 0 <fsWrite>
38: R_ARM_THM_CALL fflush
3c: 2800 cmp r0, #0
3e: d1e5 bne.n c <fsWrite+0xc>
/*
* Looks for a file in the file system with the given name.
*
* @return the matching page number if a match is found, or UINT_MAX otherwise
*/
static uint32_t lookForFile(const char *name) {
40: f8d4 3080 ldr.w r3, [r4, #128] ; 0x80
uint32_t i;
for (i = 0; i < NUM_PAGES; i++) {
44: 1afb subs r3, r7, r3
uint8_t *page = (uint8_t *)_fs_pointer(i);
if (fs.page[i] == FLAG_FILE_PRESENT) {
46: 4443 add r3, r8
48: f883 50b0 strb.w r5, [r3, #176] ; 0xb0
4c: 230c movs r3, #12
// The page has a file, not deleted, not a continuation
char *str = (char *)(&page[FILE_OFFSET_NAME]);
if (strncmp(name, str, MAX_LEN) == 0)
4e: fb03 8606 mla r6, r3, r6, r8
52: 3701 adds r7, #1
54: f8c6 7084 str.w r7, [r6, #132] ; 0x84
58: 4628 mov r0, r5
5a: e8bd 81f0 ldmia.w sp!, {r4, r5, r6, r7, r8, pc}
*
* @return the matching page number if a match is found, or UINT_MAX otherwise
*/
static uint32_t lookForFile(const char *name) {
uint32_t i;
for (i = 0; i < NUM_PAGES; i++) {
5e: bf00 nop
60: 00000000 andeq r0, r0, r0
60: R_ARM_ABS32 fs
Disassembly of section .text.fclose:
00000000 <fclose>:
/**
* Erase a page of memory.
*/
static void _fs_erase_page(uint32_t page) {
FLASH->CR = FLASH_CR_PER;
0: e92d 41f0 stmdb sp!, {r4, r5, r6, r7, r8, lr}
/**
* Return pointer to given memory page. Skips the first 128 K (64 pages).
* Assumes memory can be mapped into linear address space (not AVR!)
*/
static INLINE void * _fs_pointer(const uint32_t page) {
return (void *)((FLASH_BASE + PAGE_SIZE * 64U) + page * PAGE_SIZE);
4: 1f44 subs r4, r0, #5
/**
* Erase a page of memory.
*/
static void _fs_erase_page(uint32_t page) {
FLASH->CR = FLASH_CR_PER;
6: 2c03 cmp r4, #3
/**
* Return pointer to given memory page. Skips the first 128 K (64 pages).
* Assumes memory can be mapped into linear address space (not AVR!)
*/
static INLINE void * _fs_pointer(const uint32_t page) {
return (void *)((FLASH_BASE + PAGE_SIZE * 64U) + page * PAGE_SIZE);
8: 4606 mov r6, r0
/**
* Erase a page of memory.
*/
static void _fs_erase_page(uint32_t page) {
FLASH->CR = FLASH_CR_PER;
a: d83b bhi.n 84 <fclose+0x84>
/**
* Return pointer to given memory page. Skips the first 128 K (64 pages).
* Assumes memory can be mapped into linear address space (not AVR!)
*/
static INLINE void * _fs_pointer(const uint32_t page) {
return (void *)((FLASH_BASE + PAGE_SIZE * 64U) + page * PAGE_SIZE);
c: 4d1e ldr r5, [pc, #120] ; (88 <fclose+0x88>)
static void _fs_erase_page(uint32_t page) {
FLASH->CR = FLASH_CR_PER;
// Select page
FLASH->AR = (uint32_t)_fs_pointer(page);
// Start operation
FLASH->CR = FLASH_CR_PER | FLASH_CR_STRT;
e: 230c movs r3, #12
* Erase a page of memory.
*/
static void _fs_erase_page(uint32_t page) {
FLASH->CR = FLASH_CR_PER;
// Select page
FLASH->AR = (uint32_t)_fs_pointer(page);
10: fb03 5304 mla r3, r3, r4, r5
// Start operation
FLASH->CR = FLASH_CR_PER | FLASH_CR_STRT;
// Stall until BSY is reset (there is no sense sleeping here as IRQs cannot run while
// the erase is in progress)
while (FLASH->SR & FLASH_SR_BSY);
14: f8b3 208a ldrh.w r2, [r3, #138] ; 0x8a
18: f103 0188 add.w r1, r3, #136 ; 0x88
// Verify erasure?
}
1c: f012 0f01 tst.w r2, #1
/**
* Return pointer to given memory page. Skips the first 128 K (64 pages).
* Assumes memory can be mapped into linear address space (not AVR!)
*/
static INLINE void * _fs_pointer(const uint32_t page) {
return (void *)((FLASH_BASE + PAGE_SIZE * 64U) + page * PAGE_SIZE);
20: 46a8 mov r8, r5
22: d003 beq.n 2c <fclose+0x2c>
/**
* Program a (half)word to memory.
*/
static void _fs_prgm_word(uint32_t page, uint32_t offs, uint16_t value) {
FLASH->CR = FLASH_CR_PG;
24: 2300 movs r3, #0
/**
* Return pointer to given memory page. Skips the first 128 K (64 pages).
* Assumes memory can be mapped into linear address space (not AVR!)
*/
static INLINE void * _fs_pointer(const uint32_t page) {
return (void *)((FLASH_BASE + PAGE_SIZE * 64U) + page * PAGE_SIZE);
26: 804b strh r3, [r1, #2]
}
/**
* Program a (half)word to memory.
*/
static void _fs_prgm_word(uint32_t page, uint32_t offs, uint16_t value) {
28: e8bd 81f0 ldmia.w sp!, {r4, r5, r6, r7, r8, pc}
FLASH->CR = FLASH_CR_PG;
2c: 0792 lsls r2, r2, #30
2e: d529 bpl.n 84 <fclose+0x84>
// Ensure offs is even
//offs &= ~0x01;
// Select address by computing an offset from the desired page
uint8_t *addr = (uint8_t*)_fs_pointer(page) + offs;
*((uint16_t *)addr) = value;
30: f8d3 5084 ldr.w r5, [r3, #132] ; 0x84
// Stall until BSY is reset
while (FLASH->SR & FLASH_SR_BSY);
34: f8b3 7088 ldrh.w r7, [r3, #136] ; 0x88
}
38: 07eb lsls r3, r5, #31
3a: d503 bpl.n 44 <fclose+0x44>
3c: f04f 31ff mov.w r1, #4294967295 ; 0xffffffff
/*
* Looks for a file in the file system with the given name.
*
* @return the matching page number if a match is found, or UINT_MAX otherwise
*/
static uint32_t lookForFile(const char *name) {
40: f7ff fffe bl 0 <fclose>
40: R_ARM_THM_CALL fsWrite
uint32_t i;
for (i = 0; i < NUM_PAGES; i++) {
44: 4630 mov r0, r6
uint8_t *page = (uint8_t *)_fs_pointer(i);
if (fs.page[i] == FLAG_FILE_PRESENT) {
46: f7ff fffe bl 0 <fclose>
46: R_ARM_THM_CALL fflush
4a: 230c movs r3, #12
4c: fb03 8404 mla r4, r3, r4, r8
// The page has a file, not deleted, not a continuation
char *str = (char *)(&page[FILE_OFFSET_NAME]);
if (strncmp(name, str, MAX_LEN) == 0)
50: f8d4 3080 ldr.w r3, [r4, #128] ; 0x80
54: 4e0d ldr r6, [pc, #52] ; (8c <fclose+0x8c>)
56: 429d cmp r5, r3
58: bf28 it cs
5a: 461d movcs r5, r3
5c: 4b0c ldr r3, [pc, #48] ; (90 <fclose+0x90>)
*
* @return the matching page number if a match is found, or UINT_MAX otherwise
*/
static uint32_t lookForFile(const char *name) {
uint32_t i;
for (i = 0; i < NUM_PAGES; i++) {
5e: 4638 mov r0, r7
60: 6073 str r3, [r6, #4]
62: f103 3388 add.w r3, r3, #2290649224 ; 0x88888888
// The file names match
return i;
}
}
// Return error code
return UINT_MAX;
66: 6073 str r3, [r6, #4]
68: 2104 movs r1, #4
if (fs.page[i] == FLAG_FILE_PRESENT) {
// The page has a file, not deleted, not a continuation
char *str = (char *)(&page[FILE_OFFSET_NAME]);
if (strncmp(name, str, MAX_LEN) == 0)
// The file names match
return i;
6a: b2aa uxth r2, r5
}
}
// Return error code
return UINT_MAX;
}
6c: f7ff fffe bl 0 <fclose>
6c: R_ARM_THM_CALL _fs_prgm_word
70: 4638 mov r0, r7
72: 2106 movs r1, #6
74: 0c2a lsrs r2, r5, #16
76: f7ff fffe bl 0 <fclose>
76: R_ARM_THM_CALL _fs_prgm_word
*
* @param file the file name to erase
* @return 0 if the file was deleted, or 1 if the file could not be found
*/
int fdelete(const char *file) {
uint16_t len, page = lookForFile(file);
7a: 2380 movs r3, #128 ; 0x80
7c: 6133 str r3, [r6, #16]
7e: 2300 movs r3, #0
uint32_t i;
uint8_t *flash;
if (page < NUM_PAGES) {
80: f8a4 308a strh.w r3, [r4, #138] ; 0x8a
84: e8bd 81f0 ldmia.w sp!, {r4, r5, r6, r7, r8, pc}
88: 00000000 andeq r0, r0, r0
88: R_ARM_ABS32 fs
// Already open?
for (i = 0; i < MAX_FILES; i++)
if (fs.files[i].flags != 0U && fs.files[i].page == page)
8c: 40022000 andmi r2, r2, r0
90: 45670123 strbmi r0, [r7, #-291]! ; 0xfffffedd
Disassembly of section .rodata.str1.1:
00000000 <.rodata.str1.1>:
/**
* Erase a page of memory.
*/
static void _fs_erase_page(uint32_t page) {
FLASH->CR = FLASH_CR_PER;
0: 00770072 rsbseq r0, r7, r2, ror r0
Disassembly of section .debug_info:
00000000 <.debug_info>:
0: 00000cd1 ldrdeq r0, [r0], -r1
/**
* Return pointer to given memory page. Skips the first 128 K (64 pages).
* Assumes memory can be mapped into linear address space (not AVR!)
*/
static INLINE void * _fs_pointer(const uint32_t page) {
return (void *)((FLASH_BASE + PAGE_SIZE * 64U) + page * PAGE_SIZE);
4: 00000004 andeq r0, r0, r4
6: R_ARM_ABS32 .debug_abbrev
8: 01040000 mrseq r0, (UNDEF: 4)
c: 0000027e andeq r0, r0, lr, ror r2
c: R_ARM_ABS32 .debug_str
* Erase a page of memory.
*/
static void _fs_erase_page(uint32_t page) {
FLASH->CR = FLASH_CR_PER;
// Select page
FLASH->AR = (uint32_t)_fs_pointer(page);
10: 00011801 andeq r1, r1, r1, lsl #16
11: R_ARM_ABS32 .debug_str
// Start operation
FLASH->CR = FLASH_CR_PER | FLASH_CR_STRT;
// Stall until BSY is reset (there is no sense sleeping here as IRQs cannot run while
// the erase is in progress)
while (FLASH->SR & FLASH_SR_BSY);
14: 00021700 andeq r1, r2, r0, lsl #14
15: R_ARM_ABS32 .debug_str
18: 00010800 andeq r0, r1, r0, lsl #16
19: R_ARM_ABS32 .debug_ranges
...
21: R_ARM_ABS32 .debug_line
/**
* Program a (half)word to memory.
*/
static void _fs_prgm_word(uint32_t page, uint32_t offs, uint16_t value) {
FLASH->CR = FLASH_CR_PG;
24: 05040200 streq r0, [r4, #-512] ; 0xfffffe00
}
/**
* Program a (half)word to memory.
*/
static void _fs_prgm_word(uint32_t page, uint32_t offs, uint16_t value) {
28: 00746e69 rsbseq r6, r4, r9, ror #28
FLASH->CR = FLASH_CR_PG;
2c: 00003703 andeq r3, r0, r3, lsl #14
2d: R_ARM_ABS32 .debug_str
// Ensure offs is even
//offs &= ~0x01;
// Select address by computing an offset from the desired page
uint8_t *addr = (uint8_t*)_fs_pointer(page) + offs;
*((uint16_t *)addr) = value;
30: 37d40200 ldrbcc r0, [r4, r0, lsl #4]
// Stall until BSY is reset
while (FLASH->SR & FLASH_SR_BSY);
34: 04000000 streq r0, [r0], #-0
}
38: 01730704 cmneq r3, r4, lsl #14
3a: R_ARM_ABS32 .debug_str
3c: 01040000 mrseq r0, (UNDEF: 4)
/*
* Looks for a file in the file system with the given name.
*
* @return the matching page number if a match is found, or UINT_MAX otherwise
*/
static uint32_t lookForFile(const char *name) {
40: 00013506 andeq r3, r1, r6, lsl #10
41: R_ARM_ABS32 .debug_str
uint32_t i;
for (i = 0; i < NUM_PAGES; i++) {
44: 00f70300 rscseq r0, r7, r0, lsl #6
46: R_ARM_ABS32 .debug_str
uint8_t *page = (uint8_t *)_fs_pointer(i);
if (fs.page[i] == FLAG_FILE_PRESENT) {
48: 1d030000 stcne 0, cr0, [r3, #-0]
4c: 00000050 andeq r0, r0, r0, asr r0
// The page has a file, not deleted, not a continuation
char *str = (char *)(&page[FILE_OFFSET_NAME]);
if (strncmp(name, str, MAX_LEN) == 0)
50: 1d080104 stfnes f0, [r8, #-16]
53: R_ARM_ABS32 .debug_str
54: 04000001 streq r0, [r0], #-1
58: 002d0502 eoreq r0, sp, r2, lsl #10
5a: R_ARM_ABS32 .debug_str
5c: 70030000 andvc r0, r3, r0
5f: R_ARM_ABS32 .debug_str
*
* @return the matching page number if a match is found, or UINT_MAX otherwise
*/
static uint32_t lookForFile(const char *name) {
uint32_t i;
for (i = 0; i < NUM_PAGES; i++) {
60: 03000000 movweq r0, #0
// The file names match
return i;
}
}
// Return error code
return UINT_MAX;
64: 0000692b andeq r6, r0, fp, lsr #18
68: 07020400 streq r0, [r2, -r0, lsl #8]
}
6c: 00000196 muleq r0, r6, r1
6c: R_ARM_ABS32 .debug_str
70: e7050404 str r0, [r5, -r4, lsl #8]
73: R_ARM_ABS32 .debug_str
74: 03000000 movweq r0, #0
* The file will actually be erased from memory on the next re-boot.
*
* @param file the file name to erase
* @return 0 if the file was deleted, or 1 if the file could not be found
*/
int fdelete(const char *file) {
78: 00000060 andeq r0, r0, r0, rrx
78: R_ARM_ABS32 .debug_str
uint16_t len, page = lookForFile(file);
7c: 00824103 addeq r4, r2, r3, lsl #2
uint32_t i;
uint8_t *flash;
if (page < NUM_PAGES) {
80: 04040000 streq r0, [r4], #-0
84: 0001e107 andeq lr, r1, r7, lsl #2
85: R_ARM_ABS32 .debug_str
88: 05080400 streq r0, [r8, #-1024] ; 0xfffffc00
// Already open?
for (i = 0; i < MAX_FILES; i++)
if (fs.files[i].flags != 0U && fs.files[i].page == page)
8c: 000000c5 andeq r0, r0, r5, asr #1
8c: R_ARM_ABS32 .debug_str
90: 47070804 strmi r0, [r7, -r4, lsl #16]
93: R_ARM_ABS32 .debug_str
94: 03000001 movweq r0, #1
98: 0000008e andeq r0, r0, lr, lsl #1
98: R_ARM_ABS32 .debug_str
uint16_t len, page = lookForFile(file);
uint32_t i;
uint8_t *flash;
if (page < NUM_PAGES) {
// Already open?
for (i = 0; i < MAX_FILES; i++)
9c: 00451404 subeq r1, r5, r4, lsl #8
/**
* Return pointer to given memory page. Skips the first 128 K (64 pages).
* Assumes memory can be mapped into linear address space (not AVR!)
*/
static INLINE void * _fs_pointer(const uint32_t page) {
return (void *)((FLASH_BASE + PAGE_SIZE * 64U) + page * PAGE_SIZE);
a0: 80030000 andhi r0, r3, r0
a3: R_ARM_ABS32 .debug_str
for (i = 0; i < MAX_FILES; i++)
if (fs.files[i].flags != 0U && fs.files[i].page == page)
return 1;
// Found index, jump on it
flash = (uint8_t *)_fs_pointer(page);
len = (GET_UINT16(flash, FILE_OFFSET_LEN) + 15) / PAGE_SIZE;
a4: 04000001 streq r0, [r0], #-1
/**
* Enable programming mode for the file system.
*/
static void _fs_prgm_on() {
FLASH->KEYR = 0x45670123;
a8: 00005e1a andeq r5, r0, sl, lsl lr
// Found index, jump on it
flash = (uint8_t *)_fs_pointer(page);
len = (GET_UINT16(flash, FILE_OFFSET_LEN) + 15) / PAGE_SIZE;
_fs_prgm_on();
// Mark the pages as needing TRIM
_fs_prgm_word(page, FILE_OFFSET_STATUS, 0xA50A);
ac: 015e0300 cmpeq lr, r0, lsl #6
ae: R_ARM_ABS32 .debug_str
/**
* Enable programming mode for the file system.
*/
static void _fs_prgm_on() {
FLASH->KEYR = 0x45670123;
b0: 20040000 andcs r0, r4, r0
FLASH->KEYR = 0xCDEF89AB;
b4: 00000077 andeq r0, r0, r7, ror r0
// Found index, jump on it
flash = (uint8_t *)_fs_pointer(page);
len = (GET_UINT16(flash, FILE_OFFSET_LEN) + 15) / PAGE_SIZE;
_fs_prgm_on();
// Mark the pages as needing TRIM
_fs_prgm_word(page, FILE_OFFSET_STATUS, 0xA50A);
b8: b8030405 stmdalt r3, {r0, r2, sl}
bb: R_ARM_ABS32 .debug_str
bc: 05000000 streq r0, [r0, #-0]
/**
* Disable programming mode for the file system.
*/
static void _fs_prgm_off() {
FLASH->CR = FLASH_CR_LOCK;
c0: 00002525 andeq r2, r0, r5, lsr #10
for (i = 0; i < MAX_FILES; i++)
if (fs.files[i].flags != 0U && fs.files[i].page == page)
return 1;
// Found index, jump on it
flash = (uint8_t *)_fs_pointer(page);
len = (GET_UINT16(flash, FILE_OFFSET_LEN) + 15) / PAGE_SIZE;
c4: 00ad0600 adceq r0, sp, r0, lsl #12
c8: 24070000 strcs r0, [r7], #-0
_fs_prgm_on();
// Mark the pages as needing TRIM
_fs_prgm_word(page, FILE_OFFSET_STATUS, 0xA50A);
_fs_prgm_off();
fs.page[page++] = FLAG_FILE_DELETED;
cc: 46011406 strmi r1, [r1], -r6, lsl #8
d0: 08000001 stmdaeq r0, {r0}
d4: 00524341 subseq r4, r2, r1, asr #6
for (; len && page < NUM_PAGES; len--) {
d8: c5011506 strgt r1, [r1, #-1286] ; 0xfffffafa
dc: 00000000 andeq r0, r0, r0
// Mark the rest of the file invalid for this run
fs.page[page++] = FLAG_FILE_DELETED | FLAG_FILE_CONTINUE;
e0: 00008309 andeq r8, r0, r9, lsl #6
e1: R_ARM_ABS32 .debug_str
e4: 01170600 tsteq r7, r0, lsl #12
}
return 0;
}
return 1;
e8: 000000c5 andeq r0, r0, r5, asr #1
fs.page[page++] = FLAG_FILE_DELETED;
for (; len && page < NUM_PAGES; len--) {
// Mark the rest of the file invalid for this run
fs.page[page++] = FLAG_FILE_DELETED | FLAG_FILE_CONTINUE;
}
return 0;
ec: 00bd0904 adcseq r0, sp, r4, lsl #18
ee: R_ARM_ABS32 .debug_str
}
return 1;
}
f0: 19060000 stmdbne r6, {} ; <UNPREDICTABLE>
f4: 0000c501 andeq ip, r0, r1, lsl #10
f8: 53080800 movwpl r0, #34816 ; 0x8800
*
* @param fd the channel to check
* @return 0 if the file is not at EOF, or 1 otherwise.
*/
int fsEof(FILE *fd) {
uint32_t idx = (uint32_t)fd - FILE_CHANNEL_1;
fc: 1b060052 blne 18024c <_fs_erase_page+0x18024c>
if (idx < MAX_FILES) {
100: 0000c501 andeq ip, r0, r1, lsl #10
// Index in bounds
uint16_t flags = fs.files[idx].flags;
104: 43080c00 movwmi r0, #35840 ; 0x8c00
108: 1d060052 stcne 0, cr0, [r6, #-328] ; 0xfffffeb8
if (flags & FILE_FLAG_RD)
10c: 0000c501 andeq ip, r0, r1, lsl #10
110: 41081000 mrsmi r1, (UNDEF: 8)
return (fs.files[idx].offset >= fs.files[idx].len) ? 1 : 0;
114: 1e060052 mcrne 0, 0, r0, cr6, cr2, {2}
118: 0000c501 andeq ip, r0, r1, lsl #10
11c: 52091400 andpl r1, r9, #0, 8
11f: R_ARM_ABS32 .debug_str
120: 06000002 streq r0, [r0], -r2
// Else, can't determine
}
return 1;
124: 00c5011f sbceq r0, r5, pc, lsl r1
}
128: 08180000 ldmdaeq r8, {} ; <UNPREDICTABLE>
*
* @param fd the channel to flush
* @return 0 if the data was successfully written out to Flash, EOF otherwise
* The file data is still invalid until properly closed!
*/
int fflush(FILE *fd) {
12c: 0052424f subseq r4, r2, pc, asr #4
uint32_t idx = (uint32_t)fd - FILE_CHANNEL_1;
130: c5012006 strgt r2, [r1, #-6]
if (idx < MAX_FILES) {
134: 1c000000 stcne 0, cr0, [r0], {-0}
138: 00010109 andeq r0, r1, r9, lsl #2
139: R_ARM_ABS32 .debug_str
// Index in bounds
uint16_t flags = fs.files[idx].flags;
13c: 01220600 ; <UNDEFINED> instruction: 0x01220600
140: 000000c5 andeq r0, r0, r5, asr #1
144: 5b0a0020 blpl 280088 <_fs_erase_page+0x280088>
147: R_ARM_ABS32 .debug_str
if (flags & FILE_FLAG_WR) {
148: 06000002 streq r0, [r0], -r2
14c: 00ca0123 sbceq r0, sl, r3, lsr #2
uint16_t *dp = (uint16_t *)(&fs.data[0]);
// Calculate current position in flash memory
uint32_t offs = fs.files[idx].offset, len = fs.files[idx].len;
150: 04040000 streq r0, [r4], #-0
uint32_t page = (offs + 16U) / PAGE_SIZE;
uint32_t remain = (len - offs) & 0xFFFFFFFEU;
offs = (offs + 16U) - page * PAGE_SIZE;
page += fs.files[idx].page;
154: 00003e07 andeq r3, r0, r7, lsl #28
155: R_ARM_ABS32 .debug_str
uint16_t flags = fs.files[idx].flags;
if (flags & FILE_FLAG_WR) {
uint16_t *dp = (uint16_t *)(&fs.data[0]);
// Calculate current position in flash memory
uint32_t offs = fs.files[idx].offset, len = fs.files[idx].len;
uint32_t page = (offs + 16U) / PAGE_SIZE;
158: 5f040b00 svcpl 0x00040b00
// Index in bounds
uint16_t flags = fs.files[idx].flags;
if (flags & FILE_FLAG_WR) {
uint16_t *dp = (uint16_t *)(&fs.data[0]);
// Calculate current position in flash memory
uint32_t offs = fs.files[idx].offset, len = fs.files[idx].len;
15c: 04000001 streq r0, [r0], #-1
uint32_t page = (offs + 16U) / PAGE_SIZE;
uint32_t remain = (len - offs) & 0xFFFFFFFEU;
offs = (offs + 16U) - page * PAGE_SIZE;
160: 01b00601 lslseq r0, r1, #12
162: R_ARM_ABS32 .debug_str
/**
* Enable programming mode for the file system.
*/
static void _fs_prgm_on() {
FLASH->KEYR = 0x45670123;
164: 040b0000 streq r0, [fp], #-0
168: 0000016c andeq r0, r0, ip, ror #2
if (flags & FILE_FLAG_WR) {
uint16_t *dp = (uint16_t *)(&fs.data[0]);
// Calculate current position in flash memory
uint32_t offs = fs.files[idx].offset, len = fs.files[idx].len;
uint32_t page = (offs + 16U) / PAGE_SIZE;
uint32_t remain = (len - offs) & 0xFFFFFFFEU;
16c: 00015f0c andeq r5, r1, ip, lsl #30
/**
* Enable programming mode for the file system.
*/
static void _fs_prgm_on() {
FLASH->KEYR = 0x45670123;
FLASH->KEYR = 0xCDEF89AB;
170: 015f0d00 cmpeq pc, r0, lsl #26
if (flags & FILE_FLAG_WR) {
uint16_t *dp = (uint16_t *)(&fs.data[0]);
// Calculate current position in flash memory
uint32_t offs = fs.files[idx].offset, len = fs.files[idx].len;
uint32_t page = (offs + 16U) / PAGE_SIZE;
uint32_t remain = (len - offs) & 0xFFFFFFFEU;
174: 01810000 orreq r0, r1, r0
/**
* Enable programming mode for the file system.
*/
static void _fs_prgm_on() {
FLASH->KEYR = 0x45670123;
FLASH->KEYR = 0xCDEF89AB;
178: 520e0000 andpl r0, lr, #0
uint32_t idx = (uint32_t)fd - FILE_CHANNEL_1;
if (idx < MAX_FILES) {
// Index in bounds
uint16_t flags = fs.files[idx].flags;
if (flags & FILE_FLAG_WR) {
uint16_t *dp = (uint16_t *)(&fs.data[0]);
17c: 07000001 streq r0, [r0, -r1]
page += fs.files[idx].page;
// Program the buffer to the current location; if the buffer has an odd size,
// leave one byte behind
_fs_prgm_on();
for (; remain; remain -= 2) {
if (offs == 0) {
180: 010c0f00 tsteq ip, r0, lsl #30
if (page >= NUM_PAGES || fs.page[page] != 0U) {
184: 0001ba67 andeq fp, r1, r7, ror #20
// No space to write the rest of the buffer
fs.files[idx].offset = (len - remain) & 0xFFFFFFFEU;
188: 00f01000 rscseq r1, r0, r0
18a: R_ARM_ABS32 .debug_str
18c: 6a010000 bvs 40194 <_fs_erase_page+0x40194>
190: 000000ad andeq r0, r0, sp, lsr #1
194: 656c1100 strbvs r1, [ip, #-256]! ; 0xffffff00
/**
* Disable programming mode for the file system.
*/
static void _fs_prgm_off() {
FLASH->CR = FLASH_CR_LOCK;
198: 6b01006e blvs 40358 <_fs_erase_page+0x40358>
19c: 000000ad andeq r0, r0, sp, lsr #1
// Program the buffer to the current location; if the buffer has an odd size,
// leave one byte behind
_fs_prgm_on();
for (; remain; remain -= 2) {
if (offs == 0) {
if (page >= NUM_PAGES || fs.page[page] != 0U) {
1a0: 00e21004 rsceq r1, r2, r4
1a2: R_ARM_ABS32 .debug_str
1a4: 6d010000 stcvs 0, cr0, [r1, #-0]
fs.files[idx].offset = (len - remain) & 0xFFFFFFFEU;
_fs_prgm_off();
return EOF;
} else
// Update the page table
fs.page[page] = FLAG_FILE_PRESENT | FLAG_FILE_CONTINUE;
1a8: 000000a2 andeq r0, r0, r2, lsr #1
}
_fs_prgm_word(page, offs, *dp++);
1ac: 01411008 cmpeq r1, r8
1ae: R_ARM_ABS32 .debug_str
1b0: 6f010000 svcvs 0x00010000
offs += 2;
1b4: 000000a2 andeq r0, r0, r2, lsr #1
return EOF;
} else
// Update the page table
fs.page[page] = FLAG_FILE_PRESENT | FLAG_FILE_CONTINUE;
}
_fs_prgm_word(page, offs, *dp++);
1b8: 4703000a strmi r0, [r3, -sl]
1bb: R_ARM_ABS32 .debug_str
offs += 2;
// Wrap around to the next page
if (offs >= PAGE_SIZE) {
1bc: 01000000 mrseq r0, (UNDEF: 0)
page++;
1c0: 00018170 andeq r8, r1, r0, ror r1
offs = (offs + 16U) - page * PAGE_SIZE;
page += fs.files[idx].page;
// Program the buffer to the current location; if the buffer has an odd size,
// leave one byte behind
_fs_prgm_on();
for (; remain; remain -= 2) {
1c4: 08b01200 ldmeq r0!, {r9, ip}
/**
* Disable programming mode for the file system.
*/
static void _fs_prgm_off() {
FLASH->CR = FLASH_CR_LOCK;
1c8: 01f37301 mvnseq r7, r1, lsl #6
1cc: e2100000 ands r0, r0, #0
1cf: R_ARM_ABS32 .debug_str
offs = 0;
}
}
_fs_prgm_off();
// Reset data size to just the odd part
fs.files[idx].offset = len & 0xFFFFFFFEU;
1d0: 01000000 mrseq r0, (UNDEF: 0)
1d4: 0001f375 andeq pc, r1, r5, ror r3 ; <UNPREDICTABLE>
1d8: 71100000 tstvc r0, r0
1db: R_ARM_ABS32 .debug_str
return 0;
1dc: 01000002 tsteq r0, r2
1e0: 00020377 andeq r0, r2, r7, ror r3
} else if (flags & FILE_FLAG_RD)
1e4: dc108000 ldcle 0, cr8, [r0], {-0}
1e7: R_ARM_ABS32 .debug_str
1e8: 01000001 tsteq r0, r1
1ec: 00021379 andeq r1, r2, r9, ror r3
// No-op
return 0;
}
return EOF;
1f0: 0d00b000 stceq 0, cr11, [r0, #-0]
}
1f4: 00000097 muleq r0, r7, r0
1f8: 00000203 andeq r0, r0, r3, lsl #4
1fc: 0001520e andeq r5, r1, lr, lsl #4
200: 0d007f00 stceq 15, cr7, [r0, #-0]
*
* @param fd the file channel to check
* @return the number of bytes left, or 0 if this value could not be determined
*/
uint32_t fsLeft(FILE *fd) {
uint32_t idx = (uint32_t)fd - FILE_CHANNEL_1;
204: 000001ba ; <UNDEFINED> instruction: 0x000001ba
if (idx < MAX_FILES) {
208: 00000213 andeq r0, r0, r3, lsl r2
// Index in bounds
uint16_t flags = fs.files[idx].flags;
20c: 0001520e andeq r5, r1, lr, lsl #4
210: 0d000300 stceq 3, cr0, [r0, #-0]
if (flags & FILE_FLAG_RD)
214: 00000097 muleq r0, r7, r0
218: 00000224 andeq r0, r0, r4, lsr #4
return fs.files[idx].len - fs.files[idx].offset;
21c: 00015213 andeq r5, r1, r3, lsl r2
220: 0007ff00 andeq pc, r7, r0, lsl #30
224: 00016714 andeq r6, r1, r4, lsl r7
225: R_ARM_ABS32 .debug_str
// Else, can't determine
}
return 0;
228: b81c0100 ldmdalt ip, {r8}
}
22c: 03000000 movweq r0, #0
*
* @param file the file name
* @param mode the file mode
* @return a pointer to file data, or NULL if the file could not be opened
*/
FILE * fopen(const char *file, const char *mode) {
230: 00000240 andeq r0, r0, r0, asr #4
234: 0000e215 andeq lr, r0, r5, lsl r2
235: R_ARM_ABS32 .debug_str
uint32_t i, page;
if (strcmp(mode, "r") == 0) {
238: 401c0100 andsmi r0, ip, r0, lsl #2
23c: 00000002 andeq r0, r0, r2
240: 0000ad0c andeq sl, r0, ip, lsl #26
// READ
page = lookForFile(file);
244: 00191600 andseq r1, r9, r0, lsl #12
246: R_ARM_ABS32 .debug_str
if (page < NUM_PAGES) {
248: 2b010000 blcs 40250 <_fs_erase_page+0x40250>
// Only one write buffer
break;
}
}
}
return NULL;
24c: 01fb1701 mvnseq r1, r1, lsl #14
24e: R_ARM_ABS32 .debug_str
/**
* Return pointer to given memory page. Skips the first 128 K (64 pages).
* Assumes memory can be mapped into linear address space (not AVR!)
*/
static INLINE void * _fs_pointer(const uint32_t page) {
return (void *)((FLASH_BASE + PAGE_SIZE * 64U) + page * PAGE_SIZE);
250: b4010000 strlt r0, [r1], #-0
254: 00027b01 andeq r7, r2, r1, lsl #22
if (strcmp(mode, "r") == 0) {
// READ
page = lookForFile(file);
if (page < NUM_PAGES) {
uint8_t *flash = (uint8_t *)_fs_pointer(page);
uint32_t len = GET_UINT32(flash, FILE_OFFSET_LEN);
258: 64691800 strbtvs r1, [r9], #-2048 ; 0xfffff800
25c: b4010078 strlt r0, [r1], #-120 ; 0xffffff88
260: 000000ad andeq r0, r0, sp, lsr #1
// Look for an open file with flags == 0
for (i = 0; i < MAX_FILES; i++)
if (fs.files[i].flags == 0U) {
264: 0000e215 andeq lr, r0, r5, lsl r2
265: R_ARM_ABS32 .debug_str
* @param idx the file descriptor index
* @param page the flash page to start reading
* @param len the length of the file in bytes
*/
static void openForReading(uint32_t idx, uint32_t page, uint32_t len) {
fs.files[idx].flags = FILE_FLAG_RD;
268: adb40100 ldfges f0, [r4]
26c: 18000000 stmdane r0, {} ; <UNPREDICTABLE>
fs.files[idx].len = len;
270: 006e656c rsbeq r6, lr, ip, ror #10
fs.files[idx].offset = 0;
274: 00adb401 adceq fp, sp, r1, lsl #8
fs.files[idx].page = page;
278: 19000000 stmdbne r0, {} ; <UNPREDICTABLE>
page = lookForFile(file);
if (page < NUM_PAGES) {
uint8_t *flash = (uint8_t *)_fs_pointer(page);
uint32_t len = GET_UINT32(flash, FILE_OFFSET_LEN);
// Look for an open file with flags == 0
for (i = 0; i < MAX_FILES; i++)
27c: 000001cd andeq r0, r0, sp, asr #3
27c: R_ARM_ABS32 .debug_str
280: 00003201 andeq r3, r0, r1, lsl #4
282: R_ARM_ABS32 .text._fs_erase_page
openForReading(i, page, len);
return (FILE *)(FILE_CHANNEL_1 + i);
}
// Maximum file limit exceeded!
}
} else if (strcmp(mode, "w") == 0) {
284: 00200000 eoreq r0, r0, r0
288: 9c010000 stcls 0, cr0, [r1], {-0}
28c: 000002b5 ; <UNDEFINED> instruction: 0x000002b5
290: 0000e21a andeq lr, r0, sl, lsl r2
291: R_ARM_ABS32 .debug_str
// WRITE - no append possible due to the structure of the Flash
// Erases the file's contents!
fdelete(file);
294: ad320100 ldfges f0, [r2, #-0]
*
* @return the longest contiguous blank page range starting index
*/
static uint32_t longestBlock() {
uint32_t i;
uint32_t len = 0, blockLen = 0, page = 0;
298: 00000000 andeq r0, r0, r0
29b: R_ARM_ABS32 .debug_loc
for (i = 0; i < NUM_PAGES; i++) {
29c: 1b000000 blne 2a4 <.debug_info+0x2a4>
if (fs.page[i] == 0) {
2a0: 00000224 andeq r0, r0, r4, lsr #4
len++;
// Edge case?
if (i == NUM_PAGES - 1 && len > blockLen) {
2a4: 00000002 andeq r0, r0, r2
2a4: R_ARM_ABS32 .text._fs_erase_page
static uint32_t longestBlock() {
uint32_t i;
uint32_t len = 0, blockLen = 0, page = 0;
for (i = 0; i < NUM_PAGES; i++) {
if (fs.page[i] == 0) {
len++;
2a8: 00000000 andeq r0, r0, r0
2a8: R_ARM_ABS32 .debug_ranges
// Edge case?
if (i == NUM_PAGES - 1 && len > blockLen) {
2ac: 341c3501 ldrcc r3, [ip], #-1281 ; 0xfffffaff
blockLen = len;
page = i - len + 1;
2b0: 00000002 andeq r0, r0, r2
2b4: 00001900 andeq r1, r0, r0, lsl #18
2b6: R_ARM_ABS32 .debug_str
}
} else {
// Calculate longest block
if (len > blockLen) {
2b8: 41010000 mrsmi r0, (UNDEF: 1)
blockLen = len;
page = i - len;
2bc: 00000000 andeq r0, r0, r0
2bc: R_ARM_ABS32 .text._fs_prgm_word
}
len = 0;
2c0: 00000020 andeq r0, r0, r0, lsr #32
* @return the longest contiguous blank page range starting index
*/
static uint32_t longestBlock() {
uint32_t i;
uint32_t len = 0, blockLen = 0, page = 0;
for (i = 0; i < NUM_PAGES; i++) {
2c4: 03169c01 tsteq r6, #256 ; 0x100
2c8: e21a0000 ands r0, sl, #0
2cb: R_ARM_ABS32 .debug_str
// WRITE - no append possible due to the structure of the Flash
// Erases the file's contents!
fdelete(file);
// Look for the largest contiguous block of free space
page = longestBlock();
if (fs.page[page] == 0U) {
2cc: 01000000 mrseq r0, (UNDEF: 0)
2d0: 0000ad41 andeq sl, r0, r1, asr #26
2d4: 00003f00 andeq r3, r0, r0, lsl #30
2d5: R_ARM_ABS32 .debug_loc
// Allocate FD
for (i = 0; i < MAX_FILES; i++) {
uint16_t flags = fs.files[i].flags;
2d8: 00b31d00 adcseq r1, r3, r0, lsl #26
2da: R_ARM_ABS32 .debug_str
if (flags == 0U) {
2dc: 41010000 mrsmi r0, (UNDEF: 1)
*/
static void openForWriting(const char *file, uint32_t idx, uint32_t page) {
char c, nameBuff[8];
uint32_t i;
// Set the flags
fs.files[idx].flags = FILE_FLAG_WR;
2e0: 000000ad andeq r0, r0, sp, lsr #1
fs.files[idx].len = 0;
2e4: 881a5101 ldmdahi sl, {r0, r8, ip, lr}
2e7: R_ARM_ABS32 .debug_str
fs.files[idx].offset = 0;
2e8: 01000000 mrseq r0, (UNDEF: 0)
fs.files[idx].page = page;
2ec: 0000a241 andeq sl, r0, r1, asr #4
// Update page records
fs.page[page] = FLAG_FILE_PRESENT;
2f0: 00007e00 andeq r7, r0, r0, lsl #28
2f1: R_ARM_ABS32 .debug_loc
2f4: 00141e00 andseq r1, r4, r0, lsl #28
2f6: R_ARM_ABS32 .debug_str
for (i = 0; i < MAX_LEN; i++) {
c = *file;
// Pad name out to 8 bytes
if (c) {
nameBuff[i] = c;
2f8: 46010000 strmi r0, [r1], -r0
// Update page records
fs.page[page] = FLAG_FILE_PRESENT;
for (i = 0; i < MAX_LEN; i++) {
c = *file;
// Pad name out to 8 bytes
if (c) {
2fc: 00000316 andeq r0, r0, r6, lsl r3
fs.files[idx].len = 0;
fs.files[idx].offset = 0;
fs.files[idx].page = page;
// Update page records
fs.page[page] = FLAG_FILE_PRESENT;
for (i = 0; i < MAX_LEN; i++) {
300: 0002241b andeq r2, r2, fp, lsl r4
304: 00000000 andeq r0, r0, r0
305: R_ARM_ABS32 .text._fs_prgm_word
/**
* Enable programming mode for the file system.
*/
static void _fs_prgm_on() {
FLASH->KEYR = 0x45670123;
308: 00002000 andeq r2, r0, r0
309: R_ARM_ABS32 .debug_ranges
30c: 1c460100 stfnee f0, [r6], {-0}
FLASH->KEYR = 0xCDEF89AB;
310: 00000234 andeq r0, r0, r4, lsr r2
} else
nameBuff[i] = (char)0x00;
}
// Can write, program the status + name into NV now
_fs_prgm_on();
_fs_prgm_word(page, 0, FILE_MAGIC);
314: 040b0000 streq r0, [fp], #-0
318: 00000097 muleq r0, r7, r0
31c: 00032d1f andeq r2, r3, pc, lsl sp
31d: R_ARM_ABS32 .debug_str
// Status bits = 0xFFFF, len = 0xFFFFFFFF for now
for (i = 0; i < (MAX_LEN >> 1); i++)
_fs_prgm_word(page, FILE_OFFSET_NAME + (i << 1), ((uint16_t *)nameBuff)[i]);
320: ad9d0100 ldfges f0, [sp]
324: 00000000 andeq r0, r0, r0
327: R_ARM_ABS32 .text.lookForFile
328: 38000000 stmdacc r0, {} ; <UNPREDICTABLE>
32c: 01000000 mrseq r0, (UNDEF: 0)
}
// Can write, program the status + name into NV now
_fs_prgm_on();
_fs_prgm_word(page, 0, FILE_MAGIC);
// Status bits = 0xFFFF, len = 0xFFFFFFFF for now
for (i = 0; i < (MAX_LEN >> 1); i++)
330: 00039a9c muleq r3,
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment