Програмная часть: интерфейсы накопителей: оболочка физических средОболочка (файл media.asm.inc) обеспечивает прозрачную работу с накопителем независимо от его физического типа. ИнициализацияТак как требуемое для инициализации IDE-устройства время может превышать 10 секунд, и быстрее определить факт его отсутствия в общем случае нельзя, было решено вызов процедур инициализации накопителей возложить на оболочку сред: она знает, какой накопитель предполагается использовать и вызывает функцию инициализации только данного устройства. Эти операции выполняет процедура media_Init. После её исполнения управление передается процедуре media_Init_PT - она читает главную таблицу разделов и вычисляет смещение требуемого раздела. Номер раздела задаётся в виде целого беззнакового числа. Значение 0 указывает на использование всего накопителя целиком (т.е. в случае, если он не имеет таблицы разделов). В таблице разделов анализируются только LBA-поля, CHS-поля игнорируются. Поле типа файловой системы анализируется только на совпадение с номерами 0 (строка не заполнена), 5 и 15 (расширения таблицы разделов). В коде оболочки сред предусмотрена одна хитрость: если используемое устройство - SD-карта, перед её инициализацией вызывается процедура ide_PowerDown. Она выставляет на IDE-шину код операции 0xE6 - это режим Sleep - самый глубокий сон. Операция проводится без какого либо ожидания готовности IDE-устройства, поэтому даже в случае его отсутствия никаких ошибок диагностироваться не будет. Эта хитрость позволяет резко снижать энергопотребление плейера, если ожидается его работа с SD-картой. Но так как в штатном режиме код выставляется почти сразу после включения, IDE-устройство может не среагировать на него. В этом случае можно просто войти в главное меню и вновь выбрать SD-карту, не отключая питание плейера - тогда команда будет выполена с высокой вероятностью. Ввод-выводОбмен с выбранным накопителем осуществляется блоками по 512 байт, имеется четыре процедуры обмена: media_Read, media_ReadNoOffset, media_Write, media_WriteNoOffset. Процедуры с суффиксом NoOffset в имени оперируют адресным пространством всего накопителя, процедуры без суффикса - только блоками, лежащими от начала выбранного раздела и выше. Проверок на выход за пределы раздела не выполняется ! Процедуры записи данных на носители хотя и реализованы, но в основном коде плейера не используются. Код завершения передается в виде единственного бита во флаге C. SD-картаSD-карты документированы не полностью, некоторая часть документации доступна только за деньги. Что особенно удивительно: например, недоступны фактические размеры на чертеже разъёма карты. Т.е. как бы ни у кого нет штангенциркуля замерить их... Нда... А как раз бОльшая часть описания электронной части доступна. Хотя местами встречаются некоторые непонятки и приходится обращаться к легкому шаманству. У меня так получилось в процедуре инициализации. Однако написанный код работает стабильно, что от него и требуется. Поддерживаются только карты до 2 Гб ! Протокол обмена с картой допускает использование контрольных сумм, но в коде он не реализован. Возможны (но я могу ошибаться !) две причины: 1) в режиме SPI контроллер карты не проверяет контрольных сумм, хотя и генерирует их. 2) реализация алгоритма расчёта CCITTRR-CRC хотя и весьма проста аппаратно, но довольно накладна в случае програмного исполнения. ИнициализацияАккуратно срисована с инициализации MMC-карт + некоторые специфические SD-дополнения. Ввод-вывод и диагностика ошибокОбмен блоками по 512 байт, адрес блока также умножается на 512 (в SD-картах низкой плотности принята адресация с точностью до байта, а не сектора). Обмен анализируется на наличие разнообразных ошибок, как в протоколе (контроллер карты не понимает запросов процессора), так и в реакции карты на запрос (т.е. команда понята картой, но её полное выполнение по какой-то причине невозможно). Коды ошибок возвращаются вызвавшей обмен процедуре, однако если вызов происходил через оболочку сред, с точки зрения унификации, предпочтительнее использовать в качестве статуса завершения операции только значение флага C. IDE-накопительПротоколы обмена с IDE-устройствами давно и хорошо известны, в коде плейера есть только три отступления от святых заповедей: 1) LBA ! Код не проверяет наличие поддержки LBA-адресации у накопителя (он начал поддерживаться всеми накопителями начиная, примерно, с объёма 500 Мб), но использует только этот режим. 2) Время ожидания при инициализации накопителя составляет 10 секунд, хотя должно быть больше. На самом деле подопытный Futjitsu запускается за ~3 секунды, а константу в коде легко подправить, если нужно. 3) При возникновении ошибок информация о них передаётся вызвавшей процедуре, но сброс накопителя не выполняется, что может привести к полной блокировке обмена, например, при запросе BAD-блока. Также я не стал реализовывать всю каноническую механнику самодиагностики накопителей (которая происходит по линиям !PDIAG и !PDASP), вроде в документации она не указана как обязательная и в современных накопителях используется только в случае автоматического назначения адресов устройств на общем кабеле ("Cable Select"). Как следствие, при использовании винта в Orfey'е, джампер должен стоять в положении "Master". Аппаратная часть плейера поддерживает работу накопителей только в режиме 24-х-битной адресации - т.е. до 128 Гб. Если накопитель имеет бОльший объём - будут доступны только первые 128 Гб. ИнициализацияIDE-накопитель имеет линию аппаратного сброса !RESET, подтянутую PullUp'ом к питанию, поэтому даже если с ним ничего не делать, при появлении питания он инициализируется самостоятельно. Так как для работы в режиме LBA-24 никакой настройки параметров не требуется, процедура инициализации лишь ожидает установки бита готовности и сообщает вызвавшему её уровню, удалось ли дождаться появления этого бита в течении 10 секунд. Для того, чтобы предотвратить неопределённость значения бита готовности в случае отсутствия накопителя, на соответствующем входе ATmega32 подключается внутренний PullUp-резистор. Установки каких либо параметров, например, режима энергосбережения не предусмотрено (а смысл ? всё равно обращение за очередной дозой данных будет происходить несколько раз в секунду). Весьма немаловажный флажок, разрешающий Look-AHead (режим, в котором накопитель считывает с блинов в собственный кеш данные, которые, по его мнению, скоро будут запрошены), в проверенных мной накопителях устанавливался после инициализации самостоятельно. Ввод-вывод и диагностика ошибокБлоками 512 байт. Диагностика ошибок очень проста, результат возвращается только во флаге C, всего обнаруживаются лишь две ошибки: слишком высокий адрес (адрес ожидается в четырех 8-и-битных регистрах, но так как поддерживаемая реализация IDE-интерфейса имеет лишь 24 разряда, наличие "1" в старших битах расценивается как ошибка) и ошибка выполнения команды накопителем. Ситуация, когда накопитель слишком долго не снимает флажок занятости не анализируется (т.е. код просто будет "висеть" пока не дождётся готовности). Так же не анализируется состояние накопителя после успешного приёма им команды "Запись" (т.е. остаётся неизвестно, удалось ли накопителю выполнить запись фактически ?). |