Skip to main content
AD_716
Associate III
October 31, 2023
Solved

How long is __NOP()

  • October 31, 2023
  • 4 replies
  • 8351 views

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();
This topic has been closed for replies.
Best answer by AD_716

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

4 replies

AScha.3
Super User
October 31, 2023

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
October 31, 2023

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

AD_716
AD_716Author
Associate III
October 31, 2023

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

KnarfB
Super User
October 31, 2023

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

AD_716
AD_716Author
Associate III
October 31, 2023

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

KnarfB
Super User
November 1, 2023
Nikita91
Lead II
November 1, 2023

Replace 

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

by

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

I don't use Mbed studio

 

AD_716
AD_716Author
Associate III
November 1, 2023

Thanks, I'll give it a try!

Sincerely Antoine