cancel
Showing results for 
Search instead for 
Did you mean: 

How long is __NOP()

AD_716
Associate III

Hello,

How long does the __NOP() function last?
Is it the time of a cycle? Or 1/F = cycle time?
My MCU is an STM32F401RE, and I understand that the maximum frequency is 84 Mhz.
So 1/84 Mhz = 11.90 ns, is that the time of a cycle?

In my case, if I loop 14 times on __NOP(), it takes 1.24us or 1240 ns (measured with an oscilloscope).
But if I do 14 x 11.90 ns, I get 167 ns...
Does anyone have an explanation?

Thank you in advance for your valuable answers

Sincerely, Antoine
Code:

 

    __disable_irq();
    
    for (int i = 0; i < (nLed * (nBytePerLed * nBit8)); i++) 
        {
            int j = 0;
            Data = 1;
            if (data[i])
                {// ONE
                    for (; j < 8; j++) {__nop();} //......i = 8: 660ns
                    Data = 0;
                    for (; j < 14; j++) {__nop();}//......i = 14: 1.24us
                } 
            else 
                {// ZERO
                    for (; j < 3; j++) {__nop();}//.......i = 3: 380ns
                    Data = 0;
                    for (; j < 13; j++) {__nop();}//......i = 3: 1.20us
            }
        }
    
    __enable_irq();
1 ACCEPTED SOLUTION

Accepted Solutions

Thank you, I have already seen and read this tutorial.

My problem is that all my code is on Mbed.
The WS2812 are about 1/10th of my total program!...

That's why I can't use this tutorial!

There must be a way to do DMA from another compiler?

Why not use Tickers to send the Bit frame?
This would avoid disabling interrupts?

Sincerely Antoine

View solution in original post

9 REPLIES 9
AScha.3
Principal III

the nop will need one clock (i assume - to be 100% sure, look at the manual at ARM for this core).

to see, what you producing with the C compiler, first look at the assembler output !

and most important: all depends on the optimizer settings - what you set here?

If you feel a post has answered your question, please click "Accept as Solution".
Nikita91
Lead II

What you are measuring is loop time, not NOP time.

Look at the generated code in the debug/xxx.list file

Replace the loops with the corresponding series of NOP...

KnarfB
Principal III

Looks like you want to do some WS2812B... LED driver. There are much more efficient methods for that, like DMA, SPI. Doing such small periods by bit-banging easily leads into a dead-end.

hth

KnarfB

Good evening,

Thank you for your answer,
Yes, I want to drive WS2812. This function is taken from NeoPixel, I simply adapted the __NOP() time loop to make it work on STM32F4.

I can't use SPI or UART because I'm already busy with other functions.
I've seen that others use DMA but I haven't found any concrete examples, and never in the examples is a pin assigned to drive the LEDs. I don't understand how to implement DMA without CubeProgrammer, I code with Mbed studio.

Do you have any examples? Any advice, as my search for DMA is going nowhere...

Thanks in advance

Best regards,
Antoine

Good evening,

Thank you for your answer,
I understand better why my calculations are wrong. Thanks for the tip.
I'll take a look at the Debug file, but it's new to me! It's in the BUILD folder of the project?

What do you mean by: "Replace the loops with the corresponding series of NOP..."

Thanks in advance

Best regards,
Antoine

Nikita91
Lead II

Replace 

  for (; j < 8; j++) {__nop();} //......i = 8: 660ns

by

__nop();
__nop();
__nop();
__nop();
__nop();
__nop();
__nop();
__nop();

I don't use Mbed studio

 

Thanks, I'll give it a try!

Sincerely Antoine

Thank you, I have already seen and read this tutorial.

My problem is that all my code is on Mbed.
The WS2812 are about 1/10th of my total program!...

That's why I can't use this tutorial!

There must be a way to do DMA from another compiler?

Why not use Tickers to send the Bit frame?
This would avoid disabling interrupts?

Sincerely Antoine