Драйвер осуществляет взаимодействие
с файловой системой карт памяти 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