Details | Last modification | View Log | SVN | RSS feed
| Rev | Author | Line No. | Line |
|---|---|---|---|
| 74 | arune | 1 | |
| 2 | #ifndef _delay_h_ |
||
| 3 | #define _delay_h_ |
||
| 4 | |||
| 5 | #include <inttypes.h> |
||
| 6 | #include <avr/io.h> |
||
| 7 | |||
| 8 | /* delay function for microsec |
||
| 9 | 4 cpu cycles per loop + 1 cycles(?) overhead |
||
| 10 | when a constant is passed. */ |
||
| 11 | static inline void delayloop16(uint16_t count) |
||
| 12 | { |
||
| 13 | asm volatile ( "cp %A0,__zero_reg__ \n\t" \ |
||
| 14 | "cpc %B0,__zero_reg__ \n\t" \ |
||
| 15 | "breq L_Exit_%= \n\t" \ |
||
| 16 | "L_LOOP_%=: \n\t" \ |
||
| 17 | "sbiw %0,1 \n\t" \ |
||
| 18 | "brne L_LOOP_%= \n\t" \ |
||
| 19 | "L_Exit_%=: \n\t" \ |
||
| 20 | : "=w" (count) |
||
| 21 | : "0" (count) |
||
| 22 | ); |
||
| 23 | } |
||
| 24 | // delayloop16(x) eats 4 cycles per x |
||
| 25 | #define DELAY_US_CONV(us) ((uint16_t)(((((us)*1000L)/(1000000000/F_OSC))-1)/4)) |
||
| 26 | #define delay_us(us) delayloop16(DELAY_US_CONV(us)) |
||
| 27 | |||
| 28 | /* delay function for millisec |
||
| 29 | (6 cycles per x + 20(?) overhead) */ |
||
| 30 | void delayloop32( uint32_t l); // not inline |
||
| 31 | #define DELAY_MS_CONV(ms) ( (uint32_t) (ms*(F_OSC/6000L)) ) |
||
| 32 | #define delay_ms(ms) delayloop32(DELAY_MS_CONV(ms)) |
||
| 33 | |||
| 34 | /* mth 9/04: |
||
| 35 | Remark uSeconds: |
||
| 36 | Main Oscillator Clock given by F_OSC (makefile) in Hz |
||
| 37 | one CPU-Cycle takes 1/F_OSC seconds => 1000000/F_OSC uSeconds |
||
| 38 | so: 1 uSecond takes F_OSC/1000000 CPU-Cyles. The following code |
||
| 39 | is inspired by the avr-libc delay_loop2 function. |
||
| 40 | This it not "that precise" since it takes at least 4 cycles |
||
| 41 | but should be o.k. with any parameter (even 0). |
||
| 42 | Call function with delayloop(DELAYUS(dt [in uSeconds])). |
||
| 43 | */ |
||
| 44 | |||
| 45 | #endif |