From 49b8aee14ba44ff1adc7a81bdfae2fa982a23a94 Mon Sep 17 00:00:00 2001 From: David Lenfesty Date: Fri, 29 Nov 2019 19:41:55 -0700 Subject: [PATCH] close to a functioning skeleton --- final_project/sd_reader/Makefile | 4 +- final_project/sd_reader/fifo.c | 52 +++++++ final_project/sd_reader/fifo.h | 36 +++++ final_project/sd_reader/main.c | 246 ++++++------------------------- final_project/sd_reader/main.h | 16 ++ final_project/sd_reader/periph.c | 16 ++ 6 files changed, 166 insertions(+), 204 deletions(-) create mode 100644 final_project/sd_reader/fifo.c create mode 100644 final_project/sd_reader/fifo.h create mode 100644 final_project/sd_reader/main.h create mode 100644 final_project/sd_reader/periph.c diff --git a/final_project/sd_reader/Makefile b/final_project/sd_reader/Makefile index 80e40a1..f9c5d2b 100644 --- a/final_project/sd_reader/Makefile +++ b/final_project/sd_reader/Makefile @@ -7,7 +7,7 @@ SOURCES := $(wildcard *.c) HEADERS := $(wildcard *.h) OBJECTS := $(patsubst %.c,%.o,$(SOURCES)) -MCU := atmega328 +MCU := atmega328p MCU_AVRDUDE := m328 MCU_FREQ := 16000000UL @@ -16,7 +16,7 @@ OBJCOPY := avr-objcopy SIZE := avr-size -A DOXYGEN := doxygen -CFLAGS := -Wall -pedantic -mmcu=$(MCU) -std=c99 -g -Os -DF_CPU=$(MCU_FREQ) +CFLAGS := -Werror -Wall -pedantic -mmcu=$(MCU) -std=c99 -g -Os -DF_CPU=$(MCU_FREQ) all: $(HEX) diff --git a/final_project/sd_reader/fifo.c b/final_project/sd_reader/fifo.c new file mode 100644 index 0000000..e159ebb --- /dev/null +++ b/final_project/sd_reader/fifo.c @@ -0,0 +1,52 @@ +#include "fifo.h" + +static struct { + FIFO_TYPE buffer[FIFO_LEN]; + uint16_t rd_ptr; + uint16_t wr_ptr; + uint16_t entries; +} fifo; + +void fifo_init() { + fifo.rd_ptr = 0; + fifo.wr_ptr = 0; + fifo.entries = 0; +} + +fifo_err_t fifo_pop(FIFO_TYPE* dest) { + // FIFO is empty, nothing to return! + if (fifo.entries == 0) { + return FIFO_EMPTY; + } + + // Entries in FIFO, pop + *dest = fifo.buffer[fifo.rd_ptr]; + fifo.rd_ptr++; + fifo.entries--; + + // Ensure pointers don't overflow! + if (fifo.rd_ptr == FIFO_LEN) { + fifo.rd_ptr = 0; + } + + return FIFO_SUCCESS; +} + +fifo_err_t fifo_push(FIFO_TYPE src) { + // FIFO is full, don't store anything + if (fifo.entries == FIFO_LEN) { + return FIFO_FULL; + } + + // FIFO has space, write + fifo.buffer[fifo.wr_ptr] = src; + fifo.wr_ptr++; + fifo.entries++; + + // Ensure pointers don't overflow! + if (fifo.wr_ptr == FIFO_LEN) { + fifo.wr_ptr = 0; + } + + return FIFO_SUCCESS; +} \ No newline at end of file diff --git a/final_project/sd_reader/fifo.h b/final_project/sd_reader/fifo.h new file mode 100644 index 0000000..67b502b --- /dev/null +++ b/final_project/sd_reader/fifo.h @@ -0,0 +1,36 @@ +#ifndef FIFO_H_ +#define FIFO_H_ + +#include + +typedef enum { + FIFO_SUCCESS, + FIFO_FULL, + FIFO_EMPTY +} fifo_err_t; + +#define FIFO_LEN 20 +#define FIFO_TYPE uint8_t + +/** @brief Initialises FIFO + * + * This MUST be called before any other fifo_* functions are called. + * Unless memory is initialised to 0. Then it's fine I guess. + */ +void fifo_init(); + +/** @brief Pops most recent addition off of FIFO buffer. + * + * @retval FIFO_SUCCESS Successfully read data from FIFO + * @retval FIFO_EMPTY Buffer was empty, no data read + */ +fifo_err_t fifo_pop(FIFO_TYPE* dest); + +/** @brief Pushes entry onto FIFO buffer. + * + * @retval FIFO_SUCCESS successfully wrote data to FIFO buffer + * @retval FIFO_FULL buffer, was full, no data written + */ +fifo_err_t fifo_push(FIFO_TYPE src); + +#endif \ No newline at end of file diff --git a/final_project/sd_reader/main.c b/final_project/sd_reader/main.c index 2eb64c7..aa5124a 100644 --- a/final_project/sd_reader/main.c +++ b/final_project/sd_reader/main.c @@ -7,209 +7,22 @@ * published by the Free Software Foundation. */ -#include -#include -#include -#include "fat.h" -#include "fat_config.h" -#include "partition.h" -#include "sd_raw.h" -#include "sd_raw_config.h" +#include "main.h" #define DEBUG 1 -/** - * \mainpage MMC/SD/SDHC card library - * - * This project provides a general purpose library which implements read and write - * support for MMC, SD and SDHC memory cards. - * - * It includes - * - low-level \link sd_raw MMC, SD and SDHC read/write routines \endlink - * - \link partition partition table support \endlink - * - a simple \link fat FAT16/FAT32 read/write implementation \endlink - * - * \section circuit The circuit - * The circuit which was mainly used during development consists of an Atmel AVR - * microcontroller with some passive components. It is quite simple and provides - * an easy test environment. The circuit which can be downloaded on the - * project homepage has been - * improved with regard to operation stability. - * - * I used different microcontrollers during development, the ATmega8 with 8kBytes - * of flash, and its pin-compatible alternative, the ATmega168 with 16kBytes flash. - * The first one is the one I started with, but when I implemented FAT16 write - * support, I ran out of flash space and switched to the ATmega168. For FAT32, an - * ATmega328 is required. - * - * The circuit board is a self-made and self-soldered board consisting of a single - * copper layer and standard DIL components, except of the MMC/SD card connector. - * - * The connector is soldered to the bottom side of the board. It has a simple - * eject button which, when a card is inserted, needs some space beyond the connector - * itself. As an additional feature the connector has two electrical switches - * to detect wether a card is inserted and wether this card is write-protected. - * - * \section pictures Pictures - * \image html pic01.jpg "The circuit board used to implement and test this application." - * \image html pic02.jpg "The MMC/SD card connector on the soldering side of the circuit board." - * - * \section software The software - * The software is written in C (ISO C99). It might not be the smallest or - * the fastest one, but I think it is quite flexible. See the project's - * benchmark page to get an - * idea of the possible data rates. - * - * I implemented an example application providing a simple command prompt which is accessible - * via the UART at 9600 Baud. With commands similiar to the Unix shell you can browse different - * directories, read and write files, create new ones and delete them again. Not all commands are - * available in all software configurations. - * - cat \\n - * Writes a hexdump of \ to the terminal. - * - cd \\n - * Changes current working directory to \. - * - disk\n - * Shows card manufacturer, status, filesystem capacity and free storage space. - * - init\n - * Reinitializes and reopens the memory card. - * - ls\n - * Shows the content of the current directory. - * - mkdir \\n - * Creates a directory called \. - * - mv \ \\n - * Renames \ to \. - * - rm \\n - * Deletes \. - * - sync\n - * Ensures all buffered data is written to the card. - * - touch \\n - * Creates \. - * - write \ \\n - * Writes text to \, starting from \. The text is read - * from the UART, line by line. Finish with an empty line. - * - * \htmlonly - *

