From 744115b4464040a73bcf7f62f93f907284191031 Mon Sep 17 00:00:00 2001 From: David Lenfesty <6893214+davidlenfesty@users.noreply.github.com> Date: Tue, 3 Dec 2019 00:39:32 -0700 Subject: [PATCH] work from lab --- final_project/lcd_disp/comms.h | 87 ++++++++++++++++++++++++++++++++- final_project/lcd_disp/lcd.h | 18 +++---- final_project/lcd_disp/main.c | 53 ++++++++++++++------ final_project/lcd_disp/main.h | 4 ++ final_project/lcd_disp/periph.c | 20 ++++---- final_project/lcd_disp/periph.h | 16 ++++-- 6 files changed, 160 insertions(+), 38 deletions(-) diff --git a/final_project/lcd_disp/comms.h b/final_project/lcd_disp/comms.h index ad5c9e6..4c3443c 120000 --- a/final_project/lcd_disp/comms.h +++ b/final_project/lcd_disp/comms.h @@ -1 +1,86 @@ -../comms/comms.h \ No newline at end of file +#ifndef COMMS_H_ +#define COMMS_H_ + +#include +#include + + +/** + * 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 \ No newline at end of file diff --git a/final_project/lcd_disp/lcd.h b/final_project/lcd_disp/lcd.h index 0dbc197..2edca3a 100644 --- a/final_project/lcd_disp/lcd.h +++ b/final_project/lcd_disp/lcd.h @@ -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__) || \ diff --git a/final_project/lcd_disp/main.c b/final_project/lcd_disp/main.c index b34a70e..517285d 100644 --- a/final_project/lcd_disp/main.c +++ b/final_project/lcd_disp/main.c @@ -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,9 +42,13 @@ void handle_left_press() { */ void handle_right_press() { if (songs.num_songs == 0) { - lcd_clrscr(); - lcd_puts("No songs to play!"); - } else { + 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++; if (display_song == songs.num_songs) { @@ -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,16 +88,23 @@ 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_gotoxy(0,0); + + lcd_puts("..."); + + sei(); // Main loop while (1) { @@ -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; diff --git a/final_project/lcd_disp/main.h b/final_project/lcd_disp/main.h index a52eb9f..e89b3fc 100644 --- a/final_project/lcd_disp/main.h +++ b/final_project/lcd_disp/main.h @@ -1,6 +1,9 @@ #ifndef MAIN_H_ #define MAIN_H_ +#define F_CPU 8000000 +#define ATTINY2313 + #include #include #include @@ -20,4 +23,5 @@ /* ---- Globally available flags ---- */ extern bool update_display; + #endif \ No newline at end of file diff --git a/final_project/lcd_disp/periph.c b/final_project/lcd_disp/periph.c index bb18795..84bf8f4 100644 --- a/final_project/lcd_disp/periph.c +++ b/final_project/lcd_disp/periph.c @@ -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() { @@ -43,15 +45,15 @@ void timer_init() { // COM0x can be set to defaults // 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); } diff --git a/final_project/lcd_disp/periph.h b/final_project/lcd_disp/periph.h index e1ac82a..6c4e03f 100644 --- a/final_project/lcd_disp/periph.h +++ b/final_project/lcd_disp/periph.h @@ -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