2023-10-31 04:33 AM
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();
Solved! Go to Solution.
2023-11-01 06:27 AM - edited 2023-11-01 06:37 AM
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
2023-10-31 06:55 AM
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?
2023-10-31 07:56 AM
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...
2023-10-31 08:47 AM
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
2023-10-31 04:40 PM - edited 2023-10-31 04:50 PM
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
2023-10-31 04:44 PM - edited 2023-10-31 04:50 PM
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
2023-11-01 03:33 AM
Replace
for (; j < 8; j++) {__nop();} //......i = 8: 660ns
by
__nop();
__nop();
__nop();
__nop();
__nop();
__nop();
__nop();
__nop();
I don't use Mbed studio
2023-11-01 05:25 AM
2023-11-01 06:24 AM
Thanks, I'll give it a try!
Sincerely Antoine
2023-11-01 06:27 AM - edited 2023-11-01 06:37 AM
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