delay_macro.asm


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