terom@47: #include terom@49: #include "stdlib.h" terom@47: terom@49: #include terom@47: terom@49: #define TIMER_FLAGS GPIOR0 terom@49: #define TIMER1_BUSY 1 terom@49: terom@49: /* terom@49: * Setup timers. terom@49: */ terom@49: void timer_init (void) terom@49: { terom@49: TCCR1A = ( terom@49: // OC1A output pin disconnected terom@49: 0b00 << COM1A0 terom@49: // OC1B output pin disconnected terom@49: | 0b00 << COM1B0 terom@49: // no PWM terom@49: | 0b00 << WGM10 terom@49: ); terom@49: TCCR1B = ( terom@49: // CTC mode terom@49: 0b01 << WGM12 terom@49: ); terom@49: TCCR1C = 0; terom@49: } terom@49: terom@49: void timer1_start (short cycles) terom@49: { terom@49: // count up from zero... terom@49: TCNT1 = 0; terom@49: terom@49: // ...to the given number of timer cycles terom@49: OCR1A = cycles; terom@49: terom@49: // start! terom@49: sbi(&TIMER_FLAGS, TIMER1_BUSY); terom@49: TIMSK1 = ( terom@49: // OCA interrupt terom@49: 0b1 << OCIE1A // enable terom@49: ); terom@49: TCCR1B = ( terom@49: // WGM terom@49: 0b01 << WGM12 // CTC terom@49: terom@49: // clocksource terom@49: | 0b101 << CS10 // 1024'th terom@49: ); terom@49: } terom@49: terom@49: static void timer1_stop () terom@49: { terom@49: // WGM: normal terom@49: // clocksource: stop terom@49: TCCR1B = 0; terom@49: terom@49: cbi(&TIMER_FLAGS, TIMER1_BUSY); terom@49: } terom@49: terom@49: ISR(TIMER1_COMPA_vect) terom@49: { terom@49: timer1_stop(); terom@49: terom@49: // XXX: cpu will automatically wake up from sleep() terom@49: } terom@49: terom@49: /* terom@49: * Sleep on timer1 interrupt. terom@49: */ terom@49: void timer_sleep (int cycles) terom@49: { terom@49: // set timer terom@49: timer1_start(cycles); terom@49: terom@49: // sleep terom@49: // TODO: PRR terom@49: SMCR = ( terom@49: // idle sleep terom@49: (0b00 << SM0) terom@49: terom@49: // enable sleep terom@49: | (0b1 << SE) terom@49: ); terom@49: terom@49: // sleep terom@49: while (tbi(&TIMER_FLAGS, TIMER1_BUSY)) { terom@49: __asm__ ( "sleep" :: ); terom@49: } terom@49: terom@49: // cleanup terom@49: SMCR = 0; terom@49: } terom@47: terom@47: int main (void) terom@47: { terom@49: timer_init(); terom@49: terom@47: // LED terom@49: sbi(&DDRB, DDB5); terom@49: terom@49: sei(); terom@49: terom@49: // blink terom@49: short timeout = 1000; terom@49: short delta = 10; terom@47: terom@47: while (true) { terom@49: // bitflip terom@49: xbi(&PORTB, PORTB5); terom@47: terom@49: timer_sleep(timeout); terom@49: terom@49: timeout += delta; terom@47: } terom@47: }