44 // clocksource |
49 // clocksource |
45 | 0b101 << CS10 // 1024'th |
50 | 0b101 << CS10 // 1024'th |
46 ); |
51 ); |
47 } |
52 } |
48 |
53 |
|
54 /* |
|
55 * Keep the timer running, but clear the flag.. |
|
56 */ |
|
57 static void timer1_clear () |
|
58 { |
|
59 cbi(&TIMER_FLAGS, TIMER1_BUSY); |
|
60 } |
|
61 |
|
62 /* |
|
63 * Stop the timer at its current value. |
|
64 */ |
49 static void timer1_stop () |
65 static void timer1_stop () |
50 { |
66 { |
51 // WGM: normal |
67 // WGM: normal |
52 // clocksource: stop |
68 // clocksource: stop |
53 TCCR1B = 0; |
69 TCCR1B = 0; |
54 |
70 |
55 cbi(&TIMER_FLAGS, TIMER1_BUSY); |
71 timer1_clear(); |
56 } |
72 } |
57 |
73 |
58 ISR(TIMER1_COMPA_vect) |
74 ISR(TIMER1_COMPA_vect) |
59 { |
75 { |
60 timer1_stop(); |
76 timer1_clear(); |
61 |
77 |
62 // XXX: cpu will automatically wake up from sleep() |
78 // cpu will wake up from sleep() |
63 } |
79 } |
64 |
80 |
65 /* |
81 /* |
66 * Sleep on timer1 interrupt. |
82 * Sleep on timer1 interrupt. |
67 * |
83 * |
68 * Returns 0 on interrupt, 1 on timeout. |
84 * Starts fresh timer that sleeps given cycles if given, or continues on the running timer. |
|
85 * |
|
86 * Returns 1 on timeout, 0 on other interrupt. |
69 */ |
87 */ |
70 char timer_sleep (unsigned cycles) |
88 char timer_sleep (unsigned cycles) |
71 { |
89 { |
72 if (cycles) { |
90 if (cycles) { |
73 // set timer |
91 // set fresh timer |
74 timer1_start(cycles); |
92 timer1_start(cycles); |
|
93 } else { |
|
94 // wait for next cycle... |
|
95 timer1_set(); |
75 } |
96 } |
76 |
97 |
77 // sleep |
98 // sleep while timer is running |
78 // TODO: PRR |
99 // XXX: atomic? |
79 SMCR = ( |
100 if (tbi(&TIMER_FLAGS, TIMER1_BUSY)) { |
80 // idle sleep |
101 // TODO: PRR |
81 (0b00 << SM0) |
102 SMCR = ( |
|
103 // idle sleep |
|
104 (0b00 << SM0) |
82 |
105 |
83 // enable sleep |
106 // enable sleep |
84 | (0b1 << SE) |
107 | (0b1 << SE) |
85 ); |
108 ); |
86 |
|
87 // sleep |
|
88 __asm__ ( "sleep" :: ); |
|
89 |
109 |
90 // cleanup |
110 // sleep |
91 SMCR = 0; |
111 __asm__ ( "sleep" :: ); |
92 |
112 |
93 if (cycles && !tbi(&TIMER_FLAGS, TIMER1_BUSY)) { |
113 // cleanup |
|
114 SMCR = 0; |
|
115 } |
|
116 |
|
117 if (tbi(&TIMER_FLAGS, TIMER1_BUSY)) { |
|
118 // interrupt |
|
119 return 0; |
|
120 |
|
121 } else { |
94 // timeout |
122 // timeout |
95 return 1; |
123 return 1; |
96 } else { |
|
97 timer1_stop(); |
|
98 |
|
99 // interrupt |
|
100 return 0; |
|
101 } |
124 } |
102 } |
125 } |
103 |
126 |
104 |
127 |