work from lab

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

View File

@ -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

View File

@ -143,34 +143,34 @@
#define LCD_DATA3_PORT LCD_PORT /**< port for 4bit data bit 3 */
#endif
#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
#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
#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
#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
#ifndef LCD_RS_PORT
#define LCD_RS_PORT PORTD /**< port for RS line */
#endif
#ifndef LCD_RS_PIN
#define LCD_RS_PIN 0 /**< pin for RS line */
#define LCD_RS_PIN 6 /**< pin for RS line */
#endif
#ifndef LCD_RW_PORT
#define LCD_RW_PORT PORTD /**< port for RW line */
#define LCD_RW_PORT PORTB /**< port for RW line */
#endif
#ifndef LCD_RW_PIN
#define LCD_RW_PIN 1 /**< pin for RW line */
#define LCD_RW_PIN 0 /**< pin for RW line */
#endif
#ifndef LCD_E_PORT
#define LCD_E_PORT PORTD /**< port for Enable line */
#define LCD_E_PORT PORTB /**< port for Enable line */
#endif
#ifndef LCD_E_PIN
#define LCD_E_PIN 2 /**< pin for Enable line */
#define LCD_E_PIN 1 /**< pin for Enable line */
#endif
#elif defined(__AVR_AT90S4414__) || defined(__AVR_AT90S8515__) || defined(__AVR_ATmega64__) || \

View File

@ -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.
bool update_display = false; //! flag on whether or not to update display
struct {
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
bool playing; //! Whether the currently selected song is playing
} songs;
void say_no_songs() {
lcd_clrscr();
lcd_puts("No songs!");
}
/** @brief Handles right button press
*/
void handle_left_press() {
if (songs.num_songs == 0) {
lcd_clrscr();
lcd_puts("No songs to play!");
say_no_songs();
comms_send(COMMS_CMD_QUERY_NUM);
} else if (display_song == -1) {
if (songs.num_songs > 0) {
display_song = 0;
}
} else {
// Choose lower ID song. Wrap around.
display_song--;
@ -32,8 +42,12 @@ void handle_left_press() {
*/
void handle_right_press() {
if (songs.num_songs == 0) {
lcd_clrscr();
lcd_puts("No songs to play!");
say_no_songs();
comms_send(COMMS_CMD_QUERY_NUM);
} else if (display_song == -1) {
if (songs.num_songs > 0) {
display_song = 0;
}
} else {
// Choose higher ID song. Wrap around.
display_song++;
@ -51,8 +65,7 @@ void handle_right_press() {
void handle_playpause_press() {
// If there are no songs displayed, error
if (display_song == -1) {
lcd_clrscr();
lcd_puts("No songs to play!");
say_no_songs();
return;
}
@ -75,17 +88,24 @@ void handle_playpause_press() {
}
int main() {
DDRA |= (1 << 3); // debug
// Scratch variables
uint8_t incoming_cmd = 0;
fifo_init();
gpio_init();
timer_init();
usart_init();
lcd_init(LCD_DISP_ON);
lcd_clrscr();
lcd_gotoxy(0,0);
lcd_puts("...");
sei();
// Main loop
while (1) {
// Handle incoming messages
@ -95,6 +115,7 @@ int main() {
case (COMMS_CMD_CLR):
songs.num_songs = 0;
display_song = -1;
selected_song = -1;
break;
// change number of songs
case (COMMS_CMD_NUM):
@ -109,27 +130,29 @@ int main() {
}
// Handle "left" button press
if (BUTTONS_PORT & (1 << BUTTONS_LEFT_PIN)) {
if (!(BUTTONS_LEFT_PIN & (1 << BUTTONS_LEFT))) {
handle_left_press();
_delay_ms(100); // Delay to debounce
}
// Handle "right" button press
if (BUTTONS_PORT & (1 << BUTTONS_LEFT_PIN)) {
handle_left_press();
if (!(BUTTONS_RIGHT_PIN & (1 << BUTTONS_RIGHT))) {
handle_right_press();
_delay_ms(100); // Delay to debounce
}
// Handle play/pause button press
if (BUTTONS_PORT & (1 << BUTTONS_LEFT_PIN)) {
handle_left_press();
if (!(BUTTONS_PLAYPAUSE_PIN & (1 << BUTTONS_PLAYPAUSE))) {
handle_playpause_press();
_delay_ms(100); // Delay to debounce
}
// Update display periodically
if (update_display) {
// check if song has changed
if (last_displayed_song != display_song) {
lcd_clrscr();
comms_query_name(display_song);
char tmp_chr;
@ -161,7 +184,7 @@ int main() {
lcd_putc('0' + songs.num_songs);
} else {
lcd_puts("No song!");
lcd_puts("");
}
update_display = false;

View File

@ -1,6 +1,9 @@
#ifndef MAIN_H_
#define MAIN_H_
#define F_CPU 8000000
#define ATTINY2313
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
@ -20,4 +23,5 @@
/* ---- Globally available flags ---- */
extern bool update_display;
#endif

View File

@ -22,15 +22,17 @@ ISR(TIMER0_COMPA_vect) {
sei();
}
void gpio_init() {
// Initialise button pins as inputs
BUTTONS_DDR &= ~(1 << BUTTONS_LEFT_PIN) &
~(1 << BUTTONS_RIGHT_PIN) &
~(1 << BUTTONS_PLAYPAUSE_PIN);
BUTTONS_LEFT_DDR &= ~(1 << BUTTONS_LEFT);
BUTTONS_RIGHT_DDR &= ~(1 << BUTTONS_RIGHT);
BUTTONS_PLAYPAUSE_DDR &= ~(1 << BUTTONS_PLAYPAUSE);
// Turn on button pullups
BUTTONS_PORT |= (1 << BUTTONS_LEFT_PIN) |
(1 << BUTTONS_RIGHT_PIN) |
(1 << BUTTONS_PLAYPAUSE_PIN);
BUTTONS_LEFT_PORT |= (1 << BUTTONS_LEFT);
BUTTONS_RIGHT_PORT |= (1 << BUTTONS_RIGHT);
BUTTONS_PLAYPAUSE_PORT |= (1 << BUTTONS_PLAYPAUSE);
}
void timer_init() {
@ -44,14 +46,14 @@ void timer_init() {
// To set to CTC, WGM = 0b010
TCCR0A = (1 << WGM01);
// Set to ~20Hz
OCR0A = 195;
// CS = 0b101 -> 1024 prescaler
// Everything else should be 0.
// TCCR0B = 0b00000101; <- can't use this because binary stuff is a GCC extension
TCCR0B = 5;
// Set to ~20Hz
OCR0A = 195;
// Enable interrupt
TIMSK = (1 << OCIE0A);
}

View File

@ -19,10 +19,18 @@
#define UBRR_VALUE (((F_CPU/(USART_BAUDRATE*16UL)))-1)
#define BUTTONS_DDR DDRD
#define BUTTONS_PORT PORTD
#define BUTTONS_LEFT_PIN PORTD2
#define BUTTONS_RIGHT_PIN PORTD3
#define BUTTONS_PLAYPAUSE_PIN PORTD4
#define BUTTONS_LEFT_DDR DDRA
#define BUTTONS_RIGHT_DDR DDRA
#define BUTTONS_PLAYPAUSE_DDR DDRB
#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