This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

How to count cycles on ARM cortex m0+?

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:

int main(void)

{

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))

*/

SIM_SCGC5 |=0x400; //enable clock to port B

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

PORTB_PCR19 = 0x100; //Make PTB19 as GPIO

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

GPIOB_PDDR|=0x80000; //Make BTB19 as output pin

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)

while(1)

{

GPIOB_PDOR &= ~0x80000; //turn green led on

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);

GPIOB_PDOR |= 0x80000;

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)

//Delay_ms(500);

}

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