#ifndef COMMS_H_ #define COMMS_H_ #include #include #ifdef __AVR_ATmega328P__ #define MEGA328 #endif #ifdef __AVR_ATtiny2313__ #define TINY2313 #endif /** * 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_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) { #ifdef MEGA328 while (! (UCSR0A & (1 << TXC0))); UDR0 = cmd; #elif defined(TINY2313) while (! (UCSRA) & (1 << TXC)) UDR = cmd; #endif } /** @brief Sends the number of songs to play */ inline void comms_send_num(uint8_t num) { comms_send(COMMS_CMD_NUM); comms_send(num); } /** @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 Replies with name of song */ inline void comms_reply_name(char* name) { comms_send(COMMS_CMD_REPLY_NAME); uint8_t len = strlen(name); comms_send(len); for (uint8_t i = 0; i < len; i++) { comms_send(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