2 * Timer1 functions for ATTiny85
4 * Heavily based on code from Ardunio:
5 * https://github.com/arduino/Arduino/blob/master/hardware/arduino/avr/cores/arduino/wiring.c
7 * Copyright (c) 2005-2006 David A. Mellis
8 * Copyright 2018 Jonathan McDowell <noodles@earth.li>
10 * This program is free software: you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation, either version 3 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program. If not, see <http://www.gnu.org/licenses/>.
25 #include <avr/interrupt.h>
27 #include <util/delay.h>
29 #include <avr/pgmspace.h>
33 #define clockCyclesPerMicrosecond() (F_CPU / 1000000L)
34 /* Prescaler of 64 from CPU_CLK */
35 #define MICROSECONDS_PER_TIMER1_OVERFLOW (64 * 256 / clockCyclesPerMicrosecond())
36 #define MILLIS_INC (MICROSECONDS_PER_TIMER1_OVERFLOW / 1000)
37 #define FRACT_INC ((MICROSECONDS_PER_TIMER1_OVERFLOW % 1000) >> 3)
38 #define FRACT_MAX (1000 >> 3)
40 volatile unsigned long timer1_overflow_count = 0;
41 volatile unsigned long timer1_millis = 0;
42 static unsigned char timer1_fract = 0;
47 * bit 7: 0 (CTC1: Disabled CTC)
48 * bit 6/5: 00 (COM1A1/COM1A0: Disconnect counter from OC1A output)
49 * bit 3-0: 0111 (CS13/CS12/CS11/CS10: CPU_CK/64)
51 TCCR1 = (1 << CS12) | (1 << CS11) | (1 << CS10);
53 /* Initialise counter */
56 /* Disable Timer 1 output compare match interrupt */
57 TIMSK &= ~(OCIE1A | OCIE1B);
58 /* Enable Timer 1 overflow interrupt */
62 unsigned long micros(void)
65 uint8_t oldSREG = SREG, t;
68 m = timer1_overflow_count;
71 if ((TIFR & _BV(TOV1)) & (t < 255))
76 return ((m << 8) + t) * (64 / clockCyclesPerMicrosecond());
79 unsigned long millis(void)
82 uint8_t oldSREG = SREG;
91 SIGNAL(TIMER1_OVF_vect)
93 unsigned long m = timer1_millis;
94 unsigned char f = timer1_fract;
105 timer1_overflow_count++;