work from lab

This commit is contained in:
David Lenfesty 2019-12-03 00:38:46 -07:00 committed by GitHub
parent dcd24b56c5
commit 827e52ab5c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 127 additions and 34 deletions

View File

@ -1 +1,81 @@
../comms/comms.h #ifndef COMMS_H_
#define COMMS_H_
#include <avr/io.h>
#include <string.h>
/**
* Our format goes like this:
*
* 1 byte command, with data after
*/
typedef enum {
COMMS_CMD_CLR = 0U, //! Clears LCD and all file names
COMMS_CMD_NUM, //! sends the total number of songs to choose from
COMMS_CMD_QUERY_NUM,
COMMS_CMD_QUERY_NAME, //! Queries for the name of a given song ID
COMMS_CMD_REPLY_NAME, //! Responds with the name of the given song ID
COMMS_CMD_SELECT_FILE, //! selects a file from the given list to play, data is 1 byte for id
COMMS_CMD_PLAY, //! Starts playing file
COMMS_CMD_PAUSE //! pauses playing file
} comms_cmd_t;
/** @brief Inline function to send commands and values.
*/
inline void comms_send(comms_cmd_t cmd) {
while (! (UCSR0A & (1 << UDRE0)));
UDR0 = cmd;
}
/** @brief Selects a file from the list on the DAC side.
*
* If another song is playing, this will stop
* that song from playing and select the new one.
*/
inline void comms_select_file(uint8_t id) {
comms_send(COMMS_CMD_SELECT_FILE);
comms_send((comms_cmd_t) id);
}
/** @brief Queries for the name of the given song ID.
*/
inline void comms_query_name(uint8_t id) {
comms_send(COMMS_CMD_QUERY_NAME);
comms_send(id);
}
/** @brief Repliers with the name of the requsted song ID
*/
inline void comms_reply_name(char* name) {
uint8_t len = strlen(name);
comms_send(COMMS_CMD_REPLY_NAME);
comms_send(len);
for (uint8_t i = 0; i < len; i++) {
comms_send((uint8_t) name[i]);
}
}
/** @brief Clears the LCD list of files.
*/
inline void comms_clear() {
comms_send(COMMS_CMD_CLR);
}
/** @brief Starts playing song.
*/
inline void comms_play() {
comms_send(COMMS_CMD_PLAY);
}
/** @brief Pauses playing song.
*/
inline void comms_pause() {
comms_send(COMMS_CMD_PLAY);
}
#endif

View File

@ -20,13 +20,15 @@ uint8_t cmd_state;
// Song playing // Song playing
// TODO fix this atrocious naming // TODO fix this atrocious naming
uint16_t song_buf[2][SONG_BUF_LEN]; //! Buffers to play song from uint8_t song_buf[2][SONG_BUF_LEN]; //! Buffers to play song from
uint8_t song_position; //! where we are in the buffers uint8_t song_position; //! where we are in the buffers
bool song_buf_select; //! which buffer we're using bool song_buf_select; //! which buffer we're using
bool song_selected; //! Flag to say we just selected the song, read data in bool song_selected; //! Flag to say we just selected the song, read data in
int8_t song_selection = -1; //! ID of selected song int8_t song_selection = -1; //! ID of selected song
uint32_t song_len; uint32_t song_len;
uint32_t song_read_position; uint32_t song_read_position;
bool send_number_of_songs = true;
uint8_t num_songs = 0;
typedef struct { typedef struct {
@ -41,6 +43,7 @@ int main()
gpio_init(); gpio_init();
timer_init(); timer_init();
usart_init(); usart_init();
sei();
// TODO set SPI to highest freq possible, might just need tweaking // TODO set SPI to highest freq possible, might just need tweaking
sd_raw_init(); sd_raw_init();
@ -102,8 +105,12 @@ int main()
song_id++; song_id++;
} }
} }
num_songs = song_id;
// Print out all files/directories in top level // Print out all files/directories in top level
while (1) { while (1) {
/// do stuff /// do stuff
@ -133,6 +140,10 @@ int main()
// Wait for next loop to handle file info // Wait for next loop to handle file info
cmd_depth = 1; cmd_depth = 1;
break; break;
case (COMMS_CMD_QUERY_NUM):
comms_send(COMMS_CMD_NUM);
comms_send(num_songs);
break;
} }
} }
@ -140,18 +151,17 @@ int main()
if (cmd_depth == 1) { if (cmd_depth == 1) {
uint8_t song_id; uint8_t song_id;
if (fifo_pop(&song_id) == FIFO_SUCCESS) { while (fifo_pop(&song_id) != FIFO_SUCCESS);
switch (cmd_state) { switch (cmd_state) {
case (COMMS_CMD_SELECT_FILE): case (COMMS_CMD_SELECT_FILE):
// select proper song and begin reading in // select proper song and begin reading in
song_selection = song_id; song_selection = song_id;
song_selected = 1; song_selected = 1;
break; break;
case (COMMS_CMD_QUERY_NAME): case (COMMS_CMD_QUERY_NAME):
// Just going to hope we can bump the UART baudrate up high enough // Just going to hope we can bump the UART baudrate up high enough
comms_reply_name(songs[song_id].name); comms_reply_name(songs[song_id].name);
break; break;
}
} }
} }
@ -192,7 +202,7 @@ int main()
// We are now at the actual data // We are now at the actual data
// divide by two to get uint16 // divide by two to get uint16
song_len = header.cksize / 2; song_len = header.cksize;
song_read_position = 0; song_read_position = 0;
} }
@ -206,7 +216,7 @@ int main()
// Read in file // Read in file
// 512 bytes to read, 256 samples // 512 bytes to read, 256 samples
fat_read_file(songs[song_selection].fd, (uint8_t*) song_buf[read_song_buf], 512); fat_read_file(songs[song_selection].fd, (uint8_t*) song_buf[read_song_buf], 256);
song_read_position += 256; song_read_position += 256;
// If we selected the song, make sure we start playing from the right buffer // If we selected the song, make sure we start playing from the right buffer

