ece312/final_project/sd_reader/periph.c
2019-12-03 00:38:46 -07:00

89 lines
2.0 KiB
C

#include "main.h"
#include <avr/interrupt.h>
/** @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);
}