ece312/lab_2/notes.c
2019-10-19 22:15:38 -06:00

59 lines
1.6 KiB
C

#include "main.h"
/*
const uint8_t PROGMEM notes[OCTAVES][NOTES_PER_OCTAVE] = {
{ 140, 62, 118, 106, 94, 88, 79, 64, 112, 98, , 37 }, // 1024 prescaler octave 2
{ 141, 126, 238, 212, 188, 178, 158, 133, 225, 200, 168, 150 } // 64 prescaler octave 4
};
*/
const uint8_t PROGMEM notes[OCTAVES][NOTES_PER_OCTAVE] = {
{ 35, 31, 59, 53, 47, 44, 39, 32, 56, 49, 41, 37 }, // 1024 prescaler octave 2
{ 141, 126, 238, 212, 188, 178, 158, 133, 225, 200, 168, 150 } // 64 prescaler octave 4
};
void play_note(beat_t note, uint8_t speaker) {
if (note.note == rest) { // Handle special rest case
if (speaker == 0) {
// Turn off timer clock source, disabling
TCCR0B &= ~( (1 << CS02) | (1 << CS01) | (1 << CS00));
// Turn off output pin
PORTB &= ~(1 << PORTB2);
} else {
// turn off timer clock source, disabling
TCCR1B &= ~( (1 << CS12) | (1 << CS11) | (1 << CS10));
// turn off output pin
PORTB &= ~(1 << PORTB3);
}
} else {
// Set up so note changes always happen after rests,
// so we know CS[2:0] = 0
// See pages 86 and 114
uint8_t prescale = 0;
if (note.octave == 0) {
// set prescaler to 1024
prescale = 4;
} else {
// set prescaler to 64
prescale = 3;
}
// Get value to write to output compare
uint8_t period = pgm_read_byte((PGM_P*) &notes[note.octave][note.note]);
// Actually set clock source
if (speaker == 0) {
TCNT0 = 0; // reset counter
OCR0A = period; // set note period
TCCR0B |= prescale;
} else {
TCNT1H = 0; // reset counter
TCNT1L = 0;
OCR1AL = period; // set note period
OCR1AH = period >> 8;
TCCR1B |= prescale;
}
}
}