cancel
Showing results for 
Search instead for 
Did you mean: 

Nanosecond delay

joe23
Associate II
Posted on March 18, 2018 at 15:32

EDIT: Not sure where my intro paragraph went on the first time I posted.

I have the below code working with inline assembly nops. Now I want to have the code be clock independent. The below code is my attempt at doing this. The problem is the loops end up being 5-10 loops, which doesn't give me the needed resolution to get accurate 850ns, 800ns, 450ns , 400ns delays. Is there a better way to get nanosecond delays?

#define LOOPS_FOR_NS(ns) (ns * 800U / (SystemCoreClock / 1000))
uint32_t loops400ns = LOOPS_FOR_NS(400U);
uint32_t loops450ns = LOOPS_FOR_NS(450U);
uint32_t loops800ns = LOOPS_FOR_NS(800U);
uint32_t loops850ns = LOOPS_FOR_NS(850U);
volatile uint32_t loops;
for (;;) {
 if (p & bitMask) { // ONE
 // High 800ns
 port->BSRR = setPin;
 loops = loops800ns;
 asm(
 'mydelay_800:'
 'subs %[loops], 1;'
 'bne mydelay_800;'
 : // no output
 : [loops] 'r'(loops)
 );
 // Low 450ns
 port->BSRR = resetPin;
 loops = loops450ns;
 asm(
 'mydelay_450:'
 'subs %[loops], 1;'
 'bne mydelay_450;'
 : // no output
 : [loops] 'r'(loops)
 );
 } else { // ZERO
 // High 400ns
 port->BSRR = setPin;
 loops = loops400ns;
 asm(
 'mydelay_400:'
 'subs %[loops], 1;'
 'bne mydelay_400;'
 : // no output
 : [loops] 'r'(loops)
 );
 // Low 850ns
 port->BSRR = resetPin;
 loops = loops850ns;
 asm(
 'mydelay_850:'
 'subs %[loops], 1;'
 'bne mydelay_850;'
 : // no output
 : [loops] 'r'(loops)
 );
 }
 if (bitMask >>= 1) {
 // Move on to the next pixel
 asm('nop;');
 } else {
 if (ptr >= end) {
 break;
 }
 p = *ptr++;
 bitMask = 0x80;
 }
}�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

9 REPLIES 9
henry.dick
Senior II
Posted on March 19, 2018 at 11:14

absolutely correct.

Posted on March 19, 2018 at 13:54

DWT_CYCCNT works well at benchmarking.

Better to use a TIM for hard signal placement, either modulating the PWM, or driving GPIO+DMA

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Uwe Bonnes
Principal II
Posted on March 19, 2018 at 15:30

These delay will jitter if interrupts happen. Why not look at some fast running counter and wait until that counter reaches some value you precalculate?

henry.dick
Senior II
Posted on March 19, 2018 at 15:55

Software delays aren't that useful for precision timing, as they are dependent on too many factors.

Nano seconds delays using software are even worse.

If you absolutely have to have extremely short delays, think of hardware based solutions instead. 

joe23
Associate II
Posted on March 19, 2018 at 15:57

Thanks, I think I'm going to look at DMA based Timers and see if I can get that to work.

Posted on March 19, 2018 at 16:00

Are you signalling an LED controller?

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on March 19, 2018 at 16:13

Yes, trying to drive Adafruit NeoPixel (

https://www.adafruit.com/product/1138

) 2m strip of RGB LEDs
Posted on March 19, 2018 at 16:38

There have been other threads related to WS2812B type devices, basically modulating PWM from a large pattern buffer, ie Update loads new CCRx

Driving multiple devices via a common GPIO bank with TIM triggered DMA to GPIOx->ODR or GPIOx->BSRR.

On F4 would need to use DMA2

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on March 19, 2018 at 16:48

People have been driving those things with 8 bit mcus so you can certainly do it with a faster and more capable chip. Lots of possibilities.