- * The following table shows some typical code sizes in bytes, using the 20090330 release with a - * buffered read-write MMC/SD configuration, FAT16 and static memory allocation: - *

- * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
layercode sizestatic RAM usage
MMC/SD2410518
Partition45617
FAT167928188
- * - *

- * The static RAM is mostly used for buffering memory card access, which - * improves performance and reduces implementation complexity. - *

- * - *

- * Please note that the numbers above do not include the C library functions - * used, e.g. some string functions. These will raise the numbers somewhat - * if they are not already used in other program parts. - *

- * - *

- * When opening a partition, filesystem, file or directory, a little amount - * of RAM is used, as listed in the following table. Depending on the library - * configuration, the memory is either allocated statically or dynamically. - *

- * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
descriptordynamic/static RAM
partition17
filesystem26
file53
directory49
- * - * \endhtmlonly - * - * \section adaptation Adapting the software to your needs - * The only hardware dependent part is the communication layer talking to the - * memory card. The other parts like partition table and FAT support are - * completely independent, you could use them even for managing Compact Flash - * cards or standard ATAPI hard disks. - * - * By changing the MCU* variables in the Makefile, you can use other Atmel - * microcontrollers or different clock speeds. You might also want to change - * the configuration defines in the files fat_config.h, partition_config.h, - * sd_raw_config.h and sd-reader_config.h. For example, you could disable - * write support completely if you only need read support. - * - * For further information, visit the project's - * FAQ page. - * - * \section bugs Bugs or comments? - * If you have comments or found a bug in the software - there might be some - * of them - you may contact me per mail at feedback@roland-riegel.de. - * - * \section acknowledgements Acknowledgements - * Thanks go to Ulrich Radig, who explained on his homepage how to interface - * MMC cards to the Atmel microcontroller (http://www.ulrichradig.de/). - * I adapted his work for my circuit. - * - * \section copyright Copyright 2006-2012 by Roland Riegel - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation (http://www.gnu.org/copyleft/gpl.html). - * At your option, you can alternatively redistribute and/or modify the following - * files under the terms of the GNU Lesser General Public License version 2.1 - * as published by the Free Software Foundation (http://www.gnu.org/copyleft/lgpl.html): - * - byteordering.c - * - byteordering.h - * - fat.c - * - fat.h - * - fat_config.h - * - partition.c - * - partition.h - * - partition_config.h - * - sd_raw.c - * - sd_raw.h - * - sd_raw_config.h - * - sd-reader_config.h - */ +#define MAX_SONG_NUM 9 -static struct fat_file_struct* open_file_in_dir(struct fat_fs_struct* fs, struct fat_dir_struct* dd, const char* name); + +typedef struct { + struct fat_file_struct* fd; + char* name; +} song_info_t; + +song_info_t songs[MAX_SONG_NUM]; int main() { - lcd_init(LCD_DISP_ON); - /* we will just use ordinary idle mode */ //set_sleep_mode(SLEEP_MODE_IDLE); @@ -242,16 +55,45 @@ int main() fat_get_dir_entry_of_path(fs, "/", &directory); struct fat_dir_struct* dd = fat_open_dir(fs, &directory); + + // Get all of the song names + struct fat_dir_entry_struct dir_entry; + uint8_t song_id = 0; + while(fat_read_dir(dd, &dir_entry)) { + // too many files! + if (song_id == MAX_SONG_NUM) { + break; + } + + // Is file, so add to list + if (!(dir_entry.attributes & FAT_ATTRIB_DIR)) { + // TODO add checking if its .wav + + // Copy song name into memory + uint8_t len = strlen(dir_entry.long_name); + songs[song_id].name = malloc(len); + strcpy(songs[song_id].name, dir_entry.long_name); + + // Open file and keep info in songs + fat_open_file(fs, songs[song_id].fd); + + // Move on to reading next song + song_id++; + } + + } // Print out all files/directories in top level while (1) { - struct fat_dir_entry_struct dir_entry; - while(fat_read_dir(dd, &dir_entry)) { - // print out directory entry name - lcd_clrscr(); - lcd_gotoxy(0,0); - lcd_puts(dir_entry.long_name); + /// do stuff + + uint8_t incoming_cmd; + if (fifo_pop(&incoming_cmd) == FIFO_SUCCESS) { + // Handle incoming command + } + + // TODO check here if we are running into the end of our song buffer, and read in song data } return 0; diff --git a/final_project/sd_reader/main.h b/final_project/sd_reader/main.h new file mode 100644 index 0000000..791db21 --- /dev/null +++ b/final_project/sd_reader/main.h @@ -0,0 +1,16 @@ +#ifndef MAIN_H_ +#define MAIN_H_ + +#include +#include +#include +#include +#include "fat.h" +#include "fat_config.h" +#include "partition.h" +#include "sd_raw.h" +#include "sd_raw_config.h" +#include "fifo.h" + + +#endif \ No newline at end of file diff --git a/final_project/sd_reader/periph.c b/final_project/sd_reader/periph.c new file mode 100644 index 0000000..36b9620 --- /dev/null +++ b/final_project/sd_reader/periph.c @@ -0,0 +1,16 @@ +#include "main.h" +#include + +ISR(USART_RX_vect) { + cli(); + // Read byte into FIFO + + sei(); +} + +ISR(TIMER0_COMPA_vect) { + cli(); + // Handle music playing + + sei(); +} \ No newline at end of file