ARM: get delay.c in.
Accuracy is pretty good, see committed comments :-)
Code used for testing, in main():
uint32_t i;
SET_OUTPUT(PIO0_1);
while (1) {
// 10 seconds for each frequency, so we
// can measure all three with one upload.
for (i = 10000; i > 0; i--) {
WRITE(PIO0_1, 1);
delay_us(1000);
WRITE(PIO0_1, 0);
delay_us(1000);
}
for (i = 1000; i > 0; i--) {
WRITE(PIO0_1, 1);
delay_us(10000);
WRITE(PIO0_1, 0);
delay_us(10000);
}
for (i = 200; i > 0; i--) {
WRITE(PIO0_1, 1);
delay_us(65000);
WRITE(PIO0_1, 0);
delay_us(65000);
}
}
This commit is contained in:
parent
6c31471ffd
commit
8377de8d66
|
|
@ -97,7 +97,7 @@ TARGET = $(PROGRAM).hex
|
|||
#SOURCES = $(wildcard *.c)
|
||||
# Until the generic ARM port is completed, we'd have to wrap all sources
|
||||
# in #ifdef __AVR__. To avoid this, build only a selection for now:
|
||||
SOURCES = mendel.c cpu.c serial.c sermsg.c sersendf.c
|
||||
SOURCES = mendel.c cpu.c serial.c sermsg.c sersendf.c delay.c
|
||||
ifeq ($(MCU), lpc1114)
|
||||
SOURCES += mbed-system_LPC11xx.c
|
||||
endif
|
||||
|
|
|
|||
40
delay-arm.c
40
delay-arm.c
|
|
@ -5,13 +5,51 @@
|
|||
|
||||
#if defined TEACUP_C_INCLUDE && defined __ARMEL__
|
||||
|
||||
#include "mbed-LPC11xx.h" // For __ASM() and __SYSTEM_CLOCK.
|
||||
|
||||
|
||||
/** Delay in microseconds.
|
||||
|
||||
\param delay Time to wait in microseconds.
|
||||
|
||||
To Be Defined.
|
||||
Execution times on ARM aren't as predictable as they could be, because
|
||||
there's a code prefetch engine which can change timings depending on the
|
||||
position of the code in Flash. We could use the System Tick Timer for this
|
||||
task, but this timer is probably better used for more important tasks.
|
||||
delay_us() and delay_ms() are used only rarely and not in a way which would
|
||||
require high precision.
|
||||
|
||||
Nevertheless, calibrated on the oscilloscope. Measured accuracy:
|
||||
|
||||
delay_us(10) ...(100) ...(1000) ...(10000) ...(65000)
|
||||
48 MHz 10.82 us 100.9 us 1.002 ms 10.01 ms 65.10 ms
|
||||
|
||||
CAUTION: this currently works for a 48 MHz clock, only! As other clock rates
|
||||
appear, there's more math neccessary, see the AVR version. Or simply
|
||||
a second implementation.
|
||||
*/
|
||||
void delay_us(uint16_t delay) {
|
||||
|
||||
#if __SYSTEM_CLOCK == 48000000UL
|
||||
__ASM (".balign 16"); // No gambling with the prefetch engine.
|
||||
while (delay) {
|
||||
__ASM volatile (
|
||||
" nop \n\t" // One nop before the loop slows about 2%.
|
||||
" nop \n\t"
|
||||
" movs r7, #4 \n\t" // One more loop round slows about 20%
|
||||
"1: nop \n\t"
|
||||
" sub r7, #1 \n\t"
|
||||
" cmp r7, #0 \n\t"
|
||||
" bne 1b \n\t"
|
||||
:
|
||||
:
|
||||
: "r7", "cc"
|
||||
);
|
||||
delay--;
|
||||
}
|
||||
#else
|
||||
#error No delay_us() implementation for this CPU clock frequency.
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* defined TEACUP_C_INCLUDE && defined __ARMEL__ */
|
||||
|
|
|
|||
Loading…
Reference in New Issue