#include "main.h" #include /** @brief intercepts incoming Serial commands */ ISR(USART_RX_vect) { cli(); // Read byte into FIFO uint8_t in_byte = UDR0; fifo_push(in_byte); // Flag is cleared by reading data from UDR sei(); } /** @brief Interrupt handler for actually playing music * * Will only be called if the TIFR OCF0A flag is high, using that as our play/pause flag * * This may be possible to hand-optimise better, but I cut it down to ~40 instructions * which should be fine at 16MHz */ ISR(TIMER0_COMPA_vect) { cli(); // Handle music playing /* DAC0 -> DAC5 are on PC0 -> PC5 * Nothing relevent is on the rest of PORTC * * DAC6 -> DAC11 is PD2->PD7 * * DAC12 and DAC13 are PB0 and PB1 */ uint8_t in_data = song_buf[song_buf_select][song_position]; // DAC0 -> DAC5 // DAC6 -> DAC11 PORTD &= in_data & 0xFC; PORTB &= in_data & 0x03; // Go to next sample song_position++; // Can just wrap if it's 8 bit sei(); } void gpio_init() { // Initialise all DAC outputs /* DAC0 -> DAC5 are on PC0 -> PC5 * Nothing relevent is on the rest of PORTC * * DAC6 -> DAC11 is PD2->PD7 * * DAC12 and DAC13 are PB0 and PB1 */ DDRC |= 0x3F; DDRD |= 0xFC; DDRC |= 0x03; } void timer_init() { // Compare outputs should be default, nothing // Set to CTC, WGM = 0b010 TCCR0A = (1 << WGM01); // Set timer to use clock input w/o prescaling TCCR0B = 1; // 16 MHz / 44kHz = 182 clock cycles // Pushing it for time, may have to move to 8 bit... OCR0A = 182; // Don't enable the interrupt yet } void usart_init() { // set baudrate UBRR0L = UBRR_VALUE & 255; UBRR0H = UBRR_VALUE >> 8; // Start it up UCSR0B |= (1 << TXEN0) | (1 << RXEN0); // Set data info, no parity, 1 stop, 8-bit UCSR0C |= (1 << UCSZ01) | (1 << UCSZ00); // Enable interrupt UCSR0B |= (1 << RXCIE0); }