Author Topic: delays for ARM  (Read 4962 times)

0 Members and 1 Guest are viewing this topic.

Offline SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 17937
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
delays for ARM
« on: September 28, 2019, 04:49:54 pm »
i am writing a library to talk to the hitachi LCD controller. I see that i would need to assert signal for some ns, even at 48MHz that is hardly worthy of doing any timer based go aways and come back's as it's a couple of clock cycles.

There is i see no standard delay function for ARM. I expect i need to write my own. Anything to be aware of? I take it I need to run some sort of loop that just goes round in circles "x" amount of times based on F_CPU.
 

Offline tggzzz

  • Super Contributor
  • ***
  • Posts: 20242
  • Country: gb
  • Numbers, not adjectives
    • Having fun doing more, with less
Re: delays for ARM
« Reply #1 on: September 28, 2019, 04:58:49 pm »
i am writing a library to talk to the hitachi LCD controller. I see that i would need to assert signal for some ns, even at 48MHz that is hardly worthy of doing any timer based go aways and come back's as it's a couple of clock cycles.

There is i see no standard delay function for ARM. I expect i need to write my own. Anything to be aware of? I take it I need to run some sort of loop that just goes round in circles "x" amount of times based on F_CPU.

If there are caches or interrupts, they could introduce jitter.
There are lies, damned lies, statistics - and ADC/DAC specs.
Glider pilot's aphorism: "there is no substitute for span". Retort: "There is a substitute: skill+imagination. But you can buy span".
Having fun doing more, with less
 

Offline SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 17937
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: delays for ARM
« Reply #2 on: September 28, 2019, 05:07:57 pm »
Well I don't have a problem with the display data transaction being delayed by interupts. It's a case of a signal needs asserting for a minimum time like 200ns (10 ticks at 48MHz) but if that has to be delayed by an interrupt so be it.
 

Offline Kjelt

  • Super Contributor
  • ***
  • Posts: 6545
  • Country: nl
Re: delays for ARM
« Reply #3 on: September 28, 2019, 06:28:26 pm »
Anything to be aware of? I take it I need to run some sort of loop that just goes round in circles "x" amount of times based on F_CPU.
Yes:
1 code that has no real functionality has a large chance to becremoved if you set/enable the optimizer compiler options.
To prevent this read or increment some "volatile" declared variable in your loop.
Always check the resulting assembly after setting optimizer options, compikers can be very smart these days   ;)

2 Portability. your loop is tuned to your current cpu frequency.
Sometimes you want to lower the power consumption by lowering peripheral and/or cpu frequency and you run into problems. Or for portability in another project with other faster cpu the cpu clock differs. Anyway, The neat way of doing this is setting your cpu speed depending on some sort of #define value . You can use this value in your loop to determine the length to wait. Edit: see you already will use that  :-+

3 use an rtos or own os that does something usefull in the mean time your peripheral has to wait on the slow secondary hardware to become ready.
« Last Edit: September 28, 2019, 06:30:17 pm by Kjelt »
 

Offline SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 17937
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: delays for ARM
« Reply #4 on: September 28, 2019, 06:50:15 pm »
Well with a 20.8 ns clock a 1µs delay is 48 cycles. what can be done in 48 cycles? other delays are 450ns, 195ns and as low as 20ns.

Page 49 of the attached.
 

Online SiliconWizard

  • Super Contributor
  • ***
  • Posts: 15095
  • Country: fr
Re: delays for ARM
« Reply #5 on: September 28, 2019, 06:52:35 pm »
At the end of this thread: https://www.eevblog.com/forum/programming/while-(youre-down-there-)/

two of us gave a solution for what you need.
 

Offline SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 17937
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: delays for ARM
« Reply #6 on: September 28, 2019, 06:55:11 pm »
obviously at lower clocks the lower delays are not even a problem.
 

Offline SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 17937
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: delays for ARM
« Reply #7 on: September 28, 2019, 06:55:55 pm »
 

Offline Jeroen3

  • Super Contributor
  • ***
  • Posts: 4110
  • Country: nl
  • Embedded Engineer
    • jeroen3.nl
Re: delays for ARM
« Reply #8 on: September 28, 2019, 07:47:51 pm »
I take it I need to run some sort of loop that just goes round in circles "x" amount of times based on F_CPU.
That won't be very precise, and might not compile as intended everywhere. Not that you need it to be, you probably need to have "at least some ns".
Aside from delays being an ugly design pattern. You should put a timer in countdown mode running of system clock. This way your delays are precise, reentrant and scalable if you change system prescaler for energy savings.
Also, you can wait with WFI.

You can use DWT->CYCCNT as suggested above, but it's not enabled by default since uses the DWT, a debug feature, and is missing on the M0.
Plus you'd need to consider rollovers, and will have jitter from event to comparison.
« Last Edit: September 28, 2019, 07:51:40 pm by Jeroen3 »
 

Online SiliconWizard

  • Super Contributor
  • ***
  • Posts: 15095
  • Country: fr
