//=============================================================================
static __is_always_inline void delay_cycles(uint32_t x)
{
#define MAXNOPS 4 // delay_4cycles
if (x<=MAXNOPS)
{
if (x==1) {nop();}
else if (x==2) {nop(); nop();}
else if (x==3) {nop(); nop(); nop();}
else if (x==4) {nop(); nop(); nop(); nop();}
}
else // because of +1 cycle inside delay_4cycles
{
uint32_t rem = (x-1)%MAXNOPS;
if (rem==1) {nop();}
else if (rem==2) {nop(); nop();}
else if (rem==3) {nop(); nop(); nop();}
if ((x=(x-1)/MAXNOPS)) delay_4cycles(x); // if need more then 4 nop loop is more optimal
}
}
Thank you very much!
Allow me to share the results!
The function delay_cycles generates a delay with an accuracy of 1 clock cycle:
delay.h: ======= ======= ======= ======= ======= ======= ======= ======= ======= ======= == uint32_ t cy) // +1 cycle RELOAD_ CYCLES< 2
...
//=====
static __is_always_inline void delay_4cycles(
{
#if ARCH_PIPELINE_
# define EXTRA_NOP_CYCLES "nop"
#else
# define EXTRA_NOP_CYCLES ""
#endif
__asm__ __volatile__
EXTRA_ NOP_CYCLES "\n\t" www.nongnu. org/avr- libc/user- manual/ inline_ asm.html
(
".syntax unified" "\n\t" // is to prevent CM0,CM1 non-unified sintax
"loop%=:" "\n\t"
" subs %[cnt],#1" "\n\t"
" bne loop%=" "\n\t"
: [cnt]"+r"(cy) // output: +r means input+output http://
: // input:
: "cc" // clobbers:
);
}
//===== ======= ======= ======= ======= ======= ======= ======= ======= ======= ======= == uint32_ t x)
static __is_always_inline void delay_cycles(
{
#define MAXNOPS 4 // delay_4cycles
if (x<=MAXNOPS)
{
if (x==1) {nop();}
else if (x==2) {nop(); nop();}
else if (x==3) {nop(); nop(); nop();}
else if (x==4) {nop(); nop(); nop(); nop();}
}
else // because of +1 cycle inside delay_4cycles
{
uint32_t rem = (x-1)%MAXNOPS;
if (rem==1) {nop();}
else if (rem==2) {nop(); nop();}
else if (rem==3) {nop(); nop(); nop();}
if ((x=(x-1)/MAXNOPS)) delay_4cycles(x); // if need more then 4 nop loop is more optimal
}
}