Cortex M0+ delay routine without timers

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Cortex M0+ delay routine without timers

1,770 Views
riglesias2021
Contributor III

Hello, I´m trying to implement a small assembly routine in a cortex M0+ in order to introduce a software controlled delay in microseconds. For performing this, i wrote this small while() routine:

      while (CyclesToDelay > 0)
      {
         __no_operation();
         CyclesToDelay--;
      }


So, knowing exactly what assembly instructions are executing, the clk clock frequency, and the number of clk cycles per instruction, I can calculate the CyclesToDelay value for a desired delay to introduce.

Assembly:

__no_operation();
0002 73F8 NOP
CyclesToDelay--;
0002 73FA LDR R1, [R0]
0002 73FC SUBS R1, R1, #1
0002 73FE STR R1, [R0]
while (CyclesToDelay > 0)
0002 7400 LDR R1, [R0]
0002 7402 CMP R1, #0
0002 7404 BNE 0x000273F8


Instruction clk cycles according https://developer.arm.com/documentation/ddi0432/c/programmers-model/instruction-set-summary are:

NOP 1 clk cycles

LDR 2 clk cycles

SUBS 1 clk cycles

STR  2 clk cycles

LDR 2 clk cycles

CMP 1 clk cycles

BNE 3 clk cycles

Total clk cycles in this routine = 12 clk cycles,

CORE_CLK = 48mhz



Then,

1) 1 CORE_CLK cycle = 1 / 48 us

2) 12 CORE_CLK cycles = 12/48 us ( The number of microseconds one loop of this routine should delay)


Finally:

3)  CyclesToDelay *  (12/48) = delay_we_want_to_introduce(us) 

     or

     CyclesToDelay = delay_we_want_to_inject(us) * 48 / 12


However, measuring the delays obtained with this method does not seem to be very accurate. I dont know if this is going to be deterministic or if this is totally possible in this Cortex M0+. Feedback would be appreciated. Many thanks.

0 Kudos
Reply
3 Replies

1,743 Views
danielmartynek
NXP TechSupport
NXP TechSupport

Hello @riglesias2021,

It does not depend just on the core.

Although the S32K11x series is not that complicated, we can get different results when

  • the delay code is placed in SRAM:

danielmartynek_0-1650633876998.png

PTE8 Toggles every 0.9177ms instead of 1ms

danielmartynek_1-1650633929528.png

  • In Flash with Prefetch buffer enabled: 1.085ms

danielmartynek_2-1650634071884.png

danielmartynek_3-1650634102250.png

  • In Flash with Prefetch buffer disabled: 1.585ms
MSCM->OCMDR[0] |= (1<<4) | (1<<5);

danielmartynek_4-1650634155919.png

 

Please refer to the RM, Section 35.5.2 Speculative reads for more information about the buffer.

 

 

Regadrs,

Daniel

 

 

 

 

0 Kudos
Reply

1,717 Views
riglesias2021
Contributor III

@danielmartynek  Thanks for the reply, It seems that i dont have the Prefetch buffer enabled, Its is possible to determine with exactitude the delay of this routine with a specific MSCM config?

0 Kudos
Reply

1,705 Views
danielmartynek
NXP TechSupport
NXP TechSupport

 

Hi @riglesias2021,

The prefetch buffer is enabled by default.

danielmartynek_1-1650891540337.png

danielmartynek_3-1650891597947.png

danielmartynek_5-1650891969237.png

 

But anyway, I don't think we can determine the accuracy of the timing.

Even with the prefetch buffer disabled, it depends on the location of the code in the flash.

Also, the core accesses the Flash via the Crossbar switch.

The eDMA could add other wait states because of the arbitration on the switch,

danielmartynek_6-1650892565573.png

 

I would recommend using HW timers.

 

Regards,

Daniel

 

 

 

 

 

 

 

0 Kudos
Reply