Confusing behavior of __asm__ __volatile__("nop")
Hello dear ST-Community,
I'm currently working on a 8-Bit interface for a TFT-Display. I'm using a STM32F405RGT6 for the Project.
While debugging a timing issue i ran into, I found an interesting behavior when using __asm__ __volatile__("nop") for ns-scale delay. Here is the interesting portion of the code:
#define DELAY_5NS {__asm__ __volatile__("nop");}
#define DELAY_10NS {DELAY_5NS; DELAY_5NS;}
#define DELAY_15NS {DELAY_10NS; DELAY_5NS;}
#define DELAY_20NS {DELAY_10NS; DELAY_10NS;}
#define DELAY_25NS {DELAY_20NS; DELAY_5NS;}
#define DELAY_50NS {DELAY_20NS; DELAY_20NS; DELAY_10NS;}
#define DELAY_75NS {DELAY_50NS; DELAY_25NS;}
#define DELAY_100NS {DELAY_50NS; DELAY_50NS;}
#define DELAY_150NS {DELAY_100NS; DELAY_50NS;}
#define DELAY_200NS {DELAY_100NS; DELAY_100NS;}
#define DELAY_250NS {DELAY_150NS; DELAY_100NS;}
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_USB_DEVICE_Init();
MX_TIM1_Init();
GPIOC->MODER = 0x55555555 & 0xFFFF; // Setting Pins 0-7 of Port C as output
GPIOC->OSPEEDR = 0x55555555 & 0xFFFF; // Setting Pins 0-7 of Port C as "medium speed"
while (1)
{
GPIOC->BSRR = 0b0000000011111111;
DELAY_5NS;
GPIOC->BSRR = 0b0000000011111111 << 16;
DELAY_5NS;
}
}When I observe PC0 (or any of PC0-7) without a delay like so:
while(1)
{
GPIOC->BSRR = 0b0000000011111111;
GPIOC->BSRR = 0b0000000011111111 << 16;
}I get a Period of routhly 71,5 ns (about 12 cycles at 168MHz ?)
When running the code with DELAY_5NS (acually about 5,9ns at 168MHz) I expect an increased period of about 11-12ns. what I get is exactly have of it. I can also clearly see why, because there is absolutely no difference between the following two snippets with respect to timing:
while(1)
{
GPIOC->BSRR = 0b0000000011111111;
GPIOC->BSRR = 0b0000000011111111 << 16;
DELAY_5NS;
}
// same as
while(1)
{
GPIOC->BSRR = 0b0000000011111111;
DELAY_5NS;
GPIOC->BSRR = 0b0000000011111111 << 16;
DELAY_5NS;
}I canprove it with oscilloscope screenshots, but I have to find a USB-Stick first.
The delay between the GPIO-Operations has to be at least DELAY_15NS to affect the actual signal on the scope.
So the question is obviously: WHY?
And how can I take this into account when dealing with complicated timing problems?
Thanks in advance for feedback!
Greetings
Johannes