View File

@ -1,11 +1,15 @@
#ifndef MAIN_H_ #ifndef MAIN_H_
#define MAIN_H_ #define MAIN_H_
#define F_CPU 8000000UL
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdbool.h> #include <stdbool.h>
#include <avr/pgmspace.h> #include <avr/pgmspace.h>
#include <avr/sleep.h> #include <avr/sleep.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include "fat.h" #include "fat.h"
#include "fat_config.h" #include "fat_config.h"
#include "partition.h" #include "partition.h"
@ -21,8 +25,9 @@
// Song playing // Song playing
extern uint16_t song_buf[2][SONG_BUF_LEN]; //! Buffers to play song from extern uint8_t song_buf[2][SONG_BUF_LEN]; //! Buffers to play song from
extern uint8_t song_position; //! where we are in the buffers extern uint8_t song_position; //! where we are in the buffers
extern bool song_buf_select; //! which buffer we're using extern bool song_buf_select; //! which buffer we're using
extern bool send_number_of_songs;
#endif #endif

View File

@ -4,14 +4,15 @@
/** @brief intercepts incoming Serial commands /** @brief intercepts incoming Serial commands
*/ */
ISR(USART_RX_vect) { ISR(USART_RX_vect) {
cli(); cli();
// Read byte into FIFO // Read byte into FIFO
fifo_push(UDR0); uint8_t in_byte = UDR0;
fifo_push(in_byte);
// Flag is cleared by reading data from UDR // Flag is cleared by reading data from UDR
sei(); sei();
} }
/** @brief Interrupt handler for actually playing music /** @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 * Will only be called if the TIFR OCF0A flag is high, using that as our play/pause flag
@ -29,19 +30,11 @@ ISR(TIMER0_COMPA_vect) {
* *
* DAC12 and DAC13 are PB0 and PB1 * DAC12 and DAC13 are PB0 and PB1
*/ */
uint16_t in_data = song_buf[song_buf_select][song_position]; uint8_t in_data = song_buf[song_buf_select][song_position];
// Split into 8 bit because we are using an 8 bit MCU, so code can be better
uint8_t data_lo = in_data;
uint8_t data_hi = in_data >> 8;
// DAC0 -> DAC5 // DAC0 -> DAC5
PORTC = (data_lo >> 2) & 0x3F;
// DAC6 -> DAC11 // DAC6 -> DAC11
PORTD &= 0x03; PORTD &= in_data & 0xFC;
PORTD |= data_hi << 2; PORTB &= in_data & 0x03;
// DAC12 and DAC13
PORTB &= 0xFC; // clear bits
PORTB |= data_hi >> 6;
// Go to next sample // Go to next sample
song_position++; song_position++;
@ -66,7 +59,7 @@ void gpio_init() {
void timer_init() { void timer_init() {
// Compare outputs should be default, nothing // Compare outputs should be default, nothing
// Set to CTC, WGM = 0b010 // Set to CTC, WGM = 0b010
TCCR0A = (1 << OCIE0A); TCCR0A = (1 << WGM01);
// Set timer to use clock input w/o prescaling // Set timer to use clock input w/o prescaling
TCCR0B = 1; TCCR0B = 1;
@ -76,16 +69,21 @@ void timer_init() {
OCR0A = 182; OCR0A = 182;
// Don't enable the interrupt yet // Don't enable the interrupt yet
} }
void usart_init() { void usart_init() {
// set baudrate // set baudrate
UBRR0L = UBRR_VALUE & 255; UBRR0L = UBRR_VALUE & 255;
UBRR0H = UBRR_VALUE >> 8; UBRR0H = UBRR_VALUE >> 8;
// Start it up
UCSR0B |= (1 << TXEN0) | (1 << RXEN0);
// Set data info, no parity, 1 stop, 8-bit // Set data info, no parity, 1 stop, 8-bit
UCSR0C |= (1 << UCSZ01) | (1 << UCSZ00); UCSR0C |= (1 << UCSZ01) | (1 << UCSZ00);
// Start it up
UCSR0B |= (1 << TXEN0) | (1 << RXEN0);
// Enable interrupt
UCSR0B |= (1 << RXCIE0);
} }