src/timer.c
author Tero Marttila <terom@paivola.fi>
Wed, 24 Sep 2014 22:30:34 +0300
changeset 2 3420bd6d2d10
parent 1 04b8d469ae4c
permissions -rw-r--r--
hgignore
1
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     1
#include <avr/interrupt.h>
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     2
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     3
#include "stdlib.h"
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     4
#include "timer.h"
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     5
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     6
void timer_init (void)
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     7
{
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     8
    TCCR1A = (
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     9
            // OC1A output pin disconnected
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    10
            0b00 << COM1A0
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    11
            // OC1B output pin disconnected
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    12
        |   0b00 << COM1B0
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    13
            // no PWM
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    14
        |   0b00 << WGM10
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    15
    );
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    16
    TCCR1B = (
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    17
            // CTC mode
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    18
            0b01 << WGM12
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    19
    );
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    20
    TCCR1C = 0;
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    21
}
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    22
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    23
static void timer1_set ()
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    24
{
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    25
    sbi(&TIMER_FLAGS, TIMER1_BUSY);
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    26
}
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    27
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    28
static void timer1_start (short cycles)
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    29
{
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    30
    // count up from zero...
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    31
    TCNT1 = 0;
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    32
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    33
    // ...to the given number of timer cycles
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    34
    OCR1A = cycles;
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    35
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    36
    // start!
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    37
    timer1_set();
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    38
    TIMSK1 = (
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    39
            // OCA interrupt
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    40
            0b1 << OCIE1A       // enable
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    41
    );
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    42
    TCCR1B = (
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    43
            // WGM
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    44
            0b01  << WGM12      // CTC
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    45
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    46
            // clocksource
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    47
        |   0b101 << CS10       // 1024'th
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    48
    );
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    49
}
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    50
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    51
/*
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    52
 * Keep the timer running, but clear the flag..
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    53
 */
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    54
static void timer1_clear ()
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    55
{
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    56
    cbi(&TIMER_FLAGS, TIMER1_BUSY);
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    57
}
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    58
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    59
/*
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    60
 * Stop the timer at its current value.
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    61
 */
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    62
static void timer1_stop ()
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    63
{
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    64
    // WGM: normal
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    65
    // clocksource: stop
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    66
    TCCR1B = 0;
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    67
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    68
    timer1_clear();
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    69
}
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    70
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    71
ISR(TIMER1_COMPA_vect)
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    72
{
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    73
    timer1_clear();
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    74
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    75
    // cpu will wake up from sleep()
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    76
}
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    77
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    78
/*
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    79
 * Sleep on timer1 interrupt.
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    80
 *
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    81
 * Starts fresh timer that sleeps given cycles if given, or continues on the running timer.
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    82
 *
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    83
 * Returns 1 on timeout, 0 on other interrupt.
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    84
 */
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    85
byte timer_sleep (unsigned cycles)
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    86
{
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    87
    if (cycles) {
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    88
        // set fresh timer
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    89
        timer1_start(cycles);
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    90
    } else {
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    91
        // wait for next cycle...
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    92
        timer1_set();
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    93
    }
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    94
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    95
    // sleep while timer is running
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    96
    // XXX: atomic?
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    97
    if (tbi(&TIMER_FLAGS, TIMER1_BUSY)) {
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    98
        // TODO: PRR
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    99
        SMCR = (
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   100
                // idle sleep
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   101
                (0b00 << SM0)
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   102
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   103
                // enable sleep
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   104
            |   (0b1 << SE)
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   105
        );
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   106
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   107
        // sleep
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   108
        __asm__ ( "sleep" :: );
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   109
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   110
        // cleanup
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   111
        SMCR = 0;
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   112
    }
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   113
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   114
    if (tbi(&TIMER_FLAGS, TIMER1_BUSY)) {
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   115
        // interrupt
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   116
        return 0;
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   117
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   118
    } else {
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   119
        // timeout
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   120
        return 1;
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   121
    }
04b8d469ae4c import timer with header from qmsk-dmx
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   122
}