1 | ;
|
2 | ; wait_ns waittime in ns , cyles already used
|
3 | ;
|
4 | ; cycles already used will be subtracted from the delay
|
5 | ; the waittime resolution is 1 cycle (delay from exact to +1 cycle)
|
6 | ; the maximum delay at 20MHz (50ns/clock) is 38350ns
|
7 | ;
|
8 | .set Osc_Hz = 7372800
|
9 | .set cyle_time_ns = (1000000000 / Osc_hz)
|
10 | .def wait_reg = r16
|
11 |
|
12 | .macro wait_ns
|
13 | .set cycles = (@0 / cyle_time_ns + 1 - @1)
|
14 | .if (cycles > (255 * 3 + 2))
|
15 | .error "MACRO wait_ns - too many cycles to burn"
|
16 | .else
|
17 | .if (cycles > 3)
|
18 | .set loop_cycles = (cycles / 3)
|
19 | ldi wait_reg,loop_cycles
|
20 | dec wait_reg
|
21 | brne pc-1
|
22 | .set cycles = (cycles - (loop_cycles * 3))
|
23 | .endif
|
24 | .if (cycles > 0)
|
25 | .if (cycles & 2)
|
26 | nop
|
27 | nop
|
28 | .endif
|
29 | .if (cycles & 1)
|
30 | nop
|
31 | .endif
|
32 | .endif
|
33 | .endif
|
34 | .endmacro
|
35 | ;
|
36 | ; examples
|
37 | ;
|
38 | example: wait_ns 1000,0 ;want to wait 1000ns after previous instruction
|
39 | ldi r17,42
|
40 | wait_ns 500,1 ;want to wait 500ns including the previous instruction
|
41 | subi r17,42
|
42 | rcall my_delay ;the wait is going to be re-used
|
43 | tst r17
|
44 | rjmp example
|
45 |
|
46 |
|
47 | my_delay: wait_ns 2000,7 ;rcall/ret take 7 clocks
|
48 | ret
|