/
timer2.c
130 lines (111 loc) · 2.84 KB
/
timer2.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
/* timer2.c
** We setup timer2 to sample our push button regularly
** and act on that.
*/
#include <avr/io.h>
#include <avr/interrupt.h>
#include "notes.h"
#include "d2a.h"
#include "segment.h"
#include "led.h"
#include "serial.h"
#include "playback.h"
void quiet(void);
/* Remember the last status of the push button
** and 7SEG display
*/
volatile uint8_t prevButtonStatus = 0;
volatile uint8_t cat = 0;
/* Set up timer 2 to generate an interrupt every 1ms.
** We will divide the clock by 64 and count up to 124.
** We will therefore get an interrupt every 64 x 125
** clock cycles, i.e. every millisecond with an 8MHz
** clock.
** The counter will be reset to 0 when it reaches it's
** output compare value.
*/
void setup_timer2(void)
{
/* Set the output compare value to be 124 */
OCR2 = 124;
/* Enable an interrupt on output compare match.
** Note that interrupts have to be enabled globally
** before the interrupts will fire.
*/
TIMSK |= (1<<OCIE2);
/* Set the timer to clear on compare match (CTC mode)
** and to divide the clock by 64. This starts the timer
** running.
*/
TCCR2 = (1<<WGM21)|(0<<WGM20)|(0<<CS22)|(1<<CS21)|(1<<CS20);
}
/*Abstraction of press note button actions */
void pressNote(uint8_t n) {
/* set current note */
note = n;
/* set frequency (notes.h) */
start_note();
/* print out note (serial.h) */
output_note();
}
/* Abstraction of record note action */
void recNote(uint8_t n) {
if (recording==1) {
buffer_note(n, rec_timecounter);
rec_timecounter = 0;
}
}
ISR(TIMER2_COMP_vect)
{
/* Sample push button connected to port A pin 0.
** (We ignore other push buttons.)
** If has changed since previous sample, we act on that,
** i.e. other stop note playing or start note playing
*/
uint8_t currentButtonStatus = PINA;
uint8_t i;
/* Push Buttons
** Ensure the button state has changed,
** and the demo tune is inactive (notes.h)
*/
if ((currentButtonStatus != prevButtonStatus) && (tuneWait == 0)) {
/* Check no buttons held */
if (currentButtonStatus==0) {
/* Disable the speaker */
quiet();
/* Set no note being played */
note = ~0;
}
/* A button was released */
else if (prevButtonStatus > currentButtonStatus) {
/* Play any held-down button */
for (i=0; i<=7; i++) {
if (currentButtonStatus & (1<<i)) {
pressNote(i);
recNote(i);
break;
}
}
}
/* A button was pressed */
else if (prevButtonStatus < currentButtonStatus) {
/* Play the new button */
for (i=0; i<=7; i++) {
if ((currentButtonStatus^prevButtonStatus) & (1<<i)) {
pressNote(i);
recNote(i);
break;
}
}
}
}
/* Remember the status of the push button*/
prevButtonStatus = PINA;
/* Print to the 7Seg Display */
segmentPrint(note,cat,octave);
cat ^= 1;
/* Incrememnt the beat timer */
beatStep();
/* Run the playback tune handler */
playbackStep();
}