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

152 lines
3.0 KiB
C

/*
* GccApplication1.c
*
* Created: 10/8/2019 2:07:13 PM
* Author : lenfesty
*/
#include "main.h"
uint8_t play_flag = 0;
uint8_t button_flag = 0;
ISR(INT0_vect) {
// Disable interrupts
cli();
// Notify of button press
button_flag = 1;
}
/*
* Pin Definitions:
* PB2 -> OC0A output
* PB3 -> OC1A output
* PB0 -> Switch Input
*/
void gpio_init() {
// Piezo Out
DDRB |= (1 << DDB2) | (1 << DDB3);
// Switch Input Setup
DDRD &= ~(1 << DDD2);
PORTD |= (1 << PORTD2);
// Configure Interrupt Stuff
// Set falling edge for INT0
MCUCR |= (1 << ISC01) | (0 << ISC00);
// Enable INT0
GIMSK |= (1 << INT0);
}
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);
}
void 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;
}
// 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);
}
int main(void)
{
gpio_init();
timer_init();
sei();
/* Replace with your application code */
while (1)
{
if (play_flag) {
play_beat();
}
if (button_flag) {
button_flag = 0;
beat_t beat = {
.note = rest,
};
play_note(beat, 0);
play_note(beat, 1);
_delay_ms(100);
sei();
}
if ( bit_is_clear(PIND, PIND2) && (play_flag == 0)) {
cli();
play_flag = 1;
_delay_ms(100);
sei();
}
}
}