Nios® V/II Embedded Design Suite (EDS)
Support for Embedded Development Tools, Processors (SoCs and Nios® V/II processor), Embedded Development Suites (EDSs), Boot and Configuration, Operating Systems, C and C++
12600 Discussions

Help with us delay routine in C

Altera_Forum
Honored Contributor II
1,360 Views

Hi...I am trying to create an i2c engine in Nios to read and write to an external seeprom. The problem I am having is developing an accurate micro second delay routine for the protocol. I know the nr_delay function is for milliseconds and I'm not even sure of the accuracy of that function. I'm still a little new to C programming. One quick and dirty approach is the use of nop commands in a loop, but I don't know if the asm nop command timing is based off of my 48MHz clock coming into the chip or some predefined time. Does anyone know? Can anyone suggest something to help? 

Thanks.
0 Kudos
1 Reply
Altera_Forum
Honored Contributor II
400 Views

Here's some code that may be close enough for what you are 

doing. The following delays for a number of clock cycles. You'll 

need to define the size of the instruction cache: 

 

/* * dly_clks * * Instruction performance varies based on the core. For cores * with icache and static/dynamic branch prediction (II/f, II/s): * *  Normal ALU (e.g. add, cmp, etc):    1 cycle *  Branch (correctly predicted, taken):    2 cycles *    Negative offset is predicted (II/s). * * For cores without icache and/or no branch prediction (II/e): * *  Normal ALU (e.g. add, cmp, etc):    6 cycles *  Branch (no prediction):      6 cycles * * For simplicity, if an instruction cache is implemented * assume II/f or II/s. Otherwise, assume the II/e. * */  .globl dly_clks dly_clks: # if (ICACHE_SIZE > 0)        subi    r4, r4, 3                /* 3 clocks/loop */# else        subi    r4, r4, 12              /* 12 clocks/loop */# endif        bge    r4, r0, dly_clks        ret 

 

You can then base your delay routine on the configured 

cpu clock speed. For example: 

 

 

extern void dly_clks (unsigned long ticks); void udelay (unsigned long usec) {        unsigned long cnt = (SYS_CLK_FREQ/1000000) * usec;        dly_clks (cnt); } 

 

Your mileage may vary based on your clock & cache config ;-) 

 

Regards, 

--Scott
0 Kudos
Reply