ece312/lab_2/main.c
David Lenfesty 008c33b99f
Final code.
Could add some comments
2019-10-20 18:07:01 -06:00

137 lines
2.8 KiB
C

/*
* GccApplication1.c
*
* Created: 10/8/2019 2:07:13 PM
* Author : lenfesty
*/
#include "main.h"
bool play_flag = 0;
/*
* Pin Definitions:
* PB2 -> OC0A output
* PB3 -> OC1A output
* PD2 -> Switch Input
*/
void gpio_init() {
// Piezo Out
DDRB |= (1 << DDB2) | (1 << DDB3);
// Switch Input Setup
DDRD &= ~(1 << DDD2);
PORTD |= (1 << PORTD2);
}
void timer_init( ) {
/* --- Timer 0 (8 bit) --- */
// Set Compare mode A to toggle, and waveform generation mode to CTC
TCCR0A = (0 << COM0A1) | (1 << COM0A0) | (1 << WGM01) | (0 << WGM00);
// Nothing else relevant here, without setting notes
/* --- Timer 1 (16 bit) --- */
// Set compare mode A to toggle
TCCR1A = (0 << COM1A1) | (1 << COM1A0);
// Set waveform gen mode to CTC
TCCR1B = (1 << WGM12);
}
// Returns true for a "successful" note, false for end of song.
bool play_beat() {
static uint8_t duration_left[2] = {0};
static uint16_t song_location[2] = {0};
// If at end of song, restart
if (song_location[0] == SPEAKER0_LEN) {
song_location[0] = 0;
song_location[1] = 0;
return false;
}
// Set note
for (uint8_t speaker = 0; speaker < 2; speaker++) {
if (duration_left[speaker] == 0) {
// Move to next note
// Read in next note from program memory
uint16_t beat;
beat_t* p_beat;
// Select from correct song
if (speaker == 0) {
beat = pgm_read_word((PGM_P*) &song_speaker0[song_location[speaker]]);
} else {
beat = pgm_read_word((PGM_P*) &song_speaker1[song_location[speaker]]);
}
p_beat = (beat_t*) &beat;
// Set duration left after this beat
duration_left[speaker] = p_beat->duration - 1;
// Increment song location for next note
song_location[speaker]++;
// actually set note
play_note(*p_beat, speaker);
} else {
// Keep handling current note
// do nothing, it is set correctly
duration_left[speaker]--;
}
}
_delay_ms(BEAT_LENGTH * (1 - REST_FRACTION)); // Play note
// Rest note if at the end of the interval
for (uint8_t speaker = 0; speaker < 2; speaker++) {
if (duration_left[speaker] == 0) {
// End of note, pause here
beat_t beat = {
.note = rest,
.duration = 0,
.octave = 0, // octave doesn't matter, its a rest
};
play_note(beat, speaker);
} else {
// Note does not end, change nothing
}
}
_delay_ms(BEAT_LENGTH * REST_FRACTION);
return true;
}
int main(void)
{
gpio_init();
timer_init();
beat_t beat = {
.note = a,
.duration = 20,
.octave = 0,
};
play_note(beat, 1);
while (1)
{
if (bit_is_clear(PIND, PIND2)) {
// Play song until the end
while(play_beat());
// Turn off speakers once song is over
beat_t beat = {
.note = rest,
.duration = 0,
.octave = 0, // octave doesn't matter, its a rest
};
play_note(beat, 0);
play_note(beat, 1);
}
}
}