Драйвер FAT16
 

    Драйвер осуществляет взаимодействие с файловой системой карт памяти SD и MMC и написан на языке Си (компилятор CodeVision). При его реализации передо мной стояла довольно специфическая задача, поэтому он имеет несколько ограничений:
-FAT16, только чтение;
-чтение только корневой дирректории;
-фиксированный размер сектора(блока данных) = 512 байт;
    Код занимает довольно мало места. Так, отладочная программа, воспроизводящая звуковые WAV файлы, спокойно поместилась в Atmega48(4 Кбайт FLASH), сам же драйвер для работы потребовал около 130 байт ОЗУ. При тестировании(простое считывание файла байт за байтом), средняя скорость считывания данных составляла ~330Кбайт/сек. Условия тестирования: оптимизация кода по скорости, тактовая частота контроллера 16МГц, Sandisk microSD 256MB.
    Этот драйвер был использован в конструкции SD ILDA Laser File Player. Все функции оптимизированы по скорости.

    Описание функций.

    Файл SDIO.C - низкоуровневые функции передачи данных:
void init_SD(void)
Инициализировать SD-карту в режиме SPI

void wait_ready (void)
Ждать готовности карты памяти

char send_CMD(char cmd,unsigned long int arg)
Послать команду в карту, возращает ответ карты.

void end_read(void)
Принудительно остановить передачу данных(чтение)

void read_partial_sector(
        unsigned long adress, //абсолютный адрес сектора
        unsigned char *destination,//заполняемый массив - объект назначения
        unsigned int offset,//смещение в байтах с текущей позиции, нет смещения = 0
        unsigned char len)//сколько байтов прочитать
Читает часть сектора в массив *destination.

Для ускорения обмена данными между функциями я отказался от операций параллельного сдвига(<< и >>, а они использовались для выделения байта из многобайтовых переменных) и применил юнионы. Да к тому же и FLASH сэкономилась. Декларации юнионов:

union long_arr//convert long<>bytes
        {
        unsigned char carr[4];
        unsigned long dword;
        };

union int_arr//convert int<>bytes
        {
        unsigned char carr[2];
        unsigned int word;
        };

Надо сказать, что при реализации низкоуровневого обмена данных я заглядывал в проекты[1], поэтому в функциях имеются некотрые сходства.

    Файл FAT.C - собственно сам драйвер FAT16:
unsigned char get_FAT(void)
Загрузить информацию о файловой системе с диска(MBR, PBR и др. необходимые смещения). Возвращает 0 если обнаружена ошибка(например, диск не FAT16).

unsigned int get_cluster_status(unsigned int entry_number)
Получить статус кластера из таблицы FAT. Используется первая копия таблицы. Функция используется для получения цепочки кластеров.

struct OPEN_RESULT
*open_file(flash unsigned char *file_name,unsigned int entry_number)
Пытается открыть для чтения файл по имени file_name(имя должно хранится во флеш) и начальным номером записи entry_number. Для поиска файлов на имя может накладываться маска из символов вопроса ('?'). При сравнении имен эти символы игнорируются. Функция возвращает результат в виде указателя на структуру OPEN_RESULT, в которую помещаются данные о номере записи и статусе файла(1=найден и открыт функцией для чтения).

void reset_file(void)
Сбрасывает все указатели чтения файла в начальную позицию.

char read_file(void)
Читает и возвращает очередной байт из открытого файла.
В теле функции строка //if(++byte_counter==size_of_file) _EOF=1; закомментирована т.к. мне не нужно было проверять условие достижения конца файла. Если вам это надо, то строку раскомментируйте. Тогда индикатором конца может служить флаг _EOF.

struct FILE_PARAM
*find_file(flash unsigned char *name,unsigned int entry_number)
Осущетсвляет поиск имени+расширения файла в корневой дирректории с указанной позиции номера записи каталога entry_number. На имя также может быть наложена маска из символов '?'. Функция возвращает результат в виде указателя на структуру FILE_PARAM, в которой содержатся сведения о номере записи найденного файла, самом первом кластере файла, его размере и статусе(1=найден, 0=не найден).

unsigned int set_file_position(unsigned long position)
Устанавливает указатель чтения байта в открытом файле по указываемому адресу. Возвращает нулевое значение в случае отсутствия ошибок и ненулевое значение(1) если произошла ошибка(адрес выходит за границы файла).

Декларации структур, используемых в этом файле:

struct FILE_PARAM //Parameters of file which was found
        {
        unsigned long first_cluster;
        unsigned long file_size;
        unsigned char file_status;//0=no file found; 1=file presents
        unsigned int  entry_number;
        };

struct OPEN_RESULT //Result of opening file
        {
        unsigned char file_status;
        unsigned int entry_number;
        };
 

Остальные файлы проекта содержат функции плеера.

Файл SD.C - главный файл проекта, содержит функцию main().
Файл ILDA.C - функции загрузки, идентификации заголовков и загрузки векторов из стандартных файлов ILDA.
Файл PALETTE.C - таблица конвертации палитры в TTL цвета.
Файл STREAM.C - функции воспроизведения буферизованного потока данных. Т.к. карты памяти SD не обеспечивают равномерный поток данных, то необходима его буферизация.
 

    Скачать:
    Исходные коды SD ILDA Laser File Player вместе с драйвером FAT
 

    Ссылки:
    1. Simple SD Audio Player with an 8-pin IC
 
 

На главную

Hosted by uCoz