work from lab
This commit is contained in:
parent
dcd24b56c5
commit
827e52ab5c
@ -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
|
@ -20,13 +20,15 @@ uint8_t cmd_state;
|
||||
|
||||
// Song playing
|
||||
// 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
|
||||
bool song_buf_select; //! which buffer we're using
|
||||
bool song_selected; //! Flag to say we just selected the song, read data in
|
||||
int8_t song_selection = -1; //! ID of selected song
|
||||
uint32_t song_len;
|
||||
uint32_t song_read_position;
|
||||
bool send_number_of_songs = true;
|
||||
uint8_t num_songs = 0;
|
||||
|
||||
|
||||
typedef struct {
|
||||
@ -41,6 +43,7 @@ int main()
|
||||
gpio_init();
|
||||
timer_init();
|
||||
usart_init();
|
||||
sei();
|
||||
|
||||
// TODO set SPI to highest freq possible, might just need tweaking
|
||||
sd_raw_init();
|
||||
@ -101,9 +104,13 @@ int main()
|
||||
// Move on to reading next song
|
||||
song_id++;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
num_songs = song_id;
|
||||
|
||||
|
||||
// Print out all files/directories in top level
|
||||
while (1) {
|
||||
/// do stuff
|
||||
@ -133,6 +140,10 @@ int main()
|
||||
// Wait for next loop to handle file info
|
||||
cmd_depth = 1;
|
||||
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) {
|
||||
uint8_t song_id;
|
||||
if (fifo_pop(&song_id) == FIFO_SUCCESS) {
|
||||
switch (cmd_state) {
|
||||
case (COMMS_CMD_SELECT_FILE):
|
||||
// select proper song and begin reading in
|
||||
song_selection = song_id;
|
||||
song_selected = 1;
|
||||
break;
|
||||
case (COMMS_CMD_QUERY_NAME):
|
||||
// Just going to hope we can bump the UART baudrate up high enough
|
||||
comms_reply_name(songs[song_id].name);
|
||||
break;
|
||||
}
|
||||
while (fifo_pop(&song_id) != FIFO_SUCCESS);
|
||||
switch (cmd_state) {
|
||||
case (COMMS_CMD_SELECT_FILE):
|
||||
// select proper song and begin reading in
|
||||
song_selection = song_id;
|
||||
song_selected = 1;
|
||||
break;
|
||||
case (COMMS_CMD_QUERY_NAME):
|
||||
// Just going to hope we can bump the UART baudrate up high enough
|
||||
comms_reply_name(songs[song_id].name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -192,7 +202,7 @@ int main()
|
||||
|
||||
// We are now at the actual data
|
||||
// divide by two to get uint16
|
||||
song_len = header.cksize / 2;
|
||||
song_len = header.cksize;
|
||||
song_read_position = 0;
|
||||
}
|
||||
|
||||
@ -206,7 +216,7 @@ int main()
|
||||
|
||||
// Read in file
|
||||
// 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;
|
||||
|
||||
// If we selected the song, make sure we start playing from the right buffer
|
||||
|
@ -1,11 +1,15 @@
|
||||
#ifndef MAIN_H_
|
||||
#define MAIN_H_
|
||||
|
||||
#define F_CPU 8000000UL
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <avr/pgmspace.h>
|
||||
#include <avr/sleep.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include <util/delay.h>
|
||||
#include "fat.h"
|
||||
#include "fat_config.h"
|
||||
#include "partition.h"
|
||||
@ -21,8 +25,9 @@
|
||||
|
||||
|
||||
// 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 bool song_buf_select; //! which buffer we're using
|
||||
extern bool send_number_of_songs;
|
||||
|
||||
#endif
|
@ -4,14 +4,15 @@
|
||||
/** @brief intercepts incoming Serial commands
|
||||
*/
|
||||
ISR(USART_RX_vect) {
|
||||
|
||||
cli();
|
||||
// Read byte into FIFO
|
||||
fifo_push(UDR0);
|
||||
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
|
||||
@ -29,19 +30,11 @@ ISR(TIMER0_COMPA_vect) {
|
||||
*
|
||||
* DAC12 and DAC13 are PB0 and PB1
|
||||
*/
|
||||
uint16_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;
|
||||
|
||||
uint8_t in_data = song_buf[song_buf_select][song_position];
|
||||
// DAC0 -> DAC5
|
||||
PORTC = (data_lo >> 2) & 0x3F;
|
||||
// DAC6 -> DAC11
|
||||
PORTD &= 0x03;
|
||||
PORTD |= data_hi << 2;
|
||||
// DAC12 and DAC13
|
||||
PORTB &= 0xFC; // clear bits
|
||||
PORTB |= data_hi >> 6;
|
||||
PORTD &= in_data & 0xFC;
|
||||
PORTB &= in_data & 0x03;
|
||||
|
||||
// Go to next sample
|
||||
song_position++;
|
||||
@ -66,7 +59,7 @@ void gpio_init() {
|
||||
void timer_init() {
|
||||
// Compare outputs should be default, nothing
|
||||
// Set to CTC, WGM = 0b010
|
||||
TCCR0A = (1 << OCIE0A);
|
||||
TCCR0A = (1 << WGM01);
|
||||
|
||||
// Set timer to use clock input w/o prescaling
|
||||
TCCR0B = 1;
|
||||
@ -76,16 +69,21 @@ void timer_init() {
|
||||
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);
|
||||
|
||||
// Start it up
|
||||
UCSR0B |= (1 << TXEN0) | (1 << RXEN0);
|
||||
|
||||
|
||||
// Enable interrupt
|
||||
UCSR0B |= (1 << RXCIE0);
|
||||
}
|
Loading…
Reference in New Issue
Block a user