Re: delays for ARM
« Reply #9 on: September 28, 2019, 08:13:32 pm »
You can use DWT->CYCCNT as suggested above, but it's not enabled by default since uses the DWT, a debug feature, and is missing on the M0.
Plus you'd need to consider rollovers, and will have jitter from event to comparison.

The required initialization is mentioned in our code examples. Obviously on parts that don't have DWT, it won't be available.

Roll-over with classic *unsigned* arithmetic is actually a non-problem, as long as it doesn't roll-over more than once (which is impossible with the above code, unless it gets interrupted for a very long time, which would make your delay loop completely borked anyway (a 32-bit counter @100MHz will span over 42s). Something that's nice to know. Keep your variables all unsigned here.

Consider for instance a roll-over, with a start value of 0xFFFFFFF0 and an end value of say, 0x100. Now what is the 32-bit, unsigned difference (0x100 - 0xFFFFFFF0) ? 0x110. Which is still right.
The only problem, as I said, is if it rolls over more than once.

Jitter? Yes it will never be cycle accurate, but still much more predictable and easy to use than an hand-written delay loop in assembly or worse, in C (again unless your target is so simple that you can really write code with a cycle-accurate execution, which is not really possible on most ARM CPUs.)


 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 11615
  • Country: us
    • Personal site
Re: delays for ARM
« Reply #10 on: September 28, 2019, 08:35:33 pm »
Here are busy-wait delay functions I use all the time:

Code: [Select]
__attribute__((noinline, section(".ramfunc")))
static void delay_ms(int ms)
{
  uint32_t cycles = ms * F_CPU / 3 / 1000;

  asm volatile (
    "1: sub %[cycles], %[cycles], #1 \n"
    "   bne 1b \n"
    : [cycles] "+r"(cycles)
  );
}

__attribute__((noinline, section(".ramfunc")))
void delay_cycles(uint32_t cycles)
{
  cycles /= 4;

  asm volatile (
    "1: sub %[cycles], %[cycles], #1 \n"
    "   nop \n"
    "   bne 1b \n"
    : [cycles] "+l"(cycles)
  );
}
Alex
 

Offline westfw

  • Super Contributor
  • ***
  • Posts: 4263
  • Country: us
Re: delays for ARM
« Reply #11 on: September 29, 2019, 08:42:08 am »
At what frequency do ARM Cortex chips start inserting wait-states or other non-deterministic behavior on RAM (.ramfunc, especially)?The 120MHz SAMD51s have Data Cache, but it's not really documented very well when it comes into play...Different CM-n also have different bus structures between CPU and RAM vs Flash...
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 11615
  • Country: us
    • Personal site
Re: delays for ARM
« Reply #12 on: September 29, 2019, 08:45:38 am »
There  are no wait states at 120 MHz in D51. Data cache is only useful for the flash.

Those delays have to be adjusted for the actual core performance. They are not ideal, but they are simple and generally good enough to generate small delays often needed when talking to external devices, like LCDs.
Alex
 

Offline Kjelt

  • Super Contributor
  • ***
  • Posts: 6545
  • Country: nl
Re: delays for ARM
« Reply #13 on: September 29, 2019, 08:46:25 am »
Here are busy-wait .....
That is also IMO a good approach although portability can become an issue and colleague "c only " programmers might object.
 

Offline SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 17937
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: delays for ARM
« Reply #14 on: September 29, 2019, 09:06:21 am »
The idea of a counter based delay is nice but the systic counter while listed on the SAMC datasheet refers me to the arm datasheet for the cpu which I need to find again and the last time I looked at it it was 10 pages of nothing.
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 11615
  • Country: us
    • Personal site
Re: delays for ARM
« Reply #15 on: September 29, 2019, 09:26:03 am »
You need to look for Architecture Reference Manual (armv6m in this case), not the core documentation.

SysTick is good, but better used for the actual system time than delays.
Alex
 

Offline westfw

  • Super Contributor
  • ***
  • Posts: 4263
  • Country: us
Re: delays for ARM
« Reply #16 on: September 29, 2019, 10:10:32 am »
Quote
SysTick is good, but better used for the actual system time than delays.
http://infocenter.arm.com/help/topic/com.arm.doc.dui0662b/Babieigh.html


SysTick is usually used for the relatively slow system tick timer, like the millisecond tick used by Arduino.It's a really simple 24bit down-counter that you can set up with a reload value ("N") that will then cause an interrupt every N clock cycles.  So on your 48MHz system, you'd set the reload value to 4800, and you'd get an interrupt every 1ms.


I've seen some examples that use SysTick to do a delay, but they usually monopolize it and prevent it from being used more normally.   One of my examples linked in the earlier thread showed how to use a free-running systick to do "cylces" delays, as long as the number of cycles was somwhat smaller than the reload value that was being used...
 

Offline SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 17937
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: delays for ARM
« Reply #17 on: September 29, 2019, 10:19:50 am »
i can just check the timer value and see if the difference is long enough, it still means that interupts may extend the delay but this is not a problem and if the delay is long enough the interrupt can happen in the mean time with no change to the delay. It's just that really short delays any code will take longer than the delay itself. The 60ns delay is just 3 cycles so it's more like I need a NOP in C for that. the 20ns delay can be ignored as the time it takes to toggle a pin with 20ns tics should cause a delay that long anyway.

