/* * 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(); } } }