Hi
I'm new to to ARM and am working on FRDM25Z board. I would like to calculate the timing for a simple blinking program using Kinetis Studio, but my calculations does not fit my oscilloscope output.
Here is my c program:
#include "MKL25Z4.h"
static int i = 0;
int main(void)
{
SIM_SCGC5 |=0x400; //enable clock to port B
PORTB_PCR19 = 0x100; //Make PTB19 as GPIO
GPIOB_PDDR|=0x80000; //Make BTB19 as output pin
while(1)
GPIOB_PDOR &= ~0x80000; //turn green led on
GPIOB_PDOR |= 0x80000;
}
This compiles to:
51c: b580 push {r7, lr}
51e: af00 add r7, sp, #0
C:\Users\baldurtho\workspace.kds\TestProject_005\Debug/../Sources/main.c:57
//PORT B Data direction register
#define GPIOB_PDDR (*(volatile unsigned int*)0x400FF054)
//PortB Data output register
#define GPIOB_PDOR (*((volatile unsigned int*)0x400FF040))
*/
520: 4a10 ldr r2, [pc, #64] ; (564 <main+0x48>)
522: 4910 ldr r1, [pc, #64] ; (564 <main+0x48>)
524: 4b10 ldr r3, [pc, #64] ; (568 <main+0x4c>)
526: 58cb ldr r3, [r1, r3]
528: 2180 movs r1, #128 ; 0x80
52a: 00c9 lsls r1, r1, #3
52c: 4319 orrs r1, r3
52e: 4b0e ldr r3, [pc, #56] ; (568 <main+0x4c>)
530: 50d1 str r1, [r2, r3]
C:\Users\baldurtho\workspace.kds\TestProject_005\Debug/../Sources/main.c:58
532: 4b0e ldr r3, [pc, #56] ; (56c <main+0x50>)
534: 2280 movs r2, #128 ; 0x80
536: 0052 lsls r2, r2, #1
538: 64da str r2, [r3, #76] ; 0x4c
C:\Users\baldurtho\workspace.kds\TestProject_005\Debug/../Sources/main.c:59
53a: 4b0d ldr r3, [pc, #52] ; (570 <main+0x54>)
53c: 4a0c ldr r2, [pc, #48] ; (570 <main+0x54>)
53e: 6952 ldr r2, [r2, #20]
540: 2180 movs r1, #128 ; 0x80
542: 0309 lsls r1, r1, #12
544: 430a orrs r2, r1
546: 615a str r2, [r3, #20]
C:\Users\baldurtho\workspace.kds\TestProject_005\Debug/../Sources/main.c:62 (discriminator 1)
548: 4b09 ldr r3, [pc, #36] ; (570 <main+0x54>) <baldur: 2 cycles>
54a: 4a09 ldr r2, [pc, #36] ; (570 <main+0x54>) <baldur: 2 cycles>
54c: 6811 ldr r1, [r2, #0] <baldur: 2 cycles>
54e: 4a09 ldr r2, [pc, #36] ; (574 <main+0x58>) <baldur: 2 cycles>
550: 400a ands r2, r1 <baldur: 1 cycle>
552: 601a str r2, [r3, #0] <baldur: 2 cycles>
C:\Users\baldurtho\workspace.kds\TestProject_005\Debug/../Sources/main.c:64 (discriminator 1)
//Delay_ms(500);
554: 4b06 ldr r3, [pc, #24] ; (570 <main+0x54>) <baldur: 2 cycles>
556: 4a06 ldr r2, [pc, #24] ; (570 <main+0x54>) <baldur: 2 cycles>
558: 6812 ldr r2, [r2, #0] <baldur: 2 cycles>
55a: 2180 movs r1, #128 ; 0x80 <baldur: 1 cycle>
55c: 0309 lsls r1, r1, #12 <baldur: 1 cycle>
55e: 430a orrs r2, r1 <baldur: 1 cycle>
560: 601a str r2, [r3, #0] <baldur: 2 cycles>
C:\Users\baldurtho\workspace.kds\TestProject_005\Debug/../Sources/main.c:66 (discriminator 1)
562: e7f1 b.n 548 <main+0x2c> <baldur: 1/3 cycles>
564: 40047000 .word 0x40047000
568: 00001038 .word 0x00001038
56c: 4004a000 .word 0x4004a000
570: 400ff040 .word 0x400ff040 (address of portB on APB bus)
574: fff7ffff .word 0xfff7ffff (=~0x80000)
I have difficulties finding in the startup code what clock frequency I have. I checked by adding 10 "nop" commands.
(this was another strange thing: I found on the net that to dot "nop" I could do: __asm("mov r0,r0");, in C.
Strangely enough this was compiled to adds r0, r0, #0 !!!)
I got 477ns delay so each clock cycle is 4.77ns
( I made one project with processor expert (where I can read the clock on the processor component) and found that by default the clock is 32768x640=20.97MHz and this confirms my clock)
Here comes my problem: when I look at the signal on the scope it is 717 ns high and 618ns low. This would mean 717/47.7=15 clock cycles high and 618/47.7=13 clock cycles low.
But if I count (see above in <> brackets), and I expect the pin to flip on addresses 552 and 560 (the str command) I get 11 cycles low (missing 2 counts) and 14 counts high (assuming 3 clock cycle for branch back) (missing 1 count).
I have read that the pipeline for m0+ is two long so branching might explain the one missing on high side but what explains the two missing on the low side?
I would be happy for any comment, best regards,
Baldur
Hello Baldur,
I'm sorry I mistook your intention.
I think the big error would come from load and instruction cycles.
The 2 cycle is the fastest cycle number and it would not achieve when accessing to GPIO.
Also, as your program has many register dependency and a simple instruction could not finish within 1 cycle.
Generally peaking, cycle calculation by hand will be different from the real results.
You had better use SycTick timer if you want to the time consumption of programs.
Best regards,
Yasuhiko Koumoto.
OK, thanks for your comments, Yasuhiko :-)