this is M0+ core
 

Offline SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 17937
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: delays for ARM
« Reply #18 on: September 29, 2019, 12:25:07 pm »
Quote
SysTick is good, but better used for the actual system time than delays.
http://infocenter.arm.com/help/topic/com.arm.doc.dui0662b/Babieigh.html


SysTick is usually used for the relatively slow system tick timer, like the millisecond tick used by Arduino.It's a really simple 24bit down-counter that you can set up with a reload value ("N") that will then cause an interrupt every N clock cycles.  So on your 48MHz system, you'd set the reload value to 4800, and you'd get an interrupt every 1ms.


I've seen some examples that use SysTick to do a delay, but they usually monopolize it and prevent it from being used more normally.   One of my examples linked in the earlier thread showed how to use a free-running systick to do "cylces" delays, as long as the number of cycles was somwhat smaller than the reload value that was being used...


So that stuff from arm basically complements the Atmel/Microchip datasheet and will be valid on any M0+ core device?

Yes I usually do timing the same as you with a timer and compare the value of the timer. A rollovor is not a problem, you just check that the value you expect to be higher is not infact lower than the other valu and if it is add 1 to the left side of it, the subtraction that calculates the ticks elapsed will then work.

I fact I have an idea for the fastest possible code. Take the second value and add a 1 to it anyway (if it's a 32 bit processor and a sub 32 bit conter this still means calculations happen in one operation), then carry out the subtraction and only use the bits that correspond to the counter. If the counter did roll over the left most digit will now be 0 anyway. If the left most digit is 1 then the counter did not roll over but ignoring it will make the result right again.

It sort of guarantees the code overhead to always be the same but still takes some cycles. Really the only way to have small delays in the order of 2-3 ticks is NOP I guess.
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 11615
  • Country: us
    • Personal site
Re: delays for ARM
« Reply #19 on: September 29, 2019, 03:39:44 pm »
So that stuff from arm basically complements the Atmel/Microchip datasheet and will be valid on any M0+ core device?
Yes, the hierarchy of documents from less detailed to  more detailed:
1. DDI0419C ARM V6M Architecture Reference Manual
2. DDI0484C Cortex-M0+ Technical Reference Manual
3. Device datasheet.

Less detailed about a specific device, of course. ARM ARM is a huge documents and contains all the details you need about actual instruction set architecture.

The first one describes an abstract architecture. The second one decries a specific core implemented according to that architecture. And the last one describes a specific deice using that core.

To get a full understanding of the device architecture you have to read (or rather consult when needed) all of them.

There are also separate documents describing debug subsystems.

And then there are integration guides, which may be an interesting read, but mostly they are for people actually putting the core into the silicon.
Alex
 

Offline techman-001

  • Frequent Contributor
  • **
  • !
  • Posts: 748
  • Country: au
  • Electronics technician for the last 50 years
    • Mecrisp Stellaris Unofficial UserDoc
Re: delays for ARM
« Reply #20 on: October 02, 2019, 02:13:57 am »
Quote
SysTick is good, but better used for the actual system time than delays.
http://infocenter.arm.com/help/topic/com.arm.doc.dui0662b/Babieigh.html


SysTick is usually used for the relatively slow system tick timer, like the millisecond tick used by Arduino.It's a really simple 24bit down-counter that you can set up with a reload value ("N") that will then cause an interrupt every N clock cycles.  So on your 48MHz system, you'd set the reload value to 4800, and you'd get an interrupt every 1ms.


I've seen some examples that use SysTick to do a delay, but they usually monopolize it and prevent it from being used more normally.   One of my examples linked in the earlier thread showed how to use a free-running systick to do "cylces" delays, as long as the number of cycles was somwhat smaller than the reload value that was being used...

Systick is very handy, I used it to calibrate my in-lined Arm Thumb Machine Code Forth blocking delay.  This is similar to inlined Assembly used with C.

: 105ns  ( u --  )     \  Range 105.2 ns to 451.8640 seconds @48 MHz clock
   [
   $3e01 h,
   $46c0 h,
   $d1fc h,
   ] drop
 ;

For accurate millisecond delays it's called by the "ms" Word.
: ms ( u  -- )   
   9505 * 105ns
;

To generate the Machine Code I write the delay in Assembler.

 .syntax unified
 .cpu cortex-m0
 .thumb
 .text
Vector_Table: .word 0x20000000        @ stack pointer value when stack is empty 0x20000000
ResetVector: .word loop +1            @ Reset Handler

loop:    subs r6,r6,#1     @ subtract 1 from r6. delay number will be in R6 as that's the Forth TOS
           nop
           bne loop             @ when r6 = 0, exit loop


Compile it with arm-none-eabi-*, test it live on the actual CPU with GDB over SWD, Then paste the code from the *.list file into the "105ns" word above.

00000008 <loop>:
   8:   3e01            subs    r6, #1
   a:   46c0            nop                     ; (mov r8, r8)
   c:   d1fc             bne.n   8 <loop

 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf