work from lab
This commit is contained in:
parent
827e52ab5c
commit
744115b446
@ -1 +1,86 @@
|
|||||||
../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) {
|
||||||
|
#if defined(ATTINY2313)
|
||||||
|
while (!(UCSRA & (1 << UDRE)));
|
||||||
|
UDR = cmd;
|
||||||
|
#elif defined(ATMEGA328)
|
||||||
|
while (!(UCSR0A & (1 << UDRE0)));
|
||||||
|
UDR0 = cmd;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @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);
|
||||||
|
_delay_ms(1);
|
||||||
|
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
|
@ -143,34 +143,34 @@
|
|||||||
#define LCD_DATA3_PORT LCD_PORT /**< port for 4bit data bit 3 */
|
#define LCD_DATA3_PORT LCD_PORT /**< port for 4bit data bit 3 */
|
||||||
#endif
|
#endif
|
||||||
#ifndef LCD_DATA0_PIN
|
#ifndef LCD_DATA0_PIN
|
||||||
#define LCD_DATA0_PIN 5 /**< pin for 4bit data bit 0 */
|
#define LCD_DATA0_PIN 4 /**< pin for 4bit data bit 0 */
|
||||||
#endif
|
#endif
|
||||||
#ifndef LCD_DATA1_PIN
|
#ifndef LCD_DATA1_PIN
|
||||||
#define LCD_DATA1_PIN 4 /**< pin for 4bit data bit 1 */
|
#define LCD_DATA1_PIN 5 /**< pin for 4bit data bit 1 */
|
||||||
#endif
|
#endif
|
||||||
#ifndef LCD_DATA2_PIN
|
#ifndef LCD_DATA2_PIN
|
||||||
#define LCD_DATA2_PIN 3 /**< pin for 4bit data bit 2 */
|
#define LCD_DATA2_PIN 6 /**< pin for 4bit data bit 2 */
|
||||||
#endif
|
#endif
|
||||||
#ifndef LCD_DATA3_PIN
|
#ifndef LCD_DATA3_PIN
|
||||||
#define LCD_DATA3_PIN 2 /**< pin for 4bit data bit 3 */
|
#define LCD_DATA3_PIN 7 /**< pin for 4bit data bit 3 */
|
||||||
#endif
|
#endif
|
||||||
#ifndef LCD_RS_PORT
|
#ifndef LCD_RS_PORT
|
||||||
#define LCD_RS_PORT PORTD /**< port for RS line */
|
#define LCD_RS_PORT PORTD /**< port for RS line */
|
||||||
#endif
|
#endif
|
||||||
#ifndef LCD_RS_PIN
|
#ifndef LCD_RS_PIN
|
||||||
#define LCD_RS_PIN 0 /**< pin for RS line */
|
#define LCD_RS_PIN 6 /**< pin for RS line */
|
||||||
#endif
|
#endif
|
||||||
#ifndef LCD_RW_PORT
|
#ifndef LCD_RW_PORT
|
||||||
#define LCD_RW_PORT PORTD /**< port for RW line */
|
#define LCD_RW_PORT PORTB /**< port for RW line */
|
||||||
#endif
|
#endif
|
||||||
#ifndef LCD_RW_PIN
|
#ifndef LCD_RW_PIN
|
||||||
#define LCD_RW_PIN 1 /**< pin for RW line */
|
#define LCD_RW_PIN 0 /**< pin for RW line */
|
||||||
#endif
|
#endif
|
||||||
#ifndef LCD_E_PORT
|
#ifndef LCD_E_PORT
|
||||||
#define LCD_E_PORT PORTD /**< port for Enable line */
|
#define LCD_E_PORT PORTB /**< port for Enable line */
|
||||||
#endif
|
#endif
|
||||||
#ifndef LCD_E_PIN
|
#ifndef LCD_E_PIN
|
||||||
#define LCD_E_PIN 2 /**< pin for Enable line */
|
#define LCD_E_PIN 1 /**< pin for Enable line */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#elif defined(__AVR_AT90S4414__) || defined(__AVR_AT90S8515__) || defined(__AVR_ATmega64__) || \
|
#elif defined(__AVR_AT90S4414__) || defined(__AVR_AT90S8515__) || defined(__AVR_ATmega64__) || \
|
||||||
|
@ -6,19 +6,29 @@ int8_t last_displayed_song = -1;
|
|||||||
int8_t selected_song = -1; //! ID of the selected song. -1 if no song is selected.
|
int8_t selected_song = -1; //! ID of the selected song. -1 if no song is selected.
|
||||||
bool update_display = false; //! flag on whether or not to update display
|
bool update_display = false; //! flag on whether or not to update display
|
||||||
|
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
char name[SONG_NAME_LEN + 1]; //! array of all song names, names are allocated on heap
|
char name[SONG_NAME_LEN + 1]; //! array of all song names, names are allocated on heap
|
||||||
uint8_t num_songs; //! Number of songs loaded into display memory
|
uint8_t num_songs; //! Number of songs loaded into display memory
|
||||||
bool playing; //! Whether the currently selected song is playing
|
bool playing; //! Whether the currently selected song is playing
|
||||||
} songs;
|
} songs;
|
||||||
|
|
||||||
|
void say_no_songs() {
|
||||||
|
lcd_clrscr();
|
||||||
|
lcd_puts("No songs!");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/** @brief Handles right button press
|
/** @brief Handles right button press
|
||||||
*/
|
*/
|
||||||
void handle_left_press() {
|
void handle_left_press() {
|
||||||
if (songs.num_songs == 0) {
|
if (songs.num_songs == 0) {
|
||||||
lcd_clrscr();
|
say_no_songs();
|
||||||
lcd_puts("No songs to play!");
|
comms_send(COMMS_CMD_QUERY_NUM);
|
||||||
|
} else if (display_song == -1) {
|
||||||
|
if (songs.num_songs > 0) {
|
||||||
|
display_song = 0;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// Choose lower ID song. Wrap around.
|
// Choose lower ID song. Wrap around.
|
||||||
display_song--;
|
display_song--;
|
||||||
@ -32,9 +42,13 @@ void handle_left_press() {
|
|||||||
*/
|
*/
|
||||||
void handle_right_press() {
|
void handle_right_press() {
|
||||||
if (songs.num_songs == 0) {
|
if (songs.num_songs == 0) {
|
||||||
lcd_clrscr();
|
say_no_songs();
|
||||||
lcd_puts("No songs to play!");
|
comms_send(COMMS_CMD_QUERY_NUM);
|
||||||
} else {
|
} else if (display_song == -1) {
|
||||||
|
if (songs.num_songs > 0) {
|
||||||
|
display_song = 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
// Choose higher ID song. Wrap around.
|
// Choose higher ID song. Wrap around.
|
||||||
display_song++;
|
display_song++;
|
||||||
if (display_song == songs.num_songs) {
|
if (display_song == songs.num_songs) {
|
||||||
@ -51,8 +65,7 @@ void handle_right_press() {
|
|||||||
void handle_playpause_press() {
|
void handle_playpause_press() {
|
||||||
// If there are no songs displayed, error
|
// If there are no songs displayed, error
|
||||||
if (display_song == -1) {
|
if (display_song == -1) {
|
||||||
lcd_clrscr();
|
say_no_songs();
|
||||||
lcd_puts("No songs to play!");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,16 +88,23 @@ void handle_playpause_press() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
|
DDRA |= (1 << 3); // debug
|
||||||
// Scratch variables
|
// Scratch variables
|
||||||
uint8_t incoming_cmd = 0;
|
uint8_t incoming_cmd = 0;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
fifo_init();
|
fifo_init();
|
||||||
gpio_init();
|
gpio_init();
|
||||||
|
timer_init();
|
||||||
usart_init();
|
usart_init();
|
||||||
|
|
||||||
lcd_init(LCD_DISP_ON);
|
lcd_init(LCD_DISP_ON);
|
||||||
lcd_clrscr();
|
lcd_gotoxy(0,0);
|
||||||
lcd_gotoxy(0,0);
|
|
||||||
|
lcd_puts("...");
|
||||||
|
|
||||||
|
sei();
|
||||||
|
|
||||||
// Main loop
|
// Main loop
|
||||||
while (1) {
|
while (1) {
|
||||||
@ -95,6 +115,7 @@ int main() {
|
|||||||
case (COMMS_CMD_CLR):
|
case (COMMS_CMD_CLR):
|
||||||
songs.num_songs = 0;
|
songs.num_songs = 0;
|
||||||
display_song = -1;
|
display_song = -1;
|
||||||
|
selected_song = -1;
|
||||||
break;
|
break;
|
||||||
// change number of songs
|
// change number of songs
|
||||||
case (COMMS_CMD_NUM):
|
case (COMMS_CMD_NUM):
|
||||||
@ -109,27 +130,29 @@ int main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Handle "left" button press
|
// Handle "left" button press
|
||||||
if (BUTTONS_PORT & (1 << BUTTONS_LEFT_PIN)) {
|
if (!(BUTTONS_LEFT_PIN & (1 << BUTTONS_LEFT))) {
|
||||||
handle_left_press();
|
handle_left_press();
|
||||||
_delay_ms(100); // Delay to debounce
|
_delay_ms(100); // Delay to debounce
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle "right" button press
|
// Handle "right" button press
|
||||||
if (BUTTONS_PORT & (1 << BUTTONS_LEFT_PIN)) {
|
if (!(BUTTONS_RIGHT_PIN & (1 << BUTTONS_RIGHT))) {
|
||||||
handle_left_press();
|
handle_right_press();
|
||||||
_delay_ms(100); // Delay to debounce
|
_delay_ms(100); // Delay to debounce
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle play/pause button press
|
// Handle play/pause button press
|
||||||
if (BUTTONS_PORT & (1 << BUTTONS_LEFT_PIN)) {
|
if (!(BUTTONS_PLAYPAUSE_PIN & (1 << BUTTONS_PLAYPAUSE))) {
|
||||||
handle_left_press();
|
handle_playpause_press();
|
||||||
_delay_ms(100); // Delay to debounce
|
_delay_ms(100); // Delay to debounce
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update display periodically
|
// Update display periodically
|
||||||
if (update_display) {
|
if (update_display) {
|
||||||
|
|
||||||
// check if song has changed
|
// check if song has changed
|
||||||
if (last_displayed_song != display_song) {
|
if (last_displayed_song != display_song) {
|
||||||
|
lcd_clrscr();
|
||||||
comms_query_name(display_song);
|
comms_query_name(display_song);
|
||||||
|
|
||||||
char tmp_chr;
|
char tmp_chr;
|
||||||
@ -161,7 +184,7 @@ int main() {
|
|||||||
lcd_putc('0' + songs.num_songs);
|
lcd_putc('0' + songs.num_songs);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
lcd_puts("No song!");
|
lcd_puts("");
|
||||||
}
|
}
|
||||||
|
|
||||||
update_display = false;
|
update_display = false;
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
#ifndef MAIN_H_
|
#ifndef MAIN_H_
|
||||||
#define MAIN_H_
|
#define MAIN_H_
|
||||||
|
|
||||||
|
#define F_CPU 8000000
|
||||||
|
#define ATTINY2313
|
||||||
|
|
||||||
#include <avr/io.h>
|
#include <avr/io.h>
|
||||||
#include <avr/interrupt.h>
|
#include <avr/interrupt.h>
|
||||||
#include <util/delay.h>
|
#include <util/delay.h>
|
||||||
@ -20,4 +23,5 @@
|
|||||||
/* ---- Globally available flags ---- */
|
/* ---- Globally available flags ---- */
|
||||||
extern bool update_display;
|
extern bool update_display;
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
@ -22,15 +22,17 @@ ISR(TIMER0_COMPA_vect) {
|
|||||||
sei();
|
sei();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void gpio_init() {
|
void gpio_init() {
|
||||||
// Initialise button pins as inputs
|
// Initialise button pins as inputs
|
||||||
BUTTONS_DDR &= ~(1 << BUTTONS_LEFT_PIN) &
|
BUTTONS_LEFT_DDR &= ~(1 << BUTTONS_LEFT);
|
||||||
~(1 << BUTTONS_RIGHT_PIN) &
|
BUTTONS_RIGHT_DDR &= ~(1 << BUTTONS_RIGHT);
|
||||||
~(1 << BUTTONS_PLAYPAUSE_PIN);
|
BUTTONS_PLAYPAUSE_DDR &= ~(1 << BUTTONS_PLAYPAUSE);
|
||||||
|
|
||||||
// Turn on button pullups
|
// Turn on button pullups
|
||||||
BUTTONS_PORT |= (1 << BUTTONS_LEFT_PIN) |
|
BUTTONS_LEFT_PORT |= (1 << BUTTONS_LEFT);
|
||||||
(1 << BUTTONS_RIGHT_PIN) |
|
BUTTONS_RIGHT_PORT |= (1 << BUTTONS_RIGHT);
|
||||||
(1 << BUTTONS_PLAYPAUSE_PIN);
|
BUTTONS_PLAYPAUSE_PORT |= (1 << BUTTONS_PLAYPAUSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void timer_init() {
|
void timer_init() {
|
||||||
@ -44,14 +46,14 @@ void timer_init() {
|
|||||||
// To set to CTC, WGM = 0b010
|
// To set to CTC, WGM = 0b010
|
||||||
TCCR0A = (1 << WGM01);
|
TCCR0A = (1 << WGM01);
|
||||||
|
|
||||||
|
// Set to ~20Hz
|
||||||
|
OCR0A = 195;
|
||||||
|
|
||||||
// CS = 0b101 -> 1024 prescaler
|
// CS = 0b101 -> 1024 prescaler
|
||||||
// Everything else should be 0.
|
// Everything else should be 0.
|
||||||
// TCCR0B = 0b00000101; <- can't use this because binary stuff is a GCC extension
|
// TCCR0B = 0b00000101; <- can't use this because binary stuff is a GCC extension
|
||||||
TCCR0B = 5;
|
TCCR0B = 5;
|
||||||
|
|
||||||
// Set to ~20Hz
|
|
||||||
OCR0A = 195;
|
|
||||||
|
|
||||||
// Enable interrupt
|
// Enable interrupt
|
||||||
TIMSK = (1 << OCIE0A);
|
TIMSK = (1 << OCIE0A);
|
||||||
}
|
}
|
||||||
|
@ -19,10 +19,18 @@
|
|||||||
#define UBRR_VALUE (((F_CPU/(USART_BAUDRATE*16UL)))-1)
|
#define UBRR_VALUE (((F_CPU/(USART_BAUDRATE*16UL)))-1)
|
||||||
|
|
||||||
#define BUTTONS_DDR DDRD
|
#define BUTTONS_DDR DDRD
|
||||||
#define BUTTONS_PORT PORTD
|
#define BUTTONS_LEFT_DDR DDRA
|
||||||
#define BUTTONS_LEFT_PIN PORTD2
|
#define BUTTONS_RIGHT_DDR DDRA
|
||||||
#define BUTTONS_RIGHT_PIN PORTD3
|
#define BUTTONS_PLAYPAUSE_DDR DDRB
|
||||||
#define BUTTONS_PLAYPAUSE_PIN PORTD4
|
#define BUTTONS_LEFT_PORT PORTA
|
||||||
|
#define BUTTONS_RIGHT_PORT PORTA
|
||||||
|
#define BUTTONS_PLAYPAUSE_PORT PORTB
|
||||||
|
#define BUTTONS_LEFT_PIN PINA
|
||||||
|
#define BUTTONS_RIGHT_PIN PINA
|
||||||
|
#define BUTTONS_PLAYPAUSE_PIN PINB
|
||||||
|
#define BUTTONS_LEFT 0
|
||||||
|
#define BUTTONS_RIGHT 1
|
||||||
|
#define BUTTONS_PLAYPAUSE 2
|
||||||
|
|
||||||
|
|
||||||
/** @brief Sets up various GPIO functions
|
/** @brief Sets up various GPIO functions
|
||||||
|
Loading…
Reference in New Issue
Block a user