forked from Arlet/Freecut
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtimer.c
149 lines (133 loc) · 3.45 KB
/
timer.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
/*
* timer.c
*
* Timer 0 is used as overall (slow) event timer, as well sleep delay timer.
* Timer 1 is used as solenoid PWM, through OC1B output
* Timer 2 is used for stepper timing
* Timer 3 is used to generate tones on the speaker through OC3A output,
* period is adjusted for tone.
*
*
* Copyright 2010 <freecutfirmware@gmail.com>
*
* This file is part of Freecut.
*
* Freecut is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2.
*
* Freecut is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
* License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Freecut. If not, see http://www.gnu.org/licenses/.
*
*/
#include <avr/interrupt.h>
#include <avr/io.h>
#include <avr/wdt.h>
#include <string.h>
#include <stdio.h>
#include "timer.h"
#include "stepper.h"
static uint8_t count_Hz = 250;
static uint8_t count_25Hz = 10;
volatile uint8_t flag_Hz;
volatile uint8_t flag_25Hz;
/*
* called @250 Hz, divide further in software for slow events
*/
SIGNAL( SIG_OUTPUT_COMPARE0 )
{
if( --count_25Hz == 0 )
{
count_25Hz = 10;
flag_25Hz = 1;
}
if( --count_Hz == 0 )
{
count_Hz = 250;
flag_Hz = 1;
}
}
/*
* Timer 2 compare match, update stepper motors.
*/
SIGNAL( SIG_OUTPUT_COMPARE2 )
{
stepper_tick( );
}
/*
* Turn on beeper. Hz specifies frequency of the tone.
*/
void beeper_on( int Hz )
{
DDRE |= (1 << 3);
OCR3A = (8000000L + Hz/2) / Hz - 1;
}
void beeper_off( void )
{
DDRE &= ~(1 << 3);
}
/*
* usleep: sleep (approximate/minimum) number of microseconds. We use timer0
* which runs at 62.50 kHz, or at 16 usec/tick. Maximum delay is about 2
* milliseconds . For longer delays, use msleep().
*
*/
void usleep( int usecs )
{
signed char end = TCNT0 + usecs / 16;
while( (signed char) (TCNT0 - end) < 0 )
continue;
}
void msleep( unsigned msecs )
{
while( msecs-- != 0 )
usleep( 1000 );
}
void timer_set_stepper_speed( int delay )
{
uint8_t prescaler = 4; // default 1:64 prescaler
if( delay < 30 )
delay = 30;
else if( delay > 1000 )
delay = 1000;
TCCR2 &= ~7; // stop timer, and clear prescaler bit
if( delay > 256 )
{
delay /= 4;
prescaler = 5;
}
OCR2 = delay - 1;
TCCR2 |= prescaler;
}
void timer_set_pen_pressure( int pressure )
{
if( pressure > 1023 )
pressure = 1023;
OCR1B = pressure;
}
/*
* Init timers
*/
void timer_init( void )
{
// set timer 0 for 250 Hz period
TCCR0 = (1 << WGM01) | 6; // prescaler 1:256 -> 62.50 kHz
OCR0 = 249; // 125 kHz / 250 = 250 Hz
TIMSK = (1 << OCIE0); // enable OVF interrupt
// set timer 1, WGM mode 7, fast PWM 10 bit
DDRB |= (1 << 6); // PB6 is PWM output
TCCR1A = (1 << WGM11) | (1 << WGM10) | (1 << COM1B1);
TCCR1B = (1 << WGM12) | 1;
OCR1B = 1023; // lowest pressure
// set timer 2, variable period for stepper
TCCR2 = (1 << WGM21) | 4; // prescaler 1/256 -> 250 kHz
OCR2 = 99; // default speed 2.5k steps
TIMSK |= (1 << OCIE2); //
// Timer 3, WGM mode 15 (1111), Fast PWM using OCR3A
TCCR3A = (1 << COM3A0) | (1 << WGM31) | (1 << WGM30);
TCCR3B = (1 << WGM33) | (1 << WGM32) | 1;
}